From a82f744673bb1d9fe91a9646c4b6adfee631fa03 Mon Sep 17 00:00:00 2001 From: YaTut1901 Date: Thu, 14 Nov 2024 13:18:51 +0200 Subject: [PATCH 1/6] chore(): added emthod to duplicate predicate --- packages/account/src/predicate/predicate.ts | 20 ++++++++++++++++ .../account/test/fixtures/predicate-abi.ts | 8 ++++++- .../account/test/predicate-functions.test.ts | 23 +++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/packages/account/src/predicate/predicate.ts b/packages/account/src/predicate/predicate.ts index 3d8957f883b..4bad1dfa9c3 100644 --- a/packages/account/src/predicate/predicate.ts +++ b/packages/account/src/predicate/predicate.ts @@ -95,6 +95,26 @@ export class Predicate< } } + /** + * Creates a new Predicate instance with updated parameters while maintaining the original bytecode and ABI + * + * @param params - Object containing optional new configurableConstants and data + * @returns A new Predicate instance with the updated parameters + */ + toNewInstance(params: { + configurableConstants?: TConfigurables; + data?: TData; + }): Predicate { + return new Predicate({ + bytecode: this.bytes, + abi: this.interface?.jsonAbi, + provider: this.provider, + data: params.data ?? this.predicateData, + configurableConstants: params.configurableConstants, + loaderBytecode: this.loaderBytecode, + }); + } + /** * Populates the transaction data with predicate data. * diff --git a/packages/account/test/fixtures/predicate-abi.ts b/packages/account/test/fixtures/predicate-abi.ts index 91bf0b52c06..b8a792d2907 100644 --- a/packages/account/test/fixtures/predicate-abi.ts +++ b/packages/account/test/fixtures/predicate-abi.ts @@ -30,5 +30,11 @@ export const predicateAbi: JsonAbi = { ], loggedTypes: [], messagesTypes: [], - configurables: [], + configurables: [ + { + name: 'value', + concreteTypeId: 'b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903', + offset: 0, + }, + ], }; diff --git a/packages/account/test/predicate-functions.test.ts b/packages/account/test/predicate-functions.test.ts index 88d385e02de..9142a85fb0c 100644 --- a/packages/account/test/predicate-functions.test.ts +++ b/packages/account/test/predicate-functions.test.ts @@ -64,5 +64,28 @@ describe('Predicate', () => { }); }).toThrow('Cannot use ABI without "main" function'); }); + + it('creates a new instance with updated parameters', async () => { + using launched = await setupTestProviderAndWallets(); + const { provider } = launched; + + const predicate = new Predicate({ + bytecode: predicateBytecode, + abi: predicateAbi, + provider, + configurableConstants: { value: false }, + }); + + const newPredicate = predicate.toNewInstance({ + configurableConstants: { value: true }, + data: ['NADA'], + }); + + expect(newPredicate.predicateData).toEqual(['NADA']); + expect(newPredicate.bytes.slice(1)).toEqual(predicate.bytes.slice(1)); + expect(newPredicate.bytes[0]).not.toEqual(predicate.bytes[0]); + expect(newPredicate.interface?.jsonAbi).toEqual(predicate.interface?.jsonAbi); + expect(newPredicate.provider).toEqual(predicate.provider); + }); }); }); From 09f40e62d763d32c43146449bca8ebd97419e705 Mon Sep 17 00:00:00 2001 From: YaTut1901 Date: Thu, 14 Nov 2024 14:57:43 +0200 Subject: [PATCH 2/6] chore(): added method to duplicate predicate --- packages/account/src/predicate/predicate.ts | 2 +- templates/vite/src/components/Predicate.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/account/src/predicate/predicate.ts b/packages/account/src/predicate/predicate.ts index 4bad1dfa9c3..da5825ed6d4 100644 --- a/packages/account/src/predicate/predicate.ts +++ b/packages/account/src/predicate/predicate.ts @@ -105,7 +105,7 @@ export class Predicate< configurableConstants?: TConfigurables; data?: TData; }): Predicate { - return new Predicate({ + return new Predicate({ bytecode: this.bytes, abi: this.interface?.jsonAbi, provider: this.provider, diff --git a/templates/vite/src/components/Predicate.tsx b/templates/vite/src/components/Predicate.tsx index 0bc92492dad..45724f23341 100644 --- a/templates/vite/src/components/Predicate.tsx +++ b/templates/vite/src/components/Predicate.tsx @@ -15,7 +15,7 @@ export default function Predicate() { transactionSuccessNotification, successNotification, } = useNotification(); - const [predicate, setPredicate] = useState>(); + const [predicate, setPredicate] = useState>(); const [predicatePin, setPredicatePin] = useState(); const [isLoading, setIsLoading] = useState(false); From 78a14b670835fda538148b16663a4f07680b31f0 Mon Sep 17 00:00:00 2001 From: YaTut1901 Date: Thu, 14 Nov 2024 15:55:48 +0200 Subject: [PATCH 3/6] chore(): added method to duplicate predicate --- templates/nextjs/src/components/Predicate.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/nextjs/src/components/Predicate.tsx b/templates/nextjs/src/components/Predicate.tsx index bbc5ca23435..2a560b7b5a7 100644 --- a/templates/nextjs/src/components/Predicate.tsx +++ b/templates/nextjs/src/components/Predicate.tsx @@ -16,7 +16,7 @@ export default function Predicate() { successNotification, } = useNotification(); useNotification(); - const [predicate, setPredicate] = useState>(); + const [predicate, setPredicate] = useState>(); const [predicatePin, setPredicatePin] = useState(); const [isLoading, setIsLoading] = useState(false); From 15e66a15f0c14baadae313e2b41781b3151698cc Mon Sep 17 00:00:00 2001 From: YaTut1901 Date: Sun, 17 Nov 2024 09:59:26 +0200 Subject: [PATCH 4/6] chore: removed loaderBytecode, added initial check in test --- packages/account/src/predicate/predicate.ts | 1 - packages/account/test/predicate-functions.test.ts | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/account/src/predicate/predicate.ts b/packages/account/src/predicate/predicate.ts index cf7c30e19fd..fce98fd4ab5 100644 --- a/packages/account/src/predicate/predicate.ts +++ b/packages/account/src/predicate/predicate.ts @@ -96,7 +96,6 @@ export class Predicate< provider: this.provider, data: params.data ?? this.predicateData, configurableConstants: params.configurableConstants, - loaderBytecode: this.loaderBytecode, }); } diff --git a/packages/account/test/predicate-functions.test.ts b/packages/account/test/predicate-functions.test.ts index 9142a85fb0c..0b71dd6375b 100644 --- a/packages/account/test/predicate-functions.test.ts +++ b/packages/account/test/predicate-functions.test.ts @@ -74,8 +74,12 @@ describe('Predicate', () => { abi: predicateAbi, provider, configurableConstants: { value: false }, + data: ['DADA'], }); + expect(predicate.predicateData).toEqual(['DADA']); + expect(predicate.bytes[0]).toEqual(0); + const newPredicate = predicate.toNewInstance({ configurableConstants: { value: true }, data: ['NADA'], From e81b9f1884e675bb01d78c54d8f6b8ccd2a9333b Mon Sep 17 00:00:00 2001 From: YaTut1901 Date: Sun, 17 Nov 2024 10:48:01 +0200 Subject: [PATCH 5/6] chore: added type to function --- .../src/predicate/utils/predicate/fundPredicate.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/fuel-gauge/src/predicate/utils/predicate/fundPredicate.ts b/packages/fuel-gauge/src/predicate/utils/predicate/fundPredicate.ts index 8d092e444a0..8708a60e846 100644 --- a/packages/fuel-gauge/src/predicate/utils/predicate/fundPredicate.ts +++ b/packages/fuel-gauge/src/predicate/utils/predicate/fundPredicate.ts @@ -1,9 +1,12 @@ import type { InputValue, BigNumberish, WalletUnlocked, Predicate } from 'fuels'; import { ScriptTransactionRequest, BN } from 'fuels'; -export const fundPredicate = async ( +export const fundPredicate = async < + T extends InputValue[] = InputValue[], + C extends { [name: string]: unknown } | undefined = { [name: string]: unknown }, +>( wallet: WalletUnlocked, - predicate: Predicate, + predicate: Predicate, amountToPredicate: BigNumberish, utxosAmount: number = 1 ): Promise => { From 83e31d22fbe5645a1a512cd708b07849fdcdd5aa Mon Sep 17 00:00:00 2001 From: YaTut1901 Date: Wed, 20 Nov 2024 12:02:21 +0200 Subject: [PATCH 6/6] chore(): refactored predicate class to set data on operations --- packages/account/src/predicate/predicate.ts | 115 ++++++++---------- .../account/test/predicate-functions.test.ts | 27 ---- 2 files changed, 54 insertions(+), 88 deletions(-) diff --git a/packages/account/src/predicate/predicate.ts b/packages/account/src/predicate/predicate.ts index 46642132c27..5dbd020392e 100644 --- a/packages/account/src/predicate/predicate.ts +++ b/packages/account/src/predicate/predicate.ts @@ -48,6 +48,7 @@ export class Predicate< bytes: Uint8Array; predicateData: TData = [] as unknown as TData; interface: Interface; + configurableConstants: TConfigurables = {} as TConfigurables; /** * Creates an instance of the Predicate class. @@ -65,38 +66,29 @@ export class Predicate< data, configurableConstants, }: PredicateParams) { - const { predicateBytes, predicateInterface } = Predicate.processPredicateData( - bytecode, - abi, - configurableConstants - ); + const { predicateBytes, predicateInterface } = Predicate.processPredicateData(bytecode, abi); const address = Address.fromB256(getPredicateRoot(predicateBytes)); super(address, provider); this.bytes = predicateBytes; this.interface = predicateInterface; - if (data !== undefined && data.length > 0) { + + if (configurableConstants && Object.keys(configurableConstants).length) { + this.configurableConstants = configurableConstants; + } + if (data && data.length) { this.predicateData = data; } } /** - * Creates a new Predicate instance with updated parameters while maintaining the original bytecode and ABI + * Updates parameters of predicate * * @param params - Object containing optional new configurableConstants and data - * @returns A new Predicate instance with the updated parameters */ - toNewInstance(params: { - configurableConstants?: TConfigurables; - data?: TData; - }): Predicate { - return new Predicate({ - bytecode: this.bytes, - abi: this.interface?.jsonAbi, - provider: this.provider, - data: params.data ?? this.predicateData, - configurableConstants: params.configurableConstants, - }); + setParams(params: { configurableConstants?: TConfigurables; data?: TData }) { + this.predicateData = params.data ?? this.predicateData; + this.configurableConstants = params.configurableConstants ?? this.configurableConstants; } /** @@ -119,7 +111,13 @@ export class Predicate< request.inputs.filter(isRequestInputCoinOrMessage).forEach((input) => { if (isRequestInputResourceFromOwner(input, this.address)) { // eslint-disable-next-line no-param-reassign - input.predicate = hexlify(this.bytes); + input.predicate = hexlify( + this.setConfigurableConstants( + this.bytes, + this.configurableConstants ?? {}, + this.interface + ) + ); // eslint-disable-next-line no-param-reassign input.predicateData = hexlify(this.getPredicateData()); // eslint-disable-next-line no-param-reassign @@ -171,14 +169,9 @@ export class Predicate< * * @param bytes - The bytes of the predicate. * @param jsonAbi - The JSON ABI of the predicate. - * @param configurableConstants - Optional configurable constants for the predicate. * @returns An object containing the new predicate bytes and interface. */ - private static processPredicateData( - bytes: BytesLike, - jsonAbi: JsonAbi, - configurableConstants?: { [name: string]: unknown } - ) { + private static processPredicateData(bytes: BytesLike, jsonAbi: JsonAbi) { let predicateBytes = arrayify(bytes); const abiInterface: Interface = new Interface(jsonAbi); @@ -189,14 +182,6 @@ export class Predicate< ); } - if (configurableConstants && Object.keys(configurableConstants).length) { - predicateBytes = Predicate.setConfigurableConstants( - predicateBytes, - configurableConstants, - abiInterface - ); - } - return { predicateBytes, predicateInterface: abiInterface, @@ -221,7 +206,9 @@ export class Predicate< ); return resources.map((resource) => ({ ...resource, - predicate: hexlify(this.bytes), + predicate: hexlify( + this.setConfigurableConstants(this.bytes, this.configurableConstants ?? {}, this.interface) + ), predicateData: hexlify(this.getPredicateData()), })); } @@ -235,11 +222,41 @@ export class Predicate< override generateFakeResources(coins: FakeResources[]): Array { return super.generateFakeResources(coins).map((coin) => ({ ...coin, - predicate: hexlify(this.bytes), + predicate: hexlify( + this.setConfigurableConstants(this.bytes, this.configurableConstants ?? {}, this.interface) + ), predicateData: hexlify(this.getPredicateData()), })); } + /** + * + * @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(account: Account) { + return deployScriptOrPredicate({ + deployer: account, + abi: this.interface.jsonAbi, + bytecode: this.setConfigurableConstants( + this.bytes, + this.configurableConstants ?? {}, + this.interface + ), + loaderInstanceCallback: (loaderBytecode, newAbi) => + new Predicate({ + bytecode: loaderBytecode, + abi: newAbi, + provider: this.provider, + data: this.predicateData, + }) as T, + }); + } + /** * Sets the configurable constants for the predicate. * @@ -248,7 +265,7 @@ export class Predicate< * @param abiInterface - The ABI interface of the predicate. * @returns The mutated bytes with the configurable constants set. */ - private static setConfigurableConstants( + private setConfigurableConstants( bytes: Uint8Array, configurableConstants: { [name: string]: unknown }, abiInterface: Interface @@ -325,28 +342,4 @@ 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(account: Account) { - return deployScriptOrPredicate({ - 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, - }); - } } diff --git a/packages/account/test/predicate-functions.test.ts b/packages/account/test/predicate-functions.test.ts index 0b71dd6375b..88d385e02de 100644 --- a/packages/account/test/predicate-functions.test.ts +++ b/packages/account/test/predicate-functions.test.ts @@ -64,32 +64,5 @@ describe('Predicate', () => { }); }).toThrow('Cannot use ABI without "main" function'); }); - - it('creates a new instance with updated parameters', async () => { - using launched = await setupTestProviderAndWallets(); - const { provider } = launched; - - const predicate = new Predicate({ - bytecode: predicateBytecode, - abi: predicateAbi, - provider, - configurableConstants: { value: false }, - data: ['DADA'], - }); - - expect(predicate.predicateData).toEqual(['DADA']); - expect(predicate.bytes[0]).toEqual(0); - - const newPredicate = predicate.toNewInstance({ - configurableConstants: { value: true }, - data: ['NADA'], - }); - - expect(newPredicate.predicateData).toEqual(['NADA']); - expect(newPredicate.bytes.slice(1)).toEqual(predicate.bytes.slice(1)); - expect(newPredicate.bytes[0]).not.toEqual(predicate.bytes[0]); - expect(newPredicate.interface?.jsonAbi).toEqual(predicate.interface?.jsonAbi); - expect(newPredicate.provider).toEqual(predicate.provider); - }); }); });