From a26090e56108420e9df0cefde6372caa798ca086 Mon Sep 17 00:00:00 2001 From: archipelago Date: Sun, 26 Jul 2026 06:51:48 -0400 Subject: [PATCH] feat(ui): lightning channels All/Active/Pending/Closed tabs + closed-channel history Consumes the lnd.closedchannels RPC and closing/force_closing statuses that shipped backend-side in 00b7e179 but never reached the panel: - tab bar with per-state counts; pending covers pending_open/closing/force_closing - closed-channel cards with close type, settled balance, block height and closing-tx explorer link - closing/force_closing status dots + closing-tx link on in-flight closes - Close button hidden for channels already mid-close Co-Authored-By: Claude Fable 5 --- neode-ui/mock-backend.js | 18 +- .../src/components/LightningChannelsPanel.vue | 156 +++++++++++++++++- 2 files changed, 166 insertions(+), 8 deletions(-) diff --git a/neode-ui/mock-backend.js b/neode-ui/mock-backend.js index 57433959..39360015 100755 --- a/neode-ui/mock-backend.js +++ b/neode-ui/mock-backend.js @@ -3453,12 +3453,26 @@ app.post('/rpc/v1', (req, res) => { { chan_id: '840921088114689', remote_pubkey: '03abcdef12345678901234567890123456789012345678901234567890abcdef12', capacity: 2000000, local_balance: 1200000, remote_balance: 800000, active: true, status: 'active', channel_point: randomHex(32) + ':1', peer_alias: 'WalletOfSatoshi' }, { chan_id: '840921088114690', remote_pubkey: '02fedcba98765432109876543210987654321098765432109876543210fedcba98', capacity: 10000000, local_balance: 4500000, remote_balance: 5500000, active: true, status: 'active', channel_point: randomHex(32) + ':0', peer_alias: 'Voltage' }, { chan_id: '840921088114691', remote_pubkey: '03456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123', capacity: 3000000, local_balance: 100000, remote_balance: 2900000, active: false, status: 'inactive', channel_point: randomHex(32) + ':0', peer_alias: 'Kraken' }, + { chan_id: '', remote_pubkey: '028d98b9969fbed53784a36617eb489a59ab6dc9b9d77fcdca9ff55307cd98e3c4', capacity: 500000, local_balance: 500000, remote_balance: 0, active: false, status: 'pending_open', channel_point: randomHex(32) + ':0', peer_alias: 'ACINQ' }, + { chan_id: '', remote_pubkey: '02c16cca44562b590dd279c942200bdccfd4f990c3a69fad620c10ef2f8228eaff', capacity: 800000, local_balance: 350000, remote_balance: 450000, active: false, status: 'closing', channel_point: randomHex(32) + ':0', closing_txid: randomHex(32), peer_alias: 'Bitrefill' }, ] return res.json({ result: { channels, - total_outbound: channels.reduce((s, c) => s + c.local_balance, 0), - total_inbound: channels.reduce((s, c) => s + c.remote_balance, 0), + // Totals sum open channels only, matching the real backend. + total_outbound: channels.filter(c => ['active', 'inactive'].includes(c.status)).reduce((s, c) => s + c.local_balance, 0), + total_inbound: channels.filter(c => ['active', 'inactive'].includes(c.status)).reduce((s, c) => s + c.remote_balance, 0), + }, + }) + } + + case 'lnd.closedchannels': { + return res.json({ + result: { + channels: [ + { chan_id: '840921088110001', remote_pubkey: '03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f', capacity: 1000000, settled_balance: 612000, close_type: 'COOPERATIVE_CLOSE', closing_tx_hash: randomHex(32), channel_point: randomHex(32) + ':0', close_height: 903112 }, + { chan_id: '840921088110002', remote_pubkey: '0298f6074a454a1f5345cb2a7c6f9fce206cd0bf675d177cdbf0ca7508dd28852f', capacity: 250000, settled_balance: 0, close_type: 'REMOTE_FORCE_CLOSE', closing_tx_hash: randomHex(32), channel_point: randomHex(32) + ':1', close_height: 897540 }, + ], }, }) } diff --git a/neode-ui/src/components/LightningChannelsPanel.vue b/neode-ui/src/components/LightningChannelsPanel.vue index 85984548..d4ff7278 100644 --- a/neode-ui/src/components/LightningChannelsPanel.vue +++ b/neode-ui/src/components/LightningChannelsPanel.vue @@ -75,7 +75,7 @@ -
+
@@ -85,6 +85,23 @@
+ +
+ +
+
@@ -96,7 +113,7 @@ {{ error }}
{{ channelStatus(ch).replace('_', ' ') }}
- -
+ +
+
+ + +
+
+
+ + Closed + ยท {{ closeTypeLabel(ch) }} +
+ Block {{ ch.close_height.toLocaleString() }} +
+ +

+ {{ ch.remote_pubkey }} +

+ +
+ Settled: {{ formatSats(ch.settled_balance) }} + Capacity: {{ formatSats(ch.capacity) }} +
+ +
+ +
+
+ + +
+

{{ emptyTabMessage }}

+
@@ -299,7 +377,7 @@