diff --git a/src/currency.rs b/src/currency.rs index 1295649..69bf981 100644 --- a/src/currency.rs +++ b/src/currency.rs @@ -33,5 +33,5 @@ pub struct Currency { // means. For example, if the currency is "BTC" and the multiplier is 1000, really we're exchanging in SATs, so // `decimals` would be 8. // For details on edge cases and examples, see https://github.com/uma-universal-money-address/protocol/blob/main/umad-04-lnurlp-response.md. - pub decimals: i64, + pub decimals: i32, } diff --git a/src/protocol.rs b/src/protocol.rs index 9c15a17..68e96a0 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -194,7 +194,7 @@ impl PayRequest { } /// PayReqResponse is the response sent by the receiver to the sender to provide an invoice. -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct PayReqResponse { /// encoded_invoice is the BOLT11 invoice that the sender will pay. #[serde(rename = "pr")] @@ -240,17 +240,24 @@ pub struct PayReqResponseCompliance { pub utxo_callback: String, } -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct PayReqResponsePaymentInfo { /// CurrencyCode is the ISO 3-digit currency code that the receiver will receive for this /// payment. #[serde(rename = "currencyCode")] pub currency_code: String, + /// Number of digits after the decimal point for the receiving currency. For example, in USD, by + /// convention, there are 2 digits for cents - $5.95. In this case, `decimals` would be 2. This should align with + /// the currency's `decimals` field in the LNURLP response. It is included here for convenience. See + /// [UMAD-04](https://github.com/uma-universal-money-address/protocol/blob/main/umad-04-lnurlp-response.md) for + /// details, edge cases, and examples. + pub decimals: i32, + /// Multiplier is the conversion rate. It is the number of millisatoshis that the receiver will /// receive for 1 unit of the specified currency. #[serde(rename = "multiplier")] - pub multiplier: i64, + pub multiplier: f64, /// ExchangeFeesMillisatoshi is the fees charged (in millisats) by the receiving VASP for this /// transaction. This is separate from the Multiplier. diff --git a/src/uma.rs b/src/uma.rs index 2b22312..8303c66 100644 --- a/src/uma.rs +++ b/src/uma.rs @@ -467,7 +467,8 @@ pub fn get_pay_req_response( invoice_creator: &T, metadata: &str, currency_code: &str, - conversion_rate: i64, + currency_decimals: i32, + conversion_rate: f64, receiver_fees_millisats: i64, receiver_channel_utxos: &[String], receiver_node_pub_key: Option<&str>, @@ -476,7 +477,8 @@ pub fn get_pay_req_response( where T: UmaInvoiceCreator, { - let msats_amount = query.amount * conversion_rate + receiver_fees_millisats; + let msats_amount = + (query.amount as f64 * conversion_rate).round() as i64 + receiver_fees_millisats; let encoded_payer_data = serde_json::to_string(&query.payer_data).map_err(Error::InvalidData)?; let encoded_invoice = invoice_creator @@ -496,6 +498,7 @@ where }, payment_info: PayReqResponsePaymentInfo { currency_code: currency_code.to_string(), + decimals: currency_decimals, multiplier: conversion_rate, exchange_fees_millisatoshi: receiver_fees_millisats, }, diff --git a/src/uma_test.rs b/src/uma_test.rs index 557978d..28962e4 100644 --- a/src/uma_test.rs +++ b/src/uma_test.rs @@ -248,7 +248,8 @@ mod tests { &client, &metadata, "USD", - 34150, + 2, + 23150.0, 100_000, &["abcdef12345".to_owned()], None, diff --git a/src/version.rs b/src/version.rs index 68c6440..9572b41 100644 --- a/src/version.rs +++ b/src/version.rs @@ -1,7 +1,7 @@ use crate::uma; const MAJOR_VERSION: i32 = 0; -const MINOR_VERSION: i32 = 2; +const MINOR_VERSION: i32 = 3; pub fn uma_protocol_version() -> String { format!("{}.{}", MAJOR_VERSION, MINOR_VERSION)