Skip to content

Commit 6fea740

Browse files
Merge #36: Add test for sign_tx()
a1a1454 Add test for sign_tx (wszdexdrf) 43bd579 Add deserialize function for PSBT (wszdexdrf) 8d3c29b Change `automation.json` for signing tx. (wszdexdrf) Pull request description: Also made necessary changes to automation.json (for ledger devices). Add deserializing method for PSBT. ACKs for top commit: danielabrozzoni: utACK a1a1454 Tree-SHA512: 2d222006918c420d3d1cc21b7dc09494445791c10d067ba412551d419a3217e682ee73dce4fbc215cf8f1e20c32e828e1a3d76968e07999dfc0a8374ad93dd86
2 parents 6489251 + a1a1454 commit 6fea740

File tree

3 files changed

+77
-7
lines changed

3 files changed

+77
-7
lines changed

ci/automation.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"version": 1,
33
"rules": [
44
{
5-
"regexp": "Address \\(\\d/\\d\\)|Message hash \\(\\d/\\d\\)",
5+
"regexp": "Address \\(\\d/\\d\\)|Message hash \\(\\d/\\d\\)|Confirm|Fees|Review|Amount",
66
"actions": [
77
[ "button", 2, true ],
88
[ "button", 2, false ]
@@ -20,7 +20,7 @@
2020
]
2121
},
2222
{
23-
"regexp": "Approve|Sign",
23+
"regexp": "Approve|Sign|Accept",
2424
"actions": [
2525
[ "button", 3, true ],
2626
[ "button", 3, false ]

src/lib.rs

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,13 @@ pub mod types;
3737
mod tests {
3838
use crate::types;
3939
use crate::HWIClient;
40+
use std::collections::BTreeMap;
4041
use std::str::FromStr;
4142

42-
use bitcoin::util::bip32::DerivationPath;
43+
use bitcoin::psbt::{Input, Output};
44+
use bitcoin::util::bip32::{DerivationPath, KeySource};
45+
use bitcoin::{secp256k1, Transaction};
46+
use bitcoin::{TxIn, TxOut};
4347

4448
#[test]
4549
#[serial]
@@ -145,10 +149,66 @@ mod tests {
145149
// #[serial]
146150
// fn test_display_address_with_path_taproot() {}
147151

148-
// TODO: Create PSBT with scratch using given Hardware Wallet
149-
// #[test]
150-
// #[serial]
151-
// fn test_sign_tx() {}
152+
#[test]
153+
#[serial]
154+
fn test_sign_tx() {
155+
let devices = HWIClient::enumerate().unwrap();
156+
let device = devices.first().unwrap();
157+
let client = HWIClient::get_client(device, true, types::HWIChain::Test).unwrap();
158+
let derivation_path = DerivationPath::from_str("m/44'/1'/0'/0/0").unwrap();
159+
160+
let address = client
161+
.display_address_with_path(&derivation_path, types::HWIAddressType::Legacy)
162+
.unwrap();
163+
164+
let pk = client.get_xpub(&derivation_path, true).unwrap();
165+
let mut hd_keypaths: BTreeMap<secp256k1::PublicKey, KeySource> = Default::default();
166+
// Here device fingerprint is same as master xpub fingerprint
167+
hd_keypaths.insert(pk.public_key, (device.fingerprint, derivation_path));
168+
169+
let previous_tx = Transaction {
170+
version: 1,
171+
lock_time: 0,
172+
input: vec![TxIn::default()],
173+
output: vec![TxOut {
174+
value: 100,
175+
script_pubkey: address.address.script_pubkey(),
176+
}],
177+
};
178+
179+
let previous_txin = TxIn {
180+
previous_output: bitcoin::OutPoint {
181+
txid: previous_tx.txid(),
182+
vout: Default::default(),
183+
},
184+
..Default::default()
185+
};
186+
let psbt = bitcoin::psbt::PartiallySignedTransaction {
187+
unsigned_tx: Transaction {
188+
version: 1,
189+
lock_time: 0,
190+
input: vec![previous_txin],
191+
output: vec![TxOut {
192+
value: 50,
193+
script_pubkey: address.address.script_pubkey(),
194+
}],
195+
},
196+
xpub: Default::default(),
197+
version: Default::default(),
198+
proprietary: Default::default(),
199+
unknown: Default::default(),
200+
201+
inputs: vec![Input {
202+
non_witness_utxo: Some(previous_tx),
203+
witness_utxo: None,
204+
bip32_derivation: hd_keypaths,
205+
..Default::default()
206+
}],
207+
outputs: vec![Output::default()],
208+
};
209+
let client = get_first_device();
210+
client.sign_tx(&psbt).unwrap();
211+
}
152212

153213
#[test]
154214
#[serial]

src/types.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,19 @@ pub struct HWIAddress {
4949

5050
#[derive(Clone, Eq, PartialEq, Debug, Deserialize)]
5151
pub struct HWIPartiallySignedTransaction {
52+
#[serde(deserialize_with = "deserialize_psbt")]
5253
pub psbt: PartiallySignedTransaction,
5354
}
5455

56+
fn deserialize_psbt<'de, D: Deserializer<'de>>(
57+
d: D,
58+
) -> Result<PartiallySignedTransaction, D::Error> {
59+
let b64_string = String::deserialize(d)?;
60+
let bytes = bitcoin::base64::decode(&b64_string).map_err(serde::de::Error::custom)?;
61+
bitcoin::consensus::deserialize::<PartiallySignedTransaction>(&bytes[..])
62+
.map_err(serde::de::Error::custom)
63+
}
64+
5565
impl Deref for HWIPartiallySignedTransaction {
5666
type Target = PartiallySignedTransaction;
5767

0 commit comments

Comments
 (0)