Skip to content

Commit

Permalink
Merge branch 'master' into s/update-copyright-2024
Browse files Browse the repository at this point in the history
  • Loading branch information
satoshiotomakan committed Jan 11, 2024
2 parents 0cd8a29 + 8f8a266 commit 2284e93
Show file tree
Hide file tree
Showing 64 changed files with 1,685 additions and 832 deletions.
1 change: 1 addition & 0 deletions .github/workflows/codegen-v2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ Swift for iOS and Java (Kotlin) for Android.

For comprehensive documentation, see [developer.trustwallet.com](https://developer.trustwallet.com/wallet-core).

# Audit Reports

Security Audit reports can be found in the [audit](audit) directory.

# Supported Blockchains

Wallet Core supports more than **130** blockchains: Bitcoin, Ethereum, BNB, Cosmos, Solana, and most major blockchain platforms.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.trustwallet.core.app.blockchains.binance

import com.google.protobuf.ByteString
import com.trustwallet.core.app.utils.toHexBytes
import org.junit.Assert.assertEquals
import org.junit.Test
import wallet.core.jni.proto.Binance.SigningOutput
import wallet.core.jni.proto.WalletConnect
import wallet.core.jni.*
import wallet.core.jni.CoinType.BINANCE
import wallet.core.java.AnySigner
import wallet.core.jni.proto.Common

class TestBinanceWalletConnectSigning {
init {
System.loadLibrary("TrustWalletCore")
}

@Test
fun testSignBinanceTransactionFromWalletConnectRequest() {
// Step 1: Parse a signing request received through WalletConnect.

val parsingInput = WalletConnect.ParseRequestInput.newBuilder().apply {
method = WalletConnect.Method.CosmosSignAmino
payload = "{\"signerAddress\":\"bnb1grpf0955h0ykzq3ar5nmum7y6gdfl6lxfn46h2\",\"signDoc\":{\"account_number\":\"19\",\"chain_id\":\"chain-bnb\",\"memo\":\"\",\"data\":null,\"msgs\":[{\"inputs\":[{\"address\":\"bnb1grpf0955h0ykzq3ar5nmum7y6gdfl6lxfn46h2\",\"coins\":[{\"amount\":1001000000,\"denom\":\"BNB\"}]}],\"outputs\":[{\"address\":\"bnb13zeh6hs97d5eu2s5qerguhv8ewwue6u4ywa6yf\",\"coins\":[{\"amount\":1001000000,\"denom\":\"BNB\"}]}]}],\"sequence\":\"23\",\"source\":\"1\"}}"
}.build()

val parsingOutputBytes = WalletConnectRequest.parse(BINANCE, parsingInput.toByteArray())
val parsingOutput = WalletConnect.ParseRequestOutput.parseFrom(parsingOutputBytes)

assertEquals(parsingOutput.error, Common.SigningError.OK)

// Step 2: Set missing fields.

val signingInput = parsingOutput.binance.toBuilder().apply {
privateKey = ByteString.copyFrom("95949f757db1f57ca94a5dff23314accbe7abee89597bf6a3c7382c84d7eb832".toHexBytes())
}.build()

// Step 3: Sign the transaction.

val output = AnySigner.sign(signingInput, BINANCE, SigningOutput.parser())

assertEquals(output.error, Common.SigningError.OK)
assertEquals(output.signatureJson, "{\"pub_key\":{\"type\":\"tendermint/PubKeySecp256k1\",\"value\":\"Amo1kgCI2Yw4iMpoxT38k/RWRgJgbLuH8P5e5TPbOOUC\"},\"signature\":\"PCTHhMa7+Z1U/6uxU+3LbTxKd0k231xypdMolyVvjgYvMg+0dTMC+wqW8IxHWXTSDt/Ronu+7ac1h/WN3JWJdQ==\"}")
}
}
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use tw_coin_entry::error::AddressResult;
use tw_coin_entry::modules::json_signer::NoJsonSigner;
use tw_coin_entry::modules::message_signer::NoMessageSigner;
use tw_coin_entry::modules::plan_builder::NoPlanBuilder;
use tw_coin_entry::modules::wallet_connector::NoWalletConnector;
use tw_coin_entry::prefix::NoPrefix;
use tw_keypair::tw::PublicKey;
use tw_proto::{BLOCKCHAIN}::Proto;
Expand All @@ -33,6 +34,7 @@ impl CoinEntry for {BLOCKCHAIN}Entry {
type JsonSigner = NoJsonSigner;
type PlanBuilder = NoPlanBuilder;
type MessageSigner = NoMessageSigner;
type WalletConnector = NoWalletConnector;

#[inline]
fn parse_address(
Expand Down
25 changes: 25 additions & 0 deletions include/TrustWalletCore/TWWalletConnectRequest.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: Apache-2.0
//
// Copyright © 2017 Trust Wallet.

#pragma once

#include "TWBase.h"
#include "TWCoinType.h"
#include "TWData.h"

TW_EXTERN_C_BEGIN

/// Represents a WalletConnect signing request.
TW_EXPORT_CLASS
struct TWWalletConnectRequest;

/// Parses the WalletConnect signing request as a `SigningInput`.
///
/// \param coin The given coin type to plan the transaction for.
/// \param input The serialized data of a `WalletConnect::Proto::ParseRequestInput` proto object.
/// \return The serialized data of `WalletConnect::Proto::ParseRequestOutput` proto object.
TW_EXPORT_STATIC_METHOD
TWData* _Nonnull TWWalletConnectRequestParse(enum TWCoinType coin, TWData* _Nonnull input);

TW_EXTERN_C_END
2 changes: 1 addition & 1 deletion rust/chains/tw_binance/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ tw_evm = { path = "../../tw_evm" }
tw_hash = { path = "../../tw_hash" }
tw_keypair = { path = "../../tw_keypair" }
tw_memory = { path = "../../tw_memory" }
tw_misc = { path = "../../tw_misc" }
tw_misc = { path = "../../tw_misc", features = ["serde"] }
tw_proto = { path = "../../tw_proto" }
15 changes: 13 additions & 2 deletions rust/chains/tw_binance/src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
//
// Copyright © 2017 Trust Wallet.

use serde::Serialize;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::str::FromStr;
use tw_bech32_address::bech32_prefix::Bech32Prefix;
use tw_bech32_address::Bech32Address;
use tw_coin_entry::coin_context::CoinContext;
use tw_coin_entry::coin_entry::CoinAddress;
use tw_coin_entry::error::{AddressError, AddressResult};
use tw_cosmos_sdk::address::CosmosAddress;
use tw_keypair::tw::PublicKey;
use tw_memory::Data;

Expand All @@ -19,7 +20,7 @@ const BNB_KNOWN_HRPS: [&str; 2] = [
"bca",
];

#[derive(Serialize)]
#[derive(Deserialize, PartialEq, Serialize)]
pub struct BinanceAddress(Bech32Address);

impl CoinAddress for BinanceAddress {
Expand All @@ -29,6 +30,16 @@ impl CoinAddress for BinanceAddress {
}
}

impl CosmosAddress for BinanceAddress {
fn from_str_with_coin(coin: &dyn CoinContext, addr: &str) -> AddressResult<Self>
where
Self: Sized,
{
let prefix = None;
Self::from_str_with_coin_and_prefix(coin, addr.to_string(), prefix)
}
}

impl BinanceAddress {
pub const VALIDATOR_HRP: &'static str = "bva";

Expand Down
20 changes: 17 additions & 3 deletions rust/chains/tw_binance/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//
// Copyright © 2017 Trust Wallet.

use crate::context::BinanceContext;
use crate::modules::preimager::{JsonPreimager, JsonTxPreimage};
use crate::modules::serializer::BinanceAminoSerializer;
use crate::modules::tx_builder::TxBuilder;
Expand All @@ -10,9 +11,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;

Expand Down Expand Up @@ -67,7 +71,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::<BinanceContext>::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 {
Expand All @@ -77,8 +87,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()
})
}
Expand Down
21 changes: 21 additions & 0 deletions rust/chains/tw_binance/src/context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: Apache-2.0
//
// Copyright © 2017 Trust Wallet.

use crate::address::BinanceAddress;
use tw_cosmos_sdk::context::CosmosContext;
use tw_cosmos_sdk::hasher::sha256_hasher::Sha256Hasher;
use tw_cosmos_sdk::private_key::secp256k1::Secp256PrivateKey;
use tw_cosmos_sdk::public_key::secp256k1::Secp256PublicKey;
use tw_cosmos_sdk::signature::secp256k1::Secp256k1Signature;

pub struct BinanceContext;

impl CosmosContext for BinanceContext {
type Address = BinanceAddress;
/// Binance Beacon chain uses `sha256` hash.
type TxHasher = Sha256Hasher;
type PrivateKey = Secp256PrivateKey;
type PublicKey = Secp256PublicKey;
type Signature = Secp256k1Signature;
}
7 changes: 7 additions & 0 deletions rust/chains/tw_binance/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use crate::address::BinanceAddress;
use crate::compiler::BinanceCompiler;
use crate::modules::wallet_connect::connector::BinanceWalletConnector;
use crate::signer::BinanceSigner;
use std::str::FromStr;
use tw_bech32_address::bech32_prefix::Bech32Prefix;
Expand Down Expand Up @@ -31,6 +32,7 @@ impl CoinEntry for BinanceEntry {
type JsonSigner = NoJsonSigner;
type PlanBuilder = NoPlanBuilder;
type MessageSigner = NoMessageSigner;
type WalletConnector = BinanceWalletConnector;

#[inline]
fn parse_address(
Expand Down Expand Up @@ -86,4 +88,9 @@ impl CoinEntry for BinanceEntry {
) -> Self::SigningOutput {
BinanceCompiler::compile(coin, input, signatures, public_keys)
}

#[inline]
fn wallet_connector(&self) -> Option<Self::WalletConnector> {
Some(BinanceWalletConnector)
}
}
1 change: 1 addition & 0 deletions rust/chains/tw_binance/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
pub mod address;
pub mod amino;
pub mod compiler;
pub mod context;
pub mod entry;
pub mod modules;
pub mod signature;
Expand Down
1 change: 1 addition & 0 deletions rust/chains/tw_binance/src/modules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
pub mod preimager;
pub mod serializer;
pub mod tx_builder;
pub mod wallet_connect;
8 changes: 4 additions & 4 deletions rust/chains/tw_binance/src/modules/serializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,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;
Expand All @@ -25,7 +25,7 @@ impl BinanceAminoSerializer {
.unsigned
.msgs
.iter()
.map(|msg| msg.to_amino_protobuf().map(Cow::from))
.map(|msg| msg.as_ref().to_amino_protobuf().map(Cow::from))
.collect::<SigningResult<Vec<_>>>()?;

let signature = Self::serialize_signature(tx)?;
Expand All @@ -41,7 +41,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.
Expand All @@ -52,7 +52,7 @@ impl BinanceAminoSerializer {

pub fn serialize_signature(signed: &SignedTransaction) -> SigningResult<Data> {
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,
Expand Down
Loading

0 comments on commit 2284e93

Please sign in to comment.