Skip to content

feat: align mint quote accounting with NUT-04#2119

Open
thesimplekid wants to merge 3 commits into
cashubtc:mainfrom
thesimplekid:nut04_amount_paid
Open

feat: align mint quote accounting with NUT-04#2119
thesimplekid wants to merge 3 commits into
cashubtc:mainfrom
thesimplekid:nut04_amount_paid

Conversation

@thesimplekid

Copy link
Copy Markdown
Collaborator

Implement the mint quote accounting changes from cashubtc/nuts#377 by exposing amount_paid, amount_issued, and updated_at on mint quote responses.

Keep the deprecated state field only for BOLT11 compatibility while deriving local quote state from the canonical counters for all mint methods. Persist updated_at in wallet quote storage so stale responses cannot move amount_paid or amount_issued backwards.

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)

@cdk-bot cdk-bot left a comment

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.

Verified findings approved for disclosure:

  • Missing Supabase migration for mint_quote.updated_at (high) - Existing Supabase wallet databases can fail mint quote insert/update paths after this PR because the application sends an updated_at field that the deployed mint_quote table does not have, while startup compatibility checks still accept the old schema version.
    Unanchored locations included in summary:
    • crates/cdk-supabase/src/wallet.rs:2570

Comment thread crates/cdk-supabase/src/wallet.rs
Comment thread crates/cdk-supabase/src/wallet.rs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bf37f626a0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/cdk-supabase/src/wallet.rs
Comment thread crates/cdk-npubcash/src/types.rs Outdated
Comment thread crates/cdk/src/wallet/issue/mod.rs
@codecov

codecov Bot commented Jun 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.01609% with 82 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.53%. Comparing base (bfb5b8d) to head (d5257c1).

Files with missing lines Patch % Lines
crates/cdk/src/wallet/streams/payment.rs 70.31% 38 Missing ⚠️
crates/cdk/src/wallet/issue/mod.rs 88.52% 14 Missing ⚠️
crates/cdk-ffi/src/types/quote.rs 10.00% 9 Missing ⚠️
crates/cdk-common/src/mint.rs 77.41% 7 Missing ⚠️
crates/cdk-common/src/mint_quote.rs 42.85% 4 Missing ⚠️
crates/cashu/src/nuts/nut23.rs 50.00% 3 Missing ⚠️
crates/cashu/src/nuts/nut25.rs 0.00% 2 Missing ⚠️
crates/cdk-supabase/src/wallet.rs 0.00% 2 Missing ⚠️
crates/cashu/src/nuts/nut04.rs 75.00% 1 Missing ⚠️
crates/cashu/src/nuts/nut17/mod.rs 96.55% 1 Missing ⚠️
... and 1 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2119      +/-   ##
==========================================
+ Coverage   71.48%   71.53%   +0.05%     
==========================================
  Files         356      356              
  Lines       73857    74154     +297     
==========================================
+ Hits        52798    53049     +251     
- Misses      21059    21105      +46     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ye0man ye0man requested review from asmogo and crodas June 23, 2026 10:32
self.is_finalized = true;
Poll::Ready(None)
}
None => self.poll_event(cx),

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.

We should also implement a recursion limit and a sleep interval between events to reduce the load.

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.

If I remember correctly, this is fine because the next future would exit the call stack with a Pending

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

It looks like the recursion limit issue you bring up is valid but as @crodas said its "mostly" okay based on the next future. However, I still think we should clean it up but as a separate focused PR as its an existing pattern not introduced by this pr.

Comment on lines +150 to +154
if r.amount_paid > Amount::ZERO || r.amount_issued > Amount::ZERO {
Some(quote_state_from_amounts(r.amount_paid, r.amount_issued))
} else {
Some(r.state)
}

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.

Why are we using the state here ? I think we want to deprecate this.

Suggested change
if r.amount_paid > Amount::ZERO || r.amount_issued > Amount::ZERO {
Some(quote_state_from_amounts(r.amount_paid, r.amount_issued))
} else {
Some(r.state)
}
Some(quote_state_from_amounts(r.amount_paid, r.amount_issued))

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The bolt11 portion highlighted in the comments we need for backwards compatibility with mints that have not updated. We could move this logic of computing the amount_paid and amount_issued to the deserlizer and that would remove some of this logic. But I don't love computing fields in the serialize/deserialized but maybe for this it makes sense?

Comment on lines 178 to 181
if amount_paid == Amount::ZERO && amount_issued == Amount::ZERO {
return QuoteState::Unpaid;
}

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.

Suggested change
if amount_paid == Amount::ZERO {
return QuoteState::Unpaid;
}
if amount_issued == Amount::ZERO {
return QuoteState::Paid;
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is not a state that should happen but I cleaned it up in a830f779.

@github-project-automation github-project-automation Bot moved this from Backlog to In progress in CDK Jun 23, 2026
Implement the mint quote accounting changes from cashubtc/nuts#377
by exposing amount_paid, amount_issued, and updated_at on mint quote responses.

Keep the deprecated state field only for BOLT11 compatibility
while deriving local quote state from the canonical counters for all mint methods.
Persist updated_at in wallet quote storage so stale responses cannot move amount_paid or amount_issued backwards.
Add the Supabase mint_quote.updated_at migration and require schema version 8.
Keep imported unpaid NpubCash quotes at updated_at 0 so legacy BOLT11 status
responses can still advance them, and suppress stale websocket notifications
after monotonic quote accounting rejects an update.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

4 participants