From 45a1a737838b7f4899d92b196b0cb57cd978c025 Mon Sep 17 00:00:00 2001 From: Enigbe Date: Wed, 30 Jul 2025 20:53:16 +0100 Subject: [PATCH 1/2] prefactor: rename maybe_try_convert_enum to maybe_try_from --- src/ffi/mod.rs | 4 ++-- src/payment/bolt11.rs | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ffi/mod.rs b/src/ffi/mod.rs index 32464d044..b10ee836c 100644 --- a/src/ffi/mod.rs +++ b/src/ffi/mod.rs @@ -19,7 +19,7 @@ where } #[cfg(feature = "uniffi")] -pub fn maybe_try_convert_enum(wrapped_type: &T) -> Result +pub fn maybe_try_from(wrapped_type: &T) -> Result where for<'a> R: TryFrom<&'a T, Error = crate::error::Error>, { @@ -37,7 +37,7 @@ pub fn maybe_deref(value: &T) -> &T { } #[cfg(not(feature = "uniffi"))] -pub fn maybe_try_convert_enum(value: &T) -> Result<&T, crate::error::Error> { +pub fn maybe_try_from(value: &T) -> Result<&T, crate::error::Error> { Ok(value) } diff --git a/src/payment/bolt11.rs b/src/payment/bolt11.rs index 817a428bd..97fcd6273 100644 --- a/src/payment/bolt11.rs +++ b/src/payment/bolt11.rs @@ -13,7 +13,7 @@ use crate::config::{Config, LDK_PAYMENT_RETRY_TIMEOUT}; use crate::connection::ConnectionManager; use crate::data_store::DataStoreUpdateResult; use crate::error::Error; -use crate::ffi::{maybe_deref, maybe_try_convert_enum, maybe_wrap}; +use crate::ffi::{maybe_deref, maybe_try_from, maybe_wrap}; use crate::liquidity::LiquiditySource; use crate::logger::{log_error, log_info, LdkLogger, Logger}; use crate::payment::store::{ @@ -436,7 +436,7 @@ impl Bolt11Payment { pub fn receive( &self, amount_msat: u64, description: &Bolt11InvoiceDescription, expiry_secs: u32, ) -> Result { - let description = maybe_try_convert_enum(description)?; + let description = maybe_try_from(description)?; let invoice = self.receive_inner(Some(amount_msat), &description, expiry_secs, None)?; Ok(maybe_wrap(invoice)) } @@ -459,7 +459,7 @@ impl Bolt11Payment { &self, amount_msat: u64, description: &Bolt11InvoiceDescription, expiry_secs: u32, payment_hash: PaymentHash, ) -> Result { - let description = maybe_try_convert_enum(description)?; + let description = maybe_try_from(description)?; let invoice = self.receive_inner(Some(amount_msat), &description, expiry_secs, Some(payment_hash))?; Ok(maybe_wrap(invoice)) @@ -472,7 +472,7 @@ impl Bolt11Payment { pub fn receive_variable_amount( &self, description: &Bolt11InvoiceDescription, expiry_secs: u32, ) -> Result { - let description = maybe_try_convert_enum(description)?; + let description = maybe_try_from(description)?; let invoice = self.receive_inner(None, &description, expiry_secs, None)?; Ok(maybe_wrap(invoice)) } @@ -494,7 +494,7 @@ impl Bolt11Payment { pub fn receive_variable_amount_for_hash( &self, description: &Bolt11InvoiceDescription, expiry_secs: u32, payment_hash: PaymentHash, ) -> Result { - let description = maybe_try_convert_enum(description)?; + let description = maybe_try_from(description)?; let invoice = self.receive_inner(None, &description, expiry_secs, Some(payment_hash))?; Ok(maybe_wrap(invoice)) } @@ -571,7 +571,7 @@ impl Bolt11Payment { &self, amount_msat: u64, description: &Bolt11InvoiceDescription, expiry_secs: u32, max_total_lsp_fee_limit_msat: Option, ) -> Result { - let description = maybe_try_convert_enum(description)?; + let description = maybe_try_from(description)?; let invoice = self.receive_via_jit_channel_inner( Some(amount_msat), &description, @@ -597,7 +597,7 @@ impl Bolt11Payment { &self, description: &Bolt11InvoiceDescription, expiry_secs: u32, max_proportional_lsp_fee_limit_ppm_msat: Option, ) -> Result { - let description = maybe_try_convert_enum(description)?; + let description = maybe_try_from(description)?; let invoice = self.receive_via_jit_channel_inner( None, &description, From fbb2e9a7f49a484f7570a74d681bf54ee92f1af4 Mon Sep 17 00:00:00 2001 From: Enigbe Date: Wed, 30 Jul 2025 23:59:05 +0100 Subject: [PATCH 2/2] feat(wip): uniffi wrapper for payment preimage In a bid to create a uniffi wrapper for PaymentPreimage, we also create bindings-specific variants for the ffg types: LightningBalance, PaymentKind, and Event, all of which have fields that hold object/interface instances - PaymentPreimage, ConfirmationStatus and ClosureReason. We implement type conversion for the types created. Unfortunately the build does not compile. According to the uniffi docs: "When you want to ... store object instances as fields in records, the underlying Rust code will need to work with Arc directly, to ensure that the code behaves in the way that UniFFI expects." Arc-ing the fields that hold PaymentPreimage, ConfirmationStatus, & ClosureReason is not sufficient to circumvent the error associated with objects not being supported in enum variants. --- bindings/ldk_node.udl | 8 +- src/ffi/types.rs | 658 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 651 insertions(+), 15 deletions(-) diff --git a/bindings/ldk_node.udl b/bindings/ldk_node.udl index 3c240b43c..ed9fbf5bc 100644 --- a/bindings/ldk_node.udl +++ b/bindings/ldk_node.udl @@ -803,6 +803,11 @@ interface Bolt12Invoice { sequence encode(); }; +interface PaymentPreimage { + [Throws=NodeError, Name=from_str] + constructor([ByRef] string preimage_str); +}; + [Custom] typedef string Txid; @@ -830,9 +835,6 @@ typedef string PaymentId; [Custom] typedef string PaymentHash; -[Custom] -typedef string PaymentPreimage; - [Custom] typedef string PaymentSecret; diff --git a/src/ffi/types.rs b/src/ffi/types.rs index 984e4da8f..3a3c51907 100644 --- a/src/ffi/types.rs +++ b/src/ffi/types.rs @@ -10,15 +10,18 @@ // // Make sure to add any re-exported items that need to be used in uniffi below. +pub use crate::balance::LightningBalance as NodeLightningBalance; pub use crate::config::{ default_config, AnchorChannelsConfig, BackgroundSyncConfig, ElectrumSyncConfig, EsploraSyncConfig, MaxDustHTLCExposure, }; +pub use crate::event::Event as NodeEvent; pub use crate::graph::{ChannelInfo, ChannelUpdateInfo, NodeAnnouncementInfo, NodeInfo}; pub use crate::liquidity::{LSPS1OrderStatus, LSPS2ServiceConfig, OnchainPaymentInfo, PaymentInfo}; pub use crate::logger::{LogLevel, LogRecord, LogWriter}; pub use crate::payment::store::{ - ConfirmationStatus, LSPFeeLimits, PaymentDirection, PaymentKind, PaymentStatus, + ConfirmationStatus, LSPFeeLimits, PaymentDirection, PaymentKind as NodePaymentKind, + PaymentStatus, }; pub use crate::payment::{MaxTotalRoutingFeeLimit, QrPaymentResult, SendingParameters}; @@ -29,7 +32,9 @@ pub use lightning::offers::offer::OfferId; pub use lightning::routing::gossip::{NodeAlias, NodeId, RoutingFees}; pub use lightning::util::string::UntrustedString; -pub use lightning_types::payment::{PaymentHash, PaymentPreimage, PaymentSecret}; +pub use lightning_types::payment::{ + PaymentHash, PaymentPreimage as LdkPaymentPreimage, PaymentSecret, +}; pub use lightning_invoice::{Description, SignedRawBolt11Invoice}; @@ -665,21 +670,650 @@ impl UniffiCustomTypeConverter for PaymentHash { } } -impl UniffiCustomTypeConverter for PaymentPreimage { - type Builtin = String; +/// The payment preimage is the "secret key" which is used to claim the funds of an HTLC on-chain +/// or in a lightning channel. +#[derive(Hash, Copy, Clone, PartialEq, Eq, Ord, PartialOrd)] +pub struct PaymentPreimage { + pub(crate) inner: LdkPaymentPreimage, +} - fn into_custom(val: Self::Builtin) -> uniffi::Result { - if let Some(bytes_vec) = hex_utils::to_vec(&val) { - let bytes_res = bytes_vec.try_into(); - if let Ok(bytes) = bytes_res { - return Ok(PaymentPreimage(bytes)); +impl PaymentPreimage { + pub fn from_str(preimage_str: &str) -> Result { + preimage_str.parse() + } +} + +impl FromStr for PaymentPreimage { + type Err = Error; + + fn from_str(preimage_str: &str) -> Result { + if let Some(bytes) = hex_utils::to_vec(preimage_str) { + if let Ok(array) = bytes.try_into() { + return Ok(Self::from(LdkPaymentPreimage(array))); } } - Err(Error::InvalidPaymentPreimage.into()) + + Err(Error::InvalidPaymentPreimage) } +} - fn from_custom(obj: Self) -> Self::Builtin { - hex_utils::to_string(&obj.0) +impl From for PaymentPreimage { + fn from(preimage: LdkPaymentPreimage) -> Self { + PaymentPreimage { inner: preimage } + } +} + +impl std::fmt::Display for PaymentPreimage { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.inner) + } +} + +/// Represents the kind of a payment. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum PaymentKind { + Onchain { + txid: Txid, + status: Arc, + }, + Bolt11 { + hash: PaymentHash, + preimage: Arc>, + secret: Option, + }, + Bolt11Jit { + hash: PaymentHash, + preimage: Arc>, + secret: Option, + counterparty_skimmed_fee_msat: Option, + lsp_fee_limits: LSPFeeLimits, + }, + Bolt12Offer { + hash: Option, + preimage: Arc>, + secret: Option, + offer_id: OfferId, + payer_note: Option, + quantity: Option, + }, + Bolt12Refund { + hash: Option, + preimage: Arc>, + secret: Option, + payer_note: Option, + quantity: Option, + }, + Spontaneous { + hash: PaymentHash, + preimage: Arc>, + }, +} + +impl From for PaymentKind { + fn from(payment_kind: NodePaymentKind) -> Self { + match payment_kind { + NodePaymentKind::Onchain { txid, status } => { + PaymentKind::Onchain { txid, status: Arc::new(status) } + }, + NodePaymentKind::Bolt11 { hash, preimage, secret } => { + PaymentKind::Bolt11 { hash, preimage: Arc::new(preimage), secret } + }, + NodePaymentKind::Bolt11Jit { + hash, + preimage, + secret, + counterparty_skimmed_fee_msat, + lsp_fee_limits, + } => PaymentKind::Bolt11Jit { + hash, + preimage: Arc::new(preimage), + secret, + counterparty_skimmed_fee_msat, + lsp_fee_limits, + }, + NodePaymentKind::Bolt12Offer { + hash, + preimage, + secret, + offer_id, + payer_note, + quantity, + } => PaymentKind::Bolt12Offer { + hash, + preimage: Arc::new(preimage), + secret, + offer_id, + payer_note, + quantity, + }, + NodePaymentKind::Bolt12Refund { hash, preimage, secret, payer_note, quantity } => { + PaymentKind::Bolt12Refund { + hash, + preimage: Arc::new(preimage), + secret, + payer_note, + quantity, + } + }, + NodePaymentKind::Spontaneous { hash, preimage } => { + PaymentKind::Spontaneous { hash, preimage: Arc::new(preimage) } + }, + } + } +} + +impl From for NodePaymentKind { + fn from(kind: PaymentKind) -> Self { + match kind { + PaymentKind::Onchain { txid, status } => { + NodePaymentKind::Onchain { txid, status: *status } + }, + PaymentKind::Bolt11 { hash, preimage, secret } => { + NodePaymentKind::Bolt11 { hash, preimage: *preimage, secret } + }, + PaymentKind::Bolt11Jit { + hash, + preimage, + secret, + counterparty_skimmed_fee_msat, + lsp_fee_limits, + } => NodePaymentKind::Bolt11Jit { + hash, + preimage: *preimage, + secret, + counterparty_skimmed_fee_msat, + lsp_fee_limits, + }, + PaymentKind::Bolt12Offer { hash, preimage, secret, offer_id, payer_note, quantity } => { + NodePaymentKind::Bolt12Offer { + hash, + preimage: *preimage, + secret, + offer_id, + payer_note, + quantity, + } + }, + PaymentKind::Bolt12Refund { hash, preimage, secret, payer_note, quantity } => { + NodePaymentKind::Bolt12Refund { + hash, + preimage: *preimage, + secret, + payer_note, + quantity, + } + }, + PaymentKind::Spontaneous { hash, preimage } => { + NodePaymentKind::Spontaneous { hash, preimage: *preimage } + }, + } + } +} + +/// Details about the status of a known Lightning balance. +#[derive(Debug, Clone)] +pub enum LightningBalance { + ClaimableOnChannelClose { + channel_id: ChannelId, + counterparty_node_id: PublicKey, + amount_satoshis: u64, + transaction_fee_satoshis: u64, + outbound_payment_htlc_rounded_msat: u64, + outbound_forwarded_htlc_rounded_msat: u64, + inbound_claiming_htlc_rounded_msat: u64, + inbound_htlc_rounded_msat: u64, + }, + ClaimableAwaitingConfirmations { + channel_id: ChannelId, + counterparty_node_id: PublicKey, + amount_satoshis: u64, + confirmation_height: u32, + source: BalanceSource, + }, + ContentiousClaimable { + channel_id: ChannelId, + counterparty_node_id: PublicKey, + amount_satoshis: u64, + timeout_height: u32, + payment_hash: PaymentHash, + payment_preimage: Arc, + }, + MaybeTimeoutClaimableHTLC { + channel_id: ChannelId, + counterparty_node_id: PublicKey, + amount_satoshis: u64, + claimable_height: u32, + payment_hash: PaymentHash, + outbound_payment: bool, + }, + MaybePreimageClaimableHTLC { + channel_id: ChannelId, + counterparty_node_id: PublicKey, + amount_satoshis: u64, + expiry_height: u32, + payment_hash: PaymentHash, + }, + CounterpartyRevokedOutputClaimable { + channel_id: ChannelId, + counterparty_node_id: PublicKey, + amount_satoshis: u64, + }, +} + +impl From for LightningBalance { + fn from(balance: NodeLightningBalance) -> Self { + match balance { + NodeLightningBalance::ClaimableOnChannelClose { + channel_id, + counterparty_node_id, + amount_satoshis, + transaction_fee_satoshis, + outbound_payment_htlc_rounded_msat, + outbound_forwarded_htlc_rounded_msat, + inbound_claiming_htlc_rounded_msat, + inbound_htlc_rounded_msat, + } => LightningBalance::ClaimableOnChannelClose { + channel_id, + counterparty_node_id, + amount_satoshis, + transaction_fee_satoshis, + outbound_payment_htlc_rounded_msat, + outbound_forwarded_htlc_rounded_msat, + inbound_claiming_htlc_rounded_msat, + inbound_htlc_rounded_msat, + }, + NodeLightningBalance::ClaimableAwaitingConfirmations { + channel_id, + counterparty_node_id, + amount_satoshis, + confirmation_height, + source, + } => LightningBalance::ClaimableAwaitingConfirmations { + channel_id, + counterparty_node_id, + amount_satoshis, + confirmation_height, + source, + }, + NodeLightningBalance::ContentiousClaimable { + channel_id, + counterparty_node_id, + amount_satoshis, + timeout_height, + payment_hash, + payment_preimage, + } => LightningBalance::ContentiousClaimable { + channel_id, + counterparty_node_id, + amount_satoshis, + timeout_height, + payment_hash, + payment_preimage: Arc::new(payment_preimage), + }, + NodeLightningBalance::MaybeTimeoutClaimableHTLC { + channel_id, + counterparty_node_id, + amount_satoshis, + claimable_height, + payment_hash, + outbound_payment, + } => LightningBalance::MaybeTimeoutClaimableHTLC { + channel_id, + counterparty_node_id, + amount_satoshis, + claimable_height, + payment_hash, + outbound_payment, + }, + NodeLightningBalance::MaybePreimageClaimableHTLC { + channel_id, + counterparty_node_id, + amount_satoshis, + expiry_height, + payment_hash, + } => LightningBalance::MaybePreimageClaimableHTLC { + channel_id, + counterparty_node_id, + amount_satoshis, + expiry_height, + payment_hash, + }, + NodeLightningBalance::CounterpartyRevokedOutputClaimable { + channel_id, + counterparty_node_id, + amount_satoshis, + } => LightningBalance::CounterpartyRevokedOutputClaimable { + channel_id, + counterparty_node_id, + amount_satoshis, + }, + } + } +} + +impl From for NodeLightningBalance { + fn from(balance: LightningBalance) -> Self { + match balance { + LightningBalance::ClaimableOnChannelClose { + channel_id, + counterparty_node_id, + amount_satoshis, + transaction_fee_satoshis, + outbound_payment_htlc_rounded_msat, + outbound_forwarded_htlc_rounded_msat, + inbound_claiming_htlc_rounded_msat, + inbound_htlc_rounded_msat, + } => NodeLightningBalance::ClaimableOnChannelClose { + channel_id, + counterparty_node_id, + amount_satoshis, + transaction_fee_satoshis, + outbound_payment_htlc_rounded_msat, + outbound_forwarded_htlc_rounded_msat, + inbound_claiming_htlc_rounded_msat, + inbound_htlc_rounded_msat, + }, + LightningBalance::ClaimableAwaitingConfirmations { + channel_id, + counterparty_node_id, + amount_satoshis, + confirmation_height, + source, + } => NodeLightningBalance::ClaimableAwaitingConfirmations { + channel_id, + counterparty_node_id, + amount_satoshis, + confirmation_height, + source, + }, + LightningBalance::ContentiousClaimable { + channel_id, + counterparty_node_id, + amount_satoshis, + timeout_height, + payment_hash, + payment_preimage, + } => NodeLightningBalance::ContentiousClaimable { + channel_id, + counterparty_node_id, + amount_satoshis, + timeout_height, + payment_hash, + payment_preimage: *payment_preimage, + }, + LightningBalance::MaybeTimeoutClaimableHTLC { + channel_id, + counterparty_node_id, + amount_satoshis, + claimable_height, + payment_hash, + outbound_payment, + } => NodeLightningBalance::MaybeTimeoutClaimableHTLC { + channel_id, + counterparty_node_id, + amount_satoshis, + claimable_height, + payment_hash, + outbound_payment, + }, + LightningBalance::MaybePreimageClaimableHTLC { + channel_id, + counterparty_node_id, + amount_satoshis, + expiry_height, + payment_hash, + } => NodeLightningBalance::MaybePreimageClaimableHTLC { + channel_id, + counterparty_node_id, + amount_satoshis, + expiry_height, + payment_hash, + }, + LightningBalance::CounterpartyRevokedOutputClaimable { + channel_id, + counterparty_node_id, + amount_satoshis, + } => NodeLightningBalance::CounterpartyRevokedOutputClaimable { + channel_id, + counterparty_node_id, + amount_satoshis, + }, + } + } +} + +/// An event emitted by [`Node`], which should be handled by the user. +/// +/// [`Node`]: [`crate::Node`] +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Event { + PaymentSuccessful { + payment_id: Option, + payment_hash: PaymentHash, + payment_preimage: Arc>, + fee_paid_msat: Option, + }, + PaymentFailed { + payment_id: Option, + payment_hash: Option, + reason: Option, + }, + PaymentReceived { + payment_id: Option, + payment_hash: PaymentHash, + amount_msat: u64, + custom_records: Vec, + }, + PaymentForwarded { + prev_channel_id: ChannelId, + next_channel_id: ChannelId, + prev_user_channel_id: Option, + next_user_channel_id: Option, + prev_node_id: Option, + next_node_id: Option, + total_fee_earned_msat: Option, + skimmed_fee_msat: Option, + claim_from_onchain_tx: bool, + outbound_amount_forwarded_msat: Option, + }, + PaymentClaimable { + payment_id: PaymentId, + payment_hash: PaymentHash, + claimable_amount_msat: u64, + claim_deadline: Option, + custom_records: Vec, + }, + ChannelPending { + channel_id: ChannelId, + user_channel_id: UserChannelId, + former_temporary_channel_id: ChannelId, + counterparty_node_id: PublicKey, + funding_txo: OutPoint, + }, + ChannelReady { + channel_id: ChannelId, + user_channel_id: UserChannelId, + counterparty_node_id: Option, + }, + ChannelClosed { + channel_id: ChannelId, + user_channel_id: UserChannelId, + counterparty_node_id: Option, + reason: Arc>, + }, +} + +impl From for Event { + fn from(event: NodeEvent) -> Self { + match event { + NodeEvent::PaymentSuccessful { + payment_id, + payment_hash, + payment_preimage, + fee_paid_msat, + } => Event::PaymentSuccessful { + payment_id, + payment_hash, + payment_preimage: Arc::new(preimage), + fee_paid_msat, + }, + NodeEvent::PaymentFailed { payment_id, payment_hash, reason } => { + Event::PaymentFailed { payment_id, payment_hash, reason } + }, + NodeEvent::PaymentReceived { + payment_id, + payment_hash, + amount_msat, + custom_records, + } => Event::PaymentReceived { payment_id, payment_hash, amount_msat, custom_records }, + NodeEvent::PaymentForwarded { + prev_channel_id, + next_channel_id, + prev_user_channel_id, + next_user_channel_id, + prev_node_id, + next_node_id, + total_fee_earned_msat, + skimmed_fee_msat, + claim_from_onchain_tx, + outbound_amount_forwarded_msat, + } => Event::PaymentForwarded { + prev_channel_id, + next_channel_id, + prev_user_channel_id, + next_user_channel_id, + prev_node_id, + next_node_id, + total_fee_earned_msat, + skimmed_fee_msat, + claim_from_onchain_tx, + outbound_amount_forwarded_msat, + }, + NodeEvent::PaymentClaimable { + payment_id, + payment_hash, + claimable_amount_msat, + claim_deadline, + custom_records, + } => Event::PaymentClaimable { + payment_id, + payment_hash, + claimable_amount_msat, + claim_deadline, + custom_records, + }, + NodeEvent::ChannelPending { + channel_id, + user_channel_id, + former_temporary_channel_id, + counterparty_node_id, + funding_txo, + } => Event::ChannelPending { + channel_id, + user_channel_id, + former_temporary_channel_id, + counterparty_node_id, + funding_txo, + }, + NodeEvent::ChannelReady { channel_id, user_channel_id, counterparty_node_id } => { + Event::ChannelReady { channel_id, user_channel_id, counterparty_node_id } + }, + NodeEvent::ChannelClosed { + channel_id, + user_channel_id, + counterparty_node_id, + reason, + } => Event::ChannelClosed { + channel_id, + user_channel_id, + counterparty_node_id, + reason: Arc::new(reason), + }, + } + } +} + +impl From for NodeEvent { + fn from(event: Event) -> Self { + match event { + Event::PaymentSuccessful { + payment_id, + payment_hash, + payment_preimage, + fee_paid_msat, + } => NodeEvent::PaymentSuccessful { + payment_id, + payment_hash, + payment_preimage: *payment_preimage, + fee_paid_msat, + }, + Event::PaymentFailed { payment_id, payment_hash, reason } => { + NodeEvent::PaymentFailed { payment_id, payment_hash, reason } + }, + Event::PaymentReceived { payment_id, payment_hash, amount_msat, custom_records } => { + NodeEvent::PaymentReceived { payment_id, payment_hash, amount_msat, custom_records } + }, + Event::PaymentForwarded { + prev_channel_id, + next_channel_id, + prev_user_channel_id, + next_user_channel_id, + prev_node_id, + next_node_id, + total_fee_earned_msat, + skimmed_fee_msat, + claim_from_onchain_tx, + outbound_amount_forwarded_msat, + } => NodeEvent::PaymentForwarded { + prev_channel_id, + next_channel_id, + prev_user_channel_id, + next_user_channel_id, + prev_node_id, + next_node_id, + total_fee_earned_msat, + skimmed_fee_msat, + claim_from_onchain_tx, + outbound_amount_forwarded_msat, + }, + Event::PaymentClaimable { + payment_id, + payment_hash, + claimable_amount_msat, + claim_deadline, + custom_records, + } => NodeEvent::PaymentClaimable { + payment_id, + payment_hash, + claimable_amount_msat, + claim_deadline, + custom_records, + }, + Event::ChannelPending { + channel_id, + user_channel_id, + former_temporary_channel_id, + counterparty_node_id, + funding_txo, + } => NodeEvent::ChannelPending { + channel_id, + user_channel_id, + former_temporary_channel_id, + counterparty_node_id, + funding_txo, + }, + Event::ChannelReady { channel_id, user_channel_id, counterparty_node_id } => { + NodeEvent::ChannelReady { channel_id, user_channel_id, counterparty_node_id } + }, + Event::ChannelClosed { channel_id, user_channel_id, counterparty_node_id, reason } => { + NodeEvent::ChannelClosed { + channel_id, + user_channel_id, + counterparty_node_id, + reason, + } + }, + } } }