iop_keyvault_wasm/
lib.rs

1#![warn(missing_docs)]
2#![deny(rustdoc::broken_intra_doc_links)]
3
4//! # Keyvault
5//!
6//! Keyvault is a general purpose hierarchical deterministic (HD) generator for asymmetric keys.
7//! It is based on the same concepts as a Bitcoin HD-wallet and is built on the same specifications like
8//! [HD wallets of Bip32](https://en.bitcoin.it/wiki/BIP_0032),
9//! [Mnemonic word lists of Bip39](https://en.bitcoin.it/wiki/BIP_0039) and
10//! [Purpose fields of Bip43](https://en.bitcoin.it/wiki/BIP_0043).
11//!
12//! Though keyvault is capable of generating wallet addresses as defined in
13//! [Multi-Account cryptocurrency wallets of Bip44](https://en.bitcoin.it/wiki/BIP_0044),
14//! it is not only an address generator for multiple cryptocurrencies.
15//! Keyvault can also derive all the keys you might need in other software stacks
16//! and aims to be your all-in-one Swiss Army knife identity manager.
17//!
18//! Keyvault can
19//!
20//! - use the same seed to derive keys with multiple cipher suites, currently `ed25519` and `secp256k1`
21//! - use any purpose field and account hierarchy, not only Bip43 and Bip44
22//! - handle several purposes (i.e. attached subhierarchies) at the same time
23//! - be used from other platforms via its C and WebAssembly bindings
24//!
25//! Keyvault was originally created as part of the
26//! [Mercury communication protocol](https://github.com/Internet-of-People/mercury-rust)
27//! but being a general-purpose tool it was reused in other components as well,
28//! hence was separated into [its own repository](https://github.com/Internet-of-People/keyvault-rust) then finally merged into this monorepository.
29//!
30//! **This documentation is optimized for reading after it is copied into JSDoc**
31//!
32//! For more information on this crate and potential usage, see the [IOP developer site].
33//!
34//! [IOP developer site]: https://developer.iop.technology/glossary?id=multicipher
35
36// NOTE Always receive function arguments as references (as long as bindgen allows)
37//      and return results by value. Otherwise the generated code may destroy
38//      JS variables by moving out underlying pointers.
39
40// sub-modules
41
42mod bip32;
43mod bip39;
44mod bip44;
45mod encrypt;
46mod id;
47mod morpheus;
48mod pk;
49mod seed;
50mod sig;
51mod sk;
52
53// exports
54
55pub use bip32::*;
56pub use bip39::*;
57pub use bip44::*;
58pub use encrypt::*;
59pub use id::*;
60pub use morpheus::*;
61pub use pk::*;
62pub use seed::*;
63pub use sig::*;
64pub use sk::*;
65
66// imports from standard library
67
68// imports from 3rd party crates
69
70use serde::Serialize;
71use wasm_bindgen::prelude::*;
72
73// imports from own crates
74
75use iop_keyvault::{
76    ed25519::*, encrypt as keyvault_encrypt, multicipher::*, secp256k1::*, Bip32, Bip32Node,
77    Bip32PublicNode, Bip39, Bip39Phrase, Bip44, Bip44Account, Bip44Coin, Bip44Key,
78    Bip44PublicAccount, Bip44PublicKey, Bip44PublicSubAccount, Bip44SubAccount, Chain, Networks,
79    PrivateKey as _, PublicKey as _, Seed,
80};
81
82// code
83
84/// Converts any error that can be converted into a string into a JavaScript error string
85/// usable by wasm_bindgen
86pub fn err_to_js<E: ToString>(e: E) -> JsValue {
87    JsValue::from(e.to_string())
88}
89
90/// An extension trait on [`Result`] that helps easy conversion of Rust errors to JavaScript
91/// error strings usable by wasm_bindgen
92pub trait MapJsError<T> {
93    /// An extension method on [`Result`] to easily convert Rust errors to JavaScript ones.
94    ///
95    /// ```ignore
96    /// #[wasm_bindgen]
97    /// pub fn method(&self) -> Result<JsSomething, JsValue> {
98    ///     let result: JsSomething = self.fallible().map_err_to_js()?;
99    ///     Ok(result)
100    /// }
101    /// ```
102    fn map_err_to_js(self) -> Result<T, JsValue>;
103}
104
105impl<T, E: ToString> MapJsError<T> for Result<T, E> {
106    fn map_err_to_js(self) -> Result<T, JsValue> {
107        self.map_err(err_to_js)
108    }
109}
110
111/// Most WASM types are wrapping a Rust type one-on-one. This trait helps to enforce a convention
112/// so that WASM types can easily peek under the hood of other such wrapped WASM types.
113///
114/// See also [`WrapsMut<T>`]
115pub trait Wraps<T>: From<T> {
116    /// Converts a reference to a WASM type to a reference to the underlying Rust type.
117    fn inner(&self) -> &T;
118}
119
120/// Most WASM types are wrapping a Rust type one-on-one. This trait helps to enforce a convention
121/// so that WASM types can easily peek under the hood of other such wrapped WASM types.
122///
123/// See also [`Wraps<T>`]
124pub trait WrapsMut<T>: Wraps<T> {
125    /// Converts an exclusive reference to a WASM type to an exclusive reference to the underlying Rust type.
126    fn inner_mut(&mut self) -> &mut T;
127}
128
129/// Free function that checks if a string is a valid network name usable as a parameter in some other calls.
130///
131/// @see allNetworkNames
132#[wasm_bindgen(js_name = validateNetworkName)]
133pub fn validate_network_name(name: &str) -> bool {
134    Networks::by_name(name).is_ok()
135}
136
137#[wasm_bindgen]
138extern "C" {
139    #[wasm_bindgen(typescript_type = "string[]")]
140    pub type IStringArray;
141}
142
143#[derive(Debug, Serialize)]
144#[serde(transparent)]
145struct NetworkNames(Vec<&'static str>);
146
147/// The list of all network names accepted by {@link validateNetworkName}
148#[wasm_bindgen(js_name = allNetworkNames)]
149pub fn all_network_names() -> IStringArray {
150    let names: Vec<&'static str> = Networks::ALL.iter().map(|n| n.name()).collect();
151    let array = JsValue::from_serde(&NetworkNames(names))
152        .expect("No object keyed maps in the object graph; qed");
153    array.into()
154}