Skip to content

Commit

Permalink
Merge branch 'master' into fix/move-type-check-to-lint
Browse files Browse the repository at this point in the history
  • Loading branch information
Rohit-Bhetal authored Nov 14, 2024
2 parents 4cf294a + b0e9c84 commit 3e3f161
Show file tree
Hide file tree
Showing 54 changed files with 740 additions and 761 deletions.
5 changes: 5 additions & 0 deletions .changeset/khaki-trees-wink.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"fuels": minor
---

feat!: `onDeploy` fuels config supports all Sway program types
6 changes: 6 additions & 0 deletions .changeset/little-moons-drive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@fuel-ts/contract": minor
"@fuel-ts/account": patch
---

chore!: refactor predicate and script deployment
5 changes: 5 additions & 0 deletions .changeset/many-rings-joke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fuel-ts/account": minor
---

chore!: mandate `abi` in `Predicate` constructor
4 changes: 4 additions & 0 deletions .changeset/orange-panthers-lay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
---

chore: use typegen'd outputs in some fuel-gauge tests
5 changes: 5 additions & 0 deletions .changeset/smart-olives-attend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fuel-ts/account": minor
---

chore!: remove `blockId` in transaction list responses
5 changes: 5 additions & 0 deletions .changeset/thirty-waves-grin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"fuels": patch
---

fix: bump proxy contract versions
6 changes: 6 additions & 0 deletions .changeset/yellow-trees-talk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@fuel-ts/transactions": patch
"@fuel-ts/account": patch
---

chore: fix receipts properties and deprecate incorrect ones
6 changes: 3 additions & 3 deletions apps/demo-fuels/fuels.config.full.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable no-console */
import { createConfig } from 'fuels';
import type { ContractDeployOptions, DeployedContract, FuelsConfig } from 'fuels';
import type { ContractDeployOptions, DeployedData, FuelsConfig } from 'fuels';

const MY_FIRST_DEPLOYED_CONTRACT_NAME = '';

Expand Down Expand Up @@ -91,9 +91,9 @@ export default createConfig({
// #endregion onBuild

// #region onDeploy
// #import { DeployedContract, FuelsConfig };
// #import { DeployedData, FuelsConfig };

onDeploy: (config: FuelsConfig, data: DeployedContract[]) => {
onDeploy: (config: FuelsConfig, data: DeployedData) => {
console.log('fuels:onDeploy', { config, data });
},
// #endregion onDeploy
Expand Down
28 changes: 15 additions & 13 deletions apps/docs-snippets2/src/predicates/deploying-predicates.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// #region full
import { Provider, Wallet, ContractFactory } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../env';
import { ConfigurablePin, ConfigurablePinLoader } from '../typegend/predicates';
Expand All @@ -10,20 +10,18 @@ const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const receiver = Wallet.generate({ provider });
const baseAssetId = provider.getBaseAssetId();

// We can deploy dyanmically or via `fuels deploy`
const factory = new ContractFactory(
ConfigurablePin.bytecode,
ConfigurablePin.abi,
wallet
);
const { waitForResult: waitForDeploy } =
await factory.deployAsBlobTxForScript();
// We can deploy dynamically or via `fuels deploy`
const originalPredicate = new ConfigurablePin({
provider,
});

const { waitForResult: waitForDeploy } = await originalPredicate.deploy(wallet);
await waitForDeploy();

// First, we will need to instantiate the script via it's loader bytecode.
// This can be imported from the typegen outputs that were created on `fuels deploy`.
// Then we can use the predicate as we would normally, such as overriding the configurables.
const predicate = new ConfigurablePinLoader({
const loaderPredicate = new ConfigurablePinLoader({
data: [23],
provider,
configurableConstants: {
Expand All @@ -32,17 +30,21 @@ const predicate = new ConfigurablePinLoader({
});

// Now, let's fund the predicate
const fundTx = await wallet.transfer(predicate.address, 100_000, baseAssetId);
const fundTx = await wallet.transfer(
loaderPredicate.address,
100_000,
baseAssetId
);
await fundTx.waitForResult();

// Then we'll execute the transfer and validate the predicate
const transferTx = await predicate.transfer(
const transferTx = await loaderPredicate.transfer(
receiver.address,
1000,
baseAssetId
);
const { isStatusSuccess } = await transferTx.waitForResult();
// #endregion full

console.log('Predicate defined', predicate);
console.log('Predicate defined', loaderPredicate);
console.log('Should fund predicate successfully', isStatusSuccess);
10 changes: 3 additions & 7 deletions apps/docs-snippets2/src/scripts/deploying-scripts.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ContractFactory, Provider, Wallet, hexlify } from 'fuels';
import { Provider, Wallet, hexlify } from 'fuels';
import { launchTestNode } from 'fuels/test-utils';

import {
Expand All @@ -16,13 +16,9 @@ const {
const providerUrl = testProvider.url;
const WALLET_PVT_KEY = hexlify(testWallet.privateKey);

const factory = new ContractFactory(
TypegenScript.bytecode,
TypegenScript.abi,
testWallet
);
const originalScript = new TypegenScript(testWallet);
const { waitForResult: waitForDeploy } =
await factory.deployAsBlobTxForScript();
await originalScript.deploy(testWallet);
await waitForDeploy();

// #region deploying-scripts
Expand Down
1 change: 1 addition & 0 deletions packages/account/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export * from './wallet-manager';
export * from './predicate';
export * from './providers';
export * from './connectors';
export { deployScriptOrPredicate } from './utils/deployScriptOrPredicate';
94 changes: 36 additions & 58 deletions packages/account/src/predicate/predicate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Interface } from '@fuel-ts/abi-coder';
import { Address } from '@fuel-ts/address';
import { ErrorCode, FuelError } from '@fuel-ts/errors';
import type { BytesLike } from '@fuel-ts/interfaces';
import { arrayify, hexlify, concat } from '@fuel-ts/utils';
import { arrayify, hexlify } from '@fuel-ts/utils';

import type { FakeResources } from '../account';
import { Account } from '../account';
Expand All @@ -23,6 +23,7 @@ import type {
TransactionRequestLike,
TransactionResponse,
} from '../providers';
import { deployScriptOrPredicate } from '../utils/deployScriptOrPredicate';

import { getPredicateRoot } from './utils';

Expand All @@ -32,19 +33,11 @@ export type PredicateParams<
> = {
bytecode: BytesLike;
provider: Provider;
abi?: JsonAbi;
abi: JsonAbi;
data?: TData;
configurableConstants?: TConfigurables;
loaderBytecode?: BytesLike;
};

function getDataOffset(binary: Uint8Array): number {
const buffer = binary.buffer.slice(binary.byteOffset + 8, binary.byteOffset + 16);
const dataView = new DataView(buffer);
const dataOffset = dataView.getBigUint64(0, false); // big-endian
return Number(dataOffset);
}

/**
* `Predicate` provides methods to populate transaction data with predicate information and sending transactions with them.
*/
Expand All @@ -54,8 +47,7 @@ export class Predicate<
> extends Account {
bytes: Uint8Array;
predicateData: TData = [] as unknown as TData;
interface?: Interface;
loaderBytecode: BytesLike = '';
interface: Interface;

/**
* Creates an instance of the Predicate class.
Expand All @@ -72,12 +64,6 @@ export class Predicate<
provider,
data,
configurableConstants,
/**
* TODO: Implement a getBytes method within the Predicate class. This method should return the loaderBytecode if it is set.
* The getBytes method should be used in all places where we use this.bytes.
* Note: Do not set loaderBytecode to a default string here; it should remain undefined when not provided.
*/
loaderBytecode = '',
}: PredicateParams<TData, TConfigurables>) {
const { predicateBytes, predicateInterface } = Predicate.processPredicateData(
bytecode,
Expand All @@ -89,7 +75,6 @@ export class Predicate<

this.bytes = predicateBytes;
this.interface = predicateInterface;
this.loaderBytecode = loaderBytecode;
if (data !== undefined && data.length > 0) {
this.predicateData = data;
}
Expand Down Expand Up @@ -168,20 +153,17 @@ export class Predicate<
*/
private static processPredicateData(
bytes: BytesLike,
jsonAbi?: JsonAbi,
jsonAbi: JsonAbi,
configurableConstants?: { [name: string]: unknown }
) {
let predicateBytes = arrayify(bytes);
let abiInterface: Interface | undefined;
const abiInterface: Interface = new Interface(jsonAbi);

if (jsonAbi) {
abiInterface = new Interface(jsonAbi);
if (abiInterface.functions.main === undefined) {
throw new FuelError(
ErrorCode.ABI_MAIN_METHOD_MISSING,
'Cannot use ABI without "main" function.'
);
}
if (abiInterface.functions.main === undefined) {
throw new FuelError(
ErrorCode.ABI_MAIN_METHOD_MISSING,
'Cannot use ABI without "main" function.'
);
}

if (configurableConstants && Object.keys(configurableConstants).length) {
Expand Down Expand Up @@ -246,19 +228,11 @@ export class Predicate<
private static setConfigurableConstants(
bytes: Uint8Array,
configurableConstants: { [name: string]: unknown },
abiInterface?: Interface,
loaderBytecode?: BytesLike
abiInterface: Interface
) {
const mutatedBytes = bytes;

try {
if (!abiInterface) {
throw new FuelError(
ErrorCode.INVALID_CONFIGURABLE_CONSTANTS,
'Cannot validate configurable constants because the Predicate was instantiated without a JSON ABI'
);
}

if (Object.keys(abiInterface.configurables).length === 0) {
throw new FuelError(
ErrorCode.INVALID_CONFIGURABLE_CONSTANTS,
Expand All @@ -280,26 +254,6 @@ export class Predicate<

mutatedBytes.set(encoded, offset);
});

if (loaderBytecode) {
/**
* TODO: We mutate the predicate bytes here to be the loader bytes only if the configurables are being set.
* What we actually need to do here is to mutate the loader bytes to include the configurables.
*/
const offset = getDataOffset(bytes);

// update the dataSection here as necessary (with configurables)
const dataSection = mutatedBytes.slice(offset);

const dataSectionLen = dataSection.length;

// Convert dataSectionLen to big-endian bytes
const dataSectionLenBytes = new Uint8Array(8);
const dataSectionLenDataView = new DataView(dataSectionLenBytes.buffer);
dataSectionLenDataView.setBigUint64(0, BigInt(dataSectionLen), false);

mutatedBytes.set(concat([loaderBytecode, dataSectionLenBytes, dataSection]));
}
} catch (err) {
throw new FuelError(
ErrorCode.INVALID_CONFIGURABLE_CONSTANTS,
Expand Down Expand Up @@ -348,4 +302,28 @@ export class Predicate<

return index;
}

/**
*
* @param account - The account used to pay the deployment costs.
* @returns The _blobId_ and a _waitForResult_ callback that returns the deployed predicate
* once the blob deployment transaction finishes.
*
* The returned loader predicate will have the same configurable constants
* as the original predicate which was used to generate the loader predicate.
*/
async deploy<T = this>(account: Account) {
return deployScriptOrPredicate<T>({
deployer: account,
abi: this.interface.jsonAbi,
bytecode: this.bytes,
loaderInstanceCallback: (loaderBytecode, newAbi) =>
new Predicate({
bytecode: loaderBytecode,
abi: newAbi,
provider: this.provider,
data: this.predicateData,
}) as T,
});
}
}
Loading

0 comments on commit 3e3f161

Please sign in to comment.