Skip to content

custom payment methods#382

Open
asmogo wants to merge 5 commits into
cashubtc:mainfrom
asmogo:generic-payment-method
Open

custom payment methods#382
asmogo wants to merge 5 commits into
cashubtc:mainfrom
asmogo:generic-payment-method

Conversation

@asmogo

@asmogo asmogo commented May 27, 2026

Copy link
Copy Markdown
Contributor

Implementations

support custom payment methods not defined in a dedicated NUT.

@robwoodgate robwoodgate 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.

I think this is a fantastic step forward for wallets to be able to better support unknown methods - I've added some suggested tweaks to the base structs to make life even better.

Comment thread 04.md

### Websocket Notifications

Custom methods **MAY** support websocket subscriptions via [NUT-17][17] with kind `"{method}_mint_quote"`.

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.

Related: #372

Comment thread 05.md

### Websocket Notifications

Custom methods **MAY** support websocket subscriptions via [NUT-17][17] with kind `"{method}_melt_quote"`.

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.

Related: #372

Comment thread 04.md
Comment on lines 42 to 45
{
"unit": <str_enum[UNIT]>
// Additional method-specific fields may be required
}

This comment was marked as resolved.

Comment thread 04.md
Comment on lines 51 to 56
{
"quote": <str>,
"request": <str>,
"unit": <str_enum[UNIT]>,
// Additional method-specific fields will be included
}

This comment was marked as resolved.

Comment thread 05.md
Comment on lines 47 to 51
{
"request": <str>,
"unit": <str_enum[UNIT]>
// Additional method-specific fields will be required
}

This comment was marked as resolved.

Comment thread 05.md Outdated
Comment on lines 57 to 67

This comment was marked as resolved.

@robwoodgate

Copy link
Copy Markdown
Collaborator

Sorry @asmogo - I questioned an earlier draft that included method in the quote structs (thinking mint and wallet know by virtue of the endpoint used to request it), but this related issue highlights that for WS, and especially with the suggestion on harmonizing the base structs for custom methods, the distinction is easy to blur/lose.

So maybe we DO need to include method: <str>, in the quote structs for both mint and melt.

@robwoodgate

Copy link
Copy Markdown
Collaborator

Related #377

which adds the amount_oaid, amount_issued, updated_at parms to default quote structs

@robwoodgate robwoodgate 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.

Have implemented custom method support in cashu-ts on top of this + #377 + #387 (cashubtc/cashu-ts#698) and it works nicely. Wallets can quote, mint and melt methods they don't fully understand using just the base structs.

A few tweaks below that came out of implementing. Note the suggestions assume #377 merges first.

Related to my base struct suggestions above: expiry really wants to be in the common mint quote response - every method has one, and a wallet showing a quote for an unknown method needs to know when to stop polling. With #377 in, it's the only field from the suggested base response still left as method-specific.

(method in the quote structs is now covered by #387, which also resolves the WS routing question from #378.)

Can also confirm the optional fee_reserve in the melt base works in practice - onchain can't make it required (it uses fee_options), and bolt11/12 tighten it to required in their own NUTs.

Comment thread 04.md Outdated

For a custom `{method}`, the wallet sends a request following the common mint quote request format (see [General Flow](#general-flow)). Method-specific fields (e.g., an `amount` of tokens to mint, a `description`, or a `pubkey` for [NUT-20][20] locks) are defined by the method-specific NUT.

The mint responds with the common mint quote response format. The `request` field contains the method-specific payment request (e.g., a payment URL, an on-chain address, an account identifier). Additional method-specific fields (such as `amount` or `expiry`) are defined by the method-specific NUT.

This comment was marked as resolved.

Comment thread 05.md Outdated

For a custom `{method}`, the wallet sends a request following the common melt quote request format (see [General Flow](#general-flow)). The `request` field is the method-specific payment target (e.g., a bank account identifier, an on-chain address, a payment processor reference). `unit` is the unit the wallet would like to pay with.

The mint responds with the common melt quote response format. Method-specific fields are defined by the method-specific NUT.

This comment was marked as resolved.

robwoodgate added a commit to robwoodgate/cashu-ts that referenced this pull request Jun 12, 2026
Implements the base-shape harmonization proposed on cashubtc/nuts#382:

- MintQuoteBaseRequest gains optional amount and description; method
  NUTs tighten as needed (bolt11 requires amount).
- MintQuoteBaseResponse gains expiry (normalized to null when unset),
  subsuming the per-method expiry fields.
- MeltQuoteBaseRequest gains optional amount (onchain requires it).
- MeltQuoteBaseResponse gains request and optional fee_reserve; bolt
  methods keep fee_reserve required.
- Melt base validation now requires the payment request for every
  method, and normalizes fee_reserve when present.
- New MintQuoteGenericResponse/MeltQuoteGenericResponse passthrough
  types are the defaults on the generic quote methods, so custom-method
  fields are reachable without casting.

BREAKING CHANGE: melt quote responses without a request field now
throw; generic quote methods default to the Generic response types.
robwoodgate added a commit to robwoodgate/cashu-ts that referenced this pull request Jun 12, 2026
Implements the base-shape harmonization proposed on cashubtc/nuts#382:

- MintQuoteBaseRequest gains optional amount and description; method
  NUTs tighten as needed (bolt11 requires amount).
- MintQuoteBaseResponse gains expiry (normalized to null when unset),
  subsuming the per-method expiry fields.
- MeltQuoteBaseRequest gains optional amount (onchain requires it).
- MeltQuoteBaseResponse gains request and optional fee_reserve; bolt
  methods keep fee_reserve required.
- Melt base validation now requires the payment request for every
  method, and normalizes fee_reserve when present.
- New MintQuoteGenericResponse/MeltQuoteGenericResponse passthrough
  types are the defaults on the generic quote methods, so custom-method
  fields are reachable without casting.

BREAKING CHANGE: melt quote responses without a request field now
throw; generic quote methods default to the Generic response types.
Consolidates review feedback on the generic payment method PR. Scoped to
the delta NOT covered by cashubtc#377 (accounting fields) or cashubtc#387 (method), so
those can merge independently:

- common mint quote request: optional amount, description, pubkey
- common melt quote request: optional amount
- common mint quote response: expiry, optional pubkey
- common melt quote response: request, optional fee_reserve
- custom mint quotes MUST carry the accounting fields
- custom melt quotes MUST use the standard UNPAID/PENDING/PAID states
@robwoodgate

Copy link
Copy Markdown
Collaborator

Added asmogo#1 with my suggestions ready to merge into this PR if acceptable.

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