Skip to content

Commit

Permalink
feat!: made deployContract a non-blocking call (#2597)
Browse files Browse the repository at this point in the history
  • Loading branch information
Torres-ssf committed Jul 10, 2024
1 parent 369feef commit 17bd929
Show file tree
Hide file tree
Showing 35 changed files with 345 additions and 164 deletions.
8 changes: 8 additions & 0 deletions .changeset/tender-eyes-think.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@fuel-ts/abi-typegen": minor
"@fuel-ts/contract": minor
"@fuel-ts/account": minor
"fuels": minor
---

feat!: made `deployContract` a non-blocking call
4 changes: 2 additions & 2 deletions apps/create-fuels-counter-guide/src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Button } from "@/components/Button";
import toast from "react-hot-toast";
import { useActiveWallet } from "@/hooks/useActiveWallet";
import useAsync from "react-use/lib/useAsync";
import { CURRENT_ENVIRONMENT } from '@/lib'
import { CURRENT_ENVIRONMENT } from '@/lib';

// #region deploying-dapp-to-testnet-frontend-contract-id
const contractId =
Expand All @@ -37,7 +37,7 @@ export default function Home() {
*/
useAsync(async () => {
if (hasContract && wallet) {
const testContract = TestContractAbi__factory.connect(contractId, wallet);
const { contract: testContract } = TestContractAbi__factory.connect(contractId, wallet);
setContract(testContract);
const { value } = await testContract.functions.get_count().get();
setCounter(value.toNumber());
Expand Down
17 changes: 11 additions & 6 deletions apps/demo-bun-fuels/src/bun.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import { ContractFactory, Provider, toHex, Wallet, FUEL_NETWORK_URL } from 'fuels';
import { generateTestWallet , safeExec } from 'fuels/test-utils';
import { generateTestWallet, safeExec } from 'fuels/test-utils';

import { SampleAbi__factory } from './sway-programs-api';
import bytecode from './sway-programs-api/contracts/SampleAbi.hex';
Expand All @@ -28,7 +28,8 @@ describe('ExampleContract', () => {

// Deploy
const factory = new ContractFactory(bytecode, SampleAbi__factory.abi, wallet);
const contract = await factory.deployContract();
const { waitForResult } = await factory.deployContract();
const { contract } = await waitForResult();

// Call
const { value } = await contract.functions.return_input(1337).call();
Expand All @@ -47,7 +48,8 @@ describe('ExampleContract', () => {
const wallet = await generateTestWallet(provider, [[500_000, baseAssetId]]);

// Deploy
const contract = await SampleAbi__factory.deployContract(bytecode, wallet);
const { waitForResult } = await SampleAbi__factory.deployContract(bytecode, wallet);
const { contract } = await waitForResult();

// Call
const { value } = await contract.functions.return_input(1337).call();
Expand All @@ -62,7 +64,8 @@ describe('ExampleContract', () => {
const unfundedWallet = Wallet.generate({ provider });

const factory = new ContractFactory(bytecode, SampleAbi__factory.abi, fundedWallet);
const contract = await factory.deployContract();
const { waitForResult } = await factory.deployContract();
const { contract } = await waitForResult();
const contractInstance = SampleAbi__factory.connect(contract.id, unfundedWallet);

const { error } = await safeExec(() =>
Expand All @@ -78,7 +81,8 @@ describe('ExampleContract', () => {
const unfundedWallet = Wallet.generate({ provider });

const factory = new ContractFactory(bytecode, SampleAbi__factory.abi, fundedWallet);
const contract = await factory.deployContract();
const { waitForResult } = await factory.deployContract();
const { contract } = await waitForResult();
const contractInstance = SampleAbi__factory.connect(contract.id, unfundedWallet);

await expect(contractInstance.functions.return_input(1337).dryRun()).resolves.not.toThrow();
Expand All @@ -87,7 +91,8 @@ describe('ExampleContract', () => {
it('should demo how to use generated files just fine', async () => {
const provider = await Provider.create(FUEL_NETWORK_URL);
const wallet = await generateTestWallet(provider, [[500_000, baseAssetId]]);
const depoloyed = await SampleAbi__factory.deployContract(bytecode, wallet);
const { waitForResult } = await SampleAbi__factory.deployContract(bytecode, wallet);
const { contract: depoloyed } = await waitForResult();
const contractsIds = {
sample: depoloyed.id,
};
Expand Down
17 changes: 11 additions & 6 deletions apps/demo-fuels/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import { ContractFactory, Provider, toHex, Wallet, FUEL_NETWORK_URL } from 'fuels';
import { generateTestWallet , safeExec } from 'fuels/test-utils';
import { generateTestWallet, safeExec } from 'fuels/test-utils';

import { SampleAbi__factory } from './sway-programs-api';
import bytecode from './sway-programs-api/contracts/SampleAbi.hex';
Expand All @@ -28,7 +28,8 @@ describe('ExampleContract', () => {

// Deploy
const factory = new ContractFactory(bytecode, SampleAbi__factory.abi, wallet);
const contract = await factory.deployContract();
const { waitForResult } = await factory.deployContract();
const { contract } = await waitForResult();

// Call
const { value } = await contract.functions.return_input(1337).call();
Expand All @@ -47,7 +48,8 @@ describe('ExampleContract', () => {
const wallet = await generateTestWallet(provider, [[500_000, baseAssetId]]);

// Deploy
const contract = await SampleAbi__factory.deployContract(bytecode, wallet);
const { waitForResult } = await SampleAbi__factory.deployContract(bytecode, wallet);
const { contract } = await waitForResult();

// Call
const { value } = await contract.functions.return_input(1337).call();
Expand All @@ -62,7 +64,8 @@ describe('ExampleContract', () => {
const unfundedWallet = Wallet.generate({ provider });

const factory = new ContractFactory(bytecode, SampleAbi__factory.abi, fundedWallet);
const contract = await factory.deployContract();
const { waitForResult } = await factory.deployContract();
const { contract } = await waitForResult();
const contractInstance = SampleAbi__factory.connect(contract.id, unfundedWallet);

const { error } = await safeExec(() =>
Expand All @@ -78,7 +81,8 @@ describe('ExampleContract', () => {
const unfundedWallet = Wallet.generate({ provider });

const factory = new ContractFactory(bytecode, SampleAbi__factory.abi, fundedWallet);
const contract = await factory.deployContract();
const { waitForResult } = await factory.deployContract();
const { contract } = await waitForResult();
const contractInstance = SampleAbi__factory.connect(contract.id, unfundedWallet);

await expect(contractInstance.functions.return_input(1337).dryRun()).resolves.not.toThrow();
Expand All @@ -87,7 +91,8 @@ describe('ExampleContract', () => {
it('should demo how to use generated files just fine', async () => {
const provider = await Provider.create(FUEL_NETWORK_URL);
const wallet = await generateTestWallet(provider, [[500_000, baseAssetId]]);
const depoloyed = await SampleAbi__factory.deployContract(bytecode, wallet);
const { waitForResult } = await SampleAbi__factory.deployContract(bytecode, wallet);
const { contract: depoloyed } = await waitForResult();
const contractsIds = {
sample: depoloyed.id,
};
Expand Down
17 changes: 11 additions & 6 deletions apps/demo-typegen/src/demo.test.ts
Original file line number Diff line number Diff line change
@@ -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 { generateTestWallet, safeExec } from 'fuels/test-utils';

import storageSlots from '../contract/out/release/demo-contract-storage_slots.json';

Expand All @@ -27,9 +27,10 @@ describe('ExampleContract', () => {
// #region typegen-demo-contract-storage-slots
// #context import storageSlots from './contract/out/debug/demo-contract-storage_slots.json';

const contract = await DemoContractAbi__factory.deployContract(bytecode, wallet, {
const { waitForResult } = await DemoContractAbi__factory.deployContract(bytecode, wallet, {
storageSlots,
});
const { contract } = await waitForResult();
// #endregion typegen-demo-contract-storage-slots

expect(contract.id).toBeTruthy();
Expand All @@ -40,7 +41,8 @@ describe('ExampleContract', () => {

// Deploy
const factory = new ContractFactory(bytecode, DemoContractAbi__factory.abi, wallet);
const contract = await factory.deployContract();
const { waitForResult } = await factory.deployContract();
const { contract } = await waitForResult();
const contractId = contract.id;

// Call
Expand Down Expand Up @@ -68,7 +70,8 @@ describe('ExampleContract', () => {
// #context import bytecode from './types/DemoContractAbi.hex';

// Deploy
const contract = await DemoContractAbi__factory.deployContract(bytecode, wallet);
const { waitForResult } = await DemoContractAbi__factory.deployContract(bytecode, wallet);
const { contract } = await waitForResult();

// #endregion typegen-demo-contract-factory-deploy

Expand All @@ -87,7 +90,8 @@ it('should throw when simulating via contract factory with wallet with no resour
const unfundedWallet = Wallet.generate({ provider });

const factory = new ContractFactory(bytecode, DemoContractAbi__factory.abi, fundedWallet);
const contract = await factory.deployContract();
const { waitForResult } = await factory.deployContract();
const { contract } = await waitForResult();
const contractInstance = DemoContractAbi__factory.connect(contract.id, unfundedWallet);

const { error } = await safeExec(() => contractInstance.functions.return_input(1337).simulate());
Expand All @@ -101,7 +105,8 @@ it('should not throw when dry running via contract factory with wallet with no r
const unfundedWallet = Wallet.generate({ provider });

const factory = new ContractFactory(bytecode, DemoContractAbi__factory.abi, fundedWallet);
const contract = await factory.deployContract();
const { waitForResult } = await factory.deployContract();
const { contract } = await waitForResult();
const contractInstance = DemoContractAbi__factory.connect(contract.id, unfundedWallet);

await expect(contractInstance.functions.return_input(1337).dryRun()).resolves.not.toThrow();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,11 @@ describe('configurable-constants', () => {

const factory = new ContractFactory(bin, abi, wallet);

const contract = await factory.deployContract({
const { waitForResult } = await factory.deployContract({
configurableConstants,
});

const { contract } = await waitForResult();
// #endregion configurable-constants-2

const { value } = await contract.functions.echo_configurables(true).simulate();
Expand All @@ -68,9 +70,11 @@ describe('configurable-constants', () => {

const factory = new ContractFactory(bin, abi, wallet);

const contract = await factory.deployContract({
const { waitForResult } = await factory.deployContract({
configurableConstants,
});

const { contract } = await waitForResult();
// #endregion configurable-constants-3

const { value } = await contract.functions.echo_configurables(false).simulate();
Expand Down
13 changes: 10 additions & 3 deletions apps/docs-snippets/src/guide/contracts/deploying-contracts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,20 @@ describe(__filename, () => {
// #region contract-setup-3
const factory = new ContractFactory(byteCode, abi, wallet);

const contract = await factory.deployContract();
const { contractId, transactionId, waitForResult } = await factory.deployContract();
// #endregion contract-setup-3

// #region contract-setup-4
const { value } = await contract.functions.echo_u8(15).simulate();
const { contract, transactionResult } = await waitForResult();
// #endregion contract-setup-4

// #region contract-setup-5
const { value } = await contract.functions.echo_u8(15).call();
// #endregion contract-setup-5

expect(transactionId).toBeDefined();
expect(contractId).toBeDefined();
expect(transactionResult.isStatusSuccess).toBeTruthy();
expect(value).toBe(15);
// #endregion contract-setup-4
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,21 @@ describe(__filename, () => {
const tokenArtifacts = getDocsSnippetsForcProject(DocSnippetProjectsEnum.SIMPLE_TOKEN);
const depositorArtifacts = getDocsSnippetsForcProject(DocSnippetProjectsEnum.TOKEN_DEPOSITOR);

simpleToken = await new ContractFactory(
const { waitForResult } = await new ContractFactory(
tokenArtifacts.binHexlified,
tokenArtifacts.abiContents,
wallet
).deployContract();

tokenDepositor = await new ContractFactory(
({ contract: simpleToken } = await waitForResult());

const { waitForResult: waitForResult2 } = await new ContractFactory(
depositorArtifacts.binHexlified,
depositorArtifacts.abiContents,
wallet
).deployContract();

({ contract: tokenDepositor } = await waitForResult2());
});

it('should successfully make call to another contract', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ describe(__filename, () => {
beforeAll(async () => {
wallet = await getTestWallet();
const factory = new ContractFactory(bin, abi, wallet);
contract = await factory.deployContract();

const { waitForResult } = await factory.deployContract();
({ contract } = await waitForResult());
contractId = contract.id;
});

Expand Down
14 changes: 10 additions & 4 deletions apps/docs-snippets/src/guide/contracts/multicalls.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,17 @@ describe(__filename, () => {
wallet
);

echoContract = await factory1.deployContract();
counterContract = await factory2.deployContract({
let { waitForResult } = await factory1.deployContract();
({ contract: echoContract } = await waitForResult());

({ waitForResult } = await factory2.deployContract({
storageSlots: counterArtifacts.storageSlots,
});
contextContract = await factory3.deployContract();
}));

({ contract: counterContract } = await waitForResult());

({ waitForResult } = await factory3.deployContract());
({ contract: contextContract } = await waitForResult());
});

it('should successfully submit multiple calls from the same contract function', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ describe('Custom Transactions from Contract Calls', () => {
senderWallet = await getTestWallet();
receiverWallet = Wallet.generate({ provider: senderWallet.provider });
const factory = new ContractFactory(binHexlified, abiContents, senderWallet);
contract = await factory.deployContract({ storageSlots });
const { waitForResult } = await factory.deployContract({ storageSlots });
({ contract } = await waitForResult());
abi = abiContents;
baseAssetId = senderWallet.provider.getBaseAssetId();
contract = await factory.deployContract({ storageSlots });
});

it('creates a custom transaction from a contract call', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ describe(__filename, () => {
provider = sender.provider;
baseAssetId = provider.getBaseAssetId();
const factory = new ContractFactory(binHexlified, abiContents, sender);
liquidityPoolContract = await factory.deployContract({
const { waitForResult } = await factory.deployContract({
configurableConstants: { TOKEN: { bits: baseAssetId } },
});
({ contract: liquidityPoolContract } = await waitForResult());
});

it('deposit and withdraw cookbook guide', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ describe(__filename, () => {
);
provider = sender.provider;
const factory = new ContractFactory(binHexlified, abiContents, sender);
deployedContract = await factory.deployContract();
const { waitForResult } = await factory.deployContract();
({ contract: deployedContract } = await waitForResult());
});

it('should successfully transfer asset to another account', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ describe(__filename, () => {
];
wallet = await getTestWallet(seedQuantities);
const factory = new ContractFactory(contractBin, contractAbi, wallet);
contract = await factory.deployContract();
const { waitForResult } = await factory.deployContract();
({ contract } = await waitForResult());
});

it('transfer multiple assets to a contract', async () => {
Expand Down
5 changes: 4 additions & 1 deletion apps/docs-snippets/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,12 @@ export const createAndDeployContractFromProject = async (

const contractFactory = new ContractFactory(binHexlified, abiContents, wallet);

return contractFactory.deployContract({
const { waitForResult } = await contractFactory.deployContract({
storageSlots,
});

const { contract } = await waitForResult();
return contract;
};

export const defaultTxParams = {
Expand Down
8 changes: 6 additions & 2 deletions apps/docs/src/guide/contracts/deploying-contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,18 @@ Load the contract bytecode and JSON ABI, generated from the Sway source, into th

## 4. Deploying the Contract

Initialize a [`ContractFactory`](../../api/Contract/ContractFactory.md) with the bytecode, ABI, and wallet. Deploy the contract and use its methods.
To deploy the contract, instantiate the [`ContractFactory`](../../api/Contract/ContractFactory.md) with the bytecode, ABI, and wallet. Then, call the `deployContract` method. This call resolves as soon as the transaction to deploy the contract is submitted and returns three items: the `contractId`, the `transactionId` and a `waitForResult` function.

<<< @/../../docs-snippets/src/guide/contracts/deploying-contracts.test.ts#contract-setup-3{ts:line-numbers}

The `contract` instance will be returned only after calling `waitForResult` and waiting for it to resolve. To avoid blocking the rest of your code, you can attach this promise to a hook or listener that will use the contract only after it is fully deployed.

<<< @/../../docs-snippets/src/guide/contracts/deploying-contracts.test.ts#contract-setup-4{ts:line-numbers}

## 5. Executing a Contract Call

Now that the contract is deployed, you can interact with it. In the following steps, you'll learn how to execute contract calls.

<<< @/../../docs-snippets/src/guide/contracts/deploying-contracts.test.ts#contract-setup-4{ts:line-numbers}
<<< @/../../docs-snippets/src/guide/contracts/deploying-contracts.test.ts#contract-setup-5{ts:line-numbers}

For a more comprehensive TypeScript-backed Fuel usage, learn how to [generate types from ABI](../fuels-cli/generating-types.md)
Loading

0 comments on commit 17bd929

Please sign in to comment.