Skip to content

Commit 4732a4f

Browse files
committed
Introduce CurrencyConversion trait
Adds the `CurrencyConversion` trait to allow users to define custom logic for converting fiat amounts into millisatoshis (msat). This abstraction lays the groundwork for supporting Offers denominated in fiat currencies, where conversion is inherently context-dependent.
1 parent 95c4eaf commit 4732a4f

File tree

1 file changed

+31
-2
lines changed

1 file changed

+31
-2
lines changed

lightning/src/offers/invoice_request.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,9 @@ use crate::offers::merkle::{
7777
};
7878
use crate::offers::nonce::Nonce;
7979
use crate::offers::offer::{
80-
Amount, ExperimentalOfferTlvStream, ExperimentalOfferTlvStreamRef, Offer, OfferContents,
81-
OfferId, OfferTlvStream, OfferTlvStreamRef, EXPERIMENTAL_OFFER_TYPES, OFFER_TYPES,
80+
Amount, CurrencyCode, ExperimentalOfferTlvStream, ExperimentalOfferTlvStreamRef, Offer,
81+
OfferContents, OfferId, OfferTlvStream, OfferTlvStreamRef, EXPERIMENTAL_OFFER_TYPES,
82+
OFFER_TYPES,
8283
};
8384
use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError, ParsedMessage};
8485
use crate::offers::payer::{PayerContents, PayerTlvStream, PayerTlvStreamRef};
@@ -574,6 +575,34 @@ impl AsRef<TaggedHash> for UnsignedInvoiceRequest {
574575
}
575576
}
576577

578+
/// A trait for converting fiat currencies into millisatoshis (msats).
579+
///
580+
/// Implementations must return the conversion rate in **msats per minor unit** of the currency,
581+
/// where the minor unit is determined by its ISO-4217 exponent:
582+
/// - USD (exponent 2) → per **cent** (0.01 USD), not per dollar.
583+
/// - JPY (exponent 0) → per **yen**.
584+
/// - KWD (exponent 3) → per **fils** (0.001 KWD).
585+
///
586+
/// # Caution
587+
///
588+
/// Returning msats per major unit will be off by a factor of 10^exponent (e.g. 100× for USD).
589+
///
590+
/// This convention ensures amounts remain precise and purely integer-based when parsing and
591+
/// validating BOLT12 invoice requests.
592+
pub trait CurrencyConversion {
593+
/// Converts a fiat currency specified by its ISO-4217 code into **msats per minor unit**.
594+
fn fiat_to_msats(&self, iso4217_code: CurrencyCode) -> Result<u64, Bolt12SemanticError>;
595+
}
596+
597+
/// A default implementation of the `CurrencyConversion` trait that does not support any currency conversions.
598+
pub struct DefaultCurrencyConversion;
599+
600+
impl CurrencyConversion for DefaultCurrencyConversion {
601+
fn fiat_to_msats(&self, _iso4217_code: CurrencyCode) -> Result<u64, Bolt12SemanticError> {
602+
Err(Bolt12SemanticError::UnsupportedCurrency)
603+
}
604+
}
605+
577606
/// An `InvoiceRequest` is a request for a [`Bolt12Invoice`] formulated from an [`Offer`].
578607
///
579608
/// An offer may provide choices such as quantity, amount, chain, features, etc. An invoice request

0 commit comments

Comments
 (0)