keymaster_multisig/
lib.rs1mod error;
2mod multisig;
3mod types;
4mod version;
5
6pub use error::{MultisigError, Result};
7pub use multisig::Multisig;
8pub use types::*;
9pub use version::{PROTOCOL, PROTOCOL_VERSION, RELEASE_VERSION, VERSION};
10
11use serde_wasm_bindgen as swbg;
12use wasm_bindgen::prelude::*;
13
14#[wasm_bindgen]
15pub fn create_multisig(
16 private_keys: JsValue,
17 public_keys: JsValue,
18 m: usize,
19) -> std::result::Result<MultisigWasm, JsValue> {
20 let pub_keys: Vec<PublicKey> = swbg::from_value(public_keys)?;
21 let priv_keys: Option<Vec<PrivateKey>> = swbg::from_value(private_keys).ok();
22
23 let multisig =
24 Multisig::new(priv_keys, pub_keys, m).map_err(|e| JsValue::from_str(&e.to_string()))?;
25
26 Ok(MultisigWasm { multisig })
27}
28
29#[wasm_bindgen]
30pub fn create_locking_script(
31 public_keys: JsValue,
32 m: usize,
33) -> std::result::Result<JsValue, JsValue> {
34 let pub_keys: Vec<PublicKey> = swbg::from_value(public_keys)?;
35
36 if m == 0 || m > pub_keys.len() {
37 return Err(JsValue::from_str("Invalid m value"));
38 }
39 if pub_keys.is_empty() || pub_keys.len() > 20 {
40 return Err(JsValue::from_str("Invalid public keys"));
41 }
42
43 let mut script = vec![0x01 + (m as u8) - 1];
44
45 for pub_key in &pub_keys {
46 script.push(pub_key.key.len() as u8);
47 script.extend(&pub_key.key);
48 }
49
50 script.push(0x01 + (pub_keys.len() as u8) - 1);
51 script.push(0xae);
52
53 Ok(swbg::to_value(&script)?)
54}
55
56#[wasm_bindgen]
57pub fn estimate_multisig_length(m: usize) -> usize {
58 1 + m * (71 + 1)
59}
60
61#[wasm_bindgen]
62pub struct MultisigWasm {
63 multisig: Multisig,
64}
65
66#[wasm_bindgen]
67impl MultisigWasm {
68 #[wasm_bindgen(constructor)]
69 pub fn new(
70 private_keys: JsValue,
71 public_keys: JsValue,
72 m: usize,
73 ) -> std::result::Result<MultisigWasm, JsValue> {
74 create_multisig(private_keys, public_keys, m)
75 }
76
77 pub fn lock(&self) -> std::result::Result<JsValue, JsValue> {
78 let script = self
79 .multisig
80 .lock()
81 .map_err(|e| JsValue::from_str(&e.to_string()))?;
82 Ok(swbg::to_value(&script)?)
83 }
84
85 pub fn sign(
86 &self,
87 transaction: JsValue,
88 input_index: usize,
89 ) -> std::result::Result<JsValue, JsValue> {
90 let tx: Transaction = swbg::from_value(transaction)?;
91 let signatures = self
92 .multisig
93 .sign(&tx, input_index)
94 .map_err(|e| JsValue::from_str(&e.to_string()))?;
95 Ok(swbg::to_value(&signatures)?)
96 }
97
98 pub fn sign_one(
99 &self,
100 transaction: JsValue,
101 input_index: usize,
102 private_key: JsValue,
103 ) -> std::result::Result<JsValue, JsValue> {
104 let tx: Transaction = swbg::from_value(transaction)?;
105 let priv_key: PrivateKey = swbg::from_value(private_key)?;
106
107 let signature = self
108 .multisig
109 .sign_one(&tx, input_index, &priv_key)
110 .map_err(|e| JsValue::from_str(&e.to_string()))?;
111 Ok(swbg::to_value(&signature)?)
112 }
113
114 pub fn estimate_length(&self) -> usize {
115 self.multisig.estimate_length()
116 }
117
118 pub fn create_fake_sign(&self) -> std::result::Result<JsValue, JsValue> {
119 let script = self
120 .multisig
121 .create_fake_sign()
122 .map_err(|e| JsValue::from_str(&e.to_string()))?;
123 Ok(swbg::to_value(&script)?)
124 }
125
126 pub fn build_sign_script(&self, signatures: JsValue) -> std::result::Result<JsValue, JsValue> {
127 let sigs: Vec<Vec<u8>> = swbg::from_value(signatures)?;
128 let script = self
129 .multisig
130 .build_sign_script(&sigs)
131 .map_err(|e| JsValue::from_str(&e.to_string()))?;
132 Ok(swbg::to_value(&script)?)
133 }
134
135 pub fn get_m(&self) -> usize {
136 self.multisig.get_m()
137 }
138
139 pub fn get_n(&self) -> usize {
140 self.multisig.get_n()
141 }
142
143 pub fn get_sig_hash_type(&self) -> u8 {
144 self.multisig.get_sig_hash_type()
145 }
146}
147
148#[wasm_bindgen(start)]
149pub fn main() {
150 console_error_panic_hook::set_once();
151}
152
153#[wasm_bindgen]
154extern "C" {
155 #[wasm_bindgen(js_namespace = console)]
156 fn error(s: &str);
157}