@@ -7,35 +7,36 @@ use bdk_wallet::{
7
7
KeychainKind , SignOptions , Wallet ,
8
8
} ;
9
9
use std:: { collections:: BTreeSet , io:: Write } ;
10
+ use tokio:: time:: { sleep, Duration } ;
10
11
11
12
const SEND_AMOUNT : Amount = Amount :: from_sat ( 5000 ) ;
12
13
const STOP_GAP : usize = 5 ;
13
14
const PARALLEL_REQUESTS : usize = 5 ;
14
15
15
16
const DB_PATH : & str = "bdk-example-esplora-async.sqlite" ;
16
- const NETWORK : Network = Network :: Signet ;
17
+ const NETWORK : Network = Network :: Testnet4 ;
17
18
const EXTERNAL_DESC : & str = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/1'/0'/0/*)" ;
18
19
const INTERNAL_DESC : & str = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/1'/0'/1/*)" ;
19
- const ESPLORA_URL : & str = "http ://signet.bitcoindevkit.net " ;
20
+ const ESPLORA_URL : & str = "https ://mempool.space/testnet4/api " ;
20
21
21
22
#[ tokio:: main]
22
23
async fn main ( ) -> Result < ( ) , anyhow:: Error > {
23
- let mut conn = Connection :: open ( DB_PATH ) ?;
24
+ let mut db = Connection :: open ( DB_PATH ) ?;
24
25
let wallet_opt = Wallet :: load ( )
25
26
. descriptor ( KeychainKind :: External , Some ( EXTERNAL_DESC ) )
26
27
. descriptor ( KeychainKind :: Internal , Some ( INTERNAL_DESC ) )
27
28
. extract_keys ( )
28
29
. check_network ( NETWORK )
29
- . load_wallet ( & mut conn ) ?;
30
+ . load_wallet ( & mut db ) ?;
30
31
let mut wallet = match wallet_opt {
31
32
Some ( wallet) => wallet,
32
33
None => Wallet :: create ( EXTERNAL_DESC , INTERNAL_DESC )
33
34
. network ( NETWORK )
34
- . create_wallet ( & mut conn ) ?,
35
+ . create_wallet ( & mut db ) ?,
35
36
} ;
36
37
37
38
let address = wallet. next_unused_address ( KeychainKind :: External ) ;
38
- wallet. persist ( & mut conn ) ?;
39
+ wallet. persist ( & mut db ) ?;
39
40
println ! ( "Next unused address: ({}) {address}" , address. index) ;
40
41
41
42
let balance = wallet. balance ( ) ;
@@ -63,7 +64,7 @@ async fn main() -> Result<(), anyhow::Error> {
63
64
. await ?;
64
65
65
66
wallet. apply_update ( update) ?;
66
- wallet. persist ( & mut conn ) ?;
67
+ wallet. persist ( & mut db ) ?;
67
68
println ! ( ) ;
68
69
69
70
let balance = wallet. balance ( ) ;
@@ -78,8 +79,11 @@ async fn main() -> Result<(), anyhow::Error> {
78
79
println ! ( "Please send at least {SEND_AMOUNT} to the receiving address" ) ;
79
80
std:: process:: exit ( 0 ) ;
80
81
}
82
+
83
+ let target_fee_rate = FeeRate :: from_sat_per_vb ( 1 ) . unwrap ( ) ;
81
84
let mut tx_builder = wallet. build_tx ( ) ;
82
85
tx_builder. add_recipient ( address. script_pubkey ( ) , SEND_AMOUNT ) ;
86
+ tx_builder. fee_rate ( target_fee_rate) ;
83
87
84
88
let mut psbt = tx_builder. finish ( ) ?;
85
89
let finalized = wallet. sign ( & mut psbt, SignOptions :: default ( ) ) ?;
@@ -89,7 +93,7 @@ async fn main() -> Result<(), anyhow::Error> {
89
93
let tx = psbt. extract_tx ( ) ?;
90
94
client. broadcast ( & tx) . await ?;
91
95
let txid = tx. compute_txid ( ) ;
92
- println ! ( "Tx broadcasted! Txid: {txid}" ) ;
96
+ println ! ( "Tx broadcasted! Txid: https://mempool.space/testnet4/tx/ {txid}" ) ;
93
97
94
98
println ! ( "Partial Sync..." ) ;
95
99
print ! ( "SCANNING: " ) ;
@@ -109,9 +113,10 @@ async fn main() -> Result<(), anyhow::Error> {
109
113
let sync_update = client. sync ( sync_request, PARALLEL_REQUESTS ) . await ?;
110
114
println ! ( ) ;
111
115
wallet. apply_update ( sync_update) ?;
112
- wallet. persist ( & mut conn ) ?;
116
+ wallet. persist ( & mut db ) ?;
113
117
114
- let feerate = FeeRate :: from_sat_per_kwu ( tx_feerate. to_sat_per_kwu ( ) + 250 ) ;
118
+ // bump fee rate for tx by at least 1 sat per vbyte
119
+ let feerate = FeeRate :: from_sat_per_vb ( tx_feerate. to_sat_per_vb_ceil ( ) + 1 ) . unwrap ( ) ;
115
120
let mut builder = wallet. build_fee_bump ( txid) . expect ( "failed to bump tx" ) ;
116
121
builder. fee_rate ( feerate) ;
117
122
let mut bumped_psbt = builder. finish ( ) . unwrap ( ) ;
@@ -133,8 +138,14 @@ async fn main() -> Result<(), anyhow::Error> {
133
138
new_fee > original_fee,
134
139
"New fee ({new_fee}) should be higher than original ({original_fee})" ,
135
140
) ;
141
+
142
+ // wait for first transaction to make it into the mempool and be indexed on mempool.space
143
+ sleep ( Duration :: from_secs ( 10 ) ) . await ;
136
144
client. broadcast ( & bumped_tx) . await ?;
137
- println ! ( "Broadcasted bumped tx. Txid: {}" , bumped_tx. compute_txid( ) ) ;
145
+ println ! (
146
+ "Broadcasted bumped tx. Txid: https://mempool.space/testnet4/tx/{}" ,
147
+ bumped_tx. compute_txid( )
148
+ ) ;
138
149
139
150
println ! ( "syncing after broadcasting bumped tx..." ) ;
140
151
print ! ( "SCANNING: " ) ;
@@ -155,26 +166,17 @@ async fn main() -> Result<(), anyhow::Error> {
155
166
156
167
let mut evicted_txs = Vec :: new ( ) ;
157
168
158
- let last_seen = wallet
159
- . tx_graph ( )
160
- . full_txs ( )
161
- . find ( |full_tx| full_tx. txid == txid)
162
- . map_or ( 0 , |full_tx| full_tx. last_seen . unwrap_or ( 0 ) ) ;
163
- if !evicted_txs
164
- . iter ( )
165
- . any ( |( evicted_txid, _) | evicted_txid == & txid)
166
- {
167
- evicted_txs. push ( ( txid, last_seen) ) ;
169
+ for ( txid, last_seen) in & sync_update. tx_update . evicted_ats {
170
+ evicted_txs. push ( ( * txid, * last_seen) ) ;
168
171
}
169
172
173
+ wallet. apply_update ( sync_update) ?;
174
+
170
175
if !evicted_txs. is_empty ( ) {
171
- let evicted_count = evicted_txs. len ( ) ;
172
- wallet. apply_evicted_txs ( evicted_txs) ;
173
- println ! ( "Applied {evicted_count} evicted transactions" ) ;
176
+ println ! ( "Applied {} evicted transactions" , evicted_txs. len( ) ) ;
174
177
}
175
178
176
- wallet. apply_update ( sync_update) ?;
177
- wallet. persist ( & mut conn) ?;
179
+ wallet. persist ( & mut db) ?;
178
180
179
181
let balance_after_sync = wallet. balance ( ) ;
180
182
println ! ( "Wallet balance after sync: {}" , balance_after_sync. total( ) ) ;
0 commit comments