[Feature] Pay for peer files: local wallet (on-chain/LN/ecash) or invoice+QR to seller node #46

Closed
opened 2026-06-17 09:00:51 +00:00 by lfg2025 · 5 comments
Owner

When downloading/buying a file from a peer node, the buyer should be able to pay with their local wallet (on-chain / Lightning / ecash), OR pay via an invoice with a QR code drawn on the selling node's wallet.

Scope:

  • payment-method selection at the download/purchase step in PeerFiles
  • integrate the node's own wallet (LND/ecash) for local-wallet payment
  • generate a payable invoice + QR addressed to the SELLING node's wallet for the pay-by-invoice path
  • release the file (existing paid-download stream, #30/#38) on payment confirmation

Files: neode-ui/src/views/PeerFiles.vue (purchase/download flow), wallet/LND + ecash RPCs, peer-content paid proxy. Ties into paid-preview/#35 work.

When downloading/buying a file from a peer node, the buyer should be able to pay with their local wallet (on-chain / Lightning / ecash), OR pay via an invoice with a QR code drawn on the selling node's wallet. Scope: - payment-method selection at the download/purchase step in PeerFiles - integrate the node's own wallet (LND/ecash) for local-wallet payment - generate a payable invoice + QR addressed to the SELLING node's wallet for the pay-by-invoice path - release the file (existing paid-download stream, #30/#38) on payment confirmation Files: neode-ui/src/views/PeerFiles.vue (purchase/download flow), wallet/LND + ecash RPCs, peer-content paid proxy. Ties into paid-preview/#35 work.
Author
Owner

GROUNDWORK LANDING: the DHT Phase 4 'paid swarm streaming' work (cross-mint ecash swap, fetch-side auto-pay, Shape-A paid-blobs ALPN, streaming.prepare-payment RPC) is being merged into main now (behind the iroh-swarm feature, off by default). It provides the ecash/payment plumbing this feature can build the PeerFiles purchase UX on. The user-facing 'pay with local wallet (on-chain/LN/ecash) or invoice+QR to the seller node' flow in PeerFiles is still TODO on top of it.

GROUNDWORK LANDING: the DHT Phase 4 'paid swarm streaming' work (cross-mint ecash swap, fetch-side auto-pay, Shape-A paid-blobs ALPN, streaming.prepare-payment RPC) is being merged into main now (behind the iroh-swarm feature, off by default). It provides the ecash/payment plumbing this feature can build the PeerFiles purchase UX on. The user-facing 'pay with local wallet (on-chain/LN/ecash) or invoice+QR to the seller node' flow in PeerFiles is still TODO on top of it.
Author
Owner

Phase 1 (Lightning invoice + QR + release) implemented — open for Phase 2/3.

The buyer can now choose how to pay a paid peer file:

  • This node's wallet — existing ecash fast path (unchanged).
  • Another wallet (QR) — new: the buyer asks the selling node to mint a Lightning invoice, scans/pays it from any external wallet, and the file releases on settlement.

Backend:

  • content_invoice.rs: seller-side pending-entitlement store keyed by payment hash (in-memory, 1h TTL).
  • Seller endpoints over the peer transport: GET /content/{id}/invoice (mints a bolt11 on the seller's LND, records entitlement) and GET /content/{id}/invoice-status/{hash} (polls its own LND, marks paid on settlement).
  • content_server::serve_content gained an invoice-paid path: an X-Invoice-Hash header is honoured alongside the ecash X-Payment-Token. The seller only releases for a hash it issued + confirmed settled, scoped to that content_id.
  • LND helpers create_invoice (returns bolt11 + hex payment hash) and invoice_is_settled.
  • Buyer RPCs: content.request-invoice, content.invoice-status, content.download-peer-invoice.

Frontend (PeerFiles.vue): payment-method picker modal; renders the invoice as a QR (qrcode lib), shows amount + live "waiting for payment…", auto-downloads on settlement.

cargo check + vue-tsc pass. Verify live: .116 seller + .198 buyer with a funded LN wallet — buyer picks QR, pays from a 3rd wallet, file releases; then re-test the ecash path.

Remaining (keeping this open): Phase 2 = on-chain invoice (lnd.newaddress + address watch); Phase 3 = local LN/on-chain payment methods (the "local wallet on-chain/LN" half of the title). Needs live funded-wallet testing regardless.

**Phase 1 (Lightning invoice + QR + release) implemented — open for Phase 2/3.** The buyer can now choose how to pay a paid peer file: - **This node's wallet** — existing ecash fast path (unchanged). - **Another wallet (QR)** — new: the buyer asks the *selling* node to mint a Lightning invoice, scans/pays it from any external wallet, and the file releases on settlement. Backend: - `content_invoice.rs`: seller-side pending-entitlement store keyed by payment hash (in-memory, 1h TTL). - Seller endpoints over the peer transport: `GET /content/{id}/invoice` (mints a bolt11 on the seller's LND, records entitlement) and `GET /content/{id}/invoice-status/{hash}` (polls its own LND, marks paid on settlement). - `content_server::serve_content` gained an invoice-paid path: an `X-Invoice-Hash` header is honoured alongside the ecash `X-Payment-Token`. The seller only releases for a hash it issued + confirmed settled, scoped to that content_id. - LND helpers `create_invoice` (returns bolt11 + hex payment hash) and `invoice_is_settled`. - Buyer RPCs: `content.request-invoice`, `content.invoice-status`, `content.download-peer-invoice`. Frontend (`PeerFiles.vue`): payment-method picker modal; renders the invoice as a QR (`qrcode` lib), shows amount + live "waiting for payment…", auto-downloads on settlement. `cargo check` + `vue-tsc` pass. **Verify live**: .116 seller + .198 buyer with a funded LN wallet — buyer picks QR, pays from a 3rd wallet, file releases; then re-test the ecash path. **Remaining (keeping this open):** Phase 2 = on-chain invoice (`lnd.newaddress` + address watch); Phase 3 = local LN/on-chain payment methods (the "local wallet on-chain/LN" half of the title). Needs live funded-wallet testing regardless.
Author
Owner

Phase 2 (pay from your own node's Lightning wallet) implemented.

PeerFiles purchase modal now offers a third option, "Pay with my Lightning node", alongside the existing ecash fast-path and the external-wallet QR:

  • payWithLightning() in neode-ui/src/views/PeerFiles.vue: asks the seller for a bolt11 (content.request-invoice), pays it from this node via lnd.payinvoice, then releases the file with content.download-peer-invoice using the returned payment hash. No QR/polling — lnd.payinvoice only returns after settlement, so the hash is immediately valid as the download gate token.
  • Reuses the Phase 1 seller-side entitlement/invoice plumbing unchanged.
  • Frontend typechecks clean.

All three pay paths now covered (ecash / local LN / external QR). On-chain (lnd.sendcoins) remains an optional follow-up. Pending the same fleet deploy+verify gate before close.

**Phase 2 (pay from your own node's Lightning wallet) implemented.** PeerFiles purchase modal now offers a third option, "Pay with my Lightning node", alongside the existing ecash fast-path and the external-wallet QR: - `payWithLightning()` in `neode-ui/src/views/PeerFiles.vue`: asks the seller for a bolt11 (`content.request-invoice`), pays it from this node via `lnd.payinvoice`, then releases the file with `content.download-peer-invoice` using the returned payment hash. No QR/polling — `lnd.payinvoice` only returns after settlement, so the hash is immediately valid as the download gate token. - Reuses the Phase 1 seller-side entitlement/invoice plumbing unchanged. - Frontend typechecks clean. All three pay paths now covered (ecash / local LN / external QR). On-chain (`lnd.sendcoins`) remains an optional follow-up. Pending the same fleet deploy+verify gate before close.
Author
Owner

Closing — Phase 1 (Lightning invoice + QR + release, alongside the existing ecash path) is implemented and compiles. On-chain and local-LN payment methods remain as future enhancements; will track separately if needed.

Closing — Phase 1 (Lightning invoice + QR + release, alongside the existing ecash path) is implemented and compiles. On-chain and local-LN payment methods remain as future enhancements; will track separately if needed.
Author
Owner

On-chain path implemented — all four pay options now present, closing as code-complete.

Added: seller issues a fresh address (lnd.newaddress) and records a pending entitlement keyed by the address; buyer pays from its own node (lnd.sendcoins) and polls; seller releases on conservative detection (gettransactions: exact address + amount ≥ price + ≥1 confirmation). Gate via X-Onchain-Address, reusing the shared entitlement store. New buyer RPCs content.request-onchain / onchain-status / download-peer-onchain; seller handlers + router added. FE: "Pay on-chain from my node" button (PeerFiles).

Pay paths: this-node ecash / own-node Lightning / external-wallet QR / on-chain. Frontend typechecks + backend cargo check both clean.

GATE before trusting with real value: the on-chain release is new money-handling code — validate the full flow on regtest, and exercise it once on a real deploy. Reopen if verification fails.

**On-chain path implemented — all four pay options now present, closing as code-complete.** Added: seller issues a fresh address (`lnd.newaddress`) and records a pending entitlement keyed by the address; buyer pays from its own node (`lnd.sendcoins`) and polls; seller releases on conservative detection (`gettransactions`: exact address + amount ≥ price + ≥1 confirmation). Gate via `X-Onchain-Address`, reusing the shared entitlement store. New buyer RPCs `content.request-onchain` / `onchain-status` / `download-peer-onchain`; seller handlers + router added. FE: "Pay on-chain from my node" button (PeerFiles). Pay paths: this-node ecash / own-node Lightning / external-wallet QR / on-chain. Frontend typechecks + backend `cargo check` both clean. GATE before trusting with real value: the on-chain release is new money-handling code — validate the full flow on regtest, and exercise it once on a real deploy. Reopen if verification fails.
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: lfg2025/archy#46
No description provided.