aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-07-03 17:55:46 -0700
committerAdam Soltys <[email protected]>2026-07-03 17:55:46 -0700
commitea2c4683e71da6c050430fd0ea122821902282e0 (patch)
treedee90d01a2e0d2091f9b7d7868691bf76660c6ae
parent190c13a338462a7a76ee65e9486e42c0165a65f4 (diff)
downloadcoinosv3-ea2c4683e71da6c050430fd0ea122821902282e0.tar.gz
coinosv3-ea2c4683e71da6c050430fd0ea122821902282e0.zip
Ark: 'Payment received!' celebration for Ark receives
Same card and tap-to-acknowledge flow as on-chain receives; the ack persists in the ark state (shows exactly once) and a 2h recency guard keeps old payments from celebrating when a wallet is opened later. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
-rw-r--r--src/app.js19
-rw-r--r--src/ark/manager.js14
-rw-r--r--tools/ark/ui-test.js4
3 files changed, 37 insertions, 0 deletions
diff --git a/src/app.js b/src/app.js
index 013ae4a..e4519e5 100644
--- a/src/app.js
+++ b/src/app.js
@@ -2779,6 +2779,25 @@ function hasRecentIncoming() {
// ---------------------------------------------------------------- Receive
function receiveTab() {
+ // An Ark payment landed — same celebration as an on-chain receive, dismissed
+ // with a tap (the ack persists in the ark state so it shows exactly once).
+ const arkUnseen = ark && ark.state ? ark.unseenReceives() : [];
+ if (arkUnseen.length) {
+ const amt = arkUnseen.reduce((n, m) => n + m.amountSat, 0);
+ return h(
+ 'div',
+ {
+ class: 'card col',
+ style: 'align-items:center;text-align:center;gap:14px;cursor:pointer;padding:48px 20px',
+ onClick: () => { ark.ackReceives(); render(); },
+ },
+ h('div', { class: 'check-badge' }, '✓'),
+ h('h2', { style: 'margin:0' }, t('paymentReceived')),
+ amt ? h('div', { class: 'amount-pos', style: 'font-size:18px' }, '+' + fmtAmount(amt) + ' ' + unitLabel()) : null,
+ h('div', { class: 'small muted' }, t('tapToProceed'))
+ );
+ }
+
// A payment landed on the shown address (the fresh index advanced past what
// the user last saw) — celebrate, and wait for a tap before showing the next.
// Until receiveSeenIndex has been baselined (post-scan, in enterWallet) it
diff --git a/src/ark/manager.js b/src/ark/manager.js
index b2d01ce..1f21159 100644
--- a/src/ark/manager.js
+++ b/src/ark/manager.js
@@ -122,6 +122,20 @@ export class ArkManager {
const sum = (st) => this.state.vtxos.filter((v) => v.state === st).reduce((n, v) => n + v.amountSat, 0);
return { spendableSat: sum('spendable'), pendingSat: sum('pending') };
}
+
+ // Receives newer than the last acknowledgement — the UI's "Payment
+ // received!" celebration. Recency-guarded like the on-chain equivalent so an
+ // old payment never celebrates when a wallet is opened much later.
+ unseenReceives() {
+ const ack = this.state.receiveAckTs || 0;
+ const cutoff = Date.now() - 2 * 3600 * 1000;
+ return this.state.movements.filter((m) =>
+ m.type === 'receive' && m.status === 'complete' && m.ts > ack && m.ts > cutoff);
+ }
+ ackReceives() {
+ this.state.receiveAckTs = Date.now();
+ this._save();
+ }
vtxos() { return this.state.vtxos.slice(); }
movements() { return this.state.movements.slice(); }
pendingActions() { return this.state.actions.filter((a) => !['done', 'failed'].includes(a.step)); }
diff --git a/tools/ark/ui-test.js b/tools/ark/ui-test.js
index f8288e2..81dc3ae 100644
--- a/tools/ark/ui-test.js
+++ b/tools/ark/ui-test.js
@@ -109,6 +109,10 @@ try {
check('ark address shown', /^tark1[a-z0-9]+$/.test(arkAddr), arkAddr.slice(0, 24) + '…');
sh(`${ALICE} -q send ${arkAddr} "25000 sat"`);
check('ark balance shows 25,000', await waitLabeledNumber('ark balance', 25000, 30000), String(await labeledNumber('ark balance')));
+ check('payment celebration shown', await waitText('Payment received', 10000));
+ await clickText('.card', 'Payment received'); // tap to acknowledge
+ await sleep(400);
+ check('back to receive card after tap', await waitText('tark1', 5000));
// --- send over ark ---
console.log('\n[3] send over Ark');