feat(core): Updates to nut18 and nut26 payment request - #1059
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1059 +/- ##
==========================================
+ Coverage 74.66% 74.87% +0.20%
==========================================
Files 115 115
Lines 13205 13315 +110
==========================================
+ Hits 9860 9969 +109
- Misses 3345 3346 +1 ☔ View full report in Codecov by Harness. |
|
@KvngMikey If I am not mistaken this only adds support for decoding such payment requests with the additional fields but does not add any logic to handle them or to create a payment request with them. |
@a1denvalu3 you're right that this PR only adds encoding/decoding for the new ms / fr / sm fields and doesn't add enforcement logic. Happy to either extend this PR with that handling + a request-creation path, or land this as the serialization layer and do the behavior in a focused follow-up. Which would you prefer? |
Yes please |
|
The nut has been updated: |
|
I think there are new changes to the spec @KvngMikey |
11612fe to
91195fd
Compare
|
Noted by my agent while checking compliance to current spec:
|
|
|
I had my agent give this an initial look-over. The findings: Code reviewReviewed against NUT-18 and NUT-26 at current Both frozen vectors check out byte-for-byte, and the 1. Mint URL compared by exact string equality, so a trailing-slash mismatch silently overpays Before this PR a mismatch produced a loud "not accepted" error. Now, with nutshell/cashu/wallet/cli/cli.py Lines 303 to 306 in 27d35dd 2. NUT-05 The point of nutshell/cashu/core/mint_info.py Lines 86 to 91 in 27d35dd 3. Fee message is wrong when the request carries no mint list
nutshell/cashu/wallet/cli/cli.py Lines 335 to 342 in 27d35dd Minor: 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
…quest that carries fields
Drop `fr` and replace `sm: List[str]` with `sm: List[SupportedMethod]` (`mn`, optional `mf`) per cashubtc/nuts#381. NUT-26 tag 0x0a is now a repeatable supported_method sub-TLV (0x01=method, 0x02=fee u64 BE); 0x0b removed. Also fixes a mis-scoped guard error message (tag 0x01 is id, not transport). Byte-verified against frozen spec vectors.
Add MintInfo.payment_request_method_fee (mirrors supports_mpp): reject when the mint melts none of a request's `sm` methods, else return the lowest matching mf, unit-filtered. Wire it into `pay`: fee applies only when paying from a mint outside a strict/preferred list, or when no mint list is set. Fix `request` command's --method/--fee-reserve to match the new SupportedMethod shape (fr no longer exists).
… path the creq pay path already selects proofs via include_fees=True, which enforces sum(proofs) - input_fee(proofs) >= amount. Add a dust-proof regression test (20x 1-sat proofs at 250 ppk) proving the payer tops up rather than underpays. No CDK oracle exists for this clause.
--method now accepts name or name:fee (e.g. bolt11:50), rejecting non-integer or negative fees. Help text states the fee only applies when the payer mint is outside a preferred mint list. Full suite green (839 passed); no fr references remain outside unrelated tor binaries.
a and mf are denominated in the request unit u: reject when sm is set without u, and when u differs from the wallet unit, before the method fee lookup.
A negative mf passed model validation and was picked as the lowest fee, making the payer send less than the requested amount; constrain mf to the NUT-26 u64 range so both encodings agree. Require a positive request amount at parse time, and reject 0x09 values that are not exactly one byte (empty raised IndexError, multi-byte was silently accepted).
…e reason. Also say the request has no mint list when the fee applies for that reason, and require a non-empty method name.
49d09a5 to
ed186ad
Compare
| def payment_request_method_fee( | ||
| self, sm: Optional[List[SupportedMethod]], unit: Unit | ||
| ) -> Optional[int]: | ||
| """ | ||
| Given the `sm` (supported methods) list from a NUT-18/26 payment request, | ||
| return the lowest per-method fee this mint owes for melting via one of the | ||
| listed methods in `unit`. Returns 0 when `sm` is unset, i.e. the request | ||
| makes no method requirement, and `None` when this mint cannot melt via any | ||
| of the listed methods. | ||
| """ |
There was a problem hiding this comment.
does this really belong into mint_info.py?
implements cashubtc/nuts#381 to keep Nutshell up to date !