|
1 | 1 | use std::str::FromStr as _; |
2 | 2 |
|
3 | 3 | use anyhow::Ok; |
4 | | -use bdk_electrum::electrum_client::{Client, Config}; |
5 | 4 | use bdk_electrum::BdkElectrumClient; |
| 5 | +use bdk_electrum::electrum_client::{Client, Config}; |
6 | 6 | use bdk_kyoto::bip157::tokio; |
7 | | -use bdk_kyoto::TrustedPeer; |
| 7 | +use bdk_kyoto::{FeeRate, TrustedPeer}; |
8 | 8 | use bdk_wallet::bitcoin::{Address, Amount, Network}; |
9 | 9 | use bdk_wallet::psbt::PsbtUtils as _; |
10 | 10 | use bdk_wallet::{KeychainKind, SignOptions}; |
@@ -347,3 +347,73 @@ async fn test_cbf_persistence() -> anyhow::Result<()> { |
347 | 347 |
|
348 | 348 | Ok(()) |
349 | 349 | } |
| 350 | + |
| 351 | +#[tokio::test] |
| 352 | +async fn test_drain_wallet_with_main_balance() -> anyhow::Result<()> { |
| 353 | + // This test will attempt to drain the imported wallets UTXOs |
| 354 | + // With the main wallet having some balance it won't be touched. |
| 355 | + let env = TestEnv::new()?; |
| 356 | + env.mine_block()?; |
| 357 | + |
| 358 | + let mut wallet = BMPWallet::new(Network::Regtest)?; |
| 359 | + let addr = wallet.next_unused_address(KeychainKind::External); |
| 360 | + |
| 361 | + let amount_to_send_main_wallet = Amount::from_sat(100_000); |
| 362 | + let amount_to_send_imported = Amount::from_sat(10_000); |
| 363 | + env.fund_address(&addr, amount_to_send_main_wallet)?; |
| 364 | + |
| 365 | + let prv_keys = [new_private_key(), new_private_key()]; |
| 366 | + prv_keys.iter().for_each(|e| wallet.import_private_key(*e)); |
| 367 | + prv_keys.iter().for_each(|e| { |
| 368 | + env.fund_from_prv_key(e, amount_to_send_imported).unwrap(); |
| 369 | + }); |
| 370 | + |
| 371 | + env.mine_block()?; |
| 372 | + |
| 373 | + let client = Client::from_config(&env.electrum_url(), Config::default())?; |
| 374 | + let data_source = BdkElectrumClient::new(client); |
| 375 | + |
| 376 | + wallet.sync_all(&data_source)?; |
| 377 | + |
| 378 | + // Doing *2 because we have two imported keys with the same amount received 10_000 |
| 379 | + let current_balance = amount_to_send_main_wallet + amount_to_send_imported * 2; |
| 380 | + assert_eq!(wallet.balance(), current_balance); |
| 381 | + |
| 382 | + let mut psbt = wallet.drain(FeeRate::from_sat_per_vb(10).unwrap())?; |
| 383 | + |
| 384 | + wallet.sign(&mut psbt, SignOptions::default())?; |
| 385 | + |
| 386 | + let drained_amount = amount_to_send_imported * 2 - psbt.fee()?; |
| 387 | + |
| 388 | + let tx = psbt.extract_tx()?; |
| 389 | + |
| 390 | + env.broadcast(&tx)?; |
| 391 | + env.mine_block()?; |
| 392 | + |
| 393 | + wallet.sync_all(&data_source)?; |
| 394 | + |
| 395 | + let main_wallet_balance = drained_amount + amount_to_send_main_wallet; |
| 396 | + |
| 397 | + assert_eq!(wallet.balance(), main_wallet_balance); |
| 398 | + |
| 399 | + Ok(()) |
| 400 | +} |
| 401 | + |
| 402 | +#[tokio::test] |
| 403 | +#[should_panic(expected = "value: Output below the dust limit: 0")] |
| 404 | +async fn test_drain_wallet_no_balance() { |
| 405 | + // In this test drain is called but the wallet doesn't have any imported key |
| 406 | + // insuffucient balance should be thrown |
| 407 | + let env = TestEnv::new().unwrap(); |
| 408 | + env.mine_block().unwrap(); |
| 409 | + |
| 410 | + let mut wallet = BMPWallet::new(Network::Regtest).unwrap(); |
| 411 | + let addr = wallet.next_unused_address(KeychainKind::External); |
| 412 | + |
| 413 | + let amount_to_send_main_wallet = Amount::from_sat(100_000); |
| 414 | + |
| 415 | + env.fund_address(&addr, amount_to_send_main_wallet).unwrap(); |
| 416 | + env.mine_block().unwrap(); |
| 417 | + |
| 418 | + wallet.drain(FeeRate::from_sat_per_vb(10).unwrap()).unwrap(); |
| 419 | +} |
0 commit comments