Skip to content

Commit 9e128be

Browse files
committed
move onchain address validation for network-specific addresses to Wallet::send_to_address
1 parent 99cd15a commit 9e128be

File tree

3 files changed

+34
-30
lines changed

3 files changed

+34
-30
lines changed

src/builder.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,7 @@ fn build_with_store_internal(
10061006
Arc::clone(&tx_broadcaster),
10071007
Arc::clone(&fee_estimator),
10081008
Arc::clone(&payment_store),
1009+
Arc::clone(&config),
10091010
Arc::clone(&logger),
10101011
));
10111012

src/payment/onchain.rs

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,8 @@ use crate::logger::{log_info, LdkLogger, Logger};
1313
use crate::types::{ChannelManager, Wallet};
1414
use crate::wallet::OnchainSendAmount;
1515

16-
use bitcoin::address::NetworkUnchecked;
17-
use bitcoin::{Address, Network, Txid};
16+
use bitcoin::{Address, Txid};
1817

19-
use std::str::FromStr;
2018
use std::sync::{Arc, RwLock};
2119

2220
#[cfg(not(feature = "uniffi"))]
@@ -82,14 +80,14 @@ impl OnchainPayment {
8280
return Err(Error::NotRunning);
8381
}
8482

85-
let validated_address = self.parse_and_validate_address(self.config.network, &address)?;
83+
// let validated_address = self.parse_and_validate_address(self.config.network, &address)?;
8684

8785
let cur_anchor_reserve_sats =
8886
crate::total_anchor_channels_reserve_sats(&self.channel_manager, &self.config);
8987
let send_amount =
9088
OnchainSendAmount::ExactRetainingReserve { amount_sats, cur_anchor_reserve_sats };
9189
let fee_rate_opt = maybe_map_fee_rate_opt!(fee_rate);
92-
self.wallet.send_to_address(&validated_address, send_amount, fee_rate_opt)
90+
self.wallet.send_to_address(&address, send_amount, fee_rate_opt)
9391
}
9492

9593
/// Send an on-chain payment to the given address, draining the available funds.
@@ -115,8 +113,6 @@ impl OnchainPayment {
115113
return Err(Error::NotRunning);
116114
}
117115

118-
let validated_address = self.parse_and_validate_address(self.config.network, &address)?;
119-
120116
let send_amount = if retain_reserves {
121117
let cur_anchor_reserve_sats =
122118
crate::total_anchor_channels_reserve_sats(&self.channel_manager, &self.config);
@@ -126,24 +122,6 @@ impl OnchainPayment {
126122
};
127123

128124
let fee_rate_opt = maybe_map_fee_rate_opt!(fee_rate);
129-
self.wallet.send_to_address(&validated_address, send_amount, fee_rate_opt)
130-
}
131-
132-
/// Validates a Bitcoin address is properly formatted and matches the expected network.
133-
///
134-
/// Returns `Ok(Address)` if valid, or:
135-
/// - `InvalidAddress` if malformed or for a different network
136-
///
137-
/// # Example
138-
/// ```
139-
/// let address = "tb1q..."; // Testnet address
140-
/// parse_and_validate_address(Network::Testnet, address)?;
141-
pub fn parse_and_validate_address(
142-
&self, network: Network, address: &Address,
143-
) -> Result<Address, Error> {
144-
Address::<NetworkUnchecked>::from_str(address.to_string().as_str())
145-
.map_err(|_| Error::InvalidAddress)?
146-
.require_network(network)
147-
.map_err(|_| Error::InvalidAddress)
125+
self.wallet.send_to_address(&address, send_amount, fee_rate_opt)
148126
}
149127
}

src/wallet/mod.rs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
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;
89
use persist::KVStoreWalletPersister;
910

11+
use crate::config::Config;
1012
use crate::logger::{log_debug, log_error, log_info, log_trace, LdkLogger, Logger};
1113

1214
use crate::fee_estimator::{ConfirmationTarget, FeeEstimator};
@@ -43,11 +45,11 @@ use bitcoin::secp256k1::ecdh::SharedSecret;
4345
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
4446
use bitcoin::secp256k1::{PublicKey, Scalar, Secp256k1, SecretKey, Signing};
4547
use 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

5051
use std::ops::Deref;
52+
use std::str::FromStr;
5153
use std::sync::{Arc, Mutex};
5254

5355
pub(crate) enum OnchainSendAmount {
@@ -71,6 +73,7 @@ where
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

Comments
 (0)