diff --git a/.changeset/gentle-toes-play.md b/.changeset/gentle-toes-play.md index 0e50d5619c1..98b9a4d469b 100644 --- a/.changeset/gentle-toes-play.md +++ b/.changeset/gentle-toes-play.md @@ -2,4 +2,4 @@ "@fuel-ts/account": patch --- -chore: added static method to duplicate predicate +feat: added method to duplicate predicate diff --git a/packages/fuel-gauge/src/predicate/predicate-duplication.test.ts b/packages/fuel-gauge/src/predicate/predicate-duplication.test.ts index 156e0cace83..54cec443091 100644 --- a/packages/fuel-gauge/src/predicate/predicate-duplication.test.ts +++ b/packages/fuel-gauge/src/predicate/predicate-duplication.test.ts @@ -21,336 +21,332 @@ describe('Predicate.fromInstance', () => { ADDRESS: '0x38966262edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96', }; - describe('Basic Instance Operations', () => { - it('creates new predicate instance from existing one with default values', async () => { - using launched = await launchTestNode(); + it('creates new predicate instance from existing one with default values', async () => { + using launched = await launchTestNode(); + + const provider = launched.provider; + const basePredicate = new PredicateWithConfigurable({ + provider, + data: [defaultValues.FEE, defaultValues.ADDRESS], + configurableConstants: defaultValues, + }); - const provider = launched.provider; - const basePredicate = new PredicateWithConfigurable({ - provider, - data: [defaultValues.FEE, defaultValues.ADDRESS], - configurableConstants: defaultValues, - }); + const newPredicate: PredicateWithConfigurable = basePredicate.toNewInstance(); + + expect(newPredicate.predicateData).toEqual(basePredicate.predicateData); + expect(newPredicate.interface).toEqual(basePredicate.interface); + expect(newPredicate.provider).toEqual(basePredicate.provider); + expect(newPredicate.bytes).toEqual(basePredicate.bytes); + }); - const newPredicate: PredicateWithConfigurable = basePredicate.toNewInstance(); + it('creates new predicate instance with custom data', async () => { + using launched = await launchTestNode(); - expect(newPredicate.predicateData).toEqual(basePredicate.predicateData); - expect(newPredicate.interface).toEqual(basePredicate.interface); - expect(newPredicate.provider).toEqual(basePredicate.provider); - expect(newPredicate.bytes).toEqual(basePredicate.bytes); + const provider = launched.provider; + const basePredicate = new PredicateWithConfigurable({ + provider, + data: [defaultValues.FEE, defaultValues.ADDRESS], + configurableConstants: defaultValues, }); - it('creates new predicate instance with custom data', async () => { - using launched = await launchTestNode(); + const data: PredicateWithConfigurableInputs = [ + 13, + '0x48966232edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96', + ]; + const newPredicate: PredicateWithConfigurable = basePredicate.toNewInstance({ data }); + + expect(newPredicate.predicateData).toEqual(data); + expect(newPredicate.interface).toEqual(basePredicate.interface); + expect(newPredicate.provider).toEqual(basePredicate.provider); + expect(newPredicate.bytes).toEqual(basePredicate.bytes); + expect(newPredicate.predicateData).not.toEqual(basePredicate.predicateData); + }); - const provider = launched.provider; - const basePredicate = new PredicateWithConfigurable({ - provider, - data: [defaultValues.FEE, defaultValues.ADDRESS], - configurableConstants: defaultValues, - }); - - const data: PredicateWithConfigurableInputs = [ - 13, - '0x48966232edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96', - ]; - const newPredicate: PredicateWithConfigurable = basePredicate.toNewInstance({ data }); - - expect(newPredicate.predicateData).toEqual(data); - expect(newPredicate.interface).toEqual(basePredicate.interface); - expect(newPredicate.provider).toEqual(basePredicate.provider); - expect(newPredicate.bytes).toEqual(basePredicate.bytes); - expect(newPredicate.predicateData).not.toEqual(basePredicate.predicateData); + it('creates new predicate instance with configurable constants', async () => { + using launched = await launchTestNode(); + + const provider = launched.provider; + const basePredicate = new PredicateWithConfigurable({ + provider, + data: [defaultValues.FEE, defaultValues.ADDRESS], + configurableConstants: defaultValues, }); - it('creates new predicate instance with configurable constants', async () => { - using launched = await launchTestNode(); + const configurableConstants: PredicateWithConfigurableConfigurables = { + FEE: 13, + ADDRESS: '0x48966232edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96', + }; + const newPredicate: PredicateWithConfigurable = basePredicate.toNewInstance({ + configurableConstants, + }); - const provider = launched.provider; - const basePredicate = new PredicateWithConfigurable({ + expect(newPredicate.predicateData).toEqual(basePredicate.predicateData); + expect(newPredicate.interface).toEqual(basePredicate.interface); + expect(newPredicate.provider).toEqual(basePredicate.provider); + expect(newPredicate.bytes).toEqual( + new PredicateWithConfigurable({ provider, data: [defaultValues.FEE, defaultValues.ADDRESS], - configurableConstants: defaultValues, - }); - - const configurableConstants: PredicateWithConfigurableConfigurables = { - FEE: 13, - ADDRESS: '0x48966232edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96', - }; - const newPredicate: PredicateWithConfigurable = basePredicate.toNewInstance({ configurableConstants, - }); - - expect(newPredicate.predicateData).toEqual(basePredicate.predicateData); - expect(newPredicate.interface).toEqual(basePredicate.interface); - expect(newPredicate.provider).toEqual(basePredicate.provider); - expect(newPredicate.bytes).toEqual( - new PredicateWithConfigurable({ - provider, - data: [defaultValues.FEE, defaultValues.ADDRESS], - configurableConstants, - }).bytes - ); + }).bytes + ); + }); + + it('supports chaining withData and withConfigurableConstants', async () => { + using launched = await launchTestNode(); + + const provider = launched.provider; + const basePredicate = new PredicateWithConfigurable({ + provider, + data: [defaultValues.FEE, defaultValues.ADDRESS], + configurableConstants: defaultValues, }); - it('supports chaining withData and withConfigurableConstants', async () => { - using launched = await launchTestNode(); + const data: PredicateWithConfigurableInputs = [ + 13, + '0x48966232edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96', + ]; + const configurableConstants: PredicateWithConfigurableConfigurables = { + FEE: 13, + ADDRESS: '0x48966232edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96', + }; + const newPredicate: PredicateWithConfigurable = basePredicate.toNewInstance({ + data, + configurableConstants, + }); - const provider = launched.provider; - const basePredicate = new PredicateWithConfigurable({ + expect(newPredicate.predicateData).toEqual(data); + expect(newPredicate.interface).toEqual(basePredicate.interface); + expect(newPredicate.provider).toEqual(basePredicate.provider); + expect(newPredicate.bytes).toEqual( + new PredicateWithConfigurable({ provider, - data: [defaultValues.FEE, defaultValues.ADDRESS], - configurableConstants: defaultValues, - }); - - const data: PredicateWithConfigurableInputs = [ - 13, - '0x48966232edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96', - ]; - const configurableConstants: PredicateWithConfigurableConfigurables = { - FEE: 13, - ADDRESS: '0x48966232edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96', - }; - const newPredicate: PredicateWithConfigurable = basePredicate.toNewInstance({ data, configurableConstants, - }); - - expect(newPredicate.predicateData).toEqual(data); - expect(newPredicate.interface).toEqual(basePredicate.interface); - expect(newPredicate.provider).toEqual(basePredicate.provider); - expect(newPredicate.bytes).toEqual( - new PredicateWithConfigurable({ - provider, - data, - configurableConstants, - }).bytes - ); + }).bytes + ); + }); + + it('can create multiple different instances from same source, same bytecode', async () => { + using launched = await launchTestNode(); + + const provider = launched.provider; + const basePredicate = new PredicateWithConfigurable({ + provider, + data: [defaultValues.FEE, defaultValues.ADDRESS], + configurableConstants: defaultValues, }); - it('can create multiple different instances from same source, same bytecode', async () => { - using launched = await launchTestNode(); + const newPredicate1 = basePredicate.toNewInstance(); + const newPredicate2 = basePredicate.toNewInstance(); - const provider = launched.provider; - const basePredicate = new PredicateWithConfigurable({ - provider, - data: [defaultValues.FEE, defaultValues.ADDRESS], - configurableConstants: defaultValues, - }); + expect(newPredicate1.bytes).toEqual(newPredicate2.bytes); + }); - const newPredicate1 = basePredicate.toNewInstance(); - const newPredicate2 = basePredicate.toNewInstance(); + it('can create multiple different instances from same source, different bytecode', async () => { + using launched = await launchTestNode(); - expect(newPredicate1.bytes).toEqual(newPredicate2.bytes); + const provider = launched.provider; + const basePredicate = new PredicateWithConfigurable({ + provider, + data: [defaultValues.FEE, defaultValues.ADDRESS], + configurableConstants: defaultValues, }); - it('can create multiple different instances from same source, different bytecode', async () => { - using launched = await launchTestNode(); + const configurableConstants: PredicateWithConfigurableConfigurables = { + FEE: 13, + ADDRESS: '0x38966262edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96', + }; + const newPredicate1 = basePredicate.toNewInstance(); + const newPredicate2 = basePredicate.toNewInstance({ configurableConstants }); - const provider = launched.provider; - const basePredicate = new PredicateWithConfigurable({ - provider, - data: [defaultValues.FEE, defaultValues.ADDRESS], - configurableConstants: defaultValues, - }); + expect(newPredicate1.bytes).not.toEqual(newPredicate2.bytes); + }); - const configurableConstants: PredicateWithConfigurableConfigurables = { - FEE: 13, - ADDRESS: '0x38966262edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96', - }; - const newPredicate1 = basePredicate.toNewInstance(); - const newPredicate2 = basePredicate.toNewInstance({ configurableConstants }); + it('does not modify original instance', async () => { + using launched = await launchTestNode(); - expect(newPredicate1.bytes).not.toEqual(newPredicate2.bytes); + const provider = launched.provider; + const basePredicate = new PredicateWithConfigurable({ + provider, + data: [defaultValues.FEE, defaultValues.ADDRESS], + configurableConstants: defaultValues, }); - it('does not modify original instance', async () => { - using launched = await launchTestNode(); + const bytes = basePredicate.bytes; + const newPredicate = basePredicate.toNewInstance(); - const provider = launched.provider; - const basePredicate = new PredicateWithConfigurable({ - provider, - data: [defaultValues.FEE, defaultValues.ADDRESS], - configurableConstants: defaultValues, - }); + expect(newPredicate.bytes).toEqual(bytes); + }); + + it('can transfer funds using duplicated predicate with same data and configurable constants', async () => { + using launched = await launchTestNode(); - const bytes = basePredicate.bytes; - const newPredicate = basePredicate.toNewInstance(); + const { + provider, + wallets: [wallet], + } = launched; - expect(newPredicate.bytes).toEqual(bytes); + const basePredicate = new PredicateWithConfigurable({ + provider: wallet.provider, + data: [defaultValues.FEE, defaultValues.ADDRESS], + configurableConstants: defaultValues, }); - }); - describe('End-to-End Scenarios', () => { - it('can transfer funds using duplicated predicate with same data and configurable constants', async () => { - using launched = await launchTestNode(); + const predicate = basePredicate.toNewInstance(); - const { - provider, - wallets: [wallet], - } = launched; + const amountToTransfer = 200; - const basePredicate = new PredicateWithConfigurable({ - provider: wallet.provider, - data: [defaultValues.FEE, defaultValues.ADDRESS], - configurableConstants: defaultValues, - }); + await fundAccount(wallet, predicate, amountToPredicate); - const predicate = basePredicate.toNewInstance(); + const destination = WalletUnlocked.generate({ + provider: wallet.provider, + }); - const amountToTransfer = 200; + await assertBalance(destination, 0, provider.getBaseAssetId()); - await fundAccount(wallet, predicate, amountToPredicate); + const tx = await predicate.transfer( + destination.address, + amountToTransfer, + provider.getBaseAssetId(), + { + gasLimit: 1000, + } + ); - const destination = WalletUnlocked.generate({ - provider: wallet.provider, - }); + await tx.waitForResult(); - await assertBalance(destination, 0, provider.getBaseAssetId()); + await assertBalance(destination, amountToTransfer, provider.getBaseAssetId()); + }); - const tx = await predicate.transfer( - destination.address, - amountToTransfer, - provider.getBaseAssetId(), - { - gasLimit: 1000, - } - ); + it('can transfer funds using duplicated predicate with different data and same configurable constants', async () => { + using launched = await launchTestNode(); - await tx.waitForResult(); + const { + provider, + wallets: [wallet], + } = launched; - await assertBalance(destination, amountToTransfer, provider.getBaseAssetId()); + const basePredicate = new PredicateWithConfigurable({ + provider: wallet.provider, + data: [13, '0x48966232edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96'], + configurableConstants: defaultValues, }); - it('can transfer funds using duplicated predicate with different data and same configurable constants', async () => { - using launched = await launchTestNode(); + const predicate = basePredicate.toNewInstance({ + data: [defaultValues.FEE, defaultValues.ADDRESS], + }); - const { - provider, - wallets: [wallet], - } = launched; + const amountToTransfer = 200; - const basePredicate = new PredicateWithConfigurable({ - provider: wallet.provider, - data: [13, '0x48966232edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96'], - configurableConstants: defaultValues, - }); + await fundAccount(wallet, predicate, amountToPredicate); - const predicate = basePredicate.toNewInstance({ - data: [defaultValues.FEE, defaultValues.ADDRESS], - }); + const destination = WalletUnlocked.generate({ + provider: wallet.provider, + }); - const amountToTransfer = 200; + await assertBalance(destination, 0, provider.getBaseAssetId()); - await fundAccount(wallet, predicate, amountToPredicate); + const tx = await predicate.transfer( + destination.address, + amountToTransfer, + provider.getBaseAssetId(), + { + gasLimit: 1000, + } + ); - const destination = WalletUnlocked.generate({ - provider: wallet.provider, - }); + await tx.waitForResult(); - await assertBalance(destination, 0, provider.getBaseAssetId()); + await assertBalance(destination, amountToTransfer, provider.getBaseAssetId()); + }); - const tx = await predicate.transfer( - destination.address, - amountToTransfer, - provider.getBaseAssetId(), - { - gasLimit: 1000, - } - ); + it('can transfer funds using duplicated predicate with same data and different configurable constants', async () => { + using launched = await launchTestNode(); - await tx.waitForResult(); + const { + provider, + wallets: [wallet], + } = launched; - await assertBalance(destination, amountToTransfer, provider.getBaseAssetId()); + const basePredicate = new PredicateWithConfigurable({ + provider: wallet.provider, + data: [defaultValues.FEE, defaultValues.ADDRESS], + configurableConstants: { + FEE: 13, + ADDRESS: '0x48966232edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96', + }, }); - it('can transfer funds using duplicated predicate with same data and different configurable constants', async () => { - using launched = await launchTestNode(); + const predicate = basePredicate.toNewInstance({ configurableConstants: defaultValues }); - const { - provider, - wallets: [wallet], - } = launched; + const amountToTransfer = 200; - const basePredicate = new PredicateWithConfigurable({ - provider: wallet.provider, - data: [defaultValues.FEE, defaultValues.ADDRESS], - configurableConstants: { - FEE: 13, - ADDRESS: '0x48966232edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96', - }, - }); + await fundAccount(wallet, predicate, amountToPredicate); - const predicate = basePredicate.toNewInstance({ configurableConstants: defaultValues }); + const destination = WalletUnlocked.generate({ + provider: wallet.provider, + }); - const amountToTransfer = 200; + await assertBalance(destination, 0, provider.getBaseAssetId()); - await fundAccount(wallet, predicate, amountToPredicate); + const tx = await predicate.transfer( + destination.address, + amountToTransfer, + provider.getBaseAssetId(), + { + gasLimit: 1000, + } + ); - const destination = WalletUnlocked.generate({ - provider: wallet.provider, - }); + await tx.waitForResult(); - await assertBalance(destination, 0, provider.getBaseAssetId()); + await assertBalance(destination, amountToTransfer, provider.getBaseAssetId()); + }); - const tx = await predicate.transfer( - destination.address, - amountToTransfer, - provider.getBaseAssetId(), - { - gasLimit: 1000, - } - ); + it('can transfer funds using duplicated predicate with different data and configurable constants', async () => { + using launched = await launchTestNode(); - await tx.waitForResult(); + const { + provider, + wallets: [wallet], + } = launched; - await assertBalance(destination, amountToTransfer, provider.getBaseAssetId()); + const basePredicate = new PredicateWithConfigurable({ + provider: wallet.provider, + data: [13, '0x48966232edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96'], + configurableConstants: { + FEE: 15, + ADDRESS: '0x38966262edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96', + }, }); - it('can transfer funds using duplicated predicate with different data and configurable constants', async () => { - using launched = await launchTestNode(); - - const { - provider, - wallets: [wallet], - } = launched; - - const basePredicate = new PredicateWithConfigurable({ - provider: wallet.provider, - data: [13, '0x48966232edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96'], - configurableConstants: { - FEE: 15, - ADDRESS: '0x38966262edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96', - }, - }); - - const predicate = basePredicate.toNewInstance({ - data: [defaultValues.FEE, defaultValues.ADDRESS], - configurableConstants: defaultValues, - }); + const predicate = basePredicate.toNewInstance({ + data: [defaultValues.FEE, defaultValues.ADDRESS], + configurableConstants: defaultValues, + }); - const amountToTransfer = 200; + const amountToTransfer = 200; - await fundAccount(wallet, predicate, amountToPredicate); + await fundAccount(wallet, predicate, amountToPredicate); - const destination = WalletUnlocked.generate({ - provider: wallet.provider, - }); + const destination = WalletUnlocked.generate({ + provider: wallet.provider, + }); - await assertBalance(destination, 0, provider.getBaseAssetId()); + await assertBalance(destination, 0, provider.getBaseAssetId()); - const tx = await predicate.transfer( - destination.address, - amountToTransfer, - provider.getBaseAssetId(), - { - gasLimit: 1000, - } - ); + const tx = await predicate.transfer( + destination.address, + amountToTransfer, + provider.getBaseAssetId(), + { + gasLimit: 1000, + } + ); - await tx.waitForResult(); + await tx.waitForResult(); - await assertBalance(destination, amountToTransfer, provider.getBaseAssetId()); - }); + await assertBalance(destination, amountToTransfer, provider.getBaseAssetId()); }); });