@aztec/end-to-end 0.0.1-commit.04852196a → 0.0.1-commit.04d373f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -0
- package/dest/bench/client_flows/benchmark.d.ts +15 -1
- package/dest/bench/client_flows/benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/benchmark.js +17 -0
- package/dest/bench/client_flows/client_flows_benchmark.d.ts +2 -2
- package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.js +27 -38
- package/dest/bench/utils.d.ts +1 -1
- package/dest/bench/utils.d.ts.map +1 -1
- package/dest/bench/utils.js +2 -0
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +5 -4
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +14 -5
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +15 -4
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +1 -1
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +39 -7
- package/dest/e2e_deploy_contract/deploy_test.d.ts +3 -3
- package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
- package/dest/e2e_deploy_contract/deploy_test.js +2 -1
- package/dest/e2e_epochs/epochs_test.d.ts +25 -2
- package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
- package/dest/e2e_epochs/epochs_test.js +88 -14
- package/dest/e2e_fees/fees_test.d.ts +5 -2
- package/dest/e2e_fees/fees_test.d.ts.map +1 -1
- package/dest/e2e_fees/fees_test.js +32 -6
- package/dest/e2e_nested_contract/nested_contract_test.d.ts +3 -3
- package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
- package/dest/e2e_nested_contract/nested_contract_test.js +2 -1
- package/dest/e2e_p2p/inactivity_slash_test.d.ts +1 -1
- package/dest/e2e_p2p/inactivity_slash_test.d.ts.map +1 -1
- package/dest/e2e_p2p/inactivity_slash_test.js +5 -3
- package/dest/e2e_p2p/p2p_network.d.ts +10 -9
- package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
- package/dest/e2e_p2p/p2p_network.js +46 -27
- package/dest/e2e_p2p/reqresp/utils.d.ts +1 -1
- package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -1
- package/dest/e2e_p2p/reqresp/utils.js +42 -13
- package/dest/e2e_p2p/shared.d.ts +16 -12
- package/dest/e2e_p2p/shared.d.ts.map +1 -1
- package/dest/e2e_p2p/shared.js +57 -57
- package/dest/e2e_token_contract/token_contract_test.d.ts +3 -3
- package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
- package/dest/e2e_token_contract/token_contract_test.js +4 -2
- package/dest/fixtures/authwit_proxy.d.ts +1 -1
- package/dest/fixtures/authwit_proxy.d.ts.map +1 -1
- package/dest/fixtures/authwit_proxy.js +4 -0
- package/dest/fixtures/e2e_prover_test.d.ts +6 -5
- package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
- package/dest/fixtures/e2e_prover_test.js +9 -13
- package/dest/fixtures/fixtures.d.ts +73 -1
- package/dest/fixtures/fixtures.d.ts.map +1 -1
- package/dest/fixtures/fixtures.js +68 -0
- package/dest/fixtures/get_bb_config.d.ts +1 -1
- package/dest/fixtures/get_bb_config.d.ts.map +1 -1
- package/dest/fixtures/get_bb_config.js +5 -5
- package/dest/fixtures/ha_setup.d.ts +2 -2
- package/dest/fixtures/ha_setup.d.ts.map +1 -1
- package/dest/fixtures/ha_setup.js +1 -1
- package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts +25 -0
- package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts.map +1 -0
- package/dest/fixtures/schnorr_hardcoded_account_contract.js +37 -0
- package/dest/fixtures/setup.d.ts +43 -11
- package/dest/fixtures/setup.d.ts.map +1 -1
- package/dest/fixtures/setup.js +135 -26
- package/dest/fixtures/setup_p2p_test.d.ts +10 -6
- package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
- package/dest/fixtures/setup_p2p_test.js +8 -8
- package/dest/fixtures/token_utils.d.ts +1 -1
- package/dest/fixtures/token_utils.d.ts.map +1 -1
- package/dest/fixtures/token_utils.js +2 -5
- package/dest/fixtures/utils.d.ts +2 -2
- package/dest/fixtures/utils.d.ts.map +1 -1
- package/dest/fixtures/utils.js +1 -1
- package/dest/forward-compatibility/wallet_rpc_client.d.ts +7 -0
- package/dest/forward-compatibility/wallet_rpc_client.d.ts.map +1 -0
- package/dest/forward-compatibility/wallet_rpc_client.js +15 -0
- package/dest/forward-compatibility/wallet_service.d.ts +3 -0
- package/dest/forward-compatibility/wallet_service.d.ts.map +1 -0
- package/dest/forward-compatibility/wallet_service.js +109 -0
- package/dest/install_legacy_contracts.d.cts +10 -0
- package/dest/install_legacy_contracts.d.cts.map +1 -0
- package/dest/legacy-jest-resolver.d.cts +3 -0
- package/dest/legacy-jest-resolver.d.cts.map +1 -0
- package/dest/shared/cross_chain_test_harness.d.ts +4 -2
- package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
- package/dest/shared/cross_chain_test_harness.js +9 -5
- package/dest/shared/gas_portal_test_harness.d.ts +8 -5
- package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
- package/dest/shared/gas_portal_test_harness.js +17 -8
- package/dest/shared/uniswap_l1_l2.d.ts +1 -1
- package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
- package/dest/shared/uniswap_l1_l2.js +55 -34
- package/dest/shared/wait_for_l1_to_l2_message.d.ts +13 -0
- package/dest/shared/wait_for_l1_to_l2_message.d.ts.map +1 -0
- package/dest/shared/wait_for_l1_to_l2_message.js +10 -0
- package/dest/simulators/lending_simulator.d.ts +10 -3
- package/dest/simulators/lending_simulator.d.ts.map +1 -1
- package/dest/simulators/lending_simulator.js +24 -12
- package/dest/simulators/token_simulator.js +1 -1
- package/dest/spartan/setup_test_wallets.d.ts +4 -2
- package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
- package/dest/spartan/setup_test_wallets.js +73 -41
- package/dest/spartan/tx_metrics.d.ts +18 -4
- package/dest/spartan/tx_metrics.d.ts.map +1 -1
- package/dest/spartan/tx_metrics.js +73 -20
- package/dest/spartan/utils/config.d.ts +9 -32
- package/dest/spartan/utils/config.d.ts.map +1 -1
- package/dest/spartan/utils/config.js +1 -0
- package/dest/spartan/utils/index.d.ts +2 -1
- package/dest/spartan/utils/index.d.ts.map +1 -1
- package/dest/spartan/utils/index.js +2 -0
- package/dest/spartan/utils/nodes.js +2 -2
- package/dest/spartan/utils/pod_logs.d.ts +25 -0
- package/dest/spartan/utils/pod_logs.d.ts.map +1 -0
- package/dest/spartan/utils/pod_logs.js +74 -0
- package/dest/test-wallet/test_wallet.d.ts +25 -23
- package/dest/test-wallet/test_wallet.d.ts.map +1 -1
- package/dest/test-wallet/test_wallet.js +146 -87
- package/dest/test-wallet/utils.d.ts +3 -3
- package/dest/test-wallet/utils.d.ts.map +1 -1
- package/dest/test-wallet/utils.js +2 -7
- package/dest/test-wallet/wallet_worker_script.js +2 -2
- package/dest/test-wallet/worker_wallet.d.ts +5 -4
- package/dest/test-wallet/worker_wallet.d.ts.map +1 -1
- package/dest/test-wallet/worker_wallet.js +5 -1
- package/dest/test-wallet/worker_wallet_schema.d.ts +110 -224
- package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -1
- package/dest/test-wallet/worker_wallet_schema.js +14 -2
- package/package.json +46 -42
- package/src/bench/client_flows/benchmark.ts +19 -0
- package/src/bench/client_flows/client_flows_benchmark.ts +64 -53
- package/src/bench/utils.ts +2 -1
- package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +24 -10
- package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +49 -11
- package/src/e2e_deploy_contract/deploy_test.ts +3 -2
- package/src/e2e_epochs/epochs_test.ts +99 -11
- package/src/e2e_fees/fees_test.ts +37 -4
- package/src/e2e_nested_contract/nested_contract_test.ts +3 -1
- package/src/e2e_p2p/inactivity_slash_test.ts +5 -3
- package/src/e2e_p2p/p2p_network.ts +57 -39
- package/src/e2e_p2p/reqresp/utils.ts +51 -12
- package/src/e2e_p2p/shared.ts +57 -72
- package/src/e2e_token_contract/token_contract_test.ts +12 -2
- package/src/fixtures/authwit_proxy.ts +4 -0
- package/src/fixtures/e2e_prover_test.ts +15 -18
- package/src/fixtures/fixtures.ts +86 -0
- package/src/fixtures/get_bb_config.ts +7 -6
- package/src/fixtures/ha_setup.ts +4 -2
- package/src/fixtures/schnorr_hardcoded_account_contract.ts +49 -0
- package/src/fixtures/setup.ts +171 -31
- package/src/fixtures/setup_p2p_test.ts +13 -9
- package/src/fixtures/token_utils.ts +1 -4
- package/src/fixtures/utils.ts +2 -0
- package/src/forward-compatibility/wallet_rpc_client.ts +14 -0
- package/src/forward-compatibility/wallet_service.ts +104 -0
- package/src/guides/up_quick_start.sh +0 -2
- package/src/install_legacy_contracts.cjs +75 -0
- package/src/legacy-jest-resolver.cjs +112 -0
- package/src/shared/cross_chain_test_harness.ts +14 -4
- package/src/shared/gas_portal_test_harness.ts +20 -10
- package/src/shared/uniswap_l1_l2.ts +71 -46
- package/src/shared/wait_for_l1_to_l2_message.ts +23 -0
- package/src/simulators/lending_simulator.ts +28 -12
- package/src/simulators/token_simulator.ts +1 -1
- package/src/spartan/setup_test_wallets.ts +98 -37
- package/src/spartan/tx_metrics.ts +81 -23
- package/src/spartan/utils/config.ts +1 -0
- package/src/spartan/utils/index.ts +3 -0
- package/src/spartan/utils/nodes.ts +2 -2
- package/src/spartan/utils/pod_logs.ts +99 -0
- package/src/test-wallet/test_wallet.ts +174 -104
- package/src/test-wallet/utils.ts +3 -7
- package/src/test-wallet/wallet_worker_script.ts +2 -2
- package/src/test-wallet/worker_wallet.ts +9 -4
- package/src/test-wallet/worker_wallet_schema.ts +2 -2
|
@@ -21,7 +21,11 @@ import { computeL2ToL1MembershipWitness } from '@aztec/stdlib/messaging';
|
|
|
21
21
|
import { jest } from '@jest/globals';
|
|
22
22
|
import { type GetContractReturnType, getContract, parseEther, toFunctionSelector } from 'viem';
|
|
23
23
|
|
|
24
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
type EndToEndContext,
|
|
26
|
+
ensureAccountContractsPublished,
|
|
27
|
+
ensureAuthRegistryPublished,
|
|
28
|
+
} from '../fixtures/utils.js';
|
|
25
29
|
import type { TestWallet } from '../test-wallet/test_wallet.js';
|
|
26
30
|
import { CrossChainTestHarness } from './cross_chain_test_harness.js';
|
|
27
31
|
|
|
@@ -32,7 +36,7 @@ import { CrossChainTestHarness } from './cross_chain_test_harness.js';
|
|
|
32
36
|
// anvil --fork-url https://mainnet.infura.io/v3/9928b52099854248b3a096be07a6b23c --fork-block-number 17514288 --chain-id 31337
|
|
33
37
|
// For CI, this is configured in `run_tests.sh` and `docker-compose-images.yml`
|
|
34
38
|
|
|
35
|
-
const TIMEOUT =
|
|
39
|
+
const TIMEOUT = 15 * 60 * 1000;
|
|
36
40
|
|
|
37
41
|
export const uniswapL1L2TestSuite = (
|
|
38
42
|
setup: () => Promise<EndToEndContext>,
|
|
@@ -98,6 +102,7 @@ export const uniswapL1L2TestSuite = (
|
|
|
98
102
|
ownerEthAddress = EthAddress.fromString((await l1Client.getAddresses())[0]);
|
|
99
103
|
|
|
100
104
|
await ensureAccountContractsPublished(wallet, [ownerAddress, sponsorAddress]);
|
|
105
|
+
await ensureAuthRegistryPublished(wallet, ownerAddress);
|
|
101
106
|
|
|
102
107
|
logger.info('Deploying DAI Portal, initializing and deploying l2 contract...');
|
|
103
108
|
daiCrossChainHarness = await CrossChainTestHarness.new(
|
|
@@ -154,7 +159,6 @@ export const uniswapL1L2TestSuite = (
|
|
|
154
159
|
await cleanup();
|
|
155
160
|
});
|
|
156
161
|
|
|
157
|
-
// docs:start:uniswap_private
|
|
158
162
|
it('should uniswap trade on L1 from L2 funds privately (swaps WETH -> DAI)', async () => {
|
|
159
163
|
const wethL1BeforeBalance = await wethCrossChainHarness.getL1BalanceOf(ownerEthAddress);
|
|
160
164
|
|
|
@@ -251,10 +255,13 @@ export const uniswapL1L2TestSuite = (
|
|
|
251
255
|
// ensure that uniswap contract didn't eat the funds.
|
|
252
256
|
await wethCrossChainHarness.expectPublicBalanceOnL2(uniswapL2Contract.address, 0n);
|
|
253
257
|
|
|
254
|
-
// Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch
|
|
255
|
-
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
+
// Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch
|
|
259
|
+
// before we can ask the witness helper for a covering root.
|
|
260
|
+
const minedReceipt = await aztecNode.getTxReceipt(l2UniswapInteractionReceipt.txHash);
|
|
261
|
+
if (minedReceipt.epochNumber === undefined) {
|
|
262
|
+
throw new Error('L2 Uniswap interaction tx is not yet in an epoch');
|
|
263
|
+
}
|
|
264
|
+
await cheatCodes.rollup.advanceToEpoch(EpochNumber(minedReceipt.epochNumber + 1));
|
|
258
265
|
await waitForProven(aztecNode, l2UniswapInteractionReceipt, { provenTimeout: 300 });
|
|
259
266
|
|
|
260
267
|
// 5. Consume L2 to L1 message by calling uniswapPortal.swap_private()
|
|
@@ -262,17 +269,21 @@ export const uniswapL1L2TestSuite = (
|
|
|
262
269
|
const daiL1BalanceOfPortalBeforeSwap = await daiCrossChainHarness.getL1BalanceOf(
|
|
263
270
|
daiCrossChainHarness.tokenPortalAddress,
|
|
264
271
|
);
|
|
265
|
-
|
|
266
|
-
const
|
|
272
|
+
// Fetch the outbox roots once and share them between the two witnesses in this epoch.
|
|
273
|
+
const epochRoots = await wethCrossChainHarness.outboxContract.getRoots(minedReceipt.epochNumber);
|
|
274
|
+
const swapResult = (await computeL2ToL1MembershipWitness(aztecNode, epochRoots, swapPrivateLeaf, minedReceipt))!;
|
|
275
|
+
const { epochNumber: epoch, numCheckpointsInEpoch } = swapResult;
|
|
276
|
+
const withdrawResult = (await computeL2ToL1MembershipWitness(aztecNode, epochRoots, withdrawLeaf, minedReceipt))!;
|
|
267
277
|
|
|
268
|
-
const swapPrivateL2MessageIndex = swapResult
|
|
269
|
-
const swapPrivateSiblingPath = swapResult
|
|
278
|
+
const swapPrivateL2MessageIndex = swapResult.leafIndex;
|
|
279
|
+
const swapPrivateSiblingPath = swapResult.siblingPath;
|
|
270
280
|
|
|
271
|
-
const withdrawL2MessageIndex = withdrawResult
|
|
272
|
-
const withdrawSiblingPath = withdrawResult
|
|
281
|
+
const withdrawL2MessageIndex = withdrawResult.leafIndex;
|
|
282
|
+
const withdrawSiblingPath = withdrawResult.siblingPath;
|
|
273
283
|
|
|
274
284
|
const withdrawMessageMetadata = {
|
|
275
285
|
_epoch: BigInt(epoch),
|
|
286
|
+
_numCheckpointsInEpoch: BigInt(withdrawResult.numCheckpointsInEpoch),
|
|
276
287
|
_leafIndex: BigInt(withdrawL2MessageIndex),
|
|
277
288
|
_path: withdrawSiblingPath
|
|
278
289
|
.toBufferArray()
|
|
@@ -281,6 +292,7 @@ export const uniswapL1L2TestSuite = (
|
|
|
281
292
|
|
|
282
293
|
const swapPrivateMessageMetadata = {
|
|
283
294
|
_epoch: BigInt(epoch),
|
|
295
|
+
_numCheckpointsInEpoch: BigInt(numCheckpointsInEpoch),
|
|
284
296
|
_leafIndex: BigInt(swapPrivateL2MessageIndex),
|
|
285
297
|
_path: swapPrivateSiblingPath
|
|
286
298
|
.toBufferArray()
|
|
@@ -338,10 +350,8 @@ export const uniswapL1L2TestSuite = (
|
|
|
338
350
|
logger.info('WETH balance after swap : ', wethL2BalanceAfterSwap.toString());
|
|
339
351
|
logger.info('DAI balance after swap : ', daiL2BalanceAfterSwap.toString());
|
|
340
352
|
});
|
|
341
|
-
// docs:end:uniswap_private
|
|
342
353
|
|
|
343
354
|
// TODO(#7463): reenable look into this failure https://github.com/AztecProtocol/aztec-packages/actions/runs/9912612912/job/27388320150?pr=7462
|
|
344
|
-
// // docs:start:uniswap_public
|
|
345
355
|
// it('should uniswap trade on L1 from L2 funds publicly (swaps WETH -> DAI)', async () => {
|
|
346
356
|
// const wethL1BeforeBalance = await wethCrossChainHarness.getL1BalanceOf(ownerEthAddress);
|
|
347
357
|
|
|
@@ -574,7 +584,6 @@ export const uniswapL1L2TestSuite = (
|
|
|
574
584
|
// logger.info('WETH balance after swap : ', wethL2BalanceAfterSwap.toString());
|
|
575
585
|
// logger.info('DAI balance after swap : ', daiL2BalanceAfterSwap.toString());
|
|
576
586
|
// });
|
|
577
|
-
// // docs:end:uniswap_public
|
|
578
587
|
|
|
579
588
|
// Edge cases for the private flow:
|
|
580
589
|
// note - tests for uniswapPortal.sol and minting asset on L2 are covered in other tests.
|
|
@@ -840,19 +849,33 @@ export const uniswapL1L2TestSuite = (
|
|
|
840
849
|
chainId: new Fr(l1Client.chain.id),
|
|
841
850
|
});
|
|
842
851
|
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
852
|
+
// ensure that user's funds were burnt
|
|
853
|
+
await wethCrossChainHarness.expectPrivateBalanceOnL2(ownerAddress, wethL2BalanceBeforeSwap - wethAmountToBridge);
|
|
854
|
+
|
|
855
|
+
// Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch
|
|
856
|
+
// before we can ask the witness helper for a covering root.
|
|
857
|
+
const minedReceipt = await aztecNode.getTxReceipt(withdrawReceipt.txHash);
|
|
858
|
+
if (minedReceipt.epochNumber === undefined) {
|
|
859
|
+
throw new Error('Withdraw tx is not yet in an epoch');
|
|
860
|
+
}
|
|
861
|
+
await cheatCodes.rollup.advanceToEpoch(EpochNumber(minedReceipt.epochNumber + 1));
|
|
862
|
+
await waitForProven(aztecNode, withdrawReceipt, { provenTimeout: 300 });
|
|
863
|
+
|
|
864
|
+
// Fetch the outbox roots once and share them between the two witnesses in this epoch.
|
|
865
|
+
const epochRoots = await wethCrossChainHarness.outboxContract.getRoots(minedReceipt.epochNumber);
|
|
866
|
+
const swapResult = (await computeL2ToL1MembershipWitness(aztecNode, epochRoots, swapPrivateLeaf, minedReceipt))!;
|
|
867
|
+
const { epochNumber: epoch, numCheckpointsInEpoch } = swapResult;
|
|
868
|
+
const withdrawResult = (await computeL2ToL1MembershipWitness(aztecNode, epochRoots, withdrawLeaf, minedReceipt))!;
|
|
847
869
|
|
|
848
|
-
const swapPrivateL2MessageIndex = swapResult
|
|
849
|
-
const swapPrivateSiblingPath = swapResult
|
|
870
|
+
const swapPrivateL2MessageIndex = swapResult.leafIndex;
|
|
871
|
+
const swapPrivateSiblingPath = swapResult.siblingPath;
|
|
850
872
|
|
|
851
|
-
const withdrawL2MessageIndex = withdrawResult
|
|
852
|
-
const withdrawSiblingPath = withdrawResult
|
|
873
|
+
const withdrawL2MessageIndex = withdrawResult.leafIndex;
|
|
874
|
+
const withdrawSiblingPath = withdrawResult.siblingPath;
|
|
853
875
|
|
|
854
876
|
const withdrawMessageMetadata = {
|
|
855
877
|
_epoch: BigInt(epoch),
|
|
878
|
+
_numCheckpointsInEpoch: BigInt(withdrawResult.numCheckpointsInEpoch),
|
|
856
879
|
_leafIndex: BigInt(withdrawL2MessageIndex),
|
|
857
880
|
_path: withdrawSiblingPath
|
|
858
881
|
.toBufferArray()
|
|
@@ -861,19 +884,13 @@ export const uniswapL1L2TestSuite = (
|
|
|
861
884
|
|
|
862
885
|
const swapPrivateMessageMetadata = {
|
|
863
886
|
_epoch: BigInt(epoch),
|
|
887
|
+
_numCheckpointsInEpoch: BigInt(numCheckpointsInEpoch),
|
|
864
888
|
_leafIndex: BigInt(swapPrivateL2MessageIndex),
|
|
865
889
|
_path: swapPrivateSiblingPath
|
|
866
890
|
.toBufferArray()
|
|
867
891
|
.map((buf: Buffer) => `0x${buf.toString('hex')}`) as readonly `0x${string}`[],
|
|
868
892
|
};
|
|
869
893
|
|
|
870
|
-
// ensure that user's funds were burnt
|
|
871
|
-
await wethCrossChainHarness.expectPrivateBalanceOnL2(ownerAddress, wethL2BalanceBeforeSwap - wethAmountToBridge);
|
|
872
|
-
|
|
873
|
-
// Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch.
|
|
874
|
-
await cheatCodes.rollup.advanceToEpoch(EpochNumber(epoch + 1));
|
|
875
|
-
await waitForProven(aztecNode, withdrawReceipt, { provenTimeout: 300 });
|
|
876
|
-
|
|
877
894
|
// On L1 call swap_public!
|
|
878
895
|
logger.info('call swap_public on L1');
|
|
879
896
|
const swapArgs = [
|
|
@@ -973,19 +990,33 @@ export const uniswapL1L2TestSuite = (
|
|
|
973
990
|
chainId: new Fr(l1Client.chain.id),
|
|
974
991
|
});
|
|
975
992
|
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
993
|
+
// check weth balance of owner on L2 (we first bridged `wethAmountToBridge` into L2 and now withdrew it!)
|
|
994
|
+
await wethCrossChainHarness.expectPublicBalanceOnL2(ownerAddress, 0n);
|
|
995
|
+
|
|
996
|
+
// Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch
|
|
997
|
+
// before we can ask the witness helper for a covering root.
|
|
998
|
+
const minedReceipt = await aztecNode.getTxReceipt(withdrawReceipt.txHash);
|
|
999
|
+
if (minedReceipt.epochNumber === undefined) {
|
|
1000
|
+
throw new Error('Withdraw tx is not yet in an epoch');
|
|
1001
|
+
}
|
|
1002
|
+
await cheatCodes.rollup.advanceToEpoch(EpochNumber(minedReceipt.epochNumber + 1));
|
|
1003
|
+
await waitForProven(aztecNode, withdrawReceipt, { provenTimeout: 300 });
|
|
1004
|
+
|
|
1005
|
+
// Fetch the outbox roots once and share them between the two witnesses in this epoch.
|
|
1006
|
+
const epochRoots = await wethCrossChainHarness.outboxContract.getRoots(minedReceipt.epochNumber);
|
|
1007
|
+
const swapResult = (await computeL2ToL1MembershipWitness(aztecNode, epochRoots, swapPublicLeaf, minedReceipt))!;
|
|
1008
|
+
const { epochNumber: epoch, numCheckpointsInEpoch } = swapResult;
|
|
1009
|
+
const withdrawResult = (await computeL2ToL1MembershipWitness(aztecNode, epochRoots, withdrawLeaf, minedReceipt))!;
|
|
980
1010
|
|
|
981
|
-
const swapPublicL2MessageIndex = swapResult
|
|
982
|
-
const swapPublicSiblingPath = swapResult
|
|
1011
|
+
const swapPublicL2MessageIndex = swapResult.leafIndex;
|
|
1012
|
+
const swapPublicSiblingPath = swapResult.siblingPath;
|
|
983
1013
|
|
|
984
|
-
const withdrawL2MessageIndex = withdrawResult
|
|
985
|
-
const withdrawSiblingPath = withdrawResult
|
|
1014
|
+
const withdrawL2MessageIndex = withdrawResult.leafIndex;
|
|
1015
|
+
const withdrawSiblingPath = withdrawResult.siblingPath;
|
|
986
1016
|
|
|
987
1017
|
const withdrawMessageMetadata = {
|
|
988
1018
|
_epoch: BigInt(epoch),
|
|
1019
|
+
_numCheckpointsInEpoch: BigInt(withdrawResult.numCheckpointsInEpoch),
|
|
989
1020
|
_leafIndex: BigInt(withdrawL2MessageIndex),
|
|
990
1021
|
_path: withdrawSiblingPath
|
|
991
1022
|
.toBufferArray()
|
|
@@ -994,19 +1025,13 @@ export const uniswapL1L2TestSuite = (
|
|
|
994
1025
|
|
|
995
1026
|
const swapPublicMessageMetadata = {
|
|
996
1027
|
_epoch: BigInt(epoch),
|
|
1028
|
+
_numCheckpointsInEpoch: BigInt(numCheckpointsInEpoch),
|
|
997
1029
|
_leafIndex: BigInt(swapPublicL2MessageIndex),
|
|
998
1030
|
_path: swapPublicSiblingPath
|
|
999
1031
|
.toBufferArray()
|
|
1000
1032
|
.map((buf: Buffer) => `0x${buf.toString('hex')}`) as readonly `0x${string}`[],
|
|
1001
1033
|
};
|
|
1002
1034
|
|
|
1003
|
-
// check weth balance of owner on L2 (we first bridged `wethAmountToBridge` into L2 and now withdrew it!)
|
|
1004
|
-
await wethCrossChainHarness.expectPublicBalanceOnL2(ownerAddress, 0n);
|
|
1005
|
-
|
|
1006
|
-
// Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch.
|
|
1007
|
-
await cheatCodes.rollup.advanceToEpoch(EpochNumber(epoch + 1));
|
|
1008
|
-
await waitForProven(aztecNode, withdrawReceipt, { provenTimeout: 300 });
|
|
1009
|
-
|
|
1010
1035
|
// Call swap_private on L1
|
|
1011
1036
|
logger.info('Execute withdraw and swap on the uniswapPortal!');
|
|
1012
1037
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Fr } from '@aztec/aztec.js/fields';
|
|
2
|
+
import type { AztecNode } from '@aztec/aztec.js/node';
|
|
3
|
+
import { retryUntil } from '@aztec/foundation/retry';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Waits until the archiver has seen the L1 to L2 message and indexed it. Unlike
|
|
7
|
+
* {@link waitForL1ToL2MessageReady} from `@aztec/aztec.js/messaging`, this does not
|
|
8
|
+
* require the L2 chain to have advanced to the message's checkpoint — it only confirms
|
|
9
|
+
* the message has been picked up from L1. Use this in tests that explicitly produce L2
|
|
10
|
+
* blocks afterwards to make the message consumable.
|
|
11
|
+
*/
|
|
12
|
+
export function waitForL1ToL2MessageSeen(
|
|
13
|
+
node: Pick<AztecNode, 'getL1ToL2MessageCheckpoint'>,
|
|
14
|
+
l1ToL2MessageHash: Fr,
|
|
15
|
+
opts: { timeoutSeconds: number },
|
|
16
|
+
) {
|
|
17
|
+
return retryUntil(
|
|
18
|
+
async () => (await node.getL1ToL2MessageCheckpoint(l1ToL2MessageHash)) !== undefined,
|
|
19
|
+
`L1 to L2 message ${l1ToL2MessageHash.toString()} seen`,
|
|
20
|
+
opts.timeoutSeconds,
|
|
21
|
+
1,
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -7,6 +7,7 @@ import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
|
7
7
|
import { poseidon2Hash } from '@aztec/foundation/crypto/poseidon';
|
|
8
8
|
import type { TestDateProvider } from '@aztec/foundation/timer';
|
|
9
9
|
import type { LendingContract } from '@aztec/noir-contracts.js/Lending';
|
|
10
|
+
import type { AztecNode, AztecNodeDebug } from '@aztec/stdlib/interfaces/client';
|
|
10
11
|
|
|
11
12
|
import type { TokenSimulator } from './token_simulator.js';
|
|
12
13
|
|
|
@@ -92,30 +93,45 @@ export class LendingSimulator {
|
|
|
92
93
|
public stableCoin: TokenSimulator,
|
|
93
94
|
) {}
|
|
94
95
|
|
|
95
|
-
|
|
96
|
+
prepare() {
|
|
96
97
|
this.accumulator = BASE;
|
|
97
|
-
|
|
98
|
-
this.time = Number(await this.rollup.getTimestampForSlot(slot));
|
|
98
|
+
this.time = 0;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
/**
|
|
102
|
+
* Advances the simulator's accumulator and clock to match a block timestamp observed on chain.
|
|
103
|
+
* Call this BEFORE applying any accumulator-sensitive mutation (borrow/repay) so the mutation
|
|
104
|
+
* sees the same accumulator as the contract did during execution.
|
|
105
|
+
*/
|
|
106
|
+
observeBlockTimestamp(ts: number) {
|
|
107
|
+
const diff = ts - this.time;
|
|
108
|
+
if (diff > 0) {
|
|
109
|
+
this.accumulator = muldivDown(this.accumulator, computeMultiplier(this.rate, BigInt(diff)), BASE);
|
|
110
|
+
}
|
|
111
|
+
this.time = ts;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async progressSlots(diff: number, _dateProvider?: TestDateProvider, node?: AztecNode & AztecNodeDebug) {
|
|
102
115
|
if (diff <= 1) {
|
|
103
116
|
return;
|
|
104
117
|
}
|
|
105
118
|
|
|
106
|
-
const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.
|
|
119
|
+
const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.lastBlockTimestamp()));
|
|
107
120
|
const targetSlot = SlotNumber(slot + diff);
|
|
108
121
|
const ts = Number(await this.rollup.getTimestampForSlot(targetSlot));
|
|
109
|
-
const timeDiff = ts - this.time;
|
|
110
|
-
this.time = ts;
|
|
111
122
|
|
|
112
|
-
//
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
123
|
+
// Queue-aware warp under AutomineSequencer: atomic warp + mineBlock that advances L2 time to the
|
|
124
|
+
// target slot. The cheat code routes through the AutomineSequencer queue when one is installed,
|
|
125
|
+
// and otherwise falls back to a manual warp + mineBlock loop.
|
|
126
|
+
if (node) {
|
|
127
|
+
await this.cc.warpL2TimeAtLeastTo(node, ts);
|
|
128
|
+
} else {
|
|
129
|
+
await this.cc.eth.warp(ts - this.ethereumSlotDuration);
|
|
116
130
|
}
|
|
131
|
+
|
|
132
|
+
// Mark the latest checkpoint as proven so the rollup does not reorg pending checkpoints when
|
|
133
|
+
// time jumps far enough forward to cross an unproven epoch boundary.
|
|
117
134
|
await this.cc.rollup.markAsProven(await this.rollup.getCheckpointNumber());
|
|
118
|
-
this.accumulator = muldivDown(this.accumulator, computeMultiplier(this.rate, BigInt(timeDiff)), BASE);
|
|
119
135
|
}
|
|
120
136
|
|
|
121
137
|
depositPrivate(from: AztecAddress, onBehalfOf: Fr, amount: bigint) {
|
|
@@ -110,7 +110,7 @@ export class TokenSimulator {
|
|
|
110
110
|
chunk(calls, 5).map(batch => new BatchCall(this.defaultWallet, batch).simulate({ from: this.defaultAddress })),
|
|
111
111
|
)
|
|
112
112
|
)
|
|
113
|
-
.
|
|
113
|
+
.flatMap(r => r.result)
|
|
114
114
|
.map(r => r.result);
|
|
115
115
|
expect(results[0]).toEqual(this.totalSupply);
|
|
116
116
|
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { generateSchnorrAccounts } from '@aztec/accounts/testing';
|
|
2
|
+
import { NO_FROM } from '@aztec/aztec.js/account';
|
|
2
3
|
import { AztecAddress } from '@aztec/aztec.js/addresses';
|
|
3
4
|
import { NO_WAIT } from '@aztec/aztec.js/contracts';
|
|
4
5
|
import { L1FeeJuicePortalManager } from '@aztec/aztec.js/ethereum';
|
|
5
6
|
import { FeeJuicePaymentMethodWithClaim } from '@aztec/aztec.js/fee';
|
|
6
7
|
import { type FeePaymentMethod, SponsoredFeePaymentMethod } from '@aztec/aztec.js/fee';
|
|
7
8
|
import { Fr } from '@aztec/aztec.js/fields';
|
|
9
|
+
import { waitForL1ToL2MessageReady } from '@aztec/aztec.js/messaging';
|
|
8
10
|
import { type AztecNode, createAztecNodeClient, waitForTx } from '@aztec/aztec.js/node';
|
|
9
11
|
import type { Wallet } from '@aztec/aztec.js/wallet';
|
|
10
12
|
import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
11
13
|
import { createExtendedL1Client } from '@aztec/ethereum/client';
|
|
12
14
|
import type { Logger } from '@aztec/foundation/log';
|
|
13
|
-
import { retryUntil } from '@aztec/foundation/retry';
|
|
15
|
+
import { makeBackoff, retry, retryUntil } from '@aztec/foundation/retry';
|
|
14
16
|
import { TokenContract } from '@aztec/noir-contracts.js/Token';
|
|
15
17
|
import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
16
18
|
import { registerInitialLocalNetworkAccountsInWallet } from '@aztec/wallets/testing';
|
|
@@ -89,7 +91,7 @@ export async function deploySponsoredTestAccountsWithTokens(
|
|
|
89
91
|
const paymentMethod = new SponsoredFeePaymentMethod(await getSponsoredFPCAddress());
|
|
90
92
|
const recipientDeployMethod = await recipientAccount.getDeployMethod();
|
|
91
93
|
await recipientDeployMethod.send({
|
|
92
|
-
from:
|
|
94
|
+
from: NO_FROM,
|
|
93
95
|
fee: { paymentMethod },
|
|
94
96
|
wait: { timeout: 2400 },
|
|
95
97
|
});
|
|
@@ -97,7 +99,7 @@ export async function deploySponsoredTestAccountsWithTokens(
|
|
|
97
99
|
fundedAccounts.map(async a => {
|
|
98
100
|
const deployMethod = await a.getDeployMethod();
|
|
99
101
|
await deployMethod.send({
|
|
100
|
-
from:
|
|
102
|
+
from: NO_FROM,
|
|
101
103
|
fee: { paymentMethod },
|
|
102
104
|
wait: { timeout: 2400 },
|
|
103
105
|
}); // increase timeout on purpose in order to account for two empty epochs
|
|
@@ -129,50 +131,91 @@ export async function deploySponsoredTestAccountsWithTokens(
|
|
|
129
131
|
}
|
|
130
132
|
|
|
131
133
|
async function deployAccountWithDiagnostics(
|
|
132
|
-
account: { getDeployMethod: () => Promise<{ send: (opts: any) => any }>; address: any },
|
|
134
|
+
account: { getDeployMethod: () => Promise<{ simulate: (opts: any) => any; send: (opts: any) => any }>; address: any },
|
|
133
135
|
paymentMethod: SponsoredFeePaymentMethod,
|
|
134
136
|
aztecNode: AztecNode,
|
|
135
137
|
logger: Logger,
|
|
136
138
|
accountLabel: string,
|
|
139
|
+
estimateGas?: boolean,
|
|
137
140
|
): Promise<void> {
|
|
138
141
|
const deployMethod = await account.getDeployMethod();
|
|
139
|
-
let
|
|
140
|
-
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
logger.info(`${accountLabel} deployed at ${account.address}`);
|
|
145
|
-
} catch (error) {
|
|
146
|
-
const blockNumber = await aztecNode.getBlockNumber();
|
|
147
|
-
let receipt;
|
|
148
|
-
try {
|
|
149
|
-
receipt = await aztecNode.getTxReceipt(txHash);
|
|
150
|
-
} catch {
|
|
151
|
-
receipt = 'unavailable';
|
|
152
|
-
}
|
|
153
|
-
logger.error(`${accountLabel} deployment failed`, {
|
|
154
|
-
txHash: txHash.toString(),
|
|
155
|
-
receipt: JSON.stringify(receipt),
|
|
156
|
-
currentBlockNumber: blockNumber,
|
|
157
|
-
error: String(error),
|
|
158
|
-
});
|
|
159
|
-
throw error;
|
|
142
|
+
let gasSettings: any;
|
|
143
|
+
if (estimateGas) {
|
|
144
|
+
const sim = await deployMethod.simulate({ from: NO_FROM, fee: { paymentMethod } });
|
|
145
|
+
gasSettings = sim.estimatedGas;
|
|
146
|
+
logger.info(`${accountLabel} estimated gas: DA=${gasSettings.gasLimits.daGas} L2=${gasSettings.gasLimits.l2Gas}`);
|
|
160
147
|
}
|
|
148
|
+
|
|
149
|
+
// Track the tx hash across retries so we don't re-send when the previous tx is still pending.
|
|
150
|
+
let sentTxHash: { txHash: any } | undefined;
|
|
151
|
+
|
|
152
|
+
await retry(
|
|
153
|
+
async () => {
|
|
154
|
+
// Check if already deployed (handles case where previous attempt succeeded but waitForTx timed out)
|
|
155
|
+
const existing = await aztecNode.getContract(account.address);
|
|
156
|
+
if (existing) {
|
|
157
|
+
logger.info(`${accountLabel} already deployed at ${account.address}, skipping`);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// If we already sent a tx, check if it was dropped before deciding to re-send.
|
|
162
|
+
if (sentTxHash) {
|
|
163
|
+
const prevReceipt = await aztecNode.getTxReceipt(sentTxHash.txHash);
|
|
164
|
+
if (prevReceipt.isDropped()) {
|
|
165
|
+
logger.info(`${accountLabel} previous tx ${sentTxHash.txHash} was dropped, re-sending`);
|
|
166
|
+
sentTxHash = undefined;
|
|
167
|
+
} else {
|
|
168
|
+
logger.info(`${accountLabel} previous tx ${sentTxHash.txHash} still pending, waiting again...`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (!sentTxHash) {
|
|
173
|
+
const deployResult = await deployMethod.send({
|
|
174
|
+
from: NO_FROM,
|
|
175
|
+
fee: { paymentMethod, gasSettings },
|
|
176
|
+
wait: NO_WAIT,
|
|
177
|
+
});
|
|
178
|
+
sentTxHash = { txHash: deployResult.txHash };
|
|
179
|
+
logger.info(`${accountLabel} tx sent`, { txHash: sentTxHash.txHash.toString() });
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const receipt = await waitForTx(aztecNode, sentTxHash.txHash, { timeout: 600 });
|
|
183
|
+
if (receipt.isDropped()) {
|
|
184
|
+
sentTxHash = undefined;
|
|
185
|
+
throw new Error(`${accountLabel} tx was dropped, retrying...`);
|
|
186
|
+
}
|
|
187
|
+
logger.info(`${accountLabel} deployed at ${account.address}`);
|
|
188
|
+
},
|
|
189
|
+
`deploy ${accountLabel}`,
|
|
190
|
+
makeBackoff([1, 2, 4, 8, 16]),
|
|
191
|
+
logger,
|
|
192
|
+
);
|
|
161
193
|
}
|
|
162
194
|
|
|
163
195
|
async function deployAccountsInBatches(
|
|
164
|
-
accounts: {
|
|
196
|
+
accounts: {
|
|
197
|
+
getDeployMethod: () => Promise<{ simulate: (opts: any) => any; send: (opts: any) => any }>;
|
|
198
|
+
address: any;
|
|
199
|
+
}[],
|
|
165
200
|
paymentMethod: SponsoredFeePaymentMethod,
|
|
166
201
|
aztecNode: AztecNode,
|
|
167
202
|
logger: Logger,
|
|
168
203
|
labelPrefix: string,
|
|
169
204
|
batchSize = 2,
|
|
205
|
+
estimateGas?: boolean,
|
|
170
206
|
): Promise<void> {
|
|
171
207
|
for (let i = 0; i < accounts.length; i += batchSize) {
|
|
172
208
|
const batch = accounts.slice(i, i + batchSize);
|
|
173
209
|
await Promise.all(
|
|
174
210
|
batch.map((account, idx) =>
|
|
175
|
-
deployAccountWithDiagnostics(
|
|
211
|
+
deployAccountWithDiagnostics(
|
|
212
|
+
account,
|
|
213
|
+
paymentMethod,
|
|
214
|
+
aztecNode,
|
|
215
|
+
logger,
|
|
216
|
+
`${labelPrefix}${i + idx + 1}`,
|
|
217
|
+
estimateGas,
|
|
218
|
+
),
|
|
176
219
|
),
|
|
177
220
|
);
|
|
178
221
|
}
|
|
@@ -183,6 +226,7 @@ export async function deploySponsoredTestAccounts(
|
|
|
183
226
|
aztecNode: AztecNode,
|
|
184
227
|
logger: Logger,
|
|
185
228
|
numberOfFundedWallets = 1,
|
|
229
|
+
opts?: { estimateGas?: boolean },
|
|
186
230
|
): Promise<TestAccountsWithoutTokens> {
|
|
187
231
|
const [recipient, ...funded] = await generateSchnorrAccounts(numberOfFundedWallets + 1);
|
|
188
232
|
const recipientAccount = await wallet.createSchnorrAccount(recipient.secret, recipient.salt);
|
|
@@ -192,8 +236,23 @@ export async function deploySponsoredTestAccounts(
|
|
|
192
236
|
|
|
193
237
|
const paymentMethod = new SponsoredFeePaymentMethod(await getSponsoredFPCAddress());
|
|
194
238
|
|
|
195
|
-
await deployAccountWithDiagnostics(
|
|
196
|
-
|
|
239
|
+
await deployAccountWithDiagnostics(
|
|
240
|
+
recipientAccount,
|
|
241
|
+
paymentMethod,
|
|
242
|
+
aztecNode,
|
|
243
|
+
logger,
|
|
244
|
+
'Recipient account',
|
|
245
|
+
opts?.estimateGas,
|
|
246
|
+
);
|
|
247
|
+
await deployAccountsInBatches(
|
|
248
|
+
fundedAccounts,
|
|
249
|
+
paymentMethod,
|
|
250
|
+
aztecNode,
|
|
251
|
+
logger,
|
|
252
|
+
'Funded account ',
|
|
253
|
+
2,
|
|
254
|
+
opts?.estimateGas,
|
|
255
|
+
);
|
|
197
256
|
|
|
198
257
|
return {
|
|
199
258
|
aztecNode,
|
|
@@ -231,7 +290,7 @@ export async function deployTestAccountsWithTokens(
|
|
|
231
290
|
fundedAccounts.map(async (a, i) => {
|
|
232
291
|
const paymentMethod = new FeeJuicePaymentMethodWithClaim(a.address, claims[i]);
|
|
233
292
|
const deployMethod = await a.getDeployMethod();
|
|
234
|
-
await deployMethod.send({ from:
|
|
293
|
+
await deployMethod.send({ from: NO_FROM, fee: { paymentMethod } });
|
|
235
294
|
logger.info(`Account deployed at ${a.address}`);
|
|
236
295
|
}),
|
|
237
296
|
);
|
|
@@ -274,9 +333,7 @@ async function bridgeL1FeeJuice(
|
|
|
274
333
|
const portal = await L1FeeJuicePortalManager.new(aztecNode, l1Client, log);
|
|
275
334
|
const claim = await portal.bridgeTokensPublic(recipient, amount, true /* mint */);
|
|
276
335
|
|
|
277
|
-
|
|
278
|
-
(await aztecNode.getL1ToL2MessageCheckpoint(Fr.fromHexString(claim.messageHash))) !== undefined;
|
|
279
|
-
await retryUntil(isSynced, `message ${claim.messageHash} sync`, 24, 0.5);
|
|
336
|
+
await waitForL1ToL2MessageReady(aztecNode, Fr.fromHexString(claim.messageHash), { timeoutSeconds: 24 });
|
|
280
337
|
|
|
281
338
|
log.info(`Created a claim for ${amount} L1 fee juice to ${recipient}.`, claim);
|
|
282
339
|
return claim;
|
|
@@ -307,14 +364,18 @@ async function deployTokenAndMint(
|
|
|
307
364
|
logger: Logger,
|
|
308
365
|
) {
|
|
309
366
|
logger.verbose(`Deploying TokenContract...`);
|
|
310
|
-
const {
|
|
311
|
-
|
|
312
|
-
|
|
367
|
+
const { contract: tokenContract } = await TokenContract.deploy(
|
|
368
|
+
wallet,
|
|
369
|
+
admin,
|
|
370
|
+
TOKEN_NAME,
|
|
371
|
+
TOKEN_SYMBOL,
|
|
372
|
+
TOKEN_DECIMALS,
|
|
373
|
+
).send({
|
|
313
374
|
from: admin,
|
|
314
375
|
fee: {
|
|
315
376
|
paymentMethod,
|
|
316
377
|
},
|
|
317
|
-
wait: { timeout: 600
|
|
378
|
+
wait: { timeout: 600 },
|
|
318
379
|
});
|
|
319
380
|
|
|
320
381
|
const tokenAddress = tokenContract.address;
|