Skip to content

Commit

Permalink
Merge branch 'master' into s/derivation-enum-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
satoshiotomakan authored Aug 5, 2024
2 parents 0fe45c6 + f14ae4c commit 3bec8c5
Show file tree
Hide file tree
Showing 126 changed files with 5,565 additions and 1,436 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class TestTheOpenNetworkAddress {
fun testGenerateJettonAddress() {
val mainAddress = "UQBjKqthWBE6GEcqb_epTRFrQ1niS6Z1Z1MHMwR-mnAYRoYr"
val mainAddressBoc = TONAddressConverter.toBoc(mainAddress)
assertEquals(mainAddressBoc, "te6ccgICAAEAAQAAACQAAABDgAxlVWwrAidDCOVN/vUpoi1oazxJdM6s6mDmYI/TTgMI0A==")
assertEquals(mainAddressBoc, "te6cckEBAQEAJAAAQ4AMZVVsKwInQwjlTf71KaItaGs8SXTOrOpg5mCP004DCNAptHQU")

// curl --location 'https://toncenter.com/api/v2/runGetMethod' --header 'Content-Type: application/json' --data \
// '{"address":"EQAvlWFDxGF2lXm67y4yzC17wYKD9A0guwPkMs1gOsM__NOT","method":"get_wallet_address","method":"get_wallet_address","stack":[["tvm.Slice","te6ccgICAAEAAQAAACQAAABDgAxlVWwrAidDCOVN/vUpoi1oazxJdM6s6mDmYI/TTgMI0A=="]]}'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,21 @@ class TestTheOpenNetworkSigner {
.setWalletVersion(TheOpenNetwork.WalletVersion.WALLET_V4_R2)
.setDest("EQBm--PFwDv1yCeS-QTJ-L8oiUpqo9IT1BwgVptlSq3ts90Q")
.setAmount(10)
.setSequenceNumber(6)
.setMode(TheOpenNetwork.SendMode.PAY_FEES_SEPARATELY_VALUE or TheOpenNetwork.SendMode.IGNORE_ACTION_PHASE_ERRORS_VALUE)
.setExpireAt(1671132440)
.setBounceable(true)
.build()

val input = TheOpenNetwork.SigningInput.newBuilder()
.setTransfer(transfer)
.setPrivateKey(ByteString.copyFrom(privateKey.data()))
.addMessages(transfer)
.setSequenceNumber(6)
.setExpireAt(1671132440)
.build()

val output = AnySigner.sign(input, CoinType.TON, SigningOutput.parser())

// tx: https://tonscan.org/tx/3Z4tHpXNLyprecgu5aTQHWtY7dpHXEoo11MAX61Xyg0=
val expectedString = "te6ccgICAAQAAQAAALAAAAFFiAGwt/q8k4SrjbFbQCjJZfQr64ExRxcUMsWqaQODqTUijgwAAQGcEUPkil2aZ4s8KKparSep/OKHMC8vuXafFbW2HGp/9AcTRv0J5T4dwyW1G0JpHw+g5Ov6QI3Xo0O9RFr3KidICimpoxdjm3UYAAAABgADAAIBYmIAM33x4uAd+uQTyXyCZPxflESlNVHpCeoOECtNsqVW9tmIUAAAAAAAAAAAAAAAAAEAAwAA"
val expectedString = "te6cckEBBAEArQABRYgBsLf6vJOEq42xW0AoyWX0K+uBMUcXFDLFqmkDg6k1Io4MAQGcEUPkil2aZ4s8KKparSep/OKHMC8vuXafFbW2HGp/9AcTRv0J5T4dwyW1G0JpHw+g5Ov6QI3Xo0O9RFr3KidICimpoxdjm3UYAAAABgADAgFiYgAzffHi4B365BPJfIJk/F+URKU1UekJ6g4QK02ypVb22YhQAAAAAAAAAAAAAAAAAQMAAA08Nzs="

assertEquals(output.encoded, expectedString)
}
Expand All @@ -51,33 +51,77 @@ class TestTheOpenNetworkSigner {
fun TheOpenNetworkJettonTransferSigning() {
val privateKey = PrivateKey("c054900a527538c1b4325688a421c0469b171c29f23a62da216e90b0df2412ee".toHexByteArray())

val transferData = TheOpenNetwork.Transfer.newBuilder()
val jettonTransfer = TheOpenNetwork.JettonTransfer.newBuilder()
.setJettonAmount(500 * 1000 * 1000)
.setToOwner("EQAFwMs5ha8OgZ9M4hQr80z9NkE7rGxUpE1hCFndiY6JnDx8")
.setResponseAddress("EQBaKIMq5Am2p_rfR1IFTwsNWHxBkOpLTmwUain5Fj4llTXk")
.setForwardAmount(1)
.build()

val transfer = TheOpenNetwork.Transfer.newBuilder()
.setWalletVersion(TheOpenNetwork.WalletVersion.WALLET_V4_R2)
.setDest("EQBiaD8PO1NwfbxSkwbcNT9rXDjqhiIvXWymNO-edV0H5lja")
.setAmount(100 * 1000 * 1000)
.setSequenceNumber(1)
.setMode(TheOpenNetwork.SendMode.PAY_FEES_SEPARATELY_VALUE or TheOpenNetwork.SendMode.IGNORE_ACTION_PHASE_ERRORS_VALUE)
.setExpireAt(1787693046)
.setComment("test comment")
.setBounceable(true)
.setJettonTransfer(jettonTransfer)

val jettonTransfer = TheOpenNetwork.JettonTransfer.newBuilder()
.setTransfer(transferData)
.setJettonAmount(500 * 1000 * 1000)
.setToOwner("EQAFwMs5ha8OgZ9M4hQr80z9NkE7rGxUpE1hCFndiY6JnDx8")
.setResponseAddress("EQBaKIMq5Am2p_rfR1IFTwsNWHxBkOpLTmwUain5Fj4llTXk")
.setForwardAmount(1)
val input = TheOpenNetwork.SigningInput.newBuilder()
.setPrivateKey(ByteString.copyFrom(privateKey.data()))
.addMessages(transfer)
.setSequenceNumber(1)
.setExpireAt(1787693046)
.build()

val output = AnySigner.sign(input, CoinType.TON, SigningOutput.parser())

// tx: https://testnet.tonscan.org/tx/Er_oT5R3QK7D-qVPBKUGkJAOOq6ayVls-mgEphpI9Ck=
val expectedString = "te6cckECBAEAARUAAUWIALRRBlXIE21P9b6OpAqeFhqw+IMh1Jac2CjUU/IsfEsqDAEBnGiFlaLItV573gJqBvctP5j3jVKlLuxmO+pnW0QGlXjXgzjw5YeTNwRG9upJHOl6GA3pFetKNojqGzfkxku+owUpqaMXao4H9gAAAAEAAwIBaGIAMTQfh52puD7eKUmDbhqfta4cdUMRF662Uxp3zzqug/MgL68IAAAAAAAAAAAAAAAAAAEDAMoPin6lAAAAAAAAAABB3NZQCAALgZZzC14dAz6ZxChX5pn6bIJ3WNipSJrCELO7Ex0TOQAWiiDKuQJtqf630dSBU8LDVh8QZDqS05sFGop+RY+JZUICAAAAAHRlc3QgY29tbWVudG/bd5c="

assertEquals(output.encoded, expectedString)
}

@Test
fun TheOpenNetworkTransferCustomPayload() {
val privateKey = PrivateKey("5525e673087587bc0efd7ab09920ef7d3c1bf6b854a661430244ca59ab19e9d1".toHexByteArray())

// Doge chatbot contract payload to be deployed.
// Docs: https://docs.ton.org/develop/dapps/ton-connect/transactions#smart-contract-deployment
val dogeChatbotStateInit = "te6cckEBBAEAUwACATQBAgEU/wD0pBP0vPLICwMAEAAAAZDrkbgQAGrTMAGCCGlJILmRMODQ0wMx+kAwi0ZG9nZYcCCAGMjLBVAEzxaARfoCE8tqEssfAc8WyXP7AO4ioYU="
// Doge chatbot's address after the contract is deployed.
val dogeChatbotDeployingAddress = "0:3042cd5480da232d5ac1d9cbe324e3c9eb58f167599f6b7c20c6e638aeed0335"

// The comment has nothing to do with Doge chatbot.
// It's just used to attach the following ASCII comment to the transaction:
// "This transaction deploys Doge Chatbot contract"
val commentPayload = "te6cckEBAQEANAAAZAAAAABUaGlzIHRyYW5zYWN0aW9uIGRlcGxveXMgRG9nZSBDaGF0Ym90IGNvbnRyYWN0v84vSg=="

val customPayload = TheOpenNetwork.CustomPayload.newBuilder()
.setStateInit(dogeChatbotStateInit)
.setPayload(commentPayload)
.build()

val transfer = TheOpenNetwork.Transfer.newBuilder()
.setWalletVersion(TheOpenNetwork.WalletVersion.WALLET_V4_R2)
.setDest(dogeChatbotDeployingAddress)
// 0.069 TON
.setAmount(69_000_000)
.setMode(TheOpenNetwork.SendMode.PAY_FEES_SEPARATELY_VALUE or TheOpenNetwork.SendMode.IGNORE_ACTION_PHASE_ERRORS_VALUE)
.setBounceable(false)
.setCustomPayload(customPayload)

val input = TheOpenNetwork.SigningInput.newBuilder()
.setJettonTransfer(jettonTransfer)
.setPrivateKey(ByteString.copyFrom(privateKey.data()))
.addMessages(transfer)
.setSequenceNumber(4)
.setExpireAt(1721939714)
.build()

val output = AnySigner.sign(input, CoinType.TON, SigningOutput.parser())

// tx: https://testnet.tonscan.org/tx/Er_oT5R3QK7D-qVPBKUGkJAOOq6ayVls-mgEphpI9Ck=
val expectedString = "te6ccgICAAQAAQAAARgAAAFFiAC0UQZVyBNtT/W+jqQKnhYasPiDIdSWnNgo1FPyLHxLKgwAAQGcaIWVosi1XnveAmoG9y0/mPeNUqUu7GY76mdbRAaVeNeDOPDlh5M3BEb26kkc6XoYDekV60o2iOobN+TGS76jBSmpoxdqjgf2AAAAAQADAAIBaGIAMTQfh52puD7eKUmDbhqfta4cdUMRF662Uxp3zzqug/MgL68IAAAAAAAAAAAAAAAAAAEAAwDKD4p+pQAAAAAAAAAAQdzWUAgAC4GWcwteHQM+mcQoV+aZ+myCd1jYqUiawhCzuxMdEzkAFoogyrkCban+t9HUgVPCw1YfEGQ6ktObBRqKfkWPiWVCAgAAAAB0ZXN0IGNvbW1lbnQ="
// Successfully broadcasted: https://tonviewer.com/transaction/f4b7ed2247b1adf54f33dd2fd99216fbd61beefb281542d0b330ccea9b8d0338
val expectedString = "te6cckECCAEAATcAAUWIAfq4NsPLegfou/MPhtHE9YuzV3gnI/q6jm3MRJh2PtpaDAEBnPbyCSsWrOZpEjb7ZFxz5yYi+an6M6Lnq7rI7TFWdDS76LEtGBrVVrhMGziwxuy6LCVtsMBikI7RPVQ89FCIAAYpqaMXZqK3AgAAAAQAAwICaUIAGCFmqkBtEZatYOzl8ZJx5PWseLOsz7W+EGNzHFd2gZqgIObaAAAAAAAAAAAAAAAAAAPAAwQCATQFBgBkAAAAAFRoaXMgdHJhbnNhY3Rpb24gZGVwbG95cyBEb2dlIENoYXRib3QgY29udHJhY3QBFP8A9KQT9LzyyAsHABAAAAGQ65G4EABq0zABgghpSSC5kTDg0NMDMfpAMItGRvZ2WHAggBjIywVQBM8WgEX6AhPLahLLHwHPFslz+wAa2r/S"

assertEquals(output.encoded, expectedString)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@
// Copyright © 2017 Trust Wallet.

use tw_any_coin::test_utils::address_utils::{
test_address_get_data, test_address_invalid, test_address_normalization, test_address_valid,
test_address_derive, test_address_get_data, test_address_invalid, test_address_normalization,
test_address_valid,
};
use tw_coin_registry::coin_type::CoinType;

#[test]
fn test_{COIN_ID}_address_derive() {
test_address_derive(CoinType::{COIN_TYPE}, "PRIVATE_KEY", "EXPECTED ADDRESS");
}

#[test]
fn test_{COIN_ID}_address_normalization() {
test_address_normalization(CoinType::{COIN_TYPE}, "DENORMALIZED", "EXPECTED");
Expand Down
1 change: 1 addition & 0 deletions include/TrustWalletCore/TWTONAddressConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ TWString *_Nullable TWTONAddressConverterFromBoc(TWString *_Nonnull boc);
/// \param address raw or user-friendly address to be converted.
/// \param bounceable whether the result address should be bounceable.
/// \param testnet whether the result address should be testnet.
/// \return user-friendly address str.
TW_EXPORT_STATIC_METHOD
TWString *_Nullable TWTONAddressConverterToUserFriendly(TWString *_Nonnull address, bool bounceable, bool testnet);

Expand Down
2 changes: 1 addition & 1 deletion registry.json
Original file line number Diff line number Diff line change
Expand Up @@ -4518,7 +4518,7 @@
"coinId": 607,
"symbol": "TON",
"decimals": 9,
"blockchain": "The Open Network",
"blockchain": "TheOpenNetwork",
"derivation": [
{
"path": "m/44'/607'/0'"
Expand Down
72 changes: 64 additions & 8 deletions rust/Cargo.lock

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

4 changes: 3 additions & 1 deletion rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ members = [
"chains/tw_binance",
"chains/tw_cosmos",
"chains/tw_ethereum",
"chains/tw_internet_computer",
"chains/tw_greenfield",
"chains/tw_internet_computer",
"chains/tw_native_evmos",
"chains/tw_native_injective",
"chains/tw_ronin",
"chains/tw_solana",
"chains/tw_sui",
"chains/tw_thorchain",
"chains/tw_ton",
"frameworks/tw_ton_sdk",
"frameworks/tw_utxo",
"tw_any_coin",
"tw_base58_address",
Expand Down
5 changes: 3 additions & 2 deletions rust/chains/tw_solana/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ use tw_coin_entry::coin_context::CoinContext;
use tw_coin_entry::coin_entry::{PublicKeyBytes, SignatureBytes};
use tw_coin_entry::error::prelude::*;
use tw_coin_entry::signing_output_error;
use tw_encoding::{base58, base64};
use tw_encoding::base58;
use tw_encoding::base64::{self, STANDARD};
use tw_keypair::ed25519;
use tw_keypair::traits::VerifyingKeyTrait;
use tw_proto::Solana::Proto;
Expand Down Expand Up @@ -69,7 +70,7 @@ impl SolanaCompiler {
) -> SigningResult<Proto::SigningOutput<'static>> {
let encode = move |data| match input.tx_encoding {
Proto::Encoding::Base58 => base58::encode(data, SOLANA_ALPHABET),
Proto::Encoding::Base64 => base64::encode(data, false),
Proto::Encoding::Base64 => base64::encode(data, STANDARD),
};

if signatures.len() != public_keys.len() {
Expand Down
10 changes: 5 additions & 5 deletions rust/chains/tw_solana/src/modules/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ use crate::SOLANA_ALPHABET;
use std::borrow::Cow;
use tw_coin_entry::error::prelude::*;
use tw_coin_entry::signing_output_error;
use tw_encoding::{base58, base64};
use tw_encoding::base58;
use tw_encoding::base64::{self, STANDARD};
use tw_hash::H256;
use tw_keypair::{ed25519, KeyPairResult};
use tw_memory::Data;
Expand All @@ -33,8 +34,7 @@ impl SolanaTransaction {
recent_blockhash: &str,
private_keys: &[Data],
) -> SigningResult<Proto::SigningOutput<'static>> {
let is_url = false;
let tx_bytes = base64::decode(encoded_tx, is_url)?;
let tx_bytes = base64::decode(encoded_tx, STANDARD)?;

let tx_to_sign: VersionedTransaction =
bincode::deserialize(&tx_bytes).map_err(|_| SigningErrorType::Error_input_parse)?;
Expand Down Expand Up @@ -63,10 +63,10 @@ impl SolanaTransaction {
TxSigner::sign_versioned(msg_to_sign, &private_keys, &external_signatures)?
};

let unsigned_encoded = base64::encode(&unsigned_encoded, is_url);
let unsigned_encoded = base64::encode(&unsigned_encoded, STANDARD);
let signed_encoded =
bincode::serialize(&signed_tx).tw_err(|_| SigningErrorType::Error_internal)?;
let signed_encoded = base64::encode(&signed_encoded, is_url);
let signed_encoded = base64::encode(&signed_encoded, STANDARD);

Ok(Proto::SigningOutput {
encoded: Cow::from(signed_encoded),
Expand Down
5 changes: 3 additions & 2 deletions rust/chains/tw_solana/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ use std::borrow::Cow;
use tw_coin_entry::coin_context::CoinContext;
use tw_coin_entry::error::prelude::*;
use tw_coin_entry::signing_output_error;
use tw_encoding::{base58, base64};
use tw_encoding::base58;
use tw_encoding::base64::{self, STANDARD};
use tw_proto::Solana::Proto;

pub struct SolanaSigner;
Expand All @@ -30,7 +31,7 @@ impl SolanaSigner {
) -> SigningResult<Proto::SigningOutput<'static>> {
let encode = move |data| match input.tx_encoding {
Proto::Encoding::Base58 => base58::encode(data, SOLANA_ALPHABET),
Proto::Encoding::Base64 => base64::encode(data, false),
Proto::Encoding::Base64 => base64::encode(data, STANDARD),
};

let builder = MessageBuilder::new(input);
Expand Down
Loading

0 comments on commit 3bec8c5

Please sign in to comment.