Skip to content

fix(wallet): validate and persist Nostr payment requests - #2516

Draft
thesimplekid wants to merge 2 commits into
cashubtc:mainfrom
thesimplekid:validate_nostr_requests
Draft

thesimplekid wants to merge 2 commits into
cashubtc:mainfrom
thesimplekid:validate_nostr_requests

Conversation

@thesimplekid

Copy link
Copy Markdown
Collaborator

Reject payments with mismatched IDs, units, amounts, mint policies, or spending conditions. Require net receipts to cover applicable NUT-18 method fees using the lowest supported requested method fee.

Persist request state and receive-operation linkage for recovery after restart. Expose request recovery and cancellation through CLI and FFI, and prevent duplicate redemption across repository clones.

Cover validation, fee handling, offline delivery, cancellation, and interrupted receive recovery with regression tests.

Description


Notes to the reviewers


Suggested CHANGELOG Updates

CHANGED

ADDED

REMOVED

FIXED


Checklist

  • I followed the code style guidelines
  • I ran just quick-check before committing
  • If the Wallet API was modified (added/removed/changed), I have reflected those changes in the FFI bindings (crates/cdk-ffi)

Carry the original request and mint trust in NostrWaitInfo so the existing
wait method validates every payment. Ignore definitively invalid payments
and return operational or indeterminate failures for recovery. Keep CLI
and FFI reception on the same validated path.

BREAKING CHANGE: NostrWaitInfo replaces mints and mint_preferred with
request and trusted_mints. Older CLI records without request constraints
must be recreated. This change targets 0.19 and is not a patch backport.
Save request constraints, mint trust, and Nostr keys before sharing the
request. Use the saved record from the existing receive and wait APIs,
with additional methods for listing, checking, resuming, and cancellation.

Track receive operation IDs through uncertain outcomes. Protect reserved
proof ownership and retain incomplete recovery state rather than falsely
marking a request paid. Expose durable request management in CLI and FFI.
@thesimplekid
thesimplekid force-pushed the validate_nostr_requests branch from 14ccc16 to dd9ab14 Compare September 16, 2026 08:34
Comment on lines +109 to +110
tracing::warn!(%saga_id, "Receive inputs missing; retaining uncertain saga");
return Ok(RecoveryAction::Skipped);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we recover the case where proof replacement succeeded but the transaction completion write did not? ReceiveSaga::execute saves the new proofs and removes the inputs before separately marking the transaction Completed. A crash between those writes leaves a pending transaction with no reserved inputs, so this branch returns Skipped on every recovery attempt and the Nostr request stays Receiving.

The funds remain spendable, but the request cannot complete or be cancelled. Could we verify the recorded outputs before completing recovery, or make the two writes atomic? A regression test covering this specific interruption point would help preserve the protection against treating genuinely missing inputs as payment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

2 participants