Skip to content

Commit

Permalink
feat: add top 15 chain_id and hrp verified (#121)
Browse files Browse the repository at this point in the history
  • Loading branch information
XuNeal authored Aug 29, 2024
1 parent 386d5bb commit ffb7824
Show file tree
Hide file tree
Showing 28 changed files with 293 additions and 5 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion token-core/tcx-atom/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ anyhow = { version = "=1.0.79", features = [] }

prost = "=0.11.2"
bytes = "=1.4.0"
base64 = "=0.13.1"
base64 = "=0.13.1"
lazy_static = "1.4.0"
85 changes: 84 additions & 1 deletion token-core/tcx-atom/src/address.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -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<HashMap<String, String>> = {
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);

Expand All @@ -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()
Expand Down Expand Up @@ -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;

Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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"
);
}
}
1 change: 1 addition & 0 deletions token-core/tcx-atom/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 6 additions & 0 deletions token-core/tcx-btc-kin/src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -504,6 +507,7 @@ mod tests {
let mut hd = sample_hd_keystore();
let account = hd
.derive_coin::<BtcKinAddress>(&CoinInfo {
chain_id: "".to_string(),
coin: "DOGECOIN".to_string(),
derivation_path: "m/44'/3'/0'/0/0".to_string(),
curve: CurveType::SECP256k1,
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions token-core/tcx-btc-kin/src/bch_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
6 changes: 6 additions & 0 deletions token-core/tcx-btc-kin/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ impl MessageSigner<BtcMessageInput, BtcMessageOutput> 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,
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions token-core/tcx-btc-kin/src/psbt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions token-core/tcx-btc-kin/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ impl<T: Address + ScriptPubkey + FromStr<Err = anyhow::Error>> KinTransaction<T>
}

let coin_info = CoinInfo {
chain_id: "".to_string(),
coin: params.chain_type.clone(),
derivation_path: params.derivation_path.clone(),
curve: params.curve,
Expand Down
5 changes: 5 additions & 0 deletions token-core/tcx-ckb/src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down
Loading

0 comments on commit ffb7824

Please sign in to comment.