diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index 16600be..491ea39 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -2,9 +2,11 @@ pub mod number; use hex::FromHexError; use hex::ToHex; -use kos::chains::{get_chain_by_base_id, Chain, ChainError, Transaction}; -use kos::crypto::cipher; +use kos::chains::{ + create_custom_evm, get_chain_by_base_id, Chain, ChainError, ChainOptions, Transaction, +}; use kos::crypto::cipher::CipherAlgo; +use kos::crypto::{base64, cipher}; uniffi::setup_scaffolding!(); @@ -49,6 +51,42 @@ struct KOSTransaction { pub signature: String, } +#[derive(uniffi::Enum)] +enum TransactionChainOptions { + Evm { + chain_id: u32, + network_type: u32, + }, + Btc { + prev_scripts: Vec>, + input_amounts: Vec, + }, +} + +#[uniffi::export] +fn new_bitcoin_transaction_options( + input_amounts: Vec, + prev_scripts: Vec, +) -> TransactionChainOptions { + let prev_scripts = prev_scripts + .iter() + .map(|s| base64::simple_base64_decode(s).unwrap_or_default()) + .collect(); + + TransactionChainOptions::Btc { + prev_scripts, + input_amounts, + } +} + +#[uniffi::export] +fn new_evm_transaction_options(chain_id: u32, network_type: u32) -> TransactionChainOptions { + TransactionChainOptions::Evm { + chain_id, + network_type, + } +} + #[uniffi::export] fn generate_mnemonic(size: i32) -> Result { Ok(kos::crypto::mnemonic::generate_mnemonic(size as usize)?.to_phrase()) @@ -136,14 +174,48 @@ fn get_chain_by(id: u32) -> Result, KOSError> { } #[uniffi::export] -fn sign_transaction(account: KOSAccount, raw: String) -> Result { - let chain = get_chain_by(account.chain_id)?; +fn sign_transaction( + account: KOSAccount, + raw: String, + options: Option, +) -> Result { + let options = match options { + Some(TransactionChainOptions::Evm { + chain_id, + network_type, + }) => Some(ChainOptions::EVM { + chain_id, + network_type, + }), + Some(TransactionChainOptions::Btc { + prev_scripts, + input_amounts, + }) => Some(ChainOptions::BTC { + prev_scripts, + input_amounts, + }), + None => None, + }; + + 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( + "Failed to create custom evm chain".to_string(), + ))?; + } + let raw_tx_bytes = hex::decode(raw.clone())?; + let transaction = Transaction { raw_data: raw_tx_bytes, signature: Vec::new(), tx_hash: Vec::new(), - options: None, + options, }; let pk = hex::decode(account.private_key.clone())?; @@ -374,9 +446,9 @@ mod tests { 0, false, ) - .unwrap(); + .unwrap(); - let transaction = sign_transaction(account, raw.to_string()).unwrap(); + let transaction = sign_transaction(account, raw.to_string(), None).unwrap(); assert_eq!(transaction.chain_id, chain_id, "The chain_id doesn't match"); assert_eq!( diff --git a/packages/kos/src/chains/mod.rs b/packages/kos/src/chains/mod.rs index 3c3397d..810b43c 100644 --- a/packages/kos/src/chains/mod.rs +++ b/packages/kos/src/chains/mod.rs @@ -363,7 +363,7 @@ impl ChainRegistry { constants::BTC, ChainInfo { factory: || Box::new(btc::BTC::new()), - supported: false, + supported: true, }, ), ( @@ -384,7 +384,7 @@ impl ChainRegistry { constants::LTC, ChainInfo { factory: || Box::new(btc::BTC::new_btc_based(5, "ltc", "LTC", "Litecoin")), - supported: false, + supported: true, }, ), ( @@ -419,7 +419,7 @@ impl ChainRegistry { constants::SYS, ChainInfo { factory: || Box::new(btc::BTC::new_btc_based(15, "sys", "SYS", "Syscoin")), - supported: false, + supported: true, }, ), ( @@ -463,7 +463,7 @@ impl ChainRegistry { constants::DGB, ChainInfo { factory: || Box::new(btc::BTC::new_btc_based(16, "dgb", "DGB", "Digibyte")), - supported: false, + supported: true, }, ), ( @@ -703,6 +703,15 @@ impl ChainRegistry { } ids } + + fn create_custom_evm(&self, chain_id: u32, _network_type: u32) -> Option> { + Some(Box::new(eth::ETH::new_eth_based( + 0, + chain_id, + format!("ETH {}", chain_id).as_str(), + format!("Eth Based {}", chain_id).as_str(), + ))) + } } pub fn get_chain_by_id(id: u32) -> Option> { @@ -745,3 +754,7 @@ pub fn is_chain_supported(id: u32) -> bool { 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) +}