Summary
When a user pastes/scans a Lightning invoice (or BIP21 unified URI containing a lightning= param) that was created by their own node, the Send flow shows a misleading "Insufficient Spending Balance — ₿ X more needed to pay this Lightning invoice" toast instead of explaining that self-payments are not possible.
LDK rejects the payment internally with Cannot generate a route to ourselves, but that error is only logged — the UI never surfaces it.
Evidence (from a user support log)
Session log bitkit_2026-04-16_15-38-43.log:
:3203 — user's own node creates invoice lnbc1p57zpxp… (hash 986b2247…)
:7710 — user pastes bitcoin:bc1qv2fjjp…?lightning=lnbc1p57zpxp… (the same invoice)
:7715 — ERROR ldk_node::payment::bolt11: Failed to find route for fee estimation: "Cannot generate a route to ourselves"
:7717 — estimateRoutingFeesForAmount error [LdkError='LDK Node error: Failed to find a route for fee estimation.']
:18506 / :18521 — same pattern on a second attempt
The user then typed an amount above maxSendLightningSats (6131 sats vs. total 6485) and saw other__pay_insufficient_spending_amount_description, which is technically correct for that amount but hides the real blocker: even sending exactly maxSend would fail because the invoice's destination is their own node.
Expected behavior
As soon as the scanned/pasted Lightning invoice is decoded, compare the invoice's payee pubkey against the local node id. If they match, block the flow with a dedicated error (e.g. "You can't pay an invoice created by your own wallet").
Proposed implementation
- Early validation on scan — in
AppViewModel.validateLightningInvoice (app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt:904):
- Compare
invoice.payeePubkey with lightningRepo.getNodeId().
- If equal, call
showAddressValidationError with a new string resource (e.g. other__pay_self_invoice_title / other__pay_self_invoice_description) and return early — before the insufficient-spending check.
- Same guard for unified BIP21 — in
validateOnChainAddress where extractViableLightningInvoice pulls the embedded BOLT11 (AppViewModel.kt:951), apply the same self-payment check before switching payMethod to SendMethod.LIGHTNING.
- Same guard on the amount-entered path —
onScanLightning (AppViewModel.kt:1431) and the unified-invoice branch in onScan* (AppViewModel.kt:1396 area) for cases where the decoded invoice carries an amount or the user enters one later.
- Surface the LDK failure too — in
estimateMaxAmountRoutingFee (AppViewModel.kt:2141) and estimateLightningRoutingFeesIfNeeded (AppViewModel.kt:2120), if the underlying error is Cannot generate a route to ourselves, fire the same self-payment toast instead of silently zeroing the estimate.
- Add a new string resource in
app/src/main/res/values/strings.xml (alphabetical order) — English copy only; keep localization keys aligned with existing other__pay_* conventions.
Files to touch
app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt (:904, :931, :1431, :2120, :2141)
app/src/main/java/to/bitkit/repositories/LightningRepo.kt — confirm getNodeId() is callable from this path (:1221)
app/src/main/res/values/strings.xml
Verification
- In a dev build, receive any amount via Lightning so a channel exists.
- Open Receive, copy the BIP21 unified QR (
bitcoin:…?lightning=…).
- Paste it into the Send flow.
- Expected: the dedicated "self-payment" toast appears immediately on paste/scan — no "Insufficient Spending" toast, no amount entry screen.
- Repeat with just the raw BOLT11 (no
bitcoin: prefix) — same toast.
- Verify a genuine external invoice still works end-to-end.
Related
Diagnosed from support ticket — user reported "everytime I try it says there isn't enough btc to fill this invoice but I have enough" while repeatedly pasting their own wallet's Receive URI into Send.
Summary
When a user pastes/scans a Lightning invoice (or BIP21 unified URI containing a
lightning=param) that was created by their own node, the Send flow shows a misleading "Insufficient Spending Balance — ₿ X more needed to pay this Lightning invoice" toast instead of explaining that self-payments are not possible.LDK rejects the payment internally with
Cannot generate a route to ourselves, but that error is only logged — the UI never surfaces it.Evidence (from a user support log)
Session log
bitkit_2026-04-16_15-38-43.log::3203— user's own node creates invoicelnbc1p57zpxp…(hash986b2247…):7710— user pastesbitcoin:bc1qv2fjjp…?lightning=lnbc1p57zpxp…(the same invoice):7715—ERROR ldk_node::payment::bolt11: Failed to find route for fee estimation: "Cannot generate a route to ourselves":7717—estimateRoutingFeesForAmount error [LdkError='LDK Node error: Failed to find a route for fee estimation.']:18506/:18521— same pattern on a second attemptThe user then typed an amount above
maxSendLightningSats(6131 sats vs. total 6485) and sawother__pay_insufficient_spending_amount_description, which is technically correct for that amount but hides the real blocker: even sending exactlymaxSendwould fail because the invoice's destination is their own node.Expected behavior
As soon as the scanned/pasted Lightning invoice is decoded, compare the invoice's payee pubkey against the local node id. If they match, block the flow with a dedicated error (e.g. "You can't pay an invoice created by your own wallet").
Proposed implementation
AppViewModel.validateLightningInvoice(app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt:904):invoice.payeePubkeywithlightningRepo.getNodeId().showAddressValidationErrorwith a new string resource (e.g.other__pay_self_invoice_title/other__pay_self_invoice_description) and return early — before the insufficient-spending check.validateOnChainAddresswhereextractViableLightningInvoicepulls the embedded BOLT11 (AppViewModel.kt:951), apply the same self-payment check before switchingpayMethodtoSendMethod.LIGHTNING.onScanLightning(AppViewModel.kt:1431) and the unified-invoice branch inonScan*(AppViewModel.kt:1396area) for cases where the decoded invoice carries an amount or the user enters one later.estimateMaxAmountRoutingFee(AppViewModel.kt:2141) andestimateLightningRoutingFeesIfNeeded(AppViewModel.kt:2120), if the underlying error isCannot generate a route to ourselves, fire the same self-payment toast instead of silently zeroing the estimate.app/src/main/res/values/strings.xml(alphabetical order) — English copy only; keep localization keys aligned with existingother__pay_*conventions.Files to touch
app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt(:904,:931,:1431,:2120,:2141)app/src/main/java/to/bitkit/repositories/LightningRepo.kt— confirmgetNodeId()is callable from this path (:1221)app/src/main/res/values/strings.xmlVerification
bitcoin:…?lightning=…).bitcoin:prefix) — same toast.Related
Diagnosed from support ticket — user reported "everytime I try it says there isn't enough btc to fill this invoice but I have enough" while repeatedly pasting their own wallet's Receive URI into Send.