import type { Channel } from './shared'; import { Users, Zap } from 'lucide-react'; import { toneFill } from '@/components/Data/tone'; import { formatSats, formatTimestamp, truncateMiddle } from './format'; import { PAYMENT_STATUS_TONE } from './shared'; import { Amount } from './Amount'; import { EmptyWallet, UnsupportedSection } from './EmptyWallet'; import { useSelectedWallet } from './useSelectedWallet'; import { usePermissions, useChannels, usePayments, usePeers } from './useWalletData'; // The node's own view of itself: payments it has made, channels it holds, peers it is connected to. // // lndhub and nwc have no channels or peers of their own — they are accounts on someone else's node — so // those blocks are absent from their capability set and never rendered. Nothing here shows a control that // would come back 501. export const LightningView = () => { const { walletId, isLoading } = useSelectedWallet(); const { capabilities } = usePermissions(walletId); const hasChannels = capabilities.includes('channels'); const hasPeers = capabilities.includes('peers'); const hasPayments = capabilities.includes('lightningSend'); const anyLightning = hasChannels || hasPeers || hasPayments || capabilities.includes('lightningReceive'); const { channels } = useChannels(walletId, hasChannels); const { peers } = usePeers(walletId, hasPeers); const { payments } = usePayments(walletId, hasPayments, 25); if (!walletId) return ; if (!anyLightning) return ; return (
{hasChannels && (
{channels.length === 0 ? ( No channels open. ) : (
    {channels.map((channel) => ( ))}
)}
)} {hasPeers && (
{peers.length === 0 ? ( Not connected to anyone. ) : (
    {peers.map((peer) => (
  • {peer.alias || truncateMiddle(peer.pubkey, 14, 8)} {peer.address} {peer.inbound ? 'inbound' : 'outbound'}
  • ))}
)}
)} {hasPayments && (
{payments.length === 0 ? ( Nothing sent yet. ) : (
    {payments.map((payment) => (
  • {payment.memo || truncateMiddle(payment.destination ?? payment.paymentHash, 14, 8)} {payment.status} {/* msat stays a string all the way to the DOM — see format.ts. */}
    {formatTimestamp(payment.createdAt)} · fee {payment.failureReason && · {payment.failureReason}}
  • ))}
)}
)}
); }; const ChannelRow = ({ channel }: { channel: Channel }) => { const capacity = channel.capacitySats || 1; const localPct = Math.max(0, Math.min(100, (channel.localBalanceSats / capacity) * 100)); return (
  • {channel.remoteAlias || truncateMiddle(channel.remotePubkey, 14, 8)} {channel.private && private}
    {/* Local/remote split — the number that decides whether you can send or only receive. */}
    out {formatSats(channel.localBalanceSats)} in {formatSats(channel.remoteBalanceSats)}
  • ); }; type SectionProps = { title: string; count: number; children: React.ReactNode }; const Section = ({ title, count, children }: SectionProps) => (

    {title} {count > 0 && ({count})}

    {children}
    ); const Blank = ({ children }: { children: React.ReactNode }) => (

    {children}

    );