diff --git a/package-lock.json b/package-lock.json index 654dc19..0d18988 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "coinswap-taker", - "version": "0.2.0", + "version": "0.2.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "coinswap-taker", - "version": "0.2.0", + "version": "0.2.1", "license": "ISC", "dependencies": { "@tailwindcss/cli": "^4.1.14", diff --git a/src/components/swap/Coinswap.js b/src/components/swap/Coinswap.js index 33971e0..90dcede 100644 --- a/src/components/swap/Coinswap.js +++ b/src/components/swap/Coinswap.js @@ -147,22 +147,29 @@ export async function CoinswapComponent(container, swapConfig) { const hopStatus = hop.querySelector('.hop-status'); if (hopStatus) { - hopStatus.textContent = statusText; - const colorClass = + // Hop labels are SVG nodes, so icon SVG markup must be stripped. + const normalizedStatus = String(statusText) + .replace(/<[^>]*>/g, ' ') + .replace(/\s+/g, ' ') + .trim(); + const fillColor = color === 'green' - ? 'text-green-400' + ? '#4ADE80' : color === 'yellow' - ? 'text-yellow-400' + ? '#FACC15' : color === 'orange' - ? 'text-orange-400' + ? '#FB923C' : color === 'blue' - ? 'text-blue-400' - : 'text-gray-400'; + ? '#60A5FA' + : '#9CA3AF'; + + hopStatus.textContent = normalizedStatus; + hopStatus.setAttribute('fill', fillColor); // ✅ FIX: Use setAttribute for SVG elements hopStatus.setAttribute( 'class', - `hop-status text-xs ${colorClass} font-bold` + 'hop-status text-xs font-bold' ); if (color === 'yellow' || color === 'orange') { @@ -182,7 +189,7 @@ export async function CoinswapComponent(container, swapConfig) { function markAllMakersComplete() { for (let i = 0; i < swapData.makers; i++) { updateMakerVisibility(i, true); - updateHopStatus(i, `${icons.check(14, 'mr-1')} Complete`, 'green'); + updateHopStatus(i, 'Complete', 'green'); } } @@ -318,7 +325,7 @@ export async function CoinswapComponent(container, swapConfig) { ); if (slot !== -1) { setTransactionConfirmed(slot); - updateHopStatus(slot, `${icons.check(14, 'mr-1')} Confirmed`, 'green'); + updateHopStatus(slot, 'Confirmed', 'green'); const confirmedHops = swapData.transactions.filter( (tx) => tx.status === 'confirmed' @@ -343,7 +350,7 @@ export async function CoinswapComponent(container, swapConfig) { ); if (slot !== -1) { setTransactionConfirmed(slot); - updateHopStatus(slot, `${icons.check(14, 'mr-1')} Confirmed`, 'green'); + updateHopStatus(slot, 'Confirmed', 'green'); // ✅ When outgoing is confirmed, light up ALL makers and mark intermediate hops as "Processing" if (slot === 0) { @@ -353,7 +360,7 @@ export async function CoinswapComponent(container, swapConfig) { } // Mark intermediate hops as processing (hops 1 to N-1) for (let i = 1; i < swapData.hops - 1; i++) { - updateHopStatus(i, `${icons.refreshCw(14, 'mr-1 animate-spin')} Processing...`, 'blue'); + updateHopStatus(i, 'Processing...', 'blue'); } console.log( `✅ Outgoing contract confirmed. All ${swapData.makers} makers now active` @@ -385,7 +392,7 @@ export async function CoinswapComponent(container, swapConfig) { ) { // Mark all intermediate hops as "Keys received" for (let i = 1; i < swapData.hops - 1; i++) { - updateHopStatus(i, `${icons.key(14, 'mr-1')} Keys received`, 'green'); + updateHopStatus(i, 'Keys received', 'green'); } } // V2: "Registered watcher for taker's incoming contract" @@ -396,7 +403,7 @@ export async function CoinswapComponent(container, swapConfig) { if (txMatch) { // This is the final hop - mark it const lastHop = swapData.hops - 1; - updateHopStatus(lastHop, `${icons.arrowDownCircle(14, 'mr-1')} Receiving...`, 'blue'); + updateHopStatus(lastHop, 'Receiving...', 'blue'); } } // V2: "Sweeping taker's incoming contract" @@ -409,19 +416,19 @@ export async function CoinswapComponent(container, swapConfig) { const txMatch = message.match(/([a-f0-9]{64})/i); if (txMatch) { const lastHop = swapData.hops - 1; - updateHopStatus(lastHop, `${icons.check(14, 'mr-1')} Swept`, 'green'); + updateHopStatus(lastHop, 'Swept', 'green'); } } // V1: "Swaps settled successfully" else if (message.includes('Swaps settled successfully')) { for (let i = 0; i < swapData.hops; i++) { - updateHopStatus(i, `${icons.check(14, 'mr-1')} Complete`, 'green'); + updateHopStatus(i, 'Complete', 'green'); } } // V2: "Taker sweep completed successfully" else if (message.includes('Taker sweep completed successfully')) { for (let i = 0; i < swapData.hops; i++) { - updateHopStatus(i, `${icons.check(14, 'mr-1')} Complete`, 'green'); + updateHopStatus(i, 'Complete', 'green'); } // Make sure all makers are visible for (let i = 0; i < swapData.makers; i++) { @@ -432,7 +439,7 @@ export async function CoinswapComponent(container, swapConfig) { // V2: "Successfully Completed Taproot Coinswap" else if (message.includes('Successfully Completed Taproot Coinswap')) { for (let i = 0; i < swapData.hops; i++) { - updateHopStatus(i, `${icons.check(14, 'mr-1')} Complete`, 'green'); + updateHopStatus(i, 'Complete', 'green'); } // Make sure all makers are visible for (let i = 0; i < swapData.makers; i++) { @@ -452,7 +459,7 @@ export async function CoinswapComponent(container, swapConfig) { else if (message.includes('Starting forward-flow private key handover')) { // Mark intermediate hops as doing key exchange for (let i = 1; i < swapData.hops - 1; i++) { - updateHopStatus(i, `${icons.keyRound(14, 'mr-1')} Key exchange...`, 'yellow'); + updateHopStatus(i, 'Key exchange...', 'yellow'); } } // V2: "Downloading offer from taproot maker" @@ -487,7 +494,7 @@ export async function CoinswapComponent(container, swapConfig) { message.includes('Verified Taproot contract data from maker') ) { updateMakerVisibility(makerIndex, true); - updateHopStatus(makerIndex, `${icons.check(14, 'mr-1')} Contract ready`, 'green'); + updateHopStatus(makerIndex, 'Contract ready', 'green'); } // V2: "Received private key from maker N" else if ( @@ -495,7 +502,7 @@ export async function CoinswapComponent(container, swapConfig) { message.includes('Received private key from maker') ) { updateMakerVisibility(makerIndex, true); - updateHopStatus(makerIndex, `${icons.keyRound(14, 'mr-1')} Key received`, 'green'); + updateHopStatus(makerIndex, 'Key received', 'green'); } // V2: "Sending privkey to maker N and awaiting response" else if ( @@ -526,7 +533,10 @@ export async function CoinswapComponent(container, swapConfig) { updateYouReceive(true); } // V2: "Sweeping N completed incoming swap coins" - else if (message.includes('Sweeping') && message.includes('completed incoming swap coins')) { + else if ( + message.includes('Sweeping') && + message.includes('completed incoming swap coins') + ) { markAllMakersComplete(); updateYouReceive(true); } @@ -635,7 +645,10 @@ export async function CoinswapComponent(container, swapConfig) { const swap = result.swap; - if (swap.nativeSwapId && actualSwapConfig.nativeSwapId !== swap.nativeSwapId) { + if ( + swap.nativeSwapId && + actualSwapConfig.nativeSwapId !== swap.nativeSwapId + ) { actualSwapConfig.nativeSwapId = swap.nativeSwapId; addLog(`Backend Swap ID: ${swap.nativeSwapId}`, 'info'); } @@ -822,11 +835,10 @@ export async function CoinswapComponent(container, swapConfig) { 'swapDurationSeconds', 0 ); - const targetAmount = getValue( - 'target_amount', - 'targetAmount', - swapData.amount || 0 - ); + const targetAmount = + backendReport.outgoing_amount ?? + backendReport.outgoingAmount ?? + getValue('target_amount', 'targetAmount', swapData.amount || 0); const totalInputAmount = getValue( 'total_input_amount', 'totalInputAmount', @@ -1153,8 +1165,7 @@ export async function CoinswapComponent(container, swapConfig) { const gap = 14; if (actualMakers <= 4) { - const minRadius = - (maxNodeHalf + gap) / Math.sin(Math.PI / totalNodes); + const minRadius = (maxNodeHalf + gap) / Math.sin(Math.PI / totalNodes); const radius = Math.max(minRadius, 140); const svgSize = Math.round((radius + labelPad) * 2); const centerX = svgSize / 2; @@ -1258,7 +1269,10 @@ export async function CoinswapComponent(container, swapConfig) { ${Array.from({ length: totalNodes }, (_, i) => { - const color = i < actualMakers ? makerColors[i % makerColors.length] : '#10B981'; + const color = + i < actualMakers + ? makerColors[i % makerColors.length] + : '#10B981'; return ` `; @@ -1273,23 +1287,29 @@ export async function CoinswapComponent(container, swapConfig) { ${guideMarkup} - ${positions.map((pos, i) => { - const nextPos = positions[(i + 1) % positions.length]; - const color = i < actualMakers ? makerColors[i % makerColors.length] : '#10B981'; - const fromHalf = i === 0 ? youHalf : makerHalf; - const toHalf = (i + 1) % positions.length === 0 ? youHalf : makerHalf; - const dx = nextPos.x - pos.x; - const dy = nextPos.y - pos.y; - const len = Math.sqrt(dx * dx + dy * dy); - const sx = pos.x + (dx / len) * (fromHalf + 4); - const sy = pos.y + (dy / len) * (fromHalf + 4); - const ex = nextPos.x - (dx / len) * (toHalf + 10); - const ey = nextPos.y - (dy / len) * (toHalf + 10); - return ` + ${positions + .map((pos, i) => { + const nextPos = positions[(i + 1) % positions.length]; + const color = + i < actualMakers + ? makerColors[i % makerColors.length] + : '#10B981'; + const fromHalf = i === 0 ? youHalf : makerHalf; + const toHalf = + (i + 1) % positions.length === 0 ? youHalf : makerHalf; + const dx = nextPos.x - pos.x; + const dy = nextPos.y - pos.y; + const len = Math.sqrt(dx * dx + dy * dy); + const sx = pos.x + (dx / len) * (fromHalf + 4); + const sy = pos.y + (dy / len) * (fromHalf + 4); + const ex = nextPos.x - (dx / len) * (toHalf + 10); + const ey = nextPos.y - (dy / len) * (toHalf + 10); + return ` `; - }).join('')} + }) + .join('')} @@ -1315,11 +1335,15 @@ export async function CoinswapComponent(container, swapConfig) { width="${makerHalf * 2}" height="${makerHalf * 2}" rx="${makerRx}" fill="${color}"/> M${i + 1} - ${actualMakers <= 12 ? ` + ${ + actualMakers <= 12 + ? ` Maker ${i + 1} - ` : ''} - + ` + : '' + } + @@ -1329,10 +1353,14 @@ export async function CoinswapComponent(container, swapConfig) { `; }).join('')} - ${isV2 ? ` + ${ + isV2 + ? ` ${swapProtocol} MuSig2 - ` : ''} + ` + : '' + } `; @@ -1418,18 +1446,23 @@ export async function CoinswapComponent(container, swapConfig) {

Amount

${(swapData.amount / 100000000).toFixed(8)} BTC

- ${!isV2 - ? `

Hops: ${swapData.hops}

` - : `

${swapProtocol} swap

` + ${ + !isV2 + ? `

Hops: ${swapData.hops}

` + : `

${swapProtocol} swap

` }
- ${!isV2 ? ` + ${ + !isV2 + ? `

Hop Transactions

- ` : ''} + ` + : '' + }
diff --git a/src/components/swap/SwapHistory.js b/src/components/swap/SwapHistory.js index 7ced966..ee50fc8 100644 --- a/src/components/swap/SwapHistory.js +++ b/src/components/swap/SwapHistory.js @@ -132,7 +132,11 @@ function normalizeSwapReport(report) { completedAt, amount: toNumber( - report.amount ?? + nested.outgoingAmount ?? + nested.outgoing_amount ?? + report.totalOutputAmount ?? + report.total_output_amount ?? + report.amount ?? nested.amount ?? nested.targetAmount ?? nested.target_amount ?? diff --git a/src/components/swap/SwapReport.js b/src/components/swap/SwapReport.js index 9d0f389..c3a51bc 100644 --- a/src/components/swap/SwapReport.js +++ b/src/components/swap/SwapReport.js @@ -119,19 +119,19 @@ export function SwapReportComponent(container, swapReport) { []; const flattenedFundingTxids = dedupeTxids(normalizedFundingTxids); const normalizedTargetAmount = toNumber( - swapReport.targetAmount ?? + swapReport.outgoingAmount ?? + swapReport.outgoing_amount ?? + swapReport.targetAmount ?? swapReport.target_amount ?? swapReport.incomingAmount ?? swapReport.incoming_amount ?? - swapReport.outgoingAmount ?? - swapReport.outgoing_amount ?? nestedReport.targetAmount ?? nestedReport.target_amount ?? + nestedReport.outgoingAmount ?? + nestedReport.outgoing_amount ?? swapReport.amount ?? nestedReport.incomingAmount ?? - nestedReport.incoming_amount ?? - nestedReport.outgoingAmount ?? - nestedReport.outgoing_amount, + nestedReport.incoming_amount, 0 ); const normalizedTotalFundingTxs = toNumber( diff --git a/src/components/swap/SwapStateManager.js b/src/components/swap/SwapStateManager.js index ad412cb..9a1fa4d 100644 --- a/src/components/swap/SwapStateManager.js +++ b/src/components/swap/SwapStateManager.js @@ -124,7 +124,7 @@ export const SwapStateManager = { const historyEntry = { id: report.swapId || `swap_${Date.now()}`, completedAt: Date.now(), - amount: report.targetAmount || 0, + amount: report.totalOutputAmount || report.targetAmount || 0, totalOutputAmount: report.totalOutputAmount || 0, makersCount: report.makersCount || 0, hops: (report.makersCount || 0) + 1, diff --git a/src/styles/output.css b/src/styles/output.css index f3f0561..ffaa9a2 100644 --- a/src/styles/output.css +++ b/src/styles/output.css @@ -62,8 +62,6 @@ --text-3xl--line-height: calc(2.25 / 1.875); --text-4xl: 2.25rem; --text-4xl--line-height: calc(2.5 / 2.25); - --text-6xl: 3.75rem; - --text-6xl--line-height: 1; --font-weight-normal: 400; --font-weight-medium: 500; --font-weight-semibold: 600;