iop_sdk_wasm/hydra/private.rs
1use super::*;
2
3/// Private keys of a Hydra account in a vault.
4///
5/// @see HydraPlugin.priv
6#[wasm_bindgen(js_name = HydraPrivate)]
7pub struct JsHydraPrivate {
8 inner: HydraPrivate,
9}
10
11#[wasm_bindgen(js_class = HydraPrivate)]
12impl JsHydraPrivate {
13 /// Access to the public keys of the account. Same as {@link HydraPlugin.pub} would return.
14 #[wasm_bindgen(getter = pub)]
15 pub fn public(&self) -> JsHydraPublic {
16 let inner = self.inner.public();
17 JsHydraPublic::from(inner)
18 }
19
20 /// Name of the network this account belongs to.
21 #[wasm_bindgen(getter)]
22 pub fn network(&self) -> String {
23 self.inner.network().subtree().name().to_owned()
24 }
25
26 /// Calculates the receiving address having the given index and takes note that the address was already generated in the account.
27 ///
28 /// @see Bip44Account.key, Bip44Account.chain
29 pub fn key(&mut self, idx: i32) -> Result<JsBip44Key, JsValue> {
30 let inner = self.inner.key_mut(idx).map_err_to_js()?;
31 Ok(JsBip44Key::from(inner))
32 }
33
34 /// Finds the {@link Bip44Key} private api that belongs to the given {@link SecpPublicKey}. You can check the index of the key or
35 /// get the actual {@link SecpPrivateKey} from the returned object.
36 ///
37 /// Throws an error if the public key is not in this account, which can also happen when the key was derived outside the vault and
38 /// therefore the vault does not know it was already used. In that case, make sure to "touch" the last key index used by calling
39 /// {@link key} before calling this method.
40 #[wasm_bindgen(js_name = keyByPublicKey)]
41 pub fn key_by_pk(&self, id: &JsSecpPublicKey) -> Result<JsBip44Key, JsValue> {
42 let inner = self.inner.key_by_pk(id.inner()).map_err_to_js()?;
43 Ok(JsBip44Key::from(inner))
44 }
45
46 /// The extended public key for auditing the whole Bip44 account or deriving new public keys outside the vault.
47 #[wasm_bindgen(getter)]
48 pub fn xpub(&self) -> Result<String, JsValue> {
49 let res = self.inner().xpub().map_err_to_js()?;
50 Ok(res)
51 }
52
53 /// The extended private key for the whole account. This is only for exporting into other BIP32 compatible wallets.
54 ///
55 /// This is a secret that must not be kept unencrypted in transit or in rest!
56 #[wasm_bindgen(getter)]
57 pub fn xprv(&self) -> String {
58 self.inner().xprv()
59 }
60
61 /// How many receive addresses have been used in this {@link Bip44Account}
62 #[wasm_bindgen(getter = receiveKeys)]
63 pub fn receive_keys(&self) -> Result<u32, JsValue> {
64 let res = self.inner().receive_keys().map_err_to_js()?;
65 Ok(res)
66 }
67
68 /// How many change addresses have been used in this {@link Bip44Account}
69 #[wasm_bindgen(getter = changeKeys)]
70 pub fn change_keys(&self) -> Result<u32, JsValue> {
71 let res = self.inner().change_keys().map_err_to_js()?;
72 Ok(res)
73 }
74
75 /// Signs the Hydra transaction with the private key that belongs to the given P2PKH address.
76 ///
77 /// Fills in signature and id fields, so those can be missing in the unsigned input, but the public key needs to be already
78 /// properly set to the one matching the signer address.
79 ///
80 /// Throws an error if the address is not in this account, which can also happen when the key was derived outside the vault and
81 /// therefore the vault does not know it was already used. In that case, make sure to "touch" the last key index used by calling
82 /// {@link key} before calling this method.
83 #[wasm_bindgen(js_name = signHydraTransaction)]
84 pub fn sign_hydra_transaction(&self, hyd_addr: &str, tx: &JsValue) -> Result<JsValue, JsValue> {
85 let mut tx: HydraTransactionData =
86 tx.into_serde().with_context(|| "Parsing ITransactionData").map_err_to_js()?;
87 self.inner
88 .sign_hydra_transaction(hyd_addr, &mut tx)
89 .context("Signing ITransactionData")
90 .map_err_to_js()?;
91 let signed_tx =
92 JsValue::from_serde(&tx).context("Serializing ITransactionData").map_err_to_js()?;
93 Ok(signed_tx)
94 }
95}
96
97impl From<HydraPrivate> for JsHydraPrivate {
98 fn from(inner: HydraPrivate) -> Self {
99 Self { inner }
100 }
101}
102
103impl Wraps<HydraPrivate> for JsHydraPrivate {
104 fn inner(&self) -> &HydraPrivate {
105 &self.inner
106 }
107}