@@ -74,117 +74,122 @@ enum GossipSourceConfig {
74
74
/// - Chain data is sourced from the Esplora endpoint `https://blockstream.info/api`
75
75
/// - Gossip data is sourced via the peer-to-peer network
76
76
#[ derive( Debug ) ]
77
- pub struct Builder {
78
- config : RwLock < Config > ,
79
- entropy_source_config : RwLock < Option < EntropySourceConfig > > ,
80
- chain_data_source_config : RwLock < Option < ChainDataSourceConfig > > ,
81
- gossip_source_config : RwLock < Option < GossipSourceConfig > > ,
77
+ pub struct NodeBuilder {
78
+ config : Config ,
79
+ entropy_source_config : Option < EntropySourceConfig > ,
80
+ chain_data_source_config : Option < ChainDataSourceConfig > ,
81
+ gossip_source_config : Option < GossipSourceConfig > ,
82
82
}
83
83
84
- impl Builder {
84
+ impl NodeBuilder {
85
85
/// Creates a new builder instance with the default configuration.
86
86
pub fn new ( ) -> Self {
87
- let config = RwLock :: new ( Config :: default ( ) ) ;
88
- let entropy_source_config = RwLock :: new ( None ) ;
89
- let chain_data_source_config = RwLock :: new ( None ) ;
90
- let gossip_source_config = RwLock :: new ( None ) ;
87
+ let config = Config :: default ( ) ;
88
+ let entropy_source_config = None ;
89
+ let chain_data_source_config = None ;
90
+ let gossip_source_config = None ;
91
91
Self { config, entropy_source_config, chain_data_source_config, gossip_source_config }
92
92
}
93
93
94
94
/// Creates a new builder instance from an [`Config`].
95
95
pub fn from_config ( config : Config ) -> Self {
96
- let config = RwLock :: new ( config) ;
97
- let entropy_source_config = RwLock :: new ( None ) ;
98
- let chain_data_source_config = RwLock :: new ( None ) ;
99
- let gossip_source_config = RwLock :: new ( None ) ;
96
+ let config = config;
97
+ let entropy_source_config = None ;
98
+ let chain_data_source_config = None ;
99
+ let gossip_source_config = None ;
100
100
Self { config, entropy_source_config, chain_data_source_config, gossip_source_config }
101
101
}
102
102
103
103
/// Configures the [`Node`] instance to source its wallet entropy from a seed file on disk.
104
104
///
105
105
/// If the given file does not exist a new random seed file will be generated and
106
106
/// stored at the given location.
107
- pub fn set_entropy_seed_path ( & self , seed_path : String ) {
108
- * self . entropy_source_config . write ( ) . unwrap ( ) =
109
- Some ( EntropySourceConfig :: SeedFile ( seed_path ) ) ;
107
+ pub fn set_entropy_seed_path ( & mut self , seed_path : String ) -> & mut Self {
108
+ self . entropy_source_config = Some ( EntropySourceConfig :: SeedFile ( seed_path ) ) ;
109
+ self
110
110
}
111
111
112
112
/// Configures the [`Node`] instance to source its wallet entropy from the given 64 seed bytes.
113
113
///
114
114
/// **Note:** Panics if the length of the given `seed_bytes` differs from 64.
115
- pub fn set_entropy_seed_bytes ( & self , seed_bytes : Vec < u8 > ) {
115
+ pub fn set_entropy_seed_bytes ( & mut self , seed_bytes : Vec < u8 > ) -> & mut Self {
116
116
if seed_bytes. len ( ) != WALLET_KEYS_SEED_LEN {
117
117
panic ! ( "Failed to set seed due to invalid length." ) ;
118
118
}
119
119
let mut bytes = [ 0u8 ; WALLET_KEYS_SEED_LEN ] ;
120
120
bytes. copy_from_slice ( & seed_bytes) ;
121
- * self . entropy_source_config . write ( ) . unwrap ( ) = Some ( EntropySourceConfig :: SeedBytes ( bytes) ) ;
121
+ self . entropy_source_config = Some ( EntropySourceConfig :: SeedBytes ( bytes) ) ;
122
+ self
122
123
}
123
124
124
125
/// Configures the [`Node`] instance to source its wallet entropy from a [BIP 39] mnemonic.
125
126
///
126
127
/// [BIP 39]: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
127
- pub fn set_entropy_bip39_mnemonic ( & self , mnemonic : Mnemonic , passphrase : Option < String > ) {
128
- * self . entropy_source_config . write ( ) . unwrap ( ) =
128
+ pub fn set_entropy_bip39_mnemonic (
129
+ & mut self , mnemonic : Mnemonic , passphrase : Option < String > ,
130
+ ) -> & mut Self {
131
+ self . entropy_source_config =
129
132
Some ( EntropySourceConfig :: Bip39Mnemonic { mnemonic, passphrase } ) ;
133
+ self
130
134
}
131
135
132
136
/// Configures the [`Node`] instance to source its chain data from the given Esplora server.
133
- pub fn set_esplora_server ( & self , esplora_server_url : String ) {
134
- * self . chain_data_source_config . write ( ) . unwrap ( ) =
135
- Some ( ChainDataSourceConfig :: Esplora ( esplora_server_url ) ) ;
137
+ pub fn set_esplora_server ( & mut self , esplora_server_url : String ) -> & mut Self {
138
+ self . chain_data_source_config = Some ( ChainDataSourceConfig :: Esplora ( esplora_server_url ) ) ;
139
+ self
136
140
}
137
141
138
142
/// Configures the [`Node`] instance to source its gossip data from the Lightning peer-to-peer
139
143
/// network.
140
- pub fn set_gossip_source_p2p ( & self ) {
141
- * self . gossip_source_config . write ( ) . unwrap ( ) = Some ( GossipSourceConfig :: P2PNetwork ) ;
144
+ pub fn set_gossip_source_p2p ( & mut self ) -> & mut Self {
145
+ self . gossip_source_config = Some ( GossipSourceConfig :: P2PNetwork ) ;
146
+ self
142
147
}
143
148
144
149
/// Configures the [`Node`] instance to source its gossip data from the given RapidGossipSync
145
150
/// server.
146
- pub fn set_gossip_source_rgs ( & self , rgs_server_url : String ) {
147
- * self . gossip_source_config . write ( ) . unwrap ( ) =
148
- Some ( GossipSourceConfig :: RapidGossipSync ( rgs_server_url ) ) ;
151
+ pub fn set_gossip_source_rgs ( & mut self , rgs_server_url : String ) -> & mut Self {
152
+ self . gossip_source_config = Some ( GossipSourceConfig :: RapidGossipSync ( rgs_server_url ) ) ;
153
+ self
149
154
}
150
155
151
156
/// Sets the used storage directory path.
152
- pub fn set_storage_dir_path ( & self , storage_dir_path : String ) {
153
- let mut config = self . config . write ( ) . unwrap ( ) ;
154
- config . storage_dir_path = storage_dir_path ;
157
+ pub fn set_storage_dir_path ( & mut self , storage_dir_path : String ) -> & mut Self {
158
+ self . config . storage_dir_path = storage_dir_path ;
159
+ self
155
160
}
156
161
157
162
/// Sets the Bitcoin network used.
158
- pub fn set_network ( & self , network : Network ) {
159
- let mut config = self . config . write ( ) . unwrap ( ) ;
160
- config . network = network ;
163
+ pub fn set_network ( & mut self , network : Network ) -> & mut Self {
164
+ self . config . network = network ;
165
+ self
161
166
}
162
167
163
168
/// Sets the IP address and TCP port on which [`Node`] will listen for incoming network connections.
164
- pub fn set_listening_address ( & self , listening_address : NetAddress ) {
165
- let mut config = self . config . write ( ) . unwrap ( ) ;
166
- config . listening_address = Some ( listening_address ) ;
169
+ pub fn set_listening_address ( & mut self , listening_address : NetAddress ) -> & mut Self {
170
+ self . config . listening_address = Some ( listening_address ) ;
171
+ self
167
172
}
168
173
169
174
/// Sets the level at which [`Node`] will log messages.
170
- pub fn set_log_level ( & self , level : LogLevel ) {
171
- let mut config = self . config . write ( ) . unwrap ( ) ;
172
- config . log_level = level ;
175
+ pub fn set_log_level ( & mut self , level : LogLevel ) -> & mut Self {
176
+ self . config . log_level = level ;
177
+ self
173
178
}
174
179
175
180
/// Builds a [`Node`] instance with a [`SqliteStore`] backend and according to the options
176
181
/// previously configured.
177
- pub fn build ( & self ) -> Arc < Node < SqliteStore > > {
178
- let storage_dir_path = self . config . read ( ) . unwrap ( ) . storage_dir_path . clone ( ) ;
182
+ pub fn build ( & self ) -> Node < SqliteStore > {
183
+ let storage_dir_path = self . config . storage_dir_path . clone ( ) ;
179
184
fs:: create_dir_all ( storage_dir_path. clone ( ) ) . expect ( "Failed to create LDK data directory" ) ;
180
185
let kv_store = Arc :: new ( SqliteStore :: new ( storage_dir_path. into ( ) ) ) ;
181
186
self . build_with_store ( kv_store)
182
187
}
183
188
184
189
/// Builds a [`Node`] instance with a [`FilesystemStore`] backend and according to the options
185
190
/// previously configured.
186
- pub fn build_with_fs_store ( & self ) -> Arc < Node < FilesystemStore > > {
187
- let storage_dir_path = self . config . read ( ) . unwrap ( ) . storage_dir_path . clone ( ) ;
191
+ pub fn build_with_fs_store ( & self ) -> Node < FilesystemStore > {
192
+ let storage_dir_path = self . config . storage_dir_path . clone ( ) ;
188
193
fs:: create_dir_all ( storage_dir_path. clone ( ) ) . expect ( "Failed to create LDK data directory" ) ;
189
194
let kv_store = Arc :: new ( FilesystemStore :: new ( storage_dir_path. into ( ) ) ) ;
190
195
self . build_with_store ( kv_store)
@@ -193,29 +198,132 @@ impl Builder {
193
198
/// Builds a [`Node`] instance according to the options previously configured.
194
199
pub fn build_with_store < K : KVStore + Sync + Send + ' static > (
195
200
& self , kv_store : Arc < K > ,
196
- ) -> Arc < Node < K > > {
197
- let config = Arc :: new ( self . config . read ( ) . unwrap ( ) . clone ( ) ) ;
201
+ ) -> Node < K > {
202
+ let config = Arc :: new ( self . config . clone ( ) ) ;
198
203
199
- let entropy_source_config = self . entropy_source_config . read ( ) . unwrap ( ) ;
200
- let chain_data_source_config = self . chain_data_source_config . read ( ) . unwrap ( ) ;
201
- let gossip_source_config = self . gossip_source_config . read ( ) . unwrap ( ) ;
202
204
let runtime = Arc :: new ( RwLock :: new ( None ) ) ;
203
- Arc :: new ( build_with_store_internal (
205
+ build_with_store_internal (
204
206
config,
205
- entropy_source_config. as_ref ( ) ,
206
- chain_data_source_config. as_ref ( ) ,
207
- gossip_source_config. as_ref ( ) ,
207
+ self . entropy_source_config . as_ref ( ) ,
208
+ self . chain_data_source_config . as_ref ( ) ,
209
+ self . gossip_source_config . as_ref ( ) ,
208
210
kv_store,
209
211
runtime,
210
- ) )
212
+ )
213
+ }
214
+ }
215
+
216
+ /// A builder for an [`Node`] instance, allowing to set some configuration and module choices from
217
+ /// the getgo.
218
+ ///
219
+ /// ### Defaults
220
+ /// - Wallet entropy is sourced from a `keys_seed` file located under [`Config::storage_dir_path`]
221
+ /// - Chain data is sourced from the Esplora endpoint `https://blockstream.info/api`
222
+ /// - Gossip data is sourced via the peer-to-peer network
223
+ #[ derive( Debug ) ]
224
+ #[ cfg( feature = "uniffi" ) ]
225
+ pub struct ArcedNodeBuilder {
226
+ inner : RwLock < NodeBuilder > ,
227
+ }
228
+
229
+ #[ cfg( feature = "uniffi" ) ]
230
+ impl ArcedNodeBuilder {
231
+ /// Creates a new builder instance with the default configuration.
232
+ pub fn new ( ) -> Self {
233
+ let inner = RwLock :: new ( NodeBuilder :: new ( ) ) ;
234
+ Self { inner }
235
+ }
236
+
237
+ /// Creates a new builder instance from an [`Config`].
238
+ pub fn from_config ( config : Config ) -> Self {
239
+ let inner = RwLock :: new ( NodeBuilder :: from_config ( config) ) ;
240
+ Self { inner }
241
+ }
242
+
243
+ /// Configures the [`Node`] instance to source its wallet entropy from a seed file on disk.
244
+ ///
245
+ /// If the given file does not exist a new random seed file will be generated and
246
+ /// stored at the given location.
247
+ pub fn set_entropy_seed_path ( & self , seed_path : String ) {
248
+ self . inner . write ( ) . unwrap ( ) . set_entropy_seed_path ( seed_path) ;
249
+ }
250
+
251
+ /// Configures the [`Node`] instance to source its wallet entropy from the given 64 seed bytes.
252
+ ///
253
+ /// **Note:** Panics if the length of the given `seed_bytes` differs from 64.
254
+ pub fn set_entropy_seed_bytes ( & self , seed_bytes : Vec < u8 > ) {
255
+ self . inner . write ( ) . unwrap ( ) . set_entropy_seed_bytes ( seed_bytes) ;
256
+ }
257
+
258
+ /// Configures the [`Node`] instance to source its wallet entropy from a [BIP 39] mnemonic.
259
+ ///
260
+ /// [BIP 39]: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
261
+ pub fn set_entropy_bip39_mnemonic ( & self , mnemonic : Mnemonic , passphrase : Option < String > ) {
262
+ self . inner . write ( ) . unwrap ( ) . set_entropy_bip39_mnemonic ( mnemonic, passphrase) ;
263
+ }
264
+
265
+ /// Configures the [`Node`] instance to source its chain data from the given Esplora server.
266
+ pub fn set_esplora_server ( & self , esplora_server_url : String ) {
267
+ self . inner . write ( ) . unwrap ( ) . set_esplora_server ( esplora_server_url) ;
268
+ }
269
+
270
+ /// Configures the [`Node`] instance to source its gossip data from the Lightning peer-to-peer
271
+ /// network.
272
+ pub fn set_gossip_source_p2p ( & self ) {
273
+ self . inner . write ( ) . unwrap ( ) . set_gossip_source_p2p ( ) ;
274
+ }
275
+
276
+ /// Configures the [`Node`] instance to source its gossip data from the given RapidGossipSync
277
+ /// server.
278
+ pub fn set_gossip_source_rgs ( & self , rgs_server_url : String ) {
279
+ self . inner . write ( ) . unwrap ( ) . set_gossip_source_rgs ( rgs_server_url) ;
280
+ }
281
+
282
+ /// Sets the used storage directory path.
283
+ pub fn set_storage_dir_path ( & self , storage_dir_path : String ) {
284
+ self . inner . write ( ) . unwrap ( ) . set_storage_dir_path ( storage_dir_path) ;
285
+ }
286
+
287
+ /// Sets the Bitcoin network used.
288
+ pub fn set_network ( & self , network : Network ) {
289
+ self . inner . write ( ) . unwrap ( ) . set_network ( network) ;
290
+ }
291
+
292
+ /// Sets the IP address and TCP port on which [`Node`] will listen for incoming network connections.
293
+ pub fn set_listening_address ( & self , listening_address : NetAddress ) {
294
+ self . inner . write ( ) . unwrap ( ) . set_listening_address ( listening_address) ;
295
+ }
296
+
297
+ /// Sets the level at which [`Node`] will log messages.
298
+ pub fn set_log_level ( & self , level : LogLevel ) {
299
+ self . inner . write ( ) . unwrap ( ) . set_log_level ( level) ;
300
+ }
301
+
302
+ /// Builds a [`Node`] instance with a [`SqliteStore`] backend and according to the options
303
+ /// previously configured.
304
+ pub fn build ( & self ) -> Arc < Node < SqliteStore > > {
305
+ Arc :: new ( self . inner . read ( ) . unwrap ( ) . build ( ) )
306
+ }
307
+
308
+ /// Builds a [`Node`] instance with a [`FilesystemStore`] backend and according to the options
309
+ /// previously configured.
310
+ pub fn build_with_fs_store ( & self ) -> Arc < Node < FilesystemStore > > {
311
+ Arc :: new ( self . inner . read ( ) . unwrap ( ) . build_with_fs_store ( ) )
312
+ }
313
+
314
+ /// Builds a [`Node`] instance according to the options previously configured.
315
+ pub fn build_with_store < K : KVStore + Sync + Send + ' static > (
316
+ & self , kv_store : Arc < K > ,
317
+ ) -> Arc < Node < K > > {
318
+ Arc :: new ( self . inner . read ( ) . unwrap ( ) . build_with_store ( kv_store) )
211
319
}
212
320
}
213
321
214
322
/// Builds a [`Node`] instance according to the options previously configured.
215
- fn build_with_store_internal < ' a , K : KVStore + Sync + Send + ' static > (
216
- config : Arc < Config > , entropy_source_config : Option < & ' a EntropySourceConfig > ,
217
- chain_data_source_config : Option < & ' a ChainDataSourceConfig > ,
218
- gossip_source_config : Option < & ' a GossipSourceConfig > , kv_store : Arc < K > ,
323
+ fn build_with_store_internal < K : KVStore + Sync + Send + ' static > (
324
+ config : Arc < Config > , entropy_source_config : Option < & EntropySourceConfig > ,
325
+ chain_data_source_config : Option < & ChainDataSourceConfig > ,
326
+ gossip_source_config : Option < & GossipSourceConfig > , kv_store : Arc < K > ,
219
327
runtime : Arc < RwLock < Option < tokio:: runtime:: Runtime > > > ,
220
328
) -> Node < K > {
221
329
let ldk_data_dir = format ! ( "{}/ldk" , config. storage_dir_path) ;
0 commit comments