diff options
| author | Adam Soltys <[email protected]> | 2026-09-10 21:53:46 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-09-10 21:53:46 -0700 |
| commit | d654e2d1cb76aa4d1032db2c424b7937e44b9429 (patch) | |
| tree | dcdc1fd9cd9bedb6870659253cf910d036350e5e /src/features/ark.js | |
| parent | 3cda220c2432181b5f2dfc0c47e28c3e3cb54f18 (diff) | |
| download | coinosv3-d654e2d1cb76aa4d1032db2c424b7937e44b9429.tar.gz coinosv3-d654e2d1cb76aa4d1032db2c424b7937e44b9429.zip | |
The zap chip lands on the tap and pulses until the payment settles.
A zap took a few seconds to pay and its public receipt trailed that by
seconds more, so the tally chip appeared long after the tap — the tap looked
ignored, and the only way to tell it had worked was the toast.
Now the chip appears on the tap carrying your amount, breathing while the
payment is in flight; it goes solid the moment the payment lands, and steps
aside when the real receipt arrives (which is also how it avoids counting
your zap twice). The ark and Lightning one-tap flows report their outcome
back — a failure, or a fallback into the form, takes the chip straight off
again rather than leaving it pulsing. An unreported zap gives up after 45s.
A zap sent from the form reports too, so the tally shows it right away
instead of waiting on a relay. Reduced-motion gets a dimmed chip, no pulse.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_019mrt228Upn9nNCwGixzSLx
Diffstat (limited to 'src/features/ark.js')
| -rw-r--r-- | src/features/ark.js | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/src/features/ark.js b/src/features/ark.js index 251f740..8e74cc6 100644 --- a/src/features/ark.js +++ b/src/features/ark.js @@ -1499,16 +1499,26 @@ export function arkFeature(ctx) { ui.sendError = ''; render(); const live = () => ui.arkZap === z; + // The tap already put a pulsing chip on the note being zapped: whichever + // way this goes, say so, so the chip settles instead of pulsing until it + // times out. (A handover to the Lightning flow doesn't report — that flow + // is still carrying the same zap, and reports for itself.) + const bail = () => { + if (!z.autoSat) return; // a form zap: the card keeps the screen and its own status + ctx.hook('zapSettled', z.eventId, false); + z.autoSat = 0; ui.tab = 'send'; + }; // an instant zap: resolution succeeded — pay the default amount now, no // form, and report by toast; failures fall back to the classic form const auto = async (label) => { try { await performArkZap(z, z.autoSat); if (ui.arkZap === z) ui.arkZap = null; + ctx.hook('zapSettled', z.eventId, true, z.autoSat); toast('⚡ ' + t('zapSentShort', { n: fmtAmount(z.autoSat) + ' ' + unitLabel() })); render(); } catch (e) { - z.autoSat = 0; ui.tab = 'send'; ui.sendError = e.message; render(); + bail(); ui.sendError = e.message; render(); } }; (async () => { @@ -1517,7 +1527,7 @@ export function arkFeature(ctx) { const adv = await lookupArkZapTarget(pk).catch(() => ({ status: 'noark' })); if (!live()) return; if (adv.status === 'ready') { Object.assign(z, adv); if (z.autoSat) return auto(); render(); return; } - if (adv.status === 'wrongnet') { Object.assign(z, adv); if (z.autoSat) { z.autoSat = 0; ui.tab = 'send'; } render(); return; } + if (adv.status === 'wrongnet') { Object.assign(z, adv); bail(); render(); return; } // 1b. BIP-353 with an ark instruction; remember on-chain as last resort const uris = []; try { @@ -1557,12 +1567,12 @@ export function arkFeature(ctx) { if (onchain) { ui.arkZap = null; ui.send.recipients[0].address = onchain; - if (z.autoSat) ui.tab = 'send'; + bail(); render(); return; } - if (live()) { z.status = 'noark'; if (z.autoSat) { z.autoSat = 0; ui.tab = 'send'; } render(); } - })().catch((e) => { if (live()) { z.status = 'noark'; if (z.autoSat) { z.autoSat = 0; ui.tab = 'send'; } ui.sendError = e.message; render(); } }); + if (live()) { z.status = 'noark'; bail(); render(); } + })().catch((e) => { if (live()) { z.status = 'noark'; bail(); ui.sendError = e.message; render(); } }); } // shared by the ark and lightning zap flows (see zaps.js for the twin) @@ -1614,6 +1624,7 @@ export function arkFeature(ctx) { ui.busy = true; ui.sendError = ''; render(); try { await performArkZap(z, sats); + ctx.hook('zapSettled', z.eventId, true, sats); // the tally shows it now, not when the receipt lands ui.arkZapped = { amountSat: sats, npub: z.npub }; ui.arkZap = null; } catch (e) { |
