From 831dc130413430481f8af61056f5a397dea436f6 Mon Sep 17 00:00:00 2001 From: karooolis Date: Mon, 12 Aug 2024 15:01:20 +0200 Subject: [PATCH 01/10] deduplicate world abi --- packages/world/ts/deduplicateAbi.ts | 24 ++++++++++++++++++++++++ packages/world/ts/getWorldAbi.ts | 3 ++- 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 packages/world/ts/deduplicateAbi.ts diff --git a/packages/world/ts/deduplicateAbi.ts b/packages/world/ts/deduplicateAbi.ts new file mode 100644 index 0000000000..9c1b54f3d5 --- /dev/null +++ b/packages/world/ts/deduplicateAbi.ts @@ -0,0 +1,24 @@ +import { Abi, AbiItem } from "viem"; + +function hasNamedInputs(entry: AbiItem) { + if (!("inputs" in entry) || !entry.inputs || !entry.inputs.length) { + return false; + } + return entry.inputs.some((input) => input.name); +} + +// during deduplication, favor ABI items with named inputs +export function deduplicateAbi(abi: Abi) { + const uniqueEntries = new Map(); + + for (const entry of abi) { + const key = "name" in entry ? `${entry.type}_${entry.name}` : entry.type; + const existingEntry = uniqueEntries.get(key); + + if (!existingEntry || (hasNamedInputs(entry) && !hasNamedInputs(existingEntry))) { + uniqueEntries.set(key, entry); + } + } + + return Array.from(uniqueEntries.values()); +} diff --git a/packages/world/ts/getWorldAbi.ts b/packages/world/ts/getWorldAbi.ts index 8509782333..40fe0c2933 100644 --- a/packages/world/ts/getWorldAbi.ts +++ b/packages/world/ts/getWorldAbi.ts @@ -2,6 +2,7 @@ import { Client, Abi, Address, getAddress } from "viem"; import IBaseWorldAbi from "../out/IBaseWorld.sol/IBaseWorld.abi.json"; import { functionSignatureToAbiItem } from "./functionSignatureToAbiItem"; import { getFunctions } from "./getFunctions"; +import { deduplicateAbi } from "./deduplicateAbi"; export async function getWorldAbi({ client, @@ -21,7 +22,7 @@ export async function getWorldAbi({ toBlock, }); const worldFunctionsAbi = worldFunctions.map((func) => functionSignatureToAbiItem(func.signature)); - const abi = [...IBaseWorldAbi, ...worldFunctionsAbi]; + const abi = deduplicateAbi([...IBaseWorldAbi, ...worldFunctionsAbi]); return abi; } From aa433f99cd8ab378c557a14fbb195068590b7244 Mon Sep 17 00:00:00 2001 From: karooolis Date: Mon, 12 Aug 2024 16:15:05 +0200 Subject: [PATCH 02/10] use function signature as key --- packages/world/ts/deduplicateAbi.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/world/ts/deduplicateAbi.ts b/packages/world/ts/deduplicateAbi.ts index 9c1b54f3d5..2e67f669c3 100644 --- a/packages/world/ts/deduplicateAbi.ts +++ b/packages/world/ts/deduplicateAbi.ts @@ -1,4 +1,4 @@ -import { Abi, AbiItem } from "viem"; +import { Abi, AbiItem, toFunctionSignature } from "viem"; function hasNamedInputs(entry: AbiItem) { if (!("inputs" in entry) || !entry.inputs || !entry.inputs.length) { @@ -7,12 +7,17 @@ function hasNamedInputs(entry: AbiItem) { return entry.inputs.some((input) => input.name); } -// during deduplication, favor ABI items with named inputs +// favor ABI items with named inputs when deduplicating export function deduplicateAbi(abi: Abi) { const uniqueEntries = new Map(); for (const entry of abi) { - const key = "name" in entry ? `${entry.type}_${entry.name}` : entry.type; + const key = + entry.type === "function" + ? toFunctionSignature(entry) + : "name" in entry + ? `${entry.type}_${entry.name}` + : entry.type; const existingEntry = uniqueEntries.get(key); if (!existingEntry || (hasNamedInputs(entry) && !hasNamedInputs(existingEntry))) { From 79d5c80026ffa2829cf884364126e909ba22fd09 Mon Sep 17 00:00:00 2001 From: karooolis Date: Mon, 12 Aug 2024 17:55:03 +0200 Subject: [PATCH 03/10] concatenate base + world abi, add test --- packages/world/ts/concatBaseAbi.test.ts | 12 + packages/world/ts/concatBaseAbi.ts | 24 + packages/world/ts/getWorldAbi.ts | 5 +- packages/world/ts/mocks/combinedAbi.ts | 1179 +++++++++++++++++++++++ 4 files changed, 1217 insertions(+), 3 deletions(-) create mode 100644 packages/world/ts/concatBaseAbi.test.ts create mode 100644 packages/world/ts/concatBaseAbi.ts create mode 100644 packages/world/ts/mocks/combinedAbi.ts diff --git a/packages/world/ts/concatBaseAbi.test.ts b/packages/world/ts/concatBaseAbi.test.ts new file mode 100644 index 0000000000..bd339a80fe --- /dev/null +++ b/packages/world/ts/concatBaseAbi.test.ts @@ -0,0 +1,12 @@ +import { describe, expect, it } from "vitest"; +import { Abi } from "viem"; +import worldAbi from "./mocks/worldAbi"; +import { concatBaseAbi } from "./concatBaseAbi"; +import combinedAbi from "./mocks/combinedAbi"; + +describe("World ABI", () => { + it("should concat base and world ABI", () => { + const abi = concatBaseAbi(worldAbi as Abi); + expect(abi).toMatchObject(combinedAbi); + }); +}); diff --git a/packages/world/ts/concatBaseAbi.ts b/packages/world/ts/concatBaseAbi.ts new file mode 100644 index 0000000000..1f2ad3fbae --- /dev/null +++ b/packages/world/ts/concatBaseAbi.ts @@ -0,0 +1,24 @@ +import { Abi, AbiItem, toFunctionSignature, toEventSignature } from "viem"; +import IBaseWorldAbi from "../out/IBaseWorld.sol/IBaseWorld.abi.json"; + +function getKey(abiItem: AbiItem): string { + if (abiItem.type === "function") { + return toFunctionSignature(abiItem); + } else if (abiItem.type === "event") { + return toEventSignature(abiItem); + } else if ("name" in abiItem) { + return `${abiItem.type}_${abiItem.name}`; + } + return abiItem.type; +} + +export function concatBaseAbi(worldAbi: Abi): Abi { + const baseKeys = IBaseWorldAbi.map(getKey); + const worldFunctionsAbi = worldAbi.filter((abiItem) => { + const key = getKey(abiItem); + return !baseKeys.includes(key); + }); + const abi = [...IBaseWorldAbi, ...worldFunctionsAbi]; + + return abi; +} diff --git a/packages/world/ts/getWorldAbi.ts b/packages/world/ts/getWorldAbi.ts index 40fe0c2933..07d2a3f9d4 100644 --- a/packages/world/ts/getWorldAbi.ts +++ b/packages/world/ts/getWorldAbi.ts @@ -1,8 +1,7 @@ import { Client, Abi, Address, getAddress } from "viem"; -import IBaseWorldAbi from "../out/IBaseWorld.sol/IBaseWorld.abi.json"; import { functionSignatureToAbiItem } from "./functionSignatureToAbiItem"; import { getFunctions } from "./getFunctions"; -import { deduplicateAbi } from "./deduplicateAbi"; +import { concatBaseAbi } from "./concatBaseAbi"; export async function getWorldAbi({ client, @@ -22,7 +21,7 @@ export async function getWorldAbi({ toBlock, }); const worldFunctionsAbi = worldFunctions.map((func) => functionSignatureToAbiItem(func.signature)); - const abi = deduplicateAbi([...IBaseWorldAbi, ...worldFunctionsAbi]); + const abi = concatBaseAbi(worldFunctionsAbi); return abi; } diff --git a/packages/world/ts/mocks/combinedAbi.ts b/packages/world/ts/mocks/combinedAbi.ts new file mode 100644 index 0000000000..04a08cf23d --- /dev/null +++ b/packages/world/ts/mocks/combinedAbi.ts @@ -0,0 +1,1179 @@ +export default [ + { + type: "function", + name: "batchCall", + inputs: [ + { + name: "systemCalls", + type: "tuple[]", + internalType: "struct SystemCallData[]", + components: [ + { + name: "systemId", + type: "bytes32", + internalType: "ResourceId", + }, + { name: "callData", type: "bytes", internalType: "bytes" }, + ], + }, + ], + outputs: [{ name: "returnDatas", type: "bytes[]", internalType: "bytes[]" }], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "batchCallFrom", + inputs: [ + { + name: "systemCalls", + type: "tuple[]", + internalType: "struct SystemCallFromData[]", + components: [ + { name: "from", type: "address", internalType: "address" }, + { + name: "systemId", + type: "bytes32", + internalType: "ResourceId", + }, + { name: "callData", type: "bytes", internalType: "bytes" }, + ], + }, + ], + outputs: [{ name: "returnDatas", type: "bytes[]", internalType: "bytes[]" }], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "call", + inputs: [ + { name: "systemId", type: "bytes32", internalType: "ResourceId" }, + { name: "callData", type: "bytes", internalType: "bytes" }, + ], + outputs: [{ name: "", type: "bytes", internalType: "bytes" }], + stateMutability: "payable", + }, + { + type: "function", + name: "callFrom", + inputs: [ + { name: "delegator", type: "address", internalType: "address" }, + { name: "systemId", type: "bytes32", internalType: "ResourceId" }, + { name: "callData", type: "bytes", internalType: "bytes" }, + ], + outputs: [{ name: "", type: "bytes", internalType: "bytes" }], + stateMutability: "payable", + }, + { + type: "function", + name: "creator", + inputs: [], + outputs: [{ name: "", type: "address", internalType: "address" }], + stateMutability: "view", + }, + { + type: "function", + name: "deleteRecord", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "getDynamicField", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, + { name: "dynamicFieldIndex", type: "uint8", internalType: "uint8" }, + ], + outputs: [{ name: "", type: "bytes", internalType: "bytes" }], + stateMutability: "view", + }, + { + type: "function", + name: "getDynamicFieldLength", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, + { name: "dynamicFieldIndex", type: "uint8", internalType: "uint8" }, + ], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "getDynamicFieldSlice", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, + { name: "dynamicFieldIndex", type: "uint8", internalType: "uint8" }, + { name: "start", type: "uint256", internalType: "uint256" }, + { name: "end", type: "uint256", internalType: "uint256" }, + ], + outputs: [{ name: "data", type: "bytes", internalType: "bytes" }], + stateMutability: "view", + }, + { + type: "function", + name: "getField", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, + { name: "fieldIndex", type: "uint8", internalType: "uint8" }, + { + name: "fieldLayout", + type: "bytes32", + internalType: "FieldLayout", + }, + ], + outputs: [{ name: "data", type: "bytes", internalType: "bytes" }], + stateMutability: "view", + }, + { + type: "function", + name: "getField", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, + { name: "fieldIndex", type: "uint8", internalType: "uint8" }, + ], + outputs: [{ name: "data", type: "bytes", internalType: "bytes" }], + stateMutability: "view", + }, + { + type: "function", + name: "getFieldLayout", + inputs: [{ name: "tableId", type: "bytes32", internalType: "ResourceId" }], + outputs: [ + { + name: "fieldLayout", + type: "bytes32", + internalType: "FieldLayout", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "getFieldLength", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, + { name: "fieldIndex", type: "uint8", internalType: "uint8" }, + { + name: "fieldLayout", + type: "bytes32", + internalType: "FieldLayout", + }, + ], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "getFieldLength", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, + { name: "fieldIndex", type: "uint8", internalType: "uint8" }, + ], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "getKeySchema", + inputs: [{ name: "tableId", type: "bytes32", internalType: "ResourceId" }], + outputs: [{ name: "keySchema", type: "bytes32", internalType: "Schema" }], + stateMutability: "view", + }, + { + type: "function", + name: "getRecord", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, + { + name: "fieldLayout", + type: "bytes32", + internalType: "FieldLayout", + }, + ], + outputs: [ + { name: "staticData", type: "bytes", internalType: "bytes" }, + { + name: "encodedLengths", + type: "bytes32", + internalType: "EncodedLengths", + }, + { name: "dynamicData", type: "bytes", internalType: "bytes" }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "getRecord", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, + ], + outputs: [ + { name: "staticData", type: "bytes", internalType: "bytes" }, + { + name: "encodedLengths", + type: "bytes32", + internalType: "EncodedLengths", + }, + { name: "dynamicData", type: "bytes", internalType: "bytes" }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "getStaticField", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, + { name: "fieldIndex", type: "uint8", internalType: "uint8" }, + { + name: "fieldLayout", + type: "bytes32", + internalType: "FieldLayout", + }, + ], + outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }], + stateMutability: "view", + }, + { + type: "function", + name: "getValueSchema", + inputs: [{ name: "tableId", type: "bytes32", internalType: "ResourceId" }], + outputs: [{ name: "valueSchema", type: "bytes32", internalType: "Schema" }], + stateMutability: "view", + }, + { + type: "function", + name: "grantAccess", + inputs: [ + { name: "resourceId", type: "bytes32", internalType: "ResourceId" }, + { name: "grantee", type: "address", internalType: "address" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "initialize", + inputs: [ + { + name: "initModule", + type: "address", + internalType: "contract IModule", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "installModule", + inputs: [ + { + name: "module", + type: "address", + internalType: "contract IModule", + }, + { name: "encodedArgs", type: "bytes", internalType: "bytes" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "installRootModule", + inputs: [ + { + name: "module", + type: "address", + internalType: "contract IModule", + }, + { name: "encodedArgs", type: "bytes", internalType: "bytes" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "popFromDynamicField", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, + { name: "dynamicFieldIndex", type: "uint8", internalType: "uint8" }, + { + name: "byteLengthToPop", + type: "uint256", + internalType: "uint256", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "pushToDynamicField", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, + { name: "dynamicFieldIndex", type: "uint8", internalType: "uint8" }, + { name: "dataToPush", type: "bytes", internalType: "bytes" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "registerDelegation", + inputs: [ + { name: "delegatee", type: "address", internalType: "address" }, + { + name: "delegationControlId", + type: "bytes32", + internalType: "ResourceId", + }, + { name: "initCallData", type: "bytes", internalType: "bytes" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "registerFunctionSelector", + inputs: [ + { name: "systemId", type: "bytes32", internalType: "ResourceId" }, + { + name: "systemFunctionSignature", + type: "string", + internalType: "string", + }, + ], + outputs: [ + { + name: "worldFunctionSelector", + type: "bytes4", + internalType: "bytes4", + }, + ], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "registerNamespace", + inputs: [{ name: "namespaceId", type: "bytes32", internalType: "ResourceId" }], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "registerNamespaceDelegation", + inputs: [ + { + name: "namespaceId", + type: "bytes32", + internalType: "ResourceId", + }, + { + name: "delegationControlId", + type: "bytes32", + internalType: "ResourceId", + }, + { name: "initCallData", type: "bytes", internalType: "bytes" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "registerRootFunctionSelector", + inputs: [ + { name: "systemId", type: "bytes32", internalType: "ResourceId" }, + { + name: "worldFunctionSignature", + type: "string", + internalType: "string", + }, + { + name: "systemFunctionSignature", + type: "string", + internalType: "string", + }, + ], + outputs: [ + { + name: "worldFunctionSelector", + type: "bytes4", + internalType: "bytes4", + }, + ], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "registerStoreHook", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { + name: "hookAddress", + type: "address", + internalType: "contract IStoreHook", + }, + { name: "enabledHooksBitmap", type: "uint8", internalType: "uint8" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "registerSystem", + inputs: [ + { name: "systemId", type: "bytes32", internalType: "ResourceId" }, + { + name: "system", + type: "address", + internalType: "contract System", + }, + { name: "publicAccess", type: "bool", internalType: "bool" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "registerSystemHook", + inputs: [ + { name: "systemId", type: "bytes32", internalType: "ResourceId" }, + { + name: "hookAddress", + type: "address", + internalType: "contract ISystemHook", + }, + { name: "enabledHooksBitmap", type: "uint8", internalType: "uint8" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "registerTable", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { + name: "fieldLayout", + type: "bytes32", + internalType: "FieldLayout", + }, + { name: "keySchema", type: "bytes32", internalType: "Schema" }, + { name: "valueSchema", type: "bytes32", internalType: "Schema" }, + { name: "keyNames", type: "string[]", internalType: "string[]" }, + { name: "fieldNames", type: "string[]", internalType: "string[]" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "renounceOwnership", + inputs: [{ name: "namespaceId", type: "bytes32", internalType: "ResourceId" }], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "revokeAccess", + inputs: [ + { name: "resourceId", type: "bytes32", internalType: "ResourceId" }, + { name: "grantee", type: "address", internalType: "address" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "setDynamicField", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, + { name: "dynamicFieldIndex", type: "uint8", internalType: "uint8" }, + { name: "data", type: "bytes", internalType: "bytes" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "setField", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, + { name: "fieldIndex", type: "uint8", internalType: "uint8" }, + { name: "data", type: "bytes", internalType: "bytes" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "setField", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, + { name: "fieldIndex", type: "uint8", internalType: "uint8" }, + { name: "data", type: "bytes", internalType: "bytes" }, + { + name: "fieldLayout", + type: "bytes32", + internalType: "FieldLayout", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "setRecord", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, + { name: "staticData", type: "bytes", internalType: "bytes" }, + { + name: "encodedLengths", + type: "bytes32", + internalType: "EncodedLengths", + }, + { name: "dynamicData", type: "bytes", internalType: "bytes" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "setStaticField", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, + { name: "fieldIndex", type: "uint8", internalType: "uint8" }, + { name: "data", type: "bytes", internalType: "bytes" }, + { + name: "fieldLayout", + type: "bytes32", + internalType: "FieldLayout", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "spliceDynamicData", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, + { name: "dynamicFieldIndex", type: "uint8", internalType: "uint8" }, + { + name: "startWithinField", + type: "uint40", + internalType: "uint40", + }, + { name: "deleteCount", type: "uint40", internalType: "uint40" }, + { name: "data", type: "bytes", internalType: "bytes" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "spliceStaticData", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, + { name: "start", type: "uint48", internalType: "uint48" }, + { name: "data", type: "bytes", internalType: "bytes" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "storeVersion", + inputs: [], + outputs: [{ name: "version", type: "bytes32", internalType: "bytes32" }], + stateMutability: "view", + }, + { + type: "function", + name: "transferBalanceToAddress", + inputs: [ + { + name: "fromNamespaceId", + type: "bytes32", + internalType: "ResourceId", + }, + { name: "toAddress", type: "address", internalType: "address" }, + { name: "amount", type: "uint256", internalType: "uint256" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "transferBalanceToNamespace", + inputs: [ + { + name: "fromNamespaceId", + type: "bytes32", + internalType: "ResourceId", + }, + { + name: "toNamespaceId", + type: "bytes32", + internalType: "ResourceId", + }, + { name: "amount", type: "uint256", internalType: "uint256" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "transferOwnership", + inputs: [ + { + name: "namespaceId", + type: "bytes32", + internalType: "ResourceId", + }, + { name: "newOwner", type: "address", internalType: "address" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "unregisterDelegation", + inputs: [{ name: "delegatee", type: "address", internalType: "address" }], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "unregisterNamespaceDelegation", + inputs: [{ name: "namespaceId", type: "bytes32", internalType: "ResourceId" }], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "unregisterStoreHook", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { + name: "hookAddress", + type: "address", + internalType: "contract IStoreHook", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "unregisterSystemHook", + inputs: [ + { name: "systemId", type: "bytes32", internalType: "ResourceId" }, + { + name: "hookAddress", + type: "address", + internalType: "contract ISystemHook", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "worldVersion", + inputs: [], + outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }], + stateMutability: "view", + }, + { + type: "event", + name: "HelloStore", + inputs: [ + { + name: "storeVersion", + type: "bytes32", + indexed: true, + internalType: "bytes32", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "HelloWorld", + inputs: [ + { + name: "worldVersion", + type: "bytes32", + indexed: true, + internalType: "bytes32", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "Store_DeleteRecord", + inputs: [ + { + name: "tableId", + type: "bytes32", + indexed: true, + internalType: "ResourceId", + }, + { + name: "keyTuple", + type: "bytes32[]", + indexed: false, + internalType: "bytes32[]", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "Store_SetRecord", + inputs: [ + { + name: "tableId", + type: "bytes32", + indexed: true, + internalType: "ResourceId", + }, + { + name: "keyTuple", + type: "bytes32[]", + indexed: false, + internalType: "bytes32[]", + }, + { + name: "staticData", + type: "bytes", + indexed: false, + internalType: "bytes", + }, + { + name: "encodedLengths", + type: "bytes32", + indexed: false, + internalType: "EncodedLengths", + }, + { + name: "dynamicData", + type: "bytes", + indexed: false, + internalType: "bytes", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "Store_SpliceDynamicData", + inputs: [ + { + name: "tableId", + type: "bytes32", + indexed: true, + internalType: "ResourceId", + }, + { + name: "keyTuple", + type: "bytes32[]", + indexed: false, + internalType: "bytes32[]", + }, + { + name: "dynamicFieldIndex", + type: "uint8", + indexed: false, + internalType: "uint8", + }, + { + name: "start", + type: "uint48", + indexed: false, + internalType: "uint48", + }, + { + name: "deleteCount", + type: "uint40", + indexed: false, + internalType: "uint40", + }, + { + name: "encodedLengths", + type: "bytes32", + indexed: false, + internalType: "EncodedLengths", + }, + { + name: "data", + type: "bytes", + indexed: false, + internalType: "bytes", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "Store_SpliceStaticData", + inputs: [ + { + name: "tableId", + type: "bytes32", + indexed: true, + internalType: "ResourceId", + }, + { + name: "keyTuple", + type: "bytes32[]", + indexed: false, + internalType: "bytes32[]", + }, + { + name: "start", + type: "uint48", + indexed: false, + internalType: "uint48", + }, + { + name: "data", + type: "bytes", + indexed: false, + internalType: "bytes", + }, + ], + anonymous: false, + }, + { + type: "error", + name: "EncodedLengths_InvalidLength", + inputs: [{ name: "length", type: "uint256", internalType: "uint256" }], + }, + { type: "error", name: "FieldLayout_Empty", inputs: [] }, + { + type: "error", + name: "FieldLayout_InvalidStaticDataLength", + inputs: [ + { + name: "staticDataLength", + type: "uint256", + internalType: "uint256", + }, + { + name: "computedStaticDataLength", + type: "uint256", + internalType: "uint256", + }, + ], + }, + { + type: "error", + name: "FieldLayout_StaticLengthDoesNotFitInAWord", + inputs: [{ name: "index", type: "uint256", internalType: "uint256" }], + }, + { + type: "error", + name: "FieldLayout_StaticLengthIsNotZero", + inputs: [{ name: "index", type: "uint256", internalType: "uint256" }], + }, + { + type: "error", + name: "FieldLayout_StaticLengthIsZero", + inputs: [{ name: "index", type: "uint256", internalType: "uint256" }], + }, + { + type: "error", + name: "FieldLayout_TooManyDynamicFields", + inputs: [ + { name: "numFields", type: "uint256", internalType: "uint256" }, + { name: "maxFields", type: "uint256", internalType: "uint256" }, + ], + }, + { + type: "error", + name: "FieldLayout_TooManyFields", + inputs: [ + { name: "numFields", type: "uint256", internalType: "uint256" }, + { name: "maxFields", type: "uint256", internalType: "uint256" }, + ], + }, + { type: "error", name: "Module_AlreadyInstalled", inputs: [] }, + { + type: "error", + name: "Module_MissingDependency", + inputs: [{ name: "dependency", type: "address", internalType: "address" }], + }, + { + type: "error", + name: "Module_NonRootInstallNotSupported", + inputs: [], + }, + { type: "error", name: "Module_RootInstallNotSupported", inputs: [] }, + { + type: "error", + name: "Schema_InvalidLength", + inputs: [{ name: "length", type: "uint256", internalType: "uint256" }], + }, + { + type: "error", + name: "Schema_StaticTypeAfterDynamicType", + inputs: [], + }, + { + type: "error", + name: "Slice_OutOfBounds", + inputs: [ + { name: "data", type: "bytes", internalType: "bytes" }, + { name: "start", type: "uint256", internalType: "uint256" }, + { name: "end", type: "uint256", internalType: "uint256" }, + ], + }, + { + type: "error", + name: "Store_IndexOutOfBounds", + inputs: [ + { name: "length", type: "uint256", internalType: "uint256" }, + { name: "accessedIndex", type: "uint256", internalType: "uint256" }, + ], + }, + { + type: "error", + name: "Store_InvalidBounds", + inputs: [ + { name: "start", type: "uint256", internalType: "uint256" }, + { name: "end", type: "uint256", internalType: "uint256" }, + ], + }, + { + type: "error", + name: "Store_InvalidFieldNamesLength", + inputs: [ + { name: "expected", type: "uint256", internalType: "uint256" }, + { name: "received", type: "uint256", internalType: "uint256" }, + ], + }, + { + type: "error", + name: "Store_InvalidKeyNamesLength", + inputs: [ + { name: "expected", type: "uint256", internalType: "uint256" }, + { name: "received", type: "uint256", internalType: "uint256" }, + ], + }, + { + type: "error", + name: "Store_InvalidResourceType", + inputs: [ + { name: "expected", type: "bytes2", internalType: "bytes2" }, + { name: "resourceId", type: "bytes32", internalType: "ResourceId" }, + { name: "resourceIdString", type: "string", internalType: "string" }, + ], + }, + { + type: "error", + name: "Store_InvalidSplice", + inputs: [ + { + name: "startWithinField", + type: "uint40", + internalType: "uint40", + }, + { name: "deleteCount", type: "uint40", internalType: "uint40" }, + { name: "fieldLength", type: "uint40", internalType: "uint40" }, + ], + }, + { + type: "error", + name: "Store_InvalidStaticDataLength", + inputs: [ + { name: "expected", type: "uint256", internalType: "uint256" }, + { name: "received", type: "uint256", internalType: "uint256" }, + ], + }, + { + type: "error", + name: "Store_InvalidValueSchemaDynamicLength", + inputs: [ + { name: "expected", type: "uint256", internalType: "uint256" }, + { name: "received", type: "uint256", internalType: "uint256" }, + ], + }, + { + type: "error", + name: "Store_InvalidValueSchemaLength", + inputs: [ + { name: "expected", type: "uint256", internalType: "uint256" }, + { name: "received", type: "uint256", internalType: "uint256" }, + ], + }, + { + type: "error", + name: "Store_InvalidValueSchemaStaticLength", + inputs: [ + { name: "expected", type: "uint256", internalType: "uint256" }, + { name: "received", type: "uint256", internalType: "uint256" }, + ], + }, + { + type: "error", + name: "Store_TableAlreadyExists", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "tableIdString", type: "string", internalType: "string" }, + ], + }, + { + type: "error", + name: "Store_TableNotFound", + inputs: [ + { name: "tableId", type: "bytes32", internalType: "ResourceId" }, + { name: "tableIdString", type: "string", internalType: "string" }, + ], + }, + { + type: "error", + name: "World_AccessDenied", + inputs: [ + { name: "resource", type: "string", internalType: "string" }, + { name: "caller", type: "address", internalType: "address" }, + ], + }, + { type: "error", name: "World_AlreadyInitialized", inputs: [] }, + { + type: "error", + name: "World_CallbackNotAllowed", + inputs: [{ name: "functionSelector", type: "bytes4", internalType: "bytes4" }], + }, + { + type: "error", + name: "World_DelegationNotFound", + inputs: [ + { name: "delegator", type: "address", internalType: "address" }, + { name: "delegatee", type: "address", internalType: "address" }, + ], + }, + { + type: "error", + name: "World_FunctionSelectorAlreadyExists", + inputs: [{ name: "functionSelector", type: "bytes4", internalType: "bytes4" }], + }, + { + type: "error", + name: "World_FunctionSelectorNotFound", + inputs: [{ name: "functionSelector", type: "bytes4", internalType: "bytes4" }], + }, + { + type: "error", + name: "World_InsufficientBalance", + inputs: [ + { name: "balance", type: "uint256", internalType: "uint256" }, + { name: "amount", type: "uint256", internalType: "uint256" }, + ], + }, + { + type: "error", + name: "World_InterfaceNotSupported", + inputs: [ + { + name: "contractAddress", + type: "address", + internalType: "address", + }, + { name: "interfaceId", type: "bytes4", internalType: "bytes4" }, + ], + }, + { + type: "error", + name: "World_InvalidNamespace", + inputs: [{ name: "namespace", type: "bytes14", internalType: "bytes14" }], + }, + { + type: "error", + name: "World_InvalidResourceId", + inputs: [ + { name: "resourceId", type: "bytes32", internalType: "ResourceId" }, + { name: "resourceIdString", type: "string", internalType: "string" }, + ], + }, + { + type: "error", + name: "World_InvalidResourceType", + inputs: [ + { name: "expected", type: "bytes2", internalType: "bytes2" }, + { name: "resourceId", type: "bytes32", internalType: "ResourceId" }, + { name: "resourceIdString", type: "string", internalType: "string" }, + ], + }, + { + type: "error", + name: "World_ResourceAlreadyExists", + inputs: [ + { name: "resourceId", type: "bytes32", internalType: "ResourceId" }, + { name: "resourceIdString", type: "string", internalType: "string" }, + ], + }, + { + type: "error", + name: "World_ResourceNotFound", + inputs: [ + { name: "resourceId", type: "bytes32", internalType: "ResourceId" }, + { name: "resourceIdString", type: "string", internalType: "string" }, + ], + }, + { + type: "error", + name: "World_SystemAlreadyExists", + inputs: [{ name: "system", type: "address", internalType: "address" }], + }, + { + type: "error", + name: "World_UnlimitedDelegationNotAllowed", + inputs: [], + }, + { + name: "app__increment", + type: "function", + stateMutability: "nonpayable", + inputs: [], + outputs: [], + }, + { + type: "function", + name: "setNumber", + inputs: [{ name: "isNumberSet", type: "bool", internalType: "bool" }], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "setNumber", + inputs: [{ name: "newNumber", type: "uint256", internalType: "uint256" }], + outputs: [], + stateMutability: "nonpayable", + }, +]; From c4c406653f4deccaf3f6fb4bfa2bba1e1d9ece68 Mon Sep 17 00:00:00 2001 From: karooolis Date: Mon, 12 Aug 2024 17:58:30 +0200 Subject: [PATCH 04/10] add missing world abi mock --- packages/world/ts/mocks/worldAbi.ts | 178 ++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 packages/world/ts/mocks/worldAbi.ts diff --git a/packages/world/ts/mocks/worldAbi.ts b/packages/world/ts/mocks/worldAbi.ts new file mode 100644 index 0000000000..cb9a1a49a6 --- /dev/null +++ b/packages/world/ts/mocks/worldAbi.ts @@ -0,0 +1,178 @@ +export default [ + { name: "app__increment", type: "function", stateMutability: "nonpayable", inputs: [], outputs: [] }, + { + type: "function", + name: "setNumber", + inputs: [{ name: "isNumberSet", type: "bool", internalType: "bool" }], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "setNumber", + inputs: [{ name: "newNumber", type: "uint256", internalType: "uint256" }], + outputs: [], + stateMutability: "nonpayable", + }, + { + name: "batchCall", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "tuple[]", components: [{ type: "bytes32" }, { type: "bytes" }] }], + outputs: [], + }, + { + name: "batchCallFrom", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "tuple[]", components: [{ type: "address" }, { type: "bytes32" }, { type: "bytes" }] }], + outputs: [], + }, + { + name: "grantAccess", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "bytes32" }, { type: "address" }], + outputs: [], + }, + { + name: "installModule", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "address" }, { type: "bytes" }], + outputs: [], + }, + { + name: "registerDelegation", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "address" }, { type: "bytes32" }, { type: "bytes" }], + outputs: [], + }, + { + name: "registerFunctionSelector", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "bytes32" }, { type: "string" }], + outputs: [], + }, + { + name: "registerNamespace", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "bytes32" }], + outputs: [], + }, + { + name: "registerNamespaceDelegation", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "bytes32" }, { type: "bytes32" }, { type: "bytes" }], + outputs: [], + }, + { + name: "registerRootFunctionSelector", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "bytes32" }, { type: "string" }, { type: "string" }], + outputs: [], + }, + { + name: "registerStoreHook", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "bytes32" }, { type: "address" }, { type: "uint8" }], + outputs: [], + }, + { + name: "registerSystem", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "bytes32" }, { type: "address" }, { type: "bool" }], + outputs: [], + }, + { + name: "registerSystemHook", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "bytes32" }, { type: "address" }, { type: "uint8" }], + outputs: [], + }, + { + name: "registerTable", + type: "function", + stateMutability: "nonpayable", + inputs: [ + { type: "bytes32" }, + { type: "bytes32" }, + { type: "bytes32" }, + { type: "bytes32" }, + { type: "string[]" }, + { type: "string[]" }, + ], + outputs: [], + }, + { + name: "renounceOwnership", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "bytes32" }], + outputs: [], + }, + { + name: "revokeAccess", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "bytes32" }, { type: "address" }], + outputs: [], + }, + { + name: "transferBalanceToAddress", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "bytes32" }, { type: "address" }, { type: "uint256" }], + outputs: [], + }, + { + name: "transferBalanceToNamespace", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "bytes32" }, { type: "bytes32" }, { type: "uint256" }], + outputs: [], + }, + { + name: "transferOwnership", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "bytes32" }, { type: "address" }], + outputs: [], + }, + { + name: "unregisterDelegation", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "address" }], + outputs: [], + }, + { + name: "unregisterNamespaceDelegation", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "bytes32" }], + outputs: [], + }, + { + name: "unregisterStoreHook", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "bytes32" }, { type: "address" }], + outputs: [], + }, + { + name: "unregisterSystemHook", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "bytes32" }, { type: "address" }], + outputs: [], + }, +]; From 3f6ce3cc431e6625a40609282f7773347e5aa858 Mon Sep 17 00:00:00 2001 From: karooolis Date: Tue, 13 Aug 2024 10:16:12 +0200 Subject: [PATCH 05/10] remove deduplicateAbi --- packages/world/ts/deduplicateAbi.ts | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 packages/world/ts/deduplicateAbi.ts diff --git a/packages/world/ts/deduplicateAbi.ts b/packages/world/ts/deduplicateAbi.ts deleted file mode 100644 index 2e67f669c3..0000000000 --- a/packages/world/ts/deduplicateAbi.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Abi, AbiItem, toFunctionSignature } from "viem"; - -function hasNamedInputs(entry: AbiItem) { - if (!("inputs" in entry) || !entry.inputs || !entry.inputs.length) { - return false; - } - return entry.inputs.some((input) => input.name); -} - -// favor ABI items with named inputs when deduplicating -export function deduplicateAbi(abi: Abi) { - const uniqueEntries = new Map(); - - for (const entry of abi) { - const key = - entry.type === "function" - ? toFunctionSignature(entry) - : "name" in entry - ? `${entry.type}_${entry.name}` - : entry.type; - const existingEntry = uniqueEntries.get(key); - - if (!existingEntry || (hasNamedInputs(entry) && !hasNamedInputs(existingEntry))) { - uniqueEntries.set(key, entry); - } - } - - return Array.from(uniqueEntries.values()); -} From 992def5fc18fb6ab45c68f305a7f6e532afa3f1f Mon Sep 17 00:00:00 2001 From: karooolis Date: Tue, 13 Aug 2024 12:03:41 +0200 Subject: [PATCH 06/10] use only function selectors to filter --- packages/world/ts/concatBaseAbi.ts | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/packages/world/ts/concatBaseAbi.ts b/packages/world/ts/concatBaseAbi.ts index 1f2ad3fbae..efe138e047 100644 --- a/packages/world/ts/concatBaseAbi.ts +++ b/packages/world/ts/concatBaseAbi.ts @@ -1,23 +1,15 @@ -import { Abi, AbiItem, toFunctionSignature, toEventSignature } from "viem"; +import { Abi, AbiItem, AbiFunction, toFunctionSelector } from "viem"; import IBaseWorldAbi from "../out/IBaseWorld.sol/IBaseWorld.abi.json"; -function getKey(abiItem: AbiItem): string { - if (abiItem.type === "function") { - return toFunctionSignature(abiItem); - } else if (abiItem.type === "event") { - return toEventSignature(abiItem); - } else if ("name" in abiItem) { - return `${abiItem.type}_${abiItem.name}`; - } - return abiItem.type; +function isAbiFunction(abiItem: AbiItem): abiItem is AbiFunction { + return abiItem.type === "function"; } export function concatBaseAbi(worldAbi: Abi): Abi { - const baseKeys = IBaseWorldAbi.map(getKey); - const worldFunctionsAbi = worldAbi.filter((abiItem) => { - const key = getKey(abiItem); - return !baseKeys.includes(key); - }); + const baseFunctionSelectors = (IBaseWorldAbi as Abi).filter(isAbiFunction).map(toFunctionSelector); + const worldFunctionsAbi = worldAbi.filter( + (abiItem) => !baseFunctionSelectors.includes(toFunctionSelector(abiItem as AbiFunction)), + ); const abi = [...IBaseWorldAbi, ...worldFunctionsAbi]; return abi; From 00e7562699e45d5f894a9799cd0176a6a1ce4248 Mon Sep 17 00:00:00 2001 From: karooolis Date: Tue, 13 Aug 2024 12:11:40 +0200 Subject: [PATCH 07/10] simplify test --- packages/world/ts/concatBaseAbi.test.ts | 25 +- packages/world/ts/mocks/combinedAbi.ts | 1179 ----------------------- packages/world/ts/mocks/worldAbi.ts | 178 ---- 3 files changed, 20 insertions(+), 1362 deletions(-) delete mode 100644 packages/world/ts/mocks/combinedAbi.ts delete mode 100644 packages/world/ts/mocks/worldAbi.ts diff --git a/packages/world/ts/concatBaseAbi.test.ts b/packages/world/ts/concatBaseAbi.test.ts index bd339a80fe..5d302d0d94 100644 --- a/packages/world/ts/concatBaseAbi.test.ts +++ b/packages/world/ts/concatBaseAbi.test.ts @@ -1,12 +1,27 @@ import { describe, expect, it } from "vitest"; -import { Abi } from "viem"; -import worldAbi from "./mocks/worldAbi"; +import { AbiFunction } from "viem"; import { concatBaseAbi } from "./concatBaseAbi"; -import combinedAbi from "./mocks/combinedAbi"; + +const customAbiFunction = { + type: "function", + name: "setNumber", + inputs: [{ name: "isNumberSet", type: "bool", internalType: "bool" }], + outputs: [], + stateMutability: "nonpayable", +} as AbiFunction; + +const duplicateBatchCallAbi = { + name: "batchCall", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "tuple[]", components: [{ type: "bytes32" }, { type: "bytes" }] }], + outputs: [], +} as AbiFunction; describe("World ABI", () => { it("should concat base and world ABI", () => { - const abi = concatBaseAbi(worldAbi as Abi); - expect(abi).toMatchObject(combinedAbi); + const abi = concatBaseAbi([customAbiFunction, duplicateBatchCallAbi]); + expect(abi).toContainEqual(customAbiFunction); + expect(abi).not.toContainEqual(duplicateBatchCallAbi); }); }); diff --git a/packages/world/ts/mocks/combinedAbi.ts b/packages/world/ts/mocks/combinedAbi.ts deleted file mode 100644 index 04a08cf23d..0000000000 --- a/packages/world/ts/mocks/combinedAbi.ts +++ /dev/null @@ -1,1179 +0,0 @@ -export default [ - { - type: "function", - name: "batchCall", - inputs: [ - { - name: "systemCalls", - type: "tuple[]", - internalType: "struct SystemCallData[]", - components: [ - { - name: "systemId", - type: "bytes32", - internalType: "ResourceId", - }, - { name: "callData", type: "bytes", internalType: "bytes" }, - ], - }, - ], - outputs: [{ name: "returnDatas", type: "bytes[]", internalType: "bytes[]" }], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "batchCallFrom", - inputs: [ - { - name: "systemCalls", - type: "tuple[]", - internalType: "struct SystemCallFromData[]", - components: [ - { name: "from", type: "address", internalType: "address" }, - { - name: "systemId", - type: "bytes32", - internalType: "ResourceId", - }, - { name: "callData", type: "bytes", internalType: "bytes" }, - ], - }, - ], - outputs: [{ name: "returnDatas", type: "bytes[]", internalType: "bytes[]" }], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "call", - inputs: [ - { name: "systemId", type: "bytes32", internalType: "ResourceId" }, - { name: "callData", type: "bytes", internalType: "bytes" }, - ], - outputs: [{ name: "", type: "bytes", internalType: "bytes" }], - stateMutability: "payable", - }, - { - type: "function", - name: "callFrom", - inputs: [ - { name: "delegator", type: "address", internalType: "address" }, - { name: "systemId", type: "bytes32", internalType: "ResourceId" }, - { name: "callData", type: "bytes", internalType: "bytes" }, - ], - outputs: [{ name: "", type: "bytes", internalType: "bytes" }], - stateMutability: "payable", - }, - { - type: "function", - name: "creator", - inputs: [], - outputs: [{ name: "", type: "address", internalType: "address" }], - stateMutability: "view", - }, - { - type: "function", - name: "deleteRecord", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "getDynamicField", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, - { name: "dynamicFieldIndex", type: "uint8", internalType: "uint8" }, - ], - outputs: [{ name: "", type: "bytes", internalType: "bytes" }], - stateMutability: "view", - }, - { - type: "function", - name: "getDynamicFieldLength", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, - { name: "dynamicFieldIndex", type: "uint8", internalType: "uint8" }, - ], - outputs: [{ name: "", type: "uint256", internalType: "uint256" }], - stateMutability: "view", - }, - { - type: "function", - name: "getDynamicFieldSlice", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, - { name: "dynamicFieldIndex", type: "uint8", internalType: "uint8" }, - { name: "start", type: "uint256", internalType: "uint256" }, - { name: "end", type: "uint256", internalType: "uint256" }, - ], - outputs: [{ name: "data", type: "bytes", internalType: "bytes" }], - stateMutability: "view", - }, - { - type: "function", - name: "getField", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, - { name: "fieldIndex", type: "uint8", internalType: "uint8" }, - { - name: "fieldLayout", - type: "bytes32", - internalType: "FieldLayout", - }, - ], - outputs: [{ name: "data", type: "bytes", internalType: "bytes" }], - stateMutability: "view", - }, - { - type: "function", - name: "getField", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, - { name: "fieldIndex", type: "uint8", internalType: "uint8" }, - ], - outputs: [{ name: "data", type: "bytes", internalType: "bytes" }], - stateMutability: "view", - }, - { - type: "function", - name: "getFieldLayout", - inputs: [{ name: "tableId", type: "bytes32", internalType: "ResourceId" }], - outputs: [ - { - name: "fieldLayout", - type: "bytes32", - internalType: "FieldLayout", - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "getFieldLength", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, - { name: "fieldIndex", type: "uint8", internalType: "uint8" }, - { - name: "fieldLayout", - type: "bytes32", - internalType: "FieldLayout", - }, - ], - outputs: [{ name: "", type: "uint256", internalType: "uint256" }], - stateMutability: "view", - }, - { - type: "function", - name: "getFieldLength", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, - { name: "fieldIndex", type: "uint8", internalType: "uint8" }, - ], - outputs: [{ name: "", type: "uint256", internalType: "uint256" }], - stateMutability: "view", - }, - { - type: "function", - name: "getKeySchema", - inputs: [{ name: "tableId", type: "bytes32", internalType: "ResourceId" }], - outputs: [{ name: "keySchema", type: "bytes32", internalType: "Schema" }], - stateMutability: "view", - }, - { - type: "function", - name: "getRecord", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, - { - name: "fieldLayout", - type: "bytes32", - internalType: "FieldLayout", - }, - ], - outputs: [ - { name: "staticData", type: "bytes", internalType: "bytes" }, - { - name: "encodedLengths", - type: "bytes32", - internalType: "EncodedLengths", - }, - { name: "dynamicData", type: "bytes", internalType: "bytes" }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "getRecord", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, - ], - outputs: [ - { name: "staticData", type: "bytes", internalType: "bytes" }, - { - name: "encodedLengths", - type: "bytes32", - internalType: "EncodedLengths", - }, - { name: "dynamicData", type: "bytes", internalType: "bytes" }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "getStaticField", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, - { name: "fieldIndex", type: "uint8", internalType: "uint8" }, - { - name: "fieldLayout", - type: "bytes32", - internalType: "FieldLayout", - }, - ], - outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }], - stateMutability: "view", - }, - { - type: "function", - name: "getValueSchema", - inputs: [{ name: "tableId", type: "bytes32", internalType: "ResourceId" }], - outputs: [{ name: "valueSchema", type: "bytes32", internalType: "Schema" }], - stateMutability: "view", - }, - { - type: "function", - name: "grantAccess", - inputs: [ - { name: "resourceId", type: "bytes32", internalType: "ResourceId" }, - { name: "grantee", type: "address", internalType: "address" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "initialize", - inputs: [ - { - name: "initModule", - type: "address", - internalType: "contract IModule", - }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "installModule", - inputs: [ - { - name: "module", - type: "address", - internalType: "contract IModule", - }, - { name: "encodedArgs", type: "bytes", internalType: "bytes" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "installRootModule", - inputs: [ - { - name: "module", - type: "address", - internalType: "contract IModule", - }, - { name: "encodedArgs", type: "bytes", internalType: "bytes" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "popFromDynamicField", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, - { name: "dynamicFieldIndex", type: "uint8", internalType: "uint8" }, - { - name: "byteLengthToPop", - type: "uint256", - internalType: "uint256", - }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "pushToDynamicField", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, - { name: "dynamicFieldIndex", type: "uint8", internalType: "uint8" }, - { name: "dataToPush", type: "bytes", internalType: "bytes" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "registerDelegation", - inputs: [ - { name: "delegatee", type: "address", internalType: "address" }, - { - name: "delegationControlId", - type: "bytes32", - internalType: "ResourceId", - }, - { name: "initCallData", type: "bytes", internalType: "bytes" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "registerFunctionSelector", - inputs: [ - { name: "systemId", type: "bytes32", internalType: "ResourceId" }, - { - name: "systemFunctionSignature", - type: "string", - internalType: "string", - }, - ], - outputs: [ - { - name: "worldFunctionSelector", - type: "bytes4", - internalType: "bytes4", - }, - ], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "registerNamespace", - inputs: [{ name: "namespaceId", type: "bytes32", internalType: "ResourceId" }], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "registerNamespaceDelegation", - inputs: [ - { - name: "namespaceId", - type: "bytes32", - internalType: "ResourceId", - }, - { - name: "delegationControlId", - type: "bytes32", - internalType: "ResourceId", - }, - { name: "initCallData", type: "bytes", internalType: "bytes" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "registerRootFunctionSelector", - inputs: [ - { name: "systemId", type: "bytes32", internalType: "ResourceId" }, - { - name: "worldFunctionSignature", - type: "string", - internalType: "string", - }, - { - name: "systemFunctionSignature", - type: "string", - internalType: "string", - }, - ], - outputs: [ - { - name: "worldFunctionSelector", - type: "bytes4", - internalType: "bytes4", - }, - ], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "registerStoreHook", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { - name: "hookAddress", - type: "address", - internalType: "contract IStoreHook", - }, - { name: "enabledHooksBitmap", type: "uint8", internalType: "uint8" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "registerSystem", - inputs: [ - { name: "systemId", type: "bytes32", internalType: "ResourceId" }, - { - name: "system", - type: "address", - internalType: "contract System", - }, - { name: "publicAccess", type: "bool", internalType: "bool" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "registerSystemHook", - inputs: [ - { name: "systemId", type: "bytes32", internalType: "ResourceId" }, - { - name: "hookAddress", - type: "address", - internalType: "contract ISystemHook", - }, - { name: "enabledHooksBitmap", type: "uint8", internalType: "uint8" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "registerTable", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { - name: "fieldLayout", - type: "bytes32", - internalType: "FieldLayout", - }, - { name: "keySchema", type: "bytes32", internalType: "Schema" }, - { name: "valueSchema", type: "bytes32", internalType: "Schema" }, - { name: "keyNames", type: "string[]", internalType: "string[]" }, - { name: "fieldNames", type: "string[]", internalType: "string[]" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "renounceOwnership", - inputs: [{ name: "namespaceId", type: "bytes32", internalType: "ResourceId" }], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "revokeAccess", - inputs: [ - { name: "resourceId", type: "bytes32", internalType: "ResourceId" }, - { name: "grantee", type: "address", internalType: "address" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "setDynamicField", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, - { name: "dynamicFieldIndex", type: "uint8", internalType: "uint8" }, - { name: "data", type: "bytes", internalType: "bytes" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "setField", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, - { name: "fieldIndex", type: "uint8", internalType: "uint8" }, - { name: "data", type: "bytes", internalType: "bytes" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "setField", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, - { name: "fieldIndex", type: "uint8", internalType: "uint8" }, - { name: "data", type: "bytes", internalType: "bytes" }, - { - name: "fieldLayout", - type: "bytes32", - internalType: "FieldLayout", - }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "setRecord", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, - { name: "staticData", type: "bytes", internalType: "bytes" }, - { - name: "encodedLengths", - type: "bytes32", - internalType: "EncodedLengths", - }, - { name: "dynamicData", type: "bytes", internalType: "bytes" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "setStaticField", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, - { name: "fieldIndex", type: "uint8", internalType: "uint8" }, - { name: "data", type: "bytes", internalType: "bytes" }, - { - name: "fieldLayout", - type: "bytes32", - internalType: "FieldLayout", - }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "spliceDynamicData", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, - { name: "dynamicFieldIndex", type: "uint8", internalType: "uint8" }, - { - name: "startWithinField", - type: "uint40", - internalType: "uint40", - }, - { name: "deleteCount", type: "uint40", internalType: "uint40" }, - { name: "data", type: "bytes", internalType: "bytes" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "spliceStaticData", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "keyTuple", type: "bytes32[]", internalType: "bytes32[]" }, - { name: "start", type: "uint48", internalType: "uint48" }, - { name: "data", type: "bytes", internalType: "bytes" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "storeVersion", - inputs: [], - outputs: [{ name: "version", type: "bytes32", internalType: "bytes32" }], - stateMutability: "view", - }, - { - type: "function", - name: "transferBalanceToAddress", - inputs: [ - { - name: "fromNamespaceId", - type: "bytes32", - internalType: "ResourceId", - }, - { name: "toAddress", type: "address", internalType: "address" }, - { name: "amount", type: "uint256", internalType: "uint256" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "transferBalanceToNamespace", - inputs: [ - { - name: "fromNamespaceId", - type: "bytes32", - internalType: "ResourceId", - }, - { - name: "toNamespaceId", - type: "bytes32", - internalType: "ResourceId", - }, - { name: "amount", type: "uint256", internalType: "uint256" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "transferOwnership", - inputs: [ - { - name: "namespaceId", - type: "bytes32", - internalType: "ResourceId", - }, - { name: "newOwner", type: "address", internalType: "address" }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "unregisterDelegation", - inputs: [{ name: "delegatee", type: "address", internalType: "address" }], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "unregisterNamespaceDelegation", - inputs: [{ name: "namespaceId", type: "bytes32", internalType: "ResourceId" }], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "unregisterStoreHook", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { - name: "hookAddress", - type: "address", - internalType: "contract IStoreHook", - }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "unregisterSystemHook", - inputs: [ - { name: "systemId", type: "bytes32", internalType: "ResourceId" }, - { - name: "hookAddress", - type: "address", - internalType: "contract ISystemHook", - }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "worldVersion", - inputs: [], - outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }], - stateMutability: "view", - }, - { - type: "event", - name: "HelloStore", - inputs: [ - { - name: "storeVersion", - type: "bytes32", - indexed: true, - internalType: "bytes32", - }, - ], - anonymous: false, - }, - { - type: "event", - name: "HelloWorld", - inputs: [ - { - name: "worldVersion", - type: "bytes32", - indexed: true, - internalType: "bytes32", - }, - ], - anonymous: false, - }, - { - type: "event", - name: "Store_DeleteRecord", - inputs: [ - { - name: "tableId", - type: "bytes32", - indexed: true, - internalType: "ResourceId", - }, - { - name: "keyTuple", - type: "bytes32[]", - indexed: false, - internalType: "bytes32[]", - }, - ], - anonymous: false, - }, - { - type: "event", - name: "Store_SetRecord", - inputs: [ - { - name: "tableId", - type: "bytes32", - indexed: true, - internalType: "ResourceId", - }, - { - name: "keyTuple", - type: "bytes32[]", - indexed: false, - internalType: "bytes32[]", - }, - { - name: "staticData", - type: "bytes", - indexed: false, - internalType: "bytes", - }, - { - name: "encodedLengths", - type: "bytes32", - indexed: false, - internalType: "EncodedLengths", - }, - { - name: "dynamicData", - type: "bytes", - indexed: false, - internalType: "bytes", - }, - ], - anonymous: false, - }, - { - type: "event", - name: "Store_SpliceDynamicData", - inputs: [ - { - name: "tableId", - type: "bytes32", - indexed: true, - internalType: "ResourceId", - }, - { - name: "keyTuple", - type: "bytes32[]", - indexed: false, - internalType: "bytes32[]", - }, - { - name: "dynamicFieldIndex", - type: "uint8", - indexed: false, - internalType: "uint8", - }, - { - name: "start", - type: "uint48", - indexed: false, - internalType: "uint48", - }, - { - name: "deleteCount", - type: "uint40", - indexed: false, - internalType: "uint40", - }, - { - name: "encodedLengths", - type: "bytes32", - indexed: false, - internalType: "EncodedLengths", - }, - { - name: "data", - type: "bytes", - indexed: false, - internalType: "bytes", - }, - ], - anonymous: false, - }, - { - type: "event", - name: "Store_SpliceStaticData", - inputs: [ - { - name: "tableId", - type: "bytes32", - indexed: true, - internalType: "ResourceId", - }, - { - name: "keyTuple", - type: "bytes32[]", - indexed: false, - internalType: "bytes32[]", - }, - { - name: "start", - type: "uint48", - indexed: false, - internalType: "uint48", - }, - { - name: "data", - type: "bytes", - indexed: false, - internalType: "bytes", - }, - ], - anonymous: false, - }, - { - type: "error", - name: "EncodedLengths_InvalidLength", - inputs: [{ name: "length", type: "uint256", internalType: "uint256" }], - }, - { type: "error", name: "FieldLayout_Empty", inputs: [] }, - { - type: "error", - name: "FieldLayout_InvalidStaticDataLength", - inputs: [ - { - name: "staticDataLength", - type: "uint256", - internalType: "uint256", - }, - { - name: "computedStaticDataLength", - type: "uint256", - internalType: "uint256", - }, - ], - }, - { - type: "error", - name: "FieldLayout_StaticLengthDoesNotFitInAWord", - inputs: [{ name: "index", type: "uint256", internalType: "uint256" }], - }, - { - type: "error", - name: "FieldLayout_StaticLengthIsNotZero", - inputs: [{ name: "index", type: "uint256", internalType: "uint256" }], - }, - { - type: "error", - name: "FieldLayout_StaticLengthIsZero", - inputs: [{ name: "index", type: "uint256", internalType: "uint256" }], - }, - { - type: "error", - name: "FieldLayout_TooManyDynamicFields", - inputs: [ - { name: "numFields", type: "uint256", internalType: "uint256" }, - { name: "maxFields", type: "uint256", internalType: "uint256" }, - ], - }, - { - type: "error", - name: "FieldLayout_TooManyFields", - inputs: [ - { name: "numFields", type: "uint256", internalType: "uint256" }, - { name: "maxFields", type: "uint256", internalType: "uint256" }, - ], - }, - { type: "error", name: "Module_AlreadyInstalled", inputs: [] }, - { - type: "error", - name: "Module_MissingDependency", - inputs: [{ name: "dependency", type: "address", internalType: "address" }], - }, - { - type: "error", - name: "Module_NonRootInstallNotSupported", - inputs: [], - }, - { type: "error", name: "Module_RootInstallNotSupported", inputs: [] }, - { - type: "error", - name: "Schema_InvalidLength", - inputs: [{ name: "length", type: "uint256", internalType: "uint256" }], - }, - { - type: "error", - name: "Schema_StaticTypeAfterDynamicType", - inputs: [], - }, - { - type: "error", - name: "Slice_OutOfBounds", - inputs: [ - { name: "data", type: "bytes", internalType: "bytes" }, - { name: "start", type: "uint256", internalType: "uint256" }, - { name: "end", type: "uint256", internalType: "uint256" }, - ], - }, - { - type: "error", - name: "Store_IndexOutOfBounds", - inputs: [ - { name: "length", type: "uint256", internalType: "uint256" }, - { name: "accessedIndex", type: "uint256", internalType: "uint256" }, - ], - }, - { - type: "error", - name: "Store_InvalidBounds", - inputs: [ - { name: "start", type: "uint256", internalType: "uint256" }, - { name: "end", type: "uint256", internalType: "uint256" }, - ], - }, - { - type: "error", - name: "Store_InvalidFieldNamesLength", - inputs: [ - { name: "expected", type: "uint256", internalType: "uint256" }, - { name: "received", type: "uint256", internalType: "uint256" }, - ], - }, - { - type: "error", - name: "Store_InvalidKeyNamesLength", - inputs: [ - { name: "expected", type: "uint256", internalType: "uint256" }, - { name: "received", type: "uint256", internalType: "uint256" }, - ], - }, - { - type: "error", - name: "Store_InvalidResourceType", - inputs: [ - { name: "expected", type: "bytes2", internalType: "bytes2" }, - { name: "resourceId", type: "bytes32", internalType: "ResourceId" }, - { name: "resourceIdString", type: "string", internalType: "string" }, - ], - }, - { - type: "error", - name: "Store_InvalidSplice", - inputs: [ - { - name: "startWithinField", - type: "uint40", - internalType: "uint40", - }, - { name: "deleteCount", type: "uint40", internalType: "uint40" }, - { name: "fieldLength", type: "uint40", internalType: "uint40" }, - ], - }, - { - type: "error", - name: "Store_InvalidStaticDataLength", - inputs: [ - { name: "expected", type: "uint256", internalType: "uint256" }, - { name: "received", type: "uint256", internalType: "uint256" }, - ], - }, - { - type: "error", - name: "Store_InvalidValueSchemaDynamicLength", - inputs: [ - { name: "expected", type: "uint256", internalType: "uint256" }, - { name: "received", type: "uint256", internalType: "uint256" }, - ], - }, - { - type: "error", - name: "Store_InvalidValueSchemaLength", - inputs: [ - { name: "expected", type: "uint256", internalType: "uint256" }, - { name: "received", type: "uint256", internalType: "uint256" }, - ], - }, - { - type: "error", - name: "Store_InvalidValueSchemaStaticLength", - inputs: [ - { name: "expected", type: "uint256", internalType: "uint256" }, - { name: "received", type: "uint256", internalType: "uint256" }, - ], - }, - { - type: "error", - name: "Store_TableAlreadyExists", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "tableIdString", type: "string", internalType: "string" }, - ], - }, - { - type: "error", - name: "Store_TableNotFound", - inputs: [ - { name: "tableId", type: "bytes32", internalType: "ResourceId" }, - { name: "tableIdString", type: "string", internalType: "string" }, - ], - }, - { - type: "error", - name: "World_AccessDenied", - inputs: [ - { name: "resource", type: "string", internalType: "string" }, - { name: "caller", type: "address", internalType: "address" }, - ], - }, - { type: "error", name: "World_AlreadyInitialized", inputs: [] }, - { - type: "error", - name: "World_CallbackNotAllowed", - inputs: [{ name: "functionSelector", type: "bytes4", internalType: "bytes4" }], - }, - { - type: "error", - name: "World_DelegationNotFound", - inputs: [ - { name: "delegator", type: "address", internalType: "address" }, - { name: "delegatee", type: "address", internalType: "address" }, - ], - }, - { - type: "error", - name: "World_FunctionSelectorAlreadyExists", - inputs: [{ name: "functionSelector", type: "bytes4", internalType: "bytes4" }], - }, - { - type: "error", - name: "World_FunctionSelectorNotFound", - inputs: [{ name: "functionSelector", type: "bytes4", internalType: "bytes4" }], - }, - { - type: "error", - name: "World_InsufficientBalance", - inputs: [ - { name: "balance", type: "uint256", internalType: "uint256" }, - { name: "amount", type: "uint256", internalType: "uint256" }, - ], - }, - { - type: "error", - name: "World_InterfaceNotSupported", - inputs: [ - { - name: "contractAddress", - type: "address", - internalType: "address", - }, - { name: "interfaceId", type: "bytes4", internalType: "bytes4" }, - ], - }, - { - type: "error", - name: "World_InvalidNamespace", - inputs: [{ name: "namespace", type: "bytes14", internalType: "bytes14" }], - }, - { - type: "error", - name: "World_InvalidResourceId", - inputs: [ - { name: "resourceId", type: "bytes32", internalType: "ResourceId" }, - { name: "resourceIdString", type: "string", internalType: "string" }, - ], - }, - { - type: "error", - name: "World_InvalidResourceType", - inputs: [ - { name: "expected", type: "bytes2", internalType: "bytes2" }, - { name: "resourceId", type: "bytes32", internalType: "ResourceId" }, - { name: "resourceIdString", type: "string", internalType: "string" }, - ], - }, - { - type: "error", - name: "World_ResourceAlreadyExists", - inputs: [ - { name: "resourceId", type: "bytes32", internalType: "ResourceId" }, - { name: "resourceIdString", type: "string", internalType: "string" }, - ], - }, - { - type: "error", - name: "World_ResourceNotFound", - inputs: [ - { name: "resourceId", type: "bytes32", internalType: "ResourceId" }, - { name: "resourceIdString", type: "string", internalType: "string" }, - ], - }, - { - type: "error", - name: "World_SystemAlreadyExists", - inputs: [{ name: "system", type: "address", internalType: "address" }], - }, - { - type: "error", - name: "World_UnlimitedDelegationNotAllowed", - inputs: [], - }, - { - name: "app__increment", - type: "function", - stateMutability: "nonpayable", - inputs: [], - outputs: [], - }, - { - type: "function", - name: "setNumber", - inputs: [{ name: "isNumberSet", type: "bool", internalType: "bool" }], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "setNumber", - inputs: [{ name: "newNumber", type: "uint256", internalType: "uint256" }], - outputs: [], - stateMutability: "nonpayable", - }, -]; diff --git a/packages/world/ts/mocks/worldAbi.ts b/packages/world/ts/mocks/worldAbi.ts deleted file mode 100644 index cb9a1a49a6..0000000000 --- a/packages/world/ts/mocks/worldAbi.ts +++ /dev/null @@ -1,178 +0,0 @@ -export default [ - { name: "app__increment", type: "function", stateMutability: "nonpayable", inputs: [], outputs: [] }, - { - type: "function", - name: "setNumber", - inputs: [{ name: "isNumberSet", type: "bool", internalType: "bool" }], - outputs: [], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "setNumber", - inputs: [{ name: "newNumber", type: "uint256", internalType: "uint256" }], - outputs: [], - stateMutability: "nonpayable", - }, - { - name: "batchCall", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "tuple[]", components: [{ type: "bytes32" }, { type: "bytes" }] }], - outputs: [], - }, - { - name: "batchCallFrom", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "tuple[]", components: [{ type: "address" }, { type: "bytes32" }, { type: "bytes" }] }], - outputs: [], - }, - { - name: "grantAccess", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "bytes32" }, { type: "address" }], - outputs: [], - }, - { - name: "installModule", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "address" }, { type: "bytes" }], - outputs: [], - }, - { - name: "registerDelegation", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "address" }, { type: "bytes32" }, { type: "bytes" }], - outputs: [], - }, - { - name: "registerFunctionSelector", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "bytes32" }, { type: "string" }], - outputs: [], - }, - { - name: "registerNamespace", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "bytes32" }], - outputs: [], - }, - { - name: "registerNamespaceDelegation", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "bytes32" }, { type: "bytes32" }, { type: "bytes" }], - outputs: [], - }, - { - name: "registerRootFunctionSelector", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "bytes32" }, { type: "string" }, { type: "string" }], - outputs: [], - }, - { - name: "registerStoreHook", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "bytes32" }, { type: "address" }, { type: "uint8" }], - outputs: [], - }, - { - name: "registerSystem", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "bytes32" }, { type: "address" }, { type: "bool" }], - outputs: [], - }, - { - name: "registerSystemHook", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "bytes32" }, { type: "address" }, { type: "uint8" }], - outputs: [], - }, - { - name: "registerTable", - type: "function", - stateMutability: "nonpayable", - inputs: [ - { type: "bytes32" }, - { type: "bytes32" }, - { type: "bytes32" }, - { type: "bytes32" }, - { type: "string[]" }, - { type: "string[]" }, - ], - outputs: [], - }, - { - name: "renounceOwnership", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "bytes32" }], - outputs: [], - }, - { - name: "revokeAccess", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "bytes32" }, { type: "address" }], - outputs: [], - }, - { - name: "transferBalanceToAddress", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "bytes32" }, { type: "address" }, { type: "uint256" }], - outputs: [], - }, - { - name: "transferBalanceToNamespace", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "bytes32" }, { type: "bytes32" }, { type: "uint256" }], - outputs: [], - }, - { - name: "transferOwnership", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "bytes32" }, { type: "address" }], - outputs: [], - }, - { - name: "unregisterDelegation", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "address" }], - outputs: [], - }, - { - name: "unregisterNamespaceDelegation", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "bytes32" }], - outputs: [], - }, - { - name: "unregisterStoreHook", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "bytes32" }, { type: "address" }], - outputs: [], - }, - { - name: "unregisterSystemHook", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "bytes32" }, { type: "address" }], - outputs: [], - }, -]; From ffe64036ad6974eb73294540c4620203ec970e91 Mon Sep 17 00:00:00 2001 From: karooolis Date: Tue, 13 Aug 2024 14:52:25 +0200 Subject: [PATCH 08/10] remove concatBaseApi helper function --- packages/world/ts/common.ts | 18 +++++++++- packages/world/ts/concatBaseAbi.test.ts | 27 --------------- packages/world/ts/concatBaseAbi.ts | 16 --------- packages/world/ts/getWorldAbi.test.ts | 44 +++++++++++++++++++++++++ packages/world/ts/getWorldAbi.ts | 15 ++++++--- 5 files changed, 72 insertions(+), 48 deletions(-) delete mode 100644 packages/world/ts/concatBaseAbi.test.ts delete mode 100644 packages/world/ts/concatBaseAbi.ts create mode 100644 packages/world/ts/getWorldAbi.test.ts diff --git a/packages/world/ts/common.ts b/packages/world/ts/common.ts index 7769b1bc36..462fe68cae 100644 --- a/packages/world/ts/common.ts +++ b/packages/world/ts/common.ts @@ -1,4 +1,4 @@ -import { Hex } from "viem"; +import { Hex, createTestClient, http, publicActions, walletActions } from "viem"; export type WorldFunction = { readonly signature: string; @@ -7,3 +7,19 @@ export type WorldFunction = { readonly systemFunctionSignature: string; readonly systemFunctionSelector: Hex; }; + +export const anvilHost = "127.0.0.1"; +export const anvilPort = 8555; + +// ID of the current test worker. Used by the `@viem/anvil` proxy server. +export const poolId = Number(process.env.VITEST_POOL_ID ?? 1); + +export const anvilRpcUrl = `http://${anvilHost}:${anvilPort}/${poolId}`; + +export const testClient = createTestClient({ + mode: "anvil", + transport: http(anvilRpcUrl), + pollingInterval: 10, +}) + .extend(publicActions) + .extend(walletActions); diff --git a/packages/world/ts/concatBaseAbi.test.ts b/packages/world/ts/concatBaseAbi.test.ts deleted file mode 100644 index 5d302d0d94..0000000000 --- a/packages/world/ts/concatBaseAbi.test.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { describe, expect, it } from "vitest"; -import { AbiFunction } from "viem"; -import { concatBaseAbi } from "./concatBaseAbi"; - -const customAbiFunction = { - type: "function", - name: "setNumber", - inputs: [{ name: "isNumberSet", type: "bool", internalType: "bool" }], - outputs: [], - stateMutability: "nonpayable", -} as AbiFunction; - -const duplicateBatchCallAbi = { - name: "batchCall", - type: "function", - stateMutability: "nonpayable", - inputs: [{ type: "tuple[]", components: [{ type: "bytes32" }, { type: "bytes" }] }], - outputs: [], -} as AbiFunction; - -describe("World ABI", () => { - it("should concat base and world ABI", () => { - const abi = concatBaseAbi([customAbiFunction, duplicateBatchCallAbi]); - expect(abi).toContainEqual(customAbiFunction); - expect(abi).not.toContainEqual(duplicateBatchCallAbi); - }); -}); diff --git a/packages/world/ts/concatBaseAbi.ts b/packages/world/ts/concatBaseAbi.ts deleted file mode 100644 index efe138e047..0000000000 --- a/packages/world/ts/concatBaseAbi.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Abi, AbiItem, AbiFunction, toFunctionSelector } from "viem"; -import IBaseWorldAbi from "../out/IBaseWorld.sol/IBaseWorld.abi.json"; - -function isAbiFunction(abiItem: AbiItem): abiItem is AbiFunction { - return abiItem.type === "function"; -} - -export function concatBaseAbi(worldAbi: Abi): Abi { - const baseFunctionSelectors = (IBaseWorldAbi as Abi).filter(isAbiFunction).map(toFunctionSelector); - const worldFunctionsAbi = worldAbi.filter( - (abiItem) => !baseFunctionSelectors.includes(toFunctionSelector(abiItem as AbiFunction)), - ); - const abi = [...IBaseWorldAbi, ...worldFunctionsAbi]; - - return abi; -} diff --git a/packages/world/ts/getWorldAbi.test.ts b/packages/world/ts/getWorldAbi.test.ts new file mode 100644 index 0000000000..8b9b77fd17 --- /dev/null +++ b/packages/world/ts/getWorldAbi.test.ts @@ -0,0 +1,44 @@ +import { describe, expect, it, vi } from "vitest"; +import { getWorldAbi } from "./getWorldAbi"; +import { testClient } from "./common"; + +vi.mock("./getFunctions", () => { + const mockGetFunctionsResult = [{ signature: "setNumber(bool)" }, { signature: "batchCall((bytes32,bytes)[])" }]; + const getFunctions = vi.fn(); + getFunctions.mockResolvedValue(mockGetFunctionsResult); + + return { + getFunctions, + }; +}); + +describe("World ABI", () => { + it("should concat base and world ABI", async () => { + const abi = await getWorldAbi({ + client: testClient, + worldAddress: "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + fromBlock: 0n, + toBlock: 0n, + }); + + expect(abi).toContainEqual({ + inputs: [ + { + type: "bool", + }, + ], + name: "setNumber", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }); + + expect(abi).not.toContainEqual({ + name: "batchCall", + type: "function", + stateMutability: "nonpayable", + inputs: [{ type: "tuple[]", components: [{ type: "bytes32" }, { type: "bytes" }] }], + outputs: [], + }); + }); +}); diff --git a/packages/world/ts/getWorldAbi.ts b/packages/world/ts/getWorldAbi.ts index 07d2a3f9d4..e243a3889c 100644 --- a/packages/world/ts/getWorldAbi.ts +++ b/packages/world/ts/getWorldAbi.ts @@ -1,7 +1,11 @@ -import { Client, Abi, Address, getAddress } from "viem"; +import { Client, Abi, AbiItem, AbiFunction, Address, getAddress, toFunctionSelector } from "viem"; +import IBaseWorldAbi from "../out/IBaseWorld.sol/IBaseWorld.abi.json"; import { functionSignatureToAbiItem } from "./functionSignatureToAbiItem"; import { getFunctions } from "./getFunctions"; -import { concatBaseAbi } from "./concatBaseAbi"; + +function isAbiFunction(abiItem: AbiItem): abiItem is AbiFunction { + return abiItem.type === "function"; +} export async function getWorldAbi({ client, @@ -20,8 +24,11 @@ export async function getWorldAbi({ fromBlock, toBlock, }); - const worldFunctionsAbi = worldFunctions.map((func) => functionSignatureToAbiItem(func.signature)); - const abi = concatBaseAbi(worldFunctionsAbi); + const baseFunctionSelectors = (IBaseWorldAbi as Abi).filter(isAbiFunction).map(toFunctionSelector); + const worldFunctionsAbi = worldFunctions + .map((func) => functionSignatureToAbiItem(func.signature)) + .filter((abiItem) => !baseFunctionSelectors.includes(toFunctionSelector(abiItem as AbiFunction))); + const abi = [...IBaseWorldAbi, ...worldFunctionsAbi]; return abi; } From faaf4d39f4783de574be84f7bb8b41932ee9abb7 Mon Sep 17 00:00:00 2001 From: karooolis Date: Tue, 13 Aug 2024 15:11:39 +0200 Subject: [PATCH 09/10] simplify test client creation --- packages/world/ts/common.ts | 18 +----------------- packages/world/ts/getWorldAbi.test.ts | 11 +++++++++-- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/packages/world/ts/common.ts b/packages/world/ts/common.ts index 462fe68cae..7769b1bc36 100644 --- a/packages/world/ts/common.ts +++ b/packages/world/ts/common.ts @@ -1,4 +1,4 @@ -import { Hex, createTestClient, http, publicActions, walletActions } from "viem"; +import { Hex } from "viem"; export type WorldFunction = { readonly signature: string; @@ -7,19 +7,3 @@ export type WorldFunction = { readonly systemFunctionSignature: string; readonly systemFunctionSelector: Hex; }; - -export const anvilHost = "127.0.0.1"; -export const anvilPort = 8555; - -// ID of the current test worker. Used by the `@viem/anvil` proxy server. -export const poolId = Number(process.env.VITEST_POOL_ID ?? 1); - -export const anvilRpcUrl = `http://${anvilHost}:${anvilPort}/${poolId}`; - -export const testClient = createTestClient({ - mode: "anvil", - transport: http(anvilRpcUrl), - pollingInterval: 10, -}) - .extend(publicActions) - .extend(walletActions); diff --git a/packages/world/ts/getWorldAbi.test.ts b/packages/world/ts/getWorldAbi.test.ts index 8b9b77fd17..6658d33ec8 100644 --- a/packages/world/ts/getWorldAbi.test.ts +++ b/packages/world/ts/getWorldAbi.test.ts @@ -1,6 +1,7 @@ import { describe, expect, it, vi } from "vitest"; +import { createTestClient, http } from "viem"; import { getWorldAbi } from "./getWorldAbi"; -import { testClient } from "./common"; +import { foundry } from "viem/chains"; vi.mock("./getFunctions", () => { const mockGetFunctionsResult = [{ signature: "setNumber(bool)" }, { signature: "batchCall((bytes32,bytes)[])" }]; @@ -14,8 +15,14 @@ vi.mock("./getFunctions", () => { describe("World ABI", () => { it("should concat base and world ABI", async () => { + const client = createTestClient({ + chain: foundry, + mode: "anvil", + transport: http(), + }); + const abi = await getWorldAbi({ - client: testClient, + client, worldAddress: "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", fromBlock: 0n, toBlock: 0n, From 520e6347a9c55885b535c0c0faaa73f07379780c Mon Sep 17 00:00:00 2001 From: karooolis Date: Tue, 13 Aug 2024 15:14:33 +0200 Subject: [PATCH 10/10] adjust functionSignatureToAbiItem return type --- packages/world/ts/functionSignatureToAbiItem.ts | 12 +++++++++--- packages/world/ts/getWorldAbi.ts | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/world/ts/functionSignatureToAbiItem.ts b/packages/world/ts/functionSignatureToAbiItem.ts index e123aeecee..3309c14a78 100644 --- a/packages/world/ts/functionSignatureToAbiItem.ts +++ b/packages/world/ts/functionSignatureToAbiItem.ts @@ -1,6 +1,12 @@ -import { AbiItem, parseAbiItem } from "viem"; +import { AbiFunction, parseAbiItem } from "viem"; -export function functionSignatureToAbiItem(functionSignature: string): AbiItem { +export function functionSignatureToAbiItem(functionSignature: string): AbiFunction { const formattedSignature = `function ${functionSignature}`; - return parseAbiItem(formattedSignature); + const abiItem = parseAbiItem(formattedSignature); + + if (abiItem.type !== "function") { + throw new Error(`Expected function signature, got ${abiItem.type}`); + } + + return abiItem; } diff --git a/packages/world/ts/getWorldAbi.ts b/packages/world/ts/getWorldAbi.ts index e243a3889c..8ac8f1aadb 100644 --- a/packages/world/ts/getWorldAbi.ts +++ b/packages/world/ts/getWorldAbi.ts @@ -27,7 +27,7 @@ export async function getWorldAbi({ const baseFunctionSelectors = (IBaseWorldAbi as Abi).filter(isAbiFunction).map(toFunctionSelector); const worldFunctionsAbi = worldFunctions .map((func) => functionSignatureToAbiItem(func.signature)) - .filter((abiItem) => !baseFunctionSelectors.includes(toFunctionSelector(abiItem as AbiFunction))); + .filter((abiItem) => !baseFunctionSelectors.includes(toFunctionSelector(abiItem))); const abi = [...IBaseWorldAbi, ...worldFunctionsAbi]; return abi;