diff --git a/libs/Cargo.toml b/libs/Cargo.toml index c27f40f3e..a782c38b2 100644 --- a/libs/Cargo.toml +++ b/libs/Cargo.toml @@ -21,7 +21,6 @@ aes = "0.8" anyhow = { version = "1.0.79", features = ["backtrace"] } base64 = "0.13.0" bitcoin = "=0.29.2" # Same version as used in gl-client -# Pin the reqwest dependency until macOS linker issue is fixed: https://github.com/seanmonstar/reqwest/issues/2006 hex = "0.4" lightning = "=0.0.118" # Same version as used in gl-client lightning-invoice = "=0.26.0" # Same version as used in gl-client @@ -30,6 +29,7 @@ mockito = "1" once_cell = "1" prost = "^0.11" regex = "1.8.1" +# Pin the reqwest dependency until macOS linker issue is fixed: https://github.com/seanmonstar/reqwest/issues/2006 reqwest = { version = "=0.11.20", features = ["json"] } rusqlite = { version = "0.29", features = [ "serde_json", diff --git a/libs/sdk-common/src/input_parser.rs b/libs/sdk-common/src/input_parser.rs index fc8b8d3cb..f595bad13 100644 --- a/libs/sdk-common/src/input_parser.rs +++ b/libs/sdk-common/src/input_parser.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use std::str::FromStr; use ::bip21::Uri; @@ -5,7 +6,6 @@ use anyhow::{anyhow, Result}; use bitcoin::bech32; use bitcoin::bech32::FromBase32; use serde::{Deserialize, Serialize}; -use std::collections::HashMap; use LnUrlRequestData::*; use crate::prelude::*; @@ -418,6 +418,10 @@ pub enum InputType { Bolt11 { invoice: LNInvoice, }, + #[cfg(feature = "liquid")] + Bolt12Offer { + offer: LNOffer, + }, NodeId { node_id: String, }, diff --git a/libs/sdk-common/src/invoice.rs b/libs/sdk-common/src/invoice.rs index fe6b4c390..f7790adb5 100644 --- a/libs/sdk-common/src/invoice.rs +++ b/libs/sdk-common/src/invoice.rs @@ -2,6 +2,7 @@ use std::num::ParseIntError; use std::str::FromStr; use std::time::{SystemTimeError, UNIX_EPOCH}; +use anyhow::anyhow; use bitcoin::secp256k1::{self, PublicKey}; use hex::ToHex; use lightning::routing::gossip::RoutingFees; @@ -101,6 +102,62 @@ fn format_short_channel_id(id: u64) -> String { format!("{block_num}x{tx_num}x{tx_out}") } +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +pub enum Amount { + Bitcoin { + amount_msat: u64, + }, + /// An amount of currency specified using ISO 4712. + Currency { + /// The currency that the amount is denominated in. + iso4217_code: String, + /// The amount in the currency unit adjusted by the ISO 4712 exponent (e.g., USD cents). + fractional_amount: u64, + }, +} + +impl TryFrom for Amount { + type Error = anyhow::Error; + + fn try_from(amount: lightning::offers::offer::Amount) -> Result { + match amount { + lightning::offers::offer::Amount::Bitcoin { amount_msats } => Ok(Amount::Bitcoin { + amount_msat: amount_msats, + }), + lightning::offers::offer::Amount::Currency { + iso4217_code, + amount, + } => Ok(Amount::Currency { + iso4217_code: String::from_utf8(iso4217_code.to_vec()) + .map_err(|_| anyhow!("Expecting a valid ISO 4217 character sequence"))?, + fractional_amount: amount, + }), + } + } +} + +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +pub struct LNOffer { + /// String representation of the Bolt12 offer + pub offer: String, + pub chains: Vec, + /// If set, it represents the minimum amount that an invoice must have to be valid for this offer + pub min_amount: Option, + pub description: Option, + /// Epoch time from which an invoice should no longer be requested. If None, the offer does not expire. + pub absolute_expiry: Option, + pub issuer: Option, + /// The public key used by the recipient to sign invoices. + pub signing_pubkey: Option, + pub paths: Vec, +} + +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +pub struct LnOfferBlindedPath { + /// For each blinded hop, we store the node ID (pubkey as hex). + pub blinded_hops: Vec, +} + /// Wrapper for a BOLT11 LN invoice #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] pub struct LNInvoice {