From 9959aa887f54e2f55075cc3f52a61be19b7e67fb Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Fri, 30 Aug 2024 19:45:28 -0300 Subject: [PATCH 01/15] chore: Transaction from raw --- packages/kos-sdk/src/chains/tron/requests.rs | 1 + packages/kos-sdk/src/models.rs | 87 +++++++++++++++++++- 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/packages/kos-sdk/src/chains/tron/requests.rs b/packages/kos-sdk/src/chains/tron/requests.rs index abea6f8..9c7dced 100644 --- a/packages/kos-sdk/src/chains/tron/requests.rs +++ b/packages/kos-sdk/src/chains/tron/requests.rs @@ -2,6 +2,7 @@ use crate::utils; use kos_types::error::Error; use serde::Serialize; use serde_json::json; +use kos_proto::tron::TransferContract; #[derive(Serialize)] pub struct ContractOptions { diff --git a/packages/kos-sdk/src/models.rs b/packages/kos-sdk/src/models.rs index a9be80d..4be927d 100644 --- a/packages/kos-sdk/src/models.rs +++ b/packages/kos-sdk/src/models.rs @@ -1,9 +1,11 @@ +use pbjson::private::base64; // use crate::klever; use kos_types::{error::Error, hash::Hash}; use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; use crate::chain::Chain; +use crate::chain::Chain::KLV; #[derive(Debug, Clone, Serialize)] #[wasm_bindgen] @@ -185,7 +187,6 @@ impl Transaction { } } } - impl Transaction { pub fn new_data(&self, chain: Chain, data: TransactionRaw) -> Transaction { let mut tx = self.clone(); @@ -195,6 +196,66 @@ impl Transaction { } } +#[wasm_bindgen] +impl Transaction { + #[wasm_bindgen(js_name = fromRaw)] + pub fn from_raw(chain: Chain, data: &str) -> Self { + let mut sender = String::default(); + + let data = match chain { + Chain::KLV => { + let tx: kos_proto::klever::Transaction = + serde_json::from_str(data).expect("failed to parse klever transaction"); + + // unwrap raw_data + let raw_data = tx + .raw_data + .clone() + .ok_or_else(|| Error::InvalidTransaction("no raw TX found".to_string())).unwrap(); + + sender = String::default(); + TransactionRaw::Klever(tx) + } + Chain::TRX => { + let tx: kos_proto::tron::Transaction = + serde_json::from_str(data).unwrap(); + + let raw_data = &tx.clone().raw_data.unwrap().contract[0]; + + let value = &raw_data.parameter.clone().unwrap().value; + + + sender = String::default(); + TransactionRaw::Tron(tx) + } + + Chain::ETH => { + let data: super::chains::ETHTransaction = + serde_json::from_str(data).expect("failed to parse ethereum transaction"); + TransactionRaw::Ethereum(data) + } + Chain::MATIC => { + todo!("decode polygon transaction") + } + Chain::BTC => { + todo!("decode bitcoin transaction") + } + Chain::NONE => { + panic!("invalid chain") + } + }; + + let hash = Hash::default(); + + Self { + chain, + sender, + hash, + data: Some(data), + } + } +} + #[derive(Default, Debug, Clone, Serialize, Deserialize)] #[wasm_bindgen] pub struct AddressOptions { @@ -250,3 +311,27 @@ impl AddressOptions { self.check_summed } } + +// Test Transaction from raw +#[cfg(test)] +mod tests { + use super::*; + use crate::chains::ETHTransaction; + use kos_proto::klever::Transaction as KleverTransaction; + use kos_proto::tron::Transaction as TronTransaction; + use serde_json::json; + use web3::ethabi::ParamType::String; + + #[test] + fn test_transaction_from_raw() { + + + let tron_tx_str = r#"{"raw_data":{"ref_block_bytes":"ceda","ref_block_hash":"55821ec130fa833c","expiration":1725055080000,"contract":[{"type":"TransferContract","parameter":{"typeUrl":"type.googleapis.com/protocol.TransferContract","value":"ChVBBYOmijvNhsJasb7kgrrASiFrAmESFUHIWZER8pweHgYSZbSvk+ofJ0rXihgK"}}],"timestamp":1725055023434}}"#; + let klv_tx_str = r#"{"RawData":{"Nonce":312,"Sender":"nxNUcG11rraE8m196h+9oX4mTHWVzB7d7AuJaMG+hSQ=","Contract":[{"Parameter":{"type_url":"type.googleapis.com/proto.TransferContract","value":"CiCthZSJePbX7pPJ64gh6PZ+HBo1YPZddPMYyYs/+aLSMxIDS0xWGMCEPQ=="}}],"Data":[""],"KAppFee":1000000,"BandwidthFee":2000000,"Version":1,"ChainID":"MTA4"}}"#; + + let tx = Transaction::from_raw(Chain::TRX, tron_tx_str); + + assert_eq!(tx.chain, Chain::TRX); + + } +} From 3c728d882ebb640ae71590c151bafeb43fc6774e Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Fri, 30 Aug 2024 20:59:50 -0300 Subject: [PATCH 02/15] feat: transaction from raw (KLV and TRX) --- packages/kos-sdk/src/chains/klever/mod.rs | 5 ++++ packages/kos-sdk/src/chains/tron/mod.rs | 5 ++++ packages/kos-sdk/src/models.rs | 32 ++++++++++++++--------- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/packages/kos-sdk/src/chains/klever/mod.rs b/packages/kos-sdk/src/chains/klever/mod.rs index fdacad9..1dc53d9 100644 --- a/packages/kos-sdk/src/chains/klever/mod.rs +++ b/packages/kos-sdk/src/chains/klever/mod.rs @@ -68,6 +68,11 @@ impl KLV { Ok(address::Address::from_keypair(keypair).to_string()) } + pub fn address_from_bytes(bytes: &[u8]) -> Result { + let address = address::Address::from_bytes(bytes); + Ok(address.to_string()) + } + #[wasm_bindgen(js_name = "getPath")] pub fn get_path(options: &PathOptions) -> Result { Ok(format!("m/44'/{}'/0'/0'/{}'", BIP44_PATH, options.index)) diff --git a/packages/kos-sdk/src/chains/tron/mod.rs b/packages/kos-sdk/src/chains/tron/mod.rs index 0a0eafa..4adba0e 100644 --- a/packages/kos-sdk/src/chains/tron/mod.rs +++ b/packages/kos-sdk/src/chains/tron/mod.rs @@ -81,6 +81,11 @@ impl TRX { Ok(address::Address::from_keypair(kp).to_string()) } + pub fn address_from_bytes(bytes: &[u8]) -> Result { + let addr = address::Address::from_bytes(bytes); + Ok(addr.to_string()) + } + #[wasm_bindgen(js_name = "getPath")] pub fn get_path(options: &PathOptions) -> Result { let index = options.index; diff --git a/packages/kos-sdk/src/models.rs b/packages/kos-sdk/src/models.rs index 4be927d..e366b77 100644 --- a/packages/kos-sdk/src/models.rs +++ b/packages/kos-sdk/src/models.rs @@ -3,9 +3,9 @@ use pbjson::private::base64; use kos_types::{error::Error, hash::Hash}; use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; - +use kos_proto::tron; use crate::chain::Chain; -use crate::chain::Chain::KLV; +use crate::chains::{KLV, TRX}; #[derive(Debug, Clone, Serialize)] #[wasm_bindgen] @@ -213,19 +213,22 @@ impl Transaction { .clone() .ok_or_else(|| Error::InvalidTransaction("no raw TX found".to_string())).unwrap(); - sender = String::default(); + sender = KLV::address_from_bytes(&raw_data.sender).unwrap(); TransactionRaw::Klever(tx) } Chain::TRX => { - let tx: kos_proto::tron::Transaction = - serde_json::from_str(data).unwrap(); - - let raw_data = &tx.clone().raw_data.unwrap().contract[0]; + let raw_data_bytes = hex::decode(data).unwrap().clone(); + let raw_data: kos_proto::tron::transaction::Raw = kos_proto::from_bytes(raw_data_bytes).unwrap(); - let value = &raw_data.parameter.clone().unwrap().value; + let parameter: kos_proto::tron::TransferContract = kos_proto::unpack_from_option_any(&raw_data.contract[0].parameter).unwrap(); + let tx = kos_proto::tron::Transaction { + raw_data: Some(raw_data), + signature: Vec::new(), + ret: Vec::new(), + }; - sender = String::default(); + sender = TRX::address_from_bytes(parameter.owner_address.as_slice()).unwrap(); TransactionRaw::Tron(tx) } @@ -325,13 +328,16 @@ mod tests { #[test] fn test_transaction_from_raw() { - - let tron_tx_str = r#"{"raw_data":{"ref_block_bytes":"ceda","ref_block_hash":"55821ec130fa833c","expiration":1725055080000,"contract":[{"type":"TransferContract","parameter":{"typeUrl":"type.googleapis.com/protocol.TransferContract","value":"ChVBBYOmijvNhsJasb7kgrrASiFrAmESFUHIWZER8pweHgYSZbSvk+ofJ0rXihgK"}}],"timestamp":1725055023434}}"#; let klv_tx_str = r#"{"RawData":{"Nonce":312,"Sender":"nxNUcG11rraE8m196h+9oX4mTHWVzB7d7AuJaMG+hSQ=","Contract":[{"Parameter":{"type_url":"type.googleapis.com/proto.TransferContract","value":"CiCthZSJePbX7pPJ64gh6PZ+HBo1YPZddPMYyYs/+aLSMxIDS0xWGMCEPQ=="}}],"Data":[""],"KAppFee":1000000,"BandwidthFee":2000000,"Version":1,"ChainID":"MTA4"}}"#; + let klv_tx = Transaction::from_raw(Chain::KLV, klv_tx_str); + + assert_eq!(klv_tx.sender, "klv1nuf4gurdwkhtdp8jd47758aa59lzvnr4jhxpah0vpwyk3sd7s5jqy6mut7"); + + let tron_tx_str = "0a02d8372208e9c73b516bcd78844088c6e8ad9a325a67080112630a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412320a1541e825d52582eec346c839b4875376117904a76cbc12154120ab1300cf70c048e4cf5d5b1b33f59653ed662618c0843d70fdfee4ad9a32"; - let tx = Transaction::from_raw(Chain::TRX, tron_tx_str); + let tron_tx = Transaction::from_raw(Chain::TRX, tron_tx_str); - assert_eq!(tx.chain, Chain::TRX); + assert_eq!(tron_tx.sender, "TX8h6Df74VpJsXF6sTDz1QJsq3Ec8dABc3"); } } From 51ebf1bea104e69d85c3edf9cf5451132581a25d Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Fri, 30 Aug 2024 21:22:37 -0300 Subject: [PATCH 03/15] feat: transaction from raw (ETH) --- packages/kos-sdk/src/models.rs | 36 +++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/packages/kos-sdk/src/models.rs b/packages/kos-sdk/src/models.rs index e366b77..07bfadc 100644 --- a/packages/kos-sdk/src/models.rs +++ b/packages/kos-sdk/src/models.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; use kos_proto::tron; use crate::chain::Chain; -use crate::chains::{KLV, TRX}; +use crate::chains::{ETH, KLV, TRX}; #[derive(Debug, Clone, Serialize)] #[wasm_bindgen] @@ -201,18 +201,19 @@ impl Transaction { #[wasm_bindgen(js_name = fromRaw)] pub fn from_raw(chain: Chain, data: &str) -> Self { let mut sender = String::default(); + let mut hash = Hash::default(); let data = match chain { Chain::KLV => { let tx: kos_proto::klever::Transaction = serde_json::from_str(data).expect("failed to parse klever transaction"); - // unwrap raw_data let raw_data = tx .raw_data .clone() .ok_or_else(|| Error::InvalidTransaction("no raw TX found".to_string())).unwrap(); + hash = Hash::from_vec(KLV::hash_transaction(&tx).unwrap()).unwrap(); sender = KLV::address_from_bytes(&raw_data.sender).unwrap(); TransactionRaw::Klever(tx) } @@ -228,14 +229,27 @@ impl Transaction { ret: Vec::new(), }; + hash = Hash::from_vec(TRX::hash_transaction(&tx).unwrap()).unwrap(); + sender = TRX::address_from_bytes(parameter.owner_address.as_slice()).unwrap(); + TransactionRaw::Tron(tx) } Chain::ETH => { - let data: super::chains::ETHTransaction = + let tx: super::chains::ETHTransaction = serde_json::from_str(data).expect("failed to parse ethereum transaction"); - TransactionRaw::Ethereum(data) + + let bytes = tx.encode()?; + let digest = ETH::hash(&bytes)?; + hash = Hash::from_vec(digest)?; + + sender = match tx.from { + Some(addr) => addr.to_string(), + None => "".to_string(), + }; + + TransactionRaw::Ethereum(tx) } Chain::MATIC => { todo!("decode polygon transaction") @@ -248,7 +262,6 @@ impl Transaction { } }; - let hash = Hash::default(); Self { chain, @@ -329,6 +342,7 @@ mod tests { fn test_transaction_from_raw() { let klv_tx_str = r#"{"RawData":{"Nonce":312,"Sender":"nxNUcG11rraE8m196h+9oX4mTHWVzB7d7AuJaMG+hSQ=","Contract":[{"Parameter":{"type_url":"type.googleapis.com/proto.TransferContract","value":"CiCthZSJePbX7pPJ64gh6PZ+HBo1YPZddPMYyYs/+aLSMxIDS0xWGMCEPQ=="}}],"Data":[""],"KAppFee":1000000,"BandwidthFee":2000000,"Version":1,"ChainID":"MTA4"}}"#; + let klv_tx = Transaction::from_raw(Chain::KLV, klv_tx_str); assert_eq!(klv_tx.sender, "klv1nuf4gurdwkhtdp8jd47758aa59lzvnr4jhxpah0vpwyk3sd7s5jqy6mut7"); @@ -339,5 +353,17 @@ mod tests { assert_eq!(tron_tx.sender, "TX8h6Df74VpJsXF6sTDz1QJsq3Ec8dABc3"); + let eth_tx_str = r#"{ + "from":"0x4cbeee256240c92a9ad920ea6f4d7df6466d2cdc", + "maxPriorityFeePerGas":null,"maxFeePerGas":null, + "gas": "0x00", + "value": "0x00", + "data":"0xa9059cbb000000000000000000000000ac4145fef6c828e8ae017207ad944c988ccb2cf700000000000000000000000000000000000000000000000000000000000f4240", + "to":"0xdac17f958d2ee523a2206206994597c13d831ec7", + "nonce":"0x00"}"#; + + let eth_tx = Transaction::from_raw(Chain::ETH, eth_tx_str); + + assert_eq!(eth_tx.sender, "0x4cbeee256240c92a9ad920ea6f4d7df6466d2cdc"); } } From 0dfaa37e03dd6b2294559840523375373f258a68 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Fri, 30 Aug 2024 21:44:53 -0300 Subject: [PATCH 04/15] chore: adjust implementation --- packages/kos-sdk/src/chains/tron/mod.rs | 26 ++++++ packages/kos-sdk/src/chains/tron/requests.rs | 1 - packages/kos-sdk/src/models.rs | 90 +++----------------- 3 files changed, 40 insertions(+), 77 deletions(-) diff --git a/packages/kos-sdk/src/chains/tron/mod.rs b/packages/kos-sdk/src/chains/tron/mod.rs index 4adba0e..9c22367 100644 --- a/packages/kos-sdk/src/chains/tron/mod.rs +++ b/packages/kos-sdk/src/chains/tron/mod.rs @@ -410,6 +410,32 @@ impl TRX { let bytes = kos_proto::write_message(&raw_data); Ok(hex::encode(bytes)) } + + pub fn tx_from_raw(data: &str) -> Result { + let raw_data_bytes = hex::decode(data).unwrap().clone(); + let raw_data: kos_proto::tron::transaction::Raw = + kos_proto::from_bytes(raw_data_bytes).unwrap(); + + let parameter: kos_proto::tron::TransferContract = + kos_proto::unpack_from_option_any(&raw_data.contract[0].parameter).unwrap(); + + let tx = kos_proto::tron::Transaction { + raw_data: Some(raw_data), + signature: Vec::new(), + ret: Vec::new(), + }; + + let hash = Hash::from_vec(TRX::hash_transaction(&tx).unwrap()).unwrap(); + + let sender = TRX::address_from_bytes(parameter.owner_address.as_slice()).unwrap(); + + Ok(Transaction { + chain: chain::Chain::TRX, + sender, + hash, + data: Some(TransactionRaw::Tron(tx)), + }) + } } #[cfg(test)] diff --git a/packages/kos-sdk/src/chains/tron/requests.rs b/packages/kos-sdk/src/chains/tron/requests.rs index 9c7dced..abea6f8 100644 --- a/packages/kos-sdk/src/chains/tron/requests.rs +++ b/packages/kos-sdk/src/chains/tron/requests.rs @@ -2,7 +2,6 @@ use crate::utils; use kos_types::error::Error; use serde::Serialize; use serde_json::json; -use kos_proto::tron::TransferContract; #[derive(Serialize)] pub struct ContractOptions { diff --git a/packages/kos-sdk/src/models.rs b/packages/kos-sdk/src/models.rs index 07bfadc..32e26a5 100644 --- a/packages/kos-sdk/src/models.rs +++ b/packages/kos-sdk/src/models.rs @@ -1,11 +1,8 @@ -use pbjson::private::base64; -// use crate::klever; +use crate::chain::Chain; +use crate::chains::{ETH, KLV, TRX}; use kos_types::{error::Error, hash::Hash}; use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; -use kos_proto::tron; -use crate::chain::Chain; -use crate::chains::{ETH, KLV, TRX}; #[derive(Debug, Clone, Serialize)] #[wasm_bindgen] @@ -200,74 +197,19 @@ impl Transaction { impl Transaction { #[wasm_bindgen(js_name = fromRaw)] pub fn from_raw(chain: Chain, data: &str) -> Self { - let mut sender = String::default(); - let mut hash = Hash::default(); - - let data = match chain { - Chain::KLV => { - let tx: kos_proto::klever::Transaction = - serde_json::from_str(data).expect("failed to parse klever transaction"); - - let raw_data = tx - .raw_data - .clone() - .ok_or_else(|| Error::InvalidTransaction("no raw TX found".to_string())).unwrap(); - - hash = Hash::from_vec(KLV::hash_transaction(&tx).unwrap()).unwrap(); - sender = KLV::address_from_bytes(&raw_data.sender).unwrap(); - TransactionRaw::Klever(tx) - } - Chain::TRX => { - let raw_data_bytes = hex::decode(data).unwrap().clone(); - let raw_data: kos_proto::tron::transaction::Raw = kos_proto::from_bytes(raw_data_bytes).unwrap(); - - let parameter: kos_proto::tron::TransferContract = kos_proto::unpack_from_option_any(&raw_data.contract[0].parameter).unwrap(); - - let tx = kos_proto::tron::Transaction { - raw_data: Some(raw_data), - signature: Vec::new(), - ret: Vec::new(), - }; - - hash = Hash::from_vec(TRX::hash_transaction(&tx).unwrap()).unwrap(); - - sender = TRX::address_from_bytes(parameter.owner_address.as_slice()).unwrap(); - - TransactionRaw::Tron(tx) - } - - Chain::ETH => { - let tx: super::chains::ETHTransaction = - serde_json::from_str(data).expect("failed to parse ethereum transaction"); - - let bytes = tx.encode()?; - let digest = ETH::hash(&bytes)?; - hash = Hash::from_vec(digest)?; - - sender = match tx.from { - Some(addr) => addr.to_string(), - None => "".to_string(), - }; - - TransactionRaw::Ethereum(tx) - } + match chain { + Chain::KLV => KLV::tx_from_raw(data).unwrap(), + Chain::TRX => TRX::tx_from_raw(data).unwrap(), + Chain::ETH => ETH::tx_from_json(data).unwrap(), Chain::MATIC => { - todo!("decode polygon transaction") + todo!() } Chain::BTC => { - todo!("decode bitcoin transaction") + todo!() } Chain::NONE => { - panic!("invalid chain") + panic!("Invalid Chain") } - }; - - - Self { - chain, - sender, - hash, - data: Some(data), } } } @@ -328,24 +270,20 @@ impl AddressOptions { } } -// Test Transaction from raw #[cfg(test)] mod tests { use super::*; - use crate::chains::ETHTransaction; - use kos_proto::klever::Transaction as KleverTransaction; - use kos_proto::tron::Transaction as TronTransaction; - use serde_json::json; - use web3::ethabi::ParamType::String; #[test] fn test_transaction_from_raw() { - let klv_tx_str = r#"{"RawData":{"Nonce":312,"Sender":"nxNUcG11rraE8m196h+9oX4mTHWVzB7d7AuJaMG+hSQ=","Contract":[{"Parameter":{"type_url":"type.googleapis.com/proto.TransferContract","value":"CiCthZSJePbX7pPJ64gh6PZ+HBo1YPZddPMYyYs/+aLSMxIDS0xWGMCEPQ=="}}],"Data":[""],"KAppFee":1000000,"BandwidthFee":2000000,"Version":1,"ChainID":"MTA4"}}"#; let klv_tx = Transaction::from_raw(Chain::KLV, klv_tx_str); - assert_eq!(klv_tx.sender, "klv1nuf4gurdwkhtdp8jd47758aa59lzvnr4jhxpah0vpwyk3sd7s5jqy6mut7"); + assert_eq!( + klv_tx.sender, + "klv1nuf4gurdwkhtdp8jd47758aa59lzvnr4jhxpah0vpwyk3sd7s5jqy6mut7" + ); let tron_tx_str = "0a02d8372208e9c73b516bcd78844088c6e8ad9a325a67080112630a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412320a1541e825d52582eec346c839b4875376117904a76cbc12154120ab1300cf70c048e4cf5d5b1b33f59653ed662618c0843d70fdfee4ad9a32"; @@ -364,6 +302,6 @@ mod tests { let eth_tx = Transaction::from_raw(Chain::ETH, eth_tx_str); - assert_eq!(eth_tx.sender, "0x4cbeee256240c92a9ad920ea6f4d7df6466d2cdc"); + assert_eq!(eth_tx.sender, "0x4cBeee256240c92A9ad920ea6f4d7Df6466D2Cdc"); } } From 45ed70a17f12d60c0ab106c63b750ae0fdc929c3 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Fri, 30 Aug 2024 21:48:44 -0300 Subject: [PATCH 05/15] chore: remove unused method --- packages/kos-sdk/src/chains/klever/mod.rs | 5 ----- packages/kos-sdk/src/chains/tron/mod.rs | 7 +------ 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/packages/kos-sdk/src/chains/klever/mod.rs b/packages/kos-sdk/src/chains/klever/mod.rs index 1dc53d9..fdacad9 100644 --- a/packages/kos-sdk/src/chains/klever/mod.rs +++ b/packages/kos-sdk/src/chains/klever/mod.rs @@ -68,11 +68,6 @@ impl KLV { Ok(address::Address::from_keypair(keypair).to_string()) } - pub fn address_from_bytes(bytes: &[u8]) -> Result { - let address = address::Address::from_bytes(bytes); - Ok(address.to_string()) - } - #[wasm_bindgen(js_name = "getPath")] pub fn get_path(options: &PathOptions) -> Result { Ok(format!("m/44'/{}'/0'/0'/{}'", BIP44_PATH, options.index)) diff --git a/packages/kos-sdk/src/chains/tron/mod.rs b/packages/kos-sdk/src/chains/tron/mod.rs index 9c22367..e6b0bc0 100644 --- a/packages/kos-sdk/src/chains/tron/mod.rs +++ b/packages/kos-sdk/src/chains/tron/mod.rs @@ -81,11 +81,6 @@ impl TRX { Ok(address::Address::from_keypair(kp).to_string()) } - pub fn address_from_bytes(bytes: &[u8]) -> Result { - let addr = address::Address::from_bytes(bytes); - Ok(addr.to_string()) - } - #[wasm_bindgen(js_name = "getPath")] pub fn get_path(options: &PathOptions) -> Result { let index = options.index; @@ -427,7 +422,7 @@ impl TRX { let hash = Hash::from_vec(TRX::hash_transaction(&tx).unwrap()).unwrap(); - let sender = TRX::address_from_bytes(parameter.owner_address.as_slice()).unwrap(); + let sender = address::Address::from_bytes(parameter.owner_address.as_slice()).to_string(); Ok(Transaction { chain: chain::Chain::TRX, From bda5a0da1fefc3633f032117363f8cfa46e6958c Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Fri, 30 Aug 2024 21:50:02 -0300 Subject: [PATCH 06/15] chore: MATIC & BTC todo --- packages/kos-sdk/src/models.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/kos-sdk/src/models.rs b/packages/kos-sdk/src/models.rs index 32e26a5..8340fdc 100644 --- a/packages/kos-sdk/src/models.rs +++ b/packages/kos-sdk/src/models.rs @@ -201,12 +201,8 @@ impl Transaction { Chain::KLV => KLV::tx_from_raw(data).unwrap(), Chain::TRX => TRX::tx_from_raw(data).unwrap(), Chain::ETH => ETH::tx_from_json(data).unwrap(), - Chain::MATIC => { - todo!() - } - Chain::BTC => { - todo!() - } + Chain::MATIC => todo!(), + Chain::BTC => todo!(), Chain::NONE => { panic!("Invalid Chain") } From fc279d1aa50803a71663b068ec8102063a785ff6 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 3 Sep 2024 09:26:47 -0300 Subject: [PATCH 07/15] chore: error handling --- packages/kos-sdk/src/chains/tron/mod.rs | 22 ++++++++++++-- packages/kos-sdk/src/models.rs | 40 +------------------------ 2 files changed, 20 insertions(+), 42 deletions(-) diff --git a/packages/kos-sdk/src/chains/tron/mod.rs b/packages/kos-sdk/src/chains/tron/mod.rs index e6b0bc0..57c62e8 100644 --- a/packages/kos-sdk/src/chains/tron/mod.rs +++ b/packages/kos-sdk/src/chains/tron/mod.rs @@ -407,12 +407,14 @@ impl TRX { } pub fn tx_from_raw(data: &str) -> Result { - let raw_data_bytes = hex::decode(data).unwrap().clone(); + let raw_data_bytes = hex::decode(data)?; let raw_data: kos_proto::tron::transaction::Raw = kos_proto::from_bytes(raw_data_bytes).unwrap(); let parameter: kos_proto::tron::TransferContract = - kos_proto::unpack_from_option_any(&raw_data.contract[0].parameter).unwrap(); + kos_proto::unpack_from_option_any(&raw_data.contract[0].parameter).ok_or( + Error::InvalidTransaction("Failed to unpack transfer contract".to_string()), + )?; let tx = kos_proto::tron::Transaction { raw_data: Some(raw_data), @@ -420,7 +422,7 @@ impl TRX { ret: Vec::new(), }; - let hash = Hash::from_vec(TRX::hash_transaction(&tx).unwrap()).unwrap(); + let hash = Hash::from_vec(TRX::hash_transaction(&tx)?)?; let sender = address::Address::from_bytes(parameter.owner_address.as_slice()).to_string(); @@ -656,4 +658,18 @@ mod tests { let result = TRX::serialize_raw_data_into_hex_string(invalid_tx); assert!(result.is_err()); } + + #[test] + fn test_tx_from_raw() { + let tx = "0a02d8372208e9c73b516bcd78844088c6e8ad9a325a67080112630a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412320a1541e825d52582eec346c839b4875376117904a76cbc12154120ab1300cf70c048e4cf5d5b1b33f59653ed662618c0843d70fdfee4ad9a32"; + let result = TRX::tx_from_raw(tx); + assert!(result.is_ok()); + let t = result.unwrap(); + assert_eq!(t.chain, chain::Chain::TRX); + assert_eq!(t.sender, "TX8h6Df74VpJsXF6sTDz1QJsq3Ec8dABc3"); + assert_eq!( + t.hash.to_string(), + "3e6c463b2e88d78e912dee3aa31a14aa71c0e56bbdfbdbba012c8af4e45b8834" + ); + } } diff --git a/packages/kos-sdk/src/models.rs b/packages/kos-sdk/src/models.rs index 8340fdc..e84176f 100644 --- a/packages/kos-sdk/src/models.rs +++ b/packages/kos-sdk/src/models.rs @@ -203,9 +203,7 @@ impl Transaction { Chain::ETH => ETH::tx_from_json(data).unwrap(), Chain::MATIC => todo!(), Chain::BTC => todo!(), - Chain::NONE => { - panic!("Invalid Chain") - } + Chain::NONE => Err(Error::InvalidTransaction("Invalid chain".to_string())).unwrap(), } } } @@ -265,39 +263,3 @@ impl AddressOptions { self.check_summed } } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_transaction_from_raw() { - let klv_tx_str = r#"{"RawData":{"Nonce":312,"Sender":"nxNUcG11rraE8m196h+9oX4mTHWVzB7d7AuJaMG+hSQ=","Contract":[{"Parameter":{"type_url":"type.googleapis.com/proto.TransferContract","value":"CiCthZSJePbX7pPJ64gh6PZ+HBo1YPZddPMYyYs/+aLSMxIDS0xWGMCEPQ=="}}],"Data":[""],"KAppFee":1000000,"BandwidthFee":2000000,"Version":1,"ChainID":"MTA4"}}"#; - - let klv_tx = Transaction::from_raw(Chain::KLV, klv_tx_str); - - assert_eq!( - klv_tx.sender, - "klv1nuf4gurdwkhtdp8jd47758aa59lzvnr4jhxpah0vpwyk3sd7s5jqy6mut7" - ); - - let tron_tx_str = "0a02d8372208e9c73b516bcd78844088c6e8ad9a325a67080112630a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412320a1541e825d52582eec346c839b4875376117904a76cbc12154120ab1300cf70c048e4cf5d5b1b33f59653ed662618c0843d70fdfee4ad9a32"; - - let tron_tx = Transaction::from_raw(Chain::TRX, tron_tx_str); - - assert_eq!(tron_tx.sender, "TX8h6Df74VpJsXF6sTDz1QJsq3Ec8dABc3"); - - let eth_tx_str = r#"{ - "from":"0x4cbeee256240c92a9ad920ea6f4d7df6466d2cdc", - "maxPriorityFeePerGas":null,"maxFeePerGas":null, - "gas": "0x00", - "value": "0x00", - "data":"0xa9059cbb000000000000000000000000ac4145fef6c828e8ae017207ad944c988ccb2cf700000000000000000000000000000000000000000000000000000000000f4240", - "to":"0xdac17f958d2ee523a2206206994597c13d831ec7", - "nonce":"0x00"}"#; - - let eth_tx = Transaction::from_raw(Chain::ETH, eth_tx_str); - - assert_eq!(eth_tx.sender, "0x4cBeee256240c92A9ad920ea6f4d7Df6466D2Cdc"); - } -} From 2eac88577609ffbe53e20cd04a6c7b50f9b52f77 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 3 Sep 2024 09:31:34 -0300 Subject: [PATCH 08/15] fix: error unwrap --- packages/kos-sdk/src/models.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/kos-sdk/src/models.rs b/packages/kos-sdk/src/models.rs index e84176f..50a8ba2 100644 --- a/packages/kos-sdk/src/models.rs +++ b/packages/kos-sdk/src/models.rs @@ -203,7 +203,10 @@ impl Transaction { Chain::ETH => ETH::tx_from_json(data).unwrap(), Chain::MATIC => todo!(), Chain::BTC => todo!(), - Chain::NONE => Err(Error::InvalidTransaction("Invalid chain".to_string())).unwrap(), + Chain::NONE => panic!( + "{:?}", + Error::InvalidTransaction("Invalid chain".to_string()) + ), } } } From e41acb4cb0db009a1618af925570d9cce1779964 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 3 Sep 2024 09:37:49 -0300 Subject: [PATCH 09/15] chore: wrap from_raw with Result --- packages/kos-sdk/src/models.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/kos-sdk/src/models.rs b/packages/kos-sdk/src/models.rs index 50a8ba2..abc8839 100644 --- a/packages/kos-sdk/src/models.rs +++ b/packages/kos-sdk/src/models.rs @@ -196,17 +196,18 @@ impl Transaction { #[wasm_bindgen] impl Transaction { #[wasm_bindgen(js_name = fromRaw)] - pub fn from_raw(chain: Chain, data: &str) -> Self { + pub fn from_raw(chain: Chain, data: &str) -> Result { match chain { - Chain::KLV => KLV::tx_from_raw(data).unwrap(), - Chain::TRX => TRX::tx_from_raw(data).unwrap(), - Chain::ETH => ETH::tx_from_json(data).unwrap(), - Chain::MATIC => todo!(), - Chain::BTC => todo!(), - Chain::NONE => panic!( - "{:?}", - Error::InvalidTransaction("Invalid chain".to_string()) - ), + Chain::KLV => KLV::tx_from_raw(data), + Chain::TRX => TRX::tx_from_raw(data), + Chain::ETH => ETH::tx_from_json(data), + Chain::MATIC => Err(Error::InvalidTransaction( + "MATIC chain not implemented".to_string(), + )), + Chain::BTC => Err(Error::InvalidTransaction( + "BTC chain not implemented".to_string(), + )), + Chain::NONE => Err(Error::InvalidTransaction("Invalid chain".to_string())), } } } From 576053e51e79db0b40bac7496b78a8f8eb49c3c3 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Thu, 5 Sep 2024 16:46:11 -0300 Subject: [PATCH 10/15] feat: sign transaction mobile bind --- packages/kos-mobile/src/lib.rs | 55 ++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index af5d3c7..a62938e 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -1,10 +1,9 @@ use hex::FromHexError; use hex::ToHex; - use kos_crypto::cipher; use kos_crypto::cipher::CipherAlgo; use kos_sdk::chain::Chain; -use kos_sdk::models::PathOptions; +use kos_sdk::models::{PathOptions, Transaction}; use kos_sdk::wallet::Wallet; use kos_types::error::Error as KosError; @@ -41,6 +40,29 @@ struct KOSAccount { pub path: String, } +#[derive(uniffi::Record)] +struct KOSTransaction { + pub chain_id: i32, + pub raw: String, + pub sender: String, + pub signature: String, +} + +#[uniffi::export] +fn sign_transaction(account: KOSAccount, raw: String) -> Result { + let chain = get_chain_by(account.chain_id)?; + let wallet = Wallet::from_private_key(chain, account.private_key.to_string())?; + let transaction = Transaction::from_raw(chain, &raw)?; + let signed_transaction = wallet.sign(transaction)?; + + Ok(KOSTransaction { + chain_id: account.chain_id, + raw: signed_transaction.get_raw()?, + sender: signed_transaction.sender, + signature: todo!("get signature"), + }) +} + #[uniffi::export] fn generate_mnemonic(size: i32) -> Result { Ok(kos_crypto::mnemonic::generate_mnemonic(size as usize)?.to_phrase()) @@ -319,4 +341,33 @@ mod tests { Err(e) => assert!(matches!(e, KOSError::KOSDelegate(..)), "Invalid error"), } } + + // Transaction from raw + #[test] + fn should_sign_raw_transaction() { + let chain_id = 38; + + let raw = "{\"RawData\":{\"BandwidthFee\":1000000,\"ChainID\":\"MTAwNDIw\",\"Contract\":[{\"Parameter\":{\"type_url\":\"type.googleapis.com/proto.TransferContract\",\"value\":\"CiAysyg0Aj8xj/rr5XGU6iJ+ATI29mnRHS0W0BrC1vz0CBgK\"}}],\"KAppFee\":500000,\"Nonce\":39,\"Sender\":\"5BsyOlcf2VXgnNQWYP9EZcP0RpPIfy+upKD8QIcnyOo=\",\"Version\":1}}"; + + 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 transaction = sign_transaction(account, raw.to_string()).unwrap(); + + println!("raw: {:?}", transaction.raw); + + assert_eq!(transaction.chain_id, chain_id, "The chain_id doesn't match"); + assert_eq!( + transaction.sender, "klv1usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy", + "The sender doesn't match" + ); + assert_eq!( + transaction.raw, "{\"RawData\":{\"Nonce\":39,\"Sender\":\"5BsyOlcf2VXgnNQWYP9EZcP0RpPIfy+upKD8QIcnyOo=\",\"Contract\":[{\"Parameter\":{\"typeUrl\":\"type.googleapis.com/proto.TransferContract\",\"value\":\"CiAysyg0Aj8xj/rr5XGU6iJ+ATI29mnRHS0W0BrC1vz0CBgK\"}}],\"KAppFee\":500000,\"BandwidthFee\":1000000,\"Version\":1,\"ChainID\":\"MTAwNDIw\"},\"Signature\":[\"gUZDIPSxSq40QjTBM38/DAAuWTm7D1THo2KWVqhiTYCum5O+OSWwTYlgIU0RgJ6ungg1cuCJPcmYWNgjDKA/DA==\"]}", + "The raw doesn't match" + ); + } } From 94fa726dd703d892cd9a25b6459184013fc34121 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Thu, 5 Sep 2024 16:56:12 -0300 Subject: [PATCH 11/15] chore: signature todo --- packages/kos-mobile/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index a62938e..2ac80d0 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -59,7 +59,7 @@ fn sign_transaction(account: KOSAccount, raw: String) -> Result Date: Fri, 6 Sep 2024 12:43:30 -0300 Subject: [PATCH 12/15] feat: add Transaction signature --- packages/kos-mobile/src/lib.rs | 5 ++++- packages/kos-sdk/src/chains/bitcoin/mod.rs | 4 ++++ packages/kos-sdk/src/chains/bitcoin/transaction.rs | 5 +++++ packages/kos-sdk/src/chains/ethereum/mod.rs | 9 +++++++++ packages/kos-sdk/src/chains/klever/mod.rs | 7 +++++++ packages/kos-sdk/src/chains/klever/requests.rs | 1 + packages/kos-sdk/src/chains/tron/mod.rs | 9 +++++++++ packages/kos-sdk/src/models.rs | 7 +++++++ 8 files changed, 46 insertions(+), 1 deletion(-) diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index 2ac80d0..875d366 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -54,12 +54,15 @@ fn sign_transaction(account: KOSAccount, raw: String) -> Result Result { + let sig = self.tx.clone().extract_tx().wtxid(); + Ok(sig.to_string()) + } + pub fn finalize(&mut self) -> Result<(), Error> { for inp_idx in 0..self.tx.inputs.len() { // todo!("multi sig and redeem type"); diff --git a/packages/kos-sdk/src/chains/ethereum/mod.rs b/packages/kos-sdk/src/chains/ethereum/mod.rs index 312a4a6..157b55c 100644 --- a/packages/kos-sdk/src/chains/ethereum/mod.rs +++ b/packages/kos-sdk/src/chains/ethereum/mod.rs @@ -139,6 +139,7 @@ impl ETH { sender: tx.sender, hash: Hash::from_vec(new_hash)?, data: Some(TransactionRaw::Ethereum(new_tx)), + signature: Some(hex::encode(sig)), }; Ok(result) @@ -284,6 +285,7 @@ impl ETH { sender, hash: Hash::from_vec(digest)?, data: Some(TransactionRaw::Ethereum(tx)), + signature: None, }) } @@ -444,12 +446,16 @@ impl ETH { } }; + let signature = tx.signature.unwrap().to_standard().to_string(); + let digest = hash_transaction(&tx)?; + Ok(crate::models::Transaction { chain: chain::Chain::ETH, sender: "".to_string(), //TODO: implement sender on eth decode hash: Hash::from_vec(digest)?, data: Some(TransactionRaw::Ethereum(tx)), + signature: Some(signature), }) } @@ -465,11 +471,14 @@ impl ETH { None => "".to_string(), }; + let signature = tx.signature.unwrap().to_standard().to_string(); + Ok(crate::models::Transaction { chain: chain::Chain::ETH, sender, hash: Hash::from_vec(digest)?, data: Some(TransactionRaw::Ethereum(tx)), + signature: Some(signature), }) } } diff --git a/packages/kos-sdk/src/chains/klever/mod.rs b/packages/kos-sdk/src/chains/klever/mod.rs index fdacad9..68b5a83 100644 --- a/packages/kos-sdk/src/chains/klever/mod.rs +++ b/packages/kos-sdk/src/chains/klever/mod.rs @@ -8,6 +8,7 @@ use crate::{ use kos_crypto::{ed25519::Ed25519KeyPair, keypair::KeyPair}; use kos_types::{error::Error, hash::Hash, number::BigNumber}; +use pbjson::private::base64; use std::str::FromStr; use wasm_bindgen::prelude::*; @@ -102,12 +103,15 @@ impl KLV { let digest = KLV::hash_transaction(&klv_tx)?; let sig = KLV::sign_digest(digest.as_slice(), keypair)?; + let signature = base64::encode(sig.clone()); + new_tx.signature.push(sig); let result = Transaction { chain: tx.chain, sender: tx.sender, hash: Hash::from_vec(digest)?, data: Some(TransactionRaw::Klever(new_tx)), + signature: Some(signature), }; Ok(result) @@ -210,6 +214,7 @@ impl KLV { sender: tx.sender, hash: tx_hash, data: tx.data, + signature: None, })) } None => match result.get("error") { @@ -282,12 +287,14 @@ impl KLV { let sender = address::Address::from_bytes(&data.sender); let digest = KLV::hash_transaction(&tx)?; + let signature = base64::encode(tx.signature.first().unwrap().clone()); Ok(crate::models::Transaction { chain: crate::chain::Chain::KLV, sender: sender.to_string(), hash: Hash::from_slice(&digest)?, data: Some(TransactionRaw::Klever(tx)), + signature: Some(signature), }) } } diff --git a/packages/kos-sdk/src/chains/klever/requests.rs b/packages/kos-sdk/src/chains/klever/requests.rs index e6496b6..318625f 100644 --- a/packages/kos-sdk/src/chains/klever/requests.rs +++ b/packages/kos-sdk/src/chains/klever/requests.rs @@ -84,5 +84,6 @@ pub async fn make_request( sender, hash: Hash::new(&tx.tx_hash)?, data: Some(TransactionRaw::Klever(tx.tx)), + signature: None, }) } diff --git a/packages/kos-sdk/src/chains/tron/mod.rs b/packages/kos-sdk/src/chains/tron/mod.rs index 57c62e8..153356d 100644 --- a/packages/kos-sdk/src/chains/tron/mod.rs +++ b/packages/kos-sdk/src/chains/tron/mod.rs @@ -116,6 +116,7 @@ impl TRX { let mut new_tx = trx_tx.clone(); let digest = TRX::hash_transaction(&trx_tx)?; let sig = TRX::sign_digest(digest.as_slice(), keypair)?; + let hex_sig = hex::encode(sig.clone()); new_tx.signature.push(sig); let result = Transaction { @@ -123,6 +124,7 @@ impl TRX { sender: tx.sender, hash: Hash::from_vec(digest)?, data: Some(TransactionRaw::Tron(new_tx)), + signature: Some(hex_sig), }; Ok(result) @@ -328,6 +330,7 @@ impl TRX { sender, hash: Hash::from_vec(digest)?, data: Some(TransactionRaw::Tron(tx)), + signature: None, }) } @@ -361,6 +364,7 @@ impl TRX { sender: tx.sender, hash: tx.hash, data: tx.data, + signature: tx.signature, })) } @@ -426,11 +430,16 @@ impl TRX { let sender = address::Address::from_bytes(parameter.owner_address.as_slice()).to_string(); + let binding = tx.clone(); + let sig = binding.signature.first().unwrap(); + let signature = hex::encode(sig); + Ok(Transaction { chain: chain::Chain::TRX, sender, hash, data: Some(TransactionRaw::Tron(tx)), + signature: Some(signature), }) } } diff --git a/packages/kos-sdk/src/models.rs b/packages/kos-sdk/src/models.rs index abc8839..70fdd51 100644 --- a/packages/kos-sdk/src/models.rs +++ b/packages/kos-sdk/src/models.rs @@ -148,6 +148,8 @@ pub struct Transaction { pub hash: Hash, #[wasm_bindgen(skip)] pub data: Option, + #[wasm_bindgen(skip)] + pub signature: Option, } #[wasm_bindgen] @@ -183,6 +185,11 @@ impl Transaction { None => Err(Error::InvalidTransaction("no data found".to_string())), } } + + #[wasm_bindgen(js_name = getSignature)] + pub fn get_signature(&self) -> Option { + self.signature.clone() + } } impl Transaction { pub fn new_data(&self, chain: Chain, data: TransactionRaw) -> Transaction { From 61e1000810d8d5239b846158846f553d348980e5 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Fri, 6 Sep 2024 13:45:05 -0300 Subject: [PATCH 13/15] fix: empty signature --- packages/kos-sdk/src/chains/ethereum/mod.rs | 8 ++++---- packages/kos-sdk/src/chains/klever/klever_test.rs | 1 + packages/kos-sdk/src/chains/klever/mod.rs | 4 ++-- packages/kos-sdk/src/chains/tron/mod.rs | 9 ++++++--- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/kos-sdk/src/chains/ethereum/mod.rs b/packages/kos-sdk/src/chains/ethereum/mod.rs index 157b55c..502eed3 100644 --- a/packages/kos-sdk/src/chains/ethereum/mod.rs +++ b/packages/kos-sdk/src/chains/ethereum/mod.rs @@ -446,7 +446,7 @@ impl ETH { } }; - let signature = tx.signature.unwrap().to_standard().to_string(); + let signature = tx.signature.map(|sig| sig.to_standard().to_string()); let digest = hash_transaction(&tx)?; @@ -455,7 +455,7 @@ impl ETH { sender: "".to_string(), //TODO: implement sender on eth decode hash: Hash::from_vec(digest)?, data: Some(TransactionRaw::Ethereum(tx)), - signature: Some(signature), + signature, }) } @@ -471,14 +471,14 @@ impl ETH { None => "".to_string(), }; - let signature = tx.signature.unwrap().to_standard().to_string(); + let signature = tx.signature.map(|sig| sig.to_standard().to_string()); Ok(crate::models::Transaction { chain: chain::Chain::ETH, sender, hash: Hash::from_vec(digest)?, data: Some(TransactionRaw::Ethereum(tx)), - signature: Some(signature), + signature, }) } } diff --git a/packages/kos-sdk/src/chains/klever/klever_test.rs b/packages/kos-sdk/src/chains/klever/klever_test.rs index 48edd25..3ab6849 100644 --- a/packages/kos-sdk/src/chains/klever/klever_test.rs +++ b/packages/kos-sdk/src/chains/klever/klever_test.rs @@ -58,6 +58,7 @@ mod klever_test { hash: Hash::new("0x0000000000000000000000000000000000000000000000000000000000000000") .unwrap(), data: Some(TransactionRaw::Klever(klv_tx)), + signature: None, }; let result = tokio_test::block_on(KLV::broadcast(to_broadcast, None)); diff --git a/packages/kos-sdk/src/chains/klever/mod.rs b/packages/kos-sdk/src/chains/klever/mod.rs index 68b5a83..00e9229 100644 --- a/packages/kos-sdk/src/chains/klever/mod.rs +++ b/packages/kos-sdk/src/chains/klever/mod.rs @@ -287,14 +287,14 @@ impl KLV { let sender = address::Address::from_bytes(&data.sender); let digest = KLV::hash_transaction(&tx)?; - let signature = base64::encode(tx.signature.first().unwrap().clone()); + let signature = tx.signature.first().map(|sig| base64::encode(sig.clone())); Ok(crate::models::Transaction { chain: crate::chain::Chain::KLV, sender: sender.to_string(), hash: Hash::from_slice(&digest)?, data: Some(TransactionRaw::Klever(tx)), - signature: Some(signature), + signature, }) } } diff --git a/packages/kos-sdk/src/chains/tron/mod.rs b/packages/kos-sdk/src/chains/tron/mod.rs index 153356d..e9f64bc 100644 --- a/packages/kos-sdk/src/chains/tron/mod.rs +++ b/packages/kos-sdk/src/chains/tron/mod.rs @@ -431,15 +431,18 @@ impl TRX { let sender = address::Address::from_bytes(parameter.owner_address.as_slice()).to_string(); let binding = tx.clone(); - let sig = binding.signature.first().unwrap(); - let signature = hex::encode(sig); + let sig = binding.signature.first(); + let signature = match sig { + Some(s) => Some(hex::encode(s)), + None => None, + }; Ok(Transaction { chain: chain::Chain::TRX, sender, hash, data: Some(TransactionRaw::Tron(tx)), - signature: Some(signature), + signature, }) } } From 56a734ac89d93726bfdd1b12c0f203670b95a44e Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Mon, 9 Sep 2024 09:23:47 -0300 Subject: [PATCH 14/15] fix: signature option --- packages/kos-sdk/src/chains/tron/mod.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/kos-sdk/src/chains/tron/mod.rs b/packages/kos-sdk/src/chains/tron/mod.rs index e9f64bc..6a3867f 100644 --- a/packages/kos-sdk/src/chains/tron/mod.rs +++ b/packages/kos-sdk/src/chains/tron/mod.rs @@ -432,10 +432,7 @@ impl TRX { let binding = tx.clone(); let sig = binding.signature.first(); - let signature = match sig { - Some(s) => Some(hex::encode(s)), - None => None, - }; + let signature = sig.map(hex::encode); Ok(Transaction { chain: chain::Chain::TRX, From 45f6ee4b7fac66894f2adb3b41fa1d6c0451dc48 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Mon, 9 Sep 2024 09:45:34 -0300 Subject: [PATCH 15/15] chore: test match signature --- packages/kos-mobile/src/lib.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index 875d366..84c4547 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -345,7 +345,6 @@ mod tests { } } - // Transaction from raw #[test] fn should_sign_raw_transaction() { let chain_id = 38; @@ -361,8 +360,6 @@ mod tests { let transaction = sign_transaction(account, raw.to_string()).unwrap(); - println!("raw: {:?}", transaction.raw); - assert_eq!(transaction.chain_id, chain_id, "The chain_id doesn't match"); assert_eq!( transaction.sender, "klv1usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy", @@ -372,5 +369,9 @@ mod tests { transaction.raw, "{\"RawData\":{\"Nonce\":39,\"Sender\":\"5BsyOlcf2VXgnNQWYP9EZcP0RpPIfy+upKD8QIcnyOo=\",\"Contract\":[{\"Parameter\":{\"typeUrl\":\"type.googleapis.com/proto.TransferContract\",\"value\":\"CiAysyg0Aj8xj/rr5XGU6iJ+ATI29mnRHS0W0BrC1vz0CBgK\"}}],\"KAppFee\":500000,\"BandwidthFee\":1000000,\"Version\":1,\"ChainID\":\"MTAwNDIw\"},\"Signature\":[\"gUZDIPSxSq40QjTBM38/DAAuWTm7D1THo2KWVqhiTYCum5O+OSWwTYlgIU0RgJ6ungg1cuCJPcmYWNgjDKA/DA==\"]}", "The raw doesn't match" ); + assert_eq!( + transaction.signature, "gUZDIPSxSq40QjTBM38/DAAuWTm7D1THo2KWVqhiTYCum5O+OSWwTYlgIU0RgJ6ungg1cuCJPcmYWNgjDKA/DA==", + "The signature doesn't match" + ); } }