55// http://opensource.org/licenses/MIT>, at your option. You may not use this file except in
66// accordance with one or both of these licenses.
77
8+ use bitcoin:: address:: NetworkUnchecked ;
89use persist:: KVStoreWalletPersister ;
910
11+ use crate :: config:: Config ;
1012use crate :: logger:: { log_debug, log_error, log_info, log_trace, LdkLogger , Logger } ;
1113
1214use crate :: fee_estimator:: { ConfirmationTarget , FeeEstimator } ;
@@ -43,11 +45,11 @@ use bitcoin::secp256k1::ecdh::SharedSecret;
4345use bitcoin:: secp256k1:: ecdsa:: { RecoverableSignature , Signature } ;
4446use bitcoin:: secp256k1:: { PublicKey , Scalar , Secp256k1 , SecretKey , Signing } ;
4547use bitcoin:: {
46- Amount , FeeRate , ScriptBuf , Transaction , TxOut , Txid , WPubkeyHash , WitnessProgram ,
47- WitnessVersion ,
48+ Address , Amount , FeeRate , Network , ScriptBuf , Transaction , TxOut , Txid , WPubkeyHash , WitnessProgram , WitnessVersion
4849} ;
4950
5051use std:: ops:: Deref ;
52+ use std:: str:: FromStr ;
5153use std:: sync:: { Arc , Mutex } ;
5254
5355pub ( crate ) enum OnchainSendAmount {
7173 broadcaster : B ,
7274 fee_estimator : E ,
7375 payment_store : Arc < PaymentStore < Arc < Logger > > > ,
76+ config : Arc < Config > ,
7477 logger : L ,
7578}
7679
@@ -83,11 +86,11 @@ where
8386 pub ( crate ) fn new (
8487 wallet : bdk_wallet:: PersistedWallet < KVStoreWalletPersister > ,
8588 wallet_persister : KVStoreWalletPersister , broadcaster : B , fee_estimator : E ,
86- payment_store : Arc < PaymentStore < Arc < Logger > > > , logger : L ,
89+ payment_store : Arc < PaymentStore < Arc < Logger > > > , config : Arc < Config > , logger : L ,
8790 ) -> Self {
8891 let inner = Mutex :: new ( wallet) ;
8992 let persister = Mutex :: new ( wallet_persister) ;
90- Self { inner, persister, broadcaster, fee_estimator, payment_store, logger }
93+ Self { inner, persister, broadcaster, fee_estimator, payment_store, config , logger }
9194 }
9295
9396 pub ( crate ) fn get_full_scan_request ( & self ) -> FullScanRequest < KeychainKind > {
@@ -323,10 +326,32 @@ where
323326 self . get_balances ( total_anchor_channels_reserve_sats) . map ( |( _, s) | s)
324327 }
325328
329+ /// Validates a Bitcoin address is properly formatted and matches the expected network.
330+ ///
331+ /// Returns `Ok(Address)` if valid, or:
332+ /// - `InvalidAddress` if malformed or for a different network
333+ ///
334+ /// # Example
335+ /// ```
336+ /// let address = "tb1q..."; // Testnet address
337+ /// parse_and_validate_address(Network::Testnet, address)?;
338+ pub fn parse_and_validate_address (
339+ & self , network : Network , address : & Address ,
340+ ) -> Result < Address , Error > {
341+ Address :: < NetworkUnchecked > :: from_str ( address. to_string ( ) . as_str ( ) )
342+ . map_err ( |_| Error :: InvalidAddress ) ?
343+ . require_network ( network)
344+ . map_err ( |_| Error :: InvalidAddress )
345+ }
346+
347+
348+
326349 pub ( crate ) fn send_to_address (
327350 & self , address : & bitcoin:: Address , send_amount : OnchainSendAmount ,
328351 fee_rate : Option < FeeRate > ,
329352 ) -> Result < Txid , Error > {
353+ self . parse_and_validate_address ( self . config . network , & address) ?;
354+
330355 // Use the set fee_rate or default to fee estimation.
331356 let confirmation_target = ConfirmationTarget :: OnchainPayment ;
332357 let fee_rate =
0 commit comments