aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-08-28 18:44:33 -0700
committerAdam Soltys <[email protected]>2026-08-28 18:44:33 -0700
commite16fd7552c4f95187394f6b3c84849b31d4812b9 (patch)
treef6a958352db2603d4aaa7234e3d0d14d417ca772 /src
parent5848cc44129a7ce4450e6bedaf40682f7f3ca4d4 (diff)
downloadcoinosv3-e16fd7552c4f95187394f6b3c84849b31d4812b9.tar.gz
coinosv3-e16fd7552c4f95187394f6b3c84849b31d4812b9.zip
The exit page stops arguing with itself: the header names how much is mid-exit, and the cooperative card explains that the balance is held by the exit below — and that cancelling it (while nothing has broadcast) frees the coins for the cooperative road
Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_019eA8JRq9Wr7z2fRQk99HLi
Diffstat (limited to 'src')
-rw-r--r--src/features/ark.js12
-rw-r--r--src/i18n.js2
2 files changed, 12 insertions, 2 deletions
diff --git a/src/features/ark.js b/src/features/ark.js
index e98ecc3..c4dd30e 100644
--- a/src/features/ark.js
+++ b/src/features/ark.js
@@ -2144,6 +2144,9 @@ export function arkFeature(ctx) {
const spendable = b.spendableSat;
const total = b.spendableSat + b.pendingSat;
const nSpend = ((arkStateNow() && arkStateNow().vtxos) || []).filter((v) => v.state === 'spendable').length;
+ const exitingSat = ((arkStateNow() && arkStateNow().actions) || [])
+ .filter((a) => a.type === 'exit' && !['done', 'failed'].includes(a.step))
+ .reduce((n, a) => n + a.amountSat, 0);
const exits = arkExitStatusLines();
const back = () => { ui.arkExitPage = null; ui.arkError = ''; render(); };
return h('div', { class: 'col', style: 'gap:16px' },
@@ -2152,7 +2155,12 @@ export function arkFeature(ctx) {
h('p', { class: 'small muted', style: 'margin:0' }, t('arkExitPageIntro')),
total > 0 ? h('div', { class: 'row between', style: 'margin-top:4px' },
h('span', { class: 'small muted' }, t('arkBalance')),
- h('span', { class: 'small' }, fmtAmount(total) + ' ' + unitLabel())) : null),
+ h('span', { class: 'small' }, fmtAmount(total) + ' ' + unitLabel())) : null,
+ // money held by an in-flight exit isn't movable by anything else —
+ // say so next to the total instead of letting the cards contradict it
+ exitingSat > 0 ? h('div', { class: 'row between' },
+ h('span', { class: 'small muted' }, t('arkExitingLabel')),
+ h('span', { class: 'small' }, fmtAmount(exitingSat) + ' ' + unitLabel())) : null),
// cooperative
h('div', { class: 'card col', style: 'gap:8px' },
h('h4', { style: 'margin:0' }, t('arkCoopTitle')),
@@ -2160,7 +2168,7 @@ export function arkFeature(ctx) {
spendable > 0
? h('button', { class: 'btn-primary btn-block', disabled: !!ui.arkBusy, onClick: () => doArkOffboard() },
ui.arkBusy === 'offboard' ? h('span', { class: 'spinner sm' }) : t('arkOffboardBtn', { n: fmtAmount(spendable) + ' ' + unitLabel() }))
- : h('div', { class: 'small faint' }, t('arkExitNoBalance'))),
+ : h('div', { class: 'small faint' }, exitingSat > 0 ? t('arkExitCoopHeld') : t('arkExitNoBalance'))),
// unilateral
h('div', { class: 'card col', style: 'gap:8px' },
h('h4', { style: 'margin:0' }, t('arkUniTitle')),
diff --git a/src/i18n.js b/src/i18n.js
index a7b09ae..4fc7d3b 100644
--- a/src/i18n.js
+++ b/src/i18n.js
@@ -540,6 +540,8 @@ const STR = {
arkUniTitle: 'Unilateral exit',
arkUniDesc: 'Your escape hatch: claim the money yourself without anyone’s help. Takes about a day and costs mining fees, but works even if the server disappears.',
arkExitNoBalance: 'Nothing in Spending to move.',
+ arkExitingLabel: 'Exiting on-chain',
+ arkExitCoopHeld: 'Your balance is in the unilateral exit below. While that exit hasn’t touched the chain yet, cancelling it frees the coins for a cooperative move.',
arkZapTitle: 'Send a zap',
awTitle: 'Auto-withdraw',
awDesc: 'When Spending goes over an amount you choose, send it onward automatically — to an address, a payment name, a lightning address, or an npub.',