diff --git a/.changeset/flat-roses-lie.md b/.changeset/flat-roses-lie.md new file mode 100644 index 00000000000..632f2c9f283 --- /dev/null +++ b/.changeset/flat-roses-lie.md @@ -0,0 +1,4 @@ +--- +--- + +feat: ABI refactor diff --git a/.changeset/poor-years-hang.md b/.changeset/poor-years-hang.md new file mode 100644 index 00000000000..e1335f22087 --- /dev/null +++ b/.changeset/poor-years-hang.md @@ -0,0 +1,6 @@ +--- +"@fuel-ts/abi": minor +"fuels": minor +--- + +feat!: ABI Gen diff --git a/.changeset/tender-tigers-fry.md b/.changeset/tender-tigers-fry.md new file mode 100644 index 00000000000..2e270bb05e9 --- /dev/null +++ b/.changeset/tender-tigers-fry.md @@ -0,0 +1,7 @@ +--- +"@fuel-ts/abi": patch +"fuels": patch +"@fuel-ts/errors": patch +--- + +feat: ABI parser diff --git a/.github/actions/test-setup/action.yaml b/.github/actions/test-setup/action.yaml index 8d7c3d6cf0c..0c649356d13 100644 --- a/.github/actions/test-setup/action.yaml +++ b/.github/actions/test-setup/action.yaml @@ -39,6 +39,12 @@ runs: with: bun-version: ${{ inputs.bun-version }} + - name: Set forc and fuel-core paths + shell: bash + run: | + echo "$GITHUB_WORKSPACE/internal/forc/forc-binaries" >> $GITHUB_PATH + echo "$GITHUB_WORKSPACE/internal/fuel-core/fuel-core-binaries" >> $GITHUB_PATH + - name: Build run: pnpm build shell: bash diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index b4eebdd9f42..d35a042e492 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -92,6 +92,7 @@ jobs: PUBLISHED_NPM_TAG: next e2e: + if: false runs-on: ubuntu-latest timeout-minutes: 25 needs: [environments] diff --git a/.knip.json b/.knip.json index 5f0eb9e6e4f..46d7d8fbde3 100644 --- a/.knip.json +++ b/.knip.json @@ -8,7 +8,7 @@ "fuels", "bun", "@types/rimraf", - "@fuel-ts/abi-typegen", + "@fuel-ts/abi", "@internal/fuel-core", "get-graphql-schema", "events", diff --git a/apps/demo-typegen/package.json b/apps/demo-typegen/package.json index 520890ac0a3..9d6d61ce1b4 100644 --- a/apps/demo-typegen/package.json +++ b/apps/demo-typegen/package.json @@ -11,8 +11,8 @@ "forc:predicate": "pnpm fuels-forc build -p demo-predicate --release", "build:types": "run-p types:*", "types:contract": "pnpm fuels typegen -i demo-contract/out/release/demo-contract-abi.json -o src/contract-types", - "types:script": "pnpm fuels typegen -i demo-script/out/release/demo-script-abi.json -o src/script-types --script", - "types:predicate": "pnpm fuels typegen -i demo-predicate/out/release/demo-predicate-abi.json -o src/predicate-types --predicate" + "types:script": "pnpm fuels typegen -i demo-script/out/release/demo-script-abi.json -o src/script-types", + "types:predicate": "pnpm fuels typegen -i demo-predicate/out/release/demo-predicate-abi.json -o src/predicate-types" }, "license": "Apache-2.0", "dependencies": { diff --git a/apps/demo-typegen/src/demo.test.ts b/apps/demo-typegen/src/demo.test.ts index d52c7bf2383..9134931b910 100644 --- a/apps/demo-typegen/src/demo.test.ts +++ b/apps/demo-typegen/src/demo.test.ts @@ -2,11 +2,9 @@ import { toHex, Address, Wallet, FuelError, ErrorCode } from 'fuels'; import { expectToThrowFuelError, launchTestNode } from 'fuels/test-utils'; -import storageSlots from '../demo-contract/out/release/demo-contract-storage_slots.json'; - import { DemoContract, DemoContractFactory } from './contract-types'; import { DemoPredicate } from './predicate-types'; -import type { DemoPredicateInputs } from './predicate-types/DemoPredicate'; +import type { DemoPredicateInputs } from './predicate-types/predicates/DemoPredicate'; import { DemoScript } from './script-types'; /** @@ -25,7 +23,7 @@ describe('ExampleContract', () => { // #context import { DemoContractFactory } from './sway-programs-api'; const { waitForResult } = await DemoContractFactory.deploy(wallet, { - storageSlots, + storageSlots: DemoContractFactory.storageSlots, }); const { contract } = await waitForResult(); diff --git a/apps/docs-api/index.md b/apps/docs-api/index.md index 9e9f1c5e6bc..31a32022812 100644 --- a/apps/docs-api/index.md +++ b/apps/docs-api/index.md @@ -12,6 +12,9 @@ # Modules + + + - [abi-coder](https://fuels-ts-docs-api.vercel.app/modules/_fuel_ts_abi_coder.html) - [abi-typegen](https://fuels-ts-docs-api.vercel.app/modules/_fuel_ts_abi_typegen.html) - [account](https://fuels-ts-docs-api.vercel.app/modules/_fuel_ts_account.html) diff --git a/apps/docs-api/typedoc.json b/apps/docs-api/typedoc.json index 80cfb47a49a..f04aba511f4 100644 --- a/apps/docs-api/typedoc.json +++ b/apps/docs-api/typedoc.json @@ -2,6 +2,7 @@ "$schema": "https://typedoc.org/schema.json", "entryPointStrategy": "packages", "entryPoints": [ + "../../packages/abi", "../../packages/abi-coder", "../../packages/abi-typegen", "../../packages/address", diff --git a/apps/docs/.vitepress/config.ts b/apps/docs/.vitepress/config.ts index 288308581b4..229841ebda5 100644 --- a/apps/docs/.vitepress/config.ts +++ b/apps/docs/.vitepress/config.ts @@ -441,6 +441,10 @@ export default defineConfig({ text: 'Optimized React Example', link: '/guide/cookbook/optimized-react-example', }, + { + text: 'Working with the ABI', + link: '/guide/cookbook/working-with-the-abi', + }, ], }, { diff --git a/apps/docs/spell-check-custom-words.txt b/apps/docs/spell-check-custom-words.txt index 97456d9655b..b83448ca4cf 100644 --- a/apps/docs/spell-check-custom-words.txt +++ b/apps/docs/spell-check-custom-words.txt @@ -343,4 +343,5 @@ Workspaces WSL XOR XORs -YAML \ No newline at end of file +YAML +matcher \ No newline at end of file diff --git a/apps/docs/src/guide/contracts/snippets/proxy-contracts.ts b/apps/docs/src/guide/contracts/snippets/proxy-contracts.ts index 50db63824a0..6e1ee1faa37 100644 --- a/apps/docs/src/guide/contracts/snippets/proxy-contracts.ts +++ b/apps/docs/src/guide/contracts/snippets/proxy-contracts.ts @@ -1,10 +1,5 @@ // #region proxy-2 -import { - Provider, - Wallet, - Src14OwnedProxy, - Src14OwnedProxyFactory, -} from 'fuels'; +import { Provider, Wallet, Src14OwnedProxyFactory } from 'fuels'; import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env'; import { @@ -28,7 +23,7 @@ const { contract: counterContract } = await deploy.waitForResult(); * initialize the storage slots. */ const storageSlots = counterContractFactory.storageSlots.concat( - Src14OwnedProxy.storageSlots + Src14OwnedProxyFactory.storageSlots ); /** * These configurables are specific to our recommended SRC14 compliant diff --git a/apps/docs/src/guide/contracts/snippets/storage-slots/override-storage-slots.ts b/apps/docs/src/guide/contracts/snippets/storage-slots/override-storage-slots.ts index a4b4c289f1f..53f82cf028e 100644 --- a/apps/docs/src/guide/contracts/snippets/storage-slots/override-storage-slots.ts +++ b/apps/docs/src/guide/contracts/snippets/storage-slots/override-storage-slots.ts @@ -2,16 +2,13 @@ import { Provider, Wallet } from 'fuels'; import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env'; -import { - StorageTestContract, - StorageTestContractFactory, -} from '../../../../typegend'; +import { StorageTestContractFactory } from '../../../../typegend'; const provider = new Provider(LOCAL_NETWORK_URL); const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider); const deploymentTx = await StorageTestContractFactory.deploy(deployer, { - storageSlots: StorageTestContract.storageSlots, + storageSlots: StorageTestContractFactory.storageSlots, }); await deploymentTx.waitForResult(); diff --git a/apps/docs/src/guide/cookbook/snippets/parsing-the-abi.ts b/apps/docs/src/guide/cookbook/snippets/parsing-the-abi.ts new file mode 100644 index 00000000000..8b54490de56 --- /dev/null +++ b/apps/docs/src/guide/cookbook/snippets/parsing-the-abi.ts @@ -0,0 +1,9 @@ +// #region full +import { AbiParser } from 'fuels'; +import type { Abi, AbiSpecificationV1 } from 'fuels'; + +import { Counter } from '../../../typegend'; + +const parsedAbi: Abi = AbiParser.parse(Counter.abi as AbiSpecificationV1); +// #endregion full +console.log('Parsed ABI:', parsedAbi); diff --git a/apps/docs/src/guide/cookbook/working-with-the-abi.md b/apps/docs/src/guide/cookbook/working-with-the-abi.md new file mode 100644 index 00000000000..3824f20c576 --- /dev/null +++ b/apps/docs/src/guide/cookbook/working-with-the-abi.md @@ -0,0 +1,11 @@ +# Working with the ABI + +Building a Sway program with `forc build` outputs multiple files, one of which is a JSON representation of the program's ABI. Because ABI specifications can change from one `forc` version to another, working directly with the ABI is cumbersome due to having to manage all ABI specification versions in order to ensure proper functionality. + + + + + +To mitigate this, The SDK provides [`AbiParser`](#working-with-the-abi) which can parse all ABI specification versions and output an object that conforms to the [`Abi`](#working-with-the-abi) interface. The SDK also internally uses this `Abi` interface for implementing its encoding/decoding and TS type generation. + +<<< @./snippets/parsing-the-abi.ts#full{ts:line-numbers} diff --git a/apps/docs/src/guide/errors/index.md b/apps/docs/src/guide/errors/index.md index f28a91ef8b4..136faaa0b66 100644 --- a/apps/docs/src/guide/errors/index.md +++ b/apps/docs/src/guide/errors/index.md @@ -18,6 +18,12 @@ When the arguments supplied to the function do not match the minimum required in Check that the arguments supplied to the function match the required type. +### `ABI_SPECIFICATION_INVALID` + +When the ABI specification provided is invalid. + +Check that the ABI specification is valid. + ### `ACCOUNT_REQUIRED` When an [`Account`](https://fuels-ts-docs-api.vercel.app/classes/_fuel_ts_account.Account.html) is required for an operation. This will usually be in the form of a [`Wallet`](../wallets/index.md). @@ -324,6 +330,12 @@ In cases where the error hasn't been mapped yet, this code will be used. If you believe you found a bug, please report the [issue](https://github.com/FuelLabs/fuels-ts/issues/new/choose) to the team. +### `MATCHER_NOT_FOUND` + +When a matcher is not found for a given Sway type. + +Check that the Sway type is correct and exists in the ABI. + ### `MAX_INPUTS_EXCEEDED` When the number of transaction inputs exceeds the maximum limit allowed by the blockchain. diff --git a/apps/docs/src/guide/fuels-cli/commands.md b/apps/docs/src/guide/fuels-cli/commands.md index 97e936c676f..43bbf92925e 100644 --- a/apps/docs/src/guide/fuels-cli/commands.md +++ b/apps/docs/src/guide/fuels-cli/commands.md @@ -79,7 +79,7 @@ npx fuels@{{fuels}} build ``` 1. Build all Sway programs under your `workspace` using `forc` [1](https://docs.fuel.network/docs/forc/commands/forc_build/) -1. Generate types for them using `fuels-typegen` [2](#fuels-typegen) +1. Generate types for them using `fuels typegen` [2](#fuels-typegen) ```console-vue npx fuels@{{fuels}} build --deploy @@ -167,9 +167,6 @@ npx fuels@{{fuels}} help typegen Options: -i, --inputs Input paths/globals to your Abi JSON files -o, --output Directory path for generated files - -c, --contract Generate types for Contracts [default] - -s, --script Generate types for Scripts - -p, --predicate Generate types for Predicates -S, --silent Omit output messages ``` diff --git a/apps/docs/src/guide/fuels-cli/generating-types.md b/apps/docs/src/guide/fuels-cli/generating-types.md index 6a42b1b530d..57523586e26 100644 --- a/apps/docs/src/guide/fuels-cli/generating-types.md +++ b/apps/docs/src/guide/fuels-cli/generating-types.md @@ -27,18 +27,15 @@ Generate Typescript from Sway ABI JSON files Options: -i, --inputs Input paths/globals to your ABI JSON files -o, --output Directory path for generated files - -c, --contract Generate types for Contracts [default] - -s, --script Generate types for Scripts - -p, --predicate Generate types for Predicates -S, --silent Omit output messages -h, --help Display help ``` -## Generating Types for Contracts +## Generating Types -You can generate types for a Sway contract using the command below: +You can generate types for a Sway program using the command below: - + ```console @@ -50,30 +47,15 @@ pnpm fuels typegen -i ./abis/*-abi.json -o ./types -The path after the input flag `-i` should point to the file ending in `-abi.json` produced when the contract was built. +The path after the input flag `-i` should point to the file ending in `-abi.json` produced when the Sway program was built. -The path after the output flag `-o` will be the output directory for the generated types. +- For scripts and predicates, you'll need the bytecode of the program to be in the same folder for the command to work. +- For contracts, the command will work without the bytecode but the corresponding `ContractFactory` file won't be generated as factories need the bytecode to operate. -You can omit the `--contract` option here since it's the default. +The path after the output flag `-o` will be the output directory for the generated types. -## Generating Types for Scripts - -To generate types for a Sway script, use the `--script` flag: - -```console -pnpm fuels typegen -i ./abis/*-abi.json -o ./types --script -``` - -## Generating Types for Predicates - -To generate types for a Sway predicate, use the `--predicate` flag: - -```console -pnpm fuels typegen -i ./abis/*-abi.json -o ./types --predicate -``` - --- See also: diff --git a/apps/docs/src/guide/fuels-cli/using-generated-types.md b/apps/docs/src/guide/fuels-cli/using-generated-types.md index 4702c2e0394..7e38ecf61c3 100644 --- a/apps/docs/src/guide/fuels-cli/using-generated-types.md +++ b/apps/docs/src/guide/fuels-cli/using-generated-types.md @@ -29,7 +29,7 @@ Typegen tries to resolve, auto-load, and embed the [Storage Slots](../contracts/ After generating types via: ```console -pnpm fuels typegen -i ./abis/*-abi.json -o ./types --script +pnpm fuels typegen -i ./abis/*-abi.json -o ./types ``` We can use these files like so: @@ -41,7 +41,7 @@ We can use these files like so: After generating types via: ```console -pnpm fuels typegen -i ./abis/*-abi.json -o ./types --predicate +pnpm fuels typegen -i ./abis/*-abi.json -o ./types ``` We can use these files like so: diff --git a/apps/docs/src/guide/types/snippets/enums/using-enums-of-enums-1.ts b/apps/docs/src/guide/types/snippets/enums/using-enums-of-enums-1.ts index d3bc38d837d..2194c4fdc16 100644 --- a/apps/docs/src/guide/types/snippets/enums/using-enums-of-enums-1.ts +++ b/apps/docs/src/guide/types/snippets/enums/using-enums-of-enums-1.ts @@ -2,7 +2,7 @@ import { Provider, Wallet } from 'fuels'; import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env'; import { EchoEnumFactory } from '../../../../typegend'; -import { UserErrorInput } from '../../../../typegend/contracts/EchoEnum'; +import { UserError } from '../../../../typegend/contracts/EchoEnum'; const provider = new Provider(LOCAL_NETWORK_URL); const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider); @@ -10,7 +10,7 @@ const deploy = await EchoEnumFactory.deploy(wallet); const { contract } = await deploy.waitForResult(); // #region snippet-1 -const enumParam = { UserError: UserErrorInput.InsufficientPermissions }; +const enumParam = { UserError: UserError.InsufficientPermissions }; const { value } = await contract.functions.echo_error_enum(enumParam).get(); diff --git a/apps/docs/src/guide/types/snippets/enums/using-enums-of-enums-2.ts b/apps/docs/src/guide/types/snippets/enums/using-enums-of-enums-2.ts index d38469bd533..2c6318b0696 100644 --- a/apps/docs/src/guide/types/snippets/enums/using-enums-of-enums-2.ts +++ b/apps/docs/src/guide/types/snippets/enums/using-enums-of-enums-2.ts @@ -2,7 +2,7 @@ import { Provider, Wallet } from 'fuels'; import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env'; import { EchoEnumFactory } from '../../../../typegend'; -import { StateErrorInput } from '../../../../typegend/contracts/EchoEnum'; +import { StateError } from '../../../../typegend/contracts/EchoEnum'; const provider = new Provider(LOCAL_NETWORK_URL); const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider); @@ -10,7 +10,7 @@ const deploy = await EchoEnumFactory.deploy(wallet); const { contract } = await deploy.waitForResult(); // #region snippet-1 -const enumParam = { StateError: StateErrorInput.Completed }; +const enumParam = { StateError: StateError.Completed }; const { value } = await contract.functions.echo_error_enum(enumParam).get(); diff --git a/apps/docs/src/guide/types/snippets/enums/using-sway-enums.ts b/apps/docs/src/guide/types/snippets/enums/using-sway-enums.ts index 4c3b0233ace..93c7fc3d3c7 100644 --- a/apps/docs/src/guide/types/snippets/enums/using-sway-enums.ts +++ b/apps/docs/src/guide/types/snippets/enums/using-sway-enums.ts @@ -3,14 +3,14 @@ import { Provider, Wallet } from 'fuels'; import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env'; import { EchoEnumFactory } from '../../../../typegend'; -import { StateErrorInput } from '../../../../typegend/contracts/EchoEnum'; +import { StateError } from '../../../../typegend/contracts/EchoEnum'; const provider = new Provider(LOCAL_NETWORK_URL); const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider); const deploy = await EchoEnumFactory.deploy(wallet); const { contract } = await deploy.waitForResult(); -const enumParam = StateErrorInput.Completed; +const enumParam = StateError.Completed; const { value } = await contract.functions .echo_state_error_enum(enumParam) diff --git a/internal/check-imports/src/references.ts b/internal/check-imports/src/references.ts index aa4fbbe098a..b1a1479a66c 100644 --- a/internal/check-imports/src/references.ts +++ b/internal/check-imports/src/references.ts @@ -37,10 +37,16 @@ import { arrayify, hexlify, createConfig, + AbiParser, } from 'fuels'; const { log } = console; +/** + * abi + */ +log(AbiParser); + /** * abi-coder */ diff --git a/packages/abi-typegen/package.json b/packages/abi-typegen/package.json index a0c7a220487..d4695347303 100644 --- a/packages/abi-typegen/package.json +++ b/packages/abi-typegen/package.json @@ -3,9 +3,6 @@ "version": "0.98.0", "description": "Generates Typescript definitions from Sway ABI Json files", "author": "Fuel Labs (https://fuel.network/)", - "bin": { - "fuels-typegen": "typegen.js" - }, "main": "dist/index.js", "module": "dist/index.mjs", "types": "dist/index.d.ts", diff --git a/packages/abi/LICENSE b/packages/abi/LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/packages/abi/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/abi/README.md b/packages/abi/README.md new file mode 100644 index 00000000000..ced0388cf00 --- /dev/null +++ b/packages/abi/README.md @@ -0,0 +1,3 @@ +## @fuel-ts/abi + +TODO write up README diff --git a/packages/abi/package.json b/packages/abi/package.json new file mode 100644 index 00000000000..dc3a5066347 --- /dev/null +++ b/packages/abi/package.json @@ -0,0 +1,52 @@ +{ + "name": "@fuel-ts/abi", + "private": true, + "version": "0.0.0", + "description": "", + "author": "Fuel Labs (https://fuel.network/)", + "license": "Apache-2.0", + "main": "dist/index.js", + "module": "dist/index.mjs", + "types": "dist/index.d.ts", + "engines": { + "node": "^18.20.3 || ^20.0.0 || ^22.0.0" + }, + "bin": { + "fuels-typegen": "typegen.js" + }, + "exports": { + ".": { + "require": "./dist/index.js", + "import": "./dist/index.mjs", + "types": "./dist/index.d.ts" + }, + "./cli": { + "types": "./dist/cli.d.ts", + "require": "./dist/cli.js", + "import": "./dist/cli.mjs" + } + }, + "typesVersions": { + "*": { + "cli": [ + "./dist/cli.d.ts" + ] + } + }, + "files": [ + "dist" + ], + "scripts": { + "build": "tsup", + "postbuild": "tsx ../../scripts/postbuild.ts" + }, + "dependencies": { + "@fuel-ts/errors": "workspace:*", + "@fuel-ts/utils": "workspace:*", + "@fuel-ts/versions": "workspace:*", + "handlebars": "4.7.8", + "commander": "12.1.0", + "glob": "10.4.5" + }, + "devDependencies": {} +} diff --git a/packages/abi/src/bin.ts b/packages/abi/src/bin.ts new file mode 100755 index 00000000000..4d4c3bed880 --- /dev/null +++ b/packages/abi/src/bin.ts @@ -0,0 +1,15 @@ +import { getBinaryVersions } from '@fuel-ts/versions/cli'; +import { Command } from 'commander'; + +import { configureTypegenCliOptions } from './cli'; + +const program = new Command(); + +program.name('fuels-typegen'); +program.version(getBinaryVersions().FUELS); +program.usage(`-i ../out/*-abi.json -o ./generated/`); +program.option('-S, --silent', 'Omit output messages', false); + +configureTypegenCliOptions(program); + +program.parse(process.argv); diff --git a/packages/abi/src/cli.ts b/packages/abi/src/cli.ts new file mode 100644 index 00000000000..c37108bd746 --- /dev/null +++ b/packages/abi/src/cli.ts @@ -0,0 +1 @@ +export * from './gen/cli'; diff --git a/packages/abi/src/coder/abi-coder-types.ts b/packages/abi/src/coder/abi-coder-types.ts new file mode 100644 index 00000000000..10051c76805 --- /dev/null +++ b/packages/abi/src/coder/abi-coder-types.ts @@ -0,0 +1 @@ +// Placeholder diff --git a/packages/abi/src/coder/abi-coder.ts b/packages/abi/src/coder/abi-coder.ts new file mode 100644 index 00000000000..38325e4eff3 --- /dev/null +++ b/packages/abi/src/coder/abi-coder.ts @@ -0,0 +1,2 @@ +// Placeholder +export class AbiCoder {} diff --git a/packages/abi/src/coder/encoding/v1/index.ts b/packages/abi/src/coder/encoding/v1/index.ts new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/abi/src/coder/index.ts b/packages/abi/src/coder/index.ts new file mode 100644 index 00000000000..242ad2e5a73 --- /dev/null +++ b/packages/abi/src/coder/index.ts @@ -0,0 +1 @@ +export { AbiCoder } from './abi-coder'; diff --git a/packages/abi/src/gen/abi-gen-types.ts b/packages/abi/src/gen/abi-gen-types.ts new file mode 100644 index 00000000000..032c27a243f --- /dev/null +++ b/packages/abi/src/gen/abi-gen-types.ts @@ -0,0 +1,55 @@ +import type { BinaryVersions } from '@fuel-ts/versions'; + +import type { Abi } from '../parser'; + +export interface AbiGenInput { + /** + * The details of the program to generate the files for. + */ + programDetails: ProgramDetails[]; + /** + * The versions of the binaries used to generate the files. + */ + versions: BinaryVersions; + /** + * The mode to generate the files in. + * Defaults to 'ts' which generates typescript files. + */ + mode?: 'ts'; +} + +export interface AbiGenResult { + /** + * The filename of the generated file. + */ + filename: string; + /** + * The content of the generated file. + */ + content: string; +} + +export interface ProgramDetails { + /** + * The name of the program to generate files for. + * This will be used to name the generated files, + * as well as throughout the generated code. + */ + name: string; + /** + * The compressed bytecode of the program in base64 format. + */ + binCompressed?: string; + /** + * The abi of the program in the format returned via `AbiParser`. + */ + abi: Abi; + /** + * The original abi contents in string format. + */ + abiContents: string; + /** + * The storage slots, if working with a contract. + */ + storageSlots?: string; +} diff --git a/packages/abi/src/gen/abi-gen.ts b/packages/abi/src/gen/abi-gen.ts new file mode 100644 index 00000000000..db6b2d9f46a --- /dev/null +++ b/packages/abi/src/gen/abi-gen.ts @@ -0,0 +1,19 @@ +import type { AbiGenInput, AbiGenResult } from './abi-gen-types'; +import { getRenderer } from './renderers/getRenderer'; + +/** + * The main class to generate files for given sway programs. + * These contents of these generated files make it easier to interact + * with the sway programs, because type definitions are added, + * as well as some automatic loading is done for the user. + */ +export class AbiGen { + /** + * @returns an array of generated files for the given program details. + * They can be saved to disk as-is or further processed. + */ + public static generate({ programDetails, mode, versions }: AbiGenInput): AbiGenResult[] { + const render = getRenderer(mode); + return render(programDetails, versions); + } +} diff --git a/packages/abi/src/gen/cli/index.ts b/packages/abi/src/gen/cli/index.ts new file mode 100644 index 00000000000..939508c0f1b --- /dev/null +++ b/packages/abi/src/gen/cli/index.ts @@ -0,0 +1 @@ +export { configureTypegenCliOptions, runTypegen } from './run'; diff --git a/packages/abi/src/gen/cli/run.ts b/packages/abi/src/gen/cli/run.ts new file mode 100644 index 00000000000..ab87e9c61d4 --- /dev/null +++ b/packages/abi/src/gen/cli/run.ts @@ -0,0 +1,52 @@ +import { getBinaryVersions } from '@fuel-ts/versions/cli'; +import type { Command } from 'commander'; +import { mkdirSync, writeFileSync } from 'fs'; +import { join } from 'path'; + +import { AbiGen } from '../abi-gen'; + +import { getProgramDetails, loggingConfig } from './utils'; + +export interface RunTypegenOptions { + inputs: string[]; + output: string; + silent?: boolean; +} + +export function runTypegen(options: RunTypegenOptions) { + const { inputs, output, silent } = options; + + loggingConfig.silent = !!silent; + + const programDetails = getProgramDetails(inputs); + + const results = AbiGen.generate({ programDetails, versions: getBinaryVersions() }); + + mkdirSync(output, { recursive: true }); + + const subDirectories = new Set(); + + results.forEach((r) => { + const dir = r.filename.split('/').slice(0, -1).join('/'); + if (dir !== '') { + subDirectories.add(dir); + } + }); + + subDirectories.forEach((dir) => { + mkdirSync(join(output, dir), { recursive: true }); + }); + + results.forEach((r) => { + const outputPath = join(output, r.filename); + writeFileSync(outputPath, r.content); + }); +} + +export function configureTypegenCliOptions(program: Command) { + return program + .description(`Generate Typescript from forc build outputs`) + .requiredOption('-i, --inputs ', 'Input paths/globals to your ABI JSON files') + .requiredOption('-o, --output ', 'Directory path for generated files') + .action(runTypegen); +} diff --git a/packages/abi/src/gen/cli/utils.test.ts b/packages/abi/src/gen/cli/utils.test.ts new file mode 100644 index 00000000000..394b52180f9 --- /dev/null +++ b/packages/abi/src/gen/cli/utils.test.ts @@ -0,0 +1,38 @@ +import { ErrorCode, FuelError } from '@fuel-ts/errors'; +import { expectToThrowFuelError } from '@fuel-ts/errors/test-utils'; + +import { normalizeProjectName } from './utils'; + +/** + * @group node + */ +describe('normalizeProjectName', () => { + test('should normalize project name', () => { + expect(normalizeProjectName('DsToken')).toEqual('DsToken'); + expect(normalizeProjectName('test')).toEqual('Test'); + expect(normalizeProjectName('ds-token')).toEqual('DsToken'); + expect(normalizeProjectName('ds_token')).toEqual('DsToken'); + expect(normalizeProjectName('Aaa_bbb_CCDD-EEE')).toEqual('AaaBbbCCDDEEE'); + expect(normalizeProjectName('ds token')).toEqual('DsToken'); + expect(normalizeProjectName('name.abi')).toEqual('NameAbi'); + expect(normalizeProjectName('1234name.abi')).toEqual('NameAbi'); + expect(normalizeProjectName('ERC20.abi')).toEqual('ERC20Abi'); + expect(normalizeProjectName('my-contract')).toEqual('MyContract'); + expect(normalizeProjectName('my contract')).toEqual('MyContract'); + expect(normalizeProjectName('my.contract')).toEqual('MyContract'); + expect(normalizeProjectName('still-my.contract')).toEqual('StillMyContract'); + expect(normalizeProjectName('also my.contract')).toEqual('AlsoMyContract'); + }); + + test('throws if name cannot be normalized', async () => { + await expectToThrowFuelError( + () => normalizeProjectName(''), + new FuelError( + ErrorCode.PARSE_FAILED, + `The provided string '' results in an empty output after`.concat( + ` normalization, therefore, it can't normalize string.` + ) + ) + ); + }); +}); diff --git a/packages/abi/src/gen/cli/utils.ts b/packages/abi/src/gen/cli/utils.ts new file mode 100644 index 00000000000..dd2f987b3cc --- /dev/null +++ b/packages/abi/src/gen/cli/utils.ts @@ -0,0 +1,109 @@ +import { ErrorCode, FuelError } from '@fuel-ts/errors'; +import { assertUnreachable, compressBytecode, hexlify } from '@fuel-ts/utils'; +import { readFileSync } from 'fs'; +import { globSync } from 'glob'; + +import type { AbiSpecification } from '../../parser'; +import { AbiParser } from '../../parser'; +import type { ProgramDetails } from '../abi-gen-types'; + +export const loggingConfig = { + silent: false, +}; + +export function log(...args: Parameters) { + if (!loggingConfig.silent) { + // eslint-disable-next-line no-console + console.log(...args); + } +} + +/** + * Converts `some.string-value` into `SomeStringValue`. + * + * Examples: + * my-simple.test —— MySimpleTest + * myFile.ts —— MyFileTs + * my-abi.json —— MyAbiJson + */ +export function normalizeProjectName(str: string): string { + const transformations: ((s: string) => string)[] = [ + (s) => s.replace(/\s+/g, '-'), // spaces to - + (s) => s.replace(/\./g, '-'), // dots to - + (s) => s.replace(/_/g, '-'), // underscore to - + (s) => s.replace(/-[a-z]/g, (match) => match.slice(-1).toUpperCase()), // delete '-' and capitalize the letter after them + (s) => s.replace(/-/g, ''), // delete any '-' left + (s) => s.replace(/^\d+/, ''), // removes leading digits + ]; + + const output = transformations.reduce((s, t) => t(s), str); + + if (output === '') { + const errMsg = `The provided string '${str}' results in an empty output after`.concat( + ` normalization, therefore, it can't normalize string.` + ); + throw new FuelError(ErrorCode.PARSE_FAILED, errMsg); + } + + return output[0].toUpperCase() + output.slice(1); // capitalize first letter +} + +function handleMissingBinary(path: string, abi: AbiSpecification) { + const programType = abi.programType as 'predicate' | 'script' | 'contract' | 'library'; + switch (programType) { + case 'predicate': + throw new FuelError( + ErrorCode.BIN_FILE_NOT_FOUND, + `For predicates, the bytecode is required. No bytecode found for predicate at ${path}.` + ); + case 'script': + throw new FuelError( + ErrorCode.BIN_FILE_NOT_FOUND, + `For scripts, the bytecode is required. No bytecode found for script at ${path}.` + ); + case 'contract': + log(`No bytecode found for contract at ${path}, will not generate ContractFactory for it.`); + break; + case 'library': + // ignore; + break; + default: + assertUnreachable(programType); + } +} + +export function getProgramDetails(paths: string[]) { + const details: ProgramDetails[] = []; + paths.forEach((path) => { + const abiPath = path.match(/.+-abi\.json/) ? path : globSync(`${path}/*-abi.json`)[0]; + if (abiPath === undefined) { + log(`No abi file found in ${path}, skipping this path.`); + return; + } + + const dir = abiPath.match(/.*\//)?.[0] as string; + const projectName = abiPath.match(/([^/])+(?=-abi\.json)/)?.[0] as string; + const abiContentsStr = readFileSync(abiPath).toString(); + const abi = JSON.parse(abiContentsStr) as AbiSpecification; + + const [storageSlotsPath] = globSync(`${dir}/*-storage_slots.json`); + const storageSlots = storageSlotsPath ? readFileSync(storageSlotsPath).toString() : undefined; + + const [binPath] = globSync(`${dir}/*.bin`); + if (binPath === undefined) { + handleMissingBinary(path, abi); + } + + const binCompressed = binPath && compressBytecode(hexlify(readFileSync(binPath))); + + details.push({ + name: normalizeProjectName(projectName), + abi: AbiParser.parse(JSON.parse(abiContentsStr) as AbiSpecification), + binCompressed, + abiContents: abiContentsStr, + storageSlots, + }); + }); + + return details; +} diff --git a/packages/abi/src/gen/hbs.d.ts b/packages/abi/src/gen/hbs.d.ts new file mode 100644 index 00000000000..cefe640967a --- /dev/null +++ b/packages/abi/src/gen/hbs.d.ts @@ -0,0 +1,5 @@ +// informs TS about Handlebar `.hbs` templates extension +declare module '*.hbs' { + const value: string; + export default value; +} diff --git a/packages/abi/src/gen/index.ts b/packages/abi/src/gen/index.ts new file mode 100644 index 00000000000..29b42ee4313 --- /dev/null +++ b/packages/abi/src/gen/index.ts @@ -0,0 +1,2 @@ +export { AbiGen } from './abi-gen'; +export * from './abi-gen-types'; diff --git a/packages/abi/src/gen/renderers/getRenderer.ts b/packages/abi/src/gen/renderers/getRenderer.ts new file mode 100644 index 00000000000..bf43bb5d832 --- /dev/null +++ b/packages/abi/src/gen/renderers/getRenderer.ts @@ -0,0 +1,16 @@ +import { assertUnreachable } from '@fuel-ts/utils'; + +import type { AbiGenInput } from '../abi-gen-types'; + +import { renderTs } from './ts/render-ts'; +import type { Renderer } from './types'; + +export function getRenderer(mode: AbiGenInput['mode']): Renderer { + switch (mode) { + case 'ts': + case undefined: + return renderTs; + default: + return assertUnreachable(mode); + } +} diff --git a/packages/abi/src/gen/renderers/ts/render-ts.ts b/packages/abi/src/gen/renderers/ts/render-ts.ts new file mode 100644 index 00000000000..6654b4c6902 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/render-ts.ts @@ -0,0 +1,17 @@ +import type { AbiGenResult, ProgramDetails } from '../../abi-gen-types'; +import type { Renderer } from '../types'; + +import { renderPrograms } from './renderers/render-programs'; +import { templateRenderer } from './renderers/template-renderer'; +import commonTemplate from './templates/common.hbs'; + +export const renderTs: Renderer = (details: ProgramDetails[], versions): AbiGenResult[] => { + const results = renderPrograms(details, versions); + + results.push({ + filename: 'common.ts', + content: templateRenderer({ template: commonTemplate, versions }), + }); + + return results; +}; diff --git a/packages/abi/src/gen/renderers/ts/renderers/get-parent-dir-wrapper.ts b/packages/abi/src/gen/renderers/ts/renderers/get-parent-dir-wrapper.ts new file mode 100644 index 00000000000..a8239ef814e --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/renderers/get-parent-dir-wrapper.ts @@ -0,0 +1,32 @@ +import { assertUnreachable } from '@fuel-ts/utils'; + +import type { Abi } from '../../../../parser'; + +export function getParentDirWrapper(programType: Abi['programType']): { + parentDir: string; + withParentDir: (file: string) => string; + removeParentDir: (file: string) => string; +} { + let parentDir: string = ''; + switch (programType) { + case 'contract': + parentDir = 'contracts'; + break; + case 'predicate': + parentDir = 'predicates'; + break; + case 'script': + parentDir = 'scripts'; + break; + case 'library': + break; + default: + assertUnreachable(programType); + } + + return { + parentDir, + withParentDir: (file) => `${parentDir}/${file}`, + removeParentDir: (file) => file.split(`${parentDir}/`)[1], + }; +} diff --git a/packages/abi/src/gen/renderers/ts/renderers/render-index-files.ts b/packages/abi/src/gen/renderers/ts/renderers/render-index-files.ts new file mode 100644 index 00000000000..12c9c479871 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/renderers/render-index-files.ts @@ -0,0 +1,73 @@ +import type { BinaryVersions } from '@fuel-ts/versions'; + +import type { Abi } from '../../../../parser'; +import type { AbiGenResult } from '../../../abi-gen-types'; +import indexTemplate from '../templates/index.hbs'; + +import { getParentDirWrapper } from './get-parent-dir-wrapper'; +import { templateRenderer } from './template-renderer'; + +export type IndexContents = Map< + Abi['programType'], + { filename: string; exportedContent: string[] }[] +>; +/** + * @returns an array of index files + * that includes the root index.ts and the index.ts for each provided program type. + */ +export function renderIndexFiles( + indexContents: IndexContents, + versions: BinaryVersions +): AbiGenResult[] { + const results: AbiGenResult[] = []; + + indexContents.forEach((files, programType) => { + const { withParentDir, removeParentDir } = getParentDirWrapper(programType); + + // from index.ts to e.g. contracts/index.ts + const indexFilename = withParentDir('index.ts'); + + const exports = files.map(({ filename, exportedContent }) => { + // from e.g. contracts/AbiContract.ts to AbiContract.ts + const relativePathToFile = removeParentDir(filename); + // remove .ts extension + return { + path: relativePathToFile.split('.')[0], + exportedContent: `{ ${exportedContent.join(', ')} }`, + }; + }); + + const content = templateRenderer({ + versions, + template: indexTemplate, + data: { + exports, + }, + }); + + results.push({ + filename: indexFilename, + content, + }); + }); + + const mainIndexFileExports = [...indexContents.keys()] + .sort() + .map((programType) => getParentDirWrapper(programType).parentDir) + .map((path) => ({ path, exportedContent: '*' })); + + const mainIndexFile: AbiGenResult = { + filename: 'index.ts', + content: templateRenderer({ + versions, + template: indexTemplate, + data: { + exports: mainIndexFileExports, + }, + }), + }; + + results.push(mainIndexFile); + + return results; +} diff --git a/packages/abi/src/gen/renderers/ts/renderers/render-program.ts b/packages/abi/src/gen/renderers/ts/renderers/render-program.ts new file mode 100644 index 00000000000..7bcb0c6a017 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/renderers/render-program.ts @@ -0,0 +1,113 @@ +import { assertUnreachable } from '@fuel-ts/utils'; +import type { BinaryVersions } from '@fuel-ts/versions'; + +import type { ProgramDetails } from '../../../abi-gen-types'; +import type { TsAbiGenResult } from '../../types'; +import abiTemplate from '../templates/abi.hbs'; +import bytecodeTemplate from '../templates/bytecode.hbs'; +import contractFactoryTemplate from '../templates/contract-factory.hbs'; +import contractTemplate from '../templates/contract.hbs'; +import predicateTemplate from '../templates/predicate.hbs'; +import scriptTemplate from '../templates/script.hbs'; +import storageSlotsTemplate from '../templates/storage-slots.hbs'; + +import { getParentDirWrapper } from './get-parent-dir-wrapper'; +import { renderTypes } from './render-types'; +import { templateRenderer } from './template-renderer'; + +/** + * Renders program-related files based on the program type. + * @returns An array of results containing filenames and their corresponding content. + * The files returned are all related to the program except the types. + * This includes the abi, bytecode, and the program-related classes. + */ +export function renderProgram(details: ProgramDetails, versions: BinaryVersions): TsAbiGenResult[] { + const { abi, binCompressed, name, abiContents, storageSlots } = details; + + const results: TsAbiGenResult[] = [ + { + filename: `${name}Types.ts`, + content: renderTypes(details, versions), + }, + { + filename: `${name}-abi.ts`, + content: templateRenderer({ template: abiTemplate, versions, data: { abiContents } }), + }, + ]; + + if (binCompressed) { + results.push({ + filename: `${name}-bytecode.ts`, + content: templateRenderer({ template: bytecodeTemplate, versions, data: { binCompressed } }), + }); + } + + switch (abi.programType) { + case 'contract': + results.push( + { + filename: `${name}.ts`, + content: templateRenderer({ + template: contractTemplate, + versions, + data: { name }, + }), + exportInIndexFile: [name], + }, + + { + filename: `${name}-storage-slots.ts`, + content: templateRenderer({ + template: storageSlotsTemplate, + versions, + data: { storageSlots }, + }), + } + ); + + if (binCompressed) { + results.push({ + filename: `${name}Factory.ts`, + content: templateRenderer({ + template: contractFactoryTemplate, + versions, + data: { name }, + }), + exportInIndexFile: [`${name}Factory`], + }); + } + break; + case 'predicate': + results.push({ + filename: `${name}.ts`, + content: templateRenderer({ + template: predicateTemplate, + versions, + data: { name }, + }), + exportInIndexFile: [name], + }); + break; + case 'script': + results.push({ + filename: `${name}.ts`, + content: templateRenderer({ + template: scriptTemplate, + versions, + data: { name }, + }), + exportInIndexFile: [name], + }); + break; + case 'library': + // we do nothing for library + break; + default: + assertUnreachable(abi.programType); + break; + } + + const { withParentDir } = getParentDirWrapper(abi.programType); + + return results.map((r) => ({ ...r, filename: withParentDir(r.filename) })); +} diff --git a/packages/abi/src/gen/renderers/ts/renderers/render-programs.ts b/packages/abi/src/gen/renderers/ts/renderers/render-programs.ts new file mode 100644 index 00000000000..269e90f8676 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/renderers/render-programs.ts @@ -0,0 +1,37 @@ +import type { BinaryVersions } from '@fuel-ts/versions'; + +import type { AbiGenResult, ProgramDetails } from '../../../abi-gen-types'; + +import type { IndexContents } from './render-index-files'; +import { renderIndexFiles } from './render-index-files'; +import { renderProgram } from './render-program'; + +/** + * For the given program details, render all program-related files. + * That includes the abi, bytecode, program-related classes, + * type files and the index files. + */ +export function renderPrograms(details: ProgramDetails[], versions: BinaryVersions) { + const results: AbiGenResult[] = []; + const indexContents: IndexContents = new Map(); + + for (const d of details) { + const files = renderProgram(d, versions); + + results.push(...files); + + files.forEach((file) => { + if (!file.exportInIndexFile?.length) { + return; + } + + const contents = indexContents.get(d.abi.programType) ?? []; + contents.push({ filename: file.filename, exportedContent: file.exportInIndexFile }); + indexContents.set(d.abi.programType, contents); + }); + } + + results.push(...renderIndexFiles(indexContents, versions)); + + return results; +} diff --git a/packages/abi/src/gen/renderers/ts/renderers/render-types.ts b/packages/abi/src/gen/renderers/ts/renderers/render-types.ts new file mode 100644 index 00000000000..d8a88e2a362 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/renderers/render-types.ts @@ -0,0 +1,120 @@ +import type { BinaryVersions } from '@fuel-ts/versions'; + +import { createMatcher } from '../../../../matchers/sway-type-matchers'; +import type { Abi } from '../../../../parser'; +import { evaluateFunctionInputsOptionality } from '../../../../utils/evaluate-function-inputs-optionality'; +import type { ProgramDetails } from '../../../abi-gen-types'; +import typesTemplate from '../templates/types.hbs'; +import { generateTsType } from '../typers/generate-ts-type'; +import { flattenImports } from '../typers/helpers'; +import type { TyperReturn } from '../typers/types'; + +import { templateRenderer } from './template-renderer'; + +const metadataTypeFilter = createMatcher({ + enum: true, + struct: true, + assetId: true, + string: false, + void: false, + bool: false, + u8: false, + u16: false, + u32: false, + u64: false, + u256: false, + b256: false, + generic: false, + stdString: false, + option: false, + result: false, + str: false, + b512: false, + bytes: false, + vector: false, + tuple: false, + array: false, + evmAddress: false, + rawUntypedSlice: false, +}); + +export function sortAlphabetically(a: TyperReturn, b: TyperReturn) { + if (a.input < b.input) { + return -1; + } + if (a.input > b.input) { + return 1; + } + return 0; +} + +function mergeTypeImports(mTypes: TyperReturn[], cTypesMap: Record) { + const cTypes = Object.values(cTypesMap); + + const imports = flattenImports(mTypes.concat(cTypes)); + + const fuelsTypeImports = [...new Set(imports.fuelsTypeImports)].sort().join(', '); + + const commonTypeImports = [...new Set(imports.commonTypeImports)].sort().join(', '); + + return { fuelsTypeImports, commonTypeImports }; +} + +function mapFunctions(abi: Abi, cTypes: Record) { + return abi.functions.map((fn) => { + const inputs = evaluateFunctionInputsOptionality(fn); + + return { + name: fn.name, + inputs: `[${inputs.map((i) => `${i.name}${i.isOptional ? '?' : ''}: ${cTypes[i.type.concreteTypeId].input}`).join(', ')}]`, + output: cTypes[fn.output.concreteTypeId].output, + }; + }); +} + +function mapConfigurables(abi: Abi, cTypes: Record) { + return abi.configurables.length > 0 + ? abi.configurables.map(({ name, type }) => ({ + name, + input: cTypes[type.concreteTypeId].input, + })) + : undefined; +} + +/** + * Renders the types file for a program. + * @returns An object containing the filename and the content of the types file. + * The type rendering logic is the same for all program types. + */ +export function renderTypes( + { name: programName, abi }: ProgramDetails, + versions: BinaryVersions +): string { + const mTypes = abi.metadataTypes + .filter(metadataTypeFilter) + .map((abiType) => generateTsType({ abiType })); + + const cTypes = abi.concreteTypes.reduce>((res, abiType) => { + res[abiType.concreteTypeId] = generateTsType({ abiType, asReference: true }); + return res; + }, {}); + + const { fuelsTypeImports, commonTypeImports } = mergeTypeImports(mTypes, cTypes); + + const content = templateRenderer({ + template: typesTemplate, + versions, + data: { + isContract: abi.programType === 'contract', + name: programName, + fuelsTypeImports, + commonTypeImports, + enums: mTypes.filter(({ tsType }) => tsType === 'enum').sort(sortAlphabetically), + types: mTypes.filter(({ tsType }) => tsType === 'type').sort(sortAlphabetically), + functions: mapFunctions(abi, cTypes), + configurables: mapConfigurables(abi, cTypes), + }, + }); + + return content; +} diff --git a/packages/abi/src/gen/renderers/ts/renderers/template-renderer.ts b/packages/abi/src/gen/renderers/ts/renderers/template-renderer.ts new file mode 100644 index 00000000000..f1a4ceaf7ea --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/renderers/template-renderer.ts @@ -0,0 +1,29 @@ +import type { BinaryVersions } from '@fuel-ts/versions'; +import Handlebars from 'handlebars'; + +import headerTemplate from '../templates/header.hbs'; + +/* + Renders the given template w/ the given data, while injecting common + header for disabling lint rules and annotating Fuel component's versions. +*/ +export function templateRenderer(params: { + template: string; + data?: Record; + versions: BinaryVersions; +}) { + const { data, template, versions } = params; + + const options = { + strict: true, + noEscape: true, + }; + + const renderHeaderTemplate = Handlebars.compile(headerTemplate, options); + const renderTemplate = Handlebars.compile(template, options); + + return renderTemplate({ + header: renderHeaderTemplate(versions), + ...(data ?? {}), + }); +} diff --git a/packages/abi/src/gen/renderers/ts/templates/abi.hbs b/packages/abi/src/gen/renderers/ts/templates/abi.hbs new file mode 100644 index 00000000000..0516073cc70 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/templates/abi.hbs @@ -0,0 +1,3 @@ +{{header}} + +export const abi = {{abiContents}}; \ No newline at end of file diff --git a/packages/abi/src/gen/renderers/ts/templates/bytecode.hbs b/packages/abi/src/gen/renderers/ts/templates/bytecode.hbs new file mode 100644 index 00000000000..5d859be0dd2 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/templates/bytecode.hbs @@ -0,0 +1,5 @@ +{{header}} + +import { decompressBytecode } from "fuels"; + +export const bytecode = decompressBytecode("{{binCompressed}}"); \ No newline at end of file diff --git a/packages/abi/src/gen/renderers/ts/templates/common.hbs b/packages/abi/src/gen/renderers/ts/templates/common.hbs new file mode 100644 index 00000000000..c6bb8343a05 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/templates/common.hbs @@ -0,0 +1,44 @@ +{{header}} + +import type { FunctionFragment, InvokeFunction } from 'fuels'; + +/** + * Mimics Sway Enum. + * Requires one and only one Key-Value pair and raises error if more are provided. + */ +export type Enum = { + [K in keyof T]: Pick & { [P in Exclude]?: never }; +}[keyof T]; + +/** + * Mimics Sway Option type. + */ +export type Option = T | undefined; + +/** + * Mimics Sway Result enum type. + * Ok represents the success case, while Err represents the error case. + */ +export type Result = Enum<{ Ok: T; Err: E }>; + +/** + * Mimics Sway array type. For example, [u64; 10] is converted to ArrayOfLength. + */ +export type ArrayOfLength< + T, + Length extends number, + Arr extends unknown[] = [], +> = Arr['length'] extends Length ? Arr : ArrayOfLength; + +interface Types { + functions: Record; + configurables: Partial>; +} + +export type ProgramFunctionMapper = { + [K in keyof T]: InvokeFunction; +}; + +export type InterfaceFunctionMapper = { + [K in keyof T]: FunctionFragment; +}; \ No newline at end of file diff --git a/packages/abi/src/gen/renderers/ts/templates/contract-factory.hbs b/packages/abi/src/gen/renderers/ts/templates/contract-factory.hbs new file mode 100644 index 00000000000..b57f0ea8e33 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/templates/contract-factory.hbs @@ -0,0 +1,26 @@ +{{header}} + +import { ContractFactory } from 'fuels'; +import type { Account, Provider, DeployContractOptions } from 'fuels'; +import { {{name}} } from './{{name}}'; +import { bytecode } from './{{name}}-bytecode'; +import { abi } from './{{name}}-abi'; +import { storageSlots } from './{{name}}-storage-slots'; + +export class {{name}}Factory extends ContractFactory<{{name}}> { + + static readonly bytecode = bytecode; + static readonly storageSlots = storageSlots; + + constructor(accountOrProvider: Account | Provider) { + super(bytecode, abi, accountOrProvider, {{name}}Factory.storageSlots); + } + + static deploy ( + wallet: Account, + options: DeployContractOptions = {} + ) { + const factory = new {{name}}Factory(wallet); + return factory.deploy(options); + } +} diff --git a/packages/abi/src/gen/renderers/ts/templates/contract.hbs b/packages/abi/src/gen/renderers/ts/templates/contract.hbs new file mode 100644 index 00000000000..87ddcf43d43 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/templates/contract.hbs @@ -0,0 +1,33 @@ +{{header}} + +import { Contract, Interface } from "fuels"; +import type { Address, Account, Provider } from 'fuels'; +import type { {{name}}Types as Types } from './{{name}}Types'; +import type { InterfaceFunctionMapper, ProgramFunctionMapper } from '../common'; +import { abi } from './{{name}}-abi'; + +export * from './{{name}}Types'; + +export type {{name}}Configurables = Types['configurables']; + +export class {{name}}Interface extends Interface { + declare functions: InterfaceFunctionMapper; + + constructor() { + super(abi); + } +} + +export class {{name}} extends Contract { + declare interface: {{name}}Interface; + declare functions: ProgramFunctionMapper; + + public static readonly abi = abi; + + constructor( + id: string | Address, + accountOrProvider: Account | Provider, + ) { + super(id, abi, accountOrProvider); + } +} \ No newline at end of file diff --git a/packages/abi/src/gen/renderers/ts/templates/header.hbs b/packages/abi/src/gen/renderers/ts/templates/header.hbs new file mode 100644 index 00000000000..a8ec5578f8b --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/templates/header.hbs @@ -0,0 +1,9 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: {{FUELS}} + Forc version: {{FORC}} +*/ diff --git a/packages/abi/src/gen/renderers/ts/templates/index.hbs b/packages/abi/src/gen/renderers/ts/templates/index.hbs new file mode 100644 index 00000000000..f323c7973da --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/templates/index.hbs @@ -0,0 +1,5 @@ +{{header}} + +{{#each exports}} +export {{exportedContent}} from './{{path}}'; +{{/each}} \ No newline at end of file diff --git a/packages/abi/src/gen/renderers/ts/templates/predicate.hbs b/packages/abi/src/gen/renderers/ts/templates/predicate.hbs new file mode 100644 index 00000000000..2925628d4e5 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/templates/predicate.hbs @@ -0,0 +1,33 @@ +{{header}} + +import { Predicate } from 'fuels'; +import type { PredicateParams } from 'fuels'; +import { abi } from './{{name}}-abi'; +import { bytecode } from './{{name}}-bytecode'; +import type { {{name}}Types as Types } from './{{name}}Types'; + +export * from './{{name}}Types'; + +export type {{name}}Inputs = Types['inputs']; +export type {{name}}Output = Types['output']; +export type {{name}}Configurables = Types['configurables']; + +export type {{name}}Parameters = Omit< + PredicateParams< + Types['inputs'], + Types['configurables'] + >, + 'abi' | 'bytecode' +>; + +export class {{name}} extends Predicate< + Types['inputs'], + Types['configurables'] +> { + public static readonly abi = abi; + public static readonly bytecode = bytecode; + + constructor(params: {{name}}Parameters) { + super({ abi, bytecode, ...params }); + } +} \ No newline at end of file diff --git a/packages/abi/src/gen/renderers/ts/templates/script.hbs b/packages/abi/src/gen/renderers/ts/templates/script.hbs new file mode 100644 index 00000000000..b304d851616 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/templates/script.hbs @@ -0,0 +1,25 @@ +{{header}} + +import { Script } from 'fuels'; +import type { Account } from 'fuels'; +import { abi } from './{{name}}-abi'; +import { bytecode } from './{{name}}-bytecode'; +import type { {{name}}Types as Types } from './{{name}}Types'; + +export * from './{{name}}Types'; + +export type {{name}}Inputs = Types['inputs']; +export type {{name}}Output = Types['output']; +export type {{name}}Configurables = Types['configurables']; + +export class {{name}} extends Script< + Types['inputs'], + Types['output'] +> { + public static readonly abi = abi; + public static readonly bytecode = bytecode; + + constructor(wallet: Account) { + super(bytecode, abi, wallet); + } +} \ No newline at end of file diff --git a/packages/abi/src/gen/renderers/ts/templates/storage-slots.hbs b/packages/abi/src/gen/renderers/ts/templates/storage-slots.hbs new file mode 100644 index 00000000000..a877acccda5 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/templates/storage-slots.hbs @@ -0,0 +1,5 @@ +{{header}} + +import type { StorageSlot } from 'fuels'; + +export const storageSlots: StorageSlot[] = {{storageSlots}}; \ No newline at end of file diff --git a/packages/abi/src/gen/renderers/ts/templates/types.hbs b/packages/abi/src/gen/renderers/ts/templates/types.hbs new file mode 100644 index 00000000000..8624ec21820 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/templates/types.hbs @@ -0,0 +1,36 @@ +{{header}} + +import type { {{fuelsTypeImports}} } from 'fuels'; +import type { {{commonTypeImports}} } from '../common'; + +{{#each enums}} +export enum {{input}}; +{{/each}} + +{{#each types}} +export type {{input}}; +export type {{output}}; +{{/each}} + +export interface {{name}}Types { + {{#if isContract}} + functions: { + {{#each functions}} + {{name}}: { + inputs: {{inputs}}; + output: {{output}}; + }; + {{/each}} + }; + {{else}} + {{#each functions}} + inputs: {{inputs}}; + output: {{output}}; + {{/each}} + {{/if}} + configurables: {{#if configurables}}Partial<{ + {{#each configurables}} + {{name}}: {{input}}; + {{/each}} + }>{{else}}undefined{{/if}}; +} \ No newline at end of file diff --git a/packages/abi/src/gen/renderers/ts/typers/enums.ts b/packages/abi/src/gen/renderers/ts/typers/enums.ts new file mode 100644 index 00000000000..31e81835330 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/typers/enums.ts @@ -0,0 +1,68 @@ +import { swayTypeMatchers, ENUM_REGEX } from '../../../../matchers/sway-type-matchers'; + +import { structTyper } from './struct'; +import type { Typer, TyperAbiType } from './types'; + +function isNativeEnum(abiType: TyperAbiType) { + return abiType.components?.every((t) => swayTypeMatchers.void(t.type.swayType)) === true; +} + +export const enumTyper: Typer = (params, typer) => { + const { abiType } = params; + if (isNativeEnum(abiType)) { + const typeName = ENUM_REGEX.exec(abiType.swayType)?.[2] as string; + + if (params.asReference) { + return { input: typeName, output: typeName }; + } + + const enumFields = abiType.components?.map((c) => `${c.name} = '${c.name}'`).join(', '); + const input = `${typeName} { ${enumFields} }`; + return { + input, + output: input, + tsType: 'enum', + }; + } + + return structTyper(params, typer); +}; + +export const optionTyper: Typer = ({ abiType }, typer) => { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const { type } = abiType.components![1]!; + const some = typer({ abiType: type, asReference: true }); + const input = `Option<${some.input}>`; + const output = `Option<${some.output}>`; + return { + input, + output, + commonTypeImports: ['Option'], + }; +}; + +export const resultTyper: Typer = ({ abiType }, typer) => { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const [{ type: ok }, { type: err }] = abiType.components!; + const mappedOk = typer({ abiType: ok, asReference: true }); + const mappedErr = typer({ abiType: err, asReference: true }); + + const input = `Result<${mappedOk.input}, ${mappedErr.input}>`; + const output = `Result<${mappedOk.output}, ${mappedErr.output}>`; + + const fuelsTypeImports = [ + mappedOk.fuelsTypeImports ?? [], + mappedErr.fuelsTypeImports ?? [], + ].flat(); + const commonTypeImports = [ + mappedOk.commonTypeImports ?? [], + mappedErr.commonTypeImports ?? [], + ['Result'], + ].flat(); + return { + input, + output, + fuelsTypeImports, + commonTypeImports, + }; +}; diff --git a/packages/abi/src/gen/renderers/ts/typers/generate-ts-type.ts b/packages/abi/src/gen/renderers/ts/typers/generate-ts-type.ts new file mode 100644 index 00000000000..09ce1a1aa55 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/typers/generate-ts-type.ts @@ -0,0 +1,6 @@ +import { typerMatcher } from './typer-matcher'; +import type { TyperParams, TyperReturn } from './types'; + +export function generateTsType(params: TyperParams): TyperReturn { + return typerMatcher(params.abiType)(params, generateTsType); +} diff --git a/packages/abi/src/gen/renderers/ts/typers/helpers.ts b/packages/abi/src/gen/renderers/ts/typers/helpers.ts new file mode 100644 index 00000000000..892c6e1b62f --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/typers/helpers.ts @@ -0,0 +1,10 @@ +import type { TyperReturn } from './types'; + +export function flattenImports(mapped: TyperReturn[]) { + const fuelsTypeImports = mapped.flatMap((m) => m.fuelsTypeImports).filter((x) => x !== undefined); + const commonTypeImports = mapped + .flatMap((m) => m.commonTypeImports) + .filter((x) => x !== undefined); + + return { fuelsTypeImports, commonTypeImports }; +} diff --git a/packages/abi/src/gen/renderers/ts/typers/iterators.ts b/packages/abi/src/gen/renderers/ts/typers/iterators.ts new file mode 100644 index 00000000000..3ed4f99743d --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/typers/iterators.ts @@ -0,0 +1,37 @@ +import { ARRAY_REGEX } from '../../../../matchers/sway-type-matchers'; +import type { AbiTypeComponent } from '../../../../parser'; + +import type { Typer } from './types'; +import { mapComponents } from './utils'; + +export const tupleTyper: Typer = ({ abiType }, typer) => + mapComponents({ parent: abiType, includeComponentNames: false, typer }); + +export const arrayTyper: Typer = ({ abiType }, typer) => { + const length = ARRAY_REGEX.exec(abiType.swayType)?.[2]; + + const { type } = abiType.components?.[0] as AbiTypeComponent; + const mapped = typer({ abiType: type, asReference: true }); + + const input = `ArrayOfLength<${mapped.input}, ${length}>`; + const output = `ArrayOfLength<${mapped.output}, ${length}>`; + + return { + input, + output, + fuelsTypeImports: mapped.fuelsTypeImports, + commonTypeImports: ['ArrayOfLength', ...(mapped.commonTypeImports ?? [])], + }; +}; + +export const vectorTyper: Typer = ({ abiType }, typer) => { + const { type } = abiType.components?.[0] as AbiTypeComponent; + const mapped = typer({ abiType: type, asReference: true }); + const input = `${mapped.input}[]`; + const output = `${mapped.output}[]`; + return { + ...mapped, + input, + output, + }; +}; diff --git a/packages/abi/src/gen/renderers/ts/typers/simple.ts b/packages/abi/src/gen/renderers/ts/typers/simple.ts new file mode 100644 index 00000000000..9440f5aec51 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/typers/simple.ts @@ -0,0 +1,82 @@ +import { GENERIC_REGEX } from '../../../../matchers/sway-type-matchers'; + +import type { TyperReturn, Typer } from './types'; + +const numberTyperReturn: TyperReturn = { + input: 'BigNumberish', + output: 'number', + fuelsTypeImports: ['BigNumberish'], +}; + +export const u8Typer: Typer = () => numberTyperReturn; +export const u16Typer = u8Typer; +export const u32Typer = u8Typer; + +const u64TyperReturn: TyperReturn = { + input: 'BigNumberish', + output: 'BN', + fuelsTypeImports: ['BigNumberish', 'BN'], +}; +export const u64Typer: Typer = () => u64TyperReturn; +export const u256Typer: Typer = u64Typer; + +const boolTyperReturn = { + input: 'boolean', + output: 'boolean', +}; +export const boolTyper: Typer = () => boolTyperReturn; + +const stringTyperReturn: TyperReturn = { + input: 'string', + output: 'string', +}; +export const stringTyper: Typer = () => stringTyperReturn; +export const b256Typer: Typer = stringTyper; +export const b512Typer: Typer = stringTyper; + +const evmAddressTyperReturn: TyperReturn = { + input: 'EvmAddress', + output: 'EvmAddress', + fuelsTypeImports: ['EvmAddress'], +}; +export const evmAddressTyper: Typer = () => evmAddressTyperReturn; + +const bytesTyperReturn: TyperReturn = { + input: 'Bytes', + output: 'Bytes', + fuelsTypeImports: ['Bytes'], +}; +export const bytesTyper: Typer = () => bytesTyperReturn; + +const strTyperReturn: TyperReturn = { + input: 'StrSlice', + output: 'StrSlice', + fuelsTypeImports: ['StrSlice'], +}; +export const strTyper: Typer = () => strTyperReturn; + +const rawSliceTyperReturn: TyperReturn = { + input: 'RawSlice', + output: 'RawSlice', + fuelsTypeImports: ['RawSlice'], +}; +export const rawSliceTyper = () => rawSliceTyperReturn; + +const stdStringTyperReturn: TyperReturn = { + input: 'StdString', + output: 'StdString', + fuelsTypeImports: ['StdString'], +}; +export const stdStringTyper: Typer = () => stdStringTyperReturn; + +const voidTyperReturn: TyperReturn = { input: 'undefined', output: 'void' }; +export const voidTyper: Typer = () => voidTyperReturn; + +export const genericTyper: Typer = ({ abiType }) => { + // extracts the `T` part from `generic T` + const typeName = GENERIC_REGEX.exec(abiType.swayType)?.[1] as string; + return { + input: typeName, + output: typeName, + }; +}; diff --git a/packages/abi/src/gen/renderers/ts/typers/struct.ts b/packages/abi/src/gen/renderers/ts/typers/struct.ts new file mode 100644 index 00000000000..fbbcc5942fa --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/typers/struct.ts @@ -0,0 +1,88 @@ +import { ENUM_REGEX, STRUCT_REGEX } from '../../../../matchers/sway-type-matchers'; +import type { AbiMetadataType, AbiTypeArgument } from '../../../../parser'; + +import { flattenImports } from './helpers'; +import type { TyperReturn, Typer, GlobalTyper, TyperAbiType } from './types'; +import { mapComponents } from './utils'; + +function mapGenericTypeParameters( + typeArgs: AbiTypeArgument[] | AbiMetadataType['typeParameters'], + typer: GlobalTyper +): TyperReturn { + if (!typeArgs) { + return { + input: '', + output: '', + }; + } + const mapped = typeArgs.map((ta) => typer({ abiType: ta, asReference: true })); + const { fuelsTypeImports, commonTypeImports } = flattenImports(mapped); + + const input = mapped.map((r) => r.input).join(', '); + const output = mapped.map((r) => r.output).join(', '); + return { + fuelsTypeImports, + commonTypeImports, + input: `<${input}>`, + output: `<${output}>`, + }; +} + +function getTypeNames(abiType: TyperAbiType) { + const typeName = + STRUCT_REGEX.exec(abiType.swayType)?.[2] ?? ENUM_REGEX.exec(abiType.swayType)?.[2]; + return { + inputName: `${typeName}Input`, + outputName: `${typeName}Output`, + }; +} + +function mapStructAsReference(abiType: TyperAbiType, typer: GlobalTyper): TyperReturn { + const { inputName, outputName } = getTypeNames(abiType); + + const typeArgs = mapGenericTypeParameters( + 'metadata' in abiType + ? abiType.metadata?.typeArguments + : (abiType as AbiMetadataType).typeParameters, + typer + ); + + return { + ...typeArgs, + input: `${inputName}${typeArgs.input}`, + output: `${outputName}${typeArgs.output}`, + }; +} + +export const structTyper: Typer = ({ abiType, asReference }, typer) => { + if ('metadata' in abiType || asReference) { + return mapStructAsReference(abiType, typer); + } + + const { inputName, outputName } = getTypeNames(abiType); + + const typeParameters = mapGenericTypeParameters( + (abiType as AbiMetadataType).typeParameters, + typer + ); + const content = mapComponents({ parent: abiType, includeComponentNames: true, typer }); + + const inputType = `${inputName}${typeParameters.input}`; + const outputType = `${outputName}${typeParameters.output}`; + + const input = `${inputType} = ${content.input}`; + let output = ''; + if (content.input === content.output) { + output = `${outputType} = ${inputType}`; + } else { + output = `${outputType} = ${content.output}`; + } + + return { + input, + output, + commonTypeImports: content.commonTypeImports, + fuelsTypeImports: content.fuelsTypeImports, + tsType: 'type', + }; +}; diff --git a/packages/abi/src/gen/renderers/ts/typers/typer-matcher.ts b/packages/abi/src/gen/renderers/ts/typers/typer-matcher.ts new file mode 100644 index 00000000000..03da529b250 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/typers/typer-matcher.ts @@ -0,0 +1,51 @@ +import { createMatcher } from '../../../../matchers/sway-type-matchers'; + +import { optionTyper, enumTyper, resultTyper } from './enums'; +import { tupleTyper, arrayTyper, vectorTyper } from './iterators'; +import { + boolTyper, + u8Typer, + u16Typer, + u32Typer, + u64Typer, + u256Typer, + b256Typer, + stringTyper, + evmAddressTyper, + genericTyper, + b512Typer, + bytesTyper, + rawSliceTyper, + stdStringTyper, + strTyper, + voidTyper, +} from './simple'; +import { structTyper } from './struct'; +import type { Typer } from './types'; + +export const typerMatcher = createMatcher({ + bool: boolTyper, + u8: u8Typer, + u16: u16Typer, + u32: u32Typer, + u64: u64Typer, + u256: u256Typer, + b256: b256Typer, + b512: b512Typer, + tuple: tupleTyper, + array: arrayTyper, + struct: structTyper, + generic: genericTyper, + string: stringTyper, + vector: vectorTyper, + option: optionTyper, + bytes: bytesTyper, + str: strTyper, + rawUntypedSlice: rawSliceTyper, + stdString: stdStringTyper, + enum: enumTyper, + result: resultTyper, + void: voidTyper, + assetId: structTyper, + evmAddress: evmAddressTyper, +}); diff --git a/packages/abi/src/gen/renderers/ts/typers/types.ts b/packages/abi/src/gen/renderers/ts/typers/types.ts new file mode 100644 index 00000000000..e31a4c8f5e9 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/typers/types.ts @@ -0,0 +1,20 @@ +import type { AbiConcreteType, AbiTypeComponent, AbiMetadataType } from '../../../../parser'; + +export interface TyperReturn { + input: string; + output: string; + fuelsTypeImports?: string[]; + commonTypeImports?: string[]; + tsType?: 'enum' | 'type'; +} + +export type TyperAbiType = AbiConcreteType | AbiMetadataType | AbiTypeComponent['type']; + +export type TyperParams = { + abiType: TyperAbiType; + asReference?: boolean; +}; + +export type GlobalTyper = (p: TyperParams) => TyperReturn; + +export type Typer = (params: TyperParams, typer: GlobalTyper) => TyperReturn; diff --git a/packages/abi/src/gen/renderers/ts/typers/utils.ts b/packages/abi/src/gen/renderers/ts/typers/utils.ts new file mode 100644 index 00000000000..9305850eb43 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/typers/utils.ts @@ -0,0 +1,81 @@ +import { assertUnreachable } from '@fuel-ts/utils'; + +import { ENUM_REGEX, TUPLE_REGEX } from '../../../../matchers/sway-type-matchers'; +import type { AbiTypeComponent } from '../../../../parser'; + +import { flattenImports } from './helpers'; +import type { TyperAbiType, GlobalTyper, TyperReturn } from './types'; + +function componentMapper( + c: AbiTypeComponent, + includeName: boolean, + generateTsType: GlobalTyper +): TyperReturn { + const mapped = generateTsType({ abiType: c.type, asReference: true }); + + if (!includeName) { + return mapped; + } + + return { + ...mapped, + input: `${c.name}: ${mapped.input}`, + output: `${c.name}: ${mapped.output}`, + }; +} + +function wrapStructContent(text: string, wrap: '{}' | '[]' | 'Enum'): string { + switch (wrap) { + case '{}': + return `{ ${text} }`; + case '[]': + return `[${text}]`; + case 'Enum': { + const wrappedAsObj = wrapStructContent(text, '{}'); + return `Enum<${wrappedAsObj}>`; + } + default: + return assertUnreachable(wrap); + } +} + +/** + * This function maps components for a given parent type + * which can be a tuple or struct (and enum). + */ +export function mapComponents(params: { + parent: TyperAbiType; + /** + * Component names are included for structs and enums, + * but they're not included for tuples (we ignore the `__tuple_element` name). + */ + includeComponentNames: boolean; + typer: GlobalTyper; +}) { + const { parent, includeComponentNames, typer } = params; + const components = parent.components as AbiTypeComponent[]; + const mapped = components.map((c) => componentMapper(c, includeComponentNames, typer)); + + // eslint-disable-next-line no-nested-ternary + const wrap = ENUM_REGEX.test(parent.swayType) + ? 'Enum' + : TUPLE_REGEX.test(parent.swayType) + ? '[]' + : '{}'; + + const input = wrapStructContent(mapped.map((m) => m.input).join(', '), wrap); + const output = wrapStructContent(mapped.map((m) => m.output).join(', '), wrap); + + const { fuelsTypeImports, commonTypeImports } = flattenImports(mapped); + + if (wrap === 'Enum') { + commonTypeImports.push('Enum'); + } + + return { + input, + output, + fuelsTypeImports, + commonTypeImports, + }; +} diff --git a/packages/abi/src/gen/renderers/types.ts b/packages/abi/src/gen/renderers/types.ts new file mode 100644 index 00000000000..5d18ccaa6e9 --- /dev/null +++ b/packages/abi/src/gen/renderers/types.ts @@ -0,0 +1,9 @@ +import type { BinaryVersions } from '@fuel-ts/versions'; + +import type { AbiGenResult, ProgramDetails } from '../abi-gen-types'; + +export type Renderer = (details: ProgramDetails[], versions: BinaryVersions) => AbiGenResult[]; + +export type TsAbiGenResult = AbiGenResult & { + exportInIndexFile?: string[]; +}; diff --git a/packages/abi/src/index.ts b/packages/abi/src/index.ts new file mode 100644 index 00000000000..463cc711a6c --- /dev/null +++ b/packages/abi/src/index.ts @@ -0,0 +1,3 @@ +export * from './coder'; +export * from './gen'; +export * from './parser'; diff --git a/packages/abi/src/matchers/sway-type-matchers.test.ts b/packages/abi/src/matchers/sway-type-matchers.test.ts new file mode 100644 index 00000000000..ea6f8bfa77a --- /dev/null +++ b/packages/abi/src/matchers/sway-type-matchers.test.ts @@ -0,0 +1,271 @@ +import { FuelError } from '@fuel-ts/errors'; +import { expectToThrowFuelError } from '@fuel-ts/errors/test-utils'; + +import type { SwayType, swayTypeMatchers } from './sway-type-matchers'; +import { createMatcher } from './sway-type-matchers'; + +const testMappings: Record = { + string: 'string-matched', + void: 'void-matched', + bool: 'bool-matched', + u8: 'u8-matched', + u16: 'u16-matched', + u32: 'u32-matched', + u64: 'u64-matched', + u256: 'u256-matched', + b256: 'b256-matched', + generic: 'generic-matched', + stdString: 'stdString-matched', + option: 'option-matched', + result: 'result-matched', + enum: 'enum-matched', + struct: 'struct-matched', + b512: 'b512-matched', + bytes: 'bytes-matched', + vector: 'vector-matched', + tuple: 'tuple-matched', + array: 'array-matched', + assetId: 'assetId-matched', + evmAddress: 'evmAddress-matched', + rawUntypedSlice: 'rawUntypedSlice-matched', + str: 'str-matched', +}; + +const matcher = createMatcher(testMappings); + +async function verifyOtherMatchersDontMatch(key: keyof typeof testMappings, swayType: string) { + const testMappingsWithoutKey = Object.fromEntries( + Object.entries(testMappings).filter(([k]) => k !== key) + ); + + const verifier = createMatcher(testMappingsWithoutKey as Record); + + await expectToThrowFuelError( + () => verifier({ swayType }), + new FuelError( + FuelError.CODES.MATCHER_NOT_FOUND, + `Matcher not found for Sway type "${swayType}".` + ) + ); +} + +/** + * @group node + * @group browser + */ +describe('sway type matchers', () => { + test('void', async () => { + const key = 'void'; + const swayType = '()'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('bool', async () => { + const key = 'bool'; + const swayType = 'bool'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('u8', async () => { + const key = 'u8'; + const swayType = 'u8'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('u16', async () => { + const key = 'u16'; + const swayType = 'u16'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('u32', async () => { + const key = 'u32'; + const swayType = 'u32'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('u64', async () => { + const key = 'u64'; + const swayType = 'u64'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('u256', async () => { + const key = 'u256'; + const swayType = 'u256'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('b256', async () => { + const key = 'b256'; + const swayType = 'b256'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('string', async () => { + const key = 'string'; + const swayType = 'str[5]'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('array', async () => { + const key = 'array'; + const swayType = '[_; 3]'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('tuple', async () => { + const key = 'tuple'; + const swayType = '(_, _, _)'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('struct', async () => { + const key = 'struct'; + const swayType = 'struct MyStruct'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('assetId', async () => { + const key = 'assetId'; + const swayType = 'struct std::asset_id::AssetId'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('b512', async () => { + const key = 'b512'; + const swayType = 'struct std::b512::B512'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('assetId', async () => { + const key = 'assetId'; + const swayType = 'struct std::asset_id::AssetId'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('bytes', async () => { + const key = 'bytes'; + const swayType = 'struct std::bytes::Bytes'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('stdString', async () => { + const key = 'stdString'; + const swayType = 'struct std::string::String'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('evmAddress', async () => { + const key = 'evmAddress'; + const swayType = 'struct std::vm::evm::evm_address::EvmAddress'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('vector', async () => { + const key = 'vector'; + const swayType = 'struct std::vec::Vec'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('enum', async () => { + const key = 'enum'; + const swayType = 'enum MyEnum'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('option', async () => { + const key = 'option'; + const swayType = 'enum std::option::Option'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('result', async () => { + const key = 'result'; + const swayType = 'enum std::result::Result'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('rawUntypedSlice', async () => { + const key = 'rawUntypedSlice'; + const swayType = 'raw untyped slice'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('generic', async () => { + const key = 'generic'; + const swayType = 'generic T'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('str', async () => { + const key = 'str'; + const swayType = 'str'; + + expect(matcher({ swayType })).toEqual(`${key}-matched`); + await verifyOtherMatchersDontMatch(key, swayType); + }); + + test('matcher without mapping for valid sway type throws', async () => { + const swayType = 'str'; + + // @ts-expect-error intentionally missing key for valid swayType + const matcherWithoutMappings = createMatcher({}); + + await expectToThrowFuelError( + () => matcherWithoutMappings({ swayType }), + new FuelError( + FuelError.CODES.MATCHER_NOT_FOUND, + `Matcher not found for Sway type "${swayType}".` + ) + ); + }); +}); diff --git a/packages/abi/src/matchers/sway-type-matchers.ts b/packages/abi/src/matchers/sway-type-matchers.ts new file mode 100644 index 00000000000..c48f10c3c4e --- /dev/null +++ b/packages/abi/src/matchers/sway-type-matchers.ts @@ -0,0 +1,124 @@ +import { FuelError } from '@fuel-ts/errors'; + +export type SwayType = + | 'void' + | 'bool' + | 'u8' + | 'u16' + | 'u32' + | 'u64' + | 'u256' + | 'b256' + | 'generic' + | 'string' + | 'str' + | 'stdString' + | 'option' + | 'result' + | 'enum' + | 'struct' + | 'b512' + | 'bytes' + | 'vector' + | 'tuple' + | 'array' + | 'assetId' + | 'evmAddress' + | 'rawUntypedSlice'; + +type Matcher = (type: string) => boolean; + +const voidMatcher: Matcher = (type) => type === '()'; +const bool: Matcher = (type) => type === 'bool'; +const u8: Matcher = (type) => type === 'u8'; +const u16: Matcher = (type) => type === 'u16'; +const u32: Matcher = (type) => type === 'u32'; +const u64: Matcher = (type) => type === 'u64'; +const u256: Matcher = (type) => type === 'u256'; +const b256: Matcher = (type) => type === 'b256'; + +export const GENERIC_REGEX = /^generic ([^\s]+)$/m; +const generic: Matcher = (type) => GENERIC_REGEX.test(type); + +export const STRING_REGEX = /^str\[(?[0-9]+)\]/; +const string: Matcher = (type) => STRING_REGEX.test(type); + +const str: Matcher = (type) => type === 'str'; + +export const TUPLE_REGEX = /^\((?.+)\)$/m; +const tuple: Matcher = (type) => TUPLE_REGEX.test(type); + +export const ARRAY_REGEX = /^\[(?[\w\s\\[\]]+);\s*(?[0-9]+)\]/; +const array: Matcher = (type) => ARRAY_REGEX.test(type); + +export const STRUCT_REGEX = /^struct (.+::)?(?.+)$/m; +const STRUCT_STD_REGEX = + /^struct std::.*(AssetId|B512|Vec|RawVec|EvmAddress|Bytes|String|RawBytes)$/m; +const struct: Matcher = (type) => STRUCT_REGEX.test(type) && !STRUCT_STD_REGEX.test(type); +const assetId: Matcher = (type) => type === 'struct std::asset_id::AssetId'; +const b512: Matcher = (type) => type === 'struct std::b512::B512'; +const bytes: Matcher = (type) => type === 'struct std::bytes::Bytes'; +const evmAddress: Matcher = (type) => type === 'struct std::vm::evm::evm_address::EvmAddress'; +const stdString: Matcher = (type) => type === 'struct std::string::String'; +const vector: Matcher = (type) => type === 'struct std::vec::Vec'; + +const option: Matcher = (type) => type === 'enum std::option::Option'; +const result: Matcher = (type) => type === 'enum std::result::Result'; + +export const ENUM_REGEX = /^enum (.+::)?(?.+)$/m; +const enumMatcher: Matcher = (type) => !option(type) && !result(type) && ENUM_REGEX.test(type); + +const rawUntypedSlice: Matcher = (type) => type === 'raw untyped slice'; + +export const swayTypeMatchers: Record = { + void: voidMatcher, + generic, + bool, + u8, + u16, + u32, + u64, + u256, + b256, + str, + + string, + tuple, + array, + + struct, + assetId, + b512, + bytes, + evmAddress, + stdString, + vector, + + enum: enumMatcher, + option, + result, + + rawUntypedSlice, +}; + +const swayTypeMatcherEntries = Object.entries(swayTypeMatchers); + +export function createMatcher(mappings: Record) { + return (opts: { swayType: string }): T => { + const { swayType } = opts; + + for (const [key, matcher] of swayTypeMatcherEntries) { + if (matcher(swayType)) { + if (key in mappings) { + return mappings[key as SwayType]; + } + break; + } + } + + throw new FuelError( + FuelError.CODES.MATCHER_NOT_FOUND, + `Matcher not found for Sway type "${swayType}".` + ); + }; +} diff --git a/packages/abi/src/parser/abi-parser.ts b/packages/abi/src/parser/abi-parser.ts new file mode 100644 index 00000000000..31d230ce3cb --- /dev/null +++ b/packages/abi/src/parser/abi-parser.ts @@ -0,0 +1,44 @@ +import { FuelError } from '@fuel-ts/errors'; + +import type { Abi } from './abi'; +import type { AbiSpecificationV1 } from './specifications'; +import { AbiParserV1 } from './specifications'; + +/** + * A typed ABI object or a stringified json of a Sway program's ABI + */ +export type AbiSpecification = AbiSpecificationV1; + +export class AbiParser { + /** + * ABI specifications transpilers + */ + private static specifications = { + '1': AbiParserV1.parse, + } as const; + + /** + * Parses an ABI in JSON format. + * + * @param abi - a JSON ABI of a Sway program + * @returns an public interface for the Abi + */ + static parse(abi: AbiSpecification): Abi { + if (typeof abi.specVersion !== 'string') { + throw new FuelError( + FuelError.CODES.ABI_SPECIFICATION_INVALID, + 'Invalid ABI: the specification version is not a string.' + ); + } + + const parse = AbiParser.specifications[abi.specVersion]; + if (!parse) { + throw new FuelError( + FuelError.CODES.ABI_SPECIFICATION_INVALID, + `Invalid ABI: Unsupported ABI specification version ("${abi.specVersion}").` + ); + } + + return parse(abi); + } +} diff --git a/packages/abi/src/parser/abi.ts b/packages/abi/src/parser/abi.ts new file mode 100644 index 00000000000..345851ec354 --- /dev/null +++ b/packages/abi/src/parser/abi.ts @@ -0,0 +1,142 @@ +/** + * This interface serves as a representation of the ABI format outputted by `forc build` + * that won't be changing with the introduction of new abi specifications in Sway. + * Its purpose is to provide a stable interface for users to work with, + * which won't be affected by changing ABI specification versions. + */ +export interface Abi { + encodingVersion: string; + programType: 'contract' | 'predicate' | 'script' | 'library'; + /** + * Metadata types describe the structure of the types used in the `concreteTypes` field. + * One metadata type can be referenced multiple times if it is used in multiple concrete types. + */ + metadataTypes: AbiMetadataType[]; + /** + * Concrete types are types that are used in: + * function inputs/outputs, configurables, logged types, or message types. + * + * Their structure is fully known and they do not contain any unresolved generic parameters. + */ + concreteTypes: AbiConcreteType[]; + functions: AbiFunction[]; + loggedTypes: AbiLoggedType[]; + messageTypes: AbiMessageType[]; + configurables: AbiConfigurable[]; +} + +export interface AbiConcreteType { + swayType: string; + concreteTypeId: string; + /** + * The components field is populated when the type is any non-primitive type. + * That includes structs, enums, arrays, and tuples. + */ + components?: AbiTypeComponent[]; + /** + * A concrete type can be an implementation of a metadata type, + * in which case the `metadata` field is populated. + * If the underlying metadata type has type parameters (is generic), + * the `typeArguments` field corresponds to those type parameters. + */ + metadata?: { + metadataTypeId: number; + /** + * Type arguments used to resolve the type parameters in the metadata type. + * They are ordered in the same way as the type parameters in the metadata type. + */ + typeArguments?: AbiConcreteType[]; + }; +} + +export interface AbiMetadataType { + swayType: string; + metadataTypeId: number; + /** + * The components field is populated when the type is any non-primitive type. + * That includes structs, enums, arrays, and tuples. + */ + components?: AbiTypeComponent[]; + /** + * The existence of type parameters indicates that the metadata type is generic. + */ + typeParameters?: AbiMetadataType[]; +} + +export interface AbiTypeComponent { + name: string; + type: AbiConcreteType | AbiAppliedMetadataType; +} + +/** + * AbiAppliedMetadataType point to a metadata type but aren't the same as metadata types, + * as the metadata type describes the structure of the type, + * whereas the component is an actual implementation of that type. + */ +export interface AbiAppliedMetadataType { + swayType: string; + components?: AbiTypeComponent[]; + metadata: { + metadataTypeId: number; + typeArguments?: AbiTypeArgument[]; + }; +} + +export type AbiTypeArgument = AbiConcreteType | AbiAppliedMetadataType; + +export interface AbiFunctionInput { + name: string; + type: AbiConcreteType; +} + +export interface AbiFunction { + name: string; + inputs: AbiFunctionInput[]; + output: AbiConcreteType; + attributes?: readonly AbiFunctionAttribute[]; +} + +export interface AbiLoggedType { + logId: string; + type: AbiConcreteType; +} + +export interface AbiMessageType { + messageId: string; + type: AbiConcreteType; +} + +export interface AbiConfigurable { + name: string; + offset: number; + type: AbiConcreteType; +} + +export type AbiFunctionAttribute = + | StorageAttr + | PayableAttr + | TestAttr + | InlineAttr + | DocCommentAttr; + +export interface PayableAttr { + readonly name: 'payable'; +} + +export interface StorageAttr { + readonly name: 'storage'; + readonly arguments: readonly ('read' | 'write')[]; +} + +export interface TestAttr { + readonly name: 'test'; +} +export interface InlineAttr { + readonly name: 'inline'; + readonly arguments: 'never' | 'always'; +} + +export interface DocCommentAttr { + readonly name: 'doc-comment'; + readonly arguments: readonly string[]; +} diff --git a/packages/abi/src/parser/index.ts b/packages/abi/src/parser/index.ts new file mode 100644 index 00000000000..053e0c0a003 --- /dev/null +++ b/packages/abi/src/parser/index.ts @@ -0,0 +1,3 @@ +export { AbiParser, type AbiSpecification } from './abi-parser'; +export * from './abi'; +export * from './specifications/v1/specification'; diff --git a/packages/abi/src/parser/specifications/index.ts b/packages/abi/src/parser/specifications/index.ts new file mode 100644 index 00000000000..788ae99a778 --- /dev/null +++ b/packages/abi/src/parser/specifications/index.ts @@ -0,0 +1,2 @@ +export { AbiParserV1 } from './v1/parser'; +export * from './v1/specification'; diff --git a/packages/abi/src/parser/specifications/v1/abi-type-mappers.ts b/packages/abi/src/parser/specifications/v1/abi-type-mappers.ts new file mode 100644 index 00000000000..5dad5545b11 --- /dev/null +++ b/packages/abi/src/parser/specifications/v1/abi-type-mappers.ts @@ -0,0 +1,94 @@ +/* eslint-disable @typescript-eslint/no-use-before-define */ +import type { + AbiConcreteType, + AbiMetadataType, + AbiTypeArgument, + AbiTypeComponent, +} from '../../abi'; + +import type { ResolvableComponent, ResolvableType } from './resolvable-type'; +import type { ResolvedType } from './resolved-type'; + +function mapMetadata(type: ResolvableType | ResolvedType) { + const result: AbiTypeComponent['type']['metadata'] = { + metadataTypeId: type.metadataType?.metadataTypeId as number, + }; + + if (type.typeParamsArgsMap && type.metadataType?.typeParameters?.length) { + result.typeArguments = [...type.typeParamsArgsMap.values()].map((rt) => toTypeArgument(rt)); + } + + return result; +} + +function isResolvedConcreteType( + type: ResolvableType | ResolvedType +): type is ResolvedType & { typeId: string } { + const isResolvedType = 'typeId' in type; + + return isResolvedType && typeof type.typeId === 'string'; +} + +function mapComponentType(component: ResolvableComponent): AbiTypeComponent { + const { name, type } = component; + + let result: AbiTypeComponent['type']; + + if (isResolvedConcreteType(type)) { + result = { + swayType: type.swayType, + concreteTypeId: type.typeId, + }; + if (type.metadataType) { + result.metadata = mapMetadata(type) as AbiConcreteType['metadata']; + } + } else { + result = { + swayType: type.swayType, + metadata: mapMetadata(type), + }; + } + + if (type.components) { + result.components = type.components.map(mapComponentType); + } + + return { name, type: result }; +} + +function toTypeArgument(type: ResolvableType | ResolvedType): AbiTypeArgument { + // type args and components follow the same mapping logic + return mapComponentType({ name: '', type }).type; +} + +export function toAbiType(t: ResolvableType | ResolvedType): AbiConcreteType | AbiMetadataType { + let result: AbiConcreteType | AbiMetadataType; + + if (isResolvedConcreteType(t)) { + result = { + concreteTypeId: t.typeId, + swayType: t.swayType, + }; + + if (t.metadataType) { + result.metadata = mapMetadata(t) as AbiConcreteType['metadata']; + } + } else { + result = { + swayType: t.swayType, + metadataTypeId: t.metadataType?.metadataTypeId as number, + }; + + if (t.typeParamsArgsMap && t.metadataType?.typeParameters?.length) { + result.typeParameters = [...t.typeParamsArgsMap.values()].map( + (rt) => toAbiType(rt) as AbiMetadataType + ); + } + } + + if (t.components) { + result.components = t.components.map(mapComponentType); + } + + return result; +} diff --git a/packages/abi/src/parser/specifications/v1/cleanup-abi.ts b/packages/abi/src/parser/specifications/v1/cleanup-abi.ts new file mode 100644 index 00000000000..1d517f43707 --- /dev/null +++ b/packages/abi/src/parser/specifications/v1/cleanup-abi.ts @@ -0,0 +1,52 @@ +import type { AbiSpecificationV1 } from './specification'; + +/** + * Both RawVec and RawBytes are private sway std library types + * that can never be used directly in sway, + * and the only reason they're in the abi is because they're used internally by Vec and Bytes + * and not ignored when forc builds the outputs. + * We can safely ignore them and simplify the `Vec` and `Bytes` types. + * This makes it simpler for us to consume these types in typegen and coder, + * as well as for others consuming the parsed abi, + * who now don't have to worry about this unnecessary complexity. + * `raw untyped ptr` is also in the abi only because of RawVec and RawBytes, + * so we ignore that as well. + */ +const IGNORED_TYPES = ['struct std::vec::RawVec', 'struct std::bytes::RawBytes', 'raw untyped ptr']; + +export function cleanupAbi(abi: AbiSpecificationV1): AbiSpecificationV1 { + return { + ...abi, + metadataTypes: abi.metadataTypes + .filter((metadataType) => !IGNORED_TYPES.includes(metadataType.type)) + .map((metadataType) => { + switch (metadataType.type) { + /** + * Vectors consist of multiple components, + * but we only care about the `buf`'s first type argument + * which defines the type of the vector data. + * Everything else is being ignored, + * as it's then easier to reason about the vector. + */ + case 'struct std::vec::Vec': + return { + ...metadataType, + components: metadataType.components?.[0].typeArguments, + }; + + /** + * We treat Bytes as a special type + * that is handled only based on its type name ('struct std::bytes::Bytes') + * and not its components. + */ + case 'struct std::bytes::Bytes': + return { + type: metadataType.type, + metadataTypeId: metadataType.metadataTypeId, + }; + default: + return metadataType; + } + }), + }; +} diff --git a/packages/abi/src/parser/specifications/v1/map-attribute.ts b/packages/abi/src/parser/specifications/v1/map-attribute.ts new file mode 100644 index 00000000000..b14ea2e83c0 --- /dev/null +++ b/packages/abi/src/parser/specifications/v1/map-attribute.ts @@ -0,0 +1,23 @@ +import { assertUnreachable } from '@fuel-ts/utils'; + +import type { AbiFunctionAttribute } from '../../abi'; + +import type { AbiFunctionAttributeV1 } from './specification'; + +export const mapAttribute = (attribute: AbiFunctionAttributeV1): AbiFunctionAttribute => { + const { name, arguments: args } = attribute; + + switch (name) { + case 'inline': + return { name, arguments: args[0] }; + case 'storage': + return { name: 'storage', arguments: args }; + case 'doc-comment': + return { name, arguments: args }; + case 'payable': + case 'test': + return { name }; + default: + return assertUnreachable(attribute); + } +}; diff --git a/packages/abi/src/parser/specifications/v1/parser.ts b/packages/abi/src/parser/specifications/v1/parser.ts new file mode 100644 index 00000000000..0048ea802f3 --- /dev/null +++ b/packages/abi/src/parser/specifications/v1/parser.ts @@ -0,0 +1,75 @@ +import type { Abi, AbiConcreteType, AbiMetadataType } from '../../abi'; + +import { toAbiType } from './abi-type-mappers'; +import { cleanupAbi } from './cleanup-abi'; +import { mapAttribute } from './map-attribute'; +import { ResolvableType } from './resolvable-type'; +import { ResolvedType } from './resolved-type'; +import type { + AbiConfigurableV1, + AbiFunctionInputV1, + AbiFunctionV1, + AbiLoggedTypeV1, + AbiMessageTypeV1, + AbiSpecificationV1, +} from './specification'; + +export class AbiParserV1 { + static parse(abi: AbiSpecificationV1): Abi { + const cleanAbi = cleanupAbi(abi); + + const abiTypeMaps = { + metadataTypes: new Map(cleanAbi.metadataTypes.map((type) => [type.metadataTypeId, type])), + concreteTypes: new Map(cleanAbi.concreteTypes.map((type) => [type.concreteTypeId, type])), + }; + + const resolvableTypes = cleanAbi.metadataTypes.map( + (metadataType) => new ResolvableType(abiTypeMaps, metadataType.metadataTypeId, undefined) + ); + + const concreteTypes = cleanAbi.concreteTypes.map((concreteType) => { + const resolvableType = resolvableTypes.find( + (resolvable) => resolvable.metadataTypeId === concreteType.metadataTypeId + ); + + const resolvedType = resolvableType + ? resolvableType.resolve(concreteType) + : new ResolvedType({ swayType: concreteType.type, typeId: concreteType.concreteTypeId }); + + return toAbiType(resolvedType) as AbiConcreteType; + }); + + const getType = (concreteTypeId: string) => + // this will always be defined because it's in the context of the same ABI + concreteTypes.find((abiType) => abiType.concreteTypeId === concreteTypeId) as AbiConcreteType; + + return { + metadataTypes: resolvableTypes.map((rt) => toAbiType(rt) as AbiMetadataType), + concreteTypes, + encodingVersion: cleanAbi.encodingVersion, + programType: cleanAbi.programType as Abi['programType'], + functions: cleanAbi.functions.map((fn: AbiFunctionV1) => ({ + attributes: fn.attributes?.map(mapAttribute) ?? undefined, + name: fn.name, + output: getType(fn.output), + inputs: fn.inputs.map((input: AbiFunctionInputV1) => ({ + name: input.name, + type: getType(input.concreteTypeId), + })), + })), + loggedTypes: cleanAbi.loggedTypes.map((loggedType: AbiLoggedTypeV1) => ({ + logId: loggedType.logId, + type: getType(loggedType.concreteTypeId), + })), + messageTypes: cleanAbi.messagesTypes.map((messageType: AbiMessageTypeV1) => ({ + messageId: messageType.messageId, + type: getType(messageType.concreteTypeId), + })), + configurables: cleanAbi.configurables.map((configurable: AbiConfigurableV1) => ({ + name: configurable.name, + offset: configurable.offset, + type: getType(configurable.concreteTypeId), + })), + }; + } +} diff --git a/packages/abi/src/parser/specifications/v1/resolvable-type.ts b/packages/abi/src/parser/specifications/v1/resolvable-type.ts new file mode 100644 index 00000000000..04f297a9bf0 --- /dev/null +++ b/packages/abi/src/parser/specifications/v1/resolvable-type.ts @@ -0,0 +1,373 @@ +import { FuelError } from '@fuel-ts/errors'; + +import { swayTypeMatchers } from '../../../matchers/sway-type-matchers'; + +import type { ResolvedComponent } from './resolved-type'; +import { ResolvedType } from './resolved-type'; +import type { + AbiComponentV1, + AbiConcreteTypeV1, + AbiMetadataTypeV1, + AbiTypeArgumentV1, +} from './specification'; + +export interface ResolvableComponent { + name: string; + type: ResolvableType | ResolvedType; +} + +export class ResolvableType { + metadataType: AbiMetadataTypeV1; + swayType: string; + components: ResolvableComponent[] | undefined; + + constructor( + private abiTypeMaps: { + metadataTypes: Map; + concreteTypes: Map; + }, + public metadataTypeId: number, + public typeParamsArgsMap: Map | undefined + ) { + this.metadataType = this.findMetadataType(metadataTypeId); + this.swayType = this.metadataType.type; + this.typeParamsArgsMap ??= + this.metadataType.typeParameters && + new Map( + this.metadataType.typeParameters.map((typeParameter) => [ + typeParameter, + new ResolvableType(this.abiTypeMaps, typeParameter, undefined), + ]) + ); + + this.components = this.metadataType.components?.map((c) => + this.createResolvableComponent(this, c) + ); + } + + /** + * Find a metadata type by its ID. + * @param metadataTypeId - The ID of the metadata type to find. + * @returns The metadata type. + * + * @throws If the metadata type can not be found in the ABI. + */ + private findMetadataType(metadataTypeId: number): AbiMetadataTypeV1 { + const metadataType = this.abiTypeMaps.metadataTypes.get(metadataTypeId); + + if (!metadataType) { + throw new FuelError( + FuelError.CODES.TYPE_NOT_FOUND, + `Metadata type with id ${metadataTypeId} not found` + ); + } + return metadataType; + } + + /** + * Find a concrete type by its ID. + * @param concreteTypeId - The ID of the concrete type to find. + * @returns The concrete type. + * + * @throws If the concrete type can not be found in the ABI. + */ + private findConcreteType(concreteTypeId: string): AbiConcreteTypeV1 { + const concreteType = this.abiTypeMaps.concreteTypes.get(concreteTypeId); + + if (!concreteType) { + throw new FuelError( + FuelError.CODES.TYPE_NOT_FOUND, + `Concrete type with id ${concreteTypeId} not found` + ); + } + return concreteType; + } + + private static mapTypeParametersAndArgs( + metadataType: AbiMetadataTypeV1, + args: (ResolvableType | ResolvedType)[] + ): Map | undefined { + return ( + metadataType.typeParameters && + new Map( + metadataType.typeParameters.map((typeParameter, idx) => [typeParameter, args[idx]]) + ) + ); + } + + private createResolvableComponent( + parent: ResolvableType, + { typeId, typeArguments, name }: AbiComponentV1 | AbiTypeArgumentV1 + ): ResolvableComponent { + const isConcreteType = typeof typeId === 'string'; + + if (isConcreteType) { + const concreteType = this.findConcreteType(typeId); + return { + name, + type: this.resolveConcreteType(concreteType), + }; + } + + const metadataType = this.findMetadataType(typeId); + return { + name, + type: this.handleMetadataType(parent, metadataType, typeArguments), + }; + } + + /** + * Concrete types are *resolved* because everything is known about them. + */ + private resolveConcreteType(type: AbiConcreteTypeV1): ResolvedType { + /** + * If the concrete type doesn't have a linked metadata type, we can resolve it immediately. + * This is the case for e.g. u8, u16, ... + */ + if (type.metadataTypeId === undefined) { + return new ResolvedType({ + swayType: type.type, + typeId: type.concreteTypeId, + }); + } + /** + * The concrete type has an associated metadata type. + * If it's not generic (no type arguments), + * we'll create a ResolvableType with that metadata type, and then resolve it immediately. + * This would be the case for e.g. non-generic structs and enums. + */ + if (!type.typeArguments) { + return new ResolvableType(this.abiTypeMaps, type.metadataTypeId, undefined).resolveInternal( + type.concreteTypeId, + undefined + ); + } + + /** + * The concrete type's underlying metadata type is generic. + * We must resolve all its type parameters with the provided type arguments of the concrete type, + * and then resolve the metadata type itself. + */ + const metadataType = this.findMetadataType(type.metadataTypeId); + + const concreteTypeArgs = type.typeArguments.map((typeArgument) => { + const concreteTypeArg = this.findConcreteType(typeArgument); + return this.resolveConcreteType(concreteTypeArg); + }); + + return new ResolvableType( + this.abiTypeMaps, + type.metadataTypeId, + ResolvableType.mapTypeParametersAndArgs(metadataType, concreteTypeArgs) + ).resolveInternal(type.concreteTypeId, undefined); + } + + /** + * Metadata types are *handled* and not *resolved* because they might be generic, + * in which case they cannot be resolved. + * If they're not generic, they can be immediately resolved. + */ + private handleMetadataType( + parent: ResolvableType, + metadataType: AbiMetadataTypeV1, + typeArguments: AbiComponentV1['typeArguments'] + ): ResolvableType | ResolvedType { + /** + * If the type is generic, we can't resolve it and thus we create a `ResolvableType` from it. + * This propagates to the parent type, forcing it to be a `ResolvableType` as well, + * as it can't be resolved until this generic type is substituted with a type argument. + */ + if (swayTypeMatchers.generic(metadataType.type)) { + /** + * This search solves the case where an e.g. `generic T` is being substituted by `generic E`. + * This can happen when a generic type is nested in another generic type and they have differently-named type parameters. + * e.g. `GenericStruct` is nested in `Vec`: `struct MyStruct { a: Vec }` + * We check in the parent's typeParamsArgsMap if the metadata type we're solving for + * has been substituted with a different generic type, and then we use that generic type. + */ + const resolvableTypeParameter = parent.typeParamsArgsMap?.get(metadataType.metadataTypeId); + + return ( + resolvableTypeParameter ?? + new ResolvableType(this.abiTypeMaps, metadataType.metadataTypeId, undefined) + ); + } + + if (!metadataType.components) { + /** + * types like u8, u16 can make their way into metadata types + * if they aren't used _directly_ in a function-input/function-output/log/configurable/messageType + * These types are characterized by not having components and we can resolve them as-is + */ + return new ResolvableType( + this.abiTypeMaps, + metadataType.metadataTypeId, + undefined + ).resolveInternal(metadataType.metadataTypeId, undefined); + } + + const typeArgs = typeArguments?.map( + (typeArgument) => this.createResolvableComponent(parent, typeArgument).type + ); + + const resolvable = new ResolvableType( + this.abiTypeMaps, + metadataType.metadataTypeId, + !typeArgs?.length + ? undefined + : ResolvableType.mapTypeParametersAndArgs(metadataType, typeArgs) + ); + + /** + * If any component is unresolved, this means that the metadata type is generic. + * We can't resolve it yet, so we return the resolvable type. + * If all components are resolved, we can resolve the metadata type immediately. + */ + const isGeneric = resolvable.components?.some( + (component) => component.type instanceof ResolvableType + ); + + return isGeneric + ? resolvable + : resolvable.resolveInternal(metadataType.metadataTypeId, undefined); + } + + private resolveInternal( + typeId: string | number, + typeParamsArgsMap: Map | undefined + ): ResolvedType { + const resolvedType = new ResolvedType({ + swayType: this.swayType, + typeId, + metadataType: this.metadataType, + }); + + /** + * A type without components can be immediately resolved. + */ + if (!this.components) { + return resolvedType; + } + + /** + * Before resolving the components, + * we need to substitute the type parameters of the underlying metadata type + * with the type arguments of the concrete type, + * so that we can substitute the generic components with them later. + */ + const typeArgs = this.resolveTypeArgs(typeParamsArgsMap); + + const components: ResolvedComponent[] = this.components.map((component) => { + const { name, type } = component; + + if (type instanceof ResolvedType) { + return component as ResolvedComponent; + } + + /** + * Here the component's type is a `ResolvableType`. + * If the component is a generic type parameter itself, + * its corresponding type argument will be found in the typeArgs, + * which will be used to substitute the component with. + */ + const resolvedGenericType = typeArgs?.get(type.metadataTypeId); + + if (resolvedGenericType) { + return { + name, + type: resolvedGenericType, + }; + } + + return { + name, + /** + * The component is a `ResolvableType`, but it's not a generic type parameter itself. + * This means that one of its components (or component's components) + * is a generic type. + * We need to resolve that first before resolving the component. + * + * Note that we are passing in the original `typeParamsArgsMap` by default, + * which will be used to substitute the component's generic type parameters + * with the appropriate type arguments. + * + * The non-default case of passing `typeArgs` happens only for tuples/arrays + * which contain structs with implicit generics, + * e.g. `(bool, StructWithImplicitGenerics)` + */ + type: type.resolveInternal(type.metadataTypeId, typeParamsArgsMap ?? typeArgs), + }; + }); + + resolvedType.components = components; + resolvedType.typeParamsArgsMap = typeArgs; + + return resolvedType; + } + + private resolveTypeArgs( + typeParamsArgsMap: Map | undefined + ): Map | undefined { + /** + * This case only happens when the metadata type is *implicitly* generic. + * The type itself doesn't have any type parameters that should be resolved, + * but its components are still generic types. + * This happens in the following type: + * `struct StructWithImplicitGenerics { a: [E; 3], b: (E, F)}`. + */ + if (this.typeParamsArgsMap === undefined) { + return typeParamsArgsMap; + } + + const newMap = new Map(); + + /** + * We resolve the type parameters of the underlying metadata type + * with the type arguments of the concrete type. + */ + this.typeParamsArgsMap.forEach((arg, typeParameter) => { + /** + * Some type parameters can already be resolved + * e.g. `struct MyStruct { a: DoubleGeneric }` + * where the second type parameter of DoubleGeneric is already known. + */ + if (arg instanceof ResolvedType) { + newMap.set(typeParameter, arg); + return; + } + + /** + * The type parameter is either directly substituted with a type argument, + * or it's a metadata type which accepts the type argument, + * so that metadata type will be resolved and subsitute the type parameter. + */ + const resolved = + typeParamsArgsMap?.get(arg.metadataTypeId) ?? + arg.resolveInternal(arg.metadataTypeId, typeParamsArgsMap); + + newMap.set(arg.metadataTypeId, resolved); + }); + + return newMap; + } + + /** + * Resolves the instance of `ResolvableType` with the specific concrete type's data. + * @returns a `ResolvedType` in which all its components are resolved. + */ + public resolve(concreteType: AbiConcreteTypeV1): ResolvedType { + const concreteTypeArgs = concreteType.typeArguments?.map((typeArgument) => { + const concreteTypeArg = this.findConcreteType(typeArgument); + return this.resolveConcreteType(concreteTypeArg); + }); + + const typeParamsArgsMap = concreteTypeArgs + ? (ResolvableType.mapTypeParametersAndArgs(this.metadataType, concreteTypeArgs) as Map< + number, + ResolvedType + >) + : undefined; + + return this.resolveInternal(concreteType.concreteTypeId, typeParamsArgsMap); + } +} diff --git a/packages/abi/src/parser/specifications/v1/resolved-type.ts b/packages/abi/src/parser/specifications/v1/resolved-type.ts new file mode 100644 index 00000000000..6465d10f6d5 --- /dev/null +++ b/packages/abi/src/parser/specifications/v1/resolved-type.ts @@ -0,0 +1,28 @@ +import type { AbiMetadataTypeV1 } from './specification'; + +export interface ResolvedComponent { + name: string; + type: ResolvedType; +} + +export class ResolvedType { + public swayType: string; + public typeId: string | number; + public components: ResolvedComponent[] | undefined; + public typeParamsArgsMap: Map | undefined; + public metadataType: AbiMetadataTypeV1 | undefined; + + constructor(params: { + swayType: string; + typeId: string | number; + components?: ResolvedComponent[]; + typeParamsArgsMap?: Map; + metadataType?: AbiMetadataTypeV1; + }) { + this.swayType = params.swayType; + this.typeId = params.typeId; + this.components = params.components; + this.typeParamsArgsMap = params.typeParamsArgsMap; + this.metadataType = params.metadataType; + } +} diff --git a/packages/abi/src/parser/specifications/v1/specification.ts b/packages/abi/src/parser/specifications/v1/specification.ts new file mode 100644 index 00000000000..f360fbba8bb --- /dev/null +++ b/packages/abi/src/parser/specifications/v1/specification.ts @@ -0,0 +1,98 @@ +/** + * Types for Fuel JSON ABI Format specification v1, as defined on: + * https://github.com/FuelLabs/fuel-specs/blob/master/src/abi/json-abi-format.md + */ +export interface AbiSpecificationV1 { + readonly specVersion: '1'; + readonly encodingVersion: string; + readonly programType: string; + readonly concreteTypes: readonly AbiConcreteTypeV1[]; + readonly metadataTypes: readonly AbiMetadataTypeV1[]; + readonly functions: readonly AbiFunctionV1[]; + readonly loggedTypes: readonly AbiLoggedTypeV1[]; + readonly messagesTypes: readonly AbiMessageTypeV1[]; + readonly configurables: readonly AbiConfigurableV1[]; +} + +export interface AbiConcreteTypeV1 { + readonly type: string; + readonly concreteTypeId: string; + readonly metadataTypeId?: number; + readonly typeArguments?: readonly string[]; +} + +export interface AbiMetadataTypeV1 { + readonly type: string; + readonly metadataTypeId: number; + readonly components?: readonly AbiComponentV1[]; + readonly typeParameters?: readonly number[]; +} + +export interface AbiComponentV1 extends AbiTypeArgumentV1 {} + +export interface AbiTypeArgumentV1 { + readonly name: string; + readonly typeId: number | string; // the type metadata declaration ID or type concrete declaration hash based ID of the type of the component. + readonly typeArguments?: readonly AbiTypeArgumentV1[]; +} + +export interface AbiFunctionV1 { + readonly name: string; + readonly inputs: readonly AbiFunctionInputV1[]; + readonly output: string; + readonly attributes: readonly AbiFunctionAttributeV1[] | null; +} + +export interface AbiFunctionInputV1 { + readonly name: string; + readonly concreteTypeId: string; +} + +export interface AbiLoggedTypeV1 { + readonly logId: string; + // the _type concrete declaration_ hash based ID of the value being logged. + readonly concreteTypeId: string; +} + +export interface AbiMessageTypeV1 { + readonly messageId: string; + readonly concreteTypeId: string; +} + +export interface AbiConfigurableV1 { + readonly name: string; + readonly concreteTypeId: string; + readonly offset: number; +} + +export type AbiFunctionAttributeV1 = + | StorageAttrV1 + | PayableAttrV1 + | TestAttrV1 + | InlineAttrV1 + | DocCommentAttrV1; + +export interface PayableAttrV1 { + readonly name: 'payable'; + readonly arguments: readonly []; +} + +export interface StorageAttrV1 { + readonly name: 'storage'; + readonly arguments: readonly ('read' | 'write')[]; +} + +export interface TestAttrV1 { + readonly name: 'test'; + readonly arguments: readonly []; +} + +export interface InlineAttrV1 { + readonly name: 'inline'; + readonly arguments: readonly ['never'] | readonly ['always']; +} + +export interface DocCommentAttrV1 { + readonly name: 'doc-comment'; + readonly arguments: string[]; +} diff --git a/packages/abi/src/utils/evaluate-function-inputs-optionality.ts b/packages/abi/src/utils/evaluate-function-inputs-optionality.ts new file mode 100644 index 00000000000..280e64c917a --- /dev/null +++ b/packages/abi/src/utils/evaluate-function-inputs-optionality.ts @@ -0,0 +1,15 @@ +import { swayTypeMatchers } from '../matchers/sway-type-matchers'; +import type { AbiFunction, AbiFunctionInput } from '../parser'; + +export function evaluateFunctionInputsOptionality( + fn: AbiFunction +): (AbiFunctionInput & { isOptional: boolean })[] { + let isMandatory = false; + return fn.inputs.reduceRight<(AbiFunctionInput & { isOptional: boolean })[]>((result, input) => { + const isTypeMandatory = + !swayTypeMatchers.void(input.type.swayType) && !swayTypeMatchers.option(input.type.swayType); + + isMandatory = isMandatory || isTypeMandatory; + return [{ ...input, isOptional: !isMandatory }, ...result]; + }, []); +} diff --git a/packages/abi/tsconfig.dts.json b/packages/abi/tsconfig.dts.json new file mode 100644 index 00000000000..ccca2ac1f3e --- /dev/null +++ b/packages/abi/tsconfig.dts.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["src"], + "exclude": ["**/*.test.ts"] +} diff --git a/packages/abi/tsconfig.json b/packages/abi/tsconfig.json new file mode 100644 index 00000000000..b22c89a4b35 --- /dev/null +++ b/packages/abi/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "./dist" + }, + "include": ["src", "test"] +} diff --git a/packages/abi/tsdoc.json b/packages/abi/tsdoc.json new file mode 100644 index 00000000000..4514b072727 --- /dev/null +++ b/packages/abi/tsdoc.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", + "extends": ["../../tsdoc.base.json"] +} diff --git a/packages/abi/tsup.config.ts b/packages/abi/tsup.config.ts new file mode 100644 index 00000000000..48e24be8656 --- /dev/null +++ b/packages/abi/tsup.config.ts @@ -0,0 +1,11 @@ +import { indexBinAndCliConfig } from '@internal/tsup'; +import type { Options } from 'tsup'; + +const configs: Options = { + ...indexBinAndCliConfig, + loader: { + '.hbs': 'text', + }, +}; + +export default configs; diff --git a/packages/abi/typedoc.json b/packages/abi/typedoc.json new file mode 100644 index 00000000000..a8ec6b825f0 --- /dev/null +++ b/packages/abi/typedoc.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "extends": ["../../typedoc.base.json"], + "entryPoints": ["src/index.ts"], + "readme": "none" +} diff --git a/packages/abi/typegen.js b/packages/abi/typegen.js new file mode 100755 index 00000000000..ae13c3e8f43 --- /dev/null +++ b/packages/abi/typegen.js @@ -0,0 +1,2 @@ +#!/usr/bin/env node +require('./dist/bin.js'); diff --git a/packages/errors/src/error-codes.ts b/packages/errors/src/error-codes.ts index fdbec36d7cc..05295418479 100644 --- a/packages/errors/src/error-codes.ts +++ b/packages/errors/src/error-codes.ts @@ -13,6 +13,7 @@ export enum ErrorCode { TYPE_NOT_SUPPORTED = 'type-not-supported', INVALID_DECODE_VALUE = 'invalid-decode-value', JSON_ABI_ERROR = 'json-abi-error', + ABI_SPECIFICATION_INVALID = 'abi-specification-invalid', TYPE_ID_NOT_FOUND = 'type-id-not-found', BIN_FILE_NOT_FOUND = 'bin-file-not-found', CODER_NOT_FOUND = 'coder-not-found', @@ -23,6 +24,7 @@ export enum ErrorCode { CONFIG_FILE_NOT_FOUND = 'config-file-not-found', CONFIG_FILE_ALREADY_EXISTS = 'config-file-already-exists', WORKSPACE_NOT_DETECTED = 'workspace-not-detected', + MATCHER_NOT_FOUND = 'matcher-not-found', // address INVALID_ADDRESS = 'invalid-address', diff --git a/packages/fuel-gauge/package.json b/packages/fuel-gauge/package.json index 97986da0e89..b5932b0cec2 100644 --- a/packages/fuel-gauge/package.json +++ b/packages/fuel-gauge/package.json @@ -14,6 +14,7 @@ "fuels": "workspace:*" }, "devDependencies": { + "@fuel-ts/abi": "workspace:*", "@fuel-ts/account": "workspace:*", "@fuel-ts/errors": "workspace:*", "@fuel-ts/merkle": "workspace:*", diff --git a/packages/fuel-gauge/src/abi/abi-coder.test.ts b/packages/fuel-gauge/src/abi/abi-coder.test.ts index 5f7fe677b1a..08f6456d859 100644 --- a/packages/fuel-gauge/src/abi/abi-coder.test.ts +++ b/packages/fuel-gauge/src/abi/abi-coder.test.ts @@ -4,11 +4,8 @@ import { expectToThrowFuelError, launchTestNode } from 'fuels/test-utils'; import { AbiContractFactory } from '../../test/typegen'; import type { AbiContract } from '../../test/typegen'; -import { - EnumWithNativeInput, - EnumWithNativeOutput, - ExternalEnumInput, -} from '../../test/typegen/contracts/AbiContract'; +import type { Option, Result } from '../../test/typegen/common'; +import { EnumWithNative, ExternalEnum } from '../../test/typegen/contracts/AbiContractTypes'; import type { EnumWithBuiltinTypeInput, EnumWithBuiltinTypeOutput, @@ -32,8 +29,7 @@ import type { StructWithEnumArrayOutput, StructWithSingleOptionOutput, StructWithSingleOptionInput, -} from '../../test/typegen/contracts/AbiContract'; -import type { Option, Result, Vec } from '../../test/typegen/contracts/common'; +} from '../../test/typegen/contracts/AbiContractTypes'; import { U16_MAX, @@ -793,7 +789,7 @@ describe('AbiCoder', () => { describe('types_array_with_vector', () => { it('should encode/decode just fine', async () => { - const input = [[1, 2, 3]] as [Vec]; + const input = [[1, 2, 3]] as [BigNumberish[]]; const expected = [[3, 2, 1]]; const { waitForResult } = await contract.functions.types_array_with_vector(input).call(); @@ -1091,14 +1087,10 @@ describe('AbiCoder', () => { describe('types_struct_with_array_of_enums', () => { it.todo('should encode/decode just fine', async () => { const input: StructWithEnumArrayInput = { - a: [EnumWithNativeInput.Checked, EnumWithNativeInput.Checked, EnumWithNativeInput.Checked], + a: [EnumWithNative.Checked, EnumWithNative.Checked, EnumWithNative.Checked], }; const expected: StructWithEnumArrayOutput = { - a: [ - EnumWithNativeOutput.Pending, - EnumWithNativeOutput.Pending, - EnumWithNativeOutput.Pending, - ], + a: [EnumWithNative.Pending, EnumWithNative.Pending, EnumWithNative.Pending], }; const { waitForResult } = await contract.functions @@ -1470,8 +1462,8 @@ describe('AbiCoder', () => { */ describe('types_enum', () => { it('should encode/decode just fine', async () => { - const input = EnumWithNativeInput.Checked; - const expected = EnumWithNativeInput.Pending; + const input = EnumWithNative.Checked; + const expected = EnumWithNative.Pending; const { waitForResult } = await contract.functions.types_enum(input).call(); @@ -1579,8 +1571,8 @@ describe('AbiCoder', () => { describe('types_enum_external', () => { it('should encode/decode just fine', async () => { - const input = ExternalEnumInput.A; - const expected = ExternalEnumInput.B; + const input = ExternalEnum.A; + const expected = ExternalEnum.B; const { waitForResult } = await contract.functions.types_enum_external(input).call(); @@ -1607,7 +1599,7 @@ describe('AbiCoder', () => { describe('types_enum_with_structs', () => { it('should encode/decode just fine', async () => { - const input = { a: EnumWithNativeInput.Checked }; + const input = { a: EnumWithNative.Checked }; const expected = { b: { a: true, b: 10 } }; const { waitForResult } = await contract.functions.types_enum_with_structs(input).call(); @@ -1759,8 +1751,8 @@ describe('AbiCoder', () => { describe('types_vector_option', () => { it('should encode/decode just fine', async () => { - const input: Vec = [{ a: [1, 2, 3, 4, 5] }]; - const expected: Vec = [{ a: [5, 4, 3, 2, 1] }]; + const input: StructWithMultiOptionInput[] = [{ a: [1, 2, 3, 4, 5] }]; + const expected: StructWithMultiOptionOutput[] = [{ a: [5, 4, 3, 2, 1] }]; const { waitForResult } = await contract.functions.types_vector_option(input).call(); diff --git a/packages/fuel-gauge/src/abi/abi-gen.test.ts b/packages/fuel-gauge/src/abi/abi-gen.test.ts new file mode 100644 index 00000000000..e71c595953d --- /dev/null +++ b/packages/fuel-gauge/src/abi/abi-gen.test.ts @@ -0,0 +1,165 @@ +import { runTypegen } from '@fuel-ts/abi/cli'; +import { randomUUID } from 'crypto'; +import { cpSync, mkdirSync, readdirSync, readFileSync, rmdirSync, rmSync } from 'fs'; +import { FuelError } from 'fuels'; +import { expectToThrowFuelError } from 'fuels/test-utils'; +import { tmpdir } from 'os'; +import { join } from 'path'; + +import { AbiProjectsEnum, getAbiForcProject } from './utils'; + +function generateTmpDir(fromDir?: string) { + const dir = join(tmpdir(), 'fuels', randomUUID()); + + mkdirSync(dir, { recursive: true }); + + if (fromDir) { + cpSync(fromDir, dir, { recursive: true }); + } + + return { path: dir, [Symbol.dispose]: () => rmdirSync(dir, { recursive: true }) }; +} + +/** + * @group node + */ +describe('AbiGen', () => { + test('Generates all files correctly', () => { + const fixtureResultMap = new Map([ + ['index', 'index.ts'], + ['common', 'common.ts'], + + ['contracts/contract-index', 'contracts/index.ts'], + ['contracts/contract', 'contracts/AbiContract.ts'], + ['contracts/contract-types', 'contracts/AbiContractTypes.ts'], + ['contracts/contract-factory', 'contracts/AbiContractFactory.ts'], + ['contracts/contract-bytecode', 'contracts/AbiContract-bytecode.ts'], + ['contracts/contract-abi', 'contracts/AbiContract-abi.ts'], + ['contracts/contract-storage-slots', 'contracts/AbiContract-storage-slots.ts'], + + ['predicates/predicate-index', 'predicates/index.ts'], + ['predicates/predicate', 'predicates/AbiPredicate.ts'], + ['predicates/predicate-types', 'predicates/AbiPredicateTypes.ts'], + ['predicates/predicate-abi', 'predicates/AbiPredicate-abi.ts'], + + ['scripts/script-index', 'scripts/index.ts'], + ['scripts/script', 'scripts/AbiScript.ts'], + ['scripts/script-types', 'scripts/AbiScriptTypes.ts'], + ['scripts/script-abi', 'scripts/AbiScript-abi.ts'], + ]); + + const { buildDir: contractDir } = getAbiForcProject(AbiProjectsEnum.ABI_CONTRACT); + const { buildDir: predicateDir } = getAbiForcProject(AbiProjectsEnum.ABI_PREDICATE); + const { abiPath: scriptAbiPath } = getAbiForcProject(AbiProjectsEnum.ABI_SCRIPT); + + using output = generateTmpDir(); + + runTypegen({ + inputs: [contractDir, predicateDir, scriptAbiPath], + output: output.path, + }); + + fixtureResultMap.forEach((filename, fixture) => { + const fixtureFile = join( + process.cwd(), + `packages/fuel-gauge/src/abi/fixtures/${fixture}.txt` + ); + const expected = readFileSync(fixtureFile).toString(); + const generated = readFileSync(join(output.path, filename)).toString(); + + expect(generated).toEqual(expected); + }); + }); + + test('logs if no abi json file found and skips path', () => { + const logSpy = vi.spyOn(console, 'log').mockImplementationOnce(() => {}); + const { buildDir: scriptBuildDir, name: scriptName } = getAbiForcProject( + AbiProjectsEnum.ABI_SCRIPT + ); + const { buildDir: predicateBuildDir } = getAbiForcProject(AbiProjectsEnum.ABI_PREDICATE); + using scriptDir = generateTmpDir(scriptBuildDir); + + rmSync(join(scriptDir.path, `${scriptName}-abi.json`)); + + using predicateDir = generateTmpDir(predicateBuildDir); + + runTypegen({ + inputs: [scriptDir.path, predicateDir.path], + output: scriptDir.path, + }); + + expect(logSpy).toHaveBeenCalledWith( + `No abi file found in ${scriptDir.path}, skipping this path.` + ); + const outputDirContents = readdirSync(scriptDir.path); + + expect(outputDirContents).not.toContain('scripts'); + expect(outputDirContents).toContain('predicates'); + }); + + test('skips contract factory and bytecode generation when bytecode is missing and logs it', () => { + const { buildDir, name } = getAbiForcProject(AbiProjectsEnum.ABI_CONTRACT); + using tmpDir = generateTmpDir(buildDir); + + rmSync(join(tmpDir.path, `${name}.bin`)); + + const spy = vi.spyOn(console, 'log').mockImplementationOnce(() => {}); + + runTypegen({ + inputs: [tmpDir.path], + output: tmpDir.path, + }); + + expect(spy).toHaveBeenCalledWith( + `No bytecode found for contract at ${tmpDir.path}, will not generate ContractFactory for it.` + ); + + const contractsOutputs = readdirSync(join(tmpDir.path, 'contracts')); + + expect(contractsOutputs).toContain('index.ts'); + expect(contractsOutputs).toContain('AbiContract.ts'); + expect(contractsOutputs).toContain('AbiContractTypes.ts'); + expect(contractsOutputs).toContain('AbiContract-abi.ts'); + expect(contractsOutputs).toContain('AbiContract-storage-slots.ts'); + expect(contractsOutputs).not.toContain('AbiContractFactory.ts'); + expect(contractsOutputs).not.toContain('AbiContract-bytecode.ts'); + }); + + test('throws when missing bytecode for script', async () => { + const { buildDir, name } = getAbiForcProject(AbiProjectsEnum.ABI_SCRIPT); + using tmpDir = generateTmpDir(buildDir); + + rmSync(join(tmpDir.path, `${name}.bin`)); + + await expectToThrowFuelError( + () => + runTypegen({ + inputs: [tmpDir.path], + output: tmpDir.path, + }), + new FuelError( + FuelError.CODES.BIN_FILE_NOT_FOUND, + `For scripts, the bytecode is required. No bytecode found for script at ${tmpDir.path}.` + ) + ); + }); + + test('throws when missing bytecode for predicate', async () => { + const { buildDir, name } = getAbiForcProject(AbiProjectsEnum.ABI_PREDICATE); + using tmpDir = generateTmpDir(buildDir); + + rmSync(join(tmpDir.path, `${name}.bin`)); + + await expectToThrowFuelError( + () => + runTypegen({ + inputs: [tmpDir.path], + output: tmpDir.path, + }), + new FuelError( + FuelError.CODES.BIN_FILE_NOT_FOUND, + `For predicates, the bytecode is required. No bytecode found for predicate at ${tmpDir.path}.` + ) + ); + }); +}); diff --git a/packages/fuel-gauge/src/abi/abi-parser.json b/packages/fuel-gauge/src/abi/abi-parser.json new file mode 100644 index 00000000000..373715abe6c --- /dev/null +++ b/packages/fuel-gauge/src/abi/abi-parser.json @@ -0,0 +1,1732 @@ +{ + "metadataTypes": [ + { + "metadataTypeId": 0, + "swayType": "(_, _)", + "components": [ + { + "name": "__tuple_element", + "type": { + "swayType": "generic E", + "metadata": { + "metadataTypeId": 4 + } + } + }, + { + "name": "__tuple_element", + "type": { + "swayType": "generic F", + "metadata": { + "metadataTypeId": 5 + } + } + } + ] + }, + { + "metadataTypeId": 1, + "swayType": "(_, _)", + "components": [ + { + "name": "__tuple_element", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + }, + { + "name": "__tuple_element", + "type": { + "swayType": "struct StructWithImplicitGenerics", + "metadata": { + "metadataTypeId": 12, + "typeArguments": [ + { + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "swayType": "bool" + }, + { + "swayType": "b256", + "metadata": { + "metadataTypeId": 3 + } + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "[_; 3]", + "metadata": { + "metadataTypeId": 2 + }, + "components": [ + { + "name": "__array_element", + "type": { + "swayType": "generic E", + "metadata": { + "metadataTypeId": 4 + } + } + } + ] + } + }, + { + "name": "b", + "type": { + "swayType": "(_, _)", + "metadata": { + "metadataTypeId": 0 + }, + "components": [ + { + "name": "__tuple_element", + "type": { + "swayType": "generic E", + "metadata": { + "metadataTypeId": 4 + } + } + }, + { + "name": "__tuple_element", + "type": { + "swayType": "generic F", + "metadata": { + "metadataTypeId": 5 + } + } + } + ] + } + } + ] + } + } + ] + }, + { + "metadataTypeId": 2, + "swayType": "[_; 3]", + "components": [ + { + "name": "__array_element", + "type": { + "swayType": "generic E", + "metadata": { + "metadataTypeId": 4 + } + } + } + ] + }, + { + "metadataTypeId": 3, + "swayType": "b256" + }, + { + "metadataTypeId": 4, + "swayType": "generic E" + }, + { + "metadataTypeId": 5, + "swayType": "generic F" + }, + { + "metadataTypeId": 6, + "swayType": "generic T" + }, + { + "metadataTypeId": 8, + "swayType": "struct DoubleGeneric", + "components": [ + { + "name": "a", + "type": { + "swayType": "generic T", + "metadata": { + "metadataTypeId": 6 + } + } + }, + { + "name": "b", + "type": { + "swayType": "generic F", + "metadata": { + "metadataTypeId": 5 + } + } + } + ], + "typeParameters": [ + { + "metadataTypeId": 6, + "swayType": "generic T" + }, + { + "metadataTypeId": 5, + "swayType": "generic F" + } + ] + }, + { + "metadataTypeId": 9, + "swayType": "struct GenericStruct", + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + }, + { + "name": "b", + "type": { + "swayType": "u32", + "metadata": { + "metadataTypeId": 17 + } + } + }, + { + "name": "c", + "type": { + "swayType": "generic T", + "metadata": { + "metadataTypeId": 6 + } + } + } + ], + "typeParameters": [ + { + "metadataTypeId": 6, + "swayType": "generic T" + } + ] + }, + { + "metadataTypeId": 10, + "swayType": "struct NestedGenericStruct", + "components": [ + { + "name": "a", + "type": { + "swayType": "struct std::vec::Vec", + "metadata": { + "metadataTypeId": 16, + "typeArguments": [ + { + "swayType": "struct GenericStruct", + "metadata": { + "metadataTypeId": 9, + "typeArguments": [ + { + "swayType": "generic E", + "metadata": { + "metadataTypeId": 4 + } + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + }, + { + "name": "b", + "type": { + "swayType": "u32", + "metadata": { + "metadataTypeId": 17 + } + } + }, + { + "name": "c", + "type": { + "swayType": "generic E", + "metadata": { + "metadataTypeId": 4 + } + } + } + ] + } + ] + }, + "components": [ + { + "name": "", + "type": { + "swayType": "struct GenericStruct", + "metadata": { + "metadataTypeId": 9, + "typeArguments": [ + { + "swayType": "generic E", + "metadata": { + "metadataTypeId": 4 + } + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + }, + { + "name": "b", + "type": { + "swayType": "u32", + "metadata": { + "metadataTypeId": 17 + } + } + }, + { + "name": "c", + "type": { + "swayType": "generic E", + "metadata": { + "metadataTypeId": 4 + } + } + } + ] + } + } + ] + } + }, + { + "name": "b", + "type": { + "swayType": "struct std::vec::Vec", + "metadata": { + "metadataTypeId": 16, + "typeArguments": [ + { + "swayType": "struct GenericStruct", + "metadata": { + "metadataTypeId": 9, + "typeArguments": [ + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "swayType": "u16" + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + }, + { + "name": "b", + "type": { + "swayType": "u32", + "metadata": { + "metadataTypeId": 17 + } + } + }, + { + "name": "c", + "type": { + "swayType": "u16", + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + } + } + ] + } + ] + }, + "components": [ + { + "name": "", + "type": { + "swayType": "struct GenericStruct", + "metadata": { + "metadataTypeId": 9, + "typeArguments": [ + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "swayType": "u16" + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + }, + { + "name": "b", + "type": { + "swayType": "u32", + "metadata": { + "metadataTypeId": 17 + } + } + }, + { + "name": "c", + "type": { + "swayType": "u16", + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + } + } + ] + } + } + ] + } + }, + { + "name": "c", + "type": { + "swayType": "struct DoubleGeneric", + "metadata": { + "metadataTypeId": 8, + "typeArguments": [ + { + "swayType": "generic E", + "metadata": { + "metadataTypeId": 4 + } + }, + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "swayType": "u16" + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "generic E", + "metadata": { + "metadataTypeId": 4 + } + } + }, + { + "name": "b", + "type": { + "swayType": "u16", + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + } + } + ] + } + } + ], + "typeParameters": [ + { + "metadataTypeId": 4, + "swayType": "generic E" + } + ] + }, + { + "metadataTypeId": 11, + "swayType": "struct SimpleStruct", + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + } + ] + }, + { + "metadataTypeId": 12, + "swayType": "struct StructWithImplicitGenerics", + "components": [ + { + "name": "a", + "type": { + "swayType": "[_; 3]", + "metadata": { + "metadataTypeId": 2 + }, + "components": [ + { + "name": "__array_element", + "type": { + "swayType": "generic E", + "metadata": { + "metadataTypeId": 4 + } + } + } + ] + } + }, + { + "name": "b", + "type": { + "swayType": "(_, _)", + "metadata": { + "metadataTypeId": 0 + }, + "components": [ + { + "name": "__tuple_element", + "type": { + "swayType": "generic E", + "metadata": { + "metadataTypeId": 4 + } + } + }, + { + "name": "__tuple_element", + "type": { + "swayType": "generic F", + "metadata": { + "metadataTypeId": 5 + } + } + } + ] + } + } + ], + "typeParameters": [ + { + "metadataTypeId": 4, + "swayType": "generic E" + }, + { + "metadataTypeId": 5, + "swayType": "generic F" + } + ] + }, + { + "metadataTypeId": 13, + "swayType": "struct std::bytes::Bytes" + }, + { + "metadataTypeId": 16, + "swayType": "struct std::vec::Vec", + "components": [ + { + "name": "", + "type": { + "swayType": "generic T", + "metadata": { + "metadataTypeId": 6 + } + } + } + ], + "typeParameters": [ + { + "metadataTypeId": 6, + "swayType": "generic T" + } + ] + }, + { + "metadataTypeId": 17, + "swayType": "u32" + }, + { + "metadataTypeId": 18, + "swayType": "u64" + } + ], + "concreteTypes": [ + { + "concreteTypeId": "9dc54ad1b685b6abf04fbcc93696e440452944466e2dfd64b5df956a13ad2027", + "swayType": "(_, _)", + "metadata": { + "metadataTypeId": 1 + }, + "components": [ + { + "name": "__tuple_element", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + }, + { + "name": "__tuple_element", + "type": { + "swayType": "struct StructWithImplicitGenerics", + "metadata": { + "metadataTypeId": 12, + "typeArguments": [ + { + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "swayType": "bool" + }, + { + "swayType": "b256", + "metadata": { + "metadataTypeId": 3 + } + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "[_; 3]", + "metadata": { + "metadataTypeId": 2 + }, + "components": [ + { + "name": "__array_element", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + } + ] + } + }, + { + "name": "b", + "type": { + "swayType": "(_, _)", + "metadata": { + "metadataTypeId": 0 + }, + "components": [ + { + "name": "__tuple_element", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + }, + { + "name": "__tuple_element", + "type": { + "swayType": "b256", + "metadata": { + "metadataTypeId": 3 + } + } + } + ] + } + } + ] + } + } + ] + }, + { + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "swayType": "bool" + }, + { + "concreteTypeId": "8fa64aacdb756049c3c90d3a5fa8d1a7ebedefc8dc2f347e67bb26ef4c7140a7", + "swayType": "struct GenericStruct", + "metadata": { + "metadataTypeId": 9, + "typeArguments": [ + { + "concreteTypeId": "688b6ed7fc2c45e135ea9a2ce11e3f5313a4c057ba5d616e3381937605ea81e4", + "swayType": "struct std::vec::Vec", + "metadata": { + "metadataTypeId": 16, + "typeArguments": [ + { + "concreteTypeId": "75f7f7a06026cab5d7a70984d1fde56001e83505e3a091ff9722b92d7f56d8be", + "swayType": "struct SimpleStruct", + "metadata": { + "metadataTypeId": 11 + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + } + ] + } + ] + }, + "components": [ + { + "name": "", + "type": { + "swayType": "struct SimpleStruct", + "concreteTypeId": "75f7f7a06026cab5d7a70984d1fde56001e83505e3a091ff9722b92d7f56d8be", + "metadata": { + "metadataTypeId": 11 + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + } + ] + } + } + ] + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + }, + { + "name": "b", + "type": { + "swayType": "u32", + "metadata": { + "metadataTypeId": 17 + } + } + }, + { + "name": "c", + "type": { + "swayType": "struct std::vec::Vec", + "concreteTypeId": "688b6ed7fc2c45e135ea9a2ce11e3f5313a4c057ba5d616e3381937605ea81e4", + "metadata": { + "metadataTypeId": 16, + "typeArguments": [ + { + "concreteTypeId": "75f7f7a06026cab5d7a70984d1fde56001e83505e3a091ff9722b92d7f56d8be", + "swayType": "struct SimpleStruct", + "metadata": { + "metadataTypeId": 11 + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + } + ] + } + ] + }, + "components": [ + { + "name": "", + "type": { + "swayType": "struct SimpleStruct", + "concreteTypeId": "75f7f7a06026cab5d7a70984d1fde56001e83505e3a091ff9722b92d7f56d8be", + "metadata": { + "metadataTypeId": 11 + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + } + ] + } + } + ] + } + } + ] + }, + { + "concreteTypeId": "cc3087210794115a9b7e470ad5b5d554808a3a88aa003ae80bae7b0dc4505f50", + "swayType": "struct NestedGenericStruct", + "metadata": { + "metadataTypeId": 10, + "typeArguments": [ + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "swayType": "u8" + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "struct std::vec::Vec", + "metadata": { + "metadataTypeId": 16, + "typeArguments": [ + { + "swayType": "struct GenericStruct", + "metadata": { + "metadataTypeId": 9, + "typeArguments": [ + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "swayType": "u8" + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + }, + { + "name": "b", + "type": { + "swayType": "u32", + "metadata": { + "metadataTypeId": 17 + } + } + }, + { + "name": "c", + "type": { + "swayType": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + } + ] + } + ] + }, + "components": [ + { + "name": "", + "type": { + "swayType": "struct GenericStruct", + "metadata": { + "metadataTypeId": 9, + "typeArguments": [ + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "swayType": "u8" + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + }, + { + "name": "b", + "type": { + "swayType": "u32", + "metadata": { + "metadataTypeId": 17 + } + } + }, + { + "name": "c", + "type": { + "swayType": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + } + ] + } + } + ] + } + }, + { + "name": "b", + "type": { + "swayType": "struct std::vec::Vec", + "metadata": { + "metadataTypeId": 16, + "typeArguments": [ + { + "swayType": "struct GenericStruct", + "metadata": { + "metadataTypeId": 9, + "typeArguments": [ + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "swayType": "u16" + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + }, + { + "name": "b", + "type": { + "swayType": "u32", + "metadata": { + "metadataTypeId": 17 + } + } + }, + { + "name": "c", + "type": { + "swayType": "u16", + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + } + } + ] + } + ] + }, + "components": [ + { + "name": "", + "type": { + "swayType": "struct GenericStruct", + "metadata": { + "metadataTypeId": 9, + "typeArguments": [ + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "swayType": "u16" + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + }, + { + "name": "b", + "type": { + "swayType": "u32", + "metadata": { + "metadataTypeId": 17 + } + } + }, + { + "name": "c", + "type": { + "swayType": "u16", + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + } + } + ] + } + } + ] + } + }, + { + "name": "c", + "type": { + "swayType": "struct DoubleGeneric", + "metadata": { + "metadataTypeId": 8, + "typeArguments": [ + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "swayType": "u8" + }, + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "swayType": "u16" + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + }, + { + "name": "b", + "type": { + "swayType": "u16", + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + } + } + ] + } + } + ] + }, + { + "concreteTypeId": "75f7f7a06026cab5d7a70984d1fde56001e83505e3a091ff9722b92d7f56d8be", + "swayType": "struct SimpleStruct", + "metadata": { + "metadataTypeId": 11 + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + } + ] + }, + { + "concreteTypeId": "426345c4ea93db9f08eeb9fe6047ef0273294bfb1140600a0660be9f2a08d750", + "swayType": "struct StructWithImplicitGenerics", + "metadata": { + "metadataTypeId": 12, + "typeArguments": [ + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "swayType": "u8" + }, + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "swayType": "u16" + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "[_; 3]", + "metadata": { + "metadataTypeId": 2 + }, + "components": [ + { + "name": "__array_element", + "type": { + "swayType": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + } + ] + } + }, + { + "name": "b", + "type": { + "swayType": "(_, _)", + "metadata": { + "metadataTypeId": 0 + }, + "components": [ + { + "name": "__tuple_element", + "type": { + "swayType": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + }, + { + "name": "__tuple_element", + "type": { + "swayType": "u16", + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + } + } + ] + } + } + ] + }, + { + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "swayType": "struct std::bytes::Bytes", + "metadata": { + "metadataTypeId": 13 + } + }, + { + "concreteTypeId": "688b6ed7fc2c45e135ea9a2ce11e3f5313a4c057ba5d616e3381937605ea81e4", + "swayType": "struct std::vec::Vec", + "metadata": { + "metadataTypeId": 16, + "typeArguments": [ + { + "concreteTypeId": "75f7f7a06026cab5d7a70984d1fde56001e83505e3a091ff9722b92d7f56d8be", + "swayType": "struct SimpleStruct", + "metadata": { + "metadataTypeId": 11 + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + } + ] + } + ] + }, + "components": [ + { + "name": "", + "type": { + "swayType": "struct SimpleStruct", + "concreteTypeId": "75f7f7a06026cab5d7a70984d1fde56001e83505e3a091ff9722b92d7f56d8be", + "metadata": { + "metadataTypeId": 11 + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + } + ] + } + } + ] + }, + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "swayType": "u16" + }, + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "swayType": "u8" + } + ], + "encodingVersion": "1", + "programType": "contract", + "functions": [ + { + "name": "bytes", + "output": { + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "swayType": "bool" + }, + "inputs": [ + { + "name": "arg", + "type": { + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "swayType": "struct std::bytes::Bytes", + "metadata": { + "metadataTypeId": 13 + } + } + } + ] + }, + { + "name": "generic_structs", + "output": { + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "swayType": "bool" + }, + "inputs": [ + { + "name": "arg1", + "type": { + "concreteTypeId": "8fa64aacdb756049c3c90d3a5fa8d1a7ebedefc8dc2f347e67bb26ef4c7140a7", + "swayType": "struct GenericStruct", + "metadata": { + "metadataTypeId": 9, + "typeArguments": [ + { + "concreteTypeId": "688b6ed7fc2c45e135ea9a2ce11e3f5313a4c057ba5d616e3381937605ea81e4", + "swayType": "struct std::vec::Vec", + "metadata": { + "metadataTypeId": 16, + "typeArguments": [ + { + "concreteTypeId": "75f7f7a06026cab5d7a70984d1fde56001e83505e3a091ff9722b92d7f56d8be", + "swayType": "struct SimpleStruct", + "metadata": { + "metadataTypeId": 11 + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + } + ] + } + ] + }, + "components": [ + { + "name": "", + "type": { + "swayType": "struct SimpleStruct", + "concreteTypeId": "75f7f7a06026cab5d7a70984d1fde56001e83505e3a091ff9722b92d7f56d8be", + "metadata": { + "metadataTypeId": 11 + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + } + ] + } + } + ] + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + }, + { + "name": "b", + "type": { + "swayType": "u32", + "metadata": { + "metadataTypeId": 17 + } + } + }, + { + "name": "c", + "type": { + "swayType": "struct std::vec::Vec", + "concreteTypeId": "688b6ed7fc2c45e135ea9a2ce11e3f5313a4c057ba5d616e3381937605ea81e4", + "metadata": { + "metadataTypeId": 16, + "typeArguments": [ + { + "concreteTypeId": "75f7f7a06026cab5d7a70984d1fde56001e83505e3a091ff9722b92d7f56d8be", + "swayType": "struct SimpleStruct", + "metadata": { + "metadataTypeId": 11 + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + } + ] + } + ] + }, + "components": [ + { + "name": "", + "type": { + "swayType": "struct SimpleStruct", + "concreteTypeId": "75f7f7a06026cab5d7a70984d1fde56001e83505e3a091ff9722b92d7f56d8be", + "metadata": { + "metadataTypeId": 11 + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + } + ] + } + } + ] + } + } + ] + } + }, + { + "name": "arg2", + "type": { + "concreteTypeId": "cc3087210794115a9b7e470ad5b5d554808a3a88aa003ae80bae7b0dc4505f50", + "swayType": "struct NestedGenericStruct", + "metadata": { + "metadataTypeId": 10, + "typeArguments": [ + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "swayType": "u8" + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "struct std::vec::Vec", + "metadata": { + "metadataTypeId": 16, + "typeArguments": [ + { + "swayType": "struct GenericStruct", + "metadata": { + "metadataTypeId": 9, + "typeArguments": [ + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "swayType": "u8" + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + }, + { + "name": "b", + "type": { + "swayType": "u32", + "metadata": { + "metadataTypeId": 17 + } + } + }, + { + "name": "c", + "type": { + "swayType": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + } + ] + } + ] + }, + "components": [ + { + "name": "", + "type": { + "swayType": "struct GenericStruct", + "metadata": { + "metadataTypeId": 9, + "typeArguments": [ + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "swayType": "u8" + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + }, + { + "name": "b", + "type": { + "swayType": "u32", + "metadata": { + "metadataTypeId": 17 + } + } + }, + { + "name": "c", + "type": { + "swayType": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + } + ] + } + } + ] + } + }, + { + "name": "b", + "type": { + "swayType": "struct std::vec::Vec", + "metadata": { + "metadataTypeId": 16, + "typeArguments": [ + { + "swayType": "struct GenericStruct", + "metadata": { + "metadataTypeId": 9, + "typeArguments": [ + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "swayType": "u16" + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + }, + { + "name": "b", + "type": { + "swayType": "u32", + "metadata": { + "metadataTypeId": 17 + } + } + }, + { + "name": "c", + "type": { + "swayType": "u16", + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + } + } + ] + } + ] + }, + "components": [ + { + "name": "", + "type": { + "swayType": "struct GenericStruct", + "metadata": { + "metadataTypeId": 9, + "typeArguments": [ + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "swayType": "u16" + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + }, + { + "name": "b", + "type": { + "swayType": "u32", + "metadata": { + "metadataTypeId": 17 + } + } + }, + { + "name": "c", + "type": { + "swayType": "u16", + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + } + } + ] + } + } + ] + } + }, + { + "name": "c", + "type": { + "swayType": "struct DoubleGeneric", + "metadata": { + "metadataTypeId": 8, + "typeArguments": [ + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "swayType": "u8" + }, + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "swayType": "u16" + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + }, + { + "name": "b", + "type": { + "swayType": "u16", + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + } + } + ] + } + } + ] + } + } + ] + }, + { + "name": "implicit_generic_struct", + "output": { + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "swayType": "bool" + }, + "inputs": [ + { + "name": "arg1", + "type": { + "concreteTypeId": "426345c4ea93db9f08eeb9fe6047ef0273294bfb1140600a0660be9f2a08d750", + "swayType": "struct StructWithImplicitGenerics", + "metadata": { + "metadataTypeId": 12, + "typeArguments": [ + { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "swayType": "u8" + }, + { + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "swayType": "u16" + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "[_; 3]", + "metadata": { + "metadataTypeId": 2 + }, + "components": [ + { + "name": "__array_element", + "type": { + "swayType": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + } + ] + } + }, + { + "name": "b", + "type": { + "swayType": "(_, _)", + "metadata": { + "metadataTypeId": 0 + }, + "components": [ + { + "name": "__tuple_element", + "type": { + "swayType": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + }, + { + "name": "__tuple_element", + "type": { + "swayType": "u16", + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + } + } + ] + } + } + ] + } + }, + { + "name": "arg2", + "type": { + "concreteTypeId": "9dc54ad1b685b6abf04fbcc93696e440452944466e2dfd64b5df956a13ad2027", + "swayType": "(_, _)", + "metadata": { + "metadataTypeId": 1 + }, + "components": [ + { + "name": "__tuple_element", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + }, + { + "name": "__tuple_element", + "type": { + "swayType": "struct StructWithImplicitGenerics", + "metadata": { + "metadataTypeId": 12, + "typeArguments": [ + { + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "swayType": "bool" + }, + { + "swayType": "b256", + "metadata": { + "metadataTypeId": 3 + } + } + ] + }, + "components": [ + { + "name": "a", + "type": { + "swayType": "[_; 3]", + "metadata": { + "metadataTypeId": 2 + }, + "components": [ + { + "name": "__array_element", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + } + ] + } + }, + { + "name": "b", + "type": { + "swayType": "(_, _)", + "metadata": { + "metadataTypeId": 0 + }, + "components": [ + { + "name": "__tuple_element", + "type": { + "swayType": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + }, + { + "name": "__tuple_element", + "type": { + "swayType": "b256", + "metadata": { + "metadataTypeId": 3 + } + } + } + ] + } + } + ] + } + } + ] + } + } + ] + } + ], + "loggedTypes": [ + { + "logId": "13213829929622723620", + "type": { + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "swayType": "bool" + } + } + ], + "messageTypes": [ + { + "messageId": "0", + "type": { + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "swayType": "bool" + } + }, + { + "messageId": "1", + "type": { + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "swayType": "bool" + } + } + ], + "configurables": [ + { + "name": "U8_VALUE", + "offset": 5360, + "type": { + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "swayType": "u8" + } + } + ] +} diff --git a/packages/fuel-gauge/src/abi/abi-parser.test.ts b/packages/fuel-gauge/src/abi/abi-parser.test.ts new file mode 100644 index 00000000000..07498ae19ce --- /dev/null +++ b/packages/fuel-gauge/src/abi/abi-parser.test.ts @@ -0,0 +1,51 @@ +import { AbiParser, type AbiSpecification } from 'fuels'; + +import { Parser } from '../../test/typegen'; + +import expected from './abi-parser.json'; + +/** + * @group node + * @group browser + */ +describe('AbiParser', () => { + test('parses encoding version as expected', () => { + const parsed = AbiParser.parse(Parser.abi as AbiSpecification); + expect(parsed.encodingVersion).toEqual(expected.encodingVersion); + }); + + test('parses program type as expected', () => { + const parsed = AbiParser.parse(Parser.abi as AbiSpecification); + expect(parsed.programType).toEqual(expected.programType); + }); + + test('parses metadata types as expected', () => { + const parsed = AbiParser.parse(Parser.abi as AbiSpecification); + expect(parsed.metadataTypes).toEqual(expected.metadataTypes); + }); + + test('parses concrete types as expected', () => { + const parsed = AbiParser.parse(Parser.abi as AbiSpecification); + expect(parsed.concreteTypes).toEqual(expected.concreteTypes); + }); + + test('parses functions as expected', () => { + const parsed = AbiParser.parse(Parser.abi as AbiSpecification); + expect(parsed.functions).toEqual(expected.functions); + }); + + test('parses logged types as expected', () => { + const parsed = AbiParser.parse(Parser.abi as AbiSpecification); + expect(parsed.loggedTypes).toEqual(expected.loggedTypes); + }); + + test('parses message types as expected', () => { + const parsed = AbiParser.parse(Parser.abi as AbiSpecification); + expect(parsed.messageTypes).toEqual(expected.messageTypes); + }); + + test('parses configurables as expected', () => { + const parsed = AbiParser.parse(Parser.abi as AbiSpecification); + expect(parsed.configurables).toEqual(expected.configurables); + }); +}); diff --git a/packages/fuel-gauge/src/abi/abi-script.test.ts b/packages/fuel-gauge/src/abi/abi-script.test.ts index c6eb5eecb05..d8be4a79432 100644 --- a/packages/fuel-gauge/src/abi/abi-script.test.ts +++ b/packages/fuel-gauge/src/abi/abi-script.test.ts @@ -8,7 +8,6 @@ import { type AssetIdInput, type ScriptWithComplexArgsInputs, } from '../../test/typegen/scripts/ScriptWithComplexArgs'; -import type { Vec } from '../../test/typegen/scripts/common'; /** * @group browser @@ -52,9 +51,11 @@ describe('abi-script', () => { const arg1 = 100; const arg2 = { bits: getRandomB256() }; const arg3 = 100; - const arg4 = [[{ bits: getRandomB256() }, { bits: getRandomB256() }, true]] as Vec< - [AssetIdInput, AssetIdInput, boolean] - >; + const arg4 = [[{ bits: getRandomB256() }, { bits: getRandomB256() }, true]] as [ + AssetIdInput, + AssetIdInput, + boolean, + ][]; const arg5 = { Address: { bits: getRandomB256() } }; const arg6 = 100; const expected = [ diff --git a/packages/fuel-gauge/src/abi/fixtures/common.txt b/packages/fuel-gauge/src/abi/fixtures/common.txt new file mode 100644 index 00000000000..43cb6e6689e --- /dev/null +++ b/packages/fuel-gauge/src/abi/fixtures/common.txt @@ -0,0 +1,53 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + + +import type { FunctionFragment, InvokeFunction } from 'fuels'; + +/** + * Mimics Sway Enum. + * Requires one and only one Key-Value pair and raises error if more are provided. + */ +export type Enum = { + [K in keyof T]: Pick & { [P in Exclude]?: never }; +}[keyof T]; + +/** + * Mimics Sway Option type. + */ +export type Option = T | undefined; + +/** + * Mimics Sway Result enum type. + * Ok represents the success case, while Err represents the error case. + */ +export type Result = Enum<{ Ok: T; Err: E }>; + +/** + * Mimics Sway array type. For example, [u64; 10] is converted to ArrayOfLength. + */ +export type ArrayOfLength< + T, + Length extends number, + Arr extends unknown[] = [], +> = Arr['length'] extends Length ? Arr : ArrayOfLength; + +interface Types { + functions: Record; + configurables: Partial>; +} + +export type ProgramFunctionMapper = { + [K in keyof T]: InvokeFunction; +}; + +export type InterfaceFunctionMapper = { + [K in keyof T]: FunctionFragment; +}; \ No newline at end of file diff --git a/packages/fuel-gauge/src/abi/fixtures/contracts/contract-abi.txt b/packages/fuel-gauge/src/abi/fixtures/contracts/contract-abi.txt new file mode 100644 index 00000000000..8aae39e58b9 --- /dev/null +++ b/packages/fuel-gauge/src/abi/fixtures/contracts/contract-abi.txt @@ -0,0 +1,2808 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + + +export const abi = { + "programType": "contract", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "()", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "type": "(b256, bool)", + "concreteTypeId": "d5f6ab61fc224aae1bf15a89ab88840ed54e312a76a9735d1f60d4d0d1fae640", + "metadataTypeId": 0 + }, + { + "type": "(bool, u64)", + "concreteTypeId": "c998ca9a5f221fe7b5c66ae70c8a9562b86d964408b00d17f883c906bc1fe4be", + "metadataTypeId": 8 + }, + { + "type": "(str[5], bool)", + "concreteTypeId": "a1e229302ed2f092752a6bc4fbe66bb9305e0802b1b01ecc5e1d59356702e956", + "metadataTypeId": 1 + }, + { + "type": "(str[5], str[5])", + "concreteTypeId": "30022fd7ad3fda4035d30e4d86b705d4870924d4b4fe054624d2561fa12bb33e", + "metadataTypeId": 2 + }, + { + "type": "(struct data_structures::StructDoubleGeneric<[b256; 3],u8>, [struct data_structures::StructDoubleGeneric; 4], (str[5], bool), struct data_structures::StructSimple)", + "concreteTypeId": "343f07ddcd75b9385bc193e0419f2e89c75fad67cbf4ad1b36a01a136620817e", + "metadataTypeId": 13 + }, + { + "type": "(struct data_structures::StructSimple, struct std::vec::Vec)", + "concreteTypeId": "5ebb7c8cdd38d1f676f9c7089a2da12b27114ee3771c2047f3295d4d30f8fd2c", + "metadataTypeId": 3 + }, + { + "type": "(struct std::asset_id::AssetId, struct std::asset_id::AssetId, bool)", + "concreteTypeId": "a95e1fcceb1451b8a76471f593f66c4a52ca04bde3c227c746ad7aaf988de5c6", + "metadataTypeId": 10 + }, + { + "type": "(struct std::vec::Vec, b256)", + "concreteTypeId": "52e2726988c7da304606fbe4ed696efac04beb29e9a22e15778f8a0539c9cb94", + "metadataTypeId": 5 + }, + { + "type": "(struct std::vec::Vec, struct std::vec::Vec)", + "concreteTypeId": "87a4626758542d7b6a03099839e440a052a4d5a00e3abfdf22bcc564ca19a4fd", + "metadataTypeId": 6 + }, + { + "type": "(u32, struct std::vec::Vec, struct std::vec::Vec)", + "concreteTypeId": "18034e13b18b71de3c7e12f8f10a7bd48a23870e0dbb46eaf10faeb26d70f000", + "metadataTypeId": 9 + }, + { + "type": "(u64, struct data_structures::StructSimple)", + "concreteTypeId": "0088c28967dbcdaa34626c7e915e44b2afe72f12415f0e31edc0b5ce70e7c6dc", + "metadataTypeId": 4 + }, + { + "type": "(u8, struct data_structures::StructSingleGeneric>, str[3])", + "concreteTypeId": "6f875be99a39d9920569678a34ffce676a6c3e14b958910db250b9cb4957157f", + "metadataTypeId": 11 + }, + { + "type": "(u8, u8, u8)", + "concreteTypeId": "79239b6d6f2383e2cfbaf4da7fdf7ee7fb59b7bf517acfff2d9433e9e76e8fc4", + "metadataTypeId": 12 + }, + { + "type": "[b256; 3]", + "concreteTypeId": "81342782c917fcfd178741cb2b3a12ea1ebeaa57253fc4ee6700b4d7d6ab32d3", + "metadataTypeId": 17 + }, + { + "type": "[struct data_structures::StructDoubleGeneric,str[1]>; 2]", + "concreteTypeId": "b8164e36cce9d14142824b5cc55aebc1272036775b966af82c49c78aff114006", + "metadataTypeId": 15 + }, + { + "type": "[struct data_structures::StructDoubleGeneric; 4]", + "concreteTypeId": "b22807669faa58263e636f6e2d194df8ddbc6686bb4ea14ee28005fa30adbe85", + "metadataTypeId": 22 + }, + { + "type": "[struct data_structures::StructSimple; 3]", + "concreteTypeId": "38f2594527b516dab2c81b31356901226242d7c32554877e36797c6b23969237", + "metadataTypeId": 18 + }, + { + "type": "[struct std::vec::Vec; 1]", + "concreteTypeId": "593b39347cc381516d8ed1f8e5e628a8d455bd3f833bd9dfdd5165ba16f9f980", + "metadataTypeId": 14 + }, + { + "type": "[u8; 4]", + "concreteTypeId": "f28afa065fc5de602456160c4155d4de7d9a61e85a995d209a14eab0b34bd6b4", + "metadataTypeId": 23 + }, + { + "type": "b256", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum abi-library::ExternalEnum", + "concreteTypeId": "9a24373d8ce7688609717fd5a9b75360cd8a6bdb224ae095f0c05cc891cadd42", + "metadataTypeId": 25 + }, + { + "type": "enum data_structures::EnumDoubleGeneric", + "concreteTypeId": "d0ed93cd57cc3dfb1c119b22bf63f5d215122402536127bf17087ca6d8186307", + "metadataTypeId": 26, + "typeArguments": [ + "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + ] + }, + { + "type": "enum data_structures::EnumWithBuiltinType", + "concreteTypeId": "2136f16aedeec1ab7f1d912c57cc0566e86c36f20a2cb313e3d679cead6a0e61", + "metadataTypeId": 27 + }, + { + "type": "enum data_structures::EnumWithNative", + "concreteTypeId": "58ae0e9c51da476db1149dd48b1cda83a12187df4c049f8df5021f0b1696fb93", + "metadataTypeId": 28 + }, + { + "type": "enum data_structures::EnumWithStructs", + "concreteTypeId": "9ed6dede3ae1e66e0f951e860e863f77fb9b9499f4666a1123bf244c4a201669", + "metadataTypeId": 29 + }, + { + "type": "enum data_structures::EnumWithVector", + "concreteTypeId": "0272d5aecccd33822994b7be1494b72ec9ad860e4cb51f043deda7ac1e2cae26", + "metadataTypeId": 30 + }, + { + "type": "enum std::identity::Identity", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335", + "metadataTypeId": 31 + }, + { + "type": "enum std::option::Option", + "concreteTypeId": "25616ce23be3ca41fd26f8c546c053ec256f8fb5593036f60c9c417e86dcc92e", + "metadataTypeId": 32, + "typeArguments": [ + "ef937135956e37401e0bc90406ca8becda92d1b4e387fe938ddef8d27ee192a1" + ] + }, + { + "type": "enum std::option::Option", + "concreteTypeId": "2da102c46c7263beeed95818cd7bee801716ba8303dddafdcd0f6c9efda4a0f1", + "metadataTypeId": 32, + "typeArguments": [ + "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + ] + }, + { + "type": "enum std::result::Result", + "concreteTypeId": "9891b1ee451eed790368ea3969e3c8f550efa87de489b5d7b933e2290800791b", + "metadataTypeId": 33, + "typeArguments": [ + "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "338a25cb65b9251663dcce6362b744fe10aa849758299590f4efed5dd299bf50" + ] + }, + { + "type": "enum std::result::Result", + "concreteTypeId": "b3131b4c08c16cfa55b3150d587c3afa3e4cdebe0399f3f599fa160baaa64e0c", + "metadataTypeId": 33, + "typeArguments": [ + "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + ] + }, + { + "type": "raw untyped slice", + "concreteTypeId": "1e1c7c52c1c7a9901681337f8669555f62aac58911332c9ff6b4ea8e73786570" + }, + { + "type": "str", + "concreteTypeId": "8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a" + }, + { + "type": "str[10]", + "concreteTypeId": "338a25cb65b9251663dcce6362b744fe10aa849758299590f4efed5dd299bf50" + }, + { + "type": "str[5]", + "concreteTypeId": "84877f6e98274b9e4721db68b4c0bdb9e52b8e9572c5bd7811c07a41ced882c7" + }, + { + "type": "struct abi-library::ExternalStruct", + "concreteTypeId": "c3a770db33c4e755ad3ba4586b9c10520511fb80b767feb57dd41da1a88f6978", + "metadataTypeId": 45 + }, + { + "type": "struct data_structures::Configurables", + "concreteTypeId": "69d4f1cc5ce793681d98a55ab013f42ab56260131d39af6c1e71a5f3531557bc", + "metadataTypeId": 46 + }, + { + "type": "struct data_structures::StructA", + "concreteTypeId": "db8b04f624965fbfd7eb7dc3fc3c6a54a71d0019b37d4011a9350d1870136c9d", + "metadataTypeId": 47 + }, + { + "type": "struct data_structures::StructB", + "concreteTypeId": "9f074fde9cb9194b90bd208c8c95e709bfb1a5c736b063302e5639ce4daad5aa", + "metadataTypeId": 48 + }, + { + "type": "struct data_structures::StructC", + "concreteTypeId": "f219acbc9e3b812457419966b5454d10d51594afecacb87fb7745c9311b90012", + "metadataTypeId": 49 + }, + { + "type": "struct data_structures::StructD>>", + "concreteTypeId": "d0494e36b8daeafdf02dfbd1f65f82c66df872fb235c7fd2707fcd4147c6c292", + "metadataTypeId": 50, + "typeArguments": [ + "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "722eb56989dc44c372c470eb3a6ddb2f91e3924c1c4a0806d21e414046599d35" + ] + }, + { + "type": "struct data_structures::StructDoubleGeneric<[b256; 3],u8>", + "concreteTypeId": "7bdc2c1e9c4b8576fdf5be24c5c6569cba3a8feaba3755ed2b95d646a33c73e2", + "metadataTypeId": 51, + "typeArguments": [ + "81342782c917fcfd178741cb2b3a12ea1ebeaa57253fc4ee6700b4d7d6ab32d3", + "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + ] + }, + { + "type": "struct data_structures::StructDoubleGeneric,u32>", + "concreteTypeId": "08dbec793087c5686c1a493513b158a999bb653126ee51151dfa85fa683edce5", + "metadataTypeId": 51, + "typeArguments": [ + "4946973fc1adce1f6b23e80f9fad29b44e6a4ab25f2b45f3fab95114cfcd33a0", + "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + ] + }, + { + "type": "struct data_structures::StructDoubleGeneric", + "concreteTypeId": "4946973fc1adce1f6b23e80f9fad29b44e6a4ab25f2b45f3fab95114cfcd33a0", + "metadataTypeId": 51, + "typeArguments": [ + "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + ] + }, + { + "type": "struct data_structures::StructF>", + "concreteTypeId": "722eb56989dc44c372c470eb3a6ddb2f91e3924c1c4a0806d21e414046599d35", + "metadataTypeId": 53, + "typeArguments": [ + "49f761c61dce644e212b8182e30557d35b6b4ad46693140be677eee0d6ef2733" + ] + }, + { + "type": "struct data_structures::StructG", + "concreteTypeId": "dfd8875bb49716b14dd336285ba667f953ed9aec4e918c0d7a2eb19ff644d60e", + "metadataTypeId": 54 + }, + { + "type": "struct data_structures::StructGenericWithEnum", + "concreteTypeId": "8986b78b19c146ced98454ffbe32d17f1e9e468128ba8dcb2a32f16aaf208db2", + "metadataTypeId": 55, + "typeArguments": [ + "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + ] + }, + { + "type": "struct data_structures::StructSimple", + "concreteTypeId": "ef937135956e37401e0bc90406ca8becda92d1b4e387fe938ddef8d27ee192a1", + "metadataTypeId": 56 + }, + { + "type": "struct data_structures::StructSingleGeneric<(bool, u64)>", + "concreteTypeId": "fc0793960700fbabd2722134cff2a546743fc832b98d89aac1ec30fc669fd698", + "metadataTypeId": 57, + "typeArguments": [ + "c998ca9a5f221fe7b5c66ae70c8a9562b86d964408b00d17f883c906bc1fe4be" + ] + }, + { + "type": "struct data_structures::StructSingleGeneric", + "concreteTypeId": "7cbc352969caf2e9caa716d89c3be65e707447e2a197c779cc4ef382d0602de6", + "metadataTypeId": 57, + "typeArguments": [ + "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + ] + }, + { + "type": "struct data_structures::StructWithEnumArray", + "concreteTypeId": "d5266ee32061dbfec8c96f2ba8a054243875e4e6a586104d6366b11e3bc86f2e", + "metadataTypeId": 58 + }, + { + "type": "struct data_structures::StructWithGenericArray", + "concreteTypeId": "29843de0bbb48b2d3c601b61823f2e106cfa5833e18b482571f1fa58b507a7ad", + "metadataTypeId": 59, + "typeArguments": [ + "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + ] + }, + { + "type": "struct data_structures::StructWithImplicitGenerics", + "concreteTypeId": "549c0f0c43c9e33f7e958e0473d84e78eca4737f9f159c64614ca5dff2d91b60", + "metadataTypeId": 60, + "typeArguments": [ + "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + ] + }, + { + "type": "struct data_structures::StructWithMultiOption", + "concreteTypeId": "aa87500bb34c8bb09ffd60ab55cb1725898c366c58d3ff3aaaf8c9b532934fd1", + "metadataTypeId": 61 + }, + { + "type": "struct data_structures::StructWithNestedArray", + "concreteTypeId": "e7807205e98b513a8beeb5bcf446f0b2d684d0dce6bfeff0f324fa31df1b8948", + "metadataTypeId": 62 + }, + { + "type": "struct data_structures::StructWithNestedStruct", + "concreteTypeId": "8651356d9584265a78cb58de01c22d405dfc7006ea2f5f74fddcbe3f047f109a", + "metadataTypeId": 63 + }, + { + "type": "struct data_structures::StructWithNestedTuple", + "concreteTypeId": "d042dca573565aa653542415397934b3e95452917664e04d27c32a22091aa9a5", + "metadataTypeId": 64 + }, + { + "type": "struct data_structures::StructWithSingleOption", + "concreteTypeId": "089f2c4466ef415255917812d05776ebcb386be53e5f94bdad1ca8095f02845c", + "metadataTypeId": 65 + }, + { + "type": "struct data_structures::StructWithVector", + "concreteTypeId": "eac45984af86a06e11e1c5ff744bc1242e004db8404308cb7e574b4c2afaf621", + "metadataTypeId": 66 + }, + { + "type": "struct std::address::Address", + "concreteTypeId": "f597b637c3b0f588fb8d7086c6f4735caa3122b85f0423b82e489f9bb58e2308", + "metadataTypeId": 67 + }, + { + "type": "struct std::asset_id::AssetId", + "concreteTypeId": "c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974", + "metadataTypeId": 68 + }, + { + "type": "struct std::b512::B512", + "concreteTypeId": "745e252e80bec590efc3999ae943f07ccea4d5b45b00bb6575499b64abdd3322", + "metadataTypeId": 69 + }, + { + "type": "struct std::bytes::Bytes", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "metadataTypeId": 70 + }, + { + "type": "struct std::contract_id::ContractId", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", + "metadataTypeId": 72 + }, + { + "type": "struct std::string::String", + "concreteTypeId": "9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c", + "metadataTypeId": 73 + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "6b97d5d738359413c9fac402aced252c23902c28382469ffe27f07381e9f6f31", + "metadataTypeId": 75, + "typeArguments": [ + "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + ] + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "49f761c61dce644e212b8182e30557d35b6b4ad46693140be677eee0d6ef2733", + "metadataTypeId": 75, + "typeArguments": [ + "dfd8875bb49716b14dd336285ba667f953ed9aec4e918c0d7a2eb19ff644d60e" + ] + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "9168b00268bbefd158090041178f058b032504f76c4b9644157d5d6b5b183468", + "metadataTypeId": 75, + "typeArguments": [ + "ef937135956e37401e0bc90406ca8becda92d1b4e387fe938ddef8d27ee192a1" + ] + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "c0de252b9f65a31c6d03071b4b18a935c88c5bb0b2401a447fd30d342fd5a04d", + "metadataTypeId": 75, + "typeArguments": [ + "aa87500bb34c8bb09ffd60ab55cb1725898c366c58d3ff3aaaf8c9b532934fd1" + ] + }, + { + "type": "struct std::vec::Vec>", + "concreteTypeId": "e06c82714c52b8afd2293d5d37d05783d09d71c956311c6050ac012cab06364e", + "metadataTypeId": 75, + "typeArguments": [ + "13c38f4111bad6468fad4f8ea82fd744546b63be49db9439fb3d94e14ae2bb3a" + ] + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "13c38f4111bad6468fad4f8ea82fd744546b63be49db9439fb3d94e14ae2bb3a", + "metadataTypeId": 75, + "typeArguments": [ + "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + ] + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "d5bfe1d4e1ace20166c9b50cadd47e862020561bde24f5189cfc2723f5ed76f4", + "metadataTypeId": 75, + "typeArguments": [ + "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + ] + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "27a0fb3d3a821e04e7a3f17ab6a617f0eb10f11e6eeb0f2c0ff9e6237207319e", + "metadataTypeId": 75, + "typeArguments": [ + "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + ] + }, + { + "type": "struct std::vm::evm::evm_address::EvmAddress", + "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2", + "metadataTypeId": 76 + }, + { + "type": "u16", + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + }, + { + "type": "u256", + "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e" + }, + { + "type": "u32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "type": "u64", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "type": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "metadataTypes": [ + { + "type": "(_, _)", + "metadataTypeId": 0, + "components": [ + { + "name": "__tuple_element", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "__tuple_element", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + ] + }, + { + "type": "(_, _)", + "metadataTypeId": 1, + "components": [ + { + "name": "__tuple_element", + "typeId": "84877f6e98274b9e4721db68b4c0bdb9e52b8e9572c5bd7811c07a41ced882c7" + }, + { + "name": "__tuple_element", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + ] + }, + { + "type": "(_, _)", + "metadataTypeId": 2, + "components": [ + { + "name": "__tuple_element", + "typeId": "84877f6e98274b9e4721db68b4c0bdb9e52b8e9572c5bd7811c07a41ced882c7" + }, + { + "name": "__tuple_element", + "typeId": "84877f6e98274b9e4721db68b4c0bdb9e52b8e9572c5bd7811c07a41ced882c7" + } + ] + }, + { + "type": "(_, _)", + "metadataTypeId": 3, + "components": [ + { + "name": "__tuple_element", + "typeId": 56 + }, + { + "name": "__tuple_element", + "typeId": 75, + "typeArguments": [ + { + "name": "", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + } + ] + }, + { + "type": "(_, _)", + "metadataTypeId": 4, + "components": [ + { + "name": "__tuple_element", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "__tuple_element", + "typeId": 56 + } + ] + }, + { + "type": "(_, _)", + "metadataTypeId": 5, + "components": [ + { + "name": "__tuple_element", + "typeId": 75, + "typeArguments": [ + { + "name": "", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "name": "__tuple_element", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "(_, _)", + "metadataTypeId": 6, + "components": [ + { + "name": "__tuple_element", + "typeId": 75, + "typeArguments": [ + { + "name": "", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "name": "__tuple_element", + "typeId": 75, + "typeArguments": [ + { + "name": "", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + } + ] + }, + { + "type": "(_, _)", + "metadataTypeId": 7, + "components": [ + { + "name": "__tuple_element", + "typeId": 34 + }, + { + "name": "__tuple_element", + "typeId": 35 + } + ] + }, + { + "type": "(_, _)", + "metadataTypeId": 8, + "components": [ + { + "name": "__tuple_element", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "name": "__tuple_element", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "(_, _, _)", + "metadataTypeId": 9, + "components": [ + { + "name": "__tuple_element", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "__tuple_element", + "typeId": 75, + "typeArguments": [ + { + "name": "", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "name": "__tuple_element", + "typeId": 75, + "typeArguments": [ + { + "name": "", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + } + ] + }, + { + "type": "(_, _, _)", + "metadataTypeId": 10, + "components": [ + { + "name": "__tuple_element", + "typeId": 68 + }, + { + "name": "__tuple_element", + "typeId": 68 + }, + { + "name": "__tuple_element", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + ] + }, + { + "type": "(_, _, _)", + "metadataTypeId": 11, + "components": [ + { + "name": "__tuple_element", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "__tuple_element", + "typeId": 57, + "typeArguments": [ + { + "name": "", + "typeId": 57, + "typeArguments": [ + { + "name": "", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + } + ] + }, + { + "name": "__tuple_element", + "typeId": 44 + } + ] + }, + { + "type": "(_, _, _)", + "metadataTypeId": 12, + "components": [ + { + "name": "__tuple_element", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "__tuple_element", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "__tuple_element", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "type": "(_, _, _, _)", + "metadataTypeId": 13, + "components": [ + { + "name": "__tuple_element", + "typeId": 51, + "typeArguments": [ + { + "name": "", + "typeId": 17 + }, + { + "name": "", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "name": "__tuple_element", + "typeId": 22 + }, + { + "name": "__tuple_element", + "typeId": 1 + }, + { + "name": "__tuple_element", + "typeId": 56 + } + ] + }, + { + "type": "[_; 1]", + "metadataTypeId": 14, + "components": [ + { + "name": "__array_element", + "typeId": 75, + "typeArguments": [ + { + "name": "", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ] + } + ] + }, + { + "type": "[_; 2]", + "metadataTypeId": 15, + "components": [ + { + "name": "__array_element", + "typeId": 51, + "typeArguments": [ + { + "name": "", + "typeId": 57, + "typeArguments": [ + { + "name": "", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "name": "", + "typeId": 43 + } + ] + } + ] + }, + { + "type": "[_; 2]", + "metadataTypeId": 16, + "components": [ + { + "name": "__array_element", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "[_; 3]", + "metadataTypeId": 17, + "components": [ + { + "name": "__array_element", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "[_; 3]", + "metadataTypeId": 18, + "components": [ + { + "name": "__array_element", + "typeId": 56 + } + ] + }, + { + "type": "[_; 3]", + "metadataTypeId": 19, + "components": [ + { + "name": "__array_element", + "typeId": 51, + "typeArguments": [ + { + "name": "", + "typeId": 36 + }, + { + "name": "", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + } + ] + }, + { + "type": "[_; 3]", + "metadataTypeId": 20, + "components": [ + { + "name": "__array_element", + "typeId": 28 + } + ] + }, + { + "type": "[_; 3]", + "metadataTypeId": 21, + "components": [ + { + "name": "__array_element", + "typeId": 34 + } + ] + }, + { + "type": "[_; 4]", + "metadataTypeId": 22, + "components": [ + { + "name": "__array_element", + "typeId": 51, + "typeArguments": [ + { + "name": "", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + ] + } + ] + }, + { + "type": "[_; 4]", + "metadataTypeId": 23, + "components": [ + { + "name": "__array_element", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "type": "[_; 5]", + "metadataTypeId": 24, + "components": [ + { + "name": "__array_element", + "typeId": 32, + "typeArguments": [ + { + "name": "", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + } + ] + }, + { + "type": "enum abi-library::ExternalEnum", + "metadataTypeId": 25, + "components": [ + { + "name": "A", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "B", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum data_structures::EnumDoubleGeneric", + "metadataTypeId": 26, + "components": [ + { + "name": "a", + "typeId": 38 + }, + { + "name": "b", + "typeId": 39 + } + ], + "typeParameters": [ + 38, + 39 + ] + }, + { + "type": "enum data_structures::EnumWithBuiltinType", + "metadataTypeId": 27, + "components": [ + { + "name": "a", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "name": "b", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "enum data_structures::EnumWithNative", + "metadataTypeId": 28, + "components": [ + { + "name": "Checked", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "Pending", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum data_structures::EnumWithStructs", + "metadataTypeId": 29, + "components": [ + { + "name": "a", + "typeId": 28 + }, + { + "name": "b", + "typeId": 56 + }, + { + "name": "c", + "typeId": 51, + "typeArguments": [ + { + "name": "", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "", + "typeId": 56 + } + ] + } + ] + }, + { + "type": "enum data_structures::EnumWithVector", + "metadataTypeId": 30, + "components": [ + { + "name": "a", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "b", + "typeId": 75, + "typeArguments": [ + { + "name": "", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + } + ] + }, + { + "type": "enum std::identity::Identity", + "metadataTypeId": 31, + "components": [ + { + "name": "Address", + "typeId": 67 + }, + { + "name": "ContractId", + "typeId": 72 + } + ] + }, + { + "type": "enum std::option::Option", + "metadataTypeId": 32, + "components": [ + { + "name": "None", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "Some", + "typeId": 37 + } + ], + "typeParameters": [ + 37 + ] + }, + { + "type": "enum std::result::Result", + "metadataTypeId": 33, + "components": [ + { + "name": "Ok", + "typeId": 37 + }, + { + "name": "Err", + "typeId": 34 + } + ], + "typeParameters": [ + 37, + 34 + ] + }, + { + "type": "generic E", + "metadataTypeId": 34 + }, + { + "type": "generic F", + "metadataTypeId": 35 + }, + { + "type": "generic K", + "metadataTypeId": 36 + }, + { + "type": "generic T", + "metadataTypeId": 37 + }, + { + "type": "generic T1", + "metadataTypeId": 38 + }, + { + "type": "generic T2", + "metadataTypeId": 39 + }, + { + "type": "generic U", + "metadataTypeId": 40 + }, + { + "type": "generic V", + "metadataTypeId": 41 + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 42 + }, + { + "type": "str[1]", + "metadataTypeId": 43 + }, + { + "type": "str[3]", + "metadataTypeId": 44 + }, + { + "type": "struct abi-library::ExternalStruct", + "metadataTypeId": 45, + "components": [ + { + "name": "value", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct data_structures::Configurables", + "metadataTypeId": 46, + "components": [ + { + "name": "U8_VALUE", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "BOOL_VALUE", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "name": "B256_VALUE", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "OPTION_U8_VALUE", + "typeId": 32, + "typeArguments": [ + { + "name": "", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "name": "GENERIC_STRUCT_VALUE", + "typeId": 51, + "typeArguments": [ + { + "name": "", + "typeId": 51, + "typeArguments": [ + { + "name": "", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "", + "typeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + } + ] + }, + { + "name": "", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ] + } + ] + }, + { + "type": "struct data_structures::StructA", + "metadataTypeId": 47, + "components": [ + { + "name": "propA1", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "type": "struct data_structures::StructB", + "metadataTypeId": 48, + "components": [ + { + "name": "propB1", + "typeId": 47 + }, + { + "name": "propB2", + "typeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + } + ] + }, + { + "type": "struct data_structures::StructC", + "metadataTypeId": 49, + "components": [ + { + "name": "propC1", + "typeId": 47 + }, + { + "name": "propC2", + "typeId": 75, + "typeArguments": [ + { + "name": "", + "typeId": 48 + } + ] + }, + { + "name": "propC3", + "typeId": 50, + "typeArguments": [ + { + "name": "", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "", + "typeId": 53, + "typeArguments": [ + { + "name": "", + "typeId": 43 + } + ] + } + ] + } + ] + }, + { + "type": "struct data_structures::StructD", + "metadataTypeId": 50, + "components": [ + { + "name": "propD1", + "typeId": 75, + "typeArguments": [ + { + "name": "", + "typeId": 52, + "typeArguments": [ + { + "name": "", + "typeId": 37 + } + ] + } + ] + }, + { + "name": "propD2", + "typeId": 40 + }, + { + "name": "propD3", + "typeId": 41 + } + ], + "typeParameters": [ + 37, + 40, + 41 + ] + }, + { + "type": "struct data_structures::StructDoubleGeneric", + "metadataTypeId": 51, + "components": [ + { + "name": "a", + "typeId": 38 + }, + { + "name": "b", + "typeId": 39 + } + ], + "typeParameters": [ + 38, + 39 + ] + }, + { + "type": "struct data_structures::StructE", + "metadataTypeId": 52, + "components": [ + { + "name": "propE1", + "typeId": 47 + }, + { + "name": "propE2", + "typeId": 48 + }, + { + "name": "propE3", + "typeId": 37 + } + ], + "typeParameters": [ + 37 + ] + }, + { + "type": "struct data_structures::StructF", + "metadataTypeId": 53, + "components": [ + { + "name": "propF1", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "propF2", + "typeId": 37 + } + ], + "typeParameters": [ + 37 + ] + }, + { + "type": "struct data_structures::StructG", + "metadataTypeId": 54, + "components": [ + { + "name": "propG1", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "type": "struct data_structures::StructGenericWithEnum", + "metadataTypeId": 55, + "components": [ + { + "name": "a", + "typeId": 38 + }, + { + "name": "b", + "typeId": 26, + "typeArguments": [ + { + "name": "", + "typeId": 38 + }, + { + "name": "", + "typeId": 39 + } + ] + } + ], + "typeParameters": [ + 38, + 39 + ] + }, + { + "type": "struct data_structures::StructSimple", + "metadataTypeId": 56, + "components": [ + { + "name": "a", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "name": "b", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ] + }, + { + "type": "struct data_structures::StructSingleGeneric", + "metadataTypeId": 57, + "components": [ + { + "name": "a", + "typeId": 37 + } + ], + "typeParameters": [ + 37 + ] + }, + { + "type": "struct data_structures::StructWithEnumArray", + "metadataTypeId": 58, + "components": [ + { + "name": "a", + "typeId": 20 + } + ] + }, + { + "type": "struct data_structures::StructWithGenericArray", + "metadataTypeId": 59, + "components": [ + { + "name": "a", + "typeId": 19 + } + ], + "typeParameters": [ + 36 + ] + }, + { + "type": "struct data_structures::StructWithImplicitGenerics", + "metadataTypeId": 60, + "components": [ + { + "name": "a", + "typeId": 21 + }, + { + "name": "b", + "typeId": 7 + } + ], + "typeParameters": [ + 34, + 35 + ] + }, + { + "type": "struct data_structures::StructWithMultiOption", + "metadataTypeId": 61, + "components": [ + { + "name": "a", + "typeId": 24 + } + ] + }, + { + "type": "struct data_structures::StructWithNestedArray", + "metadataTypeId": 62, + "components": [ + { + "name": "a", + "typeId": 15 + } + ] + }, + { + "type": "struct data_structures::StructWithNestedStruct", + "metadataTypeId": 63, + "components": [ + { + "name": "a", + "typeId": 51, + "typeArguments": [ + { + "name": "", + "typeId": 57, + "typeArguments": [ + { + "name": "", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "name": "", + "typeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + } + ] + } + ] + }, + { + "type": "struct data_structures::StructWithNestedTuple", + "metadataTypeId": 64, + "components": [ + { + "name": "a", + "typeId": 11 + } + ] + }, + { + "type": "struct data_structures::StructWithSingleOption", + "metadataTypeId": 65, + "components": [ + { + "name": "a", + "typeId": 32, + "typeArguments": [ + { + "name": "", + "typeId": 61 + } + ] + } + ] + }, + { + "type": "struct data_structures::StructWithVector", + "metadataTypeId": 66, + "components": [ + { + "name": "a", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "b", + "typeId": 75, + "typeArguments": [ + { + "name": "", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + } + ] + }, + { + "type": "struct std::address::Address", + "metadataTypeId": 67, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct std::asset_id::AssetId", + "metadataTypeId": 68, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct std::b512::B512", + "metadataTypeId": 69, + "components": [ + { + "name": "bits", + "typeId": 16 + } + ] + }, + { + "type": "struct std::bytes::Bytes", + "metadataTypeId": 70, + "components": [ + { + "name": "buf", + "typeId": 71 + }, + { + "name": "len", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct std::bytes::RawBytes", + "metadataTypeId": 71, + "components": [ + { + "name": "ptr", + "typeId": 42 + }, + { + "name": "cap", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct std::contract_id::ContractId", + "metadataTypeId": 72, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct std::string::String", + "metadataTypeId": 73, + "components": [ + { + "name": "bytes", + "typeId": 70 + } + ] + }, + { + "type": "struct std::vec::RawVec", + "metadataTypeId": 74, + "components": [ + { + "name": "ptr", + "typeId": 42 + }, + { + "name": "cap", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "typeParameters": [ + 37 + ] + }, + { + "type": "struct std::vec::Vec", + "metadataTypeId": 75, + "components": [ + { + "name": "buf", + "typeId": 74, + "typeArguments": [ + { + "name": "", + "typeId": 37 + } + ] + }, + { + "name": "len", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "typeParameters": [ + 37 + ] + }, + { + "type": "struct std::vm::evm::evm_address::EvmAddress", + "metadataTypeId": 76, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + } + ], + "functions": [ + { + "inputs": [], + "name": "configurables", + "output": "69d4f1cc5ce793681d98a55ab013f42ab56260131d39af6c1e71a5f3531557bc", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "y", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + ], + "name": "multi_arg_b256_bool", + "output": "d5f6ab61fc224aae1bf15a89ab88840ed54e312a76a9735d1f60d4d0d1fae640", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "7bdc2c1e9c4b8576fdf5be24c5c6569cba3a8feaba3755ed2b95d646a33c73e2" + }, + { + "name": "y", + "concreteTypeId": "b22807669faa58263e636f6e2d194df8ddbc6686bb4ea14ee28005fa30adbe85" + }, + { + "name": "z", + "concreteTypeId": "a1e229302ed2f092752a6bc4fbe66bb9305e0802b1b01ecc5e1d59356702e956" + }, + { + "name": "a", + "concreteTypeId": "ef937135956e37401e0bc90406ca8becda92d1b4e387fe938ddef8d27ee192a1" + } + ], + "name": "multi_arg_complex", + "output": "343f07ddcd75b9385bc193e0419f2e89c75fad67cbf4ad1b36a01a136620817e", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "84877f6e98274b9e4721db68b4c0bdb9e52b8e9572c5bd7811c07a41ced882c7" + }, + { + "name": "y", + "concreteTypeId": "84877f6e98274b9e4721db68b4c0bdb9e52b8e9572c5bd7811c07a41ced882c7" + } + ], + "name": "multi_arg_str_str", + "output": "30022fd7ad3fda4035d30e4d86b705d4870924d4b4fe054624d2561fa12bb33e", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "ef937135956e37401e0bc90406ca8becda92d1b4e387fe938ddef8d27ee192a1" + }, + { + "name": "y", + "concreteTypeId": "27a0fb3d3a821e04e7a3f17ab6a617f0eb10f11e6eeb0f2c0ff9e6237207319e" + } + ], + "name": "multi_arg_struct_vector", + "output": "5ebb7c8cdd38d1f676f9c7089a2da12b27114ee3771c2047f3295d4d30f8fd2c", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "y", + "concreteTypeId": "d5bfe1d4e1ace20166c9b50cadd47e862020561bde24f5189cfc2723f5ed76f4" + }, + { + "name": "z", + "concreteTypeId": "d5bfe1d4e1ace20166c9b50cadd47e862020561bde24f5189cfc2723f5ed76f4" + } + ], + "name": "multi_arg_u32_vector_vector", + "output": "18034e13b18b71de3c7e12f8f10a7bd48a23870e0dbb46eaf10faeb26d70f000", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "y", + "concreteTypeId": "ef937135956e37401e0bc90406ca8becda92d1b4e387fe938ddef8d27ee192a1" + } + ], + "name": "multi_arg_u64_struct", + "output": "0088c28967dbcdaa34626c7e915e44b2afe72f12415f0e31edc0b5ce70e7c6dc", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "y", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "name": "multi_arg_u64_u64", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "27a0fb3d3a821e04e7a3f17ab6a617f0eb10f11e6eeb0f2c0ff9e6237207319e" + }, + { + "name": "y", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ], + "name": "multi_arg_vector_b256", + "output": "52e2726988c7da304606fbe4ed696efac04beb29e9a22e15778f8a0539c9cb94", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "27a0fb3d3a821e04e7a3f17ab6a617f0eb10f11e6eeb0f2c0ff9e6237207319e" + }, + { + "name": "y", + "concreteTypeId": "27a0fb3d3a821e04e7a3f17ab6a617f0eb10f11e6eeb0f2c0ff9e6237207319e" + } + ], + "name": "multi_arg_vector_vector", + "output": "87a4626758542d7b6a03099839e440a052a4d5a00e3abfdf22bcc564ca19a4fd", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "f597b637c3b0f588fb8d7086c6f4735caa3122b85f0423b82e489f9bb58e2308" + } + ], + "name": "types_address", + "output": "f597b637c3b0f588fb8d7086c6f4735caa3122b85f0423b82e489f9bb58e2308", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "a95e1fcceb1451b8a76471f593f66c4a52ca04bde3c227c746ad7aaf988de5c6" + } + ], + "name": "types_alias_tuple_with_native_types", + "output": "a95e1fcceb1451b8a76471f593f66c4a52ca04bde3c227c746ad7aaf988de5c6", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "f28afa065fc5de602456160c4155d4de7d9a61e85a995d209a14eab0b34bd6b4" + } + ], + "name": "types_array", + "output": "f28afa065fc5de602456160c4155d4de7d9a61e85a995d209a14eab0b34bd6b4", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "38f2594527b516dab2c81b31356901226242d7c32554877e36797c6b23969237" + } + ], + "name": "types_array_struct", + "output": "38f2594527b516dab2c81b31356901226242d7c32554877e36797c6b23969237", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "b8164e36cce9d14142824b5cc55aebc1272036775b966af82c49c78aff114006" + } + ], + "name": "types_array_with_generic_struct", + "output": "b8164e36cce9d14142824b5cc55aebc1272036775b966af82c49c78aff114006", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "593b39347cc381516d8ed1f8e5e628a8d455bd3f833bd9dfdd5165ba16f9f980" + } + ], + "name": "types_array_with_vector", + "output": "593b39347cc381516d8ed1f8e5e628a8d455bd3f833bd9dfdd5165ba16f9f980", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974" + } + ], + "name": "types_asset_id", + "output": "c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ], + "name": "types_b256", + "output": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "745e252e80bec590efc3999ae943f07ccea4d5b45b00bb6575499b64abdd3322" + } + ], + "name": "types_b512", + "output": "745e252e80bec590efc3999ae943f07ccea4d5b45b00bb6575499b64abdd3322", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + } + ], + "name": "types_bool", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "types_bytes", + "output": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" + } + ], + "name": "types_contract_id", + "output": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "58ae0e9c51da476db1149dd48b1cda83a12187df4c049f8df5021f0b1696fb93" + } + ], + "name": "types_enum", + "output": "58ae0e9c51da476db1149dd48b1cda83a12187df4c049f8df5021f0b1696fb93", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "9a24373d8ce7688609717fd5a9b75360cd8a6bdb224ae095f0c05cc891cadd42" + } + ], + "name": "types_enum_external", + "output": "9a24373d8ce7688609717fd5a9b75360cd8a6bdb224ae095f0c05cc891cadd42", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "2136f16aedeec1ab7f1d912c57cc0566e86c36f20a2cb313e3d679cead6a0e61" + } + ], + "name": "types_enum_with_builtin_type", + "output": "2136f16aedeec1ab7f1d912c57cc0566e86c36f20a2cb313e3d679cead6a0e61", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "9ed6dede3ae1e66e0f951e860e863f77fb9b9499f4666a1123bf244c4a201669" + } + ], + "name": "types_enum_with_structs", + "output": "9ed6dede3ae1e66e0f951e860e863f77fb9b9499f4666a1123bf244c4a201669", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "0272d5aecccd33822994b7be1494b72ec9ad860e4cb51f043deda7ac1e2cae26" + } + ], + "name": "types_enum_with_vector", + "output": "0272d5aecccd33822994b7be1494b72ec9ad860e4cb51f043deda7ac1e2cae26", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2" + } + ], + "name": "types_evm_address", + "output": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "d0ed93cd57cc3dfb1c119b22bf63f5d215122402536127bf17087ca6d8186307" + } + ], + "name": "types_generic_enum", + "output": "d0ed93cd57cc3dfb1c119b22bf63f5d215122402536127bf17087ca6d8186307", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "types_identity_address", + "output": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "types_identity_contract_id", + "output": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "2da102c46c7263beeed95818cd7bee801716ba8303dddafdcd0f6c9efda4a0f1" + } + ], + "name": "types_option", + "output": "2da102c46c7263beeed95818cd7bee801716ba8303dddafdcd0f6c9efda4a0f1", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "25616ce23be3ca41fd26f8c546c053ec256f8fb5593036f60c9c417e86dcc92e" + } + ], + "name": "types_option_struct", + "output": "25616ce23be3ca41fd26f8c546c053ec256f8fb5593036f60c9c417e86dcc92e", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "1e1c7c52c1c7a9901681337f8669555f62aac58911332c9ff6b4ea8e73786570" + } + ], + "name": "types_raw_slice", + "output": "1e1c7c52c1c7a9901681337f8669555f62aac58911332c9ff6b4ea8e73786570", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "b3131b4c08c16cfa55b3150d587c3afa3e4cdebe0399f3f599fa160baaa64e0c" + } + ], + "name": "types_result", + "output": "9891b1ee451eed790368ea3969e3c8f550efa87de489b5d7b933e2290800791b", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c" + } + ], + "name": "types_std_string", + "output": "9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "84877f6e98274b9e4721db68b4c0bdb9e52b8e9572c5bd7811c07a41ced882c7" + } + ], + "name": "types_str", + "output": "84877f6e98274b9e4721db68b4c0bdb9e52b8e9572c5bd7811c07a41ced882c7", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a" + } + ], + "name": "types_str_slice", + "output": "8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "8986b78b19c146ced98454ffbe32d17f1e9e468128ba8dcb2a32f16aaf208db2" + } + ], + "name": "types_struct_double_generic", + "output": "8986b78b19c146ced98454ffbe32d17f1e9e468128ba8dcb2a32f16aaf208db2", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "c3a770db33c4e755ad3ba4586b9c10520511fb80b767feb57dd41da1a88f6978" + } + ], + "name": "types_struct_external", + "output": "c3a770db33c4e755ad3ba4586b9c10520511fb80b767feb57dd41da1a88f6978", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "7cbc352969caf2e9caa716d89c3be65e707447e2a197c779cc4ef382d0602de6" + } + ], + "name": "types_struct_generic", + "output": "7cbc352969caf2e9caa716d89c3be65e707447e2a197c779cc4ef382d0602de6", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "ef937135956e37401e0bc90406ca8becda92d1b4e387fe938ddef8d27ee192a1" + } + ], + "name": "types_struct_simple", + "output": "ef937135956e37401e0bc90406ca8becda92d1b4e387fe938ddef8d27ee192a1", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "29843de0bbb48b2d3c601b61823f2e106cfa5833e18b482571f1fa58b507a7ad" + } + ], + "name": "types_struct_with_array", + "output": "29843de0bbb48b2d3c601b61823f2e106cfa5833e18b482571f1fa58b507a7ad", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "d5266ee32061dbfec8c96f2ba8a054243875e4e6a586104d6366b11e3bc86f2e" + } + ], + "name": "types_struct_with_array_of_enums", + "output": "d5266ee32061dbfec8c96f2ba8a054243875e4e6a586104d6366b11e3bc86f2e", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "d0494e36b8daeafdf02dfbd1f65f82c66df872fb235c7fd2707fcd4147c6c292" + } + ], + "name": "types_struct_with_complex_nested_struct", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "549c0f0c43c9e33f7e958e0473d84e78eca4737f9f159c64614ca5dff2d91b60" + } + ], + "name": "types_struct_with_implicit_generics", + "output": "549c0f0c43c9e33f7e958e0473d84e78eca4737f9f159c64614ca5dff2d91b60", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "db8b04f624965fbfd7eb7dc3fc3c6a54a71d0019b37d4011a9350d1870136c9d" + }, + { + "name": "y", + "concreteTypeId": "9f074fde9cb9194b90bd208c8c95e709bfb1a5c736b063302e5639ce4daad5aa" + }, + { + "name": "z", + "concreteTypeId": "f219acbc9e3b812457419966b5454d10d51594afecacb87fb7745c9311b90012" + } + ], + "name": "types_struct_with_multiple_struct_params", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "e7807205e98b513a8beeb5bcf446f0b2d684d0dce6bfeff0f324fa31df1b8948" + } + ], + "name": "types_struct_with_nested_array", + "output": "e7807205e98b513a8beeb5bcf446f0b2d684d0dce6bfeff0f324fa31df1b8948", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "8651356d9584265a78cb58de01c22d405dfc7006ea2f5f74fddcbe3f047f109a" + } + ], + "name": "types_struct_with_nested_struct", + "output": "8651356d9584265a78cb58de01c22d405dfc7006ea2f5f74fddcbe3f047f109a", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "d042dca573565aa653542415397934b3e95452917664e04d27c32a22091aa9a5" + } + ], + "name": "types_struct_with_nested_tuple", + "output": "d042dca573565aa653542415397934b3e95452917664e04d27c32a22091aa9a5", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "089f2c4466ef415255917812d05776ebcb386be53e5f94bdad1ca8095f02845c" + } + ], + "name": "types_struct_with_single_option", + "output": "089f2c4466ef415255917812d05776ebcb386be53e5f94bdad1ca8095f02845c", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "fc0793960700fbabd2722134cff2a546743fc832b98d89aac1ec30fc669fd698" + } + ], + "name": "types_struct_with_tuple", + "output": "fc0793960700fbabd2722134cff2a546743fc832b98d89aac1ec30fc669fd698", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "eac45984af86a06e11e1c5ff744bc1242e004db8404308cb7e574b4c2afaf621" + } + ], + "name": "types_struct_with_vector", + "output": "eac45984af86a06e11e1c5ff744bc1242e004db8404308cb7e574b4c2afaf621", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "79239b6d6f2383e2cfbaf4da7fdf7ee7fb59b7bf517acfff2d9433e9e76e8fc4" + } + ], + "name": "types_tuple", + "output": "79239b6d6f2383e2cfbaf4da7fdf7ee7fb59b7bf517acfff2d9433e9e76e8fc4", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "6f875be99a39d9920569678a34ffce676a6c3e14b958910db250b9cb4957157f" + } + ], + "name": "types_tuple_complex", + "output": "6f875be99a39d9920569678a34ffce676a6c3e14b958910db250b9cb4957157f", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "a95e1fcceb1451b8a76471f593f66c4a52ca04bde3c227c746ad7aaf988de5c6" + } + ], + "name": "types_tuple_with_native_types", + "output": "a95e1fcceb1451b8a76471f593f66c4a52ca04bde3c227c746ad7aaf988de5c6", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + } + ], + "name": "types_u16", + "output": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e" + } + ], + "name": "types_u256", + "output": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "types_u32", + "output": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "name": "types_u64", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "name": "types_u8", + "output": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "y", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "z", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "a", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ], + "name": "types_value_then_value_then_void_then_void", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "y", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ], + "name": "types_value_then_void", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "y", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "z", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "name": "types_value_then_void_then_value", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "6b97d5d738359413c9fac402aced252c23902c28382469ffe27f07381e9f6f31" + } + ], + "name": "types_vector_boolean", + "output": "6b97d5d738359413c9fac402aced252c23902c28382469ffe27f07381e9f6f31", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "e06c82714c52b8afd2293d5d37d05783d09d71c956311c6050ac012cab06364e" + } + ], + "name": "types_vector_inside_vector", + "output": "e06c82714c52b8afd2293d5d37d05783d09d71c956311c6050ac012cab06364e", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "c0de252b9f65a31c6d03071b4b18a935c88c5bb0b2401a447fd30d342fd5a04d" + } + ], + "name": "types_vector_option", + "output": "c0de252b9f65a31c6d03071b4b18a935c88c5bb0b2401a447fd30d342fd5a04d", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "27a0fb3d3a821e04e7a3f17ab6a617f0eb10f11e6eeb0f2c0ff9e6237207319e" + } + ], + "name": "types_vector_u8", + "output": "27a0fb3d3a821e04e7a3f17ab6a617f0eb10f11e6eeb0f2c0ff9e6237207319e", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "9168b00268bbefd158090041178f058b032504f76c4b9644157d5d6b5b183468" + } + ], + "name": "types_vector_with_struct", + "output": "9168b00268bbefd158090041178f058b032504f76c4b9644157d5d6b5b183468", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ], + "name": "types_void", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": null + }, + { + "inputs": [ + { + "name": "x", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "y", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "name": "types_void_then_value", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": null + } + ], + "loggedTypes": [ + { + "logId": "8961848586872524460", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "logId": "13213829929622723620", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "logId": "15417698811679754926", + "concreteTypeId": "d5f6ab61fc224aae1bf15a89ab88840ed54e312a76a9735d1f60d4d0d1fae640" + }, + { + "logId": "3764736462721235256", + "concreteTypeId": "343f07ddcd75b9385bc193e0419f2e89c75fad67cbf4ad1b36a01a136620817e" + }, + { + "logId": "10098701174489624218", + "concreteTypeId": "8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a" + }, + { + "logId": "3459380067145079360", + "concreteTypeId": "30022fd7ad3fda4035d30e4d86b705d4870924d4b4fe054624d2561fa12bb33e" + }, + { + "logId": "6826186604658872822", + "concreteTypeId": "5ebb7c8cdd38d1f676f9c7089a2da12b27114ee3771c2047f3295d4d30f8fd2c" + }, + { + "logId": "1730312528330453470", + "concreteTypeId": "18034e13b18b71de3c7e12f8f10a7bd48a23870e0dbb46eaf10faeb26d70f000" + }, + { + "logId": "38494492241415594", + "concreteTypeId": "0088c28967dbcdaa34626c7e915e44b2afe72f12415f0e31edc0b5ce70e7c6dc" + }, + { + "logId": "1515152261580153489", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "logId": "5972461853438630448", + "concreteTypeId": "52e2726988c7da304606fbe4ed696efac04beb29e9a22e15778f8a0539c9cb94" + }, + { + "logId": "9774045287303884155", + "concreteTypeId": "87a4626758542d7b6a03099839e440a052a4d5a00e3abfdf22bcc564ca19a4fd" + }, + { + "logId": "17696813611398264200", + "concreteTypeId": "f597b637c3b0f588fb8d7086c6f4735caa3122b85f0423b82e489f9bb58e2308" + }, + { + "logId": "12204227005198389688", + "concreteTypeId": "a95e1fcceb1451b8a76471f593f66c4a52ca04bde3c227c746ad7aaf988de5c6" + }, + { + "logId": "17477056209248181856", + "concreteTypeId": "f28afa065fc5de602456160c4155d4de7d9a61e85a995d209a14eab0b34bd6b4" + }, + { + "logId": "4103440364041737946", + "concreteTypeId": "38f2594527b516dab2c81b31356901226242d7c32554877e36797c6b23969237" + }, + { + "logId": "13264875749739450689", + "concreteTypeId": "b8164e36cce9d14142824b5cc55aebc1272036775b966af82c49c78aff114006" + }, + { + "logId": "6429795790595785041", + "concreteTypeId": "593b39347cc381516d8ed1f8e5e628a8d455bd3f833bd9dfdd5165ba16f9f980" + }, + { + "logId": "13866877265493744985", + "concreteTypeId": "c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974" + }, + { + "logId": "8385180437869151632", + "concreteTypeId": "745e252e80bec590efc3999ae943f07ccea4d5b45b00bb6575499b64abdd3322" + }, + { + "logId": "14832741149864513620", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "logId": "3008693953818743129", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" + }, + { + "logId": "6390060985836259181", + "concreteTypeId": "58ae0e9c51da476db1149dd48b1cda83a12187df4c049f8df5021f0b1696fb93" + }, + { + "logId": "11107063318498994310", + "concreteTypeId": "9a24373d8ce7688609717fd5a9b75360cd8a6bdb224ae095f0c05cc891cadd42" + }, + { + "logId": "2393365693554672043", + "concreteTypeId": "2136f16aedeec1ab7f1d912c57cc0566e86c36f20a2cb313e3d679cead6a0e61" + }, + { + "logId": "11445580549060683374", + "concreteTypeId": "9ed6dede3ae1e66e0f951e860e863f77fb9b9499f4666a1123bf244c4a201669" + }, + { + "logId": "176438282157896578", + "concreteTypeId": "0272d5aecccd33822994b7be1494b72ec9ad860e4cb51f043deda7ac1e2cae26" + }, + { + "logId": "406535131101199095", + "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2" + }, + { + "logId": "15054851639520017915", + "concreteTypeId": "d0ed93cd57cc3dfb1c119b22bf63f5d215122402536127bf17087ca6d8186307" + }, + { + "logId": "12356980511120185571", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + }, + { + "logId": "3287912245613454270", + "concreteTypeId": "2da102c46c7263beeed95818cd7bee801716ba8303dddafdcd0f6c9efda4a0f1" + }, + { + "logId": "2693553771067460161", + "concreteTypeId": "25616ce23be3ca41fd26f8c546c053ec256f8fb5593036f60c9c417e86dcc92e" + }, + { + "logId": "2169745815365986704", + "concreteTypeId": "1e1c7c52c1c7a9901681337f8669555f62aac58911332c9ff6b4ea8e73786570" + }, + { + "logId": "11132648958528852192", + "concreteTypeId": "9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c" + }, + { + "logId": "9549741647838268318", + "concreteTypeId": "84877f6e98274b9e4721db68b4c0bdb9e52b8e9572c5bd7811c07a41ced882c7" + }, + { + "logId": "9909809838135789262", + "concreteTypeId": "8986b78b19c146ced98454ffbe32d17f1e9e468128ba8dcb2a32f16aaf208db2" + }, + { + "logId": "14098361245275318101", + "concreteTypeId": "c3a770db33c4e755ad3ba4586b9c10520511fb80b767feb57dd41da1a88f6978" + }, + { + "logId": "8988117408309506793", + "concreteTypeId": "7cbc352969caf2e9caa716d89c3be65e707447e2a197c779cc4ef382d0602de6" + }, + { + "logId": "17263266271595476800", + "concreteTypeId": "ef937135956e37401e0bc90406ca8becda92d1b4e387fe938ddef8d27ee192a1" + }, + { + "logId": "2991584087911992109", + "concreteTypeId": "29843de0bbb48b2d3c601b61823f2e106cfa5833e18b482571f1fa58b507a7ad" + }, + { + "logId": "15359085500973571070", + "concreteTypeId": "d5266ee32061dbfec8c96f2ba8a054243875e4e6a586104d6366b11e3bc86f2e" + }, + { + "logId": "6096764540904137535", + "concreteTypeId": "549c0f0c43c9e33f7e958e0473d84e78eca4737f9f159c64614ca5dff2d91b60" + }, + { + "logId": "16681458389498941754", + "concreteTypeId": "e7807205e98b513a8beeb5bcf446f0b2d684d0dce6bfeff0f324fa31df1b8948" + }, + { + "logId": "9678575818972079706", + "concreteTypeId": "8651356d9584265a78cb58de01c22d405dfc7006ea2f5f74fddcbe3f047f109a" + }, + { + "logId": "15006799511514667686", + "concreteTypeId": "d042dca573565aa653542415397934b3e95452917664e04d27c32a22091aa9a5" + }, + { + "logId": "621263945896771922", + "concreteTypeId": "089f2c4466ef415255917812d05776ebcb386be53e5f94bdad1ca8095f02845c" + }, + { + "logId": "18160646294966696875", + "concreteTypeId": "fc0793960700fbabd2722134cff2a546743fc832b98d89aac1ec30fc669fd698" + }, + { + "logId": "16916744526725816430", + "concreteTypeId": "eac45984af86a06e11e1c5ff744bc1242e004db8404308cb7e574b4c2afaf621" + }, + { + "logId": "8728991397092492258", + "concreteTypeId": "79239b6d6f2383e2cfbaf4da7fdf7ee7fb59b7bf517acfff2d9433e9e76e8fc4" + }, + { + "logId": "8036493118938929554", + "concreteTypeId": "6f875be99a39d9920569678a34ffce676a6c3e14b958910db250b9cb4957157f" + }, + { + "logId": "2992671284987479467", + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + }, + { + "logId": "1970142151624111756", + "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e" + }, + { + "logId": "15520703124961489725", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "logId": "14454674236531057292", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "logId": "7752900403879318547", + "concreteTypeId": "6b97d5d738359413c9fac402aced252c23902c28382469ffe27f07381e9f6f31" + }, + { + "logId": "16171443785104013487", + "concreteTypeId": "e06c82714c52b8afd2293d5d37d05783d09d71c956311c6050ac012cab06364e" + }, + { + "logId": "13897586369399989020", + "concreteTypeId": "c0de252b9f65a31c6d03071b4b18a935c88c5bb0b2401a447fd30d342fd5a04d" + }, + { + "logId": "2855558404146077188", + "concreteTypeId": "27a0fb3d3a821e04e7a3f17ab6a617f0eb10f11e6eeb0f2c0ff9e6237207319e" + }, + { + "logId": "10477818057471029201", + "concreteTypeId": "9168b00268bbefd158090041178f058b032504f76c4b9644157d5d6b5b183468" + }, + { + "logId": "3330666440490685604", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ], + "messagesTypes": [], + "configurables": [ + { + "name": "U8_VALUE", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "offset": 119320 + }, + { + "name": "BOOL_VALUE", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "offset": 119288 + }, + { + "name": "B256_VALUE", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "offset": 119256 + }, + { + "name": "OPTION_U8_VALUE", + "concreteTypeId": "2da102c46c7263beeed95818cd7bee801716ba8303dddafdcd0f6c9efda4a0f1", + "offset": 119304 + }, + { + "name": "GENERIC_STRUCT_VALUE", + "concreteTypeId": "08dbec793087c5686c1a493513b158a999bb653126ee51151dfa85fa683edce5", + "offset": 119296 + } + ] +}; \ No newline at end of file diff --git a/packages/fuel-gauge/src/abi/fixtures/contracts/contract-bytecode.txt b/packages/fuel-gauge/src/abi/fixtures/contracts/contract-bytecode.txt new file mode 100644 index 00000000000..3739f9803fe --- /dev/null +++ b/packages/fuel-gauge/src/abi/fixtures/contracts/contract-bytecode.txt @@ -0,0 +1,14 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + + +import { decompressBytecode } from "fuels"; + +export const bytecode = decompressBytecode("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"); \ No newline at end of file diff --git a/packages/fuel-gauge/src/abi/fixtures/contracts/contract-factory.txt b/packages/fuel-gauge/src/abi/fixtures/contracts/contract-factory.txt new file mode 100644 index 00000000000..e5137e5143c --- /dev/null +++ b/packages/fuel-gauge/src/abi/fixtures/contracts/contract-factory.txt @@ -0,0 +1,35 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + + +import { ContractFactory } from 'fuels'; +import type { Account, Provider, DeployContractOptions } from 'fuels'; +import { AbiContract } from './AbiContract'; +import { bytecode } from './AbiContract-bytecode'; +import { abi } from './AbiContract-abi'; +import { storageSlots } from './AbiContract-storage-slots'; + +export class AbiContractFactory extends ContractFactory { + + static readonly bytecode = bytecode; + static readonly storageSlots = storageSlots; + + constructor(accountOrProvider: Account | Provider) { + super(bytecode, abi, accountOrProvider, AbiContractFactory.storageSlots); + } + + static deploy ( + wallet: Account, + options: DeployContractOptions = {} + ) { + const factory = new AbiContractFactory(wallet); + return factory.deploy(options); + } +} diff --git a/packages/fuel-gauge/src/abi/fixtures/contracts/contract-index.txt b/packages/fuel-gauge/src/abi/fixtures/contracts/contract-index.txt new file mode 100644 index 00000000000..efaa702960c --- /dev/null +++ b/packages/fuel-gauge/src/abi/fixtures/contracts/contract-index.txt @@ -0,0 +1,13 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + + +export { AbiContract } from './AbiContract'; +export { AbiContractFactory } from './AbiContractFactory'; diff --git a/packages/fuel-gauge/src/abi/fixtures/contracts/contract-storage-slots.txt b/packages/fuel-gauge/src/abi/fixtures/contracts/contract-storage-slots.txt new file mode 100644 index 00000000000..c97394029a2 --- /dev/null +++ b/packages/fuel-gauge/src/abi/fixtures/contracts/contract-storage-slots.txt @@ -0,0 +1,14 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + + +import type { StorageSlot } from 'fuels'; + +export const storageSlots: StorageSlot[] = []; \ No newline at end of file diff --git a/packages/fuel-gauge/src/abi/fixtures/contracts/contract-types.txt b/packages/fuel-gauge/src/abi/fixtures/contracts/contract-types.txt new file mode 100644 index 00000000000..e59afc5265d --- /dev/null +++ b/packages/fuel-gauge/src/abi/fixtures/contracts/contract-types.txt @@ -0,0 +1,373 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + + +import type { BN, BigNumberish, Bytes, EvmAddress, RawSlice, StdString, StrSlice } from 'fuels'; +import type { ArrayOfLength, Enum, Option, Result } from '../common'; + +export enum EnumWithNative { Checked = 'Checked', Pending = 'Pending' }; +export enum ExternalEnum { A = 'A', B = 'B' }; + +export type AddressInput = { bits: string }; +export type AddressOutput = AddressInput; +export type AssetIdInput = { bits: string }; +export type AssetIdOutput = AssetIdInput; +export type ConfigurablesInput = { U8_VALUE: BigNumberish, BOOL_VALUE: boolean, B256_VALUE: string, OPTION_U8_VALUE: Option, GENERIC_STRUCT_VALUE: StructDoubleGenericInput, BigNumberish> }; +export type ConfigurablesOutput = { U8_VALUE: number, BOOL_VALUE: boolean, B256_VALUE: string, OPTION_U8_VALUE: Option, GENERIC_STRUCT_VALUE: StructDoubleGenericOutput, number> }; +export type ContractIdInput = { bits: string }; +export type ContractIdOutput = ContractIdInput; +export type EnumDoubleGenericInput = Enum<{ a: T1, b: T2 }>; +export type EnumDoubleGenericOutput = EnumDoubleGenericInput; +export type EnumWithBuiltinTypeInput = Enum<{ a: boolean, b: BigNumberish }>; +export type EnumWithBuiltinTypeOutput = Enum<{ a: boolean, b: BN }>; +export type EnumWithStructsInput = Enum<{ a: EnumWithNative, b: StructSimpleInput, c: StructDoubleGenericInput }>; +export type EnumWithStructsOutput = Enum<{ a: EnumWithNative, b: StructSimpleOutput, c: StructDoubleGenericOutput }>; +export type EnumWithVectorInput = Enum<{ a: BigNumberish, b: BigNumberish[] }>; +export type EnumWithVectorOutput = Enum<{ a: number, b: number[] }>; +export type ExternalStructInput = { value: BigNumberish }; +export type ExternalStructOutput = { value: BN }; +export type IdentityInput = Enum<{ Address: AddressInput, ContractId: ContractIdInput }>; +export type IdentityOutput = Enum<{ Address: AddressOutput, ContractId: ContractIdOutput }>; +export type StructAInput = { propA1: BigNumberish }; +export type StructAOutput = { propA1: number }; +export type StructBInput = { propB1: StructAInput, propB2: BigNumberish }; +export type StructBOutput = { propB1: StructAOutput, propB2: number }; +export type StructCInput = { propC1: StructAInput, propC2: StructBInput[], propC3: StructDInput> }; +export type StructCOutput = { propC1: StructAOutput, propC2: StructBOutput[], propC3: StructDOutput> }; +export type StructDInput = { propD1: StructEInput[], propD2: U, propD3: V }; +export type StructDOutput = { propD1: StructEOutput[], propD2: U, propD3: V }; +export type StructDoubleGenericInput = { a: T1, b: T2 }; +export type StructDoubleGenericOutput = StructDoubleGenericInput; +export type StructEInput = { propE1: StructAInput, propE2: StructBInput, propE3: T }; +export type StructEOutput = { propE1: StructAOutput, propE2: StructBOutput, propE3: T }; +export type StructFInput = { propF1: BigNumberish, propF2: T }; +export type StructFOutput = { propF1: BN, propF2: T }; +export type StructGInput = { propG1: BigNumberish }; +export type StructGOutput = { propG1: number }; +export type StructGenericWithEnumInput = { a: T1, b: EnumDoubleGenericInput }; +export type StructGenericWithEnumOutput = { a: T1, b: EnumDoubleGenericOutput }; +export type StructSimpleInput = { a: boolean, b: BigNumberish }; +export type StructSimpleOutput = { a: boolean, b: number }; +export type StructSingleGenericInput = { a: T }; +export type StructSingleGenericOutput = StructSingleGenericInput; +export type StructWithEnumArrayInput = { a: ArrayOfLength }; +export type StructWithEnumArrayOutput = StructWithEnumArrayInput; +export type StructWithGenericArrayInput = { a: ArrayOfLength, 3> }; +export type StructWithGenericArrayOutput = { a: ArrayOfLength, 3> }; +export type StructWithImplicitGenericsInput = { a: ArrayOfLength, b: [E, F] }; +export type StructWithImplicitGenericsOutput = StructWithImplicitGenericsInput; +export type StructWithMultiOptionInput = { a: ArrayOfLength, 5> }; +export type StructWithMultiOptionOutput = { a: ArrayOfLength, 5> }; +export type StructWithNestedArrayInput = { a: ArrayOfLength, string>, 2> }; +export type StructWithNestedArrayOutput = { a: ArrayOfLength, string>, 2> }; +export type StructWithNestedStructInput = { a: StructDoubleGenericInput, BigNumberish> }; +export type StructWithNestedStructOutput = { a: StructDoubleGenericOutput, number> }; +export type StructWithNestedTupleInput = { a: [BigNumberish, StructSingleGenericInput>, string] }; +export type StructWithNestedTupleOutput = { a: [number, StructSingleGenericOutput>, string] }; +export type StructWithSingleOptionInput = { a: Option }; +export type StructWithSingleOptionOutput = { a: Option }; +export type StructWithVectorInput = { a: BigNumberish, b: BigNumberish[] }; +export type StructWithVectorOutput = { a: number, b: number[] }; + +export interface AbiContractTypes { + functions: { + configurables: { + inputs: []; + output: ConfigurablesOutput; + }; + multi_arg_b256_bool: { + inputs: [x: string, y: boolean]; + output: [string, boolean]; + }; + multi_arg_complex: { + inputs: [x: StructDoubleGenericInput, BigNumberish>, y: ArrayOfLength, 4>, z: [string, boolean], a: StructSimpleInput]; + output: [StructDoubleGenericOutput, number>, ArrayOfLength, 4>, [string, boolean], StructSimpleOutput]; + }; + multi_arg_str_str: { + inputs: [x: string, y: string]; + output: [string, string]; + }; + multi_arg_struct_vector: { + inputs: [x: StructSimpleInput, y: BigNumberish[]]; + output: [StructSimpleOutput, number[]]; + }; + multi_arg_u32_vector_vector: { + inputs: [x: BigNumberish, y: BigNumberish[], z: BigNumberish[]]; + output: [number, BN[], BN[]]; + }; + multi_arg_u64_struct: { + inputs: [x: BigNumberish, y: StructSimpleInput]; + output: [BN, StructSimpleOutput]; + }; + multi_arg_u64_u64: { + inputs: [x: BigNumberish, y: BigNumberish]; + output: BN; + }; + multi_arg_vector_b256: { + inputs: [x: BigNumberish[], y: string]; + output: [number[], string]; + }; + multi_arg_vector_vector: { + inputs: [x: BigNumberish[], y: BigNumberish[]]; + output: [number[], number[]]; + }; + types_address: { + inputs: [x: AddressInput]; + output: AddressOutput; + }; + types_alias_tuple_with_native_types: { + inputs: [x: [AssetIdInput, AssetIdInput, boolean]]; + output: [AssetIdOutput, AssetIdOutput, boolean]; + }; + types_array: { + inputs: [x: ArrayOfLength]; + output: ArrayOfLength; + }; + types_array_struct: { + inputs: [x: ArrayOfLength]; + output: ArrayOfLength; + }; + types_array_with_generic_struct: { + inputs: [x: ArrayOfLength, string>, 2>]; + output: ArrayOfLength, string>, 2>; + }; + types_array_with_vector: { + inputs: [x: ArrayOfLength]; + output: ArrayOfLength; + }; + types_asset_id: { + inputs: [x: AssetIdInput]; + output: AssetIdOutput; + }; + types_b256: { + inputs: [x: string]; + output: string; + }; + types_b512: { + inputs: [x: string]; + output: string; + }; + types_bool: { + inputs: [x: boolean]; + output: boolean; + }; + types_bytes: { + inputs: [x: Bytes]; + output: Bytes; + }; + types_contract_id: { + inputs: [x: ContractIdInput]; + output: ContractIdOutput; + }; + types_enum: { + inputs: [x: EnumWithNative]; + output: EnumWithNative; + }; + types_enum_external: { + inputs: [x: ExternalEnum]; + output: ExternalEnum; + }; + types_enum_with_builtin_type: { + inputs: [x: EnumWithBuiltinTypeInput]; + output: EnumWithBuiltinTypeOutput; + }; + types_enum_with_structs: { + inputs: [x: EnumWithStructsInput]; + output: EnumWithStructsOutput; + }; + types_enum_with_vector: { + inputs: [x: EnumWithVectorInput]; + output: EnumWithVectorOutput; + }; + types_evm_address: { + inputs: [x: EvmAddress]; + output: EvmAddress; + }; + types_generic_enum: { + inputs: [x: EnumDoubleGenericInput]; + output: EnumDoubleGenericOutput; + }; + types_identity_address: { + inputs: [x: IdentityInput]; + output: IdentityOutput; + }; + types_identity_contract_id: { + inputs: [x: IdentityInput]; + output: IdentityOutput; + }; + types_option: { + inputs: [x?: Option]; + output: Option; + }; + types_option_struct: { + inputs: [x?: Option]; + output: Option; + }; + types_raw_slice: { + inputs: [x: RawSlice]; + output: RawSlice; + }; + types_result: { + inputs: [x: Result]; + output: Result; + }; + types_std_string: { + inputs: [x: StdString]; + output: StdString; + }; + types_str: { + inputs: [x: string]; + output: string; + }; + types_str_slice: { + inputs: [x: StrSlice]; + output: StrSlice; + }; + types_struct_double_generic: { + inputs: [x: StructGenericWithEnumInput]; + output: StructGenericWithEnumOutput; + }; + types_struct_external: { + inputs: [x: ExternalStructInput]; + output: ExternalStructOutput; + }; + types_struct_generic: { + inputs: [x: StructSingleGenericInput]; + output: StructSingleGenericOutput; + }; + types_struct_simple: { + inputs: [x: StructSimpleInput]; + output: StructSimpleOutput; + }; + types_struct_with_array: { + inputs: [x: StructWithGenericArrayInput]; + output: StructWithGenericArrayOutput; + }; + types_struct_with_array_of_enums: { + inputs: [x: StructWithEnumArrayInput]; + output: StructWithEnumArrayOutput; + }; + types_struct_with_complex_nested_struct: { + inputs: [x: StructDInput>]; + output: boolean; + }; + types_struct_with_implicit_generics: { + inputs: [x: StructWithImplicitGenericsInput]; + output: StructWithImplicitGenericsOutput; + }; + types_struct_with_multiple_struct_params: { + inputs: [x: StructAInput, y: StructBInput, z: StructCInput]; + output: boolean; + }; + types_struct_with_nested_array: { + inputs: [x: StructWithNestedArrayInput]; + output: StructWithNestedArrayOutput; + }; + types_struct_with_nested_struct: { + inputs: [x: StructWithNestedStructInput]; + output: StructWithNestedStructOutput; + }; + types_struct_with_nested_tuple: { + inputs: [x: StructWithNestedTupleInput]; + output: StructWithNestedTupleOutput; + }; + types_struct_with_single_option: { + inputs: [x: StructWithSingleOptionInput]; + output: StructWithSingleOptionOutput; + }; + types_struct_with_tuple: { + inputs: [x: StructSingleGenericInput<[boolean, BigNumberish]>]; + output: StructSingleGenericOutput<[boolean, BN]>; + }; + types_struct_with_vector: { + inputs: [x: StructWithVectorInput]; + output: StructWithVectorOutput; + }; + types_tuple: { + inputs: [x: [BigNumberish, BigNumberish, BigNumberish]]; + output: [number, number, number]; + }; + types_tuple_complex: { + inputs: [x: [BigNumberish, StructSingleGenericInput>, string]]; + output: [number, StructSingleGenericOutput>, string]; + }; + types_tuple_with_native_types: { + inputs: [x: [AssetIdInput, AssetIdInput, boolean]]; + output: [AssetIdOutput, AssetIdOutput, boolean]; + }; + types_u16: { + inputs: [x: BigNumberish]; + output: number; + }; + types_u256: { + inputs: [x: BigNumberish]; + output: BN; + }; + types_u32: { + inputs: [x: BigNumberish]; + output: number; + }; + types_u64: { + inputs: [x: BigNumberish]; + output: BN; + }; + types_u8: { + inputs: [x: BigNumberish]; + output: number; + }; + types_value_then_value_then_void_then_void: { + inputs: [x: BigNumberish, y: BigNumberish, z?: undefined, a?: undefined]; + output: void; + }; + types_value_then_void: { + inputs: [x: BigNumberish, y?: undefined]; + output: void; + }; + types_value_then_void_then_value: { + inputs: [x: BigNumberish, y: undefined, z: BigNumberish]; + output: void; + }; + types_vector_boolean: { + inputs: [x: boolean[]]; + output: boolean[]; + }; + types_vector_inside_vector: { + inputs: [x: BigNumberish[][]]; + output: number[][]; + }; + types_vector_option: { + inputs: [x: StructWithMultiOptionInput[]]; + output: StructWithMultiOptionOutput[]; + }; + types_vector_u8: { + inputs: [x: BigNumberish[]]; + output: number[]; + }; + types_vector_with_struct: { + inputs: [x: StructSimpleInput[]]; + output: StructSimpleOutput[]; + }; + types_void: { + inputs: [x?: undefined]; + output: void; + }; + types_void_then_value: { + inputs: [x: undefined, y: BigNumberish]; + output: void; + }; + }; + configurables: Partial<{ + U8_VALUE: BigNumberish; + BOOL_VALUE: boolean; + B256_VALUE: string; + OPTION_U8_VALUE: Option; + GENERIC_STRUCT_VALUE: StructDoubleGenericInput, BigNumberish>; + }>; +} \ No newline at end of file diff --git a/packages/fuel-gauge/src/abi/fixtures/contracts/contract.txt b/packages/fuel-gauge/src/abi/fixtures/contracts/contract.txt new file mode 100644 index 00000000000..d3736139668 --- /dev/null +++ b/packages/fuel-gauge/src/abi/fixtures/contracts/contract.txt @@ -0,0 +1,42 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + + +import { Contract, Interface } from "fuels"; +import type { Address, Account, Provider } from 'fuels'; +import type { AbiContractTypes as Types } from './AbiContractTypes'; +import type { InterfaceFunctionMapper, ProgramFunctionMapper } from '../common'; +import { abi } from './AbiContract-abi'; + +export * from './AbiContractTypes'; + +export type AbiContractConfigurables = Types['configurables']; + +export class AbiContractInterface extends Interface { + declare functions: InterfaceFunctionMapper; + + constructor() { + super(abi); + } +} + +export class AbiContract extends Contract { + declare interface: AbiContractInterface; + declare functions: ProgramFunctionMapper; + + public static readonly abi = abi; + + constructor( + id: string | Address, + accountOrProvider: Account | Provider, + ) { + super(id, abi, accountOrProvider); + } +} \ No newline at end of file diff --git a/packages/fuel-gauge/src/abi/fixtures/index.txt b/packages/fuel-gauge/src/abi/fixtures/index.txt new file mode 100644 index 00000000000..a20ac585213 --- /dev/null +++ b/packages/fuel-gauge/src/abi/fixtures/index.txt @@ -0,0 +1,14 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + + +export * from './contracts'; +export * from './predicates'; +export * from './scripts'; diff --git a/packages/fuel-gauge/src/abi/fixtures/predicates/predicate-abi.txt b/packages/fuel-gauge/src/abi/fixtures/predicates/predicate-abi.txt new file mode 100644 index 00000000000..c9ecda3ce96 --- /dev/null +++ b/packages/fuel-gauge/src/abi/fixtures/predicates/predicate-abi.txt @@ -0,0 +1,283 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + + +export const abi = { + "programType": "predicate", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "b256", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum MyGenericEnum", + "concreteTypeId": "9d8b215a39e5f5f10fc294290b6ea401edbd53056cfe6e0c9331157abdbc87d0", + "metadataTypeId": 1, + "typeArguments": [ + "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + ] + }, + { + "type": "enum std::option::Option", + "concreteTypeId": "2da102c46c7263beeed95818cd7bee801716ba8303dddafdcd0f6c9efda4a0f1", + "metadataTypeId": 2, + "typeArguments": [ + "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + ] + }, + { + "type": "enum std::result::Result,u64>", + "concreteTypeId": "85dace7aaa469c8bb476be79ddec34883ef101b3cde470636f47e299bfcdc3da", + "metadataTypeId": 3, + "typeArguments": [ + "c397d34a45fb343f8315bb5af5eed88da9f13347c765e2d86089d99dbf952ef2", + "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + ] + }, + { + "type": "str[4]", + "concreteTypeId": "94f0fa95c830be5e4f711963e83259fe7e8bc723278ab6ec34449e791a99b53a" + }, + { + "type": "struct Configurables", + "concreteTypeId": "2770b4001b55ea9452a58b5063175844ad76bfd1bc30288792fe8962ef9d4169", + "metadataTypeId": 7 + }, + { + "type": "struct MyGenericStruct", + "concreteTypeId": "c397d34a45fb343f8315bb5af5eed88da9f13347c765e2d86089d99dbf952ef2", + "metadataTypeId": 8, + "typeArguments": [ + "94f0fa95c830be5e4f711963e83259fe7e8bc723278ab6ec34449e791a99b53a" + ] + }, + { + "type": "struct Validation", + "concreteTypeId": "c7cf8c2be429c961ccb5c32a2951a58f1bb2a4f748ffac2206d4d1761082beaa", + "metadataTypeId": 9 + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "9b3ded85b5c6e502acc8b7834d5d6df0460764a7a47837eb2b32d4566c4d477b", + "metadataTypeId": 11, + "typeArguments": [ + "c7cf8c2be429c961ccb5c32a2951a58f1bb2a4f748ffac2206d4d1761082beaa" + ] + }, + { + "type": "u16", + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + }, + { + "type": "u64", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "type": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "metadataTypes": [ + { + "type": "()", + "metadataTypeId": 0 + }, + { + "type": "enum MyGenericEnum", + "metadataTypeId": 1, + "components": [ + { + "name": "a", + "typeId": 5 + } + ], + "typeParameters": [ + 5 + ] + }, + { + "type": "enum std::option::Option", + "metadataTypeId": 2, + "components": [ + { + "name": "None", + "typeId": 0 + }, + { + "name": "Some", + "typeId": 5 + } + ], + "typeParameters": [ + 5 + ] + }, + { + "type": "enum std::result::Result", + "metadataTypeId": 3, + "components": [ + { + "name": "Ok", + "typeId": 5 + }, + { + "name": "Err", + "typeId": 4 + } + ], + "typeParameters": [ + 5, + 4 + ] + }, + { + "type": "generic E", + "metadataTypeId": 4 + }, + { + "type": "generic T", + "metadataTypeId": 5 + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 6 + }, + { + "type": "struct Configurables", + "metadataTypeId": 7, + "components": [ + { + "name": "U8_VALUE", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "B256_VALUE", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct MyGenericStruct", + "metadataTypeId": 8, + "components": [ + { + "name": "a", + "typeId": 5 + } + ], + "typeParameters": [ + 5 + ] + }, + { + "type": "struct Validation", + "metadataTypeId": 9, + "components": [ + { + "name": "has_account", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "name": "total_complete", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct std::vec::RawVec", + "metadataTypeId": 10, + "components": [ + { + "name": "ptr", + "typeId": 6 + }, + { + "name": "cap", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "typeParameters": [ + 5 + ] + }, + { + "type": "struct std::vec::Vec", + "metadataTypeId": 11, + "components": [ + { + "name": "buf", + "typeId": 10, + "typeArguments": [ + { + "name": "", + "typeId": 5 + } + ] + }, + { + "name": "len", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "typeParameters": [ + 5 + ] + } + ], + "functions": [ + { + "inputs": [ + { + "name": "configurables", + "concreteTypeId": "2770b4001b55ea9452a58b5063175844ad76bfd1bc30288792fe8962ef9d4169" + }, + { + "name": "vec", + "concreteTypeId": "9b3ded85b5c6e502acc8b7834d5d6df0460764a7a47837eb2b32d4566c4d477b" + }, + { + "name": "enm", + "concreteTypeId": "9d8b215a39e5f5f10fc294290b6ea401edbd53056cfe6e0c9331157abdbc87d0" + }, + { + "name": "opt", + "concreteTypeId": "2da102c46c7263beeed95818cd7bee801716ba8303dddafdcd0f6c9efda4a0f1" + }, + { + "name": "res", + "concreteTypeId": "85dace7aaa469c8bb476be79ddec34883ef101b3cde470636f47e299bfcdc3da" + } + ], + "name": "main", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": null + } + ], + "loggedTypes": [], + "messagesTypes": [], + "configurables": [ + { + "name": "U8_VALUE", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "offset": 1936 + }, + { + "name": "B256_VALUE", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "offset": 1904 + } + ] +}; \ No newline at end of file diff --git a/packages/fuel-gauge/src/abi/fixtures/predicates/predicate-index.txt b/packages/fuel-gauge/src/abi/fixtures/predicates/predicate-index.txt new file mode 100644 index 00000000000..c3352040e5a --- /dev/null +++ b/packages/fuel-gauge/src/abi/fixtures/predicates/predicate-index.txt @@ -0,0 +1,12 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + + +export { AbiPredicate } from './AbiPredicate'; diff --git a/packages/fuel-gauge/src/abi/fixtures/predicates/predicate-types.txt b/packages/fuel-gauge/src/abi/fixtures/predicates/predicate-types.txt new file mode 100644 index 00000000000..4c8c57d7ecd --- /dev/null +++ b/packages/fuel-gauge/src/abi/fixtures/predicates/predicate-types.txt @@ -0,0 +1,32 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + + +import type { BN, BigNumberish } from 'fuels'; +import type { Enum, Option, Result } from '../common'; + + +export type ConfigurablesInput = { U8_VALUE: BigNumberish, B256_VALUE: string }; +export type ConfigurablesOutput = { U8_VALUE: number, B256_VALUE: string }; +export type MyGenericEnumInput = Enum<{ a: T }>; +export type MyGenericEnumOutput = MyGenericEnumInput; +export type MyGenericStructInput = { a: T }; +export type MyGenericStructOutput = MyGenericStructInput; +export type ValidationInput = { has_account: boolean, total_complete: BigNumberish }; +export type ValidationOutput = { has_account: boolean, total_complete: BN }; + +export interface AbiPredicateTypes { + inputs: [configurables: ConfigurablesInput, vec: ValidationInput[], enm: MyGenericEnumInput, opt: Option, res: Result, BigNumberish>]; + output: boolean; + configurables: Partial<{ + U8_VALUE: BigNumberish; + B256_VALUE: string; + }>; +} \ No newline at end of file diff --git a/packages/fuel-gauge/src/abi/fixtures/predicates/predicate.txt b/packages/fuel-gauge/src/abi/fixtures/predicates/predicate.txt new file mode 100644 index 00000000000..4f6d898662e --- /dev/null +++ b/packages/fuel-gauge/src/abi/fixtures/predicates/predicate.txt @@ -0,0 +1,42 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + + +import { Predicate } from 'fuels'; +import type { PredicateParams } from 'fuels'; +import { abi } from './AbiPredicate-abi'; +import { bytecode } from './AbiPredicate-bytecode'; +import type { AbiPredicateTypes as Types } from './AbiPredicateTypes'; + +export * from './AbiPredicateTypes'; + +export type AbiPredicateInputs = Types['inputs']; +export type AbiPredicateOutput = Types['output']; +export type AbiPredicateConfigurables = Types['configurables']; + +export type AbiPredicateParameters = Omit< + PredicateParams< + Types['inputs'], + Types['configurables'] + >, + 'abi' | 'bytecode' +>; + +export class AbiPredicate extends Predicate< + Types['inputs'], + Types['configurables'] +> { + public static readonly abi = abi; + public static readonly bytecode = bytecode; + + constructor(params: AbiPredicateParameters) { + super({ abi, bytecode, ...params }); + } +} \ No newline at end of file diff --git a/packages/fuel-gauge/src/abi/fixtures/scripts/script-abi.txt b/packages/fuel-gauge/src/abi/fixtures/scripts/script-abi.txt new file mode 100644 index 00000000000..713d91f674f --- /dev/null +++ b/packages/fuel-gauge/src/abi/fixtures/scripts/script-abi.txt @@ -0,0 +1,283 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + + +export const abi = { + "programType": "script", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "b256", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum MyGenericEnum", + "concreteTypeId": "9d8b215a39e5f5f10fc294290b6ea401edbd53056cfe6e0c9331157abdbc87d0", + "metadataTypeId": 1, + "typeArguments": [ + "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + ] + }, + { + "type": "enum std::option::Option", + "concreteTypeId": "2da102c46c7263beeed95818cd7bee801716ba8303dddafdcd0f6c9efda4a0f1", + "metadataTypeId": 2, + "typeArguments": [ + "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + ] + }, + { + "type": "enum std::result::Result,u64>", + "concreteTypeId": "85dace7aaa469c8bb476be79ddec34883ef101b3cde470636f47e299bfcdc3da", + "metadataTypeId": 3, + "typeArguments": [ + "c397d34a45fb343f8315bb5af5eed88da9f13347c765e2d86089d99dbf952ef2", + "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + ] + }, + { + "type": "str[4]", + "concreteTypeId": "94f0fa95c830be5e4f711963e83259fe7e8bc723278ab6ec34449e791a99b53a" + }, + { + "type": "struct Configurables", + "concreteTypeId": "2770b4001b55ea9452a58b5063175844ad76bfd1bc30288792fe8962ef9d4169", + "metadataTypeId": 7 + }, + { + "type": "struct MyGenericStruct", + "concreteTypeId": "c397d34a45fb343f8315bb5af5eed88da9f13347c765e2d86089d99dbf952ef2", + "metadataTypeId": 8, + "typeArguments": [ + "94f0fa95c830be5e4f711963e83259fe7e8bc723278ab6ec34449e791a99b53a" + ] + }, + { + "type": "struct Validation", + "concreteTypeId": "c7cf8c2be429c961ccb5c32a2951a58f1bb2a4f748ffac2206d4d1761082beaa", + "metadataTypeId": 9 + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "9b3ded85b5c6e502acc8b7834d5d6df0460764a7a47837eb2b32d4566c4d477b", + "metadataTypeId": 11, + "typeArguments": [ + "c7cf8c2be429c961ccb5c32a2951a58f1bb2a4f748ffac2206d4d1761082beaa" + ] + }, + { + "type": "u16", + "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef" + }, + { + "type": "u64", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "type": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "metadataTypes": [ + { + "type": "()", + "metadataTypeId": 0 + }, + { + "type": "enum MyGenericEnum", + "metadataTypeId": 1, + "components": [ + { + "name": "a", + "typeId": 5 + } + ], + "typeParameters": [ + 5 + ] + }, + { + "type": "enum std::option::Option", + "metadataTypeId": 2, + "components": [ + { + "name": "None", + "typeId": 0 + }, + { + "name": "Some", + "typeId": 5 + } + ], + "typeParameters": [ + 5 + ] + }, + { + "type": "enum std::result::Result", + "metadataTypeId": 3, + "components": [ + { + "name": "Ok", + "typeId": 5 + }, + { + "name": "Err", + "typeId": 4 + } + ], + "typeParameters": [ + 5, + 4 + ] + }, + { + "type": "generic E", + "metadataTypeId": 4 + }, + { + "type": "generic T", + "metadataTypeId": 5 + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 6 + }, + { + "type": "struct Configurables", + "metadataTypeId": 7, + "components": [ + { + "name": "U8_VALUE", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "name": "B256_VALUE", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct MyGenericStruct", + "metadataTypeId": 8, + "components": [ + { + "name": "a", + "typeId": 5 + } + ], + "typeParameters": [ + 5 + ] + }, + { + "type": "struct Validation", + "metadataTypeId": 9, + "components": [ + { + "name": "has_account", + "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "name": "total_complete", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct std::vec::RawVec", + "metadataTypeId": 10, + "components": [ + { + "name": "ptr", + "typeId": 6 + }, + { + "name": "cap", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "typeParameters": [ + 5 + ] + }, + { + "type": "struct std::vec::Vec", + "metadataTypeId": 11, + "components": [ + { + "name": "buf", + "typeId": 10, + "typeArguments": [ + { + "name": "", + "typeId": 5 + } + ] + }, + { + "name": "len", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "typeParameters": [ + 5 + ] + } + ], + "functions": [ + { + "inputs": [ + { + "name": "configurables", + "concreteTypeId": "2770b4001b55ea9452a58b5063175844ad76bfd1bc30288792fe8962ef9d4169" + }, + { + "name": "vec", + "concreteTypeId": "9b3ded85b5c6e502acc8b7834d5d6df0460764a7a47837eb2b32d4566c4d477b" + }, + { + "name": "enm", + "concreteTypeId": "9d8b215a39e5f5f10fc294290b6ea401edbd53056cfe6e0c9331157abdbc87d0" + }, + { + "name": "opt", + "concreteTypeId": "2da102c46c7263beeed95818cd7bee801716ba8303dddafdcd0f6c9efda4a0f1" + }, + { + "name": "res", + "concreteTypeId": "85dace7aaa469c8bb476be79ddec34883ef101b3cde470636f47e299bfcdc3da" + } + ], + "name": "main", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": null + } + ], + "loggedTypes": [], + "messagesTypes": [], + "configurables": [ + { + "name": "U8_VALUE", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "offset": 2360 + }, + { + "name": "B256_VALUE", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "offset": 2328 + } + ] +}; \ No newline at end of file diff --git a/packages/fuel-gauge/src/abi/fixtures/scripts/script-index.txt b/packages/fuel-gauge/src/abi/fixtures/scripts/script-index.txt new file mode 100644 index 00000000000..39aff230e0b --- /dev/null +++ b/packages/fuel-gauge/src/abi/fixtures/scripts/script-index.txt @@ -0,0 +1,12 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + + +export { AbiScript } from './AbiScript'; diff --git a/packages/fuel-gauge/src/abi/fixtures/scripts/script-types.txt b/packages/fuel-gauge/src/abi/fixtures/scripts/script-types.txt new file mode 100644 index 00000000000..84e911f7f88 --- /dev/null +++ b/packages/fuel-gauge/src/abi/fixtures/scripts/script-types.txt @@ -0,0 +1,32 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + + +import type { BN, BigNumberish } from 'fuels'; +import type { Enum, Option, Result } from '../common'; + + +export type ConfigurablesInput = { U8_VALUE: BigNumberish, B256_VALUE: string }; +export type ConfigurablesOutput = { U8_VALUE: number, B256_VALUE: string }; +export type MyGenericEnumInput = Enum<{ a: T }>; +export type MyGenericEnumOutput = MyGenericEnumInput; +export type MyGenericStructInput = { a: T }; +export type MyGenericStructOutput = MyGenericStructInput; +export type ValidationInput = { has_account: boolean, total_complete: BigNumberish }; +export type ValidationOutput = { has_account: boolean, total_complete: BN }; + +export interface AbiScriptTypes { + inputs: [configurables: ConfigurablesInput, vec: ValidationInput[], enm: MyGenericEnumInput, opt: Option, res: Result, BigNumberish>]; + output: boolean; + configurables: Partial<{ + U8_VALUE: BigNumberish; + B256_VALUE: string; + }>; +} \ No newline at end of file diff --git a/packages/fuel-gauge/src/abi/fixtures/scripts/script.txt b/packages/fuel-gauge/src/abi/fixtures/scripts/script.txt new file mode 100644 index 00000000000..2eeb2cdaa03 --- /dev/null +++ b/packages/fuel-gauge/src/abi/fixtures/scripts/script.txt @@ -0,0 +1,34 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + + +import { Script } from 'fuels'; +import type { Account } from 'fuels'; +import { abi } from './AbiScript-abi'; +import { bytecode } from './AbiScript-bytecode'; +import type { AbiScriptTypes as Types } from './AbiScriptTypes'; + +export * from './AbiScriptTypes'; + +export type AbiScriptInputs = Types['inputs']; +export type AbiScriptOutput = Types['output']; +export type AbiScriptConfigurables = Types['configurables']; + +export class AbiScript extends Script< + Types['inputs'], + Types['output'] +> { + public static readonly abi = abi; + public static readonly bytecode = bytecode; + + constructor(wallet: Account) { + super(bytecode, abi, wallet); + } +} \ No newline at end of file diff --git a/packages/fuel-gauge/src/abi/utils.ts b/packages/fuel-gauge/src/abi/utils.ts new file mode 100644 index 00000000000..cc08b4ff954 --- /dev/null +++ b/packages/fuel-gauge/src/abi/utils.ts @@ -0,0 +1,19 @@ +import { getForcProject } from '@fuel-ts/utils/test-utils'; +import { join } from 'path'; + +export enum AbiProjectsEnum { + ABI_CONTRACT = 'abi-contract', + ABI_PREDICATE = 'abi-predicate', + ABI_SCRIPT = 'abi-script', +} + +const forcProjectsDir = join(__dirname, '../../test/fixtures/forc-projects'); + +export const getAbiForcProject = (project: AbiProjectsEnum) => { + const result = getForcProject({ + projectDir: join(forcProjectsDir, project), + projectName: project, + build: 'release', + }); + return result; +}; diff --git a/packages/fuel-gauge/src/contract-factory.test.ts b/packages/fuel-gauge/src/contract-factory.test.ts index bfd3f176507..b42612b9115 100644 --- a/packages/fuel-gauge/src/contract-factory.test.ts +++ b/packages/fuel-gauge/src/contract-factory.test.ts @@ -135,7 +135,7 @@ describe('Contract Factory', () => { using contract = await launchTestContract({ factory: StorageTestContractFactory, - storageSlots: StorageTestContract.storageSlots, + storageSlots: StorageTestContractFactory.storageSlots, }); const call1 = await contract.functions.return_var1().call(); @@ -203,7 +203,7 @@ describe('Contract Factory', () => { const { waitForResult } = await factory.deploy({ storageSlots: [ - ...StorageTestContract.storageSlots, // initializing from storage_slots.json + ...StorageTestContractFactory.storageSlots, // initializing from storage_slots.json { key: '0000000000000000000000000000000000000000000000000000000000000001', value: b256 }, // Initializing manual value ], }); @@ -510,7 +510,7 @@ describe('Contract Factory', () => { ); const deploy = await factory.deployAsBlobTx({ - storageSlots: StorageTestContract.storageSlots, + storageSlots: StorageTestContractFactory.storageSlots, }); const { contract } = await deploy.waitForResult(); diff --git a/packages/fuel-gauge/src/coverage-contract.test.ts b/packages/fuel-gauge/src/coverage-contract.test.ts index 876c7ca207f..8cd440410f1 100644 --- a/packages/fuel-gauge/src/coverage-contract.test.ts +++ b/packages/fuel-gauge/src/coverage-contract.test.ts @@ -12,9 +12,11 @@ import { import { TestMessage, type LaunchTestNodeOptions } from 'fuels/test-utils'; import { CoverageContractFactory } from '../test/typegen/contracts'; -import type { MixedNativeEnumInput } from '../test/typegen/contracts/CoverageContract'; -import { SmallEnumInput } from '../test/typegen/contracts/Vectors'; -import type { Vec } from '../test/typegen/contracts/common'; +import { + ColorEnum, + type MixedNativeEnumInput, +} from '../test/typegen/contracts/CoverageContractTypes'; +import { SmallEnum } from '../test/typegen/contracts/VectorsTypes'; import { launchTestContract } from './utils'; @@ -26,18 +28,6 @@ const B256 = '0x000000000000000000000000000000000000000000000000000000000000002a const B512 = '0x059bc9c43ea1112f3eb2bd30415de72ed24c1c4416a1316f0f48cc6f958073f42a6d8c12e4829826316d8dcf444498717b5a2fbf27defac367271065f6a1d4a5'; -enum ColorEnumInput { - Red = 'Red', - Green = 'Green', - Blue = 'Blue', -} - -enum ColorEnumOutput { - Red = 'Red', - Green = 'Green', - Blue = 'Blue', -} - enum MixedNativeEnum { Native = 'Native', NotNative = 12, @@ -100,7 +90,7 @@ describe('Coverage Contract', { timeout: 15_000 }, () => { expect(result.value).toStrictEqual(expectedValue); - expectedValue = SmallEnumInput.Empty; + expectedValue = SmallEnum.Empty; call = await contractInstance.functions.get_empty_enum().call(); result = await call.waitForResult(); @@ -321,7 +311,7 @@ describe('Coverage Contract', { timeout: 15_000 }, () => { it('should test enum < 8 byte variable type', async () => { using contractInstance = await setupContract(); - const INPUT = SmallEnumInput.Empty; + const INPUT = SmallEnum.Empty; const { waitForResult } = await contractInstance.functions.echo_enum_small(INPUT).call(); const { value } = await waitForResult(); expect(value).toStrictEqual(INPUT); @@ -713,8 +703,9 @@ describe('Coverage Contract', { timeout: 15_000 }, () => { it('should test native enum [Red->Green]', async () => { using contractInstance = await setupContract(); - const INPUT: ColorEnumInput = ColorEnumInput.Red; - const OUTPUT: ColorEnumOutput = ColorEnumOutput.Green; + const INPUT = ColorEnum.Red; + const OUTPUT = ColorEnum.Green; + const { waitForResult } = await contractInstance.functions.color_enum(INPUT).call(); const { value } = await waitForResult(); @@ -724,8 +715,8 @@ describe('Coverage Contract', { timeout: 15_000 }, () => { it('should test native enum [Green->Blue]', async () => { using contractInstance = await setupContract(); - const INPUT: ColorEnumInput = ColorEnumInput.Green; - const OUTPUT: ColorEnumOutput = ColorEnumOutput.Blue; + const INPUT = ColorEnum.Green; + const OUTPUT = ColorEnum.Blue; const { waitForResult } = await contractInstance.functions.color_enum(INPUT).call(); const { value } = await waitForResult(); @@ -735,8 +726,8 @@ describe('Coverage Contract', { timeout: 15_000 }, () => { it('should test native enum [Blue->Red]', async () => { using contractInstance = await setupContract(); - const INPUT: ColorEnumInput = ColorEnumInput.Blue; - const OUTPUT: ColorEnumOutput = ColorEnumOutput.Red; + const INPUT = ColorEnum.Blue; + const OUTPUT = ColorEnum.Red; const { waitForResult } = await contractInstance.functions.color_enum(INPUT).call(); const { value } = await waitForResult(); @@ -817,10 +808,10 @@ describe('Coverage Contract', { timeout: 15_000 }, () => { expect(isStatusSuccess).toBeTruthy(); }); - it('should support array in vec', async () => { + it('should support vec in array', async () => { using contractInstance = await setupContract(); - const INPUT: [Vec, Vec] = [ + const INPUT: [Array, Array] = [ [0, 1, 2], [0, 1, 2], ]; @@ -864,14 +855,14 @@ describe('Coverage Contract', { timeout: 15_000 }, () => { contractInstance.functions.echo_b256_middle(INPUT_A, INPUT_B, INPUT_C, INPUT_D), contractInstance.functions.echo_u8(13), contractInstance.functions.echo_u8(23), - contractInstance.functions.echo_enum_small(SmallEnumInput.Empty), + contractInstance.functions.echo_enum_small(SmallEnum.Empty), contractInstance.functions.echo_b256_middle(INPUT_B, INPUT_A, INPUT_C, INPUT_D), ]) .call(); const { value: results } = await waitForResult(); - expect(results).toStrictEqual([INPUT_B, 13, 23, SmallEnumInput.Empty, INPUT_A]); + expect(results).toStrictEqual([INPUT_B, 13, 23, SmallEnum.Empty, INPUT_A]); }); it('should handle multiple calls [with vectors + stack data first]', async () => { @@ -886,7 +877,7 @@ describe('Coverage Contract', { timeout: 15_000 }, () => { .multiCall([ contractInstance.functions.echo_u8(1), contractInstance.functions.echo_u8(2), - contractInstance.functions.echo_enum_small(SmallEnumInput.Empty), + contractInstance.functions.echo_enum_small(SmallEnum.Empty), contractInstance.functions.echo_b256_middle(INPUT_A, INPUT_B, INPUT_C, INPUT_D), contractInstance.functions.echo_b256_middle(INPUT_B, INPUT_A, INPUT_C, INPUT_D), ]) @@ -894,7 +885,7 @@ describe('Coverage Contract', { timeout: 15_000 }, () => { const { value: results } = await waitForResult(); - expect(results).toStrictEqual([1, 2, SmallEnumInput.Empty, INPUT_B, INPUT_A]); + expect(results).toStrictEqual([1, 2, SmallEnum.Empty, INPUT_B, INPUT_A]); }); it('should handle an enum from a library', async () => { diff --git a/packages/fuel-gauge/src/min-gas.test.ts b/packages/fuel-gauge/src/min-gas.test.ts index 788244ada8d..19d08ccec08 100644 --- a/packages/fuel-gauge/src/min-gas.test.ts +++ b/packages/fuel-gauge/src/min-gas.test.ts @@ -42,7 +42,7 @@ describe('Minimum gas tests', () => { ); const { transactionRequest: request } = contractFactory.createTransactionRequest({ - storageSlots: CoverageContract.storageSlots, + storageSlots: CoverageContractFactory.storageSlots, }); const resources = await provider.getResourcesToSpend(wallet.address, [ diff --git a/packages/fuel-gauge/src/options.test.ts b/packages/fuel-gauge/src/options.test.ts index 15b1c3be5db..6e7cfd30178 100644 --- a/packages/fuel-gauge/src/options.test.ts +++ b/packages/fuel-gauge/src/options.test.ts @@ -1,9 +1,9 @@ import type { BigNumberish } from 'fuels'; import { launchTestNode } from 'fuels/test-utils'; +import type { Option } from '../test/typegen/common'; import type { DeepStructInput } from '../test/typegen/contracts/Options'; import { OptionsFactory } from '../test/typegen/contracts/OptionsFactory'; -import type { Option } from '../test/typegen/contracts/common'; import { launchTestContract } from './utils'; diff --git a/packages/fuel-gauge/src/recipes.test.ts b/packages/fuel-gauge/src/recipes.test.ts index 6fa4daec1ed..32e5343bb04 100644 --- a/packages/fuel-gauge/src/recipes.test.ts +++ b/packages/fuel-gauge/src/recipes.test.ts @@ -34,13 +34,13 @@ describe('recipes', () => { .proxy_target() .call(); const firstTarget = await waitForFirstTarget(); - expect(firstTarget.value.bits).toEqual(targetAddress); + expect(firstTarget.value?.bits).toEqual(targetAddress); const anotherProxy = new Src14OwnedProxy(proxyAddress, wallet); const { waitForResult: waitForAnotherTarget } = await anotherProxy.functions .proxy_target() .call(); const anotherTarget = await waitForAnotherTarget(); - expect(anotherTarget.value.bits).toEqual(targetAddress); + expect(anotherTarget.value?.bits).toEqual(targetAddress); }); }); diff --git a/packages/fuel-gauge/src/reentrant-contract-calls.test.ts b/packages/fuel-gauge/src/reentrant-contract-calls.test.ts index d7d56989587..914ab20888d 100644 --- a/packages/fuel-gauge/src/reentrant-contract-calls.test.ts +++ b/packages/fuel-gauge/src/reentrant-contract-calls.test.ts @@ -71,7 +71,7 @@ describe('Reentrant Contract Calls', () => { StorageTestContractFactory.bytecode, StorageTestContract.abi, wallet - ).deploy({ storageSlots: StorageTestContract.storageSlots }); + ).deploy({ storageSlots: StorageTestContractFactory.storageSlots }); const { contract: storageContract } = await deploy.waitForResult(); diff --git a/packages/fuel-gauge/src/script-with-configurable.test.ts b/packages/fuel-gauge/src/script-with-configurable.test.ts index 3fdb883659c..c2004172124 100644 --- a/packages/fuel-gauge/src/script-with-configurable.test.ts +++ b/packages/fuel-gauge/src/script-with-configurable.test.ts @@ -36,7 +36,9 @@ describe('Script With Configurable', () => { wallets: [wallet], } = launched; - const configurableConstants: Required = { FEE: 71 }; + const configurableConstants: Required = { + FEE: 71, + }; expect(configurableConstants.FEE).not.toEqual(defaultValues.FEE); @@ -57,7 +59,9 @@ describe('Script With Configurable', () => { wallets: [wallet], } = launched; - const configurableConstants: Required = { FEE: 35 }; + const configurableConstants: Required = { + FEE: 35, + }; const script = new ScriptWithConfigurable(wallet); diff --git a/packages/fuel-gauge/src/script-with-options.test.ts b/packages/fuel-gauge/src/script-with-options.test.ts index e47cd37c08f..ac0143e6734 100644 --- a/packages/fuel-gauge/src/script-with-options.test.ts +++ b/packages/fuel-gauge/src/script-with-options.test.ts @@ -3,7 +3,7 @@ import { bn } from 'fuels'; import { launchTestNode } from 'fuels/test-utils'; import { ScriptWithOptions } from '../test/typegen'; -import type { Option } from '../test/typegen/contracts/common'; +import type { Option } from '../test/typegen/common'; /** * @group node diff --git a/packages/fuel-gauge/src/script-with-vectors.test.ts b/packages/fuel-gauge/src/script-with-vectors.test.ts index 77c4daa804c..a24723eda5b 100644 --- a/packages/fuel-gauge/src/script-with-vectors.test.ts +++ b/packages/fuel-gauge/src/script-with-vectors.test.ts @@ -7,7 +7,7 @@ import { ScriptWithVectorAdvanced, ScriptWithVectorMixed, } from '../test/typegen'; -import { StateErrorInput, UserErrorInput } from '../test/typegen/scripts/ScriptWithVectorAdvanced'; +import { StateError, UserError } from '../test/typegen/scripts/ScriptWithVectorAdvanced'; /** * @group node @@ -144,15 +144,15 @@ describe('Script With Vectors', () => { ]; const errors = [ - { StateError: StateErrorInput.Void }, - { StateError: StateErrorInput.Pending }, - { StateError: StateErrorInput.Completed }, - { UserError: UserErrorInput.InsufficientPermissions }, - { UserError: UserErrorInput.Unauthorized }, - { UserError: UserErrorInput.Unauthorized }, - { UserError: UserErrorInput.Unauthorized }, - { UserError: UserErrorInput.Unauthorized }, - { UserError: UserErrorInput.Unauthorized }, + { StateError: StateError.Void }, + { StateError: StateError.Pending }, + { StateError: StateError.Completed }, + { UserError: UserError.InsufficientPermissions }, + { UserError: UserError.Unauthorized }, + { UserError: UserError.Unauthorized }, + { UserError: UserError.Unauthorized }, + { UserError: UserError.Unauthorized }, + { UserError: UserError.Unauthorized }, ]; const vectorOfStructs = [ diff --git a/packages/fuel-gauge/src/storage-test-contract.test.ts b/packages/fuel-gauge/src/storage-test-contract.test.ts index 64d59f4cafc..300b533f014 100644 --- a/packages/fuel-gauge/src/storage-test-contract.test.ts +++ b/packages/fuel-gauge/src/storage-test-contract.test.ts @@ -15,7 +15,7 @@ describe('StorageTestContract', () => { wallets: [wallet], } = launched; - const { storageSlots } = StorageTestContract; + const { storageSlots } = StorageTestContractFactory; const factory = new ContractFactory( StorageTestContractFactory.bytecode, @@ -96,7 +96,7 @@ describe('StorageTestContract', () => { }); it('should automatically load storage slots', async () => { - const { storageSlots } = StorageTestContract; + const { storageSlots } = StorageTestContractFactory; const expectedStorageSlots = storageSlots.map(({ key, value }) => ({ key: `0x${key}`, value: `0x${value}`, @@ -123,7 +123,7 @@ describe('StorageTestContract', () => { }); it('should allow for overriding storage slots', async () => { - const { storageSlots } = StorageTestContract; + const { storageSlots } = StorageTestContractFactory; expect(storageSlots.length).toBeGreaterThan(2); const modifiedStorageSlots = storageSlots.slice(1).map(({ key }) => ({ @@ -176,7 +176,7 @@ describe('StorageTestContract', () => { }); test('automatically loads storage slots when using deployAsCreateTx', async () => { - const { storageSlots } = StorageTestContract; + const { storageSlots } = StorageTestContractFactory; const expectedStorageSlots = storageSlots.map(({ key, value }) => ({ key: `0x${key}`, value: `0x${value}`, @@ -197,7 +197,7 @@ describe('StorageTestContract', () => { }); test('automatically loads storage slots when using deployAsBlobTx', async () => { - const { storageSlots } = StorageTestContract; + const { storageSlots } = StorageTestContractFactory; const expectedStorageSlots = storageSlots.map(({ key, value }) => ({ key: `0x${key}`, value: `0x${value}`, diff --git a/packages/fuel-gauge/src/str-slice.test.ts b/packages/fuel-gauge/src/str-slice.test.ts index 0d505efd452..4e047260603 100644 --- a/packages/fuel-gauge/src/str-slice.test.ts +++ b/packages/fuel-gauge/src/str-slice.test.ts @@ -2,10 +2,7 @@ import { bn } from 'fuels'; import { launchTestNode } from 'fuels/test-utils'; import { StrSliceContractFactory, ScriptStrSlice } from '../test/typegen'; -import { - PredicateStrSlice, - type PredicateStrSliceInputs, -} from '../test/typegen/predicates/PredicateStrSlice'; +import { PredicateStrSlice } from '../test/typegen/predicates/PredicateStrSlice'; /** * @group node @@ -37,10 +34,9 @@ describe('str slice', () => { provider, } = launched; - const predicateData: PredicateStrSliceInputs = ['predicate-input']; const predicate = new PredicateStrSlice({ provider, - data: predicateData, + data: ['predicate-input'], }); const baseAssetId = await provider.getBaseAssetId(); diff --git a/packages/fuel-gauge/src/vectors.test.ts b/packages/fuel-gauge/src/vectors.test.ts index 9c94d76f40d..c3b1df2f34c 100644 --- a/packages/fuel-gauge/src/vectors.test.ts +++ b/packages/fuel-gauge/src/vectors.test.ts @@ -2,8 +2,7 @@ import { bn, randomBytes, hexlify } from 'fuels'; import type { BigNumberish, BN } from 'fuels'; import { VectorsFactory } from '../test/typegen/contracts'; -import { SmallEnumInput } from '../test/typegen/contracts/CoverageContract'; -import type { Vec } from '../test/typegen/contracts/common'; +import { SmallEnum } from '../test/typegen/contracts/CoverageContract'; import { launchTestContract } from './utils'; @@ -120,7 +119,7 @@ describe('Vector Tests', () => { it('should test (u8, u8) vector input/output', async () => { using contractInstance = await setupContract(); - const INPUT: Vec<[BigNumberish, BigNumberish]> = [ + const INPUT: Array<[BigNumberish, BigNumberish]> = [ [1, 2], [3, 4], [5, 6], @@ -137,7 +136,7 @@ describe('Vector Tests', () => { it('should test (u64, u64) vector input/output', async () => { using contractInstance = await setupContract(); - const INPUT: Vec<[BigNumberish, BigNumberish]> = [ + const INPUT: Array<[BigNumberish, BigNumberish]> = [ [111, 2222], [333, 4445], [5555, 6], @@ -168,7 +167,7 @@ describe('Vector Tests', () => { it('should test [u64; 5] vector input/output', async () => { using contractInstance = await setupContract(); - const INPUT: Vec<[BigNumberish, BigNumberish, BigNumberish, BigNumberish, BigNumberish]> = [ + const INPUT: Array<[BigNumberish, BigNumberish, BigNumberish, BigNumberish, BigNumberish]> = [ [1, 2, 3, 4, 5], [500, 600, 700, 9000, 9999], [11500, 22600, 33700, 55000, 669999], @@ -183,7 +182,7 @@ describe('Vector Tests', () => { it('should test [bool; 2] vector input/output', async () => { using contractInstance = await setupContract(); - const INPUT: Vec<[boolean, boolean]> = [ + const INPUT: Array<[boolean, boolean]> = [ [true, true], [true, false], [false, true], @@ -283,12 +282,12 @@ describe('Vector Tests', () => { it('should test SmallEnum vector input/output', async () => { using contractInstance = await setupContract(); - const INPUT: Vec = [ - SmallEnumInput.Empty, - SmallEnumInput.Empty, - SmallEnumInput.Empty, - SmallEnumInput.Empty, - SmallEnumInput.Empty, + const INPUT: Array = [ + SmallEnum.Empty, + SmallEnum.Empty, + SmallEnum.Empty, + SmallEnum.Empty, + SmallEnum.Empty, ]; const { waitForResult } = await contractInstance.functions @@ -404,7 +403,7 @@ describe('Vector Tests', () => { it('should test Vec and b256 tuple input/output', async () => { using contractInstance = await setupContract(); - const INPUT: [Vec, string] = [[1, 8, 3, 2, 55, 215], hexlify(randomBytes(32))]; + const INPUT: [Array, string] = [[1, 8, 3, 2, 55, 215], hexlify(randomBytes(32))]; const { waitForResult } = await contractInstance.functions .echo_vector_and_b256_tuple(...INPUT) @@ -417,7 +416,7 @@ describe('Vector Tests', () => { it('should test two vectors tuple input/output', async () => { using contractInstance = await setupContract(); - const INPUT: [Vec, Vec] = [ + const INPUT: [Array, Array] = [ [219, 229], [1, 254, 55], ]; @@ -433,7 +432,7 @@ describe('Vector Tests', () => { it('should test u32 and three different vectors tuple input/output', async () => { using contractInstance = await setupContract(); - const INPUT: [BigNumberish, Vec, Vec, Vec] = [ + const INPUT: [BigNumberish, Array, Array, Array] = [ 91000, [true, true, false], [95000, 153333], diff --git a/packages/fuel-gauge/src/void.test.ts b/packages/fuel-gauge/src/void.test.ts index bdd24c8003a..a46105e67ce 100644 --- a/packages/fuel-gauge/src/void.test.ts +++ b/packages/fuel-gauge/src/void.test.ts @@ -1,8 +1,8 @@ import { launchTestNode } from 'fuels/test-utils'; import { VoidFactory } from '../test/typegen'; -import type { NativeEnumInput } from '../test/typegen/contracts/Void'; -import type { Option } from '../test/typegen/contracts/common'; +import type { Option } from '../test/typegen/common'; +import { NativeEnum } from '../test/typegen/contracts/VoidTypes'; /** * @group node @@ -35,12 +35,10 @@ describe('Void Tests', () => { contracts: [voidContract], } = launched; - const enumValue: NativeEnumInput = 'C' as NativeEnumInput; - - const { waitForResult } = await voidContract.functions.echo_native_enum(enumValue).call(); + const { waitForResult } = await voidContract.functions.echo_native_enum(NativeEnum.C).call(); const { value } = await waitForResult(); - expect(value).toEqual(enumValue); + expect(value).toEqual(NativeEnum.C); }); it('should handle input arguments of type [42, void]', async () => { diff --git a/packages/fuel-gauge/test/fixtures/forc-projects/Forc.toml b/packages/fuel-gauge/test/fixtures/forc-projects/Forc.toml index 7a4dc974141..a01e7b9390a 100644 --- a/packages/fuel-gauge/test/fixtures/forc-projects/Forc.toml +++ b/packages/fuel-gauge/test/fixtures/forc-projects/Forc.toml @@ -1,6 +1,9 @@ [workspace] members = [ "abi-contract", + "abi-script", + "abi-predicate", + "parser", "advanced-logging", "advanced-logging-abi", "advanced-logging-other-contract", diff --git a/packages/fuel-gauge/test/fixtures/forc-projects/abi-predicate/Forc.toml b/packages/fuel-gauge/test/fixtures/forc-projects/abi-predicate/Forc.toml new file mode 100644 index 00000000000..07df6e22027 --- /dev/null +++ b/packages/fuel-gauge/test/fixtures/forc-projects/abi-predicate/Forc.toml @@ -0,0 +1,4 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "abi-predicate" diff --git a/packages/fuel-gauge/test/fixtures/forc-projects/abi-predicate/src/main.sw b/packages/fuel-gauge/test/fixtures/forc-projects/abi-predicate/src/main.sw new file mode 100644 index 00000000000..1759925ec32 --- /dev/null +++ b/packages/fuel-gauge/test/fixtures/forc-projects/abi-predicate/src/main.sw @@ -0,0 +1,34 @@ +predicate; + +struct Validation { + has_account: bool, + total_complete: u64, +} + +enum MyGenericEnum { + a: T, +} + +struct MyGenericStruct { + a: T, +} + +struct Configurables { + U8_VALUE: u8, + B256_VALUE: b256, +} + +configurable { + U8_VALUE: u8 = 10, + B256_VALUE: b256 = 0x38966262edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96, +} + +fn main( + configurables: Configurables, + vec: Vec, + enm: MyGenericEnum, + opt: Option, + res: Result, u64>, +) -> bool { + U8_VALUE == configurables.U8_VALUE && B256_VALUE == configurables.B256_VALUE +} diff --git a/packages/fuel-gauge/test/fixtures/forc-projects/abi-script/Forc.toml b/packages/fuel-gauge/test/fixtures/forc-projects/abi-script/Forc.toml new file mode 100644 index 00000000000..324740dd9f8 --- /dev/null +++ b/packages/fuel-gauge/test/fixtures/forc-projects/abi-script/Forc.toml @@ -0,0 +1,4 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "abi-script" diff --git a/packages/fuel-gauge/test/fixtures/forc-projects/abi-script/src/main.sw b/packages/fuel-gauge/test/fixtures/forc-projects/abi-script/src/main.sw new file mode 100644 index 00000000000..e57711aa736 --- /dev/null +++ b/packages/fuel-gauge/test/fixtures/forc-projects/abi-script/src/main.sw @@ -0,0 +1,34 @@ +script; + +struct Validation { + has_account: bool, + total_complete: u64, +} + +enum MyGenericEnum { + a: T, +} + +struct MyGenericStruct { + a: T, +} + +struct Configurables { + U8_VALUE: u8, + B256_VALUE: b256, +} + +configurable { + U8_VALUE: u8 = 10, + B256_VALUE: b256 = 0x38966262edb5997574be45f94c665aedb41a1663f5b0528e765f355086eebf96, +} + +fn main( + configurables: Configurables, + vec: Vec, + enm: MyGenericEnum, + opt: Option, + res: Result, u64>, +) -> bool { + U8_VALUE == configurables.U8_VALUE && B256_VALUE == configurables.B256_VALUE +} diff --git a/packages/fuel-gauge/test/fixtures/forc-projects/parser/Forc.toml b/packages/fuel-gauge/test/fixtures/forc-projects/parser/Forc.toml new file mode 100644 index 00000000000..591f549398f --- /dev/null +++ b/packages/fuel-gauge/test/fixtures/forc-projects/parser/Forc.toml @@ -0,0 +1,4 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "parser" diff --git a/packages/fuel-gauge/test/fixtures/forc-projects/parser/src/main.sw b/packages/fuel-gauge/test/fixtures/forc-projects/parser/src/main.sw new file mode 100644 index 00000000000..44d4262645a --- /dev/null +++ b/packages/fuel-gauge/test/fixtures/forc-projects/parser/src/main.sw @@ -0,0 +1,69 @@ +contract; +use std::bytes::Bytes; +use std::message::send_typed_message; + +struct GenericStruct { + a: bool, + b: u32, + c: T, +} + +pub struct DoubleGeneric { + pub a: T, + pub b: F, +} + +struct NestedGenericStruct { + a: Vec>, + b: Vec>, + c: DoubleGeneric, +} + +struct SimpleStruct { + a: bool, +} + +pub struct StructWithImplicitGenerics { + pub a: [E; 3], + pub b: (E, F), +} + +configurable { + U8_VALUE: u8 = 10, +} + +abi VoidContract { + fn generic_structs( + arg1: GenericStruct>, + arg2: NestedGenericStruct, + ) -> bool; + fn implicit_generic_struct( + arg1: StructWithImplicitGenerics, + arg2: (bool, StructWithImplicitGenerics), + ) -> bool; + fn bytes(arg: Bytes) -> bool; +} + +impl VoidContract for Contract { + fn generic_structs( + arg1: GenericStruct>, + arg2: NestedGenericStruct, + ) -> bool { + log(arg1.a); + send_typed_message( + 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20, + arg1.a, + 123, + ); + true + } + fn implicit_generic_struct( + arg1: StructWithImplicitGenerics, + arg2: (bool, StructWithImplicitGenerics), + ) -> bool { + true + } + fn bytes(arg: Bytes) -> bool { + true + } +} diff --git a/packages/fuels/.gitignore b/packages/fuels/.gitignore index 289ea019274..d6ba43d5252 100644 --- a/packages/fuels/.gitignore +++ b/packages/fuels/.gitignore @@ -1,2 +1,3 @@ README.md test/__temp__* +test/fixtures/typegend \ No newline at end of file diff --git a/packages/fuels/package.json b/packages/fuels/package.json index d22bfe12ee3..43104abf4ee 100644 --- a/packages/fuels/package.json +++ b/packages/fuels/package.json @@ -62,8 +62,8 @@ }, "license": "Apache-2.0", "dependencies": { + "@fuel-ts/abi": "workspace:*", "@fuel-ts/abi-coder": "workspace:*", - "@fuel-ts/abi-typegen": "workspace:*", "@fuel-ts/account": "workspace:*", "@fuel-ts/address": "workspace:*", "@fuel-ts/contract": "workspace:*", diff --git a/packages/fuels/src/cli.ts b/packages/fuels/src/cli.ts index 9a716cbfb7d..9887df494d2 100644 --- a/packages/fuels/src/cli.ts +++ b/packages/fuels/src/cli.ts @@ -1,4 +1,4 @@ -import { configureCliOptions as configureTypegenCliOptions } from '@fuel-ts/abi-typegen/cli'; +import { configureTypegenCliOptions } from '@fuel-ts/abi/cli'; import { versions } from '@fuel-ts/versions'; import { runVersions } from '@fuel-ts/versions/cli'; import { Command, Option } from 'commander'; @@ -98,11 +98,7 @@ export const configureCli = () => { /** * Routing external commands from sub-packages' CLIs */ - - // Typegen - configureTypegenCliOptions( - program.command('typegen').description(`Generate Typescript from Sway ABI JSON files`) - ); + command = configureTypegenCliOptions(program.command(Commands.typegen)); // Versions (command = program.command('versions')) diff --git a/packages/fuels/src/cli/commands/build/generateTypes.ts b/packages/fuels/src/cli/commands/build/generateTypes.ts deleted file mode 100644 index dbcb17fe4bf..00000000000 --- a/packages/fuels/src/cli/commands/build/generateTypes.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { ProgramTypeEnum } from '@fuel-ts/abi-typegen'; -import { runTypegen } from '@fuel-ts/abi-typegen/runTypegen'; -import { getBinaryVersions } from '@fuel-ts/versions/cli'; -import { writeFileSync, mkdirSync } from 'fs'; -import { globSync } from 'glob'; -import { join } from 'path'; - -import { getABIPaths } from '../../config/forcUtils'; -import { renderIndexTemplate } from '../../templates'; -import type { FuelsConfig } from '../../types'; -import { debug, log, loggingConfig } from '../../utils/logger'; - -async function generateTypesForProgramType( - config: FuelsConfig, - paths: string[], - programType: ProgramTypeEnum -) { - debug('Generating types..'); - - let filepaths = await getABIPaths(paths, config); - const pluralizedDirName = `${String(programType).toLocaleLowerCase()}s`; - const versions = getBinaryVersions(config); - - const isScript = programType === ProgramTypeEnum.SCRIPT; - const isPredicate = programType === ProgramTypeEnum.PREDICATE; - - if (isScript || isPredicate) { - const loaderFiles = paths.flatMap((dirpath) => { - const glob = `*-abi.json`; - const cwd = `${dirpath}/out`; - return globSync(glob, { cwd }).map((filename) => `${dirpath}/out/${filename}`); - }); - filepaths = filepaths.concat(loaderFiles); - } - - runTypegen({ - programType, - cwd: config.basePath, - filepaths, - output: join(config.output, pluralizedDirName), - silent: !loggingConfig.isDebugEnabled, - versions, - }); - - return pluralizedDirName; -} - -export async function generateTypes(config: FuelsConfig) { - log('Generating types..'); - - const { contracts, scripts, predicates, output } = config; - - mkdirSync(output, { recursive: true }); - - const members = [ - { type: ProgramTypeEnum.CONTRACT, programs: contracts }, - { type: ProgramTypeEnum.SCRIPT, programs: scripts }, - { type: ProgramTypeEnum.PREDICATE, programs: predicates }, - ]; - - const pluralizedDirNames = await Promise.all( - members - .filter(({ programs }) => !!programs.length) - .map(({ programs, type }) => generateTypesForProgramType(config, programs, type)) - ); - - const indexFile = await renderIndexTemplate(pluralizedDirNames); - - writeFileSync(join(config.output, 'index.ts'), indexFile); -} diff --git a/packages/fuels/src/cli/commands/build/index.test.ts b/packages/fuels/src/cli/commands/build/index.test.ts index 2983713940f..4deed12d989 100644 --- a/packages/fuels/src/cli/commands/build/index.test.ts +++ b/packages/fuels/src/cli/commands/build/index.test.ts @@ -1,9 +1,9 @@ import { fuelsConfig } from '../../../../test/fixtures/fuels.config'; import { mockLogger } from '../../../../test/utils/mockLogger'; +import * as generateTypesMod from '../generate-types'; import { build } from '.'; import * as buildSwayProgramsMod from './buildSwayPrograms'; -import * as generateTypesMod from './generateTypes'; /** * @group node diff --git a/packages/fuels/src/cli/commands/build/index.ts b/packages/fuels/src/cli/commands/build/index.ts index 65cf4799c6d..88c77a21bc4 100644 --- a/packages/fuels/src/cli/commands/build/index.ts +++ b/packages/fuels/src/cli/commands/build/index.ts @@ -4,15 +4,15 @@ import type { FuelsConfig } from '../../types'; import { log } from '../../utils/logger'; import { deploy } from '../deploy'; import { autoStartFuelCore } from '../dev/autoStartFuelCore'; +import { generateTypes } from '../generate-types'; import { buildSwayPrograms } from './buildSwayPrograms'; -import { generateTypes } from './generateTypes'; export async function build(config: FuelsConfig, program?: Command) { log('Building..'); await buildSwayPrograms(config); - await generateTypes(config); + generateTypes(config); config.onBuild?.(config); const options = program?.opts(); diff --git a/packages/fuels/src/cli/commands/deploy/deployContracts.ts b/packages/fuels/src/cli/commands/deploy/deployContracts.ts index a7c6da13d2b..52aac577516 100644 --- a/packages/fuels/src/cli/commands/deploy/deployContracts.ts +++ b/packages/fuels/src/cli/commands/deploy/deployContracts.ts @@ -48,7 +48,7 @@ export async function deployContract( const proxyBytecode = Src14OwnedProxyFactory.bytecode; const proxyAbi = Src14OwnedProxy.abi; - const proxyStorageSlots = Src14OwnedProxy.storageSlots ?? []; + const proxyStorageSlots = Src14OwnedProxyFactory.storageSlots ?? []; const isProxyEnabled = tomlContents?.proxy?.enabled; const proxyAddress = tomlContents?.proxy?.address; diff --git a/packages/fuels/src/cli/commands/deploy/index.ts b/packages/fuels/src/cli/commands/deploy/index.ts index 28b14181d41..c223b7b5488 100644 --- a/packages/fuels/src/cli/commands/deploy/index.ts +++ b/packages/fuels/src/cli/commands/deploy/index.ts @@ -1,5 +1,5 @@ import type { FuelsConfig } from '../../types'; -import { generateTypes } from '../build/generateTypes'; +import { generateTypes } from '../generate-types'; import { deployContracts } from './deployContracts'; import { deployPredicates } from './deployPredicates'; @@ -35,9 +35,9 @@ export async function deploy(config: FuelsConfig) { /** * After deploying scripts/predicates, we need to - * re-generate factory classe with the loader coee + * re-generate factory classes with the loader code */ - await generateTypes(config); + generateTypes(config); return { contracts, diff --git a/packages/fuels/src/cli/commands/generate-types.ts b/packages/fuels/src/cli/commands/generate-types.ts new file mode 100644 index 00000000000..ac992252b67 --- /dev/null +++ b/packages/fuels/src/cli/commands/generate-types.ts @@ -0,0 +1,16 @@ +import { runTypegen } from '@fuel-ts/abi/cli'; + +import type { FuelsConfig } from '../types'; + +export function generateTypes(config: FuelsConfig) { + const { contracts, scripts, predicates, output } = config; + + const loaderPaths = scripts.concat(predicates).map((path) => `${path}/out`); + + const paths = contracts + .concat(scripts, predicates) + .map((path) => `${path}/out/${config.buildMode}`) + .concat(loaderPaths); + + runTypegen({ inputs: paths, output }); +} diff --git a/packages/fuels/src/cli/templates/index.hbs b/packages/fuels/src/cli/templates/index.hbs index 569e0ad5e15..81a242dac7b 100644 --- a/packages/fuels/src/cli/templates/index.hbs +++ b/packages/fuels/src/cli/templates/index.hbs @@ -1,3 +1,3 @@ {{#each paths}} export * from './{{this}}'; -{{/each}} +{{/each}} \ No newline at end of file diff --git a/packages/fuels/src/cli/types.ts b/packages/fuels/src/cli/types.ts index f44c32cd93e..e9d641ba83e 100644 --- a/packages/fuels/src/cli/types.ts +++ b/packages/fuels/src/cli/types.ts @@ -8,6 +8,7 @@ export enum Commands { init = 'init', versions = 'versions', node = 'node', + typegen = 'typegen', } export type CommandEvent = @@ -34,6 +35,10 @@ export type CommandEvent = | { type: Commands.node; data: void; + } + | { + type: Commands.typegen; + data: void; }; export type DeployedContract = { diff --git a/packages/fuels/src/index.ts b/packages/fuels/src/index.ts index d485f2a6cc4..6cf58959170 100644 --- a/packages/fuels/src/index.ts +++ b/packages/fuels/src/index.ts @@ -15,4 +15,6 @@ export * from '@fuel-ts/utils'; export * from '@fuel-ts/account'; export * from '@fuel-ts/transactions/configs'; export * from '@fuel-ts/account/configs'; +export * from '@fuel-ts/abi'; export * from '@fuel-ts/recipes'; +export * from '@fuel-ts/abi'; diff --git a/packages/fuels/test/features/build.test.ts b/packages/fuels/test/features/build.test.ts index f03a6388419..68e159870df 100644 --- a/packages/fuels/test/features/build.test.ts +++ b/packages/fuels/test/features/build.test.ts @@ -98,7 +98,7 @@ describe('build', { timeout: 180000 }, () => { ].map((f) => join(paths.outputDir, f)); files.forEach((file) => expect(existsSync(file), `${file} does not exist`).toBeTruthy()); - expect(readdirSync(paths.outputContractsDir)).toHaveLength(3); + expect(readdirSync(paths.outputContractsDir)).toHaveLength(7); expect(autoStartFuelCore).toHaveBeenCalledTimes(0); expect(deploy).toHaveBeenCalledTimes(0); @@ -132,7 +132,7 @@ describe('build', { timeout: 180000 }, () => { ].map((f) => join(paths.outputDir, f)); files.forEach((file) => expect(existsSync(file), `${file} does not exist`).toBeTruthy()); - expect(readdirSync(paths.outputContractsDir)).toHaveLength(9); + expect(readdirSync(paths.outputContractsDir)).toHaveLength(25); expect(autoStartFuelCore).toHaveBeenCalledTimes(0); expect(deploy).toHaveBeenCalledTimes(0); diff --git a/packages/fuels/test/fixtures/fuels.config.ts b/packages/fuels/test/fixtures/fuels.config.ts index 2e25eae894c..4aeb67ebf9b 100644 --- a/packages/fuels/test/fixtures/fuels.config.ts +++ b/packages/fuels/test/fixtures/fuels.config.ts @@ -19,7 +19,7 @@ export const fuelsConfig: FuelsConfig = { ], scripts: [join(scriptsDir, 'script')], predicates: [join(predicatesDir, 'predicate')], - output: '/output', + output: './typegen', forcPath: 'fuels-forc', fuelCorePath: 'fuels-core', deployConfig: {}, @@ -27,6 +27,8 @@ export const fuelsConfig: FuelsConfig = { fuelCorePort: 4000, providerUrl: 'http://127.0.0.1:4000/v1/graphql', configPath: __filename, - forcBuildFlags: [], - buildMode: 'debug', + forcBuildFlags: ['--release'], + buildMode: 'release', }; + +export default fuelsConfig; diff --git a/packages/recipes/package.json b/packages/recipes/package.json index 41246099cac..76ca83985a3 100644 --- a/packages/recipes/package.json +++ b/packages/recipes/package.json @@ -28,9 +28,9 @@ }, "license": "Apache-2.0", "dependencies": { + "@fuel-ts/abi": "workspace:*", "@fuel-ts/address": "workspace:*", "@fuel-ts/abi-coder": "workspace:*", - "@fuel-ts/abi-typegen": "workspace:*", "@fuel-ts/account": "workspace:*", "@fuel-ts/program": "workspace:*", "@fuel-ts/transactions": "workspace:*", diff --git a/packages/recipes/scripts/build-recipes.ts b/packages/recipes/scripts/build-recipes.ts index 9df639cbcfa..bf5c190f7b3 100644 --- a/packages/recipes/scripts/build-recipes.ts +++ b/packages/recipes/scripts/build-recipes.ts @@ -2,9 +2,15 @@ import { execSync } from 'child_process'; import { readFileSync, writeFileSync } from 'fs'; import { join } from 'path'; -execSync(`fuels-typegen -i src/contracts/**/*-abi.json -o src/types`); +execSync(`fuels-typegen -i src/contracts/src14 -o src/types`); + +const typesPath = join(__dirname, '..', 'src', 'types'); +const supportedRecipes = ['Src14OwnedProxy'] + .map((s) => [s, `${s}Factory`, `${s}Types`, `${s}-bytecode`, `${s}-storage-slots`]) + .flat() + .map((s) => join(typesPath, 'contracts', `${s}.ts`)) + .concat([join(typesPath, 'common.ts')]); -const supportedRecipes = ['Src14OwnedProxy'].map((s) => [s, `${s}Factory`]).flat(); const importReplacementMap = { Contract: '@fuel-ts/program', ContractFactory: '@fuel-ts/contract', @@ -20,12 +26,11 @@ const importReplacementMap = { decompressBytecode: '@fuel-ts/utils', }; -for (const recipe of supportedRecipes) { - const contractPath = join(__dirname, '..', 'src', 'types', `${recipe}.ts`); - let contractContents = readFileSync(contractPath, 'utf-8'); +for (const filepath of supportedRecipes) { + let contents = readFileSync(filepath, 'utf-8'); // Find all imports from 'fuels' const fuelImportsRegex = /import\s+(type\s+)?{([^}]+)}\s+from\s+['"]fuels['"];?/gs; - const matches = [...contractContents.matchAll(fuelImportsRegex)]; + const matches = [...contents.matchAll(fuelImportsRegex)]; // Extract the imported items and create new import statements const importsByPackage = new Map>(); @@ -58,18 +63,15 @@ for (const recipe of supportedRecipes) { .map(([pkg, imports]) => `import { ${Array.from(imports).join(', ')} } from '${pkg}';`) .join('\n'); + // Add new imports at the top of the file + const importRegex = /.*(?=import )/s; + contents = contents.replace(importRegex, (match) => `${match}\n${newImports}`); + // Replace all 'fuels' imports with the new imports matches.forEach((match) => { - contractContents = contractContents.replace(match[0], ''); + contents = contents.replace(match[0], ''); }); - // Add new imports at the top of the file - const versionCommentRegex = /\/\*\s*Fuels version: \d+\.\d+\.\d+\s*\*\/\s*/; - contractContents = contractContents.replace( - versionCommentRegex, - (match) => `${match}\n${newImports}` - ); - // Write the modified contents back to the file - writeFileSync(contractPath, contractContents); + writeFileSync(filepath, contents); } diff --git a/packages/recipes/src/types/common.d.ts b/packages/recipes/src/types/common.d.ts deleted file mode 100644 index ef3dec5e95c..00000000000 --- a/packages/recipes/src/types/common.d.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* Autogenerated file. Do not edit manually. */ - -/* eslint-disable max-classes-per-file */ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable @typescript-eslint/consistent-type-imports */ - -/* - Fuels version: 0.97.2 -*/ - -/** - * Mimics Sway Enum. - * Requires one and only one Key-Value pair and raises error if more are provided. - */ -export type Enum = { - [K in keyof T]: Pick & { [P in Exclude]?: never }; -}[keyof T]; - -/** - * Mimics Sway Option and Vectors. - * Vectors are treated like arrays in Typescript. - */ -export type Option = T | undefined; - -export type Vec = T[]; - -/** - * Mimics Sway Result enum type. - * Ok represents the success case, while Err represents the error case. - */ -export type Result = Enum<{ Ok: T; Err: E }>; diff --git a/packages/recipes/src/types/common.ts b/packages/recipes/src/types/common.ts new file mode 100644 index 00000000000..7d2f1f7d0ee --- /dev/null +++ b/packages/recipes/src/types/common.ts @@ -0,0 +1,53 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + +import { type FunctionFragment } from '@fuel-ts/abi-coder'; +import { type InvokeFunction } from '@fuel-ts/program'; + +/** + * Mimics Sway Enum. + * Requires one and only one Key-Value pair and raises error if more are provided. + */ +export type Enum = { + [K in keyof T]: Pick & { [P in Exclude]?: never }; +}[keyof T]; + +/** + * Mimics Sway Option type. + */ +export type Option = T | undefined; + +/** + * Mimics Sway Result enum type. + * Ok represents the success case, while Err represents the error case. + */ +export type Result = Enum<{ Ok: T; Err: E }>; + +/** + * Mimics Sway array type. For example, [u64; 10] is converted to ArrayOfLength. + */ +export type ArrayOfLength< + T, + Length extends number, + Arr extends unknown[] = [], +> = Arr['length'] extends Length ? Arr : ArrayOfLength; + +interface Types { + functions: Record; + configurables: Partial>; +} + +export type ProgramFunctionMapper = { + [K in keyof T]: InvokeFunction; +}; + +export type InterfaceFunctionMapper = { + [K in keyof T]: FunctionFragment; +}; diff --git a/packages/recipes/src/types/Src14OwnedProxy.ts b/packages/recipes/src/types/contracts/Src14OwnedProxy-abi.ts similarity index 80% rename from packages/recipes/src/types/Src14OwnedProxy.ts rename to packages/recipes/src/types/contracts/Src14OwnedProxy-abi.ts index 494f285063c..8c5bcd0e3e3 100644 --- a/packages/recipes/src/types/Src14OwnedProxy.ts +++ b/packages/recipes/src/types/contracts/Src14OwnedProxy-abi.ts @@ -1,62 +1,14 @@ /* Autogenerated file. Do not edit manually. */ -/* eslint-disable max-classes-per-file */ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable @typescript-eslint/consistent-type-imports */ +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ /* - Fuels version: 0.97.2 + Fuels version: 0.98.0 + Forc version: 0.66.5 */ -import { Contract, type InvokeFunction } from '@fuel-ts/program'; -import { Interface, type FunctionFragment, type StrSlice } from '@fuel-ts/abi-coder'; -import { type Provider, type Account } from '@fuel-ts/account'; -import { type StorageSlot } from '@fuel-ts/transactions'; -import { type Address } from '@fuel-ts/address'; -import type { Option, Enum } from './common'; - -export enum AccessErrorInput { - NotOwner = 'NotOwner', -} -export enum AccessErrorOutput { - NotOwner = 'NotOwner', -} -export type IdentityInput = Enum<{ Address: AddressInput; ContractId: ContractIdInput }>; -export type IdentityOutput = Enum<{ Address: AddressOutput; ContractId: ContractIdOutput }>; -export enum InitializationErrorInput { - CannotReinitialized = 'CannotReinitialized', -} -export enum InitializationErrorOutput { - CannotReinitialized = 'CannotReinitialized', -} -export enum SetProxyOwnerErrorInput { - CannotUninitialize = 'CannotUninitialize', -} -export enum SetProxyOwnerErrorOutput { - CannotUninitialize = 'CannotUninitialize', -} -export type StateInput = Enum<{ - Uninitialized: undefined; - Initialized: IdentityInput; - Revoked: undefined; -}>; -export type StateOutput = Enum<{ Uninitialized: void; Initialized: IdentityOutput; Revoked: void }>; - -export type AddressInput = { bits: string }; -export type AddressOutput = AddressInput; -export type ContractIdInput = { bits: string }; -export type ContractIdOutput = ContractIdInput; -export type ProxyOwnerSetInput = { new_proxy_owner: StateInput }; -export type ProxyOwnerSetOutput = { new_proxy_owner: StateOutput }; -export type ProxyTargetSetInput = { new_target: ContractIdInput }; -export type ProxyTargetSetOutput = { new_target: ContractIdOutput }; - -export type Src14OwnedProxyConfigurables = Partial<{ - INITIAL_TARGET: Option; - INITIAL_OWNER: StateInput; -}>; - -const abi = { +export const abi = { programType: 'contract', specVersion: '1', encodingVersion: '1', @@ -633,53 +585,3 @@ const abi = { }, ], }; - -const storageSlots: StorageSlot[] = [ - { - key: '7bb458adc1d118713319a5baa00a2d049dd64d2916477d2688d76970c898cd55', - value: '0000000000000000000000000000000000000000000000000000000000000000', - }, - { - key: '7bb458adc1d118713319a5baa00a2d049dd64d2916477d2688d76970c898cd56', - value: '0000000000000000000000000000000000000000000000000000000000000000', - }, - { - key: 'bb79927b15d9259ea316f2ecb2297d6cc8851888a98278c0a2e03e1a091ea754', - value: '0000000000000000000000000000000000000000000000000000000000000000', - }, - { - key: 'bb79927b15d9259ea316f2ecb2297d6cc8851888a98278c0a2e03e1a091ea755', - value: '0000000000000000000000000000000000000000000000000000000000000000', - }, -]; -export class Src14OwnedProxyInterface extends Interface { - constructor() { - super(abi); - } - - declare functions: { - proxy_target: FunctionFragment; - set_proxy_target: FunctionFragment; - proxy_owner: FunctionFragment; - initialize_proxy: FunctionFragment; - set_proxy_owner: FunctionFragment; - }; -} - -export class Src14OwnedProxy extends Contract { - static readonly abi = abi; - static readonly storageSlots = storageSlots; - - declare interface: Src14OwnedProxyInterface; - declare functions: { - proxy_target: InvokeFunction<[], Option>; - set_proxy_target: InvokeFunction<[new_target: ContractIdInput], void>; - proxy_owner: InvokeFunction<[], StateOutput>; - initialize_proxy: InvokeFunction<[], void>; - set_proxy_owner: InvokeFunction<[new_proxy_owner: StateInput], void>; - }; - - constructor(id: string | Address, accountOrProvider: Account | Provider) { - super(id, abi, accountOrProvider); - } -} diff --git a/packages/recipes/src/types/Src14OwnedProxyFactory.ts b/packages/recipes/src/types/contracts/Src14OwnedProxy-bytecode.ts similarity index 89% rename from packages/recipes/src/types/Src14OwnedProxyFactory.ts rename to packages/recipes/src/types/contracts/Src14OwnedProxy-bytecode.ts index 30762b7a0e9..a27e69cb2be 100644 --- a/packages/recipes/src/types/Src14OwnedProxyFactory.ts +++ b/packages/recipes/src/types/contracts/Src14OwnedProxy-bytecode.ts @@ -1,31 +1,15 @@ /* Autogenerated file. Do not edit manually. */ -/* eslint-disable max-classes-per-file */ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable @typescript-eslint/consistent-type-imports */ +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ /* - Fuels version: 0.97.2 + Fuels version: 0.98.0 + Forc version: 0.66.5 */ -import { ContractFactory, type DeployContractOptions } from '@fuel-ts/contract'; import { decompressBytecode } from '@fuel-ts/utils'; -import { type Provider, type Account } from '@fuel-ts/account'; -import { Src14OwnedProxy } from './Src14OwnedProxy'; -const bytecode = decompressBytecode( +export const bytecode = decompressBytecode( 'H4sIAAAAAAAAA9Vbe3Abx3lfgCAFvayz+TAFSjaUUjJkRwosUQ4ly9IhIATSEM2DSVpUGBhg64c0cSyIlVQ5tsccN001aSZlHcdlO06GrtOp6z4GAB+C7T7YR2bUiTtlZhxbTeMWmiatFAst60YZqm6j/r5v93DHw4GOJ84f0QznFne73+5+j9/32FVgISxOCOEV/K/Dn7o259GuXRO/JcSQ8c6CML4nwkZJF8HFnWLovZLXeK/kOyG89+JbGN9C+BZe+q2uEfRE4LIBGiv1VHThdi0i5gJdGTHa7TW0WNNY4JLmoFfXE4jPi3T5ep/q112j337Vr8WIF3PV373nAol5YfTls6OG8Id6m9E3+DG0tVB5F96/onG7b0akejWh9XaMpWNhYcSnL44exPv49JzLnNtoTtDMpMvaR0FvmxHPaaPd6B/rGDMSxRCP7WmaMxJ5I10Wt47qYg2etxnR/CJ/i7Tj29nuSr/42Tlux3yYLygC36+aMxiIzotTuuck+LeD+If9hoxEIQS6MdDX8DxgRAudNvrzNvql96Hvl/TFJdDfaaPfDbo9oL8az7tBf8hGf8GiXxTL0/cuKPpPg36Hjf4R0O1V678H9E9b9IuaRX+m9X3on1f0HwD9XTb6Z0A3Cfrr8LwX9Ccs+jOWnOIzkm+16c8p+juXvl/9f0Z0GnonHP19CeqfigmR6hGeVER4jb5Z7FH7a+jL32Atf2tEp84ELoUxV9XYQzQWOnVO6pRvzIi+AhugdTehPVtpV8/r/TyPTcxWdIv246CfIf3dHNGEES0GjXihRHSq9+z5slrHBOYLy3XkJ7nN6zg7brar17F6c0AXYjP+lr5fNWW+x/4nqsc1PK3mHLLmLGatOaddxtSxboHPsGHF6/7Zc6MDGJNs1o347CJ4/i/pcrgEvl/AvOcCl3Teb+CCk5b/tmq5zVyE3P4cNP4C4/8S40+7y63uklr7GUtuReKXktuMfxm5tSq5ST10lVvdu6bcoON3KB0PGokpjTAq8H1nf8/vME4lcoRlQann+TFux9rnHLTfgQ2QzuCbbw57PgJcDIZ660lOYab/PejIBez77aq1vyH3nfdjfDePjxaL3I5gzmh+Pn1Z22P0Cr+kuRnYOTuEdjfhMeQziXYoFKsXkq9OPVxxCnbrH+3C2Eg75Dnt5geO0V5TPeBNr+ZJxTTowNkh6EAwlKzXoaunIb//hA4sQJb/ZcSnFqUO0J6ctPyHXXRgHuNeBY3XoAN/Bj08X0MHjigd6LZ0oPCSKXfIbX0qnhtMJXL3dXh891q2MA0ZOmmt/JaiFcR48If1qZPb0haOuNjCtiW2kBTe1CDah9U+0oXiaAbjUy0C6/A1xjRxqktsT0VzhxojQge+ebHGwB28pkLRiAi/EX8lyHyMgY/xmUnwYBp8nEmX9VkjMW0ELpLukS059c/7lotMNJtMwqD1b6D17+DtRcgEOFRLJit+6JQJYgoN6wG+G/l0OVOAXKbAk87ARYll1bbtnXKRaxFzn8U68BSvYDywwU2u3neVLM7bbDtj2fb0Ym3b9mxStl3xN9W27X3PtO2vCHHzc34zXhKTgeikCMTHRSAxJgJ9JWH052CP5h6dcZgI8B4jAnGOWIv1HjGiuU6JD851iTbqC7sKh8o+yCOX5XZ02mr3+PTAD4V4htZxNSwmsK7fxvruXhS0zhXmOuUasb5ESaTB38AVzHc1aPZfofo/Ze3Lc5HHDGNfh0qw+6q1fZL40QjdOdUt7sZTx3M1/Li3MdJEfthzB2JKrHMB6/RChjch1jpjrhnjd5PfAu40utCOUkzY2BsUpw6KGxt7gkRb0kvkzmHMesR2uuRx2Dm2i2XZB5s08TESlLgWoXgyn8EaQ6HedoqhbwC9bPqyuA7vgzXohVkGhLtl4CbRonZ0Ghhs0TIiGvkO2D3Fl9inTvtsIswtcjvG89WDHzrmg83ivfKf/P1wE2SSgRzB96uGKZenlFwq+iblWJL40RMkDBEUN2u9u0Q6Aru4gtjoqubUA7u+ZphGAnKFrpKtMW/KhPM5ndtxxNrqvRZDPM5xCPhJ+A7d4yfpHeaC3mVc9M4+H3x/lX1ka9nHSSH+2GYfrZgXtrhUP9AnyrqXhO4ZogUYqQMjpX4A16EfKzEHYgCao4r+J1ievGfSDciN2tEZWtcEyzPZZMoqCFn5+H0XvWcbPMftSJfVtmxwwYUXdVWyw94CV/BnyanOaa/gm2b2Z9wq+8YC0VxlLObSbONN+91vG29YfAcNwjXob+CdXLV+98Fe+pEfDaAP4jHCeEefWwL9ZI+78AcdMwTZ5QbYWJhzM9gYYbJjzK2Krr4M3U0c//RDt7hPvVsfznu2JjuMwBWd9m3YcGv/B+CbZxm+fYh8rzsXOITx/ZBzdOHjMgbMXwQtituADYiTONajGCxvWHEb7LYqbhMPKfzvlvg/NcZtxv9Cd6Udz8MnuuUHvqwt1pHzRwuUE9A4Fz/oOy79YIH8oBmPIp6nfMvN54tBRf+IlQtMEQ6qXGAqo74Beym2yl2PmOYG+t3WA9w7KPxtPR1jW7pBuzsLbJ7K7O7xzcN3NJDfgO3BZxTO23zGdYQHsG/KNf1tsQ5diyHeTMA+D5IdYr0xxLDURvxsHwteE35hXe2ob+SGVSylfFQ+KOOoKRm7ESaTXQ8SxhmQOWR6VXfqnN3WupdiXJblz3FUuV6H7/Nh3SEzPgbGdIf6pqFPYdKnbhfa12x+2MLPYdCGL8Yawbcm4l9I62mnusTN6ll/s3z61qea5jAfeHRC534x/KZ+8ll/M56w35zpI7EmrLWDeEE1CenfIANT9g6575R6Aru1dFnlOFV9Q8ofS9/C+UqecAO8QJ6RyMs19LBvzr7Y63uB7IJ1BjqK71m8H8f7SV4b6xJ8bDRntRO5jLWOnMyfUD8A35vS5Wwzy/0wyZL9KzC64l+vKX6vs8lSt+Mm4T/+6vHXAH+0gv2gigWYZ3GSo0Zy1G24tK46nhLjLn7wNHSklbARa2wNleFT4oypreyDh3MNqUO5FbAZ8lF+LdksmpMxHT7PQ/4J77xtg4NiywCYvPEBPTCUFVryAT2dhO/W0R9xGPvDcmYlYvBVWP9qrL+V6UfY32e4jbwO/VspXlE+fdzmx8wYxM4jpe+kiz5h2W+uFXF6Hb3Dk/kGGWFfLKMw+NYaSkyT/mH+9jmFp9D/Cp6afLPbFvI1Sx6Yw+A1S50l2hSbEF61ks6m+nL1sGWN/A7yFr/Rq/vBY9QVKZ/B3rm21GXV8qTsjnz4PsVjs2H/PNktchCOSRx5xXa2jzTHyeFQClg1nA8D47YcBz4Bo6j+cx68HKY8H+8fOt5NeZFpu2RDs0XLhmaGpM06/XHdE7LOCrsxx/WofJ/G9SAOYgwlGzpLORRjOHKjuxzr/W/269H8ONa0g2p4JmZSXNAC3mLN7ci9QqgD6Oa3VDRfrzB3DfD3DNqUI9hy2akh7O3T+DuGuuWQGVdBz9eCb7rE5yL5FunH4lN+zD+i1i1tn8ZR/MZx91mKq8kPUCyHmtL0S2bu6tjPd5SPJblCR4qEm5r0sVMU33Ebaxamz6DaO35/Vu1hFdqP2b7V0TfKeRojPs7XtaSuI+6MEW2su5KfgietDppPKJoRtB930HzCheYnZT7suq+vK99MMlD58BTlHKrOkfM76J+20Yf/RV32skiCp1TXMWVxI+Regoz2jsQ+EYHeTaBWAd63YJ4Z5LCuddl/VjUuo9KXfDS1Y1vw3qIPmYVtMtuFvRVr7O0zam+qpk97m6Y4w9wb9rGEr19SfKV9ZbCvg1h7ybGvIvb1ceyrDt9O2/bVWmNfL6l9Bd33ZdG37ws6QLVaVR8iG5mi2HCJjQS6eK2eQBfXfr5CY1CDq9iZrG25+doKX6geq+I9qrHPEu+xlgbCINTV3Hy6937l08flfqjvzEVuR4gPs5W9uceagmurWPfDdMYBXsbB5wTbYWXdUxR78t4hkwUlo1a0R13wYFzZ/GnL5gtk89C7Qg7P+4xelddzjq/wS557vGTm31jXKkULOIrzoMvaR4EZ5C/8CjMqfRn3VIwI7CLd4pgW63tPrU/Fi9OaWhvFKXJvsYzM/3mfM7LOETlB9TiV5z/A8bYL3zg+MvdPeSTe3YQzBML8f8J4lcdW1VPvUzVdqj2a9k28NuuYbYgbsqhjHqc6Jn5vIL5K3PCg5kQ6ZWG3ev/oM+SrKvGRx4yPbPm8p1TxxxTj0t7gD+Fbw1bcD9/UJTI1cHOD+t2EdovJV9s3wXqP8yz6bsMkE6c2mO9UP9gJ8yxK80q54BnTwvjzq9hQ+rVIkORO+sfxKugYKh9Y41jHLer3BrQ/4lg/favYKNeQQEvOi2dMC8l5cQ5jxcYUb1AOpM6uqmLkAGHJMrRs8a06H6hNawXRknENZGXlFmY9omasW6lxmTEu5nghOh1UMY5bfGvPexdteW+nzHuR61p5r8opeQ+o/9TOe08q3bblvaRPZt57xJb3XqxhUwWXvDdXO+8VXHems1Rb3gvfUzPv3eeS99r0H3jzwfLecSvvzVPOgTOjwiL22WnLe7nu6ZL3EnaZeS/VGSnvrYwFvU5uSz1PO/LeTpX3Up1c1iIJt6y8d/GnyE3DP2FuGv4wc1PozuhPmpui75M/T7lpla2q/MXFLt1qjr73qzkGoiUxgjqqqunX2+uqhLXQQ8Za9b1Bfa/47JEuTx31AY16uS7hrJPZ68LIoaz9OGq07ZRjNCd9c5TrNsrntpGIF/VHrj0G8dTxbAIfyBdQzkE1I1lb70esSfkdxhEekm+C7TRQX+SEK+zfIXuq4aOG2UX7Ixqo+WrIXbV6/qbqm1Sz5n7JDrOfhj5ezFfH3xQ97hPrYvxFP8qBSX/pnopZJxizycsNkxEPLJFziDCZ6o9LbRc1AZsOgG7IRQ/sdHE/pRrrHTWM4PI1DJu9Uz5LfKT4IQnMg79ifGWsz827nXdDrgXyTWwbZR5Ddwh4jPO8GH1zCmMXuD/OlEF30rRj51nmSeF73XYW63IXIj+vvpmY7Acmr6yNyfn53T0dhDcW3vYhRxqi857YmDwPBy7E8/N3xnzjsv6/xH7NuokNL71WTT4NvBy24iclX4opvmCLmW6kNvqQjo8tjY8RE1BthfYWz1GM6a3lr8CbF1zOZo+RDgHD6O6BjI8SeaqPUB0I/g9nNHxuDJrV9Gaqz40R/w2QLtSTn2lQe6Fza2o7zq1zYfY7/QUaI8+a+/OoUwW3wj5vBTbehvkn5fzI/6rn/3b1/MDqyrk17jOUg3tA607Q2gtaiBNqnVuLAy68CdnWaJ2H96MuUw5uAd1bQBe5W+6MPMt2XeOPXdZI9T5zjROgtRO0OkBrF2jBZmqucaPLGtdRrGDTgSG5Fjf51/P5tn18OqWJdCroSaegN1ey0F3o5tWM0/fYdFfI8+Cl9ctWaz/QQaplRsxaJp+VGdymPGA4twq1TIrp11AdXIv59OZYM/sXrmXCj7QNDuiqlimolskx1KcI42JzqGsKbiebKXYIaoj/if+obV6P2uYNqG020jm6rbZJd1a4tsn+2HxPbVqTdX6J89ZKrdPct73+uMRPAQNCzrMu8PcA+atUMixSg2FPqjfstdmzXe9x11BHHdbAXb3wGtDSLJlV0fwSywz+DndE5F2IQzncxQuvBY3rsF/IP4fzMvjtqrimvk+dWfOZ3zL+x4zpbBjvteIMC+NxT4vxmvDTxHjcBXHDeO9tDoynOLgGxnu3qhxW9pcYz3dE3THe+zUXjKe43sT40gfE+JILxo8B48MK4zEHY3zJwnjwZ5nzefhI1IoRb8UXdmsxDZiawx0g5z5WrKZarPTtFK9TjV5bCb1sw3MV363j+jR/O8/9UDfHeuncGvEI67c6l8N5bDVebFe1Kds5HuxT3SujGo/7fTTRoPwY6tmV2M3tTF/FEuy/KI7gengYdxICB6lgnRTPoha8Q4d8dKFvge6nN8I29KwIRurEvYhF78Y7GW9U3VWwxxvFKswZ5lhdCx0GD/rhryyf8wvKz9yv2g7bk/dFlsqhoYPthM8ouIZR4jbH9nxWQDhBcTvdeeUzC2DYuhTOyimnQx95V1jyl843TJmNm++hf42UE9HdaIV5VNOzMC/ZpW8Br0IbB0RggDFP3kdEvUiLDQicZzTzfWfUAVDLaWL68EvAP5ozByxpAR7cqO5KkK2a/oDupgL/2EaoLiTfo61s0vyG8wK33KgB90QqOa6qL+H+oFVf2oy9bcKaPkL1JZVPtqraxQTnTYy9aC+5LwKZLn+2pGIkyBr662I737HbDseflNPLGgV8WNVZkh3bcFcLdBGrVmORb4fCLcRjzD+ZS+B+OOfV0v4kJsD+3M5YQOPv+F6KvLO3AxiwhzAglVi4U+sJ4mxqYa/WG55L9S/chXrbHPA8C6wJhgabxzDXDUbMCPHv2OYxo0sPc/45BOzsGRwzDuFeOsWe6CvnBoOXYuMlFQdiPO7IXxZtqs4J3nfNGd068A41mMqdzgLdtwe+bXa904la4OdULbIFtRO6B9MFvqk7V1V9v6l0hWogpq5U7kBDV7ZDV4LQlU32WiSwFHfWKjhj6oJNXnXynBFxskM33yS9xJrWgkeEj3TGD/mg3rSsfOpvN+WjZPQpyGifxGlVVyNb7kPewPUAxlnEjqBVuVvr3Lvfo7CW7sJDVoQFU6Sf8Hmw1XjhTKWdKJCv4bW6+07PBcddbr5H6ND/keq71Pg/BZW71HRfP9iLOOEeYEKftG/3u9Sof2ypvm+Zp9pEJ2jsxvg9GN/tdt8S6zDv0VIOp2Su7l5KmX8MMm+DzDfwPVqpS83QJdJNA7pUuQPm0GM+h7DO4/iOlTqDWwiD5nrQDCzVI+iJFbsu55P31/bJ/oWfpU+GbDln+qA+GePeruWTf1b/sqPHTj+WPjEy+vCD9N+CxC8/eCJtf/f49NCf/NW3Wo/vXP/7r06u2ub76pu9W1viT24589bR7LmJvx+UfY/9yqMPjjK9o48ePXF05JGjn31QkrHoyT4bv7vq7RduWeV5nf8J7/7s9hd3bXj+pmv8T4jXHnvm8eZ/3Py1F1vevVzY+uQj536t9cwfPn167vdK+wIrb/qDgQMjjzzyiyO/9OnY6Oix0T17BniR9xw70S+XL764+Zt3fP7A9t/N/+ZE57Nf/vrLvkvPvzZ7cNOb//qZYwfLl18+uv/V/5j8h4eu+8Ku/xk+uePbe3/06xf23ZVr+sG7/m8Uv9HxR0fvemvl2vu9D6f3bfzxUz/47sbnHn7u7V/9ja6rX/3i3kfH/9To/dHLkms7/1c+d7yuns+r50H5vF19335ePtvfkM8W9X3lEfn0qff1n1PPDvV8Vj7rJuXT88b/AzdExjYINgAA' ); - -export class Src14OwnedProxyFactory extends ContractFactory { - static readonly bytecode = bytecode; - - constructor(accountOrProvider: Account | Provider) { - super(bytecode, Src14OwnedProxy.abi, accountOrProvider, Src14OwnedProxy.storageSlots); - } - - static deploy(wallet: Account, options: DeployContractOptions = {}) { - const factory = new Src14OwnedProxyFactory(wallet); - return factory.deploy(options); - } -} diff --git a/packages/recipes/src/types/contracts/Src14OwnedProxy-storage-slots.ts b/packages/recipes/src/types/contracts/Src14OwnedProxy-storage-slots.ts new file mode 100644 index 00000000000..2c9d2c2f4a9 --- /dev/null +++ b/packages/recipes/src/types/contracts/Src14OwnedProxy-storage-slots.ts @@ -0,0 +1,30 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + +import { type StorageSlot } from '@fuel-ts/transactions'; + +export const storageSlots: StorageSlot[] = [ + { + key: '7bb458adc1d118713319a5baa00a2d049dd64d2916477d2688d76970c898cd55', + value: '0000000000000000000000000000000000000000000000000000000000000000', + }, + { + key: '7bb458adc1d118713319a5baa00a2d049dd64d2916477d2688d76970c898cd56', + value: '0000000000000000000000000000000000000000000000000000000000000000', + }, + { + key: 'bb79927b15d9259ea316f2ecb2297d6cc8851888a98278c0a2e03e1a091ea754', + value: '0000000000000000000000000000000000000000000000000000000000000000', + }, + { + key: 'bb79927b15d9259ea316f2ecb2297d6cc8851888a98278c0a2e03e1a091ea755', + value: '0000000000000000000000000000000000000000000000000000000000000000', + }, +]; diff --git a/packages/recipes/src/types/contracts/Src14OwnedProxy.ts b/packages/recipes/src/types/contracts/Src14OwnedProxy.ts new file mode 100644 index 00000000000..66e88b77019 --- /dev/null +++ b/packages/recipes/src/types/contracts/Src14OwnedProxy.ts @@ -0,0 +1,41 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + +import type { Src14OwnedProxyTypes as Types } from './Src14OwnedProxyTypes'; +import type { InterfaceFunctionMapper, ProgramFunctionMapper } from '../common'; + +import { Contract } from '@fuel-ts/program'; +import { Interface } from '@fuel-ts/abi-coder'; +import { type Address } from '@fuel-ts/address'; +import { type Account, type Provider } from '@fuel-ts/account'; +import { abi } from './Src14OwnedProxy-abi'; + +export * from './Src14OwnedProxyTypes'; + +export type Src14OwnedProxyConfigurables = Types['configurables']; + +export class Src14OwnedProxyInterface extends Interface { + declare functions: InterfaceFunctionMapper; + + constructor() { + super(abi); + } +} + +export class Src14OwnedProxy extends Contract { + declare interface: Src14OwnedProxyInterface; + declare functions: ProgramFunctionMapper; + + public static readonly abi = abi; + + constructor(id: string | Address, accountOrProvider: Account | Provider) { + super(id, abi, accountOrProvider); + } +} diff --git a/packages/recipes/src/types/contracts/Src14OwnedProxyFactory.ts b/packages/recipes/src/types/contracts/Src14OwnedProxyFactory.ts new file mode 100644 index 00000000000..ccc1e94ccf7 --- /dev/null +++ b/packages/recipes/src/types/contracts/Src14OwnedProxyFactory.ts @@ -0,0 +1,31 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + +import { Src14OwnedProxy } from './Src14OwnedProxy'; +import { bytecode } from './Src14OwnedProxy-bytecode'; +import { abi } from './Src14OwnedProxy-abi'; + +import { ContractFactory, type DeployContractOptions } from '@fuel-ts/contract'; +import { type Account, type Provider } from '@fuel-ts/account'; +import { storageSlots } from './Src14OwnedProxy-storage-slots'; + +export class Src14OwnedProxyFactory extends ContractFactory { + static readonly bytecode = bytecode; + static readonly storageSlots = storageSlots; + + constructor(accountOrProvider: Account | Provider) { + super(bytecode, abi, accountOrProvider, Src14OwnedProxyFactory.storageSlots); + } + + static deploy(wallet: Account, options: DeployContractOptions = {}) { + const factory = new Src14OwnedProxyFactory(wallet); + return factory.deploy(options); + } +} diff --git a/packages/recipes/src/types/contracts/Src14OwnedProxyTypes.ts b/packages/recipes/src/types/contracts/Src14OwnedProxyTypes.ts new file mode 100644 index 00000000000..7da08d737ae --- /dev/null +++ b/packages/recipes/src/types/contracts/Src14OwnedProxyTypes.ts @@ -0,0 +1,68 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + +import { type StrSlice } from '@fuel-ts/abi-coder'; +import type { Enum, Option } from '../common'; + +export enum AccessError { + NotOwner = 'NotOwner', +} +export enum InitializationError { + CannotReinitialized = 'CannotReinitialized', +} +export enum SetProxyOwnerError { + CannotUninitialize = 'CannotUninitialize', +} + +export type AddressInput = { bits: string }; +export type AddressOutput = AddressInput; +export type ContractIdInput = { bits: string }; +export type ContractIdOutput = ContractIdInput; +export type IdentityInput = Enum<{ Address: AddressInput; ContractId: ContractIdInput }>; +export type IdentityOutput = Enum<{ Address: AddressOutput; ContractId: ContractIdOutput }>; +export type ProxyOwnerSetInput = { new_proxy_owner: StateInput }; +export type ProxyOwnerSetOutput = { new_proxy_owner: StateOutput }; +export type ProxyTargetSetInput = { new_target: ContractIdInput }; +export type ProxyTargetSetOutput = { new_target: ContractIdOutput }; +export type StateInput = Enum<{ + Uninitialized: undefined; + Initialized: IdentityInput; + Revoked: undefined; +}>; +export type StateOutput = Enum<{ Uninitialized: void; Initialized: IdentityOutput; Revoked: void }>; + +export interface Src14OwnedProxyTypes { + functions: { + proxy_target: { + inputs: []; + output: Option; + }; + set_proxy_target: { + inputs: [new_target: ContractIdInput]; + output: void; + }; + proxy_owner: { + inputs: []; + output: StateOutput; + }; + initialize_proxy: { + inputs: []; + output: void; + }; + set_proxy_owner: { + inputs: [new_proxy_owner: StateInput]; + output: void; + }; + }; + configurables: Partial<{ + INITIAL_TARGET: Option; + INITIAL_OWNER: StateInput; + }>; +} diff --git a/packages/recipes/src/types/contracts/index.ts b/packages/recipes/src/types/contracts/index.ts new file mode 100644 index 00000000000..da6555813c5 --- /dev/null +++ b/packages/recipes/src/types/contracts/index.ts @@ -0,0 +1,12 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + +export { Src14OwnedProxy } from './Src14OwnedProxy'; +export { Src14OwnedProxyFactory } from './Src14OwnedProxyFactory'; diff --git a/packages/recipes/src/types/index.ts b/packages/recipes/src/types/index.ts index 15dc6b12ae3..427c4de30dc 100644 --- a/packages/recipes/src/types/index.ts +++ b/packages/recipes/src/types/index.ts @@ -1,12 +1,11 @@ /* Autogenerated file. Do not edit manually. */ -/* eslint-disable max-classes-per-file */ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable @typescript-eslint/consistent-type-imports */ +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ /* - Fuels version: 0.97.2 + Fuels version: 0.98.0 + Forc version: 0.66.5 */ -export { Src14OwnedProxy } from './Src14OwnedProxy'; -export { Src14OwnedProxyFactory } from './Src14OwnedProxyFactory'; +export * from './contracts'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 020627fb417..d9bb030d0c9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -573,6 +573,27 @@ importers: internal/tsup: {} + packages/abi: + dependencies: + '@fuel-ts/errors': + specifier: workspace:* + version: link:../errors + '@fuel-ts/utils': + specifier: workspace:* + version: link:../utils + '@fuel-ts/versions': + specifier: workspace:* + version: link:../versions + commander: + specifier: 12.1.0 + version: 12.1.0 + glob: + specifier: 10.4.5 + version: 10.4.5 + handlebars: + specifier: 4.7.8 + version: 4.7.8 + packages/abi-coder: dependencies: '@fuel-ts/crypto': @@ -826,6 +847,9 @@ importers: specifier: workspace:* version: link:../fuels devDependencies: + '@fuel-ts/abi': + specifier: workspace:* + version: link:../abi '@fuel-ts/account': specifier: workspace:* version: link:../account @@ -841,12 +865,12 @@ importers: packages/fuels: dependencies: + '@fuel-ts/abi': + specifier: workspace:* + version: link:../abi '@fuel-ts/abi-coder': specifier: workspace:* version: link:../abi-coder - '@fuel-ts/abi-typegen': - specifier: workspace:* - version: link:../abi-typegen '@fuel-ts/account': specifier: workspace:* version: link:../account @@ -1021,12 +1045,12 @@ importers: packages/recipes: dependencies: + '@fuel-ts/abi': + specifier: workspace:* + version: link:../abi '@fuel-ts/abi-coder': specifier: workspace:* version: link:../abi-coder - '@fuel-ts/abi-typegen': - specifier: workspace:* - version: link:../abi-typegen '@fuel-ts/account': specifier: workspace:* version: link:../account diff --git a/templates/nextjs/src/sway-api/common.ts b/templates/nextjs/src/sway-api/common.ts new file mode 100644 index 00000000000..43cb6e6689e --- /dev/null +++ b/templates/nextjs/src/sway-api/common.ts @@ -0,0 +1,53 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + + +import type { FunctionFragment, InvokeFunction } from 'fuels'; + +/** + * Mimics Sway Enum. + * Requires one and only one Key-Value pair and raises error if more are provided. + */ +export type Enum = { + [K in keyof T]: Pick & { [P in Exclude]?: never }; +}[keyof T]; + +/** + * Mimics Sway Option type. + */ +export type Option = T | undefined; + +/** + * Mimics Sway Result enum type. + * Ok represents the success case, while Err represents the error case. + */ +export type Result = Enum<{ Ok: T; Err: E }>; + +/** + * Mimics Sway array type. For example, [u64; 10] is converted to ArrayOfLength. + */ +export type ArrayOfLength< + T, + Length extends number, + Arr extends unknown[] = [], +> = Arr['length'] extends Length ? Arr : ArrayOfLength; + +interface Types { + functions: Record; + configurables: Partial>; +} + +export type ProgramFunctionMapper = { + [K in keyof T]: InvokeFunction; +}; + +export type InterfaceFunctionMapper = { + [K in keyof T]: FunctionFragment; +}; \ No newline at end of file diff --git a/templates/vite/src/sway-api/common.ts b/templates/vite/src/sway-api/common.ts new file mode 100644 index 00000000000..43cb6e6689e --- /dev/null +++ b/templates/vite/src/sway-api/common.ts @@ -0,0 +1,53 @@ +/* Autogenerated file. Do not edit manually. */ + +/* eslint-disable eslint-comments/no-unlimited-disable */ +/* eslint-disable */ + +/* + Fuels version: 0.98.0 + Forc version: 0.66.5 +*/ + + +import type { FunctionFragment, InvokeFunction } from 'fuels'; + +/** + * Mimics Sway Enum. + * Requires one and only one Key-Value pair and raises error if more are provided. + */ +export type Enum = { + [K in keyof T]: Pick & { [P in Exclude]?: never }; +}[keyof T]; + +/** + * Mimics Sway Option type. + */ +export type Option = T | undefined; + +/** + * Mimics Sway Result enum type. + * Ok represents the success case, while Err represents the error case. + */ +export type Result = Enum<{ Ok: T; Err: E }>; + +/** + * Mimics Sway array type. For example, [u64; 10] is converted to ArrayOfLength. + */ +export type ArrayOfLength< + T, + Length extends number, + Arr extends unknown[] = [], +> = Arr['length'] extends Length ? Arr : ArrayOfLength; + +interface Types { + functions: Record; + configurables: Partial>; +} + +export type ProgramFunctionMapper = { + [K in keyof T]: InvokeFunction; +}; + +export type InterfaceFunctionMapper = { + [K in keyof T]: FunctionFragment; +}; \ No newline at end of file