diff --git a/.github/workflows/codegen-v2.yml b/.github/workflows/codegen-v2.yml index 108b8e42448..f8ced68b019 100644 --- a/.github/workflows/codegen-v2.yml +++ b/.github/workflows/codegen-v2.yml @@ -13,6 +13,7 @@ on: jobs: test: runs-on: ubuntu-latest + if: github.event.pull_request.draft == false steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 diff --git a/rust/chains/tw_binance/src/compiler.rs b/rust/chains/tw_binance/src/compiler.rs index 1ee1e23dd15..db36d3ae6b6 100644 --- a/rust/chains/tw_binance/src/compiler.rs +++ b/rust/chains/tw_binance/src/compiler.rs @@ -4,6 +4,7 @@ // terms governing use, modification, and redistribution, is contained in the // file LICENSE at the root of the source code distribution tree. +use crate::context::BinanceContext; use crate::modules::preimager::{JsonPreimager, JsonTxPreimage}; use crate::modules::serializer::BinanceAminoSerializer; use crate::modules::tx_builder::TxBuilder; @@ -12,9 +13,12 @@ use crate::transaction::SignerInfo; use tw_coin_entry::coin_context::CoinContext; use tw_coin_entry::coin_entry::{PublicKeyBytes, SignatureBytes}; use tw_coin_entry::common::compile_input::SingleSignaturePubkey; -use tw_coin_entry::error::SigningResult; +use tw_coin_entry::error::{SigningError, SigningErrorType, SigningResult}; use tw_coin_entry::signing_output_error; -use tw_keypair::ecdsa::secp256k1; +use tw_cosmos_sdk::modules::serializer::json_serializer::JsonSerializer; +use tw_cosmos_sdk::public_key::secp256k1::Secp256PublicKey; +use tw_cosmos_sdk::public_key::CosmosPublicKey; +use tw_misc::traits::ToBytesVec; use tw_proto::Binance::Proto; use tw_proto::TxCompiler::Proto as CompilerProto; @@ -69,7 +73,13 @@ impl BinanceCompiler { public_key, } = SingleSignaturePubkey::from_sign_pubkey_list(signatures, public_keys)?; let signature = BinanceSignature::try_from(signature.as_slice())?; - let public_key = secp256k1::PublicKey::try_from(public_key.as_slice())?; + let public_key = Secp256PublicKey::from_bytes(coin, public_key.as_slice())?; + + let signature_bytes = signature.to_vec(); + let signature_json = JsonSerializer::::serialize_signature( + &public_key, + signature_bytes.clone(), + ); let unsigned_tx = TxBuilder::unsigned_tx_from_proto(coin, &input)?; let signed_tx = unsigned_tx.into_signed(SignerInfo { @@ -79,8 +89,12 @@ impl BinanceCompiler { let encoded_tx = BinanceAminoSerializer::serialize_signed_tx(&signed_tx)?; + let signature_json = serde_json::to_string(&signature_json) + .map_err(|_| SigningError(SigningErrorType::Error_internal))?; Ok(Proto::SigningOutput { encoded: encoded_tx.into(), + signature: signature_bytes.into(), + signature_json: signature_json.into(), ..Proto::SigningOutput::default() }) } diff --git a/rust/chains/tw_binance/src/modules/preimager.rs b/rust/chains/tw_binance/src/modules/preimager.rs index e9b8fc68d40..18e2d47b5b5 100644 --- a/rust/chains/tw_binance/src/modules/preimager.rs +++ b/rust/chains/tw_binance/src/modules/preimager.rs @@ -19,8 +19,6 @@ impl JsonPreimager { pub fn preimage_hash(unsigned: &UnsignedTransaction) -> SigningResult { let encoded_tx = serde_json::to_string(unsigned) .map_err(|_| SigningError(SigningErrorType::Error_internal))?; - // TODO - println!("{}", encoded_tx); let tx_hash = sha2::sha256(encoded_tx.as_bytes()); let tx_hash = H256::try_from(tx_hash.as_slice()).expect("sha256 must return 32 bytes"); Ok(JsonTxPreimage { diff --git a/rust/chains/tw_binance/src/modules/serializer.rs b/rust/chains/tw_binance/src/modules/serializer.rs index 8473fc7e3f8..b99e0abc56d 100644 --- a/rust/chains/tw_binance/src/modules/serializer.rs +++ b/rust/chains/tw_binance/src/modules/serializer.rs @@ -8,7 +8,7 @@ use crate::amino::AminoEncoder; use crate::transaction::SignedTransaction; use std::borrow::Cow; use tw_coin_entry::error::{SigningError, SigningErrorType, SigningResult}; -use tw_hash::H264; +use tw_cosmos_sdk::public_key::CosmosPublicKey; use tw_memory::Data; use tw_misc::traits::ToBytesVec; use tw_proto::serialize; @@ -43,7 +43,7 @@ impl BinanceAminoSerializer { .encode_size_prefixed()?) } - pub fn serialize_public_key(public_key: H264) -> Data { + pub fn serialize_public_key(public_key: Data) -> Data { let public_key_len = public_key.len() as u8; AminoEncoder::new(&PUBLIC_KEY_PREFIX) // Push the length of the public key. @@ -54,7 +54,7 @@ impl BinanceAminoSerializer { pub fn serialize_signature(signed: &SignedTransaction) -> SigningResult { let sign_msg = Proto::Signature { - pub_key: Self::serialize_public_key(signed.signer.public_key.compressed()).into(), + pub_key: Self::serialize_public_key(signed.signer.public_key.to_bytes()).into(), signature: signed.signer.signature.to_vec().into(), account_number: signed.unsigned.account_number, sequence: signed.unsigned.sequence, diff --git a/rust/chains/tw_binance/src/signer.rs b/rust/chains/tw_binance/src/signer.rs index b8b1c02739e..bd1cc345ffe 100644 --- a/rust/chains/tw_binance/src/signer.rs +++ b/rust/chains/tw_binance/src/signer.rs @@ -4,16 +4,20 @@ // terms governing use, modification, and redistribution, is contained in the // file LICENSE at the root of the source code distribution tree. +use crate::context::BinanceContext; use crate::modules::preimager::{JsonPreimager, JsonTxPreimage}; use crate::modules::serializer::BinanceAminoSerializer; use crate::modules::tx_builder::TxBuilder; use crate::signature::BinanceSignature; use crate::transaction::SignerInfo; use tw_coin_entry::coin_context::CoinContext; -use tw_coin_entry::error::SigningResult; +use tw_coin_entry::error::{SigningError, SigningErrorType, SigningResult}; use tw_coin_entry::signing_output_error; +use tw_cosmos_sdk::modules::serializer::json_serializer::JsonSerializer; +use tw_cosmos_sdk::public_key::secp256k1::Secp256PublicKey; use tw_keypair::ecdsa::secp256k1; use tw_keypair::traits::{KeyPairTrait, SigningKeyTrait}; +use tw_misc::traits::ToBytesVec; use tw_proto::Binance::Proto; pub struct BinanceSigner; @@ -37,7 +41,13 @@ impl BinanceSigner { let key_pair = secp256k1::KeyPair::try_from(input.private_key.as_ref())?; let signature = BinanceSignature::from(key_pair.sign(tx_hash)?); - let public_key = key_pair.public().clone(); + let public_key = Secp256PublicKey::from_secp256k1_public_key(coin, key_pair.public())?; + + let signature_bytes = signature.to_vec(); + let signature_json = JsonSerializer::::serialize_signature( + &public_key, + signature_bytes.clone(), + ); let signed_tx = unsigned_tx.into_signed(SignerInfo { public_key, @@ -45,8 +55,12 @@ impl BinanceSigner { }); let encoded_tx = BinanceAminoSerializer::serialize_signed_tx(&signed_tx)?; + let signature_json = serde_json::to_string(&signature_json) + .map_err(|_| SigningError(SigningErrorType::Error_internal))?; Ok(Proto::SigningOutput { encoded: encoded_tx.into(), + signature: signature_bytes.into(), + signature_json: signature_json.into(), ..Proto::SigningOutput::default() }) } diff --git a/rust/chains/tw_binance/src/transaction/mod.rs b/rust/chains/tw_binance/src/transaction/mod.rs index e07bc089e3d..5391dd6f5c3 100644 --- a/rust/chains/tw_binance/src/transaction/mod.rs +++ b/rust/chains/tw_binance/src/transaction/mod.rs @@ -7,7 +7,7 @@ use crate::signature::BinanceSignature; use crate::transaction::message::BinanceMessageEnum; use serde::{Deserialize, Serialize}; -use tw_keypair::ecdsa::secp256k1; +use tw_cosmos_sdk::public_key::secp256k1::Secp256PublicKey; use tw_memory::Data; use tw_misc::serde::as_string; @@ -37,7 +37,7 @@ impl UnsignedTransaction { } pub struct SignerInfo { - pub public_key: secp256k1::PublicKey, + pub public_key: Secp256PublicKey, pub signature: BinanceSignature, } diff --git a/rust/tw_any_coin/tests/chains/binance/binance_compile.rs b/rust/tw_any_coin/tests/chains/binance/binance_compile.rs index f1104b9657e..0da4b40dfc6 100644 --- a/rust/tw_any_coin/tests/chains/binance/binance_compile.rs +++ b/rust/tw_any_coin/tests/chains/binance/binance_compile.rs @@ -55,15 +55,19 @@ fn test_binance_compile() { // Step 3: Compile transaction info // Simulate signature, normally obtained from signature server. - let signature = "1b1181faec30b60a2ddaa2804c253cf264c69180ec31814929b5de62088c0c5a45e8a816d1208fc5366bb8b041781a6771248550d04094c3d7a504f9e8310679" - .decode_hex() - .unwrap(); + let signature = "1b1181faec30b60a2ddaa2804c253cf264c69180ec31814929b5de62088c0c5a45e8a816d1208fc5366bb8b041781a6771248550d04094c3d7a504f9e8310679"; + let signature_bytes = signature.decode_hex().unwrap(); let public_key = "026a35920088d98c3888ca68c53dfc93f4564602606cbb87f0fe5ee533db38e502" .decode_hex() .unwrap(); let mut compiler = CompilerHelper::::default(); - let output = compiler.compile(CoinType::Binance, &input, vec![signature], vec![public_key]); + let output = compiler.compile( + CoinType::Binance, + &input, + vec![signature_bytes], + vec![public_key], + ); assert_eq!(output.error, SigningError::OK); let expected_tx = concat!( @@ -74,4 +78,7 @@ fn test_binance_compile() { "04f9e8310679", ); assert_eq!(output.encoded.to_hex(), expected_tx); + assert_eq!(output.signature.to_hex(), signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"Amo1kgCI2Yw4iMpoxT38k/RWRgJgbLuH8P5e5TPbOOUC"},"signature":"GxGB+uwwtgot2qKATCU88mTGkYDsMYFJKbXeYgiMDFpF6KgW0SCPxTZruLBBeBpncSSFUNBAlMPXpQT56DEGeQ=="}"#; + assert_eq!(output.signature_json, expected_signature_json); } diff --git a/rust/tw_any_coin/tests/chains/binance/binance_sign.rs b/rust/tw_any_coin/tests/chains/binance/binance_sign.rs index 200d0623135..6dac43e8df6 100644 --- a/rust/tw_any_coin/tests/chains/binance/binance_sign.rs +++ b/rust/tw_any_coin/tests/chains/binance/binance_sign.rs @@ -51,6 +51,11 @@ fn test_binance_sign_trade_order() { output.encoded.to_hex(), "dc01f0625dee0a64ce6dc0430a14ba36f0fad74d8f41045463e4774f328f4af779e5122b424133364630464144373444384634313034353436334534373734463332384634414637373945352d33361a0b4e4e422d3333385f424e422002280130b09282413880c2d72f4001126e0a26eb5ae98721029729a52e4e3c2b4a4e52aa74033eedaf8ba1df5ab6d1f518fd69e67bbd309b0e12409123cb6906bb20aeb753f4a121d4d88ff0e9750ba75b0c4e10d76caee1e7d2481290fa3b9887a6225d6997f5f939ef834ea61d596a314237c48e560da9e17b5a180c20232001" ); + + let expected_signature = "9123cb6906bb20aeb753f4a121d4d88ff0e9750ba75b0c4e10d76caee1e7d2481290fa3b9887a6225d6997f5f939ef834ea61d596a314237c48e560da9e17b5a"; + assert_eq!(output.signature.to_hex(), expected_signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"ApcppS5OPCtKTlKqdAM+7a+Lod9attH1GP1p5nu9MJsO"},"signature":"kSPLaQa7IK63U/ShIdTYj/DpdQunWwxOENdsruHn0kgSkPo7mIemIl1pl/X5Oe+DTqYdWWoxQjfEjlYNqeF7Wg=="}"#; + assert_eq!(output.signature_json, expected_signature_json); } #[test] @@ -84,6 +89,11 @@ fn test_binance_sign_cancel_trade_order() { output.encoded.to_hex(), "cc01f0625dee0a54166e681b0a14ba36f0fad74d8f41045463e4774f328f4af779e5120b4e4e422d3333385f424e421a2b424133364630464144373444384634313034353436334534373734463332384634414637373945352d3336126e0a26eb5ae98721029729a52e4e3c2b4a4e52aa74033eedaf8ba1df5ab6d1f518fd69e67bbd309b0e12403df6603426b991f7040bce22ce0137c12137df01e1d4d425cf3d9104103aec6335ac05c825e08ba26b9f72aa4cc45aa75cacfb6082df86b00692fef9701eb0f5180c20242001" ); + + let expected_signature = "3df6603426b991f7040bce22ce0137c12137df01e1d4d425cf3d9104103aec6335ac05c825e08ba26b9f72aa4cc45aa75cacfb6082df86b00692fef9701eb0f5"; + assert_eq!(output.signature.to_hex(), expected_signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"ApcppS5OPCtKTlKqdAM+7a+Lod9attH1GP1p5nu9MJsO"},"signature":"PfZgNCa5kfcEC84izgE3wSE33wHh1NQlzz2RBBA67GM1rAXIJeCLomufcqpMxFqnXKz7YILfhrAGkv75cB6w9Q=="}"#; + assert_eq!(output.signature_json, expected_signature_json); } #[test] @@ -138,6 +148,11 @@ fn test_binance_sign_send_order() { ); assert_eq!(output.error, SigningError::OK); assert_eq!(output.encoded.to_hex(), expected_encoded); + + let expected_signature = "c65a13440f18a155bd971ee40b9e0dd58586f5bf344e12ec4c76c439aebca8c7789bab7bfbfb4ce89aadc4a02df225b6b6efc861c13bbeb5f7a3eea2d7ffc80f"; + assert_eq!(output.signature.to_hex(), expected_signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"Amo1kgCI2Yw4iMpoxT38k/RWRgJgbLuH8P5e5TPbOOUC"},"signature":"xloTRA8YoVW9lx7kC54N1YWG9b80ThLsTHbEOa68qMd4m6t7+/tM6JqtxKAt8iW2tu/IYcE7vrX3o+6i1//IDw=="}"#; + assert_eq!(output.signature_json, expected_signature_json); } #[test] @@ -173,6 +188,11 @@ fn test_binance_sign_token_freeze_order() { ); assert_eq!(output.error, SigningError::OK); assert_eq!(output.encoded.to_hex(), expected_encoded); + + let expected_signature = "e3022069d897bf5bf4846d354fcd2c0e85807053be643c8b8c8596306003f7340d43a162722673eb848258b0435b1f49993d0e75d4ae43d03453a3ae57fe6991"; + assert_eq!(output.signature.to_hex(), expected_signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"A6mlXAQMjrgSDz0bMhkyUIQcCK9E6lYarJk9vg9rao/H"},"signature":"4wIgadiXv1v0hG01T80sDoWAcFO+ZDyLjIWWMGAD9zQNQ6FiciZz64SCWLBDWx9JmT0OddSuQ9A0U6OuV/5pkQ=="}"#; + assert_eq!(output.signature_json, expected_signature_json); } #[test] @@ -208,6 +228,11 @@ fn test_binance_sign_token_unfreeze_order() { ); assert_eq!(output.error, SigningError::OK); assert_eq!(output.encoded.to_hex(), expected_encoded); + + let expected_signature = "e3022069d897bf5bf4846d354fcd2c0e85807053be643c8b8c8596306003f7340d43a162722673eb848258b0435b1f49993d0e75d4ae43d03453a3ae57fe6991"; + assert_eq!(output.signature.to_hex(), expected_signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"A6mlXAQMjrgSDz0bMhkyUIQcCK9E6lYarJk9vg9rao/H"},"signature":"4wIgadiXv1v0hG01T80sDoWAcFO+ZDyLjIWWMGAD9zQNQ6FiciZz64SCWLBDWx9JmT0OddSuQ9A0U6OuV/5pkQ=="}"#; + assert_eq!(output.signature_json, expected_signature_json); } #[test] @@ -245,6 +270,11 @@ fn test_binance_sign_token_issue_order() { ); assert_eq!(output.error, SigningError::OK); assert_eq!(output.encoded.to_hex(), expected_encoded); + + let expected_signature = "1fbb993d643f03b3e8e757a502035f58c4c45aaaa6e107a3059ab7c6164283c10f1254e87feee21477c64c87b1a27d8481048533ae2f685b3ac0dc66e4edbc0b"; + assert_eq!(output.signature.to_hex(), expected_signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"A6mlXAQMjrgSDz0bMhkyUIQcCK9E6lYarJk9vg9rao/H"},"signature":"H7uZPWQ/A7Po51elAgNfWMTEWqqm4QejBZq3xhZCg8EPElTof+7iFHfGTIexon2EgQSFM64vaFs6wNxm5O28Cw=="}"#; + assert_eq!(output.signature_json, expected_signature_json); } #[test] @@ -278,6 +308,11 @@ fn test_binance_sign_token_mint_order() { ); assert_eq!(output.error, SigningError::OK); assert_eq!(output.encoded.to_hex(), expected_encoded); + + let expected_signature = "e3022069d897bf5bf4846d354fcd2c0e85807053be643c8b8c8596306003f7340d43a162722673eb848258b0435b1f49993d0e75d4ae43d03453a3ae57fe6991"; + assert_eq!(output.signature.to_hex(), expected_signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"A6mlXAQMjrgSDz0bMhkyUIQcCK9E6lYarJk9vg9rao/H"},"signature":"4wIgadiXv1v0hG01T80sDoWAcFO+ZDyLjIWWMGAD9zQNQ6FiciZz64SCWLBDWx9JmT0OddSuQ9A0U6OuV/5pkQ=="}"#; + assert_eq!(output.signature_json, expected_signature_json); } #[test] @@ -311,6 +346,11 @@ fn test_binance_sign_token_burn_order() { ); assert_eq!(output.error, SigningError::OK); assert_eq!(output.encoded.to_hex(), expected_encoded); + + let expected_signature = "e3022069d897bf5bf4846d354fcd2c0e85807053be643c8b8c8596306003f7340d43a162722673eb848258b0435b1f49993d0e75d4ae43d03453a3ae57fe6991"; + assert_eq!(output.signature.to_hex(), expected_signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"A6mlXAQMjrgSDz0bMhkyUIQcCK9E6lYarJk9vg9rao/H"},"signature":"4wIgadiXv1v0hG01T80sDoWAcFO+ZDyLjIWWMGAD9zQNQ6FiciZz64SCWLBDWx9JmT0OddSuQ9A0U6OuV/5pkQ=="}"#; + assert_eq!(output.signature_json, expected_signature_json); } #[test] @@ -353,6 +393,11 @@ fn test_binance_sign_htlt_order() { ); assert_eq!(output.error, SigningError::OK); assert_eq!(output.encoded.to_hex(), expected_encoded); + + let expected_signature = "51439de2da19fe9fd22137c903cfc5dc87553bf05dca0bb202c0e07c47f9b51269efa27243eb7b55888f5384a84ac1eac6d325c830d1be0ed042838e2dc0f6a9"; + assert_eq!(output.signature.to_hex(), expected_signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"A6mlXAQMjrgSDz0bMhkyUIQcCK9E6lYarJk9vg9rao/H"},"signature":"UUOd4toZ/p/SITfJA8/F3IdVO/BdyguyAsDgfEf5tRJp76JyQ+t7VYiPU4SoSsHqxtMlyDDRvg7QQoOOLcD2qQ=="}"#; + assert_eq!(output.signature_json, expected_signature_json); } #[test] @@ -387,6 +432,11 @@ fn test_binance_sign_deposit_htlt_order() { ); assert_eq!(output.error, SigningError::OK); assert_eq!(output.encoded.to_hex(), expected_encoded); + + let expected_signature = "0ca4144c6818e2836d09b4faf3161781d85f9adfc00badb2eaa0953174610a233b81413dafcf84716abad48a4ed3aeb9884d90eb8416eec5d5c0c6930ab60bd0"; + assert_eq!(output.signature.to_hex(), expected_signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"A432lgCE4gstB9UOFCL5QQXGJB2fFIKk63nOi/1GDxnk"},"signature":"DKQUTGgY4oNtCbT68xYXgdhfmt/AC62y6qCVMXRhCiM7gUE9r8+EcWq61IpO0665iE2Q64QW7sXVwMaTCrYL0A=="}"#; + assert_eq!(output.signature_json, expected_signature_json); } #[test] @@ -422,6 +472,11 @@ fn test_binance_sign_claim_htlt_order() { ); assert_eq!(output.error, SigningError::OK); assert_eq!(output.encoded.to_hex(), expected_encoded); + + let expected_signature = "fa30ba50111aa31d8329dacb6d044c1c7d54f1cb782bc9aa2a50c3fabce02a4579d75b76ca69a9fab11b676d9da66b5af7aa4c9ad3d18e24fffeb16433be39fb"; + assert_eq!(output.signature.to_hex(), expected_signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"A6mlXAQMjrgSDz0bMhkyUIQcCK9E6lYarJk9vg9rao/H"},"signature":"+jC6UBEaox2DKdrLbQRMHH1U8ct4K8mqKlDD+rzgKkV511t2ymmp+rEbZ22dpmta96pMmtPRjiT//rFkM745+w=="}"#; + assert_eq!(output.signature_json, expected_signature_json); } #[test] @@ -455,6 +510,11 @@ fn test_binance_sign_refund_htlt_order() { ); assert_eq!(output.error, SigningError::OK); assert_eq!(output.encoded.to_hex(), expected_encoded); + + let expected_signature = "c9f36142534d16ec8ce656f8eb7370b32206a2d15198b7165acf1e2a18952c9e4570b0f862e1ab7bb868c30781a42c9e3ec0ae08982e8d6c91c55b83c71b7b1e"; + assert_eq!(output.signature.to_hex(), expected_signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"A6mlXAQMjrgSDz0bMhkyUIQcCK9E6lYarJk9vg9rao/H"},"signature":"yfNhQlNNFuyM5lb463NwsyIGotFRmLcWWs8eKhiVLJ5FcLD4YuGre7howweBpCyePsCuCJgujWyRxVuDxxt7Hg=="}"#; + assert_eq!(output.signature_json, expected_signature_json); } #[test] @@ -490,6 +550,11 @@ fn test_binance_sign_transfer_out_order() { ); assert_eq!(output.error, SigningError::OK); assert_eq!(output.encoded.to_hex(), expected_encoded); + + let expected_signature = "7eda148e1167b1be1271a788ccf4e3eade1c7e1773e9d2093982d7f802f8f85f35ef550049011728206e4eda1a272f9e96fd95ef3983cad85a29cd14262c22e0"; + assert_eq!(output.signature.to_hex(), expected_signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"A6mlXAQMjrgSDz0bMhkyUIQcCK9E6lYarJk9vg9rao/H"},"signature":"ftoUjhFnsb4ScaeIzPTj6t4cfhdz6dIJOYLX+AL4+F8171UASQEXKCBuTtoaJy+elv2V7zmDythaKc0UJiwi4A=="}"#; + assert_eq!(output.signature_json, expected_signature_json); } #[test] @@ -526,6 +591,11 @@ fn test_binance_sign_side_chain_delegate_order() { ); assert_eq!(output.error, SigningError::OK); assert_eq!(output.encoded.to_hex(), expected_encoded); + + let expected_signature = "39302c9975fb2a09ac2b6b6fb1d3b9fb5b4c03630d3d7a7da42b1c6736d6127142a3fcdca0b70a3d065da8d4f4df8b5d9d8f46aeb3627a7d7aa901fe186af34c"; + assert_eq!(output.signature.to_hex(), expected_signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"A6mlXAQMjrgSDz0bMhkyUIQcCK9E6lYarJk9vg9rao/H"},"signature":"OTAsmXX7KgmsK2tvsdO5+1tMA2MNPXp9pCscZzbWEnFCo/zcoLcKPQZdqNT034tdnY9GrrNien16qQH+GGrzTA=="}"#; + assert_eq!(output.signature_json, expected_signature_json); } #[test] @@ -565,6 +635,11 @@ fn test_binance_sign_side_chain_redelegate_order() { ); assert_eq!(output.error, SigningError::OK); assert_eq!(output.encoded.to_hex(), expected_encoded); + + let expected_signature = "114c6927423e95ecc831ec763b629b3a40db8feeb330528a941fd74843c0d63b4271b23916770d4901988c1f56b20086e5768a12290ebec265e30a80f8f3d88e"; + assert_eq!(output.signature.to_hex(), expected_signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"A6mlXAQMjrgSDz0bMhkyUIQcCK9E6lYarJk9vg9rao/H"},"signature":"EUxpJ0I+lezIMex2O2KbOkDbj+6zMFKKlB/XSEPA1jtCcbI5FncNSQGYjB9WsgCG5XaKEikOvsJl4wqA+PPYjg=="}"#; + assert_eq!(output.signature_json, expected_signature_json); } #[test] @@ -601,6 +676,11 @@ fn test_binance_sign_side_chain_undelegate_order() { ); assert_eq!(output.error, SigningError::OK); assert_eq!(output.encoded.to_hex(), expected_encoded); + + let expected_signature = "a622b7ca7a2875e5eaa675a5ed976b2ec3b8ca055a2b05e7fb471d328bd04df854789437dd06407e41ebb1e5a345604c93663dfb660e223800636c0b94c2e798"; + assert_eq!(output.signature.to_hex(), expected_signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"A6mlXAQMjrgSDz0bMhkyUIQcCK9E6lYarJk9vg9rao/H"},"signature":"piK3ynoodeXqpnWl7ZdrLsO4ygVaKwXn+0cdMovQTfhUeJQ33QZAfkHrseWjRWBMk2Y9+2YOIjgAY2wLlMLnmA=="}"#; + assert_eq!(output.signature_json, expected_signature_json); } #[test] @@ -633,6 +713,11 @@ fn test_binance_sign_time_lock_order() { ); assert_eq!(output.error, SigningError::OK); assert_eq!(output.encoded.to_hex(), expected_encoded); + + let expected_signature = "c270822b9515ba486c6a6b3472d388a5aea872ed960c0b53de0fafdc8682ef473a126f01e7dd2c00f04a0138a601b9540f54b14026846de362f7ab7f9fed948b"; + assert_eq!(output.signature.to_hex(), expected_signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"A6mlXAQMjrgSDz0bMhkyUIQcCK9E6lYarJk9vg9rao/H"},"signature":"wnCCK5UVukhsams0ctOIpa6ocu2WDAtT3g+v3IaC70c6Em8B590sAPBKATimAblUD1SxQCaEbeNi96t/n+2Uiw=="}"#; + assert_eq!(output.signature_json, expected_signature_json); } #[test] @@ -668,6 +753,11 @@ fn test_binance_sign_time_relock_order() { ); assert_eq!(output.error, SigningError::OK); assert_eq!(output.encoded.to_hex(), expected_encoded); + + let expected_signature = "86ddaa077c8ae551d402fa409cf7e91663982b0542200967c03c0b5876b181353250f689d342f2217624a077b671ce7d09649187e29879f40abbbee9de7ab27c"; + assert_eq!(output.signature.to_hex(), expected_signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"A6mlXAQMjrgSDz0bMhkyUIQcCK9E6lYarJk9vg9rao/H"},"signature":"ht2qB3yK5VHUAvpAnPfpFmOYKwVCIAlnwDwLWHaxgTUyUPaJ00LyIXYkoHe2cc59CWSRh+KYefQKu77p3nqyfA=="}"#; + assert_eq!(output.signature_json, expected_signature_json); } #[test] @@ -699,4 +789,9 @@ fn test_binance_sign_time_unlock_order() { ); assert_eq!(output.error, SigningError::OK); assert_eq!(output.encoded.to_hex(), expected_encoded); + + let expected_signature = "da777bfd2032834f59ec9fe69fd6eaa4aca24242dfbc5ec4ef8c435cb9da7eb05ab78e1b8ca9f109657cb77996898f1b59137b3d8f1e00f842e409e18033b347"; + assert_eq!(output.signature.to_hex(), expected_signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"A6mlXAQMjrgSDz0bMhkyUIQcCK9E6lYarJk9vg9rao/H"},"signature":"2nd7/SAyg09Z7J/mn9bqpKyiQkLfvF7E74xDXLnafrBat44bjKnxCWV8t3mWiY8bWRN7PY8eAPhC5AnhgDOzRw=="}"#; + assert_eq!(output.signature_json, expected_signature_json); } diff --git a/rust/tw_any_coin/tests/chains/binance/binance_wallet_connect.rs b/rust/tw_any_coin/tests/chains/binance/binance_wallet_connect.rs index 9fc46559d85..694b5e8af8e 100644 --- a/rust/tw_any_coin/tests/chains/binance/binance_wallet_connect.rs +++ b/rust/tw_any_coin/tests/chains/binance/binance_wallet_connect.rs @@ -9,7 +9,7 @@ use std::borrow::Cow; use tw_any_coin::test_utils::sign_utils::AnySignerHelper; use tw_any_coin::test_utils::wallet_connect_utils::WalletConnectRequestHelper; use tw_coin_registry::coin_type::CoinType; -use tw_encoding::hex::DecodeHex; +use tw_encoding::hex::{DecodeHex, ToHex}; use tw_proto::Binance::Proto::{self, mod_SigningInput::OneOforder_oneof as MessageEnum}; use tw_proto::Common::Proto::SigningError; use tw_proto::WalletConnect::Proto as WCProto; @@ -46,8 +46,8 @@ fn test_binance_sign_wallet_connect_case_1() { }; let expected_signing_input = Proto::SigningInput { chain_id: "chain-bnb".into(), - account_number: 12, - sequence: 35, + account_number: 19, + sequence: 23, source: 1, memo: "".into(), private_key: Cow::default(), @@ -62,5 +62,8 @@ fn test_binance_sign_wallet_connect_case_1() { let signing_output = signer.sign(CoinType::Binance, signing_input); assert_eq!(signing_output.error, SigningError::OK); - // TODO check the signature. + let expected_signature = "3c24c784c6bbf99d54ffabb153edcb6d3c4a774936df5c72a5d32897256f8e062f320fb4753302fb0a96f08c475974d20edfd1a27bbeeda73587f58ddc958975"; + assert_eq!(signing_output.signature.to_hex(), expected_signature); + let expected_signature_json = r#"{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"Amo1kgCI2Yw4iMpoxT38k/RWRgJgbLuH8P5e5TPbOOUC"},"signature":"PCTHhMa7+Z1U/6uxU+3LbTxKd0k231xypdMolyVvjgYvMg+0dTMC+wqW8IxHWXTSDt/Ronu+7ac1h/WN3JWJdQ=="}"#; + assert_eq!(signing_output.signature_json, expected_signature_json); } diff --git a/rust/tw_any_coin/tests/chains/binance/data/wc_sign_request_case_1.json b/rust/tw_any_coin/tests/chains/binance/data/wc_sign_request_case_1.json index e3a5f4134ea..3e070de9aef 100644 --- a/rust/tw_any_coin/tests/chains/binance/data/wc_sign_request_case_1.json +++ b/rust/tw_any_coin/tests/chains/binance/data/wc_sign_request_case_1.json @@ -1,7 +1,7 @@ { "signerAddress": "bnb1grpf0955h0ykzq3ar5nmum7y6gdfl6lxfn46h2", "signDoc": { - "account_number": "12", + "account_number": "19", "chain_id": "chain-bnb", "memo": "", "data": null, @@ -31,7 +31,7 @@ ] } ], - "sequence": "35", + "sequence": "23", "source": "1" } } \ No newline at end of file diff --git a/rust/tw_cosmos_sdk/src/public_key/secp256k1.rs b/rust/tw_cosmos_sdk/src/public_key/secp256k1.rs index 3558aba8626..230582a8472 100644 --- a/rust/tw_cosmos_sdk/src/public_key/secp256k1.rs +++ b/rust/tw_cosmos_sdk/src/public_key/secp256k1.rs @@ -14,10 +14,21 @@ use tw_memory::Data; use tw_misc::traits::ToBytesVec; use tw_proto::{google, to_any}; +#[derive(Clone)] pub struct Secp256PublicKey { public_key: Data, } +impl Secp256PublicKey { + pub fn from_secp256k1_public_key( + coin: &dyn CoinContext, + public_key: &secp256k1::PublicKey, + ) -> KeyPairResult { + let public_key = prepare_secp256k1_public_key(coin, public_key.compressed().as_slice())?; + Ok(Secp256PublicKey { public_key }) + } +} + impl CosmosPublicKey for Secp256PublicKey { fn from_private_key(coin: &dyn CoinContext, private_key: &tw::PrivateKey) -> KeyPairResult where diff --git a/src/proto/Binance.proto b/src/proto/Binance.proto index 00df9f21fd2..01aa30a3698 100644 --- a/src/proto/Binance.proto +++ b/src/proto/Binance.proto @@ -382,4 +382,10 @@ message SigningOutput { // error description in case of error string error_message = 3; + + // Signature bytes. + bytes signature = 4; + + // Signature JSON string. + string signature_json = 5; }