1- use std:: io:: Write as _;
21use std:: str:: FromStr as _;
32
4- use bdk_electrum:: BdkElectrumClient ;
5- use bdk_electrum:: electrum_client:: Client ;
6- use bdk_wallet:: bitcoin:: bip32:: Xpriv ;
73use bdk_wallet:: bitcoin:: {
84 Address , Amount , FeeRate , Network , OutPoint , Psbt , Script , ScriptBuf , Transaction , TxOut , Txid ,
95 relative,
106} ;
11- use bdk_wallet:: template:: { Bip86 , DescriptorTemplate as _} ;
12- use bdk_wallet:: { AddressInfo , KeychainKind , SignOptions , Wallet } ;
137use musig2:: secp:: { MaybeScalar , Point } ;
148use musig2:: { PartialSignature , PubNonce } ;
15- use rand:: RngCore as _;
16- use testenv:: TestEnv ;
179
10+ use wallet:: protocol_wallet_api:: MemWallet ;
1811use crate :: multisig:: { KeyCtx , SigCtx } ;
1912use crate :: receiver:: { Receiver , ReceiverList } ;
2013use crate :: transaction:: {
2114 DepositTxBuilder , ForwardingTxBuilder , RedirectTxBuilder , WarningTxBuilder , WithWitnesses as _,
2215} ;
2316use crate :: wallet_service:: WalletService ;
2417
25- pub struct MemWallet {
26- wallet : Wallet ,
27- client : BdkElectrumClient < Client > ,
28- }
29-
30- impl MemWallet {
31- pub fn transaction_broadcast ( & self , tx : & Transaction ) -> anyhow:: Result < Txid > {
32- let result = self . client . transaction_broadcast ( tx) ;
33-
34- if let Err ( e) = result {
35- if e. to_string ( ) . contains ( "Transaction already in block chain" ) {
36- return Ok ( tx. compute_txid ( ) ) ;
37- }
38- return Err ( e. into ( ) ) ;
39- }
40-
41- Ok ( result?)
42- }
43-
44- pub fn funded_wallet ( env : & TestEnv ) -> Self {
45- // TODO move this line to TestEnv
46- let client =
47- BdkElectrumClient :: new ( Client :: new ( & env. electrum_url ( ) ) . unwrap ( ) ) ;
48- let mut wallet = Self :: new ( client) . unwrap ( ) ;
49- let address = wallet. next_unused_address ( ) ;
50- let txid = env
51- . fund_address ( & address, Amount :: from_btc ( 10f64 ) . unwrap ( ) )
52- . unwrap ( ) ;
53- env. mine_block ( ) . unwrap ( ) ;
54- env. wait_for_tx ( txid) . unwrap ( ) ;
55- wallet. sync ( ) . unwrap ( ) ;
56- wallet
57- }
58- }
59-
6018#[ derive( PartialEq , Eq , Clone , Copy , Debug ) ]
6119#[ expect( clippy:: exhaustive_enums) ]
6220pub enum ProtocolRole {
@@ -73,94 +31,6 @@ impl ProtocolRole {
7331 }
7432}
7533
76- // TODO think about stop_gap and batch_size
77- const STOP_GAP : usize = 50 ;
78- const BATCH_SIZE : usize = 5 ;
79-
80- impl MemWallet {
81- pub fn new ( client : BdkElectrumClient < Client > ) -> anyhow:: Result < Self > {
82- let mut seed: [ u8 ; 32 ] = [ 0u8 ; 32 ] ;
83- rand:: rng ( ) . fill_bytes ( & mut seed) ;
84-
85- let network: Network = Network :: Regtest ;
86- let xprv: Xpriv = Xpriv :: new_master ( network, & seed) ?;
87- tracing:: info!(
88- "Generated Master Private Key:\n {xprv}\n Warning: be very careful with private \
89- keys when using MainNet! We are logging these values for convenience only because this \
90- is an example on RegTest.\n "
91- ) ;
92-
93- let ( descriptor, external_map, _) = Bip86 ( xprv, KeychainKind :: External )
94- . build ( network)
95- . expect ( "Failed to build external descriptor" ) ;
96-
97- let ( change_descriptor, internal_map, _) = Bip86 ( xprv, KeychainKind :: Internal )
98- . build ( network)
99- . expect ( "Failed to build internal descriptor" ) ;
100-
101- let wallet = Wallet :: create ( descriptor, change_descriptor)
102- . network ( network)
103- . keymap ( KeychainKind :: External , external_map)
104- . keymap ( KeychainKind :: Internal , internal_map)
105- . create_wallet_no_persist ( ) ?;
106-
107- Ok ( Self { wallet, client } )
108- }
109-
110- pub fn sync ( & mut self ) -> anyhow:: Result < ( ) > {
111- // Populate the electrum client's transaction cache so it doesn't re-download transaction we
112- // already have.
113- self . client
114- . populate_tx_cache ( self . wallet . tx_graph ( ) . full_txs ( ) . map ( |tx_node| tx_node. tx ) ) ;
115-
116- let request = self . wallet . start_full_scan ( ) . inspect ( {
117- let mut stdout = std:: io:: stdout ( ) ;
118- // let mut once = HashSet::<KeychainKind>::new();
119- move |_k, _spk_i, _| {
120- // if once.insert(k) {
121- // print!("\nScanning keychain [{:?}]", k);
122- // }
123- // print!(" {:<3}", spk_i);
124- stdout. flush ( ) . expect ( "must flush" ) ;
125- }
126- } ) ;
127- tracing:: info!( "requesting update..." ) ;
128- let update = self
129- . client
130- . full_scan ( request, STOP_GAP , BATCH_SIZE , false ) ?;
131- self . wallet . apply_update ( update) ?;
132- Ok ( ( ) )
133- }
134-
135- pub fn balance ( & self ) -> Amount {
136- self . wallet . balance ( ) . trusted_spendable ( )
137- }
138-
139- pub fn next_unused_address ( & mut self ) -> AddressInfo {
140- // FIXME: `next_unused_address` just returns the same unused address over and over. It has
141- // to either be marked as used (which change isn't staged and therefore presumably never
142- // persisted) or a fresh address requested with `reveal_next_address`.
143- self . wallet . next_unused_address ( KeychainKind :: External )
144- }
145-
146- fn _transfer_to_address (
147- & mut self ,
148- address : & AddressInfo ,
149- amount : Amount ,
150- ) -> anyhow:: Result < Txid > {
151- let mut tx_builder = self . wallet . build_tx ( ) ;
152- tx_builder. add_recipient ( address. script_pubkey ( ) , amount) ;
153-
154- let mut psbt = tx_builder. finish ( ) ?;
155- let finalized = self . wallet . sign ( & mut psbt, SignOptions :: default ( ) ) ?;
156- assert ! ( finalized) ;
157-
158- let tx = psbt. extract_tx ( ) ?;
159- self . client . transaction_broadcast ( & tx) ?;
160- Ok ( tx. compute_txid ( ) )
161- }
162- }
163-
16434#[ derive( Debug ) ]
16535pub struct Round1Parameter {
16636 // DepositTx --------
@@ -497,7 +367,7 @@ impl RedirectTx {
497367 }
498368
499369 pub fn broadcast ( & self , me : & BMPContext ) -> anyhow:: Result < Txid > {
500- Ok ( me. funds . client . transaction_broadcast ( self . builder . signed_tx ( ) ? ) ?)
370+ me. funds . transaction_broadcast ( self . builder . signed_tx ( ) ?)
501371 }
502372
503373 /// sum of all f64 must be 1
@@ -559,7 +429,7 @@ impl ClaimTx {
559429 }
560430
561431 pub fn broadcast ( & self , me : & BMPContext ) -> anyhow:: Result < Txid > {
562- Ok ( me. funds . client . transaction_broadcast ( self . signed_tx ( ) ? ) ?)
432+ me. funds . transaction_broadcast ( self . signed_tx ( ) ?)
563433 }
564434}
565435
@@ -651,7 +521,7 @@ impl WarningTx {
651521 }
652522
653523 pub fn broadcast ( & self , me : & BMPContext ) -> anyhow:: Result < Txid > {
654- Ok ( me. funds . client . transaction_broadcast ( self . signed_tx ( ) ? ) ?)
524+ me. funds . transaction_broadcast ( self . signed_tx ( ) ?)
655525 }
656526}
657527
@@ -759,7 +629,7 @@ impl SwapTx {
759629 }
760630
761631 pub fn broadcast ( & self , me : & BMPContext ) -> anyhow:: Result < Txid > {
762- Ok ( me. funds . client . transaction_broadcast ( self . builder . signed_tx ( ) ? ) ?)
632+ me. funds . transaction_broadcast ( self . builder . signed_tx ( ) ?)
763633 }
764634}
765635
@@ -785,11 +655,11 @@ impl DepositTx {
785655
786656 let psbt = if ctx. am_buyer ( ) {
787657 self . builder
788- . init_buyers_half_psbt ( & mut ctx. funds . wallet , & mut rand:: rng ( ) ) ?
658+ . init_buyers_half_psbt ( & mut ctx. funds , & mut rand:: rng ( ) ) ?
789659 . buyers_half_psbt ( ) ?
790660 } else {
791661 self . builder
792- . init_sellers_half_psbt ( & mut ctx. funds . wallet , & mut rand:: rng ( ) ) ?
662+ . init_sellers_half_psbt ( & mut ctx. funds , & mut rand:: rng ( ) ) ?
793663 . sellers_half_psbt ( ) ?
794664 } ;
795665 Ok ( psbt. clone ( ) )
@@ -810,9 +680,9 @@ impl DepositTx {
810680
811681 fn sign ( & mut self , ctx : & mut BMPContext ) -> anyhow:: Result < ( ) > {
812682 if ctx. am_buyer ( ) {
813- self . builder . sign_buyer_inputs ( & ctx. funds . wallet ) ?;
683+ self . builder . sign_buyer_inputs ( & ctx. funds ) ?;
814684 } else {
815- self . builder . sign_seller_inputs ( & ctx. funds . wallet ) ?;
685+ self . builder . sign_seller_inputs ( & ctx. funds ) ?;
816686 }
817687 Ok ( ( ) )
818688 }
0 commit comments