feat(wallet): app icons, mobile layout, and a funding mode on the Lightning modal
Demo images / Build & push demo images (push) Successful in 3m18s
Demo images / Build & push demo images (push) Successful in 3m18s
Icons: each node choice now shows its app icon (lnd.png; Core Lightning's is vendored from the Umbrel gallery as core-lightning.svg). Vendored rather than hotlinked on purpose — these nodes run offline/airgapped, and a remote image would both break there and leak a request to a third-party host on every render. A missing asset falls back to a neutral bolt glyph so a row can never render a broken-image box. Mobile: the choice row keeps icon + name + blurb together and drops the action to its own full-width line under 26rem, instead of squeezing the description into a two-word column next to a button. Funding mode: a node that is running but has no funds / no inbound liquidity is neither "install one" nor "start it", so the same modal gains a third mode that explains it and routes to the run-lightning-node goal, where funding and channel-opening already live — reusing that flow rather than duplicating it. It fires where the user actually meets the problem: on a failed attempt. handleLightningFailure() maps a running node's send/receive failure onto the funding modal, matched on message text because LND surfaces "no route", "no channels" and "insufficient balance" as plain strings with no distinct code — and all three mean the same thing to a user: fund me. Verified: 5 gate tests; npm run build clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
fa26c5fc56
commit
700947ea3c
@@ -28,8 +28,10 @@ export const LIGHTNING_NODE_APP_IDS = ['lnd'] as const
|
||||
|
||||
/** `absent` — nothing installed, offer to install one.
|
||||
* `stopped` — installed but not running, point the user at My Apps.
|
||||
* `no-funds` — running, but there is nothing to pay with / no inbound
|
||||
* liquidity to be paid into; send the user to the Lightning setup goal.
|
||||
* `running` — good to go. */
|
||||
export type LightningStatus = 'absent' | 'stopped' | 'running'
|
||||
export type LightningStatus = 'absent' | 'stopped' | 'running' | 'no-funds'
|
||||
|
||||
// Module-scope: one source of truth shared by every caller and the single
|
||||
// global modal mounted in App.vue.
|
||||
@@ -73,5 +75,52 @@ export function useLightningRequired() {
|
||||
show.value = false
|
||||
}
|
||||
|
||||
return { show, status, lightningStatus, hasLightningNode, requireLightningNode, close }
|
||||
/**
|
||||
* Raise the same modal in its funding mode: the node is installed and
|
||||
* running, but has no usable balance/liquidity yet. Reuses this modal
|
||||
* rather than inventing a second one, and routes to the Lightning setup
|
||||
* goal where funding and channel-opening already live.
|
||||
*/
|
||||
function openLightningFunding() {
|
||||
status.value = 'no-funds'
|
||||
show.value = true
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a failed Lightning attempt onto the funding modal when the node is
|
||||
* running but has nothing to pay with / no inbound liquidity. Returns true
|
||||
* when it handled the error, so the caller can skip showing a raw string.
|
||||
*
|
||||
* Matched on the message because LND surfaces these as plain text: there is
|
||||
* no distinct error code for "no channels" vs "no route" vs "insufficient
|
||||
* balance", and all three mean the same thing to the user — fund me.
|
||||
*/
|
||||
function handleLightningFailure(err: unknown): boolean {
|
||||
if (lightningStatus() !== 'running') return false
|
||||
const msg = (err instanceof Error ? err.message : String(err ?? '')).toLowerCase()
|
||||
const fundingRelated = [
|
||||
'no route',
|
||||
'no routes',
|
||||
'insufficient',
|
||||
'no channel',
|
||||
'not enough',
|
||||
'balance',
|
||||
'unable to find a path',
|
||||
'no path',
|
||||
].some((needle) => msg.includes(needle))
|
||||
if (!fundingRelated) return false
|
||||
openLightningFunding()
|
||||
return true
|
||||
}
|
||||
|
||||
return {
|
||||
show,
|
||||
status,
|
||||
lightningStatus,
|
||||
hasLightningNode,
|
||||
requireLightningNode,
|
||||
openLightningFunding,
|
||||
handleLightningFailure,
|
||||
close,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user