aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-08-01 23:16:52 -0700
committerAdam Soltys <[email protected]>2026-08-01 23:16:52 -0700
commit3dab66c5d3d63f19444e7fe14017fdfeb9a8e27d (patch)
tree45d7f2074b31190ee01d0f7b644fe631086d5271
parentbabac497c1f44892b646b30be4d3ad035b461386 (diff)
downloadcoinosv3-3dab66c5d3d63f19444e7fe14017fdfeb9a8e27d.tar.gz
coinosv3-3dab66c5d3d63f19444e7fe14017fdfeb9a8e27d.zip
Speak about money, not rails: Spending and Saving
The balance card now leads with the total and names the two places money lives — Spending (instant) and Saving (on-chain) — instead of an on-chain headline with an 'Ark balance' line hanging off it. A 'Move money' button under the balance opens one screen that moves funds either way, replacing a board form buried inside the Ark receive pane. Strings throughout drop Ark and Lightning: boarding becomes 'Move to Spending', exiting becomes 'Move to Saving', the receive tabs read 'Instant' and 'Saving address', and How it works explains two balances and the escape hatch without naming a protocol. The rails keep their names in the code, where they belong. Co-Authored-By: Claude Fable 5 <[email protected]>
-rw-r--r--src/app.js24
-rw-r--r--src/features/ark.js113
-rw-r--r--src/i18n.js126
3 files changed, 157 insertions, 106 deletions
diff --git a/src/app.js b/src/app.js
index 8a33166..52a3040 100644
--- a/src/app.js
+++ b/src/app.js
@@ -1909,27 +1909,39 @@ function balanceCard() {
const firstLoad = !wallet.loaded && !wallet.offline;
const pending = wallet.pendingIncoming;
const featLines = featureAll('balanceLines');
+ // Money lives in two places and we name them for what they're FOR, not for
+ // the rails underneath: Spending is the instant off-chain balance, Saving
+ // is the on-chain one. The headline is simply everything you have.
+ const spending = featureHook('spendingSat') || 0;
+ const saving = wallet.spendable;
+ const split = spending > 0 || saving > 0;
return h(
'div',
{ class: 'card balance' },
h('div', { class: 'small faint', style: 'text-transform:uppercase;letter-spacing:.05em' }, t('balance')),
- // Headline is the spendable balance: confirmed coins plus our own pending
- // change, minus gift locks — so a pending spend debits immediately, while a
- // pending incoming receive stays out of it until it confirms.
h('div', { class: 'amt', style: firstLoad ? 'opacity:.3' : '' },
firstLoad ? h('span', { class: 'spinner sm', style: 'margin-right:8px' }) : null,
- fmtAmount(wallet.spendable), ' ', unitTag('unit')),
- pending > 0 || featLines.length
+ fmtAmount(spending + saving), ' ', unitTag('unit')),
+ split || pending > 0 || featLines.length
? h(
'div',
{ class: 'split' },
+ split
+ ? h('div', {}, h('div', { class: 'k' }, t('spendingLabel')), h('div', { class: 'v' }, fmtAmount(spending), ' ', unitTag()))
+ : null,
+ split
+ ? h('div', {}, h('div', { class: 'k' }, t('savingLabel')), h('div', { class: 'v' }, fmtAmount(saving), ' ', unitTag()))
+ : null,
pending > 0
? h('div', {}, h('div', { class: 'k' }, t('pending')), h('div', { class: 'v pending' }, fmtAmount(pending), ' ', unitTag()))
: null,
...featLines.map((l) =>
h('div', {}, h('div', { class: 'k' }, l.label), h('div', { class: 'v' }, fmtAmount(l.sat), ' ', unitTag())))
)
- : null
+ : null,
+ // "Move money" and friends: the only door between the two balances.
+ ...featureAll('balanceActions').map((a2) =>
+ h('button', { class: 'btn-sm', style: 'margin-top:10px', onClick: a2.onClick }, a2.label))
);
}
diff --git a/src/features/ark.js b/src/features/ark.js
index 0981918..baee9a4 100644
--- a/src/features/ark.js
+++ b/src/features/ark.js
@@ -843,7 +843,7 @@ export function arkFeature(ctx) {
render();
};
const head = [
- h('h3', { class: 'row gap6', style: 'align-items:center' }, h('span', { html: ARK_MARK(18) }), 'Ark'),
+ h('h3', { class: 'row gap6', style: 'align-items:center' }, t('arkTitle')),
h('p', { class: 'small muted', style: 'margin:0' }, t('arkDesc')),
h('select', { onChange: (e) => applyProvider(e.target.value) },
presets.map((p) => h('option', { value: p.id, selected: p.id === id }, p.label))),
@@ -1338,6 +1338,60 @@ export function arkFeature(ctx) {
ui.arkBusy = null; render();
}
+ // Moving money between the two balances, in plain terms. This is the only
+ // place the two rails meet, and it never names them: Saving is on-chain,
+ // Spending is instant, and the wallet handles the rest.
+ function boardForm() {
+ const minBoard = (ark && ark.info && ark.info.minBoardAmountSat) || 0;
+ const canBoard = wallet.spendable >= minBoard;
+ return h('div', { class: 'col', style: 'width:100%;gap:8px' },
+ h('div', { class: 'input-group' },
+ h('input', {
+ type: 'number', inputmode: 'numeric', min: '0',
+ placeholder: t('arkBoardPlaceholder', { n: minBoard.toLocaleString() }),
+ value: ui.arkBoardAmt || '',
+ onInput: (e) => { ui.arkBoardAmt = e.target.value; render(); },
+ }),
+ h('button', { class: 'btn-primary', disabled: !!ui.arkBusy || !canBoard, onClick: doArkBoard },
+ ui.arkBusy === 'board' ? h('span', { class: 'spinner sm' }) : t('arkBoardBtn'))),
+ (() => {
+ const sats = parseInt((ui.arkBoardAmt || '').trim(), 10);
+ if (!sats || sats < minBoard || !ark) return null;
+ const fee = boardFee(sats, ark.info.boardFees);
+ return h('div', { class: 'small muted', style: 'text-align:center' },
+ t('arkBoardFeeNote', { fee: fmtAmount(fee), net: fmtAmount(sats - fee) }));
+ })(),
+ canBoard
+ ? h('div', { class: 'small faint', style: 'text-align:center' },
+ t('arkBoardAvailable', { n: fmtAmount(wallet.spendable) + ' ' + unitLabel() }))
+ : h('div', { class: 'small faint', style: 'text-align:center' },
+ t('arkBoardNoFunds', { n: minBoard.toLocaleString() })));
+ }
+
+ function movePage() {
+ const b = arkBalance();
+ const back = () => { ui.arkMovePage = false; ui.arkError = ''; render(); };
+ if (!ark) connectArk().catch(() => {});
+ return h('div', { class: 'col', style: 'gap:16px;padding:16px;max-width:460px;margin:0 auto;width:100%' },
+ h('div', { class: 'row between' },
+ h('h3', { style: 'margin:0' }, t('moveTitle')),
+ h('span', { class: 'linklike small', onClick: back }, t('back'))),
+ ui.arkError ? h('div', { class: 'notice err' }, ui.arkError) : null,
+ h('div', { class: 'card col', style: 'gap:10px' },
+ h('h4', { style: 'margin:0' }, t('moveToSpending')),
+ h('p', { class: 'small muted', style: 'margin:0' }, t('moveToSpendingDesc')),
+ ark ? boardForm() : h('div', { class: 'row gap6', style: 'align-items:center' },
+ h('span', { class: 'spinner sm' }), h('span', { class: 'small muted' }, t('arkConnecting')))),
+ h('div', { class: 'card col', style: 'gap:10px' },
+ h('h4', { style: 'margin:0' }, t('moveToSaving')),
+ h('p', { class: 'small muted', style: 'margin:0' }, t('moveToSavingDesc')),
+ h('div', { class: 'small faint' }, t('moveAvailable', { n: fmtAmount(b ? b.spendableSat : 0) + ' ' + unitLabel() })),
+ h('button', {
+ class: 'btn-block', disabled: !b || !b.spendableSat,
+ onClick: () => { ui.arkMovePage = false; ui.arkExitPage = true; ui.arkError = ''; render(); },
+ }, t('moveToSavingBtn'))));
+ }
+
// The Ark receive pane: connect-on-demand, then address + board form.
function arkReceivePane(seg) {
if (true) {
@@ -1354,8 +1408,6 @@ export function arkFeature(ctx) {
);
}
const arkAddr = ark.address();
- const minBoard = ark.info.minBoardAmountSat || 0;
- const canBoard = wallet.spendable >= minBoard;
return h(
'div',
{ class: 'card col', style: 'align-items:center;gap:14px' },
@@ -1364,30 +1416,6 @@ export function arkFeature(ctx) {
h('div', { html: qrSvg(arkAddr) }),
h('div', { class: 'addr-box break', style: 'width:100%;font-size:11px' }, arkAddr),
copyBtn(arkAddr, t('copyAddress')),
- // Board: fund your Ark balance from this wallet's on-chain coins.
- h('div', { class: 'col', style: 'width:100%;gap:8px;border-top:1px solid var(--border,rgba(128,128,128,.2));padding-top:14px' },
- h('div', { class: 'small muted', style: 'text-align:center' }, t('arkBoardIntro')),
- h('div', { class: 'input-group' },
- h('input', {
- type: 'number', inputmode: 'numeric', min: '0',
- placeholder: t('arkBoardPlaceholder', { n: minBoard.toLocaleString() }),
- value: ui.arkBoardAmt || '',
- onInput: (e) => { ui.arkBoardAmt = e.target.value; render(); },
- }),
- h('button', { class: 'btn-sm', disabled: !!ui.arkBusy || !canBoard, onClick: doArkBoard },
- ui.arkBusy === 'board' ? h('span', { class: 'spinner sm' }) : t('arkBoardBtn'))),
- // show the server's board fee BEFORE the money moves, not after
- (() => {
- const sats = parseInt((ui.arkBoardAmt || '').trim(), 10);
- if (!sats || sats < minBoard) return null;
- const fee = boardFee(sats, ark.info.boardFees);
- return h('div', { class: 'small muted', style: 'text-align:center' },
- t('arkBoardFeeNote', { fee: fmtAmount(fee), net: fmtAmount(sats - fee) }));
- })(),
- canBoard
- ? h('div', { class: 'small faint', style: 'text-align:center' }, t('arkBoardAvailable', { n: fmtAmount(wallet.spendable) + ' ' + unitLabel() }))
- : h('div', { class: 'small faint', style: 'text-align:center' }, t('arkBoardNoFunds', { n: minBoard.toLocaleString() })),
- ui.arkError ? h('div', { class: 'notice err' }, ui.arkError) : null),
// Lightning receive straight into the ark balance (ASP-native swap)
arkLnReceiveSection()
);
@@ -1533,7 +1561,7 @@ export function arkFeature(ctx) {
id: 'ark',
init() { initArk(); },
stop() { stopArk(); },
- screenView() { return ui.arkExitPage ? arkExitPage() : null; },
+ screenView() { return ui.arkMovePage ? movePage() : ui.arkExitPage ? arkExitPage() : null; },
receiveModes() {
if (!arkAvailable()) return [];
return [{ id: 'ark', label: t('receiveArkTab'), icon: ARK_MARK(18), render: (seg) => arkReceivePane(seg) }];
@@ -1645,24 +1673,23 @@ export function arkFeature(ctx) {
ui.arkMoveDetail = null;
return null;
},
+ // The spendable off-chain balance IS the wallet's "Spending" — the balance
+ // card shows it by name, so this feature only reports the number.
+ // "Move money" under the balance — the one door between the two balances.
+ balanceActions() {
+ if (wallet.watchOnly || !arkAvailable()) return [];
+ return [{ label: t('moveMoney'), onClick: () => { ui.arkMovePage = true; ui.arkError = ''; render(); } }];
+ },
+ spendingSat() {
+ const b = arkBalance();
+ return b ? b.spendableSat + b.pendingSat : 0;
+ },
balanceLines() {
const b = arkBalance();
if (!b) return [];
- const lines = [];
- if (b.spendableSat + b.pendingSat > 0) {
- // "Ark balance … Exit" — the exit link opens the offboard/exit page.
- // Watch-only wallets can't move funds, so they just show the balance.
- const label = wallet.watchOnly
- ? t('arkBalance')
- : h('span', { class: 'row gap6', style: 'align-items:center' },
- t('arkBalance'),
- h('span', { class: 'linklike', style: 'font-size:12px', onClick: () => { ui.arkExitPage = true; ui.arkError = ''; render(); } }, t('arkExitLink')));
- lines.push({ label, sat: b.spendableSat + b.pendingSat });
- }
- // A board in flight: the sats already left the on-chain balance, so show
- // where they went instead of having them silently disappear.
- if (b.boardingSat > 0) lines.push({ label: t('arkBoarding'), sat: b.boardingSat });
- return lines;
+ // Money mid-move: it has left Saving but hasn't landed in Spending, so
+ // say where it went rather than letting it vanish for a confirmation.
+ return b.boardingSat > 0 ? [{ label: t('movingLabel'), sat: b.boardingSat }] : [];
},
decorateTxRow(tx) {
const s = arkStateNow();
diff --git a/src/i18n.js b/src/i18n.js
index 6e62e35..67e43bd 100644
--- a/src/i18n.js
+++ b/src/i18n.js
@@ -129,10 +129,10 @@ const STR = {
hiwBasics3: 'There’s no server and no account. The whole app is a single page that runs in your browser, so nobody holds your coins and nothing on a server ever sees your keys. To show your balance and history it reads from a public block explorer (mempool.space by default, or your own node if you set one in Settings).',
hiwBasics4: 'You can even save this page and open it straight from your computer with no internet at all. It keeps working offline.',
hiwBasics5: 'It follows the usual Bitcoin standards (a 12-word BIP39 phrase and BIP84 native SegWit keys), so if this site ever disappears you can restore the same phrase in Sparrow, Electrum, or any other standard wallet and your coins will be right there.',
- hiwLnTitle: 'Lightning',
- hiwLn1: 'You can pay Lightning invoices and receive Lightning payments. They run over your Ark balance: the Ark server exchanges with the Lightning network without ever holding your money — if a payment fails, the coins come back to you. A small fee applies, shown before you confirm.',
- hiwArkTitle: 'Ark',
- hiwArk1: 'Ark is a newer way to pay off-chain: sends arrive instantly, cost no mining fees, and stay self-custodial. You "board" coins from your on-chain balance into an Ark server, pay and receive freely, and move funds back on-chain whenever you like.',
+ hiwLnTitle: 'Spending and Saving',
+ hiwLn1: 'Your money sits in two places. Saving is ordinary on-chain Bitcoin: the safest place to keep it, but every move costs a mining fee and waits for a confirmation. Spending is for everyday use — it sends and arrives instantly, costs nothing to send, and still belongs only to you.',
+ hiwArkTitle: 'Moving between them',
+ hiwArk1: 'Use “Move money” under your balance to shift funds either way. Money moved into Spending is ready after one confirmation; money moved back to Saving arrives the same way. You can always get your money out on your own, even if our server disappears — that path takes about a day and costs a mining fee. Behind the scenes this uses Ark and Lightning, but you never have to think about either.',
hiwArk2: 'The server can never take your money: every coin you hold in the Ark comes with a pre-signed escape route, and the wallet can put it back on-chain even if the server disappears (“Exit on-chain without the server” in Settings — it takes a while and needs a little on-chain balance for fees, but it needs nobody’s permission).',
hiwArk3: 'The housekeeping: Ark coins expire after some weeks, so refresh them (Settings) before then — a wallet left untouched past expiry can be swept by the server. Boarding pays a small server fee plus a normal mining fee; paying inside the Ark is free; withdrawing on-chain pays a server fee taken from the amount.',
hiwSpTitle: 'Silent payments',
@@ -140,6 +140,17 @@ const STR = {
hiwGiftsTitle: 'Gifts',
hiwGifts1: 'You can gift bitcoin with a link: whoever opens it claims the coins into their own wallet — no app, no signup. On-chain gifts lock the coins until claimed and can be cancelled or reclaimed; Ark gifts claim instantly and free, even into a brand-new empty wallet. A gift can also be locked to a specific nostr account so only they can claim it.',
hiwTribute: 'Built on the shoulders of Hal Finney (1956–2014).',
+ moveMoney: 'Move money',
+ moveTitle: 'Move money',
+ moveToSpending: 'Into Spending',
+ moveToSpendingDesc: 'Make money instantly spendable, with no fees to send it.',
+ moveToSaving: 'Into Saving',
+ moveToSavingDesc: 'Park money in ordinary on-chain Bitcoin.',
+ moveToSavingBtn: 'Move to Saving',
+ moveAvailable: '{n} in Spending',
+ spendingLabel: 'Spending',
+ savingLabel: 'Saving',
+ movingLabel: 'Moving…',
balance: 'Balance',
pending: 'Pending',
tabReceive: 'Receive',
@@ -336,65 +347,66 @@ const STR = {
detectedElectrum: 'Electrum — data + instant payment notifications.',
detectedEsplora: 'Block explorer (Esplora) — data only; polls for payments.',
silentPaymentNote: 'Silent payment',
- receiveAddressTab: 'Bitcoin address',
+ receiveAddressTab: 'Saving address',
receiveLnTab: 'Lightning',
receiveSpTab: 'Silent payment',
- receiveArkTab: 'Ark',
- arkReceiveIntro: 'Receive instantly over Ark — off-chain, self-custodial, no fees.',
- arkDesc: 'Off-chain payments via an Ark server: instant, no mining fees, self-custodial (you can always exit on-chain).',
- arkServerUrl: 'Ark server URL',
+ receiveArkTab: 'Instant',
+ arkReceiveIntro: 'Receive instantly and free — straight into Spending.',
+ arkTitle: 'Spending balance',
+ arkDesc: 'Your Spending balance sends and receives instantly with no mining fees, and stays yours — you can move it back to Saving whenever you like.',
+ arkServerUrl: 'Server URL',
arkEsploraUrl: 'Esplora URL (chain source)',
- arkWatchOnly: 'Ark needs the wallet keys — load the seed to use it.',
- arkConnecting: 'Connecting to the Ark server…',
+ arkWatchOnly: 'Spending needs the wallet keys — load the seed to use it.',
+ arkConnecting: 'Connecting…',
arkConnectBtn: 'Connect',
- arkNotConnected: 'Ark is not connected — pick a server in Settings.',
- arkBalance: 'Ark balance',
- arkBoarding: 'Ark (boarding…)',
- arkBoardHistory: 'Ark board',
+ arkNotConnected: 'Not connected — pick a server in Settings.',
+ arkBalance: 'Spending',
+ arkBoarding: 'Moving…',
+ arkBoardHistory: 'Moved to Spending',
arkVtxos: 'Coins (VTXOs)',
arkPendingActions: '{n} operation(s) in progress',
- arkBoardPlaceholder: 'Board amount (min {n} sats)',
- arkBoardBtn: 'Board',
- arkBoardFeeNote: 'Ark server fee {fee} sats — {net} sats will arrive in your Ark balance (funds the exit-path fee anchor).',
- arkBoardFeeLabel: 'Ark server fee',
- arkBoardedTitle: 'Boarding!',
- arkBoardedNote: 'Spendable in the Ark after 1 confirmation.',
- arkBoardIntro: 'Or move this wallet\u2019s on-chain funds into Ark:',
- arkBoardAvailable: '{n} available on-chain',
- arkBoardNoFunds: 'Needs at least {n} sats of on-chain balance.',
+ arkBoardPlaceholder: 'Amount (min {n} sats)',
+ arkBoardBtn: 'Move to Spending',
+ arkBoardFeeNote: 'Fee {fee} sats — {net} sats will arrive in Spending.',
+ arkBoardFeeLabel: 'Fee',
+ arkBoardedTitle: 'On its way!',
+ arkBoardedNote: 'Ready to spend after 1 confirmation.',
+ arkBoardIntro: 'Move money from Saving into Spending:',
+ arkBoardAvailable: '{n} in Saving',
+ arkBoardNoFunds: 'Needs at least {n} sats in Saving.',
arkRefreshBtn: 'Refresh / consolidate {n} coin(s)',
- arkOffboardBtn: 'Move {n} back on-chain',
+ arkOffboardBtn: 'Move {n} to Saving',
giftSourceChain: 'On-chain',
- giftSourceArk: 'Ark',
- giftArkNote: 'Sent from your Ark balance — the link claims instantly, off-chain, with no fee.',
- giftArkOutstanding: '{n} unclaimed Ark gift(s)',
- giftArkRevoked: 'Gift swept back to your Ark balance.',
+ giftSourceArk: 'Spending',
+ giftArkNote: 'Sent from Spending — the link claims instantly, with no fee.',
+ giftArkOutstanding: '{n} unclaimed instant gift(s)',
+ giftArkRevoked: 'Gift swept back into Spending.',
claimArkFree: 'instant, no fee',
arkGiftWrongNet: 'This gift lives on {net} — switch the network in Settings, then open the link again.',
- arkOffboardedTitle: 'Withdrawing!',
- arkOffboardedNote: 'Arrives in this wallet’s on-chain balance after 1 confirmation.',
- arkOffboarded: 'Withdrawn on-chain',
- arkOffboardHistory: 'Ark withdrawal',
- arkExitBtn: 'Exit on-chain without the server ({n} coin(s))',
+ arkOffboardedTitle: 'On its way!',
+ arkOffboardedNote: 'Arrives in Saving after 1 confirmation.',
+ arkOffboarded: 'Moved to Saving',
+ arkOffboardHistory: 'Moved to Saving',
+ arkExitBtn: 'Move to Saving without the server ({n} coin(s))',
arkExitStarted: 'Unilateral exit started for {n} coin(s) — broadcasting the exit chain.',
- arkExitNoFeeCoin: 'Exiting needs an on-chain coin to pay the exit-chain fees.',
- arkExitChainStatus: 'Exiting {n} sats — publishing on-chain, step {done} of {total}…',
+ arkExitNoFeeCoin: 'This needs a little in Saving to pay the mining fees.',
+ arkExitChainStatus: 'Moving {n} sats — step {done} of {total}…',
arkExitTimelockStatus: 'Exiting {n} sats — {blocks} block(s) of timelock left{eta}',
arkExitClaimingStatus: 'Exiting {n} sats — almost done, awaiting confirmation',
arkExitRetrying: 'hit a snag — retrying automatically',
arkExitCancel: 'Cancel this exit',
- arkExitLink: 'Exit',
- arkExitPageTitle: 'Move Ark funds on-chain',
- arkExitPageIntro: 'Two ways to move your Ark balance back to regular on-chain Bitcoin.',
+ arkExitLink: 'Move to Saving',
+ arkExitPageTitle: 'Move money to Saving',
+ arkExitPageIntro: 'Two ways to move your Spending balance into Saving.',
arkCoopTitle: 'Cooperative (recommended)',
- arkCoopDesc: 'The Ark server co-signs one transaction paying your on-chain wallet. Fast — one confirmation — and needs no on-chain funds. A small server fee comes out of the amount.',
+ arkCoopDesc: 'The normal way: one transaction into Saving, ready after a single confirmation, with a small fee taken from the amount.',
arkUniTitle: 'Unilateral exit',
- arkUniDesc: 'Publishes your coins’ own exit transactions and claims them after a timelock (about a day), paying on-chain mining fees. Slower, but needs no cooperation from the server — your escape hatch if it ever disappears.',
- arkExitNoBalance: 'No Ark balance to move.',
- arkZapTitle: 'Zap over Ark',
- arkZapLookup: 'Looking up their Ark address…',
- arkZapNoArk: 'This nostr user hasn’t published an Ark address.',
- arkZapHint: 'Instant and free — delivered to their Ark wallet, with a zap receipt on nostr.',
+ 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.',
+ arkZapTitle: 'Send a zap',
+ arkZapLookup: 'Looking them up…',
+ arkZapNoArk: 'This nostr user can’t receive instant payments yet.',
+ arkZapHint: 'Instant and free, with a zap receipt on nostr.',
arkZapCommentPh: 'Comment (optional)',
arkZapBtn: 'Zap',
arkZapSentTitle: 'Zapped!',
@@ -404,11 +416,11 @@ const STR = {
arkOpsOffboard: '{n} withdrawal(s) confirming',
arkOpsLnPay: '{n} Lightning payment(s) in flight',
arkOpsLnRecv: '{n} Lightning invoice(s) outstanding',
- arkLnPayVia: 'Instant, from your Ark balance',
- arkLnFee: 'Ark fee',
+ arkLnPayVia: 'Instant, from your Spending balance',
+ arkLnFee: 'Fee',
arkLnPaying: 'Paying invoice…',
arkLnPayFailed: 'Payment failed',
- arkLnRefunded: 'Payment failed — funds returned to your Ark balance.',
+ arkLnRefunded: 'Payment failed — your money is back in Spending.',
arkLnPaidTitle: 'Paid!',
nlSignIn: 'Sign in with Nostr',
nlTitle: 'Log in with Nostr',
@@ -454,7 +466,7 @@ const STR = {
namesOwnDomain: 'Use your own domain',
namesOwnDomainHow: 'Have your own domain? Add this line to its DNS records (DNSSEC must be enabled) and your address works there too:',
nwcTitle: 'Nostr Wallet Connect',
- nwcDesc: 'Let another app pay from this wallet over nostr — it never sees your keys, only spends within the limits you set, and you can cut it off at any time. Payments go out over Ark.',
+ nwcDesc: 'Let another app pay from this wallet over nostr — it never sees your keys, only spends within the limits you set, and you can cut it off at any time.',
nwcTabWarning: 'Works while Coinos is open — turn on background answering below to keep working when it isn’t.',
nwcAdd: 'Add a connection',
nwcBackground: 'Answer while closed',
@@ -471,16 +483,16 @@ const STR = {
nwcRevoke: 'Revoke',
nwcRevoked: 'Revoked {name}',
nwcLimits: 'Max {max}/payment · {day}/day · {spent} spent today',
- arkLnFundsPending: 'Your Ark funds are settling from a previous payment — retrying…',
+ arkLnFundsPending: 'Your money is settling from a previous payment — retrying…',
lnZapOffer: 'Zap {addr}',
- arkLnInvoiceIntro: 'Or receive over Lightning, straight into your Ark balance.',
- arkLnPaidHistory: 'Paid Lightning invoice',
- arkLnReceivedHistory: 'Received over Lightning',
+ arkLnInvoiceIntro: 'Or take a Lightning payment, straight into Spending.',
+ arkLnPaidHistory: 'Sent',
+ arkLnReceivedHistory: 'Received',
arkLnCancelInvoice: 'Cancel invoice',
- arkExited: 'Exited on-chain',
- arkExitHistory: 'Ark exit',
+ arkExited: 'Moved to Saving',
+ arkExitHistory: 'Moved to Saving',
arkRefreshStarted: 'Refresh submitted — completes with the next round.',
- arkSendTitle: 'Send over Ark',
+ arkSendTitle: 'Send',
arkSendHint: 'Ark address — sent instantly off-chain, no mining fee.',
arkPayTo: 'To',
arkNoFee: 'none — instant off-chain send',