@@ -17,7 +17,9 @@ use std::str::FromStr;
17
17
use bitcoin:: consensus:: { deserialize, serialize} ;
18
18
use bitcoin:: hashes:: hex:: FromHex ;
19
19
use bitcoin:: hashes:: { sha256, Hash } ;
20
- use bitcoin:: { Block , BlockHash , block:: Header as BlockHeader , MerkleBlock , Script , Transaction , Txid } ;
20
+ use bitcoin:: {
21
+ block:: Header as BlockHeader , Block , BlockHash , MerkleBlock , Script , Transaction , Txid ,
22
+ } ;
21
23
use bitcoin_internals:: hex:: display:: DisplayHex ;
22
24
23
25
#[ allow( unused_imports) ]
@@ -68,7 +70,14 @@ impl AsyncClient {
68
70
return Ok ( None ) ;
69
71
}
70
72
71
- Ok ( Some ( deserialize ( & resp. error_for_status ( ) ?. bytes ( ) . await ?) ?) )
73
+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
74
+ Err ( Error :: HttpResponse {
75
+ status : resp. status ( ) . as_u16 ( ) ,
76
+ message : resp. text ( ) . await ?,
77
+ } )
78
+ } else {
79
+ Ok ( Some ( deserialize ( & resp. bytes ( ) . await ?) ?) )
80
+ }
72
81
}
73
82
74
83
/// Get a [`Transaction`] given its [`Txid`].
@@ -96,7 +105,14 @@ impl AsyncClient {
96
105
return Ok ( None ) ;
97
106
}
98
107
99
- Ok ( Some ( Txid :: from_str ( & resp. text ( ) . await ?) ?) )
108
+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
109
+ Err ( Error :: HttpResponse {
110
+ status : resp. status ( ) . as_u16 ( ) ,
111
+ message : resp. text ( ) . await ?,
112
+ } )
113
+ } else {
114
+ Ok ( Some ( Txid :: from_str ( & resp. text ( ) . await ?) ?) )
115
+ }
100
116
}
101
117
102
118
/// Get the status of a [`Transaction`] given its [`Txid`].
@@ -106,8 +122,14 @@ impl AsyncClient {
106
122
. get ( & format ! ( "{}/tx/{}/status" , self . url, txid) )
107
123
. send ( )
108
124
. await ?;
109
-
110
- Ok ( resp. error_for_status ( ) ?. json ( ) . await ?)
125
+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
126
+ Err ( Error :: HttpResponse {
127
+ status : resp. status ( ) . as_u16 ( ) ,
128
+ message : resp. text ( ) . await ?,
129
+ } )
130
+ } else {
131
+ Ok ( resp. json ( ) . await ?)
132
+ }
111
133
}
112
134
113
135
#[ deprecated(
@@ -128,9 +150,15 @@ impl AsyncClient {
128
150
. send ( )
129
151
. await ?;
130
152
131
- let header = deserialize ( & Vec :: from_hex ( & resp. text ( ) . await ?) ?) ?;
132
-
133
- Ok ( header)
153
+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
154
+ Err ( Error :: HttpResponse {
155
+ status : resp. status ( ) . as_u16 ( ) ,
156
+ message : resp. text ( ) . await ?,
157
+ } )
158
+ } else {
159
+ let header = deserialize ( & Vec :: from_hex ( & resp. text ( ) . await ?) ?) ?;
160
+ Ok ( header)
161
+ }
134
162
}
135
163
136
164
/// Get the [`BlockStatus`] given a particular [`BlockHash`].
@@ -141,7 +169,14 @@ impl AsyncClient {
141
169
. send ( )
142
170
. await ?;
143
171
144
- Ok ( resp. error_for_status ( ) ?. json ( ) . await ?)
172
+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
173
+ Err ( Error :: HttpResponse {
174
+ status : resp. status ( ) . as_u16 ( ) ,
175
+ message : resp. text ( ) . await ?,
176
+ } )
177
+ } else {
178
+ Ok ( resp. json ( ) . await ?)
179
+ }
145
180
}
146
181
147
182
/// Get a [`Block`] given a particular [`BlockHash`].
@@ -155,7 +190,15 @@ impl AsyncClient {
155
190
if let StatusCode :: NOT_FOUND = resp. status ( ) {
156
191
return Ok ( None ) ;
157
192
}
158
- Ok ( Some ( deserialize ( & resp. error_for_status ( ) ?. bytes ( ) . await ?) ?) )
193
+
194
+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
195
+ Err ( Error :: HttpResponse {
196
+ status : resp. status ( ) . as_u16 ( ) ,
197
+ message : resp. text ( ) . await ?,
198
+ } )
199
+ } else {
200
+ Ok ( Some ( deserialize ( & resp. bytes ( ) . await ?) ?) )
201
+ }
159
202
}
160
203
161
204
/// Get a merkle inclusion proof for a [`Transaction`] with the given [`Txid`].
@@ -170,7 +213,14 @@ impl AsyncClient {
170
213
return Ok ( None ) ;
171
214
}
172
215
173
- Ok ( Some ( resp. error_for_status ( ) ?. json ( ) . await ?) )
216
+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
217
+ Err ( Error :: HttpResponse {
218
+ status : resp. status ( ) . as_u16 ( ) ,
219
+ message : resp. text ( ) . await ?,
220
+ } )
221
+ } else {
222
+ Ok ( Some ( resp. json ( ) . await ?) )
223
+ }
174
224
}
175
225
176
226
/// Get a [`MerkleBlock`] inclusion proof for a [`Transaction`] with the given [`Txid`].
@@ -185,9 +235,15 @@ impl AsyncClient {
185
235
return Ok ( None ) ;
186
236
}
187
237
188
- let merkle_block = deserialize ( & Vec :: from_hex ( & resp. text ( ) . await ?) ?) ?;
189
-
190
- Ok ( Some ( merkle_block) )
238
+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
239
+ Err ( Error :: HttpResponse {
240
+ status : resp. status ( ) . as_u16 ( ) ,
241
+ message : resp. text ( ) . await ?,
242
+ } )
243
+ } else {
244
+ let merkle_block = deserialize ( & Vec :: from_hex ( & resp. text ( ) . await ?) ?) ?;
245
+ Ok ( Some ( merkle_block) )
246
+ }
191
247
}
192
248
193
249
/// Get the spending status of an output given a [`Txid`] and the output index.
@@ -206,19 +262,33 @@ impl AsyncClient {
206
262
return Ok ( None ) ;
207
263
}
208
264
209
- Ok ( Some ( resp. error_for_status ( ) ?. json ( ) . await ?) )
265
+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
266
+ Err ( Error :: HttpResponse {
267
+ status : resp. status ( ) . as_u16 ( ) ,
268
+ message : resp. text ( ) . await ?,
269
+ } )
270
+ } else {
271
+ Ok ( Some ( resp. json ( ) . await ?) )
272
+ }
210
273
}
211
274
212
275
/// Broadcast a [`Transaction`] to Esplora
213
276
pub async fn broadcast ( & self , transaction : & Transaction ) -> Result < ( ) , Error > {
214
- self . client
277
+ let resp = self
278
+ . client
215
279
. post ( & format ! ( "{}/tx" , self . url) )
216
280
. body ( serialize ( transaction) . to_lower_hex_string ( ) )
217
281
. send ( )
218
- . await ?
219
- . error_for_status ( ) ?;
282
+ . await ?;
220
283
221
- Ok ( ( ) )
284
+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
285
+ Err ( Error :: HttpResponse {
286
+ status : resp. status ( ) . as_u16 ( ) ,
287
+ message : resp. text ( ) . await ?,
288
+ } )
289
+ } else {
290
+ Ok ( ( ) )
291
+ }
222
292
}
223
293
224
294
/// Get the current height of the blockchain tip
@@ -229,7 +299,14 @@ impl AsyncClient {
229
299
. send ( )
230
300
. await ?;
231
301
232
- Ok ( resp. error_for_status ( ) ?. text ( ) . await ?. parse ( ) ?)
302
+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
303
+ Err ( Error :: HttpResponse {
304
+ status : resp. status ( ) . as_u16 ( ) ,
305
+ message : resp. text ( ) . await ?,
306
+ } )
307
+ } else {
308
+ Ok ( resp. text ( ) . await ?. parse ( ) ?)
309
+ }
233
310
}
234
311
235
312
/// Get the [`BlockHash`] of the current blockchain tip.
@@ -240,9 +317,14 @@ impl AsyncClient {
240
317
. send ( )
241
318
. await ?;
242
319
243
- Ok ( BlockHash :: from_str (
244
- & resp. error_for_status ( ) ?. text ( ) . await ?,
245
- ) ?)
320
+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
321
+ Err ( Error :: HttpResponse {
322
+ status : resp. status ( ) . as_u16 ( ) ,
323
+ message : resp. text ( ) . await ?,
324
+ } )
325
+ } else {
326
+ Ok ( BlockHash :: from_str ( & resp. text ( ) . await ?) ?)
327
+ }
246
328
}
247
329
248
330
/// Get the [`BlockHash`] of a specific block height
@@ -257,9 +339,14 @@ impl AsyncClient {
257
339
return Err ( Error :: HeaderHeightNotFound ( block_height) ) ;
258
340
}
259
341
260
- Ok ( BlockHash :: from_str (
261
- & resp. error_for_status ( ) ?. text ( ) . await ?,
262
- ) ?)
342
+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
343
+ Err ( Error :: HttpResponse {
344
+ status : resp. status ( ) . as_u16 ( ) ,
345
+ message : resp. text ( ) . await ?,
346
+ } )
347
+ } else {
348
+ Ok ( BlockHash :: from_str ( & resp. text ( ) . await ?) ?)
349
+ }
263
350
}
264
351
265
352
/// Get confirmed transaction history for the specified address/scripthash,
@@ -278,27 +365,36 @@ impl AsyncClient {
278
365
) ,
279
366
None => format ! ( "{}/scripthash/{:x}/txs" , self . url, script_hash) ,
280
367
} ;
281
- Ok ( self
282
- . client
283
- . get ( url)
284
- . send ( )
285
- . await ?
286
- . error_for_status ( ) ?
287
- . json :: < Vec < Tx > > ( )
288
- . await ?)
368
+
369
+ let resp = self . client . get ( url) . send ( ) . await ?;
370
+
371
+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
372
+ Err ( Error :: HttpResponse {
373
+ status : resp. status ( ) . as_u16 ( ) ,
374
+ message : resp. text ( ) . await ?,
375
+ } )
376
+ } else {
377
+ Ok ( resp. json :: < Vec < Tx > > ( ) . await ?)
378
+ }
289
379
}
290
380
291
381
/// Get an map where the key is the confirmation target (in number of blocks)
292
382
/// and the value is the estimated feerate (in sat/vB).
293
383
pub async fn get_fee_estimates ( & self ) -> Result < HashMap < String , f64 > , Error > {
294
- Ok ( self
384
+ let resp = self
295
385
. client
296
386
. get ( & format ! ( "{}/fee-estimates" , self . url, ) )
297
387
. send ( )
298
- . await ?
299
- . error_for_status ( ) ?
300
- . json :: < HashMap < String , f64 > > ( )
301
- . await ?)
388
+ . await ?;
389
+
390
+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
391
+ Err ( Error :: HttpResponse {
392
+ status : resp. status ( ) . as_u16 ( ) ,
393
+ message : resp. text ( ) . await ?,
394
+ } )
395
+ } else {
396
+ Ok ( resp. json :: < HashMap < String , f64 > > ( ) . await ?)
397
+ }
302
398
}
303
399
304
400
/// Gets some recent block summaries starting at the tip or at `height` if provided.
@@ -311,14 +407,16 @@ impl AsyncClient {
311
407
None => format ! ( "{}/blocks" , self . url) ,
312
408
} ;
313
409
314
- Ok ( self
315
- . client
316
- . get ( & url)
317
- . send ( )
318
- . await ?
319
- . error_for_status ( ) ?
320
- . json ( )
321
- . await ?)
410
+ let resp = self . client . get ( & url) . send ( ) . await ?;
411
+
412
+ if resp. status ( ) . is_server_error ( ) || resp. status ( ) . is_client_error ( ) {
413
+ Err ( Error :: HttpResponse {
414
+ status : resp. status ( ) . as_u16 ( ) ,
415
+ message : resp. text ( ) . await ?,
416
+ } )
417
+ } else {
418
+ Ok ( resp. json :: < Vec < BlockSummary > > ( ) . await ?)
419
+ }
322
420
}
323
421
324
422
/// Get the underlying base URL.
0 commit comments