diff --git a/src/testutils/blockchain_tests.rs b/src/testutils/blockchain_tests.rs index 556d98f6..87a77630 100644 --- a/src/testutils/blockchain_tests.rs +++ b/src/testutils/blockchain_tests.rs @@ -387,11 +387,25 @@ macro_rules! bdk_blockchain_tests { Wallet::new(&descriptors.0.to_string(), descriptors.1.as_ref(), Network::Regtest, MemoryDatabase::new()).unwrap() } - fn init_single_sig() -> (Wallet, $blockchain, (String, Option), TestClient) { + enum WalletType { + WpkhSingleSig, + TaprootKeySpend, + TaprootScriptSpend, + } + + fn init_wallet(ty: WalletType) -> (Wallet, $blockchain, (String, Option), TestClient) { let _ = env_logger::try_init(); - let descriptors = testutils! { - @descriptors ( "wpkh(Alice)" ) ( "wpkh(Alice)" ) ( @keys ( "Alice" => (@generate_xprv "/44'/0'/0'/0/*", "/44'/0'/0'/1/*") ) ) + let descriptors = match ty { + WalletType::WpkhSingleSig => testutils! { + @descriptors ( "wpkh(Alice)" ) ( "wpkh(Alice)" ) ( @keys ( "Alice" => (@generate_xprv "/44'/0'/0'/0/*", "/44'/0'/0'/1/*") ) ) + }, + WalletType::TaprootKeySpend => testutils! { + @descriptors ( "tr(Alice)" ) ( "tr(Alice)" ) ( @keys ( "Alice" => (@generate_xprv "/44'/0'/0'/0/*", "/44'/0'/0'/1/*") ) ) + }, + WalletType::TaprootScriptSpend => testutils! { + @descriptors ( "tr(Key,and_v(v:pk(Script),older(6)))" ) ( "tr(Key,and_v(v:pk(Script),older(6)))" ) ( @keys ( "Key" => (@literal "30e14486f993d5a2d222770e97286c56cec5af115e1fb2e0065f476a0fcf8788"), "Script" => (@generate_xprv "/0/*", "/1/*") ) ) + } }; let test_client = TestClient::default(); @@ -405,6 +419,10 @@ macro_rules! bdk_blockchain_tests { (wallet, blockchain, descriptors, test_client) } + fn init_single_sig() -> (Wallet, $blockchain, (String, Option), TestClient) { + init_wallet(WalletType::WpkhSingleSig) + } + #[test] fn test_sync_simple() { use std::ops::Deref; @@ -1203,6 +1221,54 @@ macro_rules! bdk_blockchain_tests { wallet.sync(&blockchain, SyncOptions::default()).unwrap(); } + + #[test] + fn test_taproot_key_spend() { + let (wallet, blockchain, descriptors, mut test_client) = init_wallet(WalletType::TaprootKeySpend); + + let _ = test_client.receive(testutils! { + @tx ( (@external descriptors, 0) => 50_000 ) + }); + wallet.sync(&blockchain, SyncOptions::default()).unwrap(); + assert_eq!(wallet.get_balance().unwrap(), 50_000); + + let tx = { + let mut builder = wallet.build_tx(); + builder.add_recipient(test_client.get_node_address(None).script_pubkey(), 25_000); + let (mut psbt, _details) = builder.finish().unwrap(); + wallet.sign(&mut psbt, Default::default()).unwrap(); + psbt.extract_tx() + }; + blockchain.broadcast(&tx).unwrap(); + } + + #[test] + fn test_taproot_script_spend() { + let (wallet, blockchain, descriptors, mut test_client) = init_wallet(WalletType::TaprootScriptSpend); + + let _ = test_client.receive(testutils! { + @tx ( (@external descriptors, 0) => 50_000 ) ( @confirmations 6 ) + }); + wallet.sync(&blockchain, SyncOptions::default()).unwrap(); + assert_eq!(wallet.get_balance().unwrap(), 50_000); + + let ext_policy = wallet.policies(KeychainKind::External).unwrap().unwrap(); + let int_policy = wallet.policies(KeychainKind::Internal).unwrap().unwrap(); + + let ext_path = vec![(ext_policy.id.clone(), vec![1])].into_iter().collect(); + let int_path = vec![(int_policy.id.clone(), vec![1])].into_iter().collect(); + + let tx = { + let mut builder = wallet.build_tx(); + builder.add_recipient(test_client.get_node_address(None).script_pubkey(), 25_000) + .policy_path(ext_path, KeychainKind::External) + .policy_path(int_path, KeychainKind::Internal); + let (mut psbt, _details) = builder.finish().unwrap(); + wallet.sign(&mut psbt, Default::default()).unwrap(); + psbt.extract_tx() + }; + blockchain.broadcast(&tx).unwrap(); + } } };