Skip to content

Commit 115f732

Browse files
committed
Add Uniffi bindings for LSPS1 API
1 parent 080570f commit 115f732

File tree

4 files changed

+172
-5
lines changed

4 files changed

+172
-5
lines changed

Diff for: bindings/ldk_node.udl

+70
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ interface Builder {
3939
void set_chain_source_bitcoind_rpc(string rpc_host, u16 rpc_port, string rpc_user, string rpc_password);
4040
void set_gossip_source_p2p();
4141
void set_gossip_source_rgs(string rgs_server_url);
42+
void set_liquidity_source_lsps1(PublicKey node_id, SocketAddress address, string? token);
4243
void set_liquidity_source_lsps2(PublicKey node_id, SocketAddress address, string? token);
4344
void set_storage_dir_path(string storage_dir_path);
4445
void set_network(Network network);
@@ -78,6 +79,7 @@ interface Node {
7879
SpontaneousPayment spontaneous_payment();
7980
OnchainPayment onchain_payment();
8081
UnifiedQrPayment unified_qr_payment();
82+
Lsps1Liquidity lsps1_liquidity();
8183
[Throws=NodeError]
8284
void connect(PublicKey node_id, SocketAddress address, boolean persist);
8385
[Throws=NodeError]
@@ -189,6 +191,13 @@ interface UnifiedQrPayment {
189191
QrPaymentResult send([ByRef]string uri_str);
190192
};
191193

194+
interface Lsps1Liquidity {
195+
[Throws=NodeError]
196+
LSPS1OrderStatus request_channel(u64 lsp_balance_sat, u64 client_balance_sat, u32 channel_expiry_blocks, boolean announce_channel);
197+
[Throws=NodeError]
198+
LSPS1OrderStatus check_order_status(OrderId order_id);
199+
};
200+
192201
[Error]
193202
enum NodeError {
194203
"AlreadyRunning",
@@ -236,6 +245,8 @@ enum NodeError {
236245
"InvalidUri",
237246
"InvalidQuantity",
238247
"InvalidNodeAlias",
248+
"InvalidDateTime",
249+
"InvalidFeeRate",
239250
"DuplicatePayment",
240251
"UnsupportedCurrency",
241252
"InsufficientFunds",
@@ -388,6 +399,59 @@ dictionary CustomTlvRecord {
388399
sequence<u8> value;
389400
};
390401

402+
dictionary LSPS1OrderStatus {
403+
OrderId order_id;
404+
OrderParameters order_params;
405+
PaymentInfo payment_options;
406+
ChannelOrderInfo? channel_state;
407+
};
408+
409+
dictionary OrderParameters {
410+
u64 lsp_balance_sat;
411+
u64 client_balance_sat;
412+
u16 required_channel_confirmations;
413+
u16 funding_confirms_within_blocks;
414+
u32 channel_expiry_blocks;
415+
string? token;
416+
boolean announce_channel;
417+
};
418+
419+
dictionary PaymentInfo {
420+
Bolt11PaymentInfo? bolt11;
421+
OnchainPaymentInfo? onchain;
422+
};
423+
424+
dictionary Bolt11PaymentInfo {
425+
PaymentState state;
426+
DateTime expires_at;
427+
u64 fee_total_sat;
428+
u64 order_total_sat;
429+
Bolt11Invoice invoice;
430+
};
431+
432+
dictionary OnchainPaymentInfo {
433+
PaymentState state;
434+
DateTime expires_at;
435+
u64 fee_total_sat;
436+
u64 order_total_sat;
437+
Address address;
438+
u16? min_onchain_payment_confirmations;
439+
FeeRate min_fee_for_0conf;
440+
Address? refund_onchain_address;
441+
};
442+
443+
dictionary ChannelOrderInfo {
444+
DateTime funded_at;
445+
OutPoint funding_outpoint;
446+
DateTime expires_at;
447+
};
448+
449+
enum PaymentState {
450+
"ExpectPayment",
451+
"Paid",
452+
"Refunded",
453+
};
454+
391455
[Enum]
392456
interface MaxTotalRoutingFeeLimit {
393457
None ();
@@ -640,3 +704,9 @@ typedef string UntrustedString;
640704

641705
[Custom]
642706
typedef string NodeAlias;
707+
708+
[Custom]
709+
typedef string OrderId;
710+
711+
[Custom]
712+
typedef string DateTime;

Diff for: src/error.rs

+6
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ pub enum Error {
106106
InvalidQuantity,
107107
/// The given node alias is invalid.
108108
InvalidNodeAlias,
109+
/// The given date time is invalid.
110+
InvalidDateTime,
111+
/// The given fee rate is invalid.
112+
InvalidFeeRate,
109113
/// A payment with the given hash has already been initiated.
110114
DuplicatePayment,
111115
/// The provided offer was denonminated in an unsupported currency.
@@ -172,6 +176,8 @@ impl fmt::Display for Error {
172176
Self::InvalidUri => write!(f, "The given URI is invalid."),
173177
Self::InvalidQuantity => write!(f, "The given quantity is invalid."),
174178
Self::InvalidNodeAlias => write!(f, "The given node alias is invalid."),
179+
Self::InvalidDateTime => write!(f, "The given date time is invalid."),
180+
Self::InvalidFeeRate => write!(f, "The given fee rate is invalid."),
175181
Self::DuplicatePayment => {
176182
write!(f, "A payment with the given hash has already been initiated.")
177183
},

Diff for: src/liquidity.rs

+64-5
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@ use lightning_liquidity::events::Event;
2121
use lightning_liquidity::lsps0::ser::RequestId;
2222
use lightning_liquidity::lsps1::client::LSPS1ClientConfig;
2323
use lightning_liquidity::lsps1::event::LSPS1ClientEvent;
24-
use lightning_liquidity::lsps1::msgs::{
25-
ChannelInfo, LSPS1Options, OrderId, OrderParameters, PaymentInfo,
26-
};
24+
use lightning_liquidity::lsps1::msgs::{ChannelInfo, LSPS1Options, OrderId, OrderParameters};
2725
use lightning_liquidity::lsps2::client::LSPS2ClientConfig;
2826
use lightning_liquidity::lsps2::event::LSPS2ClientEvent;
2927
use lightning_liquidity::lsps2::msgs::OpeningFeeParams;
@@ -280,7 +278,7 @@ where
280278
let response = LSPS1OrderStatus {
281279
order_id,
282280
order_params: order,
283-
payment_options: payment,
281+
payment_options: payment.into(),
284282
channel_state: channel,
285283
};
286284

@@ -338,7 +336,7 @@ where
338336
let response = LSPS1OrderStatus {
339337
order_id,
340338
order_params: order,
341-
payment_options: payment,
339+
payment_options: payment.into(),
342340
channel_state: channel,
343341
};
344342

@@ -885,6 +883,67 @@ pub struct LSPS1OrderStatus {
885883
pub channel_state: Option<ChannelInfo>,
886884
}
887885

886+
#[cfg(not(feature = "uniffi"))]
887+
type PaymentInfo = lightning_liquidity::lsps1::msgs::PaymentInfo;
888+
889+
/// Details regarding how to pay for an order.
890+
#[cfg(feature = "uniffi")]
891+
#[derive(Clone, Debug, PartialEq, Eq)]
892+
pub struct PaymentInfo {
893+
/// A Lightning payment using BOLT 11.
894+
pub bolt11: Option<lightning_liquidity::lsps1::msgs::Bolt11PaymentInfo>,
895+
/// An onchain payment.
896+
pub onchain: Option<OnchainPaymentInfo>,
897+
}
898+
899+
#[cfg(feature = "uniffi")]
900+
impl From<lightning_liquidity::lsps1::msgs::PaymentInfo> for PaymentInfo {
901+
fn from(value: lightning_liquidity::lsps1::msgs::PaymentInfo) -> Self {
902+
PaymentInfo { bolt11: value.bolt11, onchain: value.onchain.map(|o| o.into()) }
903+
}
904+
}
905+
906+
/// An onchain payment.
907+
#[cfg(feature = "uniffi")]
908+
#[derive(Clone, Debug, PartialEq, Eq)]
909+
pub struct OnchainPaymentInfo {
910+
/// Indicates the current state of the payment.
911+
pub state: lightning_liquidity::lsps1::msgs::PaymentState,
912+
/// The datetime when the payment option expires.
913+
pub expires_at: chrono::DateTime<chrono::Utc>,
914+
/// The total fee the LSP will charge to open this channel in satoshi.
915+
pub fee_total_sat: u64,
916+
/// The amount the client needs to pay to have the requested channel openend.
917+
pub order_total_sat: u64,
918+
/// An on-chain address the client can send [`Self::order_total_sat`] to to have the channel
919+
/// opened.
920+
pub address: bitcoin::Address,
921+
/// The minimum number of block confirmations that are required for the on-chain payment to be
922+
/// considered confirmed.
923+
pub min_onchain_payment_confirmations: Option<u16>,
924+
/// The minimum fee rate for the on-chain payment in case the client wants the payment to be
925+
/// confirmed without a confirmation.
926+
pub min_fee_for_0conf: Arc<bitcoin::FeeRate>,
927+
/// The address where the LSP will send the funds if the order fails.
928+
pub refund_onchain_address: Option<bitcoin::Address>,
929+
}
930+
931+
#[cfg(feature = "uniffi")]
932+
impl From<lightning_liquidity::lsps1::msgs::OnchainPaymentInfo> for OnchainPaymentInfo {
933+
fn from(value: lightning_liquidity::lsps1::msgs::OnchainPaymentInfo) -> Self {
934+
Self {
935+
state: value.state,
936+
expires_at: value.expires_at,
937+
fee_total_sat: value.fee_total_sat,
938+
order_total_sat: value.order_total_sat,
939+
address: value.address,
940+
min_onchain_payment_confirmations: value.min_onchain_payment_confirmations,
941+
min_fee_for_0conf: Arc::new(value.min_fee_for_0conf),
942+
refund_onchain_address: value.refund_onchain_address,
943+
}
944+
}
945+
}
946+
888947
#[derive(Debug, Clone)]
889948
pub(crate) struct LSPS2FeeResponse {
890949
opening_fee_params_menu: Vec<OpeningFeeParams>,

Diff for: src/uniffi_types.rs

+32
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub use crate::config::{
1414
default_config, AnchorChannelsConfig, EsploraSyncConfig, MaxDustHTLCExposure,
1515
};
1616
pub use crate::graph::{ChannelInfo, ChannelUpdateInfo, NodeAnnouncementInfo, NodeInfo};
17+
pub use crate::liquidity::{LSPS1OrderStatus, OnchainPaymentInfo, PaymentInfo};
1718
pub use crate::payment::store::{LSPFeeLimits, PaymentDirection, PaymentKind, PaymentStatus};
1819
pub use crate::payment::{MaxTotalRoutingFeeLimit, QrPaymentResult, SendingParameters};
1920

@@ -30,12 +31,19 @@ pub use lightning_types::payment::{PaymentHash, PaymentPreimage, PaymentSecret};
3031

3132
pub use lightning_invoice::{Bolt11Invoice, Description};
3233

34+
pub use lightning_liquidity::lsps1::msgs::ChannelInfo as ChannelOrderInfo;
35+
pub use lightning_liquidity::lsps1::msgs::{
36+
Bolt11PaymentInfo, OrderId, OrderParameters, PaymentState,
37+
};
38+
3339
pub use bitcoin::{Address, BlockHash, FeeRate, Network, OutPoint, Txid};
3440

3541
pub use bip39::Mnemonic;
3642

3743
pub use vss_client::headers::{VssHeaderProvider, VssHeaderProviderError};
3844

45+
pub type DateTime = chrono::DateTime<chrono::Utc>;
46+
3947
use crate::UniffiCustomTypeConverter;
4048

4149
use crate::builder::sanitize_alias;
@@ -393,6 +401,30 @@ impl From<lightning_invoice::Bolt11InvoiceDescription> for Bolt11InvoiceDescript
393401
}
394402
}
395403

404+
impl UniffiCustomTypeConverter for OrderId {
405+
type Builtin = String;
406+
407+
fn into_custom(val: Self::Builtin) -> uniffi::Result<Self> {
408+
Ok(Self(val))
409+
}
410+
411+
fn from_custom(obj: Self) -> Self::Builtin {
412+
obj.0
413+
}
414+
}
415+
416+
impl UniffiCustomTypeConverter for DateTime {
417+
type Builtin = String;
418+
419+
fn into_custom(val: Self::Builtin) -> uniffi::Result<Self> {
420+
Ok(DateTime::from_str(&val).map_err(|_| Error::InvalidDateTime)?)
421+
}
422+
423+
fn from_custom(obj: Self) -> Self::Builtin {
424+
obj.to_rfc3339()
425+
}
426+
}
427+
396428
#[cfg(test)]
397429
mod tests {
398430
use super::*;

0 commit comments

Comments
 (0)