1717//! - Wallet and channel states are persisted to disk.
1818//! - Gossip is retrieved over the P2P network.
1919
20- #![ deny( missing_docs) ]
2120#![ deny( broken_intra_doc_links) ]
2221#![ deny( private_intra_doc_links) ]
2322#![ allow( bare_trait_objects) ]
@@ -34,7 +33,8 @@ mod peer_store;
3433mod tests;
3534mod wallet;
3635
37- pub use error:: Error ;
36+ pub use error:: Error as NodeError ;
37+ use error:: Error ;
3838pub use event:: Event ;
3939use event:: { EventHandler , EventQueue } ;
4040use peer_store:: { PeerInfo , PeerInfoStorage } ;
@@ -64,7 +64,7 @@ use lightning_transaction_sync::EsploraSyncClient;
6464use lightning_net_tokio:: SocketDescriptor ;
6565
6666use lightning:: routing:: router:: DefaultRouter ;
67- use lightning_invoice:: { payment, Currency , Invoice } ;
67+ use lightning_invoice:: { payment, Currency , Invoice , SignedRawInvoice } ;
6868
6969use bdk:: bitcoin:: secp256k1:: Secp256k1 ;
7070use bdk:: blockchain:: esplora:: EsploraBlockchain ;
@@ -74,10 +74,11 @@ use bdk::template::Bip84;
7474use bitcoin:: hashes:: sha256:: Hash as Sha256 ;
7575use bitcoin:: hashes:: Hash ;
7676use bitcoin:: secp256k1:: PublicKey ;
77- use bitcoin:: BlockHash ;
77+ use bitcoin:: { Address , BlockHash } ;
7878
7979use rand:: Rng ;
8080
81+ use core:: str:: FromStr ;
8182use std:: collections:: HashMap ;
8283use std:: convert:: { TryFrom , TryInto } ;
8384use std:: default:: Default ;
@@ -87,6 +88,8 @@ use std::sync::atomic::{AtomicBool, Ordering};
8788use std:: sync:: { Arc , Mutex , RwLock } ;
8889use std:: time:: { Duration , Instant , SystemTime } ;
8990
91+ uniffi_macros:: include_scaffolding!( "ldk_node" ) ;
92+
9093// The used 'stop gap' parameter used by BDK's wallet sync. This seems to configure the threshold
9194// number of blocks after which BDK stops looking for scripts belonging to the wallet.
9295const BDK_CLIENT_STOP_GAP : usize = 20 ;
@@ -193,8 +196,8 @@ impl Builder {
193196 self
194197 }
195198
196- /// Builds an [`Node`] instance according to the options previously configured.
197- pub fn build ( & self ) -> Node {
199+ /// Builds a [`Node`] instance according to the options previously configured.
200+ pub fn build ( & self ) -> Arc < Node > {
198201 let config = Arc :: new ( self . config . clone ( ) ) ;
199202
200203 let ldk_data_dir = format ! ( "{}/ldk" , & config. storage_dir_path. clone( ) ) ;
@@ -427,7 +430,7 @@ impl Builder {
427430
428431 let running = RwLock :: new ( None ) ;
429432
430- Node {
433+ Arc :: new ( Node {
431434 running,
432435 config,
433436 wallet,
@@ -446,7 +449,7 @@ impl Builder {
446449 inbound_payments,
447450 outbound_payments,
448451 peer_store,
449- }
452+ } )
450453 }
451454}
452455
@@ -488,7 +491,7 @@ impl Node {
488491 /// Starts the necessary background tasks, such as handling events coming from user input,
489492 /// LDK/BDK, and the peer-to-peer network. After this returns, the [`Node`] instance can be
490493 /// controlled via the provided API methods in a thread-safe manner.
491- pub fn start ( & mut self ) -> Result < ( ) , Error > {
494+ pub fn start ( & self ) -> Result < ( ) , Error > {
492495 // Acquire a run lock and hold it until we're setup.
493496 let mut run_lock = self . running . write ( ) . unwrap ( ) ;
494497 if run_lock. is_some ( ) {
@@ -502,7 +505,7 @@ impl Node {
502505 }
503506
504507 /// Disconnects all peers, stops all running background tasks, and shuts down [`Node`].
505- pub fn stop ( & mut self ) -> Result < ( ) , Error > {
508+ pub fn stop ( & self ) -> Result < ( ) , Error > {
506509 let mut run_lock = self . running . write ( ) . unwrap ( ) ;
507510 if run_lock. is_none ( ) {
508511 return Err ( Error :: NotRunning ) ;
@@ -696,15 +699,15 @@ impl Node {
696699 }
697700
698701 /// Retrieve a new on-chain/funding address.
699- pub fn new_funding_address ( & mut self ) -> Result < bitcoin :: Address , Error > {
702+ pub fn new_funding_address ( & self ) -> Result < Address , Error > {
700703 let funding_address = self . wallet . get_new_address ( ) ?;
701704 log_info ! ( self . logger, "Generated new funding address: {}" , funding_address) ;
702705 Ok ( funding_address)
703706 }
704707
705708 #[ cfg( test) ]
706709 /// Retrieve the current on-chain balance.
707- pub fn on_chain_balance ( & mut self ) -> Result < bdk:: Balance , Error > {
710+ pub fn on_chain_balance ( & self ) -> Result < bdk:: Balance , Error > {
708711 self . wallet . get_balance ( )
709712 }
710713
@@ -1100,3 +1103,106 @@ pub(crate) type OnionMessenger = lightning::onion_message::OnionMessenger<
11001103 Arc < FilesystemLogger > ,
11011104 IgnoringMessageHandler ,
11021105> ;
1106+
1107+ impl UniffiCustomTypeConverter for PublicKey {
1108+ type Builtin = String ;
1109+
1110+ fn into_custom ( val : Self :: Builtin ) -> uniffi:: Result < Self > {
1111+ if let Ok ( key) = PublicKey :: from_str ( & val) {
1112+ return Ok ( key) ;
1113+ }
1114+
1115+ Err ( Error :: PublicKeyInvalid . into ( ) )
1116+ }
1117+
1118+ fn from_custom ( obj : Self ) -> Self :: Builtin {
1119+ obj. to_string ( )
1120+ }
1121+ }
1122+
1123+ impl UniffiCustomTypeConverter for Address {
1124+ type Builtin = String ;
1125+
1126+ fn into_custom ( val : Self :: Builtin ) -> uniffi:: Result < Self > {
1127+ if let Ok ( addr) = Address :: from_str ( & val) {
1128+ return Ok ( addr) ;
1129+ }
1130+
1131+ Err ( Error :: AddressInvalid . into ( ) )
1132+ }
1133+
1134+ fn from_custom ( obj : Self ) -> Self :: Builtin {
1135+ obj. to_string ( )
1136+ }
1137+ }
1138+
1139+ impl UniffiCustomTypeConverter for Invoice {
1140+ type Builtin = String ;
1141+
1142+ fn into_custom ( val : Self :: Builtin ) -> uniffi:: Result < Self > {
1143+ if let Ok ( signed) = val. parse :: < SignedRawInvoice > ( ) {
1144+ if let Ok ( invoice) = Invoice :: from_signed ( signed) {
1145+ return Ok ( invoice) ;
1146+ }
1147+ }
1148+
1149+ Err ( Error :: InvoiceInvalid . into ( ) )
1150+ }
1151+
1152+ fn from_custom ( obj : Self ) -> Self :: Builtin {
1153+ obj. to_string ( )
1154+ }
1155+ }
1156+
1157+ impl UniffiCustomTypeConverter for PaymentHash {
1158+ type Builtin = String ;
1159+
1160+ fn into_custom ( val : Self :: Builtin ) -> uniffi:: Result < Self > {
1161+ if let Ok ( hash) = Sha256 :: from_str ( & val) {
1162+ Ok ( PaymentHash ( hash. into_inner ( ) ) )
1163+ } else {
1164+ Err ( Error :: PaymentHashInvalid . into ( ) )
1165+ }
1166+ }
1167+
1168+ fn from_custom ( obj : Self ) -> Self :: Builtin {
1169+ Sha256 :: from_slice ( & obj. 0 ) . unwrap ( ) . to_string ( )
1170+ }
1171+ }
1172+
1173+ #[ derive( Debug , Clone , PartialEq ) ]
1174+ pub struct ChannelId ( [ u8 ; 32 ] ) ;
1175+
1176+ impl UniffiCustomTypeConverter for ChannelId {
1177+ type Builtin = String ;
1178+
1179+ fn into_custom ( val : Self :: Builtin ) -> uniffi:: Result < Self > {
1180+ if let Some ( hex_vec) = hex_utils:: to_vec ( & val) {
1181+ if hex_vec. len ( ) == 32 {
1182+ let mut channel_id = [ 0u8 ; 32 ] ;
1183+ channel_id. copy_from_slice ( & hex_vec[ ..] ) ;
1184+ return Ok ( Self ( channel_id) ) ;
1185+ }
1186+ }
1187+ Err ( Error :: ChannelIdInvalid . into ( ) )
1188+ }
1189+
1190+ fn from_custom ( obj : Self ) -> Self :: Builtin {
1191+ hex_utils:: to_string ( & obj. 0 )
1192+ }
1193+ }
1194+
1195+ #[ derive( Debug , Clone , PartialEq ) ]
1196+ pub struct UserChannelId ( u128 ) ;
1197+
1198+ impl UniffiCustomTypeConverter for UserChannelId {
1199+ type Builtin = String ;
1200+
1201+ fn into_custom ( val : Self :: Builtin ) -> uniffi:: Result < Self > {
1202+ Ok ( UserChannelId ( u128:: from_str ( & val) . map_err ( |_| Error :: ChannelIdInvalid ) ?) )
1203+ }
1204+
1205+ fn from_custom ( obj : Self ) -> Self :: Builtin {
1206+ obj. 0 . to_string ( )
1207+ }
1208+ }
0 commit comments