aboutsummaryrefslogtreecommitdiffstats
path: root/src/features
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-18 14:44:33 -0700
committerAdam Soltys <[email protected]>2026-10-18 14:44:33 -0700
commit4fcfbef28ee9f53425f552b69e99422096d8dfcb (patch)
treeacbd6212ca8e8b17b667b1e768d0fd6bbb183ff9 /src/features
parent73030636812a20fd025b6c558695b50224bdfb0e (diff)
downloadcoinosv3-4fcfbef28ee9f53425f552b69e99422096d8dfcb.tar.gz
coinosv3-4fcfbef28ee9f53425f552b69e99422096d8dfcb.zip
Settings → Wallet → Transaction history: Export CSV — every payment in Spending and Savings as a line of a CSV file, oldest first: date (UTC), account, type, rail (Lightning, Ark, on-chain), what was paid, its fee, the change to the balance and its worth in your currency at the time, status, the transaction or payment hash, who it went to, the invoice. A failed payment is left out; a renewal is its fee.
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
Diffstat (limited to 'src/features')
-rw-r--r--src/features/ark.js23
1 files changed, 21 insertions, 2 deletions
diff --git a/src/features/ark.js b/src/features/ark.js
index 1619ce4..abb297a 100644
--- a/src/features/ark.js
+++ b/src/features/ark.js
@@ -1430,6 +1430,25 @@ export function arkFeature(ctx) {
);
}
+ // a movement as a line of the history export (Settings → Wallet): what
+ // was paid, the fee beside it, and the change to the balance — a failed
+ // payment moved nothing; a renewal moved nothing but its fee
+ function arkCsvRow(m) {
+ if (m.status === 'failed') return null;
+ const out = ['send', 'offboard', 'exit', 'ln-send', 'refresh', 'reconcile'].includes(m.type);
+ const fee = m.feeSat != null ? m.feeSat : Number(((m.detail || '').match(/fee (\d+) sat/) || [])[1]) || 0;
+ const amount = m.type === 'refresh' ? 0 : m.amountSat || 0;
+ const viaLn = m.type.startsWith('ln-') || m.viaLn;
+ return {
+ ts: m.ts, type: m.type === 'reconcile' ? 'spent-elsewhere' : m.type,
+ rail: viaLn ? 'lightning' : ONCHAIN_ARK.has(m.type) ? 'onchain' : 'ark',
+ amount: out ? -amount : amount, fee: out ? fee : 0, net: out ? -(amount + fee) : amount,
+ status: m.status === 'complete' ? 'complete' : 'pending',
+ ref: m.txid || m.paymentHash || m.vtxoId || '', to: m.to || '', invoice: m.invoice || '',
+ note: m.type === 'reconcile' ? t('arkDetailsNotSynced') : '',
+ };
+ }
+
const exitStartedTs = (a) => Number((a.id || '').split('-')[1]) || Date.now();
// A Lightning payment (a zap, mostly) still settling: the money has left
// the balance, so history shows it now as the Sent row it will become.
@@ -3956,7 +3975,7 @@ export function arkFeature(ctx) {
const paid = new Set((s.movements || []).filter((m) => m.type === 'ln-send' && m.status === 'complete').map((m) => m.paymentHash));
const lnPending = (s.actions || [])
.filter((a) => a.type === 'ln-pay' && !['done', 'failed'].includes(a.step) && !paid.has(a.paymentHash))
- .map((a) => { const m = lnPendingMove(a); return { time: m.ts, render: () => arkHistoryItem(m) }; });
+ .map((a) => { const m = lnPendingMove(a); return { time: m.ts, render: () => arkHistoryItem(m), csv: arkCsvRow(m) }; });
// Same-payment duplicates (the old settle race, or a snapshot adopted
// whole before the merge learned to dedupe) fold at display time too —
// the earliest telling wins, everywhere, however the state got here.
@@ -4009,7 +4028,7 @@ export function arkFeature(ctx) {
out.push({ ...m, count: 1, vtxoIds: m.vtxoId ? [m.vtxoId] : [] });
}
}
- return exits.concat(renewals, lnPending, out.map((m) => ({ time: m.ts, render: () => arkHistoryItem(m) })));
+ return exits.concat(renewals, lnPending, out.map((m) => ({ time: m.ts, render: () => arkHistoryItem(m), csv: arkCsvRow(m) })));
},
historyDetail() {
if (ui.arkExitDetail) {