diff --git a/demo/js/index.js b/demo/js/index.js index b427395..e17ab1a 100644 --- a/demo/js/index.js +++ b/demo/js/index.js @@ -32,11 +32,14 @@ async function deriveAccounts(){ {chain: kos.Chain.TRX, model: kos.TRX}, {chain: kos.Chain.KLV, model: kos.KLV}, ].forEach((d) => { + // get path options + const pathOptions = kos.PathOptions.new(0); + // create new wallet from mnemonic let w1 = kos.Wallet.fromMnemonic( d.chain, "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", - d.model.getPath(0), + d.model.getPath(pathOptions), ); debugWallet("mnemonic", w1); @@ -78,10 +81,12 @@ window.onload = function(){ async function sendKLV(address, to, amount, token = "KLV") { const kos = window.kos; + const pathOptions = kos.PathOptions.new(0); + let klvWallet = kos.Wallet.fromMnemonic( kos.Chain.KLV, "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", - kos.KLV.getPath(0), + kos.KLV.getPath(pathOptions), ); klvWallet.setNodeUrl(NODE); diff --git a/packages/kos-sdk/src/chain.rs b/packages/kos-sdk/src/chain.rs index 87156a1..bb281a1 100644 --- a/packages/kos-sdk/src/chain.rs +++ b/packages/kos-sdk/src/chain.rs @@ -1,5 +1,5 @@ use crate::chains::*; -use crate::models::{self, BroadcastResult, Transaction}; +use crate::models::{self, BroadcastResult, PathOptions, Transaction}; use kos_crypto::keypair::KeyPair; use kos_types::error::Error; use kos_types::number::BigNumber; @@ -48,9 +48,9 @@ macro_rules! createChains { } } - pub fn get_path(&self, index: u32) -> Result { + pub fn get_path(&self, options: &PathOptions) -> Result { match self { - $(Chain::$name => $name::get_path(index),)* + $(Chain::$name => $name::get_path(options),)* } } diff --git a/packages/kos-sdk/src/chains/bitcoin/mod.rs b/packages/kos-sdk/src/chains/bitcoin/mod.rs index 34e3012..0320b02 100644 --- a/packages/kos-sdk/src/chains/bitcoin/mod.rs +++ b/packages/kos-sdk/src/chains/bitcoin/mod.rs @@ -2,7 +2,7 @@ mod requests; pub mod transaction; use crate::chain::{BaseChain, Chain}; -use crate::models::{self, BroadcastResult, Transaction, TransactionRaw}; +use crate::models::{self, BroadcastResult, PathOptions, Transaction, TransactionRaw}; use kos_crypto::{keypair::KeyPair, secp256k1::Secp256k1KeyPair}; use kos_proto::options::BTCOptions; @@ -105,8 +105,8 @@ impl BTC { } #[wasm_bindgen(js_name = "getPath")] - pub fn get_path(index: u32) -> Result { - Ok(format!("m/84'/{}'/0'/0/{}", BIP44_PATH, index)) + pub fn get_path(options: &PathOptions) -> Result { + Ok(format!("m/84'/{}'/0'/0/{}", BIP44_PATH, options.index)) } #[wasm_bindgen(js_name = "signDigest")] @@ -402,7 +402,7 @@ mod tests { ]; for (index, expected_addr) in v { - let path = BTC::get_path(index).unwrap(); + let path = BTC::get_path(&PathOptions::new(index)).unwrap(); let kp = BTC::keypair_from_mnemonic(DEFAULT_MNEMONIC, &path, None).unwrap(); let addr = BTC::get_address_from_keypair(&kp).unwrap(); diff --git a/packages/kos-sdk/src/chains/default/mod.rs b/packages/kos-sdk/src/chains/default/mod.rs index 61d77c9..42cc590 100644 --- a/packages/kos-sdk/src/chains/default/mod.rs +++ b/packages/kos-sdk/src/chains/default/mod.rs @@ -1,5 +1,5 @@ use crate::chain::BaseChain; -use crate::models::{self, BroadcastResult, Transaction}; +use crate::models::{self, BroadcastResult, PathOptions, Transaction}; use kos_crypto::keypair::KeyPair; use kos_types::error::Error; use kos_types::number::BigNumber; @@ -48,7 +48,7 @@ impl NONE { } #[wasm_bindgen(js_name = "getPath")] - pub fn get_path(_index: u32) -> Result { + pub fn get_path(_options: &PathOptions) -> Result { Err(Error::UnsupportedChain("NONE")) } diff --git a/packages/kos-sdk/src/chains/ethereum/mod.rs b/packages/kos-sdk/src/chains/ethereum/mod.rs index d6e9af4..b8e5717 100644 --- a/packages/kos-sdk/src/chains/ethereum/mod.rs +++ b/packages/kos-sdk/src/chains/ethereum/mod.rs @@ -4,7 +4,7 @@ pub mod request; pub mod transaction; use crate::chain::{self, BaseChain}; -use crate::models::{self, BroadcastResult, Transaction, TransactionRaw}; +use crate::models::{self, BroadcastResult, PathOptions, Transaction, TransactionRaw}; use kos_crypto::keypair::KeyPair; use kos_crypto::secp256k1::Secp256k1KeyPair; @@ -87,8 +87,8 @@ impl ETH { } #[wasm_bindgen(js_name = "getPath")] - pub fn get_path(index: u32) -> Result { - Ok(format!("m/44'/{}'/0'/0/{}", BIP44_PATH, index)) + pub fn get_path(options: &PathOptions) -> Result { + Ok(format!("m/44'/{}'/0'/0/{}", BIP44_PATH, options.index)) } #[wasm_bindgen(js_name = "signDigest")] @@ -465,7 +465,7 @@ mod tests { ]; for (index, expected_addr) in v { - let path = ETH::get_path(index).unwrap(); + let path = ETH::get_path(&PathOptions::new(index)).unwrap(); let kp = ETH::keypair_from_mnemonic(DEFAULT_MNEMONIC, &path, None).unwrap(); let addr = ETH::get_address_from_keypair(&kp).unwrap(); diff --git a/packages/kos-sdk/src/chains/klever/klever_test.rs b/packages/kos-sdk/src/chains/klever/klever_test.rs index fede222..eb3d315 100644 --- a/packages/kos-sdk/src/chains/klever/klever_test.rs +++ b/packages/kos-sdk/src/chains/klever/klever_test.rs @@ -4,6 +4,7 @@ mod tests { use std::str; use crate::chains::klever::*; + use crate::models::PathOptions; use crate::models::SendOptions; use hex::FromHex; use kos_types::Bytes32; @@ -134,7 +135,7 @@ mod tests { #[test] fn test_address_from_mnemonic() { - let path = KLV::get_path(0).unwrap(); + let path = KLV::get_path(&PathOptions::new(0)).unwrap(); let kp = KLV::keypair_from_mnemonic("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", &path, None).unwrap(); let address = KLV::get_address_from_keypair(&kp).unwrap(); diff --git a/packages/kos-sdk/src/chains/klever/mod.rs b/packages/kos-sdk/src/chains/klever/mod.rs index 3c247f4..fdacad9 100644 --- a/packages/kos-sdk/src/chains/klever/mod.rs +++ b/packages/kos-sdk/src/chains/klever/mod.rs @@ -3,7 +3,7 @@ pub mod models; pub mod requests; use crate::{ chain::BaseChain, - models::{AddressOptions, BroadcastResult, Transaction, TransactionRaw}, + models::{AddressOptions, BroadcastResult, PathOptions, Transaction, TransactionRaw}, }; use kos_crypto::{ed25519::Ed25519KeyPair, keypair::KeyPair}; use kos_types::{error::Error, hash::Hash, number::BigNumber}; @@ -69,8 +69,8 @@ impl KLV { } #[wasm_bindgen(js_name = "getPath")] - pub fn get_path(index: u32) -> Result { - Ok(format!("m/44'/{}'/0'/0'/{}'", BIP44_PATH, index)) + pub fn get_path(options: &PathOptions) -> Result { + Ok(format!("m/44'/{}'/0'/0'/{}'", BIP44_PATH, options.index)) } #[wasm_bindgen(js_name = "signDigest")] diff --git a/packages/kos-sdk/src/chains/polygon/mod.rs b/packages/kos-sdk/src/chains/polygon/mod.rs index 4c31c75..cfa108f 100644 --- a/packages/kos-sdk/src/chains/polygon/mod.rs +++ b/packages/kos-sdk/src/chains/polygon/mod.rs @@ -2,6 +2,7 @@ use super::ETHTransaction; use super::ETH; use crate::chain::{BaseChain, Chain}; +use crate::models::PathOptions; use crate::models::{self, BroadcastResult, TransactionRaw}; use kos_crypto::keypair::KeyPair; @@ -93,8 +94,8 @@ impl MATIC { } #[wasm_bindgen(js_name = "getPath")] - pub fn get_path(index: u32) -> Result { - ETH::get_path(index) + pub fn get_path(options: &PathOptions) -> Result { + ETH::get_path(options) } #[wasm_bindgen(js_name = "signDigest")] @@ -237,7 +238,7 @@ mod tests { ]; for (index, expected_addr) in v { - let path = MATIC::get_path(index).unwrap(); + let path = MATIC::get_path(&PathOptions::new(index)).unwrap(); let kp = MATIC::keypair_from_mnemonic(DEFAULT_MNEMONIC, &path, None).unwrap(); let addr = MATIC::get_address_from_keypair(&kp).unwrap(); diff --git a/packages/kos-sdk/src/chains/tron/mod.rs b/packages/kos-sdk/src/chains/tron/mod.rs index 03a3236..adc41bf 100644 --- a/packages/kos-sdk/src/chains/tron/mod.rs +++ b/packages/kos-sdk/src/chains/tron/mod.rs @@ -5,7 +5,7 @@ use std::str::FromStr; use crate::{ chain::{self, BaseChain}, - models::{BroadcastResult, Transaction, TransactionRaw}, + models::{BroadcastResult, PathOptions, Transaction, TransactionRaw}, }; use kos_crypto::{keypair::KeyPair, secp256k1::Secp256k1KeyPair}; use kos_types::error::Error; @@ -79,9 +79,17 @@ impl TRX { } #[wasm_bindgen(js_name = "getPath")] - pub fn get_path(index: u32) -> Result { - // use account 0 index X - Ok(format!("m/44'/{}'/0'/0/{}", BIP44_PATH, index)) + pub fn get_path(options: &PathOptions) -> Result { + let index = options.index; + + let is_legacy = options.is_legacy.unwrap_or(false); + + if is_legacy { + Ok(format!("m/44'/{}'/{}'", BIP44_PATH, index)) + } else { + // use account 0 index X + Ok(format!("m/44'/{}'/0'/0/{}", BIP44_PATH, index)) + } } #[wasm_bindgen(js_name = "signDigest")] @@ -324,7 +332,7 @@ mod tests { #[test] fn test_address_from_mnemonic() { - let path = TRX::get_path(0).unwrap(); + let path = TRX::get_path(&PathOptions::new(0)).unwrap(); let kp = TRX::keypair_from_mnemonic("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", &path, None).unwrap(); let address = TRX::get_address_from_keypair(&kp).unwrap(); @@ -389,7 +397,7 @@ mod tests { ]; for (index, expected_addr) in v { - let path = TRX::get_path(index).unwrap(); + let path = TRX::get_path(&PathOptions::new(index)).unwrap(); let kp = TRX::keypair_from_mnemonic(default_mnemonic, &path, None).unwrap(); let addr = TRX::get_address_from_keypair(&kp).unwrap(); diff --git a/packages/kos-sdk/src/models.rs b/packages/kos-sdk/src/models.rs index 6eb2a7f..a9be80d 100644 --- a/packages/kos-sdk/src/models.rs +++ b/packages/kos-sdk/src/models.rs @@ -30,6 +30,37 @@ impl BroadcastResult { serde_json::to_string(&self).unwrap() } } +#[derive(Default, Deserialize, Serialize, Clone, Debug)] +#[wasm_bindgen] +pub struct PathOptions { + #[wasm_bindgen(skip)] + pub index: u32, + #[wasm_bindgen(skip)] + pub is_legacy: Option, +} + +#[wasm_bindgen] +impl PathOptions { + #[wasm_bindgen(constructor)] + pub fn constructor() -> Self { + Self::default() + } + + pub fn new(index: u32) -> Self { + Self { + index, + is_legacy: Some(false), + } + } + #[wasm_bindgen(js_name = setIndex)] + pub fn set_index(&mut self, index: u32) { + self.index = index; + } + #[wasm_bindgen(js_name = setLegacy)] + pub fn set_legacy(&mut self, is_legacy: bool) { + self.is_legacy = Some(is_legacy); + } +} // create enum variant list of transaction types supported kos_types::enum_thing! { diff --git a/packages/kos-sdk/src/wallet.rs b/packages/kos-sdk/src/wallet.rs index d3a4bcc..aac57f0 100644 --- a/packages/kos-sdk/src/wallet.rs +++ b/packages/kos-sdk/src/wallet.rs @@ -1,6 +1,6 @@ use crate::{ chain::{BaseChain, Chain}, - models::{self, BroadcastResult, Transaction}, + models::{self, BroadcastResult, PathOptions, Transaction}, }; use kos_crypto::keypair::KeyPair; @@ -224,12 +224,12 @@ impl Wallet { pub fn from_mnemonic_index( chain: Chain, mnemonic: String, - index: u32, + path_options: &PathOptions, password: Option, ) -> Result { - let path = chain.get_path(index)?; + let path = chain.get_path(path_options)?; let mut wallet = Wallet::from_mnemonic(chain, mnemonic, path, password)?; - wallet.index = Some(index); + wallet.index = Some(path_options.index); Ok(wallet) } @@ -474,7 +474,7 @@ mod tests { let mut w1 = Wallet::from_mnemonic( Chain::KLV, "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(), - Chain::KLV.get_path(0).unwrap(), + Chain::KLV.get_path(&PathOptions::new(0)).unwrap(), None, ).unwrap(); @@ -501,7 +501,7 @@ mod tests { let mut w1 = Wallet::from_mnemonic( Chain::KLV, "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(), - Chain::KLV.get_path(0).unwrap(), + Chain::KLV.get_path(&PathOptions::new(0)).unwrap(), None, ).unwrap(); @@ -576,7 +576,7 @@ qeVTAAAA let w1 = Wallet::from_mnemonic( Chain::KLV, "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(), - Chain::KLV.get_path(0).unwrap(), + Chain::KLV.get_path(&PathOptions::new(0)).unwrap(), None, ).unwrap(); @@ -589,7 +589,7 @@ qeVTAAAA let w1 = Wallet::from_mnemonic_index( Chain::KLV, "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(), - 10, + &PathOptions::new(10), None, ).unwrap(); let result = w1.get_index(); diff --git a/packages/kos-sdk/src/wm.rs b/packages/kos-sdk/src/wm.rs index ee8461a..25d72e4 100644 --- a/packages/kos-sdk/src/wm.rs +++ b/packages/kos-sdk/src/wm.rs @@ -1,4 +1,4 @@ -use crate::wallet::Wallet; +use crate::{models::PathOptions, wallet::Wallet}; use kos_types::error::Error; use kos_utils::{pack, unpack}; @@ -249,7 +249,7 @@ impl WalletManager { let mut wallet = Wallet::from_mnemonic_index( chain, self.get_mnemonic(password.to_owned())?, - index, + &PathOptions::new(index), None, )?;