Skip to content

Commit

Permalink
[SUI]: Move SUI blockchain to Rust (#3769)
Browse files Browse the repository at this point in the history
* feat(Sui): Add Sui Rust skeleton files

* feat(ronin): reorganize tw_aptos, tw_ethereum, tw_ronin, tw_internet_computer

* feat(ronin): Implement `SuiAddress`

* feat(sui): Implement pay, paySui, payAllSui, request_addStake, request_withdrawStake

* feat(sui): Add Protobuf transaction types

* feat(sui): Remove unnecessary derives

* feat(sui): Implement direct signing

* feat(merlin): Change symbol from ETH to BTC

* feat(sui): Add direct sign tests

* feat(solana): Add delegate stake with priority fee test

* feat(sui): Add pay_sui, pay_all_sui, pay, request_add_stake, request_withdraw_stake

* feat(sui): Implement transaction preimage and compile functions

* feat(sui): Add `pay` and `pay_sui` tests

* feat(sui): Add split, merge sui and token tests

* feat(sui): Add pay_all_sui test

* feat(sui): Add request_addStake test

* feat(sui): Fix direct signing to support legacy tests

* feat(sui): Add compile test

* feat(sui): Add compile direct test

* feat(sui): Replace C++ implementation with Rust FFI

* feat(sui): Add `test_sui_sign_undelegate_sui` test

* feat(sui): Add Android, iOS tests

* feat(sui): Fix tests

* Add fuzz tests

* feat(sui): Add TransferObject transaction type

* Add fuzz tests

* feat(sui): Comment TransferObject Protobuf message

* feat(sui): Fix C++ includes
  • Loading branch information
satoshiotomakan authored Apr 11, 2024
1 parent 41bd373 commit 49a36fc
Show file tree
Hide file tree
Showing 122 changed files with 2,890 additions and 467 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class TestSuiSigner {
}

@Test
fun SuiTransactionSigning() {
fun testSuiDirectSigning() {
// Successfully broadcasted https://explorer.sui.io/txblock/HkPo6rYPyDY53x1MBszvSZVZyixVN7CHvCJGX381czAh?network=devnet
val txBytes = """
AAACAAgQJwAAAAAAAAAgJZ/4B0q0Jcu0ifI24Y4I8D8aeFa998eih3vWT3OLUBUCAgABAQAAAQEDAAAAAAEBANV1rX8Y6UhGKlz2mPVk7zlKdSpx/sYkk6+KBVwBLA1QAQbywsjB2JZN8QGdZhbpcFcZvrq9kx2idVy5SM635olk7AIAAAAAAAAgYEVuxmf1zRBGdoDr+VDtMpIFF12s2Ua7I2ru1XyGF8/Vda1/GOlIRipc9pj1ZO85SnUqcf7GJJOvigVcASwNUAEAAAAAAAAA0AcAAAAAAAAA
Expand All @@ -37,4 +37,37 @@ class TestSuiSigner {
assertEquals(result.unsignedTx, txBytes);
assertEquals(result.signature, expectedSignature)
}

@Test
fun testSuiTransfer() {
// Successfully broadcasted: https://suiscan.xyz/mainnet/tx/D4Ay9TdBJjXkGmrZSstZakpEWskEQHaWURP6xWPRXbAm
val txBytes = """
AAAEAAjoAwAAAAAAAAAIUMMAAAAAAAAAIKcXWr3V7ZLr4605DbNmxqcGR4zfUXzebPmGMAZc2jd6ACBU6A1215DCd/WkTzzpL1PSb1iUiSvzld7mN1mIh2vmsgMCAAIBAAABAQABAQMAAAAAAQIAAQEDAAABAAEDAFToDXbXkMJ39aRPPOkvU9JvWJSJK/OV3uY3WYiHa+ayAWNgILOn3HsRw6pvQZsX+KnBLn95ox0b3S3mcLTt1jAFeHEaBQAAAAAgGGuNnxrqusosgjP3gQ3jBjnhapGNBlcU0yTaupXpa0BU6A1215DCd/WkTzzpL1PSb1iUiSvzld7mN1mIh2vmsu4CAAAAAAAAwMYtAAAAAAAA
""".trimIndent()
val key =
"7e6682f7bf479ef0f627823cffd4e1a940a7af33e5fb39d9e0f631d2ecc5daff".toHexBytesInByteString()

val paySui = Sui.PaySui.newBuilder()
.addInputCoins(Sui.ObjectRef.newBuilder().apply {
objectId = "0x636020b3a7dc7b11c3aa6f419b17f8a9c12e7f79a31d1bdd2de670b4edd63005"
version = 85619064
objectDigest = "2eKuWbZSVfpFVfg8FXY9wP6W5AFXnTchSoUdp7obyYZ5"
})
.addRecipients("0xa7175abdd5ed92ebe3ad390db366c6a706478cdf517cde6cf98630065cda377a")
.addRecipients("0x54e80d76d790c277f5a44f3ce92f53d26f5894892bf395dee6375988876be6b2")
.addAmounts(1000)
.addAmounts(50000)

val signingInput = Sui.SigningInput.newBuilder()
.setPaySui(paySui)
.setPrivateKey(key)
.setGasBudget(3000000)
.setReferenceGasPrice(750)
.build()

val result = AnySigner.sign(signingInput, CoinType.SUI, Sui.SigningOutput.parser())
val expectedSignature = "AEh44B7iGArEHF1wOLAQJMLNgGnaIwn3gKPC92vtDJqITDETAM5z9plaxio1xomt6/cZReQ5FZaQsMC6l7E0BwmF69FEH+T5VPvl3GB3vwCOEZpeJpKXxvcIPQAdKsh2/g=="
assertEquals(result.unsignedTx, txBytes);
assertEquals(result.signature, expectedSignature)
}
}
17 changes: 17 additions & 0 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
[workspace]
members = [
"chains/tw_aptos",
"chains/tw_binance",
"chains/tw_cosmos",
"chains/tw_ethereum",
"chains/tw_internet_computer",
"chains/tw_greenfield",
"chains/tw_native_evmos",
"chains/tw_native_injective",
"chains/tw_ronin",
"chains/tw_solana",
"chains/tw_sui",
"chains/tw_thorchain",
"tw_any_coin",
"tw_aptos",
"tw_bech32_address",
"tw_bitcoin",
"tw_coin_entry",
"tw_coin_registry",
"tw_cosmos_sdk",
"tw_encoding",
"tw_ethereum",
"tw_evm",
"tw_hash",
"tw_internet_computer",
"tw_keypair",
"tw_memory",
"tw_misc",
"tw_number",
"tw_proto",
"tw_ronin",
"tw_utxo",
"wallet_core_rs",
]
Expand Down
22 changes: 22 additions & 0 deletions rust/chains/tw_aptos/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "tw_aptos"
version = "0.1.0"
edition = "2021"

[dependencies]
serde_json = "1.0"
tw_coin_entry = { path = "../../tw_coin_entry" }
tw_encoding = { path = "../../tw_encoding" }
tw_keypair = { path = "../../tw_keypair" }
tw_proto = { path = "../../tw_proto" }
tw_number = { path = "../../tw_number" }
tw_hash = { path = "../../tw_hash" }
tw_memory = { path = "../../tw_memory" }
move-core-types = { git = "https://github.com/move-language/move", rev = "ea70797099baea64f05194a918cebd69ed02b285", features = ["address32"] }
serde = { version = "1.0", features = ["derive"] }
serde_bytes = "0.11.12"

[dev-dependencies]
tw_coin_entry = { path = "../../tw_coin_entry", features = ["test-utils"] }
tw_encoding = { path = "../../tw_encoding" }
tw_number = { path = "../../tw_number", features = ["helpers"] }
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,11 @@ use move_core_types::account_address::{AccountAddress, AccountAddressParseError}
use std::fmt::{Display, Formatter};
use std::str::FromStr;
use tw_coin_entry::coin_entry::CoinAddress;
use tw_coin_entry::error::{AddressError, AddressResult};
use tw_coin_entry::error::AddressError;
use tw_hash::sha3::sha3_256;
use tw_keypair::ed25519;
use tw_memory::Data;

pub trait AptosAddress: FromStr<Err = AddressError> + Into<Address> {
/// Tries to parse an address from the string representation.
/// Returns `Ok(None)` if the given `s` string is empty.
#[inline]
fn from_str_optional(s: &str) -> AddressResult<Option<Self>> {
if s.is_empty() {
return Ok(None);
}

Self::from_str(s).map(Some)
}
}

impl AptosAddress for Address {}

#[repr(u8)]
pub enum Scheme {
Ed25519 = 0,
Expand All @@ -38,8 +23,8 @@ pub struct Address {

impl Address {
pub const LENGTH: usize = AccountAddress::LENGTH;
/// Initializes an address with a `ed25519` public key.

/// Initializes an address with a `ed25519` public key.
pub fn with_ed25519_pubkey(
pubkey: &ed25519::sha512::PublicKey,
) -> Result<Address, AddressError> {
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
10 changes: 5 additions & 5 deletions rust/chains/tw_binance/src/transaction/message/htlt_order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub struct HTLTOrder {
pub expected_income: String,
pub from: BinanceAddress,
pub height_span: i64,
#[serde(serialize_with = "as_hex")]
#[serde(with = "as_hex")]
pub random_number_hash: Data,
pub recipient_other_chain: String,
pub sender_other_chain: String,
Expand Down Expand Up @@ -84,7 +84,7 @@ impl TWBinanceProto for HTLTOrder {
pub struct DepositHTLTOrder {
pub amount: Vec<Token>,
pub from: BinanceAddress,
#[serde(serialize_with = "as_hex")]
#[serde(with = "as_hex")]
pub swap_id: Data,
}

Expand Down Expand Up @@ -127,9 +127,9 @@ impl TWBinanceProto for DepositHTLTOrder {
#[derive(Deserialize, Serialize)]
pub struct ClaimHTLTOrder {
pub from: BinanceAddress,
#[serde(serialize_with = "as_hex")]
#[serde(with = "as_hex")]
pub random_number: Data,
#[serde(serialize_with = "as_hex")]
#[serde(with = "as_hex")]
pub swap_id: Data,
}

Expand Down Expand Up @@ -171,7 +171,7 @@ impl TWBinanceProto for ClaimHTLTOrder {
#[derive(Deserialize, Serialize)]
pub struct RefundHTLTOrder {
pub from: BinanceAddress,
#[serde(serialize_with = "as_hex")]
#[serde(with = "as_hex")]
pub swap_id: Data,
}

Expand Down
15 changes: 15 additions & 0 deletions rust/chains/tw_ethereum/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "tw_ethereum"
version = "0.1.0"
edition = "2021"

[dependencies]
tw_coin_entry = { path = "../../tw_coin_entry" }
tw_evm = { path = "../../tw_evm" }
tw_keypair = { path = "../../tw_keypair" }
tw_proto = { path = "../../tw_proto" }

[dev-dependencies]
tw_coin_entry = { path = "../../tw_coin_entry", features = ["test-utils"] }
tw_encoding = { path = "../../tw_encoding" }
tw_number = { path = "../../tw_number", features = ["helpers"] }
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
17 changes: 17 additions & 0 deletions rust/chains/tw_internet_computer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "tw_internet_computer"
version = "0.1.0"
edition = "2021"

[dependencies]
quick-protobuf = "0.8.1"
serde = { version = "1.0", features = ["derive"] }
tw_coin_entry = { path = "../../tw_coin_entry" }
tw_encoding = { path = "../../tw_encoding" }
tw_hash = { path = "../../tw_hash" }
tw_keypair = { path = "../../tw_keypair" }
tw_memory = { path = "../../tw_memory" }
tw_proto = { path = "../../tw_proto" }

[build-dependencies]
pb-rs = "0.10.0"
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
16 changes: 16 additions & 0 deletions rust/chains/tw_ronin/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "tw_ronin"
version = "0.1.0"
edition = "2021"

[dependencies]
tw_coin_entry = { path = "../../tw_coin_entry" }
tw_evm = { path = "../../tw_evm" }
tw_keypair = { path = "../../tw_keypair" }
tw_memory = { path = "../../tw_memory" }
tw_proto = { path = "../../tw_proto" }

[dev-dependencies]
tw_coin_entry = { path = "../../tw_coin_entry", features = ["test-utils"] }
tw_encoding = { path = "../../tw_encoding" }
tw_number = { path = "../../tw_number", features = ["helpers"] }
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
16 changes: 16 additions & 0 deletions rust/chains/tw_sui/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "tw_sui"
version = "0.1.0"
edition = "2021"

[dependencies]
indexmap = "2.0"
move-core-types = { git = "https://github.com/move-language/move", rev = "ea70797099baea64f05194a918cebd69ed02b285", features = ["address32"] }
serde = { version = "1.0", features = ["derive"] }
serde_repr = "0.1"
tw_coin_entry = { path = "../../tw_coin_entry" }
tw_encoding = { path = "../../tw_encoding" }
tw_hash = { path = "../../tw_hash" }
tw_keypair = { path = "../../tw_keypair" }
tw_memory = { path = "../../tw_memory" }
tw_proto = { path = "../../tw_proto" }
5 changes: 5 additions & 0 deletions rust/chains/tw_sui/fuzz/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
target
corpus
artifacts
coverage
Cargo.lock
30 changes: 30 additions & 0 deletions rust/chains/tw_sui/fuzz/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[package]
name = "tw_sui-fuzz"
version = "0.0.0"
publish = false
edition = "2021"

[package.metadata]
cargo-fuzz = true

[dependencies]
libfuzzer-sys = "0.4"
tw_any_coin = { path = "../../../tw_any_coin", features = ["test-utils"] }
tw_coin_registry = { path = "../../../tw_coin_registry" }
tw_proto = { path = "../../../tw_proto", features = ["fuzz"] }

[dependencies.tw_sui]
path = ".."

# Prevent this from interfering with workspaces
[workspace]
members = ["."]

[profile.release]
debug = 1

[[bin]]
name = "sign"
path = "fuzz_targets/sign.rs"
test = false
doc = false
15 changes: 15 additions & 0 deletions rust/chains/tw_sui/fuzz/fuzz_targets/sign.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: Apache-2.0
//
// Copyright © 2017 Trust Wallet.

#![no_main]

use libfuzzer_sys::fuzz_target;
use tw_any_coin::test_utils::sign_utils::AnySignerHelper;
use tw_coin_registry::coin_type::CoinType;
use tw_proto::Sui::Proto;

fuzz_target!(|input: Proto::SigningInput<'_>| {
let mut signer = AnySignerHelper::<Proto::SigningOutput>::default();
let _ = signer.sign(CoinType::Sui, input);
});
Loading

0 comments on commit 49a36fc

Please sign in to comment.