Skip to content

Receive URI generation can stall 10–15s on mobile: lazy LSP reconnect + LSPS2/mint round-trips are serialized behind one opaque await #88

Description

@hash-money

Observed

On mobile (Android + iOS, orange-sdk 4e9d230, Cashu trusted tier on Mutinynet signet, LSPS2 JIT via our LSP), Wallet::get_single_use_receive_uri() intermittently takes 10–15 seconds. The variance correlates with how long the app was backgrounded first: mobile OSes kill the LSP TCP socket in the background, and the reconnect cost is paid lazily by the next operation that needs the peer — which is usually this call, right when a user is standing in front of a payer.

Where the time goes (as integrators understand it)

get_single_use_receive_uri serializes, behind one opaque await, up to all of:

  1. LSP peer reconnect (TCP + noise + init + channel_reestablish) if the connection died — the mobile-lifecycle tax.
  2. LSPS2 JIT negotiation when inbound is insufficient (fee-menu fetch + buy round-trips over LN messages).
  3. Trusted-backend quote creation (Cashu: HTTP POST to the mint) on the trusted path.
  4. On-chain address derivation (local, fine).

None of this is individually wrong, but bundling them means integrators can neither overlap the slow parts with UI (the user is typing an amount anyway) nor tell users what they're waiting for.

Asks (any subset helps)

  1. Mobile lifecycle hook / eager reconnect — an ensure_lsp_connected() (or on_foreground() hint) so apps can start the reconnect the moment the app foregrounds or the Receive screen opens, instead of paying it inside invoice generation. This is the single biggest win for perceived latency.
  2. Split preparation from construction — a prepare_receive()-style warm-up that performs the connection/fee-menu legwork, letting get_single_use_receive_uri be fast at tap time.
  3. Cache LSPS2 opening_fee_params within their valid_until window — if the fee menu is currently refetched per invoice, reusing a still-valid menu removes a round-trip from every JIT invoice.
  4. Per-stage tracing — debug-level timing per stage (reconnect / LSPS2 / trusted quote / address) so integrators can attribute field latency instead of guessing.

Context

Downstream product issue with the client-side trace: emergent-money/graduated-wallet#331. We can work around with a parallel warm-up on screen-entry once there's any connect/warm API to call — but the lazy-reconnect-inside-receive behavior is the structural cause and affects every mobile integrator.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions