feat: onchain payment method#365
Conversation
|
Discussed briefly offline: The multi-quote is quite a significant change to NUT-05. It maybe also adds resource tracking overhead (4-5 quotes per request) and requires new wallet UI to handle quote selection (vs existing methods). The tradeoff/benefit might be worth it, but perhaps we should consider setting a desired target confirmation speed in the request (eg |
@robwoodgate can you elaborate more on this? My thinking is that after the wallet picks the quote they only have to track that one and forget about the rest
Providing multiple options is pretty standard for onchain UIs. If a wallet doesn't want to offer quote selection to the user, then it can just select the fastest one and leave the UI unchanged. |
This will lead to proofs being stuck pending for 10+ min waiting for confirmation. I think this is bad ux so swapping should be forced. It's also much simpler for the mint to not have to deal with change. |
A mint has to track/hold all quotes it creates. It just seems wasteful on resources to have multiple quotes per request. Could also lead to a DoS vector.
It's different to the way all other methods are handled. In CTS, for example, I had to write custom handlers vs leaning on the generics. I just don't know as we need it when it's just as simple to send a param with desired confirmation speed up front. |
I don't think this is too much of a concern it's really only a couple extra db entry's and there is nothing really to monitor like there is for mint quotes.
This though is a valid point and would be the justification for change over the dos point. |
robwoodgate
left a comment
There was a problem hiding this comment.
The new fee_options works for me - best of both worlds. ACK.
|
A thought on SIG_ALL: onchain melt SIG_ALL currently commits to The exact input amount binds the selected fee amount, BUT if two I'm not sure that distinction matters, but if it does, duplicate fee values should also be forbidden... otherwise |
Lets just avoid this and forbid two from having the same fee. There is no reason for two to have the same fee. |
Addressed in e62c585 |
|
I am rethinking the use of an absolute fee and wondering if we should allow change. With no ability to give change the mint must be able to fairly accurately as over estimating too much will cause users to complain of high fees and underestimating will cause tx's to fail at melt time when attempting to construct the final one. I think this problem is exacerbated in payjoin where onchain inputs could change and thus the fee is changed but with a fixed fee up front there is less flexibility that allowing change would provide. The issue of change being stuck in pending for 10+ min is still valid but this could be made a wallet problem where they should send no more then amount + fee_reserve not that there is no change given. After CDK dev call seems like this is a good idea and we should allow change |
|
Resolved. It'll be in the mint-info settings. See responses below How about including the mint's (I tried to post this comment in line at |
|
TL/DR: I think the only unambiguous way to give any meaning to 'expiry' is to say that the mint must honour any payment which has achieved sufficient confirmations (e.g. 6) within 2,016 blocks of the expiry. So maybe the 'expiry' should be specified as a block height instead of a time? 'evicted' in Once a transaction is seen by anyone, the only thing that can stop it being confirmed is if at least one of its inputs is spent in another block (where that block has multiple confirmations). Until that 'double spend' happens, the transaction remains 'confirmable' for the indefinite future. Ultimately, I don't think we can specify anything related to the mempool. The only reason to even have an expiry is to free the mint from having to permanently monitor an arbitrarily large set of addresses. Therefore, I think we say that a payment either had sufficient confirmations before a deadline, or it was too late and the mint is free to ignore further payments to that address (Again, Github is giving me an "Failed to save comment: An internal error occurred, please try again.." error if I try to make the inline comment in the right place) |
Its come up a few times that it may benefit wallet ux to have an amount_incoming value that is the amount the mint sees in the mempool or onchain that has not reached the required number of confs. This would increase complexity of the mint having to mange mempool tx's that could be dropped from the mempool or removed via RBF. Also some node backends or services may not provide a mempool so the mint does not have this information. For example a mint that is using compact block filters does not have a mempool. Given this I lean towards not adding this, as we cannot guarantee mints can support it and I think providing it optionally is worse then not at all and it is up to wallets to use a mempool explorer if they want to show pending. Also having issues with inline comments. |
|
While minting: Are If yes, and And I guess a similar question apples to melting, but I haven't read that section in detail yet |
This is in the mint info, and its up to the wallet how to display this. #365 (comment) |
|
Nice. Sorry I missed that:
How about adding a few words to refer to NUT-04 and make this more explicit? I guess we can assume that mint developers would know this; but wallet devs mightn't know exactly where to check. Something like: |
NUT-XX onchain payment method (cashubtc/nuts#365) defines MintMethodSetting.options.confirmations as the minimum block depth the mint requires before crediting a deposit. We already had MINT_ZCASH_MIN_CONFIRMATIONS as a setting but did not surface it in mint info, so wallets had no way to discover it. - Broaden MintMethodSetting.options from Optional[MintMethodBolt11OptionSetting] to Optional[Dict[str, Any]] so each method can carry its own options shape. - bolt11 keeps emitting {"description": bool} via MintMethodBolt11OptionSetting.model_dump. - zcash now emits {"confirmations": MINT_ZCASH_MIN_CONFIRMATIONS}. Wallet code does not consume MintMethodBolt11OptionSetting as a typed model anywhere; only features.py builds it. Safe change. See ZCASH-CDK-COMPATIBILITY.md §6.
Aligns the mint's wire format with the unmerged onchain payment-method NUT (PR cashubtc#365) so wallets implementing it can talk to our mint without zcash-specific glue. Method rename: - backend now registered as Method("onchain") instead of Method("zcash"); the (onchain, zec) method-unit pair signals native Zcash chain. - mint info MintMethodSetting/MeltMethodSetting branch keyed on method.name == "onchain". - All internal MINT_ZCASH_* settings keep their names (they configure the zwalletd backend; only the spec-facing method changes). Router: - router_zcash.py removed; replaced with router_onchain.py serving /v1/{mint,melt}/{quote,}/onchain endpoints. - Mint quote bypasses ledger.mint_quote() so the request can be amount-less per NUT-XX. We allocate a deposit address with amount=0 internally; the running deposit total is polled from the backend on each GET /v1/mint/quote/onchain/{quote} and persisted as MintQuote.amount, surfaced as `amount_paid`. - Mint quote response uses NUT-XX shape: no `state` field; emits `amount_paid` and `amount_issued` (derived from the underlying state machine: amount_issued == amount on ISSUED, amount_paid == amount on PAID/PENDING/ISSUED, both zero on UNPAID). - Mint quote `pubkey` is REQUIRED (Pydantic enforces). - Melt quote response uses NUT-XX shape: `fee_options[]` array (single entry for Zcash's near-flat fee market), `selected_estimated_blocks` (echoed from the wallet's melt request), `outpoint` (txid for both transparent and shielded — see ZCASH-CDK-COMPATIBILITY.md §6.3 for why we don't surface vout). - Melt request requires `estimated_blocks`, validated against the quote's fee_options. Models: - New PostMintQuoteOnchainRequest/Response, PostMeltQuoteOnchainRequest/ Response, PostMeltOnchainRequest, OnchainFeeOption matching XX.md on branch thesimplekid/onchain (commit d76e7e5, last ACK 2026-05-06). Backend: - ZcashBackend.get_deposit_total(checking_id) helper exposes total_confirmed zatoshi for the onchain mint quote accounting. Tests: - All 25 backend tests in test_mint_lightning_zcash.py updated to the onchain method name and pass green. Deviations from NUT-XX still in place (tracked in ZCASH-CDK-COMPATIBILITY.md §6.5): - one mint per quote (cashu ledger marks the quote ISSUED on first mint) - one deposit per quote in practice (first deposit is captured as the full amount; later deposits to the same address bump amount_paid but cannot be minted without lifting the single-mint restriction) - `change` not yet removed from the wider model (NUT-XX forbids it; the decision is still under spec review as of 2026-05-06)
Aligns the mint's wire format with the unmerged onchain payment-method NUT (PR cashubtc#365) so wallets implementing it can talk to our mint without zcash-specific glue. Method rename: - backend now registered as Method("onchain") instead of Method("zcash"); the (onchain, zec) method-unit pair signals native Zcash chain. - mint info MintMethodSetting/MeltMethodSetting branch keyed on method.name == "onchain". - All internal MINT_ZCASH_* settings keep their names (they configure the zwalletd backend; only the spec-facing method changes). Router: - router_zcash.py removed; replaced with router_onchain.py serving /v1/{mint,melt}/{quote,}/onchain endpoints. - Mint quote bypasses ledger.mint_quote() so the request can be amount-less per NUT-XX. We allocate a deposit address with amount=0 internally; the running deposit total is polled from the backend on each GET /v1/mint/quote/onchain/{quote} and persisted as MintQuote.amount, surfaced as amount_paid. - Mint quote response uses NUT-XX shape: no state field; emits amount_paid and amount_issued (derived from the underlying state machine: amount_issued == amount on ISSUED, amount_paid == amount on PAID/PENDING/ISSUED, both zero on UNPAID). - Mint quote pubkey is REQUIRED (Pydantic enforces). - Melt quote response uses NUT-XX shape: fee_options array (single entry for Zcash near-flat fee market), selected_estimated_blocks (echoed from the wallet melt request), outpoint (txid for both transparent and shielded; we do not surface vout). - Melt request requires estimated_blocks, validated against the quote fee_options. Models: - New PostMintQuoteOnchainRequest/Response, PostMeltQuoteOnchainRequest/ Response, PostMeltOnchainRequest, OnchainFeeOption matching XX.md on branch thesimplekid/onchain (commit d76e7e5, last ACK 2026-05-06). Backend: - ZcashBackend.get_deposit_total(checking_id) helper exposes total_confirmed zatoshi for the onchain mint quote accounting. Tests: - All 25 backend tests in test_mint_lightning_zcash.py updated to the onchain method name and pass green. Deviations from NUT-XX still in place (tracked in ZCASH-CDK-COMPATIBILITY.md §6.5): - one mint per quote (cashu ledger marks the quote ISSUED on first mint) - one deposit per quote in practice (first deposit is captured as the full amount; later deposits to the same address bump amount_paid but cannot be minted without lifting the single-mint restriction) - change not yet removed from the wider model (NUT-XX forbids it; the decision is still under spec review as of 2026-05-06)
Uh oh!
There was an error while loading. Please reload this page.