Skip to content

Commit 49a36fc

Browse files
[SUI]: Move SUI blockchain to Rust (#3769)
* 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
1 parent 41bd373 commit 49a36fc

File tree

122 files changed

+2890
-467
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

122 files changed

+2890
-467
lines changed

android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/sui/TestSuiSigner.kt

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class TestSuiSigner {
2222
}
2323

2424
@Test
25-
fun SuiTransactionSigning() {
25+
fun testSuiDirectSigning() {
2626
// Successfully broadcasted https://explorer.sui.io/txblock/HkPo6rYPyDY53x1MBszvSZVZyixVN7CHvCJGX381czAh?network=devnet
2727
val txBytes = """
2828
AAACAAgQJwAAAAAAAAAgJZ/4B0q0Jcu0ifI24Y4I8D8aeFa998eih3vWT3OLUBUCAgABAQAAAQEDAAAAAAEBANV1rX8Y6UhGKlz2mPVk7zlKdSpx/sYkk6+KBVwBLA1QAQbywsjB2JZN8QGdZhbpcFcZvrq9kx2idVy5SM635olk7AIAAAAAAAAgYEVuxmf1zRBGdoDr+VDtMpIFF12s2Ua7I2ru1XyGF8/Vda1/GOlIRipc9pj1ZO85SnUqcf7GJJOvigVcASwNUAEAAAAAAAAA0AcAAAAAAAAA
@@ -37,4 +37,37 @@ class TestSuiSigner {
3737
assertEquals(result.unsignedTx, txBytes);
3838
assertEquals(result.signature, expectedSignature)
3939
}
40+
41+
@Test
42+
fun testSuiTransfer() {
43+
// Successfully broadcasted: https://suiscan.xyz/mainnet/tx/D4Ay9TdBJjXkGmrZSstZakpEWskEQHaWURP6xWPRXbAm
44+
val txBytes = """
45+
AAAEAAjoAwAAAAAAAAAIUMMAAAAAAAAAIKcXWr3V7ZLr4605DbNmxqcGR4zfUXzebPmGMAZc2jd6ACBU6A1215DCd/WkTzzpL1PSb1iUiSvzld7mN1mIh2vmsgMCAAIBAAABAQABAQMAAAAAAQIAAQEDAAABAAEDAFToDXbXkMJ39aRPPOkvU9JvWJSJK/OV3uY3WYiHa+ayAWNgILOn3HsRw6pvQZsX+KnBLn95ox0b3S3mcLTt1jAFeHEaBQAAAAAgGGuNnxrqusosgjP3gQ3jBjnhapGNBlcU0yTaupXpa0BU6A1215DCd/WkTzzpL1PSb1iUiSvzld7mN1mIh2vmsu4CAAAAAAAAwMYtAAAAAAAA
46+
""".trimIndent()
47+
val key =
48+
"7e6682f7bf479ef0f627823cffd4e1a940a7af33e5fb39d9e0f631d2ecc5daff".toHexBytesInByteString()
49+
50+
val paySui = Sui.PaySui.newBuilder()
51+
.addInputCoins(Sui.ObjectRef.newBuilder().apply {
52+
objectId = "0x636020b3a7dc7b11c3aa6f419b17f8a9c12e7f79a31d1bdd2de670b4edd63005"
53+
version = 85619064
54+
objectDigest = "2eKuWbZSVfpFVfg8FXY9wP6W5AFXnTchSoUdp7obyYZ5"
55+
})
56+
.addRecipients("0xa7175abdd5ed92ebe3ad390db366c6a706478cdf517cde6cf98630065cda377a")
57+
.addRecipients("0x54e80d76d790c277f5a44f3ce92f53d26f5894892bf395dee6375988876be6b2")
58+
.addAmounts(1000)
59+
.addAmounts(50000)
60+
61+
val signingInput = Sui.SigningInput.newBuilder()
62+
.setPaySui(paySui)
63+
.setPrivateKey(key)
64+
.setGasBudget(3000000)
65+
.setReferenceGasPrice(750)
66+
.build()
67+
68+
val result = AnySigner.sign(signingInput, CoinType.SUI, Sui.SigningOutput.parser())
69+
val expectedSignature = "AEh44B7iGArEHF1wOLAQJMLNgGnaIwn3gKPC92vtDJqITDETAM5z9plaxio1xomt6/cZReQ5FZaQsMC6l7E0BwmF69FEH+T5VPvl3GB3vwCOEZpeJpKXxvcIPQAdKsh2/g=="
70+
assertEquals(result.unsignedTx, txBytes);
71+
assertEquals(result.signature, expectedSignature)
72+
}
4073
}

rust/Cargo.lock

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/Cargo.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,31 @@
11
[workspace]
22
members = [
3+
"chains/tw_aptos",
34
"chains/tw_binance",
45
"chains/tw_cosmos",
6+
"chains/tw_ethereum",
7+
"chains/tw_internet_computer",
58
"chains/tw_greenfield",
69
"chains/tw_native_evmos",
710
"chains/tw_native_injective",
11+
"chains/tw_ronin",
812
"chains/tw_solana",
13+
"chains/tw_sui",
914
"chains/tw_thorchain",
1015
"tw_any_coin",
11-
"tw_aptos",
1216
"tw_bech32_address",
1317
"tw_bitcoin",
1418
"tw_coin_entry",
1519
"tw_coin_registry",
1620
"tw_cosmos_sdk",
1721
"tw_encoding",
18-
"tw_ethereum",
1922
"tw_evm",
2023
"tw_hash",
21-
"tw_internet_computer",
2224
"tw_keypair",
2325
"tw_memory",
2426
"tw_misc",
2527
"tw_number",
2628
"tw_proto",
27-
"tw_ronin",
2829
"tw_utxo",
2930
"wallet_core_rs",
3031
]

rust/chains/tw_aptos/Cargo.toml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[package]
2+
name = "tw_aptos"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
serde_json = "1.0"
8+
tw_coin_entry = { path = "../../tw_coin_entry" }
9+
tw_encoding = { path = "../../tw_encoding" }
10+
tw_keypair = { path = "../../tw_keypair" }
11+
tw_proto = { path = "../../tw_proto" }
12+
tw_number = { path = "../../tw_number" }
13+
tw_hash = { path = "../../tw_hash" }
14+
tw_memory = { path = "../../tw_memory" }
15+
move-core-types = { git = "https://github.com/move-language/move", rev = "ea70797099baea64f05194a918cebd69ed02b285", features = ["address32"] }
16+
serde = { version = "1.0", features = ["derive"] }
17+
serde_bytes = "0.11.12"
18+
19+
[dev-dependencies]
20+
tw_coin_entry = { path = "../../tw_coin_entry", features = ["test-utils"] }
21+
tw_encoding = { path = "../../tw_encoding" }
22+
tw_number = { path = "../../tw_number", features = ["helpers"] }
File renamed without changes.
File renamed without changes.

rust/tw_aptos/src/address.rs renamed to rust/chains/tw_aptos/src/address.rs

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,11 @@ use move_core_types::account_address::{AccountAddress, AccountAddressParseError}
66
use std::fmt::{Display, Formatter};
77
use std::str::FromStr;
88
use tw_coin_entry::coin_entry::CoinAddress;
9-
use tw_coin_entry::error::{AddressError, AddressResult};
9+
use tw_coin_entry::error::AddressError;
1010
use tw_hash::sha3::sha3_256;
1111
use tw_keypair::ed25519;
1212
use tw_memory::Data;
1313

14-
pub trait AptosAddress: FromStr<Err = AddressError> + Into<Address> {
15-
/// Tries to parse an address from the string representation.
16-
/// Returns `Ok(None)` if the given `s` string is empty.
17-
#[inline]
18-
fn from_str_optional(s: &str) -> AddressResult<Option<Self>> {
19-
if s.is_empty() {
20-
return Ok(None);
21-
}
22-
23-
Self::from_str(s).map(Some)
24-
}
25-
}
26-
27-
impl AptosAddress for Address {}
28-
2914
#[repr(u8)]
3015
pub enum Scheme {
3116
Ed25519 = 0,
@@ -38,8 +23,8 @@ pub struct Address {
3823

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

27+
/// Initializes an address with a `ed25519` public key.
4328
pub fn with_ed25519_pubkey(
4429
pubkey: &ed25519::sha512::PublicKey,
4530
) -> Result<Address, AddressError> {
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

rust/chains/tw_binance/src/transaction/message/htlt_order.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub struct HTLTOrder {
2020
pub expected_income: String,
2121
pub from: BinanceAddress,
2222
pub height_span: i64,
23-
#[serde(serialize_with = "as_hex")]
23+
#[serde(with = "as_hex")]
2424
pub random_number_hash: Data,
2525
pub recipient_other_chain: String,
2626
pub sender_other_chain: String,
@@ -84,7 +84,7 @@ impl TWBinanceProto for HTLTOrder {
8484
pub struct DepositHTLTOrder {
8585
pub amount: Vec<Token>,
8686
pub from: BinanceAddress,
87-
#[serde(serialize_with = "as_hex")]
87+
#[serde(with = "as_hex")]
8888
pub swap_id: Data,
8989
}
9090

@@ -127,9 +127,9 @@ impl TWBinanceProto for DepositHTLTOrder {
127127
#[derive(Deserialize, Serialize)]
128128
pub struct ClaimHTLTOrder {
129129
pub from: BinanceAddress,
130-
#[serde(serialize_with = "as_hex")]
130+
#[serde(with = "as_hex")]
131131
pub random_number: Data,
132-
#[serde(serialize_with = "as_hex")]
132+
#[serde(with = "as_hex")]
133133
pub swap_id: Data,
134134
}
135135

@@ -171,7 +171,7 @@ impl TWBinanceProto for ClaimHTLTOrder {
171171
#[derive(Deserialize, Serialize)]
172172
pub struct RefundHTLTOrder {
173173
pub from: BinanceAddress,
174-
#[serde(serialize_with = "as_hex")]
174+
#[serde(with = "as_hex")]
175175
pub swap_id: Data,
176176
}
177177

rust/chains/tw_ethereum/Cargo.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[package]
2+
name = "tw_ethereum"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
tw_coin_entry = { path = "../../tw_coin_entry" }
8+
tw_evm = { path = "../../tw_evm" }
9+
tw_keypair = { path = "../../tw_keypair" }
10+
tw_proto = { path = "../../tw_proto" }
11+
12+
[dev-dependencies]
13+
tw_coin_entry = { path = "../../tw_coin_entry", features = ["test-utils"] }
14+
tw_encoding = { path = "../../tw_encoding" }
15+
tw_number = { path = "../../tw_number", features = ["helpers"] }
File renamed without changes.
File renamed without changes.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "tw_internet_computer"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
quick-protobuf = "0.8.1"
8+
serde = { version = "1.0", features = ["derive"] }
9+
tw_coin_entry = { path = "../../tw_coin_entry" }
10+
tw_encoding = { path = "../../tw_encoding" }
11+
tw_hash = { path = "../../tw_hash" }
12+
tw_keypair = { path = "../../tw_keypair" }
13+
tw_memory = { path = "../../tw_memory" }
14+
tw_proto = { path = "../../tw_proto" }
15+
16+
[build-dependencies]
17+
pb-rs = "0.10.0"

rust/chains/tw_ronin/Cargo.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[package]
2+
name = "tw_ronin"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
tw_coin_entry = { path = "../../tw_coin_entry" }
8+
tw_evm = { path = "../../tw_evm" }
9+
tw_keypair = { path = "../../tw_keypair" }
10+
tw_memory = { path = "../../tw_memory" }
11+
tw_proto = { path = "../../tw_proto" }
12+
13+
[dev-dependencies]
14+
tw_coin_entry = { path = "../../tw_coin_entry", features = ["test-utils"] }
15+
tw_encoding = { path = "../../tw_encoding" }
16+
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.

rust/chains/tw_sui/Cargo.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[package]
2+
name = "tw_sui"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
indexmap = "2.0"
8+
move-core-types = { git = "https://github.com/move-language/move", rev = "ea70797099baea64f05194a918cebd69ed02b285", features = ["address32"] }
9+
serde = { version = "1.0", features = ["derive"] }
10+
serde_repr = "0.1"
11+
tw_coin_entry = { path = "../../tw_coin_entry" }
12+
tw_encoding = { path = "../../tw_encoding" }
13+
tw_hash = { path = "../../tw_hash" }
14+
tw_keypair = { path = "../../tw_keypair" }
15+
tw_memory = { path = "../../tw_memory" }
16+
tw_proto = { path = "../../tw_proto" }

rust/chains/tw_sui/fuzz/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
target
2+
corpus
3+
artifacts
4+
coverage
5+
Cargo.lock

rust/chains/tw_sui/fuzz/Cargo.toml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
[package]
2+
name = "tw_sui-fuzz"
3+
version = "0.0.0"
4+
publish = false
5+
edition = "2021"
6+
7+
[package.metadata]
8+
cargo-fuzz = true
9+
10+
[dependencies]
11+
libfuzzer-sys = "0.4"
12+
tw_any_coin = { path = "../../../tw_any_coin", features = ["test-utils"] }
13+
tw_coin_registry = { path = "../../../tw_coin_registry" }
14+
tw_proto = { path = "../../../tw_proto", features = ["fuzz"] }
15+
16+
[dependencies.tw_sui]
17+
path = ".."
18+
19+
# Prevent this from interfering with workspaces
20+
[workspace]
21+
members = ["."]
22+
23+
[profile.release]
24+
debug = 1
25+
26+
[[bin]]
27+
name = "sign"
28+
path = "fuzz_targets/sign.rs"
29+
test = false
30+
doc = false
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
//
3+
// Copyright © 2017 Trust Wallet.
4+
5+
#![no_main]
6+
7+
use libfuzzer_sys::fuzz_target;
8+
use tw_any_coin::test_utils::sign_utils::AnySignerHelper;
9+
use tw_coin_registry::coin_type::CoinType;
10+
use tw_proto::Sui::Proto;
11+
12+
fuzz_target!(|input: Proto::SigningInput<'_>| {
13+
let mut signer = AnySignerHelper::<Proto::SigningOutput>::default();
14+
let _ = signer.sign(CoinType::Sui, input);
15+
});

0 commit comments

Comments
 (0)