1
+ #![ allow( unused) ]
1
2
use bdk_electrum:: electrum_client;
2
3
use bdk_electrum:: BdkElectrumClient ;
3
4
use bdk_wallet:: bitcoin:: Amount ;
@@ -23,158 +24,158 @@ const INTERNAL_DESC: &str = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7
23
24
const ELECTRUM_URL : & str = "ssl://mempool.space:40002" ;
24
25
25
26
fn main ( ) -> Result < ( ) , anyhow:: Error > {
26
- let mut db = Connection :: open ( DB_PATH ) ?;
27
- let wallet_opt = Wallet :: load ( )
28
- . descriptor ( KeychainKind :: External , Some ( EXTERNAL_DESC ) )
29
- . descriptor ( KeychainKind :: Internal , Some ( INTERNAL_DESC ) )
30
- . extract_keys ( )
31
- . check_network ( NETWORK )
32
- . load_wallet ( & mut db) ?;
33
- let mut wallet = match wallet_opt {
34
- Some ( wallet) => wallet,
35
- None => Wallet :: create ( EXTERNAL_DESC , INTERNAL_DESC )
36
- . network ( NETWORK )
37
- . create_wallet ( & mut db) ?,
38
- } ;
39
-
40
- let address = wallet. next_unused_address ( KeychainKind :: External ) ;
41
- wallet. persist ( & mut db) ?;
42
- println ! ( "Generated Address: {address}" ) ;
43
-
44
- let balance = wallet. balance ( ) ;
45
- println ! ( "Wallet balance before syncing: {}" , balance. total( ) ) ;
46
-
47
- println ! ( "Performing Full Sync..." ) ;
48
- let client = BdkElectrumClient :: new ( electrum_client:: Client :: new ( ELECTRUM_URL ) ?) ;
49
-
50
- // Populate the electrum client's transaction cache so it doesn't redownload transaction we
51
- // already have.
52
- client. populate_tx_cache ( wallet. tx_graph ( ) . full_txs ( ) . map ( |tx_node| tx_node. tx ) ) ;
53
-
54
- let request = wallet. start_full_scan ( ) . inspect ( {
55
- let mut stdout = std:: io:: stdout ( ) ;
56
- let mut once = HashSet :: < KeychainKind > :: new ( ) ;
57
- move |k, spk_i, _| {
58
- if once. insert ( k) {
59
- print ! ( "\n Scanning keychain [{k:?}]" ) ;
60
- }
61
- if spk_i. is_multiple_of ( 5 ) {
62
- print ! ( " {spk_i:<3}" ) ;
63
- }
64
- stdout. flush ( ) . expect ( "must flush" ) ;
65
- }
66
- } ) ;
67
-
68
- let update = client. full_scan ( request, STOP_GAP , BATCH_SIZE , false ) ?;
69
-
70
- println ! ( ) ;
71
-
72
- wallet. apply_update ( update) ?;
73
- wallet. persist ( & mut db) ?;
74
-
75
- let balance = wallet. balance ( ) ;
76
- println ! ( "Wallet balance after full sync: {}" , balance. total( ) ) ;
77
- println ! (
78
- "Wallet has {} transactions and {} utxos after full sync" ,
79
- wallet. transactions( ) . count( ) ,
80
- wallet. list_unspent( ) . count( )
81
- ) ;
82
-
83
- if balance. total ( ) < SEND_AMOUNT {
84
- println ! ( "Please send at least {SEND_AMOUNT} to the receiving address" ) ;
85
- std:: process:: exit ( 0 ) ;
86
- }
87
-
88
- let target_fee_rate = FeeRate :: from_sat_per_vb ( 1 ) . unwrap ( ) ;
89
- let mut tx_builder = wallet. build_tx ( ) ;
90
- tx_builder. add_recipient ( address. script_pubkey ( ) , SEND_AMOUNT ) ;
91
- tx_builder. fee_rate ( target_fee_rate) ;
92
-
93
- let mut psbt = tx_builder. finish ( ) ?;
94
- let finalized = wallet. sign ( & mut psbt, SignOptions :: default ( ) ) ?;
95
- assert ! ( finalized) ;
96
- let original_fee = psbt. fee_amount ( ) . unwrap ( ) ;
97
- let tx_feerate = psbt. fee_rate ( ) . unwrap ( ) ;
98
- let tx = psbt. extract_tx ( ) ?;
99
- client. transaction_broadcast ( & tx) ?;
100
- let txid = tx. compute_txid ( ) ;
101
- println ! ( "Tx broadcasted! Txid: https://mempool.space/testnet4/tx/{txid}" ) ;
102
-
103
- println ! ( "Partial Sync..." ) ;
104
- print ! ( "SCANNING: " ) ;
105
- let mut last_printed = 0 ;
106
- let sync_request = wallet
107
- . start_sync_with_revealed_spks ( )
108
- . inspect ( move |_, sync_progress| {
109
- let progress_percent =
110
- ( 100 * sync_progress. consumed ( ) ) as f32 / sync_progress. total ( ) as f32 ;
111
- let progress_percent = progress_percent. round ( ) as u32 ;
112
- if progress_percent. is_multiple_of ( 5 ) && progress_percent > last_printed {
113
- print ! ( "{progress_percent}% " ) ;
114
- std:: io:: stdout ( ) . flush ( ) . expect ( "must flush" ) ;
115
- last_printed = progress_percent;
116
- }
117
- } ) ;
118
- client. populate_tx_cache ( wallet. tx_graph ( ) . full_txs ( ) . map ( |tx_node| tx_node. tx ) ) ;
119
- let sync_update = client. sync ( sync_request, BATCH_SIZE , false ) ?;
120
- println ! ( ) ;
121
- wallet. apply_update ( sync_update) ?;
122
- wallet. persist ( & mut db) ?;
123
-
124
- // bump fee rate for tx by at least 1 sat per vbyte
125
- let feerate = FeeRate :: from_sat_per_vb ( tx_feerate. to_sat_per_vb_ceil ( ) + 1 ) . unwrap ( ) ;
126
- let mut builder = wallet. build_fee_bump ( txid) . expect ( "failed to bump tx" ) ;
127
- builder. fee_rate ( feerate) ;
128
- let mut bumped_psbt = builder. finish ( ) . unwrap ( ) ;
129
- let finalize_btx = wallet. sign ( & mut bumped_psbt, SignOptions :: default ( ) ) ?;
130
- assert ! ( finalize_btx) ;
131
- let new_fee = bumped_psbt. fee_amount ( ) . unwrap ( ) ;
132
- let bumped_tx = bumped_psbt. extract_tx ( ) ?;
133
- assert_eq ! (
134
- bumped_tx
135
- . output
136
- . iter( )
137
- . find( |txout| txout. script_pubkey == address. script_pubkey( ) )
138
- . unwrap( )
139
- . value,
140
- SEND_AMOUNT ,
141
- "Recipient output should remain unchanged"
142
- ) ;
143
- assert ! (
144
- new_fee > original_fee,
145
- "New fee ({new_fee}) should be higher than original ({original_fee})"
146
- ) ;
147
-
148
- // wait for first transaction to make it into the mempool and be indexed on mempool.space
149
- sleep ( Duration :: from_secs ( 10 ) ) ;
150
- client. transaction_broadcast ( & bumped_tx) ?;
151
- println ! (
152
- "Broadcasted bumped tx. Txid: https://mempool.space/testnet4/tx/{}" ,
153
- bumped_tx. compute_txid( )
154
- ) ;
155
-
156
- println ! ( "Syncing after bumped tx broadcast..." ) ;
157
- let sync_request = wallet. start_sync_with_revealed_spks ( ) . inspect ( |_, _| { } ) ;
158
- let sync_update = client. sync ( sync_request, BATCH_SIZE , false ) ?;
159
-
160
- let mut evicted_txs = Vec :: new ( ) ;
161
- for ( txid, last_seen) in & sync_update. tx_update . evicted_ats {
162
- evicted_txs. push ( ( * txid, * last_seen) ) ;
163
- }
164
-
165
- wallet. apply_update ( sync_update) ?;
166
- if !evicted_txs. is_empty ( ) {
167
- println ! ( "Applied {} evicted transactions" , evicted_txs. len( ) ) ;
168
- }
169
- wallet. persist ( & mut db) ?;
170
-
171
- let balance_after_sync = wallet. balance ( ) ;
172
- println ! ( "Wallet balance after sync: {}" , balance_after_sync. total( ) ) ;
173
- println ! (
174
- "Wallet has {} transactions and {} utxos after partial sync" ,
175
- wallet. transactions( ) . count( ) ,
176
- wallet. list_unspent( ) . count( )
177
- ) ;
27
+ // let mut db = Connection::open(DB_PATH)?;
28
+ // let wallet_opt = Wallet::load()
29
+ // .descriptor(KeychainKind::External, Some(EXTERNAL_DESC))
30
+ // .descriptor(KeychainKind::Internal, Some(INTERNAL_DESC))
31
+ // .extract_keys()
32
+ // .check_network(NETWORK)
33
+ // .load_wallet(&mut db)?;
34
+ // let mut wallet = match wallet_opt {
35
+ // Some(wallet) => wallet,
36
+ // None => Wallet::create(EXTERNAL_DESC, INTERNAL_DESC)
37
+ // .network(NETWORK)
38
+ // .create_wallet(&mut db)?,
39
+ // };
40
+
41
+ // let address = wallet.next_unused_address(KeychainKind::External);
42
+ // wallet.persist(&mut db)?;
43
+ // println!("Generated Address: {address}");
44
+
45
+ // let balance = wallet.balance();
46
+ // println!("Wallet balance before syncing: {}", balance.total());
47
+
48
+ // println!("Performing Full Sync...");
49
+ // let client = BdkElectrumClient::new(electrum_client::Client::new(ELECTRUM_URL)?);
50
+
51
+ // // Populate the electrum client's transaction cache so it doesn't redownload transaction we
52
+ // // already have.
53
+ // client.populate_tx_cache(wallet.tx_graph().full_txs().map(|tx_node| tx_node.tx));
54
+
55
+ // let request = wallet.start_full_scan().inspect({
56
+ // let mut stdout = std::io::stdout();
57
+ // let mut once = HashSet::<KeychainKind>::new();
58
+ // move |k, spk_i, _| {
59
+ // if once.insert(k) {
60
+ // print!("\nScanning keychain [{k:?}]");
61
+ // }
62
+ // if spk_i.is_multiple_of(5) {
63
+ // print!(" {spk_i:<3}");
64
+ // }
65
+ // stdout.flush().expect("must flush");
66
+ // }
67
+ // });
68
+
69
+ // let update = client.full_scan(request, STOP_GAP, BATCH_SIZE, false)?;
70
+
71
+ // println!();
72
+
73
+ // wallet.apply_update(update)?;
74
+ // wallet.persist(&mut db)?;
75
+
76
+ // let balance = wallet.balance();
77
+ // println!("Wallet balance after full sync: {}", balance.total());
78
+ // println!(
79
+ // "Wallet has {} transactions and {} utxos after full sync",
80
+ // wallet.transactions().count(),
81
+ // wallet.list_unspent().count()
82
+ // );
83
+
84
+ // if balance.total() < SEND_AMOUNT {
85
+ // println!("Please send at least {SEND_AMOUNT} to the receiving address");
86
+ // std::process::exit(0);
87
+ // }
88
+
89
+ // let target_fee_rate = FeeRate::from_sat_per_vb(1).unwrap();
90
+ // let mut tx_builder = wallet.build_tx();
91
+ // tx_builder.add_recipient(address.script_pubkey(), SEND_AMOUNT);
92
+ // tx_builder.fee_rate(target_fee_rate);
93
+
94
+ // let mut psbt = tx_builder.finish()?;
95
+ // let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
96
+ // assert!(finalized);
97
+ // let original_fee = psbt.fee_amount().unwrap();
98
+ // let tx_feerate = psbt.fee_rate().unwrap();
99
+ // let tx = psbt.extract_tx()?;
100
+ // client.transaction_broadcast(&tx)?;
101
+ // let txid = tx.compute_txid();
102
+ // println!("Tx broadcasted! Txid: https://mempool.space/testnet4/tx/{txid}");
103
+
104
+ // println!("Partial Sync...");
105
+ // print!("SCANNING: ");
106
+ // let mut last_printed = 0;
107
+ // let sync_request = wallet
108
+ // .start_sync_with_revealed_spks()
109
+ // .inspect(move |_, sync_progress| {
110
+ // let progress_percent =
111
+ // (100 * sync_progress.consumed()) as f32 / sync_progress.total() as f32;
112
+ // let progress_percent = progress_percent.round() as u32;
113
+ // if progress_percent.is_multiple_of(5) && progress_percent > last_printed {
114
+ // print!("{progress_percent}% ");
115
+ // std::io::stdout().flush().expect("must flush");
116
+ // last_printed = progress_percent;
117
+ // }
118
+ // });
119
+ // client.populate_tx_cache(wallet.tx_graph().full_txs().map(|tx_node| tx_node.tx));
120
+ // let sync_update = client.sync(sync_request, BATCH_SIZE, false)?;
121
+ // println!();
122
+ // wallet.apply_update(sync_update)?;
123
+ // wallet.persist(&mut db)?;
124
+
125
+ // // bump fee rate for tx by at least 1 sat per vbyte
126
+ // let feerate = FeeRate::from_sat_per_vb(tx_feerate.to_sat_per_vb_ceil() + 1).unwrap();
127
+ // let mut builder = wallet.build_fee_bump(txid).expect("failed to bump tx");
128
+ // builder.fee_rate(feerate);
129
+ // let mut bumped_psbt = builder.finish().unwrap();
130
+ // let finalize_btx = wallet.sign(&mut bumped_psbt, SignOptions::default())?;
131
+ // assert!(finalize_btx);
132
+ // let new_fee = bumped_psbt.fee_amount().unwrap();
133
+ // let bumped_tx = bumped_psbt.extract_tx()?;
134
+ // assert_eq!(
135
+ // bumped_tx
136
+ // .output
137
+ // .iter()
138
+ // .find(|txout| txout.script_pubkey == address.script_pubkey())
139
+ // .unwrap()
140
+ // .value,
141
+ // SEND_AMOUNT,
142
+ // "Recipient output should remain unchanged"
143
+ // );
144
+ // assert!(
145
+ // new_fee > original_fee,
146
+ // "New fee ({new_fee}) should be higher than original ({original_fee})"
147
+ // );
148
+
149
+ // // wait for first transaction to make it into the mempool and be indexed on mempool.space
150
+ // sleep(Duration::from_secs(10));
151
+ // client.transaction_broadcast(&bumped_tx)?;
152
+ // println!(
153
+ // "Broadcasted bumped tx. Txid: https://mempool.space/testnet4/tx/{}",
154
+ // bumped_tx.compute_txid()
155
+ // );
156
+
157
+ // println!("Syncing after bumped tx broadcast...");
158
+ // let sync_request = wallet.start_sync_with_revealed_spks().inspect(|_, _| {});
159
+ // let sync_update = client.sync(sync_request, BATCH_SIZE, false)?;
160
+
161
+ // let mut evicted_txs = Vec::new();
162
+ // for (txid, last_seen) in &sync_update.tx_update.evicted_ats {
163
+ // evicted_txs.push((*txid, *last_seen));
164
+ // }
165
+
166
+ // wallet.apply_update(sync_update)?;
167
+ // if !evicted_txs.is_empty() {
168
+ // println!("Applied {} evicted transactions", evicted_txs.len());
169
+ // }
170
+ // wallet.persist(&mut db)?;
171
+
172
+ // let balance_after_sync = wallet.balance();
173
+ // println!("Wallet balance after sync: {}", balance_after_sync.total());
174
+ // println!(
175
+ // "Wallet has {} transactions and {} utxos after partial sync",
176
+ // wallet.transactions().count(),
177
+ // wallet.list_unspent().count()
178
+ // );
178
179
179
180
Ok ( ( ) )
180
181
}
0 commit comments