@@ -19,8 +19,6 @@ use alloc::{
19
19
sync:: Arc ,
20
20
vec:: Vec ,
21
21
} ;
22
- use core:: { cmp:: Ordering , fmt, mem, ops:: Deref } ;
23
-
24
22
use bdk_chain:: {
25
23
indexed_tx_graph,
26
24
indexer:: keychain_txout:: KeychainTxOutIndex ,
@@ -43,11 +41,13 @@ use bitcoin::{
43
41
transaction, Address , Amount , Block , BlockHash , FeeRate , Network , OutPoint , Psbt , ScriptBuf ,
44
42
Sequence , Transaction , TxOut , Txid , Weight , Witness ,
45
43
} ;
44
+ use core:: { cmp:: Ordering , fmt, mem, ops:: Deref } ;
46
45
use miniscript:: {
47
46
descriptor:: KeyMap ,
48
47
psbt:: { PsbtExt , PsbtInputExt , PsbtInputSatisfier } ,
49
48
} ;
50
49
use rand_core:: RngCore ;
50
+ use std:: collections:: BTreeSet ;
51
51
52
52
mod changeset;
53
53
pub mod coin_selection;
@@ -77,7 +77,13 @@ use crate::wallet::{
77
77
78
78
// re-exports
79
79
pub use bdk_chain:: Balance ;
80
+ use bdk_tx:: {
81
+ create_psbt, create_selection, CreatePsbtParams , CreateSelectionParams , InputCandidates ,
82
+ InputGroup , Output ,
83
+ } ;
84
+ use chain:: KeychainIndexed ;
80
85
pub use changeset:: ChangeSet ;
86
+ use miniscript:: plan:: Assets ;
81
87
pub use params:: * ;
82
88
pub use persisted:: * ;
83
89
pub use utils:: IsDust ;
@@ -2425,6 +2431,131 @@ impl Wallet {
2425
2431
}
2426
2432
}
2427
2433
2434
+ pub struct TransactionParams {
2435
+ pub outputs : Vec < ( ScriptBuf , Amount ) > ,
2436
+ pub target_feerate : FeeRate ,
2437
+ pub must_spend : Vec < LocalOutput > ,
2438
+ // cannot_spend: Vec<LocalOutput>,
2439
+ }
2440
+
2441
+ /// Methods that use the bdk_tx crate to build transactions
2442
+ impl Wallet {
2443
+ pub fn create_transaction (
2444
+ & mut self ,
2445
+ outputs : Vec < ( ScriptBuf , Amount ) > ,
2446
+ target_feerate : FeeRate ,
2447
+ ) -> Result < Psbt , CreateBdkTxError > {
2448
+ let local_outputs: Vec < LocalOutput > = self . list_unspent ( ) . collect ( ) ;
2449
+ let outpoints: Vec < KeychainIndexed < KeychainKind , OutPoint > > = local_outputs
2450
+ . into_iter ( )
2451
+ . map ( |o| ( ( o. keychain , o. derivation_index ) , o. outpoint . clone ( ) ) )
2452
+ . collect ( ) ;
2453
+ // let descriptors = self.keychains();
2454
+ let descriptors: Vec < ( KeychainKind , & ExtendedDescriptor ) > = self . keychains ( ) . collect ( ) ;
2455
+
2456
+ let mut descriptors_map = BTreeMap :: new ( ) ;
2457
+ let _ = descriptors. into_iter ( ) . for_each ( |( kind, desc) | {
2458
+ descriptors_map. insert ( kind, desc. clone ( ) ) ;
2459
+ } ) ;
2460
+ dbg ! ( & descriptors_map) ;
2461
+
2462
+ let input_candidates: Vec < InputGroup > = InputCandidates :: new (
2463
+ & self . tx_graph ( ) , // tx_graph
2464
+ & self . local_chain ( ) , // chain
2465
+ self . local_chain ( ) . tip ( ) . block_id ( ) . clone ( ) , // chain_tip
2466
+ outpoints, // outpoints
2467
+ descriptors_map, // descriptors
2468
+ BTreeSet :: default ( ) , // allow_malleable
2469
+ Assets :: new ( ) , // additional_assets
2470
+ )
2471
+ . unwrap ( )
2472
+ . into_single_groups ( |_| true ) ;
2473
+
2474
+ let next_change_index: u32 = self . reveal_next_address ( KeychainKind :: Internal ) . index ;
2475
+ let public_change_descriptor = self . public_descriptor ( KeychainKind :: Internal ) ;
2476
+
2477
+ let outputs_vector = outputs
2478
+ . into_iter ( )
2479
+ . map ( |o| Output :: with_script ( o. 0 , o. 1 ) )
2480
+ . collect :: < Vec < _ > > ( ) ;
2481
+
2482
+ let ( selection, metrics) = create_selection ( CreateSelectionParams :: new (
2483
+ input_candidates,
2484
+ public_change_descriptor
2485
+ . at_derivation_index ( next_change_index)
2486
+ . map_err ( |_| CreateBdkTxError :: CannotCreateTx ) ?,
2487
+ outputs_vector,
2488
+ target_feerate,
2489
+ ) )
2490
+ . map_err ( |_| CreateBdkTxError :: CannotCreateTx ) ?;
2491
+
2492
+ let ( psbt, _) = create_psbt ( CreatePsbtParams :: new ( selection) )
2493
+ . map_err ( |_| CreateBdkTxError :: CannotCreateTx ) ?;
2494
+
2495
+ Ok ( psbt)
2496
+ }
2497
+
2498
+ pub fn create_complex_transaction (
2499
+ & mut self ,
2500
+ transaction_params : TransactionParams ,
2501
+ ) -> Result < Psbt , CreateBdkTxError > {
2502
+ let local_outputs: Vec < LocalOutput > = self . list_unspent ( ) . collect ( ) ;
2503
+ let outpoints: Vec < KeychainIndexed < KeychainKind , OutPoint > > = local_outputs
2504
+ . into_iter ( )
2505
+ . map ( |o| ( ( o. keychain , o. derivation_index ) , o. outpoint . clone ( ) ) )
2506
+ . collect ( ) ;
2507
+ // let descriptors = self.keychains();
2508
+ let descriptors: Vec < ( KeychainKind , & ExtendedDescriptor ) > = self . keychains ( ) . collect ( ) ;
2509
+
2510
+ let mut descriptors_map = BTreeMap :: new ( ) ;
2511
+ let _ = descriptors. into_iter ( ) . for_each ( |( kind, desc) | {
2512
+ descriptors_map. insert ( kind, desc. clone ( ) ) ;
2513
+ } ) ;
2514
+ dbg ! ( & descriptors_map) ;
2515
+
2516
+ let input_candidates: Vec < InputGroup > = InputCandidates :: new (
2517
+ & self . tx_graph ( ) , // tx_graph
2518
+ & self . local_chain ( ) , // chain
2519
+ self . local_chain ( ) . tip ( ) . block_id ( ) . clone ( ) , // chain_tip
2520
+ outpoints, // outpoints
2521
+ descriptors_map, // descriptors
2522
+ BTreeSet :: default ( ) , // allow_malleable
2523
+ Assets :: new ( ) , // additional_assets
2524
+ )
2525
+ . unwrap ( )
2526
+ . into_single_groups ( |_| true ) ;
2527
+
2528
+ let next_change_index: u32 = self . reveal_next_address ( KeychainKind :: Internal ) . index ;
2529
+ let public_change_descriptor = self . public_descriptor ( KeychainKind :: Internal ) ;
2530
+
2531
+ let outputs_vector = transaction_params
2532
+ . outputs
2533
+ . into_iter ( )
2534
+ . map ( |o| Output :: with_script ( o. 0 , o. 1 ) )
2535
+ . collect :: < Vec < _ > > ( ) ;
2536
+
2537
+ let ( selection, metrics) = create_selection ( CreateSelectionParams :: new (
2538
+ input_candidates,
2539
+ public_change_descriptor
2540
+ . at_derivation_index ( next_change_index)
2541
+ . map_err ( |_| CreateBdkTxError :: CannotCreateTx ) ?,
2542
+ outputs_vector,
2543
+ transaction_params. target_feerate ,
2544
+ ) )
2545
+ . map_err ( |_| CreateBdkTxError :: CannotCreateTx ) ?;
2546
+
2547
+ let ( psbt, _) = create_psbt ( CreatePsbtParams :: new ( selection) )
2548
+ . map_err ( |_| CreateBdkTxError :: CannotCreateTx ) ?;
2549
+
2550
+ Ok ( psbt)
2551
+ }
2552
+ }
2553
+
2554
+ #[ derive( Debug ) ]
2555
+ pub enum CreateBdkTxError {
2556
+ CannotCreateTx ,
2557
+ }
2558
+
2428
2559
impl AsRef < bdk_chain:: tx_graph:: TxGraph < ConfirmationBlockTime > > for Wallet {
2429
2560
fn as_ref ( & self ) -> & bdk_chain:: tx_graph:: TxGraph < ConfirmationBlockTime > {
2430
2561
self . indexed_graph . graph ( )
0 commit comments