Skip to content

Commit fd7b5be

Browse files
authored
fix: retry mechanism (MetaMask#77)
1 parent 047cc82 commit fd7b5be

File tree

7 files changed

+45
-53
lines changed

7 files changed

+45
-53
lines changed

Cargo.lock

Lines changed: 0 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,12 @@ wasm-bindgen-futures = { version = "0.4.50", optional = true }
3434
anyhow = { version = "1.0.98", default-features = false }
3535
serde = { version = "1.0.219", default-features = false, features = ["derive"] }
3636
serde-wasm-bindgen = "0.6.5"
37-
web-sys = { version = "0.3.77", default-features = false }
37+
web-sys = { version = "0.3.77", default-features = false, features = [
38+
"Window",
39+
] }
3840

3941
# Compatibility to compile to WASM
4042
getrandom = { version = "0.2.16", features = ["js"] }
41-
gloo-timers = { version = "0.3.0", features = ["futures"] }
4243

4344
# Bitcoin dependencies
4445
bdk_wallet = { version = "2.0.0" }

src/bitcoin/esplora_client.rs

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,25 @@ use bdk_wallet::{
66
chain::spk_client::{FullScanRequest as BdkFullScanRequest, SyncRequest as BdkSyncRequest},
77
KeychainKind,
88
};
9-
use wasm_bindgen::prelude::wasm_bindgen;
9+
use wasm_bindgen::{
10+
prelude::{wasm_bindgen, Closure},
11+
JsCast, JsValue,
12+
};
13+
use wasm_bindgen_futures::JsFuture;
14+
use web_sys::js_sys::{Function, Promise};
1015

1116
use crate::{
1217
result::JsResult,
1318
types::{FeeEstimates, FullScanRequest, SyncRequest, Transaction, Txid, Update},
1419
};
15-
use std::time::Duration;
20+
use std::{
21+
future::Future,
22+
pin::Pin,
23+
task::{Context, Poll},
24+
time::Duration,
25+
};
1626

1727
use bdk_esplora::esplora_client::Sleeper;
18-
use gloo_timers::future::{sleep, TimeoutFuture};
19-
20-
use crate::utils::SendSyncWrapper;
2128

2229
#[wasm_bindgen]
2330
pub struct EsploraClient {
@@ -27,8 +34,10 @@ pub struct EsploraClient {
2734
#[wasm_bindgen]
2835
impl EsploraClient {
2936
#[wasm_bindgen(constructor)]
30-
pub fn new(url: &str) -> JsResult<EsploraClient> {
31-
let client = Builder::new(url).build_async_with_sleeper::<WebSleeper>()?;
37+
pub fn new(url: &str, max_retries: usize) -> JsResult<EsploraClient> {
38+
let client = Builder::new(url)
39+
.max_retries(max_retries)
40+
.build_async_with_sleeper::<WebSleeper>()?;
3241
Ok(EsploraClient { client })
3342
}
3443

@@ -65,13 +74,34 @@ impl EsploraClient {
6574
}
6675
}
6776

68-
#[derive(Clone)]
77+
struct WebSleep(JsFuture);
78+
79+
impl Future for WebSleep {
80+
type Output = ();
81+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
82+
// delegate to the inner JsFuture
83+
Pin::new(&mut self.get_mut().0).poll(cx).map(|_| ())
84+
}
85+
}
86+
87+
// SAFETY: Wasm is single-threaded; the value is never accessed concurrently.
88+
unsafe impl Send for WebSleep {}
89+
90+
#[derive(Clone, Copy)]
6991
struct WebSleeper;
7092

7193
impl Sleeper for WebSleeper {
72-
type Sleep = SendSyncWrapper<TimeoutFuture>;
94+
type Sleep = WebSleep;
7395

7496
fn sleep(dur: Duration) -> Self::Sleep {
75-
SendSyncWrapper(sleep(dur))
97+
let ms = dur.as_millis() as i32;
98+
let promise = Promise::new(&mut |resolve, _reject| {
99+
let cb = Closure::once_into_js(move || resolve.call0(&JsValue::NULL).unwrap());
100+
web_sys::window()
101+
.unwrap()
102+
.set_timeout_with_callback_and_timeout_and_arguments_0(cb.unchecked_ref::<Function>(), ms)
103+
.unwrap();
104+
});
105+
WebSleep(JsFuture::from(promise))
76106
}
77107
}

src/utils/future.rs

Lines changed: 0 additions & 24 deletions
This file was deleted.

src/utils/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
mod descriptor;
2-
mod future;
32

43
#[cfg(feature = "debug")]
54
mod panic_hook;
65
pub mod result;
76

87
pub use descriptor::*;
9-
pub use future::SendSyncWrapper;
108

119
#[cfg(feature = "debug")]
1210
pub use panic_hook::set_panic_hook;

tests/browser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ async fn test_browser() {
2323
"wpkh(tprv8ZgxMBicQKsPe2qpAuh1K1Hig72LCoP4JgNxZM2ZRWHZYnpuw5oHoGBsQm7Qb8mLgPpRJVn3hceWgGQRNbPD6x1pp2Qme2YFRAPeYh7vmvE/84'/1'/0'/0/*)#a6kgzlgq".into(),
2424
"wpkh(tprv8ZgxMBicQKsPe2qpAuh1K1Hig72LCoP4JgNxZM2ZRWHZYnpuw5oHoGBsQm7Qb8mLgPpRJVn3hceWgGQRNbPD6x1pp2Qme2YFRAPeYh7vmvE/84'/1'/0'/1/*)#vwnfl2cc".into(),
2525
).expect("wallet");
26-
let blockchain_client = EsploraClient::new("https://mutinynet.com/api").expect("esplora_client");
26+
let blockchain_client = EsploraClient::new("https://mutinynet.com/api", 6).expect("esplora_client");
2727

2828
let block_height = wallet.latest_checkpoint().height();
2929
assert_eq!(block_height, 0);

tests/node/integration/esplora.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ describe("Esplora client", () => {
2828

2929
let feeRate: FeeRate;
3030
let wallet: Wallet;
31-
const esploraClient = new EsploraClient(esploraUrl);
31+
const esploraClient = new EsploraClient(esploraUrl, 0);
3232

3333
it("creates a new wallet", () => {
3434
wallet = Wallet.create(network, externalDescriptor, internalDescriptor);

0 commit comments

Comments
 (0)