diff --git a/.changeset/friendly-spiders-drop.md b/.changeset/friendly-spiders-drop.md new file mode 100644 index 0000000000..bdafa71efa --- /dev/null +++ b/.changeset/friendly-spiders-drop.md @@ -0,0 +1,5 @@ +--- +"@fuel-ts/predicate": patch +--- + +Refactor structure of tests in the predicate package diff --git a/apps/docs/src/guide/abi-typegen/using-generated-types.md b/apps/docs/src/guide/abi-typegen/using-generated-types.md index a45fe01fff..5c518246d9 100644 --- a/apps/docs/src/guide/abi-typegen/using-generated-types.md +++ b/apps/docs/src/guide/abi-typegen/using-generated-types.md @@ -54,7 +54,7 @@ console.log({ value, logs }); Consider the following predicate: -<<< @/../../../packages/fuel-gauge/test-projects/predicate-main-args-struct/src/main.sw#Predicate-main-args{ts:line-numbers} +<<< @/../../../packages/fuel-gauge/fixtures/forc-projects/predicate-main-args-struct/src/main.sw#Predicate-main-args{ts:line-numbers} Now, after generating types via: diff --git a/apps/docs/src/guide/cookbook/deposit-and-withdraw.md b/apps/docs/src/guide/cookbook/deposit-and-withdraw.md index 8c627e8c45..b88605a4d9 100644 --- a/apps/docs/src/guide/cookbook/deposit-and-withdraw.md +++ b/apps/docs/src/guide/cookbook/deposit-and-withdraw.md @@ -2,9 +2,9 @@ Consider the following contracts: -<<< @/../../../packages/fuel-gauge/test-projects/token_contract/src/main.sw#token-contract{rust:line-numbers} +<<< @/../../../packages/fuel-gauge/fixtures/forc-projects/token_contract/src/main.sw#token-contract{rust:line-numbers} -<<< @/../../../packages/fuel-gauge/test-projects/liquidity-pool/src/main.sw#liquidity-pool-contract{rust:line-numbers} +<<< @/../../../packages/fuel-gauge/fixtures/forc-projects/liquidity-pool/src/main.sw#liquidity-pool-contract{rust:line-numbers} The first contract is a contract that represents a simple token. diff --git a/apps/docs/src/guide/scripts/calling-a-script.md b/apps/docs/src/guide/scripts/calling-a-script.md index 046e1da7e9..6377cb54d8 100644 --- a/apps/docs/src/guide/scripts/calling-a-script.md +++ b/apps/docs/src/guide/scripts/calling-a-script.md @@ -2,7 +2,7 @@ Suppose your Sway script `main` function is written using the arguments passed to the `main` function like so: -<<< @/../../../packages/fuel-gauge/test-projects/script-main-args/src/main.sw#script-with-main-args{rust:line-numbers} +<<< @/../../../packages/fuel-gauge/fixtures/forc-projects/script-main-args/src/main.sw#script-with-main-args{rust:line-numbers} You can still hand code out a solution wrapper using `callScript` utility to call your script with data. However, if you prefer to use the ABI generated from your script, you can use the `ScriptFactory` helper: diff --git a/packages/fuel-gauge/.gitignore b/packages/fuel-gauge/.gitignore index 6f39eb69d4..7a7adce350 100644 --- a/packages/fuel-gauge/.gitignore +++ b/packages/fuel-gauge/.gitignore @@ -1 +1 @@ -test-projects/**/index.ts \ No newline at end of file +fixtures/forc-projects/**/index.ts \ No newline at end of file diff --git a/packages/fuel-gauge/fixtures/abi/predicate.ts b/packages/fuel-gauge/fixtures/abi/predicate.ts new file mode 100644 index 0000000000..e3413f6623 --- /dev/null +++ b/packages/fuel-gauge/fixtures/abi/predicate.ts @@ -0,0 +1,38 @@ +import type { JsonAbi } from 'fuels'; + +export const defaultPredicateAbi: JsonAbi = { + types: [ + { + typeId: 0, + type: 'bool', + components: null, + typeParameters: null, + }, + { + typeId: 1, + type: 'b256', + components: null, + typeParameters: null, + }, + ], + functions: [ + { + inputs: [ + { + name: 'data', + type: 1, + typeArguments: null, + }, + ], + name: 'main', + output: { + name: '', + type: 0, + typeArguments: null, + }, + attributes: null, + }, + ], + loggedTypes: [], + configurables: [], +}; diff --git a/packages/fuel-gauge/fixtures/bytecode/predicate.ts b/packages/fuel-gauge/fixtures/bytecode/predicate.ts new file mode 100644 index 0000000000..a6afa8bdd8 --- /dev/null +++ b/packages/fuel-gauge/fixtures/bytecode/predicate.ts @@ -0,0 +1,2 @@ +export const defaultPredicateBytecode = + '0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8'; diff --git a/packages/fuel-gauge/test-projects/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/Forc.toml diff --git a/packages/fuel-gauge/test-projects/advanced-logging-other-contract-abi/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/advanced-logging-other-contract-abi/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/advanced-logging-other-contract-abi/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/advanced-logging-other-contract-abi/Forc.toml diff --git a/packages/fuel-gauge/test-projects/advanced-logging-other-contract-abi/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/advanced-logging-other-contract-abi/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/advanced-logging-other-contract-abi/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/advanced-logging-other-contract-abi/src/main.sw diff --git a/packages/fuel-gauge/test-projects/advanced-logging-other-contract/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/advanced-logging-other-contract/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/advanced-logging-other-contract/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/advanced-logging-other-contract/Forc.toml diff --git a/packages/fuel-gauge/test-projects/advanced-logging-other-contract/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/advanced-logging-other-contract/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/advanced-logging-other-contract/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/advanced-logging-other-contract/src/main.sw diff --git a/packages/fuel-gauge/test-projects/advanced-logging/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/advanced-logging/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/advanced-logging/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/advanced-logging/Forc.toml diff --git a/packages/fuel-gauge/test-projects/advanced-logging/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/advanced-logging/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/advanced-logging/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/advanced-logging/src/main.sw diff --git a/packages/fuel-gauge/test-projects/auth_testing_abi/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/auth_testing_abi/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/auth_testing_abi/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/auth_testing_abi/Forc.toml diff --git a/packages/fuel-gauge/test-projects/auth_testing_abi/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/auth_testing_abi/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/auth_testing_abi/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/auth_testing_abi/src/main.sw diff --git a/packages/fuel-gauge/test-projects/auth_testing_contract/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/auth_testing_contract/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/auth_testing_contract/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/auth_testing_contract/Forc.toml diff --git a/packages/fuel-gauge/test-projects/auth_testing_contract/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/auth_testing_contract/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/auth_testing_contract/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/auth_testing_contract/src/main.sw diff --git a/packages/fuel-gauge/test-projects/call-test-contract/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/call-test-contract/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/call-test-contract/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/call-test-contract/Forc.toml diff --git a/packages/fuel-gauge/test-projects/call-test-contract/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/call-test-contract/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/call-test-contract/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/call-test-contract/src/main.sw diff --git a/packages/fuel-gauge/test-projects/collision_in_fn_names/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/collision_in_fn_names/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/collision_in_fn_names/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/collision_in_fn_names/Forc.toml diff --git a/packages/fuel-gauge/test-projects/collision_in_fn_names/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/collision_in_fn_names/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/collision_in_fn_names/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/collision_in_fn_names/src/main.sw diff --git a/packages/fuel-gauge/test-projects/configurable-contract/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/configurable-contract/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/configurable-contract/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/configurable-contract/Forc.toml diff --git a/packages/fuel-gauge/test-projects/configurable-contract/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/configurable-contract/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/configurable-contract/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/configurable-contract/src/main.sw diff --git a/packages/fuel-gauge/test-projects/coverage-contract/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/coverage-contract/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/coverage-contract/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/coverage-contract/Forc.toml diff --git a/packages/fuel-gauge/test-projects/coverage-contract/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/coverage-contract/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/coverage-contract/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/coverage-contract/src/main.sw diff --git a/packages/fuel-gauge/test-projects/custom_errors/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/custom_errors/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/custom_errors/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/custom_errors/Forc.toml diff --git a/packages/fuel-gauge/test-projects/custom_errors/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/custom_errors/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/custom_errors/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/custom_errors/src/main.sw diff --git a/packages/fuel-gauge/test-projects/generic-types-contract/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/generic-types-contract/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/generic-types-contract/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/generic-types-contract/Forc.toml diff --git a/packages/fuel-gauge/test-projects/generic-types-contract/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/generic-types-contract/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/generic-types-contract/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/generic-types-contract/src/main.sw diff --git a/packages/fuel-gauge/test-projects/liquidity-pool/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/liquidity-pool/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/liquidity-pool/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/liquidity-pool/Forc.toml diff --git a/packages/fuel-gauge/test-projects/liquidity-pool/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/liquidity-pool/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/liquidity-pool/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/liquidity-pool/src/main.sw diff --git a/packages/fuel-gauge/test-projects/payable-annotation/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/payable-annotation/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/payable-annotation/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/payable-annotation/Forc.toml diff --git a/packages/fuel-gauge/test-projects/payable-annotation/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/payable-annotation/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/payable-annotation/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/payable-annotation/src/main.sw diff --git a/packages/fuel-gauge/test-projects/predicate-address/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/predicate-address/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/predicate-address/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/predicate-address/Forc.toml diff --git a/packages/fuel-gauge/test-projects/predicate-address/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/predicate-address/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/predicate-address/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/predicate-address/src/main.sw diff --git a/packages/fuel-gauge/test-projects/predicate-false/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/predicate-false/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/predicate-false/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/predicate-false/Forc.toml diff --git a/packages/fuel-gauge/test-projects/predicate-false/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/predicate-false/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/predicate-false/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/predicate-false/src/main.sw diff --git a/packages/fuel-gauge/test-projects/predicate-main-args-struct/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/predicate-main-args-struct/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/predicate-main-args-struct/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/predicate-main-args-struct/Forc.toml diff --git a/packages/fuel-gauge/test-projects/predicate-main-args-struct/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/predicate-main-args-struct/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/predicate-main-args-struct/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/predicate-main-args-struct/src/main.sw diff --git a/packages/fuel-gauge/test-projects/predicate-main-args-vector/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/predicate-main-args-vector/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/predicate-main-args-vector/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/predicate-main-args-vector/Forc.toml diff --git a/packages/fuel-gauge/test-projects/predicate-main-args-vector/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/predicate-main-args-vector/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/predicate-main-args-vector/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/predicate-main-args-vector/src/main.sw diff --git a/packages/fuel-gauge/test-projects/predicate-struct/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/predicate-struct/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/predicate-struct/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/predicate-struct/Forc.toml diff --git a/packages/fuel-gauge/test-projects/predicate-struct/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/predicate-struct/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/predicate-struct/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/predicate-struct/src/main.sw diff --git a/packages/fuel-gauge/test-projects/predicate-triple-sig/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/predicate-triple-sig/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/predicate-triple-sig/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/predicate-triple-sig/Forc.toml diff --git a/packages/fuel-gauge/test-projects/predicate-triple-sig/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/predicate-triple-sig/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/predicate-triple-sig/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/predicate-triple-sig/src/main.sw diff --git a/packages/fuel-gauge/test-projects/predicate-true/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/predicate-true/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/predicate-true/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/predicate-true/Forc.toml diff --git a/packages/fuel-gauge/test-projects/predicate-true/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/predicate-true/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/predicate-true/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/predicate-true/src/main.sw diff --git a/packages/fuel-gauge/test-projects/predicate-u32/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/predicate-u32/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/predicate-u32/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/predicate-u32/Forc.toml diff --git a/packages/fuel-gauge/test-projects/predicate-u32/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/predicate-u32/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/predicate-u32/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/predicate-u32/src/main.sw diff --git a/packages/fuel-gauge/test-projects/predicate-vector-types/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/predicate-vector-types/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/predicate-vector-types/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/predicate-vector-types/Forc.toml diff --git a/packages/fuel-gauge/test-projects/predicate-vector-types/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/predicate-vector-types/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/predicate-vector-types/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/predicate-vector-types/src/main.sw diff --git a/packages/fuel-gauge/test-projects/predicate-with-configurable/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/predicate-with-configurable/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/predicate-with-configurable/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/predicate-with-configurable/Forc.toml diff --git a/packages/fuel-gauge/test-projects/predicate-with-configurable/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/predicate-with-configurable/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/predicate-with-configurable/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/predicate-with-configurable/src/main.sw diff --git a/packages/fuel-gauge/test-projects/revert-error/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/revert-error/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/revert-error/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/revert-error/Forc.toml diff --git a/packages/fuel-gauge/test-projects/revert-error/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/revert-error/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/revert-error/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/revert-error/src/main.sw diff --git a/packages/fuel-gauge/test-projects/script-main-args/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/script-main-args/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/script-main-args/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/script-main-args/Forc.toml diff --git a/packages/fuel-gauge/test-projects/script-main-args/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/script-main-args/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/script-main-args/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/script-main-args/src/main.sw diff --git a/packages/fuel-gauge/test-projects/script-main-return-struct/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/script-main-return-struct/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/script-main-return-struct/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/script-main-return-struct/Forc.toml diff --git a/packages/fuel-gauge/test-projects/script-main-return-struct/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/script-main-return-struct/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/script-main-return-struct/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/script-main-return-struct/src/main.sw diff --git a/packages/fuel-gauge/test-projects/script-main-two-args/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/script-main-two-args/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/script-main-two-args/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/script-main-two-args/Forc.toml diff --git a/packages/fuel-gauge/test-projects/script-main-two-args/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/script-main-two-args/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/script-main-two-args/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/script-main-two-args/src/main.sw diff --git a/packages/fuel-gauge/test-projects/script-with-array/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/script-with-array/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/script-with-array/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/script-with-array/Forc.toml diff --git a/packages/fuel-gauge/test-projects/script-with-array/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/script-with-array/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/script-with-array/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/script-with-array/src/main.sw diff --git a/packages/fuel-gauge/test-projects/script-with-configurable/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/script-with-configurable/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/script-with-configurable/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/script-with-configurable/Forc.toml diff --git a/packages/fuel-gauge/test-projects/script-with-configurable/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/script-with-configurable/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/script-with-configurable/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/script-with-configurable/src/main.sw diff --git a/packages/fuel-gauge/test-projects/script-with-vector-advanced/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/script-with-vector-advanced/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/script-with-vector-advanced/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/script-with-vector-advanced/Forc.toml diff --git a/packages/fuel-gauge/test-projects/script-with-vector-advanced/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/script-with-vector-advanced/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/script-with-vector-advanced/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/script-with-vector-advanced/src/main.sw diff --git a/packages/fuel-gauge/test-projects/script-with-vector-mixed/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/script-with-vector-mixed/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/script-with-vector-mixed/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/script-with-vector-mixed/Forc.toml diff --git a/packages/fuel-gauge/test-projects/script-with-vector-mixed/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/script-with-vector-mixed/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/script-with-vector-mixed/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/script-with-vector-mixed/src/main.sw diff --git a/packages/fuel-gauge/test-projects/script-with-vector/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/script-with-vector/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/script-with-vector/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/script-with-vector/Forc.toml diff --git a/packages/fuel-gauge/test-projects/script-with-vector/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/script-with-vector/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/script-with-vector/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/script-with-vector/src/main.sw diff --git a/packages/fuel-gauge/test-projects/storage-test-contract/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/storage-test-contract/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/storage-test-contract/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/storage-test-contract/Forc.toml diff --git a/packages/fuel-gauge/test-projects/storage-test-contract/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/storage-test-contract/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/storage-test-contract/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/storage-test-contract/src/main.sw diff --git a/packages/fuel-gauge/test-projects/token_abi/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/token_abi/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/token_abi/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/token_abi/Forc.toml diff --git a/packages/fuel-gauge/test-projects/token_abi/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/token_abi/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/token_abi/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/token_abi/src/main.sw diff --git a/packages/fuel-gauge/test-projects/token_contract/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/token_contract/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/token_contract/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/token_contract/Forc.toml diff --git a/packages/fuel-gauge/test-projects/token_contract/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/token_contract/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/token_contract/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/token_contract/src/main.sw diff --git a/packages/fuel-gauge/test-projects/vector-types-contract/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/vector-types-contract/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/vector-types-contract/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/vector-types-contract/Forc.toml diff --git a/packages/fuel-gauge/test-projects/vector-types-contract/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/vector-types-contract/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/vector-types-contract/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/vector-types-contract/src/main.sw diff --git a/packages/fuel-gauge/test-projects/vector-types-script/Forc.toml b/packages/fuel-gauge/fixtures/forc-projects/vector-types-script/Forc.toml similarity index 100% rename from packages/fuel-gauge/test-projects/vector-types-script/Forc.toml rename to packages/fuel-gauge/fixtures/forc-projects/vector-types-script/Forc.toml diff --git a/packages/fuel-gauge/test-projects/vector-types-script/src/main.sw b/packages/fuel-gauge/fixtures/forc-projects/vector-types-script/src/main.sw similarity index 100% rename from packages/fuel-gauge/test-projects/vector-types-script/src/main.sw rename to packages/fuel-gauge/fixtures/forc-projects/vector-types-script/src/main.sw diff --git a/packages/fuel-gauge/package.json b/packages/fuel-gauge/package.json index 194e16625e..6d349d458f 100644 --- a/packages/fuel-gauge/package.json +++ b/packages/fuel-gauge/package.json @@ -6,7 +6,7 @@ "author": "Fuel Labs (https://fuel.network/)", "scripts": { "build": "run-s build:forc-projects build:process-predicates", - "build:forc-projects": "pnpm fuels-forc build -p test-projects", + "build:forc-projects": "pnpm fuels-forc build -p fixtures/forc-projects", "build:process-predicates": "tsx ./scripts/process-predicates.ts" }, "license": "Apache-2.0", diff --git a/packages/fuel-gauge/scripts/process-predicates.ts b/packages/fuel-gauge/scripts/process-predicates.ts index d6c66e14ea..1c42e6e335 100644 --- a/packages/fuel-gauge/scripts/process-predicates.ts +++ b/packages/fuel-gauge/scripts/process-predicates.ts @@ -2,7 +2,7 @@ import { readFileSync, readdirSync, writeFileSync } from 'fs'; import { hexlify } from 'fuels'; import { join } from 'path'; -const projectsDir = join(__dirname, '../test-projects'); +const projectsDir = join(__dirname, '../fixtures/forc-projects'); const files = readdirSync(projectsDir).filter((file) => file.includes('predicate-')); diff --git a/packages/fuel-gauge/src/auth-testing.test.ts b/packages/fuel-gauge/src/auth-testing.test.ts index c66915a85c..b18f127cd6 100644 --- a/packages/fuel-gauge/src/auth-testing.test.ts +++ b/packages/fuel-gauge/src/auth-testing.test.ts @@ -4,7 +4,7 @@ import type { Contract, WalletUnlocked } from 'fuels'; import { AssertFailedRevertError, ContractFactory, NativeAssetId, Provider } from 'fuels'; import path from 'path'; -import FactoryAbi from '../test-projects/auth_testing_contract/out/debug/auth_testing_contract-abi.json'; +import FactoryAbi from '../fixtures/forc-projects/auth_testing_contract/out/debug/auth_testing_contract-abi.json'; let contractInstance: Contract; let wallet: WalletUnlocked; @@ -17,7 +17,7 @@ describe('Auth Testing', () => { const bytecode = fs.readFileSync( path.join( __dirname, - '../test-projects/auth_testing_contract/out/debug/auth_testing_contract.bin' + '../fixtures/forc-projects/auth_testing_contract/out/debug/auth_testing_contract.bin' ) ); const factory = new ContractFactory(bytecode, FactoryAbi, wallet); diff --git a/packages/fuel-gauge/src/call-test-contract.test.ts b/packages/fuel-gauge/src/call-test-contract.test.ts index 2acd902af9..3ff63d4e73 100644 --- a/packages/fuel-gauge/src/call-test-contract.test.ts +++ b/packages/fuel-gauge/src/call-test-contract.test.ts @@ -2,12 +2,12 @@ import { readFileSync } from 'fs'; import { BN, bn, toHex, NativeAssetId } from 'fuels'; import { join } from 'path'; -import abiJSON from '../test-projects/call-test-contract/out/debug/call-test-abi.json'; +import abiJSON from '../fixtures/forc-projects/call-test-contract/out/debug/call-test-abi.json'; import { createSetupConfig } from './utils'; const contractBytecode = readFileSync( - join(__dirname, '../test-projects/call-test-contract/out/debug/call-test.bin') + join(__dirname, '../fixtures/forc-projects/call-test-contract/out/debug/call-test.bin') ); const setupContract = createSetupConfig({ diff --git a/packages/fuel-gauge/src/configurable-contract.test.ts b/packages/fuel-gauge/src/configurable-contract.test.ts index faac518f66..c95f8f23f6 100644 --- a/packages/fuel-gauge/src/configurable-contract.test.ts +++ b/packages/fuel-gauge/src/configurable-contract.test.ts @@ -4,10 +4,13 @@ import type { CoinQuantityLike, WalletUnlocked } from 'fuels'; import { getRandomB256, BN, ContractFactory, NativeAssetId, Provider } from 'fuels'; import { join } from 'path'; -import contractAbi from '../test-projects/configurable-contract/out/debug/configurable-contract-abi.json'; +import contractAbi from '../fixtures/forc-projects/configurable-contract/out/debug/configurable-contract-abi.json'; const contractBytecode = readFileSync( - join(__dirname, '../test-projects/configurable-contract/out/debug/configurable-contract.bin') + join( + __dirname, + '../fixtures/forc-projects/configurable-contract/out/debug/configurable-contract.bin' + ) ); const defaultValues = { diff --git a/packages/fuel-gauge/src/contract-factory.test.ts b/packages/fuel-gauge/src/contract-factory.test.ts index d0971ea502..63f49e9da7 100644 --- a/packages/fuel-gauge/src/contract-factory.test.ts +++ b/packages/fuel-gauge/src/contract-factory.test.ts @@ -3,7 +3,7 @@ import { readFileSync } from 'fs'; import { bn, toHex, Interface, Provider, ContractFactory, NativeAssetId } from 'fuels'; import { join } from 'path'; -import storageSlots from '../test-projects/storage-test-contract/out/debug/storage-test-storage_slots.json'; +import storageSlots from '../fixtures/forc-projects/storage-test-contract/out/debug/storage-test-storage_slots.json'; describe('Contract Factory', () => { const createContractFactory = async () => { @@ -12,13 +12,16 @@ describe('Contract Factory', () => { // load the byteCode of the contract, generated from Sway source const byteCode = readFileSync( - join(__dirname, '../test-projects/storage-test-contract/out/debug/storage-test.bin') + join(__dirname, '../fixtures/forc-projects/storage-test-contract/out/debug/storage-test.bin') ); // load the JSON abi of the contract, generated from Sway source const abi = JSON.parse( readFileSync( - join(__dirname, '../test-projects/storage-test-contract/out/debug/storage-test-abi.json') + join( + __dirname, + '../fixtures/forc-projects/storage-test-contract/out/debug/storage-test-abi.json' + ) ).toString() ); diff --git a/packages/fuel-gauge/src/contract.test.ts b/packages/fuel-gauge/src/contract.test.ts index b1d280e6b9..aa7225d382 100644 --- a/packages/fuel-gauge/src/contract.test.ts +++ b/packages/fuel-gauge/src/contract.test.ts @@ -21,16 +21,16 @@ import { } from 'fuels'; import { join } from 'path'; -import abiJSON from '../test-projects/call-test-contract/out/debug/call-test-abi.json'; +import abiJSON from '../fixtures/forc-projects/call-test-contract/out/debug/call-test-abi.json'; import { createSetupConfig } from './utils'; const contractBytecode = readFileSync( - join(__dirname, '../test-projects/call-test-contract/out/debug/call-test.bin') + join(__dirname, '../fixtures/forc-projects/call-test-contract/out/debug/call-test.bin') ); const predicateBytecode = readFileSync( - join(__dirname, '../test-projects/predicate-true/out/debug/predicate-true.bin') + join(__dirname, '../fixtures/forc-projects/predicate-true/out/debug/predicate-true.bin') ); const setupContract = createSetupConfig({ diff --git a/packages/fuel-gauge/src/doc-examples.test.ts b/packages/fuel-gauge/src/doc-examples.test.ts index fcaf1018ca..4d294f38d4 100644 --- a/packages/fuel-gauge/src/doc-examples.test.ts +++ b/packages/fuel-gauge/src/doc-examples.test.ts @@ -29,11 +29,11 @@ import { } from 'fuels'; import { join } from 'path'; -import abiJSON from '../test-projects/call-test-contract/out/debug/call-test-abi.json'; -import liquidityPoolABI from '../test-projects/liquidity-pool/out/debug/liquidity-pool-abi.json'; -import predicateTriple from '../test-projects/predicate-triple-sig'; -import testPredicateTrue from '../test-projects/predicate-true'; -import tokenContractABI from '../test-projects/token_contract/out/debug/token_contract-abi.json'; +import abiJSON from '../fixtures/forc-projects/call-test-contract/out/debug/call-test-abi.json'; +import liquidityPoolABI from '../fixtures/forc-projects/liquidity-pool/out/debug/liquidity-pool-abi.json'; +import predicateTriple from '../fixtures/forc-projects/predicate-triple-sig'; +import testPredicateTrue from '../fixtures/forc-projects/predicate-true'; +import tokenContractABI from '../fixtures/forc-projects/token_contract/out/debug/token_contract-abi.json'; const PUBLIC_KEY = '0x2f34bc0df4db0ec391792cedb05768832b49b1aa3a2dd8c30054d1af00f67d00b74b7acbbf3087c8e0b1a4c343db50aa471d21f278ff5ce09f07795d541fb47e'; @@ -442,14 +442,14 @@ test('deposit and withdraw cookbook guide', async () => { // #region deposit-and-withdraw-cookbook-contract-deployments const tokenContractBytecode = readFileSync( - join(__dirname, '../test-projects/token_contract/out/debug/token_contract.bin') + join(__dirname, '../fixtures/forc-projects/token_contract/out/debug/token_contract.bin') ); const tokenContractFactory = new ContractFactory(tokenContractBytecode, tokenContractABI, wallet); const tokenContract = await tokenContractFactory.deployContract(); const tokenContractID = tokenContract.id; const liquidityPoolContractBytecode = readFileSync( - join(__dirname, '../test-projects/liquidity-pool/out/debug/liquidity-pool.bin') + join(__dirname, '../fixtures/forc-projects/liquidity-pool/out/debug/liquidity-pool.bin') ); const liquidityPoolContractFactory = new ContractFactory( liquidityPoolContractBytecode, diff --git a/packages/fuel-gauge/src/generic-types-contract.test.ts b/packages/fuel-gauge/src/generic-types-contract.test.ts index 0d8ae6f4d8..bd95c64b8a 100644 --- a/packages/fuel-gauge/src/generic-types-contract.test.ts +++ b/packages/fuel-gauge/src/generic-types-contract.test.ts @@ -2,12 +2,15 @@ import { readFileSync } from 'fs'; import { toHex } from 'fuels'; import { join } from 'path'; -import abiJSON from '../test-projects/generic-types-contract/out/debug/generic-types-contract-abi.json'; +import abiJSON from '../fixtures/forc-projects/generic-types-contract/out/debug/generic-types-contract-abi.json'; import { setup } from './utils'; const contractBytecode = readFileSync( - join(__dirname, '../test-projects/generic-types-contract/out/debug/generic-types-contract.bin') + join( + __dirname, + '../fixtures/forc-projects/generic-types-contract/out/debug/generic-types-contract.bin' + ) ); describe('GenericTypesContract', () => { diff --git a/packages/fuel-gauge/src/payable-annotation.test.ts b/packages/fuel-gauge/src/payable-annotation.test.ts index a19da92492..013ab28dd2 100644 --- a/packages/fuel-gauge/src/payable-annotation.test.ts +++ b/packages/fuel-gauge/src/payable-annotation.test.ts @@ -2,12 +2,12 @@ import { readFileSync } from 'fs'; import { bn, NativeAssetId } from 'fuels'; import { join } from 'path'; -import abiJSON from '../test-projects/payable-annotation/out/debug/payable-annotation-abi.json'; +import abiJSON from '../fixtures/forc-projects/payable-annotation/out/debug/payable-annotation-abi.json'; import { createSetupConfig } from './utils'; const contractBytecode = readFileSync( - join(__dirname, '../test-projects/payable-annotation/out/debug/payable-annotation.bin') + join(__dirname, '../fixtures/forc-projects/payable-annotation/out/debug/payable-annotation.bin') ); const setupContract = createSetupConfig({ diff --git a/packages/fuel-gauge/src/predicate-with-configurable.test.ts b/packages/fuel-gauge/src/predicate-with-configurable.test.ts deleted file mode 100644 index 2bb5e1cd27..0000000000 --- a/packages/fuel-gauge/src/predicate-with-configurable.test.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { generateTestWallet } from '@fuel-ts/wallet/test-utils'; -import { readFileSync } from 'fs'; -import type { Account, CoinQuantityLike } from 'fuels'; -import { getRandomB256, WalletUnlocked, Predicate, BN, NativeAssetId, Provider } from 'fuels'; -import { join } from 'path'; - -import abi from '../test-projects/predicate-with-configurable/out/debug/predicate-with-configurable-abi.json'; - -const bytecode = readFileSync( - join( - __dirname, - '../test-projects/predicate-with-configurable/out/debug/predicate-with-configurable.bin' - ) -); - -const defaultValues = { - FEE: 10, - ADDRESS: '0x38966262edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96', -}; - -let wallet: WalletUnlocked; - -const fundPredicate = async (predicate: Predicate<[number]>, amount: number) => { - const tx = await wallet.transfer(predicate.address, amount); - - await tx.waitForResult(); -}; - -const assertAccountBalance = async (account: Account, valueToAssert: number) => { - const balance = await account.getBalance(NativeAssetId); - - expect(new BN(balance).toNumber()).toEqual(valueToAssert); -}; - -describe('Predicate With Configurable', () => { - beforeAll(async () => { - const provider = new Provider('http://127.0.0.1:4000/graphql'); - - const quantities: CoinQuantityLike[] = [ - { - amount: 1_000_000, - assetId: NativeAssetId, - }, - ]; - - wallet = await generateTestWallet(provider, quantities); - }); - - it('should assert when input values are set to default configurable constants values', async () => { - const chainId = await wallet.provider.getChainId(); - const predicate = new Predicate(bytecode, chainId, abi, wallet.provider); - - const amountToTransfer = 200; - - // transfer funds to predicate - await fundPredicate(predicate, 500); - - // create destination wallet - const destination = WalletUnlocked.generate(); - - await assertAccountBalance(destination, 0); - - // set predicate input data to be the same as default configurable value - predicate.setData(defaultValues.FEE, defaultValues.ADDRESS); - - const tx = await predicate.transfer(destination.address, amountToTransfer); - - await tx.waitForResult(); - - await assertAccountBalance(destination, amountToTransfer); - }); - - it('should assert when input and configurable values are set equal (FEE)', async () => { - const configurableConstants = { FEE: 35 }; - - expect(configurableConstants.FEE).not.toEqual(defaultValues.FEE); - const chainId = await wallet.provider.getChainId(); - const predicate = new Predicate(bytecode, chainId, abi, wallet.provider, configurableConstants); - - const amountToTransfer = 300; - - const destination = WalletUnlocked.generate(); - - await assertAccountBalance(destination, 0); - - // transfer funds to predicate - await fundPredicate(predicate, 500); - - predicate.setData(configurableConstants.FEE, defaultValues.ADDRESS); - - // executing predicate transfer - const tx = await predicate.transfer(destination.address, amountToTransfer); - - await tx.waitForResult(); - - await assertAccountBalance(destination, amountToTransfer); - }); - - it('should assert when input and configurable values are set equal (ADDRESS)', async () => { - const configurableConstants = { ADDRESS: getRandomB256() }; - - expect(configurableConstants.ADDRESS).not.toEqual(defaultValues.ADDRESS); - const chainId = await wallet.provider.getChainId(); - const predicate = new Predicate(bytecode, chainId, abi, wallet.provider, configurableConstants); - - const amountToTransfer = 300; - - const destination = WalletUnlocked.generate(); - - await assertAccountBalance(destination, 0); - - // transfer funds to predicate - await fundPredicate(predicate, 500); - - predicate.setData(defaultValues.FEE, configurableConstants.ADDRESS); - - // executing predicate transfer - const tx = await predicate.transfer(destination.address, amountToTransfer); - - await tx.waitForResult(); - - await assertAccountBalance(destination, amountToTransfer); - }); - - it('should assert when input and configurable values are set equal (BOTH)', async () => { - const configurableConstants = { - FEE: 90, - ADDRESS: getRandomB256(), - }; - - expect(configurableConstants.FEE).not.toEqual(defaultValues.FEE); - expect(configurableConstants.ADDRESS).not.toEqual(defaultValues.ADDRESS); - const chainId = await wallet.provider.getChainId(); - const predicate = new Predicate(bytecode, chainId, abi, wallet.provider, configurableConstants); - - const amountToTransfer = 300; - - const destination = WalletUnlocked.generate(); - - await assertAccountBalance(destination, 0); - - await fundPredicate(predicate, 500); - - predicate.setData(configurableConstants.FEE, configurableConstants.ADDRESS); - - const tx = await predicate.transfer(destination.address, amountToTransfer); - - await tx.waitForResult(); - - await assertAccountBalance(destination, amountToTransfer); - }); - - it('should throws when no input data is given', async () => { - const chainId = await wallet.provider.getChainId(); - const predicate = new Predicate(bytecode, chainId, abi, wallet.provider); - - const destination = WalletUnlocked.generate(); - - await expect(predicate.transfer(destination.address, 300)).rejects.toThrowError(); - }); -}); diff --git a/packages/fuel-gauge/src/predicate.test.ts b/packages/fuel-gauge/src/predicate.test.ts deleted file mode 100644 index 5633b5b481..0000000000 --- a/packages/fuel-gauge/src/predicate.test.ts +++ /dev/null @@ -1,700 +0,0 @@ -import { generateTestWallet } from '@fuel-ts/wallet/test-utils'; -import { readFileSync } from 'fs'; -import type { BigNumberish, WalletUnlocked, InputValue, WalletLocked, BN, JsonAbi } from 'fuels'; -import { - ContractFactory, - Script, - Address, - bn, - toHex, - toNumber, - Provider, - Predicate, - Wallet, - Contract, - NativeAssetId, -} from 'fuels'; -import { join } from 'path'; - -import contractABIJSON from '../test-projects/call-test-contract/out/debug/call-test-abi.json'; -import testPredicateAddress from '../test-projects/predicate-address'; -import testPredicateFalse from '../test-projects/predicate-false'; -import testPredicateMainArgsStruct from '../test-projects/predicate-main-args-struct'; -import predicateMainArgsStructAbi from '../test-projects/predicate-main-args-struct/out/debug/predicate-main-args-struct-abi.json'; -import testPredicateMainArgsVector from '../test-projects/predicate-main-args-vector'; -import testPredicateMainArgsVectorAbi from '../test-projects/predicate-main-args-vector/out/debug/predicate-main-args-vector-abi.json'; -import testPredicateStruct from '../test-projects/predicate-struct'; -import testPredicateTrue from '../test-projects/predicate-true'; -import testPredicateU32 from '../test-projects/predicate-u32'; - -import { createSetupConfig } from './utils'; - -const testPredicateStructBin = readFileSync( - join(__dirname, '../test-projects/predicate-struct/out/debug/predicate-struct.bin') -); - -const contractBytecode = readFileSync( - join(__dirname, '../test-projects/call-test-contract/out/debug/call-test.bin') -); - -const setupContract = createSetupConfig({ - contractBytecode, - abi: contractABIJSON, - cache: true, -}); - -const setup = async () => { - const provider = new Provider('http://127.0.0.1:4000/graphql'); - const wallet = await generateTestWallet(provider, [[5_000_000, NativeAssetId]]); - const receiver = Wallet.fromAddress(Address.fromRandom()); - return [wallet, receiver] as const; -}; - -const setupPredicate = async ( - wallet: WalletUnlocked, - predicate: Predicate, - amountToPredicate: BigNumberish -): Promise => { - const tx = await wallet.transfer(predicate.address, amountToPredicate, NativeAssetId); - await tx.waitForResult(); - // collect balance from predicate to prevent flaky tests where predicate address gets "filled up" - return predicate.getBalance(); -}; - -const assertResults = async ( - predicate: Predicate, - receiver: WalletLocked, - initialPredicateBalance: BN, - initialReceiverBalance: BN, - amountToPredicate: BigNumberish, - amountToReceiver: BigNumberish - // isSkippingInitialReceiverBalance = false -): Promise => { - // Check there are UTXO locked with the predicate hash - expect(toNumber(initialPredicateBalance)).toBeGreaterThanOrEqual(toNumber(amountToPredicate)); - expect(initialReceiverBalance.toHex()).toEqual(toHex(0)); - - // Check the balance of the receiver - const finalReceiverBalance = await receiver.getBalance(); - expect(bn(initialReceiverBalance).add(amountToReceiver).toHex()).toEqual( - finalReceiverBalance.toHex() - ); - - // Check we spent the entire predicate hash input - const finalPredicateBalance = await predicate.getBalance(); - expect(finalPredicateBalance.lte(initialPredicateBalance)).toBeTruthy(); -}; - -type Validation = { - has_account: boolean; - total_complete: BigNumberish; -}; -const AddressAbiInputs: JsonAbi = { - types: [ - { - typeId: 0, - type: 'bool', - components: null, - typeParameters: null, - }, - { - typeId: 1, - type: 'b256', - components: null, - typeParameters: null, - }, - ], - functions: [ - { - inputs: [ - { - name: 'data', - type: 1, - typeArguments: null, - }, - ], - name: 'main', - output: { - name: '', - type: 0, - typeArguments: null, - }, - attributes: null, - }, - ], - loggedTypes: [], - configurables: [], -}; - -const U32AbiInputs: JsonAbi = { - types: [ - { - typeId: 0, - type: 'bool', - components: null, - typeParameters: null, - }, - { - typeId: 1, - type: 'u32', - components: null, - typeParameters: null, - }, - ], - functions: [ - { - inputs: [ - { - name: 'data', - type: 1, - typeArguments: null, - }, - ], - name: 'main', - output: { - name: '', - type: 0, - typeArguments: null, - }, - attributes: null, - }, - ], - loggedTypes: [], - configurables: [], -}; - -const StructAbiInputs: JsonAbi = { - types: [ - { - typeId: 0, - type: 'bool', - components: null, - typeParameters: null, - }, - { - typeId: 1, - type: 'struct Validation', - components: [ - { - name: 'has_account', - type: 0, - typeArguments: null, - }, - { - name: 'total_complete', - type: 2, - typeArguments: null, - }, - ], - typeParameters: null, - }, - { - typeId: 2, - type: 'u64', - components: null, - typeParameters: null, - }, - ], - functions: [ - { - inputs: [ - { - name: 'data', - type: 1, - typeArguments: null, - }, - ], - name: 'main', - output: { - name: '', - type: 0, - typeArguments: null, - }, - attributes: null, - }, - ], - loggedTypes: [], - configurables: [], -}; -describe('Predicate', () => { - it('can call a no-arg Predicate that returns true', async () => { - const [wallet, receiver] = await setup(); - const amountToPredicate = 100; - const amountToReceiver = 50; - const chainId = await wallet.provider.getChainId(); - const predicate = new Predicate(testPredicateTrue, chainId); - - const initialReceiverBalance = await receiver.getBalance(); - const initialPredicateBalance = await setupPredicate(wallet, predicate, amountToPredicate); - - const tx = await predicate.transfer(receiver.address, amountToReceiver); - await tx.waitForResult(); - - await assertResults( - predicate, - receiver, - initialPredicateBalance, - initialReceiverBalance, - amountToPredicate, - amountToReceiver - ); - }); - - it('can call a no-arg Predicate that returns false', async () => { - const [wallet, receiver] = await setup(); - const amountToPredicate = 100; - const amountToReceiver = 50; - const chainId = await wallet.provider.getChainId(); - const predicate = new Predicate(testPredicateFalse, chainId); - - await setupPredicate(wallet, predicate, amountToPredicate); - - await expect(predicate.transfer(receiver.address, amountToReceiver)).rejects.toThrow( - 'Invalid transaction' - ); - }); - - it('can call a Coin predicate which returns true with valid predicate data [address]', async () => { - const [wallet, receiver] = await setup(); - const amountToPredicate = 100; - const amountToReceiver = 50; - const chainId = await wallet.provider.getChainId(); - const predicate = new Predicate<[string]>(testPredicateAddress, chainId, AddressAbiInputs); - - const initialPredicateBalance = await setupPredicate(wallet, predicate, amountToPredicate); - const initialReceiverBalance = await receiver.getBalance(); - - const tx = await predicate - .setData('0xef86afa9696cf0dc6385e2c407a6e159a1103cefb7e2ae0636fb33d3cb2a9e4a') - .transfer(receiver.address, amountToReceiver); - await tx.waitForResult(); - - await assertResults( - predicate, - receiver, - initialPredicateBalance, - initialReceiverBalance, - amountToPredicate, - amountToReceiver - ); - }); - - it('can call a Coin predicate which returns false with invalid predicate data [address]', async () => { - const [wallet, receiver] = await setup(); - const amountToPredicate = 10; - const chainId = await wallet.provider.getChainId(); - const predicate = new Predicate<[string]>(testPredicateAddress, chainId, AddressAbiInputs); - - const initialPredicateBalance = await setupPredicate(wallet, predicate, amountToPredicate); - const initialReceiverBalance = await receiver.getBalance(); - - // Check there are UTXO locked with the predicate hash - expect(initialPredicateBalance.gte(amountToPredicate)); - expect(initialReceiverBalance.toHex()).toEqual(toHex(0)); - - predicate.setData('0xbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbada'); - - await expect(predicate.transfer(receiver.address, 50)).rejects.toThrow('Invalid transaction'); - }); - - it('can call a Coin predicate which returns true with valid predicate data [u32]', async () => { - const [wallet, receiver] = await setup(); - const amountToPredicate = 100; - const amountToReceiver = 50; - const chainId = await wallet.provider.getChainId(); - const predicate = new Predicate<[number]>(testPredicateU32, chainId, U32AbiInputs); - - const initialPredicateBalance = await setupPredicate(wallet, predicate, amountToPredicate); - const initialReceiverBalance = await receiver.getBalance(); - - const tx = await predicate.setData(1078).transfer(receiver.address, amountToReceiver); - await tx.waitForResult(); - - await assertResults( - predicate, - receiver, - initialPredicateBalance, - initialReceiverBalance, - amountToPredicate, - amountToReceiver - ); - }); - - it('can call a Coin predicate which returns false with invalid predicate data [u32]', async () => { - const [wallet, receiver] = await setup(); - const amountToPredicate = 10; - const chainId = await wallet.provider.getChainId(); - const predicate = new Predicate<[number]>(testPredicateU32, chainId, U32AbiInputs); - - const initialPredicateBalance = await setupPredicate(wallet, predicate, amountToPredicate); - const initialReceiverBalance = await receiver.getBalance(); - - // Check there are UTXO locked with the predicate hash - expect(toNumber(initialPredicateBalance)).toBeGreaterThanOrEqual(amountToPredicate); - expect(initialReceiverBalance.toHex()).toEqual(toHex(0)); - - await expect( - predicate.setData(100).transfer(receiver.address, amountToPredicate) - ).rejects.toThrow('Invalid transaction'); - }); - - it('can call a Coin predicate which returns true with valid predicate data [struct]', async () => { - const [wallet, receiver] = await setup(); - const amountToPredicate = 100; - const amountToReceiver = 50; - const chainId = await wallet.provider.getChainId(); - const predicate = new Predicate<[Validation]>(testPredicateStruct, chainId, StructAbiInputs); - - const initialPredicateBalance = await setupPredicate(wallet, predicate, amountToPredicate); - const initialReceiverBalance = await receiver.getBalance(); - - const tx = await predicate - .setData({ - has_account: true, - total_complete: 100, - }) - .transfer(receiver.address, amountToReceiver); - await tx.waitForResult(); - - await assertResults( - predicate, - receiver, - initialPredicateBalance, - initialReceiverBalance, - amountToPredicate, - amountToReceiver - ); - }); - - it('can call a [bin] Coin predicate which returns false with invalid predicate data [struct]', async () => { - const [wallet, receiver] = await setup(); - const amountToPredicate = 10; - const chainId = await wallet.provider.getChainId(); - const predicate = new Predicate<[Validation]>(testPredicateStructBin, chainId, StructAbiInputs); - - const initialPredicateBalance = await setupPredicate(wallet, predicate, amountToPredicate); - const initialReceiverBalance = await receiver.getBalance(); - - // Check there are UTXO locked with the predicate hash - expect(toNumber(initialPredicateBalance)).toBeGreaterThanOrEqual(amountToPredicate); - expect(initialReceiverBalance.toHex()).toEqual(toHex(0)); - - await expect( - predicate - .setData({ - has_account: false, - total_complete: 0, - }) - .transfer(receiver.address, amountToPredicate) - ).rejects.toThrow('Invalid transaction'); - }); - - it('can call a Coin predicate which returns true with valid predicate data [main args struct]', async () => { - const [wallet, receiver] = await setup(); - const amountToPredicate = 100; - const amountToReceiver = 50; - const chainId = await wallet.provider.getChainId(); - const predicate = new Predicate<[Validation]>( - testPredicateStruct, - chainId, - predicateMainArgsStructAbi - ); - - const initialPredicateBalance = await setupPredicate(wallet, predicate, amountToPredicate); - const initialReceiverBalance = await receiver.getBalance(); - - const tx = await predicate - .setData({ - has_account: true, - total_complete: 100, - }) - .transfer(receiver.address, amountToReceiver); - await tx.waitForResult(); - - await assertResults( - predicate, - receiver, - initialPredicateBalance, - initialReceiverBalance, - amountToPredicate, - amountToReceiver - ); - }); - - it('can call a [bin] Coin predicate which returns false with invalid predicate data [main args struct]', async () => { - const [wallet, receiver] = await setup(); - const amountToPredicate = 100; - const chainId = await wallet.provider.getChainId(); - const predicate = new Predicate<[Validation]>( - testPredicateMainArgsStruct, - chainId, - predicateMainArgsStructAbi - ); - - const initialPredicateBalance = await setupPredicate(wallet, predicate, amountToPredicate); - - // Check there are UTXO locked with the predicate hash - expect(toNumber(initialPredicateBalance)).toBeGreaterThanOrEqual(amountToPredicate); - - await expect( - predicate - .setData({ - has_account: false, - total_complete: 0, - }) - .transfer(receiver.address, 50) - ).rejects.toThrow('Invalid transaction'); - }); - - it.skip('can call a Coin predicate which returns true with valid predicate data [main args vector]', async () => { - const [wallet, receiver] = await setup(); - const amountToPredicate = 100; - const chainId = await wallet.provider.getChainId(); - const amountToReceiver = 50; - const predicate = new Predicate<[BigNumberish[]]>( - testPredicateMainArgsVector, - chainId, - testPredicateMainArgsVectorAbi - ); - - const initialPredicateBalance = await setupPredicate(wallet, predicate, amountToPredicate); - const initialReceiverBalance = await receiver.getBalance(); - - const tx = await predicate.setData([42]).transfer(receiver.address, amountToReceiver); - await tx.waitForResult(); - - await assertResults( - predicate, - receiver, - initialPredicateBalance, - initialReceiverBalance, - amountToPredicate, - amountToReceiver - ); - }); - - it('should fail if inform gasLimit too low', async () => { - const [wallet, receiver] = await setup(); - const amountToPredicate = 100; - const chainId = await wallet.provider.getChainId(); - const predicate = new Predicate<[Validation]>( - testPredicateStruct, - chainId, - predicateMainArgsStructAbi - ); - - const predicateBalance = await setupPredicate(wallet, predicate, amountToPredicate); - - const validation: Validation = { - has_account: true, - total_complete: 100, - }; - - // Should throw if not have resouces to pay tx + gasFee - await expect( - predicate.setData(validation).transfer(receiver.address, predicateBalance) - ).rejects.toThrow(/not enough coins to fit the target/i); - - // Should throw if gasLimit is too low - // TODO: When gas is to low the return error is Invalid transaction, once is fixed on the - // fuel-client we should change with the proper error message - await expect( - predicate.setData(validation).transfer(receiver.address, 50, NativeAssetId, { - gasLimit: 1, - }) - ).rejects.toThrow(/Invalid transaction/i); - }); - - it('Should be able to use a Predicate to call a contract', async () => { - const [wallet] = await setup(); - const contract = await setupContract(); - const amountToPredicate = 100_000; - const chainId = await wallet.provider.getChainId(); - const predicate = new Predicate<[Validation]>( - testPredicateTrue, - chainId, - predicateMainArgsStructAbi - ); - // Create a instance of the contract with the predicate as the caller Account - const contractPredicate = new Contract(contract.id, contract.interface, predicate); - const predicateBalance = await setupPredicate(wallet, predicate, amountToPredicate); - - const { value } = await contractPredicate.functions - .return_context_amount() - .callParams({ - forward: [500, NativeAssetId], - }) - .call(); - expect(value.toString()).toEqual('500'); - - const finalPredicateBalance = await predicate.getBalance(); - expect(finalPredicateBalance.lt(predicateBalance)).toBeTruthy(); - }); - - it('can successfully uses proceeds of predicate in a script call', async () => { - const provider = new Provider('http://127.0.0.1:4000/graphql'); - - const sender = await generateTestWallet(provider, [[5_000_000, NativeAssetId]]); - const receiver = await generateTestWallet(provider); - - const initialReceiverBalance = toNumber(await receiver.getBalance()); - - // instantiating the script - const scriptAbi = JSON.parse( - readFileSync( - join(__dirname, '../test-projects/script-main-args/out/debug/script-main-args-abi.json') - ).toString() - ); - - const scriptBin = readFileSync( - join(__dirname, '../test-projects/script-main-args/out/debug/script-main-args.bin') - ); - - const scriptInstance = new Script(scriptBin, scriptAbi, sender); - - // calling the script with the receiver account (no resources) - const scriptInput = 1; - scriptInstance.account = receiver; - await expect(scriptInstance.functions.main(scriptInput).call()).rejects.toThrow( - /not enough coins to fit the target/ - ); - - // setup predicate - const amountToPredicate = 100; - const amountToReceiver = 50; - const chainId = await sender.provider.getChainId(); - const predicate = new Predicate<[Validation]>( - testPredicateStruct, - chainId, - predicateMainArgsStructAbi - ); - const initialPredicateBalance = toNumber(await predicate.getBalance()); - - await setupPredicate(sender, predicate, amountToPredicate); - - expect(toNumber(await predicate.getBalance())).toEqual( - initialPredicateBalance + amountToPredicate - ); - - // executing predicate to transfer resources to receiver - const tx = await predicate - .setData({ - has_account: true, - total_complete: 100, - }) - .transfer(receiver.address, amountToReceiver); - - await tx.waitForResult(); - - const finalReceiverBalance = toNumber(await receiver.getBalance()); - - // calling the script with the receiver account (with resources) - await expect(scriptInstance.functions.main(scriptInput).call()).resolves.toBeTruthy(); - - const remainingPredicateBalance = toNumber(await predicate.getBalance()); - - expect(toNumber(initialReceiverBalance)).toBe(0); - expect(initialReceiverBalance + amountToReceiver).toEqual(finalReceiverBalance); - - expect(remainingPredicateBalance).toEqual( - amountToPredicate + initialPredicateBalance - amountToReceiver - ); - }); - - it('can successfully uses proceeds of predicate in a contract call', async () => { - const provider = new Provider('http://127.0.0.1:4000/graphql'); - - const sender = await generateTestWallet(provider, [[5_000_000, NativeAssetId]]); - const receiver = await generateTestWallet(provider); - - const initialReceiverBalance = toNumber(await receiver.getBalance()); - - // instantiating the contract - const byteCode = readFileSync( - join(__dirname, '../test-projects/liquidity-pool/out/debug/liquidity-pool.bin') - ); - - const abi = JSON.parse( - readFileSync( - join(__dirname, '../test-projects/liquidity-pool/out/debug/liquidity-pool-abi.json') - ).toString() - ); - - const contract = await new ContractFactory(byteCode, abi, sender).deployContract(); - - // calling the contract with the receiver account (no resources) - contract.account = receiver; - await expect( - contract.functions - .deposit({ - value: receiver.address.toB256(), - }) - .callParams({ - forward: [100, NativeAssetId], - }) - .txParams({ - gasPrice: 1, - }) - .call() - ).rejects.toThrow(/not enough coins to fit the target/); - - // setup predicate - const amountToPredicate = 100; - const amountToReceiver = 50; - const chainId = await sender.provider.getChainId(); - const predicate = new Predicate<[Validation]>( - testPredicateStruct, - chainId, - predicateMainArgsStructAbi - ); - const initialPredicateBalance = toNumber(await predicate.getBalance()); - - await setupPredicate(sender, predicate, amountToPredicate); - - expect(toNumber(await predicate.getBalance())).toEqual( - initialPredicateBalance + amountToPredicate - ); - - // executing predicate to transfer resources to receiver - const tx = await predicate - .setData({ - has_account: true, - total_complete: 100, - }) - .transfer(receiver.address, amountToReceiver); - - await tx.waitForResult(); - - // calling the contract with the receiver account (with resources) - const gasPrice = 1; - const contractAmount = 10; - - await contract.functions.set_base_token(NativeAssetId).call(); - await expect( - contract.functions - .deposit({ - value: receiver.address.toB256(), - }) - .callParams({ - forward: [contractAmount, NativeAssetId], - }) - .txParams({ - gasPrice, - }) - .call() - ).resolves.toBeTruthy(); - - const finalReceiverBalance = toNumber(await receiver.getBalance()); - const remainingPredicateBalance = toNumber(await predicate.getBalance()); - - expect(initialReceiverBalance).toBe(0); - - expect(initialReceiverBalance + amountToReceiver).toEqual( - finalReceiverBalance + contractAmount + gasPrice - ); - - expect(remainingPredicateBalance).toEqual( - amountToPredicate + initialPredicateBalance - amountToReceiver - ); - }); -}); diff --git a/packages/fuel-gauge/src/predicate/predicate-arguments.test.ts b/packages/fuel-gauge/src/predicate/predicate-arguments.test.ts new file mode 100644 index 0000000000..d981090758 --- /dev/null +++ b/packages/fuel-gauge/src/predicate/predicate-arguments.test.ts @@ -0,0 +1,358 @@ +import type { WalletLocked, WalletUnlocked, JsonAbi } from 'fuels'; +import { toHex, toNumber, Predicate } from 'fuels'; + +import predicateBytesAddress from '../../fixtures/forc-projects/predicate-address'; +import predicateBytesMainArgsStruct from '../../fixtures/forc-projects/predicate-main-args-struct'; +import predicateAbiMainArgsStruct from '../../fixtures/forc-projects/predicate-main-args-struct/out/debug/predicate-main-args-struct-abi.json'; +import predicateBytesStruct from '../../fixtures/forc-projects/predicate-struct'; +import predicateBytesU32 from '../../fixtures/forc-projects/predicate-u32'; +import type { Validation } from '../types/predicate'; + +import { setupWallets, assertBalances, fundPredicate } from './utils/predicate'; + +describe('Predicate', () => { + describe('Arguments', () => { + let wallet: WalletUnlocked; + let receiver: WalletLocked; + let chainId: number; + + const AddressAbiInputs: JsonAbi = { + types: [ + { + typeId: 0, + type: 'bool', + components: null, + typeParameters: null, + }, + { + typeId: 1, + type: 'b256', + components: null, + typeParameters: null, + }, + ], + functions: [ + { + inputs: [ + { + name: 'data', + type: 1, + typeArguments: null, + }, + ], + name: 'main', + output: { + name: '', + type: 0, + typeArguments: null, + }, + attributes: null, + }, + ], + loggedTypes: [], + configurables: [], + }; + + const U32AbiInputs: JsonAbi = { + types: [ + { + typeId: 0, + type: 'bool', + components: null, + typeParameters: null, + }, + { + typeId: 1, + type: 'u32', + components: null, + typeParameters: null, + }, + ], + functions: [ + { + inputs: [ + { + name: 'data', + type: 1, + typeArguments: null, + }, + ], + name: 'main', + output: { + name: '', + type: 0, + typeArguments: null, + }, + attributes: null, + }, + ], + loggedTypes: [], + configurables: [], + }; + + const StructAbiInputs: JsonAbi = { + types: [ + { + typeId: 0, + type: 'bool', + components: null, + typeParameters: null, + }, + { + typeId: 1, + type: 'struct Validation', + components: [ + { + name: 'has_account', + type: 0, + typeArguments: null, + }, + { + name: 'total_complete', + type: 2, + typeArguments: null, + }, + ], + typeParameters: null, + }, + { + typeId: 2, + type: 'u64', + components: null, + typeParameters: null, + }, + ], + functions: [ + { + inputs: [ + { + name: 'data', + type: 1, + typeArguments: null, + }, + ], + name: 'main', + output: { + name: '', + type: 0, + typeArguments: null, + }, + attributes: null, + }, + ], + loggedTypes: [], + configurables: [], + }; + + beforeEach(async () => { + [wallet, receiver] = await setupWallets(); + chainId = await wallet.provider.getChainId(); + }); + + it('calls a predicate with valid address data and returns true', async () => { + const amountToPredicate = 100; + const amountToReceiver = 50; + const predicate = new Predicate<[string]>(predicateBytesAddress, chainId, AddressAbiInputs); + + const initialPredicateBalance = await fundPredicate(wallet, predicate, amountToPredicate); + const initialReceiverBalance = await receiver.getBalance(); + + const tx = await predicate + .setData('0xef86afa9696cf0dc6385e2c407a6e159a1103cefb7e2ae0636fb33d3cb2a9e4a') + .transfer(receiver.address, amountToReceiver); + await tx.waitForResult(); + + await assertBalances( + predicate, + receiver, + initialPredicateBalance, + initialReceiverBalance, + amountToPredicate, + amountToReceiver + ); + }); + + it('calls a predicate with invalid address data and returns false', async () => { + const amountToPredicate = 10; + const predicate = new Predicate<[string]>(predicateBytesAddress, chainId, AddressAbiInputs); + + const initialPredicateBalance = await fundPredicate(wallet, predicate, amountToPredicate); + const initialReceiverBalance = await receiver.getBalance(); + + // Check there are UTXO locked with the predicate hash + expect(initialPredicateBalance.gte(amountToPredicate)); + expect(initialReceiverBalance.toHex()).toEqual(toHex(0)); + + predicate.setData('0xbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbada'); + + await expect(predicate.transfer(receiver.address, 50)).rejects.toThrow('Invalid transaction'); + }); + + it('calls a predicate with valid u32 data and returns true', async () => { + const amountToPredicate = 100; + const amountToReceiver = 50; + const predicate = new Predicate<[number]>(predicateBytesU32, chainId, U32AbiInputs); + + const initialPredicateBalance = await fundPredicate(wallet, predicate, amountToPredicate); + const initialReceiverBalance = await receiver.getBalance(); + + const tx = await predicate.setData(1078).transfer(receiver.address, amountToReceiver); + await tx.waitForResult(); + + await assertBalances( + predicate, + receiver, + initialPredicateBalance, + initialReceiverBalance, + amountToPredicate, + amountToReceiver + ); + }); + + it('calls a predicate with invalid u32 data and returns false', async () => { + const amountToPredicate = 10; + const predicate = new Predicate<[number]>(predicateBytesU32, chainId, U32AbiInputs); + + const initialPredicateBalance = await fundPredicate(wallet, predicate, amountToPredicate); + const initialReceiverBalance = await receiver.getBalance(); + + // Check there are UTXO locked with the predicate hash + expect(toNumber(initialPredicateBalance)).toBeGreaterThanOrEqual(amountToPredicate); + expect(initialReceiverBalance.toHex()).toEqual(toHex(0)); + + await expect( + predicate.setData(100).transfer(receiver.address, amountToPredicate) + ).rejects.toThrow('Invalid transaction'); + }); + + it('calls a predicate with valid struct data and returns true', async () => { + const amountToPredicate = 100; + const amountToReceiver = 50; + const predicate = new Predicate<[Validation]>(predicateBytesStruct, chainId, StructAbiInputs); + + const initialPredicateBalance = await fundPredicate(wallet, predicate, amountToPredicate); + const initialReceiverBalance = await receiver.getBalance(); + + const tx = await predicate + .setData({ + has_account: true, + total_complete: 100, + }) + .transfer(receiver.address, amountToReceiver); + await tx.waitForResult(); + + await assertBalances( + predicate, + receiver, + initialPredicateBalance, + initialReceiverBalance, + amountToPredicate, + amountToReceiver + ); + }); + + it('calls a predicate with invalid struct data and returns false', async () => { + const amountToPredicate = 10; + const predicate = new Predicate<[Validation]>(predicateBytesStruct, chainId, StructAbiInputs); + + const initialPredicateBalance = await fundPredicate(wallet, predicate, amountToPredicate); + const initialReceiverBalance = await receiver.getBalance(); + + // Check there are UTXO locked with the predicate hash + expect(toNumber(initialPredicateBalance)).toBeGreaterThanOrEqual(amountToPredicate); + expect(initialReceiverBalance.toHex()).toEqual(toHex(0)); + + await expect( + predicate + .setData({ + has_account: false, + total_complete: 0, + }) + .transfer(receiver.address, amountToPredicate) + ).rejects.toThrow('Invalid transaction'); + }); + + it('calls a predicate with a valid struct argument and returns true', async () => { + const amountToPredicate = 100; + const amountToReceiver = 50; + const predicate = new Predicate<[Validation]>( + predicateBytesMainArgsStruct, + chainId, + predicateAbiMainArgsStruct + ); + + const initialPredicateBalance = await fundPredicate(wallet, predicate, amountToPredicate); + const initialReceiverBalance = await receiver.getBalance(); + + const tx = await predicate + .setData({ + has_account: true, + total_complete: 100, + }) + .transfer(receiver.address, amountToReceiver); + await tx.waitForResult(); + + await assertBalances( + predicate, + receiver, + initialPredicateBalance, + initialReceiverBalance, + amountToPredicate, + amountToReceiver + ); + }); + + it('calls a predicate with an invalid main struct argument and returns false', async () => { + const amountToPredicate = 100; + const predicate = new Predicate<[Validation]>( + predicateBytesMainArgsStruct, + chainId, + predicateAbiMainArgsStruct + ); + + const initialPredicateBalance = await fundPredicate(wallet, predicate, amountToPredicate); + + // Check there are UTXO locked with the predicate hash + expect(toNumber(initialPredicateBalance)).toBeGreaterThanOrEqual(amountToPredicate); + + await expect( + predicate + .setData({ + has_account: false, + total_complete: 0, + }) + .transfer(receiver.address, 50) + ).rejects.toThrow('Invalid transaction'); + }); + + /** + * TODO: Implement vec test + it.skip('can call a Coin predicate which returns true with valid predicate data [main args vector]', async () => { + const [wallet, receiver] = await setup(); + const amountToPredicate = 100; + const chainId = await wallet.provider.getChainId(); + const amountToReceiver = 50; + const predicate = new Predicate<[BigNumberish[]]>( + testPredicateMainArgsVector, + chainId, + testPredicateMainArgsVectorAbi + ); + + const initialPredicateBalance = await setupPredicate(wallet, predicate, amountToPredicate); + const initialReceiverBalance = await receiver.getBalance(); + + const tx = await predicate.setData([42]).transfer(receiver.address, amountToReceiver); + await tx.waitForResult(); + + await assertResults( + predicate, + receiver, + initialPredicateBalance, + initialReceiverBalance, + amountToPredicate, + amountToReceiver + ); + }); + */ + }); +}); diff --git a/packages/fuel-gauge/src/predicate/predicate-configurables.test.ts b/packages/fuel-gauge/src/predicate/predicate-configurables.test.ts new file mode 100644 index 0000000000..2b223f609a --- /dev/null +++ b/packages/fuel-gauge/src/predicate/predicate-configurables.test.ts @@ -0,0 +1,216 @@ +import { generateTestWallet } from '@fuel-ts/wallet/test-utils'; +import type { CoinQuantityLike } from 'fuels'; +import { getRandomB256, NativeAssetId, Provider, WalletUnlocked, Predicate } from 'fuels'; + +import predicateBytesTrue from '../../fixtures/forc-projects/predicate-true'; +import predicateAbiTrue from '../../fixtures/forc-projects/predicate-true/out/debug/predicate-true-abi.json'; +import predicateBytesConfigurable from '../../fixtures/forc-projects/predicate-with-configurable'; +import predicateAbiConfigurable from '../../fixtures/forc-projects/predicate-with-configurable/out/debug/predicate-with-configurable-abi.json'; + +import { fundPredicate, assertBalance } from './utils/predicate'; + +describe('Predicate', () => { + describe('Configurables', () => { + let wallet: WalletUnlocked; + let chainId: number; + + const defaultValues = { + FEE: 10, + ADDRESS: '0x38966262edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96', + }; + + beforeEach(async () => { + const provider = new Provider('http://127.0.0.1:4000/graphql'); + + const quantities: CoinQuantityLike[] = [ + { + amount: 1_000_000, + assetId: NativeAssetId, + }, + ]; + + wallet = await generateTestWallet(provider, quantities); + + chainId = await wallet.provider.getChainId(); + }); + + it('calls a predicate with configurables using default values', async () => { + const predicate = new Predicate( + predicateBytesConfigurable, + chainId, + predicateAbiConfigurable, + wallet.provider + ); + + const amountToTransfer = 200; + + await fundPredicate(wallet, predicate, 5000); + + // create destination wallet + const destination = WalletUnlocked.generate(); + + await assertBalance(destination, 0, NativeAssetId); + + // set predicate input data to be the same as default configurable value + predicate.setData(defaultValues.FEE, defaultValues.ADDRESS); + + const tx = await predicate.transfer(destination.address, amountToTransfer); + + await tx.waitForResult(); + + await assertBalance(destination, amountToTransfer, NativeAssetId); + }); + + it('calls a predicate with configurables where first param is equal', async () => { + const configurableConstants = { FEE: 35 }; + + expect(configurableConstants.FEE).not.toEqual(defaultValues.FEE); + const predicate = new Predicate( + predicateBytesConfigurable, + chainId, + predicateAbiConfigurable, + wallet.provider, + configurableConstants + ); + + const amountToTransfer = 300; + + const destination = WalletUnlocked.generate(); + + await assertBalance(destination, 0, NativeAssetId); + + // transfer funds to predicate + await fundPredicate(wallet, predicate, 5000); + + predicate.setData(configurableConstants.FEE, defaultValues.ADDRESS); + + // executing predicate transfer + const tx = await predicate.transfer(destination.address, amountToTransfer); + + await tx.waitForResult(); + + await assertBalance(destination, amountToTransfer, NativeAssetId); + }); + + it('calls a predicate with configurables where second param is equal', async () => { + const configurableConstants = { ADDRESS: getRandomB256() }; + + expect(configurableConstants.ADDRESS).not.toEqual(defaultValues.ADDRESS); + const predicate = new Predicate( + predicateBytesConfigurable, + chainId, + predicateAbiConfigurable, + wallet.provider, + configurableConstants + ); + + const amountToTransfer = 300; + + const destination = WalletUnlocked.generate(); + + await assertBalance(destination, 0, NativeAssetId); + + // transfer funds to predicate + await fundPredicate(wallet, predicate, 5000); + + predicate.setData(defaultValues.FEE, configurableConstants.ADDRESS); + + // executing predicate transfer + const tx = await predicate.transfer(destination.address, amountToTransfer); + + await tx.waitForResult(); + + await assertBalance(destination, amountToTransfer, NativeAssetId); + }); + + it('calls a predicate with configurables where both params are equal', async () => { + const configurableConstants = { + FEE: 90, + ADDRESS: getRandomB256(), + }; + + expect(configurableConstants.FEE).not.toEqual(defaultValues.FEE); + expect(configurableConstants.ADDRESS).not.toEqual(defaultValues.ADDRESS); + const predicate = new Predicate( + predicateBytesConfigurable, + chainId, + predicateAbiConfigurable, + wallet.provider, + configurableConstants + ); + + const amountToTransfer = 300; + + const destination = WalletUnlocked.generate(); + + await assertBalance(destination, 0, NativeAssetId); + + await fundPredicate(wallet, predicate, 5000); + + predicate.setData(configurableConstants.FEE, configurableConstants.ADDRESS); + + const tx = await predicate.transfer(destination.address, amountToTransfer); + + await tx.waitForResult(); + + await assertBalance(destination, amountToTransfer, NativeAssetId); + }); + + it('throws when configurable data is not set', async () => { + const predicate = new Predicate( + predicateBytesConfigurable, + chainId, + predicateAbiConfigurable, + wallet.provider + ); + + const destination = WalletUnlocked.generate(); + + await expect(predicate.transfer(destination.address, 300)).rejects.toThrow( + 'Invalid transaction' + ); + }); + + it('throws when setting configurable but predicate has none', () => { + expect(() => { + const predicate = new Predicate( + predicateBytesTrue, + chainId, + predicateAbiTrue, + wallet.provider, + { + constant: 'NADA', + } + ); + + predicate.setData('NADA'); + }).toThrow('Predicate has no configurable constants to be set'); + }); + + it('throws when setting invalid configurable', () => { + expect(() => { + const predicate = new Predicate( + predicateBytesConfigurable, + chainId, + predicateAbiConfigurable, + wallet.provider, + { + NOPE: 'NADA', + } + ); + + predicate.setData('NADA'); + }).toThrow('Predicate has no configurable constant named:'); + }); + + it('throws when setting a configurable with no ABI', () => { + expect(() => { + const predicate = new Predicate(predicateBytesConfigurable, chainId, undefined, undefined, { + NOPE: 'NADA', + }); + + predicate.setData('NADA'); + }).toThrow('Unable to validate configurable constants'); + }); + }); +}); diff --git a/packages/fuel-gauge/src/predicate/predicate-evaluations.test.ts b/packages/fuel-gauge/src/predicate/predicate-evaluations.test.ts new file mode 100644 index 0000000000..e6d729caf3 --- /dev/null +++ b/packages/fuel-gauge/src/predicate/predicate-evaluations.test.ts @@ -0,0 +1,56 @@ +import type { InputValue, WalletLocked, WalletUnlocked } from 'fuels'; +import { Predicate } from 'fuels'; + +import predicateBytesFalse from '../../fixtures/forc-projects/predicate-false'; +import predicateBytesTrue from '../../fixtures/forc-projects/predicate-true'; + +import { setupWallets, assertBalances, fundPredicate } from './utils/predicate'; + +describe('Predicate', () => { + describe('Evaluations', () => { + let predicate: Predicate; + let wallet: WalletUnlocked; + let receiver: WalletLocked; + let chainId: number; + + beforeEach(async () => { + [wallet, receiver] = await setupWallets(); + chainId = await wallet.provider.getChainId(); + }); + + it('calls a no argument predicate and returns true', async () => { + const amountToPredicate = 100; + const amountToReceiver = 50; + const initialReceiverBalance = await receiver.getBalance(); + + predicate = new Predicate(predicateBytesTrue, chainId); + + const initialPredicateBalance = await fundPredicate(wallet, predicate, amountToPredicate); + + const tx = await predicate.transfer(receiver.address, amountToReceiver); + await tx.waitForResult(); + + await assertBalances( + predicate, + receiver, + initialPredicateBalance, + initialReceiverBalance, + amountToPredicate, + amountToReceiver + ); + }); + + it('calls a no argument predicate and returns false', async () => { + const amountToPredicate = 100; + const amountToReceiver = 50; + + predicate = new Predicate(predicateBytesFalse, chainId); + + await fundPredicate(wallet, predicate, amountToPredicate); + + await expect(predicate.transfer(receiver.address, amountToReceiver)).rejects.toThrow( + 'Invalid transaction' + ); + }); + }); +}); diff --git a/packages/fuel-gauge/src/predicate/predicate-invalidations.test.ts b/packages/fuel-gauge/src/predicate/predicate-invalidations.test.ts new file mode 100644 index 0000000000..42b99db114 --- /dev/null +++ b/packages/fuel-gauge/src/predicate/predicate-invalidations.test.ts @@ -0,0 +1,51 @@ +import type { BN, WalletLocked, WalletUnlocked } from 'fuels'; +import { NativeAssetId, Predicate } from 'fuels'; + +import predicateBytesMainArgsStruct from '../../fixtures/forc-projects/predicate-main-args-struct'; +import predicateAbiMainArgsStruct from '../../fixtures/forc-projects/predicate-main-args-struct/out/debug/predicate-main-args-struct-abi.json'; +import type { Validation } from '../types/predicate'; + +import { fundPredicate, setupWallets } from './utils/predicate'; + +describe('Predicate', () => { + describe('Invalidations', () => { + let predicate: Predicate<[Validation]>; + let predicateBalance: BN; + let wallet: WalletUnlocked; + let receiver: WalletLocked; + + const validation: Validation = { + has_account: true, + total_complete: 100, + }; + + beforeAll(async () => { + [wallet, receiver] = await setupWallets(); + const amountToPredicate = 100; + const chainId = await wallet.provider.getChainId(); + predicate = new Predicate<[Validation]>( + predicateBytesMainArgsStruct, + chainId, + predicateAbiMainArgsStruct + ); + + predicateBalance = await fundPredicate(wallet, predicate, amountToPredicate); + }); + + it('throws if sender does not have enough resources for tx and gas', async () => { + await expect( + predicate.setData(validation).transfer(receiver.address, predicateBalance) + ).rejects.toThrow(/not enough coins to fit the target/i); + }); + + it('throws if the passed gas limit is too low', async () => { + // TODO: When gas is to low the return error is Invalid transaction, once is fixed on the + // fuel-client we should change with the proper error message + await expect( + predicate.setData(validation).transfer(receiver.address, 50, NativeAssetId, { + gasLimit: 1, + }) + ).rejects.toThrow(/Invalid transaction/i); + }); + }); +}); diff --git a/packages/fuel-gauge/src/predicate/predicate-with-contract.test.ts b/packages/fuel-gauge/src/predicate/predicate-with-contract.test.ts new file mode 100644 index 0000000000..580465477d --- /dev/null +++ b/packages/fuel-gauge/src/predicate/predicate-with-contract.test.ts @@ -0,0 +1,151 @@ +import { generateTestWallet } from '@fuel-ts/wallet/test-utils'; +import { readFileSync } from 'fs'; +import type { WalletUnlocked } from 'fuels'; +import { NativeAssetId, ContractFactory, toNumber, Contract, Provider, Predicate } from 'fuels'; +import { join } from 'path'; + +import contractAbi from '../../fixtures/forc-projects/call-test-contract/out/debug/call-test-abi.json'; +import liquidityPoolAbi from '../../fixtures/forc-projects/liquidity-pool/out/debug/liquidity-pool-abi.json'; +import predicateAbiMainArgsStruct from '../../fixtures/forc-projects/predicate-main-args-struct/out/debug/predicate-main-args-struct-abi.json'; +import predicateBytesStruct from '../../fixtures/forc-projects/predicate-struct'; +import predicateBytesTrue from '../../fixtures/forc-projects/predicate-true'; +import type { Validation } from '../types/predicate'; + +import { fundPredicate, setupContractWithConfig } from './utils/predicate'; + +const contractBytes = readFileSync( + join(__dirname, '../../fixtures/forc-projects/call-test-contract/out/debug/call-test.bin') +); + +const liquidityPoolBytes = readFileSync( + join(__dirname, '../../fixtures/forc-projects/liquidity-pool/out/debug/liquidity-pool.bin') +); + +describe('Predicate', () => { + describe('With Contract', () => { + let wallet: WalletUnlocked; + let receiver: WalletUnlocked; + + beforeEach(async () => { + const provider = new Provider('http://127.0.0.1:4000/graphql'); + wallet = await generateTestWallet(provider, [[1_000_000, NativeAssetId]]); + receiver = await generateTestWallet(provider); + }); + + it('calls a predicate from a contract function', async () => { + const setupContract = setupContractWithConfig({ + contractBytecode: contractBytes, + abi: contractAbi, + cache: true, + }); + const contract = await setupContract(); + const amountToPredicate = 100_000; + const chainId = await wallet.provider.getChainId(); + const predicate = new Predicate<[Validation]>( + predicateBytesTrue, + chainId, + predicateAbiMainArgsStruct + ); + // Create a instance of the contract with the predicate as the caller Account + const contractPredicate = new Contract(contract.id, contract.interface, predicate); + const predicateBalance = await fundPredicate(wallet, predicate, amountToPredicate); + + const { value } = await contractPredicate.functions + .return_context_amount() + .callParams({ + forward: [500, NativeAssetId], + }) + .call(); + + expect(value.toString()).toEqual('500'); + + const finalPredicateBalance = await predicate.getBalance(); + expect(finalPredicateBalance.lt(predicateBalance)).toBeTruthy(); + }); + + it('calls a predicate and uses proceeds for a contract call', async () => { + const initialReceiverBalance = toNumber(await receiver.getBalance()); + + const contract = await new ContractFactory( + liquidityPoolBytes, + liquidityPoolAbi, + wallet + ).deployContract(); + + // calling the contract with the receiver account (no resources) + contract.account = receiver; + await expect( + contract.functions + .deposit({ + value: receiver.address.toB256(), + }) + .callParams({ + forward: [100, NativeAssetId], + }) + .txParams({ + gasPrice: 1, + }) + .call() + ).rejects.toThrow(/not enough coins to fit the target/); + + // setup predicate + const amountToPredicate = 100; + const amountToReceiver = 50; + const chainId = await wallet.provider.getChainId(); + const predicate = new Predicate<[Validation]>( + predicateBytesStruct, + chainId, + predicateAbiMainArgsStruct + ); + const initialPredicateBalance = toNumber(await predicate.getBalance()); + + await fundPredicate(wallet, predicate, amountToPredicate); + + expect(toNumber(await predicate.getBalance())).toEqual( + initialPredicateBalance + amountToPredicate + ); + + // executing predicate to transfer resources to receiver + const tx = await predicate + .setData({ + has_account: true, + total_complete: 100, + }) + .transfer(receiver.address, amountToReceiver); + + await tx.waitForResult(); + + // calling the contract with the receiver account (with resources) + const gasPrice = 1; + const contractAmount = 10; + + await contract.functions.set_base_token(NativeAssetId).call(); + await expect( + contract.functions + .deposit({ + value: receiver.address.toB256(), + }) + .callParams({ + forward: [contractAmount, NativeAssetId], + }) + .txParams({ + gasPrice, + }) + .call() + ).resolves.toBeTruthy(); + + const finalReceiverBalance = toNumber(await receiver.getBalance()); + const remainingPredicateBalance = toNumber(await predicate.getBalance()); + + expect(initialReceiverBalance).toBe(0); + + expect(initialReceiverBalance + amountToReceiver).toEqual( + finalReceiverBalance + contractAmount + gasPrice + ); + + expect(remainingPredicateBalance).toEqual( + amountToPredicate + initialPredicateBalance - amountToReceiver + ); + }); + }); +}); diff --git a/packages/fuel-gauge/src/predicate/predicate-with-script.test.ts b/packages/fuel-gauge/src/predicate/predicate-with-script.test.ts new file mode 100644 index 0000000000..3c0a1a8711 --- /dev/null +++ b/packages/fuel-gauge/src/predicate/predicate-with-script.test.ts @@ -0,0 +1,87 @@ +import { generateTestWallet } from '@fuel-ts/wallet/test-utils'; +import { readFileSync } from 'fs'; +import type { BigNumberish, WalletUnlocked } from 'fuels'; +import { toNumber, NativeAssetId, Script, Provider, Predicate } from 'fuels'; +import { join } from 'path'; + +import predicateAbiMainArgsStruct from '../../fixtures/forc-projects/predicate-main-args-struct/out/debug/predicate-main-args-struct-abi.json'; +import predicateBytesStruct from '../../fixtures/forc-projects/predicate-struct'; +import scriptAbi from '../../fixtures/forc-projects/script-main-args/out/debug/script-main-args-abi.json'; +import type { Validation } from '../types/predicate'; + +import { fundPredicate } from './utils/predicate'; + +const scriptBytes = readFileSync( + join(__dirname, '../../fixtures/forc-projects/script-main-args/out/debug/script-main-args.bin') +); + +describe('Predicate', () => { + describe('With script', () => { + let wallet: WalletUnlocked; + let receiver: WalletUnlocked; + + const provider = new Provider('http://127.0.0.1:4000/graphql'); + + beforeEach(async () => { + wallet = await generateTestWallet(provider, [[5_000_000, NativeAssetId]]); + receiver = await generateTestWallet(provider); + }); + + it('calls a predicate and uses proceeds for a script call', async () => { + const initialReceiverBalance = toNumber(await receiver.getBalance()); + const scriptInstance = new Script( + scriptBytes, + scriptAbi, + wallet + ); + + // calling the script with the receiver account (no resources) + const scriptInput = 1; + scriptInstance.account = receiver; + await expect(scriptInstance.functions.main(scriptInput).call()).rejects.toThrow( + /not enough coins to fit the target/ + ); + + // setup predicate + const amountToPredicate = 100; + const amountToReceiver = 50; + const chainId = await wallet.provider.getChainId(); + const predicate = new Predicate<[Validation]>( + predicateBytesStruct, + chainId, + predicateAbiMainArgsStruct + ); + const initialPredicateBalance = toNumber(await predicate.getBalance()); + + await fundPredicate(wallet, predicate, amountToPredicate); + + expect(toNumber(await predicate.getBalance())).toEqual( + initialPredicateBalance + amountToPredicate + ); + + // executing predicate to transfer resources to receiver + const tx = await predicate + .setData({ + has_account: true, + total_complete: 100, + }) + .transfer(receiver.address, amountToReceiver); + + await tx.waitForResult(); + + const finalReceiverBalance = toNumber(await receiver.getBalance()); + + // calling the script with the receiver account (with resources) + await expect(scriptInstance.functions.main(scriptInput).call()).resolves.toBeTruthy(); + + const remainingPredicateBalance = toNumber(await predicate.getBalance()); + + expect(toNumber(initialReceiverBalance)).toBe(0); + expect(initialReceiverBalance + amountToReceiver).toEqual(finalReceiverBalance); + + expect(remainingPredicateBalance).toEqual( + amountToPredicate + initialPredicateBalance - amountToReceiver + ); + }); + }); +}); diff --git a/packages/fuel-gauge/src/predicate/utils/predicate/assertBalance.ts b/packages/fuel-gauge/src/predicate/utils/predicate/assertBalance.ts new file mode 100644 index 0000000000..39f1879e31 --- /dev/null +++ b/packages/fuel-gauge/src/predicate/utils/predicate/assertBalance.ts @@ -0,0 +1,8 @@ +import { BN } from 'fuels'; +import type { Account } from 'fuels'; + +export const assertBalance = async (account: Account, value: number, assetId: string) => { + const balance = await account.getBalance(assetId); + + expect(new BN(balance).toNumber()).toEqual(value); +}; diff --git a/packages/fuel-gauge/src/predicate/utils/predicate/assertBalances.ts b/packages/fuel-gauge/src/predicate/utils/predicate/assertBalances.ts new file mode 100644 index 0000000000..08f0edea0e --- /dev/null +++ b/packages/fuel-gauge/src/predicate/utils/predicate/assertBalances.ts @@ -0,0 +1,26 @@ +import { bn, toHex, toNumber } from 'fuels'; +import type { InputValue, BN, BigNumberish, WalletLocked, Predicate } from 'fuels'; + +export const assertBalances = async ( + predicate: Predicate, + receiver: WalletLocked, + initialPredicateBalance: BN, + initialReceiverBalance: BN, + amountToPredicate: BigNumberish, + amountToReceiver: BigNumberish +): Promise => { + // Check there are UTXO locked with the predicate hash + expect(toNumber(initialPredicateBalance)).toBeGreaterThanOrEqual(toNumber(amountToPredicate)); + // !isSkippingInitialReceiverBalance && expect(initialReceiverBalance.toHex()).toEqual(toHex(0)); + expect(initialReceiverBalance.toHex()).toEqual(toHex(0)); + + // Check the balance of the receiver + const finalReceiverBalance = await receiver.getBalance(); + expect(bn(initialReceiverBalance).add(amountToReceiver).toHex()).toEqual( + finalReceiverBalance.toHex() + ); + + // Check we spent the entire predicate hash input + const finalPredicateBalance = await predicate.getBalance(); + expect(finalPredicateBalance.lte(initialPredicateBalance)).toBeTruthy(); +}; diff --git a/packages/fuel-gauge/src/predicate/utils/predicate/fundPredicate.ts b/packages/fuel-gauge/src/predicate/utils/predicate/fundPredicate.ts new file mode 100644 index 0000000000..bb7b9c6231 --- /dev/null +++ b/packages/fuel-gauge/src/predicate/utils/predicate/fundPredicate.ts @@ -0,0 +1,13 @@ +import { NativeAssetId } from 'fuels'; +import type { InputValue, BN, BigNumberish, WalletUnlocked, Predicate } from 'fuels'; + +export const fundPredicate = async ( + wallet: WalletUnlocked, + predicate: Predicate, + amountToPredicate: BigNumberish +): Promise => { + const tx = await wallet.transfer(predicate.address, amountToPredicate, NativeAssetId); + await tx.waitForResult(); + + return predicate.getBalance(); +}; diff --git a/packages/fuel-gauge/src/predicate/utils/predicate/index.ts b/packages/fuel-gauge/src/predicate/utils/predicate/index.ts new file mode 100644 index 0000000000..f0e0ebd8a7 --- /dev/null +++ b/packages/fuel-gauge/src/predicate/utils/predicate/index.ts @@ -0,0 +1,5 @@ +export * from './assertBalance'; +export * from './assertBalances'; +export * from './fundPredicate'; +export * from './setupContract'; +export * from './setupWallets'; diff --git a/packages/fuel-gauge/src/predicate/utils/predicate/setupContract.ts b/packages/fuel-gauge/src/predicate/utils/predicate/setupContract.ts new file mode 100644 index 0000000000..b4447da66e --- /dev/null +++ b/packages/fuel-gauge/src/predicate/utils/predicate/setupContract.ts @@ -0,0 +1,45 @@ +import type { BytesLike } from '@ethersproject/bytes'; +import { generateTestWallet } from '@fuel-ts/wallet/test-utils'; +import { NativeAssetId, ContractFactory, Provider } from 'fuels'; +import type { Interface, JsonAbi, Contract, WalletUnlocked } from 'fuels'; + +let walletInstance: WalletUnlocked; +let contractInstance: Contract; + +export type SetupConfig = { + contractBytecode: BytesLike; + abi: JsonAbi | Interface; + cache?: boolean; +}; + +const deployContract = async (factory: ContractFactory, useCache: boolean = true) => { + if (contractInstance && useCache) return contractInstance; + contractInstance = await factory.deployContract(); + return contractInstance; +}; + +const createWallet = async () => { + if (walletInstance) return walletInstance; + const provider = new Provider('http://127.0.0.1:4000/graphql', { cacheUtxo: 10 }); + walletInstance = await generateTestWallet(provider, [ + [5_000_000, NativeAssetId], + [5_000_000, '0x0101010101010101010101010101010101010101010101010101010101010101'], + ]); + return walletInstance; +}; + +export const setup = async ({ contractBytecode, abi, cache }: SetupConfig) => { + // Create wallet + const wallet = await createWallet(); + const factory = new ContractFactory(contractBytecode, abi, wallet); + const contract = await deployContract(factory, cache); + return contract; +}; + +export const setupContractWithConfig = + (defaultConfig: SetupConfig) => async (config?: Partial) => + setup({ + contractBytecode: defaultConfig.contractBytecode, + abi: defaultConfig.abi, + ...config, + }); diff --git a/packages/fuel-gauge/src/predicate/utils/predicate/setupWallets.ts b/packages/fuel-gauge/src/predicate/utils/predicate/setupWallets.ts new file mode 100644 index 0000000000..a8a01a6d81 --- /dev/null +++ b/packages/fuel-gauge/src/predicate/utils/predicate/setupWallets.ts @@ -0,0 +1,10 @@ +import { Wallet } from '@fuel-ts/wallet'; +import { generateTestWallet } from '@fuel-ts/wallet/test-utils'; +import { Address, NativeAssetId, Provider } from 'fuels'; + +export const setupWallets = async () => { + const provider = new Provider('http://127.0.0.1:4000/graphql'); + const wallet = await generateTestWallet(provider, [[5_000_000, NativeAssetId]]); + const receiver = Wallet.fromAddress(Address.fromRandom()); + return [wallet, receiver] as const; +}; diff --git a/packages/fuel-gauge/src/revert-error.test.ts b/packages/fuel-gauge/src/revert-error.test.ts index b8b171c526..787cc98852 100644 --- a/packages/fuel-gauge/src/revert-error.test.ts +++ b/packages/fuel-gauge/src/revert-error.test.ts @@ -14,7 +14,7 @@ import { } from 'fuels'; import path from 'path'; -import FactoryAbi from '../test-projects/revert-error/out/debug/revert-error-abi.json'; +import FactoryAbi from '../fixtures/forc-projects/revert-error/out/debug/revert-error-abi.json'; let contractInstance: Contract; let wallet: WalletUnlocked; @@ -25,7 +25,7 @@ describe('Revert Error Testing', () => { wallet = await generateTestWallet(provider, [[1_000, NativeAssetId]]); const bytecode = fs.readFileSync( - path.join(__dirname, '../test-projects/revert-error/out/debug/revert-error.bin') + path.join(__dirname, '../fixtures/forc-projects/revert-error/out/debug/revert-error.bin') ); const factory = new ContractFactory(bytecode, FactoryAbi, wallet); contractInstance = await factory.deployContract(); diff --git a/packages/fuel-gauge/src/script-main-args.test.ts b/packages/fuel-gauge/src/script-main-args.test.ts index 9943e45ccd..6a99712fda 100644 --- a/packages/fuel-gauge/src/script-main-args.test.ts +++ b/packages/fuel-gauge/src/script-main-args.test.ts @@ -4,12 +4,12 @@ import type { BigNumberish } from 'fuels'; import { Provider, bn, Script, NativeAssetId } from 'fuels'; import { join } from 'path'; -import scriptAbi from '../test-projects/script-main-args/out/debug/script-main-args-abi.json'; +import scriptAbi from '../fixtures/forc-projects/script-main-args/out/debug/script-main-args-abi.json'; import { getScript } from './utils'; const scriptBin = readFileSync( - join(__dirname, '../test-projects/script-main-args/out/debug/script-main-args.bin') + join(__dirname, '../fixtures/forc-projects/script-main-args/out/debug/script-main-args.bin') ); const setup = async (balance = 5_000) => { diff --git a/packages/fuel-gauge/src/script-with-configurable.test.ts b/packages/fuel-gauge/src/script-with-configurable.test.ts index b23cc20102..a5a33a5ff9 100644 --- a/packages/fuel-gauge/src/script-with-configurable.test.ts +++ b/packages/fuel-gauge/src/script-with-configurable.test.ts @@ -4,12 +4,12 @@ import type { CoinQuantityLike, WalletUnlocked } from 'fuels'; import { BN, Script, NativeAssetId, Provider } from 'fuels'; import { join } from 'path'; -import abi from '../test-projects/script-with-configurable/out/debug/script-with-configurable-abi.json'; +import abi from '../fixtures/forc-projects/script-with-configurable/out/debug/script-with-configurable-abi.json'; const bytecode = readFileSync( join( __dirname, - '../test-projects/script-with-configurable/out/debug/script-with-configurable.bin' + '../fixtures/forc-projects/script-with-configurable/out/debug/script-with-configurable.bin' ) ); diff --git a/packages/fuel-gauge/src/storage-test-contract.test.ts b/packages/fuel-gauge/src/storage-test-contract.test.ts index 70d3c49745..d6e5b65151 100644 --- a/packages/fuel-gauge/src/storage-test-contract.test.ts +++ b/packages/fuel-gauge/src/storage-test-contract.test.ts @@ -3,8 +3,8 @@ import { readFileSync } from 'fs'; import { toHex, Provider, ContractFactory, NativeAssetId } from 'fuels'; import { join } from 'path'; -import abi from '../test-projects/storage-test-contract/out/debug/storage-test-abi.json'; -import storageSlots from '../test-projects/storage-test-contract/out/debug/storage-test-storage_slots.json'; +import abi from '../fixtures/forc-projects/storage-test-contract/out/debug/storage-test-abi.json'; +import storageSlots from '../fixtures/forc-projects/storage-test-contract/out/debug/storage-test-storage_slots.json'; const setup = async () => { const provider = new Provider('http://127.0.0.1:4000/graphql'); @@ -13,7 +13,7 @@ const setup = async () => { // Deploy contract const bytecode = readFileSync( - join(__dirname, '../test-projects/storage-test-contract/out/debug/storage-test.bin') + join(__dirname, '../fixtures/forc-projects/storage-test-contract/out/debug/storage-test.bin') ); const factory = new ContractFactory(bytecode, abi, wallet); const contract = await factory.deployContract({ diff --git a/packages/fuel-gauge/src/token-test-contract.test.ts b/packages/fuel-gauge/src/token-test-contract.test.ts index 85e5394e7c..210718256a 100644 --- a/packages/fuel-gauge/src/token-test-contract.test.ts +++ b/packages/fuel-gauge/src/token-test-contract.test.ts @@ -4,7 +4,7 @@ import type { BN } from 'fuels'; import { toHex, Provider, Wallet, ContractFactory, bn, NativeAssetId } from 'fuels'; import { join } from 'path'; -import abi from '../test-projects/token_contract/out/debug/token_contract-abi.json'; +import abi from '../fixtures/forc-projects/token_contract/out/debug/token_contract-abi.json'; const provider = new Provider('http://127.0.0.1:4000/graphql'); @@ -14,7 +14,7 @@ const setup = async () => { // Deploy contract const bytecode = readFileSync( - join(__dirname, '../test-projects/token_contract/out/debug/token_contract.bin') + join(__dirname, '../fixtures/forc-projects/token_contract/out/debug/token_contract.bin') ); const factory = new ContractFactory(bytecode, abi, wallet); const contract = await factory.deployContract(); diff --git a/packages/fuel-gauge/src/types/predicate/index.ts b/packages/fuel-gauge/src/types/predicate/index.ts new file mode 100644 index 0000000000..4d5ffa36ab --- /dev/null +++ b/packages/fuel-gauge/src/types/predicate/index.ts @@ -0,0 +1 @@ +export * from './validation'; diff --git a/packages/fuel-gauge/src/types/predicate/validation.ts b/packages/fuel-gauge/src/types/predicate/validation.ts new file mode 100644 index 0000000000..131eb9dce4 --- /dev/null +++ b/packages/fuel-gauge/src/types/predicate/validation.ts @@ -0,0 +1,6 @@ +import type { BigNumberish } from 'fuels'; + +export type Validation = { + has_account: boolean; + total_complete: BigNumberish; +}; diff --git a/packages/fuel-gauge/src/utils.ts b/packages/fuel-gauge/src/utils.ts index 163086d45b..068b3d63ac 100644 --- a/packages/fuel-gauge/src/utils.ts +++ b/packages/fuel-gauge/src/utils.ts @@ -45,7 +45,7 @@ export const createSetupConfig = }); const getFullPath = (contractName: string, next: (fullPath: string) => T) => - next(join(__dirname, `../test-projects/${contractName}/out/debug/${contractName}`)); + next(join(__dirname, `../fixtures/forc-projects/${contractName}/out/debug/${contractName}`)); export const getSetupContract = ( contractName: string diff --git a/packages/fuel-gauge/src/vector-types.test.ts b/packages/fuel-gauge/src/vector-types.test.ts index 7a42fc8bcb..f2ea63a02c 100644 --- a/packages/fuel-gauge/src/vector-types.test.ts +++ b/packages/fuel-gauge/src/vector-types.test.ts @@ -2,8 +2,8 @@ import { generateTestWallet } from '@fuel-ts/wallet/test-utils'; import type { BigNumberish } from 'fuels'; import { bn, Predicate, Wallet, Address, NativeAssetId, Provider } from 'fuels'; -import predicateVectorTypes from '../test-projects/predicate-vector-types'; -import predicateVectorTypesAbi from '../test-projects/predicate-vector-types/out/debug/predicate-vector-types-abi.json'; +import predicateVectorTypes from '../fixtures/forc-projects/predicate-vector-types'; +import predicateVectorTypesAbi from '../fixtures/forc-projects/predicate-vector-types/out/debug/predicate-vector-types-abi.json'; import { getScript, getSetupContract } from './utils'; diff --git a/packages/fuel-gauge/test-projects/custom_errors/.gitignore b/packages/fuel-gauge/test-projects/custom_errors/.gitignore deleted file mode 100644 index 77d3844f58..0000000000 --- a/packages/fuel-gauge/test-projects/custom_errors/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/packages/fuel-gauge/test-projects/payable-annotation/.gitignore b/packages/fuel-gauge/test-projects/payable-annotation/.gitignore deleted file mode 100644 index 77d3844f58..0000000000 --- a/packages/fuel-gauge/test-projects/payable-annotation/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/packages/fuel-gauge/test-projects/predicate-false/index.ts b/packages/fuel-gauge/test-projects/predicate-false/index.ts deleted file mode 100644 index 3d8cc4a91c..0000000000 --- a/packages/fuel-gauge/test-projects/predicate-false/index.ts +++ /dev/null @@ -1 +0,0 @@ -export default '0x9000000447000000000000000000001c5dfcc00110fff30024000000'; diff --git a/packages/fuel-gauge/turbo.json b/packages/fuel-gauge/turbo.json index 0d85249ed7..d9f064966f 100644 --- a/packages/fuel-gauge/turbo.json +++ b/packages/fuel-gauge/turbo.json @@ -3,11 +3,11 @@ "pipeline": { "build": { "dependsOn": ["^build", "prebuild"], - "outputs": ["dist/**", "test-projects/**/out/**"], + "outputs": ["dist/**", "fixtures/forc-projects/**/out/**"], "inputs": [ "src/**", - "test-projects/**/src/*.sw", - "test-projects/**/Forc.toml" + "fixtures/forc-projects/**/src/*.sw", + "fixtures/forc-projects/**/Forc.toml" ] } } diff --git a/packages/predicate/src/predicate.test.ts b/packages/predicate/src/predicate.test.ts deleted file mode 100644 index 66b1df1610..0000000000 --- a/packages/predicate/src/predicate.test.ts +++ /dev/null @@ -1,236 +0,0 @@ -import { arrayify, hexlify } from '@ethersproject/bytes'; -import type { JsonAbi } from '@fuel-ts/abi-coder'; -import { Address } from '@fuel-ts/address'; -import { bn } from '@fuel-ts/math'; -import { Provider, ScriptTransactionRequest } from '@fuel-ts/providers'; -import type { InputCoin } from '@fuel-ts/transactions'; -import { Account } from '@fuel-ts/wallet'; - -import { Predicate } from './predicate'; -import { getContractRoot } from './utils'; - -// This data is arbitrary, make to unit test the Predicate class -const PREDICATE_BYTECODE = - '0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8'; -const PREDICATE_ADDRESS = getContractRoot(arrayify(PREDICATE_BYTECODE), 0); -const PREDICATE_ABI: JsonAbi = { - types: [ - { - typeId: 0, - type: 'bool', - components: null, - typeParameters: null, - }, - { - typeId: 1, - type: 'b256', - components: null, - typeParameters: null, - }, - ], - functions: [ - { - inputs: [ - { - name: 'data', - type: 1, - typeArguments: null, - }, - ], - name: 'main', - output: { - name: '', - type: 0, - typeArguments: null, - }, - attributes: null, - }, - ], - loggedTypes: [], - configurables: [], -}; - -describe('Predicate', () => { - it('Should create the correct address for a given bytecode', async () => { - const provider = new Provider('http://127.0.0.1:4000/graphql'); - const chainId = await provider.getChainId(); - const predicate = new Predicate(PREDICATE_BYTECODE, chainId); - expect(predicate.address.toB256()).toEqual(PREDICATE_ADDRESS); - }); - - it('Should assign only correct data to predicate', async () => { - const provider = new Provider('http://127.0.0.1:4000/graphql'); - const chainId = await provider.getChainId(); - const predicate = new Predicate(PREDICATE_BYTECODE, chainId, PREDICATE_ABI); - const b256 = '0x0101010101010101010101010101010101010101010101010101010101010101'; - - predicate.setData<[string]>(b256); - - // Assign correct data to predicate - expect(hexlify(predicate.predicateData)).toEqual(b256); - - let error; - try { - // Try to assign incorrect data should fail predicate - predicate.setData<[string]>('0x01'); - } catch (e) { - error = e; - } - - expect((error).message).toMatch(/Invalid b256/i); - }); - - it('Should include predicate on input when sendTransaction', async () => { - const b256 = '0x0101010101010101010101010101010101010101010101010101010101010101'; - const sendTransactionMock = jest - .spyOn(Account.prototype, 'sendTransaction') - .mockImplementation(); - const provider = new Provider('http://127.0.0.1:4000/graphql'); - const chainId = await provider.getChainId(); - const predicate = new Predicate(PREDICATE_BYTECODE, chainId, PREDICATE_ABI); - - predicate.setData<[string]>(b256); - - const request = new ScriptTransactionRequest(); - - request.addResourceInputAndOutput({ - id: '0x01', - assetId: '0x0000000000000000000000000000000000000000000000000000000000000000', - amount: bn(1), - owner: Address.fromB256(PREDICATE_ADDRESS), - maturity: 0, - blockCreated: bn(0), - txCreatedIdx: bn(0), - }); - - predicate.sendTransaction(request); - - const inputCoinMock = sendTransactionMock.mock.calls[0][0].inputs?.[0] as unknown as InputCoin; - expect(hexlify(inputCoinMock.predicate)).toBe(PREDICATE_BYTECODE); - expect(hexlify(inputCoinMock.predicateData)).toBe(b256); - }); - - it('Should include predicate on input when simulateTransaction', async () => { - const b256 = '0x0101010101010101010101010101010101010101010101010101010101010101'; - const simulateTransactionMock = jest - .spyOn(Account.prototype, 'simulateTransaction') - .mockImplementation(); - const provider = new Provider('http://127.0.0.1:4000/graphql'); - const chainId = await provider.getChainId(); - const predicate = new Predicate(PREDICATE_BYTECODE, chainId, PREDICATE_ABI); - - predicate.setData<[string]>(b256); - - const request = new ScriptTransactionRequest().addResourceInputAndOutput({ - id: '0x01', - assetId: '0x0000000000000000000000000000000000000000000000000000000000000000', - amount: bn(1), - owner: Address.fromB256(PREDICATE_ADDRESS), - maturity: 0, - blockCreated: bn(0), - txCreatedIdx: bn(0), - }); - - predicate.simulateTransaction(request); - - const inputCoinMock = simulateTransactionMock.mock.calls[0][0] - .inputs?.[0] as unknown as InputCoin; - expect(hexlify(inputCoinMock.predicate)).toBe(PREDICATE_BYTECODE); - expect(hexlify(inputCoinMock.predicateData)).toBe(b256); - }); - - it('should throw when setting configurable with wrong name', async () => { - let error; - let predicate; - - const abiWithConfigurable = { - ...PREDICATE_ABI, - configurables: [ - { - name: 'BOOL', - configurableType: { - name: '', - type: 1, - typeArguments: null, - }, - offset: 120, - }, - ], - }; - - try { - const provider = new Provider('http://127.0.0.1:4000/graphql'); - const chainId = await provider.getChainId(); - predicate = new Predicate(PREDICATE_BYTECODE, chainId, abiWithConfigurable, undefined, { - NOT_BOOL: 1, - }); - } catch (e: unknown) { - error = e; - } - - expect((error).message).toMatch('Predicate has no configurable constant named:'); - expect(predicate).toBeUndefined(); - }); - - it('should throw when setting configurable but JSON abi was not given', async () => { - let error; - let predicate; - - try { - const provider = new Provider('http://127.0.0.1:4000/graphql'); - const chainId = await provider.getChainId(); - predicate = new Predicate(PREDICATE_BYTECODE, chainId, undefined, undefined, { value: 1 }); - } catch (e) { - error = e; - } - - expect((error).message).toMatch('Unable to validate configurable constants'); - expect(predicate).toBeUndefined(); - }); - - it('should throw when setting configurable but Predicate has none', async () => { - let error; - let predicate; - - try { - const provider = new Provider('http://127.0.0.1:4000/graphql'); - const chainId = await provider.getChainId(); - predicate = new Predicate(PREDICATE_BYTECODE, chainId, PREDICATE_ABI, undefined, { - value: 1, - }); - } catch (e) { - error = e; - } - - expect((error).message).toMatch('Predicate has no configurable constants to be set'); - expect(predicate).toBeUndefined(); - }); - - it('should throw when Predicate abi has no main function', async () => { - let error; - let predicate; - - const abiWithNoMain = { - ...PREDICATE_ABI, - functions: [ - { - ...PREDICATE_ABI.functions[0], - name: 'notMain', - }, - ], - }; - - try { - const provider = new Provider('http://127.0.0.1:4000/graphql'); - const chainId = await provider.getChainId(); - predicate = new Predicate(PREDICATE_BYTECODE, chainId, abiWithNoMain, undefined, { - value: 1, - }); - } catch (e) { - error = e; - } - - expect((error).message).toMatch('Cannot use ABI without "main" function'); - expect(predicate).toBeUndefined(); - }); -}); diff --git a/packages/predicate/test/features/predicate-functions.test.ts b/packages/predicate/test/features/predicate-functions.test.ts new file mode 100644 index 0000000000..3c7cce8be3 --- /dev/null +++ b/packages/predicate/test/features/predicate-functions.test.ts @@ -0,0 +1,52 @@ +import { hexlify } from '@ethersproject/bytes'; + +import { Predicate } from '../../src/predicate'; +import { defaultPredicateAbi } from '../fixtures/abi/default'; +import { defaultPredicateBytecode } from '../fixtures/bytecode/default'; + +describe('Predicate', () => { + describe('Functions', () => { + const chainId = 0; + const predicateAddress = '0x4f780df441f7a02b5c1e718fcd779776499a0d1069697db33f755c82d7bae02b'; + + it('sets predicate address for given byte code', () => { + const predicate = new Predicate(defaultPredicateBytecode, chainId); + expect(predicate.address.toB256()).toEqual(predicateAddress); + }); + + it('sets predicate data for given ABI', () => { + const predicate = new Predicate(defaultPredicateBytecode, chainId, defaultPredicateAbi); + const b256 = '0x0101010101010101010101010101010101010101010101010101010101010101'; + + predicate.setData<[string]>(b256); + + expect(hexlify(predicate.predicateData)).toEqual(b256); + }); + + it('throws when predicate ABI has no main function', () => { + const abiWithNoMain = { + ...defaultPredicateAbi, + functions: [ + { + ...defaultPredicateAbi.functions[0], + name: 'notMain', + }, + ], + }; + + expect(() => { + const predicate = new Predicate( + defaultPredicateBytecode, + chainId, + abiWithNoMain, + undefined, + { + value: 1, + } + ); + + predicate.setData('NADA'); + }).toThrow('Cannot use ABI without "main" function'); + }); + }); +}); diff --git a/packages/predicate/test/features/predicate-transactions.test.ts b/packages/predicate/test/features/predicate-transactions.test.ts new file mode 100644 index 0000000000..520261477e --- /dev/null +++ b/packages/predicate/test/features/predicate-transactions.test.ts @@ -0,0 +1,58 @@ +import { hexlify } from '@ethersproject/bytes'; +import { Address } from '@fuel-ts/address'; +import { bn } from '@fuel-ts/math'; +import { ScriptTransactionRequest } from '@fuel-ts/providers'; +import type { InputCoin } from '@fuel-ts/transactions'; +import { Account } from '@fuel-ts/wallet'; + +import { Predicate } from '../../src/predicate'; +import { defaultPredicateAbi } from '../fixtures/abi/default'; +import { defaultPredicateBytecode } from '../fixtures/bytecode/default'; + +describe('Predicate', () => { + describe('Transactions', () => { + const b256 = '0x0101010101010101010101010101010101010101010101010101010101010101'; + const chainId = 0; + const predicate = new Predicate(defaultPredicateBytecode, chainId, defaultPredicateAbi); + const predicateAddress = '0x4f780df441f7a02b5c1e718fcd779776499a0d1069697db33f755c82d7bae02b'; + + predicate.setData<[string]>(b256); + + const request = new ScriptTransactionRequest(); + request.addResourceInputAndOutput({ + id: '0x01', + assetId: '0x0000000000000000000000000000000000000000000000000000000000000000', + amount: bn(1), + owner: Address.fromB256(predicateAddress), + maturity: 0, + blockCreated: bn(0), + txCreatedIdx: bn(0), + }); + + it('includes predicate as input when sending a transaction', () => { + const sendTransactionMock = jest + .spyOn(Account.prototype, 'sendTransaction') + .mockImplementation(); + + predicate.sendTransaction(request); + + const inputCoinMock = sendTransactionMock.mock.calls[0][0] + .inputs?.[0] as unknown as InputCoin; + expect(hexlify(inputCoinMock.predicate)).toBe(defaultPredicateBytecode); + expect(hexlify(inputCoinMock.predicateData)).toBe(b256); + }); + + it('includes predicate as input when simulating a transaction', () => { + const sendTransactionMock = jest + .spyOn(Account.prototype, 'simulateTransaction') + .mockImplementation(); + + predicate.simulateTransaction(request); + + const inputCoinMock = sendTransactionMock.mock.calls[0][0] + .inputs?.[0] as unknown as InputCoin; + expect(hexlify(inputCoinMock.predicate)).toBe(defaultPredicateBytecode); + expect(hexlify(inputCoinMock.predicateData)).toBe(b256); + }); + }); +}); diff --git a/packages/predicate/test/fixtures/abi/default.ts b/packages/predicate/test/fixtures/abi/default.ts new file mode 100644 index 0000000000..492c6021fa --- /dev/null +++ b/packages/predicate/test/fixtures/abi/default.ts @@ -0,0 +1,38 @@ +import type { JsonAbi } from '@fuel-ts/abi-coder'; + +export const defaultPredicateAbi: JsonAbi = { + types: [ + { + typeId: 0, + type: 'bool', + components: null, + typeParameters: null, + }, + { + typeId: 1, + type: 'b256', + components: null, + typeParameters: null, + }, + ], + functions: [ + { + inputs: [ + { + name: 'data', + type: 1, + typeArguments: null, + }, + ], + name: 'main', + output: { + name: '', + type: 0, + typeArguments: null, + }, + attributes: null, + }, + ], + loggedTypes: [], + configurables: [], +}; diff --git a/packages/predicate/test/fixtures/bytecode/default.ts b/packages/predicate/test/fixtures/bytecode/default.ts new file mode 100644 index 0000000000..a6afa8bdd8 --- /dev/null +++ b/packages/predicate/test/fixtures/bytecode/default.ts @@ -0,0 +1,2 @@ +export const defaultPredicateBytecode = + '0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8';