From 30ee8328cf4d84d1ca8c4bf3fa9802ec45808edc Mon Sep 17 00:00:00 2001 From: Gustavo Britto Date: Thu, 16 Jan 2025 11:58:52 -0300 Subject: [PATCH 1/4] update chainid type to uint32 in test file (#83) --- .../KOSMobile/KOSMobileTests/KOSMobileTests.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/kos-mobile/ios/framework/KOSMobile/KOSMobileTests/KOSMobileTests.swift b/packages/kos-mobile/ios/framework/KOSMobile/KOSMobileTests/KOSMobileTests.swift index fa884a6..5fcaf44 100644 --- a/packages/kos-mobile/ios/framework/KOSMobile/KOSMobileTests/KOSMobileTests.swift +++ b/packages/kos-mobile/ios/framework/KOSMobile/KOSMobileTests/KOSMobileTests.swift @@ -51,19 +51,19 @@ final class KOSMobileTests: XCTestCase { let cfbDecryptedData = try! decrypt(data: cfbEncryptedData, password: password) XCTAssertEqual(dataToEncrypt, cfbDecryptedData) - let walletFromMnemonic = try! generateWalletFromMnemonic(mnemonic: mnemonic, chainId: klvChainId, index: 0, useLegacyPath: false) - XCTAssertEqual(klvChainId, walletFromMnemonic.chainId) + let walletFromMnemonic = try! generateWalletFromMnemonic(mnemonic: mnemonic, chainId: UInt32(klvChainId), index: 0, useLegacyPath: false) + XCTAssertEqual(UInt32(klvChainId), walletFromMnemonic.chainId) XCTAssertEqual(klvPk0, walletFromMnemonic.privateKey) XCTAssertEqual(klvAddr0, walletFromMnemonic.address) XCTAssertEqual(klvPath0, walletFromMnemonic.path) XCTAssertEqual(klvKey0, walletFromMnemonic.publicKey) - let walletFromPk = try! generateWalletFromPrivateKey(chainId: klvChainId, privateKey: klvPk0) - XCTAssertEqual(klvChainId, walletFromPk.chainId) + let walletFromPk = try! generateWalletFromPrivateKey(chainId: UInt32(klvChainId), privateKey: klvPk0) + XCTAssertEqual(UInt32(klvChainId), walletFromPk.chainId) XCTAssertEqual(klvPk0, walletFromPk.privateKey) XCTAssertEqual(klvAddr0, walletFromPk.address) XCTAssertEqual("", walletFromPk.path) XCTAssertEqual(klvKey0, walletFromPk.publicKey) } -} \ No newline at end of file +} From befcc82bfc154d88b1196e71e0733c55511b3d4e Mon Sep 17 00:00:00 2001 From: Pedro Camboim <72642597+pedrxlz@users.noreply.github.com> Date: Thu, 16 Jan 2025 12:07:15 -0300 Subject: [PATCH 2/4] Fix/substrate path derivation (#82) * feat: evm custom network * chore: bump version * fix: susbtrate path derivation --- packages/kos/src/chains/substrate/mod.rs | 13 +++++++++++++ packages/kos/src/crypto/bip32.rs | 8 ++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/kos/src/chains/substrate/mod.rs b/packages/kos/src/chains/substrate/mod.rs index 676086b..93434eb 100644 --- a/packages/kos/src/chains/substrate/mod.rs +++ b/packages/kos/src/chains/substrate/mod.rs @@ -159,6 +159,19 @@ mod test { let addr = dot.get_address(pbk).unwrap(); assert_eq!(addr, "13KVd4f2a4S5pLp4gTTFezyXdPWx27vQ9vS6xBXJ9yWVd7xo"); } + #[test] + fn test_get_addr1() { + let dot = super::Substrate::new(62, 42, "AVAIL", "Avail"); + + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + let path = dot.get_path(1, false); + + let seed = dot.mnemonic_to_seed(mnemonic, String::from("")).unwrap(); + let pvk = dot.derive(seed, path).unwrap(); + let pbk = dot.get_pbk(pvk).unwrap(); + let addr = dot.get_address(pbk).unwrap(); + assert_eq!(addr, "5DJ8y4CAHnmjt4rdoZpR1wgXnQDnKDksskx7JTphZhMxthiG"); + } #[test] fn test_sign_raw() { diff --git a/packages/kos/src/crypto/bip32.rs b/packages/kos/src/crypto/bip32.rs index 419f0c3..7301227 100644 --- a/packages/kos/src/crypto/bip32.rs +++ b/packages/kos/src/crypto/bip32.rs @@ -205,10 +205,10 @@ pub fn derive_sr25519(input_key: &[u8], mut path: String) -> Result<[u8; 64], Bi .strip_prefix("//") .ok_or(Bip32Err::PathError)? .to_string(); - path = path - .strip_suffix("///") - .ok_or(Bip32Err::PathError)? - .to_string(); + + if let Some(stripped) = path.strip_suffix("///") { + path = stripped.to_string(); + } let chaincode_value = u8::from_str(path.as_str()).map_err(|_| Bip32Err::PathError)?; From c94537521b286be956e20f94d99a02edce0c7879 Mon Sep 17 00:00:00 2001 From: Pedro Camboim <72642597+pedrxlz@users.noreply.github.com> Date: Tue, 21 Jan 2025 15:41:19 -0300 Subject: [PATCH 3/4] fix: android test (#84) * fix: android test * feat: adjust signature v value by adding 27 to comply with EVM standards * chore: disable BTC based chains for now * fix: android test * fix lib loading --------- Co-authored-by: Jordan --- .../kos-mobile/android/lib/build.gradle.kts | 7 +-- .../test/kotlin/uniffi/kos_mobile/KOSTest.kt | 6 +-- packages/kos-mobile/src/lib.rs | 44 +++++++++++-------- packages/kos/src/chains/eth/mod.rs | 13 +++++- packages/kos/src/chains/mod.rs | 13 +++--- 5 files changed, 45 insertions(+), 38 deletions(-) diff --git a/packages/kos-mobile/android/lib/build.gradle.kts b/packages/kos-mobile/android/lib/build.gradle.kts index f04208d..9fd6331 100644 --- a/packages/kos-mobile/android/lib/build.gradle.kts +++ b/packages/kos-mobile/android/lib/build.gradle.kts @@ -34,12 +34,7 @@ android { } dependencies { - implementation(libs.java.jna) { - artifact { - extension ="aar" - type = "aar" - } - } + implementation(libs.java.jna) testImplementation(libs.junit) } diff --git a/packages/kos-mobile/android/lib/src/test/kotlin/uniffi/kos_mobile/KOSTest.kt b/packages/kos-mobile/android/lib/src/test/kotlin/uniffi/kos_mobile/KOSTest.kt index 0f102b0..ba0b5dc 100644 --- a/packages/kos-mobile/android/lib/src/test/kotlin/uniffi/kos_mobile/KOSTest.kt +++ b/packages/kos-mobile/android/lib/src/test/kotlin/uniffi/kos_mobile/KOSTest.kt @@ -6,13 +6,11 @@ import org.junit.Assert.assertTrue import org.junit.Test class KOSTest { - @Test fun testKOS() { - val dataToEncrypt = "Hello" val password = "password" - val klvChainId = 38 + val klvChainId: UInt = 38u val mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" val klvPk0 = "8734062c1158f26a3ca8a4a0da87b527a7c168653f7f4c77045e5cf571497d9d" @@ -51,7 +49,7 @@ class KOSTest { val cfbDecryptedData = decrypt(cfbEncryptedData, password) assertEquals(dataToEncrypt, cfbDecryptedData) - val walletFromMnemonic = generateWalletFromMnemonic(mnemonic, klvChainId, 0, false) + val walletFromMnemonic = generateWalletFromMnemonic(mnemonic, klvChainId, 0u, false) assertEquals(klvChainId, walletFromMnemonic.chainId) assertEquals(klvPk0, walletFromMnemonic.privateKey) assertEquals(klvAddr0, walletFromMnemonic.address) diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index 491ea39..5e7973c 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -55,7 +55,6 @@ struct KOSTransaction { enum TransactionChainOptions { Evm { chain_id: u32, - network_type: u32, }, Btc { prev_scripts: Vec>, @@ -80,11 +79,8 @@ fn new_bitcoin_transaction_options( } #[uniffi::export] -fn new_evm_transaction_options(chain_id: u32, network_type: u32) -> TransactionChainOptions { - TransactionChainOptions::Evm { - chain_id, - network_type, - } +fn new_evm_transaction_options(chain_id: u32) -> TransactionChainOptions { + TransactionChainOptions::Evm { chain_id } } #[uniffi::export] @@ -180,13 +176,7 @@ fn sign_transaction( options: Option, ) -> Result { let options = match options { - Some(TransactionChainOptions::Evm { - chain_id, - network_type, - }) => Some(ChainOptions::EVM { - chain_id, - network_type, - }), + Some(TransactionChainOptions::Evm { chain_id }) => Some(ChainOptions::EVM { chain_id }), Some(TransactionChainOptions::Btc { prev_scripts, input_amounts, @@ -199,12 +189,8 @@ fn sign_transaction( let mut chain = get_chain_by(account.chain_id)?; - if let Some(ChainOptions::EVM { - chain_id, - network_type, - }) = options - { - chain = create_custom_evm(chain_id, network_type).ok_or(KOSError::KOSDelegate( + if let Some(ChainOptions::EVM { chain_id }) = options { + chain = create_custom_evm(chain_id).ok_or(KOSError::KOSDelegate( "Failed to create custom evm chain".to_string(), ))?; } @@ -465,6 +451,26 @@ mod tests { ); } + #[test] + fn should_sign_transaction_with_options() { + let chain_id = 61; + let raw = + "b302f101819e84ae7937b285035f6cccc58252089498de4c83810b87f0e2cd92d80c9fac28c4ded4818568c696991f80c0808080"; + + let account = generate_wallet_from_mnemonic( + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(), + chain_id, + 0, + false, + ) + .unwrap(); + + let options = new_evm_transaction_options(88888); + let transaction = sign_transaction(account, raw.to_string(), Some(options)).unwrap(); + + assert_eq!(transaction.raw, "02f87101819e84ae7937b285035f6cccc58252089498de4c83810b87f0e2cd92d80c9fac28c4ded4818568c696991f80c001a044c69f41bf47ad50dc98c74af68811384c9172055b01fcaa39e70f53df69b632a05e071cf1f9e12500b525f03a29f567520e1ea49a97e6a29d1fd432dc6303353e", "The raw doesn't match"); + } + #[test] fn should_sign_message() { let chain_id = 38; diff --git a/packages/kos/src/chains/eth/mod.rs b/packages/kos/src/chains/eth/mod.rs index a290c74..9b8c08d 100644 --- a/packages/kos/src/chains/eth/mod.rs +++ b/packages/kos/src/chains/eth/mod.rs @@ -149,7 +149,12 @@ impl Chain for ETH { if let Ok(data) = std::str::from_utf8(&message) { if let Ok(typed_data) = serde_json::from_str::(data) { let digest = typed_data.eip712_signing_hash().unwrap(); - return self.sign_raw(private_key, digest.to_vec()); + let mut sig = self.sign_raw(private_key, digest.to_vec())?; + + let last_index = sig.len() - 1; + sig[last_index] += 27; + + return Ok(sig); } } } @@ -161,7 +166,11 @@ impl Chain for ETH { ] .concat(); let hashed = keccak256_digest(&to_sign[..]); - let signature = self.sign_raw(private_key, hashed.to_vec())?; + let mut signature = self.sign_raw(private_key, hashed.to_vec())?; + + let last_index = signature.len() - 1; + signature[last_index] += 27; + Ok(signature) } diff --git a/packages/kos/src/chains/mod.rs b/packages/kos/src/chains/mod.rs index 810b43c..d49149a 100644 --- a/packages/kos/src/chains/mod.rs +++ b/packages/kos/src/chains/mod.rs @@ -258,7 +258,6 @@ pub struct Transaction { pub enum ChainOptions { EVM { chain_id: u32, - network_type: u32, }, BTC { prev_scripts: Vec>, @@ -384,7 +383,7 @@ impl ChainRegistry { constants::LTC, ChainInfo { factory: || Box::new(btc::BTC::new_btc_based(5, "ltc", "LTC", "Litecoin")), - supported: true, + supported: false, }, ), ( @@ -419,7 +418,7 @@ impl ChainRegistry { constants::SYS, ChainInfo { factory: || Box::new(btc::BTC::new_btc_based(15, "sys", "SYS", "Syscoin")), - supported: true, + supported: false, }, ), ( @@ -463,7 +462,7 @@ impl ChainRegistry { constants::DGB, ChainInfo { factory: || Box::new(btc::BTC::new_btc_based(16, "dgb", "DGB", "Digibyte")), - supported: true, + supported: false, }, ), ( @@ -704,7 +703,7 @@ impl ChainRegistry { ids } - fn create_custom_evm(&self, chain_id: u32, _network_type: u32) -> Option> { + fn create_custom_evm(&self, chain_id: u32) -> Option> { Some(Box::new(eth::ETH::new_eth_based( 0, chain_id, @@ -755,6 +754,6 @@ pub fn get_supported_chains() -> Vec { ChainRegistry::new().get_supported_chains() } -pub fn create_custom_evm(chain_id: u32, network_type: u32) -> Option> { - ChainRegistry::new().create_custom_evm(chain_id, network_type) +pub fn create_custom_evm(chain_id: u32) -> Option> { + ChainRegistry::new().create_custom_evm(chain_id) } From 2971206e9e9d065a4749a92049acd923e70bc650 Mon Sep 17 00:00:00 2001 From: Pedro Camboim <72642597+pedrxlz@users.noreply.github.com> Date: Tue, 21 Jan 2025 16:17:06 -0300 Subject: [PATCH 4/4] Bump version 0.2.2 (#85) * chore: bump version * chore: update README --- Cargo.lock | 6 +++--- Cargo.toml | 4 ++-- README.md | 63 ++++++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 59 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 814b7f1..7bd799e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1628,7 +1628,7 @@ dependencies = [ [[package]] name = "kos" -version = "0.2.0" +version = "0.2.2" dependencies = [ "aes", "aes-gcm", @@ -1670,7 +1670,7 @@ dependencies = [ [[package]] name = "kos-mobile" -version = "0.2.0" +version = "0.2.2" dependencies = [ "hex", "kos", @@ -1684,7 +1684,7 @@ dependencies = [ [[package]] name = "kos-web" -version = "0.2.0" +version = "0.2.2" dependencies = [ "enum_delegate", "enum_dispatch", diff --git a/Cargo.toml b/Cargo.toml index d3ce274..a988899 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ homepage = "https://klever.org/" license = "Apache-2.0" repository = "https://github.com/kleverio/kos-rs" rust-version = "1.69.0" -version = "0.2.0" +version = "0.2.2" [workspace.dependencies] bech32 = "0.9.1" @@ -50,5 +50,5 @@ log = "0.4" lazy_static = "1.4.0" thiserror = "1.0" -kos = { version = "0.2.0", path = "./packages/kos", default-features = false } +kos = { version = "0.2.2", path = "./packages/kos", default-features = false } kos-mobile = { version = "0.1.0", path = "./packages/kos-mobile", default-features = false } diff --git a/README.md b/README.md index 3a00b64..3bad6bc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Klever Wallet Library for Rust (kos-rs) -kos-rs is an open-source library crafted to deliver fundamental low-level crypto-wallet capabilities for blockchain actions and transactions. Built with Rust, it ensures top-tier security and versatile platform adaptability, positioning it as a premier choice for constructing secure and high-performing blockchain solutions. +kos-rs is an open-source library crafted to deliver fundamental low-level crypto-wallet capabilities for blockchain +actions and transactions. Built with Rust, it ensures top-tier security and versatile platform adaptability, positioning +it as a premier choice for constructing secure and high-performing blockchain solutions. #### KleverOS, which stands for Klever Wallet Ops Security, is a robust library meticulously crafted in Rust to guarantee the utmost security in private key generation while ensuring unparalleled auditability. @@ -19,6 +21,50 @@ kos-rs is an open-source library crafted to deliver fundamental low-level crypto - [x] Tron (TRX) - [x] Klever (KLV) - [x] Polygon (Matic) +- [x] Binance Smart Chain (BSC) +- [x] Huobi Token (HT) +- [x] Syscoin NEVM (SYS_NEVM) +- [x] Polkadot (DOT) +- [x] Kusama (KSM) +- [x] Reef (REEF) +- [x] Shiden (SDN) +- [x] Astar (ASTR) +- [x] Centrifuge (CFG) +- [x] KILT +- [x] Altair +- [x] Moonriver (MOVR) +- [x] Moonbeam (GLMR) +- [x] Sui (SUI) +- [x] Avail (AVAIL) +- [x] Rollux +- [x] Avalanche (AVAX) +- [x] Arbitrum (ARB) +- [x] Base +- [x] Near (NEAR) +- [x] Fantom (FTM) +- [x] Chiliz (CHZ) +- [x] Optimism (OP) +- [x] Polygon zkEVM +- [x] Stolz + +#### Coming soon | Under development: + +- Litecoin (LTC) +- Syscoin (SYS) +- Dogecoin (DOGE) +- Dash +- XRP +- Digibyte (DGB) +- Cosmos (ATOM) +- Celestia (TIA) +- Cudos +- Aura +- Internet Computer (ICP) +- Solana (SOL) +- BNB Chain +- Bitcoin Cash (BCH) +- Cardano (ADA) +- Aptos (APT) ## Getting Started with Javascript and Node.js @@ -43,24 +89,23 @@ To add kos-rs to your Rust project, simply include it as a dependency in your `C kos-rs = "0.1" ``` - ## Project Directory Structure - `Makefile`: Main project build and automation configuration. -- `demo/`: JavaScript demo page with instructions on how to use the `kos-rs` library in web applications. ### Packages (Monorepo) -- `packages/kos/`: Contains tools and utilities for exporting WebAssembly, designed for use in WebAssembly operations. -- `packages/kos-crypto/`: Cryptographic package with support for crypto curves for transaction signing, including asymmetric and symmetric cryptography. -- `packages/kos-proto/`: Library for building protocol messages. -- `packages/kos-sdk/`: Package for blockchain integration, wallet management, transaction construction, and signing implementations. -- `packages/kos-types/`: Package containing complex data types and helpful utilities. -- `packages/kos-utils/`: Package with utility libraries for various purposes. +- `packages/kos/`: Core package implementing all cryptocurrency wallet operations, including cryptographic functions, + curves, and basic offline wallet operations for each blockchain. +- `packages/kos-web/`: Package responsible for exporting kos functionality to JavaScript bindings, providing methods + for web-based implementations. +- `packages/kos-mobile/`: Package responsible for exporting kos functionality to mobile platforms, providing bindings + for both iOS (Swift) and Android (Kotlin). --- ## Apps powered by kos-rs + The kos-rs library powers several key applications within the Klever ecosystem: - [Klever Wallet for iOS](https://apps.apple.com/uy/app/klever-wallet-bitcoin-crypto/id1615064243)