diff --git a/.changeset/pretty-hornets-walk.md b/.changeset/pretty-hornets-walk.md new file mode 100644 index 0000000000..39b9693086 --- /dev/null +++ b/.changeset/pretty-hornets-walk.md @@ -0,0 +1,5 @@ +--- +"@fuel-ts/contract": patch +--- + +chore: integrate `launchTestNode` into current test suites diff --git a/apps/demo-typegen/src/demo.test.ts b/apps/demo-typegen/src/demo.test.ts index 2aacfd77a0..fb7c920de4 100644 --- a/apps/demo-typegen/src/demo.test.ts +++ b/apps/demo-typegen/src/demo.test.ts @@ -1,6 +1,6 @@ // #region Testing-in-ts-ts -import { ContractFactory, Provider, toHex, Wallet, FUEL_NETWORK_URL, Address } from 'fuels'; -import { generateTestWallet, safeExec } from 'fuels/test-utils'; +import { ContractFactory, toHex, Address, Wallet } from 'fuels'; +import { launchTestNode, safeExec } from 'fuels/test-utils'; import storageSlots from '../contract/out/release/demo-contract-storage_slots.json'; @@ -10,19 +10,21 @@ import type { PredicateAbiInputs } from './predicate-types'; import { PredicateAbi__factory } from './predicate-types'; import { ScriptAbi__factory } from './script-types'; -let baseAssetId: string; - /** * @group node + * @group browser */ describe('ExampleContract', () => { - beforeAll(async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - }); it('with imported storage slots', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - const wallet = await generateTestWallet(provider, [[500_000, baseAssetId]]); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 500_000, + }, + }); + + const { + wallets: [wallet], + } = launched; // #region typegen-demo-contract-storage-slots // #context import storageSlots from './contract/out/debug/demo-contract-storage_slots.json'; @@ -36,8 +38,15 @@ describe('ExampleContract', () => { expect(contract.id).toBeTruthy(); }); it('should return the input', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - const wallet = await generateTestWallet(provider, [[500_000, baseAssetId]]); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 500_000, + }, + }); + + const { + wallets: [wallet], + } = launched; // Deploy const factory = new ContractFactory(bytecode, DemoContractAbi__factory.abi, wallet); @@ -64,8 +73,15 @@ describe('ExampleContract', () => { }); it('deployContract method', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - const wallet = await generateTestWallet(provider, [[500_000, baseAssetId]]); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 500_000, + }, + }); + + const { + wallets: [wallet], + } = launched; // #region typegen-demo-contract-factory-deploy // #context import { DemoContractAbi__factory } from './types'; @@ -88,8 +104,17 @@ describe('ExampleContract', () => { // #endregion Testing-in-ts-ts it('should throw when simulating via contract factory with wallet with no resources', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - const fundedWallet = await generateTestWallet(provider, [[500_000, baseAssetId]]); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 500_000, + }, + }); + + const { + provider, + wallets: [fundedWallet], + } = launched; + const unfundedWallet = Wallet.generate({ provider }); const factory = new ContractFactory(bytecode, DemoContractAbi__factory.abi, fundedWallet); @@ -103,8 +128,16 @@ it('should throw when simulating via contract factory with wallet with no resour }); it('should not throw when dry running via contract factory with wallet with no resources', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - const fundedWallet = await generateTestWallet(provider, [[500_000, baseAssetId]]); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 500_000, + }, + }); + + const { + provider, + wallets: [fundedWallet], + } = launched; const unfundedWallet = Wallet.generate({ provider }); const factory = new ContractFactory(bytecode, DemoContractAbi__factory.abi, fundedWallet); @@ -116,8 +149,15 @@ it('should not throw when dry running via contract factory with wallet with no r }); test('Example script', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - const wallet = await generateTestWallet(provider, [[500_000, baseAssetId]]); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 500_000, + }, + }); + + const { + wallets: [wallet], + } = launched; // #region typegen-demo-script // #context import { ScriptAbi__factory } from './types'; @@ -135,18 +175,27 @@ test('Example predicate', async () => { // #context import { PredicateAbi__factory } from './types'; // In this exchange, we are first transferring some coins to the predicate - const provider = await Provider.create(FUEL_NETWORK_URL); - const wallet = await generateTestWallet(provider, [[500_000, baseAssetId]]); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 10_000_000_000, + }, + }); + + const { + provider, + wallets: [wallet], + } = launched; + const receiver = Wallet.fromAddress(Address.fromRandom(), provider); const predicateData: PredicateAbiInputs = []; const predicate = PredicateAbi__factory.createInstance(provider, predicateData); - const tx = await wallet.transfer(predicate.address, 150_000, baseAssetId); + const tx = await wallet.transfer(predicate.address, 1_000_000, provider.getBaseAssetId()); const { isStatusSuccess } = await tx.wait(); // Then we are transferring some coins from the predicate to a random address (receiver) - const tx2 = await predicate.transfer(receiver.address, 50_000, baseAssetId); + const tx2 = await predicate.transfer(receiver.address, 50_000, provider.getBaseAssetId()); await tx2.wait(); expect((await receiver.getBalance()).toNumber()).toEqual(50_000); diff --git a/apps/docs-snippets/test/fixtures/forc-projects/return-script/Forc.toml b/apps/docs-snippets/test/fixtures/forc-projects/return-script/Forc.toml index e8fdc98ec2..c4bf2224e3 100644 --- a/apps/docs-snippets/test/fixtures/forc-projects/return-script/Forc.toml +++ b/apps/docs-snippets/test/fixtures/forc-projects/return-script/Forc.toml @@ -1,4 +1,5 @@ [project] +authors = ["Fuel Labs "] entry = "main.sw" license = "Apache-2.0" name = "return-script" diff --git a/packages/contract/src/test-utils/launch-test-node.ts b/packages/contract/src/test-utils/launch-test-node.ts index 1987632aa2..0b78bbc365 100644 --- a/packages/contract/src/test-utils/launch-test-node.ts +++ b/packages/contract/src/test-utils/launch-test-node.ts @@ -7,12 +7,15 @@ import type { import { FuelError } from '@fuel-ts/errors'; import type { BytesLike } from '@fuel-ts/interfaces'; import type { SnapshotConfigs } from '@fuel-ts/utils'; +import { EventEmitter } from 'events'; import { readFileSync } from 'fs'; import * as path from 'path'; import { mergeDeepRight } from 'ramda'; import type { DeployContractOptions, DeployContractResult } from '../contract-factory'; +EventEmitter.defaultMaxListeners = 20; + export interface ContractDeployer { deployContract( bytecode: BytesLike, diff --git a/packages/fuel-gauge/src/advanced-logging.test.ts b/packages/fuel-gauge/src/advanced-logging.test.ts index f38b99121c..baf9c13aa7 100644 --- a/packages/fuel-gauge/src/advanced-logging.test.ts +++ b/packages/fuel-gauge/src/advanced-logging.test.ts @@ -1,36 +1,34 @@ import type { FuelError } from '@fuel-ts/errors'; -import type { Contract, Provider, WalletUnlocked } from 'fuels'; import { Script, bn } from 'fuels'; -import { generateTestWallet } from 'fuels/test-utils'; - -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; - -import { getSetupContract } from './utils'; - -const setupContract = getSetupContract('advanced-logging'); -const setupOtherContract = getSetupContract('advanced-logging-other-contract'); - -let provider: Provider; -let advancedLogContract: Contract; -let otherAdvancedLogContract: Contract; -let advancedLogId: string; -let otherLogId: string; -let baseAssetId: string; - -beforeAll(async () => { - advancedLogContract = await setupContract(); - otherAdvancedLogContract = await setupOtherContract({ cache: false }); - provider = advancedLogContract.provider; - advancedLogId = advancedLogContract.id.toB256(); - otherLogId = otherAdvancedLogContract.id.toB256(); - baseAssetId = provider.getBaseAssetId(); -}); +import { launchTestNode } from 'fuels/test-utils'; + +import { ScriptCallContractAbi__factory } from '../test/typegen'; +import { + AdvancedLoggingAbi__factory, + AdvancedLoggingOtherContractAbi__factory, + CallTestContractAbi__factory, + ConfigurableContractAbi__factory, + CoverageContractAbi__factory, +} from '../test/typegen/contracts'; +import AdvancedLoggingAbiHex from '../test/typegen/contracts/AdvancedLoggingAbi.hex'; +import AdvancedLoggingOtherContractAbiHex from '../test/typegen/contracts/AdvancedLoggingOtherContractAbi.hex'; +import CallTestContractAbiHex from '../test/typegen/contracts/CallTestContractAbi.hex'; +import ConfigurableContractAbiHex from '../test/typegen/contracts/ConfigurableContractAbi.hex'; +import CoverageContractAbiHex from '../test/typegen/contracts/CoverageContractAbi.hex'; + +import { launchTestContract } from './utils'; /** * @group node + * @group browser */ describe('Advanced Logging', () => { it('can get log data', async () => { + using advancedLogContract = await launchTestContract({ + deployer: AdvancedLoggingAbi__factory, + bytecode: AdvancedLoggingAbiHex, + }); + const { waitForResult } = await advancedLogContract.functions.test_function().call(); const { value, logs } = await waitForResult(); @@ -76,6 +74,11 @@ describe('Advanced Logging', () => { }); it('can get log data from require [condition=true]', async () => { + using advancedLogContract = await launchTestContract({ + deployer: AdvancedLoggingAbi__factory, + bytecode: AdvancedLoggingAbiHex, + }); + const { waitForResult } = await advancedLogContract.functions .test_function_with_require(1, 1) .call(); @@ -87,6 +90,11 @@ describe('Advanced Logging', () => { }); it('can get log data from require [condition=false]', async () => { + using advancedLogContract = await launchTestContract({ + deployer: AdvancedLoggingAbi__factory, + bytecode: AdvancedLoggingAbiHex, + }); + const invocation = advancedLogContract.functions.test_function_with_require(1, 3); try { await invocation.call(); @@ -116,6 +124,20 @@ describe('Advanced Logging', () => { }); it('can get log data from a downstream Contract', async () => { + using launched = await launchTestNode({ + contractsConfigs: [ + { deployer: AdvancedLoggingAbi__factory, bytecode: AdvancedLoggingAbiHex }, + { + deployer: AdvancedLoggingOtherContractAbi__factory, + bytecode: AdvancedLoggingOtherContractAbiHex, + }, + ], + }); + + const { + contracts: [advancedLogContract, otherAdvancedLogContract], + } = launched; + const INPUT = 3; const { waitForResult } = await advancedLogContract.functions .test_log_from_other_contract(INPUT, otherAdvancedLogContract.id.toB256()) @@ -134,11 +156,6 @@ describe('Advanced Logging', () => { }); describe('should properly decode all logs in a multicall with inter-contract calls', () => { - const setupCallTest = getSetupContract(FuelGaugeProjectsEnum.CALL_TEST_CONTRACT); - const setupConfigurable = getSetupContract(FuelGaugeProjectsEnum.CONFIGURABLE_CONTRACT); - const setupCoverage = getSetupContract(FuelGaugeProjectsEnum.COVERAGE_CONTRACT); - - let wallet: WalletUnlocked; const testStruct = { a: true, b: 100000, @@ -154,19 +171,34 @@ describe('Advanced Logging', () => { 'fuelfuel', ]; - beforeAll(async () => { - wallet = await generateTestWallet(provider, [[500_000, baseAssetId]]); - }); - it('when using InvacationScope', async () => { - const callTest = await setupCallTest({ cache: false }); - const configurable = await setupConfigurable({ cache: false }); - const coverage = await setupCoverage({ cache: false }); + using launched = await launchTestNode({ + contractsConfigs: [ + { deployer: AdvancedLoggingAbi__factory, bytecode: AdvancedLoggingAbiHex }, + { + deployer: AdvancedLoggingOtherContractAbi__factory, + bytecode: AdvancedLoggingOtherContractAbiHex, + }, + { deployer: CallTestContractAbi__factory, bytecode: CallTestContractAbiHex }, + { deployer: ConfigurableContractAbi__factory, bytecode: ConfigurableContractAbiHex }, + { deployer: CoverageContractAbi__factory, bytecode: CoverageContractAbiHex }, + ], + }); + + const { + contracts: [ + advancedLogContract, + otherAdvancedLogContract, + callTest, + configurable, + coverage, + ], + } = launched; const { waitForResult } = await callTest .multiCall([ advancedLogContract.functions - .test_log_from_other_contract(10, otherLogId) + .test_log_from_other_contract(10, otherAdvancedLogContract.id.toB256()) .addContracts([otherAdvancedLogContract]), callTest.functions.boo(testStruct), configurable.functions.echo_struct(), @@ -182,14 +214,37 @@ describe('Advanced Logging', () => { }); it('when using ScriptTransactionRequest', async () => { - const callTest = await setupCallTest({ cache: false }); - const configurable = await setupConfigurable({ cache: false }); - const coverage = await setupCoverage({ cache: false }); + using launched = await launchTestNode({ + contractsConfigs: [ + { deployer: AdvancedLoggingAbi__factory, bytecode: AdvancedLoggingAbiHex }, + { + deployer: AdvancedLoggingOtherContractAbi__factory, + bytecode: AdvancedLoggingOtherContractAbiHex, + }, + { deployer: CallTestContractAbi__factory, bytecode: CallTestContractAbiHex }, + { deployer: ConfigurableContractAbi__factory, bytecode: ConfigurableContractAbiHex }, + { deployer: CoverageContractAbi__factory, bytecode: CoverageContractAbiHex }, + ], + walletsConfig: { + amountPerCoin: 500_000, + }, + }); + + const { + contracts: [ + advancedLogContract, + otherAdvancedLogContract, + callTest, + configurable, + coverage, + ], + wallets: [wallet], + } = launched; const request = await callTest .multiCall([ advancedLogContract.functions - .test_log_from_other_contract(10, otherLogId) + .test_log_from_other_contract(10, otherAdvancedLogContract.id.toB256()) .addContracts([otherAdvancedLogContract]), callTest.functions.boo(testStruct), configurable.functions.echo_struct(), @@ -197,7 +252,7 @@ describe('Advanced Logging', () => { ]) .getTransactionRequest(); - const txCost = await provider.getTransactionCost(request, { + const txCost = await launched.provider.getTransactionCost(request, { resourcesOwner: wallet, }); @@ -223,14 +278,8 @@ describe('Advanced Logging', () => { }); describe('decode logs from a script set to manually call other contracts', () => { - const { abiContents, binHexlified } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.SCRIPT_CALL_CONTRACT - ); - const amount = Math.floor(Math.random() * 10) + 1; - let wallet: WalletUnlocked; - const expectedLogs = [ 'Hello from script', 'Hello from main Contract', @@ -239,14 +288,35 @@ describe('Advanced Logging', () => { amount, ]; - beforeAll(async () => { - wallet = await generateTestWallet(provider, [[300_000, baseAssetId]]); - }); + beforeAll(async () => {}); it('when using InvocationScope', async () => { - const script = new Script(binHexlified, abiContents, wallet); + using launched = await launchTestNode({ + contractsConfigs: [ + { deployer: AdvancedLoggingAbi__factory, bytecode: AdvancedLoggingAbiHex }, + { + deployer: AdvancedLoggingOtherContractAbi__factory, + bytecode: AdvancedLoggingOtherContractAbiHex, + }, + ], + walletsConfig: { + amountPerCoin: 300_000, + }, + }); + + const { + contracts: [advancedLogContract, otherAdvancedLogContract], + wallets: [wallet], + } = launched; + + const script = new Script( + ScriptCallContractAbi__factory.bin, + ScriptCallContractAbi__factory.abi, + wallet + ); + const { waitForResult } = await script.functions - .main(advancedLogId, otherLogId, amount) + .main(advancedLogContract.id.toB256(), otherAdvancedLogContract.id.toB256(), amount) .addContracts([advancedLogContract, otherAdvancedLogContract]) .call(); @@ -256,14 +326,36 @@ describe('Advanced Logging', () => { }); it('when using ScriptTransactionRequest', async () => { - const script = new Script(binHexlified, abiContents, wallet); + using launched = await launchTestNode({ + contractsConfigs: [ + { deployer: AdvancedLoggingAbi__factory, bytecode: AdvancedLoggingAbiHex }, + { + deployer: AdvancedLoggingOtherContractAbi__factory, + bytecode: AdvancedLoggingOtherContractAbiHex, + }, + ], + walletsConfig: { + amountPerCoin: 300_000, + }, + }); + + const { + contracts: [advancedLogContract, otherAdvancedLogContract], + wallets: [wallet], + } = launched; + + const script = new Script( + ScriptCallContractAbi__factory.bin, + ScriptCallContractAbi__factory.abi, + wallet + ); const request = await script.functions - .main(advancedLogId, otherLogId, amount) + .main(advancedLogContract.id.toB256(), otherAdvancedLogContract.id.toB256(), amount) .addContracts([advancedLogContract, otherAdvancedLogContract]) .getTransactionRequest(); - const txCost = await provider.getTransactionCost(request, { + const txCost = await launched.provider.getTransactionCost(request, { resourcesOwner: wallet, }); diff --git a/packages/fuel-gauge/src/auth-testing.test.ts b/packages/fuel-gauge/src/auth-testing.test.ts index 240b92decb..52bd1a5896 100644 --- a/packages/fuel-gauge/src/auth-testing.test.ts +++ b/packages/fuel-gauge/src/auth-testing.test.ts @@ -1,32 +1,22 @@ -import type { Contract, WalletUnlocked } from 'fuels'; -import { ContractFactory, Provider, getRandomB256, FUEL_NETWORK_URL } from 'fuels'; -import { generateTestWallet } from 'fuels/test-utils'; +import { getRandomB256 } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; +import { AuthTestingContractAbi__factory } from '../test/typegen/contracts'; +import AuthTestingAbiHex from '../test/typegen/contracts/AuthTestingContractAbi.hex'; -let contractInstance: Contract; -let wallet: WalletUnlocked; -let baseAssetId: string; +import { launchTestContract } from './utils'; /** * @group node + * @group browser */ describe('Auth Testing', () => { - beforeAll(async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - wallet = await generateTestWallet(provider, [[1_000_000, baseAssetId]]); - - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.AUTH_TESTING_CONTRACT - ); - - const factory = new ContractFactory(binHexlified, abiContents, wallet); - const { waitForResult } = await factory.deployContract(); - ({ contract: contractInstance } = await waitForResult()); - }); - it('can get is_caller_external', async () => { + using contractInstance = await launchTestContract({ + deployer: AuthTestingContractAbi__factory, + bytecode: AuthTestingAbiHex, + }); + const { waitForResult } = await contractInstance.functions.is_caller_external().call(); const { value } = await waitForResult(); @@ -34,6 +24,17 @@ describe('Auth Testing', () => { }); it('can check_msg_sender [with correct id]', async () => { + using launched = await launchTestNode({ + contractsConfigs: [ + { deployer: AuthTestingContractAbi__factory, bytecode: AuthTestingAbiHex }, + ], + }); + + const { + contracts: [contractInstance], + wallets: [wallet], + } = launched; + const { waitForResult } = await contractInstance.functions .check_msg_sender({ bits: wallet.address.toB256() }) .call(); @@ -44,6 +45,11 @@ describe('Auth Testing', () => { }); it('can check_msg_sender [with incorrect id]', async () => { + using contractInstance = await launchTestContract({ + deployer: AuthTestingContractAbi__factory, + bytecode: AuthTestingAbiHex, + }); + await expect( contractInstance.functions.check_msg_sender({ bits: getRandomB256() }).call() ).rejects.toThrow( diff --git a/packages/fuel-gauge/src/await-execution.test.ts b/packages/fuel-gauge/src/await-execution.test.ts index 2e300e600f..e25a9465c2 100644 --- a/packages/fuel-gauge/src/await-execution.test.ts +++ b/packages/fuel-gauge/src/await-execution.test.ts @@ -1,43 +1,48 @@ -import { Provider, WalletUnlocked, randomBytes, Wallet, FUEL_NETWORK_URL } from 'fuels'; -import { launchNode } from 'fuels/test-utils'; +import { WalletUnlocked, randomBytes, Wallet } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; /** * @group node + * @group browser */ describe('await-execution', () => { test('awaiting execution of a transaction on the provider works', async () => { - const { cleanup, ip, port } = await launchNode({ - args: ['--poa-instant', 'false', '--poa-interval-period', '400ms'], + using launched = await launchTestNode({ + nodeOptions: { + args: ['--poa-instant', 'false', '--poa-interval-period', '400ms'], + }, }); - const nodeProvider = await Provider.create(`http://${ip}:${port}/v1/graphql`); - const baseAssetId = nodeProvider.getBaseAssetId(); - const genesisWallet = new WalletUnlocked( - process.env.GENESIS_SECRET || randomBytes(32), - nodeProvider - ); + const { + provider, + wallets: [genesisWallet], + } = launched; - const destination = Wallet.generate({ provider: nodeProvider }); + const destination = Wallet.generate({ provider }); - const transfer = await genesisWallet.createTransfer(destination.address, 100, baseAssetId, { - gasLimit: 10_000, - }); + const transfer = await genesisWallet.createTransfer( + destination.address, + 100, + provider.getBaseAssetId(), + { + gasLimit: 10_000, + } + ); transfer.updateWitnessByOwner( genesisWallet.address, await genesisWallet.signTransaction(transfer) ); - const response = await nodeProvider.sendTransaction(transfer, { awaitExecution: true }); + const response = await provider.sendTransaction(transfer, { awaitExecution: true }); expect(response.gqlTransaction?.status?.type).toBe('SuccessStatus'); - - cleanup(); }); test.skip('transferring funds with awaitExecution works', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - const baseAssetId = provider.getBaseAssetId(); + using launched = await launchTestNode(); + + const { provider } = launched; const genesisWallet = new WalletUnlocked( process.env.GENESIS_SECRET || randomBytes(32), @@ -48,43 +53,35 @@ describe('await-execution', () => { const destination = Wallet.generate({ provider }); - await genesisWallet.transfer( - destination.address, - 100, - baseAssetId, - { - gasLimit: 10_000, - } - // { awaitExecution: true } - ); + await genesisWallet.transfer(destination.address, 100, provider.getBaseAssetId(), { + gasLimit: 10_000, + }); expect(sendTransactionSpy).toHaveBeenCalledTimes(1); const awaitExecutionArg = sendTransactionSpy.mock.calls[0][1]; expect(awaitExecutionArg).toMatchObject({ awaitExecution: true }); }); - test.skip('withdrawToBaseLayer works with awaitExecution', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - const genesisWallet = new WalletUnlocked( - process.env.GENESIS_SECRET || randomBytes(32), - provider - ); + test('withdrawToBaseLayer works with awaitExecution', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 10_000_000_000, + }, + }); + + const { + provider, + wallets: [genesisWallet], + } = launched; const sendTransactionSpy = vi.spyOn(provider, 'sendTransaction'); const destination = Wallet.generate({ provider }); - await genesisWallet.withdrawToBaseLayer( - destination.address, - 100, - { - gasLimit: 10_000, - } - // { awaitExecution: true } - ); + await genesisWallet.withdrawToBaseLayer(destination.address, 100, { + gasLimit: 100_000, + }); expect(sendTransactionSpy).toHaveBeenCalledTimes(1); - const awaitExecutionArg = sendTransactionSpy.mock.calls[0][1]; - expect(awaitExecutionArg).toMatchObject({ awaitExecution: true }); }); }); diff --git a/packages/fuel-gauge/src/bytecode-sway-lib.test.ts b/packages/fuel-gauge/src/bytecode-sway-lib.test.ts index e8af780fa8..0f9485d143 100644 --- a/packages/fuel-gauge/src/bytecode-sway-lib.test.ts +++ b/packages/fuel-gauge/src/bytecode-sway-lib.test.ts @@ -1,25 +1,26 @@ -import { FUEL_NETWORK_URL, Predicate, Provider, arrayify } from 'fuels'; +import { Predicate, arrayify } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; import { defaultPredicateAbi } from '../test/fixtures/abi/predicate'; import { defaultPredicateBytecode } from '../test/fixtures/bytecode/predicate'; +import { BytecodeSwayLibAbi__factory } from '../test/typegen/contracts'; +import BytecodeSwayLibAbiHex from '../test/typegen/contracts/BytecodeSwayLibAbi.hex'; -import { getSetupContract } from './utils'; +import { launchTestContract } from './utils'; /** * @group node + * @group browser */ describe('bytecode computations', () => { - test('compute_bytecode_root', async () => { - const { binHexlified: bytecodeFromFile } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.CALL_TEST_CONTRACT - ); - - const setupContract = getSetupContract(FuelGaugeProjectsEnum.BYTECODE_SWAY_LIB); - const contract = await setupContract(); + it('compute_bytecode_root', async () => { + using contract = await launchTestContract({ + deployer: BytecodeSwayLibAbi__factory, + bytecode: BytecodeSwayLibAbiHex, + }); const { waitForResult } = await contract.functions - .compute_bytecode_root(arrayify(bytecodeFromFile)) + .compute_bytecode_root(Array.from(arrayify(BytecodeSwayLibAbiHex))) .call(); const { logs } = await waitForResult(); @@ -30,20 +31,18 @@ describe('bytecode computations', () => { expect(bytecodeRoot.length).toBe(66); }); - test('verify_contract_bytecode', async () => { - const { binHexlified: bytecodeFromFile } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.BYTECODE_SWAY_LIB - ); - - const setupContract = getSetupContract(FuelGaugeProjectsEnum.BYTECODE_SWAY_LIB); - const contract = await setupContract(); + it('verify_contract_bytecode', async () => { + using contract = await launchTestContract({ + deployer: BytecodeSwayLibAbi__factory, + bytecode: BytecodeSwayLibAbiHex, + }); const { waitForResult } = await contract.functions .verify_contract_bytecode( { bits: contract.id.toB256(), }, - Array.from(arrayify(bytecodeFromFile)) + Array.from(arrayify(BytecodeSwayLibAbiHex)) ) .call(); @@ -52,8 +51,20 @@ describe('bytecode computations', () => { expect(value).toBeTruthy(); }); - test('compute_predicate_address', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); + it('compute_predicate_address', async () => { + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: BytecodeSwayLibAbi__factory, + bytecode: BytecodeSwayLibAbiHex, + }, + ], + }); + + const { + contracts: [contract], + provider, + } = launched; const predicate = new Predicate({ bytecode: defaultPredicateBytecode, @@ -63,9 +74,6 @@ describe('bytecode computations', () => { const address = predicate.address; - const setupContract = getSetupContract(FuelGaugeProjectsEnum.BYTECODE_SWAY_LIB); - const contract = await setupContract(); - const { waitForResult } = await contract.functions .compute_predicate_address(Array.from(arrayify(defaultPredicateBytecode))) .call(); diff --git a/packages/fuel-gauge/src/bytes.test.ts b/packages/fuel-gauge/src/bytes.test.ts index 89207c4936..48f70d7d37 100644 --- a/packages/fuel-gauge/src/bytes.test.ts +++ b/packages/fuel-gauge/src/bytes.test.ts @@ -1,16 +1,12 @@ -import { bn, Predicate, Wallet, Address, Provider, FUEL_NETWORK_URL } from 'fuels'; -import type { BN, Contract } from 'fuels'; -import { generateTestWallet } from 'fuels/test-utils'; +import { bn, Predicate, Wallet, Address } from 'fuels'; +import type { BN } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; +import { PredicateBytesAbi__factory, ScriptBytesAbi__factory } from '../test/typegen'; +import { BytesAbi__factory } from '../test/typegen/contracts'; +import BytesAbiHex from '../test/typegen/contracts/BytesAbi.hex'; -import { getScript, getSetupContract } from './utils'; - -const setupContract = getSetupContract('bytes'); -let contractInstance: Contract; -beforeAll(async () => { - contractInstance = await setupContract(); -}); +import { launchTestContract } from './utils'; type SomeEnum = { First?: boolean; @@ -21,27 +17,16 @@ type Wrapper = { inner: number[][]; inner_enum: SomeEnum; }; - -const setup = async (balance = 500_000) => { - const provider = await Provider.create(FUEL_NETWORK_URL); - const baseAssetId = provider.getBaseAssetId(); - // Create wallet - const wallet = await generateTestWallet(provider, [[balance, baseAssetId]]); - - return wallet; -}; - /** * @group node + * @group browser */ describe('Bytes Tests', () => { - let baseAssetId: string; - beforeAll(async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - }); - it('should test bytes output', async () => { + using contractInstance = await launchTestContract({ + deployer: BytesAbi__factory, + bytecode: BytesAbiHex, + }); const INPUT = 10; const { waitForResult } = await contractInstance.functions.return_bytes(INPUT).call(); @@ -51,6 +36,11 @@ describe('Bytes Tests', () => { }); it('should test bytes output [100 items]', async () => { + using contractInstance = await launchTestContract({ + deployer: BytesAbi__factory, + bytecode: BytesAbiHex, + }); + const INPUT = 100; const { waitForResult } = await contractInstance.functions.return_bytes(INPUT).call(); @@ -60,6 +50,11 @@ describe('Bytes Tests', () => { }); it('should test bytes input', async () => { + using contractInstance = await launchTestContract({ + deployer: BytesAbi__factory, + bytecode: BytesAbiHex, + }); + const INPUT = [40, 41, 42]; const { waitForResult } = await contractInstance.functions.accept_bytes(INPUT).call(); @@ -69,6 +64,10 @@ describe('Bytes Tests', () => { }); it('should test bytes input [nested]', async () => { + using contractInstance = await launchTestContract({ + deployer: BytesAbi__factory, + bytecode: BytesAbiHex, + }); const bytes = [40, 41, 42]; const INPUT: Wrapper = { @@ -86,16 +85,27 @@ describe('Bytes Tests', () => { }); it('should test bytes input [predicate-bytes]', async () => { - const wallet = await setup(1_000_000); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: BytesAbi__factory, + bytecode: BytesAbiHex, + }, + ], + walletsConfig: { + amountPerCoin: 1_000_000, + }, + }); + + const { + wallets: [wallet], + } = launched; + const receiver = Wallet.fromAddress(Address.fromRandom(), wallet.provider); const amountToPredicate = 500_000; const amountToReceiver = 50; type MainArgs = [Wrapper]; - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.PREDICATE_BYTES - ); - const bytes = [40, 41, 42]; const INPUT: Wrapper = { inner: [bytes, bytes], @@ -103,23 +113,33 @@ describe('Bytes Tests', () => { }; const predicate = new Predicate({ - bytecode: binHexlified, - abi: abiContents, + bytecode: PredicateBytesAbi__factory.bin, + abi: PredicateBytesAbi__factory.abi, provider: wallet.provider, inputData: [INPUT], }); // setup predicate - const setupTx = await wallet.transfer(predicate.address, amountToPredicate, baseAssetId, { - gasLimit: 10_000, - }); + const setupTx = await wallet.transfer( + predicate.address, + amountToPredicate, + launched.provider.getBaseAssetId(), + { + gasLimit: 10_000, + } + ); await setupTx.waitForResult(); const initialReceiverBalance = await receiver.getBalance(); - const tx = await predicate.transfer(receiver.address, amountToReceiver, baseAssetId, { - gasLimit: 10_000, - }); + const tx = await predicate.transfer( + receiver.address, + amountToReceiver, + launched.provider.getBaseAssetId(), + { + gasLimit: 10_000, + } + ); const { isStatusSuccess } = await tx.waitForResult(); @@ -133,9 +153,15 @@ describe('Bytes Tests', () => { }); it('should test bytes input [script-bytes]', async () => { - const wallet = await setup(); - type MainArgs = [number, Wrapper]; - const scriptInstance = getScript('script-bytes', wallet); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 500_000, + }, + }); + + const { + wallets: [wallet], + } = launched; const bytes = [40, 41, 42]; const INPUT: Wrapper = { @@ -143,6 +169,8 @@ describe('Bytes Tests', () => { inner_enum: { Second: bytes }, }; + const scriptInstance = ScriptBytesAbi__factory.createInstance(wallet); + const { waitForResult } = await scriptInstance.functions.main(1, INPUT).call(); const { value } = await waitForResult(); diff --git a/packages/fuel-gauge/src/call-test-contract.test.ts b/packages/fuel-gauge/src/call-test-contract.test.ts index 7e81228fd0..0dc4f880bc 100644 --- a/packages/fuel-gauge/src/call-test-contract.test.ts +++ b/packages/fuel-gauge/src/call-test-contract.test.ts @@ -1,19 +1,11 @@ import type { Contract } from 'fuels'; import { BN, bn, toHex } from 'fuels'; -import { ASSET_A, launchTestNode } from 'fuels/test-utils'; +import { ASSET_A } from 'fuels/test-utils'; import { CallTestContractAbi__factory } from '../test/typegen/contracts'; import bytecode from '../test/typegen/contracts/CallTestContractAbi.hex'; -const setupContract = async () => { - const { - contracts: [contract], - cleanup, - } = await launchTestNode({ - contractsConfigs: [{ deployer: CallTestContractAbi__factory, bytecode }], - }); - return Object.assign(contract, { [Symbol.dispose]: cleanup }); -}; +import { launchTestContract } from './utils'; const U64_MAX = bn(2).pow(64).sub(1); @@ -23,7 +15,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(); + using contract = await launchTestContract({ deployer: CallTestContractAbi__factory, bytecode }); + const { waitForResult } = await contract.functions.foo(num).call(); const { value } = await waitForResult(); expect(value.toHex()).toEqual(bn(num).add(1).toHex()); @@ -37,7 +30,8 @@ describe('CallTestContract', () => { [{ a: false, b: U64_MAX.sub(1) }], [{ a: true, b: U64_MAX.sub(1) }], ])('can call a contract with structs (%p)', async (struct) => { - using contract = await setupContract(); + using contract = await launchTestContract({ deployer: CallTestContractAbi__factory, bytecode }); + const { waitForResult } = await contract.functions.boo(struct).call(); const { value } = await waitForResult(); expect(value.a).toEqual(!struct.a); @@ -45,7 +39,7 @@ describe('CallTestContract', () => { }); it('can call a function with empty arguments', async () => { - using contract = await setupContract(); + using contract = await launchTestContract({ deployer: CallTestContractAbi__factory, bytecode }); const call1 = await contract.functions.empty().call(); const { value: empty } = await call1.waitForResult(); @@ -66,7 +60,7 @@ describe('CallTestContract', () => { }); it('function with empty return should resolve undefined', async () => { - using contract = await setupContract(); + using contract = await launchTestContract({ deployer: CallTestContractAbi__factory, bytecode }); // Call method with no params but with no result and no value on config const { waitForResult } = await contract.functions.return_void().call(); @@ -144,7 +138,10 @@ describe('CallTestContract', () => { async (method, { values, expected }) => { // Type cast to Contract because of the dynamic nature of the test // But the function names are type-constrained to correct Contract's type - using contract = await setupContract(); + using contract = await launchTestContract({ + deployer: CallTestContractAbi__factory, + bytecode, + }); const { waitForResult } = await (contract as Contract).functions[method](...values).call(); const { value } = await waitForResult(); @@ -158,7 +155,7 @@ describe('CallTestContract', () => { ); it('Forward amount value on contract call', async () => { - using contract = await setupContract(); + using contract = await launchTestContract({ deployer: CallTestContractAbi__factory, bytecode }); const baseAssetId = contract.provider.getBaseAssetId(); const { waitForResult } = await contract.functions .return_context_amount() @@ -173,7 +170,7 @@ describe('CallTestContract', () => { }); it('Forward asset_id on contract call', async () => { - using contract = await setupContract(); + using contract = await launchTestContract({ deployer: CallTestContractAbi__factory, bytecode }); const assetId = ASSET_A; const { waitForResult } = await contract.functions @@ -189,7 +186,7 @@ describe('CallTestContract', () => { }); it('Forward asset_id on contract simulate call', async () => { - using contract = await setupContract(); + using contract = await launchTestContract({ deployer: CallTestContractAbi__factory, bytecode }); const assetId = ASSET_A; const { waitForResult } = await contract.functions @@ -205,7 +202,7 @@ describe('CallTestContract', () => { }); it('can make multiple calls', async () => { - using contract = await setupContract(); + using contract = await launchTestContract({ deployer: CallTestContractAbi__factory, bytecode }); const num = 1337; const numC = 10; @@ -243,14 +240,20 @@ describe('CallTestContract', () => { }); it('Calling a simple contract function does only one dry run', async () => { - using contract = await setupContract(); + using contract = await launchTestContract({ + deployer: CallTestContractAbi__factory, + bytecode, + }); const dryRunSpy = vi.spyOn(contract.provider.operations, 'dryRun'); await contract.functions.no_params().call(); expect(dryRunSpy).toHaveBeenCalledOnce(); }); it('Simulating a simple contract function does two dry runs', async () => { - using contract = await setupContract(); + using contract = await launchTestContract({ + deployer: CallTestContractAbi__factory, + bytecode, + }); const dryRunSpy = vi.spyOn(contract.provider.operations, 'dryRun'); await contract.functions.no_params().simulate(); diff --git a/packages/fuel-gauge/src/configurable-contract.test.ts b/packages/fuel-gauge/src/configurable-contract.test.ts index 4213d39f94..7a828fddce 100644 --- a/packages/fuel-gauge/src/configurable-contract.test.ts +++ b/packages/fuel-gauge/src/configurable-contract.test.ts @@ -1,8 +1,8 @@ -import type { CoinQuantityLike, WalletUnlocked } from 'fuels'; -import { BN, ContractFactory, Provider, getRandomB256, FUEL_NETWORK_URL } from 'fuels'; -import { generateTestWallet } from 'fuels/test-utils'; +import { BN, getRandomB256 } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; +import { ConfigurableContractAbi__factory } from '../test/typegen/contracts'; +import ConfigurableContractAbiHex from '../test/typegen/contracts/ConfigurableContractAbi.hex'; const defaultValues = { U8: 10, @@ -25,35 +25,29 @@ const defaultValues = { }, }; -/** - * @group node - */ -describe('Configurable Contract', () => { - let wallet: WalletUnlocked; - let factory: ContractFactory; - let baseAssetId: string; - beforeAll(async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - const quantities: CoinQuantityLike[] = [ +async function setupContract(configurableConstants?: { [name: string]: unknown }) { + return launchTestNode({ + contractsConfigs: [ { - amount: 1_000_000, - assetId: baseAssetId, + deployer: ConfigurableContractAbi__factory, + bytecode: ConfigurableContractAbiHex, + options: { configurableConstants }, }, - ]; - - wallet = await generateTestWallet(provider, quantities); - - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.CONFIGURABLE_CONTRACT - ); - - factory = new ContractFactory(binHexlified, abiContents, wallet); + ], }); +} +/** + * @group node + * @group browser + */ +describe('Configurable Contract', () => { it('should assert default values', async () => { - const { waitForResult } = await factory.deployContract(); - const { contract } = await waitForResult(); + using contractInstance = await setupContract(); + + const { + contracts: [contract], + } = contractInstance; const { value } = await contract.functions.echo_configurables().simulate(); @@ -77,10 +71,11 @@ describe('Configurable Contract', () => { expect(defaultValues.U8).not.toBe(configurableConstants.U8); - const { waitForResult } = await factory.deployContract({ - configurableConstants, - }); - const { contract } = await waitForResult(); + using contractInstance = await setupContract(configurableConstants); + + const { + contracts: [contract], + } = contractInstance; const { value } = await contract.functions.echo_u8().simulate(); @@ -94,10 +89,11 @@ describe('Configurable Contract', () => { expect(defaultValues.U16).not.toBe(configurableConstants.U16); - const { waitForResult } = await factory.deployContract({ - configurableConstants, - }); - const { contract } = await waitForResult(); + using contractInstance = await setupContract(configurableConstants); + + const { + contracts: [contract], + } = contractInstance; const { value } = await contract.functions.echo_u16().simulate(); @@ -111,10 +107,11 @@ describe('Configurable Contract', () => { expect(defaultValues.U32).not.toBe(configurableConstants.U32); - const { waitForResult } = await factory.deployContract({ - configurableConstants, - }); - const { contract } = await waitForResult(); + using contractInstance = await setupContract(configurableConstants); + + const { + contracts: [contract], + } = contractInstance; const { value } = await contract.functions.echo_u32().simulate(); @@ -128,10 +125,11 @@ describe('Configurable Contract', () => { expect(defaultValues.U64).not.toBe(configurableConstants.U64); - const { waitForResult } = await factory.deployContract({ - configurableConstants, - }); - const { contract } = await waitForResult(); + using contractInstance = await setupContract(configurableConstants); + + const { + contracts: [contract], + } = contractInstance; const { value } = await contract.functions.echo_u64().simulate(); @@ -145,10 +143,11 @@ describe('Configurable Contract', () => { expect(defaultValues.BOOL).not.toBe(configurableConstants.BOOL); - const { waitForResult } = await factory.deployContract({ - configurableConstants, - }); - const { contract } = await waitForResult(); + using contractInstance = await setupContract(configurableConstants); + + const { + contracts: [contract], + } = contractInstance; const { value } = await contract.functions.echo_bool().simulate(); @@ -162,10 +161,11 @@ describe('Configurable Contract', () => { expect(defaultValues.B256).not.toBe(configurableConstants.B256); - const { waitForResult } = await factory.deployContract({ - configurableConstants, - }); - const { contract } = await waitForResult(); + using contractInstance = await setupContract(configurableConstants); + + const { + contracts: [contract], + } = contractInstance; const { value } = await contract.functions.echo_b256().simulate(); @@ -179,10 +179,11 @@ describe('Configurable Contract', () => { expect(defaultValues.ENUM).not.toBe(configurableConstants.ENUM); - const { waitForResult } = await factory.deployContract({ - configurableConstants, - }); - const { contract } = await waitForResult(); + using contractInstance = await setupContract(configurableConstants); + + const { + contracts: [contract], + } = contractInstance; const { value } = await contract.functions.echo_enum().simulate(); @@ -199,10 +200,11 @@ describe('Configurable Contract', () => { expect(defaultValues.ARRAY).not.toStrictEqual(configurableConstants.ARRAY); - const { waitForResult } = await factory.deployContract({ - configurableConstants, - }); - const { contract } = await waitForResult(); + using contractInstance = await setupContract(configurableConstants); + + const { + contracts: [contract], + } = contractInstance; const { value } = await contract.functions.echo_array().simulate(); @@ -216,10 +218,11 @@ describe('Configurable Contract', () => { expect(defaultValues.STR_4).not.toBe(configurableConstants.STR_4); - const { waitForResult } = await factory.deployContract({ - configurableConstants, - }); - const { contract } = await waitForResult(); + using contractInstance = await setupContract(configurableConstants); + + const { + contracts: [contract], + } = contractInstance; const { value } = await contract.functions.echo_str4().simulate(); @@ -233,10 +236,11 @@ describe('Configurable Contract', () => { expect(defaultValues.TUPLE).not.toStrictEqual(configurableConstants.TUPLE); - const { waitForResult } = await factory.deployContract({ - configurableConstants, - }); - const { contract } = await waitForResult(); + using contractInstance = await setupContract(configurableConstants); + + const { + contracts: [contract], + } = contractInstance; const { value } = await contract.functions.echo_tuple().simulate(); @@ -254,10 +258,11 @@ describe('Configurable Contract', () => { expect(defaultValues.STRUCT_1).not.toStrictEqual(configurableConstants.STRUCT_1); - const { waitForResult } = await factory.deployContract({ - configurableConstants, - }); - const { contract } = await waitForResult(); + using contractInstance = await setupContract(configurableConstants); + + const { + contracts: [contract], + } = contractInstance; const { value } = await contract.functions.echo_struct().simulate(); diff --git a/packages/fuel-gauge/src/contract-factory.test.ts b/packages/fuel-gauge/src/contract-factory.test.ts index 3dff8a6836..b720c77806 100644 --- a/packages/fuel-gauge/src/contract-factory.test.ts +++ b/packages/fuel-gauge/src/contract-factory.test.ts @@ -1,46 +1,34 @@ import type { Account, TransactionResult } from '@fuel-ts/account'; import { FuelError, ErrorCode } from '@fuel-ts/errors'; -import { BN, bn, toHex, Interface, Provider, ContractFactory, FUEL_NETWORK_URL } from 'fuels'; -import { generateTestWallet, expectToThrowFuelError } from 'fuels/test-utils'; +import { expectToThrowFuelError } from '@fuel-ts/errors/test-utils'; +import { BN, bn, toHex, Interface, ContractFactory } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; +import { StorageTestContractAbi__factory } from '../test/typegen/contracts'; +import StorageTestContractAbiHex from '../test/typegen/contracts/StorageTestContractAbi.hex'; + +import { launchTestContract } from './utils'; /** * @group node + * @group browser */ describe('Contract Factory', () => { - let baseAssetId: string; - - const { - binHexlified: byteCode, - abiContents: abi, - storageSlots, - } = getFuelGaugeForcProject(FuelGaugeProjectsEnum.STORAGE_TEST_CONTRACT); - - const createContractFactory = async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - const wallet = await generateTestWallet(provider, [[5_000_000, baseAssetId]]); - - // send byteCode and ABI to ContractFactory to load - const factory = new ContractFactory(byteCode, abi, wallet); - return factory; - }; - it('Creates a factory from inputs that can return call results', async () => { - const factory = await createContractFactory(); - - const { waitForResult } = await factory.deployContract(); - const { contract } = await waitForResult(); - + using contract = await launchTestContract({ + deployer: StorageTestContractAbi__factory, + bytecode: StorageTestContractAbiHex, + }); expect(contract.interface).toBeInstanceOf(Interface); - const call1 = await contract.functions.initialize_counter(41).call(); - const { value: valueInitial } = await call1.waitForResult(); + const { waitForResult } = await contract.functions.initialize_counter(41).call(); + const { value: valueInitial } = await waitForResult(); expect(valueInitial.toHex()).toEqual(toHex(41)); - const call2 = await contract.functions.increment_counter(1).call(); - const { value } = await call2.waitForResult(); + const { waitForResult: waitForNextResult } = await contract.functions + .increment_counter(1) + .call(); + const { value } = await waitForNextResult(); expect(value.toHex()).toEqual(toHex(42)); const { value: value2 } = await contract.functions.increment_counter(1).dryRun(); @@ -48,10 +36,10 @@ describe('Contract Factory', () => { }); it('Creates a factory from inputs that can return transaction results', async () => { - const factory = await createContractFactory(); - - const callDeploy = await factory.deployContract(); - const { contract } = await callDeploy.waitForResult(); + using contract = await launchTestContract({ + deployer: StorageTestContractAbi__factory, + bytecode: StorageTestContractAbiHex, + }); expect(contract.interface).toBeInstanceOf(Interface); @@ -96,10 +84,10 @@ describe('Contract Factory', () => { }); it('Creates a factory from inputs that can prepare call data', async () => { - const factory = await createContractFactory(); - - const { waitForResult } = await factory.deployContract(); - const { contract } = await waitForResult(); + using contract = await launchTestContract({ + deployer: StorageTestContractAbi__factory, + bytecode: StorageTestContractAbiHex, + }); const prepared = contract.functions.increment_counter(1).getCallConfig(); expect(prepared).toEqual({ @@ -114,9 +102,21 @@ describe('Contract Factory', () => { }); it('should not override user input maxFee when calling deployContract', async () => { - const factory = await createContractFactory(); - const setFee = bn(120_000); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 5_000_000, + }, + }); + const { + wallets: [wallet], + } = launched; + const setFee = bn(120_000); + const factory = new ContractFactory( + StorageTestContractAbiHex, + StorageTestContractAbi__factory.abi, + wallet + ); const spy = vi.spyOn(factory.account as Account, 'sendTransaction'); await factory.deployContract({ @@ -131,30 +131,30 @@ describe('Contract Factory', () => { }); it('Creates a contract with initial storage fixed var names', async () => { - const factory = await createContractFactory(); - const { waitForResult } = await factory.deployContract({ - storageSlots, + using contract = await launchTestContract({ + deployer: StorageTestContractAbi__factory, + bytecode: StorageTestContractAbiHex, + storageSlots: StorageTestContractAbi__factory.storageSlots, }); - const { contract } = await waitForResult(); - const call1 = await contract.functions.return_var1().call(); - const { value: var1 } = await call1.waitForResult(); + const { waitForResult } = await contract.functions.return_var1().call(); + const { value: var1 } = await waitForResult(); expect(var1.toHex()).toEqual(toHex(0)); - const call2 = await contract.functions.return_var2().call(); - const { value: var2 } = await call2.waitForResult(); + const { waitForResult: waitForSecondResult } = await contract.functions.return_var2().call(); + const { value: var2 } = await waitForSecondResult(); expect(var2).toEqual(20); - const call3 = await contract.functions.return_var3().call(); - const { value: var3 } = await call3.waitForResult(); + const { waitForResult: waitForThirdResult } = await contract.functions.return_var3().call(); + const { value: var3 } = await waitForThirdResult(); expect(var3).toEqual(30); - const call4 = await contract.functions.return_var4().call(); - const { value: var4 } = await call4.waitForResult(); + const { waitForResult: waitForFourthResult } = await contract.functions.return_var4().call(); + const { value: var4 } = await waitForFourthResult(); expect(var4).toEqual(true); - const call5 = await contract.functions.return_var5().call(); - const { value: var5 } = await call5.waitForResult(); + const { waitForResult: waitForFifthResult } = await contract.functions.return_var5().call(); + const { value: var5 } = await waitForFifthResult(); expect(JSON.stringify(var5)).toEqual( JSON.stringify({ v1: true, @@ -164,7 +164,20 @@ describe('Contract Factory', () => { }); it('Creates a contract with initial storage (dynamic key)', async () => { - const factory = await createContractFactory(); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 5_000_000, + }, + }); + const { + wallets: [wallet], + } = launched; + + const factory = new ContractFactory( + StorageTestContractAbiHex, + StorageTestContractAbi__factory.abi, + wallet + ); const b256 = '0x626f0c36909faecc316056fca8be684ab0cd06afc63247dc008bdf9e433f927a'; const { waitForResult } = await factory.deployContract({ @@ -179,12 +192,25 @@ describe('Contract Factory', () => { }); it('Creates a contract with initial storage. Both dynamic key and fixed vars', async () => { - const factory = await createContractFactory(); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 5_000_000, + }, + }); + const { + wallets: [wallet], + } = launched; + + const factory = new ContractFactory( + StorageTestContractAbiHex, + StorageTestContractAbi__factory.abi, + wallet + ); const b256 = '0x626f0c36909faecc316056fca8be684ab0cd06afc63247dc008bdf9e433f927a'; const { waitForResult } = await factory.deployContract({ storageSlots: [ - ...storageSlots, // initializing from storage_slots.json + ...StorageTestContractAbi__factory.storageSlots, // initializing from storage_slots.json { key: '0000000000000000000000000000000000000000000000000000000000000001', value: b256 }, // Initializing manual value ], }); @@ -220,7 +246,10 @@ describe('Contract Factory', () => { }); it('should throws if calls createTransactionRequest is called when provider is not set', async () => { - const factory = new ContractFactory(byteCode, abi); + const factory = new ContractFactory( + StorageTestContractAbiHex, + StorageTestContractAbi__factory.abi + ); await expectToThrowFuelError( () => factory.createTransactionRequest(), diff --git a/packages/fuel-gauge/src/contract.test.ts b/packages/fuel-gauge/src/contract.test.ts index 43df3922b5..5b544534f8 100644 --- a/packages/fuel-gauge/src/contract.test.ts +++ b/packages/fuel-gauge/src/contract.test.ts @@ -1,11 +1,4 @@ import { ErrorCode, FuelError } from '@fuel-ts/errors'; -import type { - TransactionRequestLike, - TransactionResponse, - JsonAbi, - ScriptTransactionRequest, - TransferParams, -} from 'fuels'; import { BN, getRandomB256, @@ -18,36 +11,30 @@ import { transactionRequestify, Wallet, ContractFactory, - ZeroBytes32, FUEL_NETWORK_URL, Predicate, PolicyType, + ZeroBytes32, buildFunctionResult, } from 'fuels'; -import { - generateTestWallet, - seedTestWallet, - expectToThrowFuelError, - ASSET_A, - ASSET_B, -} from 'fuels/test-utils'; - -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; - -import { createSetupConfig } from './utils'; - -const { binHexlified: predicateBytecode } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.PREDICATE_TRUE -); +import type { + TransactionRequestLike, + TransactionResponse, + JsonAbi, + ScriptTransactionRequest, + TransferParams, +} from 'fuels'; +import { expectToThrowFuelError, ASSET_A, ASSET_B, launchTestNode } from 'fuels/test-utils'; -const { binHexlified: contractBytecode, abiContents: abi } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.CALL_TEST_CONTRACT -); +import { + CallTestContractAbi__factory, + StorageTestContractAbi__factory, +} from '../test/typegen/contracts'; +import CallTestContractAbiHex from '../test/typegen/contracts/CallTestContractAbi.hex'; +import StorageTestContractAbiHex from '../test/typegen/contracts/StorageTestContractAbi.hex'; +import { PredicateTrueAbi__factory } from '../test/typegen/predicates/factories/PredicateTrueAbi__factory'; -const setupContract = createSetupConfig({ - contractBytecode, - abi, -}); +import { launchTestContract } from './utils'; const jsonFragment: JsonAbi = { configurables: [], @@ -169,21 +156,30 @@ const txPointer = '0x00000000000000000000000000000000'; const AltToken = '0x0101010101010101010101010101010101010101010101010101010101010101'; +function setupTestContract() { + return launchTestContract({ + deployer: CallTestContractAbi__factory, + bytecode: CallTestContractAbiHex, + }); +} + /** * @group node + * @group browser */ describe('Contract', () => { - let provider: Provider; - let baseAssetId: string; - beforeAll(async () => { - provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - }); - it('generates function methods on a simple contract', async () => { - const spy = vi.spyOn(provider, 'sendTransaction'); - const wallet = await generateTestWallet(provider, [[1_000, baseAssetId]]); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000, + }, + }); + const { + wallets: [wallet], + } = launched; + const contract = new Contract(ZeroBytes32, jsonFragment, wallet); + const fragment = contract.interface.getFunction('entry_one'); const interfaceSpy = vi.spyOn(fragment, 'encodeArguments'); @@ -193,14 +189,17 @@ describe('Contract', () => { // The call will fail, but it doesn't matter } - expect(spy).toHaveBeenCalled(); expect(interfaceSpy).toHaveBeenCalled(); }); it('generates function methods on a complex contract', async () => { - const spy = vi.spyOn(provider, 'sendTransaction'); - const wallet = await generateTestWallet(provider, [[1_000, baseAssetId]]); + using launched = await launchTestNode(); + const { + wallets: [wallet], + } = launched; + const contract = new Contract(ZeroBytes32, complexFragment, wallet); + const fragment = contract.interface.getFunction('tuple_function'); const interfaceSpy = vi.spyOn(fragment, 'encodeArguments'); @@ -213,18 +212,24 @@ describe('Contract', () => { // The call will fail, but it doesn't matter } - expect(spy).toHaveBeenCalled(); expect(interfaceSpy).toHaveBeenCalled(); }); - it('assigns a provider if passed', () => { + it('assigns a provider if passed', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000, + }, + }); + const { provider } = launched; + const contract = new Contract(getRandomB256(), jsonFragment, provider); expect(contract.provider).toEqual(provider); }); it('should executes a contract call just nice', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); const numberToSend = 1336; @@ -237,7 +242,7 @@ describe('Contract', () => { }); it('should fail to execute call if gasLimit is too low', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); let failed; try { @@ -255,11 +260,23 @@ describe('Contract', () => { }); it('adds multiple contracts on invocation', async () => { - const contract = await setupContract(); - const otherContract = await setupContract({ - cache: false, + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: CallTestContractAbi__factory, + bytecode: CallTestContractAbiHex, + }, + { + deployer: CallTestContractAbi__factory, + bytecode: CallTestContractAbiHex, + }, + ], }); + const { + contracts: [contract, otherContract], + } = launched; + const scope = contract.functions.call_external_foo(1336, otherContract.id.toB256()); const { waitForResult } = await scope.call(); const { value } = await waitForResult(); @@ -268,10 +285,23 @@ describe('Contract', () => { }); it('adds multiple contracts on multicalls', async () => { - const contract = await setupContract(); - const otherContract = await setupContract({ - cache: false, + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: CallTestContractAbi__factory, + bytecode: CallTestContractAbiHex, + }, + { + deployer: CallTestContractAbi__factory, + bytecode: CallTestContractAbiHex, + }, + ], }); + + const { + contracts: [contract, otherContract], + } = launched; + const calls = [ contract.functions.foo(1336), contract.functions.call_external_foo(1336, otherContract.id.toB256()), @@ -297,7 +327,8 @@ describe('Contract', () => { }); it('submits multiple calls', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); + const { waitForResult } = await contract .multiCall([contract.functions.foo(1336), contract.functions.foo(1336)]) .call(); @@ -308,7 +339,7 @@ describe('Contract', () => { }); it('submits multiple calls, six calls', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); const { waitForResult } = await contract .multiCall([ @@ -330,7 +361,8 @@ describe('Contract', () => { }); it('submits multiple calls, eight calls', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); + const { waitForResult } = await contract .multiCall([ contract.functions.foo(1336), @@ -359,7 +391,7 @@ describe('Contract', () => { }); it('should fail to execute multiple calls if gasLimit is too low', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); let failed; try { @@ -377,8 +409,22 @@ describe('Contract', () => { }); it('adds multiple contracts on multicalls', async () => { - const contract = await setupContract(); - const otherContract = await setupContract({ cache: false }); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: CallTestContractAbi__factory, + bytecode: CallTestContractAbiHex, + }, + { + deployer: CallTestContractAbi__factory, + bytecode: CallTestContractAbiHex, + }, + ], + }); + + const { + contracts: [contract, otherContract], + } = launched; const scope = contract.multiCall([contract.functions.foo(1336)]).addContracts([otherContract]); @@ -400,7 +446,7 @@ describe('Contract', () => { }); it('dryRuns multiple calls', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); const { value: results } = await contract .multiCall([contract.functions.foo(1336), contract.functions.foo(1336)]) @@ -409,7 +455,7 @@ describe('Contract', () => { }); it('simulates multiple calls', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); const { value, callResult, gasUsed } = await contract .multiCall([contract.functions.foo(1336), contract.functions.foo(1336)]) @@ -420,7 +466,7 @@ describe('Contract', () => { }); it('Returns gasUsed and transactionId', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); const { waitForResult } = await contract .multiCall([contract.functions.foo(1336), contract.functions.foo(1336)]) @@ -432,7 +478,8 @@ describe('Contract', () => { }); it('Single call with forwarding a alt token', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); + const { waitForResult } = await contract.functions .return_context_amount() .callParams({ @@ -449,12 +496,12 @@ describe('Contract', () => { }); it('MultiCall with multiple forwarding', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); const { waitForResult } = await contract .multiCall([ contract.functions.return_context_amount().callParams({ - forward: [100, baseAssetId], + forward: [100, contract.provider.getBaseAssetId()], }), contract.functions.return_context_amount().callParams({ forward: [200, AltToken], @@ -474,13 +521,13 @@ describe('Contract', () => { }); it('Check if gas per call is lower than transaction', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); await expect( contract .multiCall([ contract.functions.return_context_amount().callParams({ - forward: [100, baseAssetId], + forward: [100, contract.provider.getBaseAssetId()], gasLimit: 100, }), contract.functions.return_context_amount().callParams({ @@ -498,7 +545,7 @@ describe('Contract', () => { }); it('can forward gas to multicall calls', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); const { waitForResult } = await contract .multiCall([ @@ -527,11 +574,11 @@ describe('Contract', () => { }); it('Get transaction cost', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); const invocationScope = contract.multiCall([ contract.functions.return_context_amount().callParams({ - forward: [100, baseAssetId], + forward: [100, contract.provider.getBaseAssetId()], }), contract.functions.return_context_amount().callParams({ forward: [200, AltToken], @@ -553,10 +600,10 @@ describe('Contract', () => { }); it('Fail before submit if gasLimit is lower than gasUsed', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); const invocationScope = contract.functions.return_context_amount().callParams({ - forward: [100, baseAssetId], + forward: [100, contract.provider.getBaseAssetId()], }); const { gasUsed } = await invocationScope.getTransactionCost(); @@ -571,7 +618,7 @@ describe('Contract', () => { }); it('calls array functions', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); const call1 = await contract.functions.take_array_boolean([true, false, false]).call(); const { value: arrayBoolean } = await call1.waitForResult(); @@ -606,7 +653,7 @@ describe('Contract', () => { }); it('calls enum functions', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); const call1 = await contract.functions .take_b256_enum({ @@ -674,11 +721,11 @@ describe('Contract', () => { }); it('dryRun and get should not validate the signature', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); const { value } = await contract .multiCall([ contract.functions.return_context_amount().callParams({ - forward: [100, baseAssetId], + forward: [100, contract.provider.getBaseAssetId()], }), contract.functions.return_context_amount().callParams({ forward: [200, AltToken], @@ -690,7 +737,7 @@ describe('Contract', () => { }); it('Parse TX to JSON and parse back to TX', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); const num = 1337; const struct = { a: true, b: 1337 }; @@ -721,16 +768,21 @@ describe('Contract', () => { }); it('Parse create TX to JSON and parse back to create TX', async () => { - const wallet = Wallet.generate({ - provider, - }); - await seedTestWallet(wallet, [ - { - amount: bn(1_000_000), - assetId: baseAssetId, + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, }, - ]); - const contract = new ContractFactory(contractBytecode, abi, wallet); + }); + const { + provider, + wallets: [wallet], + } = launched; + + const contract = new ContractFactory( + StorageTestContractAbiHex, + StorageTestContractAbi__factory.abi, + wallet + ); const { transactionRequest } = contract.createTransactionRequest(); const txRequest = JSON.stringify(transactionRequest); @@ -754,18 +806,15 @@ describe('Contract', () => { expect(result.status).toBe('success'); }); - it('Provide a custom provider and public wallet to the contract instance', async () => { - const contract = await setupContract(); + // #TODO: Discuss whether this test is still relevant + it.skip('Provide a custom provider and public wallet to the contract instance', async () => { + using contract = await setupTestContract(); + + const { provider } = contract; const externalWallet = Wallet.generate({ provider, }); - await seedTestWallet(externalWallet, [ - { - amount: bn(1_000_000), - assetId: baseAssetId, - }, - ]); // Create a custom provider to emulate a external signer // like Wallet Extension or a Hardware wallet @@ -835,19 +884,7 @@ describe('Contract', () => { }); it('should ensure multicall allows multiple heap types', async () => { - const wallet = Wallet.generate({ - provider, - }); - await seedTestWallet(wallet, [ - { - amount: bn(500_000), - assetId: baseAssetId, - }, - ]); - const factory = new ContractFactory(contractBytecode, abi, wallet); - - const deploy = await factory.deployContract(); - const { contract } = await deploy.waitForResult(); + using contract = await setupTestContract(); const vector = [5, 4, 3, 2, 1]; @@ -865,7 +902,7 @@ describe('Contract', () => { }); it('Read only call', async () => { - const contract = await setupContract({ cache: false }); + using contract = await setupTestContract(); const { value } = await contract.functions.echo_b256(contract.id.toB256()).simulate(); expect(value).toEqual(contract.id.toB256()); }); @@ -876,37 +913,74 @@ describe('Contract', () => { * currently placed inside the `fuel-gauge` package. It might make sense * to move them to another test suite when addressing https://github.com/FuelLabs/fuels-ts/issues/1043. */ - it('should tranfer asset to a deployed contract just fine (NATIVE ASSET)', async () => { - const wallet = await generateTestWallet(provider, [[10_000_000, baseAssetId]]); - - const contract = await setupContract(); + it('should transfer asset to a deployed contract just fine (NATIVE ASSET)', async () => { + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: CallTestContractAbi__factory, + bytecode: CallTestContractAbiHex, + }, + ], + walletsConfig: { + amountPerCoin: 1_000_000, + }, + }); + const { + provider, + wallets: [wallet], + contracts: [contract], + } = launched; - const initialBalance = new BN(await contract.getBalance(baseAssetId)).toNumber(); + const initialBalance = new BN(await contract.getBalance(provider.getBaseAssetId())).toNumber(); const u64Amount = bn(10_000); const amountToContract = u64Amount; - const tx = await wallet.transferToContract(contract.id, amountToContract, baseAssetId); + const tx = await wallet.transferToContract( + contract.id, + amountToContract, + provider.getBaseAssetId() + ); await tx.waitForResult(); - const finalBalance = new BN(await contract.getBalance(baseAssetId)).toNumber(); + const finalBalance = new BN(await contract.getBalance(provider.getBaseAssetId())).toNumber(); expect(finalBalance).toBe(initialBalance + amountToContract.toNumber()); }); it('should set "gasLimit" and "maxFee" when transferring amounts to contract just fine', async () => { - const wallet = await generateTestWallet(provider, [[10_000_000, baseAssetId]]); - const contract = await setupContract(); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: CallTestContractAbi__factory, + bytecode: CallTestContractAbiHex, + }, + ], + walletsConfig: { + amountPerCoin: 1_000_000, + }, + }); + const { + provider, + wallets: [wallet], + contracts: [contract], + } = launched; + const amountToContract = 5_000; const gasLimit = 80_000; const maxFee = 70_000; - const tx = await wallet.transferToContract(contract.id, amountToContract, baseAssetId, { - gasLimit, - maxFee, - }); + const tx = await wallet.transferToContract( + contract.id, + amountToContract, + provider.getBaseAssetId(), + { + gasLimit, + maxFee, + } + ); const { transaction } = await tx.waitForResult(); @@ -918,9 +992,21 @@ describe('Contract', () => { }); it('should ensure gas price and gas limit are validated when transfering to contract', async () => { - const wallet = await generateTestWallet(provider, [[1000, baseAssetId]]); - - const contract = await setupContract(); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: CallTestContractAbi__factory, + bytecode: CallTestContractAbiHex, + }, + ], + walletsConfig: { + amountPerCoin: 1_000_000, + }, + }); + const { + wallets: [wallet], + contracts: [contract], + } = launched; const amountToContract = 100; @@ -928,7 +1014,7 @@ describe('Contract', () => { const result = await wallet.transferToContract( contract.id.toB256(), amountToContract, - baseAssetId, + contract.provider.getBaseAssetId(), { gasLimit: 1, } @@ -940,12 +1026,21 @@ describe('Contract', () => { it('should tranfer asset to a deployed contract just fine (NOT NATIVE ASSET)', async () => { const asset = '0x0101010101010101010101010101010101010101010101010101010101010101'; - const wallet = await generateTestWallet(provider, [ - [500_000, baseAssetId], - [200, asset], - ]); - - const contract = await setupContract(); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: CallTestContractAbi__factory, + bytecode: CallTestContractAbiHex, + }, + ], + walletsConfig: { + amountPerCoin: 1_000_000, + }, + }); + const { + wallets: [wallet], + contracts: [contract], + } = launched; const initialBalance = new BN(await contract.getBalance(asset)).toNumber(); @@ -961,36 +1056,58 @@ describe('Contract', () => { }); it('should tranfer asset to a deployed contract just fine (FROM PREDICATE)', async () => { - const wallet = await generateTestWallet(provider, [[1_000_000, baseAssetId]]); - - const contract = await setupContract(); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: CallTestContractAbi__factory, + bytecode: CallTestContractAbiHex, + }, + ], + walletsConfig: { + amountPerCoin: 1_000_000, + }, + }); + const { + provider, + wallets: [wallet], + contracts: [contract], + } = launched; - const initialBalance = new BN(await contract.getBalance(baseAssetId)).toNumber(); + const initialBalance = new BN( + await contract.getBalance(contract.provider.getBaseAssetId()) + ).toNumber(); const amountToContract = 200; const amountToPredicate = 500_000; const predicate = new Predicate({ - bytecode: predicateBytecode, + bytecode: PredicateTrueAbi__factory.bin, provider, }); - const tx1 = await wallet.transfer(predicate.address, amountToPredicate, baseAssetId); + const tx1 = await wallet.transfer( + predicate.address, + amountToPredicate, + provider.getBaseAssetId() + ); await tx1.waitForResult(); - const tx2 = await predicate.transferToContract(contract.id, amountToContract, baseAssetId); + const tx2 = await predicate.transferToContract( + contract.id, + amountToContract, + provider.getBaseAssetId() + ); await tx2.waitForResult(); - const finalBalance = new BN(await contract.getBalance(baseAssetId)).toNumber(); + const finalBalance = new BN(await contract.getBalance(provider.getBaseAssetId())).toNumber(); expect(finalBalance).toBe(initialBalance + amountToContract); }); it('should ensure TX revert error can be extracted for dryRun and simulate calls', async () => { - const contract = await setupContract({ cache: false }); - + using contract = await setupTestContract(); const scope = contract.functions.assert_u8(10, 11); await expect(scope.dryRun()).rejects.toThrowError( @@ -1003,16 +1120,8 @@ describe('Contract', () => { }); it('should ensure assets can be transfered to wallets (SINGLE TRANSFER)', async () => { - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.CALL_TEST_CONTRACT - ); - - const wallet = await generateTestWallet(provider, [[300_000, baseAssetId]]); - - const factory = new ContractFactory(binHexlified, abiContents, wallet); - - const { waitForResult } = await factory.deployContract(); - const { contract } = await waitForResult(); + using contract = await setupTestContract(); + const { provider } = contract; const receiver = Wallet.generate({ provider }); const amountToTransfer = 300; @@ -1022,7 +1131,7 @@ describe('Contract', () => { .addTransfer({ destination: receiver.address, amount: amountToTransfer, - assetId: baseAssetId, + assetId: provider.getBaseAssetId(), }) .call(); @@ -1034,17 +1143,21 @@ describe('Contract', () => { }); it('should ensure assets can be transfered to wallets (MULTI TRANSFER)', async () => { - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.CALL_TEST_CONTRACT - ); - - const wallet = await generateTestWallet(provider, [ - [300_000, baseAssetId], - [300_000, ASSET_A], - [300_000, ASSET_B], - ]); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000, + }, + }); + const { + provider, + wallets: [wallet], + } = launched; - const factory = new ContractFactory(binHexlified, abiContents, wallet); + const factory = new ContractFactory( + CallTestContractAbiHex, + CallTestContractAbi__factory.abi, + wallet + ); const { waitForResult } = await factory.deployContract(); const { contract } = await waitForResult(); @@ -1058,7 +1171,11 @@ describe('Contract', () => { const amountToTransfer3 = 122; const transferParams: TransferParams[] = [ - { destination: receiver1.address, amount: amountToTransfer1, assetId: baseAssetId }, + { + destination: receiver1.address, + amount: amountToTransfer1, + assetId: provider.getBaseAssetId(), + }, { destination: receiver2.address, amount: amountToTransfer2, assetId: ASSET_A }, { destination: receiver3.address, amount: amountToTransfer3, assetId: ASSET_B }, ]; @@ -1066,7 +1183,7 @@ describe('Contract', () => { const call = await contract.functions.sum(40, 50).addBatchTransfer(transferParams).call(); await call.waitForResult(); - const finalBalance1 = await receiver1.getBalance(baseAssetId); + const finalBalance1 = await receiver1.getBalance(provider.getBaseAssetId()); const finalBalance2 = await receiver2.getBalance(ASSET_A); const finalBalance3 = await receiver3.getBalance(ASSET_B); @@ -1076,17 +1193,21 @@ describe('Contract', () => { }); it('should throw when trying to transfer a zero or negative amount to a contract', async () => { - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.CALL_TEST_CONTRACT - ); - - const wallet = await generateTestWallet(provider, [ - [300_000, baseAssetId], - [300_000, ASSET_A], - [300_000, ASSET_B], - ]); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000, + }, + }); + const { + provider, + wallets: [wallet], + } = launched; - const factory = new ContractFactory(binHexlified, abiContents, wallet); + const factory = new ContractFactory( + CallTestContractAbiHex, + CallTestContractAbi__factory.abi, + wallet + ); const { waitForResult } = await factory.deployContract(); @@ -1094,21 +1215,21 @@ describe('Contract', () => { await expectToThrowFuelError( async () => { - await wallet.transferToContract(contract.id, 0, baseAssetId); + await wallet.transferToContract(contract.id, 0, provider.getBaseAssetId()); }, new FuelError(ErrorCode.INVALID_TRANSFER_AMOUNT, 'Transfer amount must be a positive number.') ); await expectToThrowFuelError( async () => { - await wallet.transferToContract(contract.id, -1, baseAssetId); + await wallet.transferToContract(contract.id, -1, provider.getBaseAssetId()); }, new FuelError(ErrorCode.INVALID_TRANSFER_AMOUNT, 'Transfer amount must be a positive number.') ); }); it('should throw when using "simulate" with an unfunded wallet', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); contract.account = Wallet.generate({ provider: contract.provider }); @@ -1116,28 +1237,28 @@ describe('Contract', () => { contract.functions .return_context_amount() .callParams({ - forward: [100, baseAssetId], + forward: [100, contract.provider.getBaseAssetId()], }) .simulate() ).rejects.toThrowError('not enough coins to fit the target'); }); it('should throw when using "simulate" without a wallet', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); contract.account = null; await expect( contract.functions .return_context_amount() .callParams({ - forward: [100, baseAssetId], + forward: [100, contract.provider.getBaseAssetId()], }) .simulate() ).rejects.toThrowError('Wallet is required!'); }); it('should throw when using "simulate" with a locked wallet', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); contract.account = Wallet.fromAddress(getRandomB256()); @@ -1145,14 +1266,14 @@ describe('Contract', () => { contract.functions .return_context_amount() .callParams({ - forward: [100, baseAssetId], + forward: [100, contract.provider.getBaseAssetId()], }) .simulate() ).rejects.toThrowError('An unlocked wallet is required to simulate a contract call.'); }); it('should use "dryRun" with an unfunded wallet just fine', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); contract.account = Wallet.generate({ provider: contract.provider }); @@ -1160,14 +1281,14 @@ describe('Contract', () => { contract.functions .return_context_amount() .callParams({ - forward: [100, baseAssetId], + forward: [100, contract.provider.getBaseAssetId()], }) .dryRun() ).resolves.not.toThrow(); }); it('should ensure "get" does not spend any funds', async () => { - const contract = await setupContract({ cache: false }); + using contract = await setupTestContract(); const balance = await contract.account?.getBalance(); @@ -1182,7 +1303,7 @@ describe('Contract', () => { }); it('should ensure "get" can be used to execute a contract call without a wallet', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); // contract with no account set const contractToCall = new Contract(contract.id, contract.interface, contract.provider); @@ -1194,7 +1315,7 @@ describe('Contract', () => { }); it('should ensure "get" can be used to execute a contract call with an unfunded wallet', async () => { - const contract = await setupContract(); + using contract = await setupTestContract(); const unfundedWallet = Wallet.generate({ provider: contract.provider }); @@ -1210,13 +1331,20 @@ describe('Contract', () => { }); it('should ensure "get" does not modify the blockchain state', async () => { - const { abiContents, binHexlified } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.STORAGE_TEST_CONTRACT - ); - - const wallet = await generateTestWallet(provider, [[200_000, baseAssetId]]); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000, + }, + }); + const { + wallets: [wallet], + } = launched; - const factory = new ContractFactory(binHexlified, abiContents, wallet); + const factory = new ContractFactory( + StorageTestContractAbiHex, + StorageTestContractAbi__factory.abi, + wallet + ); const { waitForResult } = await factory.deployContract(); const { contract: storageContract } = await waitForResult(); @@ -1241,15 +1369,17 @@ describe('Contract', () => { }); it('should ensure "maxFee" and "gasLimit" can be set for a contract call', async () => { - const { abiContents, binHexlified } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.STORAGE_TEST_CONTRACT - ); - - const wallet = await generateTestWallet(provider, [[350_000, baseAssetId]]); - const factory = new ContractFactory(binHexlified, abiContents, wallet); - - const deploy = await factory.deployContract(); - const { contract: storageContract } = await deploy.waitForResult(); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: StorageTestContractAbi__factory, + bytecode: StorageTestContractAbiHex, + }, + ], + }); + const { + contracts: [storageContract], + } = launched; const gasLimit = 200_000; const maxFee = 100_000; @@ -1274,9 +1404,7 @@ describe('Contract', () => { }); it('should ensure "maxFee" and "gasLimit" can be set on a multicall', async () => { - const contract = await setupContract({ - cache: false, - }); + using contract = await setupTestContract(); const gasLimit = 500_000; const maxFee = 250_000; diff --git a/packages/fuel-gauge/src/coverage-contract.test.ts b/packages/fuel-gauge/src/coverage-contract.test.ts index b03dfbcb6f..43c372670d 100644 --- a/packages/fuel-gauge/src/coverage-contract.test.ts +++ b/packages/fuel-gauge/src/coverage-contract.test.ts @@ -1,17 +1,10 @@ -import type { BN, Message, Contract } from 'fuels'; -import { - arrayify, - bn, - toHex, - Provider, - Wallet, - ScriptTransactionRequest, - randomBytes, - hexlify, - FUEL_NETWORK_URL, -} from 'fuels'; - -import { getSetupContract } from './utils'; +import type { BN, Message } from 'fuels'; +import { arrayify, bn, toHex, Wallet, ScriptTransactionRequest, randomBytes, hexlify } from 'fuels'; + +import { CoverageContractAbi__factory } from '../test/typegen/contracts'; +import CoverageContractAbiHex from '../test/typegen/contracts/CoverageContractAbi.hex'; + +import { launchTestContract } from './utils'; const RUST_U8_MAX = 255; const RUST_U16_MAX = 65535; @@ -21,15 +14,6 @@ const B256 = '0x000000000000000000000000000000000000000000000000000000000000002a const B512 = '0x059bc9c43ea1112f3eb2bd30415de72ed24c1c4416a1316f0f48cc6f958073f42a6d8c12e4829826316d8dcf444498717b5a2fbf27defac367271065f6a1d4a5'; -const setupContract = getSetupContract('coverage-contract'); - -let contractInstance: Contract; -let baseAssetId: string; -beforeAll(async () => { - contractInstance = await setupContract(); - baseAssetId = contractInstance.provider.getBaseAssetId(); -}); - enum SmallEnum { Empty = 'Empty', } @@ -51,11 +35,21 @@ enum MixedNativeEnum { NotNative = 12, } +async function setupContract() { + return launchTestContract({ + deployer: CoverageContractAbi__factory, + bytecode: CoverageContractAbiHex, + }); +} + /** * @group node + * @group browser */ describe('Coverage Contract', () => { it('can return outputs', async () => { + using contractInstance = await setupContract(); + // Call contract methods let expectedValue: unknown = '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'; @@ -127,6 +121,7 @@ describe('Coverage Contract', () => { }); it('should test u8 variable type', async () => { + using contractInstance = await setupContract(); // #region U8 const { waitForResult } = await contractInstance.functions.echo_u8(3).call(); const { value } = await waitForResult(); @@ -135,24 +130,31 @@ describe('Coverage Contract', () => { }); it('should test u8 variable type multiple params', async () => { + using contractInstance = await setupContract(); + 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 () => { + using contractInstance = await setupContract(); 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 () => { + using contractInstance = await setupContract(); + 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 () => { + using contractInstance = await setupContract(); + const INPUT = bn(RUST_U32_MAX).add(1).toHex(); const { waitForResult } = await contractInstance.functions.echo_u64(INPUT).call(); const { value } = await waitForResult(); @@ -160,6 +162,8 @@ describe('Coverage Contract', () => { }); it('should test u256 variable type', async () => { + using contractInstance = await setupContract(); + const INPUT = U256_MAX; const { waitForResult } = await contractInstance.functions.echo_u256(INPUT).call(); const { value } = await waitForResult(); @@ -167,42 +171,55 @@ describe('Coverage Contract', () => { }); it('should test bool variable type', async () => { + using contractInstance = await setupContract(); const { waitForResult } = await contractInstance.functions.echo_bool(false).call(); const { value } = await waitForResult(); expect(value).toBe(false); }); it('should test b256 variable type', async () => { + using contractInstance = await setupContract(); + const { waitForResult } = await contractInstance.functions.echo_b256(B256).call(); const { value } = await waitForResult(); expect(value).toBe(B256); }); it('should test b512 variable type', async () => { + using contractInstance = await setupContract(); + 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 () => { + using contractInstance = await setupContract(); 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 () => { + using contractInstance = await setupContract(); + 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 () => { + using contractInstance = await setupContract(); + 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 () => { + using contractInstance = await setupContract(); + const { waitForResult } = await contractInstance.functions.echo_str_8('fuel-sdk').call(); const { value } = await waitForResult(); @@ -210,18 +227,24 @@ describe('Coverage Contract', () => { }); it('should test str[9] variable type', async () => { + using contractInstance = await setupContract(); + 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 () => { + using contractInstance = await setupContract(); + 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 () => { + using contractInstance = await setupContract(); + const INPUT = [bn(RUST_U32_MAX).add(1), bn(RUST_U32_MAX).add(2)]; const { waitForResult } = await contractInstance.functions.echo_tuple_u64(INPUT).call(); const { value } = await waitForResult(); @@ -229,6 +252,8 @@ describe('Coverage Contract', () => { }); it('should test tuple mixed variable type', async () => { + using contractInstance = await setupContract(); + const INPUT = [true, bn(RUST_U32_MAX).add(1)]; const { waitForResult } = await contractInstance.functions.echo_tuple_mixed(INPUT).call(); const { value } = await waitForResult(); @@ -236,12 +261,16 @@ describe('Coverage Contract', () => { }); it('should test array < 8 bytes variable type', async () => { + using contractInstance = await setupContract(); + const { waitForResult } = await contractInstance.functions.echo_array_u8([4, 3]).call(); const { value } = await waitForResult(); expect(value).toStrictEqual([4, 3]); }); it('should test array > 8 bytes variable type', async () => { + using contractInstance = await setupContract(); + const INPUT: [number, string, BN, string, string] = [ 11, toHex(RUST_U32_MAX + 2), @@ -257,12 +286,16 @@ describe('Coverage Contract', () => { }); it('should test array bool variable type', async () => { + using contractInstance = await setupContract(); + 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 () => { + using contractInstance = await setupContract(); + const INPUT = { i: 4 }; const { waitForResult } = await contractInstance.functions.echo_struct_u8(INPUT).call(); const { value } = await waitForResult(); @@ -270,6 +303,8 @@ describe('Coverage Contract', () => { }); it('should test struct > 8 bytes variable type', async () => { + using contractInstance = await setupContract(); + const INPUT = { i: B256 }; const { waitForResult } = await contractInstance.functions.echo_struct_b256(INPUT).call(); const { value } = await waitForResult(); @@ -277,6 +312,8 @@ describe('Coverage Contract', () => { }); it('should test enum < 8 byte variable type', async () => { + using contractInstance = await setupContract(); + const INPUT = SmallEnum.Empty; const { waitForResult } = await contractInstance.functions.echo_enum_small(INPUT).call(); const { value } = await waitForResult(); @@ -284,6 +321,8 @@ describe('Coverage Contract', () => { }); it('should test enum > 8 bytes variable type', async () => { + using contractInstance = await setupContract(); + const INPUT = { AddressB: B256 }; const { waitForResult } = await contractInstance.functions.echo_enum_big(INPUT).call(); @@ -292,6 +331,8 @@ describe('Coverage Contract', () => { }); it('should test Option type', async () => { + using contractInstance = await setupContract(); + const INPUT = 187; const { waitForResult } = await contractInstance.functions.echo_option_u8(INPUT).call(); const { value } = await waitForResult(); @@ -299,6 +340,8 @@ describe('Coverage Contract', () => { }); it('should test Option extraction [Some]', async () => { + using contractInstance = await setupContract(); + const INPUT_SOME = 123; const { waitForResult } = await contractInstance.functions .echo_option_extract_u32(INPUT_SOME) @@ -309,6 +352,8 @@ describe('Coverage Contract', () => { }); it('should test Option extraction [None]', async () => { + using contractInstance = await setupContract(); + const INPUT_NONE = undefined; const call1 = await contractInstance.functions.echo_option_extract_u32(INPUT_NONE).call(); @@ -324,6 +369,8 @@ describe('Coverage Contract', () => { }); it('should test multiple Option params [Some]', async () => { + using contractInstance = await setupContract(); + const INPUT_A = 1; const INPUT_B = 4; const INPUT_C = 5; @@ -340,6 +387,8 @@ describe('Coverage Contract', () => { }); it('should test multiple Option params [None]', async () => { + using contractInstance = await setupContract(); + const INPUT = 1; // adds the three values together, but only first param value is supplied @@ -351,12 +400,16 @@ describe('Coverage Contract', () => { }); it('should test u8 empty vector input', async () => { + using contractInstance = await setupContract(); + const { waitForResult } = await contractInstance.functions.check_u8_vector([]).call(); const { value } = await waitForResult(); expect(value).toBeFalsy(); }); it('should test u8 vector input', async () => { + using contractInstance = await setupContract(); + const { waitForResult } = await contractInstance.functions .check_u8_vector([1, 2, 3, 4, 5]) .call(); @@ -370,6 +423,8 @@ describe('Coverage Contract', () => { }); it('should echo u8 vector input', async () => { + using contractInstance = await setupContract(); + const { waitForResult } = await contractInstance.functions .echo_u8_vector_first([23, 6, 1, 51, 2]) .call(); @@ -380,6 +435,8 @@ describe('Coverage Contract', () => { }); it('should echo a vector of optional u8 input', async () => { + using contractInstance = await setupContract(); + const { waitForResult } = await contractInstance.functions .echo_u8_option_vector_first([28]) .call(); @@ -390,6 +447,8 @@ describe('Coverage Contract', () => { }); it('should echo u64 vector input', async () => { + using contractInstance = await setupContract(); + const INPUT = bn(54).toHex(); const { waitForResult } = await contractInstance.functions .echo_u64_vector_last([200, 100, 24, 51, 23, INPUT]) @@ -399,6 +458,8 @@ describe('Coverage Contract', () => { }); it('should echo u32 vector addition of mixed params', async () => { + using contractInstance = await setupContract(); + const { waitForResult } = await contractInstance.functions .echo_u32_vector_addition_other_type([100, 2], 47) .call(); @@ -407,6 +468,8 @@ describe('Coverage Contract', () => { }); it('should echo u32 vector addition', async () => { + using contractInstance = await setupContract(); + const { waitForResult } = await contractInstance.functions .echo_u32_vector_addition([100, 2], [24, 54]) .call(); @@ -415,6 +478,8 @@ describe('Coverage Contract', () => { }); it('should echo u32 vector addition [variable lengths]', async () => { + using contractInstance = await setupContract(); + const { waitForResult } = await contractInstance.functions .echo_u32_vector_addition([100, 2, 1, 2, 3], [24, 54]) .call(); @@ -423,6 +488,8 @@ describe('Coverage Contract', () => { }); it('should echo struct vector input', async () => { + using contractInstance = await setupContract(); + const first = { foo: 1, bar: 10, @@ -445,6 +512,8 @@ describe('Coverage Contract', () => { }); it('should echo complex struct vector input', async () => { + using contractInstance = await setupContract(); + const last = { foo: 3, bar: bn(31337).toHex(), @@ -475,7 +544,8 @@ describe('Coverage Contract', () => { }); it('should get initial state messages from node', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); + using launched = await setupContract(); + const { provider } = launched; // #region Message-getMessages const WALLET_A = Wallet.fromPrivateKey( @@ -500,11 +570,11 @@ describe('Coverage Contract', () => { ]; const EXPECTED_MESSAGES_B: Message[] = [ { - messageId: '0x39578ef8c047ae994d0dadce8015559953b32fffa657c25c4c068fe4d6995a4b', + messageId: '0xba5fece66404c865ea533b1a0f8462e9a67c2066a20b70fcf8446ce4f2b82ed4', sender: WALLET_A.address, recipient: WALLET_B.address, nonce: '0x0e1ef2963832068b0e1ef2963832068b0e1ef2963832068b0e1ef2963832068b', - amount: bn('12704439083013451934'), + amount: bn('0xffffffffffffffff', 'hex'), data: arrayify('0x'), daHeight: bn(0), }, @@ -524,7 +594,9 @@ describe('Coverage Contract', () => { }); it('should test spending input messages', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); + using contractInstance = await setupContract(); + + const { provider } = contractInstance; const request = new ScriptTransactionRequest({ gasLimit: 1000000 }); const recipient = Wallet.generate({ @@ -535,7 +607,7 @@ describe('Coverage Contract', () => { provider ); - request.addCoinOutput(recipient.address, 10, baseAssetId); + request.addCoinOutput(recipient.address, 10, provider.getBaseAssetId()); const txCost = await sender.provider.getTransactionCost(request); @@ -551,11 +623,11 @@ describe('Coverage Contract', () => { }); it('supports result type', async () => { - const call1 = await contractInstance.functions.types_result({ Ok: 1 }).call(); - + using contractInstance = await setupContract(); + const { waitForResult } = await contractInstance.functions.types_result({ Ok: 1 }).call(); const { value: { Ok }, - } = await call1.waitForResult(); + } = await waitForResult(); expect(Ok.toNumber()).toBe(20); const call2 = await contractInstance.functions.types_result({ Ok: 0 }).call(); @@ -576,6 +648,8 @@ describe('Coverage Contract', () => { }); it('can read from produce_logs_variables', async () => { + using contractInstance = await setupContract(); + const { waitForResult } = await contractInstance.functions.produce_logs_variables().call(); const { logs } = await waitForResult(); @@ -586,6 +660,8 @@ describe('Coverage Contract', () => { }); it('should test native enum [Red->Green]', async () => { + using contractInstance = await setupContract(); + const INPUT: ColorEnumInput = ColorEnumInput.Red; const OUTPUT: ColorEnumOutput = ColorEnumOutput.Green; const { waitForResult } = await contractInstance.functions.color_enum(INPUT).call(); @@ -595,6 +671,8 @@ describe('Coverage Contract', () => { }); it('should test native enum [Green->Blue]', async () => { + using contractInstance = await setupContract(); + const INPUT: ColorEnumInput = ColorEnumInput.Green; const OUTPUT: ColorEnumOutput = ColorEnumOutput.Blue; @@ -604,6 +682,8 @@ describe('Coverage Contract', () => { }); it('should test native enum [Blue->Red]', async () => { + using contractInstance = await setupContract(); + const INPUT: ColorEnumInput = ColorEnumInput.Blue; const OUTPUT: ColorEnumOutput = ColorEnumOutput.Red; @@ -613,6 +693,8 @@ describe('Coverage Contract', () => { }); it('should test mixed native enum [Native->NotNative]', async () => { + using contractInstance = await setupContract(); + const input = MixedNativeEnum.Native; const expected = { NotNative: MixedNativeEnum.NotNative }; @@ -622,6 +704,8 @@ describe('Coverage Contract', () => { }); it('should test mixed native enum [NotNative->Native]', async () => { + using contractInstance = await setupContract(); + const input = { NotNative: MixedNativeEnum.NotNative }; const expected = 'Native'; @@ -631,6 +715,8 @@ describe('Coverage Contract', () => { }); it('should try vec_as_only_param', async () => { + using contractInstance = await setupContract(); + const { waitForResult } = await contractInstance.functions .vec_as_only_param([100, 450, 202, 340]) .call(); @@ -646,6 +732,8 @@ describe('Coverage Contract', () => { }); it('should try u32_and_vec_params', async () => { + using contractInstance = await setupContract(); + const { waitForResult } = await contractInstance.functions .u32_and_vec_params(33, [450, 202, 340]) .call(); @@ -661,6 +749,8 @@ describe('Coverage Contract', () => { }); it('should support vec in vec', async () => { + using contractInstance = await setupContract(); + const INPUT = [ [0, 1, 2], [0, 1, 2], @@ -672,6 +762,8 @@ describe('Coverage Contract', () => { }); it('should support array in vec', async () => { + using contractInstance = await setupContract(); + const INPUT = [ [0, 1, 2], [0, 1, 2], @@ -683,6 +775,8 @@ describe('Coverage Contract', () => { }); it('should test b256 multiple params vector input/output', async () => { + using contractInstance = await setupContract(); + const INPUT_A = [hexlify(randomBytes(32)), hexlify(randomBytes(32)), hexlify(randomBytes(32))]; const INPUT_B = [hexlify(randomBytes(32)), hexlify(randomBytes(32)), hexlify(randomBytes(32))]; const INPUT_C = hexlify(randomBytes(32)); @@ -698,6 +792,8 @@ describe('Coverage Contract', () => { }); it('should handle multiple calls [with vectors]', async () => { + using contractInstance = await setupContract(); + const INPUT_A = [hexlify(randomBytes(32)), hexlify(randomBytes(32)), hexlify(randomBytes(32))]; const INPUT_B = [hexlify(randomBytes(32))]; const INPUT_C = hexlify(randomBytes(32)); @@ -719,6 +815,8 @@ describe('Coverage Contract', () => { }); it('should handle multiple calls [with vectors + stack data first]', async () => { + using contractInstance = await setupContract(); + const INPUT_A = [hexlify(randomBytes(32)), hexlify(randomBytes(32)), hexlify(randomBytes(32))]; const INPUT_B = [hexlify(randomBytes(32))]; const INPUT_C = hexlify(randomBytes(32)); diff --git a/packages/fuel-gauge/src/doc-examples.test.ts b/packages/fuel-gauge/src/doc-examples.test.ts index 7817dfe11a..dba9d41f08 100644 --- a/packages/fuel-gauge/src/doc-examples.test.ts +++ b/packages/fuel-gauge/src/doc-examples.test.ts @@ -2,7 +2,6 @@ import type { Bech32Address, BigNumberish, Bytes, JsonAbi, WalletLocked } from ' import { Predicate, bn, - Provider, hashMessage, Address, arrayify, @@ -15,24 +14,12 @@ import { WalletUnlocked, Signer, ZeroBytes32, - FUEL_NETWORK_URL, - TESTNET_NETWORK_URL, } from 'fuels'; -import { generateTestWallet, seedTestWallet } from 'fuels/test-utils'; +import { AssetId, launchTestNode } from 'fuels/test-utils'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; - -const { abiContents: callTestAbi } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.CALL_TEST_CONTRACT -); - -const { binHexlified: predicateTriple } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.PREDICATE_TRIPLE_SIG -); - -const { binHexlified: testPredicateTrue } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.PREDICATE_TRUE -); +import { CallTestContractAbi__factory } from '../test/typegen/contracts'; +import { PredicateTrueAbi__factory } from '../test/typegen/predicates'; +import { PredicateTripleSigAbi__factory } from '../test/typegen/predicates/factories/PredicateTripleSigAbi__factory'; const PUBLIC_KEY = '0x2f34bc0df4db0ec391792cedb05768832b49b1aa3a2dd8c30054d1af00f67d00b74b7acbbf3087c8e0b1a4c343db50aa471d21f278ff5ce09f07795d541fb47e'; @@ -49,20 +36,9 @@ const ADDRESS_BYTES = new Uint8Array([ /** * @group node + * @group browser */ describe('Doc Examples', () => { - let baseAssetId: string; - - beforeAll(async () => { - // Avoids using the actual network. - const mockProvider = await Provider.create(FUEL_NETWORK_URL); - vi.spyOn(Provider, 'create').mockResolvedValue(mockProvider); - }); - - beforeAll(async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - }); test('it has an Address class using bech32Address', () => { const address = new Address(ADDRESS_BECH32); @@ -127,15 +103,20 @@ describe('Doc Examples', () => { }); test('it has conversion tools', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); + using node = await launchTestNode(); + const { provider } = node; const assetId: string = ZeroBytes32; const randomB256Bytes: Bytes = randomBytes(32); const hexedB256: string = hexlify(randomB256Bytes); const address = Address.fromB256(hexedB256); const arrayB256: Uint8Array = arrayify(randomB256Bytes); const walletLike: WalletLocked = Wallet.fromAddress(address, provider); - const contractLike: Contract = new Contract(address, callTestAbi, provider); + const contractLike: Contract = new Contract( + address, + CallTestContractAbi__factory.abi, + provider + ); expect(address.equals(addressify(walletLike) as Address)).toBeTruthy(); expect(address.equals(contractLike.id as Address)).toBeTruthy(); @@ -147,8 +128,9 @@ describe('Doc Examples', () => { }); test('it can work with wallets', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); + using node = await launchTestNode(); + const { provider } = node; // use the `generate` helper to make an Unlocked Wallet const myWallet: WalletUnlocked = Wallet.generate({ provider, @@ -167,7 +149,7 @@ describe('Doc Examples', () => { unlockedWallet = Wallet.fromPrivateKey(PRIVATE_KEY, provider); const newlyLockedWallet = unlockedWallet.lock(); - const balance: BigNumberish = await myWallet.getBalance(baseAssetId); + const balance: BigNumberish = await myWallet.getBalance(provider.getBaseAssetId()); const { balances } = await myWallet.getBalances(); expect(newlyLockedWallet.address).toEqual(someWallet.address); @@ -188,7 +170,9 @@ describe('Doc Examples', () => { }); it('it can work sign messages with wallets', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); + using launched = await launchTestNode(); + const { provider } = launched; + const wallet = WalletUnlocked.generate({ provider, }); @@ -204,23 +188,28 @@ describe('Doc Examples', () => { }); it('can create wallets', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - const assetIdA = '0x0101010101010101010101010101010101010101010101010101010101010101'; - const assetIdB = '0x0202020202020202020202020202020202020202020202020202020202020202'; - - // single asset - const walletA = await generateTestWallet(provider, [[42, baseAssetId]]); - - // multiple assets - const walletB = await generateTestWallet(provider, [ - // [Amount, AssetId] - [100, assetIdA], - [200, assetIdB], - [30, baseAssetId], - ]); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 100_000_000_000_000, + assets: [AssetId.A, AssetId.B], + }, + }); + + const { + provider, + wallets: [fundingWallet], + } = launched; + + const walletA = Wallet.generate({ provider }); + await fundingWallet.transfer(walletA.address, 100, provider.getBaseAssetId()); + + const walletB = Wallet.generate({ provider }); + await fundingWallet.transfer(walletB.address, 100, AssetId.A.value); + await fundingWallet.transfer(walletB.address, 100, AssetId.B.value); + await fundingWallet.transfer(walletB.address, 100, provider.getBaseAssetId()); // this wallet has no assets - const walletC = await generateTestWallet(provider); + const walletC = Wallet.generate({ provider }); // retrieve balances of wallets const { balances: walletABalances } = await walletA.getBalances(); @@ -228,17 +217,18 @@ describe('Doc Examples', () => { const { balances: walletCBalances } = await walletC.getBalances(); // validate balances - expect(walletABalances).toEqual([{ assetId: baseAssetId, amount: bn(42) }]); + expect(walletABalances).toEqual([{ assetId: provider.getBaseAssetId(), amount: bn(100) }]); expect(walletBBalances).toEqual([ - { assetId: assetIdA, amount: bn(100) }, - { assetId: assetIdB, amount: bn(200) }, - { assetId: baseAssetId, amount: bn(30) }, + { assetId: AssetId.A.value, amount: bn(100) }, + { assetId: AssetId.B.value, amount: bn(100) }, + { assetId: provider.getBaseAssetId(), amount: bn(100) }, ]); expect(walletCBalances).toEqual([]); }); it('can connect to testnet', async () => { - const provider = await Provider.create(TESTNET_NETWORK_URL); + using launched = await launchTestNode(); + const { provider } = launched; const PRIVATE_KEY = 'a1447cd75accc6b71a976fd3401a1f6ce318d27ba660b0315ee6ac347bf39568'; const wallet = Wallet.fromPrivateKey(PRIVATE_KEY, provider); @@ -248,28 +238,38 @@ describe('Doc Examples', () => { }); it('can connect to a local provider', async () => { - const localProvider = await Provider.create(FUEL_NETWORK_URL); - + using launched = await launchTestNode(); + const { provider } = launched; const PRIVATE_KEY = 'a1447cd75accc6b71a976fd3401a1f6ce318d27ba660b0315ee6ac347bf39568'; - const wallet: WalletUnlocked = Wallet.fromPrivateKey(PRIVATE_KEY, localProvider); + const wallet: WalletUnlocked = Wallet.fromPrivateKey(PRIVATE_KEY, provider); const signer = new Signer(PRIVATE_KEY); expect(wallet.address).toEqual(signer.address); }); it('can create a predicate', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); + using launched = await launchTestNode(); + const { provider } = launched; const predicate = new Predicate({ - bytecode: testPredicateTrue, + bytecode: PredicateTrueAbi__factory.bin, provider, }); expect(predicate.address).toBeTruthy(); - expect(predicate.bytes).toEqual(arrayify(testPredicateTrue)); + expect(predicate.bytes).toEqual(arrayify(PredicateTrueAbi__factory.bin)); }); it('can create a predicate and use', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000_000_000, + }, + }); + const { + provider, + wallets: [fundingWallet], + } = launched; + // Setup a private key const PRIVATE_KEY_1 = '0x862512a2363db2b3a375c0d4bbbd27172180d89f23f2e259bac850ab02619301'; const PRIVATE_KEY_2 = '0x37fa81c84ccd547c30c176b118d5cb892bdb113e8e80141f266519422ef9eefd'; @@ -279,11 +279,12 @@ describe('Doc Examples', () => { const wallet1: WalletUnlocked = Wallet.fromPrivateKey(PRIVATE_KEY_1, provider); const wallet2: WalletUnlocked = Wallet.fromPrivateKey(PRIVATE_KEY_2, provider); const wallet3: WalletUnlocked = Wallet.fromPrivateKey(PRIVATE_KEY_3, provider); - const receiver = Wallet.generate({ provider }); - await seedTestWallet(wallet1, [{ assetId: baseAssetId, amount: bn(1_000_000) }]); - await seedTestWallet(wallet2, [{ assetId: baseAssetId, amount: bn(2_000_000) }]); - await seedTestWallet(wallet3, [{ assetId: baseAssetId, amount: bn(300_000) }]); + await fundingWallet.transfer(wallet1.address, 1_000_000, provider.getBaseAssetId()); + await fundingWallet.transfer(wallet2.address, 2_000_000, provider.getBaseAssetId()); + await fundingWallet.transfer(wallet3.address, 300_000, provider.getBaseAssetId()); + + const receiver = Wallet.generate({ provider }); const AbiInputs: JsonAbi = { types: [ @@ -341,7 +342,7 @@ describe('Doc Examples', () => { const signature3 = await wallet3.signMessage(dataToSign); const signatures = [signature1, signature2, signature3]; const predicate = new Predicate({ - bytecode: predicateTriple, + bytecode: PredicateTripleSigAbi__factory.bin, provider, abi: AbiInputs, inputData: [signatures], @@ -349,20 +350,36 @@ describe('Doc Examples', () => { const amountToPredicate = 600_000; const amountToReceiver = 100; - const response = await wallet1.transfer(predicate.address, amountToPredicate, baseAssetId, { - gasLimit: 10_000, - }); + const response = await wallet1.transfer( + predicate.address, + amountToPredicate, + provider.getBaseAssetId(), + { + gasLimit: 10_000, + } + ); + await response.waitForResult(); - const depositOnPredicate = await wallet1.transfer(predicate.address, 1000, baseAssetId, { - gasLimit: 10_000, - }); + const depositOnPredicate = await wallet1.transfer( + predicate.address, + 1000, + provider.getBaseAssetId(), + { + gasLimit: 10_000, + } + ); // Wait for Transaction to succeed await depositOnPredicate.waitForResult(); - const tx = await predicate.transfer(receiver.address, amountToReceiver, baseAssetId, { - gasLimit: 10_000, - }); + const tx = await predicate.transfer( + receiver.address, + amountToReceiver, + provider.getBaseAssetId(), + { + gasLimit: 10_000, + } + ); const { isStatusSuccess } = await tx.waitForResult(); // check balance diff --git a/packages/fuel-gauge/src/dry-run-multiple-txs.test.ts b/packages/fuel-gauge/src/dry-run-multiple-txs.test.ts index 338ba5061a..89f9d6ef87 100644 --- a/packages/fuel-gauge/src/dry-run-multiple-txs.test.ts +++ b/packages/fuel-gauge/src/dry-run-multiple-txs.test.ts @@ -3,88 +3,46 @@ import type { DryRunStatus, EstimateTxDependenciesReturns, TransactionResultReceipt, - WalletUnlocked, } from 'fuels'; -import { ContractFactory, FUEL_NETWORK_URL, Provider, Wallet } from 'fuels'; -import { generateTestWallet } from 'fuels/test-utils'; - -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; +import { ContractFactory, Wallet } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; + +import { + AdvancedLoggingAbi__factory, + AdvancedLoggingOtherContractAbi__factory, + MultiTokenContractAbi__factory, + RevertErrorAbi__factory, +} from '../test/typegen/contracts'; +import AdvancedLoggingAbiHex from '../test/typegen/contracts/AdvancedLoggingAbi.hex'; +import AdvancedLoggingOtherContractAbiHex from '../test/typegen/contracts/AdvancedLoggingOtherContractAbi.hex'; +import MultiTokenAbiHex from '../test/typegen/contracts/MultiTokenContractAbi.hex'; +import RevertErrorAbiHex from '../test/typegen/contracts/RevertErrorAbi.hex'; /** * @group node + * @group browser */ describe('dry-run-multiple-txs', () => { - const { abiContents, binHexlified } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.TOKEN_CONTRACT - ); - const { abiContents: abiRevert, binHexlified: binRevert } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.REVERT_ERROR - ); - const { abiContents: abiMultiToken, binHexlified: binMultiToken } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.MULTI_TOKEN_CONTRACT - ); - const { abiContents: abiLog, binHexlified: binLog } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.ADVANCED_LOGGING - ); - const { abiContents: abiLogOther, binHexlified: binLogOther } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.ADVANCED_LOGGING_OTHER_CONTRACT - ); - - let provider: Provider; - let wallet: WalletUnlocked; - let baseAssetId: string; - - beforeAll(async () => { - provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - wallet = await generateTestWallet(provider, [[1_000_000, baseAssetId]]); - }); - - afterEach(() => { - vi.restoreAllMocks(); - }); - - const deployContracts = async () => { - const revertFactory = new ContractFactory(binRevert, abiRevert, wallet); - - let { waitForResult } = await revertFactory.deployContract({ - maxFee: 70_000, - }); - const { contract: revertContract } = await waitForResult(); - - const multiTokenFactory = new ContractFactory(binMultiToken, abiMultiToken, wallet); - - ({ waitForResult } = await multiTokenFactory.deployContract({ - maxFee: 70_000, - })); - const { contract: multiTokenContract } = await waitForResult(); - - const logFactory = new ContractFactory(binLog, abiLog, wallet); - - ({ waitForResult } = await logFactory.deployContract({ - maxFee: 70_000, - })); - const { contract: logContract } = await waitForResult(); - - const logOtherFactory = new ContractFactory(binLogOther, abiLogOther, wallet); - - ({ waitForResult } = await logOtherFactory.deployContract({ - maxFee: 70_000, - })); - const { contract: logOtherContract } = await waitForResult(); - - return { revertContract, multiTokenContract, logContract, logOtherContract }; - }; - it('should properly dry-run multiple TXs requests', async () => { - const revertFactory = new ContractFactory(binRevert, abiRevert, wallet); - - const { waitForResult } = await revertFactory.deployContract({ - maxFee: 70_000, + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: RevertErrorAbi__factory, + bytecode: RevertErrorAbiHex, + }, + ], + walletsConfig: { + amountPerCoin: 1_000_000, + }, }); - const { contract: revertContract } = await waitForResult(); - const resources = await wallet.getResourcesToSpend([[500_000, baseAssetId]]); + const { + contracts: [revertContract], + provider, + wallets: [wallet], + } = launched; + + const resources = await wallet.getResourcesToSpend([[500_000, provider.getBaseAssetId()]]); const request1 = await revertContract.functions .validate_inputs(10, 0) @@ -167,13 +125,39 @@ describe('dry-run-multiple-txs', () => { }); it('should properly estimate multiple TXs requests', async () => { - // preparing test data - const { revertContract, multiTokenContract, logContract, logOtherContract } = - await deployContracts(); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: RevertErrorAbi__factory, + bytecode: RevertErrorAbiHex, + }, + { + deployer: MultiTokenContractAbi__factory, + bytecode: MultiTokenAbiHex, + }, + { + deployer: AdvancedLoggingAbi__factory, + bytecode: AdvancedLoggingAbiHex, + }, + { + deployer: AdvancedLoggingOtherContractAbi__factory, + bytecode: AdvancedLoggingOtherContractAbiHex, + }, + ], + walletsConfig: { + amountPerCoin: 1_000_000, + }, + }); + + const { + contracts: [revertContract, multiTokenContract, logContract, logOtherContract], + provider, + wallets: [wallet], + } = launched; // subId defined on multi-token contract const subId = '0x4a778acfad1abc155a009dc976d2cf0db6197d3d360194d74b1fb92b96986b00'; - const resources = await wallet.getResourcesToSpend([[500_000, baseAssetId]]); + const resources = await wallet.getResourcesToSpend([[500_000, provider.getBaseAssetId()]]); // creating receives to be used by the request 2 and 3 const addresses = [ @@ -183,7 +167,11 @@ describe('dry-run-multiple-txs', () => { ]; // request 1 - const factory = new ContractFactory(binHexlified, abiContents, wallet); + const factory = new ContractFactory( + MultiTokenAbiHex, + MultiTokenContractAbi__factory.abi, + wallet + ); const { transactionRequest: request1 } = factory.createTransactionRequest({ maxFee: 15000, }); diff --git a/packages/fuel-gauge/src/e2e-script.test.ts b/packages/fuel-gauge/src/e2e-script.test.ts index 08d607ae90..7503a8b947 100644 --- a/packages/fuel-gauge/src/e2e-script.test.ts +++ b/packages/fuel-gauge/src/e2e-script.test.ts @@ -10,7 +10,7 @@ import { assets, } from 'fuels'; -import { getScript } from './utils'; +import { ScriptMainArgBoolAbi__factory } from '../test/typegen'; enum Networks { DEVNET = 'devnet', @@ -81,7 +81,7 @@ describe.each(selectedNetworks)('Live Script Test', (selectedNetwork) => { return; } - const scriptInstance = getScript<[boolean], boolean>('script-main-arg-bool', wallet); + const scriptInstance = ScriptMainArgBoolAbi__factory.createInstance(wallet); let output: boolean = false; try { diff --git a/packages/fuel-gauge/src/edge-cases.test.ts b/packages/fuel-gauge/src/edge-cases.test.ts index 53ed27ae44..77f40457b0 100644 --- a/packages/fuel-gauge/src/edge-cases.test.ts +++ b/packages/fuel-gauge/src/edge-cases.test.ts @@ -1,24 +1,41 @@ -import { FUEL_NETWORK_URL, Provider, TransactionResponse, Wallet } from 'fuels'; -import { generateTestWallet } from 'fuels/test-utils'; +import { TransactionResponse, Wallet } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; -import { getSetupContract } from './utils'; +import { CollisionInFnNamesAbi__factory } from '../test/typegen/contracts'; +import CollisionInFnNamesAbiHex from '../test/typegen/contracts/CollisionInFnNamesAbi.hex'; + +import { launchTestContract } from './utils'; /** * @group node + * @group browser */ 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(); + using contractInstance = await launchTestContract({ + deployer: CollisionInFnNamesAbi__factory, + bytecode: CollisionInFnNamesAbiHex, + }); + + const { waitForResult } = await contractInstance.functions.new().call(); const { value } = await waitForResult(); expect(value.toNumber()).toEqual(12345); }); test("SSE subscriptions that are closed by the node don't hang a for-await-of loop", async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000, + }, + }); + + const { + provider, + wallets: [adminWallet], + } = launched; + const baseAssetId = provider.getBaseAssetId(); - const adminWallet = await generateTestWallet(provider, [[500_000, baseAssetId]]); const destination = Wallet.generate({ provider, diff --git a/packages/fuel-gauge/src/fee.test.ts b/packages/fuel-gauge/src/fee.test.ts index b3dfdc7f73..3ff893cfa2 100644 --- a/packages/fuel-gauge/src/fee.test.ts +++ b/packages/fuel-gauge/src/fee.test.ts @@ -1,35 +1,20 @@ -import type { BN, BaseWalletUnlocked } from 'fuels'; +import { ContractFactory, Predicate, ScriptTransactionRequest, Wallet, getRandomB256 } from 'fuels'; +import type { BN } from 'fuels'; +import { launchTestNode, ASSET_A, ASSET_B, expectToBeInRange } from 'fuels/test-utils'; + import { - ContractFactory, - FUEL_NETWORK_URL, - Predicate, - Provider, - ScriptTransactionRequest, - Wallet, - getRandomB256, -} from 'fuels'; -import { generateTestWallet, ASSET_A, ASSET_B, expectToBeInRange } from 'fuels/test-utils'; - -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; + CallTestContractAbi__factory, + MultiTokenContractAbi__factory, +} from '../test/typegen/contracts'; +import CallTestContractAbiHex from '../test/typegen/contracts/CallTestContractAbi.hex'; +import MultiTokenContractAbiHex from '../test/typegen/contracts/MultiTokenContractAbi.hex'; +import { PredicateU32Abi__factory } from '../test/typegen/predicates/factories/PredicateU32Abi__factory'; /** * @group node + * @group browser */ describe('Fee', () => { - let wallet: BaseWalletUnlocked; - let provider: Provider; - let baseAssetId: string; - - beforeAll(async () => { - provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - wallet = await generateTestWallet(provider, [ - [1_000_000_000, baseAssetId], - [1_000_000_000, ASSET_A], - [1_000_000_000, ASSET_B], - ]); - }); - const expectFeeInMarginOfError = (fee: BN, expectedFee: BN) => { const feeNumber = fee.toNumber(); const expectedFeeNumber = expectedFee.toNumber(); @@ -48,13 +33,19 @@ describe('Fee', () => { }; it('should ensure fee is properly calculated when minting and burning coins', async () => { - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.MULTI_TOKEN_CONTRACT - ); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: MultiTokenContractAbi__factory, + bytecode: MultiTokenContractAbiHex, + }, + ], + }); - const factory = new ContractFactory(binHexlified, abiContents, wallet); - const { waitForResult } = await factory.deployContract(); - const { contract } = await waitForResult(); + const { + contracts: [contract], + wallets: [wallet], + } = launched; // minting coins let balanceBefore = await wallet.getBalance(); @@ -89,14 +80,26 @@ describe('Fee', () => { }); it('should ensure fee is properly calculated on simple transfer transactions', async () => { + using launched = await launchTestNode(); + + const { + provider, + wallets: [wallet], + } = launched; + const destination = Wallet.generate({ provider }); const amountToTransfer = 120; const balanceBefore = await wallet.getBalance(); - const tx = await wallet.transfer(destination.address, amountToTransfer, baseAssetId, { - gasLimit: 10_000, - }); + const tx = await wallet.transfer( + destination.address, + amountToTransfer, + provider.getBaseAssetId(), + { + gasLimit: 10_000, + } + ); const { fee } = await tx.wait(); const balanceAfter = await wallet.getBalance(); @@ -110,9 +113,16 @@ describe('Fee', () => { }); it('should ensure fee is properly calculated on multi transfer transactions', async () => { - const destination1 = Wallet.generate({ provider }); - const destination2 = Wallet.generate({ provider }); - const destination3 = Wallet.generate({ provider }); + using launched = await launchTestNode({ + walletsConfig: { + count: 4, + }, + }); + + const { + provider, + wallets: [wallet, destination1, destination2, destination3], + } = launched; const amountToTransfer = 120; const balanceBefore = await wallet.getBalance(); @@ -121,7 +131,7 @@ describe('Fee', () => { gasLimit: 10000, }); - request.addCoinOutput(destination1.address, amountToTransfer, baseAssetId); + request.addCoinOutput(destination1.address, amountToTransfer, provider.getBaseAssetId()); request.addCoinOutput(destination2.address, amountToTransfer, ASSET_A); request.addCoinOutput(destination3.address, amountToTransfer, ASSET_B); @@ -148,13 +158,20 @@ describe('Fee', () => { }); it('should ensure fee is properly calculated on a contract deploy', async () => { - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.MULTI_TOKEN_CONTRACT - ); + using launched = await launchTestNode(); + + const { + provider, + wallets: [wallet], + } = launched; const balanceBefore = await wallet.getBalance(); - const factory = new ContractFactory(binHexlified, abiContents, wallet); + const factory = new ContractFactory( + MultiTokenContractAbiHex, + MultiTokenContractAbi__factory.abi, + wallet + ); const { transactionRequest } = factory.createTransactionRequest(); const txCost = await provider.getTransactionCost(transactionRequest); @@ -176,11 +193,18 @@ describe('Fee', () => { }); it('should ensure fee is properly calculated on a contract call', async () => { - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.CALL_TEST_CONTRACT + using launched = await launchTestNode(); + + const { + wallets: [wallet], + } = launched; + + const factory = new ContractFactory( + CallTestContractAbiHex, + CallTestContractAbi__factory.abi, + wallet ); - const factory = new ContractFactory(binHexlified, abiContents, wallet); const deploy = await factory.deployContract(); const { contract } = await deploy.waitForResult(); @@ -203,13 +227,19 @@ describe('Fee', () => { }); it('should ensure fee is properly calculated a contract multi call', async () => { - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.CALL_TEST_CONTRACT - ); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: CallTestContractAbi__factory, + bytecode: CallTestContractAbiHex, + }, + ], + }); - const factory = new ContractFactory(binHexlified, abiContents, wallet); - const deploy = await factory.deployContract(); - const { contract } = await deploy.waitForResult(); + const { + contracts: [contract], + wallets: [wallet], + } = launched; const balanceBefore = await wallet.getBalance(); @@ -237,13 +267,19 @@ describe('Fee', () => { }); it('should ensure fee is properly calculated in a multi call [MINT TO 15 ADDRESSES]', async () => { - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.MULTI_TOKEN_CONTRACT - ); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: MultiTokenContractAbi__factory, + bytecode: MultiTokenContractAbiHex, + }, + ], + }); - const factory = new ContractFactory(binHexlified, abiContents, wallet); - const deploy = await factory.deployContract(); - const { contract } = await deploy.waitForResult(); + const { + contracts: [contract], + wallets: [wallet], + } = launched; const subId = '0x4a778acfad1abc155a009dc976d2cf0db6197d3d360194d74b1fb92b96986b00'; @@ -276,23 +312,30 @@ describe('Fee', () => { }); it('should ensure fee is properly calculated on transactions with predicate', async () => { - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.PREDICATE_U32 - ); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, + }, + }); + + const { + provider, + wallets: [wallet], + } = launched; const predicate = new Predicate({ - bytecode: binHexlified, - abi: abiContents, + bytecode: PredicateU32Abi__factory.bin, + abi: PredicateU32Abi__factory.abi, provider, inputData: [1078], }); - const tx1 = await wallet.transfer(predicate.address, 2000, baseAssetId); + const tx1 = await wallet.transfer(predicate.address, 1_000_000, provider.getBaseAssetId()); await tx1.wait(); const transferAmount = 100; const balanceBefore = await predicate.getBalance(); - const tx2 = await predicate.transfer(wallet.address, transferAmount, baseAssetId); + const tx2 = await predicate.transfer(wallet.address, transferAmount, provider.getBaseAssetId()); const { fee } = await tx2.wait(); diff --git a/packages/fuel-gauge/src/funding-transaction.test.ts b/packages/fuel-gauge/src/funding-transaction.test.ts index d411a11c3e..a10054f59a 100644 --- a/packages/fuel-gauge/src/funding-transaction.test.ts +++ b/packages/fuel-gauge/src/funding-transaction.test.ts @@ -1,34 +1,29 @@ import { FuelError } from '@fuel-ts/errors'; +import { expectToThrowFuelError } from '@fuel-ts/errors/test-utils'; import type { Account, CoinTransactionRequestInput } from 'fuels'; -import { FUEL_NETWORK_URL, Provider, ScriptTransactionRequest, Wallet, bn } from 'fuels'; -import { expectToThrowFuelError, seedTestWallet } from 'fuels/test-utils'; +import { ScriptTransactionRequest, Wallet, bn } from 'fuels'; +import { AssetId, launchTestNode } from 'fuels/test-utils'; /** * @group node + * @group browser */ -describe(__filename, () => { - let mainWallet: Account; - let provider: Provider; - let baseAssetId: string; - +describe('Funding Transactions', () => { const assetA = '0x0101010101010101010101010101010101010101010101010101010101010101'; const assetB = '0x0202020202020202020202020202020202020202020202020202020202020202'; - beforeAll(async () => { - provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - mainWallet = Wallet.generate({ provider }); - await seedTestWallet(mainWallet, [[200_000_000, baseAssetId]]); - }); - const fundingTxWithMultipleUTXOs = async ({ account, totalAmount, splitIn, + baseAssetId, + mainWallet, }: { account: Account; totalAmount: number; splitIn: number; + baseAssetId: string; + mainWallet: Account; }) => { const request = new ScriptTransactionRequest(); @@ -51,14 +46,26 @@ describe(__filename, () => { }; it('should successfully fund a transaction request when it is not fully funded', async () => { - const sender = Wallet.generate({ provider }); - const receiver = Wallet.generate({ provider }); + const initialAmount = 500_000; + using launched = await launchTestNode({ + walletsConfig: { + count: 2, + amountPerCoin: initialAmount, + }, + }); - // 1500 splitted in 5 = 5 UTXOs of 300 each + const { + provider, + wallets: [sender, receiver], + } = launched; + + // 1500 splitted in 5 = 5 UTXOs of 30 each await fundingTxWithMultipleUTXOs({ account: sender, totalAmount: 400_000, splitIn: 5, + baseAssetId: provider.getBaseAssetId(), + mainWallet: sender, }); const request = new ScriptTransactionRequest({ @@ -67,7 +74,7 @@ describe(__filename, () => { const amountToTransfer = 300; - request.addCoinOutput(receiver.address, amountToTransfer, baseAssetId); + request.addCoinOutput(receiver.address, amountToTransfer, provider.getBaseAssetId()); const txCost = await provider.getTransactionCost(request); @@ -85,12 +92,24 @@ describe(__filename, () => { // fund method should have been called to fetch the remaining UTXOs expect(getResourcesToSpendSpy).toHaveBeenCalled(); - const receiverBalance = await receiver.getBalance(baseAssetId); + const receiverBalance = await receiver.getBalance(provider.getBaseAssetId()); - expect(receiverBalance.toNumber()).toBe(amountToTransfer); + expect(receiverBalance.toNumber()).toBe(amountToTransfer + initialAmount); }); it('should not fund a transaction request when it is already funded', async () => { + using launched = await launchTestNode({ + walletsConfig: { + count: 1, + amountPerCoin: 200_000_000, + }, + }); + + const { + provider, + wallets: [mainWallet], + } = launched; + const sender = Wallet.generate({ provider }); const receiver = Wallet.generate({ provider }); @@ -99,10 +118,12 @@ describe(__filename, () => { account: sender, totalAmount: 400_000, splitIn: 2, + baseAssetId: provider.getBaseAssetId(), + mainWallet, }); - // sender has 2 UTXOs for 200_000 each, so it has enough resources to spend 1000 of baseAssetId - const enoughtResources = await sender.getResourcesToSpend([[100, baseAssetId]]); + // sender has 2 UTXOs for 500_000 each, so it has enough resources to spend 1000 of baseAssetId + const enoughtResources = await sender.getResourcesToSpend([[100, provider.getBaseAssetId()]]); // confirm we only fetched 1 UTXO from the expected amount expect(enoughtResources.length).toBe(1); @@ -114,7 +135,7 @@ describe(__filename, () => { const amountToTransfer = 100; - request.addCoinOutput(receiver.address, amountToTransfer, baseAssetId); + request.addCoinOutput(receiver.address, amountToTransfer, provider.getBaseAssetId()); request.addResources(enoughtResources); const txCost = await provider.getTransactionCost(request); @@ -138,19 +159,31 @@ describe(__filename, () => { // fund should not have been called since the TX request was already funded expect(getResourcesToSpendSpy).toHaveBeenCalledTimes(0); - const receiverBalance = await receiver.getBalance(baseAssetId); + const receiverBalance = await receiver.getBalance(provider.getBaseAssetId()); expect(receiverBalance.toNumber()).toBe(amountToTransfer); }); it('should fully fund a transaction when it is has no funds yet', async () => { - const sender = Wallet.generate({ provider }); - const receiver = Wallet.generate({ provider }); + const initialAmount = 500_000; + using launched = await launchTestNode({ + walletsConfig: { + count: 2, + amountPerCoin: initialAmount, + }, + }); + + const { + provider, + wallets: [sender, receiver], + } = launched; await fundingTxWithMultipleUTXOs({ account: sender, totalAmount: 200_000, splitIn: 1, + baseAssetId: provider.getBaseAssetId(), + mainWallet: sender, }); const request = new ScriptTransactionRequest({ @@ -158,7 +191,7 @@ describe(__filename, () => { }); const amountToTransfer = 1000; - request.addCoinOutput(receiver.address, amountToTransfer, baseAssetId); + request.addCoinOutput(receiver.address, amountToTransfer, provider.getBaseAssetId()); const txCost = await provider.getTransactionCost(request); @@ -179,14 +212,24 @@ describe(__filename, () => { // fund method should have been called to fetch UTXOs expect(getResourcesToSpendSpy).toHaveBeenCalledTimes(1); - const receiverBalance = await receiver.getBalance(baseAssetId); + const receiverBalance = await receiver.getBalance(provider.getBaseAssetId()); - expect(receiverBalance.toNumber()).toBe(amountToTransfer); + expect(receiverBalance.toNumber()).toBe(amountToTransfer + initialAmount); }); it('should ensure proper error is thrown when user has not enough resources', async () => { - const sender = Wallet.generate({ provider }); - const receiver = Wallet.generate({ provider }); + const initialAmount = 100_000; + using launched = await launchTestNode({ + walletsConfig: { + count: 2, + amountPerCoin: initialAmount, + }, + }); + + const { + provider, + wallets: [sender, receiver], + } = launched; const splitIn = 20; @@ -198,12 +241,14 @@ describe(__filename, () => { account: sender, totalAmount: 2400, splitIn, + baseAssetId: provider.getBaseAssetId(), + mainWallet: sender, }); const request = new ScriptTransactionRequest(); const amountToTransfer = 1000; - request.addCoinOutput(receiver.address, amountToTransfer, baseAssetId); + request.addCoinOutput(receiver.address, amountToTransfer, provider.getBaseAssetId()); const txCost = await provider.getTransactionCost(request); @@ -236,6 +281,18 @@ describe(__filename, () => { }); it('should ensure a partially funded Transaction will require only missing funds', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 100_000_000, + assets: [AssetId.A, AssetId.B], + }, + }); + + const { + provider, + wallets: [wallet], + } = launched; + const receiver = Wallet.generate({ provider }); const wallet1 = Wallet.generate({ provider }); const wallet2 = Wallet.generate({ provider }); @@ -249,16 +306,14 @@ describe(__filename, () => { * Funding wallet1 with only half of the required amount in Asset A and with enough amount * in the Base Asset to pay the fee */ - await seedTestWallet(wallet1, [ - [totalInBaseAsset, baseAssetId], - [partiallyInAssetA, assetA], - ]); + await wallet.transfer(wallet1.address, totalInBaseAsset, provider.getBaseAssetId()); + await wallet.transfer(wallet1.address, partiallyInAssetA, assetA); /** * Funding wallet2 with the remaining amount needed in Asset A. * Note: This wallet does not have any additional funds to pay for the transaction fee. */ - await seedTestWallet(wallet2, [[partiallyInAssetA, assetA]]); + await wallet.transfer(wallet2.address, totalInAssetA - partiallyInAssetA, assetA); let transactionRequest = new ScriptTransactionRequest(); @@ -274,10 +329,12 @@ describe(__filename, () => { // Manually fetching resources from wallet1 to be added to transactionRequest const partiallyResources = await wallet1.getResourcesToSpend([ [partiallyInAssetA, assetA], - [totalInBaseAsset, baseAssetId], + [totalInBaseAsset, provider.getBaseAssetId()], ]); - const baseAssetResource = partiallyResources.find((r) => r.assetId === baseAssetId); + const baseAssetResource = partiallyResources.find( + (r) => r.assetId === provider.getBaseAssetId() + ); const assetAResource = partiallyResources.find((r) => r.assetId === assetA); // Expect to have the correct amount of resources, not enough to cover the required amount in Asset A @@ -306,16 +363,19 @@ describe(__filename, () => { }); it('should ensure a funded Transaction will not require more funds from another user', async () => { - const receiver = Wallet.generate({ provider }); - const fundedWallet = Wallet.generate({ provider }); - const unfundedWallet = Wallet.generate({ provider }); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 100_000_000, + assets: [AssetId.A, AssetId.B], + }, + }); + const { + provider, + wallets: [fundedWallet], + } = launched; - // Funding the wallet with sufficient amounts for base and additional assets - await seedTestWallet(fundedWallet, [ - [300_000, baseAssetId], - [80_000, assetA], - [80_000, assetB], - ]); + const unfundedWallet = Wallet.generate({ provider }); + const receiver = Wallet.generate({ provider }); let transactionRequest = new ScriptTransactionRequest(); @@ -323,7 +383,7 @@ describe(__filename, () => { * Adding CoinOutputs for the receiver address. All required amounts can be * covered by the fundedWallet. */ - transactionRequest.addCoinOutput(receiver.address, 1500, baseAssetId); + transactionRequest.addCoinOutput(receiver.address, 1500, provider.getBaseAssetId()); transactionRequest.addCoinOutput(receiver.address, 3000, assetA); transactionRequest.addCoinOutput(receiver.address, 4500, assetB); diff --git a/packages/fuel-gauge/src/generic-types-contract.test.ts b/packages/fuel-gauge/src/generic-types-contract.test.ts index 6caa629699..25d51dd7b5 100644 --- a/packages/fuel-gauge/src/generic-types-contract.test.ts +++ b/packages/fuel-gauge/src/generic-types-contract.test.ts @@ -1,21 +1,18 @@ import { toHex } from 'fuels'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; - -import { setup } from './utils'; - -const { binHexlified: contractBytecode, abiContents: abiJSON } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.GENERIC_TYPES_CONTRACT -); +import { GenericTypesContractAbi__factory } from '../test/typegen/contracts'; +import GenericTypesContractAbiHex from '../test/typegen/contracts/GenericTypesContractAbi.hex'; +import { launchTestContract } from './utils'; /** * @group node + * @group browser */ describe('GenericTypesContract', () => { it('should call complex contract function with generic type', async () => { - const contract = await setup({ - abi: abiJSON, - contractBytecode, + using contract = await launchTestContract({ + deployer: GenericTypesContractAbi__factory, + bytecode: GenericTypesContractAbiHex, }); const b256 = '0xd5579c46dfcc7f18207013e65b44e4cb4e2c2298f4ac457ba8f82743f31e930b'; diff --git a/packages/fuel-gauge/src/is-function-readonly.test.ts b/packages/fuel-gauge/src/is-function-readonly.test.ts index bcbdf125c4..58c21273d1 100644 --- a/packages/fuel-gauge/src/is-function-readonly.test.ts +++ b/packages/fuel-gauge/src/is-function-readonly.test.ts @@ -1,31 +1,42 @@ -import { FuelGaugeProjectsEnum } from '../test/fixtures'; +import { StorageTestContractAbi__factory } from '../test/typegen/contracts'; +import StorageTestContractAbiHex from '../test/typegen/contracts/StorageTestContractAbi.hex'; -import { getSetupContract } from './utils'; +import { launchTestContract } from './utils'; /** * @group node + * @group browser */ describe('isReadOnly', () => { test('isReadOnly returns true for a read-only function', async () => { - const contract = await getSetupContract(FuelGaugeProjectsEnum.STORAGE_TEST_CONTRACT)(); + using contractInstance = await launchTestContract({ + deployer: StorageTestContractAbi__factory, + bytecode: StorageTestContractAbiHex, + }); - const isReadOnly = contract.functions.counter.isReadOnly(); + const isReadOnly = contractInstance.functions.counter.isReadOnly(); expect(isReadOnly).toBe(true); }); test('isReadOnly returns false for a function containing write operations', async () => { - const contract = await getSetupContract(FuelGaugeProjectsEnum.STORAGE_TEST_CONTRACT)(); + using contractInstance = await launchTestContract({ + deployer: StorageTestContractAbi__factory, + bytecode: StorageTestContractAbiHex, + }); - const isReadOnly = contract.functions.increment_counter.isReadOnly(); + const isReadOnly = contractInstance.functions.increment_counter.isReadOnly(); expect(isReadOnly).toBe(false); }); test('isReadOnly does not throw a runtime error for a function that does not use storage', async () => { - const contract = await getSetupContract(FuelGaugeProjectsEnum.STORAGE_TEST_CONTRACT)(); + using contractInstance = await launchTestContract({ + deployer: StorageTestContractAbi__factory, + bytecode: StorageTestContractAbiHex, + }); - const isReadOnly = contract.functions.return_true.isReadOnly(); + const isReadOnly = contractInstance.functions.return_true.isReadOnly(); expect(isReadOnly).toBe(true); }); diff --git a/packages/fuel-gauge/src/launch-test-node-types.test.ts b/packages/fuel-gauge/src/launch-test-node-types.test.ts deleted file mode 100644 index a72aa4e74d..0000000000 --- a/packages/fuel-gauge/src/launch-test-node-types.test.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { launchTestNode } from 'fuels/test-utils'; - -import type { AdvancedLoggingAbi, CallTestContractAbi } from '../test/typegen'; -import { AdvancedLoggingAbi__factory, CallTestContractAbi__factory } from '../test/typegen'; -import AdvancedLoggingBytecode from '../test/typegen/contracts/AdvancedLoggingAbi.hex'; -import CallTestContractBytecode from '../test/typegen/contracts/CallTestContractAbi.hex'; - -/** - * @group node - * @group browser - */ -describe('type level tests for launchTestNode', () => { - test('infers types correctly', async () => { - using launched = await launchTestNode({ - contractsConfigs: [ - { deployer: AdvancedLoggingAbi__factory, bytecode: AdvancedLoggingBytecode }, - { deployer: CallTestContractAbi__factory, bytecode: CallTestContractBytecode }, - { deployer: AdvancedLoggingAbi__factory, bytecode: AdvancedLoggingBytecode }, - ], - }); - const { - contracts: [c1, c2, c3], - } = launched; - - expectTypeOf(c1).toMatchTypeOf(); - expectTypeOf(c2).toMatchTypeOf(); - expectTypeOf(c3).toMatchTypeOf(); - }); -}); diff --git a/packages/fuel-gauge/src/min-gas.test.ts b/packages/fuel-gauge/src/min-gas.test.ts index db9cabb89c..8889fffeec 100644 --- a/packages/fuel-gauge/src/min-gas.test.ts +++ b/packages/fuel-gauge/src/min-gas.test.ts @@ -1,8 +1,4 @@ import { - ContractFactory, - Wallet, - FUEL_NETWORK_URL, - Provider, bn, TransactionStatus, ScriptTransactionRequest, @@ -11,43 +7,52 @@ import { hexlify, getGasUsedFromReceipts, BigNumberCoder, + ContractFactory, } from 'fuels'; -import { seedTestWallet } from 'fuels/test-utils'; +import { launchTestNode } from 'fuels/test-utils'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; +import { + ComplexPredicateAbi__factory, + ComplexScriptAbi__factory, + CoverageContractAbi__factory, +} from '../test/typegen'; +import CoverageContractAbiHex from '../test/typegen/contracts/CoverageContractAbi.hex'; /** * @group node + * @group browser */ -describe(__filename, () => { - let provider: Provider; - let baseAssetId: string; - - beforeAll(async () => { - provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - }); - +describe('Minimum gas tests', () => { it('sets gas requirements (contract)', async () => { - const wallet = Wallet.generate({ provider }); - await seedTestWallet(wallet, [[500_000, baseAssetId]]); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 500_000, + }, + }); + + const { + provider, + wallets: [wallet], + } = launched; /** * Create a contract transaction */ - const { abiContents, binHexlified, storageSlots } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.COVERAGE_CONTRACT + const contractFactory = new ContractFactory( + CoverageContractAbiHex, + CoverageContractAbi__factory.abi, + wallet ); - const contractFactory = new ContractFactory(binHexlified, abiContents, wallet); const { transactionRequest: request } = contractFactory.createTransactionRequest({ - storageSlots, + storageSlots: CoverageContractAbi__factory.storageSlots, }); + const resources = await provider.getResourcesToSpend(wallet.address, [ { amount: bn(100_000), - assetId: baseAssetId, + assetId: provider.getBaseAssetId(), }, ]); request.addResources(resources); @@ -69,19 +74,26 @@ describe(__filename, () => { }); it('sets gas requirements (script)', async () => { - const sender = Wallet.generate({ provider }); - await seedTestWallet(sender, [[500_000, baseAssetId]]); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 500_000, + }, + }); + + const { + provider, + wallets: [sender], + } = launched; /** * Create a script transaction */ - const { binHexlified } = getFuelGaugeForcProject(FuelGaugeProjectsEnum.COMPLEX_SCRIPT); const request = new ScriptTransactionRequest({ - script: binHexlified, + script: ComplexScriptAbi__factory.bin, scriptData: hexlify(new BigNumberCoder('u64').encode(bn(2000))), }); - request.addCoinOutput(Address.fromRandom(), bn(100), baseAssetId); + request.addCoinOutput(Address.fromRandom(), bn(100), provider.getBaseAssetId()); /** * Get the transaction cost to set a strict gasLimit and min gasPrice @@ -104,27 +116,38 @@ describe(__filename, () => { }); it('sets gas requirements (predicate)', async () => { - const { abiContents, binHexlified } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.COMPLEX_PREDICATE - ); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 100_000_000, + }, + }); + + const { + provider, + wallets: [wallet], + } = launched; /** * Setup predicate */ const predicate = new Predicate({ - bytecode: binHexlified, - abi: abiContents, + bytecode: ComplexPredicateAbi__factory.bin, + abi: ComplexPredicateAbi__factory.abi, provider, inputData: [bn(1000)], }); - await seedTestWallet(predicate, [[500_000, baseAssetId]]); + /** + * Fund the predicate + */ + const tx = await wallet.transfer(predicate.address, 1_000_000, provider.getBaseAssetId()); + await tx.wait(); /** * Create a script transaction transfer */ const request = new ScriptTransactionRequest(); - request.addCoinOutput(Address.fromRandom(), bn(100), baseAssetId); + request.addCoinOutput(Address.fromRandom(), bn(100), provider.getBaseAssetId()); /** * Get the transaction cost to set a strict gasLimit and min gasPrice @@ -148,36 +171,43 @@ describe(__filename, () => { }); it('sets gas requirements (account and predicate with script)', async () => { - const { abiContents, binHexlified } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.COMPLEX_PREDICATE - ); - /** - * Setup account - */ - const wallet = Wallet.generate({ provider }); - await seedTestWallet(wallet, [[500_000, baseAssetId]]); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000_000, + }, + }); + + const { + provider, + wallets: [wallet], + } = launched; + + const baseAssetId = provider.getBaseAssetId(); /** * Setup predicate */ const predicate = new Predicate({ - bytecode: binHexlified, - abi: abiContents, + bytecode: ComplexPredicateAbi__factory.bin, + abi: ComplexPredicateAbi__factory.abi, provider, inputData: [bn(1000)], }); - await seedTestWallet(predicate, [[500_000, baseAssetId]]); + + /** + * Fund the predicate + */ + const tx = await wallet.transfer(predicate.address, 1_000_000, baseAssetId); + await tx.wait(); /** * Create a script transaction */ - const { binHexlified: scriptBin } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.COMPLEX_SCRIPT - ); const request = new ScriptTransactionRequest({ - script: scriptBin, + script: ComplexScriptAbi__factory.bin, scriptData: hexlify(new BigNumberCoder('u64').encode(bn(2000))), }); + // add predicate transfer const resourcesPredicate = await predicate.getResourcesToSpend([ { diff --git a/packages/fuel-gauge/src/multi-token-contract.test.ts b/packages/fuel-gauge/src/multi-token-contract.test.ts index a6607cd65a..e81f8d1671 100644 --- a/packages/fuel-gauge/src/multi-token-contract.test.ts +++ b/packages/fuel-gauge/src/multi-token-contract.test.ts @@ -14,6 +14,7 @@ const subIds = [ /** * @group node + * @group browser */ describe('MultiTokenContract', () => { it('can mint and transfer coins', async () => { diff --git a/packages/fuel-gauge/src/options.test.ts b/packages/fuel-gauge/src/options.test.ts index afe3d76b86..ad3cf7d87a 100644 --- a/packages/fuel-gauge/src/options.test.ts +++ b/packages/fuel-gauge/src/options.test.ts @@ -1,27 +1,29 @@ -import type { Contract, WalletUnlocked } from 'fuels'; -import { generateTestWallet } from 'fuels/test-utils'; +import { launchTestNode } from 'fuels/test-utils'; -import { getSetupContract } from './utils'; +import { OptionsAbi__factory } from '../test/typegen/contracts'; +import OptionsAbiHex from '../test/typegen/contracts/OptionsAbi.hex'; + +import { launchTestContract } from './utils'; const U8_MAX = 255; const U16_MAX = 65535; const U32_MAX = 4294967295; -const setupContract = getSetupContract('options'); -let contractInstance: Contract; -let wallet: WalletUnlocked; -beforeAll(async () => { - contractInstance = await setupContract(); - wallet = await generateTestWallet(contractInstance.provider, [ - [200_000, contractInstance.provider.getBaseAssetId()], - ]); -}); +async function launchOptionsContract() { + return launchTestContract({ + bytecode: OptionsAbiHex, + deployer: OptionsAbi__factory, + }); +} /** * @group node + * @group browser */ describe('Options Tests', () => { it('calls', async () => { + using contractInstance = await launchOptionsContract(); + const { waitForResult } = await contractInstance.functions.print_enum_option_array().call(); const { value } = await waitForResult(); @@ -45,6 +47,8 @@ describe('Options Tests', () => { const someInput = U8_MAX; const noneInput = undefined; + using contractInstance = await launchOptionsContract(); + const call1 = await contractInstance.functions.echo_option(someInput).call(); const { value: someValue } = await call1.waitForResult(); @@ -64,6 +68,8 @@ describe('Options Tests', () => { two: U32_MAX, }; + using contractInstance = await launchOptionsContract(); + const call1 = await contractInstance.functions.echo_struct_enum_option(someInput).call(); const { value: someValue } = await call1.waitForResult(); @@ -85,6 +91,8 @@ describe('Options Tests', () => { it('echos vec option', async () => { const someInput = [U8_MAX, U16_MAX, U32_MAX]; + using contractInstance = await launchOptionsContract(); + const call1 = await contractInstance.functions.echo_vec_option(someInput).call(); const { value: someValue } = await call1.waitForResult(); @@ -108,6 +116,8 @@ describe('Options Tests', () => { it('echos tuple option', async () => { const someInput = [U8_MAX, U16_MAX]; + using contractInstance = await launchOptionsContract(); + const call1 = await contractInstance.functions.echo_tuple_option(someInput).call(); const { value: someValue } = await call1.waitForResult(); @@ -134,6 +144,8 @@ describe('Options Tests', () => { it('echoes enum option', async () => { const someInput = { a: U8_MAX }; + using contractInstance = await launchOptionsContract(); + const call1 = await contractInstance.functions.echo_enum_option(someInput).call(); const { value: someValue } = await call1.waitForResult(); @@ -152,6 +164,8 @@ describe('Options Tests', () => { it('echos array option', async () => { const someInput = [U8_MAX, U16_MAX, 123]; + using contractInstance = await launchOptionsContract(); + const call1 = await contractInstance.functions.echo_array_option(someInput).call(); const { value: someValue } = await call1.waitForResult(); @@ -179,6 +193,7 @@ describe('Options Tests', () => { }, }; + using contractInstance = await launchOptionsContract(); const { waitForResult } = await contractInstance.functions .echo_deeply_nested_option(input) .call(); @@ -189,6 +204,20 @@ describe('Options Tests', () => { }); it('prints struct option', async () => { + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: OptionsAbi__factory, + bytecode: OptionsAbiHex, + }, + ], + }); + + const { + contracts: [contractInstance], + wallets: [wallet], + } = launched; + const { waitForResult } = await contractInstance.functions .get_some_struct({ Address: { bits: wallet.address.toB256() } }) .call(); @@ -199,6 +228,11 @@ describe('Options Tests', () => { }); it('echoes option enum diff sizes', async () => { + using contractInstance = await launchTestContract({ + bytecode: OptionsAbiHex, + deployer: OptionsAbi__factory, + }); + const call1 = await contractInstance.functions.echo_enum_diff_sizes(undefined).call(); const { value } = await call1.waitForResult(); diff --git a/packages/fuel-gauge/src/payable-annotation.test.ts b/packages/fuel-gauge/src/payable-annotation.test.ts index 3487e4cd13..750a944a14 100644 --- a/packages/fuel-gauge/src/payable-annotation.test.ts +++ b/packages/fuel-gauge/src/payable-annotation.test.ts @@ -1,31 +1,25 @@ -import type { Contract } from 'fuels'; import { bn } from 'fuels'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; +import { PayableAnnotationAbi__factory } from '../test/typegen/contracts'; +import PayableAnnotationAbiHex from '../test/typegen/contracts/PayableAnnotationAbi.hex'; -import { createSetupConfig } from './utils'; +import { launchTestContract } from './utils'; -const { binHexlified: contractBytecode, abiContents: abiJSON } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.PAYABLE_ANNOTATION -); - -const setupContract = createSetupConfig({ - contractBytecode, - abi: abiJSON, -}); - -let contract: Contract; -let baseAssetId: string; - -beforeAll(async () => { - contract = await setupContract(); - baseAssetId = contract.provider.getBaseAssetId(); -}); +async function launchPayableContract() { + return launchTestContract({ + bytecode: PayableAnnotationAbiHex, + deployer: PayableAnnotationAbi__factory, + }); +} /** * @group node + * @group browser */ test('allow sending coins to payable functions', async () => { + using contract = await launchPayableContract(); + const baseAssetId = contract.provider.getBaseAssetId(); + // This should not fail because the function is payable await expect( contract.functions @@ -41,6 +35,9 @@ test('allow sending coins to payable functions', async () => { }); test("don't allow sending coins to non-payable functions", async () => { + using contract = await launchPayableContract(); + const baseAssetId = contract.provider.getBaseAssetId(); + // This should fail because the function is not payable await expect(async () => contract.functions diff --git a/packages/fuel-gauge/src/policies.test.ts b/packages/fuel-gauge/src/policies.test.ts index d7a619d0f9..3ccc1853f8 100644 --- a/packages/fuel-gauge/src/policies.test.ts +++ b/packages/fuel-gauge/src/policies.test.ts @@ -1,34 +1,23 @@ -import type { BaseTransactionRequest, BigNumberish, Transaction, WalletUnlocked } from 'fuels'; +import type { BaseTransactionRequest, BigNumberish, Transaction } from 'fuels'; import { ContractFactory, CreateTransactionRequest, - FUEL_NETWORK_URL, PolicyType, - Provider, Script, ScriptTransactionRequest, Wallet, bn, } from 'fuels'; -import { generateTestWallet } from 'fuels/test-utils'; +import { launchTestNode } from 'fuels/test-utils'; -import { getFuelGaugeForcProject, FuelGaugeProjectsEnum } from '../test/fixtures'; - -import { createSetupConfig } from './utils'; +import { PayableAnnotationAbi__factory, ScriptMainArgsAbi__factory } from '../test/typegen'; +import PayableAnnotationAbiHex from '../test/typegen/contracts/PayableAnnotationAbi.hex'; /** * @group node + * @group browser */ describe('Policies', () => { - let provider: Provider; - let wallet: WalletUnlocked; - let baseAssetId: string; - beforeAll(async () => { - provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - wallet = await generateTestWallet(provider, [[500_000, baseAssetId]]); - }); - type CustomTxParams = { gasLimit?: BigNumberish; maturity?: number; @@ -42,11 +31,6 @@ describe('Policies', () => { return randomValue; }; - const randomMaturity = async () => { - const { latestBlock } = await provider.fetchChain(); - return randomNumber(1, latestBlock.height.toNumber()); - }; - const validatePolicies = ({ transaction, params, @@ -58,10 +42,8 @@ describe('Policies', () => { expect(bn(transaction.policies?.[0].data).eq(bn(params.tip))).toBeTruthy(); expect(transaction.policies?.[1].type).toBe(PolicyType.WitnessLimit); expect(bn(transaction.policies?.[1].data).eq(bn(params.witnessLimit))).toBeTruthy(); - expect(transaction.policies?.[2].type).toBe(PolicyType.Maturity); - expect(transaction.policies?.[2]?.data).toBe(params.maturity); - expect(transaction.policies?.[3].type).toBe(PolicyType.MaxFee); - expect(bn(transaction.policies?.[3]?.data).lte(bn(params.maxFee))).toBeTruthy(); + expect(transaction.policies?.[2].type).toBe(PolicyType.MaxFee); + expect(bn(transaction.policies?.[2]?.data).lte(bn(params.maxFee))).toBeTruthy(); }; it('should ensure optional TX policies are not set when not informed', () => { @@ -127,18 +109,24 @@ describe('Policies', () => { }); it('should ensure TX policies are properly set (ScriptTransactionRequest)', async () => { + using launched = await launchTestNode(); + + const { + provider, + wallets: [wallet], + } = launched; + const receiver = Wallet.generate({ provider }); const txParams: CustomTxParams = { tip: 10, - maturity: await randomMaturity(), witnessLimit: randomNumber(800, 900), maxFee: 1000, }; const txRequest = new ScriptTransactionRequest(txParams); - txRequest.addCoinOutput(receiver.address, 500, baseAssetId); + txRequest.addCoinOutput(receiver.address, 500, provider.getBaseAssetId()); const txCost = await provider.getTransactionCost(txRequest); @@ -151,8 +139,8 @@ describe('Policies', () => { const { transaction } = await tx.waitForResult(); - expect(transaction.policyTypes).toBe(15); - expect(transaction.policies?.length).toBe(4); + expect(transaction.policyTypes).toBe(11); + expect(transaction.policies?.length).toBe(3); validatePolicies({ transaction, @@ -161,16 +149,22 @@ describe('Policies', () => { }); it('should ensure TX policies are properly set (CreateTransactionRequest)', async () => { - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.SCRIPT_MAIN_ARGS - ); + using launched = await launchTestNode(); - const factory = new ContractFactory(binHexlified, abiContents, wallet); + const { + provider, + wallets: [wallet], + } = launched; + + const factory = new ContractFactory( + ScriptMainArgsAbi__factory.bin, + ScriptMainArgsAbi__factory.abi, + wallet + ); const txParams: CustomTxParams = { tip: 11, witnessLimit: 2000, - maturity: await randomMaturity(), maxFee: 70_000, }; @@ -193,19 +187,22 @@ describe('Policies', () => { }); it('should ensure TX policies are properly set (BaseInvocationScope)', async () => { - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.PAYABLE_ANNOTATION - ); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: PayableAnnotationAbi__factory, + bytecode: PayableAnnotationAbiHex, + }, + ], + }); - const contract = await createSetupConfig({ - contractBytecode: binHexlified, - abi: abiContents, - cache: true, - })(); + const { + contracts: [contract], + } = launched; const callScope = contract.functions.payable().txParams({ tip: 5, - maturity: await randomMaturity(), + witnessLimit: randomNumber(800, 900), maxFee: 70_000, }); @@ -225,19 +222,21 @@ describe('Policies', () => { }); it('should ensure TX policies are properly set (ScriptInvocationScope)', async () => { - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.SCRIPT_MAIN_ARGS - ); + using launched = await launchTestNode(); + + const { + wallets: [wallet], + } = launched; const scriptInstance = new Script( - binHexlified, - abiContents, + ScriptMainArgsAbi__factory.bin, + ScriptMainArgsAbi__factory.abi, wallet ); const callScope = scriptInstance.functions.main(33).txParams({ tip: 2, - maturity: await randomMaturity(), + witnessLimit: randomNumber(800, 900), maxFee: 70_000, }); @@ -257,16 +256,28 @@ describe('Policies', () => { }); it('should ensure TX policies are properly set (Account Transfer)', async () => { + using launched = await launchTestNode(); + + const { + provider, + wallets: [wallet], + } = launched; + const receiver = Wallet.generate({ provider }); const txParams: CustomTxParams = { tip: 4, - maturity: await randomMaturity(), + witnessLimit: randomNumber(800, 900), maxFee: 70_000, }; - const pendingTx = await wallet.transfer(receiver.address, 500, baseAssetId, txParams); + const pendingTx = await wallet.transfer( + receiver.address, + 500, + provider.getBaseAssetId(), + txParams + ); const { transaction } = await pendingTx.waitForResult(); @@ -277,24 +288,34 @@ describe('Policies', () => { }); it('should ensure TX policies are properly set (Account Contract Transfer)', async () => { - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.PAYABLE_ANNOTATION - ); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: PayableAnnotationAbi__factory, + bytecode: PayableAnnotationAbiHex, + }, + ], + }); - const contract = await createSetupConfig({ - contractBytecode: binHexlified, - abi: abiContents, - cache: true, - })(); + const { + provider, + wallets: [wallet], + contracts: [contract], + } = launched; const txParams: CustomTxParams = { tip: 1, - maturity: await randomMaturity(), + witnessLimit: randomNumber(800, 900), maxFee: 70_000, }; - const pendingTx = await wallet.transferToContract(contract.id, 500, baseAssetId, txParams); + const pendingTx = await wallet.transferToContract( + contract.id, + 500, + provider.getBaseAssetId(), + txParams + ); const { transaction } = await pendingTx.waitForResult(); @@ -305,15 +326,26 @@ describe('Policies', () => { }); it('should ensure TX witnessLimit policy limits tx execution as expected', async () => { + using launched = await launchTestNode(); + + const { + provider, + wallets: [wallet], + } = launched; + const receiver = Wallet.generate({ provider }); const txParams: CustomTxParams = { - maturity: await randomMaturity(), witnessLimit: 0, }; await expect(async () => { - const pendingTx = await wallet.transfer(receiver.address, 500, baseAssetId, txParams); + const pendingTx = await wallet.transfer( + receiver.address, + 500, + provider.getBaseAssetId(), + txParams + ); await pendingTx.waitForResult(); }).rejects.toThrow(/TransactionWitnessLimitExceeded/); @@ -321,53 +353,79 @@ describe('Policies', () => { describe('should ensure TX maxFee policy limits TX execution as expected', () => { it('on account transfer', async () => { + using launched = await launchTestNode(); + + const { + provider, + wallets: [wallet], + } = launched; + const receiver = Wallet.generate({ provider }); const maxFee = 1; const txParams: CustomTxParams = { - maturity: await randomMaturity(), witnessLimit: 800, maxFee, }; await expect(async () => { - const pendingTx = await wallet.transfer(receiver.address, 500, baseAssetId, txParams); + const pendingTx = await wallet.transfer( + receiver.address, + 500, + provider.getBaseAssetId(), + txParams + ); await pendingTx.waitForResult(); }).rejects.toThrow(new RegExp(`Max fee '${maxFee}' is lower than the required`)); }); it('on account transferring to contract', async () => { - const maxFee = 1; - - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.PAYABLE_ANNOTATION - ); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: PayableAnnotationAbi__factory, + bytecode: PayableAnnotationAbiHex, + }, + ], + }); + + const { + provider, + contracts: [contract], + wallets: [wallet], + } = launched; - const contract = await createSetupConfig({ - contractBytecode: binHexlified, - abi: abiContents, - cache: true, - })(); + const maxFee = 1; const txParams: CustomTxParams = { - maturity: await randomMaturity(), witnessLimit: 800, maxFee, }; await expect(async () => { - const pendingTx = await wallet.transferToContract(contract.id, 500, baseAssetId, txParams); + const pendingTx = await wallet.transferToContract( + contract.id, + 500, + provider.getBaseAssetId(), + txParams + ); await pendingTx.waitForResult(); }).rejects.toThrow(new RegExp(`Max fee '${maxFee}' is lower than the required`)); }); it('on account withdraw to base layer', async () => { + using launched = await launchTestNode(); + + const { + provider, + wallets: [wallet], + } = launched; + const maxFee = 1; const receiver = Wallet.generate({ provider }); const txParams: CustomTxParams = { - maturity: await randomMaturity(), witnessLimit: 800, maxFee, }; @@ -379,16 +437,21 @@ describe('Policies', () => { }); it('on ContractFactory when deploying contracts', async () => { + using launched = await launchTestNode(); + + const { + wallets: [wallet], + } = launched; + const maxFee = 1; - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.SCRIPT_MAIN_ARGS + const factory = new ContractFactory( + ScriptMainArgsAbi__factory.bin, + ScriptMainArgsAbi__factory.abi, + wallet ); - const factory = new ContractFactory(binHexlified, abiContents, wallet); - const txParams: CustomTxParams = { - maturity: await randomMaturity(), witnessLimit: 800, maxFee, }; @@ -401,18 +464,20 @@ describe('Policies', () => { it('on a contract call', async () => { const maxFee = 1; - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.PAYABLE_ANNOTATION - ); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: PayableAnnotationAbi__factory, + bytecode: PayableAnnotationAbiHex, + }, + ], + }); - const contract = await createSetupConfig({ - contractBytecode: binHexlified, - abi: abiContents, - cache: true, - })(); + const { + contracts: [contract], + } = launched; const txParams: CustomTxParams = { - maturity: await randomMaturity(), witnessLimit: 800, maxFee, }; diff --git a/packages/fuel-gauge/src/predicate-conditional-inputs.test.ts b/packages/fuel-gauge/src/predicate-conditional-inputs.test.ts index 92925485f6..7bbe763ec8 100644 --- a/packages/fuel-gauge/src/predicate-conditional-inputs.test.ts +++ b/packages/fuel-gauge/src/predicate-conditional-inputs.test.ts @@ -1,25 +1,24 @@ -import { Provider, FUEL_NETWORK_URL, Predicate, Wallet, ScriptTransactionRequest, bn } from 'fuels'; -import { generateTestWallet, ASSET_A, ASSET_B } from 'fuels/test-utils'; +import { Predicate, Wallet, ScriptTransactionRequest, bn } from 'fuels'; +import { launchTestNode, ASSET_A, ASSET_B } from 'fuels/test-utils'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; +import { PredicateConditionalInputsAbi__factory } from '../test/typegen/predicates'; /** * @group node + * @group browser */ describe('PredicateConditionalInputs', () => { - let baseAssetId: string; - - const { binHexlified: predicateBytecode, abiContents: abiJSON } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.PREDICATE_CONDITIONAL_INPUTS - ); - - beforeAll(async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - }); - it('should execute custom transaction where predicate transfers to Alice (ALICE PAYS FEES)', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 100_000_000, + }, + }); + + const { + provider, + wallets: [adminWallet], + } = launched; const aliceWallet = Wallet.generate({ provider, @@ -27,14 +26,9 @@ describe('PredicateConditionalInputs', () => { const amountToTransfer = 1000; - const adminWallet = await generateTestWallet(provider, [ - [800_000, baseAssetId], - [800_000, ASSET_A], - ]); - const predicate = new Predicate({ - bytecode: predicateBytecode, - abi: abiJSON, + bytecode: PredicateConditionalInputsAbi__factory.bin, + abi: PredicateConditionalInputsAbi__factory.abi, provider, configurableConstants: { MAKER: aliceWallet.address.toB256() }, }); @@ -45,7 +39,7 @@ describe('PredicateConditionalInputs', () => { await tx1.waitForResult(); // transfer base asset to Alice so she can pay the fees - const tx2 = await adminWallet.transfer(aliceWallet.address, 200_000, baseAssetId); + const tx2 = await adminWallet.transfer(aliceWallet.address, 200_000, provider.getBaseAssetId()); await tx2.waitForResult(); @@ -53,7 +47,7 @@ describe('PredicateConditionalInputs', () => { // fetch predicate resources to spend const predicateResoruces = await predicate.getResourcesToSpend([[amountToTransfer, ASSET_A]]); - const aliceResources = await aliceWallet.getResourcesToSpend([[1, baseAssetId]]); + const aliceResources = await aliceWallet.getResourcesToSpend([[1, provider.getBaseAssetId()]]); request .addResources(aliceResources) @@ -96,7 +90,16 @@ describe('PredicateConditionalInputs', () => { }); it('should execute custom transaction where predicate transfer to Alice (PREDICATE PAYS FEES)', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 100_000_000, + }, + }); + + const { + provider, + wallets: [adminWallet], + } = launched; const aliceWallet = Wallet.generate({ provider, @@ -104,15 +107,9 @@ describe('PredicateConditionalInputs', () => { const amountToTransfer = 1000; - const adminWallet = await generateTestWallet(provider, [ - [500_000, baseAssetId], - [500_000, ASSET_A], - [500_000, ASSET_B], - ]); - const predicate = new Predicate({ - bytecode: predicateBytecode, - abi: abiJSON, + bytecode: PredicateConditionalInputsAbi__factory.bin, + abi: PredicateConditionalInputsAbi__factory.abi, provider, configurableConstants: { MAKER: aliceWallet.address.toB256() }, }); @@ -123,7 +120,7 @@ describe('PredicateConditionalInputs', () => { await tx1.waitForResult(); // transfer base asset to predicate so it can pay the fees - const tx2 = await adminWallet.transfer(predicate.address, 200_000, baseAssetId); + const tx2 = await adminWallet.transfer(predicate.address, 200_000, provider.getBaseAssetId()); await tx2.waitForResult(); diff --git a/packages/fuel-gauge/src/predicate/predicate-arguments.test.ts b/packages/fuel-gauge/src/predicate/predicate-arguments.test.ts index 6e0acaabf8..1f82814746 100644 --- a/packages/fuel-gauge/src/predicate/predicate-arguments.test.ts +++ b/packages/fuel-gauge/src/predicate/predicate-arguments.test.ts @@ -1,63 +1,60 @@ -import type { WalletLocked, WalletUnlocked, BigNumberish } from 'fuels'; -import { Provider, FUEL_NETWORK_URL, toHex, Predicate } from 'fuels'; -import { seedTestWallet } from 'fuels/test-utils'; - -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../../test/fixtures'; +import type { BigNumberish } from 'fuels'; +import { toHex, Predicate, Wallet } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; + +import { + PredicateAddressAbi__factory, + PredicateMainArgsStructAbi__factory, + PredicateMainArgsVectorAbi__factory, + PredicateMultiArgsAbi__factory, + PredicateU32Abi__factory, +} from '../../test/typegen'; import type { Validation } from '../types/predicate'; -import { setupWallets, assertBalances } from './utils/predicate'; +import { fundPredicate, assertBalances } from './utils/predicate'; /** * @group node + * @group browser */ describe('Predicate', () => { - const { binHexlified: predicateBytesAddress, abiContents: predicateAbiMainArgsAddress } = - getFuelGaugeForcProject(FuelGaugeProjectsEnum.PREDICATE_ADDRESS); - - const { binHexlified: predicateBytesMainArgsStruct, abiContents: predicateAbiMainArgsStruct } = - getFuelGaugeForcProject(FuelGaugeProjectsEnum.PREDICATE_MAIN_ARGS_STRUCT); - - const { binHexlified: predicateBytesMainArgsVector, abiContents: predicateAbiMainArgsVector } = - getFuelGaugeForcProject(FuelGaugeProjectsEnum.PREDICATE_MAIN_ARGS_VECTOR); - - const { binHexlified: predicateBytesMulti, abiContents: predicateAbiMulti } = - getFuelGaugeForcProject(FuelGaugeProjectsEnum.PREDICATE_MULTI_ARGS); - - const { binHexlified: predicateBytesMainArgsU32, abiContents: predicateAbiMainArgsU32 } = - getFuelGaugeForcProject(FuelGaugeProjectsEnum.PREDICATE_U32); - describe('Arguments', () => { - let wallet: WalletUnlocked; - let receiver: WalletLocked; - let provider: Provider; - let baseAssetId: string; const amountToReceiver = 50; const amountToPredicate = 900_000; - beforeAll(async () => { - provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - }); + it('calls a predicate with valid address data and returns true', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, + }, + }); - beforeEach(async () => { - [wallet, receiver] = await setupWallets(); - provider = wallet.provider; - }); + const { + provider, + wallets: [fundingWallet], + } = launched; - it('calls a predicate with valid address data and returns true', async () => { const predicate = new Predicate<[string]>({ - bytecode: predicateBytesAddress, - abi: predicateAbiMainArgsAddress, + bytecode: PredicateAddressAbi__factory.bin, + abi: PredicateAddressAbi__factory.abi, provider, inputData: ['0xef86afa9696cf0dc6385e2c407a6e159a1103cefb7e2ae0636fb33d3cb2a9e4a'], }); - await seedTestWallet(predicate, [[amountToPredicate, baseAssetId]], 3); + // transfer funds to predicate + await fundPredicate(fundingWallet, predicate, amountToPredicate); + + const receiver = Wallet.generate({ provider }); const initialReceiverBalance = await receiver.getBalance(); - const tx = await predicate.transfer(receiver.address, amountToReceiver, baseAssetId, { - gasLimit: 1000, - }); + const tx = await predicate.transfer( + receiver.address, + amountToReceiver, + provider.getBaseAssetId(), + { + gasLimit: 1000, + } + ); const { isStatusSuccess } = await tx.waitForResult(); await assertBalances(receiver, initialReceiverBalance, amountToReceiver); @@ -65,36 +62,68 @@ describe('Predicate', () => { }); it('calls a predicate with invalid address data and returns false', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, + }, + }); + + const { + provider, + wallets: [fundingWallet], + } = launched; + const predicate = new Predicate<[string]>({ - bytecode: predicateBytesAddress, - abi: predicateAbiMainArgsAddress, + bytecode: PredicateAddressAbi__factory.bin, + abi: PredicateAddressAbi__factory.abi, provider, - inputData: ['0xbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbada'], + inputData: ['0xbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbada'], }); - await seedTestWallet(predicate, [[amountToPredicate, baseAssetId]], 3); - const initialReceiverBalance = await receiver.getBalance(); - expect(initialReceiverBalance.toHex()).toEqual(toHex(0)); + // fund predicate + await fundPredicate(fundingWallet, predicate, amountToPredicate); + + const receiver = Wallet.generate({ provider }); await expect( - predicate.transfer(receiver.address, 50, baseAssetId, { gasLimit: 1000 }) - ).rejects.toThrow(/PredicateVerificationFailed/); + predicate.transfer(receiver.address, 50, provider.getBaseAssetId(), { gasLimit: 1000 }) + ).rejects.toThrow(/Invalid b256/); }); it('calls a predicate with valid u32 data and returns true', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, + }, + }); + + const { + provider, + wallets: [fundingWallet], + } = launched; + const predicate = new Predicate<[number]>({ - bytecode: predicateBytesMainArgsU32, - abi: predicateAbiMainArgsU32, + bytecode: PredicateU32Abi__factory.bin, + abi: PredicateU32Abi__factory.abi, provider, inputData: [1078], }); - await seedTestWallet(predicate, [[amountToPredicate, baseAssetId]], 3); + const receiver = Wallet.generate({ provider }); + const initialReceiverBalance = await receiver.getBalance(); - const tx = await predicate.transfer(receiver.address, amountToReceiver, baseAssetId, { - gasLimit: 1000, - }); + // fund predicate + await fundPredicate(fundingWallet, predicate, amountToPredicate); + + const tx = await predicate.transfer( + receiver.address, + amountToReceiver, + provider.getBaseAssetId(), + { + gasLimit: 1000, + } + ); const { isStatusSuccess } = await tx.waitForResult(); await assertBalances(receiver, initialReceiverBalance, amountToReceiver); @@ -102,45 +131,84 @@ describe('Predicate', () => { }); it('calls a predicate with invalid u32 data and returns false', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000_000, + }, + }); + + const { + provider, + wallets: [fundingWallet], + } = launched; + const predicate = new Predicate<[number]>({ - bytecode: predicateBytesMainArgsU32, - abi: predicateAbiMainArgsU32, + bytecode: PredicateU32Abi__factory.bin, + abi: PredicateU32Abi__factory.abi, provider, inputData: [100], }); - await seedTestWallet(predicate, [[amountToPredicate, baseAssetId]], 3); + // fund predicate + await fundPredicate(fundingWallet, predicate, 900_000_000); + + const receiver = Wallet.generate({ provider }); const initialReceiverBalance = await receiver.getBalance(); expect(initialReceiverBalance.toHex()).toEqual(toHex(0)); await expect( - predicate.transfer(receiver.address, amountToPredicate, baseAssetId, { + predicate.transfer(receiver.address, amountToPredicate, provider.getBaseAssetId(), { gasLimit: 1000, }) ).rejects.toThrow(/PredicateVerificationFailed/); }); it('calls a predicate with a valid struct argument and returns true', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, + }, + }); + + const { + provider, + wallets: [fundingWallet], + } = launched; + const predicateInstanceForBalance = new Predicate<[Validation]>({ - bytecode: predicateBytesMainArgsStruct, - abi: predicateAbiMainArgsStruct, + bytecode: PredicateMainArgsStructAbi__factory.bin, + abi: PredicateMainArgsStructAbi__factory.abi, provider, inputData: [{ has_account: true, total_complete: 100 }], }); - await seedTestWallet(predicateInstanceForBalance, [[amountToPredicate, baseAssetId]], 3); + const receiver = Wallet.generate({ provider }); const initialReceiverBalance = await receiver.getBalance(); + // fund the predicate + const fundTx = await fundingWallet.transfer( + predicateInstanceForBalance.address, + 100_000_000, + provider.getBaseAssetId() + ); + await fundTx.waitForResult(); + // #region predicate-struct-arg const predicate = new Predicate<[Validation]>({ - bytecode: predicateBytesMainArgsStruct, - abi: predicateAbiMainArgsStruct, + bytecode: PredicateMainArgsStructAbi__factory.bin, + abi: PredicateMainArgsStructAbi__factory.abi, provider, inputData: [{ has_account: true, total_complete: 100 }], }); - const tx = await predicate.transfer(receiver.address, amountToReceiver, baseAssetId, { - gasLimit: 1000, - }); + + const tx = await predicate.transfer( + receiver.address, + amountToReceiver, + provider.getBaseAssetId(), + { + gasLimit: 1000, + } + ); const { isStatusSuccess } = await tx.waitForResult(); // #endregion predicate-struct-arg @@ -149,9 +217,16 @@ describe('Predicate', () => { }); it('calls a predicate with an invalid main struct argument and returns false', async () => { + using launched = await launchTestNode(); + + const { + provider, + wallets: [fundingWallet], + } = launched; + const predicate = new Predicate<[Validation]>({ - bytecode: predicateBytesMainArgsStruct, - abi: predicateAbiMainArgsStruct, + bytecode: PredicateMainArgsStructAbi__factory.bin, + abi: PredicateMainArgsStructAbi__factory.abi, provider, inputData: [ { @@ -161,27 +236,49 @@ describe('Predicate', () => { ], }); - await seedTestWallet(predicate, [[amountToPredicate, baseAssetId]], 3); + const receiver = Wallet.generate({ provider }); + + // fund predicate + await fundPredicate(fundingWallet, predicate, amountToPredicate); await expect( - predicate.transfer(receiver.address, 50, baseAssetId, { gasLimit: 1000 }) + predicate.transfer(receiver.address, 50, provider.getBaseAssetId(), { gasLimit: 1000 }) ).rejects.toThrow(/PredicateVerificationFailed/); }); it('can call a Coin predicate which returns true with valid predicate data [main args vector]', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, + }, + }); + + const { + provider, + wallets: [fundingWallet], + } = launched; + const predicate = new Predicate<[BigNumberish[]]>({ - bytecode: predicateBytesMainArgsVector, - abi: predicateAbiMainArgsVector, + bytecode: PredicateMainArgsVectorAbi__factory.bin, + abi: PredicateMainArgsVectorAbi__factory.abi, provider, inputData: [[42]], }); - await seedTestWallet(predicate, [[amountToPredicate, baseAssetId]], 3); + const receiver = Wallet.generate({ provider }); const initialReceiverBalance = await receiver.getBalance(); - const tx = await predicate.transfer(receiver.address, amountToReceiver, baseAssetId, { - gasLimit: 1000, - }); + // fund predicate + await fundPredicate(fundingWallet, predicate, amountToPredicate); + + const tx = await predicate.transfer( + receiver.address, + amountToReceiver, + provider.getBaseAssetId(), + { + gasLimit: 1000, + } + ); const { isStatusSuccess } = await tx.waitForResult(); await assertBalances(receiver, initialReceiverBalance, amountToReceiver); @@ -189,26 +286,39 @@ describe('Predicate', () => { }); it('calls a predicate with valid multiple arguments and returns true', async () => { - const predicateForBalance = new Predicate({ - bytecode: predicateBytesMulti, - abi: predicateAbiMulti, - provider, - inputData: [20, 30], + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, + }, }); - await seedTestWallet(predicateForBalance, [[amountToPredicate, baseAssetId]], 3); + const { + provider, + wallets: [fundingWallet], + } = launched; + + const receiver = Wallet.generate({ provider }); const initialReceiverBalance = await receiver.getBalance(); // #region predicate-multi-args const predicate = new Predicate({ - bytecode: predicateBytesMulti, - abi: predicateAbiMulti, + bytecode: PredicateMultiArgsAbi__factory.bin, + abi: PredicateMultiArgsAbi__factory.abi, provider, inputData: [20, 30], }); - const tx = await predicate.transfer(receiver.address, amountToReceiver, baseAssetId, { - gasLimit: 1000, - }); + + // fund the predicate + await fundPredicate(fundingWallet, predicate, amountToPredicate); + + const tx = await predicate.transfer( + receiver.address, + amountToReceiver, + provider.getBaseAssetId(), + { + gasLimit: 1000, + } + ); const { isStatusSuccess } = await tx.waitForResult(); // #endregion predicate-multi-args @@ -217,19 +327,38 @@ describe('Predicate', () => { }); it('calls a predicate with valid multiple arguments and returns true - using setData', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, + }, + }); + + const { + provider, + wallets: [fundingWallet], + } = launched; + + const receiver = Wallet.generate({ provider }); + const initialReceiverBalance = await receiver.getBalance(); + const predicate = new Predicate({ - bytecode: predicateBytesMulti, - abi: predicateAbiMulti, + bytecode: PredicateMultiArgsAbi__factory.bin, + abi: PredicateMultiArgsAbi__factory.abi, provider, inputData: [20, 30], }); - await seedTestWallet(predicate, [[amountToPredicate, baseAssetId]], 3); - const initialReceiverBalance = await receiver.getBalance(); + // fund predicate + await fundPredicate(fundingWallet, predicate, amountToPredicate); - const tx = await predicate.transfer(receiver.address, amountToReceiver, baseAssetId, { - gasLimit: 1000, - }); + const tx = await predicate.transfer( + receiver.address, + amountToReceiver, + provider.getBaseAssetId(), + { + gasLimit: 1000, + } + ); const { isStatusSuccess } = await tx.waitForResult(); await assertBalances(receiver, initialReceiverBalance, amountToReceiver); @@ -237,17 +366,31 @@ describe('Predicate', () => { }); it('calls a predicate with invalid multiple arguments and throws error', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, + }, + }); + + const { + provider, + wallets: [fundingWallet], + } = launched; + const predicate = new Predicate({ - bytecode: predicateBytesMulti, - abi: predicateAbiMulti, + bytecode: PredicateMultiArgsAbi__factory.bin, + abi: PredicateMultiArgsAbi__factory.abi, provider, inputData: [20, 20], }); - await seedTestWallet(predicate, [[amountToPredicate, baseAssetId]], 3); + // fund predicate + await fundPredicate(fundingWallet, predicate, amountToPredicate); + + const receiver = Wallet.generate({ provider }); await expect( - predicate.transfer(receiver.address, 50, baseAssetId, { gasLimit: 1000 }) + predicate.transfer(receiver.address, 50, provider.getBaseAssetId(), { gasLimit: 1000 }) ).rejects.toThrow(/PredicateVerificationFailed/); }); }); diff --git a/packages/fuel-gauge/src/predicate/predicate-configurables.test.ts b/packages/fuel-gauge/src/predicate/predicate-configurables.test.ts index ab4c02f3f9..6134a9456b 100644 --- a/packages/fuel-gauge/src/predicate/predicate-configurables.test.ts +++ b/packages/fuel-gauge/src/predicate/predicate-configurables.test.ts @@ -1,49 +1,41 @@ -import type { CoinQuantityLike } from 'fuels'; -import { getRandomB256, Provider, WalletUnlocked, Predicate, FUEL_NETWORK_URL } from 'fuels'; -import { generateTestWallet } from 'fuels/test-utils'; +import { getRandomB256, WalletUnlocked, Predicate } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../../test/fixtures'; +import { + PredicateTrueAbi__factory, + PredicateWithConfigurableAbi__factory, +} from '../../test/typegen'; import { fundPredicate, assertBalance } from './utils/predicate'; /** * @group node + * @group browser */ describe('Predicate', () => { - const { binHexlified: predicateBytesTrue, abiContents: predicateAbiTrue } = - getFuelGaugeForcProject(FuelGaugeProjectsEnum.PREDICATE_TRUE); - - const { binHexlified: predicateBytesConfigurable, abiContents: predicateAbiConfigurable } = - getFuelGaugeForcProject(FuelGaugeProjectsEnum.PREDICATE_WITH_CONFIGURABLE); - describe('Configurables', () => { - let wallet: WalletUnlocked; const amountToPredicate = 300_000; - let baseAssetId: string; const defaultValues = { FEE: 10, ADDRESS: '0x38966262edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96', }; - beforeEach(async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - - const quantities: CoinQuantityLike[] = [ - { - amount: 100_000_000, - assetId: baseAssetId, + it('calls a predicate with configurables using default values', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, }, - ]; + }); - wallet = await generateTestWallet(provider, quantities); - }); + const { + provider, + wallets: [wallet], + } = launched; - it('calls a predicate with configurables using default values', async () => { const predicate = new Predicate({ - bytecode: predicateBytesConfigurable, - abi: predicateAbiConfigurable, + bytecode: PredicateWithConfigurableAbi__factory.bin, + abi: PredicateWithConfigurableAbi__factory.abi, provider: wallet.provider, inputData: [defaultValues.FEE, defaultValues.ADDRESS], // set predicate input data to be the same as default configurable value }); @@ -57,25 +49,41 @@ describe('Predicate', () => { provider: wallet.provider, }); - await assertBalance(destination, 0, baseAssetId); + await assertBalance(destination, 0, provider.getBaseAssetId()); - const tx = await predicate.transfer(destination.address, amountToTransfer, baseAssetId, { - gasLimit: 1000, - }); + const tx = await predicate.transfer( + destination.address, + amountToTransfer, + provider.getBaseAssetId(), + { + gasLimit: 1000, + } + ); await tx.waitForResult(); - await assertBalance(destination, amountToTransfer, baseAssetId); + await assertBalance(destination, amountToTransfer, provider.getBaseAssetId()); }); it('calls a predicate with configurables where first param is equal', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, + }, + }); + + const { + provider, + wallets: [wallet], + } = launched; + const configurableConstants = { FEE: 35 }; expect(configurableConstants.FEE).not.toEqual(defaultValues.FEE); const predicate = new Predicate({ - bytecode: predicateBytesConfigurable, - abi: predicateAbiConfigurable, - provider: wallet.provider, + bytecode: PredicateWithConfigurableAbi__factory.bin, + abi: PredicateWithConfigurableAbi__factory.abi, + provider, inputData: [configurableConstants.FEE, defaultValues.ADDRESS], configurableConstants, }); @@ -86,29 +94,45 @@ describe('Predicate', () => { provider: wallet.provider, }); - await assertBalance(destination, 0, baseAssetId); + await assertBalance(destination, 0, provider.getBaseAssetId()); // transfer funds to predicate await fundPredicate(wallet, predicate, amountToPredicate); // executing predicate transfer - const tx = await predicate.transfer(destination.address, amountToTransfer, baseAssetId, { - gasLimit: 1000, - }); + const tx = await predicate.transfer( + destination.address, + amountToTransfer, + provider.getBaseAssetId(), + { + gasLimit: 1000, + } + ); await tx.waitForResult(); - await assertBalance(destination, amountToTransfer, baseAssetId); + await assertBalance(destination, amountToTransfer, provider.getBaseAssetId()); }); it('calls a predicate with configurables where second param is equal', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, + }, + }); + + const { + provider, + wallets: [wallet], + } = launched; + const configurableConstants = { ADDRESS: getRandomB256() }; expect(configurableConstants.ADDRESS).not.toEqual(defaultValues.ADDRESS); const predicate = new Predicate({ - bytecode: predicateBytesConfigurable, - abi: predicateAbiConfigurable, - provider: wallet.provider, + bytecode: PredicateWithConfigurableAbi__factory.bin, + abi: PredicateWithConfigurableAbi__factory.abi, + provider, inputData: [defaultValues.FEE, configurableConstants.ADDRESS], configurableConstants, }); @@ -119,22 +143,38 @@ describe('Predicate', () => { provider: wallet.provider, }); - await assertBalance(destination, 0, baseAssetId); + await assertBalance(destination, 0, provider.getBaseAssetId()); // transfer funds to predicate await fundPredicate(wallet, predicate, amountToPredicate); // executing predicate transfer - const tx = await predicate.transfer(destination.address, amountToTransfer, baseAssetId, { - gasLimit: 1000, - }); + const tx = await predicate.transfer( + destination.address, + amountToTransfer, + provider.getBaseAssetId(), + { + gasLimit: 1000, + } + ); await tx.waitForResult(); - await assertBalance(destination, amountToTransfer, baseAssetId); + await assertBalance(destination, amountToTransfer, provider.getBaseAssetId()); }); it('calls a predicate with configurables where both params are equal', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, + }, + }); + + const { + provider, + wallets: [wallet], + } = launched; + const configurableConstants = { FEE: 90, ADDRESS: getRandomB256(), @@ -143,9 +183,9 @@ describe('Predicate', () => { expect(configurableConstants.FEE).not.toEqual(defaultValues.FEE); expect(configurableConstants.ADDRESS).not.toEqual(defaultValues.ADDRESS); const predicate = new Predicate({ - bytecode: predicateBytesConfigurable, - abi: predicateAbiConfigurable, - provider: wallet.provider, + bytecode: PredicateWithConfigurableAbi__factory.bin, + abi: PredicateWithConfigurableAbi__factory.abi, + provider, inputData: [configurableConstants.FEE, configurableConstants.ADDRESS], configurableConstants, }); @@ -156,24 +196,40 @@ describe('Predicate', () => { provider: wallet.provider, }); - await assertBalance(destination, 0, baseAssetId); + await assertBalance(destination, 0, provider.getBaseAssetId()); await fundPredicate(wallet, predicate, amountToPredicate); - const tx = await predicate.transfer(destination.address, amountToTransfer, baseAssetId, { - gasLimit: 1000, - }); + const tx = await predicate.transfer( + destination.address, + amountToTransfer, + provider.getBaseAssetId(), + { + gasLimit: 1000, + } + ); await tx.waitForResult(); - await assertBalance(destination, amountToTransfer, baseAssetId); + await assertBalance(destination, amountToTransfer, provider.getBaseAssetId()); }); it('throws when configurable data is not set', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, + }, + }); + + const { + provider, + wallets: [wallet], + } = launched; + const predicate = new Predicate({ - bytecode: predicateBytesConfigurable, - abi: predicateAbiConfigurable, - provider: wallet.provider, + bytecode: PredicateWithConfigurableAbi__factory.bin, + abi: PredicateWithConfigurableAbi__factory.abi, + provider, }); const destination = WalletUnlocked.generate({ @@ -183,17 +239,21 @@ describe('Predicate', () => { await fundPredicate(wallet, predicate, amountToPredicate); await expect( - predicate.transfer(destination.address, 300, baseAssetId, { gasLimit: 1000 }) + predicate.transfer(destination.address, 300, provider.getBaseAssetId(), { gasLimit: 1000 }) ).rejects.toThrow(/PredicateVerificationFailed/); }); - it('throws when setting configurable but predicate has none', () => { + it('throws when setting configurable but predicate has none', async () => { + using launched = await launchTestNode(); + + const { provider } = launched; + expect(() => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const predicate = new Predicate({ - bytecode: predicateBytesTrue, - abi: predicateAbiTrue, - provider: wallet.provider, + bytecode: PredicateTrueAbi__factory.bin, + abi: PredicateTrueAbi__factory.abi, + provider, inputData: ['NADA'], configurableConstants: { constant: 'NADA', @@ -202,15 +262,19 @@ describe('Predicate', () => { }).toThrow('Predicate has no configurable constants to be set'); }); - it('throws when setting invalid configurable', () => { + it('throws when setting invalid configurable', async () => { + using launched = await launchTestNode(); + + const { provider } = launched; + const errMsg = `Error setting configurable constants: No configurable constant named 'NOPE' found in the Predicate.`; expect(() => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const predicate = new Predicate({ - bytecode: predicateBytesConfigurable, - abi: predicateAbiConfigurable, - provider: wallet.provider, + bytecode: PredicateWithConfigurableAbi__factory.bin, + abi: PredicateWithConfigurableAbi__factory.abi, + provider, inputData: ['NADA'], configurableConstants: { NOPE: 'NADA', @@ -219,14 +283,17 @@ describe('Predicate', () => { }).toThrow(errMsg); }); - it('throws when setting a configurable with no ABI', () => { + it('throws when setting a configurable with no ABI', async () => { + using launched = await launchTestNode(); + + const { provider } = launched; const errMsg = `Error setting configurable constants: Cannot validate configurable constants because the Predicate was instantiated without a JSON ABI.`; expect(() => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const predicate = new Predicate({ - bytecode: predicateBytesConfigurable, - provider: wallet.provider, + bytecode: PredicateWithConfigurableAbi__factory.bin, + provider, inputData: ['NADA'], configurableConstants: { NOPE: 'NADA', diff --git a/packages/fuel-gauge/src/predicate/predicate-estimations.test.ts b/packages/fuel-gauge/src/predicate/predicate-estimations.test.ts index a24d30062a..211fe7df48 100644 --- a/packages/fuel-gauge/src/predicate/predicate-estimations.test.ts +++ b/packages/fuel-gauge/src/predicate/predicate-estimations.test.ts @@ -5,69 +5,64 @@ import type { BN, } from 'fuels'; import { - Provider, Predicate, bn, ScriptTransactionRequest, InputType, - FUEL_NETWORK_URL, getRandomB256, WalletUnlocked, isRequestInputResource, } from 'fuels'; -import { seedTestWallet } from 'fuels/test-utils'; +import { launchTestNode } from 'fuels/test-utils'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../../test/fixtures'; +import { + PredicateMainArgsStructAbi__factory, + PredicateTrueAbi__factory, + PredicateValidateTransferAbi__factory, +} from '../../test/typegen'; import type { Validation } from '../types/predicate'; +import { fundPredicate } from './utils/predicate'; + /** * @group node + * @group browser */ describe('Predicate', () => { - const { binHexlified: predicateTrueBytecode } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.PREDICATE_TRUE - ); - - const { binHexlified: predicateBytesMainArgsStruct, abiContents: predicateAbiMainArgsStruct } = - getFuelGaugeForcProject(FuelGaugeProjectsEnum.PREDICATE_MAIN_ARGS_STRUCT); - describe('Estimate predicate gas', () => { - let provider: Provider; - let predicateTrue: Predicate<[]>; - let predicateStruct: Predicate<[Validation]>; - let baseAssetId: string; const fundingAmount = 10_000; - beforeAll(async () => { - provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - predicateTrue = new Predicate({ - bytecode: predicateTrueBytecode, + it('estimatePredicates should assign gas to the correct input', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, + }, + }); + + const { + wallets: [wallet], + provider, + } = launched; + + const predicateTrue = new Predicate({ + bytecode: PredicateTrueAbi__factory.bin, provider, }); - predicateStruct = new Predicate<[Validation]>({ - bytecode: predicateBytesMainArgsStruct, - abi: predicateAbiMainArgsStruct, + + const predicateStruct = new Predicate<[Validation]>({ + bytecode: PredicateMainArgsStructAbi__factory.bin, + abi: PredicateMainArgsStructAbi__factory.abi, provider, }); - }); - beforeEach(async () => { - await seedTestWallet(predicateStruct, [ - { - assetId: baseAssetId, - amount: bn(fundingAmount), - }, - ]); - }); + await fundPredicate(wallet, predicateStruct, fundingAmount); - it('estimatePredicates should assign gas to the correct input', async () => { const tx = new ScriptTransactionRequest(); // Get resources from the predicate struct const ressources = await predicateStruct.getResourcesToSpend([ { - assetId: baseAssetId, + assetId: provider.getBaseAssetId(), amount: bn(10_000), }, ]); @@ -139,9 +134,27 @@ describe('Predicate', () => { }); test('predicate does not get estimated again if it has already been estimated', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, + }, + }); + + const { + wallets: [wallet], + provider, + } = launched; + const tx = new ScriptTransactionRequest(); - await seedTestWallet(predicateTrue, [[2000, baseAssetId]]); - const resources = await predicateTrue.getResourcesToSpend([[1, baseAssetId]]); + + const predicateTrue = new Predicate({ + bytecode: PredicateTrueAbi__factory.bin, + provider, + }); + + await fundPredicate(wallet, predicateTrue, fundingAmount); + + const resources = await predicateTrue.getResourcesToSpend([[1, provider.getBaseAssetId()]]); tx.addResources(resources); const spy = vi.spyOn(provider.operations, 'estimatePredicates'); @@ -153,16 +166,44 @@ describe('Predicate', () => { }); test('Predicates get estimated if one of them is not estimated', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, + }, + }); + + const { + wallets: [wallet], + provider, + } = launched; + + const predicateTrue = new Predicate({ + bytecode: PredicateTrueAbi__factory.bin, + provider, + }); + + const predicateStruct = new Predicate<[Validation]>({ + bytecode: PredicateMainArgsStructAbi__factory.bin, + abi: PredicateMainArgsStructAbi__factory.abi, + provider, + }); + + await fundPredicate(wallet, predicateTrue, fundingAmount); + await fundPredicate(wallet, predicateStruct, fundingAmount); + const tx = new ScriptTransactionRequest(); - await seedTestWallet(predicateTrue, [[2000, baseAssetId]]); - const trueResources = await predicateTrue.getResourcesToSpend([[1, baseAssetId]]); + const trueResources = await predicateTrue.getResourcesToSpend([ + [1, provider.getBaseAssetId()], + ]); + tx.addResources(trueResources); const spy = vi.spyOn(provider.operations, 'estimatePredicates'); await provider.estimatePredicates(tx); - await seedTestWallet(predicateStruct, [[2000, baseAssetId]]); - const structResources = await predicateStruct.getResourcesToSpend([[1, baseAssetId]]); + const structResources = await predicateStruct.getResourcesToSpend([ + [1, provider.getBaseAssetId()], + ]); tx.addResources(structResources); await provider.estimatePredicates(tx); @@ -174,20 +215,27 @@ describe('Predicate', () => { }); test('transferring funds from a predicate estimates the predicate and does only one dry run', async () => { - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.PREDICATE_VALIDATE_TRANSFER - ); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, + }, + }); + + const { + wallets: [wallet], + provider, + } = launched; const amountToPredicate = 200_000; - const predicate = new Predicate<[BN]>({ - bytecode: binHexlified, - abi: abiContents, + const predicateValidateTransfer = new Predicate<[BN]>({ + bytecode: PredicateValidateTransferAbi__factory.bin, + abi: PredicateValidateTransferAbi__factory.abi, provider, inputData: [bn(amountToPredicate)], }); - await seedTestWallet(predicate, [[amountToPredicate, baseAssetId]]); + await fundPredicate(wallet, predicateValidateTransfer, amountToPredicate); const receiverWallet = WalletUnlocked.generate({ provider, @@ -198,7 +246,11 @@ describe('Predicate', () => { const dryRunSpy = vi.spyOn(provider.operations, 'dryRun'); const estimatePredicatesSpy = vi.spyOn(provider.operations, 'estimatePredicates'); - const response = await predicate.transfer(receiverWallet.address.toB256(), 1, baseAssetId); + const response = await predicateValidateTransfer.transfer( + receiverWallet.address.toB256(), + 1, + provider.getBaseAssetId() + ); const { isStatusSuccess } = await response.waitForResult(); expect(isStatusSuccess).toBeTruthy(); @@ -212,9 +264,30 @@ describe('Predicate', () => { describe('predicate resource fetching and predicateData population', () => { test('getting predicate resources via the predicate automatically populates predicateData', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, + }, + }); + + const { + wallets: [wallet], + provider, + } = launched; + + const predicateStruct = new Predicate<[Validation]>({ + bytecode: PredicateMainArgsStructAbi__factory.bin, + abi: PredicateMainArgsStructAbi__factory.abi, + provider, + }); + + await fundPredicate(wallet, predicateStruct, fundingAmount); + const transactionRequest = new ScriptTransactionRequest(); - const resources = await predicateStruct.getResourcesToSpend([[fundingAmount, baseAssetId]]); + const resources = await predicateStruct.getResourcesToSpend([ + [fundingAmount, provider.getBaseAssetId()], + ]); resources.forEach((resource) => { expect(resource.predicateData).toBeDefined(); }); @@ -229,10 +302,29 @@ describe('Predicate', () => { }); test('getting predicate resources via the provider requires manual predicateData population', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, + }, + }); + + const { + wallets: [wallet], + provider, + } = launched; + + const predicateStruct = new Predicate<[Validation]>({ + bytecode: PredicateMainArgsStructAbi__factory.bin, + abi: PredicateMainArgsStructAbi__factory.abi, + provider, + }); + + await fundPredicate(wallet, predicateStruct, fundingAmount); + const transactionRequest = new ScriptTransactionRequest(); const resources = await provider.getResourcesToSpend(predicateStruct.address, [ - [fundingAmount, baseAssetId], + [fundingAmount, provider.getBaseAssetId()], ]); resources.forEach((resource) => { diff --git a/packages/fuel-gauge/src/predicate/predicate-evaluations.test.ts b/packages/fuel-gauge/src/predicate/predicate-evaluations.test.ts index b42419d71e..ffbd01b8ba 100644 --- a/packages/fuel-gauge/src/predicate/predicate-evaluations.test.ts +++ b/packages/fuel-gauge/src/predicate/predicate-evaluations.test.ts @@ -10,6 +10,7 @@ import { assertBalances, fundPredicate } from './utils/predicate'; /** * @group node + * @group browser */ describe('Predicate', () => { describe('Evaluations', () => { @@ -21,7 +22,7 @@ describe('Predicate', () => { provider, } = launched; - const receiver = Wallet.fromAddress(Address.fromRandom(), provider); + const receiver = Wallet.generate({ provider }); const initialReceiverBalance = await receiver.getBalance(); const predicate = PredicateTrueAbi__factory.createInstance(provider); diff --git a/packages/fuel-gauge/src/predicate/predicate-general.test.ts b/packages/fuel-gauge/src/predicate/predicate-general.test.ts index 9a9a08cf99..6f49c1e19e 100644 --- a/packages/fuel-gauge/src/predicate/predicate-general.test.ts +++ b/packages/fuel-gauge/src/predicate/predicate-general.test.ts @@ -1,26 +1,18 @@ import type { BN, FakeResources } from 'fuels'; -import { - Address, - FUEL_NETWORK_URL, - Predicate, - Provider, - ScriptTransactionRequest, - bn, -} from 'fuels'; -import { ASSET_A, ASSET_B } from 'fuels/test-utils'; +import { Address, Predicate, ScriptTransactionRequest, bn } from 'fuels'; +import { ASSET_A, ASSET_B, launchTestNode } from 'fuels/test-utils'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../../test/fixtures'; +import { PredicateSumAbi__factory } from '../../test/typegen'; /** * @group node + * @group browser */ describe('Predicate', () => { it('can generate and use fake predicate coins', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - const baseAssetId = provider.getBaseAssetId(); - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.PREDICATE_SUM - ); + using launched = await launchTestNode(); + + const { provider } = launched; const amount1 = bn(500_000); const amount2 = bn(200_000); @@ -28,7 +20,7 @@ describe('Predicate', () => { const amountToTransferBaseAsset = bn(1000); const fakeCoinsConfig: FakeResources[] = [ - { amount: amount1, assetId: baseAssetId }, + { amount: amount1, assetId: provider.getBaseAssetId() }, { amount: amount2, assetId: ASSET_A }, { amount: amount3, assetId: ASSET_B }, ]; @@ -37,8 +29,8 @@ describe('Predicate', () => { const value1 = bn(100); const predicate = new Predicate<[BN, BN]>({ - bytecode: binHexlified, - abi: abiContents, + bytecode: PredicateSumAbi__factory.bin, + abi: PredicateSumAbi__factory.abi, provider, inputData: [value1, value2], }); @@ -56,7 +48,11 @@ describe('Predicate', () => { }); request.addResources(fakeCoins); - request.addCoinOutput(Address.fromRandom(), amountToTransferBaseAsset, baseAssetId); + request.addCoinOutput( + Address.fromRandom(), + amountToTransferBaseAsset, + provider.getBaseAssetId() + ); request.addCoinOutput(Address.fromRandom(), amount2, ASSET_A); request.addCoinOutput(Address.fromRandom(), amount3, ASSET_B); diff --git a/packages/fuel-gauge/src/predicate/predicate-input-data.test.ts b/packages/fuel-gauge/src/predicate/predicate-input-data.test.ts index 13318c277a..1d29920d8d 100644 --- a/packages/fuel-gauge/src/predicate/predicate-input-data.test.ts +++ b/packages/fuel-gauge/src/predicate/predicate-input-data.test.ts @@ -1,45 +1,44 @@ -import type { InputValue, Provider, WalletLocked, WalletUnlocked } from 'fuels'; -import { Predicate } from 'fuels'; +import { Predicate, Wallet } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../../test/fixtures'; +import { PredicateInputDataAbi__factory } from '../../test/typegen'; -import { setupWallets, fundPredicate } from './utils/predicate'; +import { fundPredicate } from './utils/predicate'; /** * @group node + * @group browser */ -describe('Predicate', () => { - const { binHexlified, abiContents } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.PREDICATE_INPUT_DATA - ); +describe('Predicate', () => { describe('Input Data', () => { - let predicate: Predicate; - let wallet: WalletUnlocked; - let receiver: WalletLocked; - let provider: Provider; - let baseAssetId: string; - - beforeEach(async () => { - [wallet, receiver] = await setupWallets(); - provider = wallet.provider; - baseAssetId = provider.getBaseAssetId(); - }); - it('throws invalid transaction when input_predicate_data is required for predicate validation', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000, + }, + }); + const { + provider, + wallets: [wallet], + } = launched; + const amountToPredicate = 200_000; const amountToReceiver = 50; - predicate = new Predicate({ - bytecode: binHexlified, - abi: abiContents, + + const predicate = new Predicate({ + bytecode: PredicateInputDataAbi__factory.bin, + abi: PredicateInputDataAbi__factory.abi, provider, inputData: [true], }); await fundPredicate(wallet, predicate, amountToPredicate); + const receiver = Wallet.generate({ provider }); + await expect( - predicate.transfer(receiver.address, amountToReceiver, baseAssetId, { + predicate.transfer(receiver.address, amountToReceiver, provider.getBaseAssetId(), { gasLimit: 1000, }) ).rejects.toThrow(/PredicateVerificationFailed/i); diff --git a/packages/fuel-gauge/src/predicate/predicate-invalidations.test.ts b/packages/fuel-gauge/src/predicate/predicate-invalidations.test.ts index 9ad3da0bd9..e282ba2e90 100644 --- a/packages/fuel-gauge/src/predicate/predicate-invalidations.test.ts +++ b/packages/fuel-gauge/src/predicate/predicate-invalidations.test.ts @@ -1,56 +1,66 @@ -import type { Provider, WalletLocked, WalletUnlocked } from 'fuels'; -import { Predicate } from 'fuels'; +import { Predicate, Wallet } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../../test/fixtures'; +import { PredicateMainArgsStructAbi__factory } from '../../test/typegen'; import type { Validation } from '../types/predicate'; -import { fundPredicate, setupWallets } from './utils/predicate'; +import { fundPredicate } from './utils/predicate'; /** * @group node + * @group browser */ describe('Predicate', () => { - const { binHexlified: predicateBytesMainArgsStruct, abiContents: predicateAbiMainArgsStruct } = - getFuelGaugeForcProject(FuelGaugeProjectsEnum.PREDICATE_MAIN_ARGS_STRUCT); - describe('Invalidations', () => { - let predicate: Predicate<[Validation]>; - let wallet: WalletUnlocked; - let receiver: WalletLocked; - let provider: Provider; - let baseAssetId: string; - - const validation: Validation = { - has_account: true, - total_complete: 100, - }; - - beforeAll(async () => { - [wallet, receiver] = await setupWallets(); - const amountToPredicate = 1000; - provider = wallet.provider; - predicate = new Predicate<[Validation]>({ - bytecode: predicateBytesMainArgsStruct, - abi: predicateAbiMainArgsStruct, + it('throws if sender does not have enough resources for tx and gas', async () => { + using launched = await launchTestNode(); + const { + provider, + wallets: [wallet], + } = launched; + + const predicate = new Predicate<[Validation]>({ + bytecode: PredicateMainArgsStructAbi__factory.bin, + abi: PredicateMainArgsStructAbi__factory.abi, provider, - inputData: [validation], }); - await fundPredicate(wallet, predicate, amountToPredicate); - }); + await fundPredicate(wallet, predicate, 1000); + + const receiver = Wallet.generate({ provider }); - it('throws if sender does not have enough resources for tx and gas', async () => { await expect( - predicate.transfer(receiver.address, await predicate.getBalance(), baseAssetId, { - gasLimit: 100_000_000, - }) + predicate.transfer( + receiver.address, + await predicate.getBalance(), + provider.getBaseAssetId(), + { + gasLimit: 100_000_000, + } + ) ).rejects.toThrow(/not enough coins to fit the target/i); }); it('throws if the passed gas limit is too low', async () => { + using launched = await launchTestNode(); + const { + provider, + wallets: [wallet], + } = launched; + + const predicate = new Predicate<[Validation]>({ + bytecode: PredicateMainArgsStructAbi__factory.bin, + abi: PredicateMainArgsStructAbi__factory.abi, + provider, + }); + + await fundPredicate(wallet, predicate, 1000); + + const receiver = Wallet.generate({ provider }); + // fuel-client we should change with the proper error message await expect( - predicate.transfer(receiver.address, 1000, baseAssetId, { + predicate.transfer(receiver.address, 1000, provider.getBaseAssetId(), { gasLimit: 0, }) ).rejects.toThrow(/Gas limit '0' is lower than the required:./i); diff --git a/packages/fuel-gauge/src/predicate/predicate-populate-witness.test.ts b/packages/fuel-gauge/src/predicate/predicate-populate-witness.test.ts index 65d4802035..1b96eb8c52 100644 --- a/packages/fuel-gauge/src/predicate/predicate-populate-witness.test.ts +++ b/packages/fuel-gauge/src/predicate/predicate-populate-witness.test.ts @@ -1,41 +1,22 @@ -import type { CoinQuantityLike, ExcludeResourcesOption, Resource, WalletUnlocked } from 'fuels'; +import type { CoinQuantityLike, ExcludeResourcesOption, Resource } from 'fuels'; +import { Predicate, ScriptTransactionRequest, bn, isCoin, Wallet } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; + import { - Provider, - Predicate, - FUEL_NETWORK_URL, - ScriptTransactionRequest, - Wallet, - bn, - isCoin, -} from 'fuels'; -import { seedTestWallet } from 'fuels/test-utils'; - -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../../test/fixtures'; + PredicateAssertNumberAbi__factory, + PredicateAssertValueAbi__factory, +} from '../../test/typegen'; + +import { fundPredicate } from './utils/predicate'; /** * @group node + * @group browser */ describe('Predicate', () => { - const assertNumberArtifacts = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.PREDICATE_ASSERT_NUMBER - ); - const assertValueArtifacts = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.PREDICATE_ASSERT_VALUE - ); + const UTXOS_AMOUNT = 12; describe('Populate Predicate Witness', () => { - const UTXOS_AMOUNT = 12; - - let provider: Provider; - let receiver: WalletUnlocked; - let baseAssetId: string; - let predicate1: Predicate<[number]>; - let predicate2: Predicate<[boolean]>; - - let wallet1: WalletUnlocked; - let wallet2: WalletUnlocked; - let wallet3: WalletUnlocked; - const cacheResources = (resources: Array) => resources.reduce( (cache, resource) => { @@ -52,52 +33,45 @@ describe('Predicate', () => { } as Required ); - let quantity: CoinQuantityLike[]; - beforeAll(async () => { - provider = await Provider.create(FUEL_NETWORK_URL, { cacheUtxo: 1000 }); - baseAssetId = provider.getBaseAssetId(); - quantity = [[500, baseAssetId]]; - wallet1 = Wallet.generate({ provider }); - wallet2 = Wallet.generate({ provider }); - wallet3 = Wallet.generate({ provider }); - receiver = Wallet.generate({ provider }); - predicate1 = new Predicate<[number]>({ - bytecode: assertNumberArtifacts.binHexlified, - provider, - abi: assertNumberArtifacts.abiContents, - inputData: [11], + it('should properly populate predicate data and remove placeholder witness [CASE 1]', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000_000, + }, }); + const { + provider, + wallets: [wallet], + } = launched; + + const quantity: CoinQuantityLike[] = [[500, provider.getBaseAssetId()]]; - predicate2 = new Predicate<[boolean]>({ - bytecode: assertValueArtifacts.binHexlified, - abi: assertValueArtifacts.abiContents, + const predicateAssertNumber = new Predicate<[number]>({ + bytecode: PredicateAssertNumberAbi__factory.bin, + abi: PredicateAssertNumberAbi__factory.abi, provider, - inputData: [true], + inputData: [11], }); - await seedTestWallet( - [wallet1, wallet2, wallet3, predicate1, predicate2], - [[500_000_000, baseAssetId]], - UTXOS_AMOUNT - ); - }); + await fundPredicate(wallet, predicateAssertNumber, 500_000_000); - it('should properly populate predicate data and remove placeholder witness [CASE 1]', async () => { let transactionRequest = new ScriptTransactionRequest(); - transactionRequest.addCoinOutput(receiver.address, 100, baseAssetId); + const receiver = Wallet.generate({ provider }); + transactionRequest.addCoinOutput(receiver.address, 100, provider.getBaseAssetId()); - const predicate1WrongResources = await provider.getResourcesToSpend( - predicate1.address, + const predicateAssertNumberWrongResources = await provider.getResourcesToSpend( + predicateAssertNumber.address, quantity ); - transactionRequest.addResources(predicate1WrongResources); // will add a placeholder witness + transactionRequest.addResources(predicateAssertNumberWrongResources); // will add a placeholder witness // The request carries 1 placeholder witnesses that was added for the predicate resources expect(transactionRequest.witnesses.length).toBe(1); // populating predicates inputs with predicate data and removing placeholder witness added for Predicate - transactionRequest = predicate1.populateTransactionPredicateData(transactionRequest); + transactionRequest = + predicateAssertNumber.populateTransactionPredicateData(transactionRequest); transactionRequest = await provider.estimatePredicates(transactionRequest); // The predicate resource witness placeholder was removed @@ -114,17 +88,40 @@ describe('Predicate', () => { }); it('should properly populate predicate data and remove placeholder witness [CASE 2]', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000_000, + }, + }); + const { + provider, + wallets: [fundingWallet, wallet1], + } = launched; + + const quantity: CoinQuantityLike[] = [[500, provider.getBaseAssetId()]]; + + const receiver = Wallet.generate({ provider }); + let transactionRequest = new ScriptTransactionRequest({ gasLimit: 2000, maxFee: bn(0) }); - transactionRequest.addCoinOutput(receiver.address, 100, baseAssetId); + transactionRequest.addCoinOutput(receiver.address, 100, provider.getBaseAssetId()); + + const predicateAssertNumber = new Predicate<[number]>({ + bytecode: PredicateAssertNumberAbi__factory.bin, + abi: PredicateAssertNumberAbi__factory.abi, + provider, + inputData: [11], + }); + + await fundPredicate(fundingWallet, predicateAssertNumber, 500_000_000); const resources1 = await wallet1.getResourcesToSpend(quantity); - const predicate1WrongResources = await provider.getResourcesToSpend( - predicate1.address, + const predicateAssertNumberWrongResources = await provider.getResourcesToSpend( + predicateAssertNumber.address, quantity ); transactionRequest.addResources([ - ...predicate1WrongResources, // witnessIndex 0 but will add placeholder witness + ...predicateAssertNumberWrongResources, // witnessIndex 0 but will add placeholder witness ...resources1, // witnessIndex will be 1 and will need to be ajusted to 0 ]); @@ -132,7 +129,8 @@ describe('Predicate', () => { expect(transactionRequest.witnesses.length).toBe(2); // populating predicates inputs with predicate data and removing placeholder witness added for Predicate - transactionRequest = predicate1.populateTransactionPredicateData(transactionRequest); + transactionRequest = + predicateAssertNumber.populateTransactionPredicateData(transactionRequest); transactionRequest = await provider.estimatePredicates(transactionRequest); transactionRequest.gasLimit = bn(100_000); @@ -150,34 +148,59 @@ describe('Predicate', () => { }); it('should properly populate predicate data and remove placeholder witness [CASE 3]', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000_000, + count: 3, + }, + }); + const { + provider, + wallets: [fundingWallet, wallet1, wallet2], + } = launched; + + const quantity: CoinQuantityLike[] = [[500, provider.getBaseAssetId()]]; + + const predicateAssertNumber = new Predicate<[number]>({ + bytecode: PredicateAssertNumberAbi__factory.bin, + abi: PredicateAssertNumberAbi__factory.abi, + provider, + inputData: [11], + }); + + await fundPredicate(fundingWallet, predicateAssertNumber, 500_000_000, UTXOS_AMOUNT); + + const receiver = Wallet.generate({ provider }); + let transactionRequest = new ScriptTransactionRequest({ gasLimit: 2000, maxFee: bn(0) }); - transactionRequest.addCoinOutput(receiver.address, 100, baseAssetId); + transactionRequest.addCoinOutput(receiver.address, 100, provider.getBaseAssetId()); const resources1 = await wallet1.getResourcesToSpend(quantity); const resources2 = await wallet2.getResourcesToSpend(quantity); - const predicate1WrongResources1 = await provider.getResourcesToSpend( - predicate1.address, + const predicateAssertNumberWrongResources1 = await provider.getResourcesToSpend( + predicateAssertNumber.address, quantity ); - const predicate1WrongResources2 = await provider.getResourcesToSpend( - predicate1.address, + const predicateAssertNumberWrongResources2 = await provider.getResourcesToSpend( + predicateAssertNumber.address, quantity, - cacheResources(predicate1WrongResources1) + cacheResources(predicateAssertNumberWrongResources1) ); transactionRequest.addResources([ ...resources1, // witnessIndex 0 - ...predicate1WrongResources1, // witnessIndex 1 and will add placeholder witness + ...predicateAssertNumberWrongResources1, // witnessIndex 1 and will add placeholder witness ...resources2, // witnessIndex 2 - ...predicate1WrongResources2, // witnessIndex 1 since we already added resources from the same owner + ...predicateAssertNumberWrongResources2, // witnessIndex 1 since we already added resources from the same owner ]); // The request carries 3 placeholder witnesses, one was added for the predicate resources expect(transactionRequest.witnesses.length).toBe(3); // populating predicates inputs with predicate data and removing placeholder witness added for Predicate - transactionRequest = predicate1.populateTransactionPredicateData(transactionRequest); + transactionRequest = + predicateAssertNumber.populateTransactionPredicateData(transactionRequest); transactionRequest = await provider.estimatePredicates(transactionRequest); transactionRequest.gasLimit = bn(160_000); @@ -198,38 +221,71 @@ describe('Predicate', () => { }); it('should properly populate predicate data and remove placeholder witness [CASE 4]', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000_000, + count: 4, + }, + }); + const { + provider, + wallets: [fundingWallet, wallet1, wallet2, wallet3], + } = launched; + + const quantity: CoinQuantityLike[] = [[500, provider.getBaseAssetId()]]; + let transactionRequest = new ScriptTransactionRequest({ gasLimit: 3000, maxFee: bn(0) }); const resources1 = await wallet1.getResourcesToSpend(quantity); const resources2 = await wallet2.getResourcesToSpend(quantity); const resources3 = await wallet3.getResourcesToSpend(quantity); + const predicateAssertNumber = new Predicate<[number]>({ + bytecode: PredicateAssertNumberAbi__factory.bin, + abi: PredicateAssertNumberAbi__factory.abi, + provider, + inputData: [11], + }); + + await fundPredicate(fundingWallet, predicateAssertNumber, 500_000, UTXOS_AMOUNT); + + const predicateAssertValue = new Predicate<[boolean]>({ + bytecode: PredicateAssertValueAbi__factory.bin, + abi: PredicateAssertValueAbi__factory.abi, + provider, + inputData: [true], + }); + + await fundPredicate(fundingWallet, predicateAssertValue, 500_000, UTXOS_AMOUNT); + // predicate resources fetched as non predicate resources - const predicate1WrongResources = await provider.getResourcesToSpend( - predicate1.address, + const predicateAssertNumberWrongResources = await provider.getResourcesToSpend( + predicateAssertNumber.address, quantity ); // predicate resources fetched as predicate resources - const predicate1Resources = await predicate1.getResourcesToSpend( + const predicateAssertNumberResources = await predicateAssertNumber.getResourcesToSpend( quantity, - cacheResources(predicate1WrongResources) + cacheResources(predicateAssertNumberWrongResources) ); // predicate resources fetched as non predicate resources - const predicate2WrongResources = await provider.getResourcesToSpend( - predicate2.address, + const predicateAssertValueWrongResources = await provider.getResourcesToSpend( + predicateAssertValue.address, quantity ); - transactionRequest.addCoinOutput(receiver.address, 100, baseAssetId); + const receiver = Wallet.generate({ provider }); + + transactionRequest.addCoinOutput(receiver.address, 100, provider.getBaseAssetId()); transactionRequest.addResources([ - ...predicate1WrongResources, // witnessIndex 0 but will generate a placeholder witness + ...predicateAssertNumberWrongResources, // witnessIndex 0 but will generate a placeholder witness ...resources1, // witnessIndex 1 - ...predicate2WrongResources, // witnessIndex 2 and will generate a placeholder witness, + ...predicateAssertValueWrongResources, // witnessIndex 2 and will generate a placeholder witness, ...resources2, // witnessIndex 3 - ...predicate1Resources, // witnessIndex 0 because these predicate resources were properly fetched + ...predicateAssertNumberResources, // witnessIndex 0 because these predicate resources were properly fetched ...resources3, // witnessIndex 4 ]); @@ -237,8 +293,10 @@ describe('Predicate', () => { expect(transactionRequest.witnesses.length).toBe(5); // populating predicates inputs with predicate data and removing placeholder witness added for Predicate - transactionRequest = predicate1.populateTransactionPredicateData(transactionRequest); - transactionRequest = predicate2.populateTransactionPredicateData(transactionRequest); + transactionRequest = + predicateAssertNumber.populateTransactionPredicateData(transactionRequest); + transactionRequest = + predicateAssertValue.populateTransactionPredicateData(transactionRequest); transactionRequest = await provider.estimatePredicates(transactionRequest); transactionRequest.gasLimit = bn(250_000); @@ -259,34 +317,68 @@ describe('Predicate', () => { }); it('should properly populate predicate data and remove placeholder witness [CASE 5]', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000_000, + count: 3, + }, + }); + const { + provider, + wallets: [fundingWallet, wallet1, wallet2], + } = launched; + + const quantity: CoinQuantityLike[] = [[500, provider.getBaseAssetId()]]; + let transactionRequest = new ScriptTransactionRequest({ gasLimit: 2000, maxFee: bn(0) }); + const predicateAssertNumber = new Predicate<[number]>({ + bytecode: PredicateAssertNumberAbi__factory.bin, + abi: PredicateAssertNumberAbi__factory.abi, + provider, + inputData: [11], + }); + + await fundPredicate(fundingWallet, predicateAssertNumber, 500_000, UTXOS_AMOUNT); + + const predicateAssertValue = new Predicate<[boolean]>({ + bytecode: PredicateAssertValueAbi__factory.bin, + abi: PredicateAssertValueAbi__factory.abi, + provider, + inputData: [true], + }); + + await fundPredicate(fundingWallet, predicateAssertValue, 500_000, UTXOS_AMOUNT); + const resources1 = await wallet1.getResourcesToSpend(quantity); const resources2 = await wallet2.getResourcesToSpend(quantity); - const predicate1WrongResources = await provider.getResourcesToSpend( - predicate1.address, + const predicateAssertNumberWrongResources = await provider.getResourcesToSpend( + predicateAssertNumber.address, quantity ); - const predicate1Resources = await predicate1.getResourcesToSpend( + const predicateAssertNumberResources = await predicateAssertNumber.getResourcesToSpend( quantity, - cacheResources(predicate1WrongResources) + cacheResources(predicateAssertNumberWrongResources) ); - transactionRequest.addCoinOutput(receiver.address, 100, baseAssetId); + const receiver = Wallet.generate({ provider }); + + transactionRequest.addCoinOutput(receiver.address, 100, provider.getBaseAssetId()); transactionRequest.addResources([ ...resources1, // witnessIndex 0 ...resources2, // witnessIndex 1 - ...predicate1Resources, // witnessIndex 0 and no placeholder witness - ...predicate1WrongResources, // witnessIndex 0 and no placeholder wit since it has resources from same owner + ...predicateAssertNumberResources, // witnessIndex 0 and no placeholder witness + ...predicateAssertNumberWrongResources, // witnessIndex 0 and no placeholder wit since it has resources from same owner ]); // The request carries 2 placeholder witnesses, none was added for the predicate resources expect(transactionRequest.witnesses.length).toBe(2); // populating predicates inputs with predicate data - transactionRequest = predicate1.populateTransactionPredicateData(transactionRequest); + transactionRequest = + predicateAssertNumber.populateTransactionPredicateData(transactionRequest); transactionRequest = await provider.estimatePredicates(transactionRequest); const { gasLimit, maxFee } = await provider.estimateTxGasAndFee({ transactionRequest }); @@ -308,43 +400,78 @@ describe('Predicate', () => { }); it('should properly populate predicate data and remove placeholder witness [CASE 6]', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000_000, + count: 4, + }, + }); + const { + provider, + wallets: [fundingWallet, wallet1, wallet2, wallet3], + } = launched; + + const quantity: CoinQuantityLike[] = [[500, provider.getBaseAssetId()]]; + let transactionRequest = new ScriptTransactionRequest({ gasLimit: 2000, maxFee: bn(0) }); const resources1 = await wallet1.getResourcesToSpend(quantity); const resources2 = await wallet2.getResourcesToSpend(quantity); const resources3 = await wallet3.getResourcesToSpend(quantity); - const predicate1WrongResources = await provider.getResourcesToSpend( - predicate1.address, + const predicateAssertNumber = new Predicate<[number]>({ + bytecode: PredicateAssertNumberAbi__factory.bin, + abi: PredicateAssertNumberAbi__factory.abi, + provider, + inputData: [11], + }); + + await fundPredicate(fundingWallet, predicateAssertNumber, 500_000, UTXOS_AMOUNT); + + const predicateAssertNumberWrongResources = await provider.getResourcesToSpend( + predicateAssertNumber.address, quantity ); - const predicate1Resources = await predicate1.getResourcesToSpend( + const predicateAssertNumberResources = await predicateAssertNumber.getResourcesToSpend( quantity, - cacheResources(predicate1WrongResources) + cacheResources(predicateAssertNumberWrongResources) ); - const predicate2WrongResources = await provider.getResourcesToSpend( - predicate2.address, + const predicateAssertValue = new Predicate<[boolean]>({ + bytecode: PredicateAssertValueAbi__factory.bin, + abi: PredicateAssertValueAbi__factory.abi, + provider, + inputData: [true], + }); + + await fundPredicate(fundingWallet, predicateAssertValue, 500_000, UTXOS_AMOUNT); + + const predicateAssertValueWrongResources = await provider.getResourcesToSpend( + predicateAssertValue.address, quantity ); - transactionRequest.addCoinOutput(receiver.address, 100, baseAssetId); + const receiver = Wallet.generate({ provider }); + + transactionRequest.addCoinOutput(receiver.address, 100, provider.getBaseAssetId()); transactionRequest.addResources([ ...resources1, // witnessIndex 0 ...resources2, // witnessIndex 1 - ...predicate1Resources, // witnessIndex 0 and no placeholder witness - ...predicate2WrongResources, // witnessIndex 2 and will add a placeholder witness - ...predicate1WrongResources, // witnessIndex 0 because resources from same owner were already added + ...predicateAssertNumberResources, // witnessIndex 0 and no placeholder witness + ...predicateAssertValueWrongResources, // witnessIndex 2 and will add a placeholder witness + ...predicateAssertNumberWrongResources, // witnessIndex 0 because resources from same owner were already added ...resources3, // witnessIndex 3 ]); - // The request carries 4 placeholder witnesses, one was added for the predicate2 wrong resources + // The request carries 4 placeholder witnesses, one was added for the predicateAssertValue wrong resources expect(transactionRequest.witnesses.length).toBe(4); // populating predicates inputs with predicate data - transactionRequest = predicate1.populateTransactionPredicateData(transactionRequest); - transactionRequest = predicate2.populateTransactionPredicateData(transactionRequest); + transactionRequest = + predicateAssertNumber.populateTransactionPredicateData(transactionRequest); + transactionRequest = + predicateAssertValue.populateTransactionPredicateData(transactionRequest); transactionRequest = await provider.estimatePredicates(transactionRequest); 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 e90d29ff89..a1dc5eb0f3 100644 --- a/packages/fuel-gauge/src/predicate/predicate-with-contract.test.ts +++ b/packages/fuel-gauge/src/predicate/predicate-with-contract.test.ts @@ -16,6 +16,7 @@ import { fundPredicate } from './utils/predicate'; /** * @group node + * @group browser */ describe('Predicate', () => { describe('With Contract', () => { 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 659072ff56..17110a39bd 100644 --- a/packages/fuel-gauge/src/predicate/predicate-with-script.test.ts +++ b/packages/fuel-gauge/src/predicate/predicate-with-script.test.ts @@ -1,39 +1,38 @@ -import type { BigNumberish, WalletUnlocked } from 'fuels'; -import { toNumber, Script, Provider, Predicate, FUEL_NETWORK_URL } from 'fuels'; -import { generateTestWallet, seedTestWallet } from 'fuels/test-utils'; - -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../../test/fixtures'; +import type { BigNumberish } from 'fuels'; +import { toNumber, Script, Predicate, Wallet } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; + +import { + PredicateMainArgsStructAbi__factory, + ScriptMainArgsAbi__factory, +} from '../../test/typegen'; import type { Validation } from '../types/predicate'; +import { fundPredicate } from './utils/predicate'; + /** * @group node + * @group browser */ describe('Predicate', () => { - const { binHexlified: scriptBytes, abiContents: scriptAbi } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.SCRIPT_MAIN_ARGS - ); - - const { binHexlified: predicateBytesStruct, abiContents: predicateAbiMainArgsStruct } = - getFuelGaugeForcProject(FuelGaugeProjectsEnum.PREDICATE_MAIN_ARGS_STRUCT); - describe('With script', () => { - let wallet: WalletUnlocked; - let receiver: WalletUnlocked; - let provider: Provider; + it('calls a predicate and uses proceeds for a script call', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000_000_000, + }, + }); + const { + provider, + wallets: [wallet], + } = launched; - let baseAssetId: string; - beforeAll(async () => { - provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - wallet = await generateTestWallet(provider, [[10_000_000, baseAssetId]]); - receiver = await generateTestWallet(provider); - }); + const receiver = Wallet.generate({ provider }); - it('calls a predicate and uses proceeds for a script call', async () => { const initialReceiverBalance = toNumber(await receiver.getBalance()); const scriptInstance = new Script( - scriptBytes, - scriptAbi, + ScriptMainArgsAbi__factory.bin, + ScriptMainArgsAbi__factory.abi, wallet ); @@ -49,9 +48,9 @@ describe('Predicate', () => { const amountToPredicate = 900_000; const amountToReceiver = 100_000; const predicate = new Predicate<[Validation]>({ - bytecode: predicateBytesStruct, + bytecode: PredicateMainArgsStructAbi__factory.bin, provider, - abi: predicateAbiMainArgsStruct, + abi: PredicateMainArgsStructAbi__factory.abi, inputData: [ { has_account: true, @@ -60,12 +59,17 @@ describe('Predicate', () => { ], }); - await seedTestWallet(predicate, [[amountToPredicate, baseAssetId]], 3); + await fundPredicate(wallet, predicate, amountToPredicate); // executing predicate to transfer resources to receiver - const tx = await predicate.transfer(receiver.address, amountToReceiver, baseAssetId, { - gasLimit: 1000, - }); + const tx = await predicate.transfer( + receiver.address, + amountToReceiver, + provider.getBaseAssetId(), + { + gasLimit: 1000, + } + ); const { isStatusSuccess } = await tx.waitForResult(); expect(isStatusSuccess).toBeTruthy(); diff --git a/packages/fuel-gauge/src/predicate/utils/predicate/assertBalances.ts b/packages/fuel-gauge/src/predicate/utils/predicate/assertBalances.ts index dade153768..d2cbf5755c 100644 --- a/packages/fuel-gauge/src/predicate/utils/predicate/assertBalances.ts +++ b/packages/fuel-gauge/src/predicate/utils/predicate/assertBalances.ts @@ -1,8 +1,8 @@ import { bn, toHex } from 'fuels'; -import type { BN, BigNumberish, WalletLocked } from 'fuels'; +import type { BN, BigNumberish, WalletUnlocked } from 'fuels'; export const assertBalances = async ( - receiver: WalletLocked, + receiver: WalletUnlocked, initialReceiverBalance: BN, amountToReceiver: BigNumberish ): Promise => { diff --git a/packages/fuel-gauge/src/predicate/utils/predicate/fundPredicate.ts b/packages/fuel-gauge/src/predicate/utils/predicate/fundPredicate.ts index 9ebdb50a5c..d23d89e522 100644 --- a/packages/fuel-gauge/src/predicate/utils/predicate/fundPredicate.ts +++ b/packages/fuel-gauge/src/predicate/utils/predicate/fundPredicate.ts @@ -1,15 +1,23 @@ -import { ScriptTransactionRequest } from 'fuels'; -import type { InputValue, BN, BigNumberish, WalletUnlocked, Predicate } from 'fuels'; +import type { InputValue, BigNumberish, WalletUnlocked, Predicate } from 'fuels'; +import { ScriptTransactionRequest, BN } from 'fuels'; export const fundPredicate = async ( wallet: WalletUnlocked, predicate: Predicate, - amountToPredicate: BigNumberish + amountToPredicate: BigNumberish, + utxosAmount: number = 1 ): Promise => { const baseAssetId = wallet.provider.getBaseAssetId(); const request = new ScriptTransactionRequest(); - request.addCoinOutput(predicate.address, amountToPredicate, baseAssetId); + for (let i = 0; i < utxosAmount; i++) { + request.addCoinOutput( + predicate.address, + new BN(amountToPredicate).div(utxosAmount), + baseAssetId + ); + } + const txCost = await wallet.provider.getTransactionCost(request); request.gasLimit = txCost.gasUsed; request.maxFee = txCost.maxFee; diff --git a/packages/fuel-gauge/src/predicate/utils/predicate/index.ts b/packages/fuel-gauge/src/predicate/utils/predicate/index.ts index f0e0ebd8a7..c538f8abb1 100644 --- a/packages/fuel-gauge/src/predicate/utils/predicate/index.ts +++ b/packages/fuel-gauge/src/predicate/utils/predicate/index.ts @@ -1,5 +1,3 @@ export * from './assertBalance'; export * from './assertBalances'; export * from './fundPredicate'; -export * from './setupContract'; -export * from './setupWallets'; diff --git a/packages/fuel-gauge/src/predicate/utils/predicate/setupContract.ts b/packages/fuel-gauge/src/predicate/utils/predicate/setupContract.ts deleted file mode 100644 index 4e2e43cec2..0000000000 --- a/packages/fuel-gauge/src/predicate/utils/predicate/setupContract.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { ContractFactory, FUEL_NETWORK_URL, Provider } from 'fuels'; -import type { Interface, JsonAbi, Contract, WalletUnlocked, BytesLike } from 'fuels'; -import { generateTestWallet, ASSET_A } from 'fuels/test-utils'; - -let walletInstance: WalletUnlocked; -let contractInstance: Contract; - -export type SetupConfig = { - contractBytecode: BytesLike; - abi: JsonAbi | Interface; - cache?: boolean; -}; - -const deployContract = async ( - factory: ContractFactory, - provider: Provider, - useCache: boolean = true -) => { - if (contractInstance && useCache) { - return contractInstance; - } - const { waitForResult } = await factory.deployContract(); - ({ contract: contractInstance } = await waitForResult()); - return contractInstance; -}; - -const createWallet = async () => { - if (walletInstance) { - return walletInstance; - } - const provider = await Provider.create(FUEL_NETWORK_URL, { cacheUtxo: 10 }); - const baseAssetId = provider.getBaseAssetId(); - walletInstance = await generateTestWallet(provider, [ - [5_000_000, baseAssetId], - [5_000_000, ASSET_A], - ]); - return walletInstance; -}; - -export const setup = async ({ contractBytecode, abi, cache }: SetupConfig) => { - // Create wallet - const wallet = await createWallet(); - const factory = new ContractFactory(contractBytecode, abi, wallet); - const contract = await deployContract(factory, wallet.provider, cache); - return contract; -}; - -export const setupContractWithConfig = - (defaultConfig: SetupConfig) => async (config?: Partial) => - setup({ - contractBytecode: defaultConfig.contractBytecode, - abi: defaultConfig.abi, - ...config, - }); diff --git a/packages/fuel-gauge/src/predicate/utils/predicate/setupWallets.ts b/packages/fuel-gauge/src/predicate/utils/predicate/setupWallets.ts deleted file mode 100644 index 2222df9502..0000000000 --- a/packages/fuel-gauge/src/predicate/utils/predicate/setupWallets.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Wallet } from '@fuel-ts/account'; -import { Address, FUEL_NETWORK_URL, Provider } from 'fuels'; -import { generateTestWallet } from 'fuels/test-utils'; - -export const setupWallets = async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - const baseAssetId = provider.getBaseAssetId(); - const wallet = await generateTestWallet(provider, [[100_000_000_000, baseAssetId]]); - const receiver = Wallet.fromAddress(Address.fromRandom(), provider); - return [wallet, receiver] as const; -}; diff --git a/packages/fuel-gauge/src/raw-slice.test.ts b/packages/fuel-gauge/src/raw-slice.test.ts index 038e25a42a..c284bfca39 100644 --- a/packages/fuel-gauge/src/raw-slice.test.ts +++ b/packages/fuel-gauge/src/raw-slice.test.ts @@ -1,10 +1,13 @@ -import { bn, Predicate, Wallet, Address, Provider, FUEL_NETWORK_URL } from 'fuels'; -import type { BN, Contract } from 'fuels'; -import { generateTestWallet } from 'fuels/test-utils'; +import { bn, Predicate, Wallet, Address } from 'fuels'; +import type { BN } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; +import { ScriptRawSliceAbi__factory } from '../test/typegen'; +import { RawSliceAbi__factory } from '../test/typegen/contracts'; +import RawSliceAbiHex from '../test/typegen/contracts/RawSliceAbi.hex'; +import { PredicateRawSliceAbi__factory } from '../test/typegen/predicates'; -import { getScript, getSetupContract } from './utils'; +import { launchTestContract } from './utils'; type SomeEnum = { First?: boolean; @@ -16,29 +19,20 @@ type Wrapper = { inner_enum: SomeEnum; }; -const setup = async (balance = 500_000) => { - const provider = await Provider.create(FUEL_NETWORK_URL); - const baseAssetId = provider.getBaseAssetId(); - - // Create wallet - const wallet = await generateTestWallet(provider, [[balance, baseAssetId]]); - - return wallet; -}; - -const setupContract = getSetupContract('raw-slice'); -let contractInstance: Contract; -let baseAssetId: string; -beforeAll(async () => { - contractInstance = await setupContract(); - baseAssetId = contractInstance.provider.getBaseAssetId(); -}); - +async function setupRawSliceContract() { + return launchTestContract({ + deployer: RawSliceAbi__factory, + bytecode: RawSliceAbiHex, + }); +} /** * @group node + * @group browser */ describe('Raw Slice Tests', () => { it('should test raw slice output', async () => { + using contractInstance = await setupRawSliceContract(); + const INPUT = 10; const { waitForResult } = await contractInstance.functions.return_raw_slice(INPUT).call(); @@ -48,6 +42,8 @@ describe('Raw Slice Tests', () => { }); it('should test raw slice input', async () => { + using contractInstance = await setupRawSliceContract(); + const INPUT = [40, 41, 42]; const { waitForResult } = await contractInstance.functions @@ -60,6 +56,8 @@ describe('Raw Slice Tests', () => { }); it('should test raw slice input [nested]', async () => { + using contractInstance = await setupRawSliceContract(); + const slice = [40, 41, 42]; const INPUT = { inner: [slice, slice], @@ -76,15 +74,18 @@ describe('Raw Slice Tests', () => { }); it('should test raw slice input [predicate-raw-slice]', async () => { - const wallet = await setup(); - const receiver = Wallet.fromAddress(Address.fromRandom(), wallet.provider); + using launched = await launchTestNode(); + + const { + provider, + wallets: [wallet], + } = launched; + + const receiver = Wallet.fromAddress(Address.fromRandom(), provider); const amountToPredicate = 300_000; const amountToReceiver = 50; type MainArgs = [Wrapper]; - const { binHexlified: predicateRawSlice, abiContents: predicateRawSliceAbi } = - getFuelGaugeForcProject(FuelGaugeProjectsEnum.PREDICATE_RAW_SLICE); - const bytes = [40, 41, 42]; const INPUT: Wrapper = { inner: [bytes, bytes], @@ -92,23 +93,33 @@ describe('Raw Slice Tests', () => { }; const predicate = new Predicate({ - bytecode: predicateRawSlice, - abi: predicateRawSliceAbi, + bytecode: PredicateRawSliceAbi__factory.bin, + abi: PredicateRawSliceAbi__factory.abi, provider: wallet.provider, inputData: [INPUT], }); // setup predicate - const setupTx = await wallet.transfer(predicate.address, amountToPredicate, baseAssetId, { - gasLimit: 10_000, - }); + const setupTx = await wallet.transfer( + predicate.address, + amountToPredicate, + provider.getBaseAssetId(), + { + gasLimit: 10_000, + } + ); await setupTx.waitForResult(); const initialReceiverBalance = await receiver.getBalance(); - const tx = await predicate.transfer(receiver.address, amountToReceiver, baseAssetId, { - gasLimit: 10_000, - }); + const tx = await predicate.transfer( + receiver.address, + amountToReceiver, + provider.getBaseAssetId(), + { + gasLimit: 10_000, + } + ); const { isStatusSuccess } = await tx.waitForResult(); // Check the balance of the receiver @@ -120,9 +131,13 @@ describe('Raw Slice Tests', () => { }); it('should test raw slice input [script-raw-slice]', async () => { - const wallet = await setup(); - type MainArgs = [number, Wrapper]; - const scriptInstance = getScript('script-raw-slice', wallet); + using launched = await launchTestNode(); + + const { + wallets: [wallet], + } = launched; + + const scriptInstance = ScriptRawSliceAbi__factory.createInstance(wallet); const bytes = [40, 41, 42]; const INPUT: Wrapper = { diff --git a/packages/fuel-gauge/src/reentrant-contract-calls.test.ts b/packages/fuel-gauge/src/reentrant-contract-calls.test.ts index d4118047b2..912b9d770d 100644 --- a/packages/fuel-gauge/src/reentrant-contract-calls.test.ts +++ b/packages/fuel-gauge/src/reentrant-contract-calls.test.ts @@ -1,37 +1,38 @@ -import type { Contract, WalletUnlocked } from 'fuels'; -import { ContractFactory, FUEL_NETWORK_URL, Provider, ReceiptType, bn } from 'fuels'; -import { generateTestWallet } from 'fuels/test-utils'; - -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; - -const bar = getFuelGaugeForcProject(FuelGaugeProjectsEnum.REENTRANT_BAR); -const foo = getFuelGaugeForcProject(FuelGaugeProjectsEnum.REENTRANT_FOO); -const storageTest = getFuelGaugeForcProject(FuelGaugeProjectsEnum.STORAGE_TEST_CONTRACT); +import { ContractFactory, ReceiptType, bn } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; + +import { + ReentrantBarAbi__factory, + ReentrantFooAbi__factory, + StorageTestContractAbi__factory, +} from '../test/typegen/contracts'; +import ReentrantBarAbiHex from '../test/typegen/contracts/ReentrantBarAbi.hex'; +import ReentrantFooAbiHex from '../test/typegen/contracts/ReentrantFooAbi.hex'; +import StorageTestContractAbiHex from '../test/typegen/contracts/StorageTestContractAbi.hex'; /** * @group node + * @group browser */ describe('Reentrant Contract Calls', () => { - let barContract: Contract; - let fooContract: Contract; - let wallet: WalletUnlocked; - let baseAssetId: string; - - beforeAll(async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - wallet = await generateTestWallet(provider, [[500_000, baseAssetId]]); - - const factoryBar = new ContractFactory(bar.binHexlified, bar.abiContents, wallet); - let { waitForResult } = await factoryBar.deployContract(); - ({ contract: barContract } = await waitForResult()); - - const factoryFoo = new ContractFactory(foo.binHexlified, foo.abiContents, wallet); - ({ waitForResult } = await factoryFoo.deployContract()); - ({ contract: fooContract } = await waitForResult()); - }); - it('should ensure the SDK returns the proper value for a reentrant call', async () => { + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: ReentrantFooAbi__factory, + bytecode: ReentrantFooAbiHex, + }, + { + deployer: ReentrantBarAbi__factory, + bytecode: ReentrantBarAbiHex, + }, + ], + }); + + const { + contracts: [fooContract, barContract], + } = launched; + const { waitForResult } = await fooContract.functions .foo({ bits: fooContract.id.toB256() }, { bits: barContract.id.toB256() }) .addContracts([barContract]) @@ -68,11 +69,29 @@ describe('Reentrant Contract Calls', () => { }); it('should ensure the SDK returns the proper value for a reentrant call on multi-call', async () => { + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: ReentrantFooAbi__factory, + bytecode: ReentrantFooAbiHex, + }, + { + deployer: ReentrantBarAbi__factory, + bytecode: ReentrantBarAbiHex, + }, + ], + }); + + const { + wallets: [wallet], + contracts: [fooContract, barContract], + } = launched; + const deploy = await new ContractFactory( - storageTest.binHexlified, - storageTest.abiContents, + StorageTestContractAbiHex, + StorageTestContractAbi__factory.abi, wallet - ).deployContract({ storageSlots: storageTest.storageSlots }); + ).deployContract({ storageSlots: StorageTestContractAbi__factory.storageSlots }); const { contract: storageContract } = await deploy.waitForResult(); diff --git a/packages/fuel-gauge/src/revert-error.test.ts b/packages/fuel-gauge/src/revert-error.test.ts index 204175b169..b9abc9352f 100644 --- a/packages/fuel-gauge/src/revert-error.test.ts +++ b/packages/fuel-gauge/src/revert-error.test.ts @@ -1,35 +1,30 @@ import { ErrorCode, FuelError } from '@fuel-ts/errors'; -import type { Contract, WalletUnlocked, TransactionResultReceipt } from 'fuels'; -import { bn, ContractFactory, Provider, FUEL_NETWORK_URL, getRandomB256 } from 'fuels'; -import { expectToThrowFuelError, generateTestWallet } from 'fuels/test-utils'; +import { expectToThrowFuelError } from '@fuel-ts/errors/test-utils'; +import type { TransactionResultReceipt } from 'fuels'; +import { bn, getRandomB256, ContractFactory } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; +import { RevertErrorAbi__factory, TokenContractAbi__factory } from '../test/typegen/contracts'; +import RevertErrorAbiHex from '../test/typegen/contracts/RevertErrorAbi.hex'; +import TokenContractAbiHex from '../test/typegen/contracts/TokenContractAbi.hex'; -let contractInstance: Contract; -let wallet: WalletUnlocked; +import { launchTestContract } from './utils'; + +async function launchContract() { + return launchTestContract({ + deployer: RevertErrorAbi__factory, + bytecode: RevertErrorAbiHex, + }); +} /** * @group node + * @group browser */ describe('Revert Error Testing', () => { - let provider: Provider; - let baseAssetId: string; - - beforeAll(async () => { - provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - wallet = await generateTestWallet(provider, [[1_000_000, baseAssetId]]); - - const { binHexlified: bytecode, abiContents: FactoryAbi } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.REVERT_ERROR - ); - - const factory = new ContractFactory(bytecode, FactoryAbi, wallet); - const { waitForResult } = await factory.deployContract(); - ({ contract: contractInstance } = await waitForResult()); - }); - it('can pass require checks [valid]', async () => { + using contractInstance = await launchContract(); + const INPUT_PRICE = bn(10); const INPUT_TOKEN_ID = bn(100); @@ -50,6 +45,8 @@ describe('Revert Error Testing', () => { }); it('should throw for "require" revert TX [PriceCantBeZero]', async () => { + using contractInstance = await launchContract(); + const INPUT_PRICE = bn(0); const INPUT_TOKEN_ID = bn(100); @@ -70,6 +67,8 @@ describe('Revert Error Testing', () => { }); it('should throw for "require" revert TX [InvalidTokenId]', async () => { + using contractInstance = await launchContract(); + const INPUT_PRICE = bn(10); const INPUT_TOKEN_ID = bn(55); @@ -95,6 +94,8 @@ describe('Revert Error Testing', () => { }); it('should throw for revert TX with reason "TransferZeroCoins"', async () => { + using contractInstance = await launchContract(); + await expectToThrowFuelError( () => contractInstance.functions.failed_transfer_revert().call(), new FuelError( @@ -112,6 +113,8 @@ describe('Revert Error Testing', () => { }); it('should throw for "assert" revert TX', async () => { + using contractInstance = await launchContract(); + const INPUT_PRICE = bn(100); const INPUT_TOKEN_ID = bn(100); @@ -132,6 +135,8 @@ describe('Revert Error Testing', () => { }); it('should throw for revert TX with reason "NotEnoughBalance"', async () => { + using contractInstance = await launchContract(); + await expectToThrowFuelError( () => contractInstance.functions.failed_transfer().call(), new FuelError( @@ -149,6 +154,8 @@ describe('Revert Error Testing', () => { }); it('should throw for "assert_eq" revert TX', async () => { + using contractInstance = await launchContract(); + await expectToThrowFuelError( () => contractInstance.functions.assert_value_eq_10(9).call(), new FuelError( @@ -166,6 +173,8 @@ describe('Revert Error Testing', () => { }); it('should throw for "assert_ne" revert TX', async () => { + using contractInstance = await launchContract(); + await expectToThrowFuelError( () => contractInstance.functions.assert_value_ne_5(5).call(), new FuelError( @@ -183,11 +192,14 @@ describe('Revert Error Testing', () => { }); it('should throw for a missing OutputChange', async () => { - const { binHexlified: tokenBytecode, abiContents: tokenAbi } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.TOKEN_CONTRACT - ); + using launched = await launchTestNode(); + + const { + wallets: [wallet], + provider, + } = launched; - const factory = new ContractFactory(tokenBytecode, tokenAbi, wallet); + const factory = new ContractFactory(TokenContractAbiHex, TokenContractAbi__factory.abi, wallet); const { waitForResult } = await factory.deployContract(); const { contract: tokenContract } = await waitForResult(); @@ -232,6 +244,8 @@ describe('Revert Error Testing', () => { }); it('should throw UNKNOWN Error for revert', async () => { + using contractInstance = await launchContract(); + await expectToThrowFuelError( () => contractInstance.functions.revert_with_0().call(), new FuelError(ErrorCode.UNKNOWN, `The transaction reverted with an unknown reason: 0`, { @@ -245,6 +259,8 @@ describe('Revert Error Testing', () => { }); it('should ensure errors from getTransactionCost dry-run are properly thrown', async () => { + using contractInstance = await launchContract(); + await expectToThrowFuelError( () => contractInstance.functions.assert_value_ne_5(5).getTransactionCost(), new FuelError( diff --git a/packages/fuel-gauge/src/script-main-args.test.ts b/packages/fuel-gauge/src/script-main-args.test.ts index db1ba54810..962b83d235 100644 --- a/packages/fuel-gauge/src/script-main-args.test.ts +++ b/packages/fuel-gauge/src/script-main-args.test.ts @@ -1,20 +1,12 @@ import type { BigNumberish } from 'fuels'; -import { Provider, bn, Script, FUEL_NETWORK_URL } from 'fuels'; -import { generateTestWallet } from 'fuels/test-utils'; +import { bn, Script } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; - -import { getScript } from './utils'; - -const setup = async (balance = 500_000) => { - const provider = await Provider.create(FUEL_NETWORK_URL); - const baseAssetId = provider.getBaseAssetId(); - - // Create wallet - const wallet = await generateTestWallet(provider, [[balance, baseAssetId]]); - - return wallet; -}; +import { + ScriptMainArgsAbi__factory, + ScriptMainReturnStructAbi__factory, + ScriptMainTwoArgsAbi__factory, +} from '../test/typegen'; type Baz = { x: number; @@ -22,17 +14,22 @@ type Baz = { /** * @group node + * @group browser */ describe('Script Coverage', () => { - const { binHexlified: scriptBin, abiContents: scriptAbi } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.SCRIPT_MAIN_ARGS - ); - it('can call script and use main arguments', async () => { - const wallet = await setup(); + using launched = await launchTestNode(); + const { + wallets: [wallet], + } = launched; + // #region script-call-factory const foo = 33; - const scriptInstance = new Script(scriptBin, scriptAbi, wallet); + const scriptInstance = new Script( + ScriptMainArgsAbi__factory.bin, + ScriptMainArgsAbi__factory.abi, + wallet + ); const { waitForResult } = await scriptInstance.functions.main(foo).call(); @@ -44,8 +41,12 @@ describe('Script Coverage', () => { }); it('can call script and use main arguments [two args, read logs]', async () => { - const wallet = await setup(); - const scriptInstance = getScript<[BigNumberish, Baz], Baz>('script-main-two-args', wallet); + using launched = await launchTestNode(); + const { + wallets: [wallet], + } = launched; + + const scriptInstance = ScriptMainTwoArgsAbi__factory.createInstance(wallet); const foo = 33; const bar: Baz = { x: 12, @@ -59,8 +60,12 @@ describe('Script Coverage', () => { }); it('can call script and use main arguments [two args, struct return]', async () => { - const wallet = await setup(); - const scriptInstance = getScript<[BigNumberish, Baz], Baz>('script-main-return-struct', wallet); + using launched = await launchTestNode(); + const { + wallets: [wallet], + } = launched; + + const scriptInstance = ScriptMainReturnStructAbi__factory.createInstance(wallet); const foo = 1; const bar: Baz = { x: 2, @@ -75,8 +80,16 @@ describe('Script Coverage', () => { }); it('can call script and use main arguments [tx params]', async () => { - const wallet = await setup(); - const scriptInstance = new Script(scriptBin, scriptAbi, wallet); + using launched = await launchTestNode(); + const { + wallets: [wallet], + } = launched; + + const scriptInstance = new Script( + ScriptMainArgsAbi__factory.bin, + ScriptMainArgsAbi__factory.abi, + wallet + ); const foo = 42; await expect( diff --git a/packages/fuel-gauge/src/script-with-configurable.test.ts b/packages/fuel-gauge/src/script-with-configurable.test.ts index a92985d8d7..26580181a8 100644 --- a/packages/fuel-gauge/src/script-with-configurable.test.ts +++ b/packages/fuel-gauge/src/script-with-configurable.test.ts @@ -1,38 +1,33 @@ -import type { CoinQuantityLike, WalletUnlocked } from 'fuels'; -import { Script, Provider, FUEL_NETWORK_URL } from 'fuels'; -import { generateTestWallet } from 'fuels/test-utils'; +import { Script } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; +import { ScriptWithConfigurableAbi__factory } from '../test/typegen'; const defaultValues = { FEE: 5, }; -let wallet: WalletUnlocked; - /** * @group node + * @group browser */ describe('Script With Configurable', () => { - const { binHexlified: bytecode, abiContents: abi } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.SCRIPT_WITH_CONFIGURABLE - ); - - beforeAll(async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - const baseAssetId = provider.getBaseAssetId(); - const quantities: CoinQuantityLike[] = [ - { - amount: 1_000_000, - assetId: baseAssetId, + it('should returns true when input value matches default configurable constant', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000, }, - ]; + }); - wallet = await generateTestWallet(provider, quantities); - }); + const { + wallets: [wallet], + } = launched; - it('should returns true when input value matches default configurable constant', async () => { - const script = new Script(bytecode, abi, wallet); + const script = new Script( + ScriptWithConfigurableAbi__factory.bin, + ScriptWithConfigurableAbi__factory.abi, + wallet + ); script.setConfigurableConstants(defaultValues); @@ -43,11 +38,25 @@ describe('Script With Configurable', () => { }); it('should returns false when input value differs from default configurable constant', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000, + }, + }); + + const { + wallets: [wallet], + } = launched; + const configurableConstants = { FEE: 71 }; expect(configurableConstants.FEE).not.toEqual(defaultValues.FEE); - const script = new Script(bytecode, abi, wallet); + const script = new Script( + ScriptWithConfigurableAbi__factory.bin, + ScriptWithConfigurableAbi__factory.abi, + wallet + ); script.setConfigurableConstants(defaultValues); @@ -58,9 +67,23 @@ describe('Script With Configurable', () => { }); it('should returns true when input value matches manually set configurable constant', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000, + }, + }); + + const { + wallets: [wallet], + } = launched; + const configurableConstants = { FEE: 35 }; - const script = new Script(bytecode, abi, wallet); + const script = new Script( + ScriptWithConfigurableAbi__factory.bin, + ScriptWithConfigurableAbi__factory.abi, + wallet + ); script.setConfigurableConstants(configurableConstants); @@ -71,13 +94,27 @@ describe('Script With Configurable', () => { }); it('should returns false when input value differs from manually set configurable constant', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000, + }, + }); + + const { + wallets: [wallet], + } = launched; + const configurableConstants = { FEE: 10 }; const input = { FEE: 15 }; expect(configurableConstants.FEE).not.toEqual(input.FEE); - const script = new Script(bytecode, abi, wallet); + const script = new Script( + ScriptWithConfigurableAbi__factory.bin, + ScriptWithConfigurableAbi__factory.abi, + wallet + ); script.setConfigurableConstants(configurableConstants); diff --git a/packages/fuel-gauge/src/script-with-vectors.test.ts b/packages/fuel-gauge/src/script-with-vectors.test.ts index cb3eabddb3..d5e1659bff 100644 --- a/packages/fuel-gauge/src/script-with-vectors.test.ts +++ b/packages/fuel-gauge/src/script-with-vectors.test.ts @@ -1,27 +1,30 @@ -import type { BigNumberish } from 'fuels'; -import { FUEL_NETWORK_URL, Provider } from 'fuels'; -import { generateTestWallet } from 'fuels/test-utils'; +import { launchTestNode } from 'fuels/test-utils'; -import { getScript } from './utils'; - -const setup = async (balance = 500_000) => { - const provider = await Provider.create(FUEL_NETWORK_URL); - const baseAssetId = provider.getBaseAssetId(); - - // Create wallet - const wallet = await generateTestWallet(provider, [[balance, baseAssetId]]); - - return wallet; -}; +import { + ScriptWithArrayAbi__factory, + ScriptWithVectorAbi__factory, + ScriptWithVectorAdvancedAbi__factory, + ScriptWithVectorMixedAbi__factory, +} from '../test/typegen'; /** * @group node + * @group browser */ describe('Script With Vectors', () => { it('can call script and use main argument [array]', async () => { - const wallet = await setup(); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000, + }, + }); + + const { + wallets: [wallet], + } = launched; + const someArray = [1, 100]; - const scriptInstance = getScript<[BigNumberish[]], void>('script-with-array', wallet); + const scriptInstance = ScriptWithArrayAbi__factory.createInstance(wallet); const { waitForResult } = await scriptInstance.functions.main(someArray).call(); const { logs } = await waitForResult(); @@ -30,9 +33,18 @@ describe('Script With Vectors', () => { }); it('can call script and use main argument [vec]', async () => { - const wallet = await setup(); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000, + }, + }); + + const { + wallets: [wallet], + } = launched; + const someVec = [7, 2, 1, 5]; - const scriptInstance = getScript<[BigNumberish[]], void>('script-with-vector', wallet); + const scriptInstance = ScriptWithVectorAbi__factory.createInstance(wallet); const scriptInvocationScope = scriptInstance.functions.main(someVec); @@ -55,7 +67,15 @@ describe('Script With Vectors', () => { }); it('can call script and use main argument [struct in vec in struct in vec in struct in vec]', async () => { - const wallet = await setup(); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000, + }, + }); + + const { + wallets: [wallet], + } = launched; const importantDates = [ { @@ -87,8 +107,7 @@ describe('Script With Vectors', () => { }, ]; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const scriptInstance = getScript<[any], void>('script-with-vector-mixed', wallet); + const scriptInstance = ScriptWithVectorMixedAbi__factory.createInstance(wallet); const { waitForResult } = await scriptInstance.functions.main(importantDates).call(); const { value } = await waitForResult(); @@ -96,7 +115,15 @@ describe('Script With Vectors', () => { }); it('can call script and use main argument [struct in vec in struct in vec in struct in vec]', async () => { - const wallet = await setup(); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000, + }, + }); + + const { + wallets: [wallet], + } = launched; const scores = [24, 56, 43]; @@ -155,8 +182,7 @@ describe('Script With Vectors', () => { }, ]; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const scriptInstance = getScript<[any[]], void>('script-with-vector-advanced', wallet); + const scriptInstance = ScriptWithVectorAdvancedAbi__factory.createInstance(wallet); const { waitForResult } = await scriptInstance.functions.main(vectorOfStructs).call(); const { value } = await waitForResult(); diff --git a/packages/fuel-gauge/src/std-lib-string.test.ts b/packages/fuel-gauge/src/std-lib-string.test.ts index 145782e022..e3e54c2768 100644 --- a/packages/fuel-gauge/src/std-lib-string.test.ts +++ b/packages/fuel-gauge/src/std-lib-string.test.ts @@ -1,47 +1,40 @@ -import { bn, Predicate, Wallet, Address, Provider, FUEL_NETWORK_URL } from 'fuels'; -import type { Contract } from 'fuels'; -import { generateTestWallet } from 'fuels/test-utils'; +import { bn, Predicate, Wallet, Address } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; +import { + PredicateStdLibStringAbi__factory, + ScriptStdLibStringAbi__factory, + StdLibStringAbi__factory, +} from '../test/typegen'; +import StdLibStringAbiHex from '../test/typegen/contracts/StdLibStringAbi.hex'; -import { getScript, getSetupContract } from './utils'; - -const setupContract = getSetupContract('std-lib-string'); -let contractInstance: Contract; - -let baseAssetId: string; -beforeAll(async () => { - contractInstance = await setupContract(); - baseAssetId = contractInstance.provider.getBaseAssetId(); -}); - -const setup = async (balance = 500_000) => { - const provider = await Provider.create(FUEL_NETWORK_URL); - - // Create wallet - const wallet = await generateTestWallet(provider, [[balance, baseAssetId]]); - - return wallet; -}; +import { launchTestContract } from './utils'; /** * @group node + * @group browser */ -describe('std-lib-string Tests', () => { - const { binHexlified: predicateStdString, abiContents: predicateStdStringAbi } = - getFuelGaugeForcProject(FuelGaugeProjectsEnum.PREDICATE_STD_LIB_STRING); +async function setupContract() { + return launchTestContract({ + deployer: StdLibStringAbi__factory, + bytecode: StdLibStringAbiHex, + }); +} + +describe('std-lib-string Tests', () => { it('should test std-lib-string return', async () => { + using contractInstance = await setupContract(); 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 () => { + using contractInstance = await setupContract(); const INPUT = 'Hello World'; const { waitForResult } = await contractInstance.functions.accepts_dynamic_string(INPUT).call(); @@ -51,28 +44,49 @@ describe('std-lib-string Tests', () => { }); it('should test String input [predicate-std-lib-string]', async () => { - const wallet = await setup(); - const receiver = Wallet.fromAddress(Address.fromRandom(), wallet.provider); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000, + }, + }); + + const { + provider, + wallets: [wallet], + } = launched; + + const receiver = Wallet.fromAddress(Address.fromRandom(), provider); + const amountToPredicate = 300_000; const amountToReceiver = 50; type MainArgs = [number, number, string]; const predicate = new Predicate({ - bytecode: predicateStdString, - abi: predicateStdStringAbi, - provider: wallet.provider, + bytecode: PredicateStdLibStringAbi__factory.bin, + abi: PredicateStdLibStringAbi__factory.abi, + provider, inputData: [1, 2, 'Hello World'], }); // setup predicate - const setupTx = await wallet.transfer(predicate.address, amountToPredicate, baseAssetId, { - gasLimit: 10_000, - }); + const setupTx = await wallet.transfer( + predicate.address, + amountToPredicate, + provider.getBaseAssetId(), + { + gasLimit: 10_000, + } + ); await setupTx.waitForResult(); const initialReceiverBalance = await receiver.getBalance(); - const tx = await predicate.transfer(receiver.address, amountToReceiver, baseAssetId, { - gasLimit: 10_000, - }); + const tx = await predicate.transfer( + receiver.address, + amountToReceiver, + provider.getBaseAssetId(), + { + gasLimit: 10_000, + } + ); const { isStatusSuccess } = await tx.waitForResult(); // Check the balance of the receiver @@ -85,10 +99,18 @@ describe('std-lib-string Tests', () => { }); it('should test String input [script-std-lib-string]', async () => { - const wallet = await setup(); - type MainArgs = [string]; - const scriptInstance = getScript('script-std-lib-string', wallet); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 1_000_000, + }, + }); + + const { + wallets: [wallet], + } = launched; + const INPUT = 'Hello World'; + const scriptInstance = ScriptStdLibStringAbi__factory.createInstance(wallet); const { waitForResult } = await scriptInstance.functions.main(INPUT).call(); const { value } = await waitForResult(); diff --git a/packages/fuel-gauge/src/storage-test-contract.test.ts b/packages/fuel-gauge/src/storage-test-contract.test.ts index 891058d689..d93920dd1d 100644 --- a/packages/fuel-gauge/src/storage-test-contract.test.ts +++ b/packages/fuel-gauge/src/storage-test-contract.test.ts @@ -1,44 +1,37 @@ -import { toHex, Provider, ContractFactory, FUEL_NETWORK_URL } from 'fuels'; -import { generateTestWallet } from 'fuels/test-utils'; - -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; - -const { - binHexlified: bytecode, - abiContents: abi, - storageSlots, -} = getFuelGaugeForcProject(FuelGaugeProjectsEnum.STORAGE_TEST_CONTRACT); - -const setup = async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - const baseAssetId = provider.getBaseAssetId(); - // Create wallet - const wallet = await generateTestWallet(provider, [[1_000_000, baseAssetId]]); - // Deploy contract - // #region contract-deployment-storage-slots - // #context import storageSlots from '../your-sway-project/out/debug/your-sway-project-storage_slots.json'; - - const factory = new ContractFactory(bytecode, abi, wallet); - const { waitForResult } = await factory.deployContract({ - storageSlots, - }); - const { contract } = await waitForResult(); - // #endregion contract-deployment-storage-slots +import { toHex, ContractFactory } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; - return contract; -}; +import { StorageTestContractAbi__factory } from '../test/typegen'; +import StorageTestContractAbiHex from '../test/typegen/contracts/StorageTestContractAbi.hex'; /** * @group node + * @group browser */ describe('StorageTestContract', () => { - let baseAssetId: string; - beforeAll(async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - }); it('can increment counter', async () => { - const contract = await setup(); + using launched = await launchTestNode(); + + const { + wallets: [wallet], + } = launched; + + const { storageSlots } = StorageTestContractAbi__factory; + + // #region contract-deployment-storage-slots + // #context import storageSlots from '../your-sway-project/out/debug/your-sway-project-storage_slots.json'; + + const factory = new ContractFactory( + StorageTestContractAbiHex, + StorageTestContractAbi__factory.abi, + wallet + ); + const deploy = await factory.deployContract({ + storageSlots, + }); + + const { contract } = await deploy.waitForResult(); + // #endregion contract-deployment-storage-slots // Call contract const call1 = await contract.functions.initialize_counter(1300).call(); @@ -58,9 +51,17 @@ describe('StorageTestContract', () => { }); it('can increment counter - using custom inline storage slots', async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - const wallet = await generateTestWallet(provider, [[500_000, baseAssetId]]); - const factory = new ContractFactory(bytecode, abi, wallet); + using launched = await launchTestNode(); + + const { + wallets: [wallet], + } = launched; + + const factory = new ContractFactory( + StorageTestContractAbiHex, + StorageTestContractAbi__factory.abi, + wallet + ); // #region contract-deployment-storage-slots-inline const { waitForResult } = await factory.deployContract({ storageSlots: [ diff --git a/packages/fuel-gauge/src/str-slice.test.ts b/packages/fuel-gauge/src/str-slice.test.ts index 69bb4a5fa3..35a5464d87 100644 --- a/packages/fuel-gauge/src/str-slice.test.ts +++ b/packages/fuel-gauge/src/str-slice.test.ts @@ -11,6 +11,7 @@ import contractBytes from '../test/typegen/contracts/StrSliceAbi.hex'; /** * @group node + * @group browser */ describe('str slice', () => { it('echoes a str slice [CONTRACT]', async () => { diff --git a/packages/fuel-gauge/src/token-test-contract.test.ts b/packages/fuel-gauge/src/token-test-contract.test.ts index f410bd2a78..2344cf4f46 100644 --- a/packages/fuel-gauge/src/token-test-contract.test.ts +++ b/packages/fuel-gauge/src/token-test-contract.test.ts @@ -1,41 +1,33 @@ import { ErrorCode, FuelError } from '@fuel-ts/errors'; import type { AssetId, BN } from 'fuels'; -import { toHex, Provider, Wallet, ContractFactory, bn, FUEL_NETWORK_URL } from 'fuels'; -import { expectToThrowFuelError, generateTestWallet } from 'fuels/test-utils'; - -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; - -const { binHexlified: bytecode, abiContents: abi } = getFuelGaugeForcProject( - FuelGaugeProjectsEnum.TOKEN_CONTRACT -); - -let provider: Provider; -let baseAssetId: string; - -const setup = async () => { - // Create wallet - const wallet = await generateTestWallet(provider, [[5_000_000, baseAssetId]]); - - // Deploy contract - const factory = new ContractFactory(bytecode, abi, wallet); - const { waitForResult } = await factory.deployContract(); - const { contract } = await waitForResult(); - return contract; -}; - -beforeAll(async () => { - provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); -}); +import { toHex, Wallet, bn } from 'fuels'; +import { expectToThrowFuelError, launchTestNode } from 'fuels/test-utils'; +import { TokenContractAbi__factory } from '../test/typegen'; +import TokenContractAbiHex from '../test/typegen/contracts/TokenContractAbi.hex'; /** * @group node + * @group browser */ + describe('TokenTestContract', () => { it('Can mint and transfer coins', async () => { // New wallet to transfer coins and check balance + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: TokenContractAbi__factory, + bytecode: TokenContractAbiHex, + }, + ], + }); + + const { + provider, + contracts: [token], + } = launched; + const userWallet = Wallet.generate({ provider }); - const token = await setup(); const tokenContractId = { bits: token.id.toB256() }; const addressId = { bits: userWallet.address.toB256() }; @@ -71,16 +63,27 @@ describe('TokenTestContract', () => { }); it('Automatically add variableOuputs', async () => { - const [wallet1, wallet2, wallet3] = Array.from({ length: 3 }, () => - Wallet.generate({ provider }) - ); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: TokenContractAbi__factory, + bytecode: TokenContractAbiHex, + }, + ], + walletsConfig: { + count: 3, + }, + }); + + const { + wallets: [wallet1, wallet2, wallet3], + contracts: [token], + } = launched; const addresses = [wallet1, wallet2, wallet3].map((wallet) => ({ bits: wallet.address.toB256(), })); - const token = await setup(); - const functionCallOne = token.functions.mint_to_addresses(addresses, 10); await functionCallOne.dryRun(); const call1 = await functionCallOne.call(); @@ -135,8 +138,20 @@ describe('TokenTestContract', () => { }); it('Contract getBalance', async () => { - const userWallet = Wallet.generate({ provider }); - const token = await setup(); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: TokenContractAbi__factory, + bytecode: TokenContractAbiHex, + }, + ], + }); + + const { + wallets: [userWallet], + contracts: [token], + } = launched; + const addressId = { bits: userWallet.address.toB256(), }; @@ -153,19 +168,35 @@ describe('TokenTestContract', () => { expect((await getBalance()).toHex()).toEqual(bn(100).toHex()); // transfer 50 coins to user wallet - await token.functions.transfer_to_address(addressId, assetId, 50).call(); + const { waitForResult: waitForResult2 } = await token.functions + .transfer_to_address(addressId, assetId, 50) + .call(); + await waitForResult2(); // the contract should now have only 50 coins expect((await getBalance()).toHex()).toEqual(bn(50).toHex()); }); it('throws when passing entire Address object as address parameter', async () => { - const userWallet = Wallet.generate({ provider }); - const token = await setup(); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: TokenContractAbi__factory, + bytecode: TokenContractAbiHex, + }, + ], + }); + + const { + provider, + wallets: [userWallet], + contracts: [token], + } = launched; + const addressParameter = { bits: userWallet.address, }; - const assetId: AssetId = { bits: baseAssetId }; + const assetId: AssetId = { bits: provider.getBaseAssetId() }; await expectToThrowFuelError( () => token.functions.transfer_to_address(addressParameter, assetId, 50).call(), diff --git a/packages/fuel-gauge/src/transaction-response.test.ts b/packages/fuel-gauge/src/transaction-response.test.ts index df02414420..db0eb834f5 100644 --- a/packages/fuel-gauge/src/transaction-response.test.ts +++ b/packages/fuel-gauge/src/transaction-response.test.ts @@ -1,14 +1,6 @@ import { ErrorCode } from '@fuel-ts/errors'; -import { - FUEL_NETWORK_URL, - Provider, - TransactionResponse, - Wallet, - randomBytes, - WalletUnlocked, - ScriptTransactionRequest, -} from 'fuels'; -import { generateTestWallet, launchNode, expectToThrowFuelError } from 'fuels/test-utils'; +import { TransactionResponse, Wallet, ScriptTransactionRequest } from 'fuels'; +import { expectToThrowFuelError, launchTestNode } from 'fuels/test-utils'; import type { MockInstance } from 'vitest'; async function verifyKeepAliveMessageWasSent(subscriptionStream: ReadableStream) { @@ -81,19 +73,21 @@ function getSubscriptionStreamFromFetch(streamHolder: { stream: ReadableStream { - let provider: Provider; - let adminWallet: WalletUnlocked; - - let baseAssetId: string; - beforeAll(async () => { - provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - adminWallet = await generateTestWallet(provider, [[500_000, baseAssetId]]); - }); - it('should ensure create method waits till a transaction response is given', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 500_000, + }, + }); + + const { + provider, + wallets: [adminWallet], + } = launched; + const destination = Wallet.generate({ provider, }); @@ -101,7 +95,7 @@ describe('TransactionResponse', () => { const { id: transactionId } = await adminWallet.transfer( destination.address, 100, - baseAssetId, + provider.getBaseAssetId(), { gasLimit: 10_000 } ); @@ -113,16 +107,26 @@ describe('TransactionResponse', () => { }); it('should ensure getTransactionSummary fetchs a transaction and assembles transaction summary', async () => { - const { ip, port } = await launchNode({ - args: ['--poa-instant', 'false', '--poa-interval-period', '1s'], + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 500_000, + }, }); - const nodeProvider = await Provider.create(`http://${ip}:${port}/v1/graphql`); + + const { + provider, + wallets: [adminWallet], + } = launched; const destination = Wallet.generate({ - provider: nodeProvider, + provider, }); - const { id: transactionId } = await adminWallet.transfer(destination.address, 100, baseAssetId); + const { id: transactionId } = await adminWallet.transfer( + destination.address, + 100, + provider.getBaseAssetId() + ); const response = await TransactionResponse.create(transactionId, provider); @@ -153,7 +157,7 @@ describe('TransactionResponse', () => { }); it.skip('should ensure waitForResult always waits for the transaction to be processed', async () => { - const { cleanup, ip, port } = await launchNode({ + using launched = await launchTestNode({ /** * This is set to so long in order to test keep-alive message handling as well. * Keep-alive messages are sent every 15s. @@ -164,24 +168,23 @@ describe('TransactionResponse', () => { * all our subscriptions would break. * We need at least one long test to ensure that the keep-alive messages are handled correctly. * */ - args: ['--poa-instant', 'false', '--poa-interval-period', '17sec'], + nodeOptions: { + args: ['--poa-instant', 'false', '--poa-interval-period', '17sec'], + }, }); - const nodeProvider = await Provider.create(`http://${ip}:${port}/v1/graphql`); - const genesisWallet = new WalletUnlocked( - process.env.GENESIS_SECRET || randomBytes(32), - nodeProvider - ); - - const destination = Wallet.generate({ provider: nodeProvider }); + const { + provider, + wallets: [genesisWallet, destination], + } = launched; const { id: transactionId } = await genesisWallet.transfer( destination.address, 100, - baseAssetId, + provider.getBaseAssetId(), { gasLimit: 10_000 } ); - const response = await TransactionResponse.create(transactionId, nodeProvider); + const response = await TransactionResponse.create(transactionId, provider); expect(response.gqlTransaction?.status?.type).toBe('SubmittedStatus'); @@ -197,71 +200,79 @@ describe('TransactionResponse', () => { expect(response.gqlTransaction?.id).toBe(transactionId); await verifyKeepAliveMessageWasSent(subscriptionStreamHolder.stream); + }); - cleanup(); - }, 18500); - - it('should throw error for a SqueezedOut status update [waitForResult]', async () => { - const { cleanup, ip, port } = await launchNode({ + it( + 'should throw error for a SqueezedOut status update [waitForResult]', + async () => { /** * a larger --tx-pool-ttl 1s is necessary to ensure that the transaction doesn't get squeezed out * before the waitForResult (provider.operations.statusChange) call is made * */ - args: ['--poa-instant', 'false', '--poa-interval-period', '2s', '--tx-pool-ttl', '1s'], - loggingEnabled: false, - }); - const nodeProvider = await Provider.create(`http://${ip}:${port}/v1/graphql`); - - const genesisWallet = new WalletUnlocked( - process.env.GENESIS_SECRET || randomBytes(32), - nodeProvider - ); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 500_000, + }, + nodeOptions: { + args: ['--poa-instant', 'false', '--poa-interval-period', '2s', '--tx-pool-ttl', '1s'], + loggingEnabled: false, + }, + }); - const request = new ScriptTransactionRequest(); + const { + provider, + wallets: [genesisWallet], + } = launched; - request.addCoinOutput(Wallet.generate(), 100, baseAssetId); + const request = new ScriptTransactionRequest(); - const txCost = await genesisWallet.provider.getTransactionCost(request); + request.addCoinOutput(Wallet.generate(), 100, provider.getBaseAssetId()); - request.gasLimit = txCost.gasUsed; - request.maxFee = txCost.maxFee; + const txCost = await genesisWallet.provider.getTransactionCost(request); - await genesisWallet.fund(request, txCost); + request.gasLimit = txCost.gasUsed; + request.maxFee = txCost.maxFee; - request.updateWitnessByOwner( - genesisWallet.address, - await genesisWallet.signTransaction(request) - ); + await genesisWallet.fund(request, txCost); - const response = await nodeProvider.sendTransaction(request); + request.updateWitnessByOwner( + genesisWallet.address, + await genesisWallet.signTransaction(request) + ); - await expectToThrowFuelError( - async () => { - await response.waitForResult(); - }, - { code: ErrorCode.TRANSACTION_SQUEEZED_OUT } - ); + const response = await provider.sendTransaction(request); - cleanup(); - }); + await expectToThrowFuelError( + async () => { + await response.waitForResult(); + }, + { code: ErrorCode.TRANSACTION_SQUEEZED_OUT } + ); + }, + { timeout: 10_000 } + ); it( 'should throw error for a SqueezedOut status update [submitAndAwait]', async () => { - const { cleanup, ip, port } = await launchNode({ - args: ['--poa-instant', 'false', '--poa-interval-period', '4s', '--tx-pool-ttl', '1s'], - loggingEnabled: false, + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 500_000, + }, + nodeOptions: { + args: ['--poa-instant', 'false', '--poa-interval-period', '4s', '--tx-pool-ttl', '1s'], + loggingEnabled: false, + }, }); - const nodeProvider = await Provider.create(`http://${ip}:${port}/v1/graphql`); - const genesisWallet = new WalletUnlocked( - process.env.GENESIS_SECRET || randomBytes(32), - nodeProvider - ); + const { + provider, + wallets: [genesisWallet], + } = launched; const request = new ScriptTransactionRequest(); - request.addCoinOutput(Wallet.generate(), 100, baseAssetId); + request.addCoinOutput(Wallet.generate(), 100, provider.getBaseAssetId()); const txCost = await genesisWallet.provider.getTransactionCost(request, { signatureCallback: (tx) => tx.addAccountWitnesses(genesisWallet), @@ -279,11 +290,10 @@ describe('TransactionResponse', () => { await expectToThrowFuelError( async () => { - await nodeProvider.sendTransaction(request, { awaitExecution: true }); + await provider.sendTransaction(request, { awaitExecution: true }); }, { code: ErrorCode.TRANSACTION_SQUEEZED_OUT } ); - cleanup(); }, { retry: 10 } ); diff --git a/packages/fuel-gauge/src/transaction-summary.test.ts b/packages/fuel-gauge/src/transaction-summary.test.ts index 2507ee80ca..d34891a5e5 100644 --- a/packages/fuel-gauge/src/transaction-summary.test.ts +++ b/packages/fuel-gauge/src/transaction-summary.test.ts @@ -1,5 +1,4 @@ import type { - WalletUnlocked, TransactionResultReceipt, Operation, TransactionSummary, @@ -8,37 +7,26 @@ import type { } from 'fuels'; import { BN, - FUEL_NETWORK_URL, getTransactionsSummaries, getTransactionSummary, getTransactionSummaryFromRequest, - Provider, ScriptTransactionRequest, TransactionTypeName, Wallet, AddressType, OperationName, } from 'fuels'; -import { generateTestWallet, ASSET_A, ASSET_B } from 'fuels/test-utils'; +import { ASSET_A, ASSET_B, launchTestNode } from 'fuels/test-utils'; -import { FuelGaugeProjectsEnum } from '../test/fixtures'; - -import { getSetupContract } from './utils'; +import { MultiTokenContractAbi__factory, TokenContractAbi__factory } from '../test/typegen'; +import MultiTokenContractAbiHex from '../test/typegen/contracts/MultiTokenContractAbi.hex'; +import TokenContractAbiHex from '../test/typegen/contracts/TokenContractAbi.hex'; /** * @group node + * @group browser */ describe('TransactionSummary', () => { - let provider: Provider; - let adminWallet: WalletUnlocked; - - let baseAssetId: string; - beforeAll(async () => { - provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - adminWallet = await generateTestWallet(provider, [[100_000_000, baseAssetId]]); - }); - const verifyTransactionSummary = (params: { transaction: TransactionResult | TransactionSummary; isRequest?: boolean; @@ -66,6 +54,17 @@ describe('TransactionSummary', () => { }; it('should ensure getTransactionSummary executes just fine', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 100_000_000, + }, + }); + + const { + provider, + wallets: [adminWallet], + } = launched; + const destination = Wallet.generate({ provider, }); @@ -76,7 +75,7 @@ describe('TransactionSummary', () => { gasLimit: 10000, }); - request.addCoinOutput(destination.address, amountToTransfer, baseAssetId); + request.addCoinOutput(destination.address, amountToTransfer, provider.getBaseAssetId()); const txCost = await adminWallet.provider.getTransactionCost(request); @@ -103,11 +102,22 @@ describe('TransactionSummary', () => { }); it('should ensure getTransactionsSummaries executes just fine', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 100_000_000, + }, + }); + + const { + provider, + wallets: [adminWallet], + } = launched; + const sender = Wallet.generate({ provider, }); - const tx1 = await adminWallet.transfer(sender.address, 500_000, baseAssetId, { + const tx1 = await adminWallet.transfer(sender.address, 500_000, provider.getBaseAssetId(), { gasLimit: 10_000, }); const transactionResponse1 = await tx1.waitForResult(); @@ -118,9 +128,14 @@ describe('TransactionSummary', () => { provider, }); - const tx2 = await sender.transfer(destination.address, amountToTransfer, baseAssetId, { - gasLimit: 10_000, - }); + const tx2 = await sender.transfer( + destination.address, + amountToTransfer, + provider.getBaseAssetId(), + { + gasLimit: 10_000, + } + ); const transactionResponse2 = await tx2.waitForResult(); const { transactions } = await getTransactionsSummaries({ @@ -144,6 +159,17 @@ describe('TransactionSummary', () => { }); it('should ensure getTransactionSummaryFromRequest executes just fine', async () => { + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 100_000_000, + }, + }); + + const { + provider, + wallets: [adminWallet], + } = launched; + const request = new ScriptTransactionRequest({ gasLimit: 10000, }); @@ -170,12 +196,6 @@ describe('TransactionSummary', () => { }); describe('Transfer Operations', () => { - const setupContract = getSetupContract(FuelGaugeProjectsEnum.TOKEN_CONTRACT); - - beforeAll(async () => { - provider = await Provider.create(FUEL_NETWORK_URL); - }); - const validateTransferOperation = (params: { operations: Operation[]; sender: AbstractAddress; @@ -201,13 +221,22 @@ describe('TransactionSummary', () => { }; it('should ensure transfer operation is assembled (ACCOUNT TRANSFER)', async () => { - const wallet = await generateTestWallet(provider, [[300_000, baseAssetId]]); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 100_000_000, + }, + }); + + const { + provider, + wallets: [wallet], + } = launched; const recipient = Wallet.generate({ provider }); const amount = 1233; - const tx1 = await wallet.transfer(recipient.address, amount, baseAssetId); + const tx1 = await wallet.transfer(recipient.address, amount, provider.getBaseAssetId()); const { operations } = await tx1.waitForResult(); @@ -219,22 +248,35 @@ describe('TransactionSummary', () => { fromType: AddressType.account, toType: AddressType.account, recipients: [ - { address: recipient.address, quantities: [{ amount, assetId: baseAssetId }] }, + { + address: recipient.address, + quantities: [{ amount, assetId: provider.getBaseAssetId() }], + }, ], }); }); it('should ensure transfer operation is assembled (ACCOUNT TRANSFER TO CONTRACT)', async () => { - const wallet = await generateTestWallet(provider, [ - [300_000, baseAssetId], - [10_000, ASSET_A], - ]); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: MultiTokenContractAbi__factory, + bytecode: MultiTokenContractAbiHex, + }, + ], + walletsConfig: { + amountPerCoin: 100_000_000, + }, + }); - const contract1 = await setupContract({ cache: false }); + const { + contracts: [contract], + wallets: [wallet], + } = launched; const amount = 234; - const tx1 = await wallet.transferToContract(contract1.id, amount, ASSET_A); + const tx1 = await wallet.transferToContract(contract.id, amount, ASSET_A); const { operations } = await tx1.waitForResult(); @@ -245,15 +287,27 @@ describe('TransactionSummary', () => { sender: wallet.address, fromType: AddressType.account, toType: AddressType.contract, - recipients: [{ address: contract1.id, quantities: [{ amount, assetId: ASSET_A }] }], + recipients: [{ address: contract.id, quantities: [{ amount, assetId: ASSET_A }] }], }); }); it('should ensure transfer operation is assembled (CONTRACT TRANSFER TO ACCOUNT)', async () => { - const wallet = await generateTestWallet(provider, [[300_000, baseAssetId]]); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: TokenContractAbi__factory, + bytecode: TokenContractAbiHex, + }, + ], + walletsConfig: { + amountPerCoin: 100_000_000, + }, + }); - const contract = await setupContract(); - contract.account = wallet; + const { + provider, + contracts: [contract], + } = launched; const recipient = Wallet.generate({ provider }); const amount = 1055; @@ -280,79 +334,115 @@ describe('TransactionSummary', () => { }); }); - it('should ensure transfer operations are assembled (CONTRACT TRANSFER TO ACCOUNTS)', async () => { - const wallet = await generateTestWallet(provider, [ - [300_000, baseAssetId], - [50_000, ASSET_A], - [50_000, ASSET_B], - ]); - - const senderContract = await setupContract({ cache: false }); - senderContract.account = wallet; - const fundAmount = 5_000; + it( + 'should ensure transfer operations are assembled (CONTRACT TRANSFER TO ACCOUNTS)', + async () => { + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: TokenContractAbi__factory, + bytecode: TokenContractAbiHex, + }, + ], + walletsConfig: { + amountPerCoin: 100_000_000, + }, + }); - const assets = [baseAssetId, ASSET_A, ASSET_B]; - for await (const asset of assets) { - const tx = await wallet.transferToContract(senderContract.id, fundAmount, asset); - await tx.waitForResult(); - } + const { + contracts: [senderContract], + provider, + wallets: [wallet], + } = launched; + + const walletA = Wallet.generate({ provider }); + const walletB = Wallet.generate({ provider }); + + await wallet.transfer(walletA.address, 50_000, ASSET_A); + await wallet.transfer(walletB.address, 50_000, ASSET_B); + + senderContract.account = wallet; + const fundAmount = 5_000; + + const assets = [provider.getBaseAssetId(), ASSET_A, ASSET_B]; + for await (const asset of assets) { + const tx = await wallet.transferToContract(senderContract.id, fundAmount, asset); + await tx.waitForResult(); + } + + const transferData1 = { + address: Wallet.generate({ provider }).address, + quantities: [ + { amount: 543, assetId: ASSET_A }, + { amount: 40, assetId: ASSET_B }, + { amount: 123, assetId: provider.getBaseAssetId() }, + ], + }; + const transferData2 = { + address: Wallet.generate({ provider }).address, + quantities: [ + { amount: 12, assetId: provider.getBaseAssetId() }, + { amount: 612, assetId: ASSET_B }, + ], + }; + + const { waitForResult } = await senderContract.functions + .multi_address_transfer([ + // 3 Transfers for recipient contract 1 + ...transferData1.quantities.map(({ amount, assetId }) => ({ + recipient: { bits: transferData1.address.toB256() }, + asset_id: { bits: assetId }, + amount, + })), + // 2 Transfers for recipient contract 2 + ...transferData2.quantities.map(({ amount, assetId }) => ({ + recipient: { bits: transferData2.address.toB256() }, + asset_id: { bits: assetId }, + amount, + })), + ]) + .call(); + + const { + transactionResult: { operations }, + } = await waitForResult(); + + validateTransferOperation({ + operations, + sender: senderContract.id, + fromType: AddressType.contract, + toType: AddressType.account, + recipients: [transferData1, transferData2], + }); + }, + { timeout: 10_000 } + ); - const transferData1 = { - address: Wallet.generate({ provider }).address, - quantities: [ - { amount: 543, assetId: ASSET_A }, - { amount: 400, assetId: ASSET_B }, - { amount: 123, assetId: baseAssetId }, - ], - }; - const transferData2 = { - address: Wallet.generate({ provider }).address, - quantities: [ - { amount: 12, assetId: baseAssetId }, - { amount: 612, assetId: ASSET_B }, + it('should ensure transfer operation is assembled (CONTRACT TRANSFER TO CONTRACT)', async () => { + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: TokenContractAbi__factory, + bytecode: TokenContractAbiHex, + }, + { + deployer: TokenContractAbi__factory, + bytecode: TokenContractAbiHex, + }, ], - }; - - const { waitForResult } = await senderContract.functions - .multi_address_transfer([ - // 3 Transfers for recipient contract 1 - ...transferData1.quantities.map(({ amount, assetId }) => ({ - recipient: { bits: transferData1.address.toB256() }, - asset_id: { bits: assetId }, - amount, - })), - // 2 Transfers for recipient contract 2 - ...transferData2.quantities.map(({ amount, assetId }) => ({ - recipient: { bits: transferData2.address.toB256() }, - asset_id: { bits: assetId }, - amount, - })), - ]) - .call(); - - const { - transactionResult: { operations }, - } = await waitForResult(); - - validateTransferOperation({ - operations, - sender: senderContract.id, - fromType: AddressType.contract, - toType: AddressType.account, - recipients: [transferData1, transferData2], + walletsConfig: { + amountPerCoin: 100_000_000, + }, }); - }); - it('should ensure transfer operation is assembled (CONTRACT TRANSFER TO CONTRACT)', async () => { - const wallet = await generateTestWallet(provider, [[300_000, baseAssetId]]); + const { + wallets: [wallet], + contracts: [contractSender, contractRecipient], + } = launched; - const contractSender = await setupContract({ cache: false }); contractSender.account = wallet; - const contractRecipient = await setupContract({ cache: false }); - const call1 = await contractSender.functions.mint_coins(100000).call(); - const { transactionResult: { mintedAssets }, } = await call1.waitForResult(); @@ -381,25 +471,41 @@ describe('TransactionSummary', () => { }); it('should ensure transfer operations are assembled (CONTRACT TRANSFER TO CONTRACTS)', async () => { - const wallet = await generateTestWallet(provider, [ - [300_000, baseAssetId], - [60_000, ASSET_A], - [60_000, ASSET_B], - ]); + using launched = await launchTestNode({ + contractsConfigs: [ + { + deployer: TokenContractAbi__factory, + bytecode: TokenContractAbiHex, + }, + { + deployer: TokenContractAbi__factory, + bytecode: TokenContractAbiHex, + }, + { + deployer: TokenContractAbi__factory, + bytecode: TokenContractAbiHex, + }, + ], + walletsConfig: { + amountPerCoin: 100_000_000, + }, + }); + + const { + provider, + wallets: [wallet], + contracts: [senderContract, contractRecipient1, contractRecipient2], + } = launched; - const senderContract = await setupContract({ cache: false }); senderContract.account = wallet; const fundAmount = 5_000; - const assets = [baseAssetId, ASSET_A, ASSET_B]; + const assets = [provider.getBaseAssetId(), ASSET_A, ASSET_B]; for await (const asset of assets) { const tx = await wallet.transferToContract(senderContract.id, fundAmount, asset); await tx.waitForResult(); } - const contractRecipient1 = await setupContract({ cache: false }); - const contractRecipient2 = await setupContract({ cache: false }); - const transferData1 = { address: contractRecipient1.id, quantities: [ @@ -412,7 +518,7 @@ describe('TransactionSummary', () => { quantities: [ { amount: 500, assetId: ASSET_A }, { amount: 700, assetId: ASSET_B }, - { amount: 100, assetId: baseAssetId }, + { amount: 100, assetId: provider.getBaseAssetId() }, ], }; @@ -447,11 +553,22 @@ describe('TransactionSummary', () => { }); it('should ensure transfer operations are assembled (CUSTOM SCRIPT TRANSFER)', async () => { - const wallet = await generateTestWallet(provider, [ - [200_000, baseAssetId], - [10_000, ASSET_A], - [10_000, ASSET_B], - ]); + using launched = await launchTestNode({ + walletsConfig: { + amountPerCoin: 100_000_000, + }, + }); + + const { + provider, + wallets: [wallet], + } = launched; + + const walletA = Wallet.generate({ provider }); + const walletB = Wallet.generate({ provider }); + + await wallet.transfer(walletA.address, 10_000, ASSET_A); + await wallet.transfer(walletB.address, 10_000, ASSET_B); const recipient1Data = { address: Wallet.generate({ provider }).address, @@ -470,7 +587,7 @@ describe('TransactionSummary', () => { quantities: [ { amount: 500, assetId: ASSET_A }, { amount: 700, assetId: ASSET_B }, - { amount: 100, assetId: baseAssetId }, + { amount: 100, assetId: provider.getBaseAssetId() }, ], }; diff --git a/packages/fuel-gauge/src/transaction.test.ts b/packages/fuel-gauge/src/transaction.test.ts index e23b872a24..81db1975da 100644 --- a/packages/fuel-gauge/src/transaction.test.ts +++ b/packages/fuel-gauge/src/transaction.test.ts @@ -1,24 +1,23 @@ -import { sleep, Provider, TransactionType } from 'fuels'; -import { launchNode } from 'fuels/test-utils'; +import { TransactionType } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; /** * @group node + * @group browser */ describe('Transaction', () => { it('should ensure a mint transaction can be decoded just fine', async () => { - const { cleanup, ip, port } = await launchNode({ - args: ['--poa-instant', 'false', '--poa-interval-period', '100ms'], - loggingEnabled: false, + using launched = await launchTestNode({ + nodeOptions: { + args: ['--poa-instant', 'false', '--poa-interval-period', '1ms'], + }, }); + const { provider } = launched; - await sleep(500); - const nodeProvider = await Provider.create(`http://${ip}:${port}/v1/graphql`); const { transactions: [tx], - } = await nodeProvider.getTransactions({ first: 1 }); + } = await provider.getTransactions({ first: 1 }); expect(tx.type).toBe(TransactionType.Mint); - - cleanup(); }); }); diff --git a/packages/fuel-gauge/src/utils.ts b/packages/fuel-gauge/src/utils.ts index 9e174bcc9a..1a2a6cfc3a 100644 --- a/packages/fuel-gauge/src/utils.ts +++ b/packages/fuel-gauge/src/utils.ts @@ -1,92 +1,14 @@ -import { readFileSync } from 'fs'; -import type { Interface, Contract, WalletUnlocked, JsonAbi, BytesLike } from 'fuels'; -import { Script, Provider, ContractFactory, FUEL_NETWORK_URL } from 'fuels'; -import { ASSET_A, generateTestWallet } from 'fuels/test-utils'; -import { join } from 'path'; - -let contractInstance: Contract; -const deployContract = async ( - factory: ContractFactory, - provider: Provider, - useCache: boolean = true -) => { - if (contractInstance && useCache) { - return contractInstance; - } - const { waitForResult } = await factory.deployContract(); - ({ contract: contractInstance } = await waitForResult()); - return contractInstance; -}; - -let walletInstance: WalletUnlocked; -export const createWallet = async () => { - if (walletInstance) { - return walletInstance; - } - const provider = await Provider.create(FUEL_NETWORK_URL); - const baseAssetId = provider.getBaseAssetId(); - walletInstance = await generateTestWallet(provider, [ - [500_000_000, baseAssetId], - [500_000_000, ASSET_A], - ]); - return walletInstance; -}; - -export type SetupConfig = { - contractBytecode: BytesLike; - abi: JsonAbi | Interface; - cache?: boolean; -}; - -export const setup = async ({ - contractBytecode, - abi, - cache, -}: SetupConfig) => { - // Create wallet - const wallet = await createWallet(); - const factory = new ContractFactory(contractBytecode, abi, wallet); - const contract = await deployContract(factory, wallet.provider, cache); - return contract as TContract; -}; - -export const createSetupConfig = - (defaultConfig: SetupConfig) => - async (config?: Partial) => - setup({ - contractBytecode: defaultConfig.contractBytecode, - abi: defaultConfig.abi, - ...config, - }); - -const getFullPath = (contractName: string, next: (fullPath: string) => T) => - next( - join(__dirname, `../test/fixtures/forc-projects/${contractName}/out/release/${contractName}`) - ); - -export const getSetupContract = ( - contractName: string -): ((config?: Partial) => Promise) => - getFullPath(contractName, (fullPath: string) => - createSetupConfig({ - contractBytecode: readFileSync(`${fullPath}.bin`), - abi: JSON.parse(readFileSync(`${fullPath}-abi.json`, 'utf8')), - }) - ); - -export const getScript = ( - scriptName: string, - wallet: WalletUnlocked -): Script => - getFullPath( - scriptName, - (fullPath: string) => - new Script( - readFileSync(`${fullPath}.bin`), - JSON.parse(readFileSync(`${fullPath}-abi.json`, 'utf8')), - wallet - ) - ); - -export const getProgramDir = (name: string) => - join(__dirname, `../test/fixtures/forc-projects/${name}`); +import type { DeployContractConfig } from 'fuels/test-utils'; +import { launchTestNode } from 'fuels/test-utils'; + +export async function launchTestContract(config: T) { + const { + contracts: [contract], + cleanup, + } = await launchTestNode({ + contractsConfigs: [config], + }); + return Object.assign(contract, { + [Symbol.dispose]: () => Promise.resolve(cleanup()), + }); +} diff --git a/packages/fuel-gauge/src/vector-types.test.ts b/packages/fuel-gauge/src/vector-types.test.ts index 0eba10dda0..69aea48368 100644 --- a/packages/fuel-gauge/src/vector-types.test.ts +++ b/packages/fuel-gauge/src/vector-types.test.ts @@ -1,10 +1,12 @@ -import type { BigNumberish } from 'fuels'; -import { bn, Predicate, Wallet, Address, Provider, FUEL_NETWORK_URL } from 'fuels'; -import { generateTestWallet } from 'fuels/test-utils'; +import { bn, Predicate, Wallet, Address } from 'fuels'; +import { launchTestNode } from 'fuels/test-utils'; -import { FuelGaugeProjectsEnum, getFuelGaugeForcProject } from '../test/fixtures'; +import { VectorTypesScriptAbi__factory } from '../test/typegen'; +import { VectorTypesContractAbi__factory } from '../test/typegen/contracts'; +import VectorTypesContractAbiHex from '../test/typegen/contracts/VectorTypesContractAbi.hex'; +import { PredicateVectorTypesAbi__factory } from '../test/typegen/predicates'; -import { getScript, getSetupContract } from './utils'; +import { launchTestContract } from './utils'; const U32_VEC = [0, 1, 2]; const VEC_IN_VEC = [ @@ -75,32 +77,16 @@ type MainArgs = [ VecInAStructInAVec, // VEC_IN_A_VEC_IN_A_STRUCT_IN_A_VEC ]; -const setup = async (balance = 500_000) => { - const provider = await Provider.create(FUEL_NETWORK_URL); - const baseAssetId = provider.getBaseAssetId(); - - // Create wallet - const wallet = await generateTestWallet(provider, [[balance, baseAssetId]]); - - return wallet; -}; - /** * @group node + * @group browser */ describe('Vector Types Validation', () => { - let baseAssetId: string; - const { binHexlified: predicateVectorTypes, abiContents: predicateVectorTypesAbi } = - getFuelGaugeForcProject(FuelGaugeProjectsEnum.PREDICATE_VECTOR_TYPES); - - beforeAll(async () => { - const provider = await Provider.create(FUEL_NETWORK_URL); - baseAssetId = provider.getBaseAssetId(); - }); - it('can use supported vector types [vector-types-contract]', async () => { - const setupContract = getSetupContract('vector-types-contract'); - const contractInstance = await setupContract(); + using contractInstance = await launchTestContract({ + deployer: VectorTypesContractAbi__factory, + bytecode: VectorTypesContractAbiHex, + }); const { waitForResult } = await contractInstance.functions .test_all( @@ -124,8 +110,12 @@ describe('Vector Types Validation', () => { }); it('can use supported vector types [vector-types-script]', async () => { - const wallet = await setup(); - const scriptInstance = getScript('vector-types-script', wallet); + using launched = await launchTestNode(); + const { + wallets: [wallet], + } = launched; + + const scriptInstance = VectorTypesScriptAbi__factory.createInstance(wallet); const { waitForResult } = await scriptInstance.functions .main( @@ -149,14 +139,20 @@ describe('Vector Types Validation', () => { }); it('can use supported vector types [predicate-vector-types]', async () => { - const wallet = await setup(); + using launched = await launchTestNode(); + + const { + provider, + wallets: [wallet], + } = launched; + const receiver = Wallet.fromAddress(Address.fromRandom(), wallet.provider); const amountToPredicate = 300_000; const amountToReceiver = 50; const predicate = new Predicate({ - bytecode: predicateVectorTypes, + bytecode: PredicateVectorTypesAbi__factory.bin, provider: wallet.provider, - abi: predicateVectorTypesAbi, + abi: PredicateVectorTypesAbi__factory.abi, inputData: [ U32_VEC, VEC_IN_VEC, @@ -173,16 +169,26 @@ describe('Vector Types Validation', () => { }); // setup predicate - const setupTx = await wallet.transfer(predicate.address, amountToPredicate, baseAssetId, { - gasLimit: 10_000, - }); + const setupTx = await wallet.transfer( + predicate.address, + amountToPredicate, + provider.getBaseAssetId(), + { + gasLimit: 10_000, + } + ); await setupTx.waitForResult(); const initialReceiverBalance = await receiver.getBalance(); - const tx = await predicate.transfer(receiver.address, amountToReceiver, baseAssetId, { - gasLimit: 10_000, - }); + const tx = await predicate.transfer( + receiver.address, + amountToReceiver, + provider.getBaseAssetId(), + { + gasLimit: 10_000, + } + ); const { isStatusSuccess } = await tx.waitForResult(); // Check the balance of the receiver diff --git a/packages/fuel-gauge/src/vectors.test.ts b/packages/fuel-gauge/src/vectors.test.ts index eb314510af..0e7ab54f78 100644 --- a/packages/fuel-gauge/src/vectors.test.ts +++ b/packages/fuel-gauge/src/vectors.test.ts @@ -1,13 +1,10 @@ import { bn, randomBytes, hexlify } from 'fuels'; -import type { BN, Contract } from 'fuels'; +import type { BN } from 'fuels'; -import { getSetupContract } from './utils'; +import { VectorsAbi__factory } from '../test/typegen/contracts'; +import VectorsAbiHex from '../test/typegen/contracts/VectorsAbi.hex'; -const setupContract = getSetupContract('vectors'); -let contractInstance: Contract; -beforeAll(async () => { - contractInstance = await setupContract(); -}); +import { launchTestContract } from './utils'; const toNumbers = (nums: BN[]) => nums.map((num: BN) => bn(num).toNumber()); @@ -15,11 +12,20 @@ enum SmallEnum { Empty = 'Empty', } +async function setupContract() { + return launchTestContract({ + deployer: VectorsAbi__factory, + bytecode: VectorsAbiHex, + }); +} + /** * @group node + * @group browser */ describe('Vector Tests', () => { it('should test u8 vector input/output', async () => { + using contractInstance = await setupContract(); const INPUT = [8, 6, 7, 5, 3, 0, 9]; const { waitForResult } = await contractInstance.functions.echo_u8(INPUT).call(); @@ -29,6 +35,7 @@ describe('Vector Tests', () => { }); it('should test u16 vector input/output', async () => { + using contractInstance = await setupContract(); const INPUT = [8, 6, 7, 5, 3, 0, 9]; const { waitForResult } = await contractInstance.functions.echo_u16(INPUT).call(); @@ -38,6 +45,8 @@ describe('Vector Tests', () => { }); it('should test u32 vector input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = [8, 6, 7, 5, 3, 0, 9]; const { waitForResult } = await contractInstance.functions.echo_u32(INPUT).call(); @@ -47,6 +56,8 @@ describe('Vector Tests', () => { }); it('should test u64 vector input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = [8, 6, 7, 5, 3, 0, 9]; const { waitForResult } = await contractInstance.functions.echo_u64(INPUT).call(); @@ -56,6 +67,8 @@ describe('Vector Tests', () => { }); it('should test bool vector input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = [true, false, true, true]; const { waitForResult } = await contractInstance.functions.echo_bool(INPUT).call(); @@ -65,6 +78,8 @@ describe('Vector Tests', () => { }); it('should test b256 vector input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = [hexlify(randomBytes(32)), hexlify(randomBytes(32)), hexlify(randomBytes(32))]; const { waitForResult } = await contractInstance.functions.echo_b256(INPUT).call(); @@ -74,6 +89,8 @@ describe('Vector Tests', () => { }); it('should test b512 vector input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = [hexlify(randomBytes(64)), hexlify(randomBytes(64)), hexlify(randomBytes(64))]; const { waitForResult } = await contractInstance.functions.echo_b512(INPUT).call(); @@ -83,6 +100,8 @@ describe('Vector Tests', () => { }); it('should test str[1] vector input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = ['a', 'b', 'c', 'd']; const { waitForResult } = await contractInstance.functions.echo_str_1(INPUT).call(); @@ -92,6 +111,8 @@ describe('Vector Tests', () => { }); it('should test str[9] vector input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = ['123456789', 'abcdefghi', 'catdogcat', 'onetwoone']; const { waitForResult } = await contractInstance.functions.echo_str_9(INPUT).call(); @@ -101,6 +122,8 @@ describe('Vector Tests', () => { }); it('should test (u8, u8) vector input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = [ [1, 2], [3, 4], @@ -116,6 +139,8 @@ describe('Vector Tests', () => { }); it('should test (u64, u64) vector input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = [ [111, 2222], [333, 4445], @@ -129,6 +154,8 @@ describe('Vector Tests', () => { }); it('should test [u8; 2] vector input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = [ [1, 2], [5, 6], @@ -143,6 +170,8 @@ describe('Vector Tests', () => { }); it('should test [u64; 5] vector input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = [ [1, 2, 3, 4, 5], [500, 600, 700, 9000, 9999], @@ -156,6 +185,8 @@ describe('Vector Tests', () => { }); it('should test [bool; 2] vector input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = [ [true, true], [true, false], @@ -173,6 +204,8 @@ describe('Vector Tests', () => { }); it('should test U8Struct vector input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = [ { i: 1, @@ -194,6 +227,8 @@ describe('Vector Tests', () => { }); it('should test B256Struct vector input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = [ { i: hexlify(randomBytes(32)), @@ -215,6 +250,8 @@ describe('Vector Tests', () => { }); it('should test ComplexStruct vector input/output', async () => { + using contractInstance = await setupContract(); + type ComplexStruct = { foo: number; bar: BN; baz: string }; const INPUT = [ { @@ -248,6 +285,8 @@ describe('Vector Tests', () => { }); it('should test SmallEnum vector input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = [ SmallEnum.Empty, SmallEnum.Empty, @@ -265,6 +304,8 @@ describe('Vector Tests', () => { }); it('should test BigEnum vector input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = [ { AddressA: hexlify(randomBytes(32)), @@ -286,6 +327,8 @@ describe('Vector Tests', () => { }); it('should test Option vector input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = [undefined, 1, undefined, 2, undefined, 3]; const { waitForResult } = await contractInstance.functions.echo_option_u8(INPUT).call(); @@ -295,6 +338,8 @@ describe('Vector Tests', () => { }); it('should test Vec inside struct input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = { num: 2, vec: [1, 5, 98], @@ -309,6 +354,8 @@ describe('Vector Tests', () => { }); it('should test Vec inside enum input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = { vec: [1, 5, 98], }; @@ -322,6 +369,8 @@ describe('Vector Tests', () => { }); it('should test Vec inside vector input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = [[1, 5, 98], [2, 44], [34]]; const { waitForResult } = await contractInstance.functions @@ -333,6 +382,8 @@ describe('Vector Tests', () => { }); it('should test struct and Vec input/output', async () => { + using contractInstance = await setupContract(); + type Struct = { foo: number; bar: BN; baz: string }; const INPUT: [Struct, number[]] = [ { @@ -355,6 +406,8 @@ describe('Vector Tests', () => { }); it('should test Vec and b256 tuple input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = [[1, 8, 3, 2, 55, 215], hexlify(randomBytes(32))]; const { waitForResult } = await contractInstance.functions @@ -366,6 +419,8 @@ describe('Vector Tests', () => { }); it('should test two vectors tuple input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = [ [219, 229], [1, 254, 55], @@ -380,6 +435,8 @@ describe('Vector Tests', () => { }); it('should test u32 and three different vectors tuple input/output', async () => { + using contractInstance = await setupContract(); + const INPUT = [91000, [true, true, false], [95000, 153333], [20000, 65500]]; const { waitForResult } = await contractInstance.functions @@ -391,6 +448,8 @@ describe('Vector Tests', () => { }); it('should test multiCall vectors', async () => { + using contractInstance = await setupContract(); + const { waitForResult } = await contractInstance .multiCall([ contractInstance.functions.echo_u8([1]), diff --git a/packages/fuel-gauge/test/fixtures/forc-projects/Forc.toml b/packages/fuel-gauge/test/fixtures/forc-projects/Forc.toml index e853095e25..b017851d10 100644 --- a/packages/fuel-gauge/test/fixtures/forc-projects/Forc.toml +++ b/packages/fuel-gauge/test/fixtures/forc-projects/Forc.toml @@ -60,8 +60,8 @@ members = [ "small-bytes", "std-lib-string", "storage-test-contract", - "token_abi", - "token_contract", + "token-abi", + "token-contract", "vector-types-contract", "vector-types-script", "vectors", diff --git a/packages/fuel-gauge/test/fixtures/forc-projects/token_abi/Forc.toml b/packages/fuel-gauge/test/fixtures/forc-projects/token-abi/Forc.toml similarity index 82% rename from packages/fuel-gauge/test/fixtures/forc-projects/token_abi/Forc.toml rename to packages/fuel-gauge/test/fixtures/forc-projects/token-abi/Forc.toml index 616942145b..ccb9d450b7 100644 --- a/packages/fuel-gauge/test/fixtures/forc-projects/token_abi/Forc.toml +++ b/packages/fuel-gauge/test/fixtures/forc-projects/token-abi/Forc.toml @@ -1,6 +1,6 @@ [project] authors = ["Fuel Labs "] license = "Apache-2.0" -name = "token_abi" +name = "token-abi" [dependencies] diff --git a/packages/fuel-gauge/test/fixtures/forc-projects/token_abi/src/main.sw b/packages/fuel-gauge/test/fixtures/forc-projects/token-abi/src/main.sw similarity index 100% rename from packages/fuel-gauge/test/fixtures/forc-projects/token_abi/src/main.sw rename to packages/fuel-gauge/test/fixtures/forc-projects/token-abi/src/main.sw diff --git a/packages/fuel-gauge/test/fixtures/forc-projects/token_contract/Forc.toml b/packages/fuel-gauge/test/fixtures/forc-projects/token-contract/Forc.toml similarity index 59% rename from packages/fuel-gauge/test/fixtures/forc-projects/token_contract/Forc.toml rename to packages/fuel-gauge/test/fixtures/forc-projects/token-contract/Forc.toml index e1c68c87ef..4992478666 100644 --- a/packages/fuel-gauge/test/fixtures/forc-projects/token_contract/Forc.toml +++ b/packages/fuel-gauge/test/fixtures/forc-projects/token-contract/Forc.toml @@ -1,7 +1,7 @@ [project] authors = ["Fuel Labs "] license = "Apache-2.0" -name = "token_contract" +name = "token-contract" [dependencies] -token_abi = { path = "../token_abi" } +token-abi = { path = "../token-abi" } diff --git a/packages/fuel-gauge/test/fixtures/forc-projects/token_contract/src/main.sw b/packages/fuel-gauge/test/fixtures/forc-projects/token-contract/src/main.sw similarity index 100% rename from packages/fuel-gauge/test/fixtures/forc-projects/token_contract/src/main.sw rename to packages/fuel-gauge/test/fixtures/forc-projects/token-contract/src/main.sw diff --git a/packages/fuel-gauge/test/fixtures/index.ts b/packages/fuel-gauge/test/fixtures/index.ts index 444dbe8713..e33c1093a9 100644 --- a/packages/fuel-gauge/test/fixtures/index.ts +++ b/packages/fuel-gauge/test/fixtures/index.ts @@ -18,6 +18,7 @@ export enum FuelGaugeProjectsEnum { COVERAGE_CONTRACT = 'coverage-contract', GENERIC_TYPES_CONTRACT = 'generic-types-contract', MULTI_TOKEN_CONTRACT = 'multi-token-contract', + OPTIONS = 'options', PAYABLE_ANNOTATION = 'payable-annotation', PREDICATE_ADDRESS = 'predicate-address', PREDICATE_ASSERT_VALUE = 'predicate-assert-value', @@ -56,8 +57,8 @@ export enum FuelGaugeProjectsEnum { SCRIPT_WITH_VECTOR_MIXED = 'script-with-vector-mixed', STD_LIB_STRING = 'std-lib-string', STORAGE_TEST_CONTRACT = 'storage-test-contract', - TOKEN_ABI = 'token_abi', - TOKEN_CONTRACT = 'token_contract', + TOKEN_ABI = 'token-abi', + TOKEN_CONTRACT = 'token-contract', VECTOR_TYPES_CONTRACT = 'vector-types-contract', VECTOR_TYPES_SCRIPT = 'vector-types-script', VECTORS = 'vectors', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cc7ee71d0d..4769817637 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2323,8 +2323,8 @@ packages: resolution: {integrity: sha512-TNPDN6aBFaUox2Lu+H/Y1dKKQgr4ucz/FGyCz67RVYLsBpVpUFf1dDngzg+Od8aqbrqwyztkaZjtWCZEUOT8zA==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.23.4': - resolution: {integrity: sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg==} + '@babel/runtime@7.24.7': + resolution: {integrity: sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==} engines: {node: '>=6.9.0'} '@babel/template@7.24.6': @@ -5825,9 +5825,6 @@ packages: arity-n@1.0.4: resolution: {integrity: sha512-fExL2kFDC1Q2DUOx3whE/9KoN66IzkY4b4zUHUBFM1ojEYjZZYDcUW3bek/ufGionX9giIKDC5redH2IlGqcQQ==} - array-buffer-byte-length@1.0.0: - resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} - array-buffer-byte-length@1.0.1: resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} engines: {node: '>= 0.4'} @@ -8156,9 +8153,6 @@ packages: get-intrinsic@1.2.1: resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} - get-intrinsic@1.2.2: - resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} - get-intrinsic@1.2.4: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} @@ -8717,9 +8711,6 @@ packages: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} engines: {node: '>= 0.4'} - is-array-buffer@3.0.2: - resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} - is-array-buffer@3.0.4: resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} engines: {node: '>= 0.4'} @@ -8913,9 +8904,6 @@ packages: is-set@2.0.2: resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} - is-shared-array-buffer@1.0.2: - resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} - is-shared-array-buffer@1.0.3: resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} engines: {node: '>= 0.4'} @@ -11442,7 +11430,6 @@ packages: engines: {node: '>=0.6.0', teleport: '>=0.2.0'} deprecated: |- You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other. - (For a CapTP with native promises, see @endo/eventual-send and @endo/captp) qr-code-styling@1.6.0-rc.1: @@ -11756,10 +11743,6 @@ packages: resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==} engines: {node: '>= 0.4'} - regexp.prototype.flags@1.5.1: - resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} - engines: {node: '>= 0.4'} - regexp.prototype.flags@1.5.2: resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} engines: {node: '>= 0.4'} @@ -13749,18 +13732,10 @@ packages: resolution: {integrity: sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==} engines: {node: '>=8.15'} - which-typed-array@1.1.13: - resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} - engines: {node: '>= 0.4'} - which-typed-array@1.1.15: resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} engines: {node: '>= 0.4'} - which-typed-array@1.1.9: - resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==} - engines: {node: '>= 0.4'} - which@1.3.1: resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} hasBin: true @@ -14181,7 +14156,7 @@ snapshots: '@babel/core': 7.24.4 '@babel/generator': 7.24.4 '@babel/parser': 7.24.7 - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@babel/traverse': 7.24.1 '@babel/types': 7.24.6 babel-preset-fbjs: 3.4.0(@babel/core@7.24.4) @@ -16365,7 +16340,7 @@ snapshots: core-js-pure: 3.31.0 regenerator-runtime: 0.13.11 - '@babel/runtime@7.23.4': + '@babel/runtime@7.24.7': dependencies: regenerator-runtime: 0.14.0 @@ -16442,7 +16417,7 @@ snapshots: '@changesets/apply-release-plan@7.0.4': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@changesets/config': 3.0.2 '@changesets/get-version-range-type': 0.4.0 '@changesets/git': 3.0.0 @@ -16459,7 +16434,7 @@ snapshots: '@changesets/assemble-release-plan@6.0.3': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@changesets/errors': 0.2.0 '@changesets/get-dependents-graph': 2.1.1 '@changesets/should-skip-package': 0.1.0 @@ -16473,7 +16448,7 @@ snapshots: '@changesets/cli@2.27.7': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@changesets/apply-release-plan': 7.0.4 '@changesets/assemble-release-plan': 6.0.3 '@changesets/changelog-git': 0.2.0 @@ -16537,7 +16512,7 @@ snapshots: '@changesets/get-release-plan@4.0.3': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@changesets/assemble-release-plan': 6.0.3 '@changesets/config': 3.0.2 '@changesets/pre': 2.0.0 @@ -16549,7 +16524,7 @@ snapshots: '@changesets/git@3.0.0': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@changesets/errors': 0.2.0 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 @@ -16568,7 +16543,7 @@ snapshots: '@changesets/pre@2.0.0': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@changesets/errors': 0.2.0 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 @@ -16576,7 +16551,7 @@ snapshots: '@changesets/read@0.6.0': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@changesets/git': 3.0.0 '@changesets/logger': 0.1.0 '@changesets/parse': 0.4.0 @@ -16587,7 +16562,7 @@ snapshots: '@changesets/should-skip-package@0.1.0': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 @@ -16597,7 +16572,7 @@ snapshots: '@changesets/write@0.3.1': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@changesets/types': 6.0.0 fs-extra: 7.0.1 human-id: 1.0.2 @@ -17987,14 +17962,14 @@ snapshots: '@manypkg/find-root@1.1.0': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 '@manypkg/get-packages@1.1.3': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@changesets/types': 4.1.0 '@manypkg/find-root': 1.1.0 fs-extra: 8.1.0 @@ -18547,25 +18522,25 @@ snapshots: '@radix-ui/primitive@1.0.1': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@radix-ui/react-compose-refs@1.0.1(@types/react@18.3.3)(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 react: 18.3.1 optionalDependencies: '@types/react': 18.3.3 '@radix-ui/react-context@1.0.1(@types/react@18.3.3)(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 react: 18.3.1 optionalDependencies: '@types/react': 18.3.3 '@radix-ui/react-dialog@1.0.5(@types/react-dom@18.2.4)(@types/react@18.3.3)(react-dom@18.2.0(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@radix-ui/primitive': 1.0.1 '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) '@radix-ui/react-context': 1.0.1(@types/react@18.3.3)(react@18.3.1) @@ -18588,7 +18563,7 @@ snapshots: '@radix-ui/react-dialog@1.0.5(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@radix-ui/primitive': 1.0.1 '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) '@radix-ui/react-context': 1.0.1(@types/react@18.3.3)(react@18.3.1) @@ -18611,7 +18586,7 @@ snapshots: '@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.2.4)(@types/react@18.3.3)(react-dom@18.2.0(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@radix-ui/primitive': 1.0.1 '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.4)(@types/react@18.3.3)(react-dom@18.2.0(react@18.3.1))(react@18.3.1) @@ -18625,7 +18600,7 @@ snapshots: '@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@radix-ui/primitive': 1.0.1 '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -18639,14 +18614,14 @@ snapshots: '@radix-ui/react-focus-guards@1.0.1(@types/react@18.3.3)(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 react: 18.3.1 optionalDependencies: '@types/react': 18.3.3 '@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.2.4)(@types/react@18.3.3)(react-dom@18.2.0(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.4)(@types/react@18.3.3)(react-dom@18.2.0(react@18.3.1))(react@18.3.1) '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.3)(react@18.3.1) @@ -18658,7 +18633,7 @@ snapshots: '@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.3)(react@18.3.1) @@ -18670,7 +18645,7 @@ snapshots: '@radix-ui/react-id@1.0.1(@types/react@18.3.3)(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.3)(react@18.3.1) react: 18.3.1 optionalDependencies: @@ -18678,7 +18653,7 @@ snapshots: '@radix-ui/react-portal@1.0.4(@types/react-dom@18.2.4)(@types/react@18.3.3)(react-dom@18.2.0(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.4)(@types/react@18.3.3)(react-dom@18.2.0(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.2.0(react@18.3.1) @@ -18688,7 +18663,7 @@ snapshots: '@radix-ui/react-portal@1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -18698,7 +18673,7 @@ snapshots: '@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.4)(@types/react@18.3.3)(react-dom@18.2.0(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.3)(react@18.3.1) react: 18.3.1 @@ -18709,7 +18684,7 @@ snapshots: '@radix-ui/react-presence@1.0.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.3)(react@18.3.1) react: 18.3.1 @@ -18720,7 +18695,7 @@ snapshots: '@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.4)(@types/react@18.3.3)(react-dom@18.2.0(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@radix-ui/react-slot': 1.0.2(@types/react@18.3.3)(react@18.3.1) react: 18.3.1 react-dom: 18.2.0(react@18.3.1) @@ -18730,7 +18705,7 @@ snapshots: '@radix-ui/react-primitive@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@radix-ui/react-slot': 1.0.2(@types/react@18.3.3)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -18740,7 +18715,7 @@ snapshots: '@radix-ui/react-slot@1.0.2(@types/react@18.3.3)(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) react: 18.3.1 optionalDependencies: @@ -18748,14 +18723,14 @@ snapshots: '@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.3.3)(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 react: 18.3.1 optionalDependencies: '@types/react': 18.3.3 '@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.3.3)(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.3)(react@18.3.1) react: 18.3.1 optionalDependencies: @@ -18763,7 +18738,7 @@ snapshots: '@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.3.3)(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.3)(react@18.3.1) react: 18.3.1 optionalDependencies: @@ -18771,7 +18746,7 @@ snapshots: '@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.3.3)(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 react: 18.3.1 optionalDependencies: '@types/react': 18.3.3 @@ -19424,7 +19399,7 @@ snapshots: '@testing-library/dom@8.20.1': dependencies: '@babel/code-frame': 7.24.7 - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@types/aria-query': 5.0.1 aria-query: 5.1.3 chalk: 4.1.2 @@ -19434,7 +19409,7 @@ snapshots: '@testing-library/react@16.0.0(@testing-library/dom@8.20.1)(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@testing-library/dom': 8.20.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -21168,7 +21143,7 @@ snapshots: aria-query@4.2.2: dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@babel/runtime-corejs3': 7.22.5 aria-query@5.1.3: @@ -21181,11 +21156,6 @@ snapshots: arity-n@1.0.4: {} - array-buffer-byte-length@1.0.0: - dependencies: - call-bind: 1.0.5 - is-array-buffer: 3.0.2 - array-buffer-byte-length@1.0.1: dependencies: call-bind: 1.0.7 @@ -21273,7 +21243,7 @@ snapshots: array.prototype.reduce@1.0.5: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 es-array-method-boxes-properly: 1.0.0 @@ -21304,13 +21274,13 @@ snapshots: arraybuffer.prototype.slice@1.0.2: dependencies: - array-buffer-byte-length: 1.0.0 - call-bind: 1.0.5 + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 - get-intrinsic: 1.2.2 - is-array-buffer: 3.0.2 - is-shared-array-buffer: 1.0.2 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 arraybuffer.prototype.slice@1.0.3: dependencies: @@ -21340,10 +21310,10 @@ snapshots: assert@2.1.0: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 is-nan: 1.3.2 object-is: 1.1.5 - object.assign: 4.1.4 + object.assign: 4.1.5 util: 0.12.5 assertion-error@1.1.0: {} @@ -21490,7 +21460,7 @@ snapshots: babel-plugin-macros@3.1.0: dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 cosmiconfig: 7.1.0 resolve: 1.22.8 @@ -21649,7 +21619,7 @@ snapshots: '@babel/preset-env': 7.22.5(@babel/core@7.22.5) '@babel/preset-react': 7.22.5(@babel/core@7.22.5) '@babel/preset-typescript': 7.22.5(@babel/core@7.22.5) - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 babel-plugin-macros: 3.1.0 babel-plugin-transform-react-remove-prop-types: 0.4.24 transitivePeerDependencies: @@ -21916,7 +21886,7 @@ snapshots: call-bind@1.0.5: dependencies: function-bind: 1.1.2 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 set-function-length: 1.1.1 call-bind@1.0.7: @@ -22626,7 +22596,7 @@ snapshots: date-fns@2.30.0: dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 dayjs@1.11.10: {} @@ -22672,24 +22642,24 @@ snapshots: deep-equal@2.2.1: dependencies: - array-buffer-byte-length: 1.0.0 - call-bind: 1.0.5 + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 es-get-iterator: 1.1.3 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 is-arguments: 1.1.1 - is-array-buffer: 3.0.2 + is-array-buffer: 3.0.4 is-date-object: 1.0.5 is-regex: 1.1.4 - is-shared-array-buffer: 1.0.2 + is-shared-array-buffer: 1.0.3 isarray: 2.0.5 object-is: 1.1.5 object-keys: 1.1.1 - object.assign: 4.1.4 - regexp.prototype.flags: 1.5.1 - side-channel: 1.0.4 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + side-channel: 1.0.6 which-boxed-primitive: 1.0.2 which-collection: 1.0.1 - which-typed-array: 1.1.13 + which-typed-array: 1.1.15 deep-is@0.1.4: {} @@ -22713,9 +22683,9 @@ snapshots: define-data-property@1.1.1: dependencies: - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 gopd: 1.0.1 - has-property-descriptors: 1.0.0 + has-property-descriptors: 1.0.2 define-data-property@1.1.4: dependencies: @@ -23008,13 +22978,13 @@ snapshots: es-abstract@1.21.2: dependencies: - array-buffer-byte-length: 1.0.0 + array-buffer-byte-length: 1.0.1 available-typed-arrays: 1.0.5 - call-bind: 1.0.2 + call-bind: 1.0.7 es-set-tostringtag: 2.0.1 es-to-primitive: 1.2.1 function.prototype.name: 1.1.5 - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.4 get-symbol-description: 1.0.0 globalthis: 1.0.3 gopd: 1.0.1 @@ -23023,36 +22993,36 @@ snapshots: has-proto: 1.0.1 has-symbols: 1.0.3 internal-slot: 1.0.5 - is-array-buffer: 3.0.2 + is-array-buffer: 3.0.4 is-callable: 1.2.7 is-negative-zero: 2.0.2 is-regex: 1.1.4 - is-shared-array-buffer: 1.0.2 + is-shared-array-buffer: 1.0.3 is-string: 1.0.7 is-typed-array: 1.1.10 is-weakref: 1.0.2 object-inspect: 1.12.3 object-keys: 1.1.1 - object.assign: 4.1.4 - regexp.prototype.flags: 1.5.0 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 safe-regex-test: 1.0.0 string.prototype.trim: 1.2.7 string.prototype.trimend: 1.0.6 string.prototype.trimstart: 1.0.6 typed-array-length: 1.0.4 unbox-primitive: 1.0.2 - which-typed-array: 1.1.9 + which-typed-array: 1.1.15 es-abstract@1.22.3: dependencies: - array-buffer-byte-length: 1.0.0 + array-buffer-byte-length: 1.0.1 arraybuffer.prototype.slice: 1.0.2 available-typed-arrays: 1.0.5 - call-bind: 1.0.5 + call-bind: 1.0.7 es-set-tostringtag: 2.0.1 es-to-primitive: 1.2.1 function.prototype.name: 1.1.6 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 get-symbol-description: 1.0.0 globalthis: 1.0.3 gopd: 1.0.1 @@ -23061,18 +23031,18 @@ snapshots: has-symbols: 1.0.3 hasown: 2.0.0 internal-slot: 1.0.5 - is-array-buffer: 3.0.2 + is-array-buffer: 3.0.4 is-callable: 1.2.7 is-negative-zero: 2.0.2 is-regex: 1.1.4 - is-shared-array-buffer: 1.0.2 + is-shared-array-buffer: 1.0.3 is-string: 1.0.7 is-typed-array: 1.1.12 is-weakref: 1.0.2 object-inspect: 1.13.1 object-keys: 1.1.1 - object.assign: 4.1.4 - regexp.prototype.flags: 1.5.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 safe-array-concat: 1.0.1 safe-regex-test: 1.0.0 string.prototype.trim: 1.2.8 @@ -23083,7 +23053,7 @@ snapshots: typed-array-byte-offset: 1.0.0 typed-array-length: 1.0.4 unbox-primitive: 1.0.2 - which-typed-array: 1.1.13 + which-typed-array: 1.1.15 es-abstract@1.23.3: dependencies: @@ -23144,8 +23114,8 @@ snapshots: es-get-iterator@1.1.3: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 is-arguments: 1.1.1 is-map: 2.0.2 @@ -23196,9 +23166,9 @@ snapshots: es-set-tostringtag@2.0.1: dependencies: - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.4 has: 1.0.3 - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 es-set-tostringtag@2.0.3: dependencies: @@ -23569,7 +23539,7 @@ snapshots: eslint-plugin-jsx-a11y@6.6.1(eslint@8.57.0): dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 aria-query: 4.2.2 array-includes: 3.1.6 ast-types-flow: 0.0.7 @@ -23586,7 +23556,7 @@ snapshots: eslint-plugin-jsx-a11y@6.7.1(eslint@8.54.0): dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 aria-query: 5.3.0 array-includes: 3.1.7 array.prototype.flatmap: 1.3.2 @@ -24352,14 +24322,14 @@ snapshots: function.prototype.name@1.1.5: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 functions-have-names: 1.2.3 function.prototype.name@1.1.6: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 functions-have-names: 1.2.3 @@ -24403,18 +24373,11 @@ snapshots: has-proto: 1.0.1 has-symbols: 1.0.3 - get-intrinsic@1.2.2: - dependencies: - function-bind: 1.1.2 - has-proto: 1.0.1 - has-symbols: 1.0.3 - hasown: 2.0.0 - get-intrinsic@1.2.4: dependencies: es-errors: 1.3.0 function-bind: 1.1.2 - has-proto: 1.0.1 + has-proto: 1.0.3 has-symbols: 1.0.3 hasown: 2.0.2 @@ -24440,8 +24403,8 @@ snapshots: get-symbol-description@1.0.0: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 get-symbol-description@1.0.2: dependencies: @@ -24549,7 +24512,7 @@ snapshots: gopd@1.0.1: dependencies: - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 got@12.6.1: dependencies: @@ -24678,7 +24641,7 @@ snapshots: has-property-descriptors@1.0.0: dependencies: - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.4 has-property-descriptors@1.0.2: dependencies: @@ -24899,11 +24862,11 @@ snapshots: i18next-browser-languagedetector@7.1.0: dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 i18next@22.5.1: dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 iconv-lite@0.4.24: dependencies: @@ -25004,15 +24967,15 @@ snapshots: internal-slot@1.0.5: dependencies: - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.4 has: 1.0.3 - side-channel: 1.0.4 + side-channel: 1.0.6 internal-slot@1.0.7: dependencies: es-errors: 1.3.0 hasown: 2.0.2 - side-channel: 1.0.4 + side-channel: 1.0.6 invariant@2.2.4: dependencies: @@ -25042,14 +25005,8 @@ snapshots: is-arguments@1.1.1: dependencies: - call-bind: 1.0.5 - has-tostringtag: 1.0.0 - - is-array-buffer@3.0.2: - dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 - is-typed-array: 1.1.12 + call-bind: 1.0.7 + has-tostringtag: 1.0.2 is-array-buffer@3.0.4: dependencies: @@ -25060,7 +25017,7 @@ snapshots: is-async-function@2.0.0: dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 is-bigint@1.0.4: dependencies: @@ -25072,8 +25029,8 @@ snapshots: is-boolean-object@1.1.2: dependencies: - call-bind: 1.0.5 - has-tostringtag: 1.0.0 + call-bind: 1.0.7 + has-tostringtag: 1.0.2 is-buffer@1.1.6: {} @@ -25099,7 +25056,7 @@ snapshots: is-date-object@1.0.5: dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 is-decimal@1.0.4: {} @@ -25115,7 +25072,7 @@ snapshots: is-finalizationregistry@1.0.2: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 is-fullwidth-code-point@2.0.0: {} @@ -25125,7 +25082,7 @@ snapshots: is-generator-function@1.0.10: dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 is-glob@4.0.3: dependencies: @@ -25151,7 +25108,7 @@ snapshots: is-nan@1.3.2: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 is-negative-zero@2.0.2: {} @@ -25160,7 +25117,7 @@ snapshots: is-number-object@1.0.7: dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 is-number@4.0.0: {} @@ -25184,8 +25141,8 @@ snapshots: is-regex@1.1.4: dependencies: - call-bind: 1.0.5 - has-tostringtag: 1.0.0 + call-bind: 1.0.7 + has-tostringtag: 1.0.2 is-regexp@1.0.0: {} @@ -25197,10 +25154,6 @@ snapshots: is-set@2.0.2: {} - is-shared-array-buffer@1.0.2: - dependencies: - call-bind: 1.0.5 - is-shared-array-buffer@1.0.3: dependencies: call-bind: 1.0.7 @@ -25223,15 +25176,15 @@ snapshots: is-typed-array@1.1.10: dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.5 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 for-each: 0.3.3 gopd: 1.0.1 - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 is-typed-array@1.1.12: dependencies: - which-typed-array: 1.1.13 + which-typed-array: 1.1.15 is-typed-array@1.1.13: dependencies: @@ -25255,12 +25208,12 @@ snapshots: is-weakref@1.0.2: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 is-weakset@2.0.2: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 is-windows@1.0.2: {} @@ -25384,7 +25337,7 @@ snapshots: iterator.prototype@1.1.2: dependencies: define-properties: 1.2.1 - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 reflect.getprototypeof: 1.0.4 set-function-name: 2.0.1 @@ -26667,7 +26620,7 @@ snapshots: metro-runtime@0.80.9: dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 metro-source-map@0.80.9: dependencies: @@ -27283,7 +27236,7 @@ snapshots: object-is@1.1.5: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 object-keys@1.1.1: {} @@ -27340,7 +27293,7 @@ snapshots: object.getownpropertydescriptors@2.1.6: dependencies: array.prototype.reduce: 1.0.5 - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 safe-array-concat: 1.0.1 @@ -28457,11 +28410,11 @@ snapshots: qs@6.11.0: dependencies: - side-channel: 1.0.4 + side-channel: 1.0.6 qs@6.11.2: dependencies: - side-channel: 1.0.4 + side-channel: 1.0.6 query-selector-shadow-dom@1.0.1: {} @@ -28600,7 +28553,7 @@ snapshots: react-i18next@13.5.0(i18next@22.5.1)(react-dom@18.3.1(react@18.3.1))(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.22.5(@babel/core@7.24.7))(@types/react@18.3.3)(bufferutil@4.0.8)(react@18.3.1)(utf-8-validate@6.0.4))(react@18.3.1): dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 html-parse-stringify: 3.0.1 i18next: 22.5.1 react: 18.3.1 @@ -28900,10 +28853,10 @@ snapshots: reflect.getprototypeof@1.0.4: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 globalthis: 1.0.3 which-builtin-type: 1.1.3 @@ -28919,22 +28872,16 @@ snapshots: regenerator-transform@0.15.1: dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 regex-parser@2.2.11: {} regexp.prototype.flags@1.5.0: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.2.0 functions-have-names: 1.2.3 - regexp.prototype.flags@1.5.1: - dependencies: - call-bind: 1.0.5 - define-properties: 1.2.1 - set-function-name: 2.0.1 - regexp.prototype.flags@1.5.2: dependencies: call-bind: 1.0.7 @@ -28959,7 +28906,7 @@ snapshots: relay-runtime@12.0.0: dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 fbjs: 3.0.5 invariant: 2.2.4 transitivePeerDependencies: @@ -29163,7 +29110,7 @@ snapshots: rtl-css-js@1.16.1: dependencies: - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 run-async@2.4.1: {} @@ -29179,8 +29126,8 @@ snapshots: safe-array-concat@1.0.1: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 isarray: 2.0.5 @@ -29197,8 +29144,8 @@ snapshots: safe-regex-test@1.0.0: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 is-regex: 1.1.4 safe-regex-test@1.0.3: @@ -29362,10 +29309,10 @@ snapshots: set-function-length@1.1.1: dependencies: - define-data-property: 1.1.1 - get-intrinsic: 1.2.2 + define-data-property: 1.1.4 + get-intrinsic: 1.2.4 gopd: 1.0.1 - has-property-descriptors: 1.0.0 + has-property-descriptors: 1.0.2 set-function-length@1.2.2: dependencies: @@ -29378,9 +29325,9 @@ snapshots: set-function-name@2.0.1: dependencies: - define-data-property: 1.1.1 + define-data-property: 1.1.4 functions-have-names: 1.2.3 - has-property-descriptors: 1.0.0 + has-property-descriptors: 1.0.2 set-function-name@2.0.2: dependencies: @@ -29435,8 +29382,8 @@ snapshots: side-channel@1.0.4: dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 object-inspect: 1.12.3 side-channel@1.0.6: @@ -29677,7 +29624,7 @@ snapshots: stop-iteration-iterator@1.0.0: dependencies: - internal-slot: 1.0.5 + internal-slot: 1.0.7 stream-browserify@3.0.0: dependencies: @@ -29769,13 +29716,13 @@ snapshots: string.prototype.trim@1.2.7: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 string.prototype.trim@1.2.8: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 @@ -29788,13 +29735,13 @@ snapshots: string.prototype.trimend@1.0.6: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 string.prototype.trimend@1.0.7: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 @@ -29806,13 +29753,13 @@ snapshots: string.prototype.trimstart@1.0.6: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 string.prototype.trimstart@1.0.7: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 @@ -30532,8 +30479,8 @@ snapshots: typed-array-buffer@1.0.0: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 is-typed-array: 1.1.12 typed-array-buffer@1.0.2: @@ -30544,9 +30491,9 @@ snapshots: typed-array-byte-length@1.0.0: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 for-each: 0.3.3 - has-proto: 1.0.1 + has-proto: 1.0.3 is-typed-array: 1.1.12 typed-array-byte-length@1.0.1: @@ -30559,10 +30506,10 @@ snapshots: typed-array-byte-offset@1.0.0: dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.5 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 for-each: 0.3.3 - has-proto: 1.0.1 + has-proto: 1.0.3 is-typed-array: 1.1.12 typed-array-byte-offset@1.0.2: @@ -30576,7 +30523,7 @@ snapshots: typed-array-length@1.0.4: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 for-each: 0.3.3 is-typed-array: 1.1.12 @@ -30637,7 +30584,7 @@ snapshots: unbox-primitive@1.0.2: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 @@ -30857,7 +30804,7 @@ snapshots: is-arguments: 1.1.1 is-generator-function: 1.0.10 is-typed-array: 1.1.12 - which-typed-array: 1.1.13 + which-typed-array: 1.1.15 utila@0.4.0: {} @@ -31427,7 +31374,7 @@ snapshots: which-builtin-type@1.1.3: dependencies: function.prototype.name: 1.1.6 - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 is-async-function: 2.0.0 is-date-object: 1.0.5 is-finalizationregistry: 1.0.2 @@ -31437,7 +31384,7 @@ snapshots: isarray: 2.0.5 which-boxed-primitive: 1.0.2 which-collection: 1.0.1 - which-typed-array: 1.1.13 + which-typed-array: 1.1.15 which-collection@1.0.1: dependencies: @@ -31453,14 +31400,6 @@ snapshots: load-yaml-file: 0.2.0 path-exists: 4.0.0 - which-typed-array@1.1.13: - dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.5 - for-each: 0.3.3 - gopd: 1.0.1 - has-tostringtag: 1.0.0 - which-typed-array@1.1.15: dependencies: available-typed-arrays: 1.0.7 @@ -31469,15 +31408,6 @@ snapshots: gopd: 1.0.1 has-tostringtag: 1.0.2 - which-typed-array@1.1.9: - dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.5 - for-each: 0.3.3 - gopd: 1.0.1 - has-tostringtag: 1.0.0 - is-typed-array: 1.1.12 - which@1.3.1: dependencies: isexe: 2.0.0 @@ -31511,7 +31441,7 @@ snapshots: '@apideck/better-ajv-errors': 0.3.6(ajv@8.12.0) '@babel/core': 7.22.5 '@babel/preset-env': 7.22.5(@babel/core@7.22.5) - '@babel/runtime': 7.23.4 + '@babel/runtime': 7.24.7 '@rollup/plugin-babel': 5.3.1(@babel/core@7.22.5)(@types/babel__core@7.20.5)(rollup@2.79.1) '@rollup/plugin-node-resolve': 11.2.1(rollup@2.79.1) '@rollup/plugin-replace': 2.4.2(rollup@2.79.1)