You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(payment-processor): propagate mint quote_id to backend
Adds the mint's QuoteId to the three OutgoingPaymentOptions struct variants
so custom payment-method backends can deterministically correlate their
`get_payment_quote` and `make_payment` calls for the same melt.
Today, the gRPC payment-processor proto carries no link between those two
calls for the same melt: a backend's `get_payment_quote` returns a
PaymentQuoteResponse whose `request_lookup_id` the mint stores on the quote,
but the eventual `make_payment` receives an OutgoingPaymentOptions with
neither the stored lookup_id nor the mint's quote_id (`from_melt_quote_with_fee`
in cdk-common drops `extra_json` and has no quote_id field). bolt11/bolt12
backends are insulated by the payment_hash / offer being intrinsically
derivable from the invoice in both calls. Custom backends have no such
anchor, and have to fabricate a derivation — typically hashing `request` —
which forces the wallet to make `request` unique per melt. That's awkward
for any custom rail whose "request" doesn't naturally carry uniqueness
(branch tickets, account IDs, free-text references). With `quote_id`
plumbed through, the backend has the same stable key the mint uses
everywhere else, so correlation is trivial.
Changes:
- cdk-common::payment: add `quote_id: QuoteId` to Bolt11/Bolt12/Custom
OutgoingPaymentOptions structs. Propagate it in `from_melt_quote_with_fee`
from `melt_quote.id`.
- cdk::mint::melt: pre-generate the quote_id before each `get_payment_quote`
call (bolt11, bolt12, custom paths) and pass it both to the backend and to
`MeltQuote::new`, replacing the previous implicit auto-generation.
- payment_processor.proto: add required `string quote_id` to
Bolt11/Bolt12/CustomOutgoingPaymentOptions and PaymentQuoteRequest.
Field-numbers appended (5/6/7/6) to preserve wire compatibility with the
existing fields.
- cdk-payment-processor server/client: serialize/deserialize quote_id
directly (no Option wrapping). Empty/invalid values surface as
`Status::invalid_argument("Invalid quote_id: ...")` from QuoteId::from_str.
- cdk-common: bump PAYMENT_PROCESSOR_PROTOCOL_VERSION 2.0.0 -> 3.0.0. The
VersionInterceptor's strict equality check means any old mint/backend
pair will see a clear "Protocol version mismatch" at connection time
instead of misbehaving silently, which already covers the case where one
side doesn't know about quote_id.
- cdk-integration-tests: extend the existing custom-payment-processor
fixture to capture the received quote_id, and add a regression test
asserting it matches the quote_id surfaced to the wallet.
Existing bolt11/bolt12 backends (cln, lnd, lnbits, ldk-node, fake-wallet)
need no code changes — they continue to correlate via payment_hash / offer
and simply ignore the new field on the OutgoingPaymentOptions struct they
already receive. The struct gains one field; consumers using non-exhaustive
field access (`opts.bolt11`, `opts.melt_options`, etc.) are unaffected.
Only consumers that exhaustively destructure the struct would need to add
the new field to their pattern.
0 commit comments