Skip to content

Commit 18d3003

Browse files
committed
fix(mint): return null expiry for no-expiry Bolt12 quotes
Map the internal 0 expiry sentinel back to None when converting Bolt12 mint quotes to API responses, matching the onchain conversion behavior. Add regression coverage for direct and generic Bolt12 quote response paths.
1 parent 10cab2a commit 18d3003

1 file changed

Lines changed: 70 additions & 2 deletions

File tree

crates/cdk-common/src/mint.rs

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,7 +1267,7 @@ impl TryFrom<MintQuote> for MintQuoteBolt12Response<QuoteId> {
12671267
Ok(MintQuoteBolt12Response {
12681268
quote: mint_quote.id.clone(),
12691269
request: mint_quote.request,
1270-
expiry: Some(mint_quote.expiry),
1270+
expiry: (mint_quote.expiry != 0).then_some(mint_quote.expiry),
12711271
amount_paid: mint_quote.amount_paid.into(),
12721272
amount_issued: mint_quote.amount_issued.into(),
12731273
pubkey: mint_quote.pubkey.ok_or(Error::PubkeyRequired)?,
@@ -1398,7 +1398,7 @@ impl TryFrom<MintQuote> for MintQuoteResponse<QuoteId> {
13981398
amount: quote.amount.as_ref().map(|a| a.clone().into()),
13991399
unit: quote.unit.clone(),
14001400
method: PaymentMethod::Known(cashu::nuts::nut00::KnownMethod::Bolt12),
1401-
expiry: Some(quote.expiry),
1401+
expiry: (quote.expiry != 0).then_some(quote.expiry),
14021402
pubkey: quote.pubkey.ok_or(Error::PubkeyRequired)?,
14031403
amount_paid: quote.amount_paid().into(),
14041404
amount_issued: quote.amount_issued().into(),
@@ -1824,6 +1824,74 @@ mod tests {
18241824
assert_eq!(response.amount_issued, Amount::from(1_000));
18251825
}
18261826

1827+
fn dummy_bolt12_mint_quote(expiry: u64) -> (MintQuote, QuoteId, PublicKey) {
1828+
let pubkey = PublicKey::from_hex(
1829+
"03d56ce4e446a85bbdaa547b4ec2b073d40ff802831352b8272b7dd7a4de5a7cac",
1830+
)
1831+
.expect("test pubkey must parse");
1832+
let quote_id = QuoteId::new();
1833+
let mint_quote = MintQuote::new(
1834+
Some(quote_id.clone()),
1835+
"lno1testoffer".to_string(),
1836+
CurrencyUnit::Sat,
1837+
Some(Amount::new(10_000, CurrencyUnit::Sat)),
1838+
expiry,
1839+
PaymentIdentifier::QuoteId(quote_id.clone()),
1840+
Some(pubkey),
1841+
Amount::new(10_000, CurrencyUnit::Sat),
1842+
Amount::new(1_000, CurrencyUnit::Sat),
1843+
PaymentMethod::BOLT12,
1844+
unix_time(),
1845+
vec![],
1846+
vec![],
1847+
None,
1848+
);
1849+
1850+
(mint_quote, quote_id, pubkey)
1851+
}
1852+
1853+
#[test]
1854+
fn test_mint_quote_bolt12_response_converts_zero_expiry_to_none() {
1855+
let (mint_quote, quote_id, pubkey) = dummy_bolt12_mint_quote(0);
1856+
1857+
let response: MintQuoteBolt12Response<QuoteId> =
1858+
MintQuoteBolt12Response::try_from(mint_quote).unwrap();
1859+
1860+
assert_eq!(response.quote, quote_id);
1861+
assert_eq!(response.expiry, None);
1862+
assert_eq!(response.pubkey, pubkey);
1863+
assert_eq!(response.amount_paid, Amount::from(10_000));
1864+
assert_eq!(response.amount_issued, Amount::from(1_000));
1865+
}
1866+
1867+
#[test]
1868+
fn test_mint_quote_bolt12_response_preserves_nonzero_expiry() {
1869+
let expiry = unix_time() + 3600;
1870+
let (mint_quote, quote_id, _) = dummy_bolt12_mint_quote(expiry);
1871+
1872+
let response: MintQuoteBolt12Response<QuoteId> =
1873+
MintQuoteBolt12Response::try_from(mint_quote).unwrap();
1874+
1875+
assert_eq!(response.quote, quote_id);
1876+
assert_eq!(response.expiry, Some(expiry));
1877+
}
1878+
1879+
#[test]
1880+
fn test_mint_quote_response_bolt12_converts_zero_expiry_to_none() {
1881+
let (mint_quote, quote_id, pubkey) = dummy_bolt12_mint_quote(0);
1882+
1883+
let response = MintQuoteResponse::try_from(mint_quote).unwrap();
1884+
1885+
match response {
1886+
MintQuoteResponse::Bolt12(response) => {
1887+
assert_eq!(response.quote, quote_id);
1888+
assert_eq!(response.expiry, None);
1889+
assert_eq!(response.pubkey, pubkey);
1890+
}
1891+
_ => panic!("expected MintQuoteResponse::Bolt12 variant"),
1892+
}
1893+
}
1894+
18271895
#[test]
18281896
fn test_melt_quote_into_response_onchain_includes_change() {
18291897
let address = "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq";

0 commit comments

Comments
 (0)