From ffb78246316affb656e700481f3ba36fb3f5d106 Mon Sep 17 00:00:00 2001 From: Neal Xu Date: Thu, 29 Aug 2024 15:12:00 +0800 Subject: [PATCH] feat: add top 15 chain_id and hrp verified (#121) --- Cargo.lock | 1 + token-core/tcx-atom/Cargo.toml | 3 +- token-core/tcx-atom/src/address.rs | 85 ++++++++++++++++++- token-core/tcx-atom/src/signer.rs | 1 + token-core/tcx-btc-kin/src/address.rs | 6 ++ token-core/tcx-btc-kin/src/bch_address.rs | 2 + token-core/tcx-btc-kin/src/message.rs | 6 ++ token-core/tcx-btc-kin/src/psbt.rs | 2 + token-core/tcx-btc-kin/src/signer.rs | 1 + token-core/tcx-ckb/src/address.rs | 5 ++ token-core/tcx-ckb/src/signer.rs | 8 ++ .../tcx-constants/src/btc_fork_network.rs | 1 + token-core/tcx-constants/src/coin_info.rs | 42 +++++++++ token-core/tcx-docs/INTEGRATION.md | 2 + token-core/tcx-eth/src/address.rs | 2 + token-core/tcx-filecoin/src/address.rs | 2 + token-core/tcx-keystore/src/keystore/hd.rs | 21 +++++ token-core/tcx-keystore/src/keystore/mod.rs | 3 + .../tcx-keystore/src/keystore/private.rs | 1 + token-core/tcx-migration/src/migration.rs | 7 ++ token-core/tcx-proto/src/params.proto | 1 + token-core/tcx-substrate/src/address.rs | 5 ++ token-core/tcx-tezos/src/address.rs | 3 + token-core/tcx-tron/src/address.rs | 2 + token-core/tcx/src/api.rs | 2 + token-core/tcx/src/handler.rs | 4 + token-core/tcx/src/reset_password.rs | 2 + token-core/tcx/tests/derive_test.rs | 78 ++++++++++++++++- 28 files changed, 293 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1a355dd3..ab82340a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4350,6 +4350,7 @@ dependencies = [ "base64 0.13.1", "bech32 0.9.1", "bytes", + "lazy_static", "prost", "tcx-common", "tcx-constants", diff --git a/token-core/tcx-atom/Cargo.toml b/token-core/tcx-atom/Cargo.toml index 8f413b8a..d19791d5 100644 --- a/token-core/tcx-atom/Cargo.toml +++ b/token-core/tcx-atom/Cargo.toml @@ -17,4 +17,5 @@ anyhow = { version = "=1.0.79", features = [] } prost = "=0.11.2" bytes = "=1.4.0" -base64 = "=0.13.1" \ No newline at end of file +base64 = "=0.13.1" +lazy_static = "1.4.0" \ No newline at end of file diff --git a/token-core/tcx-atom/src/address.rs b/token-core/tcx-atom/src/address.rs index ee455584..a0fe3454 100644 --- a/token-core/tcx-atom/src/address.rs +++ b/token-core/tcx-atom/src/address.rs @@ -1,6 +1,10 @@ +use anyhow::{anyhow, format_err}; use core::str::FromStr; +use std::collections::HashMap; +use std::sync::RwLock; use bech32::{FromBase32, ToBase32, Variant}; +use lazy_static::lazy_static; use tcx_common::{ripemd160, sha256}; use tcx_constants::CoinInfo; use tcx_keystore::{Address, Result}; @@ -9,6 +13,41 @@ use tcx_primitive::TypedPublicKey; // size of address pub const LENGTH: usize = 20; +// pub const HRP_MAP: +lazy_static! { + static ref CHAIN_ID_HRP_MAP: RwLock> = { + let mut chain_id_hrp_map = HashMap::new(); + chain_id_hrp_map.insert("cosmoshub-4".to_string(), "cosmos".to_string()); + chain_id_hrp_map.insert("osmosis-1".to_string(), "osmo".to_string()); + chain_id_hrp_map.insert("celestia".to_string(), "celestia".to_string()); + chain_id_hrp_map.insert("neutron-1".to_string(), "neutron".to_string()); + chain_id_hrp_map.insert("noble-1".to_string(), "noble".to_string()); + chain_id_hrp_map.insert("stride-1".to_string(), "stride".to_string()); + chain_id_hrp_map.insert("stargaze-1".to_string(), "stars".to_string()); + chain_id_hrp_map.insert("axelar-dojo-1".to_string(), "axelar".to_string()); + chain_id_hrp_map.insert("juno-1".to_string(), "juno".to_string()); + chain_id_hrp_map.insert("injective-1".to_string(), "inj".to_string()); + chain_id_hrp_map.insert("dydx-mainnet-1".to_string(), "dydx".to_string()); + chain_id_hrp_map.insert("dymension_1100-1".to_string(), "dym".to_string()); + chain_id_hrp_map.insert("secret-4".to_string(), "secret".to_string()); + chain_id_hrp_map.insert("archway-1".to_string(), "archway".to_string()); + chain_id_hrp_map.insert("akashnet-2".to_string(), "akash".to_string()); + chain_id_hrp_map.insert("core-1".to_string(), "persistence".to_string()); + RwLock::new(chain_id_hrp_map) + }; +} + +fn verify_hrp(coin_info: &CoinInfo) -> Result<()> { + let map = CHAIN_ID_HRP_MAP.read().unwrap(); + let embed_hrp = map.get(&coin_info.chain_id); + if (embed_hrp.is_some()) { + if (&coin_info.hrp != embed_hrp.unwrap()) { + return Err(anyhow!("chain_id_and_hrp_not_match")); + } + } + return Ok(()); +} + #[derive(PartialEq, Eq, Clone)] pub struct AtomAddress(String); @@ -18,7 +57,8 @@ impl Address for AtomAddress { let mut bytes = [0u8; LENGTH]; let pub_key_hash = ripemd160(&sha256(&pub_key_bytes)); bytes.copy_from_slice(&pub_key_hash[..LENGTH]); - let hrp = if (coin.hrp.is_empty()) { + verify_hrp(&coin)?; + let hrp = if coin.hrp.is_empty() { "cosmos" } else { coin.hrp.as_str() @@ -68,6 +108,7 @@ impl ToString for AtomAddress { #[cfg(test)] mod tests { use crate::address::AtomAddress; + use anyhow::anyhow; use std::str::FromStr; use tcx_keystore::Address; @@ -77,6 +118,7 @@ mod tests { fn get_test_coin() -> CoinInfo { CoinInfo { + chain_id: "".to_string(), coin: "COSMOS".to_string(), derivation_path: "m/44'/118'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -154,6 +196,7 @@ mod tests { .unwrap() .public_key(); let coin_info = CoinInfo { + chain_id: "cosmoshub-4".to_string(), coin: "COSMOS".to_string(), derivation_path: "m/44'/118'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -198,6 +241,7 @@ mod tests { ]; for (hrp, path, expected_addr) in testcase { let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "COSMOS".to_string(), derivation_path: path.to_string(), curve: CurveType::SECP256k1, @@ -212,4 +256,43 @@ mod tests { assert_eq!(address, expected_addr) } } + #[test] + fn test_chain_id_hrp_verify() { + let prv_str = "80e81ea269e66a0a05b11236df7919fb7fbeedba87452d667489d7403a02f005"; + let pub_key = + TypedPrivateKey::from_slice(CurveType::SECP256k1, &Vec::from_hex(prv_str).unwrap()) + .unwrap() + .public_key(); + let coin_info = CoinInfo { + chain_id: "cosmoshub-4".to_string(), + coin: "COSMOS".to_string(), + derivation_path: "m/44'/118'/0'/0/0".to_string(), + curve: CurveType::SECP256k1, + network: "MAINNET".to_string(), + seg_wit: "NONE".to_string(), + hrp: "cosmos-wrong".to_string(), + }; + let address = AtomAddress::from_public_key(&pub_key, &coin_info); + + assert_eq!( + format!("{}", address.err().unwrap()), + "chain_id_and_hrp_not_match" + ); + + let coin_info = CoinInfo { + chain_id: "cosmoshub-4".to_string(), + coin: "COSMOS".to_string(), + derivation_path: "m/44'/118'/0'/0/0".to_string(), + curve: CurveType::SECP256k1, + network: "MAINNET".to_string(), + seg_wit: "NONE".to_string(), + hrp: "cosmos".to_string(), + }; + + let address = AtomAddress::from_public_key(&pub_key, &coin_info); + assert_eq!( + address.unwrap().to_string(), + "cosmos1hsk6jryyqjfhp5dhc55tc9jtckygx0eph6dd02" + ); + } } diff --git a/token-core/tcx-atom/src/signer.rs b/token-core/tcx-atom/src/signer.rs index 9bd05ef5..a0b59ba5 100644 --- a/token-core/tcx-atom/src/signer.rs +++ b/token-core/tcx-atom/src/signer.rs @@ -45,6 +45,7 @@ mod tests { Keystore::Hd(HdKeystore::from_mnemonic(&TEST_MNEMONIC, &TEST_PASSWORD, meta).unwrap()); let _coin_info = CoinInfo { + chain_id: "".to_string(), coin: "COSMOS".to_string(), derivation_path: "m/44'/118'/0'/0/0".to_string(), curve: CurveType::SECP256k1, diff --git a/token-core/tcx-btc-kin/src/address.rs b/token-core/tcx-btc-kin/src/address.rs index 2039120f..10030800 100644 --- a/token-core/tcx-btc-kin/src/address.rs +++ b/token-core/tcx-btc-kin/src/address.rs @@ -355,6 +355,7 @@ mod tests { let bitcoin_xprv_str = "xprv9yrdwPSRnvomqFK4u1y5uW2SaXS2Vnr3pAYTjJjbyRZR8p9BwoadRsCxtgUFdAKeRPbwvGRcCSYMV69nNK4N2kadevJ6L5iQVy1SwGKDTHQ"; let anprv = Bip32DeterministicPrivateKey::from_ss58check(bitcoin_xprv_str).unwrap(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "LITECOIN".to_string(), derivation_path: "m/44'/2'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -375,6 +376,7 @@ mod tests { .unwrap() .deterministic_public_key(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "LITECOIN".to_string(), derivation_path: "m/44'/2'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -467,6 +469,7 @@ mod tests { .unwrap() .public_key(); let mut coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/44'/2'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -504,6 +507,7 @@ mod tests { let mut hd = sample_hd_keystore(); let account = hd .derive_coin::(&CoinInfo { + chain_id: "".to_string(), coin: "DOGECOIN".to_string(), derivation_path: "m/44'/3'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -535,6 +539,7 @@ mod tests { for (coin, network, path, xpub) in test_cases { let coin_info = CoinInfo { + chain_id: "".to_string(), coin: coin.to_string(), derivation_path: path.to_string(), curve: CurveType::SECP256k1, @@ -556,6 +561,7 @@ mod tests { ) .unwrap(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/84'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, diff --git a/token-core/tcx-btc-kin/src/bch_address.rs b/token-core/tcx-btc-kin/src/bch_address.rs index 71017aee..0eea854b 100644 --- a/token-core/tcx-btc-kin/src/bch_address.rs +++ b/token-core/tcx-btc-kin/src/bch_address.rs @@ -191,6 +191,7 @@ mod tests { ); let wrong_coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOINCASH".to_string(), derivation_path: "".to_string(), curve: CurveType::SECP256k1, @@ -283,6 +284,7 @@ mod tests { .unwrap() .public_key(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOINCASH".to_string(), derivation_path: "".to_string(), curve: CurveType::SECP256k1, diff --git a/token-core/tcx-btc-kin/src/message.rs b/token-core/tcx-btc-kin/src/message.rs index 408e26d5..faf7fdc2 100644 --- a/token-core/tcx-btc-kin/src/message.rs +++ b/token-core/tcx-btc-kin/src/message.rs @@ -103,6 +103,7 @@ impl MessageSigner for Keystore { let public_key = self.get_public_key(CurveType::SECP256k1, &path)?; let coin_info = CoinInfo { + chain_id: "".to_string(), coin: params.chain_type.to_string(), derivation_path: path.clone(), curve: CurveType::SECP256k1, @@ -153,6 +154,7 @@ mod tests { let message = "hello world"; let mut ks = sample_hd_keystore(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/44'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -177,6 +179,7 @@ mod tests { let message = "hello world"; let mut ks = sample_hd_keystore(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/49'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -213,6 +216,7 @@ mod tests { let message = "hello world"; let mut ks = sample_hd_keystore(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/44'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -250,6 +254,7 @@ mod tests { let message = "hello world"; let mut ks = sample_hd_keystore(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/44'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -286,6 +291,7 @@ mod tests { let message = "Sign this message to log in to https://www.subber.xyz // 200323342"; let mut ks = wif_keystore("L4F5BYm82Bck6VEY64EbqQkoBXqkegq9X9yc6iLTV3cyJoqUasnY"); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/86'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, diff --git a/token-core/tcx-btc-kin/src/psbt.rs b/token-core/tcx-btc-kin/src/psbt.rs index 3f9638f6..28a07c2b 100644 --- a/token-core/tcx-btc-kin/src/psbt.rs +++ b/token-core/tcx-btc-kin/src/psbt.rs @@ -440,6 +440,7 @@ mod tests { fn test_sign_psbt_no_script() { let mut hd = sample_hd_keystore(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/86'/1'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -480,6 +481,7 @@ mod tests { fn test_sign_psbt_script() { let mut hd = sample_hd_keystore(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/86'/1'/0'/0/0".to_string(), curve: CurveType::SECP256k1, diff --git a/token-core/tcx-btc-kin/src/signer.rs b/token-core/tcx-btc-kin/src/signer.rs index 887c38f3..46432cb7 100644 --- a/token-core/tcx-btc-kin/src/signer.rs +++ b/token-core/tcx-btc-kin/src/signer.rs @@ -248,6 +248,7 @@ impl> KinTransaction } let coin_info = CoinInfo { + chain_id: "".to_string(), coin: params.chain_type.clone(), derivation_path: params.derivation_path.clone(), curve: params.curve, diff --git a/token-core/tcx-ckb/src/address.rs b/token-core/tcx-ckb/src/address.rs index cf60c173..e5307662 100644 --- a/token-core/tcx-ckb/src/address.rs +++ b/token-core/tcx-ckb/src/address.rs @@ -99,6 +99,7 @@ mod tests { ]; for (network, address) in network_addresses { let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "NERVOS".to_string(), derivation_path: "".to_string(), curve: CurveType::SECP256k1, @@ -128,6 +129,7 @@ mod tests { ]; for (network, address) in valid_addresses { let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "NERVOS".to_string(), derivation_path: "".to_string(), curve: CurveType::SECP256k1, @@ -144,6 +146,7 @@ mod tests { ]; for (address, network) in invalid_addresses { let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "NERVOS".to_string(), derivation_path: "".to_string(), curve: CurveType::SECP256k1, @@ -165,6 +168,7 @@ mod tests { ]; for invalid_address in invalid_address { let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "NERVOS".to_string(), derivation_path: "".to_string(), curve: CurveType::SECP256k1, @@ -191,6 +195,7 @@ mod tests { .unwrap() .public_key(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "NERVOS".to_string(), derivation_path: "".to_string(), curve: CurveType::SECP256k1, diff --git a/token-core/tcx-ckb/src/signer.rs b/token-core/tcx-ckb/src/signer.rs index c1b9c1f5..b24c8510 100644 --- a/token-core/tcx-ckb/src/signer.rs +++ b/token-core/tcx-ckb/src/signer.rs @@ -299,6 +299,7 @@ mod tests { }; let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "NERVOS".to_string(), derivation_path: "m/44'/309'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -435,6 +436,7 @@ mod tests { ks.unlock_by_password(TEST_PASSWORD).unwrap(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "NERVOS".to_string(), derivation_path: "".to_string(), curve: CurveType::SECP256k1, @@ -518,6 +520,7 @@ mod tests { }; let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "NERVOS".to_string(), derivation_path: "m/44'/309'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -584,6 +587,7 @@ mod tests { }; let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "NERVOS".to_string(), derivation_path: "m/44'/309'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -654,6 +658,7 @@ mod tests { }; let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "NERVOS".to_string(), derivation_path: "m/44'/309'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -692,6 +697,7 @@ mod tests { let tx_hash = "0x719933ec055272734ab709a80492edb44c083e6b675e5c37e5bb3f720fe88e5e"; let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "NERVOS".to_string(), derivation_path: "m/44'/309'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -739,6 +745,7 @@ mod tests { let tx_hash = "0x719933ec055272734ab709a80492edb44c083e6b675e5c37e5bb3f720fe88e5e"; let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "NERVOS".to_string(), derivation_path: "m/44'/309'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -886,6 +893,7 @@ mod tests { }; let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "NERVOS".to_string(), derivation_path: "m/44'/309'/0'/0/0".to_string(), curve: CurveType::SECP256k1, diff --git a/token-core/tcx-constants/src/btc_fork_network.rs b/token-core/tcx-constants/src/btc_fork_network.rs index 6a3d7bc7..600124cd 100644 --- a/token-core/tcx-constants/src/btc_fork_network.rs +++ b/token-core/tcx-constants/src/btc_fork_network.rs @@ -249,6 +249,7 @@ mod test { #[test] fn test_network_from_coin() { let network = super::network_from_coin(&super::CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "".to_string(), curve: CurveType::SECP256k1, diff --git a/token-core/tcx-constants/src/coin_info.rs b/token-core/tcx-constants/src/coin_info.rs index 9e9f3bcd..db600675 100644 --- a/token-core/tcx-constants/src/coin_info.rs +++ b/token-core/tcx-constants/src/coin_info.rs @@ -22,6 +22,7 @@ pub struct CoinInfo { pub network: String, pub seg_wit: String, pub hrp: String, + pub chain_id: String, } impl Default for CoinInfo { @@ -33,6 +34,7 @@ impl Default for CoinInfo { network: "".to_string(), seg_wit: "".to_string(), hrp: "".to_string(), + chain_id: "".to_string(), } } } @@ -41,6 +43,7 @@ lazy_static! { static ref COIN_INFOS: RwLock> = { let coin_infos = vec![ CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/44'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -49,6 +52,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/44'/1'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -57,6 +61,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/49'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -65,6 +70,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/49'/1'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -73,6 +79,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/84'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -81,6 +88,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/84'/1'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -89,6 +97,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/86'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -97,6 +106,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/86'/1'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -105,6 +115,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "BITCOINCASH".to_string(), derivation_path: "m/44'/145'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -113,6 +124,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "BITCOINCASH".to_string(), derivation_path: "m/44'/1'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -121,6 +133,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "LITECOIN".to_string(), derivation_path: "m/44'/2'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -129,6 +142,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "LITECOIN".to_string(), derivation_path: "m/44'/1'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -137,6 +151,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "LITECOIN".to_string(), derivation_path: "m/49'/2'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -145,6 +160,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "LITECOIN".to_string(), derivation_path: "m/49'/1'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -153,6 +169,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "TRON".to_string(), derivation_path: "m/44'/195'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -161,6 +178,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "NERVOS".to_string(), derivation_path: "m/44'/309'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -169,6 +187,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "NERVOS".to_string(), derivation_path: "m/44'/309'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -177,6 +196,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "POLKADOT".to_string(), derivation_path: "//polkadot//imToken/0".to_string(), curve: CurveType::SR25519, @@ -185,6 +205,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "KUSAMA".to_string(), derivation_path: "//kusama//imToken/0".to_string(), curve: CurveType::SR25519, @@ -193,6 +214,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "TEZOS".to_string(), derivation_path: "m/44'/1729'/0'/0'".to_string(), curve: CurveType::ED25519, @@ -201,6 +223,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "FILECOIN".to_string(), derivation_path: "m/44'/461'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -209,6 +232,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "FILECOIN".to_string(), derivation_path: "m/44'/461'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -217,6 +241,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "FILECOIN".to_string(), derivation_path: "m/2334/461/0/0".to_string(), curve: CurveType::BLS, @@ -225,6 +250,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "FILECOIN".to_string(), derivation_path: "m/2334/461/0/0".to_string(), curve: CurveType::BLS, @@ -233,6 +259,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "ETHEREUM".to_string(), derivation_path: "m/44'/60'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -241,6 +268,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "ETHEREUM".to_string(), derivation_path: "m/44'/60'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -249,6 +277,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "ETHEREUM2".to_string(), derivation_path: "m/12381/3600/0/0".to_string(), curve: CurveType::BLS, @@ -257,6 +286,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "ETHEREUM2".to_string(), derivation_path: "m/12381/3600/0/0".to_string(), curve: CurveType::BLS, @@ -265,6 +295,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "COSMOS".to_string(), derivation_path: "m/44'/118'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -273,6 +304,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "EOS".to_string(), derivation_path: "m/44'/194'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -281,6 +313,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "COSMOS".to_string(), derivation_path: "m/44'/118'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -289,6 +322,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "EOS".to_string(), derivation_path: "m/44'/194'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -297,6 +331,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "DOGECOIN".to_string(), derivation_path: "m/44'/3'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -305,6 +340,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "DOGECOIN".to_string(), derivation_path: "m/44'/1'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -313,6 +349,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "DOGECOIN".to_string(), derivation_path: "m/49'/3'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -321,6 +358,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "DOGECOIN".to_string(), derivation_path: "m/49'/1'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -329,6 +367,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "DOGECOIN".to_string(), derivation_path: "m/84'/3'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -337,6 +376,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "DOGECOIN".to_string(), derivation_path: "m/84'/1'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -345,6 +385,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "DOGECOIN".to_string(), derivation_path: "m/86'/3'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -353,6 +394,7 @@ lazy_static! { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "DOGECOIN".to_string(), derivation_path: "m/86'/1'/0'/0/0".to_string(), curve: CurveType::SECP256k1, diff --git a/token-core/tcx-docs/INTEGRATION.md b/token-core/tcx-docs/INTEGRATION.md index 2cf8d35a..45c513cf 100644 --- a/token-core/tcx-docs/INTEGRATION.md +++ b/token-core/tcx-docs/INTEGRATION.md @@ -25,6 +25,7 @@ Declare blockchain wallet information to [coin_info.rs](tcx-constans/src/coin_in ```rust coin_infos.push(CoinInfo { +chain_id: "".to_string(), coin: "BITCOIN".to_string(), // Chain full name derivation_path: "m/44'/0'/0'/0/0".to_string(), // BIP44 or SLIP44 path curve: CurveType::SECP256k1, // Curve type, now only support secp256k1 @@ -32,6 +33,7 @@ coin_infos.push(CoinInfo { seg_wit: "NONE".to_string(), // Segwit type, options is ['', 'NONE', 'P2WPKH'] }); coin_infos.push(CoinInfo { +chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/44'/1'/0'/0/0".to_string(), curve: CurveType::SECP256k1, diff --git a/token-core/tcx-eth/src/address.rs b/token-core/tcx-eth/src/address.rs index 253f8c29..96f7c169 100644 --- a/token-core/tcx-eth/src/address.rs +++ b/token-core/tcx-eth/src/address.rs @@ -127,6 +127,7 @@ mod test { secp256k1_private_key.0.compressed = false; let typed_public_key = TypedPrivateKey::Secp256k1(secp256k1_private_key).public_key(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "ETHEREUM".to_string(), derivation_path: "m/44'/60'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -208,6 +209,7 @@ mod test { .unwrap() .public_key(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "ETHEREUM".to_string(), derivation_path: "m/44'/60'/0'/0/0".to_string(), curve: CurveType::SECP256k1, diff --git a/token-core/tcx-filecoin/src/address.rs b/token-core/tcx-filecoin/src/address.rs index 89dc300f..9ff1a5ec 100644 --- a/token-core/tcx-filecoin/src/address.rs +++ b/token-core/tcx-filecoin/src/address.rs @@ -161,6 +161,7 @@ mod tests { ]; let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "FILECOIN".to_string(), derivation_path: "".to_string(), curve: CurveType::BLS, @@ -257,6 +258,7 @@ mod tests { ]; let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "FILECOIN".to_string(), derivation_path: "".to_string(), curve: CurveType::SECP256k1, diff --git a/token-core/tcx-keystore/src/keystore/hd.rs b/token-core/tcx-keystore/src/keystore/hd.rs index 84dfe77a..f17d1578 100644 --- a/token-core/tcx-keystore/src/keystore/hd.rs +++ b/token-core/tcx-keystore/src/keystore/hd.rs @@ -341,6 +341,7 @@ mod tests { let coin_infos = [ CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/44'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -349,6 +350,7 @@ mod tests { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/49'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -357,6 +359,7 @@ mod tests { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/84'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -365,6 +368,7 @@ mod tests { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/86'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -373,6 +377,7 @@ mod tests { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/44'/1'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -381,6 +386,7 @@ mod tests { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/49'/1'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -389,6 +395,7 @@ mod tests { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/84'/1'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -397,6 +404,7 @@ mod tests { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/86'/1'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -405,6 +413,7 @@ mod tests { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "TEZOS".to_string(), derivation_path: "m/44'/1729'/0'/0'".to_string(), curve: CurveType::ED25519, @@ -438,6 +447,7 @@ mod tests { HdKeystore::from_mnemonic(MNEMONIC_WITH_WHITESPACE, TEST_PASSWORD, Metadata::default()) .unwrap(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/44'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -547,6 +557,7 @@ mod tests { let mut keystore = HdKeystore::from_mnemonic(TEST_MNEMONIC, TEST_PASSWORD, Metadata::default()).unwrap(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/44'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -614,6 +625,7 @@ mod tests { let mut keystore = HdKeystore::from_mnemonic(TEST_MNEMONIC, TEST_PASSWORD, Metadata::default()).unwrap(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/44'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -658,6 +670,7 @@ mod tests { .unwrap(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/44'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -682,6 +695,7 @@ mod tests { let coin_infos = [ CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/44'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -690,6 +704,7 @@ mod tests { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/49'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -698,6 +713,7 @@ mod tests { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/84'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -706,6 +722,7 @@ mod tests { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/84'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -714,6 +731,7 @@ mod tests { hrp: "".to_string(), }, CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/84'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -746,6 +764,7 @@ mod tests { .unwrap(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/49'/1'/0'".to_string(), curve: CurveType::SECP256k1, @@ -757,6 +776,7 @@ mod tests { assert_eq!(acc.ext_pub_key, "tpubDD7tXK8KeQ3YY83yWq755fHY2JW8Ha8Q765tknUM5rSvjPcGWfUppDFMpQ1ScziKfW3ZNtZvAD7M3u7bSs7HofjTD3KP3YxPK7X6hwV8Rk2"); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/49'/1'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -780,6 +800,7 @@ mod tests { .unwrap(); let mut coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/84'/0'/0'".to_string(), curve: CurveType::SECP256k1, diff --git a/token-core/tcx-keystore/src/keystore/mod.rs b/token-core/tcx-keystore/src/keystore/mod.rs index 46e5d327..11326590 100644 --- a/token-core/tcx-keystore/src/keystore/mod.rs +++ b/token-core/tcx-keystore/src/keystore/mod.rs @@ -897,6 +897,7 @@ pub(crate) mod tests { assert!(!keystore.verify_password(&Key::DerivedKey("731dd44109f9897eb39980907161b7531be44714352ddaa40542da22fb4fab7533678f2e132226389174faad4e653c542811a7b0c9391ae3cce4e75039a15adc".to_string()))); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/44'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -970,6 +971,7 @@ pub(crate) mod tests { assert!(!keystore.verify_password(&Key::DerivedKey("731dd44109f9897eb39980907161b7531be44714352ddaa40542da22fb4fab7533678f2e132226389174faad4e653c542811a7b0c9391ae3cce4e75039a15adc".to_string()))); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/44'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -1015,6 +1017,7 @@ pub(crate) mod tests { #[test] fn test_derive_sub_account() { let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "0/0".to_string(), curve: CurveType::SECP256k1, diff --git a/token-core/tcx-keystore/src/keystore/private.rs b/token-core/tcx-keystore/src/keystore/private.rs index a898f9ce..b67be6bc 100644 --- a/token-core/tcx-keystore/src/keystore/private.rs +++ b/token-core/tcx-keystore/src/keystore/private.rs @@ -265,6 +265,7 @@ mod tests { .unwrap(); let coin_infos = [CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/44'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, diff --git a/token-core/tcx-migration/src/migration.rs b/token-core/tcx-migration/src/migration.rs index be2eacab..ed7992a1 100644 --- a/token-core/tcx-migration/src/migration.rs +++ b/token-core/tcx-migration/src/migration.rs @@ -396,6 +396,7 @@ mod tests { let mut keystore = ks.migrate(&key, &IdentityNetwork::Testnet).unwrap(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "EOS".to_string(), derivation_path: "m/44'/194'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -454,6 +455,7 @@ mod tests { assert_eq!(keystore.id(), "02a55ab6-554a-4e78-bc26-6a7acced7e5e"); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOIN".to_string(), derivation_path: "m/44'/0'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -481,6 +483,7 @@ mod tests { assert_eq!(keystore.id(), "045861fe-0e9b-4069-92aa-0ac03cad55e0"); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "ETHEREUM".to_string(), derivation_path: "".to_string(), curve: CurveType::SECP256k1, @@ -507,6 +510,7 @@ mod tests { assert_eq!(keystore.id(), "045861fe-0e9b-4069-92aa-0ac03cad55e1"); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "ETHEREUM".to_string(), derivation_path: "".to_string(), curve: CurveType::SECP256k1, @@ -531,6 +535,7 @@ mod tests { assert_eq!(keystore.derivable(), true); assert_eq!(keystore.id(), "175169f7-5a35-4df7-93c1-1ff612168e71"); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "ETHEREUM".to_string(), derivation_path: "m/44'/60'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -555,6 +560,7 @@ mod tests { assert_eq!(keystore.derivable(), true); assert_eq!(keystore.id(), "5991857a-2488-4546-b730-463a5f84ea6a"); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "ETHEREUM".to_string(), derivation_path: "m/44'/60'/0'/0/0".to_string(), curve: CurveType::SECP256k1, @@ -583,6 +589,7 @@ mod tests { assert_eq!(keystore.derivable(), true); assert_eq!(keystore.id(), "6f8c2912-ebe8-4359-90f4-f1d1f1af1e4d"); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "ETHEREUM".to_string(), derivation_path: "m/44'/60'/0'/0/0".to_string(), curve: CurveType::SECP256k1, diff --git a/token-core/tcx-proto/src/params.proto b/token-core/tcx-proto/src/params.proto index a3c384a7..b7ae81e9 100644 --- a/token-core/tcx-proto/src/params.proto +++ b/token-core/tcx-proto/src/params.proto @@ -192,6 +192,7 @@ message DeriveSubAccountsParam { repeated string relativePaths = 5; string extendedPublicKey = 6; string hrp = 7; + string chain_id = 8; } message DeriveSubAccountsResult { diff --git a/token-core/tcx-substrate/src/address.rs b/token-core/tcx-substrate/src/address.rs index be79f135..472e1990 100644 --- a/token-core/tcx-substrate/src/address.rs +++ b/token-core/tcx-substrate/src/address.rs @@ -71,6 +71,7 @@ mod test_super { ( "12pWV6LvG4iAfNpFNTvvkWy3H9H8wtCkjiXupAzo2BCmPViM", CoinInfo { + chain_id: "".to_string(), coin: "POLKADOT".to_string(), derivation_path: "//imToken//polakdot/0".to_string(), curve: CurveType::SR25519, @@ -82,6 +83,7 @@ mod test_super { ( "EPq15Rj2eTcyVdBBXgyWKVta7Zj4FTo7beB3YHPwtPjxEkr", CoinInfo { + chain_id: "".to_string(), coin: "KUSAMA".to_string(), derivation_path: "//imToken//kusama/0".to_string(), curve: CurveType::SR25519, @@ -101,6 +103,7 @@ mod test_super { let pub_key = sec_key.public_key(); let typed_key = TypedPublicKey::SR25519(pub_key); let mut kusama_coin_info = CoinInfo { + chain_id: "".to_string(), coin: "KUSAMA".to_string(), derivation_path: "//imToken//kusama/0".to_string(), curve: CurveType::SR25519, @@ -122,6 +125,7 @@ mod test_super { #[test] fn test_address_is_valid() { let mut coin_info = CoinInfo { + chain_id: "".to_string(), coin: "KUSAMA".to_string(), derivation_path: "//imToken//kusama/0".to_string(), curve: CurveType::SR25519, @@ -150,6 +154,7 @@ mod test_super { #[test] fn test_address_is_invalid() { let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "KUSAMA".to_string(), derivation_path: "//imToken//kusama/0".to_string(), curve: CurveType::SR25519, diff --git a/token-core/tcx-tezos/src/address.rs b/token-core/tcx-tezos/src/address.rs index e58779ff..bc844c9b 100644 --- a/token-core/tcx-tezos/src/address.rs +++ b/token-core/tcx-tezos/src/address.rs @@ -90,6 +90,7 @@ mod test { #[test] fn from_public_key_test() { let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "TEZOS".to_string(), derivation_path: "".to_string(), curve: CurveType::ED25519, @@ -129,6 +130,7 @@ mod test { #[test] fn is_valid_test() { let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "TEZOS".to_string(), derivation_path: "".to_string(), curve: CurveType::ED25519, @@ -152,6 +154,7 @@ mod test { #[test] fn cross_test_tw() { let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "TEZOS".to_string(), derivation_path: "".to_string(), curve: CurveType::ED25519, diff --git a/token-core/tcx-tron/src/address.rs b/token-core/tcx-tron/src/address.rs index 166b3e8d..a23f1550 100644 --- a/token-core/tcx-tron/src/address.rs +++ b/token-core/tcx-tron/src/address.rs @@ -61,6 +61,7 @@ mod tests { fn tron_address() { let bytes = Vec::from_hex("04DAAC763B1B3492720E404C53D323BAF29391996F7DD5FA27EF0D12F7D50D694700684A32AD97FF4C09BF9CF0B9D0AC7F0091D9C6CB8BE9BB6A1106DA557285D8").unwrap(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "".to_string(), derivation_path: "".to_string(), curve: CurveType::SECP256k1, @@ -129,6 +130,7 @@ mod tests { .unwrap() .public_key(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin: "BITCOINCASH".to_string(), derivation_path: "m/44'/2'/0'/0/0".to_string(), curve: CurveType::SECP256k1, diff --git a/token-core/tcx/src/api.rs b/token-core/tcx/src/api.rs index f3d84dc1..5fed7ccc 100644 --- a/token-core/tcx/src/api.rs +++ b/token-core/tcx/src/api.rs @@ -552,6 +552,8 @@ pub struct DeriveSubAccountsParam { pub extended_public_key: ::prost::alloc::string::String, #[prost(string, tag = "7")] pub hrp: ::prost::alloc::string::String, + #[prost(string, tag = "8")] + pub chain_id: ::prost::alloc::string::String, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] diff --git a/token-core/tcx/src/handler.rs b/token-core/tcx/src/handler.rs index 448132d5..ce936983 100644 --- a/token-core/tcx/src/handler.rs +++ b/token-core/tcx/src/handler.rs @@ -105,6 +105,7 @@ fn derive_account(keystore: &mut Keystore, derivation: &Derivation) -> Result Result> { let pub_key = &public_keys[idx]; let derivation = ¶m.derivations[idx]; let coin_info = CoinInfo { + chain_id: "".to_string(), coin: derivation.chain_type.to_string(), derivation_path: derivation.path.to_string(), curve: CurveType::from_str(&derivation.curve), @@ -1297,6 +1299,7 @@ pub fn derive_sub_accounts(data: &[u8]) -> Result> { )?; coin_info.derivation_path = relative_path.to_string(); coin_info.hrp = param.hrp.to_string(); + coin_info.chain_id = param.chain_id.to_string(); let acc: Account = derive_sub_account(&xpub, &coin_info)?; @@ -1327,6 +1330,7 @@ pub fn mnemonic_to_public(data: &[u8]) -> Result> { let param = MnemonicToPublicKeyParam::decode(data)?; let public_key = tcx_primitive::mnemonic_to_public(¶m.mnemonic, ¶m.path, ¶m.curve)?; let coin_info = CoinInfo { + chain_id: "".to_string(), derivation_path: param.path, curve: CurveType::from_str(¶m.curve), coin: param.encoding, diff --git a/token-core/tcx/src/reset_password.rs b/token-core/tcx/src/reset_password.rs index 640d165f..85078197 100644 --- a/token-core/tcx/src/reset_password.rs +++ b/token-core/tcx/src/reset_password.rs @@ -68,6 +68,7 @@ fn parse_coin_info_from_legacy_ks(value: Value) -> Result<(CoinInfo, String)> { }; let coin_info = CoinInfo { + chain_id: "".to_string(), coin: chain_str.to_string(), derivation_path, curve: CurveType::SECP256k1, @@ -142,6 +143,7 @@ fn parse_coin_info_from_legacy_tcx_ks(legacy_tcx_ks: Value) -> Result<(CoinInfo, .unwrap_or_default() .to_string(); let coin_info = CoinInfo { + chain_id: "".to_string(), coin, derivation_path, curve, diff --git a/token-core/tcx/tests/derive_test.rs b/token-core/tcx/tests/derive_test.rs index 2abfd0a4..61484b42 100644 --- a/token-core/tcx/tests/derive_test.rs +++ b/token-core/tcx/tests/derive_test.rs @@ -20,6 +20,7 @@ use tcx_constants::{OTHER_MNEMONIC, TEST_MNEMONIC, TEST_PASSWORD}; use tcx_constants::{TEST_PRIVATE_KEY, TEST_WIF}; use sp_core::ByteArray; +use tcx::api::derive_accounts_param::Key::Password; use tcx::handler::*; @@ -433,9 +434,9 @@ pub fn test_get_public_keys_ethereum2() { let public_key_result: GetPublicKeysResult = GetPublicKeysResult::decode(ret_bytes.as_slice()).unwrap(); assert_eq!( - "0x99833eeee8cfad1bb7a82a5ceecca02590eeb342ad491c64c270fdb9bd739c398b7f8ca8608bfada25ba4efb5d8e5653", - public_key_result.public_keys[0] - ); + "0x99833eeee8cfad1bb7a82a5ceecca02590eeb342ad491c64c270fdb9bd739c398b7f8ca8608bfada25ba4efb5d8e5653", + public_key_result.public_keys[0] + ); }) } @@ -489,6 +490,7 @@ pub fn test_derive_btc_legacy_sub_accounts() { let (_wallet, accounts) = import_and_derive(derivation); let params = DeriveSubAccountsParam { + chain_id: "".to_string(), chain_type: "BITCOIN".to_string(), curve: "secp256k1".to_string(), network: "MAINNET".to_string(), @@ -531,6 +533,7 @@ pub fn test_derive_btc_p2wpkh_sub_accounts() { let (_wallet, accounts) = import_and_derive(derivation); let params = DeriveSubAccountsParam { + chain_id: "".to_string(), chain_type: "BITCOIN".to_string(), curve: "secp256k1".to_string(), network: "MAINNET".to_string(), @@ -573,6 +576,7 @@ pub fn test_derive_eth_sub_accounts() { let (_, accounts) = import_and_derive(derivation); let params = DeriveSubAccountsParam { + chain_id: "".to_string(), chain_type: "ETHEREUM".to_string(), curve: "secp256k1".to_string(), network: "MAINNET".to_string(), @@ -611,6 +615,7 @@ pub fn test_derive_cosmos_sub_accounts() { let (_, accounts) = import_and_derive(derivation); let params = DeriveSubAccountsParam { + chain_id: "".to_string(), chain_type: "COSMOS".to_string(), curve: "secp256k1".to_string(), network: "MAINNET".to_string(), @@ -632,6 +637,7 @@ pub fn test_derive_cosmos_sub_accounts() { ); let params = DeriveSubAccountsParam { + chain_id: "".to_string(), chain_type: "COSMOS".to_string(), curve: "secp256k1".to_string(), network: "MAINNET".to_string(), @@ -654,6 +660,72 @@ pub fn test_derive_cosmos_sub_accounts() { }) } +#[test] +#[serial] +pub fn test_derive_verify_hrp() { + run_test(|| { + let derivation = Derivation { + chain_type: "COSMOS".to_string(), + path: "m/44'/118'/0'/0/0".to_string(), + network: "MAINNET".to_string(), + seg_wit: "".to_string(), + chain_id: "osmosis-1".to_string(), + curve: "secp256k1".to_string(), + hrp: "cosmos".to_string(), + }; + + let wallet = import_default_wallet(); + + let derivation_param = DeriveAccountsParam { + id: wallet.id.to_string(), + derivations: vec![derivation], + key: Some(Password(TEST_PASSWORD.to_string())), + }; + + let result = derive_accounts(&encode_message(derivation_param).unwrap()); + assert_eq!( + format!("{}", result.err().unwrap()), + "chain_id_and_hrp_not_match" + ); + + let derivation = Derivation { + chain_type: "COSMOS".to_string(), + path: "m/44'/118'/0'/0/0".to_string(), + network: "MAINNET".to_string(), + seg_wit: "".to_string(), + chain_id: "cosmoshub-4".to_string(), + curve: "secp256k1".to_string(), + hrp: "cosmos".to_string(), + }; + + let derivation_param = DeriveAccountsParam { + id: wallet.id.to_string(), + derivations: vec![derivation], + key: Some(Password(TEST_PASSWORD.to_string())), + }; + + let result = derive_accounts(&encode_message(derivation_param).unwrap()).unwrap(); + + let account = DeriveAccountsResult::decode(result.as_slice()).unwrap(); + let params = DeriveSubAccountsParam { + chain_id: "osmosis-1".to_string(), + chain_type: "COSMOS".to_string(), + curve: "secp256k1".to_string(), + network: "MAINNET".to_string(), + seg_wit: "".to_string(), + relative_paths: vec!["0/0".to_string(), "0/1".to_string()], + extended_public_key: account.accounts[0].extended_public_key.to_string(), + hrp: "cosmos".to_string(), + }; + + let result = derive_sub_accounts(&encode_message(params).unwrap()); + assert_eq!( + format!("{}", result.err().unwrap()), + "chain_id_and_hrp_not_match" + ); + }) +} + #[test] #[serial] pub fn test_mnemonic_to_public() {