Skip to content

Commit 344d195

Browse files
committed
chore(example): add example using async-hwi
1 parent 0cf9f28 commit 344d195

File tree

4 files changed

+112
-1
lines changed

4 files changed

+112
-1
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ members = [
55
"examples/example_wallet_electrum",
66
"examples/example_wallet_esplora_blocking",
77
"examples/example_wallet_esplora_async",
8-
"examples/example_wallet_rpc",
8+
"examples/example_wallet_rpc",
9+
"examples/example_wallet_hwi_signer",
910
]
1011

1112
[workspace.package]
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[package]
2+
name = "example_wallet_hwi_signer"
3+
version = "0.1.0"
4+
edition = "2021"
5+
authors.workspace = true
6+
7+
[features]
8+
simulator = []
9+
10+
[dependencies]
11+
bdk_wallet = { path = "../../wallet", features = ["file_store", "test-utils"] }
12+
tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
13+
# Once the next release happens on crates.io we can update here
14+
async-hwi = { git = "https://github.com/wizardsardine/async-hwi", branch = "master"}
15+
anyhow = "1"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Example signing with HWI Interface
2+
3+
4+
## Requirements
5+
6+
sudo apt install libudev-dev
7+
8+
## Build and run
9+
10+
`$ cargo run --bin example_wallet_hwi_signer`
11+
12+
## Running with simulator
13+
14+
Download a simulator at `https://github.com/BitBoxSwiss/bitbox02-firmware/releases/`.
15+
16+
Run the simulator and then run the example with `--features=simulator` enabled.
17+
18+
```sh
19+
20+
curl https://github.com/BitBoxSwiss/bitbox02-firmware/releases/download/firmware%2Fv9.19.0/bitbox02-multi-v9.19.0-simulator1.0.0-linux-amd64
21+
22+
./bitbox02-multi-v9.19.0-simulator1.0.0-linux-amd64
23+
24+
cargo run --bin example_wallet_hwi_signer --features simulator
25+
```
26+
27+
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
use async_hwi::bitbox::api::runtime::TokioRuntime;
2+
use async_hwi::bitbox::api::BitBox;
3+
use async_hwi::bitbox::NoiseConfigNoCache;
4+
use bdk_wallet::bitcoin::absolute::LockTime;
5+
use bdk_wallet::bitcoin::{Amount, FeeRate, Network};
6+
7+
use bdk_wallet::test_utils::get_funded_wallet;
8+
use async_hwi::{bitbox::BitBox02, HWI};
9+
use bdk_wallet::KeychainKind;
10+
11+
const SEND_AMOUNT: Amount = Amount::from_sat(5000);
12+
const NETWORK: Network = Network::Regtest;
13+
const EXTERNAL_DESC: &str = "wpkh(tprv8ZgxMBicQKsPdfCLpvozodGytD3gRUa1M5WQz4kNuDZVf1inhcsSHXRpyLWN3k3Qy3nucrzz5hw2iZiEs6spehpee2WxqfSi31ByRJEu4rZ/84h/1h/0h/0/*)";
14+
const INTERNAL_DESC: &str = "wpkh(tprv8ZgxMBicQKsPdfCLpvozodGytD3gRUa1M5WQz4kNuDZVf1inhcsSHXRpyLWN3k3Qy3nucrzz5hw2iZiEs6spehpee2WxqfSi31ByRJEu4rZ/84h/1h/0h/1/*)";
15+
16+
#[tokio::main]
17+
async fn main() -> Result<(), anyhow::Error> {
18+
19+
let (mut wallet, _) = get_funded_wallet(EXTERNAL_DESC, INTERNAL_DESC);
20+
21+
// Pairing with Bitbox connected Bitbox device
22+
let noise_config = Box::new(NoiseConfigNoCache {});
23+
24+
let bitbox = {
25+
#[cfg(feature = "simulator")]
26+
{
27+
BitBox::<TokioRuntime>::from_simulator(None, noise_config).await?
28+
}
29+
30+
#[cfg(not(feature = "simulator"))]
31+
{
32+
use async_hwi::bitbox::api::usb;
33+
BitBox::<TokioRuntime>::from_hid_device(usb::get_any_bitbox02().unwrap(), noise_config)
34+
.await?
35+
}
36+
};
37+
38+
let pairing_device = bitbox.unlock_and_pair().await?;
39+
let paired_device = pairing_device.wait_confirm().await?;
40+
41+
if let Ok(_) = paired_device.restore_from_mnemonic().await {
42+
println!("Initializing device with mnemonic...");
43+
} else {
44+
println!("Device already initialized proceeding...");
45+
}
46+
47+
let bb = BitBox02::from(paired_device);
48+
let bb = bb.with_network(NETWORK);
49+
50+
let receiving_address = wallet.next_unused_address(KeychainKind::External);
51+
52+
println!("Wallet balance {}", wallet.balance());
53+
54+
let mut tx_builder = wallet.build_tx();
55+
56+
tx_builder
57+
.add_recipient(receiving_address.script_pubkey(), SEND_AMOUNT)
58+
.fee_rate(FeeRate::from_sat_per_vb(2).unwrap())
59+
.nlocktime(LockTime::from_height(0).unwrap());
60+
61+
let mut psbt = tx_builder.finish()?;
62+
63+
// Sign with the connected bitbox or any hardware device
64+
bb.sign_tx(&mut psbt).await?;
65+
66+
println!("Signing with bitbox done. Balance After signing {}", wallet.balance());
67+
Ok(())
68+
}

0 commit comments

Comments
 (0)