Skip to content

Commit 037b4c9

Browse files
custom wallet types
1 parent 885a377 commit 037b4c9

5 files changed

Lines changed: 179 additions & 75 deletions

File tree

packages/kos-web/Cargo.toml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,9 @@ version.workspace = true
1111
[lib]
1212
crate-type = ["cdylib", "rlib"]
1313

14-
[features]
15-
default = ["serde"]
16-
1714
[dependencies]
1815
strum = { version = "0.26.3", features = ["derive"] }
19-
serde = { workspace = true, features = ["derive"], optional = true }
16+
serde = { workspace = true, features = ["derive"] }
2017
serde_json = { workspace = true }
2118
serde-wasm-bindgen = "0.5"
2219
qrcode-generator = "4.1"

packages/kos-web/src/error.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,6 @@ impl KOSError {
2121
pub fn get_message(&self) -> String {
2222
self.message.clone()
2323
}
24-
25-
#[wasm_bindgen(js_name = toString)]
26-
pub fn to_string(&self) -> String {
27-
self.message.clone()
28-
}
2924
}
3025

3126
impl KOSError {

packages/kos-web/src/lib.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ impl KOSTransaction {
123123

124124
#[wasm_bindgen]
125125
pub fn generate_mnemonic(size: i32) -> Result<String, KOSError> {
126+
if size < 0 {
127+
return Err(KOSError::kos_delegate("invalid mnemonic".to_string()));
128+
}
126129
Ok(kos::crypto::mnemonic::generate_mnemonic(size as usize)?.to_phrase())
127130
}
128131

@@ -295,11 +298,8 @@ pub fn sign_message(account: KOSAccount, hex: String, legacy: bool) -> Result<Ve
295298

296299
let message_encoded = kos_codec::encode_for_sign_message(kos_codec_acc, message)?;
297300

298-
let signature = chain.sign_message(
299-
hex::decode(account.private_key).unwrap(),
300-
message_encoded,
301-
legacy,
302-
)?;
301+
let signature =
302+
chain.sign_message(hex::decode(account.private_key)?, message_encoded, legacy)?;
303303
Ok(signature)
304304
}
305305

@@ -683,7 +683,7 @@ mod tests {
683683
simple_base64_encode(&hex::decode("76a9145bb0ba5ba58cdab459f27f2d29f40e1dd5db238188ac").unwrap()),
684684
simple_base64_encode(&hex::decode("76a9145bb0ba5ba58cdab459f27f2d29f40e1dd5db238188ac").unwrap()),
685685
],
686-
)),
686+
).unwrap()),
687687
)
688688
.unwrap();
689689
assert_eq!(transaction.raw, "0100000002afa8838dbaa03cd3e4fee38bdcb6a428965559ae941dca5a8f91999cfd6d8b0d010000006b48304502210099626d28374fa3d1a0034330fee7745ab02db07cd37649e6d3ffbe046ff92e9402203793bee2372ab59a05b45188c2bace3b48e73209a01e4d5d862925971632c80a412102bbe7dbcdf8b2261530a867df7180b17a90b482f74f2736b8a30d3f756e42e217ffffffffdb6d60d4a93a95738e72f641bcdd166c94f6e1f439dfe695e40583997284463c010000006a4730440220447084aae4c6800db7c86b8bc8da675e464991a035b2b4010cde48b64a1013a10220582acfb5265c22eae9c2880e07ae66fc86cbef2e97a2ca1bc513535ba322360d412102bbe7dbcdf8b2261530a867df7180b17a90b482f74f2736b8a30d3f756e42e217ffffffff0240420f00000000001976a91434bf902df5d66f0e9b89d0f83fbcad638ad19ae988acea970700000000001976a9145bb0ba5ba58cdab459f27f2d29f40e1dd5db238188ac00000000", "The raw doesn't match");
@@ -703,7 +703,7 @@ mod tests {
703703
simple_base64_encode(&hex::decode("0014546d5f8e86641e4d1eec5b9155a540d953245e4a").unwrap()),
704704
simple_base64_encode(&hex::decode("0014546d5f8e86641e4d1eec5b9155a540d953245e4a").unwrap()),
705705
],
706-
)),
706+
).unwrap()),
707707
)
708708
.unwrap();
709709
assert_eq!(transaction.raw, "01000000000102badfa0606bc6a1738d8ddf951b1ebf9e87779934a5774b836668efb5a6d643970000000000fffffffffe60fbeb66791b10c765a207c900a08b2a9bd7ef21e1dd6e5b2ef1e9d686e5230000000000ffffffff028813000000000000160014e4132ab9175345e24b344f50e6d6764a651a89e6c21f000000000000160014546d5f8e86641e4d1eec5b9155a540d953245e4a02483045022100ca1df8381e56e2ac2228e040cc2ff1c1079928222365f5c62cd6c18f398a6f55022029dca1177ab6edcfa03a25c7df32e1644c5d1fe496c6c7995a715373b56a591901210330d54fd0dd420a6e5f8d3624f5f3482cae350f79d5f0753bf5beef9c2d91af3c024830450221009496122a56551a0dab4fa8562474c943c79158f7592a845abd7b60ddf34c10c902205021b73e27a44b0c365fbd015133a4bb6dce79dd09705096de1c7b31a1f9b8a701210330d54fd0dd420a6e5f8d3624f5f3482cae350f79d5f0753bf5beef9c2d91af3c00000000", "The raw doesn't match");
@@ -722,7 +722,7 @@ mod tests {
722722
vec![
723723
simple_base64_encode(&hex::decode("76a914be4232b46086c1d46d12c65eacbd807e87b92a5488ac").unwrap()),
724724
],
725-
)),
725+
).unwrap()),
726726
)
727727
.unwrap();
728728
assert_eq!(transaction.raw, "0100000001c2c12c2f80249f568cf90ffd87d47afbbed81e803d2a7076c554e81b73253ab5000000006a4730440220423d61c364084d0c24f155519d4991549b1090bdd65ac6c74ebc6f3917d5dff6022056c3af1de9b4e33369dcd134591a80554ce5a108c300bc0cc2ed4c11d0a6861c0121026fa9a6f213b6ba86447965f6b4821264aaadd7521f049f00db9c43a770ea7405ffffffff02e8030000000000001976a914a3d92f1bab64bb8154ed118cd27fb5081344ca8488ac04580f00000000001976a914be4232b46086c1d46d12c65eacbd807e87b92a5488ac00000000", "The raw doesn't match");
@@ -746,7 +746,7 @@ mod tests {
746746
vec![
747747
simple_base64_encode(&hex::decode("76a91479975a24fdab613e17cf184bc185071aad17441888ac").unwrap()),
748748
],
749-
)),
749+
).unwrap()),
750750
)
751751
.unwrap();
752752
assert_eq!(transaction.raw, "0100000001c4d32b8d271b3d4c7c269f2af31f87ad71315b72610744843bca92600c6c662d030000006a4730440220198e150a394004850b0ab50423ab583e7b4a7fdb12f6ff98849ed532a8b8f5fc02202cfea08c49254a1b245cf9f460d596812e0f4dd0d1ddb1f008fe01d52f3d74f7012102cc6b0dc33aabcf3a23643e5e2919a80c50fb3dd2129ce409bbc5f0d4643d05e0feffffff01f98b1acc0e0000001976a9146dc8f8d77f0d1ea8c42f2374e5b3abbb77fda44f88ac00000000", "The raw doesn't match");
@@ -770,7 +770,8 @@ mod tests {
770770
15,
771771
None,
772772
None,
773-
);
773+
)
774+
.unwrap();
774775
let transaction = sign_transaction(
775776
account,
776777
"0a0300b8c8ac77e723fae060f2dc70d00a591e1127ec07e0e81e2237a823cbe5210d1e02286bee05011800000082841e000f00000068d56f15f85d3136970ec16946040bc1752654e906147f7e43e9d539d7c3de2f781cf57533b15a5a13729a33543fd6ae137bce54ef14eb933b0a4813489e7e0a00".to_string(),

packages/kos-web/src/models.rs

Lines changed: 147 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,51 +3,108 @@ use kos::chains::{ChainOptions, CustomChainType};
33
use kos::crypto::base64;
44
use wasm_bindgen::prelude::*;
55

6-
#[wasm_bindgen]
7-
#[derive(Debug, Clone, Copy, PartialEq)]
6+
use crate::error::KOSError;
7+
8+
#[derive(Debug, Clone, PartialEq)]
89
pub enum WalletChainOptionsType {
9-
None,
10-
CustomEth,
11-
CustomIcp,
10+
NotCustom(u32),
11+
NotCustomBase(u32),
12+
CustomEth(u32),
13+
CustomSubstrate(u32),
14+
CustomCosmos(String),
15+
CustomIcp(String),
1216
}
1317

1418
#[wasm_bindgen]
1519
#[derive(Debug, Clone)]
1620
pub struct WalletChainOptions {
17-
pub kind: WalletChainOptionsType,
18-
pub chain_id: u32, // used when kind == CustomEth
19-
key_type: String, // used when kind == CustomIcp ("ed25519" | "secp256k1")
21+
kind: WalletChainOptionsType,
2022
}
2123

2224
#[wasm_bindgen]
2325
impl WalletChainOptions {
26+
#[wasm_bindgen(getter)]
27+
pub fn variant_type(&self) -> String {
28+
match &self.kind {
29+
WalletChainOptionsType::NotCustom(_) => "NotCustom".to_string(),
30+
WalletChainOptionsType::NotCustomBase(_) => "NotCustomBase".to_string(),
31+
WalletChainOptionsType::CustomEth(_) => "CustomEth".to_string(),
32+
WalletChainOptionsType::CustomSubstrate(_) => "CustomSubstrate".to_string(),
33+
WalletChainOptionsType::CustomCosmos(_) => "CustomCosmos".to_string(),
34+
WalletChainOptionsType::CustomIcp(_) => "CustomIcp".to_string(),
35+
}
36+
}
37+
2438
#[wasm_bindgen(getter)]
2539
pub fn key_type(&self) -> String {
26-
self.key_type.clone()
40+
match &self.kind {
41+
WalletChainOptionsType::CustomIcp(key_type) => key_type.clone(),
42+
_ => String::new(),
43+
}
2744
}
2845

29-
#[wasm_bindgen(setter)]
30-
pub fn set_key_type(&mut self, val: String) {
31-
self.key_type = val;
46+
#[wasm_bindgen(getter)]
47+
pub fn chain_id(&self) -> u32 {
48+
match &self.kind {
49+
WalletChainOptionsType::NotCustom(id) => *id,
50+
WalletChainOptionsType::NotCustomBase(id) => *id,
51+
WalletChainOptionsType::CustomEth(id) => *id,
52+
WalletChainOptionsType::CustomSubstrate(id) => *id,
53+
_ => 0,
54+
}
55+
}
56+
57+
#[wasm_bindgen(getter)]
58+
pub fn cosmos_chain_id(&self) -> String {
59+
match &self.kind {
60+
WalletChainOptionsType::CustomCosmos(chain_id) => chain_id.clone(),
61+
_ => String::new(),
62+
}
63+
}
64+
65+
pub fn new_not_custom(chain_id: u32) -> WalletChainOptions {
66+
WalletChainOptions {
67+
kind: WalletChainOptionsType::NotCustom(chain_id),
68+
}
69+
}
70+
71+
pub fn new_not_custom_base(chain_id: u32) -> WalletChainOptions {
72+
WalletChainOptions {
73+
kind: WalletChainOptionsType::NotCustomBase(chain_id),
74+
}
3275
}
3376

3477
pub fn new_eth(chain_id: u32) -> WalletChainOptions {
3578
WalletChainOptions {
36-
kind: WalletChainOptionsType::CustomEth,
37-
chain_id,
38-
key_type: String::new(),
79+
kind: WalletChainOptionsType::CustomEth(chain_id),
80+
}
81+
}
82+
83+
pub fn new_substrate(chain_id: u32) -> WalletChainOptions {
84+
WalletChainOptions {
85+
kind: WalletChainOptionsType::CustomSubstrate(chain_id),
86+
}
87+
}
88+
89+
pub fn new_cosmos(chain_id: String) -> WalletChainOptions {
90+
WalletChainOptions {
91+
kind: WalletChainOptionsType::CustomCosmos(chain_id),
3992
}
4093
}
4194

4295
pub fn new_icp(key_type: String) -> WalletChainOptions {
4396
WalletChainOptions {
44-
kind: WalletChainOptionsType::CustomIcp,
45-
chain_id: 0,
46-
key_type,
97+
kind: WalletChainOptionsType::CustomIcp(key_type),
4798
}
4899
}
49100
}
50101

102+
impl WalletChainOptions {
103+
pub fn get_kind(&self) -> &WalletChainOptionsType {
104+
&self.kind
105+
}
106+
}
107+
51108
#[wasm_bindgen]
52109
#[derive(Debug, Clone)]
53110
pub struct WalletOptions {
@@ -76,6 +133,22 @@ pub fn new_wallet_options(use_legacy_path: bool) -> WalletOptions {
76133
}
77134
}
78135

136+
#[wasm_bindgen]
137+
pub fn new_not_custom_wallet_options(use_legacy_path: bool, chain_id: u32) -> WalletOptions {
138+
WalletOptions {
139+
use_legacy_path,
140+
specific: Some(WalletChainOptions::new_not_custom(chain_id)),
141+
}
142+
}
143+
144+
#[wasm_bindgen]
145+
pub fn new_not_custom_base_wallet_options(use_legacy_path: bool, chain_id: u32) -> WalletOptions {
146+
WalletOptions {
147+
use_legacy_path,
148+
specific: Some(WalletChainOptions::new_not_custom_base(chain_id)),
149+
}
150+
}
151+
79152
#[wasm_bindgen]
80153
pub fn new_eth_wallet_options(use_legacy_path: bool, chain_id: u32) -> WalletOptions {
81154
WalletOptions {
@@ -84,6 +157,22 @@ pub fn new_eth_wallet_options(use_legacy_path: bool, chain_id: u32) -> WalletOpt
84157
}
85158
}
86159

160+
#[wasm_bindgen]
161+
pub fn new_substrate_wallet_options(use_legacy_path: bool, chain_id: u32) -> WalletOptions {
162+
WalletOptions {
163+
use_legacy_path,
164+
specific: Some(WalletChainOptions::new_substrate(chain_id)),
165+
}
166+
}
167+
168+
#[wasm_bindgen]
169+
pub fn new_cosmos_wallet_options(use_legacy_path: bool, chain_id: String) -> WalletOptions {
170+
WalletOptions {
171+
use_legacy_path,
172+
specific: Some(WalletChainOptions::new_cosmos(chain_id)),
173+
}
174+
}
175+
87176
#[wasm_bindgen]
88177
pub fn new_icp_wallet_options(use_legacy_path: bool, key_type: String) -> WalletOptions {
89178
WalletOptions {
@@ -255,18 +344,22 @@ pub fn new_evm_transaction_options(chain_id: u32) -> TransactionChainOptions {
255344
pub fn new_bitcoin_transaction_options(
256345
input_amounts: Vec<u64>,
257346
prev_scripts: Vec<String>,
258-
) -> TransactionChainOptions {
259-
let prev_scripts = prev_scripts
347+
) -> Result<TransactionChainOptions, KOSError> {
348+
let prev_scripts: Result<Vec<_>, _> = prev_scripts
260349
.iter()
261-
.map(|s| base64::simple_base64_decode(s).unwrap_or_default())
350+
.map(|s| {
351+
base64::simple_base64_decode(s)
352+
.map_err(|e| KOSError::kos_delegate(format!("Base64 decode error: {}", e)))
353+
})
262354
.collect();
355+
let prev_scripts = prev_scripts?;
263356

264-
TransactionChainOptions {
357+
Ok(TransactionChainOptions {
265358
kind: TransactionChainOptionsType::Btc,
266359
input_amounts,
267360
prev_scripts,
268361
..Default::default()
269-
}
362+
})
270363
}
271364

272365
#[allow(clippy::too_many_arguments)]
@@ -283,22 +376,31 @@ pub fn new_substrate_transaction_options(
283376
transaction_version: u32,
284377
app_id: Option<u32>,
285378
signed_extensions: Option<Vec<String>>,
286-
) -> TransactionChainOptions {
287-
TransactionChainOptions {
379+
) -> Result<TransactionChainOptions, KOSError> {
380+
let call = hex_string_to_vec(call.as_str())
381+
.map_err(|e| KOSError::hex_decode(format!("call hex decode error: {}", e)))?;
382+
let era = hex_string_to_vec(era.as_str())
383+
.map_err(|e| KOSError::hex_decode(format!("era hex decode error: {}", e)))?;
384+
let block_hash = hex_string_to_vec(block_hash.as_str())
385+
.map_err(|e| KOSError::hex_decode(format!("block_hash hex decode error: {}", e)))?;
386+
let genesis_hash = hex_string_to_vec(genesis_hash.as_str())
387+
.map_err(|e| KOSError::hex_decode(format!("genesis_hash hex decode error: {}", e)))?;
388+
389+
Ok(TransactionChainOptions {
288390
kind: TransactionChainOptionsType::Substrate,
289-
call: hex_string_to_vec(call.as_str()).unwrap_or_default(),
290-
era: hex_string_to_vec(era.as_str()).unwrap_or_default(),
391+
call,
392+
era,
291393
nonce,
292394
tip,
293395
asset_id,
294-
block_hash: hex_string_to_vec(block_hash.as_str()).unwrap_or_default(),
295-
genesis_hash: hex_string_to_vec(genesis_hash.as_str()).unwrap_or_default(),
396+
block_hash,
397+
genesis_hash,
296398
spec_version,
297399
transaction_version,
298400
app_id,
299401
signed_extensions,
300402
..Default::default()
301-
}
403+
})
302404
}
303405

304406
#[wasm_bindgen]
@@ -320,17 +422,21 @@ pub fn wallet_options_to_chain_type(
320422
) -> CustomChainType {
321423
match options {
322424
Some(opts) => match &opts.specific {
323-
Some(WalletChainOptions {
324-
kind: WalletChainOptionsType::CustomEth,
325-
chain_id: custom_chain_id,
326-
..
327-
}) => CustomChainType::CustomEth(*custom_chain_id),
328-
Some(WalletChainOptions {
329-
kind: WalletChainOptionsType::CustomIcp,
330-
key_type,
331-
..
332-
}) => CustomChainType::CustomIcp(key_type.clone()),
333-
_ => CustomChainType::NotCustomBase(chain_id),
425+
Some(wallet_options) => match wallet_options.get_kind() {
426+
WalletChainOptionsType::NotCustom(id) => CustomChainType::NotCustom(*id),
427+
WalletChainOptionsType::NotCustomBase(id) => CustomChainType::NotCustomBase(*id),
428+
WalletChainOptionsType::CustomEth(id) => CustomChainType::CustomEth(*id),
429+
WalletChainOptionsType::CustomSubstrate(id) => {
430+
CustomChainType::CustomSubstrate(*id)
431+
}
432+
WalletChainOptionsType::CustomCosmos(chain_id) => {
433+
CustomChainType::CustomCosmos(chain_id.clone())
434+
}
435+
WalletChainOptionsType::CustomIcp(key_type) => {
436+
CustomChainType::CustomIcp(key_type.clone())
437+
}
438+
},
439+
None => CustomChainType::NotCustomBase(chain_id),
334440
},
335441
None => CustomChainType::NotCustomBase(chain_id),
336442
}

0 commit comments

Comments
 (0)