From b9b7079958d7f50baeb491935aba4f1364f18e3e Mon Sep 17 00:00:00 2001 From: xiaoguang1010 <40228114+xiaoguang1010@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:37:47 +0800 Subject: [PATCH 1/5] chore: remove useless serde-aux library (#103) --- Cargo.lock | 12 ------------ token-core/tcx-migration/Cargo.toml | 1 - 2 files changed, 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5575fb73..7d54a54e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3567,17 +3567,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-aux" -version = "4.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d2e8bfba469d06512e11e3311d4d051a4a387a5b42d010404fecf3200321c95" -dependencies = [ - "chrono", - "serde", - "serde_json", -] - [[package]] name = "serde_derive" version = "1.0.147" @@ -4606,7 +4595,6 @@ dependencies = [ "prost", "prost-types", "serde", - "serde-aux", "serde_json", "tcx-atom", "tcx-btc-kin", diff --git a/token-core/tcx-migration/Cargo.toml b/token-core/tcx-migration/Cargo.toml index cd96e165..4b760f51 100644 --- a/token-core/tcx-migration/Cargo.toml +++ b/token-core/tcx-migration/Cargo.toml @@ -41,4 +41,3 @@ base64 = "=0.13.1" base58 = "=0.2.0" parking_lot = "=0.12.1" uuid = { version = "=1.2.2", features = ["serde", "v4"] } -serde-aux = {version = "=4.5.0"} From 82548afa3950537dadf6597fb02b26fc016ec495 Mon Sep 17 00:00:00 2001 From: Neal Xu Date: Tue, 2 Jul 2024 16:31:42 +0800 Subject: [PATCH 2/5] fix: import mnemonic return wrong existed id (#104) --- token-core/tcx/src/filemanager.rs | 7 ++++ token-core/tcx/src/handler.rs | 12 ++++--- token-core/tcx/tests/common/mod.rs | 26 +++++++++++++++ token-core/tcx/tests/import_test.rs | 46 +++++++++++++++++++++++++- token-core/tcx/tests/migration_test.rs | 26 --------------- 5 files changed, 86 insertions(+), 31 deletions(-) diff --git a/token-core/tcx/src/filemanager.rs b/token-core/tcx/src/filemanager.rs index be1fb29e..6ee94195 100644 --- a/token-core/tcx/src/filemanager.rs +++ b/token-core/tcx/src/filemanager.rs @@ -45,3 +45,10 @@ pub fn delete_keystore_file(wid: &str) -> Result<()> { fs::remove_file(path)?; Ok(()) } + +pub fn exist_migrated_file(id: &str) -> bool { + let file_dir = WALLET_FILE_DIR.read(); + let ks_path = format!("{}/{}.json", file_dir, id); + let path = Path::new(&ks_path); + path.exists() +} diff --git a/token-core/tcx/src/handler.rs b/token-core/tcx/src/handler.rs index fe0a28ae..7daf047b 100644 --- a/token-core/tcx/src/handler.rs +++ b/token-core/tcx/src/handler.rs @@ -45,8 +45,8 @@ use crate::api::{EthBatchPersonalSignParam, EthBatchPersonalSignResult}; use crate::api::{InitTokenCoreXParam, SignParam}; use crate::error_handling::Result; use crate::filemanager::{ - cache_keystore, clean_keystore, flush_keystore, KEYSTORE_BASE_DIR, LEGACY_WALLET_FILE_DIR, - WALLET_FILE_DIR, WALLET_V1_DIR, WALLET_V2_DIR, + cache_keystore, clean_keystore, exist_migrated_file, flush_keystore, KEYSTORE_BASE_DIR, + LEGACY_WALLET_FILE_DIR, WALLET_FILE_DIR, WALLET_V1_DIR, WALLET_V2_DIR, }; use crate::filemanager::{delete_keystore_file, KEYSTORE_MAP}; @@ -152,7 +152,9 @@ fn import_private_key_internal( let fingerprint = fingerprint_from_any_format_pk(¶m.private_key)?; let map = KEYSTORE_MAP.read(); if let Some(founded) = map.values().find(|keystore| { - keystore.fingerprint() == fingerprint && keystore.id() != overwrite_id.to_string() + keystore.fingerprint() == fingerprint + && keystore.id() != overwrite_id.to_string() + && exist_migrated_file(&keystore.id()) }) { target_id = Some(founded.id()); } @@ -533,7 +535,9 @@ pub fn import_mnemonic(data: &[u8]) -> Result> { let fingerprint = fingerprint_from_mnemonic(¶m.mnemonic)?; let map = KEYSTORE_MAP.read(); if let Some(founded) = map.values().find(|keystore| { - keystore.fingerprint() == fingerprint && keystore.id() != param.overwrite_id.to_string() + keystore.fingerprint() == fingerprint + && keystore.id() != param.overwrite_id.to_string() + && exist_migrated_file(&keystore.id()) }) { target_id = Some(founded.id()); } diff --git a/token-core/tcx/tests/common/mod.rs b/token-core/tcx/tests/common/mod.rs index cea1e76d..30dc345d 100644 --- a/token-core/tcx/tests/common/mod.rs +++ b/token-core/tcx/tests/common/mod.rs @@ -175,3 +175,29 @@ pub fn remove_created_wallet(wid: &str) { let p = Path::new(&full_file_path); remove_file(p).expect("should remove file"); } + +fn copy_dir(src: &Path, dst: &Path) -> tcx::Result<()> { + if src.is_dir() { + fs::create_dir_all(dst)?; // Create destination directory if it doesn't exist + for entry in src.read_dir()? { + let entry = entry?; + let path = entry.path(); + let new_dest = dst.join(path.strip_prefix(src)?); + if path.is_dir() { + copy_dir(&path, &new_dest)?; // Recursively copy subdirectories + } else { + fs::copy(&path, &new_dest)?; // Copy files + } + } + } else { + return Err(anyhow!("source is not a directory")); + } + Ok(()) +} + +pub fn setup_test(old_wallet_dir: &str) { + let _ = fs::remove_dir_all("/tmp/token-core-x"); + copy_dir(&Path::new(old_wallet_dir), &Path::new("/tmp/token-core-x")).unwrap(); + + init_token_core_x("/tmp/token-core-x"); +} diff --git a/token-core/tcx/tests/import_test.rs b/token-core/tcx/tests/import_test.rs index 5f259b4c..72fc7acd 100644 --- a/token-core/tcx/tests/import_test.rs +++ b/token-core/tcx/tests/import_test.rs @@ -17,7 +17,7 @@ use tcx::api::{ ExistsJsonParam, ExistsKeystoreResult, ExistsPrivateKeyParam, ExportJsonParam, ExportJsonResult, ExportMnemonicParam, ExportMnemonicResult, ExportPrivateKeyParam, ExportPrivateKeyResult, ImportJsonParam, ImportMnemonicParam, ImportPrivateKeyParam, - ImportPrivateKeyResult, KeystoreResult, WalletKeyParam, + ImportPrivateKeyResult, KeystoreResult, MigrateKeystoreParam, WalletKeyParam, }; use tcx::handler::{encode_message, import_private_key}; @@ -1588,6 +1588,50 @@ pub fn test_reset_password_hd_seed_already_exist() { }) } +#[test] +#[serial] +pub fn test_reset_password_multi_hd_wallet() { + setup_test("../test-data/reset-password-wallets"); + let import_param = ImportMnemonicParam { + mnemonic: TEST_MNEMONIC.to_string(), + password: "imToken@1".to_string(), + network: "MAINNET".to_string(), + name: "reset_password".to_string(), + password_hint: "".to_string(), + overwrite_id: "a7c5ed76-5249-4e23-adcc-a36c519383a5".to_string(), + }; + + let ret = call_api("import_mnemonic", import_param).unwrap(); + let import_mnemonic_result = KeystoreResult::decode(ret.as_slice()).unwrap(); + assert!(!import_mnemonic_result.is_existed); + + let migration_param = MigrateKeystoreParam { + id: "0551d81c-d923-4b8f-ac83-07b575eebcd4".to_string(), + network: "MAINNET".to_string(), + key: Some(api::migrate_keystore_param::Key::Password( + "imToken@1".to_string(), + )), + }; + + call_api("migrate_keystore", migration_param).unwrap(); + + let import_param = ImportMnemonicParam { + mnemonic: TEST_MNEMONIC.to_string(), + password: "imToken@1".to_string(), + network: "MAINNET".to_string(), + name: "reset_password".to_string(), + password_hint: "".to_string(), + overwrite_id: "b7e27e86-6214-4e31-9f8f-ec493754e0fc".to_string(), + }; + + let ret = call_api("import_mnemonic", import_param).unwrap(); + let import_mnemonic_result = KeystoreResult::decode(ret.as_slice()).unwrap(); + assert_eq!( + import_mnemonic_result.existed_id, + "a7c5ed76-5249-4e23-adcc-a36c519383a5" + ) +} + #[test] #[serial] pub fn test_reset_password_hd_valid_overwrite_wallet_first() { diff --git a/token-core/tcx/tests/migration_test.rs b/token-core/tcx/tests/migration_test.rs index 98307461..7572ac9b 100644 --- a/token-core/tcx/tests/migration_test.rs +++ b/token-core/tcx/tests/migration_test.rs @@ -741,32 +741,6 @@ pub fn test_migrate_keystores_identified_chain_types_mainnet() { ); } -fn copy_dir(src: &Path, dst: &Path) -> Result<()> { - if src.is_dir() { - fs::create_dir_all(dst)?; // Create destination directory if it doesn't exist - for entry in src.read_dir()? { - let entry = entry?; - let path = entry.path(); - let new_dest = dst.join(path.strip_prefix(src)?); - if path.is_dir() { - copy_dir(&path, &new_dest)?; // Recursively copy subdirectories - } else { - fs::copy(&path, &new_dest)?; // Copy files - } - } - } else { - return Err(anyhow!("source is not a directory")); - } - Ok(()) -} - -fn setup_test(old_wallet_dir: &str) { - let _ = fs::remove_dir_all("/tmp/token-core-x"); - copy_dir(&Path::new(old_wallet_dir), &Path::new("/tmp/token-core-x")).unwrap(); - - init_token_core_x("/tmp/token-core-x"); -} - #[test] #[serial] fn test_migrate_duplicate_then_delete_keystore() { From c223227333bda7d036cb20e46afdc7a26d9cfdd9 Mon Sep 17 00:00:00 2001 From: Neal Xu Date: Mon, 8 Jul 2024 14:53:56 +0800 Subject: [PATCH 3/5] feat: allow import test wif in production env (#105) --- VERSION | 2 +- token-core/tcx/src/handler.rs | 10 ------ token-core/tcx/tests/derive_test.rs | 41 +++++++++++++++++++++- token-core/tcx/tests/import_test.rs | 54 +++++++++-------------------- 4 files changed, 57 insertions(+), 50 deletions(-) diff --git a/VERSION b/VERSION index 2c9b4ef4..a4dd9dba 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.7.3 +2.7.4 diff --git a/token-core/tcx/src/handler.rs b/token-core/tcx/src/handler.rs index 7daf047b..0d93c9eb 100644 --- a/token-core/tcx/src/handler.rs +++ b/token-core/tcx/src/handler.rs @@ -173,16 +173,6 @@ fn import_private_key_internal( } let decoded_ret = decode_private_key(¶m.private_key)?; - if !decoded_ret.network.is_empty() { - let expected_network = if param.network.is_empty() { - "MAINNET" - } else { - param.network.as_str() - }; - if decoded_ret.network != expected_network { - return Err(anyhow!("{}", "private_key_network_mismatch")); - } - } let private_key = decoded_ret.bytes.to_hex(); let meta_source = if let Some(source) = source { diff --git a/token-core/tcx/tests/derive_test.rs b/token-core/tcx/tests/derive_test.rs index e9c999b7..e29cd1e7 100644 --- a/token-core/tcx/tests/derive_test.rs +++ b/token-core/tcx/tests/derive_test.rs @@ -16,8 +16,8 @@ use tcx::api::{ }; use tcx::handler::encode_message; use tcx::handler::import_mnemonic; -use tcx_constants::TEST_PRIVATE_KEY; use tcx_constants::{OTHER_MNEMONIC, TEST_MNEMONIC, TEST_PASSWORD}; +use tcx_constants::{TEST_PRIVATE_KEY, TEST_WIF}; use sp_core::ByteArray; @@ -821,3 +821,42 @@ fn test_derive_other_curve_on_pk_keystore() { ); }) } + +#[test] +#[serial] +fn test_derive_mainnet_account_on_test_wif() { + run_test(|| { + let param = ImportPrivateKeyParam { + password: TEST_PASSWORD.to_string(), + private_key: TEST_WIF.to_string(), + name: "wif".to_string(), + password_hint: "".to_string(), + network: "MAINNET".to_string(), + overwrite_id: "".to_string(), + }; + let ret = call_api("import_private_key", param).unwrap(); + let imported = ImportPrivateKeyResult::decode(ret.as_slice()).unwrap(); + + let derive_param = DeriveAccountsParam { + id: imported.id.to_string(), + derivations: vec![Derivation { + chain_type: "BITCOIN".to_string(), + chain_id: "".to_string(), + path: "".to_string(), + network: "TESTNET".to_string(), + curve: "secp256k1".to_string(), + seg_wit: "VERSION_1".to_string(), + bech32_prefix: "".to_string(), + }], + key: Some(api::derive_accounts_param::Key::Password( + TEST_PASSWORD.to_string(), + )), + }; + let ret = call_api("derive_accounts", derive_param).unwrap(); + let accounts = DeriveAccountsResult::decode(ret.as_slice()).unwrap(); + assert_eq!( + accounts.accounts[0].address, + "tb1pqpae4d6594jj3yueluku5tlu7r6nqwm24xc8thk5g396s9e5anvqdwrut7" + ); + }) +} diff --git a/token-core/tcx/tests/import_test.rs b/token-core/tcx/tests/import_test.rs index 72fc7acd..a7f11dbc 100644 --- a/token-core/tcx/tests/import_test.rs +++ b/token-core/tcx/tests/import_test.rs @@ -13,11 +13,12 @@ use tcx_keystore::keystore::IdentityNetwork; use prost::Message; use tcx::api::{ - export_private_key_param, CreateKeystoreParam, DeriveAccountsParam, DeriveAccountsResult, - ExistsJsonParam, ExistsKeystoreResult, ExistsPrivateKeyParam, ExportJsonParam, - ExportJsonResult, ExportMnemonicParam, ExportMnemonicResult, ExportPrivateKeyParam, - ExportPrivateKeyResult, ImportJsonParam, ImportMnemonicParam, ImportPrivateKeyParam, - ImportPrivateKeyResult, KeystoreResult, MigrateKeystoreParam, WalletKeyParam, + export_private_key_param, wallet_key_param, BackupResult, CreateKeystoreParam, + DeriveAccountsParam, DeriveAccountsResult, ExistsJsonParam, ExistsKeystoreResult, + ExistsPrivateKeyParam, ExportJsonParam, ExportJsonResult, ExportMnemonicParam, + ExportMnemonicResult, ExportPrivateKeyParam, ExportPrivateKeyResult, ImportJsonParam, + ImportMnemonicParam, ImportPrivateKeyParam, ImportPrivateKeyResult, KeystoreResult, + MigrateKeystoreParam, WalletKeyParam, }; use tcx::handler::{encode_message, import_private_key}; @@ -1161,20 +1162,6 @@ pub fn test_import_hex_private_key() { #[serial] pub fn test_import_wif_network_mismatch() { run_test(|| { - let param: ImportPrivateKeyParam = ImportPrivateKeyParam { - private_key: TEST_WIF.to_string(), - password: TEST_PASSWORD.to_string(), - name: "import_private_key_wallet".to_string(), - password_hint: "".to_string(), - network: "".to_string(), - overwrite_id: "".to_string(), - }; - let ret = call_api("import_private_key", param); - assert_eq!( - format!("{}", ret.unwrap_err()), - "private_key_network_mismatch" - ); - let param: ImportPrivateKeyParam = ImportPrivateKeyParam { private_key: TEST_WIF.to_string(), password: TEST_PASSWORD.to_string(), @@ -1183,26 +1170,17 @@ pub fn test_import_wif_network_mismatch() { network: "MAINNET".to_string(), overwrite_id: "".to_string(), }; - let ret = call_api("import_private_key", param); - // let import_result: ImportPrivateKeyResult = - // ImportPrivateKeyResult::decode(ret.as_slice()); - assert_eq!( - format!("{}", ret.unwrap_err()), - "private_key_network_mismatch" - ); - - let param: ImportPrivateKeyParam = ImportPrivateKeyParam { - private_key: TEST_WIF.to_string(), - password: TEST_PASSWORD.to_string(), - name: "import_private_key_wallet".to_string(), - password_hint: "".to_string(), - network: "TESTNET".to_string(), - overwrite_id: "".to_string(), + let ret = call_api("import_private_key", param).expect("import_private_key_test"); + let import_private_key_ret = ImportPrivateKeyResult::decode(ret.as_slice()).unwrap(); + assert_eq!("TESTNET", import_private_key_ret.identified_network); + let backup_param = WalletKeyParam { + id: import_private_key_ret.id.to_string(), + key: Some(wallet_key_param::Key::Password(TEST_PASSWORD.to_string())), }; - let ret = call_api("import_private_key", param).unwrap(); - let import_result: ImportPrivateKeyResult = - ImportPrivateKeyResult::decode(ret.as_slice()).unwrap(); - assert_eq!(import_result.identified_network, "TESTNET"); + + let ret = call_api("backup", backup_param).unwrap(); + let backup_result = BackupResult::decode(ret.as_slice()).unwrap(); + assert_eq!(backup_result.original, TEST_WIF); }) } From 74b634bc50464ee102838894ac581b5ba94c20b8 Mon Sep 17 00:00:00 2001 From: Neal Xu Date: Thu, 11 Jul 2024 14:19:24 +0800 Subject: [PATCH 4/5] feat: taproot sign script (#98) * Add PsbtSigner * finish taproot sign in psbt * feat: add taproot sign script fix: rebase issue fix: append script and control block to witness * fix: sign tap script no need tweak privatekey Fix after rebase * fix: merge missing code * chore: remove println hash * add bip322 message signature * add multi address type in bitcoin psbt * add tests for bitcoin bip322 sign --------- Co-authored-by: Sun Feng --- Cargo.lock | 5 + token-core/tcx-btc-kin/Cargo.toml | 2 +- token-core/tcx-btc-kin/src/bch_sighash.rs | 10 + token-core/tcx-btc-kin/src/lib.rs | 56 ++- token-core/tcx-btc-kin/src/message.rs | 235 +++++++++++ token-core/tcx-btc-kin/src/psbt.rs | 464 ++++++++++++++++++---- token-core/tcx-btc-kin/src/sighash.rs | 23 ++ token-core/tcx-btc-kin/src/signer.rs | 35 +- token-core/tcx-btc-kin/src/transaction.rs | 12 + token-core/tcx-proto/src/btc_kin.proto | 8 + token-core/tcx/tests/sign_test.rs | 42 +- 11 files changed, 784 insertions(+), 108 deletions(-) create mode 100644 token-core/tcx-btc-kin/src/message.rs diff --git a/Cargo.lock b/Cargo.lock index 7d54a54e..1a355dd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -222,6 +222,7 @@ dependencies = [ "bech32 0.9.1", "bitcoin_hashes", "secp256k1", + "serde", ] [[package]] @@ -229,6 +230,9 @@ name = "bitcoin_hashes" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" +dependencies = [ + "serde", +] [[package]] name = "bitflags" @@ -3509,6 +3513,7 @@ dependencies = [ "bitcoin_hashes", "rand 0.8.5", "secp256k1-sys", + "serde", ] [[package]] diff --git a/token-core/tcx-btc-kin/Cargo.toml b/token-core/tcx-btc-kin/Cargo.toml index 9fe6f3a3..7eede65b 100644 --- a/token-core/tcx-btc-kin/Cargo.toml +++ b/token-core/tcx-btc-kin/Cargo.toml @@ -14,7 +14,7 @@ tcx-common = { path = "../tcx-common" } hex = "=0.4.3" base64 = "=0.13.1" -bitcoin = "=0.29.2" +bitcoin = {version = "=0.29.2", features = ["serde", "std", "secp-recovery"] } secp256k1 = {version ="=0.24.3", features = ["rand", "recovery", "rand-std"] } tiny-bip39 = "=1.0.0" bitcoin_hashes = "=0.11.0" diff --git a/token-core/tcx-btc-kin/src/bch_sighash.rs b/token-core/tcx-btc-kin/src/bch_sighash.rs index fc101d35..8961ffe9 100644 --- a/token-core/tcx-btc-kin/src/bch_sighash.rs +++ b/token-core/tcx-btc-kin/src/bch_sighash.rs @@ -181,4 +181,14 @@ impl TxSignatureHasher for BitcoinCashSighash { ) -> Result { Err(Error::UnsupportedTaproot.into()) } + + fn taproot_script_spend_signature_hash( + &mut self, + input_index: usize, + prevouts: &Prevouts, + tap_leaf_hash: TapLeafHash, + sighash_type: SchnorrSighashType, + ) -> Result { + Err(Error::UnsupportedTaproot.into()) + } } diff --git a/token-core/tcx-btc-kin/src/lib.rs b/token-core/tcx-btc-kin/src/lib.rs index c259b19e..f3fe6d15 100644 --- a/token-core/tcx-btc-kin/src/lib.rs +++ b/token-core/tcx-btc-kin/src/lib.rs @@ -9,6 +9,7 @@ pub mod network; pub mod signer; pub mod transaction; +mod message; mod psbt; use core::result; @@ -56,6 +57,9 @@ pub enum Error { ConstructBchAddressFailed(String), #[error("unsupported_taproot")] UnsupportedTaproot, + + #[error("missing_signature")] + MissingSignature, } pub mod bitcoin { @@ -64,6 +68,10 @@ pub mod bitcoin { pub type Address = crate::BtcKinAddress; pub type TransactionInput = crate::transaction::BtcKinTxInput; pub type TransactionOutput = crate::transaction::BtcKinTxOutput; + + pub type MessageInput = crate::transaction::BtcMessageInput; + + pub type MessageOutput = crate::transaction::BtcMessageOutput; } pub mod bitcoincash { @@ -76,6 +84,10 @@ pub mod bitcoincash { pub type TransactionInput = crate::transaction::BtcKinTxInput; pub type TransactionOutput = crate::transaction::BtcKinTxOutput; + + pub type MessageInput = crate::transaction::BtcMessageInput; + + pub type MessageOutput = crate::transaction::BtcMessageOutput; } pub mod omni { @@ -92,8 +104,10 @@ pub mod omni { #[cfg(test)] mod tests { - use tcx_constants::{TEST_MNEMONIC, TEST_PASSWORD}; + use tcx_common::ToHex; + use tcx_constants::{CurveType, TEST_MNEMONIC, TEST_PASSWORD, TEST_WIF}; use tcx_keystore::{Keystore, Metadata}; + use tcx_primitive::{PrivateKey, Secp256k1PrivateKey}; pub fn hd_keystore(mnemonic: &str) -> Keystore { let mut keystore = @@ -102,7 +116,47 @@ mod tests { keystore } + pub fn private_keystore(wif: &str) -> Keystore { + let sec_key = Secp256k1PrivateKey::from_wif(wif).unwrap(); + let mut keystore = Keystore::from_private_key( + &sec_key.to_bytes().to_hex(), + TEST_PASSWORD, + CurveType::SECP256k1, + Metadata::default(), + None, + ) + .unwrap(); + keystore.unlock_by_password(TEST_PASSWORD).unwrap(); + keystore + } + pub fn sample_hd_keystore() -> Keystore { hd_keystore(TEST_MNEMONIC) } + + pub fn hex_keystore(hex: &str) -> Keystore { + let mut keystore = Keystore::from_private_key( + hex, + TEST_PASSWORD, + CurveType::SECP256k1, + Metadata::default(), + None, + ) + .unwrap(); + keystore.unlock_by_password(TEST_PASSWORD).unwrap(); + keystore + } + + pub fn wif_keystore(wif: &str) -> Keystore { + let hex = Secp256k1PrivateKey::from_wif(wif) + .unwrap() + .to_bytes() + .to_hex(); + + hex_keystore(&hex) + } + + pub fn sample_wif_keystore() -> Keystore { + wif_keystore(TEST_WIF) + } } diff --git a/token-core/tcx-btc-kin/src/message.rs b/token-core/tcx-btc-kin/src/message.rs new file mode 100644 index 00000000..800241b4 --- /dev/null +++ b/token-core/tcx-btc-kin/src/message.rs @@ -0,0 +1,235 @@ +use crate::psbt::PsbtSigner; +use crate::transaction::{BtcMessageInput, BtcMessageOutput}; +use crate::{BtcKinAddress, Error, Result}; +use bitcoin::psbt::PartiallySignedTransaction; +use bitcoin::{ + OutPoint, PackedLockTime, Script, Sequence, Transaction, TxIn, TxOut, Txid, Witness, +}; +use tcx_common::{sha256, utf8_or_hex_to_bytes, FromHex, ToHex}; +use tcx_constants::{CoinInfo, CurveType}; +use tcx_keystore::{Address, Keystore, MessageSigner, SignatureParameters}; + +const UTXO: &str = "0000000000000000000000000000000000000000000000000000000000000000"; +const TAG: &str = "BIP0322-signed-message"; +fn get_spend_tx_id(data: &[u8], script_pub_key: Script) -> Result { + let tag_hash = sha256(&TAG.as_bytes().to_vec()); + let mut to_sign = Vec::new(); + to_sign.extend(tag_hash.clone()); + to_sign.extend(tag_hash); + to_sign.extend(data); + + let hash = sha256(&to_sign); + let mut script_sig = Vec::new(); + script_sig.extend([0x00, 0x20]); + script_sig.extend(hash); + + //Tx ins + let ins = vec![TxIn { + previous_output: OutPoint { + txid: UTXO.parse()?, + vout: 0xFFFFFFFF, + }, + script_sig: Script::from(script_sig), + sequence: Sequence(0), + witness: Witness::new(), + }]; + + //Tx outs + let outs = vec![TxOut { + value: 0, + script_pubkey: script_pub_key, + }]; + + let tx = Transaction { + version: 0, + lock_time: PackedLockTime::ZERO, + input: ins, + output: outs, + }; + + Ok(tx.txid()) +} + +fn create_to_sign_empty(txid: Txid, script_pub_key: Script) -> Result { + //Tx ins + let ins = vec![TxIn { + previous_output: OutPoint { txid, vout: 0 }, + script_sig: Script::new(), + sequence: Sequence(0), + witness: Witness::new(), + }]; + + //Tx outs + let outs = vec![TxOut { + value: 0, + script_pubkey: Script::from(Vec::::from_hex("6a")?), + }]; + + let tx = Transaction { + version: 0, + lock_time: PackedLockTime::ZERO, + input: ins, + output: outs, + }; + + let mut psbt = PartiallySignedTransaction::from_unsigned_tx(tx)?; + psbt.inputs[0].witness_utxo = Some(TxOut { + value: 0, + script_pubkey: script_pub_key, + }); + + Ok(psbt) +} + +fn witness_to_vec(witness: Vec>) -> Vec { + let mut ret: Vec = Vec::new(); + ret.push(witness.len() as u8); + for item in witness { + ret.push(item.len() as u8); + ret.extend(item); + } + ret +} + +impl MessageSigner for Keystore { + fn sign_message( + &mut self, + params: &SignatureParameters, + message_input: &BtcMessageInput, + ) -> tcx_keystore::Result { + let data = utf8_or_hex_to_bytes(&message_input.message)?; + let path = format!("{}/0/0", params.derivation_path); + + let public_key = self.get_public_key(CurveType::SECP256k1, &path)?; + let coin_info = CoinInfo { + coin: params.chain_type.to_string(), + derivation_path: path.clone(), + curve: CurveType::SECP256k1, + network: params.network.to_string(), + seg_wit: params.seg_wit.to_string(), + }; + + let address = BtcKinAddress::from_public_key(&public_key, &coin_info)?; + + let tx_id = get_spend_tx_id(&data, address.script_pubkey())?; + let mut psbt = create_to_sign_empty(tx_id, address.script_pubkey())?; + let mut psbt_signer = PsbtSigner::new( + &mut psbt, + self, + ¶ms.chain_type, + ¶ms.derivation_path, + true, + ); + + psbt_signer.sign()?; + + if let Some(witness) = &psbt.inputs[0].final_script_witness { + Ok(BtcMessageOutput { + signature: witness_to_vec(witness.to_vec()).to_hex(), + }) + } else { + Err(Error::MissingSignature.into()) + } + } +} + +#[cfg(test)] +mod tests { + use crate::tests::{sample_hd_keystore, wif_keystore}; + use crate::BtcKinAddress; + use tcx_constants::{CoinInfo, CurveType}; + use tcx_keystore::{Address, MessageSigner}; + + #[test] + fn test_to_spend_tx_id() { + let message = "hello world"; + let mut ks = sample_hd_keystore(); + let coin_info = CoinInfo { + coin: "BITCOIN".to_string(), + derivation_path: "m/44'/0'/0'/0/0".to_string(), + curve: CurveType::SECP256k1, + network: "MAINNET".to_string(), + seg_wit: "VERSION_0".to_string(), + }; + + let account = ks.derive_coin::(&coin_info).unwrap(); + let address = BtcKinAddress::from_public_key(&account.public_key, &coin_info).unwrap(); + + assert_eq!( + super::get_spend_tx_id(message.as_bytes(), address.script_pubkey()) + .unwrap() + .to_string(), + "24bca2df5140bcf6a6aeafd141ad40b0595aa6998ca0fc733488d7131ca7763f" + ); + } + + #[test] + fn test_bip322_segwit() { + let message = "hello world"; + let mut ks = sample_hd_keystore(); + let coin_info = CoinInfo { + coin: "BITCOIN".to_string(), + derivation_path: "m/44'/0'/0'/0/0".to_string(), + curve: CurveType::SECP256k1, + network: "MAINNET".to_string(), + seg_wit: "VERSION_0".to_string(), + }; + + let account = ks.derive_coin::(&coin_info).unwrap(); + let address = BtcKinAddress::from_public_key(&account.public_key, &coin_info).unwrap(); + + let params = tcx_keystore::SignatureParameters { + curve: CurveType::SECP256k1, + chain_type: "BITCOIN".to_string(), + network: "MAINNET".to_string(), + seg_wit: "VERSION_0".to_string(), + derivation_path: "m/44'/0'/0'".to_string(), + }; + + let output = ks + .sign_message( + ¶ms, + &super::BtcMessageInput { + message: message.to_string(), + }, + ) + .unwrap(); + + assert_eq!(output.signature, "024830450221009f003820d1db93bf78be08dafdd05b7dde7c31a73c9be36b705a15329bd3d0e502203eb6f1a34466995e4b9c281bf4a093a1f55a21b2ef961438c9ae284efab27dda0121026b5b6a9d041bc5187e0b34f9e496436c7bff261c6c1b5f3c06b433c61394b868"); + } + + #[test] + fn test_bip322_taproot() { + let message = "Sign this message to log in to https://www.subber.xyz // 200323342"; + let mut ks = wif_keystore("L4F5BYm82Bck6VEY64EbqQkoBXqkegq9X9yc6iLTV3cyJoqUasnY"); + let coin_info = CoinInfo { + coin: "BITCOIN".to_string(), + derivation_path: "m/86'/0'/0'/0/0".to_string(), + curve: CurveType::SECP256k1, + network: "MAINNET".to_string(), + seg_wit: "VERSION_1".to_string(), + }; + + let account = ks.derive_coin::(&coin_info).unwrap(); + let address = BtcKinAddress::from_public_key(&account.public_key, &coin_info).unwrap(); + + let params = tcx_keystore::SignatureParameters { + curve: CurveType::SECP256k1, + chain_type: "BITCOIN".to_string(), + network: "MAINNET".to_string(), + seg_wit: "VERSION_1".to_string(), + derivation_path: "m/86'/0'/0'".to_string(), + }; + + let output = ks + .sign_message( + ¶ms, + &super::BtcMessageInput { + message: message.to_string(), + }, + ) + .unwrap(); + + // assert_eq!(output.signature, "0140717dbc46e9d816d7c9e26b5a5f6153c1fceb734489afaaee4ed80bc7c119a39af44de7f6d66c30e530c7c696a25d45bab052cc55012fc57ef6cb24313b31014b"); + } +} diff --git a/token-core/tcx-btc-kin/src/psbt.rs b/token-core/tcx-btc-kin/src/psbt.rs index 09c4ee50..08ab127b 100644 --- a/token-core/tcx-btc-kin/src/psbt.rs +++ b/token-core/tcx-btc-kin/src/psbt.rs @@ -2,11 +2,12 @@ use crate::bch_sighash::BitcoinCashSighash; use crate::sighash::TxSignatureHasher; use crate::transaction::{PsbtInput, PsbtOutput}; use crate::{Error, Result, BITCOINCASH}; +use bitcoin::blockdata::script::Builder; use bitcoin::consensus::{Decodable, Encodable}; use bitcoin::psbt::{Prevouts, Psbt}; use bitcoin::schnorr::TapTweak; -use bitcoin::util::bip32::KeySource; use bitcoin::util::sighash::SighashCache; +use bitcoin::util::taproot::TapLeafHash; use bitcoin::{ EcdsaSig, EcdsaSighashType, SchnorrSig, SchnorrSighashType, Script, TxOut, WPubkeyHash, Witness, }; @@ -24,62 +25,19 @@ pub struct PsbtSigner<'a> { psbt: &'a mut Psbt, keystore: &'a mut Keystore, derivation_path: String, + auto_finalize: bool, prevouts: Vec, sighash_cache: Box, } -pub trait PsbtInputExtra { - fn is_taproot(&self) -> bool; - - fn clear_finalized_input(&mut self); - - fn finalize(&mut self); -} - -impl PsbtInputExtra for bitcoin::psbt::Input { - fn is_taproot(&self) -> bool { - return self.tap_internal_key.is_some() - || !self.tap_key_origins.is_empty() - || self.tap_merkle_root.is_some() - || self.tap_key_sig.is_some() - || !self.tap_script_sigs.is_empty(); - } - - fn clear_finalized_input(&mut self) { - self.tap_key_sig = None; - self.tap_scripts = BTreeMap::new(); - self.tap_internal_key = None; - self.tap_merkle_root = None; - self.tap_script_sigs = BTreeMap::new(); - - self.partial_sigs = BTreeMap::new(); - self.sighash_type = None; - self.redeem_script = None; - self.witness_script = None; - self.bip32_derivation = BTreeMap::new(); - self.unknown = BTreeMap::new(); - } - - fn finalize(&mut self) { - if self.is_taproot() { - if self.tap_key_sig.is_some() { - let mut witness = Witness::new(); - witness.push(self.tap_key_sig.unwrap().to_vec()); - self.final_script_witness = Some(witness); - } - } - - self.clear_finalized_input(); - } -} - impl<'a> PsbtSigner<'a> { pub fn new( psbt: &'a mut Psbt, keystore: &'a mut Keystore, chain_type: &str, derivation_path: &str, + auto_finalize: bool, ) -> Self { let unsigned_tx = psbt.unsigned_tx.clone(); @@ -93,14 +51,15 @@ impl<'a> PsbtSigner<'a> { psbt, keystore, derivation_path: derivation_path.to_string(), + auto_finalize, sighash_cache, prevouts: Vec::new(), } } - fn hash160(&self, input: &[u8]) -> hash160::Hash { - hash160::Hash::hash(input) + fn hash160(input: &[u8]) -> hash160::Hash { + Hash::hash(input) } fn sign_ecdsa(data: &[u8], key: &Secp256k1PrivateKey) -> Result { @@ -129,18 +88,28 @@ impl<'a> PsbtSigner<'a> { Ok(utxos) } - fn get_private_key(&mut self, index: usize) -> Result { + fn get_private_key(&mut self, index: usize, is_p2tr: bool) -> Result { let input = &self.psbt.inputs[index]; - let bip32_derivations: Vec<&KeySource> = input.bip32_derivation.values().collect(); - - let path = if !bip32_derivations.is_empty() { - bip32_derivations[0].1.to_string() - } else if !self.derivation_path.is_empty() { - self.derivation_path.clone() + "/0/0" + let mut path = if !self.derivation_path.is_empty() { + format!("{}/0/0", self.derivation_path) } else { "".to_string() }; + if is_p2tr { + let tap_bip32_derivation = input.tap_key_origins.first_key_value(); + + if let Some((_, key_source)) = tap_bip32_derivation { + path = key_source.1 .1.to_string(); + } + } else { + let bip32_derivations = input.bip32_derivation.first_key_value(); + + if let Some((_, key_source)) = bip32_derivations { + path = key_source.1.to_string(); + } + } + Ok(self .keystore .get_private_key(CurveType::SECP256k1, &path)? @@ -148,8 +117,91 @@ impl<'a> PsbtSigner<'a> { .clone()) } + fn finalize_p2wpkh(&mut self, index: usize) { + let mut input = &mut self.psbt.inputs[index]; + + if !input.partial_sigs.is_empty() { + let sig = input.partial_sigs.first_key_value().unwrap(); + let mut witness = Witness::new(); + + witness.push(sig.1.to_vec()); + witness.push(sig.0.to_bytes()); + + input.final_script_witness = Some(witness) + } + } + + fn finalize_p2pkh(&mut self, index: usize) { + let mut input = &mut self.psbt.inputs[index]; + + if !input.partial_sigs.is_empty() { + let sig = input.partial_sigs.first_key_value().unwrap(); + + input.final_script_sig = Some( + Builder::new() + .push_slice(&sig.1.to_vec()) + .push_slice(&sig.0.to_bytes()) + .into_script(), + ); + } + } + + fn finalize_p2sh_nested_p2wpkh(&mut self, index: usize) { + let mut input = &mut self.psbt.inputs[index]; + + if !input.partial_sigs.is_empty() { + let sig = input.partial_sigs.first_key_value().unwrap(); + + let script = + Script::new_v0_p2wpkh(&WPubkeyHash::from_hash(Self::hash160(&sig.0.to_bytes()))); + + input.final_script_sig = Some(script); + + let mut witness = Witness::new(); + witness.push(sig.1.to_vec()); + witness.push(sig.0.to_bytes()); + + input.final_script_witness = Some(witness); + } + } + + fn finalize_p2tr(&mut self, index: usize) { + let mut input = &mut self.psbt.inputs[index]; + + if input.tap_key_sig.is_some() { + let mut witness = Witness::new(); + witness.push(input.tap_key_sig.unwrap().to_vec()); + + if !input.tap_scripts.is_empty() { + let (control_block, script_leaf) = input.tap_scripts.first_key_value().unwrap(); + + let (script, _) = script_leaf; + witness.push(script.as_bytes().to_vec()); + witness.push(control_block.serialize()) + } + + input.final_script_witness = Some(witness); + } + } + + fn clear_finalized_input(&mut self, index: usize) { + let mut input = &mut self.psbt.inputs[index]; + input.tap_key_sig = None; + input.tap_scripts = BTreeMap::new(); + input.tap_internal_key = None; + input.tap_merkle_root = None; + input.tap_script_sigs = BTreeMap::new(); + + input.partial_sigs = BTreeMap::new(); + input.sighash_type = None; + input.redeem_script = None; + input.witness_script = None; + input.bip32_derivation = BTreeMap::new(); + input.unknown = BTreeMap::new(); + } + fn sign_p2pkh(&mut self, index: usize) -> Result<()> { - let key = self.get_private_key(index)?; + let key = self.get_private_key(index, false)?; let prevout = &self.prevouts[index]; @@ -170,12 +222,12 @@ impl<'a> PsbtSigner<'a> { fn sign_p2sh_nested_p2wpkh(&mut self, index: usize) -> Result<()> { let prevout = &self.prevouts[index].clone(); - let key = self.get_private_key(index)?; + let key = self.get_private_key(index, false)?; let pub_key = key.public_key(); - let script = Script::new_v0_p2wpkh(&WPubkeyHash::from_hash( - self.hash160(&pub_key.to_compressed()), - )); + let script = Script::new_v0_p2wpkh(&WPubkeyHash::from_hash(Self::hash160( + &pub_key.to_compressed(), + ))); let hash = self.sighash_cache.segwit_hash( index, @@ -193,7 +245,7 @@ impl<'a> PsbtSigner<'a> { } fn sign_p2wpkh(&mut self, index: usize) -> Result<()> { - let key = self.get_private_key(index)?; + let key = self.get_private_key(index, false)?; let prevout = &self.prevouts[index]; let hash = self.sighash_cache.segwit_hash( @@ -215,7 +267,7 @@ impl<'a> PsbtSigner<'a> { } fn sign_p2tr(&mut self, index: usize) -> Result<()> { - let key = self.get_private_key(index)?; + let key = self.get_private_key(index, true)?; let key_pair = bitcoin::schnorr::UntweakedKeyPair::from_seckey_slice( &SECP256K1_ENGINE, @@ -242,7 +294,36 @@ impl<'a> PsbtSigner<'a> { Ok(()) } - fn sign(&mut self) -> Result<()> { + fn sign_p2tr_script(&mut self, index: usize) -> Result<()> { + let key = self.get_private_key(index, true)?; + + let key_pair = bitcoin::schnorr::UntweakedKeyPair::from_seckey_slice( + &SECP256K1_ENGINE, + &key.to_bytes(), + )?; + + let input = self.psbt.inputs[index].clone(); + let (_, script_leaf) = input.tap_scripts.first_key_value().unwrap(); + + let (script, leaf_version) = script_leaf; + let hash = self.sighash_cache.taproot_script_spend_signature_hash( + index, + &Prevouts::All(&self.prevouts.clone()), + TapLeafHash::from_script(script, leaf_version.clone()), + SchnorrSighashType::Default, + )?; + + let msg = Message::from_slice(&hash[..])?; + let sig = SECP256K1_ENGINE.sign_schnorr(&msg, &key_pair); + self.psbt.inputs[index].tap_key_sig = Some(SchnorrSig { + hash_ty: SchnorrSighashType::Default, + sig, + }); + + Ok(()) + } + + pub fn sign(&mut self) -> Result<()> { self.prevouts = self.prevouts()?; for idx in 0..self.prevouts.len() { @@ -250,12 +331,38 @@ impl<'a> PsbtSigner<'a> { if prevout.script_pubkey.is_p2pkh() { self.sign_p2pkh(idx)?; + + if self.auto_finalize { + self.finalize_p2pkh(idx); + } } else if prevout.script_pubkey.is_p2sh() { self.sign_p2sh_nested_p2wpkh(idx)?; + + if self.auto_finalize { + self.finalize_p2sh_nested_p2wpkh(idx); + } } else if prevout.script_pubkey.is_v0_p2wpkh() { self.sign_p2wpkh(idx)?; + + if self.auto_finalize { + self.finalize_p2wpkh(idx); + } + } else if !self.psbt.inputs.first().unwrap().tap_scripts.is_empty() { + self.sign_p2tr_script(idx)?; + + if self.auto_finalize { + self.finalize_p2tr(idx); + } } else if prevout.script_pubkey.is_v1_p2tr() { self.sign_p2tr(idx)?; + + if self.auto_finalize { + self.finalize_p2tr(idx); + } + } + + if self.auto_finalize { + self.clear_finalized_input(idx); } } @@ -272,16 +379,15 @@ pub fn sign_psbt( let mut reader = Cursor::new(Vec::::from_hex(psbt_input.data)?); let mut psbt = Psbt::consensus_decode(&mut reader)?; - let mut signer = PsbtSigner::new(&mut psbt, keystore, chain_type, derivation_path); + let mut signer = PsbtSigner::new( + &mut psbt, + keystore, + chain_type, + derivation_path, + psbt_input.auto_finalize, + ); signer.sign()?; - // FINALIZER - // if psbt_input.auto_finalize { - psbt.inputs.iter_mut().for_each(|input| { - input.finalize(); - }); - // } - let mut vec = Vec::::new(); let mut writer = Cursor::new(&mut vec); psbt.consensus_encode(&mut writer)?; @@ -291,24 +397,40 @@ pub fn sign_psbt( #[cfg(test)] mod tests { + use crate::psbt::PsbtSigner; use crate::tests::sample_hd_keystore; use crate::transaction::PsbtInput; + use crate::BtcKinAddress; use bitcoin::consensus::Decodable; + use bitcoin::psbt::serialize::{Deserialize, Serialize}; use bitcoin::psbt::Psbt; - use bitcoin::schnorr; use bitcoin::schnorr::TapTweak; + use bitcoin::util::bip32::{DerivationPath, KeySource}; + use bitcoin::{schnorr, Script, Transaction, TxOut, Witness}; + use secp256k1::schnorr::Signature; use secp256k1::{Message, XOnlyPublicKey}; use std::io::Cursor; - use tcx_common::FromHex; + use std::str::FromStr; + use tcx_common::{FromHex, ToHex}; + use tcx_constants::{CoinInfo, CurveType}; use tcx_primitive::{PublicKey, SECP256K1_ENGINE}; #[test] - fn test_sign_psbt() { + fn test_sign_psbt_no_script() { let mut hd = sample_hd_keystore(); + let coin_info = CoinInfo { + coin: "BITCOIN".to_string(), + derivation_path: "m/86'/1'/0'/0/0".to_string(), + curve: CurveType::SECP256k1, + network: "TESTNET".to_string(), + seg_wit: "VERSION_1".to_string(), + }; + + let account = hd.derive_coin::(&coin_info).unwrap(); let psbt_input = PsbtInput { data: "70736274ff0100db0200000001fa4c8d58b9b6c56ed0b03f78115246c99eb70f99b837d7b4162911d1016cda340200000000fdffffff0350c30000000000002251202114eda66db694d87ff15ddd5d3c4e77306b6e6dd5720cbd90cd96e81016c2b30000000000000000496a47626274340066f873ad53d80688c7739d0d268acd956366275004fdceab9e9fc30034a4229ec20acf33c17e5a6c92cced9f1d530cccab7aa3e53400456202f02fac95e9c481fa00d47b1700000000002251208f4ca6a7384f50a1fe00cba593d5a834b480c65692a76ae6202e1ce46cb1c233d80f03000001012be3bf1d00000000002251208f4ca6a7384f50a1fe00cba593d5a834b480c65692a76ae6202e1ce46cb1c23301172066f873ad53d80688c7739d0d268acd956366275004fdceab9e9fc30034a4229e00000000".to_string(), - auto_finalize: true + auto_finalize: true, }; let psbt_output = super::sign_psbt("BITCOIN", "m/86'/1'/0'", &mut hd, psbt_input).unwrap(); @@ -331,4 +453,196 @@ mod tests { assert!(sig.sig.verify(&msg, &tweak_pub_key.0.to_inner()).is_ok()); } + + #[test] + fn test_sign_psbt_script() { + let mut hd = sample_hd_keystore(); + let coin_info = CoinInfo { + coin: "BITCOIN".to_string(), + derivation_path: "m/86'/1'/0'/0/0".to_string(), + curve: CurveType::SECP256k1, + network: "TESTNET".to_string(), + seg_wit: "VERSION_1".to_string(), + }; + + let account = hd.derive_coin::(&coin_info).unwrap(); + + let psbt_input = PsbtInput { + data: "70736274ff01005e02000000012bd2f6479f3eeaffe95c03b5fdd76a873d346459114dec99c59192a0cb6409e90000000000ffffffff01409c000000000000225120677cc88dc36a75707b370e27efff3e454d446ad55004dac1685c1725ee1a89ea000000000001012b50c3000000000000225120a9a3350206de400f09a73379ec1bcfa161fc11ac095e5f3d7354126f0ec8e87f6215c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0d2956573f010fa1a3c135279c5eb465ec2250205dcdfe2122637677f639b1021356c963cd9c458508d6afb09f3fa2f9b48faec88e75698339a4bbb11d3fc9b0efd570120aff94eb65a2fe773a57c5bd54e62d8436a5467573565214028422b41bd43e29bad200aee0509b16db71c999238a4827db945526859b13c95487ab46725357c9a9f25ac20113c3a32a9d320b72190a04a020a0db3976ef36972673258e9a38a364f3dc3b0ba2017921cf156ccb4e73d428f996ed11b245313e37e27c978ac4d2cc21eca4672e4ba203bb93dfc8b61887d771f3630e9a63e97cbafcfcc78556a474df83a31a0ef899cba2040afaf47c4ffa56de86410d8e47baa2bb6f04b604f4ea24323737ddc3fe092dfba2079a71ffd71c503ef2e2f91bccfc8fcda7946f4653cef0d9f3dde20795ef3b9f0ba20d21faf78c6751a0d38e6bd8028b907ff07e9a869a43fc837d6b3f8dff6119a36ba20f5199efae3f28bb82476163a7e458c7ad445d9bffb0682d10d3bdb2cb41f8e8eba20fa9d882d45f4060bdb8042183828cd87544f1ea997380e586cab77d5fd698737ba569cc001172050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac00000".to_string(), + auto_finalize: true, + }; + + let psbt_output = super::sign_psbt("BITCOIN", "m/86'/1'/0'", &mut hd, psbt_input).unwrap(); + let mut reader = Cursor::new(Vec::::from_hex(psbt_output.data).unwrap()); + let psbt = Psbt::consensus_decode(&mut reader).unwrap(); + let tx = psbt.extract_tx(); + let witness = tx.input[0].witness.to_vec(); + let sig = schnorr::SchnorrSig::from_slice(&witness[0]).unwrap(); + + let data = + Vec::::from_hex("56b6c5fd09753fbbbeb8f530308e4f7d2f404e02da767f033e926d27fcc2f37e") + .unwrap(); + let msg = Message::from_slice(&data).unwrap(); + let x_pub_key = XOnlyPublicKey::from_slice( + Vec::::from_hex("66f873ad53d80688c7739d0d268acd956366275004fdceab9e9fc30034a4229e") + .unwrap() + .as_slice(), + ) + .unwrap(); + + let script = witness[1].to_hex(); + let control_block = witness[2].to_hex(); + assert_eq!(script, "20aff94eb65a2fe773a57c5bd54e62d8436a5467573565214028422b41bd43e29bad200aee0509b16db71c999238a4827db945526859b13c95487ab46725357c9a9f25ac20113c3a32a9d320b72190a04a020a0db3976ef36972673258e9a38a364f3dc3b0ba2017921cf156ccb4e73d428f996ed11b245313e37e27c978ac4d2cc21eca4672e4ba203bb93dfc8b61887d771f3630e9a63e97cbafcfcc78556a474df83a31a0ef899cba2040afaf47c4ffa56de86410d8e47baa2bb6f04b604f4ea24323737ddc3fe092dfba2079a71ffd71c503ef2e2f91bccfc8fcda7946f4653cef0d9f3dde20795ef3b9f0ba20d21faf78c6751a0d38e6bd8028b907ff07e9a869a43fc837d6b3f8dff6119a36ba20f5199efae3f28bb82476163a7e458c7ad445d9bffb0682d10d3bdb2cb41f8e8eba20fa9d882d45f4060bdb8042183828cd87544f1ea997380e586cab77d5fd698737ba569c"); + assert_eq!(control_block, "c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0d2956573f010fa1a3c135279c5eb465ec2250205dcdfe2122637677f639b1021356c963cd9c458508d6afb09f3fa2f9b48faec88e75698339a4bbb11d3fc9b0e"); + + assert!(sig.sig.verify(&msg, &x_pub_key).is_ok()); + } + + #[test] + fn test_sign_psbt_multipayment() { + let mut hd = sample_hd_keystore(); + + let raw_tx = "02000000054adc61444e5a4dd7021e52dc6f5adadd9a3286d346f5d9f023ebcde2af80a0ae0000000000ffffffff4adc61444e5a4dd7021e52dc6f5adadd9a3286d346f5d9f023ebcde2af80a0ae0100000000ffffffff12cc8049bf85b5e18cb2be8aa7aefc3afb8df4ec5c1f766750014cc95ca2dc130000000000ffffffff729e6570928cc65200f1d53def65a7934d2e9b543059d90598ed1d166af422010100000000ffffffffa126724475cd2f3252352b3543c8455c7999a8283883bd7a712a7d66609d92d80100000000ffffffff02409c00000000000022512036079c540758a51a86eeaf9e17668d4d8543d8b1b7e56fe2da0982c390c5655ef8fa0700000000002251209303a116174dd21ea473766659568ac24eb6b828c3ee998982d2ba070ea0615500000000"; + let tx = Transaction::deserialize(&Vec::from_hex(&raw_tx).unwrap()).unwrap(); + + let mut psbt = Psbt::from_unsigned_tx(tx).unwrap(); + let fake_pub_key = secp256k1::PublicKey::from_slice( + &Vec::::from_hex( + "0266f873ad53d80688c7739d0d268acd956366275004fdceab9e9fc30034a4229e", + ) + .unwrap(), + ) + .unwrap(); + let fake_xonly_pub_key = XOnlyPublicKey::from_slice( + Vec::::from_hex("66f873ad53d80688c7739d0d268acd956366275004fdceab9e9fc30034a4229e") + .unwrap() + .as_slice(), + ) + .unwrap(); + + psbt.inputs[0].tap_key_origins.insert( + fake_xonly_pub_key, + ( + Default::default(), + ( + Default::default(), + DerivationPath::from_str("m/86'/1'/0'/0/0").unwrap(), + ), + ), + ); + psbt.inputs[0].witness_utxo = Some(TxOut { + value: 20000, + script_pubkey: BtcKinAddress::from_str( + "tb1p3ax2dfecfag2rlsqewje84dgxj6gp3jkj2nk4e3q9cwwgm93cgesa0zwj4", + ) + .unwrap() + .script_pubkey(), + }); + + psbt.inputs[1].tap_key_origins.insert( + fake_xonly_pub_key, + ( + Default::default(), + ( + Default::default(), + DerivationPath::from_str("m/86'/1'/0'/1/53").unwrap(), + ), + ), + ); + psbt.inputs[1].witness_utxo = Some(TxOut { + value: 283000, + script_pubkey: BtcKinAddress::from_str( + "tb1pjvp6z9shfhfpafrnwen9j452cf8tdwpgc0hfnzvz62aqwr4qv92sg7qj9r", + ) + .unwrap() + .script_pubkey(), + }); + + psbt.inputs[2].bip32_derivation.insert( + fake_pub_key, + ( + Default::default(), + DerivationPath::from_str("m/84'/1'/0'/0/0").unwrap(), + ), + ); + psbt.inputs[2].witness_utxo = Some(TxOut { + value: 100000, + script_pubkey: BtcKinAddress::from_str("tb1qrfaf3g4elgykshfgahktyaqj2r593qkrae5v95") + .unwrap() + .script_pubkey(), + }); + + psbt.inputs[3].bip32_derivation.insert( + fake_pub_key, + ( + Default::default(), + DerivationPath::from_str("m/49'/1'/0'/0/0").unwrap(), + ), + ); + psbt.inputs[3].witness_utxo = Some(TxOut { + value: 100000, + script_pubkey: BtcKinAddress::from_str("2MwN441dq8qudMvtM5eLVwC3u4zfKuGSQAB") + .unwrap() + .script_pubkey(), + }); + + psbt.inputs[4].bip32_derivation.insert( + fake_pub_key, + ( + Default::default(), + DerivationPath::from_str("m/44'/1'/0'/0/0").unwrap(), + ), + ); + psbt.inputs[4].witness_utxo = Some(TxOut { + value: 100000, + script_pubkey: BtcKinAddress::from_str("mkeNU5nVnozJiaACDELLCsVUc8Wxoh1rQN") + .unwrap() + .script_pubkey(), + }); + + let mut signer = PsbtSigner::new(&mut psbt, &mut hd, "BITCOIN", "", true); + signer.sign().unwrap(); + + let tx = psbt.extract_tx(); + + let msg = Message::from_slice( + &Vec::from_hex("f01ba76b329132e48188ad10d00791647ee6d2f7fee5ef397f3481993c898de3") + .unwrap(), + ) + .unwrap(); + let sig = Signature::from_slice(&tx.input[0].witness.to_vec()[0]).unwrap(); + let pub_key = XOnlyPublicKey::from_slice( + &Vec::from_hex("8f4ca6a7384f50a1fe00cba593d5a834b480c65692a76ae6202e1ce46cb1c233") + .unwrap(), + ) + .unwrap(); + assert!(sig.verify(&msg, &pub_key).is_ok()); + + let msg = Message::from_slice( + &Vec::from_hex("d0691b5ac1b338b9341790ea69417cb454cf346a718342fb4a846dbb8ae142e8") + .unwrap(), + ) + .unwrap(); + let sig = Signature::from_slice(&tx.input[1].witness.to_vec()[0]).unwrap(); + let pub_key = XOnlyPublicKey::from_slice( + &Vec::from_hex("9303a116174dd21ea473766659568ac24eb6b828c3ee998982d2ba070ea06155") + .unwrap(), + ) + .unwrap(); + assert!(sig.verify(&msg, &pub_key).is_ok()); + + assert_eq!(tx.input[2].witness.to_vec()[0].to_hex(), "3044022022c2feaa4a225496fc6789c969fb776da7378f44c588ad812a7e1227ebe69b6302204fc7bf5107c6d02021fe4833629bc7ab71cefe354026ebd0d9c0da7d4f335f9401"); + assert_eq!( + tx.input[2].witness.to_vec()[1].to_hex(), + "02e24f625a31c9a8bae42239f2bf945a306c01a450a03fd123316db0e837a660c0" + ); + + assert_eq!(tx.input[3].witness.to_vec()[0].to_hex(), "3045022100dec4d3fd189b532ef04f41f68319ff7dc6a7f2351a0a8f98cb7f1ec1f6d71c7a02205e507162669b642fdb480a6c496abbae5f798bce4fd42cc390aa58e3847a1b9101"); + assert_eq!( + tx.input[3].witness.to_vec()[1].to_hex(), + "031aee5e20399d68cf0035d1a21564868f22bc448ab205292b4279136b15ecaebc" + ); + + assert_eq!(tx.input[4].script_sig.to_hex(), "483045022100ca32abc7b180c84cf76907e4e1e0c3f4c0d6e64de23b0708647ac6fee1c04c5b02206e7412a712424eb9406f18e00a42e0dffbfb5901932d1ef97843d9273865550e0121033d710ab45bb54ac99618ad23b3c1da661631aa25f23bfe9d22b41876f1d46e4e"); + } } diff --git a/token-core/tcx-btc-kin/src/sighash.rs b/token-core/tcx-btc-kin/src/sighash.rs index 4fc9a120..88fd173a 100644 --- a/token-core/tcx-btc-kin/src/sighash.rs +++ b/token-core/tcx-btc-kin/src/sighash.rs @@ -30,6 +30,14 @@ pub trait TxSignatureHasher { leaf_hash_code_separator: Option<(TapLeafHash, u32)>, sighash_type: SchnorrSighashType, ) -> Result; + + fn taproot_script_spend_signature_hash( + &mut self, + input_index: usize, + prevouts: &Prevouts, + tap_leaf_hash: TapLeafHash, + sighash_type: SchnorrSighashType, + ) -> Result; } impl TxSignatureHasher for SighashCache> { @@ -73,4 +81,19 @@ impl TxSignatureHasher for SighashCache> { sighash_type, )?) } + + fn taproot_script_spend_signature_hash( + &mut self, + input_index: usize, + prevouts: &Prevouts, + tap_leaf_hash: TapLeafHash, + sighash_type: SchnorrSighashType, + ) -> Result { + Ok(self.taproot_script_spend_signature_hash( + input_index, + &prevouts, + tap_leaf_hash, + sighash_type, + )?) + } } diff --git a/token-core/tcx-btc-kin/src/signer.rs b/token-core/tcx-btc-kin/src/signer.rs index 1248ebac..dcad738e 100644 --- a/token-core/tcx-btc-kin/src/signer.rs +++ b/token-core/tcx-btc-kin/src/signer.rs @@ -447,38 +447,13 @@ mod tests { use super::*; - fn hex_keystore(hex: &str) -> Keystore { - let mut keystore = Keystore::from_private_key( - hex, - TEST_PASSWORD, - CurveType::SECP256k1, - Metadata::default(), - None, - ) - .unwrap(); - keystore.unlock_by_password(TEST_PASSWORD).unwrap(); - keystore - } - - fn wif_keystore(_wif: &str) -> Keystore { - let hex = Secp256k1PrivateKey::from_wif(TEST_WIF) - .unwrap() - .to_bytes() - .to_hex(); - - hex_keystore(&hex) - } - - fn sample_private_key_keystore() -> Keystore { - wif_keystore(TEST_WIF) - } - mod kin { use super::*; + use crate::tests::sample_wif_keystore; #[test] fn test_sign_less_than_dust() { - let mut ks = sample_private_key_keystore(); + let mut ks = sample_wif_keystore(); let inputs = vec![Utxo { tx_hash: "e112b1215813c8888b31a80d215169809f7901359c0f4bf7e7374174ab2a64f4" @@ -636,7 +611,7 @@ mod tests { mod btc { use super::*; - use crate::tests::sample_hd_keystore; + use crate::tests::{sample_hd_keystore, sample_wif_keystore}; use bitcoin::psbt::serialize::Deserialize; use secp256k1::schnorr::Signature; use secp256k1::XOnlyPublicKey; @@ -840,7 +815,7 @@ mod tests { #[test] fn test_sign_with_private_key_on_testnet() { - let mut ks = sample_private_key_keystore(); + let mut ks = sample_wif_keystore(); let inputs = vec![Utxo { tx_hash: "e112b1215813c8888b31a80d215169809f7901359c0f4bf7e7374174ab2a64f4" @@ -1145,7 +1120,7 @@ mod tests { mod ltc { use super::*; - use crate::tests::sample_hd_keystore; + use crate::tests::{hex_keystore, sample_hd_keystore, wif_keystore}; #[test] fn test_sign_with_hd_on_testnet() { diff --git a/token-core/tcx-btc-kin/src/transaction.rs b/token-core/tcx-btc-kin/src/transaction.rs index 9bc58e74..3efaa5d7 100644 --- a/token-core/tcx-btc-kin/src/transaction.rs +++ b/token-core/tcx-btc-kin/src/transaction.rs @@ -67,3 +67,15 @@ pub struct PsbtOutput { #[prost(string, tag = "1")] pub data: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BtcMessageInput { + #[prost(string, tag = "1")] + pub message: ::prost::alloc::string::String, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BtcMessageOutput { + #[prost(string, tag = "1")] + pub signature: ::prost::alloc::string::String, +} diff --git a/token-core/tcx-proto/src/btc_kin.proto b/token-core/tcx-proto/src/btc_kin.proto index 7dfec591..9238fb3f 100644 --- a/token-core/tcx-proto/src/btc_kin.proto +++ b/token-core/tcx-proto/src/btc_kin.proto @@ -46,3 +46,11 @@ message PsbtInput { message PsbtOutput { string data = 1; } + +message BtcMessageInput { + string message = 1; +} + +message BtcMessageOutput { + string signature = 1; +} diff --git a/token-core/tcx/tests/sign_test.rs b/token-core/tcx/tests/sign_test.rs index 45908c7e..beb80fc0 100644 --- a/token-core/tcx/tests/sign_test.rs +++ b/token-core/tcx/tests/sign_test.rs @@ -27,7 +27,7 @@ use tcx::api::{ use tcx::handler::encode_message; use tcx::handler::get_derived_key; -use tcx_btc_kin::transaction::BtcKinTxInput; +use tcx_btc_kin::transaction::{BtcKinTxInput, BtcMessageInput, BtcMessageOutput}; use tcx_btc_kin::Utxo; use tcx_ckb::{CachedCell, CellInput, CkbTxInput, CkbTxOutput, OutPoint, Script, Witness}; use tcx_constants::{sample_key, CurveType}; @@ -542,6 +542,46 @@ fn test_tron_sign_message() { }); } +#[test] +#[serial] +fn test_bitcoin_sign_message() { + run_test(|| { + let wallet = import_default_wallet(); + + let input_expects = vec![ + (BtcMessageInput{ + message: "hello world".to_string(), + }, "02473044022062775640116afb7f17d23c222b0a6904fdaf2aea0d76e550d75c8fd362b80dcb022067c299fde774aaab689f8a53ebd0956395ff45b7ff6b7e99569d0abec85110c80121031aee5e20399d68cf0035d1a21564868f22bc448ab205292b4279136b15ecaebc"), + (BtcMessageInput{ + message: "test1".to_string(), + }, "02483045022100b805ccd16f1a664ae394bf292962ea6d76e0ddd5beb0b050cca4a1aa9ababc9a02201503132e39dc600957ec8f33663b10ab0cff0c4e37cab2811619152be8d919300121031aee5e20399d68cf0035d1a21564868f22bc448ab205292b4279136b15ecaebc"), + (BtcMessageInput{ + message: "test2".to_string(), + }, "02483045022100e96bfdb41b3562a1ff5a4c816da2620e82bcc8d702843ae1cec506666d4569c302206477d7d93c082cb42d462200a136e6aef7edde053722008a206ab8b9b356f0380121031aee5e20399d68cf0035d1a21564868f22bc448ab205292b4279136b15ecaebc"), + ]; + + for (input, expected) in input_expects { + let tx = SignParam { + id: wallet.id.to_string(), + key: Some(Key::Password(TEST_PASSWORD.to_string())), + chain_type: "BITCOIN".to_string(), + path: "m/49'/1'/0'".to_string(), + curve: "secp256k1".to_string(), + network: "TESTNET".to_string(), + seg_wit: "VERSION_0".to_string(), + input: Some(::prost_types::Any { + type_url: "imtoken".to_string(), + value: encode_message(input).unwrap(), + }), + }; + + let sign_result = call_api("sign_msg", tx).unwrap(); + let ret: BtcMessageOutput = BtcMessageOutput::decode(sign_result.as_slice()).unwrap(); + assert_eq!(expected, ret.signature); + } + }); +} + #[test] #[serial] fn test_sign_by_dk_hd_store() { From 1d4c8a9cc875f2ec3da7eaeeb861cc7a1e431eff Mon Sep 17 00:00:00 2001 From: Neal Xu Date: Thu, 11 Jul 2024 14:30:21 +0800 Subject: [PATCH 5/5] fix: remove deprecated fil library (#106) * fix: remove deprecated fil library * feat: upgrade deprecated fil dep in ikc * Update build-release-ios.yml runs-on * Update build-release-ios.yml runs-on macos-14 * feat: remove forest_bigint support --- .github/workflows/build-release-ios.yml | 2 +- Cargo.lock | 891 ++++++++---------- VERSION | 2 +- imkey-core/ikc-common/Cargo.toml | 10 +- imkey-core/ikc-device/Cargo.toml | 4 +- imkey-core/ikc-wallet/coin-bch/Cargo.toml | 4 +- imkey-core/ikc-wallet/coin-bitcoin/Cargo.toml | 2 +- .../ikc-wallet/coin-btc-fork/Cargo.toml | 4 +- imkey-core/ikc-wallet/coin-cosmos/Cargo.toml | 10 +- .../ikc-wallet/coin-ethereum/Cargo.toml | 10 +- .../ikc-wallet/coin-filecoin/Cargo.toml | 24 +- .../coin-filecoin/src/transaction.rs | 150 ++- .../ikc-wallet/coin-filecoin/src/utils.rs | 21 + token-core/tcx-btc-kin/Cargo.toml | 8 +- token-core/tcx-constants/Cargo.toml | 2 +- token-core/tcx-crypto/Cargo.toml | 2 +- token-core/tcx-filecoin/Cargo.toml | 21 +- token-core/tcx-filecoin/src/address.rs | 99 +- token-core/tcx-filecoin/src/signer.rs | 157 ++- token-core/tcx-filecoin/src/utils.rs | 23 +- token-core/tcx-keystore/Cargo.toml | 2 +- token-core/tcx-migration/Cargo.toml | 2 +- token-core/tcx-primitive/Cargo.toml | 8 +- token-core/tcx-substrate/Cargo.toml | 2 +- token-core/tcx-tron/Cargo.toml | 8 +- token-core/tcx/Cargo.toml | 2 +- 26 files changed, 765 insertions(+), 705 deletions(-) diff --git a/.github/workflows/build-release-ios.yml b/.github/workflows/build-release-ios.yml index 4793c399..bce63acd 100644 --- a/.github/workflows/build-release-ios.yml +++ b/.github/workflows/build-release-ios.yml @@ -14,7 +14,7 @@ jobs: build: name: Build iOS Release if: github.event.review.state == 'approved' - runs-on: macos-12 + runs-on: macos-14 steps: - name: Get the latest commit SHA id: sha diff --git a/Cargo.lock b/Cargo.lock index 1a355dd3..7b9dc7f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -130,7 +130,7 @@ checksum = "fdf6721fb0140e4f897002dd086c06f6c27775df19cfe1fccb21181a48fd2c98" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.69", ] [[package]] @@ -172,12 +172,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" -[[package]] -name = "base64" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" - [[package]] name = "base64" version = "0.13.1" @@ -245,6 +239,9 @@ name = "bitflags" version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +dependencies = [ + "serde", +] [[package]] name = "bitvec" @@ -277,17 +274,6 @@ dependencies = [ "cty", ] -[[package]] -name = "blake2b_simd" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" -dependencies = [ - "arrayref", - "arrayvec 0.5.2", - "constant_time_eq 0.1.5", -] - [[package]] name = "blake2b_simd" version = "1.0.1" @@ -371,25 +357,11 @@ dependencies = [ "generic-array 0.14.7", ] -[[package]] -name = "bls-signatures" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b44c36726a8b4cae930903a96f3193b496664ed7c28f74f1c1b3feae0e212c3" -dependencies = [ - "blst", - "blstrs", - "fff", - "groupy", - "rand_core 0.5.1", - "thiserror", -] - [[package]] name = "blst" -version = "0.3.3" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd7cb1b48c09ac759808ad27811ca44e27c037d309f837651fc80506bc19819f" +checksum = "62dc83a094a71d43eeadd254b1ec2d24cb6a0bb6cadce00df51f0db594711a32" dependencies = [ "cc", "glob", @@ -397,18 +369,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "blstrs" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecf78c2e543a5fd41b41499fc242d603862b436dc2c167658e7f4870523781ac" -dependencies = [ - "blst", - "fff", - "groupy", - "rand_core 0.5.1", -] - [[package]] name = "bs58" version = "0.2.5" @@ -488,6 +448,15 @@ dependencies = [ "cipher", ] +[[package]] +name = "cbor4ii" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544cf8c89359205f4f990d0e6f3828db42df85b5dac95d09157a250eb0749c4" +dependencies = [ + "serde", +] + [[package]] name = "cc" version = "1.0.83" @@ -517,13 +486,28 @@ dependencies = [ [[package]] name = "cid" -version = "0.6.1" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd94671561e36e4e7de75f753f577edafb0e7c05d6e4547229fdf7938fbcd2c3" +dependencies = [ + "core2", + "multibase", + "multihash 0.18.1", + "serde", + "serde_bytes", + "unsigned-varint 0.7.2", +] + +[[package]] +name = "cid" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff0e3bc0b6446b3f9663c1a6aba6ef06c5aeaa1bc92bd18077be337198ab9768" +checksum = "3147d8272e8fa0ccd29ce51194dd98f79ddfb8191ba9e3409884e751798acf3a" dependencies = [ - "multibase 0.8.0", - "multihash 0.13.2", - "unsigned-varint 0.5.1", + "core2", + "multibase", + "multihash 0.19.1", + "unsigned-varint 0.8.0", ] [[package]] @@ -550,7 +534,7 @@ dependencies = [ "ikc-common", "ikc-device", "ikc-transport", - "num-bigint 0.4.3", + "num-bigint", "prost", "prost-types", "secp256k1", @@ -571,7 +555,7 @@ dependencies = [ "ikc-common", "ikc-device", "ikc-transport", - "num-bigint 0.4.3", + "num-bigint", "prost", "prost-types", "secp256k1", @@ -582,7 +566,7 @@ name = "coin-btc-fork" version = "0.1.0" dependencies = [ "anyhow", - "base64 0.13.1", + "base64", "bech32 0.9.1", "bitcoin", "bitcoin_hashes", @@ -592,7 +576,7 @@ dependencies = [ "ikc-device", "ikc-transport", "lazy_static", - "num-bigint 0.4.3", + "num-bigint", "parking_lot", "prost", "prost-types", @@ -607,7 +591,7 @@ name = "coin-ckb" version = "0.1.0" dependencies = [ "anyhow", - "base64 0.13.1", + "base64", "bech32 0.9.1", "bitcoin", "blake2b-rs", @@ -627,7 +611,7 @@ name = "coin-cosmos" version = "0.1.0" dependencies = [ "anyhow", - "base64 0.13.1", + "base64", "bech32 0.9.1", "bitcoin", "bitcoin_hashes", @@ -637,7 +621,7 @@ dependencies = [ "ikc-device", "ikc-transport", "linked-hash-map", - "num-bigint 0.4.3", + "num-bigint", "num-integer", "num-traits", "prost", @@ -669,7 +653,7 @@ name = "coin-ethereum" version = "0.1.0" dependencies = [ "anyhow", - "base64 0.13.1", + "base64", "bitcoin", "bitcoin_hashes", "bytes", @@ -681,7 +665,7 @@ dependencies = [ "jsonrpc-core", "keccak-hash", "lazy_static", - "num-bigint 0.4.3", + "num-bigint", "num-integer", "num-traits", "prost", @@ -702,25 +686,24 @@ version = "0.1.0" dependencies = [ "anyhow", "base32", - "base64 0.13.1", + "base64", "bech32 0.9.1", "bitcoin", "bitcoin_hashes", "blake2b-rs", "bytes", - "forest_address", - "forest_bigint", - "forest_cid", - "forest_crypto", - "forest_encoding", - "forest_message", - "forest_vm", + "cid 0.11.1", + "fvm_ipld_encoding", + "fvm_shared", "hex", "ikc-common", "ikc-device", "ikc-transport", "linked-hash-map", - "num-bigint 0.4.3", + "multihash-codetable", + "num", + "num-bigint", + "num-derive", "num-integer", "num-traits", "prost", @@ -728,6 +711,9 @@ dependencies = [ "secp256k1", "serde", "serde_json", + "serde_tuple", + "strum 0.26.3", + "strum_macros 0.26.4", ] [[package]] @@ -752,7 +738,7 @@ version = "0.1.0" dependencies = [ "anyhow", "bitcoin", - "blake2b_simd 1.0.1", + "blake2b_simd", "hex", "ikc-common", "ikc-device", @@ -784,12 +770,6 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - [[package]] name = "constant_time_eq" version = "0.2.6" @@ -879,25 +859,6 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42014d4c82e74bc17aaccc4bd75d3615d2b8236198de81c51bed5ddefaae6435" -[[package]] -name = "cs_serde_bytes" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc673ddabf48214550526b068dc28065a75f05e21e452880095247c635b1d91" -dependencies = [ - "serde", -] - -[[package]] -name = "cs_serde_cbor" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7b77425566bdb3932243a292a4b072e1e34fb93aba95926f8d4a3b6ce542c5" -dependencies = [ - "half", - "serde", -] - [[package]] name = "ctr" version = "0.9.2" @@ -964,42 +925,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", -] - -[[package]] -name = "darling" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 1.0.109", -] - -[[package]] -name = "darling_macro" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" -dependencies = [ - "darling_core", - "quote", - "syn 1.0.109", + "syn 2.0.69", ] [[package]] @@ -1068,31 +994,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" -[[package]] -name = "derive_builder" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2658621297f2cf68762a6f7dc0bb7e1ff2cfd6583daef8ee0fed6f7ec468ec0" -dependencies = [ - "darling", - "derive_builder_core", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "derive_builder_core" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2791ea3e372c8495c0bc2033991d76b512cd799d07491fbd6890124db9458bef" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "derive_more" version = "0.99.17" @@ -1312,7 +1213,7 @@ dependencies = [ "proc-macro2", "quote", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -1330,18 +1231,6 @@ dependencies = [ "instant", ] -[[package]] -name = "fff" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2544d325b4870bd803d371a7df3c6845e84dcfcb6ebe7ffcae0eac6d5d676133" -dependencies = [ - "byteorder 1.4.3", - "cc", - "lazy_static", - "rand_core 0.5.1", -] - [[package]] name = "fiat-crypto" version = "0.2.5" @@ -1396,128 +1285,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -[[package]] -name = "forest_address" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36b7dbc8805f7d93e4a3c63a5be26dd521d3a62b20cc9453eaf722022d7f8ee" -dependencies = [ - "data-encoding", - "data-encoding-macro", - "forest_encoding", - "leb128", - "log", - "num-derive", - "num-traits", - "once_cell", - "serde", - "thiserror", -] - -[[package]] -name = "forest_bigint" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "559d63f33ef82723a75b2b25703b31c50a55d2950ead45e239e49b19aeefd1e7" -dependencies = [ - "cs_serde_bytes", - "num-bigint 0.3.3", - "num-integer", - "serde", -] - -[[package]] -name = "forest_cid" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1a935d7f977a7debbc507de2ab7990b834d85e94c819e5268b1adaefd7d434" -dependencies = [ - "cid", - "cs_serde_bytes", - "cs_serde_cbor", - "forest_json_utils", - "generic-array 0.14.7", - "integer-encoding", - "multibase 0.9.1", - "multihash 0.13.2", - "serde", -] - -[[package]] -name = "forest_crypto" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecfe12e10b7f6aa5643dcde74533d8192720ab7366ce473ff4043c71b5132c27" -dependencies = [ - "bls-signatures", - "forest_address", - "forest_encoding", - "libsecp256k1 0.6.0", - "num-derive", - "num-traits", - "serde", - "thiserror", -] - -[[package]] -name = "forest_encoding" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c8339c6dc1741c3144ba06cfb0512a2e858bd603be97bff24bf630d91cce7d" -dependencies = [ - "blake2b_simd 0.5.11", - "cs_serde_bytes", - "cs_serde_cbor", - "forest_cid", - "serde", - "serde_repr", - "serde_tuple", - "thiserror", -] - -[[package]] -name = "forest_json_utils" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0da39ba6848c04b22e70520a1339f04f304502a0ebfd4526ea8a566452ea62a8" -dependencies = [ - "serde", -] - -[[package]] -name = "forest_message" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c512b9fbaea31e6bbc98c10ae32568a87b7d99b8c1f63d334ec91c482b35d30" -dependencies = [ - "derive_builder", - "forest_address", - "forest_bigint", - "forest_cid", - "forest_crypto", - "forest_encoding", - "forest_vm", - "num-traits", - "serde", -] - -[[package]] -name = "forest_vm" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cba5f1b93b15568dc4d96b333c73a1949bfba11ce539a6b5495c02e9a9d9190a" -dependencies = [ - "forest_address", - "forest_bigint", - "forest_cid", - "forest_encoding", - "lazy_static", - "num-derive", - "num-traits", - "serde", - "thiserror", -] - [[package]] name = "fragile" version = "2.0.0" @@ -1587,7 +1354,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.69", ] [[package]] @@ -1620,6 +1387,59 @@ dependencies = [ "slab", ] +[[package]] +name = "fvm_ipld_blockstore" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d064b957420f5ecc137a153baaa6c32e2eb19b674135317200b6f2537eabdbfd" +dependencies = [ + "anyhow", + "cid 0.10.1", + "multihash 0.18.1", +] + +[[package]] +name = "fvm_ipld_encoding" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90608092e31d9a06236268c58f7c36668ab4b2a48afafe3a97e08f094ad7ae50" +dependencies = [ + "anyhow", + "cid 0.10.1", + "fvm_ipld_blockstore", + "multihash 0.18.1", + "serde", + "serde_ipld_dagcbor", + "serde_repr", + "serde_tuple", + "thiserror", +] + +[[package]] +name = "fvm_shared" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a907c935312f9a47a64fbe1d45f2cb7b2b0a5fbb989a90ecac395b40466069d" +dependencies = [ + "anyhow", + "bitflags 2.4.1", + "blake2b_simd", + "cid 0.10.1", + "data-encoding", + "data-encoding-macro", + "fvm_ipld_encoding", + "lazy_static", + "multihash 0.18.1", + "num-bigint", + "num-derive", + "num-integer", + "num-traits", + "serde", + "serde_tuple", + "thiserror", + "unsigned-varint 0.7.2", +] + [[package]] name = "generic-array" version = "0.12.4" @@ -1675,18 +1495,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" -[[package]] -name = "groupy" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d38f1bec17d75a7c30b754cd74db6e7cb5927529021ced14fbd622411c04d8b" -dependencies = [ - "fff", - "rand 0.7.3", - "rand_xorshift", - "thiserror", -] - [[package]] name = "h2" version = "0.3.26" @@ -1706,12 +1514,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "half" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" - [[package]] name = "hash-db" version = "0.15.2" @@ -1748,6 +1550,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.3" @@ -1835,9 +1643,9 @@ checksum = "fc736091aacb31ddaa4cd5f6988b3c21e99913ac846b41f32538c5fae5d71bfe" [[package]] name = "http" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -1857,9 +1665,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -1939,18 +1747,12 @@ dependencies = [ "cc", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "ikc" version = "0.1.0" dependencies = [ "anyhow", - "base64 0.13.1", + "base64", "bitcoin", "bytes", "coin-bch", @@ -1984,7 +1786,7 @@ version = "0.1.0" dependencies = [ "aes", "anyhow", - "base64 0.13.1", + "base64", "bitcoin", "byteorder 1.4.3", "bytes", @@ -1994,7 +1796,7 @@ dependencies = [ "hyper-timeout", "hyper-tls", "lazy_static", - "num-bigint 0.4.3", + "num-bigint", "num-integer", "num-traits", "parking_lot", @@ -2015,7 +1817,7 @@ name = "ikc-device" version = "0.1.0" dependencies = [ "anyhow", - "base64 0.13.1", + "base64", "bytes", "hex", "ikc-common", @@ -2032,7 +1834,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "sha1", + "sha1 0.6.1", "thiserror", ] @@ -2126,12 +1928,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "integer-encoding" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c27df786dcc3a75ccd134f83ece166af0a1e5785d52b12b7375d0d063e1d5c47" - [[package]] name = "integer-sqrt" version = "0.1.5" @@ -2219,12 +2015,6 @@ dependencies = [ "spin", ] -[[package]] -name = "leb128" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" - [[package]] name = "libc" version = "0.2.140" @@ -2237,25 +2027,6 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" -[[package]] -name = "libsecp256k1" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" -dependencies = [ - "arrayref", - "base64 0.12.3", - "digest 0.9.0", - "hmac-drbg", - "libsecp256k1-core 0.2.2", - "libsecp256k1-gen-ecmult 0.2.1", - "libsecp256k1-gen-genmult 0.2.1", - "rand 0.7.3", - "serde", - "sha2 0.9.9", - "typenum", -] - [[package]] name = "libsecp256k1" version = "0.7.1" @@ -2263,29 +2034,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1" dependencies = [ "arrayref", - "base64 0.13.1", + "base64", "digest 0.9.0", "hmac-drbg", - "libsecp256k1-core 0.3.0", - "libsecp256k1-gen-ecmult 0.3.0", - "libsecp256k1-gen-genmult 0.3.0", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", "rand 0.8.5", "serde", "sha2 0.9.9", "typenum", ] -[[package]] -name = "libsecp256k1-core" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" -dependencies = [ - "crunchy", - "digest 0.9.0", - "subtle", -] - [[package]] name = "libsecp256k1-core" version = "0.3.0" @@ -2297,31 +2057,13 @@ dependencies = [ "subtle", ] -[[package]] -name = "libsecp256k1-gen-ecmult" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" -dependencies = [ - "libsecp256k1-core 0.2.2", -] - [[package]] name = "libsecp256k1-gen-ecmult" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" dependencies = [ - "libsecp256k1-core 0.3.0", -] - -[[package]] -name = "libsecp256k1-gen-genmult" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" -dependencies = [ - "libsecp256k1-core 0.2.2", + "libsecp256k1-core", ] [[package]] @@ -2330,7 +2072,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" dependencies = [ - "libsecp256k1-core 0.3.0", + "libsecp256k1-core", ] [[package]] @@ -2469,9 +2211,9 @@ dependencies = [ [[package]] name = "multibase" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b78c60039650ff12e140ae867ef5299a58e19dded4d334c849dc7177083667e2" +checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" dependencies = [ "base-x", "data-encoding", @@ -2479,71 +2221,90 @@ dependencies = [ ] [[package]] -name = "multibase" -version = "0.9.1" +name = "multihash" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" +checksum = "cfd8a792c1694c6da4f68db0a9d707c72bd260994da179e6030a5dcee00bb815" dependencies = [ - "base-x", - "data-encoding", - "data-encoding-macro", + "blake2b_simd", + "blake2s_simd", + "blake3", + "core2", + "digest 0.10.6", + "multihash-derive 0.8.1", + "serde", + "serde-big-array", + "sha2 0.10.6", + "sha3", + "unsigned-varint 0.7.2", ] [[package]] name = "multihash" -version = "0.13.2" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dac63698b887d2d929306ea48b63760431ff8a24fac40ddb22f9c7f49fb7cab" +checksum = "076d548d76a0e2a0d4ab471d0b1c36c577786dfc4471242035d97a12a735c492" dependencies = [ - "blake2b_simd 0.5.11", - "generic-array 0.14.7", - "multihash-derive 0.7.2", - "unsigned-varint 0.5.1", + "core2", + "unsigned-varint 0.7.2", ] [[package]] -name = "multihash" -version = "0.18.1" +name = "multihash-codetable" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfd8a792c1694c6da4f68db0a9d707c72bd260994da179e6030a5dcee00bb815" +checksum = "c35f0fb09f635b18e95053fc2a9a4843272d3acf898792a14471dcf6f83df0cc" dependencies = [ - "blake2b_simd 1.0.1", + "blake2b_simd", "blake2s_simd", "blake3", "core2", "digest 0.10.6", - "multihash-derive 0.8.1", + "multihash-derive 0.9.0", + "ripemd", + "sha1 0.10.5", "sha2 0.10.6", "sha3", - "unsigned-varint 0.7.2", + "strobe-rs", ] [[package]] name = "multihash-derive" -version = "0.7.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "424f6e86263cd5294cbd7f1e95746b95aca0e0d66bff31e5a40d6baa87b4aa99" +checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" dependencies = [ "proc-macro-crate 1.1.3", "proc-macro-error", "proc-macro2", "quote", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] name = "multihash-derive" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" +checksum = "890e72cb7396cb99ed98c1246a97b243cc16394470d94e0bc8b0c2c11d84290e" dependencies = [ - "proc-macro-crate 1.1.3", + "core2", + "multihash 0.19.1", + "multihash-derive-impl", +] + +[[package]] +name = "multihash-derive-impl" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3958713ce794e12f7c6326fac9aa274c68d74c4881dd37b3e2662b8a2046bb19" +dependencies = [ + "proc-macro-crate 2.0.0", "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", - "synstructure", + "syn 2.0.69", + "synstructure 0.13.1", ] [[package]] @@ -2554,11 +2315,10 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -2583,23 +2343,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] -name = "num-bigint" -version = "0.3.3" +name = "num" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ - "autocfg", + "num-bigint", + "num-complex", "num-integer", + "num-iter", + "num-rational", "num-traits", ] [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -2621,15 +2383,24 @@ dependencies = [ "zeroize", ] +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + [[package]] name = "num-derive" -version = "0.3.3" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.69", ] [[package]] @@ -2644,19 +2415,18 @@ dependencies = [ [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-iter" -version = "0.1.43" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", "num-integer", @@ -2665,21 +2435,20 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "autocfg", - "num-bigint 0.4.3", + "num-bigint", "num-integer", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -2724,9 +2493,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.62" +version = "0.10.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" dependencies = [ "bitflags 2.4.1", "cfg-if", @@ -2745,7 +2514,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.69", ] [[package]] @@ -2756,9 +2525,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.98" +version = "0.9.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" dependencies = [ "cc", "libc", @@ -2816,7 +2585,7 @@ checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" dependencies = [ "proc-macro2", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -2960,9 +2729,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "platforms" @@ -3086,9 +2855,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -3110,7 +2879,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "276470f7f281b0ed53d2ae42dd52b4a8d08853a3c70e7fe95882acbb98a6ae94" dependencies = [ "bytes", - "heck", + "heck 0.4.1", "itertools", "lazy_static", "log", @@ -3244,15 +3013,6 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "rand_xorshift" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8" -dependencies = [ - "rand_core 0.5.1", -] - [[package]] name = "redox_syscall" version = "0.3.5" @@ -3288,7 +3048,7 @@ checksum = "2566c4bf6845f2c2e83b27043c3f5dfcd5ba8f2937d6c00dc009bfb51a079dc4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.69", ] [[package]] @@ -3335,6 +3095,15 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.6", +] + [[package]] name = "rlp" version = "0.5.2" @@ -3536,9 +3305,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -3549,9 +3318,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" dependencies = [ "core-foundation-sys", "libc", @@ -3565,22 +3334,52 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" -version = "1.0.147" +version = "1.0.165" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "c939f902bb7d0ccc5bce4f03297e161543c2dcb30914faf032c2bd0b7a0d48fc" dependencies = [ "serde_derive", ] +[[package]] +name = "serde-big-array" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd31f59f6fe2b0c055371bb2f16d7f0aa7d8881676c04a55b1596d1a17cd10a4" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_bytes" +version = "0.11.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c5113243e4a3a1c96587342d067f3e6b0f50790b6cf40d2868eb647a3eef0e" +dependencies = [ + "serde", +] + [[package]] name = "serde_derive" -version = "1.0.147" +version = "1.0.165" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +checksum = "6eaae920e25fffe4019b75ff65e7660e72091e59dd204cb5849bbd6a3fd343d7" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.69", +] + +[[package]] +name = "serde_ipld_dagcbor" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e880e0b1f9c7a8db874642c1217f7e19b29e325f24ab9f0fcb11818adec7f01" +dependencies = [ + "cbor4ii", + "cid 0.10.1", + "scopeguard", + "serde", ] [[package]] @@ -3602,7 +3401,7 @@ checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.69", ] [[package]] @@ -3648,7 +3447,7 @@ checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.69", ] [[package]] @@ -3660,6 +3459,17 @@ dependencies = [ "sha1_smol", ] +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.6", +] + [[package]] name = "sha1_smol" version = "1.0.0" @@ -3723,9 +3533,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -3819,7 +3629,7 @@ dependencies = [ "hash256-std-hasher", "impl-serde", "lazy_static", - "libsecp256k1 0.7.1", + "libsecp256k1", "log", "merlin", "num-traits", @@ -3894,7 +3704,7 @@ dependencies = [ "bytes", "futures", "hash-db", - "libsecp256k1 0.7.1", + "libsecp256k1", "log", "parity-scale-codec", "parking_lot", @@ -4167,7 +3977,7 @@ checksum = "f923762d556417668b192ac2fdc9827ea21e6df011d8a0a7e68f3d5da095a675" dependencies = [ "bitvec", "hex", - "num-bigint 0.4.3", + "num-bigint", "serde", "sha2 0.9.9", "ssz_rs_derive", @@ -4192,10 +4002,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] -name = "strsim" -version = "0.9.3" +name = "strobe-rs" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" +checksum = "fabb238a1cccccfa4c4fb703670c0d157e1256c1ba695abf1b93bd2bb14bab2d" +dependencies = [ + "bitflags 1.3.2", + "byteorder 1.4.3", + "keccak", + "subtle", + "zeroize", +] [[package]] name = "strum" @@ -4215,13 +4032,22 @@ dependencies = [ "strum_macros 0.25.3", ] +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros 0.26.4", +] + [[package]] name = "strum_macros" version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "rustversion", @@ -4234,11 +4060,24 @@ version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "rustversion", - "syn 2.0.48", + "syn 2.0.69", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.69", ] [[package]] @@ -4273,9 +4112,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "201fcda3845c23e8212cd466bfebf0bd20694490fc0356ae8e428e0824a915a6" dependencies = [ "proc-macro2", "quote", @@ -4294,6 +4133,17 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.69", +] + [[package]] name = "tap" version = "1.0.1" @@ -4306,7 +4156,7 @@ version = "0.1.0" dependencies = [ "anyhow", "base58", - "base64 0.13.1", + "base64", "bytes", "ethereum-types", "hex", @@ -4347,7 +4197,7 @@ name = "tcx-atom" version = "0.1.0" dependencies = [ "anyhow", - "base64 0.13.1", + "base64", "bech32 0.9.1", "bytes", "prost", @@ -4363,7 +4213,7 @@ name = "tcx-btc-kin" version = "0.1.0" dependencies = [ "anyhow", - "base64 0.13.1", + "base64", "bch_addr", "bech32 0.9.1", "bitcoin", @@ -4372,7 +4222,7 @@ dependencies = [ "bytes", "hex", "mockall", - "num-bigint 0.4.3", + "num-bigint", "num-integer", "num-traits", "prost", @@ -4474,7 +4324,7 @@ name = "tcx-eos" version = "0.1.0" dependencies = [ "anyhow", - "base64 0.13.1", + "base64", "bitcoin", "bytes", "prost", @@ -4532,20 +4382,24 @@ version = "0.1.0" dependencies = [ "anyhow", "base32", - "base64 0.13.1", + "base64", "blake2b-rs", "byteorder 1.4.3", "bytes", - "forest_address", - "forest_cid", - "forest_crypto", - "forest_encoding", - "forest_message", - "forest_vm", + "cid 0.11.1", + "fvm_ipld_encoding", + "fvm_shared", "lazy_static", + "multihash-codetable", + "num", + "num-derive", + "num-traits", "prost", "serde", "serde_json", + "serde_tuple", + "strum 0.26.3", + "strum_macros 0.26.4", "tcx-common", "tcx-constants", "tcx-crypto", @@ -4590,7 +4444,7 @@ version = "0.1.0" dependencies = [ "anyhow", "base58", - "base64 0.13.1", + "base64", "bytes", "hex", "lazy_static", @@ -4625,7 +4479,7 @@ dependencies = [ "anyhow", "bitcoin", "bitcoin_hashes", - "blake2b_simd 1.0.1", + "blake2b_simd", "blst", "byteorder 1.4.3", "digest 0.10.6", @@ -4636,7 +4490,7 @@ dependencies = [ "hex-literal", "hkdf", "lazy_static", - "num-bigint 0.4.3", + "num-bigint", "num-traits", "regex", "schnorrkel", @@ -4667,7 +4521,7 @@ version = "0.1.0" dependencies = [ "anyhow", "base58", - "base64 0.13.1", + "base64", "byteorder 1.4.3", "bytes", "parity-scale-codec", @@ -4707,7 +4561,7 @@ version = "0.1.0" dependencies = [ "anyhow", "bitcoin", - "blake2b_simd 1.0.1", + "blake2b_simd", "bytes", "hex", "prost", @@ -4732,7 +4586,7 @@ dependencies = [ "digest 0.10.6", "hex", "hex-literal", - "num-bigint 0.4.3", + "num-bigint", "num-integer", "num-traits", "prost", @@ -4784,7 +4638,7 @@ checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.69", ] [[package]] @@ -4905,7 +4759,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.69", ] [[package]] @@ -4920,16 +4774,15 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] @@ -4983,7 +4836,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.69", ] [[package]] @@ -5130,15 +4983,15 @@ dependencies = [ [[package]] name = "unsigned-varint" -version = "0.5.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fdeedbf205afadfe39ae559b75c3240f24e257d0ca27e85f85cb82aa19ac35" +checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" [[package]] name = "unsigned-varint" -version = "0.7.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" +checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" [[package]] name = "uuid" @@ -5210,7 +5063,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.69", "wasm-bindgen-shared", ] @@ -5232,7 +5085,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.69", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5564,5 +5417,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.69", ] diff --git a/VERSION b/VERSION index a4dd9dba..a603bb50 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.7.4 +2.7.5 diff --git a/imkey-core/ikc-common/Cargo.toml b/imkey-core/ikc-common/Cargo.toml index a3dc774a..2d984820 100644 --- a/imkey-core/ikc-common/Cargo.toml +++ b/imkey-core/ikc-common/Cargo.toml @@ -11,15 +11,15 @@ hyper = { version = "=0.14.23", features = ["full"] } hyper-tls = "=0.5.0" hyper-timeout = "=0.4.1" rustc-serialize = "=0.3.24" -serde = { version = "=1.0.147", features = ["derive"] } -serde_derive = "=1.0.147" +serde = { version = "=1.0.165", features = ["derive"] } +serde_derive = "=1.0.165" serde_json = "=1.0.89" hex = "=0.4.3" tokio = { version = "=1.28.2", features = ["full"] } regex = "=1.9.3" -num-bigint = "=0.4.3" -num-traits = "=0.2.15" -num-integer = "=0.1.45" +num-bigint = "=0.4.6" +num-traits = "=0.2.19" +num-integer = "=0.1.46" prost = "=0.11.2" bytes = "=1.4.0" prost-types = "=0.11.2" diff --git a/imkey-core/ikc-device/Cargo.toml b/imkey-core/ikc-device/Cargo.toml index 3739d47a..d538f3ee 100644 --- a/imkey-core/ikc-device/Cargo.toml +++ b/imkey-core/ikc-device/Cargo.toml @@ -9,8 +9,8 @@ edition = "2018" [dependencies] ikc-common = {path = "../ikc-common"} ikc-transport = {path = "../ikc-transport"} -serde = { version = "=1.0.147", features = ["derive"] } -serde_derive = "=1.0.147" +serde = { version = "=1.0.165", features = ["derive"] } +serde_derive = "=1.0.165" serde_json = "=1.0.89" base64 = "=0.13.1" hex = "=0.4.3" diff --git a/imkey-core/ikc-wallet/coin-bch/Cargo.toml b/imkey-core/ikc-wallet/coin-bch/Cargo.toml index 0ec8a606..4fe5d15f 100644 --- a/imkey-core/ikc-wallet/coin-bch/Cargo.toml +++ b/imkey-core/ikc-wallet/coin-bch/Cargo.toml @@ -17,10 +17,10 @@ secp256k1 = {version ="=0.24.3", features = ["rand", "recovery"] } tiny-bip39 = "=1.0.0" anyhow = "=1.0.79" hex = "=0.4.3" -serde = { version = "=1.0.147", features = ["derive"] } +serde = { version = "=1.0.165", features = ["derive"] } serde_json = "=1.0.89" bitcoin_hashes = "=0.11.0" -num-bigint = "=0.4.3" +num-bigint = "=0.4.6" bytes = "=1.4.0" prost = "=0.11.2" prost-types = "=0.11.2" diff --git a/imkey-core/ikc-wallet/coin-bitcoin/Cargo.toml b/imkey-core/ikc-wallet/coin-bitcoin/Cargo.toml index 208aafa0..a4048972 100644 --- a/imkey-core/ikc-wallet/coin-bitcoin/Cargo.toml +++ b/imkey-core/ikc-wallet/coin-bitcoin/Cargo.toml @@ -14,7 +14,7 @@ bitcoin = "=0.29.2" hex = "=0.4.3" secp256k1 = {version ="=0.24.3", features = ["rand", "recovery"] } bitcoin_hashes = "=0.11.0" -num-bigint = "=0.4.3" +num-bigint = "=0.4.6" anyhow = "=1.0.79" bytes = "=1.4.0" prost = "=0.11.2" diff --git a/imkey-core/ikc-wallet/coin-btc-fork/Cargo.toml b/imkey-core/ikc-wallet/coin-btc-fork/Cargo.toml index 7c760da9..e898c856 100644 --- a/imkey-core/ikc-wallet/coin-btc-fork/Cargo.toml +++ b/imkey-core/ikc-wallet/coin-btc-fork/Cargo.toml @@ -16,10 +16,10 @@ secp256k1 = {version ="=0.24.3", features = ["rand", "recovery"] } tiny-bip39 = "=1.0.0" anyhow = "=1.0.79" hex = "=0.4.3" -serde = { version = "=1.0.147", features = ["derive"] } +serde = { version = "=1.0.165", features = ["derive"] } serde_json = "=1.0.89" bitcoin_hashes = "=0.11.0" -num-bigint = "=0.4.3" +num-bigint = "=0.4.6" bytes = "=1.4.0" prost = "=0.11.2" prost-types = "=0.11.2" diff --git a/imkey-core/ikc-wallet/coin-cosmos/Cargo.toml b/imkey-core/ikc-wallet/coin-cosmos/Cargo.toml index 6f4c60ea..0288c8a1 100644 --- a/imkey-core/ikc-wallet/coin-cosmos/Cargo.toml +++ b/imkey-core/ikc-wallet/coin-cosmos/Cargo.toml @@ -15,12 +15,12 @@ hex = "=0.4.3" bitcoin = "=0.29.2" secp256k1 = {version ="=0.24.3", features = ["rand", "recovery"] } bech32 = "=0.9.1" -serde = { version = "=1.0.147", features = ["derive"] } -serde_derive = "=1.0.147" +serde = { version = "=1.0.165", features = ["derive"] } +serde_derive = "=1.0.165" serde_json = { version = "=1.0.89", default-features = false, features = ["alloc"] } -num-bigint = "=0.4.3" -num-traits = "=0.2.15" -num-integer = "=0.1.45" +num-bigint = "=0.4.6" +num-traits = "=0.2.19" +num-integer = "0.1.46" base64 = "=0.13.1" anyhow = "=1.0.79" bytes = "=1.4.0" diff --git a/imkey-core/ikc-wallet/coin-ethereum/Cargo.toml b/imkey-core/ikc-wallet/coin-ethereum/Cargo.toml index 185c24c1..3f8a6214 100644 --- a/imkey-core/ikc-wallet/coin-ethereum/Cargo.toml +++ b/imkey-core/ikc-wallet/coin-ethereum/Cargo.toml @@ -17,8 +17,8 @@ keccak-hash = "=0.10.0" lazy_static = "=1.4.0" rustc-hex = "=2.1.0" serde_json = "=1.0.89" -serde = { version = "=1.0.147", features = ["derive"] } -serde_derive = "=1.0.147" +serde = { version = "=1.0.165", features = ["derive"] } +serde_derive = "=1.0.165" jsonrpc-core = "=18.0.0" bitcoin = "=0.29.2" bitcoin_hashes = "=0.11.0" @@ -26,9 +26,9 @@ hex = "=0.4.3" regex = "=1.9.3" tiny-keccak = { version = "=2.0.2", features = ["keccak"] } anyhow = "=1.0.79" -num-bigint = "=0.4.3" -num-traits = "=0.2.15" -num-integer = "=0.1.45" +num-bigint = "=0.4.6" +num-traits = "=0.2.19" +num-integer = "=0.1.46" bytes = "=1.4.0" prost = "=0.11.2" prost-types = "=0.11.2" diff --git a/imkey-core/ikc-wallet/coin-filecoin/Cargo.toml b/imkey-core/ikc-wallet/coin-filecoin/Cargo.toml index a6305523..b98f17af 100644 --- a/imkey-core/ikc-wallet/coin-filecoin/Cargo.toml +++ b/imkey-core/ikc-wallet/coin-filecoin/Cargo.toml @@ -16,9 +16,10 @@ bitcoin_hashes = "=0.11.0" hex = "=0.4.3" secp256k1 = {version ="=0.24.3", features = ["rand", "recovery"] } bech32 = "=0.9.1" -num-bigint = "=0.4.3" -num-traits = "=0.2.15" -num-integer = "=0.1.45" +num-bigint = "=0.4.6" +num = "0.4.3" +num-traits = "=0.2.19" +num-integer = "=0.1.46" base64 = "=0.13.1" anyhow = "=1.0.79" bytes = "=1.4.0" @@ -28,15 +29,16 @@ linked-hash-map = { version = "=0.5.6", features = ["serde_impl"] } base32 = "=0.4.0" blake2b-rs = "=0.2.0" -serde = { version = "=1.0.147", features = ["derive"] } +serde = { version = "=1.0.165", features = ["derive"] } serde_json = "=1.0.89" -forest_vm = "=0.3.2" -forest_message = "=0.7.2" -forest_address = "=0.3.2" -forest_encoding = "=0.2.2" -forest_cid = "=0.3.0" -forest_crypto = "=0.5.3" -num_bigint_chainsafe = { package = "forest_bigint", version = "=0.1.4"} +multihash-codetable = { version = "=0.1.3", features = ["blake2b"] } +cid = "=0.11.1" +fvm_shared = "=4.3.1" +fvm_ipld_encoding = "0.4.0" +serde_tuple = "0.5.0" +strum_macros = "0.26.3" +strum = { version = "0.26.3", features = ["derive"] } bitcoin = "=0.29.2" +num-derive = "0.4.2" diff --git a/imkey-core/ikc-wallet/coin-filecoin/src/transaction.rs b/imkey-core/ikc-wallet/coin-filecoin/src/transaction.rs index 1338b936..c03cb09c 100644 --- a/imkey-core/ikc-wallet/coin-filecoin/src/transaction.rs +++ b/imkey-core/ikc-wallet/coin-filecoin/src/transaction.rs @@ -2,6 +2,7 @@ use crate::address::FilecoinAddress; use crate::filecoinapi::{FilecoinTxInput, FilecoinTxOutput, Signature}; use crate::utils::{digest, HashSize}; use crate::Result; +use std::borrow::Cow; use ikc_common::apdu::{ApduCheck, Secp256k1Apdu}; use ikc_common::error::CoinError; @@ -9,46 +10,132 @@ use ikc_common::utility::{hex_to_bytes, secp256k1_sign}; use ikc_common::{constants, path, utility, SignParam}; use ikc_device::device_binding::KEY_MANAGER; -use anyhow::anyhow; -use forest_address::Address; -use forest_cid::Cid; -use forest_encoding::Cbor; -use forest_message::UnsignedMessage as ForestUnsignedMessage; -use forest_vm::{Serialized, TokenAmount}; use ikc_transport::message::send_apdu_timeout; use secp256k1::ecdsa::Signature as SecpSignature; use std::str::FromStr; +use num::FromPrimitive; +use num_derive::FromPrimitive; + +use crate::utils::CidCborExt; +use cid::{Cid, CidGeneric}; +use fvm_ipld_encoding::RawBytes; +use fvm_ipld_encoding::{ + de, + repr::{Deserialize_repr, Serialize_repr}, + ser, strict_bytes, +}; +use fvm_shared::address::Address; +use fvm_shared::econ::TokenAmount; +use fvm_shared::message::Message as ForestUnsignedMessage; +use serde_tuple::{self, Deserialize_tuple, Serialize_tuple}; +use std::convert::TryFrom; + #[derive(Default, Debug, Clone, PartialEq, Eq)] pub struct Transaction {} +fn str_to_token_amount(str: &str) -> TokenAmount { + TokenAmount::from_atto(u64::from_str(str).unwrap()) +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct ForestSignature { + pub sig_type: SignatureType, + pub bytes: Vec, +} + +impl ser::Serialize for ForestSignature { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: ser::Serializer, + { + let mut bytes = Vec::with_capacity(self.bytes.len() + 1); + // Insert signature type byte + bytes.push(self.sig_type as u8); + bytes.extend_from_slice(&self.bytes); + + strict_bytes::Serialize::serialize(&bytes, serializer) + } +} + +impl<'de> de::Deserialize<'de> for ForestSignature { + fn deserialize(deserializer: D) -> std::result::Result + where + D: de::Deserializer<'de>, + { + let bytes: Cow<'de, [u8]> = strict_bytes::Deserialize::deserialize(deserializer)?; + match bytes.split_first() { + None => Err(de::Error::custom("Cannot deserialize empty bytes")), + Some((&sig_byte, rest)) => { + // Remove signature type byte + let sig_type = SignatureType::from_u8(sig_byte).ok_or_else(|| { + de::Error::custom(format!( + "Invalid signature type byte (must be 1, 2 or 3), was {}", + sig_byte + )) + })?; + + Ok(ForestSignature { + bytes: rest.to_vec(), + sig_type, + }) + } + } + } +} + +#[derive(PartialEq, Clone, Debug, Serialize_tuple, Deserialize_tuple, Hash, Eq)] +pub struct ForestSignedMessage { + pub message: ForestUnsignedMessage, + pub signature: ForestSignature, +} + +#[derive( + Clone, + Debug, + PartialEq, + FromPrimitive, + Copy, + Eq, + Serialize_repr, + Deserialize_repr, + Hash, + strum::Display, + strum::EnumString, +)] +#[repr(u8)] +#[strum(serialize_all = "lowercase")] +pub enum SignatureType { + Secp256k1 = 1, + Bls = 2, + Delegated = 3, +} + impl Transaction { fn convert_message(message: &FilecoinTxInput) -> Result { let to = Address::from_str(&message.to).map_err(|_| CoinError::InvalidAddress)?; let from = Address::from_str(&message.from).map_err(|_| CoinError::InvalidAddress)?; - let value = TokenAmount::from_str(&message.value).map_err(|_| CoinError::InvalidNumber)?; + let value = str_to_token_amount(&message.value); let gas_limit = message.gas_limit; - let gas_fee_cap = - TokenAmount::from_str(&message.gas_fee_cap).map_err(|_| CoinError::InvalidNumber)?; - let gas_premium = - TokenAmount::from_str(&message.gas_premium).map_err(|_| CoinError::InvalidNumber)?; + let gas_fee_cap = str_to_token_amount(&message.gas_fee_cap); + let gas_premium = str_to_token_amount(&message.gas_premium); let message_params_bytes = base64::decode(&message.params).map_err(|_| CoinError::InvalidParam)?; - let params = Serialized::new(message_params_bytes); - - let tmp = ForestUnsignedMessage::builder() - .to(to) - .from(from) - .sequence(message.nonce) - .value(value) - .method_num(message.method) - .params(params) - .gas_limit(gas_limit) - .gas_premium(gas_premium) - .gas_fee_cap(gas_fee_cap) - .build() - .map_err(|_| CoinError::InvalidFormat)?; + let params = RawBytes::from(message_params_bytes); + + let tmp = ForestUnsignedMessage { + version: 0, + from, + to, + sequence: message.nonce, + value, + method_num: message.method, + params, + gas_limit: gas_limit as u64, + gas_fee_cap, + gas_premium, + }; Ok(tmp) } @@ -72,7 +159,7 @@ impl Transaction { let res_msg_pubkey = FilecoinAddress::get_pub_key(sign_param.path.as_str())?; let pubkey_raw = hex_to_bytes(&res_msg_pubkey[..130]).unwrap(); - let mut cid: Cid = unsigned_message.cid()?; + let mut cid: Cid = as CidCborExt>::from_cbor_blake2b256(&unsigned_message)?; let data = &digest(&cid.to_bytes(), HashSize::Default); //organize data @@ -137,14 +224,15 @@ impl Transaction { data_arr[0..64].copy_from_slice(&normalizes_sig_vec[0..64]); data_arr[64] = rec_id.to_i32() as u8; - let forest_sig = forest_crypto::Signature::new_secp256k1(data_arr.to_vec()); - let forest_signed_msg = forest_message::SignedMessage { + let forest_sig = ForestSignature { + sig_type: SignatureType::Secp256k1, + bytes: data_arr.clone().to_vec(), + }; + let forest_signed_msg = ForestSignedMessage { message: unsigned_message, signature: forest_sig, }; - cid = forest_signed_msg - .cid() - .map_err(|_e| anyhow!("{}", "forest_message cid error"))?; + cid = as CidCborExt>::from_cbor_blake2b256(&forest_signed_msg)?; let signature_type = 1; diff --git a/imkey-core/ikc-wallet/coin-filecoin/src/utils.rs b/imkey-core/ikc-wallet/coin-filecoin/src/utils.rs index 3d24863e..458a7fbf 100644 --- a/imkey-core/ikc-wallet/coin-filecoin/src/utils.rs +++ b/imkey-core/ikc-wallet/coin-filecoin/src/utils.rs @@ -1,4 +1,7 @@ use blake2b_rs::Blake2bBuilder; +use cid::Cid; +use fvm_ipld_encoding::Error; +use multihash_codetable::{Code, MultihashDigest}; pub enum HashSize { Checksum = 4, @@ -17,6 +20,24 @@ pub fn digest(ingest: &[u8], hash_size: HashSize) -> Vec { result[0..size].to_vec() } +/// Extension methods for constructing `dag-cbor` [Cid] +pub trait CidCborExt { + /// Default CID builder for Filecoin + /// + /// - The default codec is [`fvm_ipld_encoding::DAG_CBOR`] + /// - The default hash function is 256 bit BLAKE2b + /// + /// This matches [`abi.CidBuilder`](https://github.com/filecoin-project/go-state-types/blob/master/abi/cid.go#L49) in go + fn from_cbor_blake2b256(obj: &S) -> Result { + let bytes = fvm_ipld_encoding::to_vec(obj)?; + Ok(Cid::new_v1( + fvm_ipld_encoding::DAG_CBOR, + Code::Blake2b256.digest(&bytes), + )) + } +} + +impl CidCborExt for Cid {} #[cfg(test)] mod tests { use crate::utils::{digest, HashSize}; diff --git a/token-core/tcx-btc-kin/Cargo.toml b/token-core/tcx-btc-kin/Cargo.toml index 7eede65b..bd8e348f 100644 --- a/token-core/tcx-btc-kin/Cargo.toml +++ b/token-core/tcx-btc-kin/Cargo.toml @@ -19,13 +19,13 @@ secp256k1 = {version ="=0.24.3", features = ["rand", "recovery", "rand-std"] } tiny-bip39 = "=1.0.0" bitcoin_hashes = "=0.11.0" #bitcoinconsensus = { version = "0.19.0-2", optional = true } -serde = { version = "=1.0.147", features = ["derive"] } +serde = { version = "=1.0.165", features = ["derive"] } serde_json = "=1.0.89" uuid = { version = "=1.2.2", features = ["serde", "v4"] } anyhow = { version = "=1.0.79", features = [] } -num-bigint = "=0.4.3" -num-traits = "=0.2.15" -num-integer = "=0.1.45" +num-bigint = "=0.4.6" +num-traits = "=0.2.19" +num-integer = "=0.1.46" byteorder = "=1.4.3" bech32 = "=0.9.1" prost = "=0.11.2" diff --git a/token-core/tcx-constants/Cargo.toml b/token-core/tcx-constants/Cargo.toml index fb05447e..e5b78e08 100644 --- a/token-core/tcx-constants/Cargo.toml +++ b/token-core/tcx-constants/Cargo.toml @@ -11,5 +11,5 @@ tcx-common = { path = "../tcx-common" } anyhow = { version = "=1.0.79", features = [] } lazy_static = "=1.4.0" serde_json = "=1.0.89" -serde = { version = "=1.0.147", features = ["derive"] } +serde = { version = "=1.0.165", features = ["derive"] } parking_lot = "=0.12.1" diff --git a/token-core/tcx-crypto/Cargo.toml b/token-core/tcx-crypto/Cargo.toml index fb63c9ec..c46e0a7f 100644 --- a/token-core/tcx-crypto/Cargo.toml +++ b/token-core/tcx-crypto/Cargo.toml @@ -9,7 +9,7 @@ tcx-constants = {path="../tcx-constants"} tcx-common = {path="../tcx-common"} serde_json = "=1.0.89" -serde = { version = "=1.0.147", features = ["derive"] } +serde = { version = "=1.0.165", features = ["derive"] } rand = "=0.8.5" tiny-keccak = { version = "=2.0.2", features = ["keccak"] } scrypt = { version = "=0.10.0", default-features = false } diff --git a/token-core/tcx-filecoin/Cargo.toml b/token-core/tcx-filecoin/Cargo.toml index 663c58c7..8bd6b7d7 100644 --- a/token-core/tcx-filecoin/Cargo.toml +++ b/token-core/tcx-filecoin/Cargo.toml @@ -19,14 +19,21 @@ blake2b-rs = "=0.2.0" anyhow = { version = "=1.0.79", features = [] } byteorder = "=1.4.3" base32 = "=0.4.0" -serde = { version = "=1.0.147", features = ["derive"] } +serde = { version = "=1.0.165", features = ["derive"] } serde_json = "=1.0.89" base64 = "=0.13.1" lazy_static = "=1.4.0" -forest_vm = "=0.3.2" -forest_message = "=0.7.2" -forest_address = "=0.3.2" -forest_encoding = "=0.2.2" -forest_cid = "=0.3.0" -forest_crypto = "0.5.3" thiserror = "=1.0.56" + + + +multihash-codetable = { version = "=0.1.3", features = ["blake2b"] } +cid = "=0.11.1" +fvm_shared = "=4.3.1" +fvm_ipld_encoding = "0.4.0" +serde_tuple = "0.5.0" +strum_macros = "0.26.3" +strum = { version = "0.26.3", features = ["derive"] } +num-traits = "0.2.15" +num = "0.4.3" +num-derive = "0.4.2" \ No newline at end of file diff --git a/token-core/tcx-filecoin/src/address.rs b/token-core/tcx-filecoin/src/address.rs index 72b8d422..34bc3d85 100644 --- a/token-core/tcx-filecoin/src/address.rs +++ b/token-core/tcx-filecoin/src/address.rs @@ -2,11 +2,12 @@ use tcx_constants::CoinInfo; use tcx_keystore::{Address, Result}; use tcx_primitive::{PublicKey, TypedPublicKey}; -use forest_address::Address as ForestAddress; +use fvm_shared::address::Network; +use fvm_shared::address::{set_current_network, Address as ForestAddress}; use super::Error; use crate::utils::{digest, HashSize}; -use base32::Alphabet; +use fvm_shared::address::Network::{Mainnet, Testnet}; use std::str::FromStr; const MAINNET_PREFIX: &str = "f"; @@ -33,55 +34,35 @@ impl FilecoinAddress { impl Address for FilecoinAddress { fn from_public_key(public_key: &TypedPublicKey, coin: &CoinInfo) -> Result { - let network_prefix = match coin.network.as_str() { - "TESTNET" => TESTNET_PREFIX, - _ => MAINNET_PREFIX, + match coin.network.as_str() { + "TESTNET" => set_current_network(Testnet), + _ => set_current_network(Mainnet), }; - let protocol; - let payload; - let checksum; - match public_key { + let addr_str = match public_key { TypedPublicKey::Secp256k1(pk) => { - protocol = Protocol::Secp256k1; - payload = Self::address_hash(&pk.to_uncompressed()); - - checksum = Self::checksum(&[vec![protocol as u8], payload.to_vec()].concat()); + let addr = ForestAddress::new_secp256k1(&pk.to_uncompressed())?; + addr.to_string() } TypedPublicKey::BLS(pk) => { - protocol = Protocol::Bls; - payload = pk.to_bytes(); - - checksum = Self::checksum(&[vec![protocol as u8], payload.to_vec()].concat()); + let addr = ForestAddress::new_bls(&pk.to_bytes())?; + addr.to_string() } _ => { return Err(Error::InvalidCurveType.into()); } }; - Ok(FilecoinAddress(format!( - "{}{}{}", - network_prefix, - protocol as i8, - base32::encode( - Alphabet::RFC4648 { padding: false }, - &[payload, checksum].concat() - ) - .to_lowercase() - ))) + Ok(FilecoinAddress(addr_str)) } fn is_valid(address: &str, coin: &CoinInfo) -> bool { let ntwk = match coin.network.as_str() { - "TESTNET" => TESTNET_PREFIX, - _ => MAINNET_PREFIX, + "TESTNET" => Testnet, + _ => Mainnet, }; - if !address.starts_with(ntwk) { - return false; - } - - ForestAddress::from_str(address).is_ok() + ntwk.parse_address(address).is_ok() } } @@ -117,47 +98,47 @@ mod tests { FilecoinAddress::is_valid("t12i3bop43tprlnymx2c75u6uvlq7iur2rcd7qsey", &coin_info), true ); - assert_eq!(FilecoinAddress::is_valid("t3qdyntx5snnwgmjkp2ztd6tf6hhcmurxfj53zylrqyympwvzvbznx6vnvdqloate5eviphnzrkupno4wheesa",&coin_info), true); - assert_eq!(FilecoinAddress::is_valid("t3rynpyphoo6pxfzb4ljy3zmf224vjihlok4oewbpjii3uq2mgl7jgrpxsiddaowsxccnnbi2p4ei4sdmsxfaq",&coin_info), true); - assert_eq!(FilecoinAddress::is_valid("t3rynpyphoo6pxfzb4ljy3zmf224vjihlok4oewbpjii3uq2mgl7jgrpxsiddaowsxccnnbi2p4ei4sdmsxfaqt",&coin_info), false); + assert_eq!(FilecoinAddress::is_valid("t3qdyntx5snnwgmjkp2ztd6tf6hhcmurxfj53zylrqyympwvzvbznx6vnvdqloate5eviphnzrkupno4wheesa", &coin_info), true); + assert_eq!(FilecoinAddress::is_valid("t3rynpyphoo6pxfzb4ljy3zmf224vjihlok4oewbpjii3uq2mgl7jgrpxsiddaowsxccnnbi2p4ei4sdmsxfaq", &coin_info), true); + assert_eq!(FilecoinAddress::is_valid("t3rynpyphoo6pxfzb4ljy3zmf224vjihlok4oewbpjii3uq2mgl7jgrpxsiddaowsxccnnbi2p4ei4sdmsxfaqt", &coin_info), false); let coin_info = coin_info_from_param("FILECOIN", "MAINNET", "", "").unwrap(); assert_eq!( FilecoinAddress::is_valid("t12i3bop43tprlnymx2c75u6uvlq7iur2rcd7qsey", &coin_info), false ); - assert_eq!(FilecoinAddress::is_valid("t3qdyntx5snnwgmjkp2ztd6tf6hhcmurxfj53zylrqyympwvzvbznx6vnvdqloate5eviphnzrkupno4wheesa",&coin_info), false); - assert_eq!(FilecoinAddress::is_valid("t3rynpyphoo6pxfzb4ljy3zmf224vjihlok4oewbpjii3uq2mgl7jgrpxsiddaowsxccnnbi2p4ei4sdmsxfaq",&coin_info), false); + assert_eq!(FilecoinAddress::is_valid("t3qdyntx5snnwgmjkp2ztd6tf6hhcmurxfj53zylrqyympwvzvbznx6vnvdqloate5eviphnzrkupno4wheesa", &coin_info), false); + assert_eq!(FilecoinAddress::is_valid("t3rynpyphoo6pxfzb4ljy3zmf224vjihlok4oewbpjii3uq2mgl7jgrpxsiddaowsxccnnbi2p4ei4sdmsxfaq", &coin_info), false); } #[test] fn test_bls_address() { let test_cases = vec![ (vec![173, 88, 223, 105, 110, 45, 78, 145, 234, 134, 200, 129, 233, 56, - 186, 78, 168, 27, 57, 94, 18, 121, 123, 132, 185, 207, 49, 75, 149, 70, - 112, 94, 131, 156, 122, 153, 214, 6, 178, 71, 221, 180, 249, 172, 122, - 52, 20, 221], - "t3vvmn62lofvhjd2ugzca6sof2j2ubwok6cj4xxbfzz4yuxfkgobpihhd2thlanmsh3w2ptld2gqkn2jvlss4a"), + 186, 78, 168, 27, 57, 94, 18, 121, 123, 132, 185, 207, 49, 75, 149, 70, + 112, 94, 131, 156, 122, 153, 214, 6, 178, 71, 221, 180, 249, 172, 122, + 52, 20, 221], + "t3vvmn62lofvhjd2ugzca6sof2j2ubwok6cj4xxbfzz4yuxfkgobpihhd2thlanmsh3w2ptld2gqkn2jvlss4a"), (vec![179, 41, 79, 10, 46, 41, 224, 198, 110, 188, 35, 93, 47, 237, - 202, 86, 151, 191, 120, 74, 246, 5, 199, 90, 246, 8, 230, 166, 61, 92, - 211, 142, 168, 92, 168, 152, 158, 14, 253, 233, 24, 139, 56, 47, - 147, 114, 70, 13], - "t3wmuu6crofhqmm3v4enos73okk2l366ck6yc4owxwbdtkmpk42ohkqxfitcpa57pjdcftql4tojda2poeruwa"), + 202, 86, 151, 191, 120, 74, 246, 5, 199, 90, 246, 8, 230, 166, 61, 92, + 211, 142, 168, 92, 168, 152, 158, 14, 253, 233, 24, 139, 56, 47, + 147, 114, 70, 13], + "t3wmuu6crofhqmm3v4enos73okk2l366ck6yc4owxwbdtkmpk42ohkqxfitcpa57pjdcftql4tojda2poeruwa"), (vec![150, 161, 163, 228, 234, 122, 20, 212, 153, 133, 230, 97, 178, - 36, 1, 212, 79, 237, 64, 45, 29, 9, 37, 178, 67, 201, 35, 88, 156, - 15, 188, 126, 50, 205, 4, 226, 158, 215, 141, 21, 211, 125, 58, 170, - 63, 230, 218, 51], - "t3s2q2hzhkpiknjgmf4zq3ejab2rh62qbndueslmsdzervrhapxr7dftie4kpnpdiv2n6tvkr743ndhrsw6d3a"), + 36, 1, 212, 79, 237, 64, 45, 29, 9, 37, 178, 67, 201, 35, 88, 156, + 15, 188, 126, 50, 205, 4, 226, 158, 215, 141, 21, 211, 125, 58, 170, + 63, 230, 218, 51], + "t3s2q2hzhkpiknjgmf4zq3ejab2rh62qbndueslmsdzervrhapxr7dftie4kpnpdiv2n6tvkr743ndhrsw6d3a"), (vec![134, 180, 84, 37, 140, 88, 148, 117, 247, 209, 111, 90, 172, 1, - 138, 121, 246, 193, 22, 157, 32, 252, 51, 146, 29, 216, 181, 206, 28, - 172, 108, 52, 143, 144, 163, 96, 54, 36, 246, 174, 185, 27, 100, 81, - 140, 46, 128, 149], - "t3q22fijmmlckhl56rn5nkyamkph3mcfu5ed6dheq53c244hfmnq2i7efdma3cj5voxenwiummf2ajlsbxc65a"), + 138, 121, 246, 193, 22, 157, 32, 252, 51, 146, 29, 216, 181, 206, 28, + 172, 108, 52, 143, 144, 163, 96, 54, 36, 246, 174, 185, 27, 100, 81, + 140, 46, 128, 149], + "t3q22fijmmlckhl56rn5nkyamkph3mcfu5ed6dheq53c244hfmnq2i7efdma3cj5voxenwiummf2ajlsbxc65a"), (vec![167, 114, 107, 3, 128, 34, 247, 90, 56, 70, 23, 88, 83, 96, 206, - 230, 41, 7, 10, 45, 157, 40, 113, 41, 101, 229, 242, 110, 204, 64, - 133, 131, 130, 128, 55, 36, 237, 52, 242, 114, 3, 54, 240, 157, 182, - 49, 240, 116], - "t3u5zgwa4ael3vuocgc5mfgygo4yuqocrntuuhcklf4xzg5tcaqwbyfabxetwtj4tsam3pbhnwghyhijr5mixa"), + 230, 41, 7, 10, 45, 157, 40, 113, 41, 101, 229, 242, 110, 204, 64, + 133, 131, 130, 128, 55, 36, 237, 52, 242, 114, 3, 54, 240, 157, 182, + 49, 240, 116], + "t3u5zgwa4ael3vuocgc5mfgygo4yuqocrntuuhcklf4xzg5tcaqwbyfabxetwtj4tsam3pbhnwghyhijr5mixa"), ]; let coin_info = CoinInfo { diff --git a/token-core/tcx-filecoin/src/signer.rs b/token-core/tcx-filecoin/src/signer.rs index 413c7526..d53283f7 100644 --- a/token-core/tcx-filecoin/src/signer.rs +++ b/token-core/tcx-filecoin/src/signer.rs @@ -1,17 +1,106 @@ use crate::transaction::{Signature, SignedMessage, UnsignedMessage}; use crate::utils::{digest, HashSize}; use crate::Error; -use anyhow::anyhow; -use forest_address::Address; -use forest_cid::Cid; -use forest_encoding::Cbor; -use forest_message::UnsignedMessage as ForestUnsignedMessage; -use forest_vm::{Serialized, TokenAmount}; +use fvm_shared::address::Address; +use std::borrow::Cow; + +use crate::utils::CidCborExt; +use cid::{Cid, CidGeneric}; +use fvm_ipld_encoding::RawBytes; +use fvm_ipld_encoding::{ + de, + repr::{Deserialize_repr, Serialize_repr}, + ser, strict_bytes, +}; +use fvm_shared::econ::TokenAmount; +use fvm_shared::message::Message as ForestUnsignedMessage; +use serde_tuple::{self, Deserialize_tuple, Serialize_tuple}; use std::convert::TryFrom; use std::str::FromStr; use tcx_constants::CurveType; use tcx_keystore::{tcx_ensure, Keystore, Result, SignatureParameters, Signer, TransactionSigner}; +use num::FromPrimitive; +use num_derive::FromPrimitive; +use strum::*; + +#[derive( + Clone, + Debug, + PartialEq, + FromPrimitive, + Copy, + Eq, + Serialize_repr, + Deserialize_repr, + Hash, + strum::Display, + strum::EnumString, +)] +#[repr(u8)] +#[strum(serialize_all = "lowercase")] +pub enum SignatureType { + Secp256k1 = 1, + Bls = 2, + Delegated = 3, +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct ForestSignature { + pub sig_type: SignatureType, + pub bytes: Vec, +} + +impl ser::Serialize for ForestSignature { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: ser::Serializer, + { + let mut bytes = Vec::with_capacity(self.bytes.len() + 1); + // Insert signature type byte + bytes.push(self.sig_type as u8); + bytes.extend_from_slice(&self.bytes); + + strict_bytes::Serialize::serialize(&bytes, serializer) + } +} + +impl<'de> de::Deserialize<'de> for ForestSignature { + fn deserialize(deserializer: D) -> std::result::Result + where + D: de::Deserializer<'de>, + { + let bytes: Cow<'de, [u8]> = strict_bytes::Deserialize::deserialize(deserializer)?; + match bytes.split_first() { + None => Err(de::Error::custom("Cannot deserialize empty bytes")), + Some((&sig_byte, rest)) => { + // Remove signature type byte + let sig_type = SignatureType::from_u8(sig_byte).ok_or_else(|| { + de::Error::custom(format!( + "Invalid signature type byte (must be 1, 2 or 3), was {}", + sig_byte + )) + })?; + + Ok(ForestSignature { + bytes: rest.to_vec(), + sig_type, + }) + } + } + } +} + +#[derive(PartialEq, Clone, Debug, Serialize_tuple, Deserialize_tuple, Hash, Eq)] +pub struct ForestSignedMessage { + pub message: ForestUnsignedMessage, + pub signature: ForestSignature, +} + +fn str_to_token_amount(str: &str) -> TokenAmount { + TokenAmount::from_atto(u64::from_str(str).unwrap()) +} + impl TryFrom<&UnsignedMessage> for ForestUnsignedMessage { type Error = crate::Error; @@ -20,30 +109,28 @@ impl TryFrom<&UnsignedMessage> for ForestUnsignedMessage { ) -> core::result::Result { let to = Address::from_str(&message.to).map_err(|_| Error::InvalidAddress)?; let from = Address::from_str(&message.from).map_err(|_| Error::InvalidAddress)?; - let value = TokenAmount::from_str(&message.value).map_err(|_| Error::InvalidNumber)?; + let value = str_to_token_amount(&message.value); let gas_limit = message.gas_limit; - let gas_fee_cap = - TokenAmount::from_str(&message.gas_fee_cap).map_err(|_| Error::InvalidNumber)?; - let gas_premium = - TokenAmount::from_str(&message.gas_premium).map_err(|_| Error::InvalidNumber)?; + let gas_fee_cap = str_to_token_amount(&message.gas_fee_cap); + let gas_premium = str_to_token_amount(&message.gas_premium); let message_params_bytes = base64::decode(&message.params).map_err(|_| Error::InvalidParam)?; - let params = Serialized::new(message_params_bytes); + let params = RawBytes::from(message_params_bytes); tcx_ensure!(message.method == 0, Error::InvalidMethodId); - let tmp = ForestUnsignedMessage::builder() - .to(to) - .from(from) - .sequence(message.nonce) - .value(value) - .method_num(message.method) - .params(params) - .gas_limit(gas_limit) - .gas_premium(gas_premium) - .gas_fee_cap(gas_fee_cap) - .build() - .map_err(|_| Error::InvalidFormat)?; + let tmp = Self { + version: 0, + from, + to, + sequence: message.nonce, + value, + method_num: message.method, + params, + gas_limit: gas_limit as u64, + gas_fee_cap, + gas_premium, + }; Ok(tmp) } @@ -55,12 +142,12 @@ impl TransactionSigner for Keystore { sign_context: &SignatureParameters, tx: &UnsignedMessage, ) -> Result { - let unsigned_message = forest_message::UnsignedMessage::try_from(tx)?; + let unsigned_message = ForestUnsignedMessage::try_from(tx)?; let signature_type; let signature; - let mut cid: Cid = unsigned_message.cid()?; + let mut cid: Cid = as CidCborExt>::from_cbor_blake2b256(&unsigned_message)?; match sign_context.curve { CurveType::SECP256k1 => { signature_type = 1; @@ -69,24 +156,24 @@ impl TransactionSigner for Keystore { &sign_context.derivation_path, )?; - let forest_sig = forest_crypto::Signature::new_secp256k1(signature.clone()); - let forest_signed_msg = forest_message::SignedMessage { + let forest_signed_msg = ForestSignedMessage { message: unsigned_message, - signature: forest_sig, + signature: ForestSignature { + sig_type: SignatureType::Secp256k1, + bytes: signature.clone(), + }, }; - cid = forest_signed_msg - .cid() - .map_err(|_e| anyhow!("{}", "forest_message cid error"))?; + cid = as CidCborExt>::from_cbor_blake2b256(&forest_signed_msg)?; } CurveType::BLS => { signature_type = 2; + cid = as CidCborExt>::from_cbor_blake2b256(&unsigned_message)?; signature = self.bls_sign( &cid.to_bytes(), &sign_context.derivation_path, "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_", )?; // use unsigned_message https://github.com/filecoin-project/lotus/issues/101 - cid = unsigned_message.cid()?; } _ => return Err(Error::InvalidCurveType.into()), } @@ -208,7 +295,7 @@ mod tests { gas_fee_cap: "151367".to_string(), gas_premium: "150313".to_string(), method: 0, - params: "".to_string() + params: "".to_string(), }; let key_info = @@ -255,7 +342,7 @@ mod tests { gas_fee_cap: "151367".to_string(), gas_premium: "150313".to_string(), method: 0, - params: "".to_string() + params: "".to_string(), }; let key_info = diff --git a/token-core/tcx-filecoin/src/utils.rs b/token-core/tcx-filecoin/src/utils.rs index 3d24863e..bdaaeaef 100644 --- a/token-core/tcx-filecoin/src/utils.rs +++ b/token-core/tcx-filecoin/src/utils.rs @@ -1,5 +1,7 @@ use blake2b_rs::Blake2bBuilder; - +use cid::Cid; +use fvm_ipld_encoding::Error; +use multihash_codetable::{Code, MultihashDigest}; pub enum HashSize { Checksum = 4, Payload = 20, @@ -17,6 +19,25 @@ pub fn digest(ingest: &[u8], hash_size: HashSize) -> Vec { result[0..size].to_vec() } +/// Extension methods for constructing `dag-cbor` [Cid] +pub trait CidCborExt { + /// Default CID builder for Filecoin + /// + /// - The default codec is [`fvm_ipld_encoding::DAG_CBOR`] + /// - The default hash function is 256 bit BLAKE2b + /// + /// This matches [`abi.CidBuilder`](https://github.com/filecoin-project/go-state-types/blob/master/abi/cid.go#L49) in go + fn from_cbor_blake2b256(obj: &S) -> Result { + let bytes = fvm_ipld_encoding::to_vec(obj)?; + Ok(Cid::new_v1( + fvm_ipld_encoding::DAG_CBOR, + Code::Blake2b256.digest(&bytes), + )) + } +} + +impl CidCborExt for Cid {} + #[cfg(test)] mod tests { use crate::utils::{digest, HashSize}; diff --git a/token-core/tcx-keystore/Cargo.toml b/token-core/tcx-keystore/Cargo.toml index 951801f5..49f748be 100644 --- a/token-core/tcx-keystore/Cargo.toml +++ b/token-core/tcx-keystore/Cargo.toml @@ -16,7 +16,7 @@ secp256k1 = { version = "=0.24.3", features = ["rand", "recovery"] } tiny-bip39 = "=1.0.0" bitcoin_hashes = "=0.11.0" uuid = { version = "=1.2.2", features = ["serde", "v4"] } -serde = { version = "=1.0.147", features = ["derive"] } +serde = { version = "=1.0.165", features = ["derive"] } serde_json = "=1.0.89" anyhow = { version = "=1.0.79", features = [] } regex = "=1.9.3" diff --git a/token-core/tcx-migration/Cargo.toml b/token-core/tcx-migration/Cargo.toml index 4b760f51..42314f61 100644 --- a/token-core/tcx-migration/Cargo.toml +++ b/token-core/tcx-migration/Cargo.toml @@ -33,7 +33,7 @@ prost-types = "=0.11.2" libc = "=0.2.140" log = "=0.4.17" serde_json = "=1.0.89" -serde = { version = "=1.0.147", features = ["derive"] } +serde = { version = "=1.0.165", features = ["derive"] } anyhow = { version = "=1.0.79", features = [] } lazy_static = "=1.4.0" hex = "=0.4.3" diff --git a/token-core/tcx-primitive/Cargo.toml b/token-core/tcx-primitive/Cargo.toml index ad3c655b..2da7e089 100644 --- a/token-core/tcx-primitive/Cargo.toml +++ b/token-core/tcx-primitive/Cargo.toml @@ -19,15 +19,15 @@ hex-literal = "=0.3.4" hex = "=0.4.3" lazy_static = "=1.4.0" anyhow = { version = "=1.0.79", features = [] } -serde = { version = "=1.0.147", features = ["derive"] } +serde = { version = "=1.0.165", features = ["derive"] } serde_json = "=1.0.89" tiny-bip39 = "=1.0.0" ed25519-bip32 = "=0.3.2" ed25519-dalek = "=2.1.0" blake2b_simd = "=1.0.1" -blst = "=0.3.3" -num-bigint = "=0.4.3" -num-traits = "=0.2.15" +blst = "=0.3.12" +num-bigint = "=0.4.6" +num-traits = "=0.2.19" sha2 = "=0.10.6" digest = "=0.10.6" hkdf = "=0.12.3" diff --git a/token-core/tcx-substrate/Cargo.toml b/token-core/tcx-substrate/Cargo.toml index d9d2c18e..e0c0138b 100644 --- a/token-core/tcx-substrate/Cargo.toml +++ b/token-core/tcx-substrate/Cargo.toml @@ -28,7 +28,7 @@ anyhow = { version = "=1.0.79", features = [] } #tweetnacl = "0.2.1" xsalsa20poly1305 = "=0.9.0" serde_json = "=1.0.89" -serde = { version = "=1.0.147", features = ["derive"] } +serde = { version = "=1.0.165", features = ["derive"] } base64 = "=0.13.1" scrypt = { version = "=0.10.0", default-features = false } regex = "=1.9.3" diff --git a/token-core/tcx-tron/Cargo.toml b/token-core/tcx-tron/Cargo.toml index 91c450c3..93e59d78 100644 --- a/token-core/tcx-tron/Cargo.toml +++ b/token-core/tcx-tron/Cargo.toml @@ -19,13 +19,13 @@ bitcoin = "=0.29.2" secp256k1 = {version = "=0.24.3", features = ["rand", "recovery"] } tiny-bip39 = "=1.0.0" bitcoin_hashes = "=0.11.0" -serde = { version = "=1.0.147", features = ["derive"] } +serde = { version = "=1.0.165", features = ["derive"] } serde_json = "=1.0.89" uuid = { version = "=1.2.2", features = ["serde", "v4"] } anyhow = { version = "=1.0.79", features = [] } -num-bigint = "=0.4.3" -num-traits = "=0.2.15" -num-integer = "=0.1.45" +num-bigint = "=0.4.6" +num-traits = "=0.2.19" +num-integer = "=0.1.46" byteorder = "=1.4.3" bytebuffer = "=0.2.1" hex = "=0.4.3" diff --git a/token-core/tcx/Cargo.toml b/token-core/tcx/Cargo.toml index d895c960..f9b015b9 100644 --- a/token-core/tcx/Cargo.toml +++ b/token-core/tcx/Cargo.toml @@ -31,7 +31,7 @@ prost-types = "=0.11.2" libc = "=0.2.140" log = "=0.4.17" serde_json = "=1.0.89" -serde = { version = "=1.0.147", features = ["derive"] } +serde = { version = "=1.0.165", features = ["derive"] } anyhow = { version = "=1.0.79", features = [] } lazy_static = "=1.4.0" hex = "=0.4.3"