Skip to content

[Bug]: Self-payment on Lightning shows misleading "Insufficient Spending" error #901

@jvsena42

Description

@jvsena42

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)
  • :7715ERROR ldk_node::payment::bolt11: Failed to find route for fee estimation: "Cannot generate a route to ourselves"
  • :7717estimateRoutingFeesForAmount 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

  1. 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.
  2. 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.
  3. Same guard on the amount-entered pathonScanLightning (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.
  4. 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.
  5. 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

  1. In a dev build, receive any amount via Lightning so a channel exists.
  2. Open Receive, copy the BIP21 unified QR (bitcoin:…?lightning=…).
  3. Paste it into the Send flow.
  4. Expected: the dedicated "self-payment" toast appears immediately on paste/scan — no "Insufficient Spending" toast, no amount entry screen.
  5. Repeat with just the raw BOLT11 (no bitcoin: prefix) — same toast.
  6. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions