From ca053143fbacf8f45c47ee5cbd985e398382e7e9 Mon Sep 17 00:00:00 2001 From: neodiX Date: Thu, 10 Oct 2024 15:16:45 +0400 Subject: [PATCH] make Faucet contracts available in development; add toBounceableTestnet() and toNonBounceableTestnet() to Address; --- README.md | 13 +- .../java/org/ton/java/address/Address.java | 13 +- smartcontract/highload-v3-example.md | 66 +- smartcontract/plugin-example.md | 2 +- smartcontract/sample-smc-example.md | 2 +- .../smartcontract/faucet/TestnetFaucet.java | 85 + .../faucet/TestnetJettonFaucet.java | 81 + .../java/smartcontract/GenerateWallet.java | 113 +- .../ton/java/smartcontract/TestFaucet.java | 207 +- .../java/smartcontract/TestJettonFaucet.java | 408 ++-- .../TestTonSdkTestCasesSmartContracts.java | 14 +- .../integrationtests/TestExampleContract.java | 100 +- .../TestHighloadWalletV2.java | 345 ++-- .../TestHighloadWalletV3.java | 1099 +++++----- .../integrationtests/TestLibraryDeployer.java | 9 +- .../integrationtests/TestLockupWallet.java | 385 ++-- .../integrationtests/TestWalletFeesV1.java | 19 +- .../integrationtests/TestWalletFeesV2.java | 19 +- .../integrationtests/TestWalletFeesV3.java | 467 ++--- .../integrationtests/TestWalletFeesV4.java | 440 +++-- .../integrationtests/TestWalletMultiSig.java | 1759 +++++++++-------- .../integrationtests/TestWalletV1R1.java | 17 +- .../integrationtests/TestWalletV1R2.java | 13 +- .../integrationtests/TestWalletV1R3.java | 344 ++-- .../integrationtests/TestWalletV1R3Short.java | 79 +- .../integrationtests/TestWalletV2R1Short.java | 98 +- .../integrationtests/TestWalletV2R2Short.java | 128 +- .../integrationtests/TestWalletV3R1.java | 15 +- .../integrationtests/TestWalletV3R1Short.java | 41 +- .../integrationtests/TestWalletV3R2Short.java | 22 +- .../TestWalletV4R2Plugins.java | 12 +- .../integrationtests/TestWalletV5.java | 45 +- .../unittests/TestSmartContractCompiler.java | 190 +- .../unittests/TestWalletsV3.java | 4 +- smartcontract/v1r2-example.md | 4 +- 35 files changed, 3451 insertions(+), 3207 deletions(-) create mode 100644 smartcontract/src/main/java/org/ton/java/smartcontract/faucet/TestnetFaucet.java create mode 100644 smartcontract/src/main/java/org/ton/java/smartcontract/faucet/TestnetJettonFaucet.java diff --git a/README.md b/README.md index 537475f2..044ed97c 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ found [here](https://github.com/ton-blockchain/ton/actions). ## Maven [![Maven Central][maven-central-svg]][maven-central] ```xml + io.github.neodix42 smartcontract @@ -21,6 +22,7 @@ found [here](https://github.com/ton-blockchain/ton/actions). ## Jitpack [![JitPack][jitpack-svg]][jitpack] ```xml + jitpack.io @@ -30,6 +32,7 @@ found [here](https://github.com/ton-blockchain/ton/actions). ``` ```xml + io.github.neodix42 ton4j @@ -60,6 +63,11 @@ You can use each submodule individually. Click the module below to get more deta * ✅ Cell builder and cell slicer (reader) * ✅ Tonlib wrapper * ✅ Lite-client wrapper +* ✅ Fift wrapper +* ✅ Func wrapper +* ✅ TVM emulator wrapper +* ✅ Transaction emulator wrapper +* ✅ TonConnect * ✅ Support num, cell and slice as arguments for runMethod * ✅ Render List, Tuple, Slice, Cell and Number results from runMethod * ✅ Generate or import private key, sign, encrypt and decrypt using Tonlib @@ -67,9 +75,8 @@ You can use each submodule individually. Click the module below to get more deta * ✅ Send external message * ✅ Get block transactions * ✅ Deploy contracts and send external messages using Tonlib -* ✅ Wallets - Simple (V1), V2, V3, V4 (plugins), Lockup, Highload/Highload-V3, DNS, Jetton, StableCoin, NFT, - Payment-channels, - Multisig V1 +* ✅ Wallets - Simple (V1), V2, V3, V4 (plugins), V5, Lockup, Highload/Highload-V3, DNS, Jetton, StableCoin, NFT, + Payment-channels, Multisig V1 * ✅ HashMap, HashMapE, PfxHashMap, PfxHashMapE, HashMapAug, HashMapAugE serialization / deserialization ## Support ton4j development diff --git a/address/src/main/java/org/ton/java/address/Address.java b/address/src/main/java/org/ton/java/address/Address.java index 191b84da..7a59efc1 100644 --- a/address/src/main/java/org/ton/java/address/Address.java +++ b/address/src/main/java/org/ton/java/address/Address.java @@ -1,6 +1,6 @@ package org.ton.java.address; -import org.ton.java.utils.Utils; +import static java.util.Objects.isNull; import java.io.IOException; import java.math.BigInteger; @@ -8,8 +8,7 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; - -import static java.util.Objects.isNull; +import org.ton.java.utils.Utils; public class Address { @@ -191,6 +190,10 @@ public String toBounceable() { return toString(true, true, true, false); } + public String toBounceableTestnet() { + return toString(true, true, true, true); + } + public String toRaw() { return toString(false, true, true, false); } @@ -199,6 +202,10 @@ public String toNonBounceable() { return toString(true, true, false, false); } + public String toNonBounceableTestnet() { + return toString(true, true, false, true); + } + public String toString(boolean isUserFriendly, boolean isUrlSafe, boolean isBounceable, diff --git a/smartcontract/highload-v3-example.md b/smartcontract/highload-v3-example.md index 52c4ee1e..f567e60b 100644 --- a/smartcontract/highload-v3-example.md +++ b/smartcontract/highload-v3-example.md @@ -3,63 +3,63 @@ ### Example of usage of Highload Wallet V3 ```java -HighloadWalletV3 contract = HighloadWalletV3.builder() +HighloadWalletV3 contract=HighloadWalletV3.builder() .tonlib(tonlib) .walletId(42) .build(); -String nonBounceableAddress = contract.getAddress().toNonBounceable(); -String bounceableAddress = contract.getAddress().toBounceable(); -String rawAddress = contract.getAddress().toRaw(); + String nonBounceableAddress=contract.getAddress().toNonBounceable(); + String bounceableAddress=contract.getAddress().toBounceable(); + String rawAddress=contract.getAddress().toRaw(); -log.info("non-bounceable address {}", nonBounceableAddress); -log.info(" bounceable address {}", bounceableAddress); -log.info(" raw address {}", rawAddress); -log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); -log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); + log.info("non-bounceable address {}",nonBounceableAddress); + log.info(" bounceable address {}",bounceableAddress); + log.info(" raw address {}",rawAddress); + log.info("pub-key {}",Utils.bytesToHex(contract.getKeyPair().getPublicKey())); + log.info("prv-key {}",Utils.bytesToHex(contract.getKeyPair().getSecretKey())); // top up new wallet using test-faucet-wallet -BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(12)); -Utils.sleep(30, "topping up..."); -log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + BigInteger balance=TestnetFaucet.topUpContract(tonlib,Address.of(nonBounceableAddress),Utils.toNano(12)); + Utils.sleep(30,"topping up..."); + log.info("new wallet {} balance: {}",contract.getName(),Utils.formatNanoValue(balance)); -HighloadV3Config config = HighloadV3Config.builder() + HighloadV3Config config=HighloadV3Config.builder() .walletId(42) .queryId(HighloadQueryId.fromSeqno(0).getQueryId()) .build(); -ExtMessageInfo extMessageInfo = contract.deploy(config); -assertThat(extMessageInfo.getError().getCode()).isZero(); + ExtMessageInfo extMessageInfo=contract.deploy(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); -contract.waitForDeployment(45); + contract.waitForDeployment(45); -config = HighloadV3Config.builder() + config=HighloadV3Config.builder() .walletId(42) .queryId(HighloadQueryId.fromSeqno(1).getQueryId()) .body(contract.createBulkTransfer( - createDummyDestinations(300), - BigInteger.valueOf(HighloadQueryId.fromSeqno(1).getQueryId()))) + createDummyDestinations(300), + BigInteger.valueOf(HighloadQueryId.fromSeqno(1).getQueryId()))) .build(); -extMessageInfo = contract.send(config); -assertThat(extMessageInfo.getError().getCode()).isZero(); -log.info("sent 1000 messages"); + extMessageInfo=contract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + log.info("sent 1000 messages"); // help method -List createDummyDestinations(int count) throws NoSuchAlgorithmException { - List result = new ArrayList<>(); - for (int i = 0; i < count; i++) { - String dstDummyAddress = "0:" + Utils.bytesToHex(MessageDigest.getInstance("SHA-256").digest(UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8))); + List createDummyDestinations(int count)throws NoSuchAlgorithmException{ + List result=new ArrayList<>(); + for(int i=0;i 0) { + throw new Error( + "Too many TONs requested from the TestnetFaucet, maximum amount per request is 20."); + } + + TweetNaclFast.Signature.KeyPair keyPair = + TweetNaclFast.Signature.keyPair_fromSeed(Utils.hexToSignedBytes(SECRET_KEY)); + + WalletV1R3 faucet = WalletV1R3.builder().tonlib(tonlib).keyPair(keyPair).build(); + + BigInteger faucetBalance = null; + int i = 0; + do { + try { + if (i++ > 10) { + throw new Error("Cannot get faucet balance. Restart."); + } + + faucetBalance = faucet.getBalance(); + System.out.println( + "Faucet address " + + faucet.getAddress().toBounceable() + + ", balance " + + Utils.formatNanoValue(faucetBalance)); + if (faucetBalance.compareTo(amount) < 0) { + throw new Error( + "Faucet does not have that much toncoins. faucet balance " + + Utils.formatNanoValue(faucetBalance) + + ", requested " + + Utils.formatNanoValue(amount)); + } + } catch (Exception e) { + System.out.println("Cannot get faucet balance. Restarting..."); + Utils.sleep(5, "Waiting for faucet balance"); + } + } while (isNull(faucetBalance)); + + WalletV1R3Config config = + WalletV1R3Config.builder() + .bounce(false) + .seqno(faucet.getSeqno()) + .destination(destinationAddress) + .amount(amount) + .comment("top-up from ton4j faucet") + .build(); + + ExtMessageInfo extMessageInfo = faucet.send(config); + + if (extMessageInfo.getError().getCode() != 0) { + throw new Error(extMessageInfo.getError().getMessage()); + } + + ContractUtils.waitForBalanceChange(tonlib, destinationAddress, 120); + + return tonlib.getAccountBalance(destinationAddress); + } +} diff --git a/smartcontract/src/main/java/org/ton/java/smartcontract/faucet/TestnetJettonFaucet.java b/smartcontract/src/main/java/org/ton/java/smartcontract/faucet/TestnetJettonFaucet.java new file mode 100644 index 00000000..6e514b76 --- /dev/null +++ b/smartcontract/src/main/java/org/ton/java/smartcontract/faucet/TestnetJettonFaucet.java @@ -0,0 +1,81 @@ +package org.ton.java.smartcontract.faucet; + +import com.iwebpp.crypto.TweetNaclFast; +import java.math.BigInteger; +import org.ton.java.address.Address; +import org.ton.java.smartcontract.token.ft.JettonMinter; +import org.ton.java.smartcontract.token.ft.JettonWallet; +import org.ton.java.smartcontract.types.WalletV3Config; +import org.ton.java.smartcontract.utils.MsgUtils; +import org.ton.java.smartcontract.wallet.ContractUtils; +import org.ton.java.smartcontract.wallet.v3.WalletV3R2; +import org.ton.java.tonlib.Tonlib; +import org.ton.java.tonlib.types.ExtMessageInfo; +import org.ton.java.utils.Utils; + +/** Faucet for NEOJ jettons. */ +public class TestnetJettonFaucet { + + public static String ADMIN_WALLET_PUBLIC_KEY = + "d1d4515b2635b81de98d58f65502f2c242bb0e63615520341b83a12dd4d0f516"; + static String ADMIN_WALLET_SECRET_KEY = + "be0bbb1725807ec0df984702a32a143864418400d797a48e267a120c3dc5f8d0d1d4515b2635b81de98d58f65502f2c242bb0e63615520341b83a12dd4d0f516"; + public static String ADMIN_WALLET_ADDRESS = + "0:98972d1ab4b86f6be34ad03d64bb5e2cb369f0d7b5e53f13348664672b893010"; + public static String ADMIN_WALLET_BOUNCEABLE_ADDRESS = + "EQCYly0atLhva-NK0D1ku14ss2nw17XlPxM0hmRnK4kwEO86"; + public static String FAUCET_MASTER_ADDRESS = "kQAN6TAGauShFKDQvZCwNb_EeTUIjQDwRZ9t6GOn4FBzfg9Y"; + + public static BigInteger topUpContractWithNeoj( + Tonlib tonlib, Address destinationAddress, BigInteger jettonsAmount) { + + if (jettonsAmount.compareTo(Utils.toNano(100)) > 0) { + throw new Error( + "Too many NEOJ jettons requested from the TestnetJettonFaucet, maximum amount per request is 100."); + } + + TweetNaclFast.Signature.KeyPair keyPair = + TweetNaclFast.Signature.keyPair_fromSeed(Utils.hexToSignedBytes(ADMIN_WALLET_SECRET_KEY)); + + WalletV3R2 adminWallet = + WalletV3R2.builder().tonlib(tonlib).walletId(42).keyPair(keyPair).build(); + + JettonMinter jettonMinterWallet = + JettonMinter.builder() + .tonlib(tonlib) + .customAddress(Address.of(FAUCET_MASTER_ADDRESS)) + .build(); + + JettonWallet adminJettonWallet = jettonMinterWallet.getJettonWallet(adminWallet.getAddress()); + + WalletV3Config walletV3Config = + WalletV3Config.builder() + .walletId(42) + .seqno(adminWallet.getSeqno()) + .destination(adminJettonWallet.getAddress()) + .amount(Utils.toNano(0.06)) + .body( + JettonWallet.createTransferBody( + 0, + jettonsAmount, + destinationAddress, // recipient + adminWallet.getAddress(), // response address + null, // custom payload + BigInteger.ONE, // forward amount + MsgUtils.createTextMessageBody( + "jetton top up from ton4j faucet") // forward payload + )) + .build(); + ExtMessageInfo extMessageInfo = adminWallet.send(walletV3Config); + + if (extMessageInfo.getError().getCode() != 0) { + throw new Error(extMessageInfo.getError().getMessage()); + } + + ContractUtils.waitForJettonBalanceChange( + tonlib, Address.of(FAUCET_MASTER_ADDRESS), adminWallet.getAddress(), 60); + Utils.sleep(10); + return ContractUtils.getJettonBalance( + tonlib, Address.of(FAUCET_MASTER_ADDRESS), destinationAddress); + } +} diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/GenerateWallet.java b/smartcontract/src/test/java/org/ton/java/smartcontract/GenerateWallet.java index b2cff8fb..1bba7b97 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/GenerateWallet.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/GenerateWallet.java @@ -1,7 +1,11 @@ package org.ton.java.smartcontract; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import java.math.BigInteger; import lombok.extern.slf4j.Slf4j; import org.ton.java.address.Address; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.highload.HighloadWalletV3; import org.ton.java.smartcontract.types.HighloadQueryId; import org.ton.java.smartcontract.types.HighloadV3Config; @@ -10,82 +14,75 @@ import org.ton.java.tonlib.types.ExtMessageInfo; import org.ton.java.utils.Utils; -import java.math.BigInteger; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; - @Slf4j - public class GenerateWallet { - public static WalletV3R1 randomV3R1(Tonlib tonlib, long initialBalanceInToncoins) throws InterruptedException { - log.info("generating WalletV3R1 wallet..."); - - WalletV3R1 wallet = WalletV3R1.builder() - .tonlib(tonlib) - .wc(0) - .walletId(42) - .build(); - + public static WalletV3R1 randomV3R1(Tonlib tonlib, long initialBalanceInToncoins) + throws InterruptedException { + log.info("generating WalletV3R1 wallet..."); - Address address = wallet.getAddress(); + WalletV3R1 wallet = WalletV3R1.builder().tonlib(tonlib).wc(0).walletId(42).build(); - String nonBounceableAddress = address.toNonBounceable(); - String bounceableAddress = address.toBounceable(); - String rawAddress = address.toRaw(); + Address address = wallet.getAddress(); - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - log.info(" raw address {}", rawAddress); - log.info("pubKey: {}", Utils.bytesToHex(wallet.getKeyPair().getPublicKey())); + String nonBounceableAddress = address.toNonBounceable(); + String bounceableAddress = address.toBounceable(); + String rawAddress = address.toRaw(); + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + log.info(" raw address {}", rawAddress); + log.info("pubKey: {}", Utils.bytesToHex(wallet.getKeyPair().getPublicKey())); - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(initialBalanceInToncoins)); - log.info("new wallet balance {}", Utils.formatNanoValue(balance)); + BigInteger balance = + TestnetFaucet.topUpContract( + tonlib, Address.of(nonBounceableAddress), Utils.toNano(initialBalanceInToncoins)); + log.info("new wallet balance {}", Utils.formatNanoValue(balance)); - // deploy new wallet - ExtMessageInfo extMessageInfo = wallet.deploy(); - assertThat(extMessageInfo.getError().getCode()).isZero(); - wallet.waitForDeployment(60); + // deploy new wallet + ExtMessageInfo extMessageInfo = wallet.deploy(); + assertThat(extMessageInfo.getError().getCode()).isZero(); + wallet.waitForDeployment(60); - return wallet; - } + return wallet; + } - public static HighloadWalletV3 randomHighloadV3R1(Tonlib tonlib, long initialBalanceInToncoins) throws InterruptedException { + public static HighloadWalletV3 randomHighloadV3R1(Tonlib tonlib, long initialBalanceInToncoins) + throws InterruptedException { - log.info("generating HighloadWalletV3 wallet..."); - HighloadWalletV3 wallet = HighloadWalletV3.builder() - .tonlib(tonlib) - .walletId(42) - .build(); + log.info("generating HighloadWalletV3 wallet..."); + HighloadWalletV3 wallet = HighloadWalletV3.builder().tonlib(tonlib).walletId(42).build(); - String nonBounceableAddress = wallet.getAddress().toNonBounceable(); - String bounceableAddress = wallet.getAddress().toBounceable(); - String rawAddress = wallet.getAddress().toRaw(); + String nonBounceableAddress = wallet.getAddress().toNonBounceable(); + String bounceableAddress = wallet.getAddress().toBounceable(); + String rawAddress = wallet.getAddress().toRaw(); - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - log.info(" raw address {}", rawAddress); + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + log.info(" raw address {}", rawAddress); - log.info("pub-key {}", Utils.bytesToHex(wallet.getKeyPair().getPublicKey())); - log.info("prv-key {}", Utils.bytesToHex(wallet.getKeyPair().getSecretKey())); + log.info("pub-key {}", Utils.bytesToHex(wallet.getKeyPair().getPublicKey())); + log.info("prv-key {}", Utils.bytesToHex(wallet.getKeyPair().getSecretKey())); - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(initialBalanceInToncoins)); - Utils.sleep(30, "topping up..."); - log.info("highload wallet {} balance: {}", wallet.getName(), Utils.formatNanoValue(balance)); + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract( + tonlib, Address.of(nonBounceableAddress), Utils.toNano(initialBalanceInToncoins)); + Utils.sleep(30, "topping up..."); + log.info("highload wallet {} balance: {}", wallet.getName(), Utils.formatNanoValue(balance)); - HighloadV3Config highloadV3Config = HighloadV3Config.builder() - .walletId(42) - .queryId(HighloadQueryId.fromSeqno(0).getQueryId()) - .build(); + HighloadV3Config highloadV3Config = + HighloadV3Config.builder() + .walletId(42) + .queryId(HighloadQueryId.fromSeqno(0).getQueryId()) + .build(); - ExtMessageInfo extMessageInfo = wallet.deploy(highloadV3Config); - assertThat(extMessageInfo.getError().getCode()).isZero(); + ExtMessageInfo extMessageInfo = wallet.deploy(highloadV3Config); + assertThat(extMessageInfo.getError().getCode()).isZero(); - wallet.waitForDeployment(45); + wallet.waitForDeployment(45); - // highload v3 wallet deploy - end - return wallet; - } + // highload v3 wallet deploy - end + return wallet; + } } diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/TestFaucet.java b/smartcontract/src/test/java/org/ton/java/smartcontract/TestFaucet.java index af88a79a..83a6d9b0 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/TestFaucet.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/TestFaucet.java @@ -1,13 +1,15 @@ package org.ton.java.smartcontract; +import static org.assertj.core.api.Assertions.assertThat; + import com.iwebpp.crypto.TweetNaclFast; +import java.math.BigInteger; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.ton.java.address.Address; -import org.ton.java.smartcontract.types.WalletV1R3Config; -import org.ton.java.smartcontract.wallet.ContractUtils; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.wallet.v1.WalletV1R3; import org.ton.java.tonlib.Tonlib; import org.ton.java.tonlib.types.AccountAddressOnly; @@ -16,131 +18,84 @@ import org.ton.java.tonlib.types.VerbosityLevel; import org.ton.java.utils.Utils; -import java.math.BigInteger; - -import static java.util.Objects.isNull; -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; - @Slf4j @RunWith(JUnit4.class) public class TestFaucet { - public static String PUBLIC_KEY = "c02ece00eceb299066597ccc7a8ac0b2d08f0ad425f28c0ea92e74e2064f41f0"; - public static String SECRET_KEY = "46aab91daaaa375d40588384fdf7e36c62d0c0f38c46adfea7f9c904c5973d97c02ece00eceb299066597ccc7a8ac0b2d08f0ad425f28c0ea92e74e2064f41f0"; - public static String FAUCET_ADDRESS_RAW = "0:b52a16ba3735501df19997550e7ed4c41754ee501ded8a841088ce4278b66de4"; - public static String NON_BOUNCEABLE = "0QC1Kha6NzVQHfGZl1UOftTEF1TuUB3tioQQiM5CeLZt5FIA"; - public static String BOUNCEABLE = "kQC1Kha6NzVQHfGZl1UOftTEF1TuUB3tioQQiM5CeLZt5A_F"; - - public static BigInteger topUpContract(Tonlib tonlib, Address destinationAddress, BigInteger amount) throws InterruptedException { - TweetNaclFast.Signature.KeyPair keyPair = TweetNaclFast.Signature.keyPair_fromSeed(Utils.hexToSignedBytes(SECRET_KEY)); - - WalletV1R3 faucet = WalletV1R3.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .build(); - - BigInteger faucetBalance = null; - int i = 0; - do { - try { - if (i++ > 10) { - throw new Error("Cannot get faucet balance. Restart."); - } - - faucetBalance = faucet.getBalance(); - log.info("Faucet address {}, balance {}", faucet.getAddress().toString(true, true, true), Utils.formatNanoValue(faucetBalance)); - if (faucetBalance.compareTo(amount) < 0) { - throw new Error("Faucet does not have that much toncoins. faucet balance " + Utils.formatNanoValue(faucetBalance) + ", requested " + Utils.formatNanoValue(amount)); - } - } catch (Exception e) { - log.info("Cannot get faucet balance. Restarting..."); - Utils.sleep(5, "Waiting for faucet balance"); - } - } while (isNull(faucetBalance)); - - WalletV1R3Config config = WalletV1R3Config.builder() - .bounce(false) - .seqno(faucet.getSeqno()) - .destination(destinationAddress) - .amount(amount) - .comment("top-up from ton4j faucet") - .build(); - - ExtMessageInfo extMessageInfo = faucet.send(config); - - if (extMessageInfo.getError().getCode() != 0) { - throw new Error(extMessageInfo.getError().getMessage()); - } - - ContractUtils.waitForBalanceChange(tonlib, destinationAddress, 120); - - return tonlib.getAccountBalance(destinationAddress); - } - - @Test - public void testFaucetBalance() { - Tonlib tonlib = Tonlib.builder() - .testnet(true) - .ignoreCache(false) - .build(); - FullAccountState state = tonlib.getAccountState(AccountAddressOnly.builder().account_address(FAUCET_ADDRESS_RAW).build()); - log.info("account {}", state); - log.info("TEST FAUCET BALANCE {}", Utils.formatNanoValue(state.getBalance(), 2)); - } - - @Test - public void createFaucetWallet() { - WalletV1R3 contract = WalletV1R3.builder() - .build(); - - assertThat(contract.getAddress()).isNotNull(); - log.info("Private key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); - log.info("Public key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); - log.info("Non-bounceable address (for init): {}", contract.getAddress().toString(true, true, false, true)); - log.info("Bounceable address (for later access): {}", contract.getAddress().toString(true, true, true, true)); - log.info("Raw address: {}", contract.getAddress().toString(false)); - } - - /** - * Top up the non-bounceable address and then deploy the faucet. - * Update SECRET_KEY and FAUCET_ADDRESS_RAW variables - */ - @Test - public void deployFaucetWallet() { - byte[] secretKey = Utils.hexToSignedBytes(SECRET_KEY); - TweetNaclFast.Signature.KeyPair keyPair = TweetNaclFast.Signature.keyPair_fromSeed(secretKey); - - Tonlib tonlib = Tonlib.builder() - .testnet(true) - .ignoreCache(false) - .verbosityLevel(VerbosityLevel.DEBUG) - .build(); - - WalletV1R3 contract = WalletV1R3.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .build(); - - log.info("Private key {}", Utils.bytesToHex(keyPair.getSecretKey())); - log.info("Public key {}", Utils.bytesToHex(keyPair.getPublicKey())); - String nonBounceableAddress = contract.getAddress().toString(true, true, false, true); - log.info("Non-bounceable address (for init): {}", nonBounceableAddress); - log.info("Bounceable address (for later access): {}", contract.getAddress().toString(true, true, true, true)); - log.info("Raw address: {}", contract.getAddress().toString(false)); - - -// Message msg = contract.createExternalMessage(contract.getAddress(), true, null); - ExtMessageInfo extMessageInfo = contract.deploy(); - assertThat(extMessageInfo.getError().getCode()).isZero(); - } - - @Test - public void topUpAnyContract() throws InterruptedException { - Tonlib tonlib = Tonlib.builder() - .testnet(true) - .ignoreCache(false) - .build(); - BigInteger newBalance = TestFaucet.topUpContract(tonlib, Address.of("Ef_lZ1T4NCb2mwkme9h2rJfESCE0W34ma9lWp7-_uY3zXDvq"), Utils.toNano(1)); - log.info("new balance " + Utils.formatNanoValue(newBalance)); - } -} \ No newline at end of file + static String PUBLIC_KEY = "c02ece00eceb299066597ccc7a8ac0b2d08f0ad425f28c0ea92e74e2064f41f0"; + static String SECRET_KEY = + "46aab91daaaa375d40588384fdf7e36c62d0c0f38c46adfea7f9c904c5973d97c02ece00eceb299066597ccc7a8ac0b2d08f0ad425f28c0ea92e74e2064f41f0"; + static String FAUCET_ADDRESS_RAW = + "0:b52a16ba3735501df19997550e7ed4c41754ee501ded8a841088ce4278b66de4"; + static String NON_BOUNCEABLE = "0QC1Kha6NzVQHfGZl1UOftTEF1TuUB3tioQQiM5CeLZt5FIA"; + static String BOUNCEABLE = "kQC1Kha6NzVQHfGZl1UOftTEF1TuUB3tioQQiM5CeLZt5A_F"; + + @Test + public void testFaucetBalance() { + Tonlib tonlib = Tonlib.builder().testnet(true).ignoreCache(false).build(); + FullAccountState state = + tonlib.getAccountState( + AccountAddressOnly.builder().account_address(FAUCET_ADDRESS_RAW).build()); + log.info("account {}", state); + log.info("TEST FAUCET BALANCE {}", Utils.formatNanoValue(state.getBalance(), 2)); + } + + @Test + public void createFaucetWallet() { + WalletV1R3 contract = WalletV1R3.builder().build(); + + assertThat(contract.getAddress()).isNotNull(); + log.info("Private key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); + log.info("Public key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); + log.info( + "Non-bounceable address (for init): {}", + contract.getAddress().toString(true, true, false, true)); + log.info( + "Bounceable address (for later access): {}", + contract.getAddress().toString(true, true, true, true)); + log.info("Raw address: {}", contract.getAddress().toString(false)); + } + + /** + * Top up the non-bounceable address and then deploy the faucet. Update SECRET_KEY and + * FAUCET_ADDRESS_RAW variables + */ + @Test + public void deployFaucetWallet() { + byte[] secretKey = Utils.hexToSignedBytes(SECRET_KEY); + TweetNaclFast.Signature.KeyPair keyPair = TweetNaclFast.Signature.keyPair_fromSeed(secretKey); + + Tonlib tonlib = + Tonlib.builder() + .testnet(true) + .ignoreCache(false) + .verbosityLevel(VerbosityLevel.DEBUG) + .build(); + + WalletV1R3 contract = WalletV1R3.builder().tonlib(tonlib).keyPair(keyPair).build(); + + log.info("Private key {}", Utils.bytesToHex(keyPair.getSecretKey())); + log.info("Public key {}", Utils.bytesToHex(keyPair.getPublicKey())); + String nonBounceableAddress = contract.getAddress().toString(true, true, false, true); + log.info("Non-bounceable address (for init): {}", nonBounceableAddress); + log.info( + "Bounceable address (for later access): {}", + contract.getAddress().toString(true, true, true, true)); + log.info("Raw address: {}", contract.getAddress().toString(false)); + + // Message msg = contract.createExternalMessage(contract.getAddress(), true, null); + ExtMessageInfo extMessageInfo = contract.deploy(); + assertThat(extMessageInfo.getError().getCode()).isZero(); + } + + @Test + public void topUpAnyContract() throws InterruptedException { + Tonlib tonlib = Tonlib.builder().testnet(true).ignoreCache(false).build(); + BigInteger newBalance = + TestnetFaucet.topUpContract( + tonlib, + Address.of("Ef_lZ1T4NCb2mwkme9h2rJfESCE0W34ma9lWp7-_uY3zXDvq"), + Utils.toNano(1)); + log.info("new balance " + Utils.formatNanoValue(newBalance)); + } +} diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/TestJettonFaucet.java b/smartcontract/src/test/java/org/ton/java/smartcontract/TestJettonFaucet.java index 6bdba14b..22ecac9f 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/TestJettonFaucet.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/TestJettonFaucet.java @@ -1,11 +1,16 @@ package org.ton.java.smartcontract; +import static org.assertj.core.api.Assertions.assertThat; + import com.iwebpp.crypto.TweetNaclFast; +import java.math.BigInteger; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.ton.java.address.Address; +import org.ton.java.smartcontract.faucet.TestnetFaucet; +import org.ton.java.smartcontract.faucet.TestnetJettonFaucet; import org.ton.java.smartcontract.token.ft.JettonMinter; import org.ton.java.smartcontract.token.ft.JettonWallet; import org.ton.java.smartcontract.token.nft.NftUtils; @@ -19,237 +24,180 @@ import org.ton.java.tonlib.types.FullAccountState; import org.ton.java.utils.Utils; -import java.math.BigInteger; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; - -/** - * Faucet for NEOJ jettons. - */ +/** Faucet for NEOJ jettons. */ @Slf4j @RunWith(JUnit4.class) public class TestJettonFaucet { - public static String ADMIN_WALLET_PUBLIC_KEY = "d1d4515b2635b81de98d58f65502f2c242bb0e63615520341b83a12dd4d0f516"; - public static String ADMIN_WALLET_SECRET_KEY = "be0bbb1725807ec0df984702a32a143864418400d797a48e267a120c3dc5f8d0d1d4515b2635b81de98d58f65502f2c242bb0e63615520341b83a12dd4d0f516"; - public static String ADMIN_WALLET_ADDRESS = "0:98972d1ab4b86f6be34ad03d64bb5e2cb369f0d7b5e53f13348664672b893010"; - public static String ADMIN_WALLET_BOUNCEABLE_ADDRESS = "EQCYly0atLhva-NK0D1ku14ss2nw17XlPxM0hmRnK4kwEO86"; - public static String FAUCET_MASTER_ADDRESS = "kQAN6TAGauShFKDQvZCwNb_EeTUIjQDwRZ9t6GOn4FBzfg9Y"; - - public static BigInteger topUpContractWithNeoj(Tonlib tonlib, Address destinationAddress, BigInteger jettonsAmount) { - - TweetNaclFast.Signature.KeyPair keyPair = TweetNaclFast.Signature.keyPair_fromSeed(Utils.hexToSignedBytes(ADMIN_WALLET_SECRET_KEY)); - - WalletV3R2 adminWallet = WalletV3R2.builder() - .tonlib(tonlib) - .walletId(42) - .keyPair(keyPair) - .build(); - - JettonMinter jettonMinterWallet = JettonMinter.builder() - .tonlib(tonlib) - .customAddress(Address.of(FAUCET_MASTER_ADDRESS)) - .build(); - - JettonWallet adminJettonWallet = jettonMinterWallet.getJettonWallet(adminWallet.getAddress()); - - WalletV3Config walletV3Config = WalletV3Config.builder() - .walletId(42) - .seqno(adminWallet.getSeqno()) - .destination(adminJettonWallet.getAddress()) - .amount(Utils.toNano(0.06)) - .body(JettonWallet.createTransferBody( - 0, - jettonsAmount, - destinationAddress, // recipient - adminWallet.getAddress(), // response address - null, // custom payload - BigInteger.ONE, // forward amount - MsgUtils.createTextMessageBody("jetton top up from ton4j faucet") // forward payload - )).build(); - ExtMessageInfo extMessageInfo = adminWallet.send(walletV3Config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - if (extMessageInfo.getError().getCode() != 0) { - throw new Error(extMessageInfo.getError().getMessage()); - } - - ContractUtils.waitForJettonBalanceChange(tonlib, Address.of(FAUCET_MASTER_ADDRESS), adminWallet.getAddress(), 60); - Utils.sleep(10); - return ContractUtils.getJettonBalance(tonlib, Address.of(FAUCET_MASTER_ADDRESS), destinationAddress); - } - - @Test - public void testJettonFaucetBalance() { - Tonlib tonlib = Tonlib.builder() - .testnet(true) - .ignoreCache(false) - .build(); - - TweetNaclFast.Signature.KeyPair keyPair = TweetNaclFast.Signature.keyPair_fromSeed(Utils.hexToSignedBytes(ADMIN_WALLET_SECRET_KEY)); - - WalletV3R2 adminWallet = WalletV3R2.builder() - .tonlib(tonlib) - .walletId(42) - .keyPair(keyPair) - .build(); - - JettonMinter jettonMinterWallet = JettonMinter.builder() - .tonlib(tonlib) - .customAddress(Address.of(FAUCET_MASTER_ADDRESS)) - .build(); - - JettonWallet adminJettonWallet = jettonMinterWallet.getJettonWallet(adminWallet.getAddress()); - - FullAccountState state = tonlib.getAccountState(Address.of(FAUCET_MASTER_ADDRESS)); - - log.info("TEST FAUCET BALANCE IN TONCOINS {}", Utils.formatNanoValue(state.getBalance(), 2)); - log.info("TEST FAUCET BALANCE TOTAL SUPPLY: {}", Utils.formatJettonValue(jettonMinterWallet.getTotalSupply(), 2, 2)); - log.info("TEST FAUCET ADMIN BALANCE in TONCOINS: {}", Utils.formatNanoValue(adminWallet.getBalance())); - log.info("TEST FAUCET ADMIN BALANCE in JETTONS: {}", Utils.formatJettonValue(adminJettonWallet.getBalance(), 2, 2)); - } - - @Test - public void createJettonFaucetAdminWallet() { - WalletV3R2 contract = WalletV3R2.builder() - .walletId(42) - .build(); - - assertThat(contract.getAddress()).isNotNull(); - log.info("Private key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); - log.info("Public key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); - log.info("Non-bounceable address (for init): {}", contract.getAddress().toNonBounceable()); - log.info("Bounceable address (for later access): {}", contract.getAddress().toBounceable()); - log.info("Raw address: {}", contract.getAddress().toRaw()); - } - - @Test - public void deployJettonFaucetAdminWallet() throws InterruptedException { - byte[] secretKey = Utils.hexToSignedBytes(ADMIN_WALLET_SECRET_KEY); - TweetNaclFast.Signature.KeyPair keyPair = TweetNaclFast.Signature.keyPair_fromSeed(secretKey); - - Tonlib tonlib = Tonlib.builder() - .testnet(true) - .ignoreCache(false) - .build(); - - WalletV3R2 adminWallet = WalletV3R2.builder() - .tonlib(tonlib) - .walletId(42) - .keyPair(keyPair) - .build(); - - log.info("Private key {}", Utils.bytesToHex(keyPair.getSecretKey())); - log.info("Public key {}", Utils.bytesToHex(keyPair.getPublicKey())); - log.info("Non-bounceable address (for init): {}", adminWallet.getAddress().toNonBounceable()); - log.info("Bounceable address (for later access): {}", adminWallet.getAddress().toBounceable()); - log.info("Raw address: {}", adminWallet.getAddress().toRaw()); - - - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(adminWallet.getAddress().toNonBounceable()), Utils.toNano(10)); - Utils.sleep(30, "topping up..."); - - ExtMessageInfo extMessageInfo = adminWallet.deploy(); - assertThat(extMessageInfo.getError().getCode()).isZero(); - } - - @Test - public void deployJettonFaucetMinter() { - - Tonlib tonlib = Tonlib.builder() - .testnet(true) - .ignoreCache(false) - .build(); - - byte[] secretKey = Utils.hexToSignedBytes(ADMIN_WALLET_SECRET_KEY); - TweetNaclFast.Signature.KeyPair keyPair = TweetNaclFast.Signature.keyPair_fromSeed(secretKey); - - WalletV3R2 adminWallet = WalletV3R2.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .walletId(42) - .build(); - - JettonMinter minter = JettonMinter.builder() - .tonlib(tonlib) - .adminAddress(adminWallet.getAddress()) - .content(NftUtils.createOffChainUriCell("https://raw.githubusercontent.com/neodix42/ton4j/main/1-media/neo-jetton.json")) - .jettonWalletCodeHex(WalletCodes.jettonWallet.getValue()) - .build(); - - log.info("jetton minter address {}", minter.getAddress()); - - WalletV3Config walletV3Config = WalletV3Config.builder() - .walletId(42) - .seqno(adminWallet.getSeqno()) - .destination(minter.getAddress()) - .amount(Utils.toNano(2)) - .stateInit(minter.getStateInit()) - .comment("deploy minter") - .build(); - - ExtMessageInfo extMessageInfo = adminWallet.send(walletV3Config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - } - - @Test - public void mintTestJettonsFaucet() { - Tonlib tonlib = Tonlib.builder() - .testnet(true) - .ignoreCache(false) - .build(); - - byte[] secretKey = Utils.hexToSignedBytes(ADMIN_WALLET_SECRET_KEY); - TweetNaclFast.Signature.KeyPair keyPair = TweetNaclFast.Signature.keyPair_fromSeed(secretKey); - - WalletV3R2 adminWallet = WalletV3R2.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .walletId(42) - .build(); - - WalletV3Config walletV3Config = WalletV3Config.builder() - .walletId(42) - .seqno(adminWallet.getSeqno()) - .destination(Address.of(FAUCET_MASTER_ADDRESS)) - .amount(Utils.toNano(0.1)) - .body(JettonMinter.createMintBody(0, - adminWallet.getAddress(), - Utils.toNano(0.1), - new BigInteger("10_000_000_000_000_000"), - null, - null, - BigInteger.ONE, - MsgUtils.createTextMessageBody("minting"))) - .build(); - - ExtMessageInfo extMessageInfo = adminWallet.send(walletV3Config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - } - - @Test - public void topUpAnyContractWithNeoJettons() { - Tonlib tonlib = Tonlib.builder() - .testnet(true) - .ignoreCache(false) - .build(); - BigInteger newBalance = TestJettonFaucet.topUpContractWithNeoj(tonlib, - Address.of("0QCUqgn-Ix3kuzhPAkKKiqqXQazsJ98K3VSCi4QJ3ZTGC7O1"), BigInteger.valueOf(100)); - log.info("new balance " + Utils.formatNanoValue(newBalance)); - } - - @Test - public void testJettonBalance() { - - Tonlib tonlib = Tonlib.builder() - .testnet(true) - .ignoreCache(false) - .build(); - - log.info("balance: {}", ContractUtils.getJettonBalance( - tonlib, - Address.of(FAUCET_MASTER_ADDRESS), - Address.of("0:cf2d917d55ed2d9fde43b5a5b5512216c3a027661311bbd771c394892836b3a4") - )); - } -} \ No newline at end of file + static String ADMIN_WALLET_PUBLIC_KEY = + "d1d4515b2635b81de98d58f65502f2c242bb0e63615520341b83a12dd4d0f516"; + static String ADMIN_WALLET_SECRET_KEY = + "be0bbb1725807ec0df984702a32a143864418400d797a48e267a120c3dc5f8d0d1d4515b2635b81de98d58f65502f2c242bb0e63615520341b83a12dd4d0f516"; + public static String ADMIN_WALLET_ADDRESS = + "0:98972d1ab4b86f6be34ad03d64bb5e2cb369f0d7b5e53f13348664672b893010"; + public static String ADMIN_WALLET_BOUNCEABLE_ADDRESS = + "EQCYly0atLhva-NK0D1ku14ss2nw17XlPxM0hmRnK4kwEO86"; + public static String FAUCET_MASTER_ADDRESS = "kQAN6TAGauShFKDQvZCwNb_EeTUIjQDwRZ9t6GOn4FBzfg9Y"; + + @Test + public void testJettonFaucetBalance() { + Tonlib tonlib = Tonlib.builder().testnet(true).ignoreCache(false).build(); + + TweetNaclFast.Signature.KeyPair keyPair = + TweetNaclFast.Signature.keyPair_fromSeed(Utils.hexToSignedBytes(ADMIN_WALLET_SECRET_KEY)); + + WalletV3R2 adminWallet = + WalletV3R2.builder().tonlib(tonlib).walletId(42).keyPair(keyPair).build(); + + JettonMinter jettonMinterWallet = + JettonMinter.builder() + .tonlib(tonlib) + .customAddress(Address.of(FAUCET_MASTER_ADDRESS)) + .build(); + + JettonWallet adminJettonWallet = jettonMinterWallet.getJettonWallet(adminWallet.getAddress()); + + FullAccountState state = tonlib.getAccountState(Address.of(FAUCET_MASTER_ADDRESS)); + + log.info("TEST FAUCET BALANCE IN TONCOINS {}", Utils.formatNanoValue(state.getBalance(), 2)); + log.info( + "TEST FAUCET BALANCE TOTAL SUPPLY: {}", + Utils.formatJettonValue(jettonMinterWallet.getTotalSupply(), 2, 2)); + log.info( + "TEST FAUCET ADMIN BALANCE in TONCOINS: {}", + Utils.formatNanoValue(adminWallet.getBalance())); + log.info( + "TEST FAUCET ADMIN BALANCE in JETTONS: {}", + Utils.formatJettonValue(adminJettonWallet.getBalance(), 2, 2)); + } + + @Test + public void createJettonFaucetAdminWallet() { + WalletV3R2 contract = WalletV3R2.builder().walletId(42).build(); + + assertThat(contract.getAddress()).isNotNull(); + log.info("Private key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); + log.info("Public key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); + log.info("Non-bounceable address (for init): {}", contract.getAddress().toNonBounceable()); + log.info("Bounceable address (for later access): {}", contract.getAddress().toBounceable()); + log.info("Raw address: {}", contract.getAddress().toRaw()); + } + + @Test + public void deployJettonFaucetAdminWallet() throws InterruptedException { + byte[] secretKey = Utils.hexToSignedBytes(ADMIN_WALLET_SECRET_KEY); + TweetNaclFast.Signature.KeyPair keyPair = TweetNaclFast.Signature.keyPair_fromSeed(secretKey); + + Tonlib tonlib = Tonlib.builder().testnet(true).ignoreCache(false).build(); + + WalletV3R2 adminWallet = + WalletV3R2.builder().tonlib(tonlib).walletId(42).keyPair(keyPair).build(); + + log.info("Private key {}", Utils.bytesToHex(keyPair.getSecretKey())); + log.info("Public key {}", Utils.bytesToHex(keyPair.getPublicKey())); + log.info("Non-bounceable address (for init): {}", adminWallet.getAddress().toNonBounceable()); + log.info("Bounceable address (for later access): {}", adminWallet.getAddress().toBounceable()); + log.info("Raw address: {}", adminWallet.getAddress().toRaw()); + + BigInteger balance = + TestnetFaucet.topUpContract( + tonlib, Address.of(adminWallet.getAddress().toNonBounceable()), Utils.toNano(10)); + Utils.sleep(30, "topping up..."); + + ExtMessageInfo extMessageInfo = adminWallet.deploy(); + assertThat(extMessageInfo.getError().getCode()).isZero(); + } + + @Test + public void deployJettonFaucetMinter() { + + Tonlib tonlib = Tonlib.builder().testnet(true).ignoreCache(false).build(); + + byte[] secretKey = Utils.hexToSignedBytes(ADMIN_WALLET_SECRET_KEY); + TweetNaclFast.Signature.KeyPair keyPair = TweetNaclFast.Signature.keyPair_fromSeed(secretKey); + + WalletV3R2 adminWallet = + WalletV3R2.builder().tonlib(tonlib).keyPair(keyPair).walletId(42).build(); + + JettonMinter minter = + JettonMinter.builder() + .tonlib(tonlib) + .adminAddress(adminWallet.getAddress()) + .content( + NftUtils.createOffChainUriCell( + "https://raw.githubusercontent.com/neodix42/ton4j/main/1-media/neo-jetton.json")) + .jettonWalletCodeHex(WalletCodes.jettonWallet.getValue()) + .build(); + + log.info("jetton minter address {}", minter.getAddress()); + + WalletV3Config walletV3Config = + WalletV3Config.builder() + .walletId(42) + .seqno(adminWallet.getSeqno()) + .destination(minter.getAddress()) + .amount(Utils.toNano(2)) + .stateInit(minter.getStateInit()) + .comment("deploy minter") + .build(); + + ExtMessageInfo extMessageInfo = adminWallet.send(walletV3Config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + } + + @Test + public void mintTestJettonsFaucet() { + Tonlib tonlib = Tonlib.builder().testnet(true).ignoreCache(false).build(); + + byte[] secretKey = Utils.hexToSignedBytes(ADMIN_WALLET_SECRET_KEY); + TweetNaclFast.Signature.KeyPair keyPair = TweetNaclFast.Signature.keyPair_fromSeed(secretKey); + + WalletV3R2 adminWallet = + WalletV3R2.builder().tonlib(tonlib).keyPair(keyPair).walletId(42).build(); + + WalletV3Config walletV3Config = + WalletV3Config.builder() + .walletId(42) + .seqno(adminWallet.getSeqno()) + .destination(Address.of(FAUCET_MASTER_ADDRESS)) + .amount(Utils.toNano(0.1)) + .body( + JettonMinter.createMintBody( + 0, + adminWallet.getAddress(), + Utils.toNano(0.1), + new BigInteger("10_000_000_000_000_000"), + null, + null, + BigInteger.ONE, + MsgUtils.createTextMessageBody("minting"))) + .build(); + + ExtMessageInfo extMessageInfo = adminWallet.send(walletV3Config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + } + + @Test + public void topUpAnyContractWithNeoJettons() { + Tonlib tonlib = Tonlib.builder().testnet(true).ignoreCache(false).build(); + BigInteger newBalance = + TestnetJettonFaucet.topUpContractWithNeoj( + tonlib, + Address.of("0QCUqgn-Ix3kuzhPAkKKiqqXQazsJ98K3VSCi4QJ3ZTGC7O1"), + BigInteger.valueOf(100)); + log.info("new balance " + Utils.formatNanoValue(newBalance)); + } + + @Test + public void testJettonBalance() { + + Tonlib tonlib = Tonlib.builder().testnet(true).ignoreCache(false).build(); + + log.info( + "balance: {}", + ContractUtils.getJettonBalance( + tonlib, + Address.of(FAUCET_MASTER_ADDRESS), + Address.of("0:cf2d917d55ed2d9fde43b5a5b5512216c3a027661311bbd771c394892836b3a4"))); + } +} diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/TestTonSdkTestCasesSmartContracts.java b/smartcontract/src/test/java/org/ton/java/smartcontract/TestTonSdkTestCasesSmartContracts.java index 4909f4f1..187ae1dd 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/TestTonSdkTestCasesSmartContracts.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/TestTonSdkTestCasesSmartContracts.java @@ -26,6 +26,8 @@ import org.junit.runners.JUnit4; import org.ton.java.address.Address; import org.ton.java.cell.CellBuilder; +import org.ton.java.smartcontract.faucet.TestnetFaucet; +import org.ton.java.smartcontract.faucet.TestnetJettonFaucet; import org.ton.java.smartcontract.highload.HighloadWalletV3; import org.ton.java.smartcontract.token.ft.JettonMinter; import org.ton.java.smartcontract.token.ft.JettonMinterStableCoin; @@ -837,7 +839,7 @@ public void testSmartContracts16() throws InterruptedException, NoSuchAlgorithmE // top up new wallet using test-faucet-wallet BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); Utils.sleep(30, "topping up..."); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); @@ -923,7 +925,7 @@ public void testSmartContracts17() throws InterruptedException, NoSuchAlgorithmE // top up new wallet using test-faucet-wallet BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(7)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(7)); Utils.sleep(30, "topping up..."); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); @@ -1019,7 +1021,7 @@ public void testSmartContracts18() throws InterruptedException, NoSuchAlgorithmE // top up new wallet using test-faucet-wallet BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); log.info( "new wallet {} toncoins balance: {}", highloadWalletV3.getName(), @@ -1027,7 +1029,7 @@ public void testSmartContracts18() throws InterruptedException, NoSuchAlgorithmE // top up new wallet with NEOJ using test-jetton-faucet-wallet balance = - TestJettonFaucet.topUpContractWithNeoj( + TestnetJettonFaucet.topUpContractWithNeoj( tonlib, Address.of(nonBounceableAddress), BigInteger.valueOf(100)); log.info( "new wallet {} jetton balance: {}", @@ -1140,7 +1142,7 @@ public void testSmartContracts19() throws InterruptedException, NoSuchAlgorithmE // top up new wallet using test-faucet-wallet BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(20)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(20)); log.info( "new wallet {} toncoins balance: {}", highloadWalletV3.getName(), @@ -1148,7 +1150,7 @@ public void testSmartContracts19() throws InterruptedException, NoSuchAlgorithmE // top up new wallet with NEOJ using test-jetton-faucet-wallet balance = - TestJettonFaucet.topUpContractWithNeoj( + TestnetJettonFaucet.topUpContractWithNeoj( tonlib, Address.of(nonBounceableAddress), expectedTotalSumOfJettonsAt300Addresses); log.info( "new wallet {} jetton balance: {}", diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestExampleContract.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestExampleContract.java index 1300da21..2e24602e 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestExampleContract.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestExampleContract.java @@ -9,7 +9,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.ton.java.address.Address; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.types.CustomContractConfig; import org.ton.java.tonlib.Tonlib; import org.ton.java.tonlib.types.ExtMessageInfo; @@ -21,71 +21,69 @@ @RunWith(JUnit4.class) public class TestExampleContract { - @Test - public void testExampleContract() throws InterruptedException { - // echo "F182111193F30D79D517F2339A1BA7C25FDF6C52142F0F2C1D960A1F1D65E1E4" | xxd -r -p - > new-wallet.pk - //byte[] secretKey = Utils.hexToBytes("F182111193F30D79D517F2339A1BA7C25FDF6C52142F0F2C1D960A1F1D65E1E4"); - //TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPairFromSeed(secretKey); + @Test + public void testExampleContract() throws InterruptedException { + // echo "F182111193F30D79D517F2339A1BA7C25FDF6C52142F0F2C1D960A1F1D65E1E4" | xxd -r -p - > + // new-wallet.pk + // byte[] secretKey = + // Utils.hexToBytes("F182111193F30D79D517F2339A1BA7C25FDF6C52142F0F2C1D960A1F1D65E1E4"); + // TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPairFromSeed(secretKey); - Tonlib tonlib = Tonlib.builder() - .testnet(true) - .ignoreCache(false) - .build(); + Tonlib tonlib = Tonlib.builder().testnet(true).ignoreCache(false).build(); - TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); + TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); - ExampleContract exampleContract = ExampleContract.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .build(); + ExampleContract exampleContract = + ExampleContract.builder().tonlib(tonlib).keyPair(keyPair).build(); - log.info("pubkey {}", Utils.bytesToHex(exampleContract.getKeyPair().getPublicKey())); + log.info("pubkey {}", Utils.bytesToHex(exampleContract.getKeyPair().getPublicKey())); - Address address = exampleContract.getAddress(); - log.info("contract address {}", address); + Address address = exampleContract.getAddress(); + log.info("contract address {}", address); - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(address.toString(true)), Utils.toNano(0.1)); - log.info("new wallet {} balance: {}", address.toString(true), Utils.formatNanoValue(balance)); + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(address.toString(true)), Utils.toNano(0.1)); + log.info("new wallet {} balance: {}", address.toString(true), Utils.formatNanoValue(balance)); - ExtMessageInfo extMessageInfo = exampleContract.deploy(); - assertThat(extMessageInfo.getError().getCode()).isZero(); + ExtMessageInfo extMessageInfo = exampleContract.deploy(); + assertThat(extMessageInfo.getError().getCode()).isZero(); - exampleContract.waitForDeployment(45); + exampleContract.waitForDeployment(45); - log.info("seqno: {}", exampleContract.getSeqno()); + log.info("seqno: {}", exampleContract.getSeqno()); - RunResult result = tonlib.runMethod(address, "get_x_data"); - log.info("gas_used {}, exit_code {} ", result.getGas_used(), result.getExit_code()); - TvmStackEntryNumber x_data = (TvmStackEntryNumber) result.getStack().get(0); - log.info("x_data: {}", x_data.getNumber()); + RunResult result = tonlib.runMethod(address, "get_x_data"); + log.info("gas_used {}, exit_code {} ", result.getGas_used(), result.getExit_code()); + TvmStackEntryNumber x_data = (TvmStackEntryNumber) result.getStack().get(0); + log.info("x_data: {}", x_data.getNumber()); - result = tonlib.runMethod(address, "get_extra_field"); - log.info("gas_used {}, exit_code {} ", result.getGas_used(), result.getExit_code()); - TvmStackEntryNumber extra_field = (TvmStackEntryNumber) result.getStack().get(0); - log.info("extra_field: {}", extra_field.getNumber()); + result = tonlib.runMethod(address, "get_extra_field"); + log.info("gas_used {}, exit_code {} ", result.getGas_used(), result.getExit_code()); + TvmStackEntryNumber extra_field = (TvmStackEntryNumber) result.getStack().get(0); + log.info("extra_field: {}", extra_field.getNumber()); - Address destinationAddress = Address.of("kf_sPxv06KagKaRmOOKxeDQwApCx3i8IQOwv507XD51JOLka"); + Address destinationAddress = Address.of("kf_sPxv06KagKaRmOOKxeDQwApCx3i8IQOwv507XD51JOLka"); - CustomContractConfig config = CustomContractConfig.builder() - .seqno(exampleContract.getSeqno()) - .destination(destinationAddress) - .amount(Utils.toNano(0.05)) - .extraField(42) - .comment("no-way") - .build(); + CustomContractConfig config = + CustomContractConfig.builder() + .seqno(exampleContract.getSeqno()) + .destination(destinationAddress) + .amount(Utils.toNano(0.05)) + .extraField(42) + .comment("no-way") + .build(); - extMessageInfo = exampleContract.send(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); + extMessageInfo = exampleContract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); - exampleContract.waitForBalanceChange(45); + exampleContract.waitForBalanceChange(45); - result = tonlib.runMethod(address, "get_extra_field"); - log.info("gas_used {}, exit_code {} ", result.getGas_used(), result.getExit_code()); - extra_field = (TvmStackEntryNumber) result.getStack().get(0); - log.info("extra_field: {}", extra_field.getNumber()); + result = tonlib.runMethod(address, "get_extra_field"); + log.info("gas_used {}, exit_code {} ", result.getGas_used(), result.getExit_code()); + extra_field = (TvmStackEntryNumber) result.getStack().get(0); + log.info("extra_field: {}", extra_field.getNumber()); - assertThat(extra_field.getNumber().longValue()).isEqualTo(42); - - } + assertThat(extra_field.getNumber().longValue()).isEqualTo(42); + } } diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestHighloadWalletV2.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestHighloadWalletV2.java index d6596b2b..b7408439 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestHighloadWalletV2.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestHighloadWalletV2.java @@ -14,7 +14,7 @@ import org.junit.runners.JUnit4; import org.ton.java.address.Address; import org.ton.java.cell.CellBuilder; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.highload.HighloadWallet; import org.ton.java.smartcontract.types.Destination; import org.ton.java.smartcontract.types.HighloadConfig; @@ -26,170 +26,183 @@ @RunWith(JUnit4.class) public class TestHighloadWalletV2 extends CommonTest { - @Test - public void testSendTo10() throws InterruptedException { - - TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); - - BigInteger queryId = BigInteger.valueOf(Instant.now().getEpochSecond() + 5 * 60L << 32); - - HighloadWallet contract = HighloadWallet.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .walletId(42L) - .queryId(queryId) - .build(); - - String nonBounceableAddress = contract.getAddress().toNonBounceable(); - String bounceableAddress = contract.getAddress().toBounceable(); - String rawAddress = contract.getAddress().toRaw(); - - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - log.info(" raw address {}", rawAddress); - log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); - log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); - - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(5)); - Utils.sleep(30, "topping up..."); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - - - ExtMessageInfo extMessageInfo = contract.deploy(); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForDeployment(30); - - HighloadConfig config = HighloadConfig.builder() - .walletId(42) - .queryId(BigInteger.valueOf(Instant.now().getEpochSecond() + 5 * 60L << 32)) - .destinations(Arrays.asList( - Destination.builder() - .address("EQAyjRKDnEpTBNfRHqYdnzGEQjdY4KG3gxgqiG3DpDY46u8G") - .amount(Utils.toNano(0.2)) - .comment("test-comment-1") - .build(), - Destination.builder() - .address("EQBrpstctZ5gF-VaaPswcWHe3JQijjNbtJVn5USXlZ-bAgO3") - .amount(Utils.toNano(0.1)) - .mode(3) - .body(CellBuilder.beginCell() - .storeUint(0, 32) - .storeString("test-comment-2") - .endCell() - ).build(), - Destination.builder() - .address("EQAaGHUHfkpWFGs428ETmym4vbvRNxCA1o4sTkwqigKjgf-_") - .amount(Utils.toNano(0.3)) - .build(), - Destination.builder() - .address("EQAUEeWmzaf2An-MmNi1DRlFAU6ol_qTLP-_LlUnfgF-lA00") - .amount(Utils.toNano(0.6)) - .build(), - Destination.builder() - .address("EQCwqNA5WhNTTQtl-QDlOlwcBDUS377Q4tRW69V82Q3LXvru") - .amount(Utils.toNano(0.2)) - .build(), - Destination.builder() - .address("EQAQ93wokze84Loos4arP5aK7AlQFqbg1HDjEogsMCCbZyNo") - .amount(Utils.toNano(0.1)) - .build(), - Destination.builder() - .address("EQALeq_z73heR4wMQRFKgA_fwkbZgxEf0ya0Kl6UjvpvG-A3") - .amount(Utils.toNano(0.15)) - .build(), - Destination.builder() - .address("EQCP-ejxzoB6KJ6auhnsPrW1pW6gAZ8uHXnUSHuHGNpY1zJf") - .amount(Utils.toNano(0.42)) - .build(), - Destination.builder() - .address("EQCkS2OnOOjeLV-LEEUmIPh-_in4pdFr1cScZG1Inft3qUea") - .amount(Utils.toNano(0.22)) - .build(), - Destination.builder() - .address("EQCZlgy61mcgYNXK0yiFHC9CxjoxxAFkwiUtzTONrk6_Qk6W") - .amount(Utils.toNano(0.33)) - .build() - )) - .build(); - - // transfer coins to multiple destination as specified in options - extMessageInfo = contract.send(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - log.info("sending to 10 destinations"); - contract.waitForBalanceChange(90); - - balance = contract.getBalance(); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(contract.getBalance())); - assertThat(balance.longValue()).isLessThan(Utils.toNano(3).longValue()); - } - - @Test - public void testSendTo250() throws InterruptedException { - - TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); - - BigInteger queryId = BigInteger.valueOf(Instant.now().getEpochSecond() + 5 * 60L << 32); - - HighloadWallet contract = HighloadWallet.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .walletId(42L) - .queryId(queryId) - .build(); - - String nonBounceableAddress = contract.getAddress().toNonBounceable(); - String bounceableAddress = contract.getAddress().toBounceable(); - - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); - log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); - - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(15)); - Utils.sleep(30, "topping up..."); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - - ExtMessageInfo extMessageInfo = contract.deploy(); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForDeployment(60); - - List destinations = generateTargetsWithSameAmountAndSendMode(250); - - HighloadConfig highloadConfig = HighloadConfig.builder() - .walletId(42) - .queryId(BigInteger.valueOf(Instant.now().getEpochSecond() + 5 * 60L << 32)) - .destinations(destinations) - .build(); - - extMessageInfo = contract.send(highloadConfig); - assertThat(extMessageInfo.getError().getCode()).isZero(); - } - - private List generateTargetsWithSameAmountAndSendMode(int count) { - - List result = new ArrayList<>(); - - for (int i = 0; i < count; i++) { - - WalletV3R2 contract = WalletV3R2.builder().build(); - - Address dest = contract.getAddress(); - double amount = 0.05; - log.info("will send {} to {}", Utils.formatNanoValue(Utils.toNano(amount)), dest.toNonBounceable()); - - Destination destination = Destination.builder() - .bounce(false) - .address(dest.toNonBounceable()) - .amount(Utils.toNano(amount)) - .build(); - - result.add(destination); - } - return result; + @Test + public void testSendTo10() throws InterruptedException { + + TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); + + BigInteger queryId = BigInteger.valueOf(Instant.now().getEpochSecond() + 5 * 60L << 32); + + HighloadWallet contract = + HighloadWallet.builder() + .tonlib(tonlib) + .keyPair(keyPair) + .walletId(42L) + .queryId(queryId) + .build(); + + String nonBounceableAddress = contract.getAddress().toNonBounceable(); + String bounceableAddress = contract.getAddress().toBounceable(); + String rawAddress = contract.getAddress().toRaw(); + + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + log.info(" raw address {}", rawAddress); + log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); + log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); + + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(5)); + Utils.sleep(30, "topping up..."); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + + ExtMessageInfo extMessageInfo = contract.deploy(); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForDeployment(30); + + HighloadConfig config = + HighloadConfig.builder() + .walletId(42) + .queryId(BigInteger.valueOf(Instant.now().getEpochSecond() + 5 * 60L << 32)) + .destinations( + Arrays.asList( + Destination.builder() + .address("EQAyjRKDnEpTBNfRHqYdnzGEQjdY4KG3gxgqiG3DpDY46u8G") + .amount(Utils.toNano(0.2)) + .comment("test-comment-1") + .build(), + Destination.builder() + .address("EQBrpstctZ5gF-VaaPswcWHe3JQijjNbtJVn5USXlZ-bAgO3") + .amount(Utils.toNano(0.1)) + .mode(3) + .body( + CellBuilder.beginCell() + .storeUint(0, 32) + .storeString("test-comment-2") + .endCell()) + .build(), + Destination.builder() + .address("EQAaGHUHfkpWFGs428ETmym4vbvRNxCA1o4sTkwqigKjgf-_") + .amount(Utils.toNano(0.3)) + .build(), + Destination.builder() + .address("EQAUEeWmzaf2An-MmNi1DRlFAU6ol_qTLP-_LlUnfgF-lA00") + .amount(Utils.toNano(0.6)) + .build(), + Destination.builder() + .address("EQCwqNA5WhNTTQtl-QDlOlwcBDUS377Q4tRW69V82Q3LXvru") + .amount(Utils.toNano(0.2)) + .build(), + Destination.builder() + .address("EQAQ93wokze84Loos4arP5aK7AlQFqbg1HDjEogsMCCbZyNo") + .amount(Utils.toNano(0.1)) + .build(), + Destination.builder() + .address("EQALeq_z73heR4wMQRFKgA_fwkbZgxEf0ya0Kl6UjvpvG-A3") + .amount(Utils.toNano(0.15)) + .build(), + Destination.builder() + .address("EQCP-ejxzoB6KJ6auhnsPrW1pW6gAZ8uHXnUSHuHGNpY1zJf") + .amount(Utils.toNano(0.42)) + .build(), + Destination.builder() + .address("EQCkS2OnOOjeLV-LEEUmIPh-_in4pdFr1cScZG1Inft3qUea") + .amount(Utils.toNano(0.22)) + .build(), + Destination.builder() + .address("EQCZlgy61mcgYNXK0yiFHC9CxjoxxAFkwiUtzTONrk6_Qk6W") + .amount(Utils.toNano(0.33)) + .build())) + .build(); + + // transfer coins to multiple destination as specified in options + extMessageInfo = contract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + log.info("sending to 10 destinations"); + contract.waitForBalanceChange(90); + + balance = contract.getBalance(); + log.info( + "new wallet {} balance: {}", + contract.getName(), + Utils.formatNanoValue(contract.getBalance())); + assertThat(balance.longValue()).isLessThan(Utils.toNano(3).longValue()); + } + + @Test + public void testSendTo250() throws InterruptedException { + + TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); + + BigInteger queryId = BigInteger.valueOf(Instant.now().getEpochSecond() + 5 * 60L << 32); + + HighloadWallet contract = + HighloadWallet.builder() + .tonlib(tonlib) + .keyPair(keyPair) + .walletId(42L) + .queryId(queryId) + .build(); + + String nonBounceableAddress = contract.getAddress().toNonBounceable(); + String bounceableAddress = contract.getAddress().toBounceable(); + + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); + log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); + + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(15)); + Utils.sleep(30, "topping up..."); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + + ExtMessageInfo extMessageInfo = contract.deploy(); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForDeployment(60); + + List destinations = generateTargetsWithSameAmountAndSendMode(250); + + HighloadConfig highloadConfig = + HighloadConfig.builder() + .walletId(42) + .queryId(BigInteger.valueOf(Instant.now().getEpochSecond() + 5 * 60L << 32)) + .destinations(destinations) + .build(); + + extMessageInfo = contract.send(highloadConfig); + assertThat(extMessageInfo.getError().getCode()).isZero(); + } + + private List generateTargetsWithSameAmountAndSendMode(int count) { + + List result = new ArrayList<>(); + + for (int i = 0; i < count; i++) { + + WalletV3R2 contract = WalletV3R2.builder().build(); + + Address dest = contract.getAddress(); + double amount = 0.05; + log.info( + "will send {} to {}", + Utils.formatNanoValue(Utils.toNano(amount)), + dest.toNonBounceable()); + + Destination destination = + Destination.builder() + .bounce(false) + .address(dest.toNonBounceable()) + .amount(Utils.toNano(amount)) + .build(); + + result.add(destination); } + return result; + } } diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestHighloadWalletV3.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestHighloadWalletV3.java index f1ecabb6..4c4ac15c 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestHighloadWalletV3.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestHighloadWalletV3.java @@ -17,8 +17,8 @@ import org.ton.java.address.Address; import org.ton.java.cell.Cell; import org.ton.java.cell.CellBuilder; -import org.ton.java.smartcontract.TestFaucet; -import org.ton.java.smartcontract.TestJettonFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; +import org.ton.java.smartcontract.faucet.TestnetJettonFaucet; import org.ton.java.smartcontract.highload.HighloadWalletV3; import org.ton.java.smartcontract.token.ft.JettonMinter; import org.ton.java.smartcontract.token.ft.JettonWallet; @@ -37,571 +37,602 @@ @RunWith(JUnit4.class) public class TestHighloadWalletV3 extends CommonTest { - @Test - public void testBulkTransferSimplified_2() throws InterruptedException { - - TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); - - HighloadWalletV3 contract = HighloadWalletV3.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .walletId(42) - .build(); - - String nonBounceableAddress = contract.getAddress().toNonBounceable(); - String bounceableAddress = contract.getAddress().toBounceable(); - String rawAddress = contract.getAddress().toRaw(); - - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - log.info(" raw address {}", rawAddress); - log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); - log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); - - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); - Utils.sleep(30, "topping up..."); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - - HighloadV3Config config = HighloadV3Config.builder() - .walletId(42) - .queryId(HighloadQueryId.fromSeqno(0).getQueryId()) -// .createdAt(createdAt) // default = now - 60 seconds - //.timeOut(60) //default timeout = 5 minutes - .build(); - - ExtMessageInfo extMessageInfo = contract.deploy(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForDeployment(45); - - config = HighloadV3Config.builder() - .walletId(42) - .queryId(HighloadQueryId.fromSeqno(1).getQueryId()) - .body( - contract.createBulkTransfer(Arrays.asList( - Destination.builder() - .address("0QAs9VlT6S776tq3unJcP5Ogsj-ELLunLXuOb1EKcOQi4-QO") - .amount(Utils.toNano(0.022)) - .body(CellBuilder.beginCell() - .storeUint(0, 32) - .storeString("test-comment-1") - .endCell()).build(), - Destination.builder() - .address("EQAyjRKDnEpTBNfRHqYdnzGEQjdY4KG3gxgqiG3DpDY46u8G") - .amount(Utils.toNano(0.033)) - .comment("test-comment-2") - .build()), - BigInteger.valueOf(HighloadQueryId.fromSeqno(1).getQueryId()))) - .build(); - - extMessageInfo = contract.send(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - log.info("sent 2 messages"); - } - - - /** - * Sends 1000 messages with values without comment/memo field - */ - @Test - public void testBulkTransferSimplified_1000() throws InterruptedException, NoSuchAlgorithmException { - - TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); - - HighloadWalletV3 contract = HighloadWalletV3.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .walletId(42) - .build(); - - String nonBounceableAddress = contract.getAddress().toNonBounceable(); - String bounceableAddress = contract.getAddress().toBounceable(); - String rawAddress = contract.getAddress().toRaw(); - - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - log.info(" raw address {}", rawAddress); - log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); - log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); - - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(12)); - Utils.sleep(30, "topping up..."); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - - HighloadV3Config config = HighloadV3Config.builder() - .walletId(42) - .queryId(HighloadQueryId.fromSeqno(0).getQueryId()) - .build(); - - ExtMessageInfo extMessageInfo = contract.deploy(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForDeployment(45); - - config = HighloadV3Config.builder() - .walletId(42) - .queryId(HighloadQueryId.fromSeqno(1).getQueryId()) - .body(contract.createBulkTransfer( - createDummyDestinations(1000), - BigInteger.valueOf(HighloadQueryId.fromSeqno(1).getQueryId()))) - .build(); - - extMessageInfo = contract.send(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - log.info("sent 1000 messages"); - } - - - /** - * Sends 1000 messages with jetton values with comment - */ - @Test - public void testBulkJettonTransferSimplified_1000() throws InterruptedException, NoSuchAlgorithmException { - - TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); - - HighloadWalletV3 contract = HighloadWalletV3.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .walletId(42) - .build(); - - String nonBounceableAddress = contract.getAddress().toNonBounceable(); - String bounceableAddress = contract.getAddress().toBounceable(); - String rawAddress = contract.getAddress().toRaw(); - - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - log.info(" raw address {}", rawAddress); - log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); - log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); - - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(12)); - Utils.sleep(30, "topping up..."); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - - HighloadV3Config config = HighloadV3Config.builder() - .walletId(42) - .queryId(HighloadQueryId.fromSeqno(0).getQueryId()) - .build(); - - ExtMessageInfo extMessageInfo = contract.deploy(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForDeployment(45); - - config = HighloadV3Config.builder() - .walletId(42) - .queryId(HighloadQueryId.fromSeqno(1).getQueryId()) - .body(contract.createBulkTransfer( - createDummyDestinations(300), - BigInteger.valueOf(HighloadQueryId.fromSeqno(1).getQueryId()))) - .build(); - - extMessageInfo = contract.send(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - log.info("sent 1000 messages"); - } - - @Test - public void testSinglePayloadTransfer() throws InterruptedException { - - TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); - - HighloadWalletV3 contract = HighloadWalletV3.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .walletId(42) - .build(); - - String nonBounceableAddress = contract.getAddress().toNonBounceable(); - String bounceableAddress = contract.getAddress().toBounceable(); - String rawAddress = contract.getAddress().toRaw(); - - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - log.info(" raw address {}", rawAddress); - log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); - log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); - - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); - Utils.sleep(30, "topping up..."); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - - Address destAddress = Address.of("EQAyjRKDnEpTBNfRHqYdnzGEQjdY4KG3gxgqiG3DpDY46u8G"); - - HighloadV3Config config = HighloadV3Config.builder() - .walletId(42) - .queryId(HighloadQueryId.fromSeqno(0).getQueryId()) -// .createdAt(createdAt) // default = now - 60 seconds - //.timeOut(60) //default timeout = 5 minutes - .build(); - - ExtMessageInfo extMessageInfo = contract.deploy(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForDeployment(45); - - config = HighloadV3Config.builder() - .walletId(42) - .queryId(HighloadQueryId.fromSeqno(1).getQueryId()) - .body(contract.createSingleTransfer(destAddress, - Utils.toNano(0.02), - true, - null, -// MsgUtils.createTextMessageBody("ton4j") - CellBuilder.beginCell().endCell() - )) - .build(); - - extMessageInfo = contract.send(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - log.info("sent single message"); - } - - @Test - public void testTransfer_3_DifferentRecipients() throws InterruptedException, NoSuchAlgorithmException { - tonlib = Tonlib.builder() - .testnet(true) - .ignoreCache(false) - .verbosityLevel(VerbosityLevel.DEBUG) - .build(); - - TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); - - HighloadWalletV3 contract = HighloadWalletV3.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .walletId(42) - .build(); - - String nonBounceableAddress = contract.getAddress().toNonBounceable(); - String bounceableAddress = contract.getAddress().toBounceable(); - String rawAddress = contract.getAddress().toRaw(); - - - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - log.info(" raw address {}", rawAddress); - log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); - log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); + @Test + public void testBulkTransferSimplified_2() throws InterruptedException { + + TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); + + HighloadWalletV3 contract = + HighloadWalletV3.builder().tonlib(tonlib).keyPair(keyPair).walletId(42).build(); + + String nonBounceableAddress = contract.getAddress().toNonBounceable(); + String bounceableAddress = contract.getAddress().toBounceable(); + String rawAddress = contract.getAddress().toRaw(); + + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + log.info(" raw address {}", rawAddress); + log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); + log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); + + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); + Utils.sleep(30, "topping up..."); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + + HighloadV3Config config = + HighloadV3Config.builder() + .walletId(42) + .queryId(HighloadQueryId.fromSeqno(0).getQueryId()) + // .createdAt(createdAt) // default = now - 60 seconds + // .timeOut(60) //default timeout = 5 minutes + .build(); + + ExtMessageInfo extMessageInfo = contract.deploy(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForDeployment(45); + + config = + HighloadV3Config.builder() + .walletId(42) + .queryId(HighloadQueryId.fromSeqno(1).getQueryId()) + .body( + contract.createBulkTransfer( + Arrays.asList( + Destination.builder() + .address("0QAs9VlT6S776tq3unJcP5Ogsj-ELLunLXuOb1EKcOQi4-QO") + .amount(Utils.toNano(0.022)) + .body( + CellBuilder.beginCell() + .storeUint(0, 32) + .storeString("test-comment-1") + .endCell()) + .build(), + Destination.builder() + .address("EQAyjRKDnEpTBNfRHqYdnzGEQjdY4KG3gxgqiG3DpDY46u8G") + .amount(Utils.toNano(0.033)) + .comment("test-comment-2") + .build()), + BigInteger.valueOf(HighloadQueryId.fromSeqno(1).getQueryId()))) + .build(); + + extMessageInfo = contract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + log.info("sent 2 messages"); + } + + /** Sends 1000 messages with values without comment/memo field */ + @Test + public void testBulkTransferSimplified_1000() + throws InterruptedException, NoSuchAlgorithmException { + + TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); + + HighloadWalletV3 contract = + HighloadWalletV3.builder().tonlib(tonlib).keyPair(keyPair).walletId(42).build(); + + String nonBounceableAddress = contract.getAddress().toNonBounceable(); + String bounceableAddress = contract.getAddress().toBounceable(); + String rawAddress = contract.getAddress().toRaw(); + + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + log.info(" raw address {}", rawAddress); + log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); + log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); + + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(12)); + Utils.sleep(30, "topping up..."); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + + HighloadV3Config config = + HighloadV3Config.builder() + .walletId(42) + .queryId(HighloadQueryId.fromSeqno(0).getQueryId()) + .build(); + + ExtMessageInfo extMessageInfo = contract.deploy(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForDeployment(45); + + config = + HighloadV3Config.builder() + .walletId(42) + .queryId(HighloadQueryId.fromSeqno(1).getQueryId()) + .body( + contract.createBulkTransfer( + createDummyDestinations(1000), + BigInteger.valueOf(HighloadQueryId.fromSeqno(1).getQueryId()))) + .build(); + + extMessageInfo = contract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + log.info("sent 1000 messages"); + } + + /** Sends 1000 messages with jetton values with comment */ + @Test + public void testBulkJettonTransferSimplified_1000() + throws InterruptedException, NoSuchAlgorithmException { + + TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); + + HighloadWalletV3 contract = + HighloadWalletV3.builder().tonlib(tonlib).keyPair(keyPair).walletId(42).build(); + + String nonBounceableAddress = contract.getAddress().toNonBounceable(); + String bounceableAddress = contract.getAddress().toBounceable(); + String rawAddress = contract.getAddress().toRaw(); + + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + log.info(" raw address {}", rawAddress); + log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); + log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); + + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(12)); + Utils.sleep(30, "topping up..."); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + + HighloadV3Config config = + HighloadV3Config.builder() + .walletId(42) + .queryId(HighloadQueryId.fromSeqno(0).getQueryId()) + .build(); + + ExtMessageInfo extMessageInfo = contract.deploy(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForDeployment(45); + + config = + HighloadV3Config.builder() + .walletId(42) + .queryId(HighloadQueryId.fromSeqno(1).getQueryId()) + .body( + contract.createBulkTransfer( + createDummyDestinations(300), + BigInteger.valueOf(HighloadQueryId.fromSeqno(1).getQueryId()))) + .build(); + + extMessageInfo = contract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + log.info("sent 1000 messages"); + } + + @Test + public void testSinglePayloadTransfer() throws InterruptedException { + + TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); + + HighloadWalletV3 contract = + HighloadWalletV3.builder().tonlib(tonlib).keyPair(keyPair).walletId(42).build(); + + String nonBounceableAddress = contract.getAddress().toNonBounceable(); + String bounceableAddress = contract.getAddress().toBounceable(); + String rawAddress = contract.getAddress().toRaw(); + + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + log.info(" raw address {}", rawAddress); + log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); + log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); + + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); + Utils.sleep(30, "topping up..."); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + + Address destAddress = Address.of("EQAyjRKDnEpTBNfRHqYdnzGEQjdY4KG3gxgqiG3DpDY46u8G"); + + HighloadV3Config config = + HighloadV3Config.builder() + .walletId(42) + .queryId(HighloadQueryId.fromSeqno(0).getQueryId()) + // .createdAt(createdAt) // default = now - 60 seconds + // .timeOut(60) //default timeout = 5 minutes + .build(); + + ExtMessageInfo extMessageInfo = contract.deploy(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForDeployment(45); + + config = + HighloadV3Config.builder() + .walletId(42) + .queryId(HighloadQueryId.fromSeqno(1).getQueryId()) + .body( + contract.createSingleTransfer( + destAddress, + Utils.toNano(0.02), + true, + null, + // MsgUtils.createTextMessageBody("ton4j") + CellBuilder.beginCell().endCell())) + .build(); + + extMessageInfo = contract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + log.info("sent single message"); + } + + @Test + public void testTransfer_3_DifferentRecipients() + throws InterruptedException, NoSuchAlgorithmException { + tonlib = + Tonlib.builder() + .testnet(true) + .ignoreCache(false) + .verbosityLevel(VerbosityLevel.DEBUG) + .build(); + + TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); + + HighloadWalletV3 contract = + HighloadWalletV3.builder().tonlib(tonlib).keyPair(keyPair).walletId(42).build(); + + String nonBounceableAddress = contract.getAddress().toNonBounceable(); + String bounceableAddress = contract.getAddress().toBounceable(); + String rawAddress = contract.getAddress().toRaw(); + + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + log.info(" raw address {}", rawAddress); + log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); + log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); + + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + + HighloadV3Config config = + HighloadV3Config.builder() + .walletId(42) + .queryId(HighloadQueryId.fromSeqno(0).getQueryId()) + .build(); - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + ExtMessageInfo extMessageInfo = contract.deploy(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); - HighloadV3Config config = HighloadV3Config.builder() - .walletId(42) - .queryId(HighloadQueryId.fromSeqno(0).getQueryId()) - .build(); + contract.waitForDeployment(30); - ExtMessageInfo extMessageInfo = contract.deploy(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); + int numberOfRecipients = 3; + BigInteger amountToSendTotal = Utils.toNano(0.01 * numberOfRecipients); - contract.waitForDeployment(30); + Cell nMessages = createDummyRecipients(numberOfRecipients, contract, null); - int numberOfRecipients = 3; - BigInteger amountToSendTotal = Utils.toNano(0.01 * numberOfRecipients); + Cell extMsgWith3Mgs = contract.createBulkTransfer(amountToSendTotal, nMessages); - Cell nMessages = createDummyRecipients(numberOfRecipients, contract, null); + config = + HighloadV3Config.builder() + .walletId(42) + .body(extMsgWith3Mgs) + .queryId(HighloadQueryId.fromSeqno(1).getQueryId()) + .build(); + + extMessageInfo = contract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + log.info("sent {} messages", numberOfRecipients); + } - Cell extMsgWith3Mgs = contract.createBulkTransfer(amountToSendTotal, nMessages); + @Test + public void testTransfer_200_CustomCell() throws InterruptedException, NoSuchAlgorithmException { + + TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); - config = HighloadV3Config.builder() - .walletId(42) - .body(extMsgWith3Mgs) - .queryId(HighloadQueryId.fromSeqno(1).getQueryId()) - .build(); + HighloadWalletV3 contract = + HighloadWalletV3.builder().tonlib(tonlib).keyPair(keyPair).walletId(42).build(); + + String nonBounceableAddress = contract.getAddress().toNonBounceable(); + String bounceableAddress = contract.getAddress().toBounceable(); + + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + log.info(" raw address {}", contract.getAddress().toString(false)); + log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); + log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); + + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(3)); + + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + + // long createdAt = Instant.now().getEpochSecond() - 60 * 5; + + HighloadV3Config config = + HighloadV3Config.builder() + .walletId(42) + .queryId(HighloadQueryId.fromSeqno(0).getQueryId()) + .build(); - extMessageInfo = contract.send(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - log.info("sent {} messages", numberOfRecipients); - } - - @Test - public void testTransfer_200_CustomCell() throws InterruptedException, NoSuchAlgorithmException { - - TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); - - HighloadWalletV3 contract = HighloadWalletV3.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .walletId(42) - .build(); + ExtMessageInfo extMessageInfo = contract.deploy(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); - String nonBounceableAddress = contract.getAddress().toNonBounceable(); - String bounceableAddress = contract.getAddress().toBounceable(); + contract.waitForDeployment(30); - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - log.info(" raw address {}", contract.getAddress().toString(false)); - log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); - log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); + int numberOfRecipients = 200; + BigInteger amountToSendTotal = Utils.toNano(0.01 * numberOfRecipients); - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(3)); + Cell nMessages = createDummyRecipients(numberOfRecipients, contract, null); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + Cell extMsgWith200Mgs = contract.createBulkTransfer(amountToSendTotal, nMessages); -// long createdAt = Instant.now().getEpochSecond() - 60 * 5; + config = + HighloadV3Config.builder() + .walletId(42) + .body(extMsgWith200Mgs) + .queryId(HighloadQueryId.fromSeqno(1).getQueryId()) + .build(); - HighloadV3Config config = HighloadV3Config.builder() - .walletId(42) - .queryId(HighloadQueryId.fromSeqno(0).getQueryId()) - .build(); + extMessageInfo = contract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + log.info("sent {} messages", numberOfRecipients); + } - ExtMessageInfo extMessageInfo = contract.deploy(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); + @Test + public void testTransfer_1000_CustomCell() throws InterruptedException, NoSuchAlgorithmException { - contract.waitForDeployment(30); + TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); - int numberOfRecipients = 200; - BigInteger amountToSendTotal = Utils.toNano(0.01 * numberOfRecipients); + HighloadWalletV3 contract = + HighloadWalletV3.builder().tonlib(tonlib).keyPair(keyPair).walletId(42).build(); - Cell nMessages = createDummyRecipients(numberOfRecipients, contract, null); - - Cell extMsgWith200Mgs = contract.createBulkTransfer(amountToSendTotal, nMessages); - - config = HighloadV3Config.builder() - .walletId(42) - .body(extMsgWith200Mgs) - .queryId(HighloadQueryId.fromSeqno(1).getQueryId()) - .build(); - - extMessageInfo = contract.send(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - log.info("sent {} messages", numberOfRecipients); - } + String nonBounceableAddress = contract.getAddress().toNonBounceable(); + String bounceableAddress = contract.getAddress().toBounceable(); - @Test - public void testTransfer_1000_CustomCell() throws InterruptedException, NoSuchAlgorithmException { + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + log.info(" raw address {}", contract.getAddress().toString(false)); - TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(12)); - HighloadWalletV3 contract = HighloadWalletV3.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .walletId(42) - .build(); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - String nonBounceableAddress = contract.getAddress().toNonBounceable(); - String bounceableAddress = contract.getAddress().toBounceable(); + HighloadV3Config config = + HighloadV3Config.builder() + .walletId(42) + .queryId(HighloadQueryId.fromSeqno(0).getQueryId()) + .build(); - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - log.info(" raw address {}", contract.getAddress().toString(false)); + ExtMessageInfo extMessageInfo = contract.deploy(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(12)); + contract.waitForDeployment(30); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + Cell nMessages1 = createDummyRecipients(250, contract, null); + Cell nMessages2 = createDummyRecipients(250, contract, nMessages1); + Cell nMessages3 = createDummyRecipients(250, contract, nMessages2); + Cell nMessages4 = createDummyRecipients(250, contract, nMessages3); + Cell extMsgWith400Mgs = contract.createBulkTransfer(Utils.toNano(11), nMessages4); - HighloadV3Config config = HighloadV3Config.builder() - .walletId(42) - .queryId(HighloadQueryId.fromSeqno(0).getQueryId()) - .build(); + config = + HighloadV3Config.builder() + .walletId(42) + .body(extMsgWith400Mgs) + .queryId(HighloadQueryId.fromSeqno(1).getQueryId()) + .build(); - ExtMessageInfo extMessageInfo = contract.deploy(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); + extMessageInfo = contract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + log.info("sent {} messages", 1000); + } - contract.waitForDeployment(30); - - Cell nMessages1 = createDummyRecipients(250, contract, null); - Cell nMessages2 = createDummyRecipients(250, contract, nMessages1); - Cell nMessages3 = createDummyRecipients(250, contract, nMessages2); - Cell nMessages4 = createDummyRecipients(250, contract, nMessages3); - Cell extMsgWith400Mgs = contract.createBulkTransfer(Utils.toNano(11), nMessages4); - - config = HighloadV3Config.builder() - .walletId(42) - .body(extMsgWith400Mgs) - .queryId(HighloadQueryId.fromSeqno(1).getQueryId()) - .build(); - - extMessageInfo = contract.send(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - log.info("sent {} messages", 1000); + @Test + public void testHighloadQueryId() { + HighloadQueryId qid = new HighloadQueryId(); + assertThat(qid.getQueryId()).isEqualTo(0); + qid = qid.getNext(); + assertThat(qid.getQueryId()).isEqualTo(1); + for (int i = 0; i < 1022; i++) { + qid = qid.getNext(); } - - @Test - public void testHighloadQueryId() { - HighloadQueryId qid = new HighloadQueryId(); - assertThat(qid.getQueryId()).isEqualTo(0); - qid = qid.getNext(); - assertThat(qid.getQueryId()).isEqualTo(1); - for (int i = 0; i < 1022; i++) { - qid = qid.getNext(); - } - assertThat(qid.getQueryId()).isEqualTo(1024); - assertThat(qid.toSeqno()).isEqualTo(1023); - - qid = HighloadQueryId.fromShiftAndBitNumber(8191, 1020); - assertThat(qid.hasNext()).isTrue(); - qid = qid.getNext(); - assertThat(qid.hasNext()).isFalse(); - - int nqid = qid.getQueryId(); - qid = HighloadQueryId.fromSeqno(qid.toSeqno()); - assertThat(nqid).isEqualTo(qid.getQueryId()); - qid = HighloadQueryId.fromQueryId(qid.getQueryId()); - assertThat(nqid).isEqualTo(qid.getQueryId()); + assertThat(qid.getQueryId()).isEqualTo(1024); + assertThat(qid.toSeqno()).isEqualTo(1023); + + qid = HighloadQueryId.fromShiftAndBitNumber(8191, 1020); + assertThat(qid.hasNext()).isTrue(); + qid = qid.getNext(); + assertThat(qid.hasNext()).isFalse(); + + int nqid = qid.getQueryId(); + qid = HighloadQueryId.fromSeqno(qid.toSeqno()); + assertThat(nqid).isEqualTo(qid.getQueryId()); + qid = HighloadQueryId.fromQueryId(qid.getQueryId()); + assertThat(nqid).isEqualTo(qid.getQueryId()); + } + + Cell createDummyRecipients(int numRecipients, HighloadWalletV3 contract, Cell body) + throws NoSuchAlgorithmException { + List outActions = new ArrayList<>(); + for (int i = 0; i < numRecipients; i++) { + Address destinationAddress = + Address.of( + "0:" + + Utils.bytesToHex( + MessageDigest.getInstance("SHA-256") + .digest(UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8)))); + log.info("dest {} is {}", i, destinationAddress.toBounceable()); + OutAction outAction = + ActionSendMsg.builder() + .mode((byte) 3) + .outMsg( + MessageRelaxed.builder() + .info( + InternalMessageInfoRelaxed.builder() + .bounce(false) // warning, for tests only + .dstAddr( + MsgAddressIntStd.builder() + .workchainId(destinationAddress.wc) + .address(destinationAddress.toBigInteger()) + .build()) + .value(CurrencyCollection.builder().coins(Utils.toNano(0.01)).build()) + .build()) + .build()) + .build(); + outActions.add(outAction); } - Cell createDummyRecipients(int numRecipients, HighloadWalletV3 contract, Cell body) throws NoSuchAlgorithmException { - List outActions = new ArrayList<>(); - for (int i = 0; i < numRecipients; i++) { - Address destinationAddress = Address.of("0:" + Utils.bytesToHex(MessageDigest.getInstance("SHA-256").digest(UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8)))); - log.info("dest {} is {}", i, destinationAddress.toBounceable()); - OutAction outAction = ActionSendMsg.builder() - .mode((byte) 3) - .outMsg(MessageRelaxed.builder() - .info(InternalMessageInfoRelaxed.builder() - .bounce(false) // warning, for tests only - .dstAddr(MsgAddressIntStd.builder() - .workchainId(destinationAddress.wc) - .address(destinationAddress.toBigInteger()) - .build()) - .value(CurrencyCollection.builder() - .coins(Utils.toNano(0.01)) - .build()) - .build()) - .build()) - .build(); - outActions.add(outAction); - } - - if (nonNull(body)) { // one of those N messages can contain internal message with other X recipients - OutAction outAction = ActionSendMsg.builder() - .mode(3) - .outMsg(MessageRelaxed.builder() - .info(InternalMessageInfoRelaxed.builder() - .dstAddr(MsgAddressIntStd.builder() - .workchainId(contract.getAddress().wc) - .address(contract.getAddress().toBigInteger()) - .build()) - .value(CurrencyCollection.builder() - .coins(Utils.toNano(0.01)) - .build()) - .build()) - .body(body) // added other X messages - .build()) - .build(); - outActions.add(outAction); - } - - return HighloadV3InternalMessageBody.builder() - .queryId(BigInteger.ZERO) - .actions(OutList.builder() - .actions(outActions) - .build()) - .build().toCell(); - } - - - @Test - public void testBulkJettonTransfer() throws InterruptedException, NoSuchAlgorithmException { - - Tonlib tonlib = Tonlib.builder() - .testnet(true) - .ignoreCache(false) - .build(); - - TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); - - HighloadWalletV3 myHighLoadWalletV3 = HighloadWalletV3.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .walletId(42) - .build(); - - String nonBounceableAddress = myHighLoadWalletV3.getAddress().toNonBounceable(); - String bounceableAddress = myHighLoadWalletV3.getAddress().toBounceable(); - String rawAddress = myHighLoadWalletV3.getAddress().toRaw(); - - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - log.info(" raw address {}", rawAddress); - log.info("pub-key {}", Utils.bytesToHex(myHighLoadWalletV3.getKeyPair().getPublicKey())); - log.info("prv-key {}", Utils.bytesToHex(myHighLoadWalletV3.getKeyPair().getSecretKey())); - - - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); - log.info("new wallet {} toncoins balance: {}", myHighLoadWalletV3.getName(), Utils.formatNanoValue(balance)); - - // top up new wallet with NEOJ using test-jetton-faucet-wallet - balance = TestJettonFaucet.topUpContractWithNeoj(tonlib, Address.of(nonBounceableAddress), BigInteger.valueOf(100)); - log.info("new wallet {} jetton balance: {}", myHighLoadWalletV3.getName(), Utils.formatJettonValue(balance, 2, 2)); - - HighloadV3Config config = HighloadV3Config.builder() - .walletId(42) - .queryId(HighloadQueryId.fromSeqno(0).getQueryId()) - .build(); - - ExtMessageInfo extMessageInfo = myHighLoadWalletV3.deploy(config); - Assertions.assertThat(extMessageInfo.getError().getCode()).isZero(); - - myHighLoadWalletV3.waitForDeployment(60); - - String singleRandomAddress = "0:" + Utils.bytesToHex(MessageDigest.getInstance("SHA-256").digest(UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8))); - - JettonMinter jettonMinterWallet = JettonMinter.builder() - .tonlib(tonlib) - .customAddress(Address.of("kQAN6TAGauShFKDQvZCwNb_EeTUIjQDwRZ9t6GOn4FBzfg9Y")) - .build(); - - JettonWallet myJettonHighLoadWallet = jettonMinterWallet.getJettonWallet(myHighLoadWalletV3.getAddress()); - - config = HighloadV3Config.builder() - .walletId(42) - .queryId(HighloadQueryId.fromSeqno(1).getQueryId()) - .body(myHighLoadWalletV3.createBulkTransfer( - Collections.singletonList( - Destination.builder() - .address(myJettonHighLoadWallet.getAddress().toBounceable()) - .amount(Utils.toNano(0.07)) - .body(JettonWallet.createTransferBody( - 0, - BigInteger.valueOf(100), - Address.of(singleRandomAddress), // recipient - myJettonHighLoadWallet.getAddress(), // response address - null, // custom payload - BigInteger.ONE, // forward amount - MsgUtils.createTextMessageBody("test sdk") // forward payload - )).build()), - BigInteger.valueOf(HighloadQueryId.fromSeqno(1).getQueryId()) - )) - .mode(3) - .build(); - - extMessageInfo = myHighLoadWalletV3.send(config); - Assertions.assertThat(extMessageInfo.getError().getCode()).isZero(); - - Utils.sleep(60, "sending jettons..."); - - BigInteger balanceOfDestinationWallet = tonlib.getAccountBalance(Address.of(singleRandomAddress)); - log.info("balanceOfDestinationWallet in nanocoins: {}", balanceOfDestinationWallet); - - JettonWallet randomJettonWallet = jettonMinterWallet.getJettonWallet(Address.of(singleRandomAddress)); - log.info("balanceOfDestinationWallet in jettons: {}", randomJettonWallet.getBalance()); + if (nonNull( + body)) { // one of those N messages can contain internal message with other X recipients + OutAction outAction = + ActionSendMsg.builder() + .mode(3) + .outMsg( + MessageRelaxed.builder() + .info( + InternalMessageInfoRelaxed.builder() + .dstAddr( + MsgAddressIntStd.builder() + .workchainId(contract.getAddress().wc) + .address(contract.getAddress().toBigInteger()) + .build()) + .value(CurrencyCollection.builder().coins(Utils.toNano(0.01)).build()) + .build()) + .body(body) // added other X messages + .build()) + .build(); + outActions.add(outAction); } - List createDummyDestinations(int count) throws NoSuchAlgorithmException { - List result = new ArrayList<>(); - for (int i = 0; i < count; i++) { - String dstDummyAddress = "0:" + Utils.bytesToHex(MessageDigest.getInstance("SHA-256").digest(UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8))); - - result.add(Destination.builder() - .bounce(false) - .address(dstDummyAddress) - .amount(Utils.toNano(0.01)) -// .comment("comment-" + i) - .build()); - } - return result; + return HighloadV3InternalMessageBody.builder() + .queryId(BigInteger.ZERO) + .actions(OutList.builder().actions(outActions).build()) + .build() + .toCell(); + } + + @Test + public void testBulkJettonTransfer() throws InterruptedException, NoSuchAlgorithmException { + + Tonlib tonlib = Tonlib.builder().testnet(true).ignoreCache(false).build(); + + TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); + + HighloadWalletV3 myHighLoadWalletV3 = + HighloadWalletV3.builder().tonlib(tonlib).keyPair(keyPair).walletId(42).build(); + + String nonBounceableAddress = myHighLoadWalletV3.getAddress().toNonBounceable(); + String bounceableAddress = myHighLoadWalletV3.getAddress().toBounceable(); + String rawAddress = myHighLoadWalletV3.getAddress().toRaw(); + + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + log.info(" raw address {}", rawAddress); + log.info("pub-key {}", Utils.bytesToHex(myHighLoadWalletV3.getKeyPair().getPublicKey())); + log.info("prv-key {}", Utils.bytesToHex(myHighLoadWalletV3.getKeyPair().getSecretKey())); + + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); + log.info( + "new wallet {} toncoins balance: {}", + myHighLoadWalletV3.getName(), + Utils.formatNanoValue(balance)); + + // top up new wallet with NEOJ using test-jetton-faucet-wallet + balance = + TestnetJettonFaucet.topUpContractWithNeoj( + tonlib, Address.of(nonBounceableAddress), BigInteger.valueOf(100)); + log.info( + "new wallet {} jetton balance: {}", + myHighLoadWalletV3.getName(), + Utils.formatJettonValue(balance, 2, 2)); + + HighloadV3Config config = + HighloadV3Config.builder() + .walletId(42) + .queryId(HighloadQueryId.fromSeqno(0).getQueryId()) + .build(); + + ExtMessageInfo extMessageInfo = myHighLoadWalletV3.deploy(config); + Assertions.assertThat(extMessageInfo.getError().getCode()).isZero(); + + myHighLoadWalletV3.waitForDeployment(60); + + String singleRandomAddress = + "0:" + + Utils.bytesToHex( + MessageDigest.getInstance("SHA-256") + .digest(UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8))); + + JettonMinter jettonMinterWallet = + JettonMinter.builder() + .tonlib(tonlib) + .customAddress(Address.of("kQAN6TAGauShFKDQvZCwNb_EeTUIjQDwRZ9t6GOn4FBzfg9Y")) + .build(); + + JettonWallet myJettonHighLoadWallet = + jettonMinterWallet.getJettonWallet(myHighLoadWalletV3.getAddress()); + + config = + HighloadV3Config.builder() + .walletId(42) + .queryId(HighloadQueryId.fromSeqno(1).getQueryId()) + .body( + myHighLoadWalletV3.createBulkTransfer( + Collections.singletonList( + Destination.builder() + .address(myJettonHighLoadWallet.getAddress().toBounceable()) + .amount(Utils.toNano(0.07)) + .body( + JettonWallet.createTransferBody( + 0, + BigInteger.valueOf(100), + Address.of(singleRandomAddress), // recipient + myJettonHighLoadWallet.getAddress(), // response address + null, // custom payload + BigInteger.ONE, // forward amount + MsgUtils.createTextMessageBody("test sdk") // forward payload + )) + .build()), + BigInteger.valueOf(HighloadQueryId.fromSeqno(1).getQueryId()))) + .mode(3) + .build(); + + extMessageInfo = myHighLoadWalletV3.send(config); + Assertions.assertThat(extMessageInfo.getError().getCode()).isZero(); + + Utils.sleep(60, "sending jettons..."); + + BigInteger balanceOfDestinationWallet = + tonlib.getAccountBalance(Address.of(singleRandomAddress)); + log.info("balanceOfDestinationWallet in nanocoins: {}", balanceOfDestinationWallet); + + JettonWallet randomJettonWallet = + jettonMinterWallet.getJettonWallet(Address.of(singleRandomAddress)); + log.info("balanceOfDestinationWallet in jettons: {}", randomJettonWallet.getBalance()); + } + + List createDummyDestinations(int count) throws NoSuchAlgorithmException { + List result = new ArrayList<>(); + for (int i = 0; i < count; i++) { + String dstDummyAddress = + "0:" + + Utils.bytesToHex( + MessageDigest.getInstance("SHA-256") + .digest(UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8))); + + result.add( + Destination.builder() + .bounce(false) + .address(dstDummyAddress) + .amount(Utils.toNano(0.01)) + // .comment("comment-" + i) + .build()); } + return result; + } } diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestLibraryDeployer.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestLibraryDeployer.java index edf9bd71..3a4fba12 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestLibraryDeployer.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestLibraryDeployer.java @@ -1,5 +1,7 @@ package org.ton.java.smartcontract.integrationtests; +import java.math.BigInteger; +import java.util.Collections; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; @@ -8,15 +10,12 @@ import org.ton.java.cell.Cell; import org.ton.java.cell.CellBuilder; import org.ton.java.smartcontract.LibraryDeployer; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.types.WalletCodes; import org.ton.java.tonlib.types.SmcLibraryEntry; import org.ton.java.tonlib.types.SmcLibraryResult; import org.ton.java.utils.Utils; -import java.math.BigInteger; -import java.util.Collections; - @Slf4j @RunWith(JUnit4.class) public class TestLibraryDeployer extends CommonTest { @@ -40,7 +39,7 @@ public void testDeployLibraryDeployer() throws InterruptedException { log.info("raw address {}", libraryDeployer.getAddress().toRaw()); BigInteger balanceLib = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddressLib), Utils.toNano(1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddressLib), Utils.toNano(1)); log.info( "new wallet {} balance: {}", libraryDeployer.getName(), Utils.formatNanoValue(balanceLib)); libraryDeployer.deploy(); diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestLockupWallet.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestLockupWallet.java index fdf88a16..8a0dc704 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestLockupWallet.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestLockupWallet.java @@ -11,7 +11,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.ton.java.address.Address; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.lockup.LockupWalletV1; import org.ton.java.smartcontract.types.LockupConfig; import org.ton.java.smartcontract.types.LockupWalletV1Config; @@ -22,186 +22,205 @@ @RunWith(JUnit4.class) public class TestLockupWallet extends CommonTest { - @Test - public void testNewWalletLockup() throws InterruptedException { - - TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); - - LockupWalletV1 contract = LockupWalletV1.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .walletId(42) - .lockupConfig(LockupConfig.builder() - .configPublicKey(Utils.bytesToHex(keyPair.getPublicKey())) - // important to specify totalRestrictedValue! otherwise wallet will send to prohibited addresses - // can be more than total balance wallet - .totalRestrictedValue(Utils.toNano(5_000_000)) - .allowedDestinations(Arrays.asList( - TestFaucet.BOUNCEABLE, - "kf_YRLxA4Oe_e3FwvJ8CJgK9YDgeUprNQW3Or3B8ksegmjbj")) - .build()) - .build(); - - Address address = contract.getAddress(); - - String nonBounceableAddress = address.toNonBounceable(); - String bounceableAddress = address.toBounceable(); - String rawAddress = address.toRaw(); - - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - log.info(" raw address {}", rawAddress); - log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); - log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); - - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(5)); - log.info("new {} wallet balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - - ExtMessageInfo extMessageInfo = contract.deploy(); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForDeployment(60); - - log.info("seqno {}", contract.getSeqno()); - log.info("sub-wallet id {}", contract.getWalletId()); - log.info("public key {}", contract.getPublicKey()); - - log.info("liquid balance {}", Utils.formatNanoValue(contract.getLiquidBalance())); - log.info("restricted balance {}", Utils.formatNanoValue(contract.getNominalRestrictedBalance())); - log.info("time-locked balance {}", Utils.formatNanoValue(contract.getNominalLockedBalance())); - - // below returns -1 - means true - log.info("destination 1 allowed {}", contract.check_destination(TestFaucet.BOUNCEABLE)); - log.info("destination 2 allowed {}", contract.check_destination("kf_YRLxA4Oe_e3FwvJ8CJgK9YDgeUprNQW3Or3B8ksegmjbj")); - log.info("destination 3 allowed {}", contract.check_destination("EQDZno6LOWYJRHPpRv-MM3qrhFPk6OHOxVOg1HvEEAtJxK3y")); - - // try to transfer coins from new lockup wallet to allowed address (back to faucet) - log.info("sending toncoins to allowed address..."); - LockupWalletV1Config config = LockupWalletV1Config.builder() - .seqno(contract.getSeqno()) - .walletId(42) - .destination(Address.of(TestFaucet.BOUNCEABLE)) - .amount(Utils.toNano(4)) - .comment("send-to-allowed-1") - .build(); - - extMessageInfo = contract.send(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - Utils.sleep(50); - - balance = contract.getBalance(); - log.info("new lockup wallet balance: {}", Utils.formatNanoValue(balance)); - assertThat(balance.longValue()).isLessThan(Utils.toNano(4).longValue()); - - log.info("sending toncoins to prohibited address 1st time ..."); - config = LockupWalletV1Config.builder() - .seqno(contract.getSeqno()) - .walletId(42) - .destination(Address.of("EQDZno6LOWYJRHPpRv-MM3qrhFPk6OHOxVOg1HvEEAtJxK3y")) - .amount(Utils.toNano(1.5)) - .comment("send-to-prohibited-1") - .build(); - extMessageInfo = contract.send(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - Utils.sleep(50); - - log.info("liquid balance {}", Utils.formatNanoValue(contract.getLiquidBalance())); - log.info("restricted balance {}", Utils.formatNanoValue(contract.getNominalRestrictedBalance())); - log.info("time-locked balance {}", Utils.formatNanoValue(contract.getNominalLockedBalance())); - - balance = contract.getBalance(); - log.info("new lockup wallet balance: {}", Utils.formatNanoValue(balance)); - - log.info("sending toncoins to prohibited address 2nd time ..."); - config = LockupWalletV1Config.builder() - .seqno(contract.getSeqno()) - .walletId(42) - .destination(Address.of("0f_N_wfrFUwuWVkwpqmkRRYIJRzByJRobEwRCJTeQ8lq06n9")) - .amount(Utils.toNano(1.6)) - .comment("send-to-prohibited-2") - .build(); - extMessageInfo = contract.send(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - Utils.sleep(50); - - log.info("liquid balance {}", Utils.formatNanoValue(contract.getLiquidBalance())); - log.info("restricted balance {}", Utils.formatNanoValue(contract.getNominalRestrictedBalance())); - log.info("time-locked balance {}", Utils.formatNanoValue(contract.getNominalLockedBalance())); - - balance = new BigInteger(tonlib.getAccountState(address).getBalance()); - log.info("new lockup wallet balance: {}", Utils.formatNanoValue(balance)); - - - assertThat(balance.longValue()).isGreaterThan(Utils.toNano(0.9).longValue()); - - log.info("sending toncoins to allowed address..."); - config = LockupWalletV1Config.builder() - .seqno(contract.getSeqno()) - .walletId(42) - .destination(Address.of("kf_YRLxA4Oe_e3FwvJ8CJgK9YDgeUprNQW3Or3B8ksegmjbj")) - .amount(Utils.toNano(0.5)) - .build(); - extMessageInfo = contract.send(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - Utils.sleep(50); - - log.info("liquid balance {}", Utils.formatNanoValue(contract.getLiquidBalance())); - log.info("restricted balance {}", Utils.formatNanoValue(contract.getNominalRestrictedBalance())); - log.info("time-locked balance {}", Utils.formatNanoValue(contract.getNominalLockedBalance())); - - balance = new BigInteger(tonlib.getAccountState(address).getBalance()); - log.info("new lockup wallet balance: {}", Utils.formatNanoValue(balance)); - assertThat(balance.longValue()).isLessThan(Utils.toNano(0.7).longValue()); - } - - @Test - public void testDeployWalletLockup() throws IOException, InterruptedException { - - Address elector = Address.of("-1:3333333333333333333333333333333333333333333333333333333333333333"); - Address myWallet = Address.of("kf_YRLxA4Oe_e3FwvJ8CJgK9YDgeUprNQW3Or3B8ksegmjbj"); - - TweetNaclFast.Box.KeyPair boxKeyPair = Utils.generateKeyPair(); - TweetNaclFast.Signature.KeyPair sigKeyPair = Utils.generateSignatureKeyPairFromSeed(boxKeyPair.getSecretKey()); - - log.info("restricted-validator-wallet-001.pk {}", Utils.bytesToHex(boxKeyPair.getSecretKey())); - - // echo 'hex-prv-key' | xxd -r -p > /usr/local/bin/mytoncore/wallets/restricted-validator-wallet-001.pk - - LockupWalletV1 contract = LockupWalletV1.builder() - .tonlib(tonlib) - .keyPair(sigKeyPair) - .walletId(42) - .lockupConfig(LockupConfig.builder() - .configPublicKey(Utils.bytesToHex(sigKeyPair.getPublicKey())) // same as owner - .totalRestrictedValue(Utils.toNano(5_000_000)) - .allowedDestinations(Arrays.asList( - elector.toString(), - myWallet.toString()) - ).build()) - .build(); - - Address address = contract.getAddress(); - - String nonBounceableAddress = address.toNonBounceable(); - String bounceableAddress = address.toBounceable(); - - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - - -// Tonlib tonlib = Tonlib.builder().testnet(true).build(); - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(5)); - log.info("new {} wallet balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - - ExtMessageInfo extMessageInfo = contract.deploy(); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForDeployment(60); - - log.info("seqno {}", contract.getSeqno()); - address.saveToFile("restricted-validator-wallet-001.addr"); - } + @Test + public void testNewWalletLockup() throws InterruptedException { + + TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); + + LockupWalletV1 contract = + LockupWalletV1.builder() + .tonlib(tonlib) + .keyPair(keyPair) + .walletId(42) + .lockupConfig( + LockupConfig.builder() + .configPublicKey(Utils.bytesToHex(keyPair.getPublicKey())) + // important to specify totalRestrictedValue! otherwise wallet will send to + // prohibited addresses + // can be more than total balance wallet + .totalRestrictedValue(Utils.toNano(5_000_000)) + .allowedDestinations( + Arrays.asList( + TestnetFaucet.BOUNCEABLE, + "kf_YRLxA4Oe_e3FwvJ8CJgK9YDgeUprNQW3Or3B8ksegmjbj")) + .build()) + .build(); + + Address address = contract.getAddress(); + + String nonBounceableAddress = address.toNonBounceable(); + String bounceableAddress = address.toBounceable(); + String rawAddress = address.toRaw(); + + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + log.info(" raw address {}", rawAddress); + log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); + log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); + + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(5)); + log.info("new {} wallet balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + + ExtMessageInfo extMessageInfo = contract.deploy(); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForDeployment(60); + + log.info("seqno {}", contract.getSeqno()); + log.info("sub-wallet id {}", contract.getWalletId()); + log.info("public key {}", contract.getPublicKey()); + + log.info("liquid balance {}", Utils.formatNanoValue(contract.getLiquidBalance())); + log.info( + "restricted balance {}", Utils.formatNanoValue(contract.getNominalRestrictedBalance())); + log.info("time-locked balance {}", Utils.formatNanoValue(contract.getNominalLockedBalance())); + + // below returns -1 - means true + log.info("destination 1 allowed {}", contract.check_destination(TestnetFaucet.BOUNCEABLE)); + log.info( + "destination 2 allowed {}", + contract.check_destination("kf_YRLxA4Oe_e3FwvJ8CJgK9YDgeUprNQW3Or3B8ksegmjbj")); + log.info( + "destination 3 allowed {}", + contract.check_destination("EQDZno6LOWYJRHPpRv-MM3qrhFPk6OHOxVOg1HvEEAtJxK3y")); + + // try to transfer coins from new lockup wallet to allowed address (back to faucet) + log.info("sending toncoins to allowed address..."); + LockupWalletV1Config config = + LockupWalletV1Config.builder() + .seqno(contract.getSeqno()) + .walletId(42) + .destination(Address.of(TestnetFaucet.BOUNCEABLE)) + .amount(Utils.toNano(4)) + .comment("send-to-allowed-1") + .build(); + + extMessageInfo = contract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + Utils.sleep(50); + + balance = contract.getBalance(); + log.info("new lockup wallet balance: {}", Utils.formatNanoValue(balance)); + assertThat(balance.longValue()).isLessThan(Utils.toNano(4).longValue()); + + log.info("sending toncoins to prohibited address 1st time ..."); + config = + LockupWalletV1Config.builder() + .seqno(contract.getSeqno()) + .walletId(42) + .destination(Address.of("EQDZno6LOWYJRHPpRv-MM3qrhFPk6OHOxVOg1HvEEAtJxK3y")) + .amount(Utils.toNano(1.5)) + .comment("send-to-prohibited-1") + .build(); + extMessageInfo = contract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + Utils.sleep(50); + + log.info("liquid balance {}", Utils.formatNanoValue(contract.getLiquidBalance())); + log.info( + "restricted balance {}", Utils.formatNanoValue(contract.getNominalRestrictedBalance())); + log.info("time-locked balance {}", Utils.formatNanoValue(contract.getNominalLockedBalance())); + + balance = contract.getBalance(); + log.info("new lockup wallet balance: {}", Utils.formatNanoValue(balance)); + + log.info("sending toncoins to prohibited address 2nd time ..."); + config = + LockupWalletV1Config.builder() + .seqno(contract.getSeqno()) + .walletId(42) + .destination(Address.of("0f_N_wfrFUwuWVkwpqmkRRYIJRzByJRobEwRCJTeQ8lq06n9")) + .amount(Utils.toNano(1.6)) + .comment("send-to-prohibited-2") + .build(); + extMessageInfo = contract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + Utils.sleep(50); + + log.info("liquid balance {}", Utils.formatNanoValue(contract.getLiquidBalance())); + log.info( + "restricted balance {}", Utils.formatNanoValue(contract.getNominalRestrictedBalance())); + log.info("time-locked balance {}", Utils.formatNanoValue(contract.getNominalLockedBalance())); + + balance = new BigInteger(tonlib.getAccountState(address).getBalance()); + log.info("new lockup wallet balance: {}", Utils.formatNanoValue(balance)); + + assertThat(balance.longValue()).isGreaterThan(Utils.toNano(0.9).longValue()); + + log.info("sending toncoins to allowed address..."); + config = + LockupWalletV1Config.builder() + .seqno(contract.getSeqno()) + .walletId(42) + .destination(Address.of("kf_YRLxA4Oe_e3FwvJ8CJgK9YDgeUprNQW3Or3B8ksegmjbj")) + .amount(Utils.toNano(0.5)) + .build(); + extMessageInfo = contract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + Utils.sleep(50); + + log.info("liquid balance {}", Utils.formatNanoValue(contract.getLiquidBalance())); + log.info( + "restricted balance {}", Utils.formatNanoValue(contract.getNominalRestrictedBalance())); + log.info("time-locked balance {}", Utils.formatNanoValue(contract.getNominalLockedBalance())); + + balance = new BigInteger(tonlib.getAccountState(address).getBalance()); + log.info("new lockup wallet balance: {}", Utils.formatNanoValue(balance)); + assertThat(balance.longValue()).isLessThan(Utils.toNano(0.7).longValue()); + } + + @Test + public void testDeployWalletLockup() throws IOException, InterruptedException { + + Address elector = + Address.of("-1:3333333333333333333333333333333333333333333333333333333333333333"); + Address myWallet = Address.of("kf_YRLxA4Oe_e3FwvJ8CJgK9YDgeUprNQW3Or3B8ksegmjbj"); + + TweetNaclFast.Box.KeyPair boxKeyPair = Utils.generateKeyPair(); + TweetNaclFast.Signature.KeyPair sigKeyPair = + Utils.generateSignatureKeyPairFromSeed(boxKeyPair.getSecretKey()); + + log.info("restricted-validator-wallet-001.pk {}", Utils.bytesToHex(boxKeyPair.getSecretKey())); + + // echo 'hex-prv-key' | xxd -r -p > + // /usr/local/bin/mytoncore/wallets/restricted-validator-wallet-001.pk + + LockupWalletV1 contract = + LockupWalletV1.builder() + .tonlib(tonlib) + .keyPair(sigKeyPair) + .walletId(42) + .lockupConfig( + LockupConfig.builder() + .configPublicKey(Utils.bytesToHex(sigKeyPair.getPublicKey())) // same as owner + .totalRestrictedValue(Utils.toNano(5_000_000)) + .allowedDestinations(Arrays.asList(elector.toString(), myWallet.toString())) + .build()) + .build(); + + Address address = contract.getAddress(); + + String nonBounceableAddress = address.toNonBounceable(); + String bounceableAddress = address.toBounceable(); + + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + + // Tonlib tonlib = Tonlib.builder().testnet(true).build(); + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(5)); + log.info("new {} wallet balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + + ExtMessageInfo extMessageInfo = contract.deploy(); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForDeployment(60); + + log.info("seqno {}", contract.getSeqno()); + address.saveToFile("restricted-validator-wallet-001.addr"); + } } diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletFeesV1.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletFeesV1.java index ee1c519a..41a9d2a5 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletFeesV1.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletFeesV1.java @@ -1,13 +1,19 @@ package org.ton.java.smartcontract.integrationtests; +import static org.assertj.core.api.Assertions.assertThat; + import com.iwebpp.crypto.TweetNaclFast; +import java.math.BigInteger; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.assertj.core.api.AssertionsForClassTypes; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.ton.java.address.Address; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.types.WalletV1R3Config; import org.ton.java.smartcontract.wallet.v1.WalletV1R3; import org.ton.java.tlb.types.Message; @@ -16,13 +22,6 @@ import org.ton.java.tonlib.types.QueryFees; import org.ton.java.utils.Utils; -import java.math.BigInteger; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import static org.assertj.core.api.Assertions.assertThat; - @Slf4j @RunWith(JUnit4.class) public class TestWalletFeesV1 extends CommonTest { @@ -57,12 +56,12 @@ public void testWalletFeesV1() throws InterruptedException { // top up new walletA using test-faucet-wallet BigInteger balance1 = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddrWalletA), Utils.toNano(1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddrWalletA), Utils.toNano(1)); log.info("balance walletA: {}", Utils.formatNanoValue(balance1)); // top up new walletB using test-faucet-wallet BigInteger balance2 = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddrWalletB), Utils.toNano(1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddrWalletB), Utils.toNano(1)); log.info("balance walletB: {} ", Utils.formatNanoValue(balance2)); ExtMessageInfo extMessageInfo = walletA.deploy(); diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletFeesV2.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletFeesV2.java index 77bd4737..d08e52be 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletFeesV2.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletFeesV2.java @@ -1,13 +1,19 @@ package org.ton.java.smartcontract.integrationtests; +import static org.assertj.core.api.Assertions.assertThat; + import com.iwebpp.crypto.TweetNaclFast; +import java.math.BigInteger; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.assertj.core.api.AssertionsForClassTypes; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.ton.java.address.Address; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.types.WalletV2R2Config; import org.ton.java.smartcontract.wallet.v2.WalletV2R2; import org.ton.java.tlb.types.Message; @@ -16,13 +22,6 @@ import org.ton.java.tonlib.types.QueryFees; import org.ton.java.utils.Utils; -import java.math.BigInteger; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import static org.assertj.core.api.Assertions.assertThat; - @Slf4j @RunWith(JUnit4.class) public class TestWalletFeesV2 extends CommonTest { @@ -57,12 +56,12 @@ public void testWalletFeesV2() throws InterruptedException { // top up new walletA using test-faucet-wallet BigInteger balance1 = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddrWalletA), Utils.toNano(1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddrWalletA), Utils.toNano(1)); log.info("balance walletA: {}", Utils.formatNanoValue(balance1)); // top up new walletB using test-faucet-wallet BigInteger balance2 = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddrWalletB), Utils.toNano(1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddrWalletB), Utils.toNano(1)); log.info("balance walletB: {} ", Utils.formatNanoValue(balance2)); ExtMessageInfo extMessageInfo = walletA.deploy(); diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletFeesV3.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletFeesV3.java index c45fa4ac..1db5974c 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletFeesV3.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletFeesV3.java @@ -13,7 +13,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.ton.java.address.Address; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.types.WalletV3Config; import org.ton.java.smartcontract.wallet.v3.WalletV3R2; import org.ton.java.tlb.types.Message; @@ -26,237 +26,254 @@ @RunWith(JUnit4.class) public class TestWalletFeesV3 extends CommonTest { - /** - * Trying to send amount of toncoins so that recipient gets the exact amount. - * There might be a mistake of several nano coins if transaction lasts too long. - */ - @Test - public void testWalletFeesV3() throws InterruptedException { + /** + * Trying to send amount of toncoins so that recipient gets the exact amount. There might be a + * mistake of several nano coins if transaction lasts too long. + */ + @Test + public void testWalletFeesV3() throws InterruptedException { - Tonlib tonlib = Tonlib.builder() - .testnet(true) - .ignoreCache(false) - .build(); + Tonlib tonlib = Tonlib.builder().testnet(true).ignoreCache(false).build(); - TweetNaclFast.Signature.KeyPair keyPairA = Utils.generateSignatureKeyPair(); + TweetNaclFast.Signature.KeyPair keyPairA = Utils.generateSignatureKeyPair(); - WalletV3R2 walletA = WalletV3R2.builder() - .tonlib(tonlib) - .keyPair(keyPairA) - .walletId(42) - .build(); + WalletV3R2 walletA = WalletV3R2.builder().tonlib(tonlib).keyPair(keyPairA).walletId(42).build(); - String nonBounceableAddrWalletA = walletA.getAddress().toNonBounceable(); - String rawAddrWalletA = walletA.getAddress().toRaw(); + String nonBounceableAddrWalletA = walletA.getAddress().toNonBounceable(); + String rawAddrWalletA = walletA.getAddress().toRaw(); - log.info("rawAddressA: {}", rawAddrWalletA); - log.info("pub-key {}", Utils.bytesToHex(walletA.getKeyPair().getPublicKey())); - log.info("prv-key {}", Utils.bytesToHex(walletA.getKeyPair().getSecretKey())); + log.info("rawAddressA: {}", rawAddrWalletA); + log.info("pub-key {}", Utils.bytesToHex(walletA.getKeyPair().getPublicKey())); + log.info("prv-key {}", Utils.bytesToHex(walletA.getKeyPair().getSecretKey())); - TweetNaclFast.Signature.KeyPair keyPairB = Utils.generateSignatureKeyPair(); + TweetNaclFast.Signature.KeyPair keyPairB = Utils.generateSignatureKeyPair(); - WalletV3R2 walletB = WalletV3R2.builder() - .tonlib(tonlib) - .keyPair(keyPairB) - .walletId(98) - .build(); + WalletV3R2 walletB = WalletV3R2.builder().tonlib(tonlib).keyPair(keyPairB).walletId(98).build(); - String nonBounceableAddrWalletB = walletB.getAddress().toNonBounceable(); - String rawAddrWalletB = walletB.getAddress().toRaw(); + String nonBounceableAddrWalletB = walletB.getAddress().toNonBounceable(); + String rawAddrWalletB = walletB.getAddress().toRaw(); + + log.info("rawAddressB: {}", rawAddrWalletB); - log.info("rawAddressB: {}", rawAddrWalletB); - - log.info("pub-key {}", Utils.bytesToHex(walletB.getKeyPair().getPublicKey())); - log.info("prv-key {}", Utils.bytesToHex(walletB.getKeyPair().getSecretKey())); - - // top up new walletA using test-faucet-wallet - BigInteger balance1 = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddrWalletA), Utils.toNano(1)); - log.info("walletId {} new wallet {} balance: {}", walletA.getWalletId(), walletA.getName(), Utils.formatNanoValue(balance1)); - - // top up new walletB using test-faucet-wallet - BigInteger balance2 = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddrWalletB), Utils.toNano(1)); - log.info("walletId {} new wallet {} balance: {}", walletB.getWalletId(), walletB.getName(), Utils.formatNanoValue(balance2)); - - ExtMessageInfo extMessageInfo = walletA.deploy(); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - walletA.waitForDeployment(30); - - extMessageInfo = walletB.deploy(); - AssertionsForClassTypes.assertThat(extMessageInfo.getError().getCode()).isZero(); - - walletB.waitForDeployment(30); - - // transfer 0.1 from walletA to walletB where B receives exact amount i.e. 0.1 - BigInteger balanceAbefore = walletA.getBalance(); - BigInteger balanceBbefore = walletB.getBalance(); - log.info("walletA balance before: {}", Utils.formatNanoValue(balanceAbefore)); - log.info("walletB balance before: {}", Utils.formatNanoValue(balanceBbefore)); - - WalletV3Config configA = WalletV3Config.builder() - .walletId(42) - .seqno(walletA.getSeqno()) - .destination(walletB.getAddress()) - .mode(3) - .build(); - - Message msg = walletA.prepareExternalMsg(configA); - - QueryFees fees = tonlib.estimateFees( - walletB.getAddress().toBounceable(), - msg.getBody().toBase64()); - - // adjust amount by including storage fee - configA.setAmount(Utils.toNano(0.1).add(walletA.getGasFees()).add(BigInteger.valueOf(fees.getSource_fees().getStorage_fee()))); - - log.info("fees on walletB with msg body from A: {}", fees); - log.info("sending {}", Utils.formatNanoValue(configA.getAmount())); - - walletA.send(configA); - - walletB.waitForBalanceChange(30); - - BigInteger balanceAafter = walletA.getBalance(); - BigInteger balanceBafter = walletB.getBalance(); - log.info("walletA balance after: {}", Utils.formatNanoValue(balanceAafter)); - log.info("walletB balance after: {}", Utils.formatNanoValue(balanceBafter)); - - log.info("diff walletA (debited): -{}", Utils.formatNanoValue(balanceAbefore.subtract(balanceAafter))); - log.info("diff walletB (credited): +{}, missing value {}", Utils.formatNanoValue(balanceBafter.subtract(balanceBbefore)), - Utils.formatNanoValue(Utils.toNano(0.1).subtract(balanceBafter.subtract(balanceBbefore)))); - - assertThat(Utils.toNano(0.1).subtract(balanceBafter.subtract(balanceBbefore))).isEqualTo(BigInteger.ZERO); - } - - /** - * Trying to send amount of toncoins so that recipient gets the exact amount. - * There might be a mistake of several nano coins if transaction lasts too long. - */ - @Test - public void testWithDeployedWalletsAB() { - - Tonlib tonlib = Tonlib.builder() - .testnet(true) - .ignoreCache(false) - .build(); - - TweetNaclFast.Box.KeyPair keyPairBoxA = Utils.generateKeyPairFromSecretKey(Utils.hexToSignedBytes("28e1ae64e97c16e93b882bbdd4bde84ed48ab7148f64ab3e78f6b404c924c79a13f3c53b711d1a92dcba43dca7b9fa3b95f6b75faff7f39ce77f1c0eb5cbc730")); - TweetNaclFast.Signature.KeyPair keyPairSignatureA = Utils.generateSignatureKeyPairFromSeed(keyPairBoxA.getSecretKey()); - WalletV3R2 walletA = WalletV3R2.builder() - .keyPair(keyPairSignatureA) - .tonlib(tonlib) - .walletId(42) - .build(); - log.info("rawAddressA {}", walletA.getAddress().toRaw()); - log.info("bounceableA {}", walletA.getAddress().toBounceable()); - - TweetNaclFast.Box.KeyPair keyPairBoxB = Utils.generateKeyPairFromSecretKey(Utils.hexToSignedBytes("dabc0aa5c3883ba7e9f810a051e002d9b88fa54daa21b17508b166a550ff1c74dd9a2d66e2bac9bef666fd01a41ed0d872265502d40757cdd047933021601317")); - TweetNaclFast.Signature.KeyPair keyPairSignatureB = Utils.generateSignatureKeyPairFromSeed(keyPairBoxB.getSecretKey()); - WalletV3R2 walletB = WalletV3R2.builder() - .keyPair(keyPairSignatureB) - .tonlib(tonlib) - .walletId(98) - .build(); - log.info("rawAddressB {}", walletB.getAddress().toRaw()); - log.info("bounceableB {}", walletB.getAddress().toBounceable()); - - - BigInteger balanceAbefore = walletA.getBalance(); - BigInteger balanceBbefore = walletB.getBalance(); - log.info("walletA balance before: {}", Utils.formatNanoValue(balanceAbefore)); - log.info("walletB balance before: {}", Utils.formatNanoValue(balanceBbefore)); - - - WalletV3Config configA = WalletV3Config.builder() - .walletId(42) - .seqno(walletA.getSeqno()) - .destination(walletB.getAddress()) - .mode(3) - .build(); - - Message msg = walletA.prepareExternalMsg(configA); - QueryFees feesWithCodeData = tonlib.estimateFees( - walletB.getAddress().toBounceable(), - msg.getBody().toBase64(), null, null, true); - - //adjust new amount - configA.setAmount(Utils.toNano(0.1).add(walletA.getGasFees()).add(BigInteger.valueOf(feesWithCodeData.getSource_fees().getStorage_fee()))); - - log.info("fees on walletB with msg body from A: {}", feesWithCodeData); - - walletA.send(configA); - - walletB.waitForBalanceChange(30); - - BigInteger balanceAafter = walletA.getBalance(); - BigInteger balanceBafter = walletB.getBalance(); - log.info("walletA balance after: {}", Utils.formatNanoValue(balanceAafter)); - log.info("walletB balance after: {}", Utils.formatNanoValue(balanceBafter)); - - log.info("diff walletA (debited): -{}", Utils.formatNanoValue(balanceAbefore.subtract(balanceAafter))); - log.info("diff walletB (credited): +{}, missing value {}", Utils.formatNanoValue(balanceBafter.subtract(balanceBbefore)), - Utils.formatNanoValue(Utils.toNano(0.1).subtract(balanceBafter.subtract(balanceBbefore)))); - - assertThat(Utils.toNano(0.1).subtract(balanceBafter.subtract(balanceBbefore))).isEqualTo(BigInteger.ZERO); -/* - send mode 3 - Pay transfer fees separately from the message value - diff walletA -0.102204003 - diff walletB +0.099959997 - diff walletA -0.102204004 - diff walletB +0.099959996 - - diff walletA -0.102204025 (intMsg Forward Fee: 0.000266669 TON + Tx Total Fee 0.001937356 TON - diff walletB +0.099959975 (0.1 - 0.099959975 = 0.000040025) gasFee 40000 + StorageFee 25 - - 1ton and deploy - result B 0.998095999 - send 0.1 to B, result 1.098055985 (should be 1.098095999) - difference (0.000040014) - */ - } - - @Test - public void testWalletStorageFeeSpeedV3() { - - Tonlib tonlib = Tonlib.builder() - .testnet(true) - .ignoreCache(false) - .build(); - - TweetNaclFast.Box.KeyPair keyPairBoxA = Utils.generateKeyPairFromSecretKey(Utils.hexToSignedBytes("28e1ae64e97c16e93b882bbdd4bde84ed48ab7148f64ab3e78f6b404c924c79a13f3c53b711d1a92dcba43dca7b9fa3b95f6b75faff7f39ce77f1c0eb5cbc730")); - TweetNaclFast.Signature.KeyPair keyPairSignatureA = Utils.generateSignatureKeyPairFromSeed(keyPairBoxA.getSecretKey()); - WalletV3R2 walletA = WalletV3R2.builder() - .keyPair(keyPairSignatureA) - .tonlib(tonlib) - .walletId(42) - .build(); - log.info("rawAddressA {}", walletA.getAddress().toRaw()); - log.info("bounceableA {}", walletA.getAddress().toBounceable()); - - TweetNaclFast.Box.KeyPair keyPairBoxB = Utils.generateKeyPairFromSecretKey(Utils.hexToSignedBytes("dabc0aa5c3883ba7e9f810a051e002d9b88fa54daa21b17508b166a550ff1c74dd9a2d66e2bac9bef666fd01a41ed0d872265502d40757cdd047933021601317")); - TweetNaclFast.Signature.KeyPair keyPairSignatureB = Utils.generateSignatureKeyPairFromSeed(keyPairBoxB.getSecretKey()); - WalletV3R2 walletB = WalletV3R2.builder() - .keyPair(keyPairSignatureB) - .tonlib(tonlib) - .walletId(98) - .build(); - - WalletV3Config configA = WalletV3Config.builder() - .walletId(42) - .seqno(walletA.getSeqno()) - .destination(walletB.getAddress()) - .mode(3) - .build(); - - Message msg = walletA.prepareExternalMsg(configA); - - ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); - executorService.scheduleAtFixedRate(() -> { - QueryFees f = tonlib.estimateFees( - walletB.getAddress().toBounceable(), - msg.getBody().toBase64(), null, null, true); - log.info("fees {}", f); - }, 0, 15, TimeUnit.SECONDS); - - Utils.sleep(600); - } + log.info("pub-key {}", Utils.bytesToHex(walletB.getKeyPair().getPublicKey())); + log.info("prv-key {}", Utils.bytesToHex(walletB.getKeyPair().getSecretKey())); + + // top up new walletA using test-faucet-wallet + BigInteger balance1 = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddrWalletA), Utils.toNano(1)); + log.info( + "walletId {} new wallet {} balance: {}", + walletA.getWalletId(), + walletA.getName(), + Utils.formatNanoValue(balance1)); + + // top up new walletB using test-faucet-wallet + BigInteger balance2 = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddrWalletB), Utils.toNano(1)); + log.info( + "walletId {} new wallet {} balance: {}", + walletB.getWalletId(), + walletB.getName(), + Utils.formatNanoValue(balance2)); + + ExtMessageInfo extMessageInfo = walletA.deploy(); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + walletA.waitForDeployment(30); + + extMessageInfo = walletB.deploy(); + AssertionsForClassTypes.assertThat(extMessageInfo.getError().getCode()).isZero(); + + walletB.waitForDeployment(30); + + // transfer 0.1 from walletA to walletB where B receives exact amount i.e. 0.1 + BigInteger balanceAbefore = walletA.getBalance(); + BigInteger balanceBbefore = walletB.getBalance(); + log.info("walletA balance before: {}", Utils.formatNanoValue(balanceAbefore)); + log.info("walletB balance before: {}", Utils.formatNanoValue(balanceBbefore)); + + WalletV3Config configA = + WalletV3Config.builder() + .walletId(42) + .seqno(walletA.getSeqno()) + .destination(walletB.getAddress()) + .mode(3) + .build(); + + Message msg = walletA.prepareExternalMsg(configA); + + QueryFees fees = + tonlib.estimateFees(walletB.getAddress().toBounceable(), msg.getBody().toBase64()); + + // adjust amount by including storage fee + configA.setAmount( + Utils.toNano(0.1) + .add(walletA.getGasFees()) + .add(BigInteger.valueOf(fees.getSource_fees().getStorage_fee()))); + + log.info("fees on walletB with msg body from A: {}", fees); + log.info("sending {}", Utils.formatNanoValue(configA.getAmount())); + + walletA.send(configA); + + walletB.waitForBalanceChange(30); + + BigInteger balanceAafter = walletA.getBalance(); + BigInteger balanceBafter = walletB.getBalance(); + log.info("walletA balance after: {}", Utils.formatNanoValue(balanceAafter)); + log.info("walletB balance after: {}", Utils.formatNanoValue(balanceBafter)); + + log.info( + "diff walletA (debited): -{}", + Utils.formatNanoValue(balanceAbefore.subtract(balanceAafter))); + log.info( + "diff walletB (credited): +{}, missing value {}", + Utils.formatNanoValue(balanceBafter.subtract(balanceBbefore)), + Utils.formatNanoValue(Utils.toNano(0.1).subtract(balanceBafter.subtract(balanceBbefore)))); + + assertThat(Utils.toNano(0.1).subtract(balanceBafter.subtract(balanceBbefore))) + .isEqualTo(BigInteger.ZERO); + } + + /** + * Trying to send amount of toncoins so that recipient gets the exact amount. There might be a + * mistake of several nano coins if transaction lasts too long. + */ + @Test + public void testWithDeployedWalletsAB() { + + Tonlib tonlib = Tonlib.builder().testnet(true).ignoreCache(false).build(); + + TweetNaclFast.Box.KeyPair keyPairBoxA = + Utils.generateKeyPairFromSecretKey( + Utils.hexToSignedBytes( + "28e1ae64e97c16e93b882bbdd4bde84ed48ab7148f64ab3e78f6b404c924c79a13f3c53b711d1a92dcba43dca7b9fa3b95f6b75faff7f39ce77f1c0eb5cbc730")); + TweetNaclFast.Signature.KeyPair keyPairSignatureA = + Utils.generateSignatureKeyPairFromSeed(keyPairBoxA.getSecretKey()); + WalletV3R2 walletA = + WalletV3R2.builder().keyPair(keyPairSignatureA).tonlib(tonlib).walletId(42).build(); + log.info("rawAddressA {}", walletA.getAddress().toRaw()); + log.info("bounceableA {}", walletA.getAddress().toBounceable()); + + TweetNaclFast.Box.KeyPair keyPairBoxB = + Utils.generateKeyPairFromSecretKey( + Utils.hexToSignedBytes( + "dabc0aa5c3883ba7e9f810a051e002d9b88fa54daa21b17508b166a550ff1c74dd9a2d66e2bac9bef666fd01a41ed0d872265502d40757cdd047933021601317")); + TweetNaclFast.Signature.KeyPair keyPairSignatureB = + Utils.generateSignatureKeyPairFromSeed(keyPairBoxB.getSecretKey()); + WalletV3R2 walletB = + WalletV3R2.builder().keyPair(keyPairSignatureB).tonlib(tonlib).walletId(98).build(); + log.info("rawAddressB {}", walletB.getAddress().toRaw()); + log.info("bounceableB {}", walletB.getAddress().toBounceable()); + + BigInteger balanceAbefore = walletA.getBalance(); + BigInteger balanceBbefore = walletB.getBalance(); + log.info("walletA balance before: {}", Utils.formatNanoValue(balanceAbefore)); + log.info("walletB balance before: {}", Utils.formatNanoValue(balanceBbefore)); + + WalletV3Config configA = + WalletV3Config.builder() + .walletId(42) + .seqno(walletA.getSeqno()) + .destination(walletB.getAddress()) + .mode(3) + .build(); + + Message msg = walletA.prepareExternalMsg(configA); + QueryFees feesWithCodeData = + tonlib.estimateFees( + walletB.getAddress().toBounceable(), msg.getBody().toBase64(), null, null, true); + + // adjust new amount + configA.setAmount( + Utils.toNano(0.1) + .add(walletA.getGasFees()) + .add(BigInteger.valueOf(feesWithCodeData.getSource_fees().getStorage_fee()))); + + log.info("fees on walletB with msg body from A: {}", feesWithCodeData); + + walletA.send(configA); + + walletB.waitForBalanceChange(30); + + BigInteger balanceAafter = walletA.getBalance(); + BigInteger balanceBafter = walletB.getBalance(); + log.info("walletA balance after: {}", Utils.formatNanoValue(balanceAafter)); + log.info("walletB balance after: {}", Utils.formatNanoValue(balanceBafter)); + + log.info( + "diff walletA (debited): -{}", + Utils.formatNanoValue(balanceAbefore.subtract(balanceAafter))); + log.info( + "diff walletB (credited): +{}, missing value {}", + Utils.formatNanoValue(balanceBafter.subtract(balanceBbefore)), + Utils.formatNanoValue(Utils.toNano(0.1).subtract(balanceBafter.subtract(balanceBbefore)))); + + assertThat(Utils.toNano(0.1).subtract(balanceBafter.subtract(balanceBbefore))) + .isEqualTo(BigInteger.ZERO); + /* + send mode 3 + Pay transfer fees separately from the message value + diff walletA -0.102204003 + diff walletB +0.099959997 + diff walletA -0.102204004 + diff walletB +0.099959996 + + diff walletA -0.102204025 (intMsg Forward Fee: 0.000266669 TON + Tx Total Fee 0.001937356 TON + diff walletB +0.099959975 (0.1 - 0.099959975 = 0.000040025) gasFee 40000 + StorageFee 25 + + 1ton and deploy - result B 0.998095999 + send 0.1 to B, result 1.098055985 (should be 1.098095999) - difference (0.000040014) + */ + } + + @Test + public void testWalletStorageFeeSpeedV3() { + + Tonlib tonlib = Tonlib.builder().testnet(true).ignoreCache(false).build(); + + TweetNaclFast.Box.KeyPair keyPairBoxA = + Utils.generateKeyPairFromSecretKey( + Utils.hexToSignedBytes( + "28e1ae64e97c16e93b882bbdd4bde84ed48ab7148f64ab3e78f6b404c924c79a13f3c53b711d1a92dcba43dca7b9fa3b95f6b75faff7f39ce77f1c0eb5cbc730")); + TweetNaclFast.Signature.KeyPair keyPairSignatureA = + Utils.generateSignatureKeyPairFromSeed(keyPairBoxA.getSecretKey()); + WalletV3R2 walletA = + WalletV3R2.builder().keyPair(keyPairSignatureA).tonlib(tonlib).walletId(42).build(); + log.info("rawAddressA {}", walletA.getAddress().toRaw()); + log.info("bounceableA {}", walletA.getAddress().toBounceable()); + + TweetNaclFast.Box.KeyPair keyPairBoxB = + Utils.generateKeyPairFromSecretKey( + Utils.hexToSignedBytes( + "dabc0aa5c3883ba7e9f810a051e002d9b88fa54daa21b17508b166a550ff1c74dd9a2d66e2bac9bef666fd01a41ed0d872265502d40757cdd047933021601317")); + TweetNaclFast.Signature.KeyPair keyPairSignatureB = + Utils.generateSignatureKeyPairFromSeed(keyPairBoxB.getSecretKey()); + WalletV3R2 walletB = + WalletV3R2.builder().keyPair(keyPairSignatureB).tonlib(tonlib).walletId(98).build(); + + WalletV3Config configA = + WalletV3Config.builder() + .walletId(42) + .seqno(walletA.getSeqno()) + .destination(walletB.getAddress()) + .mode(3) + .build(); + + Message msg = walletA.prepareExternalMsg(configA); + + ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); + executorService.scheduleAtFixedRate( + () -> { + QueryFees f = + tonlib.estimateFees( + walletB.getAddress().toBounceable(), msg.getBody().toBase64(), null, null, true); + log.info("fees {}", f); + }, + 0, + 15, + TimeUnit.SECONDS); + + Utils.sleep(600); + } } diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletFeesV4.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletFeesV4.java index c464d8e4..043a8c12 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletFeesV4.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletFeesV4.java @@ -13,7 +13,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.ton.java.address.Address; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.types.WalletV4R2Config; import org.ton.java.smartcontract.wallet.v4.WalletV4R2; import org.ton.java.tlb.types.Message; @@ -26,223 +26,239 @@ @RunWith(JUnit4.class) public class TestWalletFeesV4 extends CommonTest { - /** - * Trying to send amount of toncoins so that recipient gets the exact amount. - * There might be a mistake of several nano coins if transaction lasts too long. - */ - @Test - public void testWalletFeesV4() throws InterruptedException { + /** + * Trying to send amount of toncoins so that recipient gets the exact amount. There might be a + * mistake of several nano coins if transaction lasts too long. + */ + @Test + public void testWalletFeesV4() throws InterruptedException { - Tonlib tonlib = Tonlib.builder() - .testnet(true) - .ignoreCache(false) - .build(); + Tonlib tonlib = Tonlib.builder().testnet(true).ignoreCache(false).build(); - TweetNaclFast.Signature.KeyPair keyPairA = Utils.generateSignatureKeyPair(); + TweetNaclFast.Signature.KeyPair keyPairA = Utils.generateSignatureKeyPair(); - WalletV4R2 walletA = WalletV4R2.builder() - .tonlib(tonlib) - .keyPair(keyPairA) - .walletId(42) - .build(); + WalletV4R2 walletA = WalletV4R2.builder().tonlib(tonlib).keyPair(keyPairA).walletId(42).build(); - String nonBounceableAddrWalletA = walletA.getAddress().toNonBounceable(); - String rawAddrWalletA = walletA.getAddress().toRaw(); + String nonBounceableAddrWalletA = walletA.getAddress().toNonBounceable(); + String rawAddrWalletA = walletA.getAddress().toRaw(); - log.info("rawAddressA: {}", rawAddrWalletA); - log.info("pub-key {}", Utils.bytesToHex(walletA.getKeyPair().getPublicKey())); - log.info("prv-key {}", Utils.bytesToHex(walletA.getKeyPair().getSecretKey())); + log.info("rawAddressA: {}", rawAddrWalletA); + log.info("pub-key {}", Utils.bytesToHex(walletA.getKeyPair().getPublicKey())); + log.info("prv-key {}", Utils.bytesToHex(walletA.getKeyPair().getSecretKey())); - TweetNaclFast.Signature.KeyPair keyPairB = Utils.generateSignatureKeyPair(); + TweetNaclFast.Signature.KeyPair keyPairB = Utils.generateSignatureKeyPair(); - WalletV4R2 walletB = WalletV4R2.builder() - .tonlib(tonlib) - .keyPair(keyPairB) - .walletId(98) - .build(); - - String nonBounceableAddrWalletB = walletB.getAddress().toNonBounceable(); - String rawAddrWalletB = walletB.getAddress().toRaw(); + WalletV4R2 walletB = WalletV4R2.builder().tonlib(tonlib).keyPair(keyPairB).walletId(98).build(); - log.info("rawAddressB: {}", rawAddrWalletB); - - log.info("pub-key {}", Utils.bytesToHex(walletB.getKeyPair().getPublicKey())); - log.info("prv-key {}", Utils.bytesToHex(walletB.getKeyPair().getSecretKey())); - - // top up new walletA using test-faucet-wallet - BigInteger balance1 = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddrWalletA), Utils.toNano(1)); - log.info("walletId {} new wallet {} balance: {}", walletA.getWalletId(), walletA.getName(), Utils.formatNanoValue(balance1)); - - // top up new walletB using test-faucet-wallet - BigInteger balance2 = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddrWalletB), Utils.toNano(1)); - log.info("walletId {} new wallet {} balance: {}", walletB.getWalletId(), walletB.getName(), Utils.formatNanoValue(balance2)); - - ExtMessageInfo extMessageInfo = walletA.deploy(); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - walletA.waitForDeployment(30); - - extMessageInfo = walletB.deploy(); - AssertionsForClassTypes.assertThat(extMessageInfo.getError().getCode()).isZero(); - - walletB.waitForDeployment(30); - - // transfer 0.1 from walletA to walletB where B receives exact amount i.e. 0.1 - BigInteger balanceAbefore = walletA.getBalance(); - BigInteger balanceBbefore = walletB.getBalance(); - log.info("walletA balance before: {}", Utils.formatNanoValue(balanceAbefore)); - log.info("walletB balance before: {}", Utils.formatNanoValue(balanceBbefore)); - - WalletV4R2Config configA = WalletV4R2Config.builder() - .walletId(42) - .seqno(walletA.getSeqno()) - .destination(walletB.getAddress()) -// .amount(Utils.toNano(0.1 + 0.000040000)) - .mode(3) - .build(); - - Message msg = walletA.prepareExternalMsg(configA); - - QueryFees fees = tonlib.estimateFees( - walletB.getAddress().toBounceable(), - msg.getBody().toBase64(), null, null, true); - - // adjust amount by including storage fee - configA.setAmount(Utils.toNano(0.1).add(walletA.getGasFees()).add(BigInteger.valueOf(fees.getSource_fees().getStorage_fee()))); - - log.info("fees on walletB with msg body from A: {}", fees); - log.info("sending {}", Utils.formatNanoValue(configA.getAmount())); - - walletA.send(configA); - - walletB.waitForBalanceChange(30); - - BigInteger balanceAafter = walletA.getBalance(); - BigInteger balanceBafter = walletB.getBalance(); - log.info("walletA balance after: {}", Utils.formatNanoValue(balanceAafter)); - log.info("walletB balance after: {}", Utils.formatNanoValue(balanceBafter)); - - log.info("diff walletA (debited): -{}", Utils.formatNanoValue(balanceAbefore.subtract(balanceAafter))); - log.info("diff walletB (credited): +{}, missing value {}", Utils.formatNanoValue(balanceBafter.subtract(balanceBbefore)), - Utils.formatNanoValue(Utils.toNano(0.1).subtract(balanceBafter.subtract(balanceBbefore)))); - - assertThat(Utils.toNano(0.1).subtract(balanceBafter.subtract(balanceBbefore))).isEqualTo(BigInteger.ZERO); - } - - /** - * Trying to send amount of toncoins so that recipient gets the exact amount. - * There might be a mistake of several nano coins if transaction lasts too long. - */ - @Test - public void testWithDeployedWalletsV4AB() { - - Tonlib tonlib = Tonlib.builder() - .testnet(true) - .ignoreCache(false) - .build(); - - TweetNaclFast.Box.KeyPair keyPairBoxA = Utils.generateKeyPairFromSecretKey(Utils.hexToSignedBytes("3d3015dcc3c0f3d51710bfe4894de954334bb6f44f75061109d9e7dcaf7b5a85c2ca482a19f06f63c9975fd7e679d89014ab2b4b645fc591c287a2818dabb42f")); - TweetNaclFast.Signature.KeyPair keyPairSignatureA = Utils.generateSignatureKeyPairFromSeed(keyPairBoxA.getSecretKey()); - WalletV4R2 walletA = WalletV4R2.builder() - .keyPair(keyPairSignatureA) - .tonlib(tonlib) - .walletId(42) - .build(); - log.info("rawAddressA {}", walletA.getAddress().toRaw()); - log.info("bounceableA {}", walletA.getAddress().toBounceable()); - - TweetNaclFast.Box.KeyPair keyPairBoxB = Utils.generateKeyPairFromSecretKey(Utils.hexToSignedBytes("6763fd614cd1658c4f0c0b08dd82d49060f329387c4d38f1281db7ccb91f6eb3219d2acaa90c2091813785426feb5234af9027637db05b55e65ff3e54a94ad0b")); - TweetNaclFast.Signature.KeyPair keyPairSignatureB = Utils.generateSignatureKeyPairFromSeed(keyPairBoxB.getSecretKey()); - WalletV4R2 walletB = WalletV4R2.builder() - .keyPair(keyPairSignatureB) - .tonlib(tonlib) - .walletId(98) - .build(); - log.info("rawAddressB {}", walletB.getAddress().toRaw()); - log.info("bounceableB {}", walletB.getAddress().toBounceable()); - - - BigInteger balanceAbefore = walletA.getBalance(); - BigInteger balanceBbefore = walletB.getBalance(); - log.info("walletA balance before: {}", Utils.formatNanoValue(balanceAbefore)); - log.info("walletB balance before: {}", Utils.formatNanoValue(balanceBbefore)); - - - WalletV4R2Config configA = WalletV4R2Config.builder() - .walletId(42) - .seqno(walletA.getSeqno()) - .destination(walletB.getAddress()) - .amount(Utils.toNano(0.1)) - .mode(3) - .build(); - - Message msg = walletA.prepareExternalMsg(configA); - QueryFees feesWithCodeData = tonlib.estimateFees( - walletB.getAddress().toBounceable(), - msg.getBody().toBase64(), null, null, true); - - //adjust new amount - configA.setAmount(Utils.toNano(0.1).add(walletA.getGasFees()).add(BigInteger.valueOf(feesWithCodeData.getSource_fees().getStorage_fee()))); - - log.info("fees on walletB with msg body from A: {}", feesWithCodeData); - - walletA.send(configA); - - walletB.waitForBalanceChange(30); - - BigInteger balanceAafter = walletA.getBalance(); - BigInteger balanceBafter = walletB.getBalance(); - log.info("walletA balance after: {}", Utils.formatNanoValue(balanceAafter)); - log.info("walletB balance after: {}", Utils.formatNanoValue(balanceBafter)); - - log.info("diff walletA (debited): -{}", Utils.formatNanoValue(balanceAbefore.subtract(balanceAafter))); - log.info("diff walletB (credited): +{}, missing value {}", Utils.formatNanoValue(balanceBafter.subtract(balanceBbefore)), - Utils.formatNanoValue(Utils.toNano(0.1).subtract(balanceBafter.subtract(balanceBbefore)))); - } - - @Test - public void testWalletStorageFeeSpeedV4() { - - Tonlib tonlib = Tonlib.builder() - .testnet(true) - .ignoreCache(false) - .build(); - - TweetNaclFast.Box.KeyPair keyPairBoxA = Utils.generateKeyPairFromSecretKey(Utils.hexToSignedBytes("3d3015dcc3c0f3d51710bfe4894de954334bb6f44f75061109d9e7dcaf7b5a85c2ca482a19f06f63c9975fd7e679d89014ab2b4b645fc591c287a2818dabb42f")); - TweetNaclFast.Signature.KeyPair keyPairSignatureA = Utils.generateSignatureKeyPairFromSeed(keyPairBoxA.getSecretKey()); - WalletV4R2 walletA = WalletV4R2.builder() - .keyPair(keyPairSignatureA) - .tonlib(tonlib) - .walletId(42) - .build(); - log.info("rawAddressA {}", walletA.getAddress().toRaw()); - log.info("bounceableA {}", walletA.getAddress().toBounceable()); - - TweetNaclFast.Box.KeyPair keyPairBoxB = Utils.generateKeyPairFromSecretKey(Utils.hexToSignedBytes("6763fd614cd1658c4f0c0b08dd82d49060f329387c4d38f1281db7ccb91f6eb3219d2acaa90c2091813785426feb5234af9027637db05b55e65ff3e54a94ad0b")); - TweetNaclFast.Signature.KeyPair keyPairSignatureB = Utils.generateSignatureKeyPairFromSeed(keyPairBoxB.getSecretKey()); - WalletV4R2 walletB = WalletV4R2.builder() - .keyPair(keyPairSignatureB) - .tonlib(tonlib) - .walletId(98) - .build(); - - WalletV4R2Config configA = WalletV4R2Config.builder() - .walletId(42) - .seqno(walletA.getSeqno()) - .destination(walletB.getAddress()) - .mode(3) - .build(); - - Message msg = walletA.prepareExternalMsg(configA); - - ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); - executorService.scheduleAtFixedRate(() -> { - QueryFees f = tonlib.estimateFees( - walletB.getAddress().toBounceable(), - msg.getBody().toBase64()); - log.info("fees {}", f); - }, 0, 15, TimeUnit.SECONDS); - - Utils.sleep(600); - } + String nonBounceableAddrWalletB = walletB.getAddress().toNonBounceable(); + String rawAddrWalletB = walletB.getAddress().toRaw(); + + log.info("rawAddressB: {}", rawAddrWalletB); + + log.info("pub-key {}", Utils.bytesToHex(walletB.getKeyPair().getPublicKey())); + log.info("prv-key {}", Utils.bytesToHex(walletB.getKeyPair().getSecretKey())); + + // top up new walletA using test-faucet-wallet + BigInteger balance1 = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddrWalletA), Utils.toNano(1)); + log.info( + "walletId {} new wallet {} balance: {}", + walletA.getWalletId(), + walletA.getName(), + Utils.formatNanoValue(balance1)); + + // top up new walletB using test-faucet-wallet + BigInteger balance2 = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddrWalletB), Utils.toNano(1)); + log.info( + "walletId {} new wallet {} balance: {}", + walletB.getWalletId(), + walletB.getName(), + Utils.formatNanoValue(balance2)); + + ExtMessageInfo extMessageInfo = walletA.deploy(); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + walletA.waitForDeployment(30); + + extMessageInfo = walletB.deploy(); + AssertionsForClassTypes.assertThat(extMessageInfo.getError().getCode()).isZero(); + + walletB.waitForDeployment(30); + + // transfer 0.1 from walletA to walletB where B receives exact amount i.e. 0.1 + BigInteger balanceAbefore = walletA.getBalance(); + BigInteger balanceBbefore = walletB.getBalance(); + log.info("walletA balance before: {}", Utils.formatNanoValue(balanceAbefore)); + log.info("walletB balance before: {}", Utils.formatNanoValue(balanceBbefore)); + + WalletV4R2Config configA = + WalletV4R2Config.builder() + .walletId(42) + .seqno(walletA.getSeqno()) + .destination(walletB.getAddress()) + // .amount(Utils.toNano(0.1 + 0.000040000)) + .mode(3) + .build(); + + Message msg = walletA.prepareExternalMsg(configA); + + QueryFees fees = + tonlib.estimateFees( + walletB.getAddress().toBounceable(), msg.getBody().toBase64(), null, null, true); + + // adjust amount by including storage fee + configA.setAmount( + Utils.toNano(0.1) + .add(walletA.getGasFees()) + .add(BigInteger.valueOf(fees.getSource_fees().getStorage_fee()))); + + log.info("fees on walletB with msg body from A: {}", fees); + log.info("sending {}", Utils.formatNanoValue(configA.getAmount())); + + walletA.send(configA); + + walletB.waitForBalanceChange(30); + + BigInteger balanceAafter = walletA.getBalance(); + BigInteger balanceBafter = walletB.getBalance(); + log.info("walletA balance after: {}", Utils.formatNanoValue(balanceAafter)); + log.info("walletB balance after: {}", Utils.formatNanoValue(balanceBafter)); + + log.info( + "diff walletA (debited): -{}", + Utils.formatNanoValue(balanceAbefore.subtract(balanceAafter))); + log.info( + "diff walletB (credited): +{}, missing value {}", + Utils.formatNanoValue(balanceBafter.subtract(balanceBbefore)), + Utils.formatNanoValue(Utils.toNano(0.1).subtract(balanceBafter.subtract(balanceBbefore)))); + + assertThat(Utils.toNano(0.1).subtract(balanceBafter.subtract(balanceBbefore))) + .isEqualTo(BigInteger.ZERO); + } + + /** + * Trying to send amount of toncoins so that recipient gets the exact amount. There might be a + * mistake of several nano coins if transaction lasts too long. + */ + @Test + public void testWithDeployedWalletsV4AB() { + + Tonlib tonlib = Tonlib.builder().testnet(true).ignoreCache(false).build(); + + TweetNaclFast.Box.KeyPair keyPairBoxA = + Utils.generateKeyPairFromSecretKey( + Utils.hexToSignedBytes( + "3d3015dcc3c0f3d51710bfe4894de954334bb6f44f75061109d9e7dcaf7b5a85c2ca482a19f06f63c9975fd7e679d89014ab2b4b645fc591c287a2818dabb42f")); + TweetNaclFast.Signature.KeyPair keyPairSignatureA = + Utils.generateSignatureKeyPairFromSeed(keyPairBoxA.getSecretKey()); + WalletV4R2 walletA = + WalletV4R2.builder().keyPair(keyPairSignatureA).tonlib(tonlib).walletId(42).build(); + log.info("rawAddressA {}", walletA.getAddress().toRaw()); + log.info("bounceableA {}", walletA.getAddress().toBounceable()); + + TweetNaclFast.Box.KeyPair keyPairBoxB = + Utils.generateKeyPairFromSecretKey( + Utils.hexToSignedBytes( + "6763fd614cd1658c4f0c0b08dd82d49060f329387c4d38f1281db7ccb91f6eb3219d2acaa90c2091813785426feb5234af9027637db05b55e65ff3e54a94ad0b")); + TweetNaclFast.Signature.KeyPair keyPairSignatureB = + Utils.generateSignatureKeyPairFromSeed(keyPairBoxB.getSecretKey()); + WalletV4R2 walletB = + WalletV4R2.builder().keyPair(keyPairSignatureB).tonlib(tonlib).walletId(98).build(); + log.info("rawAddressB {}", walletB.getAddress().toRaw()); + log.info("bounceableB {}", walletB.getAddress().toBounceable()); + + BigInteger balanceAbefore = walletA.getBalance(); + BigInteger balanceBbefore = walletB.getBalance(); + log.info("walletA balance before: {}", Utils.formatNanoValue(balanceAbefore)); + log.info("walletB balance before: {}", Utils.formatNanoValue(balanceBbefore)); + + WalletV4R2Config configA = + WalletV4R2Config.builder() + .walletId(42) + .seqno(walletA.getSeqno()) + .destination(walletB.getAddress()) + .amount(Utils.toNano(0.1)) + .mode(3) + .build(); + + Message msg = walletA.prepareExternalMsg(configA); + QueryFees feesWithCodeData = + tonlib.estimateFees( + walletB.getAddress().toBounceable(), msg.getBody().toBase64(), null, null, true); + + // adjust new amount + configA.setAmount( + Utils.toNano(0.1) + .add(walletA.getGasFees()) + .add(BigInteger.valueOf(feesWithCodeData.getSource_fees().getStorage_fee()))); + + log.info("fees on walletB with msg body from A: {}", feesWithCodeData); + + walletA.send(configA); + + walletB.waitForBalanceChange(30); + + BigInteger balanceAafter = walletA.getBalance(); + BigInteger balanceBafter = walletB.getBalance(); + log.info("walletA balance after: {}", Utils.formatNanoValue(balanceAafter)); + log.info("walletB balance after: {}", Utils.formatNanoValue(balanceBafter)); + + log.info( + "diff walletA (debited): -{}", + Utils.formatNanoValue(balanceAbefore.subtract(balanceAafter))); + log.info( + "diff walletB (credited): +{}, missing value {}", + Utils.formatNanoValue(balanceBafter.subtract(balanceBbefore)), + Utils.formatNanoValue(Utils.toNano(0.1).subtract(balanceBafter.subtract(balanceBbefore)))); + } + + @Test + public void testWalletStorageFeeSpeedV4() { + + Tonlib tonlib = Tonlib.builder().testnet(true).ignoreCache(false).build(); + + TweetNaclFast.Box.KeyPair keyPairBoxA = + Utils.generateKeyPairFromSecretKey( + Utils.hexToSignedBytes( + "3d3015dcc3c0f3d51710bfe4894de954334bb6f44f75061109d9e7dcaf7b5a85c2ca482a19f06f63c9975fd7e679d89014ab2b4b645fc591c287a2818dabb42f")); + TweetNaclFast.Signature.KeyPair keyPairSignatureA = + Utils.generateSignatureKeyPairFromSeed(keyPairBoxA.getSecretKey()); + WalletV4R2 walletA = + WalletV4R2.builder().keyPair(keyPairSignatureA).tonlib(tonlib).walletId(42).build(); + log.info("rawAddressA {}", walletA.getAddress().toRaw()); + log.info("bounceableA {}", walletA.getAddress().toBounceable()); + + TweetNaclFast.Box.KeyPair keyPairBoxB = + Utils.generateKeyPairFromSecretKey( + Utils.hexToSignedBytes( + "6763fd614cd1658c4f0c0b08dd82d49060f329387c4d38f1281db7ccb91f6eb3219d2acaa90c2091813785426feb5234af9027637db05b55e65ff3e54a94ad0b")); + TweetNaclFast.Signature.KeyPair keyPairSignatureB = + Utils.generateSignatureKeyPairFromSeed(keyPairBoxB.getSecretKey()); + WalletV4R2 walletB = + WalletV4R2.builder().keyPair(keyPairSignatureB).tonlib(tonlib).walletId(98).build(); + + WalletV4R2Config configA = + WalletV4R2Config.builder() + .walletId(42) + .seqno(walletA.getSeqno()) + .destination(walletB.getAddress()) + .mode(3) + .build(); + + Message msg = walletA.prepareExternalMsg(configA); + + ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); + executorService.scheduleAtFixedRate( + () -> { + QueryFees f = + tonlib.estimateFees(walletB.getAddress().toBounceable(), msg.getBody().toBase64()); + log.info("fees {}", f); + }, + 0, + 15, + TimeUnit.SECONDS); + + Utils.sleep(600); + } } diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletMultiSig.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletMultiSig.java index caee9c9f..c5772cef 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletMultiSig.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletMultiSig.java @@ -18,7 +18,7 @@ import org.ton.java.cell.Cell; import org.ton.java.cell.CellBuilder; import org.ton.java.cell.TonHashMapE; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.multisig.MultiSigWallet; import org.ton.java.smartcontract.types.MultiSigConfig; import org.ton.java.smartcontract.types.MultisigSignature; @@ -31,873 +31,934 @@ @RunWith(JUnit4.class) public class TestWalletMultiSig extends CommonTest { - TweetNaclFast.Signature.KeyPair ownerKeyPair = Utils.generateSignatureKeyPair(); - TweetNaclFast.Signature.KeyPair keyPair2 = Utils.generateSignatureKeyPair(); - TweetNaclFast.Signature.KeyPair keyPair3 = Utils.generateSignatureKeyPair(); - TweetNaclFast.Signature.KeyPair keyPair4 = Utils.generateSignatureKeyPair(); - TweetNaclFast.Signature.KeyPair keyPair5 = Utils.generateSignatureKeyPair(); - - /** - * Any user deploys a multiSig wallet. - * Any user from the list creates an order and gathers all the required signatures, - * then sends the order to the wallet. - */ - @Test - public void testWalletMultiSigOffline() throws InterruptedException { - - log.info("pubKey0 {}", Utils.bytesToHex(ownerKeyPair.getPublicKey())); - log.info("pubKey2 {}", Utils.bytesToHex(keyPair2.getPublicKey())); - log.info("pubKey3 {}", Utils.bytesToHex(keyPair3.getPublicKey())); - log.info("pubKey4 {}", Utils.bytesToHex(keyPair4.getPublicKey())); - log.info("pubKey5 {}", Utils.bytesToHex(keyPair5.getPublicKey())); - - BigInteger queryId = new BigInteger("9223372036854775807"); - - Long walletId = 1045609917L; - log.info("queryId {}, walletId {}", queryId, walletId); - - int rootIndex = 0; - int pubkey2Index = 1; - int pubkey3Index = 2; - int pubkey4Index = 3; - int pubkey5Index = 4; - int k = 3; - int n = 5; - - MultiSigWallet contract = MultiSigWallet.builder() - .tonlib(tonlib) - .keyPair(ownerKeyPair) - .walletId(walletId) - .config(MultiSigConfig.builder() - .queryId(queryId) - .k(k) - .n(n) - .rootI(rootIndex) - .owners( - Arrays.asList( - OwnerInfo.builder() - .publicKey(ownerKeyPair.getPublicKey()) - .flood(1) - .build(), - OwnerInfo.builder() - .publicKey(keyPair2.getPublicKey()) - .flood(2) - .build(), - OwnerInfo.builder() - .publicKey(keyPair3.getPublicKey()) - .flood(3) - .build(), - OwnerInfo.builder() - .publicKey(keyPair4.getPublicKey()) - .flood(4) - .build(), - OwnerInfo.builder() - .publicKey(keyPair5.getPublicKey()) - .flood(5) - .build() - ) - ).build()) - .build(); - - String nonBounceableAddress = contract.getAddress().toNonBounceable(); - String bounceableAddress = contract.getAddress().toBounceable(); - - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(5)); - Utils.sleep(30, "topping up..."); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - - ExtMessageInfo extMessageInfo = contract.deploy(); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForDeployment(30); // with empty ext-msg - - log.info("owners publicKeys {}", contract.getPublicKeys()); - log.info("owners publicKeysHex {}", contract.getPublicKeysHex()); - - Pair n_k = contract.getNandK(); - log.info("n {}, k {}", n_k.getLeft(), n_k.getRight()); - - // You can include up to 3 destinations - Cell msg1 = MultiSigWallet.createOneInternalMsg(Address.of("EQAaGHUHfkpWFGs428ETmym4vbvRNxCA1o4sTkwqigKjgf-_"), Utils.toNano(0.5), 3); - Cell msg2 = MultiSigWallet.createOneInternalMsg(Address.of("EQDUna0j-TKlMU9pOBBHNoLzpwlewHl7S1qXtnaYdTTs_Ict"), Utils.toNano(0.6), 3); - Cell msg3 = MultiSigWallet.createOneInternalMsg(Address.of("EQCAy2ue54I-uDvEgD3qXdqjtrJI4F4OeFn3V10Kgt0jXpQn"), Utils.toNano(0.7), 3); - - // Having message(s) to send you can group it to a new order - Cell order = MultiSigWallet.createOrder(walletId, queryId, msg1, msg2, msg3); - order.toFile("order.boc"); - - byte[] orderSignatureUser1 = MultiSigWallet.signOrder(ownerKeyPair, order); - byte[] orderSignatureUser2 = MultiSigWallet.signOrder(keyPair2, order); - byte[] orderSignatureUser3 = MultiSigWallet.signOrder(keyPair3, order); - byte[] orderSignatureUser4 = MultiSigWallet.signOrder(keyPair4, order); - byte[] orderSignatureUser5 = MultiSigWallet.signOrder(keyPair5, order); - - // collected two more signatures - Cell signedOrder = MultiSigWallet.addSignatures(order, - Arrays.asList( - MultisigSignature.builder() - .pubKeyPosition(pubkey3Index) - .signature(orderSignatureUser3) - .build(), - MultisigSignature.builder() - .pubKeyPosition(pubkey4Index) - .signature(orderSignatureUser4) - .build(), - MultisigSignature.builder() - .pubKeyPosition(pubkey5Index) - .signature(orderSignatureUser5) - .build() - ) - ); - - signedOrder.toFile("signedOrder.boc", false); - - // submitter keypair must come from User3 or User4, otherwise you get error 34 - extMessageInfo = contract.sendOrder(keyPair5, pubkey5Index, signedOrder); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForBalanceChange(30); - - Pair queryState = contract.getQueryState(queryId); - log.info("get_query_state (query {}): status {}, mask {}", queryId, queryState.getLeft(), queryState.getRight()); - - assertThat(queryState.getLeft()).isEqualTo(-1); - } - - /** - * One user deploys a multisig wallet and send the first order, - * other user then collects offline more signatures and sends them to the wallet. - * Hybrid: On-chain/Off-chain consensus. - */ - @Test - public void testWalletMultiSigHybrid() throws InterruptedException { - - log.info("pubKey0 {}", Utils.bytesToHex(ownerKeyPair.getPublicKey())); - log.info("pubKey2 {}", Utils.bytesToHex(keyPair2.getPublicKey())); - log.info("pubKey3 {}", Utils.bytesToHex(keyPair3.getPublicKey())); - log.info("pubKey4 {}", Utils.bytesToHex(keyPair4.getPublicKey())); - log.info("pubKey5 {}", Utils.bytesToHex(keyPair5.getPublicKey())); - - BigInteger queryId = BigInteger.valueOf(Instant.now().getEpochSecond() + 5 * 60 * 60L << 32); - - Long walletId = new Random().nextLong() & 0xffffffffL; - log.info("queryId {}, walletId {}", queryId, walletId); - - int rootIndex = 0; - int pubkey2Index = 1; - int pubkey3Index = 2; - int pubkey4Index = 3; - int pubkey5Index = 4; - int k = 3; - int n = 5; - - MultiSigWallet contract = MultiSigWallet.builder() - .tonlib(tonlib) - .keyPair(ownerKeyPair) - .walletId(walletId) - .config(MultiSigConfig.builder() - .queryId(queryId) - .k(k) - .n(n) - .rootI(rootIndex) - .owners(Arrays.asList( - OwnerInfo.builder() - .publicKey(ownerKeyPair.getPublicKey()) - .flood(1) - .build(), - OwnerInfo.builder() - .publicKey(keyPair2.getPublicKey()) - .flood(2) - .build(), - OwnerInfo.builder() - .publicKey(keyPair3.getPublicKey()) - .flood(3) - .build(), - OwnerInfo.builder() - .publicKey(keyPair4.getPublicKey()) - .flood(4) - .build(), - OwnerInfo.builder() - .publicKey(keyPair5.getPublicKey()) - .flood(5) - .build() - )).build()) - .build(); - - String nonBounceableAddress = contract.getAddress().toNonBounceable(); - String bounceableAddress = contract.getAddress().toBounceable(); - - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(5)); - Utils.sleep(30, "topping up..."); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - - ExtMessageInfo extMessageInfo = contract.deploy(); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForDeployment(45); // with empty ext-msg - - log.info("owners publicKeysHex {}", contract.getPublicKeysHex()); - - Pair n_k = contract.getNandK(); - log.info("n {}, k {}", n_k.getLeft(), n_k.getRight()); - - // You can include up to 3 destinations - Cell msg1 = MultiSigWallet.createOneInternalMsg(Address.of("EQAaGHUHfkpWFGs428ETmym4vbvRNxCA1o4sTkwqigKjgf-_"), Utils.toNano(0.5), 3); - Cell msg2 = MultiSigWallet.createOneInternalMsg(Address.of("EQDUna0j-TKlMU9pOBBHNoLzpwlewHl7S1qXtnaYdTTs_Ict"), Utils.toNano(0.6), 3); - Cell msg3 = MultiSigWallet.createOneInternalMsg(Address.of("EQCAy2ue54I-uDvEgD3qXdqjtrJI4F4OeFn3V10Kgt0jXpQn"), Utils.toNano(0.7), 3); - - // Having message(s) to send you can group it to a new order - Cell order = MultiSigWallet.createOrder(walletId, queryId, msg1, msg2, msg3); - order.toFile("order.boc", false); - - byte[] orderSignatureUser1 = MultiSigWallet.signOrder(ownerKeyPair, order); - byte[] orderSignatureUser2 = MultiSigWallet.signOrder(keyPair2, order); - byte[] orderSignatureUser3 = MultiSigWallet.signOrder(keyPair3, order); - byte[] orderSignatureUser4 = MultiSigWallet.signOrder(keyPair4, order); - byte[] orderSignatureUser5 = MultiSigWallet.signOrder(keyPair5, order); - - extMessageInfo = contract.sendOrder(ownerKeyPair, rootIndex, order); - assertThat(extMessageInfo.getError().getCode()).isZero(); -// Utils.sleep(30, "processing 1st query"); - contract.waitForBalanceChange(30); - - Pair queryState = contract.getQueryState(queryId); - log.info("get_query_state (query {}): status {}, mask {}", queryId, queryState.getLeft(), queryState.getRight()); - - // collected two more signatures - Cell signedOrder = MultiSigWallet.addSignatures(order, - Arrays.asList( - MultisigSignature.builder() - .pubKeyPosition(pubkey3Index) - .signature(orderSignatureUser3) - .build(), - MultisigSignature.builder() - .pubKeyPosition(pubkey4Index) - .signature(orderSignatureUser4) - .build() - ) - ); - - signedOrder.toFile("signedOrder.boc", false); - - // submitter keypair must come from User3 or User4, otherwise you get error 34 - extMessageInfo = contract.sendOrder(keyPair3, pubkey3Index, signedOrder); - assertThat(extMessageInfo.getError().getCode()).isZero(); -// Utils.sleep(20, "processing 1st query"); - contract.waitForBalanceChange(30); - - showMessagesInfo(contract.getMessagesUnsigned(), "Messages-Unsigned"); - showMessagesInfo(contract.getMessagesSignedByIndex(rootIndex), "Messages-SignedByIndex-" + rootIndex); - showMessagesInfo(contract.getMessagesUnsignedByIndex(rootIndex), "Messages-UnsignedByIndex-" + rootIndex); - showMessagesInfo(contract.getMessagesSignedByIndex(pubkey2Index), "Messages-SignedByIndex-" + pubkey2Index); - showMessagesInfo(contract.getMessagesUnsignedByIndex(pubkey2Index), "Messages-UnsignedByIndex-" + pubkey2Index); - - queryState = contract.getQueryState(queryId); - log.info("get_query_state (query {}): status {}, mask {}", queryId, queryState.getLeft(), queryState.getRight()); - - assertThat(queryState.getLeft()).isEqualTo(-1); - - // 1 2 3 - Cell query = MultiSigWallet.createQuery(ownerKeyPair, - Arrays.asList( - MultisigSignature.builder() - .pubKeyPosition(rootIndex) - .signature(orderSignatureUser1) + TweetNaclFast.Signature.KeyPair ownerKeyPair = Utils.generateSignatureKeyPair(); + TweetNaclFast.Signature.KeyPair keyPair2 = Utils.generateSignatureKeyPair(); + TweetNaclFast.Signature.KeyPair keyPair3 = Utils.generateSignatureKeyPair(); + TweetNaclFast.Signature.KeyPair keyPair4 = Utils.generateSignatureKeyPair(); + TweetNaclFast.Signature.KeyPair keyPair5 = Utils.generateSignatureKeyPair(); + + /** + * Any user deploys a multiSig wallet. Any user from the list creates an order and gathers all the + * required signatures, then sends the order to the wallet. + */ + @Test + public void testWalletMultiSigOffline() throws InterruptedException { + + log.info("pubKey0 {}", Utils.bytesToHex(ownerKeyPair.getPublicKey())); + log.info("pubKey2 {}", Utils.bytesToHex(keyPair2.getPublicKey())); + log.info("pubKey3 {}", Utils.bytesToHex(keyPair3.getPublicKey())); + log.info("pubKey4 {}", Utils.bytesToHex(keyPair4.getPublicKey())); + log.info("pubKey5 {}", Utils.bytesToHex(keyPair5.getPublicKey())); + + BigInteger queryId = new BigInteger("9223372036854775807"); + + Long walletId = 1045609917L; + log.info("queryId {}, walletId {}", queryId, walletId); + + int rootIndex = 0; + int pubkey2Index = 1; + int pubkey3Index = 2; + int pubkey4Index = 3; + int pubkey5Index = 4; + int k = 3; + int n = 5; + + MultiSigWallet contract = + MultiSigWallet.builder() + .tonlib(tonlib) + .keyPair(ownerKeyPair) + .walletId(walletId) + .config( + MultiSigConfig.builder() + .queryId(queryId) + .k(k) + .n(n) + .rootI(rootIndex) + .owners( + Arrays.asList( + OwnerInfo.builder() + .publicKey(ownerKeyPair.getPublicKey()) + .flood(1) .build(), - MultisigSignature.builder() - .pubKeyPosition(pubkey2Index) - .signature(orderSignatureUser2) + OwnerInfo.builder().publicKey(keyPair2.getPublicKey()).flood(2).build(), + OwnerInfo.builder().publicKey(keyPair3.getPublicKey()).flood(3).build(), + OwnerInfo.builder().publicKey(keyPair4.getPublicKey()).flood(4).build(), + OwnerInfo.builder() + .publicKey(keyPair5.getPublicKey()) + .flood(5) + .build())) + .build()) + .build(); + + String nonBounceableAddress = contract.getAddress().toNonBounceable(); + String bounceableAddress = contract.getAddress().toBounceable(); + + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(5)); + Utils.sleep(30, "topping up..."); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + + ExtMessageInfo extMessageInfo = contract.deploy(); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForDeployment(30); // with empty ext-msg + + log.info("owners publicKeys {}", contract.getPublicKeys()); + log.info("owners publicKeysHex {}", contract.getPublicKeysHex()); + + Pair n_k = contract.getNandK(); + log.info("n {}, k {}", n_k.getLeft(), n_k.getRight()); + + // You can include up to 3 destinations + Cell msg1 = + MultiSigWallet.createOneInternalMsg( + Address.of("EQAaGHUHfkpWFGs428ETmym4vbvRNxCA1o4sTkwqigKjgf-_"), Utils.toNano(0.5), 3); + Cell msg2 = + MultiSigWallet.createOneInternalMsg( + Address.of("EQDUna0j-TKlMU9pOBBHNoLzpwlewHl7S1qXtnaYdTTs_Ict"), Utils.toNano(0.6), 3); + Cell msg3 = + MultiSigWallet.createOneInternalMsg( + Address.of("EQCAy2ue54I-uDvEgD3qXdqjtrJI4F4OeFn3V10Kgt0jXpQn"), Utils.toNano(0.7), 3); + + // Having message(s) to send you can group it to a new order + Cell order = MultiSigWallet.createOrder(walletId, queryId, msg1, msg2, msg3); + order.toFile("order.boc"); + + byte[] orderSignatureUser1 = MultiSigWallet.signOrder(ownerKeyPair, order); + byte[] orderSignatureUser2 = MultiSigWallet.signOrder(keyPair2, order); + byte[] orderSignatureUser3 = MultiSigWallet.signOrder(keyPair3, order); + byte[] orderSignatureUser4 = MultiSigWallet.signOrder(keyPair4, order); + byte[] orderSignatureUser5 = MultiSigWallet.signOrder(keyPair5, order); + + // collected two more signatures + Cell signedOrder = + MultiSigWallet.addSignatures( + order, + Arrays.asList( + MultisigSignature.builder() + .pubKeyPosition(pubkey3Index) + .signature(orderSignatureUser3) + .build(), + MultisigSignature.builder() + .pubKeyPosition(pubkey4Index) + .signature(orderSignatureUser4) + .build(), + MultisigSignature.builder() + .pubKeyPosition(pubkey5Index) + .signature(orderSignatureUser5) + .build())); + + signedOrder.toFile("signedOrder.boc", false); + + // submitter keypair must come from User3 or User4, otherwise you get error 34 + extMessageInfo = contract.sendOrder(keyPair5, pubkey5Index, signedOrder); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForBalanceChange(30); + + Pair queryState = contract.getQueryState(queryId); + log.info( + "get_query_state (query {}): status {}, mask {}", + queryId, + queryState.getLeft(), + queryState.getRight()); + + assertThat(queryState.getLeft()).isEqualTo(-1); + } + + /** + * One user deploys a multisig wallet and send the first order, other user then collects offline + * more signatures and sends them to the wallet. Hybrid: On-chain/Off-chain consensus. + */ + @Test + public void testWalletMultiSigHybrid() throws InterruptedException { + + log.info("pubKey0 {}", Utils.bytesToHex(ownerKeyPair.getPublicKey())); + log.info("pubKey2 {}", Utils.bytesToHex(keyPair2.getPublicKey())); + log.info("pubKey3 {}", Utils.bytesToHex(keyPair3.getPublicKey())); + log.info("pubKey4 {}", Utils.bytesToHex(keyPair4.getPublicKey())); + log.info("pubKey5 {}", Utils.bytesToHex(keyPair5.getPublicKey())); + + BigInteger queryId = BigInteger.valueOf(Instant.now().getEpochSecond() + 5 * 60 * 60L << 32); + + Long walletId = new Random().nextLong() & 0xffffffffL; + log.info("queryId {}, walletId {}", queryId, walletId); + + int rootIndex = 0; + int pubkey2Index = 1; + int pubkey3Index = 2; + int pubkey4Index = 3; + int pubkey5Index = 4; + int k = 3; + int n = 5; + + MultiSigWallet contract = + MultiSigWallet.builder() + .tonlib(tonlib) + .keyPair(ownerKeyPair) + .walletId(walletId) + .config( + MultiSigConfig.builder() + .queryId(queryId) + .k(k) + .n(n) + .rootI(rootIndex) + .owners( + Arrays.asList( + OwnerInfo.builder() + .publicKey(ownerKeyPair.getPublicKey()) + .flood(1) .build(), - MultisigSignature.builder() - .pubKeyPosition(pubkey3Index) - .signature(orderSignatureUser3) - .build() - ), order); - Pair cnt_mask = contract.checkQuerySignatures(tonlib, query); - log.info("cnt {}, mask {}", cnt_mask.getLeft(), cnt_mask.getRight()); - - // 1 2 3 5 - query = MultiSigWallet.createQuery(ownerKeyPair, - Arrays.asList( - MultisigSignature.builder() - .pubKeyPosition(rootIndex) - .signature(orderSignatureUser1) + OwnerInfo.builder().publicKey(keyPair2.getPublicKey()).flood(2).build(), + OwnerInfo.builder().publicKey(keyPair3.getPublicKey()).flood(3).build(), + OwnerInfo.builder().publicKey(keyPair4.getPublicKey()).flood(4).build(), + OwnerInfo.builder() + .publicKey(keyPair5.getPublicKey()) + .flood(5) + .build())) + .build()) + .build(); + + String nonBounceableAddress = contract.getAddress().toNonBounceable(); + String bounceableAddress = contract.getAddress().toBounceable(); + + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(5)); + Utils.sleep(30, "topping up..."); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + + ExtMessageInfo extMessageInfo = contract.deploy(); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForDeployment(45); // with empty ext-msg + + log.info("owners publicKeysHex {}", contract.getPublicKeysHex()); + + Pair n_k = contract.getNandK(); + log.info("n {}, k {}", n_k.getLeft(), n_k.getRight()); + + // You can include up to 3 destinations + Cell msg1 = + MultiSigWallet.createOneInternalMsg( + Address.of("EQAaGHUHfkpWFGs428ETmym4vbvRNxCA1o4sTkwqigKjgf-_"), Utils.toNano(0.5), 3); + Cell msg2 = + MultiSigWallet.createOneInternalMsg( + Address.of("EQDUna0j-TKlMU9pOBBHNoLzpwlewHl7S1qXtnaYdTTs_Ict"), Utils.toNano(0.6), 3); + Cell msg3 = + MultiSigWallet.createOneInternalMsg( + Address.of("EQCAy2ue54I-uDvEgD3qXdqjtrJI4F4OeFn3V10Kgt0jXpQn"), Utils.toNano(0.7), 3); + + // Having message(s) to send you can group it to a new order + Cell order = MultiSigWallet.createOrder(walletId, queryId, msg1, msg2, msg3); + order.toFile("order.boc", false); + + byte[] orderSignatureUser1 = MultiSigWallet.signOrder(ownerKeyPair, order); + byte[] orderSignatureUser2 = MultiSigWallet.signOrder(keyPair2, order); + byte[] orderSignatureUser3 = MultiSigWallet.signOrder(keyPair3, order); + byte[] orderSignatureUser4 = MultiSigWallet.signOrder(keyPair4, order); + byte[] orderSignatureUser5 = MultiSigWallet.signOrder(keyPair5, order); + + extMessageInfo = contract.sendOrder(ownerKeyPair, rootIndex, order); + assertThat(extMessageInfo.getError().getCode()).isZero(); + // Utils.sleep(30, "processing 1st query"); + contract.waitForBalanceChange(30); + + Pair queryState = contract.getQueryState(queryId); + log.info( + "get_query_state (query {}): status {}, mask {}", + queryId, + queryState.getLeft(), + queryState.getRight()); + + // collected two more signatures + Cell signedOrder = + MultiSigWallet.addSignatures( + order, + Arrays.asList( + MultisigSignature.builder() + .pubKeyPosition(pubkey3Index) + .signature(orderSignatureUser3) + .build(), + MultisigSignature.builder() + .pubKeyPosition(pubkey4Index) + .signature(orderSignatureUser4) + .build())); + + signedOrder.toFile("signedOrder.boc", false); + + // submitter keypair must come from User3 or User4, otherwise you get error 34 + extMessageInfo = contract.sendOrder(keyPair3, pubkey3Index, signedOrder); + assertThat(extMessageInfo.getError().getCode()).isZero(); + // Utils.sleep(20, "processing 1st query"); + contract.waitForBalanceChange(30); + + showMessagesInfo(contract.getMessagesUnsigned(), "Messages-Unsigned"); + showMessagesInfo( + contract.getMessagesSignedByIndex(rootIndex), "Messages-SignedByIndex-" + rootIndex); + showMessagesInfo( + contract.getMessagesUnsignedByIndex(rootIndex), "Messages-UnsignedByIndex-" + rootIndex); + showMessagesInfo( + contract.getMessagesSignedByIndex(pubkey2Index), "Messages-SignedByIndex-" + pubkey2Index); + showMessagesInfo( + contract.getMessagesUnsignedByIndex(pubkey2Index), + "Messages-UnsignedByIndex-" + pubkey2Index); + + queryState = contract.getQueryState(queryId); + log.info( + "get_query_state (query {}): status {}, mask {}", + queryId, + queryState.getLeft(), + queryState.getRight()); + + assertThat(queryState.getLeft()).isEqualTo(-1); + + // 1 2 3 + Cell query = + MultiSigWallet.createQuery( + ownerKeyPair, + Arrays.asList( + MultisigSignature.builder() + .pubKeyPosition(rootIndex) + .signature(orderSignatureUser1) + .build(), + MultisigSignature.builder() + .pubKeyPosition(pubkey2Index) + .signature(orderSignatureUser2) + .build(), + MultisigSignature.builder() + .pubKeyPosition(pubkey3Index) + .signature(orderSignatureUser3) + .build()), + order); + Pair cnt_mask = contract.checkQuerySignatures(tonlib, query); + log.info("cnt {}, mask {}", cnt_mask.getLeft(), cnt_mask.getRight()); + + // 1 2 3 5 + query = + MultiSigWallet.createQuery( + ownerKeyPair, + Arrays.asList( + MultisigSignature.builder() + .pubKeyPosition(rootIndex) + .signature(orderSignatureUser1) + .build(), + MultisigSignature.builder() + .pubKeyPosition(pubkey2Index) + .signature(orderSignatureUser2) + .build(), + MultisigSignature.builder() + .pubKeyPosition(pubkey3Index) + .signature(orderSignatureUser3) + .build(), + MultisigSignature.builder() + .pubKeyPosition(pubkey4Index) + .signature(orderSignatureUser4) + .build(), + MultisigSignature.builder() + .pubKeyPosition(pubkey5Index) + .signature(orderSignatureUser5) + .build()), + order); + + cnt_mask = contract.checkQuerySignatures(tonlib, query); + log.info("cnt {}, mask {}", cnt_mask.getLeft(), cnt_mask.getRight()); + } + + @Test + public void testGetInitState() throws InterruptedException { + + log.info("pubKey0 {}", Utils.bytesToHex(ownerKeyPair.getPublicKey())); + log.info("pubKey1 {}", Utils.bytesToHex(keyPair2.getPublicKey())); + + BigInteger queryId = BigInteger.valueOf(Instant.now().getEpochSecond() + 5 * 60L << 32); + + Long walletId = new Random().nextLong() & 0xffffffffL; + log.info("queryId {}, walletId {}", queryId.toString(10), walletId); + + int k = 1; + int n = 2; + + MultiSigWallet contract = + MultiSigWallet.builder() + .tonlib(tonlib) + .keyPair(ownerKeyPair) + .walletId(walletId) + .config( + MultiSigConfig.builder() + .queryId(queryId) + .k(k) + .n(n) + .rootI(0) + .owners( + Arrays.asList( + OwnerInfo.builder() + .publicKey(ownerKeyPair.getPublicKey()) + .flood(1) .build(), - MultisigSignature.builder() - .pubKeyPosition(pubkey2Index) - .signature(orderSignatureUser2) + OwnerInfo.builder() + .publicKey(keyPair2.getPublicKey()) + .flood(2) + .build())) + .build()) + .build(); + + String nonBounceableAddress = contract.getAddress().toNonBounceable(); + String bounceableAddress = contract.getAddress().toBounceable(); + + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); + Utils.sleep(30, "topping up..."); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + + ExtMessageInfo extMessageInfo = contract.deploy(); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForDeployment(45); // with empty ext msg + + List ownersPublicKeys = + Arrays.asList( + OwnerInfo.builder().publicKey(ownerKeyPair.getPublicKey()).flood(0).build(), + OwnerInfo.builder().publicKey(keyPair2.getPublicKey()).flood(1).build()); + + Cell stateInit = + contract.getInitState(walletId, n, k, contract.createOwnersInfoDict(ownersPublicKeys)); + log.info("state-init {}", stateInit.toHex(false)); + } + + /** Test different root index and multiple orders. Consensus gets calculated on-chain. */ + @Test + public void testRootIAndMultipleOrdersOnChain() throws InterruptedException { + log.info("pubKey0 {}", Utils.bytesToHex(ownerKeyPair.getPublicKey())); + log.info("pubKey1 {}", Utils.bytesToHex(keyPair2.getPublicKey())); + log.info("pubKey2 {}", Utils.bytesToHex(keyPair3.getPublicKey())); + + BigInteger queryId1 = + BigInteger.valueOf((long) Math.pow(Instant.now().getEpochSecond() + 10 * 60L, 32)); + BigInteger queryId2 = + BigInteger.valueOf((long) Math.pow(Instant.now().getEpochSecond() + 10 * 60L, 32) - 5); + + Long walletId = new Random().nextLong() & 0xffffffffL; + log.info("queryId-1 {}, walletId {}", queryId1.toString(10), walletId); + log.info("queryId-2 {}, walletId {}", queryId2.toString(10), walletId); + + int k = 2; + int n = 3; + + MultiSigWallet contract = + MultiSigWallet.builder() + .tonlib(tonlib) + .keyPair(ownerKeyPair) + .walletId(walletId) + .config( + MultiSigConfig.builder() + .queryId(queryId1) + .k(k) + .n(n) + .rootI(2) // initial root index + .owners( + Arrays.asList( + OwnerInfo.builder() + .publicKey(ownerKeyPair.getPublicKey()) + .flood(1) .build(), - MultisigSignature.builder() - .pubKeyPosition(pubkey3Index) - .signature(orderSignatureUser3) + OwnerInfo.builder().publicKey(keyPair2.getPublicKey()).flood(2).build(), + OwnerInfo.builder() + .publicKey(keyPair3.getPublicKey()) + .flood(3) + .build())) + .build()) + .build(); + + String nonBounceableAddress = contract.getAddress().toNonBounceable(); + String bounceableAddress = contract.getAddress().toBounceable(); + + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(5)); + Utils.sleep(30, "topping up..."); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + + ExtMessageInfo extMessageInfo = contract.deploy(); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForDeployment(45); // with empty ext msg + + log.info("owners publicKeysHex {}", contract.getPublicKeysHex()); + + Pair n_k = contract.getNandK(); + log.info("n {}, k {}", n_k.getLeft(), n_k.getRight()); + + Cell txMsg1 = + MultiSigWallet.createOneInternalMsg( + Address.of("EQAaGHUHfkpWFGs428ETmym4vbvRNxCA1o4sTkwqigKjgf-_"), Utils.toNano(0.5), 3); + Cell order1 = MultiSigWallet.createOrder(walletId, queryId1, txMsg1); + byte[] order1Signature3 = MultiSigWallet.signCell(keyPair3, order1); + + // send order-1 signed by 3rd owner (root index 2) + extMessageInfo = contract.sendOrder(keyPair3, 2, order1); // root index 2 + assertThat(extMessageInfo.getError().getCode()).isZero(); + contract.waitForBalanceChange(30); + + Pair queryState = contract.getQueryState(queryId1); + log.info( + "get_query_state (query {}): status {}, mask {}", + queryId1.toString(10), + queryState.getLeft(), + queryState.getRight()); + + Cell msg2 = + MultiSigWallet.createOneInternalMsg( + Address.of("EQCAy2ue54I-uDvEgD3qXdqjtrJI4F4OeFn3V10Kgt0jXpQn"), Utils.toNano(0.8), 3); + Cell order2 = MultiSigWallet.createOrder(walletId, queryId2, msg2); + + // send order-2 signed by 2nd owner (root index 1) + extMessageInfo = contract.sendOrder(keyPair2, 1, order2); + assertThat(extMessageInfo.getError().getCode()).isZero(); + contract.waitForBalanceChange(30); + + queryState = contract.getQueryState(queryId2); + log.info( + "get_query_state (query {}): status {}, mask {}", + queryId2, + queryState.getLeft(), + queryState.getRight()); + + // send order-2 signed by 3rd owner (root index 2) + extMessageInfo = contract.sendOrder(keyPair3, 2, order2); + assertThat(extMessageInfo.getError().getCode()).isZero(); + contract.waitForBalanceChange(30); + + queryState = contract.getQueryState(queryId2); + log.info( + "get_query_state (query {}): status {}, mask {}", + queryId2, + queryState.getLeft(), + queryState.getRight()); + assertThat(queryState.getLeft()).isEqualTo(-1); + } + + /** + * Each owner sends the extmsg signed by him, containing the order. Consensus gets calculated + * on-chain. + */ + @Test + public void testEmptySignaturesListOnChain() throws InterruptedException { + + log.info("pubKey0 {}", Utils.bytesToHex(ownerKeyPair.getPublicKey())); + log.info("pubKey1 {}", Utils.bytesToHex(keyPair2.getPublicKey())); + log.info("pubKey2 {}", Utils.bytesToHex(keyPair3.getPublicKey())); + + BigInteger queryId = + BigInteger.valueOf((long) Math.pow(Instant.now().getEpochSecond() + 10 * 60L, 32)); + + Long walletId = new Random().nextLong() & 0xffffffffL; + log.info("queryId-1 {}, walletId {}", queryId.toString(10), walletId); + + int k = 2; + int n = 3; + + MultiSigWallet contract = + MultiSigWallet.builder() + .tonlib(tonlib) + .keyPair(ownerKeyPair) + .walletId(walletId) + .config( + MultiSigConfig.builder() + .queryId(queryId) + .k(k) + .n(n) + .rootI(0) // initial root index + .owners( + Arrays.asList( + OwnerInfo.builder() + .publicKey(ownerKeyPair.getPublicKey()) + .flood(1) .build(), - MultisigSignature.builder() - .pubKeyPosition(pubkey4Index) - .signature(orderSignatureUser4) + OwnerInfo.builder() + .publicKey(keyPair2.getPublicKey()) + .flood(2) + .build())) + .build()) + .build(); + + String nonBounceableAddress = contract.getAddress().toNonBounceable(); + String bounceableAddress = contract.getAddress().toBounceable(); + + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); + Utils.sleep(30, "topping up..."); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + + ExtMessageInfo extMessageInfo = contract.deploy(); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForDeployment(45); // with empty ext msg + + log.info("owners publicKeysHex {}", contract.getPublicKeysHex()); + + Pair n_k = contract.getNandK(); + log.info("n {}, k {}", n_k.getLeft(), n_k.getRight()); + + Cell txMsg1 = + MultiSigWallet.createOneInternalMsg( + Address.of("EQAaGHUHfkpWFGs428ETmym4vbvRNxCA1o4sTkwqigKjgf-_"), Utils.toNano(0.5), 3); + Cell order = MultiSigWallet.createOrder(walletId, queryId, txMsg1); + + // send order-1 signed by 1st owner (root index 0) + extMessageInfo = contract.sendOrder(ownerKeyPair.getSecretKey(), 0, order); // root index 0 + assertThat(extMessageInfo.getError().getCode()).isZero(); + contract.waitForBalanceChange(30); + + showMessagesInfo(contract.getMessagesUnsignedByIndex(0), "MessagesUnsignedByIndex-" + 0); + showMessagesInfo(contract.getMessagesSignedByIndex(0), "MessagesSignedByIndex-" + 0); + + Pair queryState = contract.getQueryState(queryId); + log.info( + "get_query_state (query {}): status {}, mask {}", + queryId, + queryState.getLeft(), + queryState.getRight()); + + // send order-1 signed by 2nd owner (root index 1) + extMessageInfo = contract.sendOrder(keyPair2.getSecretKey(), 1, order); // root index 1 + assertThat(extMessageInfo.getError().getCode()).isZero(); + contract.waitForBalanceChange(30); + + queryState = contract.getQueryState(queryId); + log.info( + "get_query_state (query {}): status {}, mask {}", + queryId, + queryState.getLeft(), + queryState.getRight()); + assertThat(queryState.getLeft()).isEqualTo(-1); + } + + @Test + public void testMultiSigPendingQueries() throws InterruptedException { + log.info("pubKey0 {}", Utils.bytesToHex(ownerKeyPair.getPublicKey())); + log.info("pubKey2 {}", Utils.bytesToHex(keyPair2.getPublicKey())); + log.info("pubKey3 {}", Utils.bytesToHex(keyPair3.getPublicKey())); + log.info("pubKey4 {}", Utils.bytesToHex(keyPair4.getPublicKey())); + log.info("pubKey5 {}", Utils.bytesToHex(keyPair5.getPublicKey())); + + BigInteger queryId1 = BigInteger.valueOf(Instant.now().getEpochSecond() + 5 * 60L << 32); + BigInteger queryId2 = + BigInteger.valueOf((long) Math.pow(Instant.now().getEpochSecond() + 10 * 60L, 32) - 5); + + Long walletId = new Random().nextLong() & 0xffffffffL; + log.info("queryId-1 {}, walletId {}", queryId1.toString(10), walletId); + log.info("queryId-2 {}, walletId {}", queryId2.toString(10), walletId); + + int rootIndex = 0; + int pubkey3Index = 2; + int k = 3; + int n = 5; + + Cell msg1 = + MultiSigWallet.createOneInternalMsg( + Address.of("EQAaGHUHfkpWFGs428ETmym4vbvRNxCA1o4sTkwqigKjgf-_"), Utils.toNano(0.3), 3); + Cell order1 = MultiSigWallet.createOrder(walletId, queryId1, msg1); + + Cell msg2 = + MultiSigWallet.createOneInternalMsg( + Address.of("EQDUna0j-TKlMU9pOBBHNoLzpwlewHl7S1qXtnaYdTTs_Ict"), Utils.toNano(0.4), 3); + + MultiSigWallet contract = + MultiSigWallet.builder() + .tonlib(tonlib) + .keyPair(ownerKeyPair) + .walletId(walletId) + .config( + MultiSigConfig.builder() + .queryId(queryId1) + .k(k) + .n(n) + .rootI(rootIndex) + .owners( + Arrays.asList( + OwnerInfo.builder() + .publicKey(ownerKeyPair.getPublicKey()) + .flood(1) .build(), - MultisigSignature.builder() - .pubKeyPosition(pubkey5Index) - .signature(orderSignatureUser5) - .build() - ), order); - - cnt_mask = contract.checkQuerySignatures(tonlib, query); - log.info("cnt {}, mask {}", cnt_mask.getLeft(), cnt_mask.getRight()); - } - - @Test - public void testGetInitState() throws InterruptedException { - - log.info("pubKey0 {}", Utils.bytesToHex(ownerKeyPair.getPublicKey())); - log.info("pubKey1 {}", Utils.bytesToHex(keyPair2.getPublicKey())); - - BigInteger queryId = BigInteger.valueOf(Instant.now().getEpochSecond() + 5 * 60L << 32); - - Long walletId = new Random().nextLong() & 0xffffffffL; - log.info("queryId {}, walletId {}", queryId.toString(10), walletId); - - int k = 1; - int n = 2; - - MultiSigWallet contract = MultiSigWallet.builder() - .tonlib(tonlib) - .keyPair(ownerKeyPair) - .walletId(walletId) - .config(MultiSigConfig.builder() - .queryId(queryId) - .k(k) - .n(n) - .rootI(0) - .owners(Arrays.asList( - OwnerInfo.builder() - .publicKey(ownerKeyPair.getPublicKey()) - .flood(1) - .build(), - OwnerInfo.builder() - .publicKey(keyPair2.getPublicKey()) - .flood(2) - .build())) - .build()) - .build(); - - String nonBounceableAddress = contract.getAddress().toNonBounceable(); - String bounceableAddress = contract.getAddress().toBounceable(); - - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); - Utils.sleep(30, "topping up..."); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - - ExtMessageInfo extMessageInfo = contract.deploy(); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForDeployment(45); // with empty ext msg - - List ownersPublicKeys = Arrays.asList( - OwnerInfo.builder() - .publicKey(ownerKeyPair.getPublicKey()) - .flood(0) - .build(), - OwnerInfo.builder() - .publicKey(keyPair2.getPublicKey()) - .flood(1) - .build() - ); - - Cell stateInit = contract.getInitState(walletId, n, k, contract.createOwnersInfoDict(ownersPublicKeys)); - log.info("state-init {}", stateInit.toHex(false)); - } - - /** - * Test different root index and multiple orders. Consensus gets calculated on-chain. - */ - @Test - public void testRootIAndMultipleOrdersOnChain() throws InterruptedException { - log.info("pubKey0 {}", Utils.bytesToHex(ownerKeyPair.getPublicKey())); - log.info("pubKey1 {}", Utils.bytesToHex(keyPair2.getPublicKey())); - log.info("pubKey2 {}", Utils.bytesToHex(keyPair3.getPublicKey())); - - BigInteger queryId1 = BigInteger.valueOf((long) Math.pow(Instant.now().getEpochSecond() + 10 * 60L, 32)); - BigInteger queryId2 = BigInteger.valueOf((long) Math.pow(Instant.now().getEpochSecond() + 10 * 60L, 32) - 5); - - Long walletId = new Random().nextLong() & 0xffffffffL; - log.info("queryId-1 {}, walletId {}", queryId1.toString(10), walletId); - log.info("queryId-2 {}, walletId {}", queryId2.toString(10), walletId); - - int k = 2; - int n = 3; - - MultiSigWallet contract = MultiSigWallet.builder() - .tonlib(tonlib) - .keyPair(ownerKeyPair) - .walletId(walletId) - .config(MultiSigConfig.builder() - .queryId(queryId1) - .k(k) - .n(n) - .rootI(2) // initial root index - .owners(Arrays.asList( - OwnerInfo.builder() - .publicKey(ownerKeyPair.getPublicKey()) - .flood(1) - .build(), - OwnerInfo.builder() - .publicKey(keyPair2.getPublicKey()) - .flood(2) - .build(), - OwnerInfo.builder() - .publicKey(keyPair3.getPublicKey()) - .flood(3) - .build())) - .build()) - .build(); - - String nonBounceableAddress = contract.getAddress().toNonBounceable(); - String bounceableAddress = contract.getAddress().toBounceable(); - - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(5)); - Utils.sleep(30, "topping up..."); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - - - ExtMessageInfo extMessageInfo = contract.deploy(); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForDeployment(45); // with empty ext msg - - log.info("owners publicKeysHex {}", contract.getPublicKeysHex()); - - Pair n_k = contract.getNandK(); - log.info("n {}, k {}", n_k.getLeft(), n_k.getRight()); - - Cell txMsg1 = MultiSigWallet.createOneInternalMsg(Address.of("EQAaGHUHfkpWFGs428ETmym4vbvRNxCA1o4sTkwqigKjgf-_"), Utils.toNano(0.5), 3); - Cell order1 = MultiSigWallet.createOrder(walletId, queryId1, txMsg1); - byte[] order1Signature3 = MultiSigWallet.signCell(keyPair3, order1); - - // send order-1 signed by 3rd owner (root index 2) - extMessageInfo = contract.sendOrder(keyPair3, 2, order1); // root index 2 - assertThat(extMessageInfo.getError().getCode()).isZero(); - contract.waitForBalanceChange(30); - - Pair queryState = contract.getQueryState(queryId1); - log.info("get_query_state (query {}): status {}, mask {}", queryId1.toString(10), queryState.getLeft(), queryState.getRight()); - - Cell msg2 = MultiSigWallet.createOneInternalMsg(Address.of("EQCAy2ue54I-uDvEgD3qXdqjtrJI4F4OeFn3V10Kgt0jXpQn"), Utils.toNano(0.8), 3); - Cell order2 = MultiSigWallet.createOrder(walletId, queryId2, msg2); - - // send order-2 signed by 2nd owner (root index 1) - extMessageInfo = contract.sendOrder(keyPair2, 1, order2); - assertThat(extMessageInfo.getError().getCode()).isZero(); - contract.waitForBalanceChange(30); - - queryState = contract.getQueryState(queryId2); - log.info("get_query_state (query {}): status {}, mask {}", queryId2, queryState.getLeft(), queryState.getRight()); - - // send order-2 signed by 3rd owner (root index 2) - extMessageInfo = contract.sendOrder(keyPair3, 2, order2); - assertThat(extMessageInfo.getError().getCode()).isZero(); - contract.waitForBalanceChange(30); - - queryState = contract.getQueryState(queryId2); - log.info("get_query_state (query {}): status {}, mask {}", queryId2, queryState.getLeft(), queryState.getRight()); - assertThat(queryState.getLeft()).isEqualTo(-1); - } - - /** - * Each owner sends the extmsg signed by him, containing the order. Consensus gets calculated on-chain. - */ - @Test - public void testEmptySignaturesListOnChain() throws InterruptedException { - - log.info("pubKey0 {}", Utils.bytesToHex(ownerKeyPair.getPublicKey())); - log.info("pubKey1 {}", Utils.bytesToHex(keyPair2.getPublicKey())); - log.info("pubKey2 {}", Utils.bytesToHex(keyPair3.getPublicKey())); - - BigInteger queryId = BigInteger.valueOf((long) Math.pow(Instant.now().getEpochSecond() + 10 * 60L, 32)); - - Long walletId = new Random().nextLong() & 0xffffffffL; - log.info("queryId-1 {}, walletId {}", queryId.toString(10), walletId); - - int k = 2; - int n = 3; - - MultiSigWallet contract = MultiSigWallet.builder() - .tonlib(tonlib) - .keyPair(ownerKeyPair) - .walletId(walletId) - .config(MultiSigConfig.builder() - .queryId(queryId) - .k(k) - .n(n) - .rootI(0) // initial root index - .owners(Arrays.asList( - OwnerInfo.builder() - .publicKey(ownerKeyPair.getPublicKey()) - .flood(1) - .build(), - OwnerInfo.builder() - .publicKey(keyPair2.getPublicKey()) - .flood(2) - .build())) - .build()) - .build(); - - String nonBounceableAddress = contract.getAddress().toNonBounceable(); - String bounceableAddress = contract.getAddress().toBounceable(); - - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); - Utils.sleep(30, "topping up..."); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - - ExtMessageInfo extMessageInfo = contract.deploy(); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForDeployment(45); // with empty ext msg - - log.info("owners publicKeysHex {}", contract.getPublicKeysHex()); - - Pair n_k = contract.getNandK(); - log.info("n {}, k {}", n_k.getLeft(), n_k.getRight()); - - Cell txMsg1 = MultiSigWallet.createOneInternalMsg(Address.of("EQAaGHUHfkpWFGs428ETmym4vbvRNxCA1o4sTkwqigKjgf-_"), Utils.toNano(0.5), 3); - Cell order = MultiSigWallet.createOrder(walletId, queryId, txMsg1); - - // send order-1 signed by 1st owner (root index 0) - extMessageInfo = contract.sendOrder(ownerKeyPair.getSecretKey(), 0, order); // root index 0 - assertThat(extMessageInfo.getError().getCode()).isZero(); - contract.waitForBalanceChange(30); - - showMessagesInfo(contract.getMessagesUnsignedByIndex(0), "MessagesUnsignedByIndex-" + 0); - showMessagesInfo(contract.getMessagesSignedByIndex(0), "MessagesSignedByIndex-" + 0); - - Pair queryState = contract.getQueryState(queryId); - log.info("get_query_state (query {}): status {}, mask {}", queryId, queryState.getLeft(), queryState.getRight()); - - // send order-1 signed by 2nd owner (root index 1) - extMessageInfo = contract.sendOrder(keyPair2.getSecretKey(), 1, order); // root index 1 - assertThat(extMessageInfo.getError().getCode()).isZero(); - contract.waitForBalanceChange(30); - - queryState = contract.getQueryState(queryId); - log.info("get_query_state (query {}): status {}, mask {}", queryId, queryState.getLeft(), queryState.getRight()); - assertThat(queryState.getLeft()).isEqualTo(-1); - } - - @Test - public void testMultiSigPendingQueries() throws InterruptedException { - log.info("pubKey0 {}", Utils.bytesToHex(ownerKeyPair.getPublicKey())); - log.info("pubKey2 {}", Utils.bytesToHex(keyPair2.getPublicKey())); - log.info("pubKey3 {}", Utils.bytesToHex(keyPair3.getPublicKey())); - log.info("pubKey4 {}", Utils.bytesToHex(keyPair4.getPublicKey())); - log.info("pubKey5 {}", Utils.bytesToHex(keyPair5.getPublicKey())); - - BigInteger queryId1 = BigInteger.valueOf(Instant.now().getEpochSecond() + 5 * 60L << 32); - BigInteger queryId2 = BigInteger.valueOf((long) Math.pow(Instant.now().getEpochSecond() + 10 * 60L, 32) - 5); - - Long walletId = new Random().nextLong() & 0xffffffffL; - log.info("queryId-1 {}, walletId {}", queryId1.toString(10), walletId); - log.info("queryId-2 {}, walletId {}", queryId2.toString(10), walletId); - - int rootIndex = 0; - int pubkey3Index = 2; - int k = 3; - int n = 5; - - Cell msg1 = MultiSigWallet.createOneInternalMsg(Address.of("EQAaGHUHfkpWFGs428ETmym4vbvRNxCA1o4sTkwqigKjgf-_"), Utils.toNano(0.3), 3); - Cell order1 = MultiSigWallet.createOrder(walletId, queryId1, msg1); - - Cell msg2 = MultiSigWallet.createOneInternalMsg(Address.of("EQDUna0j-TKlMU9pOBBHNoLzpwlewHl7S1qXtnaYdTTs_Ict"), Utils.toNano(0.4), 3); - - MultiSigWallet contract = MultiSigWallet.builder() - .tonlib(tonlib) - .keyPair(ownerKeyPair) - .walletId(walletId) - .config(MultiSigConfig.builder() - .queryId(queryId1) - .k(k) - .n(n) - .rootI(rootIndex) - .owners(Arrays.asList( - OwnerInfo.builder() - .publicKey(ownerKeyPair.getPublicKey()) - .flood(1) - .build(), - OwnerInfo.builder() - .publicKey(keyPair2.getPublicKey()) - .flood(2) - .build(), - OwnerInfo.builder() - .publicKey(keyPair3.getPublicKey()) - .flood(3) - .build(), - OwnerInfo.builder() - .publicKey(keyPair4.getPublicKey()) - .flood(4) - .build(), - OwnerInfo.builder() - .publicKey(keyPair5.getPublicKey()) - .flood(5) - .build())) - .pendingQueries(Arrays.asList( - PendingQuery.builder() - .queryId(queryId1) - .creatorI(rootIndex) - .cnt(2) // number of confirmation - .cntBits(3) // bit mask of confirmed pubkeys - .msg(msg1) - .build(), - PendingQuery.builder() - .queryId(queryId2) - .creatorI(rootIndex) - .cnt(1) - .cntBits(1) - .msg(msg2) - .build())) - .build()) - .build(); - - - String nonBounceableAddress = contract.getAddress().toNonBounceable(); - String bounceableAddress = contract.getAddress().toBounceable(); - - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); - Utils.sleep(30, "topping up..."); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - - ExtMessageInfo extMessageInfo = contract.deploy(); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForDeployment(45); // with empty ext msg - - log.info("owners publicKeysHex {}", contract.getPublicKeysHex()); - - Pair queryState = contract.getQueryState(queryId1); - log.info("get_query_state (query-1 {}): status {}, mask {}", queryId1, queryState.getLeft(), queryState.getRight()); - - queryState = contract.getQueryState(queryId2); - log.info("get_query_state (query-2 {}): status {}, mask {}", queryId2, queryState.getLeft(), queryState.getRight()); - - - showMessagesInfo(contract.getMessagesUnsigned(), "Messages-Unsigned"); - showMessagesInfo(contract.getMessagesSignedByIndex(rootIndex), "Messages-SignedByIndex-" + rootIndex); - showMessagesInfo(contract.getMessagesUnsignedByIndex(rootIndex), "Messages-UnsignedByIndex-" + rootIndex); - - extMessageInfo = contract.sendOrder(keyPair3.getSecretKey(), pubkey3Index, order1); - assertThat(extMessageInfo.getError().getCode()).isZero(); -// Utils.sleep(30, "processing query"); - contract.waitForBalanceChange(30); - - queryState = contract.getQueryState(queryId1); - log.info("get_query_state (query-1 {}): status {}, mask {}", queryId1, queryState.getLeft(), queryState.getRight()); - - assertThat(queryState.getLeft()).isEqualTo(-1); - - showMessagesInfo(contract.getMessagesUnsigned(), "Messages-Unsigned"); - showMessagesInfo(contract.getMessagesSignedByIndex(rootIndex), "Messages-SignedByIndex-" + rootIndex); - } - - @Test - public void testMergePendingQueries() throws InterruptedException { - log.info("pubKey0 {}", Utils.bytesToHex(ownerKeyPair.getPublicKey())); - log.info("pubKey1 {}", Utils.bytesToHex(keyPair2.getPublicKey())); - log.info("pubKey2 {}", Utils.bytesToHex(keyPair3.getPublicKey())); - - BigInteger queryId1 = BigInteger.valueOf((long) Math.pow(Instant.now().getEpochSecond() + 10 * 60L, 32)); - BigInteger queryId2 = BigInteger.valueOf((long) Math.pow(Instant.now().getEpochSecond() + 10 * 60L, 32) - 5); - - Long walletId = new Random().nextLong() & 0xffffffffL; - log.info("queryId-1 {}, walletId {}", queryId1.toString(10), walletId); - - int k = 2; - int n = 3; - - Cell msg1 = MultiSigWallet.createOneInternalMsg(Address.of("EQAaGHUHfkpWFGs428ETmym4vbvRNxCA1o4sTkwqigKjgf-_"), Utils.toNano(0.3), 3); - Cell msg2 = MultiSigWallet.createOneInternalMsg(Address.of("EQDUna0j-TKlMU9pOBBHNoLzpwlewHl7S1qXtnaYdTTs_Ict"), Utils.toNano(0.4), 3); - - MultiSigWallet contract = MultiSigWallet.builder() - .tonlib(tonlib) - .keyPair(ownerKeyPair) - .walletId(walletId) - .config(MultiSigConfig.builder() - .queryId(queryId1) - .k(k) - .n(n) - .rootI(0) // initial root index - .owners(Arrays.asList( - OwnerInfo.builder() - .publicKey(ownerKeyPair.getPublicKey()) - .flood(1) - .build(), - OwnerInfo.builder() - .publicKey(keyPair2.getPublicKey()) - .flood(2) - .build())) - .build()) - .build(); - - String nonBounceableAddress = contract.getAddress().toNonBounceable(); - String bounceableAddress = contract.getAddress().toBounceable(); - - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); - Utils.sleep(30, "topping up..."); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - - ExtMessageInfo extMessageInfo = contract.deploy(); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForDeployment(45); // with empty ext msg - - log.info("owners publicKeysHex {}", contract.getPublicKeysHex()); - Cell dict1 = MultiSigWallet.createPendingQueries( - Arrays.asList( - PendingQuery.builder() + OwnerInfo.builder().publicKey(keyPair2.getPublicKey()).flood(2).build(), + OwnerInfo.builder().publicKey(keyPair3.getPublicKey()).flood(3).build(), + OwnerInfo.builder().publicKey(keyPair4.getPublicKey()).flood(4).build(), + OwnerInfo.builder() + .publicKey(keyPair5.getPublicKey()) + .flood(5) + .build())) + .pendingQueries( + Arrays.asList( + PendingQuery.builder() .queryId(queryId1) - .creatorI(0) + .creatorI(rootIndex) .cnt(2) // number of confirmation .cntBits(3) // bit mask of confirmed pubkeys .msg(msg1) .build(), - PendingQuery.builder() + PendingQuery.builder() .queryId(queryId2) - .creatorI(0) - .cnt(2) - .cntBits(3) - .msg(msg1) - .build() - ), n); - - Cell dict2 = MultiSigWallet.createPendingQueries( - Arrays.asList( - PendingQuery.builder() - .queryId(queryId1) - .creatorI(0) - .cnt(2) - .cntBits(3) - .msg(msg1) - .build(), - PendingQuery.builder() - .queryId(queryId2) - .creatorI(0) - .cnt(2) - .cntBits(3) - .msg(msg1) - .build() - ), n); - - log.info("pendingQueriesToMerge1 {}", dict1.toHex(false)); - log.info("pendingQueriesToMerge2 {}", dict2.toHex(false)); - log.info("pendingQueriesToMerge1-hash {}", Utils.bytesToHex(dict1.getHash())); - log.info("pendingQueriesToMerge2-hash {}", Utils.bytesToHex(dict2.getHash())); - - Cell mergeDict = contract.mergePendingQueries(tonlib, dict1, dict2); - log.info("merged dict {}", mergeDict); - assertThat(mergeDict).isNotNull(); - } - - private void showMessagesInfo(Map messages, String label) { - if (messages.isEmpty()) { - log.info("{} result is empty", label); - } - for (Map.Entry entry : messages.entrySet()) { - BigInteger query_id = entry.getKey(); - Cell query = entry.getValue(); - - log.info("{} query-id {}, msg {}", label, query_id, query); - } - } - - @Test - public void testCellSerialization5() { - - CellBuilder cell = CellBuilder.beginCell(); - - cell.storeUint(42, 32); - cell.storeUint(5, 8); - cell.storeUint(3, 8); - cell.storeUint(0, 64); - cell.storeDict(createOwnersInfoDict(Arrays.asList( - OwnerInfo.builder() + .creatorI(rootIndex) + .cnt(1) + .cntBits(1) + .msg(msg2) + .build())) + .build()) + .build(); + + String nonBounceableAddress = contract.getAddress().toNonBounceable(); + String bounceableAddress = contract.getAddress().toBounceable(); + + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); + Utils.sleep(30, "topping up..."); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + + ExtMessageInfo extMessageInfo = contract.deploy(); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForDeployment(45); // with empty ext msg + + log.info("owners publicKeysHex {}", contract.getPublicKeysHex()); + + Pair queryState = contract.getQueryState(queryId1); + log.info( + "get_query_state (query-1 {}): status {}, mask {}", + queryId1, + queryState.getLeft(), + queryState.getRight()); + + queryState = contract.getQueryState(queryId2); + log.info( + "get_query_state (query-2 {}): status {}, mask {}", + queryId2, + queryState.getLeft(), + queryState.getRight()); + + showMessagesInfo(contract.getMessagesUnsigned(), "Messages-Unsigned"); + showMessagesInfo( + contract.getMessagesSignedByIndex(rootIndex), "Messages-SignedByIndex-" + rootIndex); + showMessagesInfo( + contract.getMessagesUnsignedByIndex(rootIndex), "Messages-UnsignedByIndex-" + rootIndex); + + extMessageInfo = contract.sendOrder(keyPair3.getSecretKey(), pubkey3Index, order1); + assertThat(extMessageInfo.getError().getCode()).isZero(); + // Utils.sleep(30, "processing query"); + contract.waitForBalanceChange(30); + + queryState = contract.getQueryState(queryId1); + log.info( + "get_query_state (query-1 {}): status {}, mask {}", + queryId1, + queryState.getLeft(), + queryState.getRight()); + + assertThat(queryState.getLeft()).isEqualTo(-1); + + showMessagesInfo(contract.getMessagesUnsigned(), "Messages-Unsigned"); + showMessagesInfo( + contract.getMessagesSignedByIndex(rootIndex), "Messages-SignedByIndex-" + rootIndex); + } + + @Test + public void testMergePendingQueries() throws InterruptedException { + log.info("pubKey0 {}", Utils.bytesToHex(ownerKeyPair.getPublicKey())); + log.info("pubKey1 {}", Utils.bytesToHex(keyPair2.getPublicKey())); + log.info("pubKey2 {}", Utils.bytesToHex(keyPair3.getPublicKey())); + + BigInteger queryId1 = + BigInteger.valueOf((long) Math.pow(Instant.now().getEpochSecond() + 10 * 60L, 32)); + BigInteger queryId2 = + BigInteger.valueOf((long) Math.pow(Instant.now().getEpochSecond() + 10 * 60L, 32) - 5); + + Long walletId = new Random().nextLong() & 0xffffffffL; + log.info("queryId-1 {}, walletId {}", queryId1.toString(10), walletId); + + int k = 2; + int n = 3; + + Cell msg1 = + MultiSigWallet.createOneInternalMsg( + Address.of("EQAaGHUHfkpWFGs428ETmym4vbvRNxCA1o4sTkwqigKjgf-_"), Utils.toNano(0.3), 3); + Cell msg2 = + MultiSigWallet.createOneInternalMsg( + Address.of("EQDUna0j-TKlMU9pOBBHNoLzpwlewHl7S1qXtnaYdTTs_Ict"), Utils.toNano(0.4), 3); + + MultiSigWallet contract = + MultiSigWallet.builder() + .tonlib(tonlib) + .keyPair(ownerKeyPair) + .walletId(walletId) + .config( + MultiSigConfig.builder() + .queryId(queryId1) + .k(k) + .n(n) + .rootI(0) // initial root index + .owners( + Arrays.asList( + OwnerInfo.builder() .publicKey(ownerKeyPair.getPublicKey()) .flood(1) .build(), - OwnerInfo.builder() + OwnerInfo.builder() .publicKey(keyPair2.getPublicKey()) .flood(2) - .build(), - OwnerInfo.builder() - .publicKey(keyPair3.getPublicKey()) - .flood(3) - .build(), - OwnerInfo.builder() - .publicKey(keyPair4.getPublicKey()) - .flood(4) - .build(), - OwnerInfo.builder() - .publicKey(keyPair5.getPublicKey()) - .flood(5) - .build() - ) - )); - cell.storeBit(false); // initial pending queries dict - - System.out.println("print cell: " + cell.endCell().print()); - - String bocHexWithCrc = cell.endCell().toHex(); - System.out.println("print (bocHexWithCrc): " + bocHexWithCrc); - - Cell c = Cell.fromBoc(bocHexWithCrc); - System.out.println("print c: \n" + c.print()); + .build())) + .build()) + .build(); + + String nonBounceableAddress = contract.getAddress().toNonBounceable(); + String bounceableAddress = contract.getAddress().toBounceable(); + + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); + Utils.sleep(30, "topping up..."); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + + ExtMessageInfo extMessageInfo = contract.deploy(); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForDeployment(45); // with empty ext msg + + log.info("owners publicKeysHex {}", contract.getPublicKeysHex()); + Cell dict1 = + MultiSigWallet.createPendingQueries( + Arrays.asList( + PendingQuery.builder() + .queryId(queryId1) + .creatorI(0) + .cnt(2) // number of confirmation + .cntBits(3) // bit mask of confirmed pubkeys + .msg(msg1) + .build(), + PendingQuery.builder() + .queryId(queryId2) + .creatorI(0) + .cnt(2) + .cntBits(3) + .msg(msg1) + .build()), + n); + + Cell dict2 = + MultiSigWallet.createPendingQueries( + Arrays.asList( + PendingQuery.builder() + .queryId(queryId1) + .creatorI(0) + .cnt(2) + .cntBits(3) + .msg(msg1) + .build(), + PendingQuery.builder() + .queryId(queryId2) + .creatorI(0) + .cnt(2) + .cntBits(3) + .msg(msg1) + .build()), + n); + + log.info("pendingQueriesToMerge1 {}", dict1.toHex(false)); + log.info("pendingQueriesToMerge2 {}", dict2.toHex(false)); + log.info("pendingQueriesToMerge1-hash {}", Utils.bytesToHex(dict1.getHash())); + log.info("pendingQueriesToMerge2-hash {}", Utils.bytesToHex(dict2.getHash())); + + Cell mergeDict = contract.mergePendingQueries(tonlib, dict1, dict2); + log.info("merged dict {}", mergeDict); + assertThat(mergeDict).isNotNull(); + } + + private void showMessagesInfo(Map messages, String label) { + if (messages.isEmpty()) { + log.info("{} result is empty", label); } + for (Map.Entry entry : messages.entrySet()) { + BigInteger query_id = entry.getKey(); + Cell query = entry.getValue(); - private Cell createOwnersInfoDict(List testOwnerInfos) { - int dictKeySize = 8; - TonHashMapE dictDestinations = new TonHashMapE(dictKeySize); - - long i = 0; // key, index 16bit - for (OwnerInfo testOwnerInfo : testOwnerInfos) { - - CellBuilder ownerInfoCell = CellBuilder.beginCell(); - ownerInfoCell.storeBytes(testOwnerInfo.getPublicKey()); //256 bits - ownerInfoCell.storeUint(testOwnerInfo.getFlood(), 8); - - dictDestinations.elements.put( - i++, // key - index - ownerInfoCell.endCell() // value - cell - OwnerInfo - ); - } + log.info("{} query-id {}, msg {}", label, query_id, query); + } + } + + @Test + public void testCellSerialization5() { + + CellBuilder cell = CellBuilder.beginCell(); + + cell.storeUint(42, 32); + cell.storeUint(5, 8); + cell.storeUint(3, 8); + cell.storeUint(0, 64); + cell.storeDict( + createOwnersInfoDict( + Arrays.asList( + OwnerInfo.builder().publicKey(ownerKeyPair.getPublicKey()).flood(1).build(), + OwnerInfo.builder().publicKey(keyPair2.getPublicKey()).flood(2).build(), + OwnerInfo.builder().publicKey(keyPair3.getPublicKey()).flood(3).build(), + OwnerInfo.builder().publicKey(keyPair4.getPublicKey()).flood(4).build(), + OwnerInfo.builder().publicKey(keyPair5.getPublicKey()).flood(5).build()))); + cell.storeBit(false); // initial pending queries dict + + System.out.println("print cell: " + cell.endCell().print()); + + String bocHexWithCrc = cell.endCell().toHex(); + System.out.println("print (bocHexWithCrc): " + bocHexWithCrc); + + Cell c = Cell.fromBoc(bocHexWithCrc); + System.out.println("print c: \n" + c.print()); + } + + private Cell createOwnersInfoDict(List testOwnerInfos) { + int dictKeySize = 8; + TonHashMapE dictDestinations = new TonHashMapE(dictKeySize); + + long i = 0; // key, index 16bit + for (OwnerInfo testOwnerInfo : testOwnerInfos) { + + CellBuilder ownerInfoCell = CellBuilder.beginCell(); + ownerInfoCell.storeBytes(testOwnerInfo.getPublicKey()); // 256 bits + ownerInfoCell.storeUint(testOwnerInfo.getFlood(), 8); + + dictDestinations.elements.put( + i++, // key - index + ownerInfoCell.endCell() // value - cell - OwnerInfo + ); + } - Cell cellDict = dictDestinations.serialize( - k -> CellBuilder.beginCell().storeUint((Long) k, dictKeySize).endCell().getBits(), - v -> (Cell) v - ); + Cell cellDict = + dictDestinations.serialize( + k -> CellBuilder.beginCell().storeUint((Long) k, dictKeySize).endCell().getBits(), + v -> (Cell) v); - return cellDict; - } + return cellDict; + } } diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV1R1.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV1R1.java index 4a2af958..75a3d62a 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV1R1.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV1R1.java @@ -1,22 +1,21 @@ package org.ton.java.smartcontract.integrationtests; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + import com.iwebpp.crypto.TweetNaclFast; +import java.math.BigInteger; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.ton.java.address.Address; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.types.WalletV1R1Config; import org.ton.java.smartcontract.wallet.v1.WalletV1R1; import org.ton.java.tonlib.types.ExtMessageInfo; import org.ton.java.tonlib.types.RawAccountState; import org.ton.java.utils.Utils; -import java.math.BigInteger; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; - @Slf4j @RunWith(JUnit4.class) public class TestWalletV1R1 extends CommonTest { @@ -33,7 +32,7 @@ public void testNewWalletV1R1AutoKeyPair() throws InterruptedException { log.info("Wallet address {}", walletAddress); // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, walletAddress, Utils.toNano(0.1)); + BigInteger balance = TestnetFaucet.topUpContract(tonlib, walletAddress, Utils.toNano(0.1)); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); ExtMessageInfo extMessageInfo = contract.deploy(); @@ -47,7 +46,7 @@ public void testNewWalletV1R1AutoKeyPair() throws InterruptedException { WalletV1R1Config config = WalletV1R1Config.builder() .seqno(1) // V1R1 does not have get_seqno method - .destination(Address.of(TestFaucet.BOUNCEABLE)) + .destination(Address.of(TestnetFaucet.BOUNCEABLE)) .amount(Utils.toNano(0.08)) .comment("testNewWalletV1R1") .build(); @@ -74,7 +73,7 @@ public void testNewWalletV1R1() throws InterruptedException { // top up new wallet using test-faucet-wallet BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); ExtMessageInfo extMessageInfo = contract.deploy(); @@ -87,7 +86,7 @@ public void testNewWalletV1R1() throws InterruptedException { WalletV1R1Config config = WalletV1R1Config.builder() .seqno(1) - .destination(Address.of(TestFaucet.BOUNCEABLE)) + .destination(Address.of(TestnetFaucet.BOUNCEABLE)) .amount(Utils.toNano(0.08)) .comment("testNewWalletV1R1") .build(); diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV1R2.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV1R2.java index 40e11bf0..7da8f43e 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV1R2.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV1R2.java @@ -1,20 +1,19 @@ package org.ton.java.smartcontract.integrationtests; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import java.math.BigInteger; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.ton.java.address.Address; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.types.WalletV1R2Config; import org.ton.java.smartcontract.wallet.v1.WalletV1R2; import org.ton.java.tonlib.types.ExtMessageInfo; import org.ton.java.utils.Utils; -import java.math.BigInteger; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; - @Slf4j @RunWith(JUnit4.class) public class TestWalletV1R2 extends CommonTest { @@ -33,7 +32,7 @@ public void testNewWalletV1R2() throws InterruptedException { // top up new wallet using test-faucet-wallet BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); log.info("wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); ExtMessageInfo extMessageInfo = contract.deploy(); @@ -46,7 +45,7 @@ public void testNewWalletV1R2() throws InterruptedException { WalletV1R2Config config = WalletV1R2Config.builder() .seqno(contract.getSeqno()) - .destination(Address.of(TestFaucet.BOUNCEABLE)) + .destination(Address.of(TestnetFaucet.BOUNCEABLE)) .amount(Utils.toNano(0.08)) .comment("testNewWalletV1R2") .build(); diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV1R3.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV1R3.java index f8fd4f89..890aad97 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV1R3.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV1R3.java @@ -16,7 +16,7 @@ import org.ton.java.cell.CellBuilder; import org.ton.java.mnemonic.Mnemonic; import org.ton.java.mnemonic.Pair; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.types.WalletV1R3Config; import org.ton.java.smartcontract.utils.MsgUtils; import org.ton.java.smartcontract.wallet.v1.WalletV1R3; @@ -29,174 +29,176 @@ @RunWith(JUnit4.class) public class TestWalletV1R3 extends CommonTest { - @Test - public void testWalletV1R3() throws InterruptedException { - TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); - - WalletV1R3 contract = WalletV1R3.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .build(); - - Cell deployMessage = CellBuilder.beginCell().storeUint(BigInteger.ZERO, 32).endCell(); - Message msg = MsgUtils.createExternalMessageWithSignedBody(keyPair, contract.getAddress(), - contract.getStateInit(), deployMessage); - Address address = msg.getInit().getAddress(); - - String nonBounceableAddress = address.toNonBounceable(); - String bounceableAddress = address.toBounceable(); - - String my = "Creating new wallet in workchain " + contract.getWc() + "\n"; - my = my + "Loading private key from file new-wallet.pk" + "\n"; - my = my + "StateInit: " + msg.getInit().toCell().print() + "\n"; - my = my + "new wallet address = " + address.toString(false) + "\n"; - my = my + "(Saving address to file new-wallet.addr)" + "\n"; - my = my + "Non-bounceable address (for init): " + nonBounceableAddress + "\n"; - my = my + "Bounceable address (for later access): " + bounceableAddress + "\n"; - my = my + "signing message: " + msg.getBody().print() + "\n"; - my = my + "External message for initialization is " + msg.toCell().print() + "\n"; - my = my + Utils.bytesToHex(msg.toCell().toBoc()).toUpperCase() + "\n"; - my = my + "(Saved wallet creating query to file new-wallet-query.boc)" + "\n"; - log.info(my); - - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - - // deploy new wallet - ExtMessageInfo extMessageInfo = tonlib.sendRawMessage(msg.toCell().toBase64()); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForDeployment(20); - - WalletV1R3Config config = WalletV1R3Config.builder() - .seqno(contract.getSeqno()) - .destination(Address.of(TestFaucet.BOUNCEABLE)) - .amount(Utils.toNano(0.08)) - .comment("testNewWalletV1R3") - .build(); - - // transfer coins from new wallet (back to faucet) - extMessageInfo = contract.send(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForBalanceChange(30); - - balance = new BigInteger(tonlib.getAccountState(address).getBalance()); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - assertThat(balance.longValue()).isLessThan(Utils.toNano(0.02).longValue()); - - log.info("seqno {}", contract.getSeqno()); - log.info("pubkey {}", contract.getPublicKey()); - } - - @Test - public void testWalletV1R3WithMnemonic() throws InterruptedException, NoSuchAlgorithmException, InvalidKeyException { - List mnemonic = Mnemonic.generate(24); - Pair keyPair = Mnemonic.toKeyPair(mnemonic); - - log.info("pubkey " + Utils.bytesToHex(keyPair.getPublicKey())); - log.info("seckey " + Utils.bytesToHex(keyPair.getSecretKey())); - - TweetNaclFast.Signature.KeyPair keyPairSig = TweetNaclFast.Signature.keyPair_fromSeed(keyPair.getSecretKey()); - - log.info("pubkey " + Utils.bytesToHex(keyPairSig.getPublicKey())); - log.info("seckey " + Utils.bytesToHex(keyPairSig.getSecretKey())); - - WalletV1R3 contract = WalletV1R3.builder() - .tonlib(tonlib) - .keyPair(keyPairSig) - .build(); - - Message msg = MsgUtils.createExternalMessageWithSignedBody(keyPairSig, contract.getAddress(), - contract.getStateInit(), - CellBuilder.beginCell().storeUint(BigInteger.ZERO, 32).endCell()); - Address address = msg.getInit().getAddress(); - - String nonBounceableAddress = address.toBounceable(); - String bounceableAddress = address.toNonBounceable(); - - String my = "Creating new wallet in workchain " + contract.getWc() + "\n"; - my = my + "Loading private key from file new-wallet.pk" + "\n"; - my = my + "StateInit: " + msg.getInit().toCell().print() + "\n"; - my = my + "new wallet address = " + address.toString(false) + "\n"; - my = my + "(Saving address to file new-wallet.addr)" + "\n"; - my = my + "Non-bounceable address (for init): " + nonBounceableAddress + "\n"; - my = my + "Bounceable address (for later access): " + bounceableAddress + "\n"; - my = my + "signing message: " + msg.getBody().print() + "\n"; - my = my + "External message for initialization is " + msg.toCell().print() + "\n"; - my = my + Utils.bytesToHex(msg.toCell().toBoc()).toUpperCase() + "\n"; - my = my + "(Saved wallet creating query to file new-wallet-query.boc)" + "\n"; - log.info(my); - - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - - // deploy new wallet - ExtMessageInfo extMessageInfo = tonlib.sendRawMessage(msg.toCell().toBase64()); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForDeployment(30); - - WalletV1R3Config config = WalletV1R3Config.builder() - .seqno(contract.getSeqno()) - .destination(Address.of(TestFaucet.BOUNCEABLE)) - .amount(Utils.toNano(0.08)) - .comment("testNewWalletV1R3") - .build(); - - // transfer coins from new wallet (back to faucet) - extMessageInfo = contract.send(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForBalanceChange(30); - - balance = new BigInteger(tonlib.getAccountState(address).getBalance()); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - assertThat(balance.longValue()).isLessThan(Utils.toNano(0.02).longValue()); - - log.info("seqno {}", contract.getSeqno()); - log.info("pubkey {}", contract.getPublicKey()); - } - - @Test - public void testWalletV1R3EstimateFees() throws NoSuchAlgorithmException, InvalidKeyException { - List mnemonic = Mnemonic.generate(24); - Pair keyPair = Mnemonic.toKeyPair(mnemonic); - - log.info("pubkey " + Utils.bytesToHex(keyPair.getPublicKey())); - log.info("seckey " + Utils.bytesToHex(keyPair.getSecretKey())); - - TweetNaclFast.Signature.KeyPair keyPairSig = TweetNaclFast.Signature.keyPair_fromSeed(keyPair.getSecretKey()); - - log.info("pubkey " + Utils.bytesToHex(keyPairSig.getPublicKey())); - log.info("seckey " + Utils.bytesToHex(keyPairSig.getSecretKey())); - - WalletV1R3 contract = WalletV1R3.builder() - .keyPair(keyPairSig) - .build(); - - Message msg = MsgUtils.createExternalMessageWithSignedBody(keyPairSig, contract.getAddress(), - contract.getStateInit(), null); - - QueryFees feesWithCodeData = tonlib.estimateFees( - msg.getInit().getAddress().toString(), - msg.getBody().toBase64(), // message to cell not the whole external - msg.getInit().getCode().toBase64(), - msg.getInit().getData().toBase64(), - false); - - log.info("fees {}", feesWithCodeData); - assertThat(feesWithCodeData).isNotNull(); - - QueryFees feesBodyOnly = tonlib.estimateFees( - msg.getInit().getAddress().toString(), - msg.getBody().toBase64(), - null, - null, - false); - log.info("fees {}", feesBodyOnly); - assertThat(feesBodyOnly).isNotNull(); - } + @Test + public void testWalletV1R3() throws InterruptedException { + TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); + + WalletV1R3 contract = WalletV1R3.builder().tonlib(tonlib).keyPair(keyPair).build(); + + Cell deployMessage = CellBuilder.beginCell().storeUint(BigInteger.ZERO, 32).endCell(); + Message msg = + MsgUtils.createExternalMessageWithSignedBody( + keyPair, contract.getAddress(), contract.getStateInit(), deployMessage); + Address address = msg.getInit().getAddress(); + + String nonBounceableAddress = address.toNonBounceable(); + String bounceableAddress = address.toBounceable(); + + String my = "Creating new wallet in workchain " + contract.getWc() + "\n"; + my = my + "Loading private key from file new-wallet.pk" + "\n"; + my = my + "StateInit: " + msg.getInit().toCell().print() + "\n"; + my = my + "new wallet address = " + address.toString(false) + "\n"; + my = my + "(Saving address to file new-wallet.addr)" + "\n"; + my = my + "Non-bounceable address (for init): " + nonBounceableAddress + "\n"; + my = my + "Bounceable address (for later access): " + bounceableAddress + "\n"; + my = my + "signing message: " + msg.getBody().print() + "\n"; + my = my + "External message for initialization is " + msg.toCell().print() + "\n"; + my = my + Utils.bytesToHex(msg.toCell().toBoc()).toUpperCase() + "\n"; + my = my + "(Saved wallet creating query to file new-wallet-query.boc)" + "\n"; + log.info(my); + + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + + // deploy new wallet + ExtMessageInfo extMessageInfo = tonlib.sendRawMessage(msg.toCell().toBase64()); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForDeployment(20); + + WalletV1R3Config config = + WalletV1R3Config.builder() + .seqno(contract.getSeqno()) + .destination(Address.of(TestnetFaucet.BOUNCEABLE)) + .amount(Utils.toNano(0.08)) + .comment("testNewWalletV1R3") + .build(); + + // transfer coins from new wallet (back to faucet) + extMessageInfo = contract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForBalanceChange(30); + + balance = new BigInteger(tonlib.getAccountState(address).getBalance()); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + assertThat(balance.longValue()).isLessThan(Utils.toNano(0.02).longValue()); + + log.info("seqno {}", contract.getSeqno()); + log.info("pubkey {}", contract.getPublicKey()); + } + + @Test + public void testWalletV1R3WithMnemonic() + throws InterruptedException, NoSuchAlgorithmException, InvalidKeyException { + List mnemonic = Mnemonic.generate(24); + Pair keyPair = Mnemonic.toKeyPair(mnemonic); + + log.info("pubkey " + Utils.bytesToHex(keyPair.getPublicKey())); + log.info("seckey " + Utils.bytesToHex(keyPair.getSecretKey())); + + TweetNaclFast.Signature.KeyPair keyPairSig = + TweetNaclFast.Signature.keyPair_fromSeed(keyPair.getSecretKey()); + + log.info("pubkey " + Utils.bytesToHex(keyPairSig.getPublicKey())); + log.info("seckey " + Utils.bytesToHex(keyPairSig.getSecretKey())); + + WalletV1R3 contract = WalletV1R3.builder().tonlib(tonlib).keyPair(keyPairSig).build(); + + Message msg = + MsgUtils.createExternalMessageWithSignedBody( + keyPairSig, + contract.getAddress(), + contract.getStateInit(), + CellBuilder.beginCell().storeUint(BigInteger.ZERO, 32).endCell()); + Address address = msg.getInit().getAddress(); + + String nonBounceableAddress = address.toBounceable(); + String bounceableAddress = address.toNonBounceable(); + + String my = "Creating new wallet in workchain " + contract.getWc() + "\n"; + my = my + "Loading private key from file new-wallet.pk" + "\n"; + my = my + "StateInit: " + msg.getInit().toCell().print() + "\n"; + my = my + "new wallet address = " + address.toString(false) + "\n"; + my = my + "(Saving address to file new-wallet.addr)" + "\n"; + my = my + "Non-bounceable address (for init): " + nonBounceableAddress + "\n"; + my = my + "Bounceable address (for later access): " + bounceableAddress + "\n"; + my = my + "signing message: " + msg.getBody().print() + "\n"; + my = my + "External message for initialization is " + msg.toCell().print() + "\n"; + my = my + Utils.bytesToHex(msg.toCell().toBoc()).toUpperCase() + "\n"; + my = my + "(Saved wallet creating query to file new-wallet-query.boc)" + "\n"; + log.info(my); + + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + + // deploy new wallet + ExtMessageInfo extMessageInfo = tonlib.sendRawMessage(msg.toCell().toBase64()); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForDeployment(30); + + WalletV1R3Config config = + WalletV1R3Config.builder() + .seqno(contract.getSeqno()) + .destination(Address.of(TestnetFaucet.BOUNCEABLE)) + .amount(Utils.toNano(0.08)) + .comment("testNewWalletV1R3") + .build(); + + // transfer coins from new wallet (back to faucet) + extMessageInfo = contract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForBalanceChange(30); + + balance = new BigInteger(tonlib.getAccountState(address).getBalance()); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + assertThat(balance.longValue()).isLessThan(Utils.toNano(0.02).longValue()); + + log.info("seqno {}", contract.getSeqno()); + log.info("pubkey {}", contract.getPublicKey()); + } + + @Test + public void testWalletV1R3EstimateFees() throws NoSuchAlgorithmException, InvalidKeyException { + List mnemonic = Mnemonic.generate(24); + Pair keyPair = Mnemonic.toKeyPair(mnemonic); + + log.info("pubkey " + Utils.bytesToHex(keyPair.getPublicKey())); + log.info("seckey " + Utils.bytesToHex(keyPair.getSecretKey())); + + TweetNaclFast.Signature.KeyPair keyPairSig = + TweetNaclFast.Signature.keyPair_fromSeed(keyPair.getSecretKey()); + + log.info("pubkey " + Utils.bytesToHex(keyPairSig.getPublicKey())); + log.info("seckey " + Utils.bytesToHex(keyPairSig.getSecretKey())); + + WalletV1R3 contract = WalletV1R3.builder().keyPair(keyPairSig).build(); + + Message msg = + MsgUtils.createExternalMessageWithSignedBody( + keyPairSig, contract.getAddress(), contract.getStateInit(), null); + + QueryFees feesWithCodeData = + tonlib.estimateFees( + msg.getInit().getAddress().toString(), + msg.getBody().toBase64(), // message to cell not the whole external + msg.getInit().getCode().toBase64(), + msg.getInit().getData().toBase64(), + false); + + log.info("fees {}", feesWithCodeData); + assertThat(feesWithCodeData).isNotNull(); + + QueryFees feesBodyOnly = + tonlib.estimateFees( + msg.getInit().getAddress().toString(), msg.getBody().toBase64(), null, null, false); + log.info("fees {}", feesBodyOnly); + assertThat(feesBodyOnly).isNotNull(); + } } diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV1R3Short.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV1R3Short.java index 90d2d655..933be5dd 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV1R3Short.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV1R3Short.java @@ -10,7 +10,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.ton.java.address.Address; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.types.WalletV1R3Config; import org.ton.java.smartcontract.wallet.v1.WalletV1R3; import org.ton.java.tonlib.types.ExtMessageInfo; @@ -20,54 +20,57 @@ @RunWith(JUnit4.class) public class TestWalletV1R3Short extends CommonTest { - @Test - public void testWalletV1R3() throws InterruptedException { + @Test + public void testWalletV1R3() throws InterruptedException { - TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); + TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); - WalletV1R3 contract = WalletV1R3.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .build(); + WalletV1R3 contract = WalletV1R3.builder().tonlib(tonlib).keyPair(keyPair).build(); - String nonBounceableAddress = contract.getAddress().toNonBounceable(); - String bounceableAddress = contract.getAddress().toBounceable(); + String nonBounceableAddress = contract.getAddress().toNonBounceable(); + String bounceableAddress = contract.getAddress().toBounceable(); - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - String status = tonlib.getAccountStatus(Address.of(bounceableAddress)); - log.info("account status {}", status); + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + String status = tonlib.getAccountStatus(Address.of(bounceableAddress)); + log.info("account status {}", status); - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); - log.info("new wallet {} balance: {}", contract.getName(), formatNanoValue(balance)); + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); + log.info("new wallet {} balance: {}", contract.getName(), formatNanoValue(balance)); - ExtMessageInfo extMessageInfo = contract.deploy(); - assertThat(extMessageInfo.getError().getCode()).isZero(); + ExtMessageInfo extMessageInfo = contract.deploy(); + assertThat(extMessageInfo.getError().getCode()).isZero(); - contract.waitForDeployment(20); + contract.waitForDeployment(20); - // transfer coins from new wallet (back to faucet) - WalletV1R3Config config = WalletV1R3Config.builder() - .seqno(contract.getSeqno()) - .destination(Address.of(TestFaucet.BOUNCEABLE)) - .amount(Utils.toNano(0.08)) - .comment("testNewWalletV1R2") - .build(); + // transfer coins from new wallet (back to faucet) + WalletV1R3Config config = + WalletV1R3Config.builder() + .seqno(contract.getSeqno()) + .destination(Address.of(TestnetFaucet.BOUNCEABLE)) + .amount(Utils.toNano(0.08)) + .comment("testNewWalletV1R2") + .build(); - extMessageInfo = contract.send(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); + extMessageInfo = contract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); - contract.waitForBalanceChange(30); + contract.waitForBalanceChange(30); - balance = contract.getBalance(); - status = tonlib.getAccountStatus(Address.of(bounceableAddress)); - log.info("new wallet {} with status {} and balance: {}", contract.getName(), status, formatNanoValue(balance)); + balance = contract.getBalance(); + status = tonlib.getAccountStatus(Address.of(bounceableAddress)); + log.info( + "new wallet {} with status {} and balance: {}", + contract.getName(), + status, + formatNanoValue(balance)); - assertThat(balance.longValue()).isLessThan(Utils.toNano(0.02).longValue()); + assertThat(balance.longValue()).isLessThan(Utils.toNano(0.02).longValue()); - log.info("seqno {}", contract.getSeqno()); - log.info("pubkey {}", contract.getPublicKey()); - log.info("transactions {}", contract.getTransactions()); - } + log.info("seqno {}", contract.getSeqno()); + log.info("pubkey {}", contract.getPublicKey()); + log.info("transactions {}", contract.getTransactions()); + } } diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV2R1Short.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV2R1Short.java index b34c6e53..adfe59a9 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV2R1Short.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV2R1Short.java @@ -9,7 +9,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.ton.java.address.Address; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.types.WalletV2R1Config; import org.ton.java.smartcontract.wallet.v2.WalletV2R1; import org.ton.java.tonlib.types.ExtMessageInfo; @@ -19,67 +19,67 @@ @RunWith(JUnit4.class) public class TestWalletV2R1Short extends CommonTest { - @Test - public void testWalletV2R1() throws InterruptedException { + @Test + public void testWalletV2R1() throws InterruptedException { - TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); + TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); - WalletV2R1 contract = WalletV2R1.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .build(); + WalletV2R1 contract = WalletV2R1.builder().tonlib(tonlib).keyPair(keyPair).build(); - String nonBounceableAddress = contract.getAddress().toNonBounceable(); - String bounceableAddress = contract.getAddress().toBounceable(); + String nonBounceableAddress = contract.getAddress().toNonBounceable(); + String bounceableAddress = contract.getAddress().toBounceable(); - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + ExtMessageInfo extMessageInfo = contract.deploy(); + assertThat(extMessageInfo.getError().getCode()).isZero(); - ExtMessageInfo extMessageInfo = contract.deploy(); - assertThat(extMessageInfo.getError().getCode()).isZero(); + contract.waitForDeployment(20); - contract.waitForDeployment(20); + // transfer coins from new wallet (back to faucet) + WalletV2R1Config config = + WalletV2R1Config.builder() + .seqno(contract.getSeqno()) + .destination1(Address.of(TestnetFaucet.BOUNCEABLE)) + .amount1(Utils.toNano(0.1)) + .build(); - // transfer coins from new wallet (back to faucet) - WalletV2R1Config config = WalletV2R1Config.builder() - .seqno(contract.getSeqno()) - .destination1(Address.of(TestFaucet.BOUNCEABLE)) - .amount1(Utils.toNano(0.1)) - .build(); + extMessageInfo = contract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); - extMessageInfo = contract.send(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); + log.info("sending to one destination"); + contract.waitForBalanceChange(90); - log.info("sending to one destination"); - contract.waitForBalanceChange(90); + // multi send + config = + WalletV2R1Config.builder() + .seqno(contract.getSeqno()) + .destination1(Address.of("EQA84DSUMyREa1Frp32wxFATnAVIXnWlYrbd3TFS1NLCbC-B")) + .destination2(Address.of("EQCJZ3sJnes-o86xOa4LDDug6Lpz23RzyJ84CkTMIuVCCuan")) + .destination3(Address.of("EQBjS7elE36MmEmE6-jbHQZNEEK0ObqRgaAxXWkx4pDGeefB")) + .destination4(Address.of("EQAaGHUHfkpWFGs428ETmym4vbvRNxCA1o4sTkwqigKjgf-_")) + .amount1(Utils.toNano(0.15)) + .amount2(Utils.toNano(0.15)) + .amount3(Utils.toNano(0.15)) + .amount4(Utils.toNano(0.15)) + .build(); - //multi send - config = WalletV2R1Config.builder() - .seqno(contract.getSeqno()) - .destination1(Address.of("EQA84DSUMyREa1Frp32wxFATnAVIXnWlYrbd3TFS1NLCbC-B")) - .destination2(Address.of("EQCJZ3sJnes-o86xOa4LDDug6Lpz23RzyJ84CkTMIuVCCuan")) - .destination3(Address.of("EQBjS7elE36MmEmE6-jbHQZNEEK0ObqRgaAxXWkx4pDGeefB")) - .destination4(Address.of("EQAaGHUHfkpWFGs428ETmym4vbvRNxCA1o4sTkwqigKjgf-_")) - .amount1(Utils.toNano(0.15)) - .amount2(Utils.toNano(0.15)) - .amount3(Utils.toNano(0.15)) - .amount4(Utils.toNano(0.15)).build(); + extMessageInfo = contract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); - extMessageInfo = contract.send(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); + log.info("sending to four destinations"); + contract.waitForBalanceChange(90); - log.info("sending to four destinations"); - contract.waitForBalanceChange(90); + balance = new BigInteger(tonlib.getAccountState(Address.of(bounceableAddress)).getBalance()); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + assertThat(balance.longValue()).isLessThan(Utils.toNano(0.3).longValue()); - balance = new BigInteger(tonlib.getAccountState(Address.of(bounceableAddress)).getBalance()); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - assertThat(balance.longValue()).isLessThan(Utils.toNano(0.3).longValue()); - - log.info("seqno {}", contract.getSeqno()); - } + log.info("seqno {}", contract.getSeqno()); + } } diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV2R2Short.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV2R2Short.java index 2cd43424..c1be0e3c 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV2R2Short.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV2R2Short.java @@ -9,7 +9,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.ton.java.address.Address; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.types.WalletV2R2Config; import org.ton.java.smartcontract.wallet.v2.WalletV2R2; import org.ton.java.tonlib.types.ExtMessageInfo; @@ -19,68 +19,66 @@ @RunWith(JUnit4.class) public class TestWalletV2R2Short extends CommonTest { - @Test - public void testWalletV2R2() throws InterruptedException { - TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); - - WalletV2R2 contract = WalletV2R2.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .build(); - - String nonBounceableAddress = contract.getAddress().toNonBounceable(); - String bounceableAddress = contract.getAddress().toBounceable(); - - log.info("non-bounceable address {}", nonBounceableAddress); - log.info(" bounceable address {}", bounceableAddress); - log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); - log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); - - - // top up new wallet using test-faucet-wallet - BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - - - ExtMessageInfo extMessageInfo = contract.deploy(); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - contract.waitForDeployment(20); - - // transfer coins from new wallet (back to faucet) - WalletV2R2Config config = WalletV2R2Config.builder() - .seqno(contract.getSeqno()) - .destination1(Address.of(TestFaucet.BOUNCEABLE)) - .amount1(Utils.toNano(0.1)) - .build(); - - extMessageInfo = contract.send(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - log.info("sending to one destination"); - contract.waitForBalanceChange(90); - - //multi send - config = WalletV2R2Config.builder() - .seqno(contract.getSeqno()) - .destination1(Address.of("EQA84DSUMyREa1Frp32wxFATnAVIXnWlYrbd3TFS1NLCbC-B")) - .destination2(Address.of("EQCJZ3sJnes-o86xOa4LDDug6Lpz23RzyJ84CkTMIuVCCuan")) - .destination3(Address.of("EQBjS7elE36MmEmE6-jbHQZNEEK0ObqRgaAxXWkx4pDGeefB")) - .destination4(Address.of("EQAaGHUHfkpWFGs428ETmym4vbvRNxCA1o4sTkwqigKjgf-_")) - .amount1(Utils.toNano(0.15)) - .amount2(Utils.toNano(0.15)) - .amount3(Utils.toNano(0.15)) - .amount4(Utils.toNano(0.15)) - .build(); - - extMessageInfo = contract.send(config); - assertThat(extMessageInfo.getError().getCode()).isZero(); - - log.info("sending to four destinations"); - contract.waitForBalanceChange(90); - - balance = contract.getBalance(); - log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); - assertThat(balance.longValue()).isLessThan(Utils.toNano(0.3).longValue()); - } + @Test + public void testWalletV2R2() throws InterruptedException { + TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); + + WalletV2R2 contract = WalletV2R2.builder().tonlib(tonlib).keyPair(keyPair).build(); + + String nonBounceableAddress = contract.getAddress().toNonBounceable(); + String bounceableAddress = contract.getAddress().toBounceable(); + + log.info("non-bounceable address {}", nonBounceableAddress); + log.info(" bounceable address {}", bounceableAddress); + log.info("pub-key {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); + log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); + + // top up new wallet using test-faucet-wallet + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + + ExtMessageInfo extMessageInfo = contract.deploy(); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + contract.waitForDeployment(20); + + // transfer coins from new wallet (back to faucet) + WalletV2R2Config config = + WalletV2R2Config.builder() + .seqno(contract.getSeqno()) + .destination1(Address.of(TestnetFaucet.BOUNCEABLE)) + .amount1(Utils.toNano(0.1)) + .build(); + + extMessageInfo = contract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + log.info("sending to one destination"); + contract.waitForBalanceChange(90); + + // multi send + config = + WalletV2R2Config.builder() + .seqno(contract.getSeqno()) + .destination1(Address.of("EQA84DSUMyREa1Frp32wxFATnAVIXnWlYrbd3TFS1NLCbC-B")) + .destination2(Address.of("EQCJZ3sJnes-o86xOa4LDDug6Lpz23RzyJ84CkTMIuVCCuan")) + .destination3(Address.of("EQBjS7elE36MmEmE6-jbHQZNEEK0ObqRgaAxXWkx4pDGeefB")) + .destination4(Address.of("EQAaGHUHfkpWFGs428ETmym4vbvRNxCA1o4sTkwqigKjgf-_")) + .amount1(Utils.toNano(0.15)) + .amount2(Utils.toNano(0.15)) + .amount3(Utils.toNano(0.15)) + .amount4(Utils.toNano(0.15)) + .build(); + + extMessageInfo = contract.send(config); + assertThat(extMessageInfo.getError().getCode()).isZero(); + + log.info("sending to four destinations"); + contract.waitForBalanceChange(90); + + balance = contract.getBalance(); + log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); + assertThat(balance.longValue()).isLessThan(Utils.toNano(0.3).longValue()); + } } diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV3R1.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV3R1.java index 13f14eca..ec30bc59 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV3R1.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV3R1.java @@ -1,13 +1,17 @@ package org.ton.java.smartcontract.integrationtests; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + import com.iwebpp.crypto.TweetNaclFast; +import java.math.BigInteger; +import java.time.Instant; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.ton.java.address.Address; import org.ton.java.cell.CellBuilder; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.types.WalletV3Config; import org.ton.java.smartcontract.utils.MsgUtils; import org.ton.java.smartcontract.wallet.v3.WalletV3R1; @@ -15,11 +19,6 @@ import org.ton.java.tonlib.types.ExtMessageInfo; import org.ton.java.utils.Utils; -import java.math.BigInteger; -import java.time.Instant; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; - @Slf4j @RunWith(JUnit4.class) public class TestWalletV3R1 extends CommonTest { @@ -62,7 +61,7 @@ public void testWalletV3R1() throws InterruptedException { // top up new wallet using test-faucet-wallet BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); // deploy new wallet @@ -76,7 +75,7 @@ public void testWalletV3R1() throws InterruptedException { WalletV3Config.builder() .seqno(contract.getSeqno()) .walletId(42) - .destination(Address.of(TestFaucet.BOUNCEABLE)) + .destination(Address.of(TestnetFaucet.BOUNCEABLE)) .amount(Utils.toNano(0.8)) .comment("testWalletV3R1") .build(); diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV3R1Short.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV3R1Short.java index 92ef8916..3c0e2408 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV3R1Short.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV3R1Short.java @@ -5,7 +5,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.wallet.v3.WalletV3R1; import org.ton.java.utils.Utils; @@ -13,25 +13,26 @@ @RunWith(JUnit4.class) public class TestWalletV3R1Short extends CommonTest { + /* + * addr - EQA-XwAkPLS-i4s9_N5v0CXGVFecw7lZV2rYeXDAimuWi9zI + * pub key - 2c188d86ba469755554baad436663b8073145b29f117550432426c513e7c582a + * prv key - c67cf48806f08929a49416ebebd97078100540ac8a3283646222b4d958b3e9e22c188d86ba469755554baad436663b8073145b29f117550432426c513e7c582a + */ + @Test + public void testWalletV3R1() throws InterruptedException { + WalletV3R1 contract = WalletV3R1.builder().tonlib(tonlib).walletId(42).build(); + log.info("pub key: {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); + log.info("prv key: {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); - /* - * addr - EQA-XwAkPLS-i4s9_N5v0CXGVFecw7lZV2rYeXDAimuWi9zI - * pub key - 2c188d86ba469755554baad436663b8073145b29f117550432426c513e7c582a - * prv key - c67cf48806f08929a49416ebebd97078100540ac8a3283646222b4d958b3e9e22c188d86ba469755554baad436663b8073145b29f117550432426c513e7c582a - */ - @Test - public void testWalletV3R1() throws InterruptedException { - WalletV3R1 contract = WalletV3R1.builder() - .tonlib(tonlib) - .walletId(42) - .build(); - log.info("pub key: {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); - log.info("prv key: {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, contract.getAddress(), Utils.toNano(1)); + log.info( + "walletId {} new wallet {} balance: {}", + contract.getWalletId(), + contract.getName(), + Utils.formatNanoValue(balance)); - BigInteger balance = TestFaucet.topUpContract(tonlib, contract.getAddress(), Utils.toNano(1)); - log.info("walletId {} new wallet {} balance: {}", contract.getWalletId(), contract.getName(), Utils.formatNanoValue(balance)); - - contract.deploy(); - contract.waitForDeployment(60); - } + contract.deploy(); + contract.waitForDeployment(60); + } } diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV3R2Short.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV3R2Short.java index 27a1d33f..5c2fe63f 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV3R2Short.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV3R2Short.java @@ -1,6 +1,10 @@ package org.ton.java.smartcontract.integrationtests; +import static java.util.Objects.nonNull; +import static org.assertj.core.api.Assertions.assertThat; + import com.iwebpp.crypto.TweetNaclFast; +import java.math.BigInteger; import lombok.extern.slf4j.Slf4j; import org.assertj.core.api.AssertionsForClassTypes; import org.junit.Test; @@ -9,7 +13,7 @@ import org.ton.java.address.Address; import org.ton.java.cell.Cell; import org.ton.java.cell.CellSlice; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.types.WalletV3Config; import org.ton.java.smartcontract.wallet.v3.WalletV3R2; import org.ton.java.tonlib.types.ExtMessageInfo; @@ -18,11 +22,6 @@ import org.ton.java.tonlib.types.RawTransactions; import org.ton.java.utils.Utils; -import java.math.BigInteger; - -import static java.util.Objects.nonNull; -import static org.assertj.core.api.Assertions.assertThat; - @Slf4j @RunWith(JUnit4.class) public class TestWalletV3R2Short extends CommonTest { @@ -71,7 +70,7 @@ public void testWalletV3R2() throws InterruptedException { // top up new wallet using test-faucet-wallet BigInteger balance1 = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress1), Utils.toNano(1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress1), Utils.toNano(1)); log.info( "walletId {} new wallet {} balance: {}", contract1.getWalletId(), @@ -79,7 +78,7 @@ public void testWalletV3R2() throws InterruptedException { Utils.formatNanoValue(balance1)); BigInteger balance2 = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress2), Utils.toNano(1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress2), Utils.toNano(1)); log.info( "walletId {} new wallet {} balance: {}", contract2.getWalletId(), @@ -100,7 +99,7 @@ public void testWalletV3R2() throws InterruptedException { WalletV3Config.builder() .walletId(42) .seqno(contract1.getSeqno()) - .destination(Address.of(TestFaucet.BOUNCEABLE)) + .destination(Address.of(TestnetFaucet.BOUNCEABLE)) .amount(Utils.toNano(0.8)) .comment("testWalletV3R2-42") .build(); @@ -115,7 +114,7 @@ public void testWalletV3R2() throws InterruptedException { WalletV3Config.builder() .walletId(98) .seqno(contract2.getSeqno()) - .destination(Address.of(TestFaucet.BOUNCEABLE)) + .destination(Address.of(TestnetFaucet.BOUNCEABLE)) .amount(Utils.toNano(0.7)) .comment("testWalletV3R2-98") .build(); @@ -210,7 +209,8 @@ public void testWallet() throws InterruptedException { log.info("pub key: {}", Utils.bytesToHex(contract.getKeyPair().getPublicKey())); log.info("prv key: {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); - BigInteger balance = TestFaucet.topUpContract(tonlib, contract.getAddress(), Utils.toNano(1)); + BigInteger balance = + TestnetFaucet.topUpContract(tonlib, contract.getAddress(), Utils.toNano(1)); log.info( "walletId {} new wallet {} balance: {}", contract.getWalletId(), diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV4R2Plugins.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV4R2Plugins.java index 691ebfe9..f4ffa7c1 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV4R2Plugins.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV4R2Plugins.java @@ -1,7 +1,6 @@ package org.ton.java.smartcontract.integrationtests; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.ton.java.smartcontract.TestFaucet.FAUCET_ADDRESS_RAW; import com.iwebpp.crypto.TweetNaclFast; import java.math.BigInteger; @@ -12,7 +11,7 @@ import org.junit.runners.JUnit4; import org.ton.java.address.Address; import org.ton.java.cell.Cell; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.types.DeployedPlugin; import org.ton.java.smartcontract.types.NewPlugin; import org.ton.java.smartcontract.types.WalletV4R2Config; @@ -27,6 +26,9 @@ @RunWith(JUnit4.class) public class TestWalletV4R2Plugins extends CommonTest { + static String FAUCET_ADDRESS_RAW = + "0:b52a16ba3735501df19997550e7ed4c41754ee501ded8a841088ce4278b66de4"; + @Test public void testWalletV4Deploy() throws InterruptedException { @@ -43,7 +45,7 @@ public void testWalletV4Deploy() throws InterruptedException { log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); ExtMessageInfo extMessageInfo = contract.deploy(); @@ -66,7 +68,7 @@ public void testPlugins() throws InterruptedException { log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(7)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(7)); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); // deploy wallet-v4 @@ -269,7 +271,7 @@ public void testSimpleSend() throws InterruptedException { log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1)); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); // deploy wallet-v4 diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV5.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV5.java index 44e014d0..d0811792 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV5.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestWalletV5.java @@ -15,7 +15,7 @@ import org.ton.java.cell.Cell; import org.ton.java.cell.CellSlice; import org.ton.java.cell.TonHashMapE; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.types.Destination; import org.ton.java.smartcontract.types.WalletV3Config; import org.ton.java.smartcontract.types.WalletV5Config; @@ -63,7 +63,7 @@ public void testWalletV5Deployment() throws InterruptedException { log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); // deploy wallet-v5 @@ -106,7 +106,7 @@ public void testWalletV5SimpleTransfer1() throws InterruptedException { log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); // deploy wallet-v5 @@ -169,7 +169,7 @@ public void testWalletV5SimpleTransfer255Recipients() log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1.5)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(1.5)); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); // deploy wallet-v5 @@ -211,7 +211,7 @@ public void testWalletV5SimpleTransfer0() throws InterruptedException { log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); // deploy wallet-v5 @@ -255,7 +255,7 @@ public void testWalletV5DeployOneExtension() throws InterruptedException { log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); // deploy wallet-v5 @@ -313,7 +313,7 @@ public void testWalletV5DeployTwoExtensions() throws InterruptedException { log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); // deploy wallet-v5 @@ -394,7 +394,7 @@ public void testWalletV5DeployWithOneExtension() throws InterruptedException { log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.5)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.5)); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); // deploy wallet-v5 @@ -440,7 +440,7 @@ public void testWalletV5DeployWithThreeExtensions() throws InterruptedException log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.5)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.5)); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); // deploy wallet-v5 @@ -486,7 +486,7 @@ public void testWalletV5DeployWithThreeExtensionsAndDeleteOne() throws Interrupt log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.5)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.5)); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); // deploy wallet-v5 @@ -566,7 +566,7 @@ public void testWalletV5DeployWithTwoExtensionsAndDeleteOneExtensionAndSendTrans log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.5)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.5)); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); // deploy wallet-v5 @@ -642,7 +642,7 @@ public void testWalletV5ModifySignatureAuthAllowed() throws InterruptedException log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); // deploy wallet-v5 @@ -712,7 +712,7 @@ public void testWalletV5InternalTransfer1() throws InterruptedException { log.info("prv key: {}", Utils.bytesToHex(contractV3.getKeyPair().getSecretKey())); BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.2)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.2)); log.info( "walletId {} new wallet v3 {} balance: {}", contractV3.getWalletId(), @@ -742,7 +742,8 @@ public void testWalletV5InternalTransfer1() throws InterruptedException { log.info("pub-key {}", Utils.bytesToHex(contractV5.getKeyPair().getPublicKey())); log.info("prv-key {}", Utils.bytesToHex(contractV5.getKeyPair().getSecretKey())); - balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.2)); + balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.2)); log.info("new wallet v5 {} balance: {}", contractV5.getName(), Utils.formatNanoValue(balance)); // deploy wallet v5 @@ -808,7 +809,7 @@ public void testWalletV5TransferFromExtension() throws InterruptedException { log.info("prv key: {}", Utils.bytesToHex(contractV3.getKeyPair().getSecretKey())); BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.2)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.2)); log.info( "walletId {} new wallet v3 {} balance: {}", contractV3.getWalletId(), @@ -842,7 +843,8 @@ public void testWalletV5TransferFromExtension() throws InterruptedException { log.info("pub-key {}", Utils.bytesToHex(contractV5.getKeyPair().getPublicKey())); log.info("prv-key {}", Utils.bytesToHex(contractV5.getKeyPair().getSecretKey())); - balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.2)); + balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.2)); log.info("new wallet v5 {} balance: {}", contractV5.getName(), Utils.formatNanoValue(balance)); // deploy wallet v5 @@ -900,7 +902,7 @@ public void testWalletV5ManageExtensionsFromExtension() throws InterruptedExcept log.info("prv key: {}", Utils.bytesToHex(contractV3.getKeyPair().getSecretKey())); BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.2)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.2)); log.info( "walletId {} new wallet v3 {} balance: {}", contractV3.getWalletId(), @@ -936,7 +938,8 @@ public void testWalletV5ManageExtensionsFromExtension() throws InterruptedExcept log.info("pub-key {}", Utils.bytesToHex(contractV5.getKeyPair().getPublicKey())); log.info("prv-key {}", Utils.bytesToHex(contractV5.getKeyPair().getSecretKey())); - balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.2)); + balance = + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.2)); log.info("new wallet v5 {} balance: {}", contractV5.getName(), Utils.formatNanoValue(balance)); // deploy wallet v5 @@ -1001,7 +1004,7 @@ public void testWalletV5DeploymentAsLibrary() throws InterruptedException { log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.5)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.5)); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); // deploy wallet-v5 @@ -1033,7 +1036,7 @@ public void testWalletV5DeployAsLibrary() throws InterruptedException { log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); // deploy wallet-v5 @@ -1070,7 +1073,7 @@ public void testWalletV5SimpleTransfer1WhenDeployedAsLibrary() throws Interrupte log.info("prv-key {}", Utils.bytesToHex(contract.getKeyPair().getSecretKey())); BigInteger balance = - TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); + TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); log.info("new wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); // deploy wallet-v5 diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/unittests/TestSmartContractCompiler.java b/smartcontract/src/test/java/org/ton/java/smartcontract/unittests/TestSmartContractCompiler.java index 05321eac..f4e7c29c 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/unittests/TestSmartContractCompiler.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/unittests/TestSmartContractCompiler.java @@ -19,96 +19,100 @@ @Slf4j @RunWith(JUnit4.class) public class TestSmartContractCompiler { - /** - * Make sure you have fift and func installed in your system. See packages for instructions. - * Example is based on new-wallet-v4r2.fc smart contract. You can specify path to any smart contract. - */ - @Test - public void testSmartContractCompiler() throws URISyntaxException, InterruptedException, IOException { -// URL resource = FuncCompiler.class.getResource("/contracts/stablecoin/contracts/jetton-minter.fc"); - URL resource = SmartContractCompiler.class.getResource("/contracts/wallets/new-wallet-v4r2.fc"); - String contractAbsolutePath = Paths.get(resource.toURI()).toFile().getAbsolutePath(); - SmartContractCompiler smcFunc = SmartContractCompiler.builder() -// .contractPath("C:/stablecoin/contracts/jetton-minter.fc") - .contractPath(contractAbsolutePath) -// .fiftExecutablePath("C:/ProgramData/chocolatey/bin/fift") -// .funcExecutablePath("C:/ProgramData/chocolatey/bin/func") -// .fiftAsmLibraryPath("C:/ProgramData/chocolatey/lib/ton/bin/lib") -// .fiftSmartcontLibraryPath("C:/ProgramData/chocolatey/lib/ton/bin/smartcont") - .build(); - - String codeCellHex = smcFunc.compile(); - - TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); - - String dataCellHex = CellBuilder.beginCell() - .storeUint(0, 32) // seqno - .storeUint(42, 32) // wallet id - .storeBytes(keyPair.getPublicKey()) - .storeUint(0, 1) //plugins dict empty - .endCell() - .toHex(); - - log.info("codeCellHex {}", codeCellHex); - log.info("dataCellHex {}", dataCellHex); - - Tonlib tonlib = Tonlib.builder() - .testnet(true) - .ignoreCache(false) - .build(); - - GenericSmartContract smc = GenericSmartContract.builder() - .tonlib(tonlib) - .keyPair(keyPair) - .code(codeCellHex) - .data(dataCellHex) - .build(); - - String nonBounceableAddress = smc.getAddress().toNonBounceable(); - String bounceableAddress = smc.getAddress().toBounceable(); - String rawAddress = smc.getAddress().toRaw(); - - log.info("non-bounceable address: {}", nonBounceableAddress); - log.info(" bounceable address: {}", bounceableAddress); - log.info(" raw address: {}", rawAddress); - log.info("pub-key {}", Utils.bytesToHex(smc.getKeyPair().getPublicKey())); - log.info("prv-key {}", Utils.bytesToHex(smc.getKeyPair().getSecretKey())); -// -// BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); -// log.info("new wallet {} balance: {}", smc.getName(), Utils.formatNanoValue(balance)); -// -// Cell deployMessageBody = CellBuilder.beginCell() -// .storeUint(42, 32) // wallet-id -// .storeInt(-1, 32) // valid-until -// .storeUint(0, 32) //seqno -// .endCell(); -// -// smc.deploy(deployMessageBody); - } - - @Test - public void testWalletV5Compiler() throws URISyntaxException, IOException { - URL resource = SmartContractCompiler.class.getResource("/contracts/wallets/new-wallet-v5.fc"); - String contractAbsolutePath = Paths.get(resource.toURI()).toFile().getAbsolutePath(); - SmartContractCompiler smcFunc = SmartContractCompiler.builder() - .contractPath(contractAbsolutePath) - .build(); - - String codeCellHex = smcFunc.compile(); - - log.info("codeCellHex {}", codeCellHex); - } - - @Test - public void testLibraryDeployerCompiler() throws URISyntaxException, IOException { - URL resource = SmartContractCompiler.class.getResource("/contracts/wallets/library-deployer.fc"); - String contractAbsolutePath = Paths.get(resource.toURI()).toFile().getAbsolutePath(); - SmartContractCompiler smcFunc = SmartContractCompiler.builder() - .contractPath(contractAbsolutePath) - .build(); - - String codeCellHex = smcFunc.compile(); - - log.info("codeCellHex {}", codeCellHex); - } -} \ No newline at end of file + /** + * Make sure you have fift and func installed in your system. See packages for instructions. Example is + * based on new-wallet-v4r2.fc smart contract. You can specify path to any smart contract. + */ + @Test + public void testSmartContractCompiler() + throws URISyntaxException, InterruptedException, IOException { + // URL resource = + // FuncCompiler.class.getResource("/contracts/stablecoin/contracts/jetton-minter.fc"); + URL resource = SmartContractCompiler.class.getResource("/contracts/wallets/new-wallet-v4r2.fc"); + String contractAbsolutePath = Paths.get(resource.toURI()).toFile().getAbsolutePath(); + SmartContractCompiler smcFunc = + SmartContractCompiler.builder() + // .contractPath("C:/stablecoin/contracts/jetton-minter.fc") + .contractPath(contractAbsolutePath) + // .fiftExecutablePath("C:/ProgramData/chocolatey/bin/fift") + // .funcExecutablePath("C:/ProgramData/chocolatey/bin/func") + // .fiftAsmLibraryPath("C:/ProgramData/chocolatey/lib/ton/bin/lib") + // + // .fiftSmartcontLibraryPath("C:/ProgramData/chocolatey/lib/ton/bin/smartcont") + .build(); + + String codeCellHex = smcFunc.compile(); + + TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); + + String dataCellHex = + CellBuilder.beginCell() + .storeUint(0, 32) // seqno + .storeUint(42, 32) // wallet id + .storeBytes(keyPair.getPublicKey()) + .storeUint(0, 1) // plugins dict empty + .endCell() + .toHex(); + + log.info("codeCellHex {}", codeCellHex); + log.info("dataCellHex {}", dataCellHex); + + Tonlib tonlib = Tonlib.builder().testnet(true).ignoreCache(false).build(); + + GenericSmartContract smc = + GenericSmartContract.builder() + .tonlib(tonlib) + .keyPair(keyPair) + .code(codeCellHex) + .data(dataCellHex) + .build(); + + String nonBounceableAddress = smc.getAddress().toNonBounceable(); + String bounceableAddress = smc.getAddress().toBounceable(); + String rawAddress = smc.getAddress().toRaw(); + + log.info("non-bounceable address: {}", nonBounceableAddress); + log.info(" bounceable address: {}", bounceableAddress); + log.info(" raw address: {}", rawAddress); + log.info("pub-key {}", Utils.bytesToHex(smc.getKeyPair().getPublicKey())); + log.info("prv-key {}", Utils.bytesToHex(smc.getKeyPair().getSecretKey())); + // + // BigInteger balance = TestnetFaucet.topUpContract(tonlib, + // Address.of(nonBounceableAddress), Utils.toNano(0.1)); + // log.info("new wallet {} balance: {}", smc.getName(), Utils.formatNanoValue(balance)); + // + // Cell deployMessageBody = CellBuilder.beginCell() + // .storeUint(42, 32) // wallet-id + // .storeInt(-1, 32) // valid-until + // .storeUint(0, 32) //seqno + // .endCell(); + // + // smc.deploy(deployMessageBody); + } + + @Test + public void testWalletV5Compiler() throws URISyntaxException, IOException { + URL resource = SmartContractCompiler.class.getResource("/contracts/wallets/new-wallet-v5.fc"); + String contractAbsolutePath = Paths.get(resource.toURI()).toFile().getAbsolutePath(); + SmartContractCompiler smcFunc = + SmartContractCompiler.builder().contractPath(contractAbsolutePath).build(); + + String codeCellHex = smcFunc.compile(); + + log.info("codeCellHex {}", codeCellHex); + } + + @Test + public void testLibraryDeployerCompiler() throws URISyntaxException, IOException { + URL resource = + SmartContractCompiler.class.getResource("/contracts/wallets/library-deployer.fc"); + String contractAbsolutePath = Paths.get(resource.toURI()).toFile().getAbsolutePath(); + SmartContractCompiler smcFunc = + SmartContractCompiler.builder().contractPath(contractAbsolutePath).build(); + + String codeCellHex = smcFunc.compile(); + + log.info("codeCellHex {}", codeCellHex); + } +} diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/unittests/TestWalletsV3.java b/smartcontract/src/test/java/org/ton/java/smartcontract/unittests/TestWalletsV3.java index df9b5fb9..0c1d8132 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/unittests/TestWalletsV3.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/unittests/TestWalletsV3.java @@ -9,7 +9,7 @@ import org.junit.runners.JUnit4; import org.ton.java.address.Address; import org.ton.java.cell.Cell; -import org.ton.java.smartcontract.TestFaucet; +import org.ton.java.smartcontract.faucet.TestnetFaucet; import org.ton.java.smartcontract.types.WalletV3Config; import org.ton.java.smartcontract.utils.MsgUtils; import org.ton.java.smartcontract.wallet.v3.WalletV3R1; @@ -107,7 +107,7 @@ public void testNewWalletV3R2() { WalletV3Config.builder() .walletId(42) .seqno(contract.getSeqno()) - .destination(Address.of(TestFaucet.BOUNCEABLE)) + .destination(Address.of(TestnetFaucet.BOUNCEABLE)) .amount(Utils.toNano(0.8)) .build(); diff --git a/smartcontract/v1r2-example.md b/smartcontract/v1r2-example.md index 4d3f8bf6..a358a566 100644 --- a/smartcontract/v1r2-example.md +++ b/smartcontract/v1r2-example.md @@ -21,7 +21,7 @@ log.info(" bounceable address {}", bounceableAddress); log.info(" raw address {}", contract.getAddress().toString(false)); // top up new wallet using test-faucet-wallet -BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); +BigInteger balance = TestnetFaucet.topUpContract(tonlib, Address.of(nonBounceableAddress), Utils.toNano(0.1)); log.info("wallet {} balance: {}", contract.getName(), Utils.formatNanoValue(balance)); @@ -34,7 +34,7 @@ log.info("wallet seqno: {}", contract.getSeqno()); WalletV1R2Config config = WalletV1R2Config.builder() .seqno(contract.getSeqno()) - .destination(Address.of(TestFaucet.BOUNCEABLE)) + .destination(Address.of(TestnetFaucet.BOUNCEABLE)) .amount(Utils.toNano(0.08)) .comment("testNewWalletV1R2") .build();