From 661b15353e0bdec19cf23e6fe51dbdf76b2812b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Torres?= <30977845+Torres-ssf@users.noreply.github.com> Date: Wed, 10 Jul 2024 14:30:29 -0300 Subject: [PATCH] feat!: implement non-blocking contract call (#2692) --- .changeset/spicy-trains-provide.md | 6 + .../src/app/page.tsx | 7 +- apps/demo-bun-fuels/src/bun.test.ts | 19 +- apps/demo-fuels/src/index.test.ts | 17 +- apps/demo-typegen/src/demo.test.ts | 20 +- .../src/guide/contracts/add-transfer.test.ts | 11 +- .../guide/contracts/call-parameters.test.ts | 17 +- .../guide/contracts/contract-balance.test.ts | 4 +- .../contracts/deploying-contracts.test.ts | 4 +- .../contracts/inter-contract-calls.test.ts | 16 +- .../interacting-with-contracts.test.ts | 22 +- .../contracts/is-function-readonly.test.ts | 3 +- .../src/guide/contracts/logs.test.ts | 6 +- .../contracts/minted-token-asset-id.test.ts | 3 +- .../src/guide/contracts/multicalls.test.ts | 11 +- .../guide/contracts/variable-outputs.test.ts | 7 +- .../cookbook/deposit-and-withdraw.test.ts | 8 +- .../cookbook/signing-transactions.test.ts | 4 +- .../scripts/script-with-configurable.test.ts | 6 +- .../testing/launching-a-test-node.test.ts | 3 +- .../transaction-parameters.test.ts | 4 +- .../transactions/transaction-response.test.ts | 8 +- .../src/guide/types/numbers.test.ts | 6 +- .../src/guide/types/vector.test.ts | 4 +- .../guide/utilities/unit-conversion.test.ts | 3 +- apps/docs/src/guide/contracts/methods.md | 2 +- .../src/test-utils/launch-test-node.test.ts | 22 +- .../fuel-gauge/src/advanced-logging.test.ts | 19 +- packages/fuel-gauge/src/auth-testing.test.ts | 7 +- .../fuel-gauge/src/bytecode-sway-lib.test.ts | 12 +- packages/fuel-gauge/src/bytes.test.ts | 21 +- .../fuel-gauge/src/call-test-contract.test.ts | 47 ++- .../fuel-gauge/src/contract-factory.test.ts | 43 ++- packages/fuel-gauge/src/contract.test.ts | 138 +++++--- .../fuel-gauge/src/coverage-contract.test.ts | 324 +++++++++++------- packages/fuel-gauge/src/e2e-script.test.ts | 3 +- packages/fuel-gauge/src/edge-cases.test.ts | 4 +- packages/fuel-gauge/src/fee.test.ts | 38 +- .../src/generic-types-contract.test.ts | 11 +- .../src/multi-token-contract.test.ts | 178 +++++----- packages/fuel-gauge/src/options.test.ts | 97 +++--- packages/fuel-gauge/src/policies.test.ts | 8 +- .../predicate/predicate-with-contract.test.ts | 13 +- .../predicate/predicate-with-script.test.ts | 4 +- packages/fuel-gauge/src/raw-slice.test.ts | 16 +- .../src/reentrant-contract-calls.test.ts | 18 +- packages/fuel-gauge/src/revert-error.test.ts | 11 +- .../fuel-gauge/src/script-main-args.test.ts | 10 +- .../src/script-with-configurable.test.ts | 12 +- .../src/script-with-vectors.test.ts | 12 +- .../fuel-gauge/src/std-lib-string.test.ts | 13 +- .../src/storage-test-contract.test.ts | 18 +- packages/fuel-gauge/src/str-slice.test.ts | 7 +- .../src/token-test-contract.test.ts | 25 +- .../src/transaction-summary.test.ts | 43 ++- packages/fuel-gauge/src/vector-types.test.ts | 9 +- packages/fuel-gauge/src/vectors.test.ts | 111 ++++-- .../src/functions/base-invocation-scope.ts | 49 ++- templates/nextjs/src/app/page.tsx | 7 +- templates/nextjs/src/app/script/page.tsx | 3 +- 60 files changed, 1011 insertions(+), 563 deletions(-) create mode 100644 .changeset/spicy-trains-provide.md diff --git a/.changeset/spicy-trains-provide.md b/.changeset/spicy-trains-provide.md new file mode 100644 index 0000000000..333fd82d22 --- /dev/null +++ b/.changeset/spicy-trains-provide.md @@ -0,0 +1,6 @@ +--- +"@fuel-ts/contract": minor +"@fuel-ts/program": minor +--- + +feat!: implement non-blocking contract call diff --git a/apps/create-fuels-counter-guide/src/app/page.tsx b/apps/create-fuels-counter-guide/src/app/page.tsx index e62a225786..2f0339a9b0 100644 --- a/apps/create-fuels-counter-guide/src/app/page.tsx +++ b/apps/create-fuels-counter-guide/src/app/page.tsx @@ -50,7 +50,8 @@ export default function Home() { ); } - const { value } = await contract.functions.increment_counter(bn(1)).call(); + const { waitForResult } = await contract.functions.increment_counter(bn(1)).call(); + const { value } = await waitForResult(); setCounter(value.toNumber()); await refreshWalletBalance?.(); @@ -68,7 +69,9 @@ export default function Home() { ); } - const { value } = await contract.functions.decrement_counter(bn(1)).call(); + const { waitForResult } = await contract.functions.decrement_counter(bn(1)).call(); + const { value } = await waitForResult(); + setCounter(value.toNumber()); await refreshWalletBalance?.(); diff --git a/apps/demo-bun-fuels/src/bun.test.ts b/apps/demo-bun-fuels/src/bun.test.ts index ccd805c089..6af92e2dbb 100644 --- a/apps/demo-bun-fuels/src/bun.test.ts +++ b/apps/demo-bun-fuels/src/bun.test.ts @@ -32,14 +32,20 @@ describe('ExampleContract', () => { const { contract } = await waitForResult(); // Call - const { value } = await contract.functions.return_input(1337).call(); + const call1 = await contract.functions.return_input(1337).call(); + + // Wait for result + const { value } = await call1.waitForResult(); // Assert expect(value.toHex()).toEqual(toHex(1337)); // You can also make a call using the factory const contractInstance = SampleAbi__factory.connect(contract.id, wallet); - const { value: v2 } = await contractInstance.functions.return_input(1337).call(); + const call2 = await contractInstance.functions.return_input(1337).call(); + + // Wait for result + const { value: v2 } = await call2.waitForResult(); expect(v2.toHex()).toBe(toHex(1337)); }); @@ -48,11 +54,14 @@ describe('ExampleContract', () => { const wallet = await generateTestWallet(provider, [[500_000, baseAssetId]]); // Deploy - const { waitForResult } = await SampleAbi__factory.deployContract(bytecode, wallet); - const { contract } = await waitForResult(); + const deploy = await SampleAbi__factory.deployContract(bytecode, wallet); + const { contract } = await deploy.waitForResult(); // Call - const { value } = await contract.functions.return_input(1337).call(); + const { waitForResult } = await contract.functions.return_input(1337).call(); + + // Wait for result + const { value } = await waitForResult(); // Assert expect(value.toHex()).toEqual(toHex(1337)); diff --git a/apps/demo-fuels/src/index.test.ts b/apps/demo-fuels/src/index.test.ts index 0e22ee3413..d958543760 100644 --- a/apps/demo-fuels/src/index.test.ts +++ b/apps/demo-fuels/src/index.test.ts @@ -28,18 +28,20 @@ describe('ExampleContract', () => { // Deploy const factory = new ContractFactory(bytecode, SampleAbi__factory.abi, wallet); - const { waitForResult } = await factory.deployContract(); - const { contract } = await waitForResult(); + const deploy = await factory.deployContract(); + const { contract } = await deploy.waitForResult(); // Call - const { value } = await contract.functions.return_input(1337).call(); + const { waitForResult } = await contract.functions.return_input(1337).call(); + const { value } = await waitForResult(); // Assert expect(value.toHex()).toEqual(toHex(1337)); // You can also make a call using the factory const contractInstance = SampleAbi__factory.connect(contract.id, wallet); - const { value: v2 } = await contractInstance.functions.return_input(1337).call(); + const call2 = await contractInstance.functions.return_input(1337).call(); + const { value: v2 } = await call2.waitForResult(); expect(v2.toHex()).toBe(toHex(1337)); }); @@ -48,11 +50,12 @@ describe('ExampleContract', () => { const wallet = await generateTestWallet(provider, [[500_000, baseAssetId]]); // Deploy - const { waitForResult } = await SampleAbi__factory.deployContract(bytecode, wallet); - const { contract } = await waitForResult(); + const deploy = await SampleAbi__factory.deployContract(bytecode, wallet); + const { contract } = await deploy.waitForResult(); // Call - const { value } = await contract.functions.return_input(1337).call(); + const { waitForResult } = await contract.functions.return_input(1337).call(); + const { value } = await waitForResult(); // Assert expect(value.toHex()).toEqual(toHex(1337)); diff --git a/apps/demo-typegen/src/demo.test.ts b/apps/demo-typegen/src/demo.test.ts index bf58d3e7db..2aacfd77a0 100644 --- a/apps/demo-typegen/src/demo.test.ts +++ b/apps/demo-typegen/src/demo.test.ts @@ -41,12 +41,13 @@ describe('ExampleContract', () => { // Deploy const factory = new ContractFactory(bytecode, DemoContractAbi__factory.abi, wallet); - const { waitForResult } = await factory.deployContract(); - const { contract } = await waitForResult(); + const deploy = await factory.deployContract(); + const { contract } = await deploy.waitForResult(); const contractId = contract.id; // Call - const { value } = await contract.functions.return_input(1337).call(); + const { waitForResult } = await contract.functions.return_input(1337).call(); + const { value } = await waitForResult(); // Assert expect(value.toHex()).toEqual(toHex(1337)); @@ -56,7 +57,8 @@ describe('ExampleContract', () => { // #context import { DemoContractAbi__factory } from './types'; const contractInstance = DemoContractAbi__factory.connect(contractId, wallet); - const { value: v2 } = await contractInstance.functions.return_input(1337).call(); + const call2 = await contractInstance.functions.return_input(1337).call(); + const { value: v2 } = await call2.waitForResult(); // #endregion typegen-demo-contract-factory-connect expect(v2.toHex()).toBe(toHex(1337)); }); @@ -70,13 +72,14 @@ describe('ExampleContract', () => { // #context import bytecode from './types/DemoContractAbi.hex'; // Deploy - const { waitForResult } = await DemoContractAbi__factory.deployContract(bytecode, wallet); - const { contract } = await waitForResult(); + const deploy = await DemoContractAbi__factory.deployContract(bytecode, wallet); + const { contract } = await deploy.waitForResult(); // #endregion typegen-demo-contract-factory-deploy // Call - const { value } = await contract.functions.return_input(1337).call(); + const { waitForResult } = await contract.functions.return_input(1337).call(); + const { value } = await waitForResult(); // Assert expect(value.toHex()).toEqual(toHex(1337)); @@ -120,7 +123,8 @@ test('Example script', async () => { // #context import { ScriptAbi__factory } from './types'; const script = ScriptAbi__factory.createInstance(wallet); - const { value } = await script.functions.main().call(); + const { waitForResult } = await script.functions.main().call(); + const { value } = await waitForResult(); // #endregion typegen-demo-script expect(value).toStrictEqual(10); }); diff --git a/apps/docs-snippets/src/guide/contracts/add-transfer.test.ts b/apps/docs-snippets/src/guide/contracts/add-transfer.test.ts index ba453a6ad2..dba7a010c7 100644 --- a/apps/docs-snippets/src/guide/contracts/add-transfer.test.ts +++ b/apps/docs-snippets/src/guide/contracts/add-transfer.test.ts @@ -31,7 +31,7 @@ describe(__filename, () => { // #region add-transfer-1 const recipient = Wallet.generate({ provider }); - await contract.functions + const { waitForResult } = await contract.functions .echo_u64(100) .addTransfer({ destination: recipient.address, @@ -39,6 +39,8 @@ describe(__filename, () => { assetId: baseAssetId, }) .call(); + + await waitForResult(); // #endregion add-transfer-1 const recipientBalance = await recipient.getBalance(baseAssetId); @@ -57,7 +59,12 @@ describe(__filename, () => { { destination: recipient2.address, amount: 300, assetId: ASSET_B }, ]; - await contract.functions.echo_u64(100).addBatchTransfer(transferParams).call(); + const { waitForResult } = await contract.functions + .echo_u64(100) + .addBatchTransfer(transferParams) + .call(); + + await waitForResult(); // #endregion add-transfer-2 const recipient1BalanceBaseAsset = await recipient1.getBalance(baseAssetId); diff --git a/apps/docs-snippets/src/guide/contracts/call-parameters.test.ts b/apps/docs-snippets/src/guide/contracts/call-parameters.test.ts index 8e0dc3f739..f13033ce65 100644 --- a/apps/docs-snippets/src/guide/contracts/call-parameters.test.ts +++ b/apps/docs-snippets/src/guide/contracts/call-parameters.test.ts @@ -21,13 +21,15 @@ describe(__filename, () => { // #region call-params-1 const amountToForward = 10; - const { value } = await contract.functions + const { waitForResult } = await contract.functions .return_context_amount() .callParams({ forward: [amountToForward, baseAssetId], }) .call(); + const { value } = await waitForResult(); + expect(new BN(value).toNumber()).toBe(amountToForward); // #endregion call-params-1 }); @@ -35,15 +37,17 @@ describe(__filename, () => { it('should throw error due not enough gas', async () => { // #region call-params-2 - await expect( - contract.functions + await expect(async () => { + const call = await contract.functions .return_context_amount() .callParams({ forward: [10, baseAssetId], gasLimit: 1, }) - .call() - ).rejects.toThrow('The transaction reverted with reason: "OutOfGas"'); + .call(); + + await call.waitForResult(); + }).rejects.toThrow('The transaction reverted with reason: "OutOfGas"'); // #endregion call-params-2 }); @@ -53,7 +57,7 @@ describe(__filename, () => { const contractCallGasLimit = 4000; const transactionGasLimit = 100_000; - const result = await contract.functions + const { waitForResult } = await contract.functions .return_context_amount() .callParams({ forward: [amountToForward, baseAssetId], @@ -64,6 +68,7 @@ describe(__filename, () => { }) .call(); + const result = await waitForResult(); const { value } = result; const expectedValue = 10; diff --git a/apps/docs-snippets/src/guide/contracts/contract-balance.test.ts b/apps/docs-snippets/src/guide/contracts/contract-balance.test.ts index c06266d632..6e8e6bda28 100644 --- a/apps/docs-snippets/src/guide/contracts/contract-balance.test.ts +++ b/apps/docs-snippets/src/guide/contracts/contract-balance.test.ts @@ -32,13 +32,15 @@ describe(__filename, () => { bits: baseAssetId, }; - await contract.functions + const { waitForResult } = await contract.functions .transfer(amountToTransfer, asset, recipient.address.toB256()) .callParams({ forward: [amountToForward, baseAssetId], }) .call(); + await waitForResult(); + const contractBalance = await contract.getBalance(baseAssetId); const expectedBalance = amountToForward - amountToTransfer; diff --git a/apps/docs-snippets/src/guide/contracts/deploying-contracts.test.ts b/apps/docs-snippets/src/guide/contracts/deploying-contracts.test.ts index 5efc4f500c..207ea7a7e7 100644 --- a/apps/docs-snippets/src/guide/contracts/deploying-contracts.test.ts +++ b/apps/docs-snippets/src/guide/contracts/deploying-contracts.test.ts @@ -52,7 +52,9 @@ describe(__filename, () => { // #endregion contract-setup-4 // #region contract-setup-5 - const { value } = await contract.functions.echo_u8(15).call(); + const call = await contract.functions.echo_u8(15).call(); + + const { value } = await call.waitForResult(); // #endregion contract-setup-5 expect(transactionId).toBeDefined(); diff --git a/apps/docs-snippets/src/guide/contracts/inter-contract-calls.test.ts b/apps/docs-snippets/src/guide/contracts/inter-contract-calls.test.ts index 73a71094f0..ba5676fc1e 100644 --- a/apps/docs-snippets/src/guide/contracts/inter-contract-calls.test.ts +++ b/apps/docs-snippets/src/guide/contracts/inter-contract-calls.test.ts @@ -41,20 +41,22 @@ describe(__filename, () => { it('should successfully make call to another contract', async () => { // #region inter-contract-calls-3 const amountToDeposit = 70; - const { value: initialBalance } = await simpleToken.functions - .get_balance(wallet.address.toB256()) - .call(); + const call1 = await simpleToken.functions.get_balance(wallet.address.toB256()).call(); + + const { value: initialBalance } = await call1.waitForResult(); expect(new BN(initialBalance).toNumber()).toBe(0); - await tokenDepositor.functions + const call2 = await tokenDepositor.functions .deposit_to_simple_token(simpleToken.id.toB256(), amountToDeposit) .addContracts([simpleToken]) .call(); - const { value: finalBalance } = await simpleToken.functions - .get_balance(wallet.address.toB256()) - .call(); + await call2.waitForResult(); + + const call3 = await simpleToken.functions.get_balance(wallet.address.toB256()).call(); + + const { value: finalBalance } = await call3.waitForResult(); expect(new BN(finalBalance).toNumber()).toBe(amountToDeposit); // #endregion inter-contract-calls-3 diff --git a/apps/docs-snippets/src/guide/contracts/interacting-with-contracts.test.ts b/apps/docs-snippets/src/guide/contracts/interacting-with-contracts.test.ts index d76685a578..e24e276460 100644 --- a/apps/docs-snippets/src/guide/contracts/interacting-with-contracts.test.ts +++ b/apps/docs-snippets/src/guide/contracts/interacting-with-contracts.test.ts @@ -18,7 +18,8 @@ describe(__filename, () => { }); it('should successfully use "get" to read from the blockchain', async () => { - await counterContract.functions.increment_count(1).call(); + const { waitForResult } = await counterContract.functions.increment_count(1).call(); + await waitForResult(); const { id: contractId, interface: abi } = counterContract; @@ -54,14 +55,27 @@ describe(__filename, () => { expect(value.toNumber()).toBeGreaterThanOrEqual(10); }); - it('should successfully execute a contract call without a wallet', async () => { + it('should successfully execute a contract call without a wallet [call]', async () => { const contract = counterContract; // #region interacting-with-contracts-4 - await contract.functions.increment_count(10).call(); + const { transactionId, waitForResult } = await contract.functions.increment_count(10).call(); + + const { value } = await waitForResult(); // #endregion interacting-with-contracts-4 - const { value } = await contract.functions.get_count().get(); + expect(transactionId).toBeDefined(); + expect(value.toNumber()).toBeGreaterThanOrEqual(10); + }); + + it('should successfully execute a contract call without a wallet [call]', async () => { + const contract = counterContract; + + // #region interacting-with-contracts-5 + const { waitForResult } = await contract.functions.increment_count(10).call(); + const { value } = await waitForResult(); + // #endregion interacting-with-contracts-5 + expect(value.toNumber()).toBeGreaterThanOrEqual(10); }); }); diff --git a/apps/docs-snippets/src/guide/contracts/is-function-readonly.test.ts b/apps/docs-snippets/src/guide/contracts/is-function-readonly.test.ts index 7b7a6ffba5..bd4556a3c2 100644 --- a/apps/docs-snippets/src/guide/contracts/is-function-readonly.test.ts +++ b/apps/docs-snippets/src/guide/contracts/is-function-readonly.test.ts @@ -13,7 +13,8 @@ test('isReadOnly returns true for read-only functions', async () => { if (isReadOnly) { await contract.functions.get_count().get(); } else { - await contract.functions.get_count().call(); + const { waitForResult } = await contract.functions.get_count().call(); + await waitForResult(); } // #endregion is-function-readonly-1 diff --git a/apps/docs-snippets/src/guide/contracts/logs.test.ts b/apps/docs-snippets/src/guide/contracts/logs.test.ts index 007ace6c67..2f022035fd 100644 --- a/apps/docs-snippets/src/guide/contracts/logs.test.ts +++ b/apps/docs-snippets/src/guide/contracts/logs.test.ts @@ -21,7 +21,11 @@ describe(__filename, () => { const value3 = 'Fuel'; const value4 = [1, 2, 3]; - const { logs } = await contract.functions.log_values(value1, value2, value3, value4).call(); + const { waitForResult } = await contract.functions + .log_values(value1, value2, value3, value4) + .call(); + + const { logs } = await waitForResult(); expect(new BN(logs[0]).toNumber()).toBe(value1); expect(logs[1]).toBe(value2); diff --git a/apps/docs-snippets/src/guide/contracts/minted-token-asset-id.test.ts b/apps/docs-snippets/src/guide/contracts/minted-token-asset-id.test.ts index c2635e6751..d20f903f0b 100644 --- a/apps/docs-snippets/src/guide/contracts/minted-token-asset-id.test.ts +++ b/apps/docs-snippets/src/guide/contracts/minted-token-asset-id.test.ts @@ -22,7 +22,8 @@ describe(__filename, () => { const subID = '0xc7fd1d987ada439fc085cfa3c49416cf2b504ac50151e3c2335d60595cb90745'; const mintAmount = bn(1000); - const txResult = await contract.functions.mint_coins(subID, mintAmount).call(); + const { waitForResult } = await contract.functions.mint_coins(subID, mintAmount).call(); + const txResult = await waitForResult(); const mintedAssetId = getMintedAssetId(subID, contract.id.toB256()); // #endregion minted-token-asset-id-2 diff --git a/apps/docs-snippets/src/guide/contracts/multicalls.test.ts b/apps/docs-snippets/src/guide/contracts/multicalls.test.ts index 638a4efa53..c93f2d2fd8 100644 --- a/apps/docs-snippets/src/guide/contracts/multicalls.test.ts +++ b/apps/docs-snippets/src/guide/contracts/multicalls.test.ts @@ -58,7 +58,7 @@ describe(__filename, () => { it('should successfully submit multiple calls from the same contract function', async () => { // #region multicall-1 - const { value: results } = await counterContract + const { waitForResult } = await counterContract .multiCall([ counterContract.functions.get_count(), counterContract.functions.increment_count(2), @@ -66,6 +66,8 @@ describe(__filename, () => { ]) .call(); + const { value: results } = await waitForResult(); + const initialValue = new BN(results[0]).toNumber(); const incrementedValue1 = new BN(results[1]).toNumber(); const incrementedValue2 = new BN(results[2]).toNumber(); @@ -84,7 +86,8 @@ describe(__filename, () => { counterContract.functions.increment_count(5), ]); - const { value: results } = await chain.call(); + const { waitForResult } = await chain.call(); + const { value: results } = await waitForResult(); const echoedValue = results[0]; const initialCounterValue = new BN(results[1]).toNumber(); @@ -98,7 +101,7 @@ describe(__filename, () => { it('should successfully submit multiple calls from different contracts functions', async () => { // #region multicall-3 - const { value: results } = await contextContract + const { waitForResult } = await contextContract .multiCall([ echoContract.functions.echo_u8(10), contextContract.functions.return_context_amount().callParams({ @@ -107,6 +110,8 @@ describe(__filename, () => { ]) .call(); + const { value: results } = await waitForResult(); + const echoedValue = results[0]; const fowardedValue = new BN(results[1]).toNumber(); diff --git a/apps/docs-snippets/src/guide/contracts/variable-outputs.test.ts b/apps/docs-snippets/src/guide/contracts/variable-outputs.test.ts index a614ee41c5..e8653dcbca 100644 --- a/apps/docs-snippets/src/guide/contracts/variable-outputs.test.ts +++ b/apps/docs-snippets/src/guide/contracts/variable-outputs.test.ts @@ -16,18 +16,21 @@ describe(__filename, () => { it('should successfully execute contract call with variable outputs', async () => { const subId = getRandomB256(); - await contract.functions.mint_coins(subId, 100).call(); + const call1 = await contract.functions.mint_coins(subId, 100).call(); + await call1.waitForResult(); const address = { bits: Wallet.generate().address.toB256() }; const assetId = { bits: getMintedAssetId(contract.id.toB256(), subId) }; // #region variable-outputs-2 - const { transactionResult } = await contract.functions + const { waitForResult } = await contract.functions .transfer_to_address(address, assetId, 100) .txParams({ variableOutputs: 1, }) .call(); + + const { transactionResult } = await waitForResult(); // #endregion variable-outputs-2 expect(transactionResult.isStatusSuccess).toBeTruthy(); diff --git a/apps/docs-snippets/src/guide/cookbook/deposit-and-withdraw.test.ts b/apps/docs-snippets/src/guide/cookbook/deposit-and-withdraw.test.ts index babecf3cea..17556f76bf 100644 --- a/apps/docs-snippets/src/guide/cookbook/deposit-and-withdraw.test.ts +++ b/apps/docs-snippets/src/guide/cookbook/deposit-and-withdraw.test.ts @@ -42,24 +42,28 @@ describe(__filename, () => { const assetId = getMintedAssetId(contractId, subId); - await liquidityPoolContract.functions + const call1 = await liquidityPoolContract.functions .deposit({ bits: liquidityOwner.address.toB256() }) .callParams({ forward: [depositAmount, baseAssetId] }) .txParams({ variableOutputs: 1 }) .call(); + await call1.waitForResult(); + const liquidityAmount = await liquidityOwner.getBalance(assetId); expect(liquidityAmount.toNumber()).toBe(depositAmount * 2); // #endregion deposit-and-withdraw-cookbook-2 // #region deposit-and-withdraw-cookbook-3 - await liquidityPoolContract.functions + const call2 = await liquidityPoolContract.functions .withdraw({ bits: liquidityOwner.address.toB256() }) .callParams({ forward: [depositAmount, baseAssetId] }) .txParams({ variableOutputs: 1 }) .call(); + await call2.waitForResult(); + const baseAssetAfterWithdraw = await liquidityOwner.getBalance(baseAssetId); expect(baseAssetAfterWithdraw.toNumber()).toBe(depositAmount / 2); diff --git a/apps/docs-snippets/src/guide/cookbook/signing-transactions.test.ts b/apps/docs-snippets/src/guide/cookbook/signing-transactions.test.ts index 6b3a7fb68f..45893a1d7e 100644 --- a/apps/docs-snippets/src/guide/cookbook/signing-transactions.test.ts +++ b/apps/docs-snippets/src/guide/cookbook/signing-transactions.test.ts @@ -50,7 +50,7 @@ describe('Signing transactions', () => { // #import { Script }; const script = new Script(bytecode, abi, sender); - const { value } = await script.functions + const { waitForResult } = await script.functions .main(signer.address.toB256()) .addTransfer({ destination: receiver.address, @@ -59,6 +59,8 @@ describe('Signing transactions', () => { }) .addSigners(signer) .call(); + + const { value } = await waitForResult(); // #endregion multiple-signers-2 expect(value).toBe(true); diff --git a/apps/docs-snippets/src/guide/scripts/script-with-configurable.test.ts b/apps/docs-snippets/src/guide/scripts/script-with-configurable.test.ts index 81550ce2f4..cf73545b61 100644 --- a/apps/docs-snippets/src/guide/scripts/script-with-configurable.test.ts +++ b/apps/docs-snippets/src/guide/scripts/script-with-configurable.test.ts @@ -32,7 +32,8 @@ describe(__filename, () => { const inputtedValue = 10; - const { value } = await script.functions.main(inputtedValue).call(); + const { waitForResult } = await script.functions.main(inputtedValue).call(); + const { value } = await waitForResult(); const expectedTotal = inputtedValue + configurableConstants.AMOUNT; @@ -59,7 +60,8 @@ describe(__filename, () => { const txId = await tx.getTransactionId(); // Retrieve the value of the call and the actual gas used - const { value, gasUsed } = await tx.call(); + const { waitForResult } = await tx.call(); + const { value, gasUsed } = await waitForResult(); // #endregion preparing-scripts expect(txRequest).toBeDefined(); expect(txId).toBeDefined(); diff --git a/apps/docs-snippets/src/guide/testing/launching-a-test-node.test.ts b/apps/docs-snippets/src/guide/testing/launching-a-test-node.test.ts index c5a1c7fe71..355259e43d 100644 --- a/apps/docs-snippets/src/guide/testing/launching-a-test-node.test.ts +++ b/apps/docs-snippets/src/guide/testing/launching-a-test-node.test.ts @@ -69,7 +69,8 @@ describe('launching a test node', () => { wallets, } = launched; - const response = await contract.functions.get_count().call(); + const { waitForResult } = await contract.functions.get_count().call(); + const response = await waitForResult(); // #endregion basic-example expect(response.value.toNumber()).toBe(0); expect(provider).toBeDefined(); diff --git a/apps/docs-snippets/src/guide/transactions/transaction-parameters.test.ts b/apps/docs-snippets/src/guide/transactions/transaction-parameters.test.ts index fa865dbfa9..964c53ea4e 100644 --- a/apps/docs-snippets/src/guide/transactions/transaction-parameters.test.ts +++ b/apps/docs-snippets/src/guide/transactions/transaction-parameters.test.ts @@ -92,12 +92,14 @@ describe(__filename, () => { it('executes contract call with txParams', async () => { // #region transaction-parameters-8 - const { transactionResult } = await contract.functions + const { waitForResult } = await contract.functions .increment_count(15) .txParams({ variableOutputs: 1, }) .call(); + + const { transactionResult } = await waitForResult(); // #endregion transaction-parameters-8 expect(transactionResult.isStatusSuccess).toBeTruthy(); diff --git a/apps/docs-snippets/src/guide/transactions/transaction-response.test.ts b/apps/docs-snippets/src/guide/transactions/transaction-response.test.ts index ee2bf990c2..af003917be 100644 --- a/apps/docs-snippets/src/guide/transactions/transaction-response.test.ts +++ b/apps/docs-snippets/src/guide/transactions/transaction-response.test.ts @@ -27,13 +27,11 @@ describe('Transaction Response', () => { it('gets transaction response from contract call', async () => { // #region transaction-response-1 - // #import { TransactionResponse }; - // Call a contract function const call = await contract.functions.increment_count(15).call(); - // Pick off the transaction response - const transactionResponse: TransactionResponse = call.transactionResponse; + // Wait for the result + const { transactionResponse } = await call.waitForResult(); // Retrieve the full transaction summary const transactionSummary = await transactionResponse.getTransactionSummary(); @@ -94,8 +92,6 @@ describe('Transaction Response', () => { ); // #region transaction-response-3 - // #import { TransactionResponse }; - // Take a transaction ID from a previous transaction const transactionId = previouslySubmittedTransactionId; // 0x... diff --git a/apps/docs-snippets/src/guide/types/numbers.test.ts b/apps/docs-snippets/src/guide/types/numbers.test.ts index cc4c89da24..cd76fb5ae2 100644 --- a/apps/docs-snippets/src/guide/types/numbers.test.ts +++ b/apps/docs-snippets/src/guide/types/numbers.test.ts @@ -38,7 +38,8 @@ describe(__filename, () => { // #region numbers-docs-3 const originalNumber = 20; - const { value } = await contract.functions.echo_u64(bn(originalNumber)).call(); + const { waitForResult } = await contract.functions.echo_u64(bn(originalNumber)).call(); + const { value } = await waitForResult(); expect(value.toNumber()).toEqual(originalNumber); // #endregion numbers-docs-3 @@ -50,7 +51,8 @@ describe(__filename, () => { // #region numbers-docs-4 const originalNumber = 20; - const { value } = await contract.functions.echo_u8(originalNumber).call(); + const { waitForResult } = await contract.functions.echo_u8(originalNumber).call(); + const { value } = await waitForResult(); expect(value).toEqual(originalNumber); // #endregion numbers-docs-4 diff --git a/apps/docs-snippets/src/guide/types/vector.test.ts b/apps/docs-snippets/src/guide/types/vector.test.ts index c5e10928f2..42d7edfb9e 100644 --- a/apps/docs-snippets/src/guide/types/vector.test.ts +++ b/apps/docs-snippets/src/guide/types/vector.test.ts @@ -72,9 +72,11 @@ describe(__filename, () => { const bytecode = await readFile(bytecodePath); const bytecodeAsVecU8 = arrayify(bytecode); - const { value: bytecodeRoot } = await bytecodeContract.functions + const { waitForResult } = await bytecodeContract.functions .compute_bytecode_root(bytecodeAsVecU8) .call(); + + const { value: bytecodeRoot } = await waitForResult(); // #endregion vector-bytecode-input-ts expect(bytecodeRoot).toBeDefined(); diff --git a/apps/docs-snippets/src/guide/utilities/unit-conversion.test.ts b/apps/docs-snippets/src/guide/utilities/unit-conversion.test.ts index 13dcb6976b..95f5c12de6 100644 --- a/apps/docs-snippets/src/guide/utilities/unit-conversion.test.ts +++ b/apps/docs-snippets/src/guide/utilities/unit-conversion.test.ts @@ -42,7 +42,8 @@ describe('unit-conversion', () => { // #region contract-calls-1 const MAX_U64 = bn('18446744073709551615'); - const { value } = await contract.functions.echo_u64(MAX_U64).call(); + const { waitForResult } = await contract.functions.echo_u64(MAX_U64).call(); + const { value } = await waitForResult(); value.toString(); // "18446744073709551615" diff --git a/apps/docs/src/guide/contracts/methods.md b/apps/docs/src/guide/contracts/methods.md index 7aef78b3c9..ccd5f04baa 100644 --- a/apps/docs/src/guide/contracts/methods.md +++ b/apps/docs/src/guide/contracts/methods.md @@ -24,7 +24,7 @@ A funded wallet it's required: ## `call` -The `call` method should be used to submit a real contract call transaction to the node. +The `call` method submits a real contract call transaction to the node, resolving immediately upon submission and returning a `transactionId` along with a `waitForResult` callback to wait for transaction execution. This behavior aligns with the natural behaviour of blockchains, where transactions may take a few seconds before being recorded on the chain. Real resources are consumed, and any operations executed by the contract function will be processed on the blockchain. diff --git a/packages/contract/src/test-utils/launch-test-node.test.ts b/packages/contract/src/test-utils/launch-test-node.test.ts index 41480cbc38..6088a712a3 100644 --- a/packages/contract/src/test-utils/launch-test-node.test.ts +++ b/packages/contract/src/test-utils/launch-test-node.test.ts @@ -133,7 +133,8 @@ describe('launchTestNode', () => { contracts: [contract], } = launched; - const response = await contract.functions.test_function().call(); + const { waitForResult } = await contract.functions.test_function().call(); + const response = await waitForResult(); expect(response.value).toBe(true); }); @@ -165,8 +166,12 @@ describe('launchTestNode', () => { contracts: [contract, contract2], } = launched; - const response1 = await contract.functions.test_function().call(); - const response2 = await contract2.functions.test_function().call(); + const { waitForResult: waitForResult1 } = await contract.functions.test_function().call(); + const { waitForResult: waitForResult2 } = await contract2.functions.test_function().call(); + + const response1 = await waitForResult1(); + const response2 = await waitForResult2(); + expect(response1.value).toBe(true); expect(response2.value).toBe(true); }); @@ -204,11 +209,14 @@ describe('launchTestNode', () => { wallets: [wallet1, wallet2], } = launched; - const contract1Response = (await contract1.functions.test_function().call()).value; - const contract2Response = (await contract2.functions.test_function().call()).value; + const { waitForResult: waitForResult1 } = await contract1.functions.test_function().call(); + const { waitForResult: waitForResult2 } = await contract2.functions.test_function().call(); + + const contract1Response = await waitForResult1(); + const contract2Response = await waitForResult2(); - expect(contract1Response).toBe(true); - expect(contract2Response).toBe(true); + expect(contract1Response.value).toBe(true); + expect(contract2Response.value).toBe(true); expect(contract1.account).toEqual(wallet1); expect(contract2.account).toEqual(wallet2); diff --git a/packages/fuel-gauge/src/advanced-logging.test.ts b/packages/fuel-gauge/src/advanced-logging.test.ts index 5ddc90954a..f38b99121c 100644 --- a/packages/fuel-gauge/src/advanced-logging.test.ts +++ b/packages/fuel-gauge/src/advanced-logging.test.ts @@ -31,7 +31,8 @@ beforeAll(async () => { */ describe('Advanced Logging', () => { it('can get log data', async () => { - const { value, logs } = await advancedLogContract.functions.test_function().call(); + const { waitForResult } = await advancedLogContract.functions.test_function().call(); + const { value, logs } = await waitForResult(); expect(value).toBeTruthy(); logs[5].game_id = logs[5].game_id.toHex(); @@ -75,10 +76,12 @@ describe('Advanced Logging', () => { }); it('can get log data from require [condition=true]', async () => { - const { value, logs } = await advancedLogContract.functions + const { waitForResult } = await advancedLogContract.functions .test_function_with_require(1, 1) .call(); + const { value, logs } = await waitForResult(); + expect(value).toBeTruthy(); expect(logs).toEqual(['Hello Tester', { Playing: 1 }]); }); @@ -114,11 +117,13 @@ describe('Advanced Logging', () => { it('can get log data from a downstream Contract', async () => { const INPUT = 3; - const { value, logs } = await advancedLogContract.functions + const { waitForResult } = await advancedLogContract.functions .test_log_from_other_contract(INPUT, otherAdvancedLogContract.id.toB256()) .addContracts([otherAdvancedLogContract]) .call(); + const { value, logs } = await waitForResult(); + expect(value).toBeTruthy(); expect(logs).toEqual([ 'Hello from main Contract', @@ -158,7 +163,7 @@ describe('Advanced Logging', () => { const configurable = await setupConfigurable({ cache: false }); const coverage = await setupCoverage({ cache: false }); - const { logs } = await callTest + const { waitForResult } = await callTest .multiCall([ advancedLogContract.functions .test_log_from_other_contract(10, otherLogId) @@ -169,6 +174,8 @@ describe('Advanced Logging', () => { ]) .call(); + const { logs } = await waitForResult(); + logs.forEach((log, i) => { expect(JSON.stringify(log)).toBe(JSON.stringify(expectedLogs[i])); }); @@ -238,11 +245,13 @@ describe('Advanced Logging', () => { it('when using InvocationScope', async () => { const script = new Script(binHexlified, abiContents, wallet); - const { logs } = await script.functions + const { waitForResult } = await script.functions .main(advancedLogId, otherLogId, amount) .addContracts([advancedLogContract, otherAdvancedLogContract]) .call(); + const { logs } = await waitForResult(); + expect(logs).toStrictEqual(expectedLogs); }); diff --git a/packages/fuel-gauge/src/auth-testing.test.ts b/packages/fuel-gauge/src/auth-testing.test.ts index 04d4181092..240b92decb 100644 --- a/packages/fuel-gauge/src/auth-testing.test.ts +++ b/packages/fuel-gauge/src/auth-testing.test.ts @@ -27,16 +27,19 @@ describe('Auth Testing', () => { }); it('can get is_caller_external', async () => { - const { value } = await contractInstance.functions.is_caller_external().call(); + const { waitForResult } = await contractInstance.functions.is_caller_external().call(); + const { value } = await waitForResult(); expect(value).toBeTruthy(); }); it('can check_msg_sender [with correct id]', async () => { - const { value } = await contractInstance.functions + const { waitForResult } = await contractInstance.functions .check_msg_sender({ bits: wallet.address.toB256() }) .call(); + const { value } = await waitForResult(); + expect(value).toBeTruthy(); }); diff --git a/packages/fuel-gauge/src/bytecode-sway-lib.test.ts b/packages/fuel-gauge/src/bytecode-sway-lib.test.ts index 4621d0b293..e8af780fa8 100644 --- a/packages/fuel-gauge/src/bytecode-sway-lib.test.ts +++ b/packages/fuel-gauge/src/bytecode-sway-lib.test.ts @@ -18,10 +18,12 @@ describe('bytecode computations', () => { const setupContract = getSetupContract(FuelGaugeProjectsEnum.BYTECODE_SWAY_LIB); const contract = await setupContract(); - const { logs } = await contract.functions + const { waitForResult } = await contract.functions .compute_bytecode_root(arrayify(bytecodeFromFile)) .call(); + const { logs } = await waitForResult(); + const bytecodeRoot: string = logs[0]; expect(bytecodeRoot).toBeDefined(); @@ -36,7 +38,7 @@ describe('bytecode computations', () => { const setupContract = getSetupContract(FuelGaugeProjectsEnum.BYTECODE_SWAY_LIB); const contract = await setupContract(); - const { value } = await contract.functions + const { waitForResult } = await contract.functions .verify_contract_bytecode( { bits: contract.id.toB256(), @@ -45,6 +47,8 @@ describe('bytecode computations', () => { ) .call(); + const { value } = await waitForResult(); + expect(value).toBeTruthy(); }); @@ -62,10 +66,12 @@ describe('bytecode computations', () => { const setupContract = getSetupContract(FuelGaugeProjectsEnum.BYTECODE_SWAY_LIB); const contract = await setupContract(); - const { value } = await contract.functions + const { waitForResult } = await contract.functions .compute_predicate_address(Array.from(arrayify(defaultPredicateBytecode))) .call(); + const { value } = await waitForResult(); + expect(value.bits).toEqual(address.toB256()); }); }); diff --git a/packages/fuel-gauge/src/bytes.test.ts b/packages/fuel-gauge/src/bytes.test.ts index bd6098402c..89207c4936 100644 --- a/packages/fuel-gauge/src/bytes.test.ts +++ b/packages/fuel-gauge/src/bytes.test.ts @@ -44,7 +44,8 @@ describe('Bytes Tests', () => { it('should test bytes output', async () => { const INPUT = 10; - const { value } = await contractInstance.functions.return_bytes(INPUT).call(); + const { waitForResult } = await contractInstance.functions.return_bytes(INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])); }); @@ -52,7 +53,8 @@ describe('Bytes Tests', () => { it('should test bytes output [100 items]', async () => { const INPUT = 100; - const { value } = await contractInstance.functions.return_bytes(INPUT).call(); + const { waitForResult } = await contractInstance.functions.return_bytes(INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(new Uint8Array(Array.from({ length: 100 }, (e, i) => i))); }); @@ -60,7 +62,9 @@ describe('Bytes Tests', () => { it('should test bytes input', async () => { const INPUT = [40, 41, 42]; - const { value } = await contractInstance.functions.accept_bytes(INPUT).call(); + const { waitForResult } = await contractInstance.functions.accept_bytes(INPUT).call(); + const { value } = await waitForResult(); + expect(value).toBeUndefined(); }); @@ -72,7 +76,12 @@ describe('Bytes Tests', () => { inner_enum: { Second: bytes }, }; - const { value } = await contractInstance.functions.accept_nested_bytes(INPUT).call(); + const { waitForResult } = await contractInstance.functions + .accept_nested_bytes(INPUT) + .call(); + + const { value } = await waitForResult(); + expect(value).toBeUndefined(); }); @@ -134,7 +143,9 @@ describe('Bytes Tests', () => { inner_enum: { Second: bytes }, }; - const { value } = await scriptInstance.functions.main(1, INPUT).call(); + const { waitForResult } = await scriptInstance.functions.main(1, INPUT).call(); + const { value } = await waitForResult(); + expect(value).toBe(true); }); }); diff --git a/packages/fuel-gauge/src/call-test-contract.test.ts b/packages/fuel-gauge/src/call-test-contract.test.ts index b590df8e97..7e81228fd0 100644 --- a/packages/fuel-gauge/src/call-test-contract.test.ts +++ b/packages/fuel-gauge/src/call-test-contract.test.ts @@ -24,7 +24,8 @@ const U64_MAX = bn(2).pow(64).sub(1); describe('CallTestContract', () => { it.each([0, 1337, U64_MAX.sub(1)])('can call a contract with u64 (%p)', async (num) => { using contract = await setupContract(); - const { value } = await contract.functions.foo(num).call(); + const { waitForResult } = await contract.functions.foo(num).call(); + const { value } = await waitForResult(); expect(value.toHex()).toEqual(bn(num).add(1).toHex()); }); @@ -37,7 +38,8 @@ describe('CallTestContract', () => { [{ a: true, b: U64_MAX.sub(1) }], ])('can call a contract with structs (%p)', async (struct) => { using contract = await setupContract(); - const { value } = await contract.functions.boo(struct).call(); + const { waitForResult } = await contract.functions.boo(struct).call(); + const { value } = await waitForResult(); expect(value.a).toEqual(!struct.a); expect(value.b.toHex()).toEqual(bn(struct.b).add(1).toHex()); }); @@ -45,18 +47,21 @@ describe('CallTestContract', () => { it('can call a function with empty arguments', async () => { using contract = await setupContract(); - const { value: empty } = await contract.functions.empty().call(); + const call1 = await contract.functions.empty().call(); + const { value: empty } = await call1.waitForResult(); expect(empty.toHex()).toEqual(toHex(63)); - const { value: emptyThenValue } = await contract.functions.empty_then_value(35).call(); + const call2 = await contract.functions.empty_then_value(35).call(); + const { value: emptyThenValue } = await call2.waitForResult(); expect(emptyThenValue.toHex()).toEqual(toHex(63)); - const { value: valueThenEmpty } = await contract.functions.value_then_empty(35).call(); + const call3 = await contract.functions.value_then_empty(35).call(); + const { value: valueThenEmpty } = await call3.waitForResult(); expect(valueThenEmpty.toHex()).toEqual(toHex(63)); - const { value: valueThenEmptyThenValue } = await contract.functions - .value_then_empty_then_value(35, 35) - .call(); + const call4 = await contract.functions.value_then_empty_then_value(35, 35).call(); + + const { value: valueThenEmptyThenValue } = await call4.waitForResult(); expect(valueThenEmptyThenValue.toHex()).toEqual(toHex(63)); }); @@ -64,7 +69,8 @@ describe('CallTestContract', () => { using contract = await setupContract(); // Call method with no params but with no result and no value on config - const { value } = await contract.functions.return_void().call(); + const { waitForResult } = await contract.functions.return_void().call(); + const { value } = await waitForResult(); expect(value).toEqual(undefined); }); @@ -140,7 +146,8 @@ describe('CallTestContract', () => { // But the function names are type-constrained to correct Contract's type using contract = await setupContract(); - const { value } = await (contract as Contract).functions[method](...values).call(); + const { waitForResult } = await (contract as Contract).functions[method](...values).call(); + const { value } = await waitForResult(); if (BN.isBN(value)) { expect(toHex(value)).toBe(toHex(expected)); @@ -153,12 +160,15 @@ describe('CallTestContract', () => { it('Forward amount value on contract call', async () => { using contract = await setupContract(); const baseAssetId = contract.provider.getBaseAssetId(); - const { value } = await contract.functions + const { waitForResult } = await contract.functions .return_context_amount() .callParams({ forward: [1_000_000, baseAssetId], }) .call(); + + const { value } = await waitForResult(); + expect(value.toHex()).toBe(bn(1_000_000).toHex()); }); @@ -166,12 +176,15 @@ describe('CallTestContract', () => { using contract = await setupContract(); const assetId = ASSET_A; - const { value } = await contract.functions + const { waitForResult } = await contract.functions .return_context_asset() .callParams({ forward: [0, assetId], }) .call(); + + const { value } = await waitForResult(); + expect(value).toBe(assetId); }); @@ -179,12 +192,15 @@ describe('CallTestContract', () => { using contract = await setupContract(); const assetId = ASSET_A; - const { value } = await contract.functions + const { waitForResult } = await contract.functions .return_context_asset() .callParams({ forward: [0, assetId], }) .call(); + + const { value } = await waitForResult(); + expect(value).toBe(assetId); }); @@ -206,9 +222,12 @@ describe('CallTestContract', () => { async function expectContractCall() { // Submit multi-call transaction + const { waitForResult } = await multiCallScope.call(); + + // Wait for the result const { value: [resultA, resultB, resultC], - } = await multiCallScope.call(); + } = await waitForResult(); expect(resultA.toHex()).toEqual(bn(num).add(1).toHex()); expect(resultB.a).toEqual(!struct.a); diff --git a/packages/fuel-gauge/src/contract-factory.test.ts b/packages/fuel-gauge/src/contract-factory.test.ts index 46a2c970da..3dff8a6836 100644 --- a/packages/fuel-gauge/src/contract-factory.test.ts +++ b/packages/fuel-gauge/src/contract-factory.test.ts @@ -35,10 +35,12 @@ describe('Contract Factory', () => { expect(contract.interface).toBeInstanceOf(Interface); - const { value: valueInitial } = await contract.functions.initialize_counter(41).call(); + const call1 = await contract.functions.initialize_counter(41).call(); + const { value: valueInitial } = await call1.waitForResult(); expect(valueInitial.toHex()).toEqual(toHex(41)); - const { value } = await contract.functions.increment_counter(1).call(); + const call2 = await contract.functions.increment_counter(1).call(); + const { value } = await call2.waitForResult(); expect(value.toHex()).toEqual(toHex(42)); const { value: value2 } = await contract.functions.increment_counter(1).dryRun(); @@ -48,14 +50,15 @@ describe('Contract Factory', () => { it('Creates a factory from inputs that can return transaction results', async () => { const factory = await createContractFactory(); - const { waitForResult } = await factory.deployContract(); - const { contract } = await waitForResult(); + const callDeploy = await factory.deployContract(); + const { contract } = await callDeploy.waitForResult(); expect(contract.interface).toBeInstanceOf(Interface); await contract.functions.initialize_counter(100).call(); - const { transactionResult } = await contract.functions.increment_counter(1).call(); + const { waitForResult } = await contract.functions.increment_counter(1).call(); + const { transactionResult } = await waitForResult(); expect(transactionResult).toEqual({ blockId: expect.stringMatching(/^0x/), receipts: expect.arrayContaining([expect.any(Object)]), @@ -134,19 +137,24 @@ describe('Contract Factory', () => { }); const { contract } = await waitForResult(); - const { value: var1 } = await contract.functions.return_var1().call(); + const call1 = await contract.functions.return_var1().call(); + const { value: var1 } = await call1.waitForResult(); expect(var1.toHex()).toEqual(toHex(0)); - const { value: var2 } = await contract.functions.return_var2().call(); + const call2 = await contract.functions.return_var2().call(); + const { value: var2 } = await call2.waitForResult(); expect(var2).toEqual(20); - const { value: var3 } = await contract.functions.return_var3().call(); + const call3 = await contract.functions.return_var3().call(); + const { value: var3 } = await call3.waitForResult(); expect(var3).toEqual(30); - const { value: var4 } = await contract.functions.return_var4().call(); + const call4 = await contract.functions.return_var4().call(); + const { value: var4 } = await call4.waitForResult(); expect(var4).toEqual(true); - const { value: var5 } = await contract.functions.return_var5().call(); + const call5 = await contract.functions.return_var5().call(); + const { value: var5 } = await call5.waitForResult(); expect(JSON.stringify(var5)).toEqual( JSON.stringify({ v1: true, @@ -182,19 +190,24 @@ describe('Contract Factory', () => { }); const { contract } = await waitForResult(); - const { value: var1 } = await contract.functions.return_var1().call(); + const call1 = await contract.functions.return_var1().call(); + const { value: var1 } = await call1.waitForResult(); expect(var1.toHex()).toEqual(toHex(0)); - const { value: var2 } = await contract.functions.return_var2().call(); + const call2 = await contract.functions.return_var2().call(); + const { value: var2 } = await call2.waitForResult(); expect(var2).toEqual(20); - const { value: var3 } = await contract.functions.return_var3().call(); + const call3 = await contract.functions.return_var3().call(); + const { value: var3 } = await call3.waitForResult(); expect(var3).toEqual(30); - const { value: var4 } = await contract.functions.return_var4().call(); + const call4 = await contract.functions.return_var4().call(); + const { value: var4 } = await call4.waitForResult(); expect(var4).toEqual(true); - const { value: var5 } = await contract.functions.return_var5().call(); + const call5 = await contract.functions.return_var5().call(); + const { value: var5 } = await call5.waitForResult(); expect(JSON.stringify(var5)).toEqual( JSON.stringify({ v1: true, diff --git a/packages/fuel-gauge/src/contract.test.ts b/packages/fuel-gauge/src/contract.test.ts index d074f6068e..43df3922b5 100644 --- a/packages/fuel-gauge/src/contract.test.ts +++ b/packages/fuel-gauge/src/contract.test.ts @@ -223,6 +223,19 @@ describe('Contract', () => { expect(contract.provider).toEqual(provider); }); + it('should executes a contract call just nice', async () => { + const contract = await setupContract(); + + const numberToSend = 1336; + + const { waitForResult } = await contract.functions.foo(numberToSend).call(); + + const { value, transactionResult } = await waitForResult(); + + expect(value.toNumber()).toEqual(numberToSend + 1); + expect(transactionResult.isStatusSuccess).toBeTruthy(); + }); + it('should fail to execute call if gasLimit is too low', async () => { const contract = await setupContract(); @@ -248,10 +261,10 @@ describe('Contract', () => { }); const scope = contract.functions.call_external_foo(1336, otherContract.id.toB256()); + const { waitForResult } = await scope.call(); + const { value } = await waitForResult(); - const { value: results } = await scope.call(); - - expect(results.toHex()).toEqual(toHex(1338)); + expect(value.toHex()).toEqual(toHex(1338)); }); it('adds multiple contracts on multicalls', async () => { @@ -278,22 +291,26 @@ describe('Contract', () => { { type: 1, inputIndex: 1 }, ]); - const { value: results } = await scope.call(); + const { waitForResult } = await scope.call(); + const { value: results } = await waitForResult(); expect(JSON.stringify(results)).toEqual(JSON.stringify([bn(1337), bn(1338)])); }); it('submits multiple calls', async () => { const contract = await setupContract(); - const { value: results } = await contract + const { waitForResult } = await contract .multiCall([contract.functions.foo(1336), contract.functions.foo(1336)]) .call(); + + const { value: results } = await waitForResult(); + expect(JSON.stringify(results)).toEqual(JSON.stringify([bn(1337), bn(1337)])); }); it('submits multiple calls, six calls', async () => { const contract = await setupContract(); - const { value: results } = await contract + const { waitForResult } = await contract .multiCall([ contract.functions.foo(1336), contract.functions.foo(1336), @@ -304,6 +321,9 @@ describe('Contract', () => { contract.functions.foo(1336), ]) .call(); + + const { value: results } = await waitForResult(); + expect(JSON.stringify(results)).toEqual( JSON.stringify([bn(1337), bn(1337), bn(1337), bn(1337), bn(1337), bn(1337)]) ); @@ -311,8 +331,7 @@ describe('Contract', () => { it('submits multiple calls, eight calls', async () => { const contract = await setupContract(); - - const { value: results } = await contract + const { waitForResult } = await contract .multiCall([ contract.functions.foo(1336), contract.functions.foo(1336), @@ -324,6 +343,7 @@ describe('Contract', () => { contract.functions.foo(1336), ]) .call(); + const { value: results } = await waitForResult(); expect(JSON.stringify(results)).toEqual( JSON.stringify([ bn(1337), @@ -374,7 +394,8 @@ describe('Contract', () => { { type: 1, inputIndex: 1 }, ]); - const { value: results } = await scope.call(); + const { waitForResult } = await scope.call(); + const { value: results } = await waitForResult(); expect(JSON.stringify(results)).toEqual(JSON.stringify([bn(1337)])); }); @@ -401,16 +422,18 @@ describe('Contract', () => { it('Returns gasUsed and transactionId', async () => { const contract = await setupContract(); - const { transactionId, gasUsed } = await contract + const { waitForResult } = await contract .multiCall([contract.functions.foo(1336), contract.functions.foo(1336)]) .call(); + + const { transactionId, gasUsed } = await waitForResult(); expect(transactionId).toBeTruthy(); expect(toNumber(gasUsed)).toBeGreaterThan(0); }); it('Single call with forwarding a alt token', async () => { const contract = await setupContract(); - const { value } = await contract.functions + const { waitForResult } = await contract.functions .return_context_amount() .callParams({ forward: [200, AltToken], @@ -420,13 +443,15 @@ describe('Contract', () => { gasLimit: 3000000, }) .call(); + + const { value } = await waitForResult(); expect(value.toHex()).toEqual(toHex(200)); }); it('MultiCall with multiple forwarding', async () => { const contract = await setupContract(); - const { value } = await contract + const { waitForResult } = await contract .multiCall([ contract.functions.return_context_amount().callParams({ forward: [100, baseAssetId], @@ -442,6 +467,9 @@ describe('Contract', () => { gasLimit: 5000000, }) .call<[BN, BN, BN]>(); + + const { value } = await waitForResult(); + expect(JSON.stringify(value)).toEqual(JSON.stringify([bn(100), bn(200), AltToken])); }); @@ -472,7 +500,7 @@ describe('Contract', () => { it('can forward gas to multicall calls', async () => { const contract = await setupContract(); - const { value } = await contract + const { waitForResult } = await contract .multiCall([ contract.functions.return_context_gas().callParams({ // Forward only 500_000 gas @@ -488,6 +516,7 @@ describe('Contract', () => { }) .call<[BN, BN]>(); + const { value } = await waitForResult(); const minThreshold = 0.019; expect(value[0].toNumber()).toBeGreaterThanOrEqual(500_000 * minThreshold); @@ -513,12 +542,13 @@ describe('Contract', () => { expect(toNumber(transactionCost.minFee)).toBeGreaterThanOrEqual(0); expect(toNumber(transactionCost.gasUsed)).toBeGreaterThan(300); - const { value } = await invocationScope + const { waitForResult } = await invocationScope .txParams({ gasLimit: transactionCost.gasUsed, }) .call<[string, string]>(); + const { value } = await waitForResult(); expect(JSON.stringify(value)).toEqual(JSON.stringify([bn(100), bn(200)])); }); @@ -543,88 +573,103 @@ describe('Contract', () => { it('calls array functions', async () => { const contract = await setupContract(); - const { value: arrayBoolean } = await contract.functions - .take_array_boolean([true, false, false]) - .call(); + const call1 = await contract.functions.take_array_boolean([true, false, false]).call(); + const { value: arrayBoolean } = await call1.waitForResult(); expect(arrayBoolean).toEqual(true); - const { value: arrayNumber } = await contract.functions.take_array_number([1, 2, 3]).call(); + const call2 = await contract.functions.take_array_number([1, 2, 3]).call(); + const { value: arrayNumber } = await call2.waitForResult(); expect(arrayNumber.toHex()).toEqual(toHex(1)); - const { value: arrayReturnShuffle } = await contract.functions - .take_array_string_shuffle(['abc', 'efg', 'hij']) - .call(); + const call3 = await contract.functions.take_array_string_shuffle(['abc', 'efg', 'hij']).call(); + const { value: arrayReturnShuffle } = await call3.waitForResult(); expect(arrayReturnShuffle).toEqual(['hij', 'abc', 'efg']); - const { value: arrayReturnSingle } = await contract.functions + const call4 = await contract.functions .take_array_string_return_single(['abc', 'efg', 'hij']) .call(); + const { value: arrayReturnSingle } = await call4.waitForResult(); + expect(arrayReturnSingle).toEqual(['abc']); - const { value: arrayReturnSingleElement } = await contract.functions + const call5 = await contract.functions .take_array_string_return_single_element(['abc', 'efg', 'hij']) .call(); + const { value: arrayReturnSingleElement } = await call5.waitForResult(); + expect(arrayReturnSingleElement).toEqual('abc'); }); it('calls enum functions', async () => { const contract = await setupContract(); - const { value: enumB256ReturnValue } = await contract.functions + const call1 = await contract.functions .take_b256_enum({ Value: '0xd5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930b', }) .call(); + const { value: enumB256ReturnValue } = await call1.waitForResult(); + expect(enumB256ReturnValue).toEqual( '0xd5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930b' ); - const { value: enumB256ReturnData } = await contract.functions + const call2 = await contract.functions .take_b256_enum({ Data: '0x1111111111111111111111111111111111111111111111111111111111111111', }) .call(); + const { value: enumB256ReturnData } = await call2.waitForResult(); + expect(enumB256ReturnData).toEqual( '0x1111111111111111111111111111111111111111111111111111111111111111' ); - const { value: enumBoolReturnValue } = await contract.functions + const call3 = await contract.functions .take_bool_enum({ Value: true, }) .call(); + const { value: enumBoolReturnValue } = await call3.waitForResult(); + expect(enumBoolReturnValue).toEqual(true); - const { value: enumBoolReturnData } = await contract.functions + const call4 = await contract.functions .take_bool_enum({ Data: false, }) .call(); + const { value: enumBoolReturnData } = await call4.waitForResult(); + expect(enumBoolReturnData).toEqual(false); - const { value: enumStrReturnValue } = await contract.functions + const call5 = await contract.functions .take_string_enum({ Value: 'abc', }) .call(); + const { value: enumStrReturnValue } = await call5.waitForResult(); + expect(enumStrReturnValue).toEqual('abc'); - const { value: enumStrReturnData } = await contract.functions + const call6 = await contract.functions .take_string_enum({ Data: 'efg', }) .call(); + const { value: enumStrReturnData } = await call6.waitForResult(); + expect(enumStrReturnData).toEqual('efg'); }); @@ -801,12 +846,12 @@ describe('Contract', () => { ]); const factory = new ContractFactory(contractBytecode, abi, wallet); - const { waitForResult } = await factory.deployContract(); - const { contract } = await waitForResult(); + const deploy = await factory.deployContract(); + const { contract } = await deploy.waitForResult(); const vector = [5, 4, 3, 2, 1]; - const { value } = await contract + const { waitForResult } = await contract .multiCall([ contract.functions.return_context_amount(), contract.functions.return_vector(vector), // returns heap type Vec @@ -814,6 +859,8 @@ describe('Contract', () => { ]) .call(); + const { value } = await waitForResult(); + expect(JSON.stringify(value)).toBe(JSON.stringify([bn(0), vector, new Uint8Array()])); }); @@ -970,7 +1017,7 @@ describe('Contract', () => { const receiver = Wallet.generate({ provider }); const amountToTransfer = 300; - await contract.functions + const call = await contract.functions .sum(40, 50) .addTransfer({ destination: receiver.address, @@ -979,6 +1026,8 @@ describe('Contract', () => { }) .call(); + await call.waitForResult(); + const finalBalance = await receiver.getBalance(); expect(finalBalance.toNumber()).toBe(amountToTransfer); @@ -1014,7 +1063,8 @@ describe('Contract', () => { { destination: receiver3.address, amount: amountToTransfer3, assetId: ASSET_B }, ]; - await contract.functions.sum(40, 50).addBatchTransfer(transferParams).call(); + const call = await contract.functions.sum(40, 50).addBatchTransfer(transferParams).call(); + await call.waitForResult(); const finalBalance1 = await receiver1.getBalance(baseAssetId); const finalBalance2 = await receiver2.getBalance(ASSET_A); @@ -1198,15 +1248,13 @@ describe('Contract', () => { const wallet = await generateTestWallet(provider, [[350_000, baseAssetId]]); const factory = new ContractFactory(binHexlified, abiContents, wallet); - const { waitForResult } = await factory.deployContract(); - const { contract: storageContract } = await waitForResult(); + const deploy = await factory.deployContract(); + const { contract: storageContract } = await deploy.waitForResult(); const gasLimit = 200_000; const maxFee = 100_000; - const { - transactionResult: { transaction }, - } = await storageContract.functions + const { waitForResult } = await storageContract.functions .counter() .txParams({ gasLimit, @@ -1214,6 +1262,10 @@ describe('Contract', () => { }) .call(); + const { + transactionResult: { transaction }, + } = await waitForResult(); + const maxFeePolicy = transaction.policies?.find((policy) => policy.type === PolicyType.MaxFee); const scriptGasLimit = transaction.scriptGasLimit; @@ -1229,9 +1281,7 @@ describe('Contract', () => { const gasLimit = 500_000; const maxFee = 250_000; - const { - transactionResult: { transaction }, - } = await contract + const { waitForResult } = await contract .multiCall([ contract.functions.foo(1336), contract.functions.foo(1336), @@ -1245,6 +1295,10 @@ describe('Contract', () => { .txParams({ gasLimit, maxFee }) .call(); + const { + transactionResult: { transaction }, + } = await waitForResult(); + const { scriptGasLimit, policies } = transaction; const maxFeePolicy = policies?.find((policy) => policy.type === PolicyType.MaxFee); diff --git a/packages/fuel-gauge/src/coverage-contract.test.ts b/packages/fuel-gauge/src/coverage-contract.test.ts index f5315e0120..b03dfbcb6f 100644 --- a/packages/fuel-gauge/src/coverage-contract.test.ts +++ b/packages/fuel-gauge/src/coverage-contract.test.ts @@ -57,184 +57,187 @@ enum MixedNativeEnum { describe('Coverage Contract', () => { it('can return outputs', async () => { // Call contract methods - expect((await contractInstance.functions.get_id().call()).value).toEqual( - '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' - ); - expect( - ( - await contractInstance.functions - .get_small_string() - - .call() - ).value - ).toEqual('gggggggg'); - expect( - ( - await contractInstance.functions - .get_large_string() - - .call() - ).value - ).toEqual('ggggggggg'); - expect( - ( - await contractInstance.functions - .get_u32_struct() - - .call() - ).value - ).toStrictEqual({ + let expectedValue: unknown = + '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'; + let call = await contractInstance.functions.get_id().call(); + let result = await call.waitForResult(); + + expect(result.value).toEqual(expectedValue); + + expectedValue = 'gggggggg'; + call = await contractInstance.functions.get_small_string().call(); + result = await call.waitForResult(); + + expect(result.value).toEqual(expectedValue); + + expectedValue = 'ggggggggg'; + call = await contractInstance.functions.get_large_string().call(); + result = await call.waitForResult(); + + expect(result.value).toEqual(expectedValue); + + expectedValue = { foo: 100, - }); - expect( - ( - await contractInstance.functions - .get_large_struct() - - .call() - ).value - ).toStrictEqual({ + }; + call = await contractInstance.functions.get_u32_struct().call(); + result = await call.waitForResult(); + + expect(result.value).toStrictEqual(expectedValue); + + expectedValue = { foo: 12, bar: 42, - }); - expect( - ( - await contractInstance.functions - .get_large_array() - - .call() - ).value - ).toStrictEqual([1, 2]); - expect( - ( - await contractInstance.functions - .get_empty_enum() - - .call() - ).value - ).toStrictEqual(SmallEnum.Empty); - expect( - ( - await contractInstance.functions - .get_contract_id() - - .call() - ).value - ).toStrictEqual({ + }; + call = await contractInstance.functions.get_large_struct().call(); + result = await call.waitForResult(); + + expect(result.value).toStrictEqual(expectedValue); + + expectedValue = [1, 2]; + call = await contractInstance.functions.get_large_array().call(); + result = await call.waitForResult(); + + expect(result.value).toStrictEqual(expectedValue); + + expectedValue = SmallEnum.Empty; + call = await contractInstance.functions.get_empty_enum().call(); + result = await call.waitForResult(); + + expect(result.value).toStrictEqual(expectedValue); + + expectedValue = { bits: '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', - }); - expect( - ( - await contractInstance.functions - .get_some_option_u8() + }; + call = await contractInstance.functions.get_contract_id().call(); + result = await call.waitForResult(); + + expect(result.value).toStrictEqual(expectedValue); + + expectedValue = 113; + call = await contractInstance.functions.get_some_option_u8().call(); + result = await call.waitForResult(); + + expect(result.value).toEqual(113); - .call() - ).value - ).toEqual(113); - expect( - ( - await contractInstance.functions - .get_none_option_u8() + expectedValue = undefined; + call = await contractInstance.functions.get_none_option_u8().call(); + result = await call.waitForResult(); - .call() - ).value - ).toEqual(undefined); + expect(result.value).toEqual(undefined); }); it('should test u8 variable type', async () => { // #region U8 - const { value } = await contractInstance.functions.echo_u8(3).call(); + const { waitForResult } = await contractInstance.functions.echo_u8(3).call(); + const { value } = await waitForResult(); expect(value).toBe(3); // #endregion U8 }); it('should test u8 variable type multiple params', async () => { - const { value } = await contractInstance.functions.echo_u8_addition(3, 4, 3).call(); + const { waitForResult } = await contractInstance.functions.echo_u8_addition(3, 4, 3).call(); + const { value } = await waitForResult(); expect(value).toBe(10); }); it('should test u16 variable type', async () => { - const { value } = await contractInstance.functions.echo_u16(RUST_U8_MAX + 1).call(); + const { waitForResult } = await contractInstance.functions.echo_u16(RUST_U8_MAX + 1).call(); + const { value } = await waitForResult(); expect(value).toBe(RUST_U8_MAX + 1); }); it('should test u32 variable type', async () => { - const { value } = await contractInstance.functions.echo_u32(RUST_U16_MAX + 1).call(); + const { waitForResult } = await contractInstance.functions.echo_u32(RUST_U16_MAX + 1).call(); + const { value } = await waitForResult(); expect(value).toBe(RUST_U16_MAX + 1); }); it('should test u64 variable type', async () => { const INPUT = bn(RUST_U32_MAX).add(1).toHex(); - const { value } = await contractInstance.functions.echo_u64(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_u64(INPUT).call(); + const { value } = await waitForResult(); expect(value.toHex()).toBe(INPUT); }); it('should test u256 variable type', async () => { const INPUT = U256_MAX; - const { value } = await contractInstance.functions.echo_u256(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_u256(INPUT).call(); + const { value } = await waitForResult(); expect(JSON.stringify(value)).toEqual(JSON.stringify(INPUT)); }); it('should test bool variable type', async () => { - const { value } = await contractInstance.functions.echo_bool(false).call(); + const { waitForResult } = await contractInstance.functions.echo_bool(false).call(); + const { value } = await waitForResult(); expect(value).toBe(false); }); it('should test b256 variable type', async () => { - const { value } = await contractInstance.functions.echo_b256(B256).call(); + const { waitForResult } = await contractInstance.functions.echo_b256(B256).call(); + const { value } = await waitForResult(); expect(value).toBe(B256); }); it('should test b512 variable type', async () => { - const { value } = await contractInstance.functions.echo_b512(B512).call(); + const { waitForResult } = await contractInstance.functions.echo_b512(B512).call(); + const { value } = await waitForResult(); expect(value).toBe(B512); }); it('should test str[1] variable type', async () => { - const { value } = await contractInstance.functions.echo_str_1('f').call(); + const { waitForResult } = await contractInstance.functions.echo_str_1('f').call(); + const { value } = await waitForResult(); expect(value).toBe('f'); }); it('should test str[2] variable type', async () => { - const { value } = await contractInstance.functions.echo_str_2('fu').call(); + const { waitForResult } = await contractInstance.functions.echo_str_2('fu').call(); + const { value } = await waitForResult(); expect(value).toBe('fu'); }); it('should test str[3] variable type', async () => { - const { value } = await contractInstance.functions.echo_str_3('fue').call(); + const { waitForResult } = await contractInstance.functions.echo_str_3('fue').call(); + const { value } = await waitForResult(); expect(value).toBe('fue'); }); it('should test str[8] variable type', async () => { - const { value } = await contractInstance.functions.echo_str_8('fuel-sdk').call(); + const { waitForResult } = await contractInstance.functions.echo_str_8('fuel-sdk').call(); + const { value } = await waitForResult(); expect(value).toBe('fuel-sdk'); }); it('should test str[9] variable type', async () => { - const { value } = await contractInstance.functions.echo_str_9('fuel-sdks').call(); + const { waitForResult } = await contractInstance.functions.echo_str_9('fuel-sdks').call(); + const { value } = await waitForResult(); expect(value).toBe('fuel-sdks'); }); it('should test tuple < 8 bytes variable type', async () => { - const { value } = await contractInstance.functions.echo_tuple_u8([21, 22]).call(); + const { waitForResult } = await contractInstance.functions.echo_tuple_u8([21, 22]).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual([21, 22]); }); it('should test tuple > 8 bytes variable type', async () => { const INPUT = [bn(RUST_U32_MAX).add(1), bn(RUST_U32_MAX).add(2)]; - const { value } = await contractInstance.functions.echo_tuple_u64(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_tuple_u64(INPUT).call(); + const { value } = await waitForResult(); expect(JSON.stringify(value)).toStrictEqual(JSON.stringify(INPUT)); }); it('should test tuple mixed variable type', async () => { const INPUT = [true, bn(RUST_U32_MAX).add(1)]; - const { value } = await contractInstance.functions.echo_tuple_mixed(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_tuple_mixed(INPUT).call(); + const { value } = await waitForResult(); expect(JSON.stringify(value)).toStrictEqual(JSON.stringify(INPUT)); }); it('should test array < 8 bytes variable type', async () => { - const { value } = await contractInstance.functions.echo_array_u8([4, 3]).call(); + const { waitForResult } = await contractInstance.functions.echo_array_u8([4, 3]).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual([4, 3]); }); @@ -246,64 +249,77 @@ describe('Coverage Contract', () => { toHex(bn('9009', 10)), '0x1fffffffffffff', ]; - const { value } = await contractInstance.functions.echo_array_u64(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_array_u64(INPUT).call(); + const { value } = await waitForResult(); const OUTPUT = INPUT.map((v) => toHex(v)); expect(JSON.stringify(value)).toStrictEqual(JSON.stringify(OUTPUT)); }); it('should test array bool variable type', async () => { - const { value } = await contractInstance.functions.echo_array_bool([true, true]).call(); + const { waitForResult } = await contractInstance.functions.echo_array_bool([true, true]).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual([true, true]); }); it('should test struct < 8 bytes variable type', async () => { const INPUT = { i: 4 }; - const { value } = await contractInstance.functions.echo_struct_u8(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_struct_u8(INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); it('should test struct > 8 bytes variable type', async () => { const INPUT = { i: B256 }; - const { value } = await contractInstance.functions.echo_struct_b256(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_struct_b256(INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); it('should test enum < 8 byte variable type', async () => { const INPUT = SmallEnum.Empty; - const { value } = await contractInstance.functions.echo_enum_small(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_enum_small(INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); it('should test enum > 8 bytes variable type', async () => { const INPUT = { AddressB: B256 }; - const { value } = await contractInstance.functions.echo_enum_big(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_enum_big(INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); it('should test Option type', async () => { const INPUT = 187; - const { value } = await contractInstance.functions.echo_option_u8(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_option_u8(INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); it('should test Option extraction [Some]', async () => { const INPUT_SOME = 123; - const { value: Some } = await contractInstance.functions + const { waitForResult } = await contractInstance.functions .echo_option_extract_u32(INPUT_SOME) .call(); + + const { value: Some } = await waitForResult(); expect(Some).toStrictEqual(INPUT_SOME); }); it('should test Option extraction [None]', async () => { const INPUT_NONE = undefined; - const { value: None } = await contractInstance.functions - .echo_option_extract_u32(INPUT_NONE) - .call(); + const call1 = await contractInstance.functions.echo_option_extract_u32(INPUT_NONE).call(); + + const { value: None } = await call1.waitForResult(); + expect(None).toStrictEqual(500); - const { value: NoneVoid } = await contractInstance.functions.echo_option_extract_u32().call(); + const call2 = await contractInstance.functions.echo_option_extract_u32().call(); + + const { value: NoneVoid } = await call2.waitForResult(); + expect(NoneVoid).toStrictEqual(500); }); @@ -313,10 +329,12 @@ describe('Coverage Contract', () => { const INPUT_C = 5; // adds the three values (if Some value given) together - const { value: Some } = await contractInstance.functions + const { waitForResult } = await contractInstance.functions .echo_option_three_u8(INPUT_A, INPUT_B, INPUT_C) .call(); + const { value: Some } = await waitForResult(); + // we receive the result of adding whatever was passed expect(Some).toStrictEqual(10); }); @@ -325,22 +343,26 @@ describe('Coverage Contract', () => { const INPUT = 1; // adds the three values together, but only first param value is supplied - const { value: Some } = await contractInstance.functions.echo_option_three_u8(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_option_three_u8(INPUT).call(); + const { value: Some } = await waitForResult(); // we receive the result of adding whatever was passed expect(Some).toStrictEqual(1); }); it('should test u8 empty vector input', async () => { - const { value } = await contractInstance.functions.check_u8_vector([]).call(); + const { waitForResult } = await contractInstance.functions.check_u8_vector([]).call(); + const { value } = await waitForResult(); expect(value).toBeFalsy(); }); it('should test u8 vector input', async () => { - const { value, logs } = await contractInstance.functions + const { waitForResult } = await contractInstance.functions .check_u8_vector([1, 2, 3, 4, 5]) .call(); + const { value, logs } = await waitForResult(); + expect(value).toBeTruthy(); const formattedLog = logs.map((l) => (typeof l === 'string' ? l : bn(l).toNumber())); @@ -348,45 +370,55 @@ describe('Coverage Contract', () => { }); it('should echo u8 vector input', async () => { - const { value } = await contractInstance.functions + const { waitForResult } = await contractInstance.functions .echo_u8_vector_first([23, 6, 1, 51, 2]) .call(); + const { value } = await waitForResult(); + expect(value).toBe(23); }); it('should echo a vector of optional u8 input', async () => { - const { value } = await contractInstance.functions.echo_u8_option_vector_first([28]).call(); + const { waitForResult } = await contractInstance.functions + .echo_u8_option_vector_first([28]) + .call(); + + const { value } = await waitForResult(); expect(value).toBe(28); }); it('should echo u64 vector input', async () => { const INPUT = bn(54).toHex(); - const { value } = await contractInstance.functions + const { waitForResult } = await contractInstance.functions .echo_u64_vector_last([200, 100, 24, 51, 23, INPUT]) .call(); + const { value } = await waitForResult(); expect(value.toHex()).toBe(INPUT); }); it('should echo u32 vector addition of mixed params', async () => { - const { value } = await contractInstance.functions + const { waitForResult } = await contractInstance.functions .echo_u32_vector_addition_other_type([100, 2], 47) .call(); + const { value } = await waitForResult(); expect(value).toBe(147); }); it('should echo u32 vector addition', async () => { - const { value } = await contractInstance.functions + const { waitForResult } = await contractInstance.functions .echo_u32_vector_addition([100, 2], [24, 54]) .call(); + const { value } = await waitForResult(); expect(value).toBe(124); }); it('should echo u32 vector addition [variable lengths]', async () => { - const { value } = await contractInstance.functions + const { waitForResult } = await contractInstance.functions .echo_u32_vector_addition([100, 2, 1, 2, 3], [24, 54]) .call(); + const { value } = await waitForResult(); expect(value).toBe(124); }); @@ -395,7 +427,7 @@ describe('Coverage Contract', () => { foo: 1, bar: 10, }; - const { value } = await contractInstance.functions + const { waitForResult } = await contractInstance.functions .echo_struct_vector_first([ first, { @@ -408,6 +440,7 @@ describe('Coverage Contract', () => { }, ]) .call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(first); }); @@ -417,7 +450,7 @@ describe('Coverage Contract', () => { bar: bn(31337).toHex(), baz: 'abcdefghi', }; - const { value } = await contractInstance.functions + const { waitForResult } = await contractInstance.functions .echo_struct_vector_last([ { foo: 1, @@ -432,6 +465,7 @@ describe('Coverage Contract', () => { last, ]) .call(); + const { value } = await waitForResult(); const unhexed = { foo: value.foo, bar: bn(value.bar).toHex(), @@ -517,24 +551,33 @@ describe('Coverage Contract', () => { }); it('supports result type', async () => { + const call1 = await contractInstance.functions.types_result({ Ok: 1 }).call(); + const { value: { Ok }, - } = await contractInstance.functions.types_result({ Ok: 1 }).call(); + } = await call1.waitForResult(); expect(Ok.toNumber()).toBe(20); + const call2 = await contractInstance.functions.types_result({ Ok: 0 }).call(); + const { value: { Err: DivisError }, - } = await contractInstance.functions.types_result({ Ok: 0 }).call(); + } = await call2.waitForResult(); + expect(DivisError).toBe('DivisError'); + const call3 = await contractInstance.functions.types_result({ Err: 1 }).call(); + const { value: { Err: InputError }, - } = await contractInstance.functions.types_result({ Err: 1 }).call(); + } = await call3.waitForResult(); + expect(InputError).toBe('InputError'); }); it('can read from produce_logs_variables', async () => { - const { logs } = await contractInstance.functions.produce_logs_variables().call(); + const { waitForResult } = await contractInstance.functions.produce_logs_variables().call(); + const { logs } = await waitForResult(); expect(logs[0].toHex()).toEqual(bn(64).toHex()); expect(logs[1]).toEqual('0xef86afa9696cf0dc6385e2c407a6e159a1103cefb7e2ae0636fb33d3cb2a9e4a'); @@ -545,7 +588,8 @@ describe('Coverage Contract', () => { it('should test native enum [Red->Green]', async () => { const INPUT: ColorEnumInput = ColorEnumInput.Red; const OUTPUT: ColorEnumOutput = ColorEnumOutput.Green; - const { value } = await contractInstance.functions.color_enum(INPUT).call(); + const { waitForResult } = await contractInstance.functions.color_enum(INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(OUTPUT); }); @@ -554,7 +598,8 @@ describe('Coverage Contract', () => { const INPUT: ColorEnumInput = ColorEnumInput.Green; const OUTPUT: ColorEnumOutput = ColorEnumOutput.Blue; - const { value } = await contractInstance.functions.color_enum(INPUT).call(); + const { waitForResult } = await contractInstance.functions.color_enum(INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(OUTPUT); }); @@ -562,7 +607,8 @@ describe('Coverage Contract', () => { const INPUT: ColorEnumInput = ColorEnumInput.Blue; const OUTPUT: ColorEnumOutput = ColorEnumOutput.Red; - const { value } = await contractInstance.functions.color_enum(INPUT).call(); + const { waitForResult } = await contractInstance.functions.color_enum(INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(OUTPUT); }); @@ -570,7 +616,8 @@ describe('Coverage Contract', () => { const input = MixedNativeEnum.Native; const expected = { NotNative: MixedNativeEnum.NotNative }; - const { value } = await contractInstance.functions.mixed_native_enum(input).call(); + const { waitForResult } = await contractInstance.functions.mixed_native_enum(input).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(expected); }); @@ -578,15 +625,18 @@ describe('Coverage Contract', () => { const input = { NotNative: MixedNativeEnum.NotNative }; const expected = 'Native'; - const { value } = await contractInstance.functions.mixed_native_enum(input).call(); + const { waitForResult } = await contractInstance.functions.mixed_native_enum(input).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(expected); }); it('should try vec_as_only_param', async () => { - const { value } = await contractInstance.functions + const { waitForResult } = await contractInstance.functions .vec_as_only_param([100, 450, 202, 340]) .call(); + const { value } = await waitForResult(); + expect(value.map((v: BN) => v.toHex())).toStrictEqual([ bn(4).toHex(), bn(100).toHex(), @@ -596,10 +646,12 @@ describe('Coverage Contract', () => { }); it('should try u32_and_vec_params', async () => { - const { value } = await contractInstance.functions + const { waitForResult } = await contractInstance.functions .u32_and_vec_params(33, [450, 202, 340]) .call(); + const { value } = await waitForResult(); + expect(value.map((v: BN) => v.toHex())).toStrictEqual([ bn(3).toHex(), bn(450).toHex(), @@ -636,10 +688,12 @@ describe('Coverage Contract', () => { const INPUT_C = hexlify(randomBytes(32)); const INPUT_D = hexlify(randomBytes(32)); - const { value } = await contractInstance.functions + const { waitForResult } = await contractInstance.functions .echo_b256_middle(INPUT_A, INPUT_B, INPUT_C, INPUT_D) .call(); + const { value } = await waitForResult(); + expect(value).toStrictEqual(INPUT_B); }); @@ -649,7 +703,7 @@ describe('Coverage Contract', () => { const INPUT_C = hexlify(randomBytes(32)); const INPUT_D = hexlify(randomBytes(32)); - const { value: results } = await contractInstance + const { waitForResult } = await contractInstance .multiCall([ contractInstance.functions.echo_b256_middle(INPUT_A, INPUT_B, INPUT_C, INPUT_D), contractInstance.functions.echo_u8(13), @@ -658,6 +712,9 @@ describe('Coverage Contract', () => { contractInstance.functions.echo_b256_middle(INPUT_B, INPUT_A, INPUT_C, INPUT_D), ]) .call(); + + const { value: results } = await waitForResult(); + expect(results).toStrictEqual([INPUT_B, 13, 23, SmallEnum.Empty, INPUT_A]); }); @@ -667,7 +724,7 @@ describe('Coverage Contract', () => { const INPUT_C = hexlify(randomBytes(32)); const INPUT_D = hexlify(randomBytes(32)); - const { value: results } = await contractInstance + const { waitForResult } = await contractInstance .multiCall([ contractInstance.functions.echo_u8(1), contractInstance.functions.echo_u8(2), @@ -676,6 +733,9 @@ describe('Coverage Contract', () => { contractInstance.functions.echo_b256_middle(INPUT_B, INPUT_A, INPUT_C, INPUT_D), ]) .call(); + + const { value: results } = await waitForResult(); + expect(results).toStrictEqual([1, 2, SmallEnum.Empty, INPUT_B, INPUT_A]); }); }); diff --git a/packages/fuel-gauge/src/e2e-script.test.ts b/packages/fuel-gauge/src/e2e-script.test.ts index b5e855a9c5..08d607ae90 100644 --- a/packages/fuel-gauge/src/e2e-script.test.ts +++ b/packages/fuel-gauge/src/e2e-script.test.ts @@ -87,7 +87,8 @@ describe.each(selectedNetworks)('Live Script Test', (selectedNetwork) => { try { const callScope = scriptInstance.functions.main(true); - const { value } = await callScope.call(); + const { waitForResult } = await callScope.call(); + const { value } = await waitForResult(); output = value; } catch (e) { diff --git a/packages/fuel-gauge/src/edge-cases.test.ts b/packages/fuel-gauge/src/edge-cases.test.ts index ec697345c5..53ed27ae44 100644 --- a/packages/fuel-gauge/src/edge-cases.test.ts +++ b/packages/fuel-gauge/src/edge-cases.test.ts @@ -9,8 +9,10 @@ import { getSetupContract } from './utils'; describe('Edge Cases', () => { it('can run collision_in_fn_names', async () => { const contract = await getSetupContract('collision_in_fn_names')(); + const { waitForResult } = await contract.functions.new().call(); + const { value } = await waitForResult(); - expect((await contract.functions.new().call()).value.toNumber()).toEqual(12345); + expect(value.toNumber()).toEqual(12345); }); test("SSE subscriptions that are closed by the node don't hang a for-await-of loop", async () => { diff --git a/packages/fuel-gauge/src/fee.test.ts b/packages/fuel-gauge/src/fee.test.ts index b7f95b33fa..b3dfdc7f73 100644 --- a/packages/fuel-gauge/src/fee.test.ts +++ b/packages/fuel-gauge/src/fee.test.ts @@ -61,9 +61,10 @@ describe('Fee', () => { const subId = '0x4a778acfad1abc155a009dc976d2cf0db6197d3d360194d74b1fb92b96986b00'; + const call1 = await contract.functions.mint_coins(subId, 1_000).call(); const { transactionResult: { fee: fee1 }, - } = await contract.functions.mint_coins(subId, 1_000).call(); + } = await call1.waitForResult(); let balanceAfter = await wallet.getBalance(); @@ -74,9 +75,11 @@ describe('Fee', () => { // burning coins balanceBefore = await wallet.getBalance(); + const call2 = await contract.functions.mint_coins(subId, 1_000).call(); + const { transactionResult: { fee: fee2 }, - } = await contract.functions.mint_coins(subId, 1_000).call(); + } = await call2.waitForResult(); balanceAfter = await wallet.getBalance(); @@ -178,17 +181,16 @@ describe('Fee', () => { ); const factory = new ContractFactory(binHexlified, abiContents, wallet); - const { waitForResult } = await factory.deployContract(); - const { contract } = await waitForResult(); + const deploy = await factory.deployContract(); + const { contract } = await deploy.waitForResult(); const balanceBefore = await wallet.getBalance(); + const { waitForResult } = await contract.functions.sum_multparams(1, 2, 3, 4, 5).call(); + const { transactionResult: { fee }, - } = await contract.functions - .sum_multparams(1, 2, 3, 4, 5) - - .call(); + } = await waitForResult(); const balanceAfter = await wallet.getBalance(); const balanceDiff = balanceBefore.sub(balanceAfter).toNumber(); @@ -206,8 +208,8 @@ describe('Fee', () => { ); const factory = new ContractFactory(binHexlified, abiContents, wallet); - const { waitForResult } = await factory.deployContract(); - const { contract } = await waitForResult(); + const deploy = await factory.deployContract(); + const { contract } = await deploy.waitForResult(); const balanceBefore = await wallet.getBalance(); @@ -218,9 +220,11 @@ describe('Fee', () => { contract.functions.return_bytes(), ]); + const { waitForResult } = await scope.call(); + const { transactionResult: { fee }, - } = await scope.call(); + } = await waitForResult(); const balanceAfter = await wallet.getBalance(); const balanceDiff = balanceBefore.sub(balanceAfter).toNumber(); @@ -238,8 +242,8 @@ describe('Fee', () => { ); const factory = new ContractFactory(binHexlified, abiContents, wallet); - const { waitForResult } = await factory.deployContract(); - const { contract } = await waitForResult(); + const deploy = await factory.deployContract(); + const { contract } = await deploy.waitForResult(); const subId = '0x4a778acfad1abc155a009dc976d2cf0db6197d3d360194d74b1fb92b96986b00'; @@ -251,13 +255,15 @@ describe('Fee', () => { const balanceBefore = await wallet.getBalance(); - const { - transactionResult: { fee }, - } = await contract + const { waitForResult } = await contract .multiCall(calls) .txParams({ variableOutputs: calls.length * 3 }) .call(); + const { + transactionResult: { fee }, + } = await waitForResult(); + const balanceAfter = await wallet.getBalance(); const balanceDiff = balanceBefore.sub(balanceAfter).toNumber(); diff --git a/packages/fuel-gauge/src/generic-types-contract.test.ts b/packages/fuel-gauge/src/generic-types-contract.test.ts index 9cab32da72..6caa629699 100644 --- a/packages/fuel-gauge/src/generic-types-contract.test.ts +++ b/packages/fuel-gauge/src/generic-types-contract.test.ts @@ -20,7 +20,7 @@ describe('GenericTypesContract', () => { const b256 = '0xd5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930b'; const bimArg1 = 'Yes'; - const { value } = await contract.functions + const call1 = await contract.functions .generic_type_function( [ { @@ -77,6 +77,8 @@ describe('GenericTypesContract', () => { ) .call(); + const { value } = await call1.waitForResult(); + const arg1 = { bim: toHex(1), bam: true, @@ -104,11 +106,10 @@ describe('GenericTypesContract', () => { }), }; - const { value: call2 } = await contract.functions - .generic_complex_type_function(arg1, arg2) - .call(); + const call2 = await contract.functions.generic_complex_type_function(arg1, arg2).call(); + const { value: value2 } = await call2.waitForResult(); expect(value).toEqual(bimArg1); - expect(JSON.stringify([arg1, arg2])).toEqual(JSON.stringify(call2)); + expect(JSON.stringify([arg1, arg2])).toEqual(JSON.stringify(value2)); }); }); diff --git a/packages/fuel-gauge/src/multi-token-contract.test.ts b/packages/fuel-gauge/src/multi-token-contract.test.ts index 89cbef5c69..a6607cd65a 100644 --- a/packages/fuel-gauge/src/multi-token-contract.test.ts +++ b/packages/fuel-gauge/src/multi-token-contract.test.ts @@ -16,101 +16,98 @@ const subIds = [ * @group node */ describe('MultiTokenContract', () => { - it( - 'can mint and transfer coins', - async () => { - using launched = await launchTestNode({ - contractsConfigs: [ - { - deployer: MultiTokenContractAbi__factory, - bytecode: binHexlified, - }, - ], - }); - const { - provider, - contracts: [multiTokenContract], - } = launched; - // New wallet to transfer coins and check balance - const userWallet = Wallet.generate({ provider }); - - const contractId = { bits: multiTokenContract.id.toB256() }; - - const helperDict: { [key: string]: { assetId: string; amount: number } } = { - [subIds[0]]: { - assetId: '', - amount: 100, - }, - [subIds[1]]: { - assetId: '', - amount: 300, - }, - [subIds[2]]: { - assetId: '', - amount: 400, + it('can mint and transfer coins', async () => { + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: MultiTokenContractAbi__factory, + bytecode: binHexlified, }, - }; + ], + }); + const { + provider, + contracts: [multiTokenContract], + } = launched; + // New wallet to transfer coins and check balance + const userWallet = Wallet.generate({ provider }); - // mint some coins of the 3 subIds on MultiTokenContract - const { transactionResult } = await multiTokenContract - .multiCall( - subIds.map((subId) => - multiTokenContract.functions.mint_coins(subId, helperDict[subId].amount) - ) + const contractId = { bits: multiTokenContract.id.toB256() }; + + const helperDict: { [key: string]: { assetId: string; amount: number } } = { + [subIds[0]]: { + assetId: '', + amount: 100, + }, + [subIds[1]]: { + assetId: '', + amount: 300, + }, + [subIds[2]]: { + assetId: '', + amount: 400, + }, + }; + + // mint some coins of the 3 subIds on MultiTokenContract + const call1 = await multiTokenContract + .multiCall( + subIds.map((subId) => + multiTokenContract.functions.mint_coins(subId, helperDict[subId].amount) ) - .call(); + ) + .call(); + const { transactionResult } = await call1.waitForResult(); - // update assetId on helperDict object - (transactionResult?.mintedAssets || []).forEach(({ subId, assetId }) => { - helperDict[subId].assetId = assetId || ''; - }); + // update assetId on helperDict object + (transactionResult?.mintedAssets || []).forEach(({ subId, assetId }) => { + helperDict[subId].assetId = assetId || ''; + }); - // define helper to get contract balance - const getBalance = async (address: { bits: string }, assetId: string) => { - const { value } = await multiTokenContract.functions - .get_balance(address, { bits: assetId }) + // define helper to get contract balance + const getBalance = async (address: { bits: string }, assetId: string) => { + const { value } = await multiTokenContract.functions + .get_balance(address, { bits: assetId }) - .simulate(); - return value; - }; + .simulate(); + return value; + }; - // validates contract has expected balance after mint - const validateMintPromises = subIds.map(async (subId) => { - expect(bn(await getBalance(contractId, helperDict[subId].assetId)).toNumber()).toBe( - helperDict[subId].amount - ); - }); - - await Promise.all(validateMintPromises); - - // transfer coins to user wallet - await multiTokenContract - .multiCall( - subIds.map((subId) => - multiTokenContract.functions.transfer_to_address( - { bits: userWallet.address.toB256() }, - { bits: helperDict[subId].assetId }, - helperDict[subId].amount - ) + // validates contract has expected balance after mint + const validateMintPromises = subIds.map(async (subId) => { + expect(bn(await getBalance(contractId, helperDict[subId].assetId)).toNumber()).toBe( + helperDict[subId].amount + ); + }); + + await Promise.all(validateMintPromises); + + // transfer coins to user wallet + const call2 = await multiTokenContract + .multiCall( + subIds.map((subId) => + multiTokenContract.functions.transfer_to_address( + { bits: userWallet.address.toB256() }, + { bits: helperDict[subId].assetId }, + helperDict[subId].amount ) ) - .call(); - - const validateTransferPromises = subIds.map(async (subId) => { - // validates that user wallet has expected balance after transfer - expect(bn(await userWallet.getBalance(helperDict[subId].assetId)).toNumber()).toBe( - helperDict[subId].amount - ); - // validates contract has not balance after transfer - expect(bn(await getBalance(contractId, helperDict[subId].assetId)).toNumber()).toBe(0); - }); - - await Promise.all(validateTransferPromises); - }, - { - timeout: 15000, - } - ); + ) + .call(); + + await call2.waitForResult(); + + const validateTransferPromises = subIds.map(async (subId) => { + // validates that user wallet has expected balance after transfer + expect(bn(await userWallet.getBalance(helperDict[subId].assetId)).toNumber()).toBe( + helperDict[subId].amount + ); + // validates contract has not balance after transfer + expect(bn(await getBalance(contractId, helperDict[subId].assetId)).toNumber()).toBe(0); + }); + + await Promise.all(validateTransferPromises); + }); it('can burn coins', async () => { using launched = await launchTestNode({ @@ -151,7 +148,7 @@ describe('MultiTokenContract', () => { }; // mint some coins of the 3 subIds on MultiTokenContract - const { transactionResult } = await multiTokenContract + const { waitForResult } = await multiTokenContract .multiCall( subIds.map((subId) => multiTokenContract.functions.mint_coins(subId, helperDict[subId].amount) @@ -159,6 +156,8 @@ describe('MultiTokenContract', () => { ) .call(); + const { transactionResult } = await waitForResult(); + // update assetId on helperDict object (transactionResult?.mintedAssets || []).forEach(({ subId, assetId }) => { helperDict[subId].assetId = assetId || ''; @@ -168,7 +167,6 @@ describe('MultiTokenContract', () => { const getBalance = async (address: { bits: string }, assetId: string) => { const { value } = await multiTokenContract.functions .get_balance(address, { bits: assetId }) - .simulate(); return value; }; @@ -183,7 +181,7 @@ describe('MultiTokenContract', () => { await Promise.all(validateMintPromises); // burning coins - await multiTokenContract + const multiCall = await multiTokenContract .multiCall( subIds.map((subId) => multiTokenContract.functions.burn_coins(subId, helperDict[subId].amountToBurn) @@ -191,6 +189,8 @@ describe('MultiTokenContract', () => { ) .call(); + await multiCall.waitForResult(); + const validateBurnPromises = subIds.map(async (subId) => { // validates contract has expected balance for each coin after burn expect(bn(await getBalance(contractId, helperDict[subId].assetId)).toNumber()).toBe( diff --git a/packages/fuel-gauge/src/options.test.ts b/packages/fuel-gauge/src/options.test.ts index 1253f320f7..afe3d76b86 100644 --- a/packages/fuel-gauge/src/options.test.ts +++ b/packages/fuel-gauge/src/options.test.ts @@ -22,7 +22,8 @@ beforeAll(async () => { */ describe('Options Tests', () => { it('calls', async () => { - const { value } = await contractInstance.functions.print_enum_option_array().call(); + const { waitForResult } = await contractInstance.functions.print_enum_option_array().call(); + const { value } = await waitForResult(); expect(value).toStrictEqual({ inner: [ @@ -44,11 +45,13 @@ describe('Options Tests', () => { const someInput = U8_MAX; const noneInput = undefined; - const { value: someValue } = await contractInstance.functions.echo_option(someInput).call(); + const call1 = await contractInstance.functions.echo_option(someInput).call(); + const { value: someValue } = await call1.waitForResult(); expect(someValue).toBe(someInput); - const { value: noneValue } = await contractInstance.functions.echo_option(noneInput).call(); + const call2 = await contractInstance.functions.echo_option(noneInput).call(); + const { value: noneValue } = await call2.waitForResult(); expect(noneValue).toBe(noneInput); }); @@ -61,9 +64,8 @@ describe('Options Tests', () => { two: U32_MAX, }; - const { value: someValue } = await contractInstance.functions - .echo_struct_enum_option(someInput) - .call(); + const call1 = await contractInstance.functions.echo_struct_enum_option(someInput).call(); + const { value: someValue } = await call1.waitForResult(); expect(someValue).toStrictEqual(someInput); @@ -74,9 +76,8 @@ describe('Options Tests', () => { two: undefined, }; - const { value: noneValue } = await contractInstance.functions - .echo_struct_enum_option(noneInput) - .call(); + const call2 = await contractInstance.functions.echo_struct_enum_option(noneInput).call(); + const { value: noneValue } = await call2.waitForResult(); expect(noneValue).toStrictEqual(noneInput); }); @@ -84,21 +85,22 @@ describe('Options Tests', () => { it('echos vec option', async () => { const someInput = [U8_MAX, U16_MAX, U32_MAX]; - const { value: someValue } = await contractInstance.functions.echo_vec_option(someInput).call(); + const call1 = await contractInstance.functions.echo_vec_option(someInput).call(); + const { value: someValue } = await call1.waitForResult(); expect(someValue).toStrictEqual(someInput); const noneInput = [undefined, undefined, undefined]; - const { value: noneValue } = await contractInstance.functions.echo_vec_option(noneInput).call(); + const call2 = await contractInstance.functions.echo_vec_option(noneInput).call(); + const { value: noneValue } = await call2.waitForResult(); expect(noneValue).toStrictEqual(noneInput); const mixedInput = [U8_MAX, undefined, U32_MAX]; - const { value: mixedValue } = await contractInstance.functions - .echo_vec_option(mixedInput) - .call(); + const call3 = await contractInstance.functions.echo_vec_option(mixedInput).call(); + const { value: mixedValue } = await call3.waitForResult(); expect(mixedValue).toStrictEqual(mixedInput); }); @@ -106,25 +108,25 @@ describe('Options Tests', () => { it('echos tuple option', async () => { const someInput = [U8_MAX, U16_MAX]; - const { value: someValue } = await contractInstance.functions - .echo_tuple_option(someInput) - .call(); + const call1 = await contractInstance.functions.echo_tuple_option(someInput).call(); + + const { value: someValue } = await call1.waitForResult(); expect(someValue).toStrictEqual(someInput); const noneInput = [undefined, undefined]; - const { value: noneValue } = await contractInstance.functions - .echo_tuple_option(noneInput) - .call(); + const call2 = await contractInstance.functions.echo_tuple_option(noneInput).call(); + + const { value: noneValue } = await call2.waitForResult(); expect(noneValue).toStrictEqual(noneInput); const mixedInput = [U8_MAX, undefined]; - const { value: mixedValue } = await contractInstance.functions - .echo_tuple_option(mixedInput) - .call(); + const call3 = await contractInstance.functions.echo_tuple_option(mixedInput).call(); + + const { value: mixedValue } = await call3.waitForResult(); expect(mixedValue).toStrictEqual(mixedInput); }); @@ -132,17 +134,17 @@ describe('Options Tests', () => { it('echoes enum option', async () => { const someInput = { a: U8_MAX }; - const { value: someValue } = await contractInstance.functions - .echo_enum_option(someInput) - .call(); + const call1 = await contractInstance.functions.echo_enum_option(someInput).call(); + + const { value: someValue } = await call1.waitForResult(); expect(someValue).toStrictEqual(someInput); const noneInput = { b: undefined }; - const { value: noneValue } = await contractInstance.functions - .echo_enum_option(noneInput) - .call(); + const call2 = await contractInstance.functions.echo_enum_option(noneInput).call(); + + const { value: noneValue } = await call2.waitForResult(); expect(noneValue).toStrictEqual(noneInput); }); @@ -150,25 +152,22 @@ describe('Options Tests', () => { it('echos array option', async () => { const someInput = [U8_MAX, U16_MAX, 123]; - const { value: someValue } = await contractInstance.functions - .echo_array_option(someInput) - .call(); + const call1 = await contractInstance.functions.echo_array_option(someInput).call(); + const { value: someValue } = await call1.waitForResult(); expect(someValue).toStrictEqual(someInput); const noneInput = [undefined, undefined, undefined]; - const { value: noneValue } = await contractInstance.functions - .echo_array_option(noneInput) - .call(); + const call2 = await contractInstance.functions.echo_array_option(noneInput).call(); + const { value: noneValue } = await call2.waitForResult(); expect(noneValue).toStrictEqual(noneInput); const mixedInput = [U8_MAX, undefined, 123]; - const { value: mixedValue } = await contractInstance.functions - .echo_array_option(mixedInput) - .call(); + const call3 = await contractInstance.functions.echo_array_option(mixedInput).call(); + const { value: mixedValue } = await call3.waitForResult(); expect(mixedValue).toStrictEqual(mixedInput); }); @@ -180,36 +179,44 @@ describe('Options Tests', () => { }, }; - const { value } = await contractInstance.functions.echo_deeply_nested_option(input).call(); + const { waitForResult } = await contractInstance.functions + .echo_deeply_nested_option(input) + .call(); + + const { value } = await waitForResult(); expect(value).toStrictEqual(input); }); it('prints struct option', async () => { - const { value } = await contractInstance.functions + const { waitForResult } = await contractInstance.functions .get_some_struct({ Address: { bits: wallet.address.toB256() } }) .call(); + const { value } = await waitForResult(); + expect(value).toStrictEqual(undefined); }); it('echoes option enum diff sizes', async () => { - const { value } = await contractInstance.functions.echo_enum_diff_sizes(undefined).call(); + const call1 = await contractInstance.functions.echo_enum_diff_sizes(undefined).call(); + const { value } = await call1.waitForResult(); expect(value).toStrictEqual(undefined); - const { value: value2 } = await contractInstance.functions - .echo_enum_diff_sizes({ a: U8_MAX }) - .call(); + const call2 = await contractInstance.functions.echo_enum_diff_sizes({ a: U8_MAX }).call(); + const { value: value2 } = await call2.waitForResult(); expect(value2).toStrictEqual({ a: U8_MAX }); - const { value: value3 } = await contractInstance.functions + const call3 = await contractInstance.functions .echo_enum_diff_sizes({ b: '0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c', }) .call(); + const { value: value3 } = await call3.waitForResult(); + expect(value3).toStrictEqual({ b: '0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c', }); diff --git a/packages/fuel-gauge/src/policies.test.ts b/packages/fuel-gauge/src/policies.test.ts index fc0fcd2b15..d7a619d0f9 100644 --- a/packages/fuel-gauge/src/policies.test.ts +++ b/packages/fuel-gauge/src/policies.test.ts @@ -212,9 +212,11 @@ describe('Policies', () => { const txRequest = await callScope.getTransactionRequest(); + const { waitForResult } = await callScope.call(); + const { transactionResult: { transaction }, - } = await callScope.call(); + } = await waitForResult(); validatePolicies({ transaction, @@ -242,9 +244,11 @@ describe('Policies', () => { const txRequest = await callScope.getTransactionRequest(); + const { waitForResult } = await callScope.call(); + const { transactionResult: { transaction }, - } = await callScope.call(); + } = await waitForResult(); validatePolicies({ transaction, diff --git a/packages/fuel-gauge/src/predicate/predicate-with-contract.test.ts b/packages/fuel-gauge/src/predicate/predicate-with-contract.test.ts index 32965c971d..e90d29ff89 100644 --- a/packages/fuel-gauge/src/predicate/predicate-with-contract.test.ts +++ b/packages/fuel-gauge/src/predicate/predicate-with-contract.test.ts @@ -37,13 +37,15 @@ describe('Predicate', () => { const contractPredicate = new Contract(contract.id, contract.interface, predicate); await fundPredicate(wallet, predicate, amountToPredicate); - const { value, transactionResult } = await contractPredicate.functions + const { waitForResult } = await contractPredicate.functions .return_context_amount() .callParams({ forward: [500, provider.getBaseAssetId()], }) .call(); + const { value, transactionResult } = await waitForResult(); + expect(value.toString()).toEqual('500'); expect(transactionResult.isStatusSuccess).toBeTruthy(); }); @@ -86,17 +88,16 @@ describe('Predicate', () => { amountToReceiver, provider.getBaseAssetId() ); - let { isStatusSuccess } = await tx.waitForResult(); + const { isStatusSuccess } = await tx.waitForResult(); expect(isStatusSuccess).toBeTruthy(); const receiverFinalBalance = await receiver.getBalance(); expect(receiverFinalBalance.gt(receiverInitialBalance)).toBeTruthy(); - ({ - transactionResult: { isStatusSuccess }, - } = await contract.functions.mint_coins(200).call()); + const call = await contract.functions.mint_coins(200).call(); + const { transactionResult } = await call.waitForResult(); - expect(isStatusSuccess).toBeTruthy(); + expect(transactionResult.isStatusSuccess).toBeTruthy(); }); }); }); diff --git a/packages/fuel-gauge/src/predicate/predicate-with-script.test.ts b/packages/fuel-gauge/src/predicate/predicate-with-script.test.ts index f980e8d883..659072ff56 100644 --- a/packages/fuel-gauge/src/predicate/predicate-with-script.test.ts +++ b/packages/fuel-gauge/src/predicate/predicate-with-script.test.ts @@ -70,7 +70,9 @@ describe('Predicate', () => { const { isStatusSuccess } = await tx.waitForResult(); expect(isStatusSuccess).toBeTruthy(); - const res = await scriptInstance.functions.main(scriptInput).call(); + const { waitForResult } = await scriptInstance.functions.main(scriptInput).call(); + const res = await waitForResult(); + expect(res.transactionResult.isStatusSuccess).toBeTruthy(); const receiverFinalBalance = await receiver.getBalance(); diff --git a/packages/fuel-gauge/src/raw-slice.test.ts b/packages/fuel-gauge/src/raw-slice.test.ts index ff6e0f9c24..038e25a42a 100644 --- a/packages/fuel-gauge/src/raw-slice.test.ts +++ b/packages/fuel-gauge/src/raw-slice.test.ts @@ -41,7 +41,8 @@ describe('Raw Slice Tests', () => { it('should test raw slice output', async () => { const INPUT = 10; - const { value } = await contractInstance.functions.return_raw_slice(INPUT).call(); + const { waitForResult } = await contractInstance.functions.return_raw_slice(INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); }); @@ -49,7 +50,11 @@ describe('Raw Slice Tests', () => { it('should test raw slice input', async () => { const INPUT = [40, 41, 42]; - const { value } = await contractInstance.functions.accept_raw_slice(INPUT).call(); + const { waitForResult } = await contractInstance.functions + .accept_raw_slice(INPUT) + .call(); + + const { value } = await waitForResult(); expect(value).toBeUndefined(); }); @@ -61,10 +66,12 @@ describe('Raw Slice Tests', () => { inner_enum: { Second: slice }, }; - const { value } = await contractInstance.functions + const { waitForResult } = await contractInstance.functions .accept_nested_raw_slice(INPUT) .call(); + const { value } = await waitForResult(); + expect(value).toBeUndefined(); }); @@ -123,7 +130,8 @@ describe('Raw Slice Tests', () => { inner_enum: { Second: bytes }, }; - const { value } = await scriptInstance.functions.main(3, INPUT).call(); + const { waitForResult } = await scriptInstance.functions.main(3, INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual([0, 1, 2]); }); }); diff --git a/packages/fuel-gauge/src/reentrant-contract-calls.test.ts b/packages/fuel-gauge/src/reentrant-contract-calls.test.ts index 1d475fb91e..d4118047b2 100644 --- a/packages/fuel-gauge/src/reentrant-contract-calls.test.ts +++ b/packages/fuel-gauge/src/reentrant-contract-calls.test.ts @@ -32,14 +32,16 @@ describe('Reentrant Contract Calls', () => { }); it('should ensure the SDK returns the proper value for a reentrant call', async () => { - const { - value, - transactionResult: { receipts }, - } = await fooContract.functions + const { waitForResult } = await fooContract.functions .foo({ bits: fooContract.id.toB256() }, { bits: barContract.id.toB256() }) .addContracts([barContract]) .call(); + const { + value, + transactionResult: { receipts }, + } = await waitForResult(); + /** * First, the test will call: * Foo.foo() @@ -66,23 +68,25 @@ describe('Reentrant Contract Calls', () => { }); it('should ensure the SDK returns the proper value for a reentrant call on multi-call', async () => { - const { waitForResult } = await new ContractFactory( + const deploy = await new ContractFactory( storageTest.binHexlified, storageTest.abiContents, wallet ).deployContract({ storageSlots: storageTest.storageSlots }); - const { contract: storageContract } = await waitForResult(); + const { contract: storageContract } = await deploy.waitForResult(); const reentrantCall = fooContract.functions.foo( { bits: fooContract.id.toB256() }, { bits: barContract.id.toB256() } ); - const result = await fooContract + const { waitForResult } = await fooContract .multiCall([reentrantCall, storageContract.functions.return_var3(), reentrantCall]) .call(); + const result = await waitForResult(); + const expectedReentrantValue = 42; // return value from first call to reentrant contract call diff --git a/packages/fuel-gauge/src/revert-error.test.ts b/packages/fuel-gauge/src/revert-error.test.ts index 6f2ee20e1a..204175b169 100644 --- a/packages/fuel-gauge/src/revert-error.test.ts +++ b/packages/fuel-gauge/src/revert-error.test.ts @@ -33,10 +33,12 @@ describe('Revert Error Testing', () => { const INPUT_PRICE = bn(10); const INPUT_TOKEN_ID = bn(100); - const { logs } = await contractInstance.functions + const { waitForResult } = await contractInstance.functions .validate_inputs(INPUT_TOKEN_ID, INPUT_PRICE) .call(); + const { logs } = await waitForResult(); + expect( logs.map((d) => ({ token_id: d.token_id?.toString(), price: d.price?.toString() })) ).toEqual([ @@ -72,7 +74,12 @@ describe('Revert Error Testing', () => { const INPUT_TOKEN_ID = bn(55); await expectToThrowFuelError( - () => contractInstance.functions.validate_inputs(INPUT_TOKEN_ID, INPUT_PRICE).call(), + async () => { + const { waitForResult } = await contractInstance.functions + .validate_inputs(INPUT_TOKEN_ID, INPUT_PRICE) + .call(); + await waitForResult(); + }, new FuelError( ErrorCode.SCRIPT_REVERTED, `The transaction reverted because a "require" statement has thrown "InvalidTokenId".`, diff --git a/packages/fuel-gauge/src/script-main-args.test.ts b/packages/fuel-gauge/src/script-main-args.test.ts index ed35e4e10c..db1ba54810 100644 --- a/packages/fuel-gauge/src/script-main-args.test.ts +++ b/packages/fuel-gauge/src/script-main-args.test.ts @@ -34,7 +34,9 @@ describe('Script Coverage', () => { const foo = 33; const scriptInstance = new Script(scriptBin, scriptAbi, wallet); - const { value, logs } = await scriptInstance.functions.main(foo).call(); + const { waitForResult } = await scriptInstance.functions.main(foo).call(); + + const { value, logs } = await waitForResult(); // #endregion script-call-factory expect(value?.toString()).toEqual(bn(foo).toString()); @@ -49,7 +51,8 @@ describe('Script Coverage', () => { x: 12, }; - const { value, logs } = await scriptInstance.functions.main(foo, bar).call(); + const { waitForResult } = await scriptInstance.functions.main(foo, bar).call(); + const { value, logs } = await waitForResult(); expect(value?.toString()).toEqual(bn(foo + bar.x).toString()); expect(logs).toEqual(['u8 foo', 33, 'u8 bar', 12, 'u8 bar', 12]); @@ -63,7 +66,8 @@ describe('Script Coverage', () => { x: 2, }; - const { value } = await scriptInstance.functions.main(foo, bar).call(); + const { waitForResult } = await scriptInstance.functions.main(foo, bar).call(); + const { value } = await waitForResult(); expect(value).toEqual({ x: 3, diff --git a/packages/fuel-gauge/src/script-with-configurable.test.ts b/packages/fuel-gauge/src/script-with-configurable.test.ts index 0984199e35..a92985d8d7 100644 --- a/packages/fuel-gauge/src/script-with-configurable.test.ts +++ b/packages/fuel-gauge/src/script-with-configurable.test.ts @@ -36,7 +36,8 @@ describe('Script With Configurable', () => { script.setConfigurableConstants(defaultValues); - const { value } = await script.functions.main(defaultValues.FEE).call(); + const { waitForResult } = await script.functions.main(defaultValues.FEE).call(); + const { value } = await waitForResult(); expect(value).toBe(true); }); @@ -50,7 +51,8 @@ describe('Script With Configurable', () => { script.setConfigurableConstants(defaultValues); - const { value } = await script.functions.main(configurableConstants.FEE).call(); + const { waitForResult } = await script.functions.main(configurableConstants.FEE).call(); + const { value } = await waitForResult(); expect(value).toBe(false); }); @@ -62,7 +64,8 @@ describe('Script With Configurable', () => { script.setConfigurableConstants(configurableConstants); - const { value } = await script.functions.main(configurableConstants.FEE).call(); + const { waitForResult } = await script.functions.main(configurableConstants.FEE).call(); + const { value } = await waitForResult(); expect(value).toBe(true); }); @@ -78,7 +81,8 @@ describe('Script With Configurable', () => { script.setConfigurableConstants(configurableConstants); - const { value } = await script.functions.main(input.FEE).call(); + const { waitForResult } = await script.functions.main(input.FEE).call(); + const { value } = await waitForResult(); expect(value).toBe(false); }); diff --git a/packages/fuel-gauge/src/script-with-vectors.test.ts b/packages/fuel-gauge/src/script-with-vectors.test.ts index a31dfece17..cb3eabddb3 100644 --- a/packages/fuel-gauge/src/script-with-vectors.test.ts +++ b/packages/fuel-gauge/src/script-with-vectors.test.ts @@ -23,7 +23,8 @@ describe('Script With Vectors', () => { const someArray = [1, 100]; const scriptInstance = getScript<[BigNumberish[]], void>('script-with-array', wallet); - const { logs } = await scriptInstance.functions.main(someArray).call(); + const { waitForResult } = await scriptInstance.functions.main(someArray).call(); + const { logs } = await waitForResult(); expect(logs.map((n) => n.toNumber())).toEqual([1]); }); @@ -35,7 +36,8 @@ describe('Script With Vectors', () => { const scriptInvocationScope = scriptInstance.functions.main(someVec); - const { logs } = await scriptInvocationScope.call(); + const { waitForResult } = await scriptInvocationScope.call(); + const { logs } = await waitForResult(); const formattedLog = logs.map((l) => (typeof l === 'string' ? l : l.toNumber())); @@ -88,7 +90,8 @@ describe('Script With Vectors', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const scriptInstance = getScript<[any], void>('script-with-vector-mixed', wallet); - const { value } = await scriptInstance.functions.main(importantDates).call(); + const { waitForResult } = await scriptInstance.functions.main(importantDates).call(); + const { value } = await waitForResult(); expect(value).toBe(true); }); @@ -155,7 +158,8 @@ describe('Script With Vectors', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const scriptInstance = getScript<[any[]], void>('script-with-vector-advanced', wallet); - const { value } = await scriptInstance.functions.main(vectorOfStructs).call(); + const { waitForResult } = await scriptInstance.functions.main(vectorOfStructs).call(); + const { value } = await waitForResult(); expect(value).toBe(true); }); }); diff --git a/packages/fuel-gauge/src/std-lib-string.test.ts b/packages/fuel-gauge/src/std-lib-string.test.ts index 2661fdbc73..145782e022 100644 --- a/packages/fuel-gauge/src/std-lib-string.test.ts +++ b/packages/fuel-gauge/src/std-lib-string.test.ts @@ -32,14 +32,20 @@ describe('std-lib-string Tests', () => { getFuelGaugeForcProject(FuelGaugeProjectsEnum.PREDICATE_STD_LIB_STRING); it('should test std-lib-string return', async () => { - const { value } = await contractInstance.functions.return_dynamic_string().call(); + const { waitForResult } = await contractInstance.functions + .return_dynamic_string() + .call(); + + const { value } = await waitForResult(); + expect(value).toBe('Hello World'); }); it('should test std-lib-string input', async () => { const INPUT = 'Hello World'; - const { value } = await contractInstance.functions.accepts_dynamic_string(INPUT).call(); + const { waitForResult } = await contractInstance.functions.accepts_dynamic_string(INPUT).call(); + const { value } = await waitForResult(); expect(value).toBeUndefined(); }); @@ -84,7 +90,8 @@ describe('std-lib-string Tests', () => { const scriptInstance = getScript('script-std-lib-string', wallet); const INPUT = 'Hello World'; - const { value } = await scriptInstance.functions.main(INPUT).call(); + const { waitForResult } = await scriptInstance.functions.main(INPUT).call(); + const { value } = await waitForResult(); expect(value).toBe(true); }); diff --git a/packages/fuel-gauge/src/storage-test-contract.test.ts b/packages/fuel-gauge/src/storage-test-contract.test.ts index bbd6abe971..891058d689 100644 --- a/packages/fuel-gauge/src/storage-test-contract.test.ts +++ b/packages/fuel-gauge/src/storage-test-contract.test.ts @@ -41,9 +41,16 @@ describe('StorageTestContract', () => { const contract = await setup(); // Call contract - const { value: initializeResult } = await contract.functions.initialize_counter(1300).call(); + const call1 = await contract.functions.initialize_counter(1300).call(); + + // Wait for result + const { value: initializeResult } = await call1.waitForResult(); + expect(initializeResult.toHex()).toEqual(toHex(1300)); - const { value: incrementResult } = await contract.functions.increment_counter(37).call(); + + const call2 = await contract.functions.increment_counter(37).call(); + const { value: incrementResult } = await call2.waitForResult(); + expect(incrementResult.toHex()).toEqual(toHex(1337)); const { value: count } = await contract.functions.counter().simulate(); @@ -81,9 +88,12 @@ describe('StorageTestContract', () => { }); const { contract } = await waitForResult(); // #endregion contract-deployment-storage-slots-inline - const { value: initializeResult } = await contract.functions.initialize_counter(1300).call(); + const call1 = await contract.functions.initialize_counter(1300).call(); + const { value: initializeResult } = await call1.waitForResult(); expect(initializeResult.toHex()).toEqual(toHex(1300)); - const { value: incrementResult } = await contract.functions.increment_counter(37).call(); + + const call2 = await contract.functions.increment_counter(37).call(); + const { value: incrementResult } = await call2.waitForResult(); expect(incrementResult.toHex()).toEqual(toHex(1337)); const { value: count } = await contract.functions.counter().simulate(); diff --git a/packages/fuel-gauge/src/str-slice.test.ts b/packages/fuel-gauge/src/str-slice.test.ts index 26485cc7c1..69bb4a5fa3 100644 --- a/packages/fuel-gauge/src/str-slice.test.ts +++ b/packages/fuel-gauge/src/str-slice.test.ts @@ -28,7 +28,9 @@ describe('str slice', () => { const input = 'contract-input'; const output = 'contract-return'; - const { value } = await strSliceContract.functions.echoes_str_slice(input).call(); + const { waitForResult } = await strSliceContract.functions.echoes_str_slice(input).call(); + const { value } = await waitForResult(); + expect(value).toEqual(output); }); @@ -71,7 +73,8 @@ describe('str slice', () => { const script = await ScriptStrSliceAbi__factory.createInstance(sender); const input = 'script-input'; const output = 'script-return'; - const { value } = await script.functions.main(input).call(); + const { waitForResult } = await script.functions.main(input).call(); + const { value } = await waitForResult(); expect(value).toEqual(output); }); }); diff --git a/packages/fuel-gauge/src/token-test-contract.test.ts b/packages/fuel-gauge/src/token-test-contract.test.ts index e6dbe22252..f410bd2a78 100644 --- a/packages/fuel-gauge/src/token-test-contract.test.ts +++ b/packages/fuel-gauge/src/token-test-contract.test.ts @@ -40,7 +40,8 @@ describe('TokenTestContract', () => { const addressId = { bits: userWallet.address.toB256() }; // Mint some coins - const { transactionResult } = await token.functions.mint_coins(100).call(); + const mintCall1 = await token.functions.mint_coins(100).call(); + const { transactionResult } = await mintCall1.waitForResult(); const { mintedAssets } = transactionResult; @@ -51,12 +52,17 @@ describe('TokenTestContract', () => { return value; }; // Check balance is correct - await token.functions.mint_coins(100).call(); + const mintCall2 = await token.functions.mint_coins(100).call(); + await mintCall2.waitForResult(); expect((await getBalance()).toHex()).toEqual(toHex(200)); // Transfer some coins - await token.functions.transfer_to_address(addressId, assetId, 50).call(); + const { waitForResult } = await token.functions + .transfer_to_address(addressId, assetId, 50) + .call(); + + await waitForResult(); // Check new wallet received the coins from the token contract const { balances } = await userWallet.getBalances(); @@ -77,7 +83,8 @@ describe('TokenTestContract', () => { const functionCallOne = token.functions.mint_to_addresses(addresses, 10); await functionCallOne.dryRun(); - const { transactionResult } = await functionCallOne.call(); + const call1 = await functionCallOne.call(); + const { transactionResult } = await call1.waitForResult(); const { mintedAssets } = transactionResult; const assetId = mintedAssets?.[0].assetId; @@ -96,7 +103,8 @@ describe('TokenTestContract', () => { const functionCallTwo = token.functions.mint_to_addresses(addresses, 10); await functionCallTwo.simulate(); - await functionCallTwo.call(); + const call2 = await functionCallTwo.call(); + await call2.waitForResult(); ({ balances } = await wallet1.getBalances()); tokenBalance = balances.find((b) => b.assetId === assetId); @@ -110,7 +118,9 @@ describe('TokenTestContract', () => { tokenBalance = balances.find((b) => b.assetId === assetId); expect(tokenBalance?.amount.toHex()).toEqual(toHex(20)); - await token.functions.mint_to_addresses(addresses, 10).call(); + const call3 = await token.functions.mint_to_addresses(addresses, 10).call(); + await call3.waitForResult(); + ({ balances } = await wallet1.getBalances()); tokenBalance = balances.find((b) => b.assetId === assetId); expect(tokenBalance?.amount.toHex()).toEqual(toHex(30)); @@ -132,7 +142,8 @@ describe('TokenTestContract', () => { }; // mint 100 coins - const { transactionResult } = await token.functions.mint_coins(100).call(); + const { waitForResult } = await token.functions.mint_coins(100).call(); + const { transactionResult } = await waitForResult(); const { mintedAssets } = transactionResult; const assetId: AssetId = { bits: mintedAssets?.[0].assetId || '' }; diff --git a/packages/fuel-gauge/src/transaction-summary.test.ts b/packages/fuel-gauge/src/transaction-summary.test.ts index a51d2fdd07..2507ee80ca 100644 --- a/packages/fuel-gauge/src/transaction-summary.test.ts +++ b/packages/fuel-gauge/src/transaction-summary.test.ts @@ -258,18 +258,19 @@ describe('TransactionSummary', () => { const recipient = Wallet.generate({ provider }); const amount = 1055; - const { - transactionResult: { mintedAssets }, - } = await contract.functions.mint_coins(100000).call(); + const call1 = await contract.functions.mint_coins(100000).call(); + const res1 = await call1.waitForResult(); - const { assetId } = mintedAssets[0]; + const { assetId } = res1.transactionResult.mintedAssets[0]; - const { - transactionResult: { operations }, - } = await contract.functions + const call2 = await contract.functions .transfer_to_address({ bits: recipient.address.toB256() }, { bits: assetId }, amount) .call(); + const { + transactionResult: { operations }, + } = await call2.waitForResult(); + validateTransferOperation({ operations, sender: contract.id, @@ -312,9 +313,7 @@ describe('TransactionSummary', () => { ], }; - const { - transactionResult: { operations }, - } = await senderContract.functions + const { waitForResult } = await senderContract.functions .multi_address_transfer([ // 3 Transfers for recipient contract 1 ...transferData1.quantities.map(({ amount, assetId }) => ({ @@ -331,6 +330,10 @@ describe('TransactionSummary', () => { ]) .call(); + const { + transactionResult: { operations }, + } = await waitForResult(); + validateTransferOperation({ operations, sender: senderContract.id, @@ -348,15 +351,15 @@ describe('TransactionSummary', () => { const contractRecipient = await setupContract({ cache: false }); + const call1 = await contractSender.functions.mint_coins(100000).call(); + const { transactionResult: { mintedAssets }, - } = await contractSender.functions.mint_coins(100000).call(); + } = await call1.waitForResult(); const amount = 2345; const { assetId } = mintedAssets[0]; - const { - transactionResult: { operations }, - } = await contractSender.functions + const call2 = await contractSender.functions .transfer_to_contract( { bits: contractRecipient.id.toB256() }, { bits: mintedAssets[0].assetId }, @@ -364,6 +367,10 @@ describe('TransactionSummary', () => { ) .call(); + const { + transactionResult: { operations }, + } = await call2.waitForResult(); + validateTransferOperation({ operations, sender: contractSender.id, @@ -409,9 +416,7 @@ describe('TransactionSummary', () => { ], }; - const { - transactionResult: { operations }, - } = await senderContract.functions + const { waitForResult } = await senderContract.functions .multi_contract_transfer([ // 2 Transfers for recipient contract 1 ...transferData1.quantities.map(({ amount, assetId }) => ({ @@ -428,6 +433,10 @@ describe('TransactionSummary', () => { ]) .call(); + const { + transactionResult: { operations }, + } = await waitForResult(); + validateTransferOperation({ operations, sender: senderContract.id, diff --git a/packages/fuel-gauge/src/vector-types.test.ts b/packages/fuel-gauge/src/vector-types.test.ts index 7700d797b7..0eba10dda0 100644 --- a/packages/fuel-gauge/src/vector-types.test.ts +++ b/packages/fuel-gauge/src/vector-types.test.ts @@ -102,7 +102,7 @@ describe('Vector Types Validation', () => { const setupContract = getSetupContract('vector-types-contract'); const contractInstance = await setupContract(); - const { value } = await contractInstance.functions + const { waitForResult } = await contractInstance.functions .test_all( U32_VEC, VEC_IN_VEC, @@ -117,6 +117,9 @@ describe('Vector Types Validation', () => { VEC_IN_A_VEC_IN_A_STRUCT_IN_A_VEC ) .call(); + + const { value } = await waitForResult(); + expect(value).toBe(true); }); @@ -124,7 +127,7 @@ describe('Vector Types Validation', () => { const wallet = await setup(); const scriptInstance = getScript('vector-types-script', wallet); - const { value } = await scriptInstance.functions + const { waitForResult } = await scriptInstance.functions .main( U32_VEC, VEC_IN_VEC, @@ -140,6 +143,8 @@ describe('Vector Types Validation', () => { ) .call(); + const { value } = await waitForResult(); + expect(value).toBe(true); }); diff --git a/packages/fuel-gauge/src/vectors.test.ts b/packages/fuel-gauge/src/vectors.test.ts index d386b3327d..eb314510af 100644 --- a/packages/fuel-gauge/src/vectors.test.ts +++ b/packages/fuel-gauge/src/vectors.test.ts @@ -22,7 +22,8 @@ describe('Vector Tests', () => { it('should test u8 vector input/output', async () => { const INPUT = [8, 6, 7, 5, 3, 0, 9]; - const { value } = await contractInstance.functions.echo_u8(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_u8(INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -30,7 +31,8 @@ describe('Vector Tests', () => { it('should test u16 vector input/output', async () => { const INPUT = [8, 6, 7, 5, 3, 0, 9]; - const { value } = await contractInstance.functions.echo_u16(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_u16(INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -38,7 +40,8 @@ describe('Vector Tests', () => { it('should test u32 vector input/output', async () => { const INPUT = [8, 6, 7, 5, 3, 0, 9]; - const { value } = await contractInstance.functions.echo_u32(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_u32(INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -46,7 +49,8 @@ describe('Vector Tests', () => { it('should test u64 vector input/output', async () => { const INPUT = [8, 6, 7, 5, 3, 0, 9]; - const { value } = await contractInstance.functions.echo_u64(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_u64(INPUT).call(); + const { value } = await waitForResult(); expect(toNumbers(value)).toStrictEqual(INPUT); }); @@ -54,7 +58,8 @@ describe('Vector Tests', () => { it('should test bool vector input/output', async () => { const INPUT = [true, false, true, true]; - const { value } = await contractInstance.functions.echo_bool(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_bool(INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -62,7 +67,8 @@ describe('Vector Tests', () => { it('should test b256 vector input/output', async () => { const INPUT = [hexlify(randomBytes(32)), hexlify(randomBytes(32)), hexlify(randomBytes(32))]; - const { value } = await contractInstance.functions.echo_b256(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_b256(INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -70,7 +76,8 @@ describe('Vector Tests', () => { it('should test b512 vector input/output', async () => { const INPUT = [hexlify(randomBytes(64)), hexlify(randomBytes(64)), hexlify(randomBytes(64))]; - const { value } = await contractInstance.functions.echo_b512(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_b512(INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -78,7 +85,8 @@ describe('Vector Tests', () => { it('should test str[1] vector input/output', async () => { const INPUT = ['a', 'b', 'c', 'd']; - const { value } = await contractInstance.functions.echo_str_1(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_str_1(INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -86,7 +94,8 @@ describe('Vector Tests', () => { it('should test str[9] vector input/output', async () => { const INPUT = ['123456789', 'abcdefghi', 'catdogcat', 'onetwoone']; - const { value } = await contractInstance.functions.echo_str_9(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_str_9(INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -98,7 +107,10 @@ describe('Vector Tests', () => { [5, 6], ]; - const { value } = await contractInstance.functions.echo_tuple_u8(INPUT).call(); + const { waitForResult } = await contractInstance.functions + .echo_tuple_u8(INPUT) + .call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -110,7 +122,8 @@ describe('Vector Tests', () => { [5555, 6], ]; - const { value } = await contractInstance.functions.echo_tuple_u64(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_tuple_u64(INPUT).call(); + const { value } = await waitForResult(); expect(value.map((nums: BN[]) => toNumbers(nums))).toStrictEqual(INPUT); }); @@ -121,7 +134,10 @@ describe('Vector Tests', () => { [5, 6], ]; - const { value } = await contractInstance.functions.echo_array_u8(INPUT).call(); + const { waitForResult } = await contractInstance.functions + .echo_array_u8(INPUT) + .call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -133,7 +149,8 @@ describe('Vector Tests', () => { [11500, 22600, 33700, 55000, 669999], ]; - const { value } = await contractInstance.functions.echo_array_u64(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_array_u64(INPUT).call(); + const { value } = await waitForResult(); expect(value.map((nums: BN[]) => toNumbers(nums))).toStrictEqual(INPUT); }); @@ -147,7 +164,10 @@ describe('Vector Tests', () => { [true, true], ]; - const { value } = await contractInstance.functions.echo_array_bool(INPUT).call(); + const { waitForResult } = await contractInstance.functions + .echo_array_bool(INPUT) + .call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -165,7 +185,10 @@ describe('Vector Tests', () => { }, ]; - const { value } = await contractInstance.functions.echo_struct_u8(INPUT).call(); + const { waitForResult } = await contractInstance.functions + .echo_struct_u8(INPUT) + .call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -183,7 +206,10 @@ describe('Vector Tests', () => { }, ]; - const { value } = await contractInstance.functions.echo_struct_b256(INPUT).call(); + const { waitForResult } = await contractInstance.functions + .echo_struct_b256(INPUT) + .call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -208,9 +234,10 @@ describe('Vector Tests', () => { }, ]; - const { value } = await contractInstance.functions + const { waitForResult } = await contractInstance.functions .echo_struct_complex(INPUT) .call(); + const { value } = await waitForResult(); expect( value.map((data: ComplexStruct) => ({ @@ -229,7 +256,10 @@ describe('Vector Tests', () => { SmallEnum.Empty, ]; - const { value } = await contractInstance.functions.echo_enum_small(INPUT).call(); + const { waitForResult } = await contractInstance.functions + .echo_enum_small(INPUT) + .call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -247,7 +277,10 @@ describe('Vector Tests', () => { }, ]; - const { value } = await contractInstance.functions.echo_enum_big(INPUT).call(); + const { waitForResult } = await contractInstance.functions + .echo_enum_big(INPUT) + .call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -255,7 +288,8 @@ describe('Vector Tests', () => { it('should test Option vector input/output', async () => { const INPUT = [undefined, 1, undefined, 2, undefined, 3]; - const { value } = await contractInstance.functions.echo_option_u8(INPUT).call(); + const { waitForResult } = await contractInstance.functions.echo_option_u8(INPUT).call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -266,7 +300,10 @@ describe('Vector Tests', () => { vec: [1, 5, 98], }; - const { value } = await contractInstance.functions.echo_vector_inside_struct(INPUT).call(); + const { waitForResult } = await contractInstance.functions + .echo_vector_inside_struct(INPUT) + .call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -276,7 +313,10 @@ describe('Vector Tests', () => { vec: [1, 5, 98], }; - const { value } = await contractInstance.functions.echo_vector_inside_enum(INPUT).call(); + const { waitForResult } = await contractInstance.functions + .echo_vector_inside_enum(INPUT) + .call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -284,7 +324,10 @@ describe('Vector Tests', () => { it('should test Vec inside vector input/output', async () => { const INPUT = [[1, 5, 98], [2, 44], [34]]; - const { value } = await contractInstance.functions.echo_vector_inside_vector(INPUT).call(); + const { waitForResult } = await contractInstance.functions + .echo_vector_inside_vector(INPUT) + .call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -300,9 +343,10 @@ describe('Vector Tests', () => { [1, 4], ]; - const { value } = await contractInstance.functions + const { waitForResult } = await contractInstance.functions .echo_struct_and_vector_tuple(INPUT[0], INPUT[1]) .call(); + const { value } = await waitForResult(); expect(value[0].foo).toStrictEqual(INPUT[0].foo); expect(value[0].bar.toNumber()).toStrictEqual(INPUT[0].bar.toNumber()); @@ -313,7 +357,10 @@ describe('Vector Tests', () => { it('should test Vec and b256 tuple input/output', async () => { const INPUT = [[1, 8, 3, 2, 55, 215], hexlify(randomBytes(32))]; - const { value } = await contractInstance.functions.echo_vector_and_b256_tuple(...INPUT).call(); + const { waitForResult } = await contractInstance.functions + .echo_vector_and_b256_tuple(...INPUT) + .call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -324,7 +371,10 @@ describe('Vector Tests', () => { [1, 254, 55], ]; - const { value } = await contractInstance.functions.echo_two_vectors_tuple(...INPUT).call(); + const { waitForResult } = await contractInstance.functions + .echo_two_vectors_tuple(...INPUT) + .call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); @@ -332,19 +382,24 @@ describe('Vector Tests', () => { it('should test u32 and three different vectors tuple input/output', async () => { const INPUT = [91000, [true, true, false], [95000, 153333], [20000, 65500]]; - const { value } = await contractInstance.functions.echo_u32_then_three_vectors(...INPUT).call(); + const { waitForResult } = await contractInstance.functions + .echo_u32_then_three_vectors(...INPUT) + .call(); + const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); }); it('should test multiCall vectors', async () => { - const { value: results } = await contractInstance + const { waitForResult } = await contractInstance .multiCall([ contractInstance.functions.echo_u8([1]), contractInstance.functions.echo_u8([2, 2]), contractInstance.functions.echo_u8([3, 3, 3]), ]) .call(); + + const { value: results } = await waitForResult(); expect(results).toStrictEqual([[1], [2, 2], [3, 3, 3]]); }); }); diff --git a/packages/program/src/functions/base-invocation-scope.ts b/packages/program/src/functions/base-invocation-scope.ts index 09fc19eb85..f5bbcda27a 100644 --- a/packages/program/src/functions/base-invocation-scope.ts +++ b/packages/program/src/functions/base-invocation-scope.ts @@ -1,7 +1,14 @@ /* eslint-disable no-param-reassign */ /* eslint-disable @typescript-eslint/no-explicit-any */ import type { InputValue, JsonAbi } from '@fuel-ts/abi-coder'; -import type { Provider, CoinQuantity, CallResult, Account, TransferParams } from '@fuel-ts/account'; +import type { + Provider, + CoinQuantity, + CallResult, + Account, + TransferParams, + TransactionResponse, +} from '@fuel-ts/account'; import { ScriptTransactionRequest } from '@fuel-ts/account'; import { Address } from '@fuel-ts/address'; import { ErrorCode, FuelError } from '@fuel-ts/errors'; @@ -360,26 +367,40 @@ export class BaseInvocationScope { } /** - * Submits a transaction. + * Submits the contract call transaction and returns a promise that resolves to an object + * containing the transaction ID and a function to wait for the result. The promise will resolve + * as soon as the transaction is submitted to the node. * - * @returns The result of the function invocation. + * @returns A promise that resolves to an object containing: + * - `transactionId`: The ID of the submitted transaction. + * - `waitForResult`: A function that waits for the transaction result. + * @template T - The type of the return value. */ - async call(): Promise> { + async call(): Promise<{ + transactionId: string; + waitForResult: () => Promise>; + }> { assert(this.program.account, 'Wallet is required!'); const transactionRequest = await this.fundWithRequiredCoins(); - const response = await this.program.account.sendTransaction(transactionRequest, { - awaitExecution: true, + const response = (await this.program.account.sendTransaction(transactionRequest, { + awaitExecution: false, estimateTxDependencies: false, - }); - - return buildFunctionResult({ - funcScope: this.functionInvocationScopes, - isMultiCall: this.isMultiCall, - program: this.program, - transactionResponse: response, - }); + })) as TransactionResponse; + + const transactionId = response.id; + + return { + transactionId, + waitForResult: async () => + buildFunctionResult({ + funcScope: this.functionInvocationScopes, + isMultiCall: this.isMultiCall, + program: this.program, + transactionResponse: response, + }), + }; } /** diff --git a/templates/nextjs/src/app/page.tsx b/templates/nextjs/src/app/page.tsx index 588cd40b98..d44b12a02f 100644 --- a/templates/nextjs/src/app/page.tsx +++ b/templates/nextjs/src/app/page.tsx @@ -48,7 +48,12 @@ export default function Home() { ); } - const { value } = await contract.functions.increment_counter(bn(1)).call(); + const { waitForResult } = await contract.functions + .increment_counter(bn(1)) + .call(); + + const { value } = await waitForResult(); + setCounter(value.toNumber()); await refreshWalletBalance?.(); diff --git a/templates/nextjs/src/app/script/page.tsx b/templates/nextjs/src/app/script/page.tsx index c5e87b36c6..95ac804a0f 100644 --- a/templates/nextjs/src/app/script/page.tsx +++ b/templates/nextjs/src/app/script/page.tsx @@ -31,7 +31,8 @@ export default function ScriptExample() { return toast.error("Script not loaded"); } - const { value } = await script.functions.main(bn(input)).call(); + const { waitForResult } = await script.functions.main(bn(input)).call(); + const { value } = await waitForResult(); setResult(value.toString()); } catch (error) {