feat: secure cash-in via server-stamped create_withdraw RPC (#52) #66
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "cash-in-create-withdraw"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The bitspire consumer half of the secure cash-in design (spirekeeper#31, schema pinned; spirekeeper#32 handler live on the dev stack). Replaces the dev-stack-proof cash-in path (ATM creates the link + sets amount/extra itself) with the verified-attribution flow.
What changes
LnbitsClient.createWithdraw(walletId, body)— new signed kind-21000 RPC. Request:{ principal_sats, fiat_amount?, fiat_code?, title?, wait_time?, client_ref? }. Response:{ link_id, lnurl, net_sats, principal_sats, fee_sats }. Non-idempotent (mints a link) → not retry-wrapped.lightning.tsgenerateLnurlWithdraw—createWithdrawLink→createWithdraw. The ATM sends only the hardware-attestedprincipal_sats; the operator side derives fee + NET and stampssource/nostr_sender_pubkeyfrom the verified signer. The ATM no longer computes the amount or extra.link_id— the secure response carries nounique_hash. Settlement-watch half unchanged (subscribe_payments { tag:'withdraw', link_id }).Security
Closes both issues from the 2026-06-22 spec supersession: no client-controlled amount (can't understate the fee) and no self-asserted attribution (server stamps from the verified sender).
principalstays ATM-attested — same trust boundary as the cash-out wire amount.Status
Server RPC is live (spirekeeper#32), so this is ready for the joint cash-in test. typecheck 12/12; full suite (29 lnbits / 29 machine) + electron prod build green. I'll coordinate the deploy with the bunker/lnbits side watching the full chain (RPC → server-stamped net link → claim → cash_in settlement + super payout).
Do NOT use the MCP merge endpoint — merge via the Forgejo UI after review.
🤖 Generated with Claude Code
Replaces the cash-in LNURL-withdraw creation with the secure create_withdraw RPC (aiolabs/spirekeeper#31/#32). The ATM now sends only the hardware-attested gross principal_sats; the operator side verifies the signer, derives fee + NET, and stamps the link's attribution (source/nostr_sender_pubkey) from the VERIFIED sender. Closes the dev-stack weakness where the ATM set the withdraw amount + extra itself (could understate the fee / forge attribution). - LnbitsClient.createWithdraw(walletId, {principal_sats, fiat_amount?, fiat_code?, title?, wait_time?, client_ref?}) -> {link_id, lnurl, net_sats, principal_sats, fee_sats}. Non-idempotent (mints a link) -> not retry-wrapped. - lightning.ts generateLnurlWithdraw: createWithdrawLink -> createWithdraw; the ATM no longer computes amount/fee/extra. LNURL-session map re-keyed on link_id (the secure response carries no unique_hash); settlement-watch half unchanged (subscribe_payments tag:'withdraw', link_id). Server RPC is live on the dev stack (spirekeeper#32 registered create_withdraw), so this is ready for the joint cash-in test. typecheck 12/12, full suite + prod build green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>