Skip to content
Merged
Show file tree
Hide file tree
Changes from 177 commits
Commits
Show all changes
179 commits
Select commit Hold shift + click to select a range
8f9f28d
feat: intitial support for deploying large contract via blob tx
danielbate Jul 24, 2024
853a442
fix: blob import
danielbate Jul 24, 2024
3173287
feat: remove instanceof checks
danielbate Jul 24, 2024
740745c
feat: blob tx spec and validity fixes
danielbate Jul 24, 2024
2f013fc
feat: correctly get blobIds
danielbate Jul 24, 2024
1e1fbb6
feat: add loader instructions
danielbate Jul 25, 2024
0bbcfdc
feat: append blob ids to loader
danielbate Jul 25, 2024
a0e761e
feat: lots of cleanup
danielbate Jul 25, 2024
584cd22
Merge branch 'master' of https://github.com/FuelLabs/fuels-ts into db…
danielbate Jul 25, 2024
3baba23
feat: fix wait for result in blob tx
danielbate Jul 25, 2024
57e8410
chore: linting
danielbate Jul 25, 2024
e04d773
test: test mods
danielbate Jul 25, 2024
6829095
chore: add demo package build filter
danielbate Jul 25, 2024
cfe4029
test: add max size test for initial deploy method
danielbate Jul 26, 2024
1a04238
Merge branch 'master' of https://github.com/FuelLabs/fuels-ts into db…
danielbate Jul 26, 2024
7d93486
feat: upgrade asm package
danielbate Jul 29, 2024
1b98257
Merge branch 'master' of https://github.com/FuelLabs/fuels-ts into db…
danielbate Jul 30, 2024
b14c753
feat: fix blob cost estimation, funding and blob id handling
danielbate Jul 31, 2024
f683923
feat: dynamic blob sizing
danielbate Jul 31, 2024
fd95a20
chore: lint
danielbate Jul 31, 2024
a7608f7
Merge branch 'master' of https://github.com/FuelLabs/fuels-ts into db…
danielbate Aug 1, 2024
60e7db7
feat: fuel-core with ed19
danielbate Aug 1, 2024
2335817
feat: v4 gas costs, loader fixes and better blob id handling
danielbate Aug 2, 2024
b725b29
feat: simplify funding
danielbate Aug 2, 2024
e60ef9b
feat: loader contract fixes
danielbate Aug 2, 2024
22864f3
chore: remove redundant code
danielbate Aug 2, 2024
adb4548
Merge branch 'master' of https://github.com/FuelLabs/fuels-ts into db…
danielbate Aug 5, 2024
7d3b0fb
feat: isTransactionType helper
danielbate Aug 5, 2024
3bafa2b
chore: doc blocks and pr refactors
danielbate Aug 5, 2024
7c63591
chore: remove math from contract
danielbate Aug 5, 2024
0a97c56
feat: use fuel-core release
danielbate Aug 6, 2024
ebd92fc
chore: isTransactionType cleanups
danielbate Aug 6, 2024
7ecfc8c
feat: use regex for response id check
danielbate Aug 6, 2024
bb24c41
chore: cleanups
danielbate Aug 6, 2024
96b6e0d
feat: chunk size tolerance
danielbate Aug 6, 2024
0ce01e2
test: deploy test cases
danielbate Aug 6, 2024
57adf3d
feat: add ed19 dependent cost to chain
danielbate Aug 6, 2024
d2ebf94
feat: getBytecodeSize
danielbate Aug 6, 2024
dda9dc9
docs: documentation for deploy methods
danielbate Aug 6, 2024
aac2745
chore: use tolerance const
danielbate Aug 7, 2024
36358fa
chore: update docs
danielbate Aug 7, 2024
4194751
chore: update docs
danielbate Aug 7, 2024
bf7ba3b
feat: use [email protected]
danielbate Aug 7, 2024
2aa7735
chore: add test groups
danielbate Aug 7, 2024
82e08fb
Merge branch 'master' of https://github.com/FuelLabs/fuels-ts into db…
danielbate Aug 7, 2024
0ca3c42
Merge branch 'db/feat/blob-contract-deploys' of https://github.com/Fu…
danielbate Aug 7, 2024
cf5832c
docs: add chunk tolerance documentation
danielbate Aug 7, 2024
3f76a9a
chore: fix doc
danielbate Aug 7, 2024
90e557e
chore: remove redundant method
danielbate Aug 7, 2024
eac868b
chore: deployContractOptions -> deployOptions
danielbate Aug 7, 2024
60322d6
feat: isTransactionTypeBlob
danielbate Aug 7, 2024
16f9189
Merge branch 'master' of https://github.com/FuelLabs/fuels-ts into db…
danielbate Aug 7, 2024
e6e736c
feat: fail blob deploys for invalid funds
danielbate Aug 7, 2024
563a702
chore: fix casing in gas config
danielbate Aug 7, 2024
29d4aa6
chore: linting
danielbate Aug 7, 2024
648999b
test: add e2e
danielbate Aug 7, 2024
350ca5c
chore: enable e2e
danielbate Aug 7, 2024
e85c688
chore: update e2e timeout
danielbate Aug 7, 2024
1d534ee
chore: add networkUrl to e2e log
danielbate Aug 7, 2024
e1690de
ajust fuel core version
Torres-ssf Aug 7, 2024
5f74186
update fuel core schema
Torres-ssf Aug 7, 2024
dbddb32
fixing test case
Torres-ssf Aug 7, 2024
7cefdb6
fix maxFee tests
Torres-ssf Aug 7, 2024
8dd8d53
simplify some tests
Torres-ssf Aug 7, 2024
a881d65
ajust some tests
Torres-ssf Aug 7, 2024
2e8a396
chore: add missing test groups
danielbate Aug 7, 2024
389d917
Merge branch 'db/feat/blob-contract-deploys' of https://github.com/Fu…
danielbate Aug 7, 2024
5000b71
chore: enable devnet test
danielbate Aug 7, 2024
a1d47e9
chore: enable only devnet
danielbate Aug 7, 2024
0ec2b48
add group test
Torres-ssf Aug 7, 2024
75a0606
fix test
Torres-ssf Aug 7, 2024
effa5b7
feat: optimise cost estimation
danielbate Aug 7, 2024
2a1d070
add missing import from suggestion
Torres-ssf Aug 7, 2024
097f4ae
make linter happy
Torres-ssf Aug 7, 2024
6fbbc0a
increate test timeout
Torres-ssf Aug 7, 2024
da27f7d
increase blob tx tests timeout
Torres-ssf Aug 7, 2024
9e966ce
remove .only
Torres-ssf Aug 7, 2024
71cd33e
feat: pass deploy options to size estimation
danielbate Aug 8, 2024
3417fff
Merge branch 'db/feat/blob-contract-deploys' of https://github.com/Fu…
danielbate Aug 8, 2024
65b4bae
chore: disable testnet
danielbate Aug 8, 2024
cf1a3c6
test: update isTypeBlob test
danielbate Aug 8, 2024
5208c09
test: use typegend factories in some factory tests
danielbate Aug 8, 2024
a5a4aa8
Merge branch 'db/feat/blob-contract-deploys' of https://github.com/Fu…
danielbate Aug 8, 2024
0641c7d
test: add missing properties to test chain config
danielbate Aug 8, 2024
55d0739
chore: lint
danielbate Aug 8, 2024
a321b81
docs: add loader script rference
danielbate Aug 8, 2024
7905c38
chore: improve chunk fuc
danielbate Aug 8, 2024
d4b2f27
chore: remove redundant cast
danielbate Aug 8, 2024
8339d10
docs: update deploying contracts intro
danielbate Aug 8, 2024
6f1d2e1
feat: update max size error message
danielbate Aug 8, 2024
6a9fb26
chore: small refactor for factoryt
danielbate Aug 8, 2024
0d7c34f
chore: refactor
danielbate Aug 8, 2024
339ec6c
chore: nit
danielbate Aug 8, 2024
51901f6
docs: update errors docs
danielbate Aug 8, 2024
f08abe5
test: transactionRequestify tests
danielbate Aug 8, 2024
5091527
test: add another devnet test
danielbate Aug 8, 2024
fd23a7c
doc: add further info around chunk size tolerance
danielbate Aug 8, 2024
13f6dec
Merge branch 'master' of https://github.com/FuelLabs/fuels-ts into db…
danielbate Aug 8, 2024
a86a6ac
chore: return e2e to defualts
danielbate Aug 8, 2024
83bc54b
chore: add spell check words
danielbate Aug 8, 2024
a71e4ba
chore: remove breaking change
danielbate Aug 8, 2024
fda0c11
chore: changeset
danielbate Aug 8, 2024
f9879c8
fix: arrayify bytecode
danielbate Aug 8, 2024
efdc3ed
fix: use workspace version
danielbate Aug 8, 2024
581d662
chore: lock file
danielbate Aug 8, 2024
12ffc55
fix: changeset
danielbate Aug 8, 2024
ab792e9
chore: depsync
danielbate Aug 8, 2024
9dff6c0
chore: update lock
danielbate Aug 8, 2024
7117181
Merge branch 'master' into db/feat/blob-contract-deploys
danielbate Aug 8, 2024
4a3f1c5
docs: fix links
danielbate Aug 8, 2024
a9cbbce
Merge branch 'db/feat/blob-contract-deploys' of https://github.com/Fu…
danielbate Aug 8, 2024
09d809c
feat: BytesLike in contract factory
danielbate Aug 9, 2024
63f13f1
chore: disable testnet
danielbate Aug 9, 2024
080df58
Merge branch 'master' of https://github.com/FuelLabs/fuels-ts into db…
danielbate Aug 9, 2024
586a0da
test: fix docs assertion
danielbate Aug 9, 2024
853bf35
feat: account for max tx size consensus param
danielbate Aug 9, 2024
369576b
test: blob configurable test
danielbate Aug 9, 2024
65d6c7c
test: fix assertion
danielbate Aug 9, 2024
469f8d3
test: deploy via blobs with storage
danielbate Aug 9, 2024
15e8510
feat: chunkSizeTolerance -> chunkSizeOverride
danielbate Aug 9, 2024
41da418
feat: manually use v4 gas types
danielbate Aug 9, 2024
83bc39f
chore: update snippet
danielbate Aug 9, 2024
1312fe3
feat: user patch fuel-core, fixes for devnet, blob ID already uploade…
danielbate Aug 9, 2024
434aa92
chore: chunkSizeTolerance ->chunkSizeOverride
danielbate Aug 9, 2024
a405449
Merge branch 'master' of https://github.com/FuelLabs/fuels-ts into db…
danielbate Aug 9, 2024
84a876d
test: e2e updates
danielbate Aug 9, 2024
38db5a5
chore: merge conflict
danielbate Aug 9, 2024
27ee501
chore: restore fuel-core version
danielbate Aug 9, 2024
b592cf9
chore: fix built in version
danielbate Aug 9, 2024
9bf6c1c
chore: 0.32.1 upgrade
danielbate Aug 10, 2024
7d0ecad
chore: changeset
danielbate Aug 10, 2024
9ecb1dc
choer: e2e
danielbate Aug 10, 2024
4d685ef
Merge branch 'master' of https://github.com/FuelLabs/fuels-ts into db…
danielbate Aug 10, 2024
3eb9e1e
chore: lint
danielbate Aug 10, 2024
22013c2
chore: enable testnet
danielbate Aug 10, 2024
c84c76a
chore: lint
danielbate Aug 10, 2024
226455c
chore: update changeset
danielbate Aug 11, 2024
faa4c86
docs: add typegen to snippet
danielbate Aug 12, 2024
da41c8b
Merge branch 'db/feat/blob-contract-deploys' of https://github.com/Fu…
danielbate Aug 12, 2024
9a12071
chore: dont export chunk size constant
danielbate Aug 12, 2024
a0991d7
undo test modification after fuel-core patch
Torres-ssf Aug 12, 2024
71dceae
docs: update doc
danielbate Aug 12, 2024
041bbaf
feat: override -> multiplier
danielbate Aug 12, 2024
d2f0987
Merge branch 'db/feat/blob-contract-deploys' of https://github.com/Fu…
danielbate Aug 12, 2024
5223798
Merge branch 'master' of https://github.com/FuelLabs/fuels-ts into db…
danielbate Aug 12, 2024
4cb5ff6
test: add bytecode size check
danielbate Aug 12, 2024
1b17536
test: fix assertion
danielbate Aug 12, 2024
f7737a8
Merge branch 'master' of https://github.com/FuelLabs/fuels-ts into db…
danielbate Aug 13, 2024
05bd455
Merge branch 'master' into db/feat/blob-contract-deploys
danielbate Aug 13, 2024
5999897
chore: follow ups
danielbate Aug 13, 2024
1ebb3db
increase funding attempts to 5
Torres-ssf Aug 13, 2024
85e98eb
create error code
Torres-ssf Aug 13, 2024
0a5dfb4
throw error if funding attempts are exceed
Torres-ssf Aug 13, 2024
2eb233d
add gasPrice to fund method params to avoid re-fetch
Torres-ssf Aug 13, 2024
4b931ee
chore: remove blob e2e
danielbate Aug 13, 2024
a6d3daf
Merge branch 'db/feat/blob-contract-deploys' of github.com:FuelLabs/f…
Torres-ssf Aug 13, 2024
4930b8e
Merge branch 'db/feat/blob-contract-deploys' of https://github.com/Fu…
danielbate Aug 13, 2024
1b4c38d
chore: remove script infinite
danielbate Aug 13, 2024
373dbb1
Merge branch 'master' of https://github.com/FuelLabs/fuels-ts into db…
danielbate Aug 13, 2024
4e76889
Merge branch 'db/feat/blob-contract-deploys' into db/feat/blob-sync-d…
danielbate Aug 13, 2024
b21f256
chore: lint
danielbate Aug 13, 2024
25851f1
Merge branch 'db/feat/blob-sync-deploys' of https://github.com/FuelLa…
danielbate Aug 13, 2024
8aca437
chore: reset the bare
danielbate Aug 14, 2024
eeddb07
feat: getTransactionId promise
danielbate Aug 14, 2024
6990bb2
Merge branch 'master' of https://github.com/FuelLabs/fuels-ts into db…
danielbate Aug 14, 2024
8f69f4b
chore: further conflicts
danielbate Aug 14, 2024
af3d9fd
chore: reintroduce test groups in e2e
danielbate Aug 14, 2024
f20242f
Merge branch 'master' into db/feat/blob-sync-deploys
danielbate Aug 14, 2024
a484486
chore: fix tests and merge conflictt
danielbate Aug 14, 2024
8e964e8
Merge branch 'db/feat/blob-sync-deploys' of https://github.com/FuelLa…
danielbate Aug 14, 2024
ed1753a
Merge branch 'master' into db/feat/blob-sync-deploys
danielbate Aug 14, 2024
a7b05ad
chore: fix test group
danielbate Aug 14, 2024
37d3942
Merge branch 'db/feat/blob-sync-deploys' of https://github.com/FuelLa…
danielbate Aug 14, 2024
4e5bdf1
feat: improve polling and docs
danielbate Aug 14, 2024
80546a0
chore: changeset
danielbate Aug 14, 2024
b6814ce
chore: getTransactionId -> waitForTransactionId
danielbate Aug 14, 2024
9bb8102
doc: make blob note more verbose
danielbate Aug 14, 2024
980ec66
feat: remove poll for resolver
danielbate Aug 14, 2024
14022af
chore: lint
danielbate Aug 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/forty-apes-tell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fuel-ts/contract": minor
---

feat!: non-blocking blob deployment
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ describe('Deploying Contracts', () => {

// #region deploy
// Deploy the contract
const { waitForResult, contractId, transactionId } = await factory.deploy();
const { waitForResult, contractId, waitForTransactionId } = await factory.deploy();
// Retrieve the transactionId
const transactionId = await waitForTransactionId();
// Await it's deployment
const { contract, transactionResult } = await waitForResult();
// #endregion deploy
Expand Down Expand Up @@ -90,14 +92,15 @@ describe('Deploying Contracts', () => {
const factory = new ContractFactory(bytecode, abi, wallet);

// Deploy the contract as blobs
const { waitForResult, contractId, transactionId } = await factory.deployAsBlobTx({
const { waitForResult, contractId, waitForTransactionId } = await factory.deployAsBlobTx({
// Increasing chunk size multiplier to be 90% of the max chunk size
chunkSizeMultiplier: 0.9,
});
// Await it's deployment
const { contract, transactionResult } = await waitForResult();
// #endregion blobs

const transactionId = await waitForTransactionId();
expect(contract).toBeDefined();
expect(transactionId).toBeDefined();
expect(transactionResult.status).toBeTruthy();
Expand Down
6 changes: 3 additions & 3 deletions apps/docs/src/guide/contracts/deploying-contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ Once you have the contract artifacts, it can be passed to the `ContractFactory`

As mentioned earlier, there are two different processes for contract deployment handled by the `ContractFactory`. These can be used interchangeably, however, the `deploy` method is recommended as it will automatically choose the appropriate deployment process based on the contract size.

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.
This call resolves as soon as the transaction to deploy the contract is submitted and returns three items: the `contractId`, a `waitForTransactionId` function and a `waitForResult` function.

<<< @/../../docs-snippets/src/guide/contracts/deploying-contracts.test.ts#deploy{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.
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. Similarly, the transaction ID is only available once the underlying transaction has been funded. To avoid blocking the code until the ID is ready, you can use the `waitForTransactionId` function to await it's retrieval.

### 3. Executing a Contract Call

Expand All @@ -59,4 +59,4 @@ In the above guide we use the recommended `deploy` method. If you are working wi

In the above example, we also pass a `chunkSizeMultiplier` option to the deployment method. The SDK will attempt to chunk the contract to the most optimal about, however the transaction size can fluctuate and you can also be limited by request size limits against the node. By default we set a multiplier of 0.95, meaning the chunk size will be 95% of the potential maximum size, however you can adjust this to suit your needs and ensure the transaction passes. It must be set to a value between 0 and 1.

> **Note:** Blob deployments contain multiple dependent transactions, so you will need to wait longer than usual for the contract to be fully deployed and can be interacted with.
> **Note:** Deploying large contracts using blob transactions will take more time. Each transaction is dependent and has to wait for a block to be produced before it gets mined. Then a create transaction is submitted as normal. So you will need to wait longer than usual for the contract to be fully deployed and can be interacted with.
124 changes: 77 additions & 47 deletions packages/contract/src/contract-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import type { BytesLike } from '@fuel-ts/interfaces';
import { bn } from '@fuel-ts/math';
import { Contract } from '@fuel-ts/program';
import type { StorageSlot } from '@fuel-ts/transactions';
import { arrayify, isDefined } from '@fuel-ts/utils';
import { arrayify, isDefined, sleep } from '@fuel-ts/utils';

import { getLoaderInstructions, getContractChunks } from './loader';
import { getContractId, getContractStorageRoot, hexlifyWithPrefix } from './util';
Expand All @@ -41,8 +41,8 @@ export type DeployContractOptions = {
} & CreateTransactionRequestLike;

export type DeployContractResult<TContract extends Contract = Contract> = {
transactionId: string;
contractId: string;
waitForTransactionId: () => Promise<string>;
waitForResult: () => Promise<{
contract: TContract;
transactionResult: TransactionResult<TransactionType.Create>;
Expand Down Expand Up @@ -235,7 +235,11 @@ export default class ContractFactory {
return { contract, transactionResult };
};

return { waitForResult, contractId, transactionId: transactionResponse.id };
return {
contractId,
waitForTransactionId: () => Promise.resolve(transactionResponse.id),
waitForResult,
};
}

/**
Expand All @@ -255,7 +259,7 @@ export default class ContractFactory {
this.setConfigurableConstants(configurableConstants);
}

// Generate the chunks based on the maximum chunk size
// Generate the chunks based on the maximum chunk size and create blob txs
const chunkSize = this.getMaxChunkSize(deployOptions, chunkSizeMultiplier);
const chunks = getContractChunks(arrayify(this.bytecode), chunkSize).map((c) => {
const transactionRequest = this.blobTransactionRequest({
Expand All @@ -269,10 +273,19 @@ export default class ContractFactory {
};
});

// Check the account can afford to deploy all chunks
// Generate the associated create tx for the loader contract
const blobIds = chunks.map(({ blobId }) => blobId);
const loaderBytecode = getLoaderInstructions(blobIds);
const { contractId, transactionRequest: createRequest } = this.createTransactionRequest({
bytecode: loaderBytecode,
...deployOptions,
});

// Check the account can afford to deploy all chunks and loader
let totalCost = bn(0);
const chainInfo = account.provider.getChain();
const gasPrice = await account.provider.estimateGasPrice(10);
const priceFactor = chainInfo.consensusParameters.feeParameters.gasPriceFactor;
const estimatedBlobIds: string[] = [];

for (const { transactionRequest, blobId } of chunks) {
Expand All @@ -281,73 +294,90 @@ export default class ContractFactory {
const minFee = calculateGasFee({
gasPrice,
gas: minGas,
priceFactor: chainInfo.consensusParameters.feeParameters.gasPriceFactor,
priceFactor,
tip: transactionRequest.tip,
}).add(1);

totalCost = totalCost.add(minFee);
estimatedBlobIds.push(blobId);
}
const createMinGas = createRequest.calculateMinGas(chainInfo);
const createMinFee = calculateGasFee({
gasPrice,
gas: createMinGas,
priceFactor,
tip: createRequest.tip,
}).add(1);
totalCost = totalCost.add(createMinFee);
}
if (totalCost.gt(await account.getBalance())) {
throw new FuelError(ErrorCode.FUNDS_TOO_LOW, 'Insufficient balance to deploy contract.');
}

// Upload the blob if it hasn't been uploaded yet. Duplicate blob IDs will fail gracefully.
const uploadedBlobs: string[] = [];
// Transaction id is unset until we have funded the create tx, which is dependent on the blob txs
let transactionId: string;

// Deploy the chunks as blob txs
for (const { blobId, transactionRequest } of chunks) {
if (!uploadedBlobs.includes(blobId)) {
const fundedBlobRequest = await this.fundTransactionRequest(
transactionRequest,
deployOptions
);
const waitForResult = async () => {
// Upload the blob if it hasn't been uploaded yet. Duplicate blob IDs will fail gracefully.
const uploadedBlobs: string[] = [];
// Deploy the chunks as blob txs
for (const { blobId, transactionRequest } of chunks) {
if (!uploadedBlobs.includes(blobId)) {
const fundedBlobRequest = await this.fundTransactionRequest(
transactionRequest,
deployOptions
);

let result: TransactionResult<TransactionType.Blob>;

try {
const blobTx = await account.sendTransaction(fundedBlobRequest);
result = await blobTx.waitForResult();
} catch (err: unknown) {
// Core will throw for blobs that have already been uploaded, but the blobId
// is still valid so we can use this for the loader contract
if ((<Error>err).message.indexOf(`BlobId is already taken ${blobId}`) > -1) {
// eslint-disable-next-line no-continue
continue;
let result: TransactionResult<TransactionType.Blob>;

try {
const blobTx = await account.sendTransaction(fundedBlobRequest);
result = await blobTx.waitForResult();
} catch (err: unknown) {
// Core will throw for blobs that have already been uploaded, but the blobId
// is still valid so we can use this for the loader contract
if ((<Error>err).message.indexOf(`BlobId is already taken ${blobId}`) > -1) {
// eslint-disable-next-line no-continue
continue;
}

throw new FuelError(ErrorCode.TRANSACTION_FAILED, 'Failed to deploy contract chunk');
}

throw new FuelError(ErrorCode.TRANSACTION_FAILED, 'Failed to deploy contract chunk');
}
if (!result.status || result.status !== TransactionStatus.success) {
throw new FuelError(ErrorCode.TRANSACTION_FAILED, 'Failed to deploy contract chunk');
}

if (!result.status || result.status !== TransactionStatus.success) {
throw new FuelError(ErrorCode.TRANSACTION_FAILED, 'Failed to deploy contract chunk');
uploadedBlobs.push(blobId);
}

uploadedBlobs.push(blobId);
}
}

// Get the loader bytecode
const blobIds = chunks.map(({ blobId }) => blobId);
const loaderBytecode = getLoaderInstructions(blobIds);

// Deploy the loader contract via create tx
const { contractId, transactionRequest: createRequest } = this.createTransactionRequest({
bytecode: loaderBytecode,
...deployOptions,
});
await this.fundTransactionRequest(createRequest, deployOptions);
const transactionResponse = await account.sendTransaction(createRequest);

const waitForResult = async () => {
await this.fundTransactionRequest(createRequest, deployOptions);
transactionId = createRequest.getTransactionId(account.provider.getChainId());
const transactionResponse = await account.sendTransaction(createRequest);
const transactionResult = await transactionResponse.waitForResult<TransactionType.Create>();
const contract = new Contract(contractId, this.interface, account) as TContract;

return { contract, transactionResult };
};

return { waitForResult, contractId, transactionId: transactionResponse.id };
const waitForTransactionId = async () => {
const maxPollingTime = 15_000_000; // 15 Minutes
const timePerPoll = 500; // 1/2 Second
const maxPollingAttempts = maxPollingTime / timePerPoll;
let attempts = 0;

while (!transactionId) {
if (attempts++ > maxPollingAttempts) {
throw new FuelError(ErrorCode.TRANSACTION_FAILED, 'Failed to retrieve transaction ID');
}

await sleep(timePerPoll);
}
return Promise.resolve(transactionId);
};

return { waitForResult, contractId, waitForTransactionId };
}

/**
Expand Down
28 changes: 28 additions & 0 deletions packages/fuel-gauge/src/contract-factory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,34 @@ describe('Contract Factory', () => {
expect(value.toNumber()).toBe(1001);
}, 15000);

it('deploys large contracts via blobs and awaits transaction id', async () => {
using launched = await launchTestNode({
nodeOptions: {
args: ['--tx-pool-ttl', '1s'],
},
providerOptions: {
resourceCacheTTL: -1,
},
});

const {
wallets: [wallet],
} = launched;

const factory = new ContractFactory(LargeContractFactory.bytecode, LargeContract.abi, wallet);
const deploy = await factory.deployAsBlobTx<LargeContract>();
const initTxId = deploy.waitForTransactionId();
expect(initTxId).toStrictEqual(new Promise(() => {}));
const { contract } = await deploy.waitForResult();
expect(contract.id).toBeDefined();
const awaitTxId = await deploy.waitForTransactionId();
expect(awaitTxId).toBeTruthy();

const call = await contract.functions.something().call();
const { value } = await call.waitForResult();
expect(value.toNumber()).toBe(1001);
});

it('deploys large contracts via blobs [padded]', async () => {
using launched = await launchTestNode({
providerOptions: {
Expand Down