diff --git a/.changeset/fast-zebras-drum.md b/.changeset/fast-zebras-drum.md new file mode 100644 index 0000000000..4fd1653e07 --- /dev/null +++ b/.changeset/fast-zebras-drum.md @@ -0,0 +1,41 @@ +--- +"@latticexyz/store": major +"@latticexyz/world": major +--- + +The `World` now performs `ERC165` interface checks to ensure that the `StoreHook`, `SystemHook`, `System`, `DelegationControl` and `Module` contracts to actually implement their respective interfaces before registering them in the World. + +The required `supportsInterface` methods are implemented on the respective base contracts. +When creating one of these contracts, the recommended approach is to extend the base contract rather than the interface. + +```diff +- import { IStoreHook } from "@latticexyz/store/src/IStore.sol"; ++ import { StoreHook } from "@latticexyz/store/src/StoreHook.sol"; + +- contract MyStoreHook is IStoreHook {} ++ contract MyStoreHook is StoreHook {} +``` + +```diff +- import { ISystemHook } from "@latticexyz/world/src/interfaces/ISystemHook.sol"; ++ import { SystemHook } from "@latticexyz/world/src/SystemHook.sol"; + +- contract MySystemHook is ISystemHook {} ++ contract MySystemHook is SystemHook {} +``` + +```diff +- import { IDelegationControl } from "@latticexyz/world/src/interfaces/IDelegationControl.sol"; ++ import { DelegationControl } from "@latticexyz/world/src/DelegationControl.sol"; + +- contract MyDelegationControl is IDelegationControl {} ++ contract MyDelegationControl is DelegationControl {} +``` + +```diff +- import { IModule } from "@latticexyz/world/src/interfaces/IModule.sol"; ++ import { Module } from "@latticexyz/world/src/Module.sol"; + +- contract MyModule is IModule {} ++ contract MyModule is Module {} +``` diff --git a/packages/cli/src/utils/deploy.ts b/packages/cli/src/utils/deploy.ts index 9d606bb567..bc5096bed8 100644 --- a/packages/cli/src/utils/deploy.ts +++ b/packages/cli/src/utils/deploy.ts @@ -48,6 +48,8 @@ export async function deploy( deployConfig; const forgeOutDirectory = await getOutDirectory(profile); + const baseSystemFunctionNames = (await loadFunctionSignatures("System")).map((item) => item.functionName); + // Set up signer for deployment const provider = new ethers.providers.StaticJsonRpcProvider(rpc); provider.pollingInterval = pollInterval; @@ -443,7 +445,7 @@ export async function deploy( async function loadFunctionSignatures(contractName: string): Promise { const { abi } = await getContractData(contractName); - return abi + const functionSelectors = abi .filter((item) => ["fallback", "function"].includes(item.type)) .map((item) => { if (item.type === "fallback") return { functionName: "", functionArgs: "" }; @@ -453,6 +455,11 @@ export async function deploy( functionArgs: parseComponents(item.inputs), }; }); + + return contractName === "System" + ? functionSelectors + : // Filter out functions that are defined in the base System contract for all non-base systems + functionSelectors.filter((item) => !baseSystemFunctionNames.includes(item.functionName)); } /** diff --git a/packages/store/abi/EchoSubscriber.sol/EchoSubscriber.abi.json b/packages/store/abi/EchoSubscriber.sol/EchoSubscriber.abi.json index d2ea7262eb..33ff18626b 100644 --- a/packages/store/abi/EchoSubscriber.sol/EchoSubscriber.abi.json +++ b/packages/store/abi/EchoSubscriber.sol/EchoSubscriber.abi.json @@ -179,5 +179,24 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" } ] \ No newline at end of file diff --git a/packages/store/abi/EchoSubscriber.sol/EchoSubscriber.abi.json.d.ts b/packages/store/abi/EchoSubscriber.sol/EchoSubscriber.abi.json.d.ts index b2650bcda6..9bab444311 100644 --- a/packages/store/abi/EchoSubscriber.sol/EchoSubscriber.abi.json.d.ts +++ b/packages/store/abi/EchoSubscriber.sol/EchoSubscriber.abi.json.d.ts @@ -179,6 +179,25 @@ declare const abi: [ outputs: []; stateMutability: "nonpayable"; type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; } ]; export default abi; diff --git a/packages/store/abi/IERC165.sol/IERC165.abi.json b/packages/store/abi/IERC165.sol/IERC165.abi.json new file mode 100644 index 0000000000..f9e19986d2 --- /dev/null +++ b/packages/store/abi/IERC165.sol/IERC165.abi.json @@ -0,0 +1,21 @@ +[ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceID", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/store/abi/IERC165.sol/IERC165.abi.json.d.ts b/packages/store/abi/IERC165.sol/IERC165.abi.json.d.ts new file mode 100644 index 0000000000..41da21a6f2 --- /dev/null +++ b/packages/store/abi/IERC165.sol/IERC165.abi.json.d.ts @@ -0,0 +1,22 @@ +declare const abi: [ + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceID"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "view"; + type: "function"; + } +]; +export default abi; diff --git a/packages/store/abi/IStore.sol/IStoreHook.abi.json b/packages/store/abi/IStoreHook.sol/IStoreHook.abi.json similarity index 90% rename from packages/store/abi/IStore.sol/IStoreHook.abi.json rename to packages/store/abi/IStoreHook.sol/IStoreHook.abi.json index 316af6422c..b35f6251af 100644 --- a/packages/store/abi/IStore.sol/IStoreHook.abi.json +++ b/packages/store/abi/IStoreHook.sol/IStoreHook.abi.json @@ -166,5 +166,24 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceID", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" } ] \ No newline at end of file diff --git a/packages/world/abi/src/IStore.sol/IStoreHook.abi.json.d.ts b/packages/store/abi/IStoreHook.sol/IStoreHook.abi.json.d.ts similarity index 90% rename from packages/world/abi/src/IStore.sol/IStoreHook.abi.json.d.ts rename to packages/store/abi/IStoreHook.sol/IStoreHook.abi.json.d.ts index 2e39c851eb..ae36ae3637 100644 --- a/packages/world/abi/src/IStore.sol/IStoreHook.abi.json.d.ts +++ b/packages/store/abi/IStoreHook.sol/IStoreHook.abi.json.d.ts @@ -166,6 +166,25 @@ declare const abi: [ outputs: []; stateMutability: "nonpayable"; type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceID"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "view"; + type: "function"; } ]; export default abi; diff --git a/packages/store/abi/MirrorSubscriber.sol/MirrorSubscriber.abi.json b/packages/store/abi/MirrorSubscriber.sol/MirrorSubscriber.abi.json index 7d3335b604..5325629c8a 100644 --- a/packages/store/abi/MirrorSubscriber.sol/MirrorSubscriber.abi.json +++ b/packages/store/abi/MirrorSubscriber.sol/MirrorSubscriber.abi.json @@ -261,5 +261,24 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" } ] \ No newline at end of file diff --git a/packages/store/abi/MirrorSubscriber.sol/MirrorSubscriber.abi.json.d.ts b/packages/store/abi/MirrorSubscriber.sol/MirrorSubscriber.abi.json.d.ts index 14369e1ee9..47a8e089b3 100644 --- a/packages/store/abi/MirrorSubscriber.sol/MirrorSubscriber.abi.json.d.ts +++ b/packages/store/abi/MirrorSubscriber.sol/MirrorSubscriber.abi.json.d.ts @@ -261,6 +261,25 @@ declare const abi: [ outputs: []; stateMutability: "nonpayable"; type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; } ]; export default abi; diff --git a/packages/store/abi/RevertSubscriber.sol/RevertSubscriber.abi.json b/packages/store/abi/RevertSubscriber.sol/RevertSubscriber.abi.json index b81dff7d47..2dcffc5af8 100644 --- a/packages/store/abi/RevertSubscriber.sol/RevertSubscriber.abi.json +++ b/packages/store/abi/RevertSubscriber.sol/RevertSubscriber.abi.json @@ -166,5 +166,24 @@ "outputs": [], "stateMutability": "pure", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" } ] \ No newline at end of file diff --git a/packages/store/abi/RevertSubscriber.sol/RevertSubscriber.abi.json.d.ts b/packages/store/abi/RevertSubscriber.sol/RevertSubscriber.abi.json.d.ts index b7eb63707e..589b6d8b05 100644 --- a/packages/store/abi/RevertSubscriber.sol/RevertSubscriber.abi.json.d.ts +++ b/packages/store/abi/RevertSubscriber.sol/RevertSubscriber.abi.json.d.ts @@ -166,6 +166,25 @@ declare const abi: [ outputs: []; stateMutability: "pure"; type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; } ]; export default abi; diff --git a/packages/store/abi/StoreHook.sol/StoreHook.abi.json b/packages/store/abi/StoreHook.sol/StoreHook.abi.json new file mode 100644 index 0000000000..3d219e7777 --- /dev/null +++ b/packages/store/abi/StoreHook.sol/StoreHook.abi.json @@ -0,0 +1,189 @@ +[ + { + "inputs": [ + { + "internalType": "bytes32", + "name": "table", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "internalType": "Schema", + "name": "valueSchema", + "type": "bytes32" + } + ], + "name": "onAfterDeleteRecord", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "table", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "internalType": "uint8", + "name": "schemaIndex", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "Schema", + "name": "valueSchema", + "type": "bytes32" + } + ], + "name": "onAfterSetField", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "table", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "Schema", + "name": "valueSchema", + "type": "bytes32" + } + ], + "name": "onAfterSetRecord", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "table", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "internalType": "Schema", + "name": "valueSchema", + "type": "bytes32" + } + ], + "name": "onBeforeDeleteRecord", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "table", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "internalType": "uint8", + "name": "schemaIndex", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "Schema", + "name": "valueSchema", + "type": "bytes32" + } + ], + "name": "onBeforeSetField", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "table", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "Schema", + "name": "valueSchema", + "type": "bytes32" + } + ], + "name": "onBeforeSetRecord", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/store/abi/StoreHook.sol/StoreHook.abi.json.d.ts b/packages/store/abi/StoreHook.sol/StoreHook.abi.json.d.ts new file mode 100644 index 0000000000..494a46cc19 --- /dev/null +++ b/packages/store/abi/StoreHook.sol/StoreHook.abi.json.d.ts @@ -0,0 +1,190 @@ +declare const abi: [ + { + inputs: [ + { + internalType: "bytes32"; + name: "table"; + type: "bytes32"; + }, + { + internalType: "bytes32[]"; + name: "key"; + type: "bytes32[]"; + }, + { + internalType: "Schema"; + name: "valueSchema"; + type: "bytes32"; + } + ]; + name: "onAfterDeleteRecord"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes32"; + name: "table"; + type: "bytes32"; + }, + { + internalType: "bytes32[]"; + name: "key"; + type: "bytes32[]"; + }, + { + internalType: "uint8"; + name: "schemaIndex"; + type: "uint8"; + }, + { + internalType: "bytes"; + name: "data"; + type: "bytes"; + }, + { + internalType: "Schema"; + name: "valueSchema"; + type: "bytes32"; + } + ]; + name: "onAfterSetField"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes32"; + name: "table"; + type: "bytes32"; + }, + { + internalType: "bytes32[]"; + name: "key"; + type: "bytes32[]"; + }, + { + internalType: "bytes"; + name: "data"; + type: "bytes"; + }, + { + internalType: "Schema"; + name: "valueSchema"; + type: "bytes32"; + } + ]; + name: "onAfterSetRecord"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes32"; + name: "table"; + type: "bytes32"; + }, + { + internalType: "bytes32[]"; + name: "key"; + type: "bytes32[]"; + }, + { + internalType: "Schema"; + name: "valueSchema"; + type: "bytes32"; + } + ]; + name: "onBeforeDeleteRecord"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes32"; + name: "table"; + type: "bytes32"; + }, + { + internalType: "bytes32[]"; + name: "key"; + type: "bytes32[]"; + }, + { + internalType: "uint8"; + name: "schemaIndex"; + type: "uint8"; + }, + { + internalType: "bytes"; + name: "data"; + type: "bytes"; + }, + { + internalType: "Schema"; + name: "valueSchema"; + type: "bytes32"; + } + ]; + name: "onBeforeSetField"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes32"; + name: "table"; + type: "bytes32"; + }, + { + internalType: "bytes32[]"; + name: "key"; + type: "bytes32[]"; + }, + { + internalType: "bytes"; + name: "data"; + type: "bytes"; + }, + { + internalType: "Schema"; + name: "valueSchema"; + type: "bytes32"; + } + ]; + name: "onBeforeSetRecord"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; + } +]; +export default abi; diff --git a/packages/store/gas-report.json b/packages/store/gas-report.json index dcfe0a654a..6ffd6db563 100644 --- a/packages/store/gas-report.json +++ b/packages/store/gas-report.json @@ -585,19 +585,19 @@ "file": "test/StoreCoreGas.t.sol", "test": "testHooks", "name": "set record on table with subscriber", - "gasUsed": 70983 + "gasUsed": 71005 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooks", "name": "set static field on table with subscriber", - "gasUsed": 24290 + "gasUsed": 24312 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooks", "name": "delete record on table with subscriber", - "gasUsed": 19379 + "gasUsed": 19401 }, { "file": "test/StoreCoreGas.t.sol", @@ -609,19 +609,19 @@ "file": "test/StoreCoreGas.t.sol", "test": "testHooksDynamicData", "name": "set (dynamic) record on table with subscriber", - "gasUsed": 163851 + "gasUsed": 163873 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooksDynamicData", "name": "set (dynamic) field on table with subscriber", - "gasUsed": 26226 + "gasUsed": 26248 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooksDynamicData", "name": "delete (dynamic) record on table with subscriber", - "gasUsed": 20852 + "gasUsed": 20837 }, { "file": "test/StoreCoreGas.t.sol", @@ -783,7 +783,7 @@ "file": "test/StoreHook.t.sol", "test": "testCallHook", "name": "call an enabled hook", - "gasUsed": 10135 + "gasUsed": 10157 }, { "file": "test/StoreHook.t.sol", diff --git a/packages/store/src/IERC165.sol b/packages/store/src/IERC165.sol new file mode 100644 index 0000000000..4151b0a405 --- /dev/null +++ b/packages/store/src/IERC165.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +bytes4 constant ERC165_INTERFACE_ID = IERC165.supportsInterface.selector; + +// See https://eips.ethereum.org/EIPS/eip-165 +interface IERC165 { + /// @notice Query if a contract implements an interface + /// @param interfaceID The interface identifier, as specified in ERC-165 + /// @dev Interface identification is specified in ERC-165. This function + /// uses less than 30,000 gas. + /// @return `true` if the contract implements `interfaceID` and + /// `interfaceID` is not 0xffffffff, `false` otherwise + function supportsInterface(bytes4 interfaceID) external view returns (bool); +} diff --git a/packages/store/src/IStore.sol b/packages/store/src/IStore.sol index 988e9c5b25..e75dadd2da 100644 --- a/packages/store/src/IStore.sol +++ b/packages/store/src/IStore.sol @@ -3,6 +3,7 @@ pragma solidity >=0.8.0; import { IStoreErrors } from "./IStoreErrors.sol"; import { Schema } from "./Schema.sol"; +import { IStoreHook } from "./IStoreHook.sol"; interface IStoreRead { function getValueSchema(bytes32 table) external view returns (Schema schema); @@ -130,29 +131,3 @@ interface IStoreRegistration { } interface IStore is IStoreData, IStoreRegistration, IStoreEphemeral, IStoreErrors {} - -interface IStoreHook { - function onBeforeSetRecord(bytes32 table, bytes32[] memory key, bytes memory data, Schema valueSchema) external; - - function onAfterSetRecord(bytes32 table, bytes32[] memory key, bytes memory data, Schema valueSchema) external; - - function onBeforeSetField( - bytes32 table, - bytes32[] memory key, - uint8 schemaIndex, - bytes memory data, - Schema valueSchema - ) external; - - function onAfterSetField( - bytes32 table, - bytes32[] memory key, - uint8 schemaIndex, - bytes memory data, - Schema valueSchema - ) external; - - function onBeforeDeleteRecord(bytes32 table, bytes32[] memory key, Schema valueSchema) external; - - function onAfterDeleteRecord(bytes32 table, bytes32[] memory key, Schema valueSchema) external; -} diff --git a/packages/store/src/IStoreHook.sol b/packages/store/src/IStoreHook.sol new file mode 100644 index 0000000000..f12db1affa --- /dev/null +++ b/packages/store/src/IStoreHook.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { Schema } from "./Schema.sol"; +import { IERC165, ERC165_INTERFACE_ID } from "./IERC165.sol"; + +// ERC-165 Interface ID (see https://eips.ethereum.org/EIPS/eip-165) +bytes4 constant STORE_HOOK_INTERFACE_ID = IStoreHook.onBeforeSetRecord.selector ^ + IStoreHook.onAfterSetRecord.selector ^ + IStoreHook.onBeforeSetField.selector ^ + IStoreHook.onAfterSetField.selector ^ + IStoreHook.onBeforeDeleteRecord.selector ^ + IStoreHook.onAfterDeleteRecord.selector ^ + ERC165_INTERFACE_ID; + +interface IStoreHook is IERC165 { + function onBeforeSetRecord(bytes32 table, bytes32[] memory key, bytes memory data, Schema valueSchema) external; + + function onAfterSetRecord(bytes32 table, bytes32[] memory key, bytes memory data, Schema valueSchema) external; + + function onBeforeSetField( + bytes32 table, + bytes32[] memory key, + uint8 schemaIndex, + bytes memory data, + Schema valueSchema + ) external; + + function onAfterSetField( + bytes32 table, + bytes32[] memory key, + uint8 schemaIndex, + bytes memory data, + Schema valueSchema + ) external; + + function onBeforeDeleteRecord(bytes32 table, bytes32[] memory key, Schema valueSchema) external; + + function onAfterDeleteRecord(bytes32 table, bytes32[] memory key, Schema valueSchema) external; +} diff --git a/packages/store/src/StoreCore.sol b/packages/store/src/StoreCore.sol index e95c2dc2c8..6555c689e9 100644 --- a/packages/store/src/StoreCore.sol +++ b/packages/store/src/StoreCore.sol @@ -10,7 +10,7 @@ import { PackedCounter } from "./PackedCounter.sol"; import { Slice, SliceLib } from "./Slice.sol"; import { StoreHooks, Tables, StoreHooksTableId } from "./codegen/Tables.sol"; import { IStoreErrors } from "./IStoreErrors.sol"; -import { IStoreHook } from "./IStore.sol"; +import { IStoreHook } from "./IStoreHook.sol"; import { StoreSwitch } from "./StoreSwitch.sol"; import { Hook, HookLib } from "./Hook.sol"; import { StoreHookLib, StoreHookType } from "./StoreHook.sol"; diff --git a/packages/store/src/StoreHook.sol b/packages/store/src/StoreHook.sol index 82cacb7cc2..0d7de0f899 100644 --- a/packages/store/src/StoreHook.sol +++ b/packages/store/src/StoreHook.sol @@ -2,7 +2,8 @@ pragma solidity >=0.8.0; import { Hook, HookLib } from "./Hook.sol"; -import { IStoreHook } from "./IStore.sol"; +import { IStoreHook, STORE_HOOK_INTERFACE_ID } from "./IStoreHook.sol"; +import { ERC165_INTERFACE_ID } from "./IERC165.sol"; enum StoreHookType { BEFORE_SET_RECORD, @@ -42,3 +43,10 @@ library StoreHookLib { return HookLib.encode(address(storeHook), enabledHooksBitmap); } } + +abstract contract StoreHook is IStoreHook { + // ERC-165 supportsInterface (see https://eips.ethereum.org/EIPS/eip-165) + function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) { + return interfaceId == STORE_HOOK_INTERFACE_ID || interfaceId == ERC165_INTERFACE_ID; + } +} diff --git a/packages/store/src/StoreSwitch.sol b/packages/store/src/StoreSwitch.sol index e165e3a161..28912a08ba 100644 --- a/packages/store/src/StoreSwitch.sol +++ b/packages/store/src/StoreSwitch.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import { IStore, IStoreHook } from "./IStore.sol"; +import { IStore } from "./IStore.sol"; +import { IStoreHook } from "./IStoreHook.sol"; import { StoreCore } from "./StoreCore.sol"; import { Schema } from "./Schema.sol"; diff --git a/packages/store/test/EchoSubscriber.sol b/packages/store/test/EchoSubscriber.sol index 6c7682b4bc..f36dd0ce67 100644 --- a/packages/store/test/EchoSubscriber.sol +++ b/packages/store/test/EchoSubscriber.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import { IStoreHook } from "../src/IStore.sol"; +import { StoreHook } from "../src/StoreHook.sol"; import { Schema } from "../src/Schema.sol"; -contract EchoSubscriber is IStoreHook { +contract EchoSubscriber is StoreHook { event HookCalled(bytes); function onBeforeSetRecord(bytes32 table, bytes32[] memory key, bytes memory data, Schema valueSchema) public { diff --git a/packages/store/test/MirrorSubscriber.sol b/packages/store/test/MirrorSubscriber.sol index b5adf0f5a2..cdb701268a 100644 --- a/packages/store/test/MirrorSubscriber.sol +++ b/packages/store/test/MirrorSubscriber.sol @@ -1,13 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import { IStore, IStoreHook } from "../src/IStore.sol"; +import { IStore } from "../src/IStore.sol"; +import { StoreHook } from "../src/StoreHook.sol"; import { StoreSwitch } from "../src/StoreSwitch.sol"; import { Schema } from "../src/Schema.sol"; bytes32 constant indexerTableId = keccak256("indexer.table"); -contract MirrorSubscriber is IStoreHook { +contract MirrorSubscriber is StoreHook { bytes32 _table; constructor( diff --git a/packages/store/test/RevertSubscriber.sol b/packages/store/test/RevertSubscriber.sol index 38d48a86a0..110207dc88 100644 --- a/packages/store/test/RevertSubscriber.sol +++ b/packages/store/test/RevertSubscriber.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import { IStoreHook } from "../src/IStore.sol"; +import { StoreHook } from "../src/StoreHook.sol"; import { Schema } from "../src/Schema.sol"; -contract RevertSubscriber is IStoreHook { +contract RevertSubscriber is StoreHook { function onBeforeSetRecord(bytes32, bytes32[] memory, bytes memory, Schema) public pure { revert("onBeforeSetRecord"); } diff --git a/packages/world/abi/AccessManagementSystem.sol/AccessManagementSystem.abi.json b/packages/world/abi/AccessManagementSystem.sol/AccessManagementSystem.abi.json index 18b98f95fe..ef43178b6f 100644 --- a/packages/world/abi/AccessManagementSystem.sol/AccessManagementSystem.abi.json +++ b/packages/world/abi/AccessManagementSystem.sol/AccessManagementSystem.abi.json @@ -79,6 +79,45 @@ "name": "StoreCore_InvalidDataLength", "type": "error" }, + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -115,6 +154,25 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [ { diff --git a/packages/world/abi/AccessManagementSystem.sol/AccessManagementSystem.abi.json.d.ts b/packages/world/abi/AccessManagementSystem.sol/AccessManagementSystem.abi.json.d.ts index 9a9eb5e2c7..7bdaba9c70 100644 --- a/packages/world/abi/AccessManagementSystem.sol/AccessManagementSystem.abi.json.d.ts +++ b/packages/world/abi/AccessManagementSystem.sol/AccessManagementSystem.abi.json.d.ts @@ -79,6 +79,45 @@ declare const abi: [ name: "StoreCore_InvalidDataLength"; type: "error"; }, + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: "sender"; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: "value"; + type: "uint256"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, { inputs: [ { @@ -115,6 +154,25 @@ declare const abi: [ stateMutability: "nonpayable"; type: "function"; }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, { inputs: [ { diff --git a/packages/world/abi/BalanceTransferSystem.sol/BalanceTransferSystem.abi.json b/packages/world/abi/BalanceTransferSystem.sol/BalanceTransferSystem.abi.json index 4a4280c78f..a50016d9d9 100644 --- a/packages/world/abi/BalanceTransferSystem.sol/BalanceTransferSystem.abi.json +++ b/packages/world/abi/BalanceTransferSystem.sol/BalanceTransferSystem.abi.json @@ -69,6 +69,22 @@ "name": "InsufficientBalance", "type": "error" }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "InterfaceNotSupported", + "type": "error" + }, { "inputs": [ { @@ -188,6 +204,64 @@ "name": "SystemExists", "type": "error" }, + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [ { diff --git a/packages/world/abi/BalanceTransferSystem.sol/BalanceTransferSystem.abi.json.d.ts b/packages/world/abi/BalanceTransferSystem.sol/BalanceTransferSystem.abi.json.d.ts index 4aa167e722..7e36d4bc4d 100644 --- a/packages/world/abi/BalanceTransferSystem.sol/BalanceTransferSystem.abi.json.d.ts +++ b/packages/world/abi/BalanceTransferSystem.sol/BalanceTransferSystem.abi.json.d.ts @@ -69,6 +69,22 @@ declare const abi: [ name: "InsufficientBalance"; type: "error"; }, + { + inputs: [ + { + internalType: "address"; + name: "contractAddress"; + type: "address"; + }, + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "InterfaceNotSupported"; + type: "error"; + }, { inputs: [ { @@ -188,6 +204,64 @@ declare const abi: [ name: "SystemExists"; type: "error"; }, + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: "sender"; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: "value"; + type: "uint256"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, { inputs: [ { diff --git a/packages/world/abi/CallboundDelegationControl.sol/CallboundDelegationControl.abi.json b/packages/world/abi/CallboundDelegationControl.sol/CallboundDelegationControl.abi.json index 27a04c7a72..33ca75c04e 100644 --- a/packages/world/abi/CallboundDelegationControl.sol/CallboundDelegationControl.abi.json +++ b/packages/world/abi/CallboundDelegationControl.sol/CallboundDelegationControl.abi.json @@ -63,6 +63,45 @@ "name": "StoreCore_InvalidDataLength", "type": "error" }, + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -91,6 +130,25 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [ { diff --git a/packages/world/abi/CallboundDelegationControl.sol/CallboundDelegationControl.abi.json.d.ts b/packages/world/abi/CallboundDelegationControl.sol/CallboundDelegationControl.abi.json.d.ts index a8cf1229b9..16df83d0da 100644 --- a/packages/world/abi/CallboundDelegationControl.sol/CallboundDelegationControl.abi.json.d.ts +++ b/packages/world/abi/CallboundDelegationControl.sol/CallboundDelegationControl.abi.json.d.ts @@ -63,6 +63,45 @@ declare const abi: [ name: "StoreCore_InvalidDataLength"; type: "error"; }, + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: "sender"; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: "value"; + type: "uint256"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, { inputs: [ { @@ -91,6 +130,25 @@ declare const abi: [ stateMutability: "nonpayable"; type: "function"; }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, { inputs: [ { diff --git a/packages/world/abi/CoreModule.sol/CoreModule.abi.json b/packages/world/abi/CoreModule.sol/CoreModule.abi.json index 472cd505dc..8f31605e6b 100644 --- a/packages/world/abi/CoreModule.sol/CoreModule.abi.json +++ b/packages/world/abi/CoreModule.sol/CoreModule.abi.json @@ -132,6 +132,45 @@ "name": "StoreCore_TableAlreadyExists", "type": "error" }, + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "getName", @@ -170,5 +209,24 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" } ] \ No newline at end of file diff --git a/packages/world/abi/CoreModule.sol/CoreModule.abi.json.d.ts b/packages/world/abi/CoreModule.sol/CoreModule.abi.json.d.ts index 1f2c1eb490..c5b23d3877 100644 --- a/packages/world/abi/CoreModule.sol/CoreModule.abi.json.d.ts +++ b/packages/world/abi/CoreModule.sol/CoreModule.abi.json.d.ts @@ -132,6 +132,45 @@ declare const abi: [ name: "StoreCore_TableAlreadyExists"; type: "error"; }, + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: "sender"; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: "value"; + type: "uint256"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, { inputs: []; name: "getName"; @@ -170,6 +209,25 @@ declare const abi: [ outputs: []; stateMutability: "nonpayable"; type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; } ]; export default abi; diff --git a/packages/world/abi/CoreSystem.sol/CoreSystem.abi.json b/packages/world/abi/CoreSystem.sol/CoreSystem.abi.json index e3194498ac..cce7725a39 100644 --- a/packages/world/abi/CoreSystem.sol/CoreSystem.abi.json +++ b/packages/world/abi/CoreSystem.sol/CoreSystem.abi.json @@ -69,6 +69,22 @@ "name": "InsufficientBalance", "type": "error" }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "InterfaceNotSupported", + "type": "error" + }, { "inputs": [ { @@ -266,6 +282,45 @@ "name": "StoreEphemeralRecord", "type": "event" }, + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -544,6 +599,25 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [ { diff --git a/packages/world/abi/CoreSystem.sol/CoreSystem.abi.json.d.ts b/packages/world/abi/CoreSystem.sol/CoreSystem.abi.json.d.ts index 1fc9762cd2..3fd08490f2 100644 --- a/packages/world/abi/CoreSystem.sol/CoreSystem.abi.json.d.ts +++ b/packages/world/abi/CoreSystem.sol/CoreSystem.abi.json.d.ts @@ -69,6 +69,22 @@ declare const abi: [ name: "InsufficientBalance"; type: "error"; }, + { + inputs: [ + { + internalType: "address"; + name: "contractAddress"; + type: "address"; + }, + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "InterfaceNotSupported"; + type: "error"; + }, { inputs: [ { @@ -266,6 +282,45 @@ declare const abi: [ name: "StoreEphemeralRecord"; type: "event"; }, + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: "sender"; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: "value"; + type: "uint256"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, { inputs: [ { @@ -544,6 +599,25 @@ declare const abi: [ stateMutability: "nonpayable"; type: "function"; }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, { inputs: [ { diff --git a/packages/world/abi/DelegationControl.sol/DelegationControl.abi.json b/packages/world/abi/DelegationControl.sol/DelegationControl.abi.json index 5b5a35e503..ef2b1cf902 100644 --- a/packages/world/abi/DelegationControl.sol/DelegationControl.abi.json +++ b/packages/world/abi/DelegationControl.sol/DelegationControl.abi.json @@ -1,4 +1,62 @@ [ + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [ { diff --git a/packages/world/abi/DelegationControl.sol/DelegationControl.abi.json.d.ts b/packages/world/abi/DelegationControl.sol/DelegationControl.abi.json.d.ts index 3bc9ed06dd..924052088b 100644 --- a/packages/world/abi/DelegationControl.sol/DelegationControl.abi.json.d.ts +++ b/packages/world/abi/DelegationControl.sol/DelegationControl.abi.json.d.ts @@ -1,4 +1,62 @@ declare const abi: [ + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: "sender"; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: "value"; + type: "uint256"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, { inputs: [ { diff --git a/packages/world/abi/EphemeralRecordSystem.sol/EphemeralRecordSystem.abi.json b/packages/world/abi/EphemeralRecordSystem.sol/EphemeralRecordSystem.abi.json index bd15689e98..9874e18914 100644 --- a/packages/world/abi/EphemeralRecordSystem.sol/EphemeralRecordSystem.abi.json +++ b/packages/world/abi/EphemeralRecordSystem.sol/EphemeralRecordSystem.abi.json @@ -72,6 +72,45 @@ "name": "StoreEphemeralRecord", "type": "event" }, + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -99,5 +138,24 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" } ] \ No newline at end of file diff --git a/packages/world/abi/EphemeralRecordSystem.sol/EphemeralRecordSystem.abi.json.d.ts b/packages/world/abi/EphemeralRecordSystem.sol/EphemeralRecordSystem.abi.json.d.ts index 69fc2e4772..f074bc64fb 100644 --- a/packages/world/abi/EphemeralRecordSystem.sol/EphemeralRecordSystem.abi.json.d.ts +++ b/packages/world/abi/EphemeralRecordSystem.sol/EphemeralRecordSystem.abi.json.d.ts @@ -72,6 +72,45 @@ declare const abi: [ name: "StoreEphemeralRecord"; type: "event"; }, + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: "sender"; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: "value"; + type: "uint256"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, { inputs: [ { @@ -99,6 +138,25 @@ declare const abi: [ outputs: []; stateMutability: "nonpayable"; type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; } ]; export default abi; diff --git a/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json b/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json index 50884b02cc..1031a22ebf 100644 --- a/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json +++ b/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json @@ -69,6 +69,22 @@ "name": "InsufficientBalance", "type": "error" }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "InterfaceNotSupported", + "type": "error" + }, { "inputs": [ { diff --git a/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json.d.ts b/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json.d.ts index 5ee4ca34f2..4274de6990 100644 --- a/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json.d.ts +++ b/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json.d.ts @@ -69,6 +69,22 @@ declare const abi: [ name: "InsufficientBalance"; type: "error"; }, + { + inputs: [ + { + internalType: "address"; + name: "contractAddress"; + type: "address"; + }, + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "InterfaceNotSupported"; + type: "error"; + }, { inputs: [ { diff --git a/packages/world/abi/IDelegationControl.sol/IDelegationControl.abi.json b/packages/world/abi/IDelegationControl.sol/IDelegationControl.abi.json index 5b5a35e503..787307f1d3 100644 --- a/packages/world/abi/IDelegationControl.sol/IDelegationControl.abi.json +++ b/packages/world/abi/IDelegationControl.sol/IDelegationControl.abi.json @@ -1,4 +1,62 @@ [ + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceID", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { diff --git a/packages/world/abi/IDelegationControl.sol/IDelegationControl.abi.json.d.ts b/packages/world/abi/IDelegationControl.sol/IDelegationControl.abi.json.d.ts index 3bc9ed06dd..d28e50242a 100644 --- a/packages/world/abi/IDelegationControl.sol/IDelegationControl.abi.json.d.ts +++ b/packages/world/abi/IDelegationControl.sol/IDelegationControl.abi.json.d.ts @@ -1,4 +1,62 @@ declare const abi: [ + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: ""; + type: "uint256"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceID"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "view"; + type: "function"; + }, { inputs: [ { diff --git a/packages/world/abi/IERC165.sol/IERC165.abi.json b/packages/world/abi/IERC165.sol/IERC165.abi.json new file mode 100644 index 0000000000..f9e19986d2 --- /dev/null +++ b/packages/world/abi/IERC165.sol/IERC165.abi.json @@ -0,0 +1,21 @@ +[ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceID", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/world/abi/IERC165.sol/IERC165.abi.json.d.ts b/packages/world/abi/IERC165.sol/IERC165.abi.json.d.ts new file mode 100644 index 0000000000..41da21a6f2 --- /dev/null +++ b/packages/world/abi/IERC165.sol/IERC165.abi.json.d.ts @@ -0,0 +1,22 @@ +declare const abi: [ + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceID"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "view"; + type: "function"; + } +]; +export default abi; diff --git a/packages/world/abi/IModule.sol/IModule.abi.json b/packages/world/abi/IModule.sol/IModule.abi.json index e4683fbb5e..7700a8ec17 100644 --- a/packages/world/abi/IModule.sol/IModule.abi.json +++ b/packages/world/abi/IModule.sol/IModule.abi.json @@ -58,5 +58,24 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceID", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" } ] \ No newline at end of file diff --git a/packages/world/abi/IModule.sol/IModule.abi.json.d.ts b/packages/world/abi/IModule.sol/IModule.abi.json.d.ts index 522a06fb65..a7d79f1b71 100644 --- a/packages/world/abi/IModule.sol/IModule.abi.json.d.ts +++ b/packages/world/abi/IModule.sol/IModule.abi.json.d.ts @@ -58,6 +58,25 @@ declare const abi: [ outputs: []; stateMutability: "nonpayable"; type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceID"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "view"; + type: "function"; } ]; export default abi; diff --git a/packages/world/abi/src/IStore.sol/IStoreHook.abi.json b/packages/world/abi/IStoreHook.sol/IStoreHook.abi.json similarity index 90% rename from packages/world/abi/src/IStore.sol/IStoreHook.abi.json rename to packages/world/abi/IStoreHook.sol/IStoreHook.abi.json index 316af6422c..b35f6251af 100644 --- a/packages/world/abi/src/IStore.sol/IStoreHook.abi.json +++ b/packages/world/abi/IStoreHook.sol/IStoreHook.abi.json @@ -166,5 +166,24 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceID", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" } ] \ No newline at end of file diff --git a/packages/store/abi/IStore.sol/IStoreHook.abi.json.d.ts b/packages/world/abi/IStoreHook.sol/IStoreHook.abi.json.d.ts similarity index 90% rename from packages/store/abi/IStore.sol/IStoreHook.abi.json.d.ts rename to packages/world/abi/IStoreHook.sol/IStoreHook.abi.json.d.ts index 2e39c851eb..ae36ae3637 100644 --- a/packages/store/abi/IStore.sol/IStoreHook.abi.json.d.ts +++ b/packages/world/abi/IStoreHook.sol/IStoreHook.abi.json.d.ts @@ -166,6 +166,25 @@ declare const abi: [ outputs: []; stateMutability: "nonpayable"; type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceID"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "view"; + type: "function"; } ]; export default abi; diff --git a/packages/world/abi/ISystemHook.sol/ISystemHook.abi.json b/packages/world/abi/ISystemHook.sol/ISystemHook.abi.json index 9ff64abcc5..dd464a5aec 100644 --- a/packages/world/abi/ISystemHook.sol/ISystemHook.abi.json +++ b/packages/world/abi/ISystemHook.sol/ISystemHook.abi.json @@ -44,5 +44,24 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceID", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" } ] \ No newline at end of file diff --git a/packages/world/abi/ISystemHook.sol/ISystemHook.abi.json.d.ts b/packages/world/abi/ISystemHook.sol/ISystemHook.abi.json.d.ts index 8a9f012eab..45a2851b1c 100644 --- a/packages/world/abi/ISystemHook.sol/ISystemHook.abi.json.d.ts +++ b/packages/world/abi/ISystemHook.sol/ISystemHook.abi.json.d.ts @@ -44,6 +44,25 @@ declare const abi: [ outputs: []; stateMutability: "nonpayable"; type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceID"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "view"; + type: "function"; } ]; export default abi; diff --git a/packages/world/abi/IWorldContextConsumer.sol/IWorldContextConsumer.abi.json b/packages/world/abi/IWorldContextConsumer.sol/IWorldContextConsumer.abi.json new file mode 100644 index 0000000000..25ad4672dc --- /dev/null +++ b/packages/world/abi/IWorldContextConsumer.sol/IWorldContextConsumer.abi.json @@ -0,0 +1,60 @@ +[ + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceID", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/world/abi/IWorldContextConsumer.sol/IWorldContextConsumer.abi.json.d.ts b/packages/world/abi/IWorldContextConsumer.sol/IWorldContextConsumer.abi.json.d.ts new file mode 100644 index 0000000000..ab71db2ba6 --- /dev/null +++ b/packages/world/abi/IWorldContextConsumer.sol/IWorldContextConsumer.abi.json.d.ts @@ -0,0 +1,61 @@ +declare const abi: [ + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: ""; + type: "uint256"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceID"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "view"; + type: "function"; + } +]; +export default abi; diff --git a/packages/world/abi/IWorldErrors.sol/IWorldErrors.abi.json b/packages/world/abi/IWorldErrors.sol/IWorldErrors.abi.json index ea3fca584b..0af520372a 100644 --- a/packages/world/abi/IWorldErrors.sol/IWorldErrors.abi.json +++ b/packages/world/abi/IWorldErrors.sol/IWorldErrors.abi.json @@ -69,6 +69,22 @@ "name": "InsufficientBalance", "type": "error" }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "InterfaceNotSupported", + "type": "error" + }, { "inputs": [ { diff --git a/packages/world/abi/IWorldErrors.sol/IWorldErrors.abi.json.d.ts b/packages/world/abi/IWorldErrors.sol/IWorldErrors.abi.json.d.ts index 14acc066fd..476da1d71c 100644 --- a/packages/world/abi/IWorldErrors.sol/IWorldErrors.abi.json.d.ts +++ b/packages/world/abi/IWorldErrors.sol/IWorldErrors.abi.json.d.ts @@ -69,6 +69,22 @@ declare const abi: [ name: "InsufficientBalance"; type: "error"; }, + { + inputs: [ + { + internalType: "address"; + name: "contractAddress"; + type: "address"; + }, + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "InterfaceNotSupported"; + type: "error"; + }, { inputs: [ { diff --git a/packages/world/abi/IWorldKernel.sol/IWorldKernel.abi.json b/packages/world/abi/IWorldKernel.sol/IWorldKernel.abi.json index 393e339799..5c7a2545d7 100644 --- a/packages/world/abi/IWorldKernel.sol/IWorldKernel.abi.json +++ b/packages/world/abi/IWorldKernel.sol/IWorldKernel.abi.json @@ -69,6 +69,22 @@ "name": "InsufficientBalance", "type": "error" }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "InterfaceNotSupported", + "type": "error" + }, { "inputs": [ { diff --git a/packages/world/abi/IWorldKernel.sol/IWorldKernel.abi.json.d.ts b/packages/world/abi/IWorldKernel.sol/IWorldKernel.abi.json.d.ts index c5dbe952a9..f6f89bf906 100644 --- a/packages/world/abi/IWorldKernel.sol/IWorldKernel.abi.json.d.ts +++ b/packages/world/abi/IWorldKernel.sol/IWorldKernel.abi.json.d.ts @@ -69,6 +69,22 @@ declare const abi: [ name: "InsufficientBalance"; type: "error"; }, + { + inputs: [ + { + internalType: "address"; + name: "contractAddress"; + type: "address"; + }, + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "InterfaceNotSupported"; + type: "error"; + }, { inputs: [ { diff --git a/packages/world/abi/KeysInTableHook.sol/KeysInTableHook.abi.json b/packages/world/abi/KeysInTableHook.sol/KeysInTableHook.abi.json index d4a8fde8ea..eaff373dca 100644 --- a/packages/world/abi/KeysInTableHook.sol/KeysInTableHook.abi.json +++ b/packages/world/abi/KeysInTableHook.sol/KeysInTableHook.abi.json @@ -251,5 +251,24 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" } ] \ No newline at end of file diff --git a/packages/world/abi/KeysInTableHook.sol/KeysInTableHook.abi.json.d.ts b/packages/world/abi/KeysInTableHook.sol/KeysInTableHook.abi.json.d.ts index ac7b1c5e5b..b6b7fd772c 100644 --- a/packages/world/abi/KeysInTableHook.sol/KeysInTableHook.abi.json.d.ts +++ b/packages/world/abi/KeysInTableHook.sol/KeysInTableHook.abi.json.d.ts @@ -251,6 +251,25 @@ declare const abi: [ outputs: []; stateMutability: "nonpayable"; type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; } ]; export default abi; diff --git a/packages/world/abi/KeysInTableModule.sol/KeysInTableModule.abi.json b/packages/world/abi/KeysInTableModule.sol/KeysInTableModule.abi.json index 54e901cb10..1b73bd958f 100644 --- a/packages/world/abi/KeysInTableModule.sol/KeysInTableModule.abi.json +++ b/packages/world/abi/KeysInTableModule.sol/KeysInTableModule.abi.json @@ -36,6 +36,45 @@ "name": "SchemaLib_StaticTypeAfterDynamicType", "type": "error" }, + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "getName", @@ -74,5 +113,24 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" } ] \ No newline at end of file diff --git a/packages/world/abi/KeysInTableModule.sol/KeysInTableModule.abi.json.d.ts b/packages/world/abi/KeysInTableModule.sol/KeysInTableModule.abi.json.d.ts index 96427e2f6b..00f96c935d 100644 --- a/packages/world/abi/KeysInTableModule.sol/KeysInTableModule.abi.json.d.ts +++ b/packages/world/abi/KeysInTableModule.sol/KeysInTableModule.abi.json.d.ts @@ -36,6 +36,45 @@ declare const abi: [ name: "SchemaLib_StaticTypeAfterDynamicType"; type: "error"; }, + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: "sender"; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: "value"; + type: "uint256"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, { inputs: []; name: "getName"; @@ -74,6 +113,25 @@ declare const abi: [ outputs: []; stateMutability: "nonpayable"; type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; } ]; export default abi; diff --git a/packages/world/abi/KeysWithValueHook.sol/KeysWithValueHook.abi.json b/packages/world/abi/KeysWithValueHook.sol/KeysWithValueHook.abi.json index 0df0c4e92f..873654242c 100644 --- a/packages/world/abi/KeysWithValueHook.sol/KeysWithValueHook.abi.json +++ b/packages/world/abi/KeysWithValueHook.sol/KeysWithValueHook.abi.json @@ -235,5 +235,24 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" } ] \ No newline at end of file diff --git a/packages/world/abi/KeysWithValueHook.sol/KeysWithValueHook.abi.json.d.ts b/packages/world/abi/KeysWithValueHook.sol/KeysWithValueHook.abi.json.d.ts index 799f8fd0b2..77467bcde6 100644 --- a/packages/world/abi/KeysWithValueHook.sol/KeysWithValueHook.abi.json.d.ts +++ b/packages/world/abi/KeysWithValueHook.sol/KeysWithValueHook.abi.json.d.ts @@ -235,6 +235,25 @@ declare const abi: [ outputs: []; stateMutability: "nonpayable"; type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; } ]; export default abi; diff --git a/packages/world/abi/KeysWithValueModule.sol/KeysWithValueModule.abi.json b/packages/world/abi/KeysWithValueModule.sol/KeysWithValueModule.abi.json index 54e901cb10..1b73bd958f 100644 --- a/packages/world/abi/KeysWithValueModule.sol/KeysWithValueModule.abi.json +++ b/packages/world/abi/KeysWithValueModule.sol/KeysWithValueModule.abi.json @@ -36,6 +36,45 @@ "name": "SchemaLib_StaticTypeAfterDynamicType", "type": "error" }, + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "getName", @@ -74,5 +113,24 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" } ] \ No newline at end of file diff --git a/packages/world/abi/KeysWithValueModule.sol/KeysWithValueModule.abi.json.d.ts b/packages/world/abi/KeysWithValueModule.sol/KeysWithValueModule.abi.json.d.ts index 96427e2f6b..00f96c935d 100644 --- a/packages/world/abi/KeysWithValueModule.sol/KeysWithValueModule.abi.json.d.ts +++ b/packages/world/abi/KeysWithValueModule.sol/KeysWithValueModule.abi.json.d.ts @@ -36,6 +36,45 @@ declare const abi: [ name: "SchemaLib_StaticTypeAfterDynamicType"; type: "error"; }, + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: "sender"; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: "value"; + type: "uint256"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, { inputs: []; name: "getName"; @@ -74,6 +113,25 @@ declare const abi: [ outputs: []; stateMutability: "nonpayable"; type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; } ]; export default abi; diff --git a/packages/world/abi/Module.sol/Module.abi.json b/packages/world/abi/Module.sol/Module.abi.json new file mode 100644 index 0000000000..f1dc03fdc9 --- /dev/null +++ b/packages/world/abi/Module.sol/Module.abi.json @@ -0,0 +1,120 @@ +[ + { + "inputs": [], + "name": "NonRootInstallNotSupported", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "resourceSelector", + "type": "string" + } + ], + "name": "RequiredModuleNotFound", + "type": "error" + }, + { + "inputs": [], + "name": "RootInstallModeNotSupported", + "type": "error" + }, + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getName", + "outputs": [ + { + "internalType": "bytes16", + "name": "name", + "type": "bytes16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "args", + "type": "bytes" + } + ], + "name": "install", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "args", + "type": "bytes" + } + ], + "name": "installRoot", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/world/abi/Module.sol/Module.abi.json.d.ts b/packages/world/abi/Module.sol/Module.abi.json.d.ts new file mode 100644 index 0000000000..bc24608fee --- /dev/null +++ b/packages/world/abi/Module.sol/Module.abi.json.d.ts @@ -0,0 +1,121 @@ +declare const abi: [ + { + inputs: []; + name: "NonRootInstallNotSupported"; + type: "error"; + }, + { + inputs: [ + { + internalType: "string"; + name: "resourceSelector"; + type: "string"; + } + ]; + name: "RequiredModuleNotFound"; + type: "error"; + }, + { + inputs: []; + name: "RootInstallModeNotSupported"; + type: "error"; + }, + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: "sender"; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: "value"; + type: "uint256"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "getName"; + outputs: [ + { + internalType: "bytes16"; + name: "name"; + type: "bytes16"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes"; + name: "args"; + type: "bytes"; + } + ]; + name: "install"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes"; + name: "args"; + type: "bytes"; + } + ]; + name: "installRoot"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; + } +]; +export default abi; diff --git a/packages/world/abi/ModuleInstallationSystem.sol/ModuleInstallationSystem.abi.json b/packages/world/abi/ModuleInstallationSystem.sol/ModuleInstallationSystem.abi.json index 3ba41db3c5..171f1ba0fb 100644 --- a/packages/world/abi/ModuleInstallationSystem.sol/ModuleInstallationSystem.abi.json +++ b/packages/world/abi/ModuleInstallationSystem.sol/ModuleInstallationSystem.abi.json @@ -1,4 +1,20 @@ [ + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "InterfaceNotSupported", + "type": "error" + }, { "inputs": [ { @@ -52,6 +68,45 @@ "name": "StoreCore_InvalidDataLength", "type": "error" }, + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -69,5 +124,24 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" } ] \ No newline at end of file diff --git a/packages/world/abi/ModuleInstallationSystem.sol/ModuleInstallationSystem.abi.json.d.ts b/packages/world/abi/ModuleInstallationSystem.sol/ModuleInstallationSystem.abi.json.d.ts index 2f3301d8b8..46bcda0db2 100644 --- a/packages/world/abi/ModuleInstallationSystem.sol/ModuleInstallationSystem.abi.json.d.ts +++ b/packages/world/abi/ModuleInstallationSystem.sol/ModuleInstallationSystem.abi.json.d.ts @@ -1,4 +1,20 @@ declare const abi: [ + { + inputs: [ + { + internalType: "address"; + name: "contractAddress"; + type: "address"; + }, + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "InterfaceNotSupported"; + type: "error"; + }, { inputs: [ { @@ -52,6 +68,45 @@ declare const abi: [ name: "StoreCore_InvalidDataLength"; type: "error"; }, + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: "sender"; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: "value"; + type: "uint256"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, { inputs: [ { @@ -69,6 +124,25 @@ declare const abi: [ outputs: []; stateMutability: "nonpayable"; type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; } ]; export default abi; diff --git a/packages/world/abi/StandardDelegationsModule.sol/StandardDelegationsModule.abi.json b/packages/world/abi/StandardDelegationsModule.sol/StandardDelegationsModule.abi.json index 1235206c8a..0d83727d33 100644 --- a/packages/world/abi/StandardDelegationsModule.sol/StandardDelegationsModule.abi.json +++ b/packages/world/abi/StandardDelegationsModule.sol/StandardDelegationsModule.abi.json @@ -121,6 +121,45 @@ "name": "StoreCore_TableAlreadyExists", "type": "error" }, + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "getName", @@ -159,5 +198,24 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" } ] \ No newline at end of file diff --git a/packages/world/abi/StandardDelegationsModule.sol/StandardDelegationsModule.abi.json.d.ts b/packages/world/abi/StandardDelegationsModule.sol/StandardDelegationsModule.abi.json.d.ts index 1b9972cc81..a6067f64e3 100644 --- a/packages/world/abi/StandardDelegationsModule.sol/StandardDelegationsModule.abi.json.d.ts +++ b/packages/world/abi/StandardDelegationsModule.sol/StandardDelegationsModule.abi.json.d.ts @@ -121,6 +121,45 @@ declare const abi: [ name: "StoreCore_TableAlreadyExists"; type: "error"; }, + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: "sender"; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: "value"; + type: "uint256"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, { inputs: []; name: "getName"; @@ -159,6 +198,25 @@ declare const abi: [ outputs: []; stateMutability: "nonpayable"; type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; } ]; export default abi; diff --git a/packages/world/abi/StoreHook.sol/StoreHook.abi.json b/packages/world/abi/StoreHook.sol/StoreHook.abi.json new file mode 100644 index 0000000000..3d219e7777 --- /dev/null +++ b/packages/world/abi/StoreHook.sol/StoreHook.abi.json @@ -0,0 +1,189 @@ +[ + { + "inputs": [ + { + "internalType": "bytes32", + "name": "table", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "internalType": "Schema", + "name": "valueSchema", + "type": "bytes32" + } + ], + "name": "onAfterDeleteRecord", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "table", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "internalType": "uint8", + "name": "schemaIndex", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "Schema", + "name": "valueSchema", + "type": "bytes32" + } + ], + "name": "onAfterSetField", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "table", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "Schema", + "name": "valueSchema", + "type": "bytes32" + } + ], + "name": "onAfterSetRecord", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "table", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "internalType": "Schema", + "name": "valueSchema", + "type": "bytes32" + } + ], + "name": "onBeforeDeleteRecord", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "table", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "internalType": "uint8", + "name": "schemaIndex", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "Schema", + "name": "valueSchema", + "type": "bytes32" + } + ], + "name": "onBeforeSetField", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "table", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "Schema", + "name": "valueSchema", + "type": "bytes32" + } + ], + "name": "onBeforeSetRecord", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/world/abi/StoreHook.sol/StoreHook.abi.json.d.ts b/packages/world/abi/StoreHook.sol/StoreHook.abi.json.d.ts new file mode 100644 index 0000000000..494a46cc19 --- /dev/null +++ b/packages/world/abi/StoreHook.sol/StoreHook.abi.json.d.ts @@ -0,0 +1,190 @@ +declare const abi: [ + { + inputs: [ + { + internalType: "bytes32"; + name: "table"; + type: "bytes32"; + }, + { + internalType: "bytes32[]"; + name: "key"; + type: "bytes32[]"; + }, + { + internalType: "Schema"; + name: "valueSchema"; + type: "bytes32"; + } + ]; + name: "onAfterDeleteRecord"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes32"; + name: "table"; + type: "bytes32"; + }, + { + internalType: "bytes32[]"; + name: "key"; + type: "bytes32[]"; + }, + { + internalType: "uint8"; + name: "schemaIndex"; + type: "uint8"; + }, + { + internalType: "bytes"; + name: "data"; + type: "bytes"; + }, + { + internalType: "Schema"; + name: "valueSchema"; + type: "bytes32"; + } + ]; + name: "onAfterSetField"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes32"; + name: "table"; + type: "bytes32"; + }, + { + internalType: "bytes32[]"; + name: "key"; + type: "bytes32[]"; + }, + { + internalType: "bytes"; + name: "data"; + type: "bytes"; + }, + { + internalType: "Schema"; + name: "valueSchema"; + type: "bytes32"; + } + ]; + name: "onAfterSetRecord"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes32"; + name: "table"; + type: "bytes32"; + }, + { + internalType: "bytes32[]"; + name: "key"; + type: "bytes32[]"; + }, + { + internalType: "Schema"; + name: "valueSchema"; + type: "bytes32"; + } + ]; + name: "onBeforeDeleteRecord"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes32"; + name: "table"; + type: "bytes32"; + }, + { + internalType: "bytes32[]"; + name: "key"; + type: "bytes32[]"; + }, + { + internalType: "uint8"; + name: "schemaIndex"; + type: "uint8"; + }, + { + internalType: "bytes"; + name: "data"; + type: "bytes"; + }, + { + internalType: "Schema"; + name: "valueSchema"; + type: "bytes32"; + } + ]; + name: "onBeforeSetField"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes32"; + name: "table"; + type: "bytes32"; + }, + { + internalType: "bytes32[]"; + name: "key"; + type: "bytes32[]"; + }, + { + internalType: "bytes"; + name: "data"; + type: "bytes"; + }, + { + internalType: "Schema"; + name: "valueSchema"; + type: "bytes32"; + } + ]; + name: "onBeforeSetRecord"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; + } +]; +export default abi; diff --git a/packages/world/abi/StoreRegistrationSystem.sol/StoreRegistrationSystem.abi.json b/packages/world/abi/StoreRegistrationSystem.sol/StoreRegistrationSystem.abi.json index 5c2c6fb55e..ddb3deb9fe 100644 --- a/packages/world/abi/StoreRegistrationSystem.sol/StoreRegistrationSystem.abi.json +++ b/packages/world/abi/StoreRegistrationSystem.sol/StoreRegistrationSystem.abi.json @@ -69,6 +69,22 @@ "name": "InsufficientBalance", "type": "error" }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "InterfaceNotSupported", + "type": "error" + }, { "inputs": [ { @@ -241,6 +257,45 @@ "name": "SystemExists", "type": "error" }, + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -297,6 +352,25 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [ { diff --git a/packages/world/abi/StoreRegistrationSystem.sol/StoreRegistrationSystem.abi.json.d.ts b/packages/world/abi/StoreRegistrationSystem.sol/StoreRegistrationSystem.abi.json.d.ts index 9c27c02ca1..02d4278711 100644 --- a/packages/world/abi/StoreRegistrationSystem.sol/StoreRegistrationSystem.abi.json.d.ts +++ b/packages/world/abi/StoreRegistrationSystem.sol/StoreRegistrationSystem.abi.json.d.ts @@ -69,6 +69,22 @@ declare const abi: [ name: "InsufficientBalance"; type: "error"; }, + { + inputs: [ + { + internalType: "address"; + name: "contractAddress"; + type: "address"; + }, + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "InterfaceNotSupported"; + type: "error"; + }, { inputs: [ { @@ -241,6 +257,45 @@ declare const abi: [ name: "SystemExists"; type: "error"; }, + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: "sender"; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: "value"; + type: "uint256"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, { inputs: [ { @@ -297,6 +352,25 @@ declare const abi: [ stateMutability: "nonpayable"; type: "function"; }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, { inputs: [ { diff --git a/packages/world/abi/System.sol/System.abi.json b/packages/world/abi/System.sol/System.abi.json index 0637a088a0..6dedac7faa 100644 --- a/packages/world/abi/System.sol/System.abi.json +++ b/packages/world/abi/System.sol/System.abi.json @@ -1 +1,60 @@ -[] \ No newline at end of file +[ + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/world/abi/System.sol/System.abi.json.d.ts b/packages/world/abi/System.sol/System.abi.json.d.ts new file mode 100644 index 0000000000..7ec709a682 --- /dev/null +++ b/packages/world/abi/System.sol/System.abi.json.d.ts @@ -0,0 +1,61 @@ +declare const abi: [ + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: "sender"; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: "value"; + type: "uint256"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; + } +]; +export default abi; diff --git a/packages/world/abi/SystemHook.sol/SystemHook.abi.json b/packages/world/abi/SystemHook.sol/SystemHook.abi.json new file mode 100644 index 0000000000..4f2910c550 --- /dev/null +++ b/packages/world/abi/SystemHook.sol/SystemHook.abi.json @@ -0,0 +1,67 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "msgSender", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "resourceSelector", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "funcSelectorAndArgs", + "type": "bytes" + } + ], + "name": "onAfterCallSystem", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "msgSender", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "resourceSelector", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "funcSelectorAndArgs", + "type": "bytes" + } + ], + "name": "onBeforeCallSystem", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/world/abi/SystemHook.sol/SystemHook.abi.json.d.ts b/packages/world/abi/SystemHook.sol/SystemHook.abi.json.d.ts new file mode 100644 index 0000000000..b8b6cae0cb --- /dev/null +++ b/packages/world/abi/SystemHook.sol/SystemHook.abi.json.d.ts @@ -0,0 +1,68 @@ +declare const abi: [ + { + inputs: [ + { + internalType: "address"; + name: "msgSender"; + type: "address"; + }, + { + internalType: "bytes32"; + name: "resourceSelector"; + type: "bytes32"; + }, + { + internalType: "bytes"; + name: "funcSelectorAndArgs"; + type: "bytes"; + } + ]; + name: "onAfterCallSystem"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "address"; + name: "msgSender"; + type: "address"; + }, + { + internalType: "bytes32"; + name: "resourceSelector"; + type: "bytes32"; + }, + { + internalType: "bytes"; + name: "funcSelectorAndArgs"; + type: "bytes"; + } + ]; + name: "onBeforeCallSystem"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "view"; + type: "function"; + } +]; +export default abi; diff --git a/packages/world/abi/TimeboundDelegationControl.sol/TimeboundDelegationControl.abi.json b/packages/world/abi/TimeboundDelegationControl.sol/TimeboundDelegationControl.abi.json index 00b7f632e4..e44457fe5a 100644 --- a/packages/world/abi/TimeboundDelegationControl.sol/TimeboundDelegationControl.abi.json +++ b/packages/world/abi/TimeboundDelegationControl.sol/TimeboundDelegationControl.abi.json @@ -63,6 +63,45 @@ "name": "StoreCore_InvalidDataLength", "type": "error" }, + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -81,6 +120,25 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [ { diff --git a/packages/world/abi/TimeboundDelegationControl.sol/TimeboundDelegationControl.abi.json.d.ts b/packages/world/abi/TimeboundDelegationControl.sol/TimeboundDelegationControl.abi.json.d.ts index b72c291457..b7a1195398 100644 --- a/packages/world/abi/TimeboundDelegationControl.sol/TimeboundDelegationControl.abi.json.d.ts +++ b/packages/world/abi/TimeboundDelegationControl.sol/TimeboundDelegationControl.abi.json.d.ts @@ -63,6 +63,45 @@ declare const abi: [ name: "StoreCore_InvalidDataLength"; type: "error"; }, + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: "sender"; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: "value"; + type: "uint256"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, { inputs: [ { @@ -81,6 +120,25 @@ declare const abi: [ stateMutability: "nonpayable"; type: "function"; }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, { inputs: [ { diff --git a/packages/world/abi/UniqueEntityModule.sol/UniqueEntityModule.abi.json b/packages/world/abi/UniqueEntityModule.sol/UniqueEntityModule.abi.json index 90b64315e3..dc2f477d69 100644 --- a/packages/world/abi/UniqueEntityModule.sol/UniqueEntityModule.abi.json +++ b/packages/world/abi/UniqueEntityModule.sol/UniqueEntityModule.abi.json @@ -36,6 +36,45 @@ "name": "SchemaLib_StaticTypeAfterDynamicType", "type": "error" }, + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "getName", @@ -74,5 +113,24 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" } ] \ No newline at end of file diff --git a/packages/world/abi/UniqueEntityModule.sol/UniqueEntityModule.abi.json.d.ts b/packages/world/abi/UniqueEntityModule.sol/UniqueEntityModule.abi.json.d.ts index 7965ef95be..8f66fa3fb9 100644 --- a/packages/world/abi/UniqueEntityModule.sol/UniqueEntityModule.abi.json.d.ts +++ b/packages/world/abi/UniqueEntityModule.sol/UniqueEntityModule.abi.json.d.ts @@ -36,6 +36,45 @@ declare const abi: [ name: "SchemaLib_StaticTypeAfterDynamicType"; type: "error"; }, + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: "sender"; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: "value"; + type: "uint256"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, { inputs: []; name: "getName"; @@ -74,6 +113,25 @@ declare const abi: [ outputs: []; stateMutability: "nonpayable"; type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; } ]; export default abi; diff --git a/packages/world/abi/UniqueEntitySystem.sol/UniqueEntitySystem.abi.json b/packages/world/abi/UniqueEntitySystem.sol/UniqueEntitySystem.abi.json index ea11319630..a93a479904 100644 --- a/packages/world/abi/UniqueEntitySystem.sol/UniqueEntitySystem.abi.json +++ b/packages/world/abi/UniqueEntitySystem.sol/UniqueEntitySystem.abi.json @@ -63,6 +63,45 @@ "name": "StoreCore_InvalidDataLength", "type": "error" }, + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "getUniqueEntity", @@ -75,5 +114,24 @@ ], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" } ] \ No newline at end of file diff --git a/packages/world/abi/UniqueEntitySystem.sol/UniqueEntitySystem.abi.json.d.ts b/packages/world/abi/UniqueEntitySystem.sol/UniqueEntitySystem.abi.json.d.ts index 3235234c15..af0dc9f756 100644 --- a/packages/world/abi/UniqueEntitySystem.sol/UniqueEntitySystem.abi.json.d.ts +++ b/packages/world/abi/UniqueEntitySystem.sol/UniqueEntitySystem.abi.json.d.ts @@ -63,6 +63,45 @@ declare const abi: [ name: "StoreCore_InvalidDataLength"; type: "error"; }, + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: "sender"; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: "value"; + type: "uint256"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, { inputs: []; name: "getUniqueEntity"; @@ -75,6 +114,25 @@ declare const abi: [ ]; stateMutability: "nonpayable"; type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; } ]; export default abi; diff --git a/packages/world/abi/World.sol/World.abi.json b/packages/world/abi/World.sol/World.abi.json index f4e0e2d4c7..d25fe2f864 100644 --- a/packages/world/abi/World.sol/World.abi.json +++ b/packages/world/abi/World.sol/World.abi.json @@ -74,6 +74,22 @@ "name": "InsufficientBalance", "type": "error" }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "InterfaceNotSupported", + "type": "error" + }, { "inputs": [ { diff --git a/packages/world/abi/World.sol/World.abi.json.d.ts b/packages/world/abi/World.sol/World.abi.json.d.ts index 865d2dd465..27b4d3902e 100644 --- a/packages/world/abi/World.sol/World.abi.json.d.ts +++ b/packages/world/abi/World.sol/World.abi.json.d.ts @@ -74,6 +74,22 @@ declare const abi: [ name: "InsufficientBalance"; type: "error"; }, + { + inputs: [ + { + internalType: "address"; + name: "contractAddress"; + type: "address"; + }, + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "InterfaceNotSupported"; + type: "error"; + }, { inputs: [ { diff --git a/packages/world/abi/WorldContext.sol/WorldContextConsumer.abi.json b/packages/world/abi/WorldContext.sol/WorldContextConsumer.abi.json index 0637a088a0..6dedac7faa 100644 --- a/packages/world/abi/WorldContext.sol/WorldContextConsumer.abi.json +++ b/packages/world/abi/WorldContext.sol/WorldContextConsumer.abi.json @@ -1 +1,60 @@ -[] \ No newline at end of file +[ + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/world/abi/WorldContext.sol/WorldContextConsumer.abi.json.d.ts b/packages/world/abi/WorldContext.sol/WorldContextConsumer.abi.json.d.ts new file mode 100644 index 0000000000..7ec709a682 --- /dev/null +++ b/packages/world/abi/WorldContext.sol/WorldContextConsumer.abi.json.d.ts @@ -0,0 +1,61 @@ +declare const abi: [ + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: "sender"; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: "value"; + type: "uint256"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; + } +]; +export default abi; diff --git a/packages/world/abi/WorldRegistrationSystem.sol/WorldRegistrationSystem.abi.json b/packages/world/abi/WorldRegistrationSystem.sol/WorldRegistrationSystem.abi.json index 22d93fb963..7db7f553cb 100644 --- a/packages/world/abi/WorldRegistrationSystem.sol/WorldRegistrationSystem.abi.json +++ b/packages/world/abi/WorldRegistrationSystem.sol/WorldRegistrationSystem.abi.json @@ -69,6 +69,22 @@ "name": "InsufficientBalance", "type": "error" }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "InterfaceNotSupported", + "type": "error" + }, { "inputs": [ { @@ -193,6 +209,45 @@ "name": "SystemExists", "type": "error" }, + { + "inputs": [], + "name": "_msgSender", + "outputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_msgValue", + "outputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "_world", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -333,6 +388,25 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [ { diff --git a/packages/world/abi/WorldRegistrationSystem.sol/WorldRegistrationSystem.abi.json.d.ts b/packages/world/abi/WorldRegistrationSystem.sol/WorldRegistrationSystem.abi.json.d.ts index 89e7d11d89..ebcd66f75e 100644 --- a/packages/world/abi/WorldRegistrationSystem.sol/WorldRegistrationSystem.abi.json.d.ts +++ b/packages/world/abi/WorldRegistrationSystem.sol/WorldRegistrationSystem.abi.json.d.ts @@ -69,6 +69,22 @@ declare const abi: [ name: "InsufficientBalance"; type: "error"; }, + { + inputs: [ + { + internalType: "address"; + name: "contractAddress"; + type: "address"; + }, + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "InterfaceNotSupported"; + type: "error"; + }, { inputs: [ { @@ -193,6 +209,45 @@ declare const abi: [ name: "SystemExists"; type: "error"; }, + { + inputs: []; + name: "_msgSender"; + outputs: [ + { + internalType: "address"; + name: "sender"; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, + { + inputs: []; + name: "_msgValue"; + outputs: [ + { + internalType: "uint256"; + name: "value"; + type: "uint256"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, + { + inputs: []; + name: "_world"; + outputs: [ + { + internalType: "address"; + name: ""; + type: "address"; + } + ]; + stateMutability: "view"; + type: "function"; + }, { inputs: [ { @@ -333,6 +388,25 @@ declare const abi: [ stateMutability: "nonpayable"; type: "function"; }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; + }, { inputs: [ { diff --git a/packages/world/abi/interfaces/IERC165.sol/IERC165.abi.json b/packages/world/abi/interfaces/IERC165.sol/IERC165.abi.json new file mode 100644 index 0000000000..f9e19986d2 --- /dev/null +++ b/packages/world/abi/interfaces/IERC165.sol/IERC165.abi.json @@ -0,0 +1,21 @@ +[ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceID", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/world/abi/interfaces/IERC165.sol/IERC165.abi.json.d.ts b/packages/world/abi/interfaces/IERC165.sol/IERC165.abi.json.d.ts new file mode 100644 index 0000000000..41da21a6f2 --- /dev/null +++ b/packages/world/abi/interfaces/IERC165.sol/IERC165.abi.json.d.ts @@ -0,0 +1,22 @@ +declare const abi: [ + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceID"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "view"; + type: "function"; + } +]; +export default abi; diff --git a/packages/world/abi/IStore.sol/IStoreHook.abi.json b/packages/world/abi/src/IStoreHook.sol/IStoreHook.abi.json similarity index 90% rename from packages/world/abi/IStore.sol/IStoreHook.abi.json rename to packages/world/abi/src/IStoreHook.sol/IStoreHook.abi.json index 316af6422c..b35f6251af 100644 --- a/packages/world/abi/IStore.sol/IStoreHook.abi.json +++ b/packages/world/abi/src/IStoreHook.sol/IStoreHook.abi.json @@ -166,5 +166,24 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceID", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" } ] \ No newline at end of file diff --git a/packages/world/abi/IStore.sol/IStoreHook.abi.json.d.ts b/packages/world/abi/src/IStoreHook.sol/IStoreHook.abi.json.d.ts similarity index 90% rename from packages/world/abi/IStore.sol/IStoreHook.abi.json.d.ts rename to packages/world/abi/src/IStoreHook.sol/IStoreHook.abi.json.d.ts index 2e39c851eb..ae36ae3637 100644 --- a/packages/world/abi/IStore.sol/IStoreHook.abi.json.d.ts +++ b/packages/world/abi/src/IStoreHook.sol/IStoreHook.abi.json.d.ts @@ -166,6 +166,25 @@ declare const abi: [ outputs: []; stateMutability: "nonpayable"; type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceID"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "view"; + type: "function"; } ]; export default abi; diff --git a/packages/world/abi/src/StoreHook.sol/StoreHook.abi.json b/packages/world/abi/src/StoreHook.sol/StoreHook.abi.json new file mode 100644 index 0000000000..3d219e7777 --- /dev/null +++ b/packages/world/abi/src/StoreHook.sol/StoreHook.abi.json @@ -0,0 +1,189 @@ +[ + { + "inputs": [ + { + "internalType": "bytes32", + "name": "table", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "internalType": "Schema", + "name": "valueSchema", + "type": "bytes32" + } + ], + "name": "onAfterDeleteRecord", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "table", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "internalType": "uint8", + "name": "schemaIndex", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "Schema", + "name": "valueSchema", + "type": "bytes32" + } + ], + "name": "onAfterSetField", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "table", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "Schema", + "name": "valueSchema", + "type": "bytes32" + } + ], + "name": "onAfterSetRecord", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "table", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "internalType": "Schema", + "name": "valueSchema", + "type": "bytes32" + } + ], + "name": "onBeforeDeleteRecord", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "table", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "internalType": "uint8", + "name": "schemaIndex", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "Schema", + "name": "valueSchema", + "type": "bytes32" + } + ], + "name": "onBeforeSetField", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "table", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "Schema", + "name": "valueSchema", + "type": "bytes32" + } + ], + "name": "onBeforeSetRecord", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/world/abi/src/StoreHook.sol/StoreHook.abi.json.d.ts b/packages/world/abi/src/StoreHook.sol/StoreHook.abi.json.d.ts new file mode 100644 index 0000000000..494a46cc19 --- /dev/null +++ b/packages/world/abi/src/StoreHook.sol/StoreHook.abi.json.d.ts @@ -0,0 +1,190 @@ +declare const abi: [ + { + inputs: [ + { + internalType: "bytes32"; + name: "table"; + type: "bytes32"; + }, + { + internalType: "bytes32[]"; + name: "key"; + type: "bytes32[]"; + }, + { + internalType: "Schema"; + name: "valueSchema"; + type: "bytes32"; + } + ]; + name: "onAfterDeleteRecord"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes32"; + name: "table"; + type: "bytes32"; + }, + { + internalType: "bytes32[]"; + name: "key"; + type: "bytes32[]"; + }, + { + internalType: "uint8"; + name: "schemaIndex"; + type: "uint8"; + }, + { + internalType: "bytes"; + name: "data"; + type: "bytes"; + }, + { + internalType: "Schema"; + name: "valueSchema"; + type: "bytes32"; + } + ]; + name: "onAfterSetField"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes32"; + name: "table"; + type: "bytes32"; + }, + { + internalType: "bytes32[]"; + name: "key"; + type: "bytes32[]"; + }, + { + internalType: "bytes"; + name: "data"; + type: "bytes"; + }, + { + internalType: "Schema"; + name: "valueSchema"; + type: "bytes32"; + } + ]; + name: "onAfterSetRecord"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes32"; + name: "table"; + type: "bytes32"; + }, + { + internalType: "bytes32[]"; + name: "key"; + type: "bytes32[]"; + }, + { + internalType: "Schema"; + name: "valueSchema"; + type: "bytes32"; + } + ]; + name: "onBeforeDeleteRecord"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes32"; + name: "table"; + type: "bytes32"; + }, + { + internalType: "bytes32[]"; + name: "key"; + type: "bytes32[]"; + }, + { + internalType: "uint8"; + name: "schemaIndex"; + type: "uint8"; + }, + { + internalType: "bytes"; + name: "data"; + type: "bytes"; + }, + { + internalType: "Schema"; + name: "valueSchema"; + type: "bytes32"; + } + ]; + name: "onBeforeSetField"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes32"; + name: "table"; + type: "bytes32"; + }, + { + internalType: "bytes32[]"; + name: "key"; + type: "bytes32[]"; + }, + { + internalType: "bytes"; + name: "data"; + type: "bytes"; + }, + { + internalType: "Schema"; + name: "valueSchema"; + type: "bytes32"; + } + ]; + name: "onBeforeSetRecord"; + outputs: []; + stateMutability: "nonpayable"; + type: "function"; + }, + { + inputs: [ + { + internalType: "bytes4"; + name: "interfaceId"; + type: "bytes4"; + } + ]; + name: "supportsInterface"; + outputs: [ + { + internalType: "bool"; + name: ""; + type: "bool"; + } + ]; + stateMutability: "pure"; + type: "function"; + } +]; +export default abi; diff --git a/packages/world/gas-report.json b/packages/world/gas-report.json index 980f15a975..11e7d508fa 100644 --- a/packages/world/gas-report.json +++ b/packages/world/gas-report.json @@ -39,67 +39,67 @@ "file": "test/KeysInTableModule.t.sol", "test": "testInstallComposite", "name": "install keys in table module", - "gasUsed": 1433865 + "gasUsed": 1438155 }, { "file": "test/KeysInTableModule.t.sol", "test": "testInstallGas", "name": "install keys in table module", - "gasUsed": 1433865 + "gasUsed": 1438155 }, { "file": "test/KeysInTableModule.t.sol", "test": "testInstallGas", "name": "set a record on a table with keysInTableModule installed", - "gasUsed": 182589 + "gasUsed": 180111 }, { "file": "test/KeysInTableModule.t.sol", "test": "testInstallSingleton", "name": "install keys in table module", - "gasUsed": 1433865 + "gasUsed": 1438155 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookCompositeGas", "name": "install keys in table module", - "gasUsed": 1433865 + "gasUsed": 1438155 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookCompositeGas", "name": "change a composite record on a table with keysInTableModule installed", - "gasUsed": 26174 + "gasUsed": 26196 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookCompositeGas", "name": "delete a composite record on a table with keysInTableModule installed", - "gasUsed": 251091 + "gasUsed": 251113 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookGas", "name": "install keys in table module", - "gasUsed": 1433865 + "gasUsed": 1438155 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookGas", "name": "change a record on a table with keysInTableModule installed", - "gasUsed": 24894 + "gasUsed": 24916 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookGas", "name": "delete a record on a table with keysInTableModule installed", - "gasUsed": 129380 + "gasUsed": 129402 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testGetKeysWithValueGas", "name": "install keys with value module", - "gasUsed": 677067 + "gasUsed": 681318 }, { "file": "test/KeysWithValueModule.t.sol", @@ -117,49 +117,49 @@ "file": "test/KeysWithValueModule.t.sol", "test": "testInstall", "name": "install keys with value module", - "gasUsed": 677067 + "gasUsed": 681318 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testInstall", "name": "set a record on a table with KeysWithValueModule installed", - "gasUsed": 151906 + "gasUsed": 149428 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetAndDeleteRecordHook", "name": "install keys with value module", - "gasUsed": 677067 + "gasUsed": 681318 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetAndDeleteRecordHook", "name": "change a record on a table with KeysWithValueModule installed", - "gasUsed": 118369 + "gasUsed": 118391 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetAndDeleteRecordHook", "name": "delete a record on a table with KeysWithValueModule installed", - "gasUsed": 43982 + "gasUsed": 44004 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetField", "name": "install keys with value module", - "gasUsed": 677067 + "gasUsed": 681318 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetField", "name": "set a field on a table with KeysWithValueModule installed", - "gasUsed": 158593 + "gasUsed": 156137 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetField", "name": "change a field on a table with KeysWithValueModule installed", - "gasUsed": 120851 + "gasUsed": 120895 }, { "file": "test/query.t.sol", @@ -231,67 +231,67 @@ "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromCallboundDelegation", "name": "register a callbound delegation", - "gasUsed": 122630 + "gasUsed": 127108 }, { "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromCallboundDelegation", "name": "call a system via a callbound delegation", - "gasUsed": 44360 + "gasUsed": 44406 }, { "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromTimeboundDelegation", "name": "register a timebound delegation", - "gasUsed": 116879 + "gasUsed": 121379 }, { "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromTimeboundDelegation", "name": "call a system via a timebound delegation", - "gasUsed": 35065 + "gasUsed": 35111 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstall", "name": "install unique entity module", - "gasUsed": 727195 + "gasUsed": 731650 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstall", "name": "get a unique entity nonce (non-root module)", - "gasUsed": 65315 + "gasUsed": 62871 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstallRoot", "name": "installRoot unique entity module", - "gasUsed": 712496 + "gasUsed": 716849 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstallRoot", "name": "get a unique entity nonce (root module)", - "gasUsed": 65315 + "gasUsed": 62871 }, { "file": "test/World.t.sol", "test": "testCall", "name": "call a system via the World", - "gasUsed": 17637 + "gasUsed": 17615 }, { "file": "test/World.t.sol", "test": "testCallFromUnlimitedDelegation", "name": "register an unlimited delegation", - "gasUsed": 55612 + "gasUsed": 55635 }, { "file": "test/World.t.sol", "test": "testCallFromUnlimitedDelegation", "name": "call a system via an unlimited delegation", - "gasUsed": 18011 + "gasUsed": 17989 }, { "file": "test/World.t.sol", @@ -309,37 +309,37 @@ "file": "test/World.t.sol", "test": "testRegisterFallbackSystem", "name": "Register a fallback system", - "gasUsed": 70563 + "gasUsed": 70603 }, { "file": "test/World.t.sol", "test": "testRegisterFallbackSystem", "name": "Register a root fallback system", - "gasUsed": 63803 + "gasUsed": 63918 }, { "file": "test/World.t.sol", "test": "testRegisterFunctionSelector", "name": "Register a function selector", - "gasUsed": 91157 + "gasUsed": 91197 }, { "file": "test/World.t.sol", "test": "testRegisterNamespace", "name": "Register a new namespace", - "gasUsed": 140240 + "gasUsed": 140243 }, { "file": "test/World.t.sol", "test": "testRegisterRootFunctionSelector", "name": "Register a root function selector", - "gasUsed": 85721 + "gasUsed": 85836 }, { "file": "test/World.t.sol", "test": "testRegisterTable", "name": "Register a new table in the namespace", - "gasUsed": 650471 + "gasUsed": 650451 }, { "file": "test/World.t.sol", diff --git a/packages/world/src/DelegationControl.sol b/packages/world/src/DelegationControl.sol index 29c432e2ad..905a7bedb2 100644 --- a/packages/world/src/DelegationControl.sol +++ b/packages/world/src/DelegationControl.sol @@ -2,6 +2,17 @@ pragma solidity >=0.8.0; import { WorldContextConsumer } from "./WorldContext.sol"; -import { IDelegationControl } from "./interfaces/IDelegationControl.sol"; +import { IDelegationControl, DELEGATION_CONTROL_INTERFACE_ID } from "./interfaces/IDelegationControl.sol"; +import { WORLD_CONTEXT_CONSUMER_INTERFACE_ID } from "./interfaces/IWorldContextConsumer.sol"; +import { IERC165, ERC165_INTERFACE_ID } from "./interfaces/IERC165.sol"; -abstract contract DelegationControl is WorldContextConsumer, IDelegationControl {} +abstract contract DelegationControl is WorldContextConsumer, IDelegationControl { + function supportsInterface( + bytes4 interfaceId + ) public pure virtual override(IERC165, WorldContextConsumer) returns (bool) { + return + interfaceId == DELEGATION_CONTROL_INTERFACE_ID || + interfaceId == WORLD_CONTEXT_CONSUMER_INTERFACE_ID || + interfaceId == ERC165_INTERFACE_ID; + } +} diff --git a/packages/world/src/Module.sol b/packages/world/src/Module.sol new file mode 100644 index 0000000000..5d8663129e --- /dev/null +++ b/packages/world/src/Module.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { WorldContextConsumer } from "./WorldContext.sol"; +import { IModule, MODULE_INTERFACE_ID } from "./interfaces/IModule.sol"; +import { IERC165, ERC165_INTERFACE_ID } from "./interfaces/IERC165.sol"; + +abstract contract Module is IModule, WorldContextConsumer { + // ERC-165 supportsInterface (see https://eips.ethereum.org/EIPS/eip-165) + function supportsInterface( + bytes4 interfaceId + ) public pure virtual override(IERC165, WorldContextConsumer) returns (bool) { + return interfaceId == MODULE_INTERFACE_ID || interfaceId == ERC165_INTERFACE_ID; + } +} diff --git a/packages/world/src/SystemHook.sol b/packages/world/src/SystemHook.sol index 60b9408392..f663b9b8f7 100644 --- a/packages/world/src/SystemHook.sol +++ b/packages/world/src/SystemHook.sol @@ -2,7 +2,8 @@ pragma solidity >=0.8.0; import { Hook, HookLib } from "@latticexyz/store/src/Hook.sol"; -import { ISystemHook } from "./interfaces/ISystemHook.sol"; +import { ISystemHook, SYSTEM_HOOK_INTERFACE_ID } from "./interfaces/ISystemHook.sol"; +import { ERC165_INTERFACE_ID } from "./interfaces/IERC165.sol"; enum SystemHookType { BEFORE_CALL_SYSTEM, @@ -27,3 +28,10 @@ library SystemHookLib { return HookLib.encode(address(systemHook), enabledHooksBitmap); } } + +abstract contract SystemHook is ISystemHook { + // ERC-165 supportsInterface (see https://eips.ethereum.org/EIPS/eip-165) + function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { + return interfaceId == SYSTEM_HOOK_INTERFACE_ID || interfaceId == ERC165_INTERFACE_ID; + } +} diff --git a/packages/world/src/World.sol b/packages/world/src/World.sol index 75839ca583..8d5abb4b99 100644 --- a/packages/world/src/World.sol +++ b/packages/world/src/World.sol @@ -15,13 +15,13 @@ import { SystemCall } from "./SystemCall.sol"; import { WorldContextProvider } from "./WorldContext.sol"; import { revertWithBytes } from "./revertWithBytes.sol"; import { Delegation } from "./Delegation.sol"; +import { requireInterface } from "./requireInterface.sol"; import { NamespaceOwner } from "./tables/NamespaceOwner.sol"; import { InstalledModules } from "./tables/InstalledModules.sol"; import { Delegations } from "./tables/Delegations.sol"; -import { ISystemHook } from "./interfaces/ISystemHook.sol"; -import { IModule } from "./interfaces/IModule.sol"; +import { IModule, MODULE_INTERFACE_ID } from "./interfaces/IModule.sol"; import { IWorldKernel } from "./interfaces/IWorldKernel.sol"; import { IDelegationControl } from "./interfaces/IDelegationControl.sol"; @@ -51,6 +51,9 @@ contract World is StoreRead, IStoreData, IWorldKernel { function installRootModule(IModule module, bytes memory args) public { AccessControl.requireOwner(ROOT_NAMESPACE, msg.sender); + // Require the provided address to implement the IModule interface + requireInterface(address(module), MODULE_INTERFACE_ID); + WorldContextProvider.delegatecallWithContextOrRevert({ msgSender: msg.sender, msgValue: 0, diff --git a/packages/world/src/WorldContext.sol b/packages/world/src/WorldContext.sol index 06c5a22d07..167bb88ee8 100644 --- a/packages/world/src/WorldContext.sol +++ b/packages/world/src/WorldContext.sol @@ -3,15 +3,17 @@ pragma solidity >=0.8.0; import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; import { revertWithBytes } from "./revertWithBytes.sol"; +import { ERC165_INTERFACE_ID } from "./interfaces/IERC165.sol"; +import { IWorldContextConsumer, WORLD_CONTEXT_CONSUMER_INTERFACE_ID } from "./interfaces/IWorldContextConsumer.sol"; // The context size is 20 bytes for msg.sender, and 32 bytes for msg.value uint256 constant CONTEXT_BYTES = 20 + 32; // Similar to https://eips.ethereum.org/EIPS/eip-2771, but any contract can be the trusted forwarder. // This should only be used for contracts without own storage, like Systems. -abstract contract WorldContextConsumer { +abstract contract WorldContextConsumer is IWorldContextConsumer { // Extract the trusted msg.sender value appended to the calldata - function _msgSender() internal view returns (address sender) { + function _msgSender() public view returns (address sender) { assembly { // Load 32 bytes from calldata at position calldatasize() - context size, // then shift left 96 bits (to right-align the address) @@ -22,16 +24,21 @@ abstract contract WorldContextConsumer { } // Extract the trusted msg.value value appended to the calldata - function _msgValue() internal pure returns (uint256 value) { + function _msgValue() public pure returns (uint256 value) { assembly { // Load 32 bytes from calldata at position calldatasize() - 32 bytes, value := calldataload(sub(calldatasize(), 32)) } } - function _world() internal view returns (address) { + function _world() public view returns (address) { return StoreSwitch.getStoreAddress(); } + + // ERC-165 supportsInterface (see https://eips.ethereum.org/EIPS/eip-165) + function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) { + return interfaceId == WORLD_CONTEXT_CONSUMER_INTERFACE_ID || interfaceId == ERC165_INTERFACE_ID; + } } /** diff --git a/packages/world/src/interfaces/IDelegationControl.sol b/packages/world/src/interfaces/IDelegationControl.sol index 468994f05e..2da8324ec1 100644 --- a/packages/world/src/interfaces/IDelegationControl.sol +++ b/packages/world/src/interfaces/IDelegationControl.sol @@ -1,6 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -interface IDelegationControl { +import { IWorldContextConsumer, WORLD_CONTEXT_CONSUMER_INTERFACE_ID } from "./IWorldContextConsumer.sol"; + +// ERC-165 Interface ID (see https://eips.ethereum.org/EIPS/eip-165) +bytes4 constant DELEGATION_CONTROL_INTERFACE_ID = IDelegationControl.verify.selector ^ + WORLD_CONTEXT_CONSUMER_INTERFACE_ID; + +interface IDelegationControl is IWorldContextConsumer { function verify(address delegator, bytes32 systemId, bytes calldata funcSelectorAndArgs) external returns (bool); } diff --git a/packages/world/src/interfaces/IERC165.sol b/packages/world/src/interfaces/IERC165.sol new file mode 100644 index 0000000000..4151b0a405 --- /dev/null +++ b/packages/world/src/interfaces/IERC165.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +bytes4 constant ERC165_INTERFACE_ID = IERC165.supportsInterface.selector; + +// See https://eips.ethereum.org/EIPS/eip-165 +interface IERC165 { + /// @notice Query if a contract implements an interface + /// @param interfaceID The interface identifier, as specified in ERC-165 + /// @dev Interface identification is specified in ERC-165. This function + /// uses less than 30,000 gas. + /// @return `true` if the contract implements `interfaceID` and + /// `interfaceID` is not 0xffffffff, `false` otherwise + function supportsInterface(bytes4 interfaceID) external view returns (bool); +} diff --git a/packages/world/src/interfaces/IModule.sol b/packages/world/src/interfaces/IModule.sol index 990fbcde48..a4eb728608 100644 --- a/packages/world/src/interfaces/IModule.sol +++ b/packages/world/src/interfaces/IModule.sol @@ -1,7 +1,15 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -interface IModule { +import { IERC165, ERC165_INTERFACE_ID } from "./IERC165.sol"; + +// ERC-165 Interface ID (see https://eips.ethereum.org/EIPS/eip-165) +bytes4 constant MODULE_INTERFACE_ID = IModule.getName.selector ^ + IModule.installRoot.selector ^ + IModule.install.selector ^ + ERC165_INTERFACE_ID; + +interface IModule is IERC165 { error RequiredModuleNotFound(string resourceSelector); error RootInstallModeNotSupported(); error NonRootInstallNotSupported(); diff --git a/packages/world/src/interfaces/ISystemHook.sol b/packages/world/src/interfaces/ISystemHook.sol index 3810f571a6..cb1526bcf2 100644 --- a/packages/world/src/interfaces/ISystemHook.sol +++ b/packages/world/src/interfaces/ISystemHook.sol @@ -1,7 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -interface ISystemHook { +import { IERC165, ERC165_INTERFACE_ID } from "./IERC165.sol"; + +// ERC-165 Interface ID (see https://eips.ethereum.org/EIPS/eip-165) +bytes4 constant SYSTEM_HOOK_INTERFACE_ID = ISystemHook.onBeforeCallSystem.selector ^ + ISystemHook.onAfterCallSystem.selector ^ + ERC165_INTERFACE_ID; + +interface ISystemHook is IERC165 { function onBeforeCallSystem(address msgSender, bytes32 resourceSelector, bytes memory funcSelectorAndArgs) external; function onAfterCallSystem(address msgSender, bytes32 resourceSelector, bytes memory funcSelectorAndArgs) external; diff --git a/packages/world/src/interfaces/IWorldContextConsumer.sol b/packages/world/src/interfaces/IWorldContextConsumer.sol new file mode 100644 index 0000000000..496f8c57b9 --- /dev/null +++ b/packages/world/src/interfaces/IWorldContextConsumer.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { IERC165, ERC165_INTERFACE_ID } from "./IERC165.sol"; + +// ERC-165 Interface ID (see https://eips.ethereum.org/EIPS/eip-165) +bytes4 constant WORLD_CONTEXT_CONSUMER_INTERFACE_ID = IWorldContextConsumer._msgSender.selector ^ + IWorldContextConsumer._msgValue.selector ^ + IWorldContextConsumer._world.selector ^ + ERC165_INTERFACE_ID; + +interface IWorldContextConsumer is IERC165 { + function _msgSender() external view returns (address); + + function _msgValue() external view returns (uint256); + + function _world() external view returns (address); +} diff --git a/packages/world/src/interfaces/IWorldErrors.sol b/packages/world/src/interfaces/IWorldErrors.sol index 918f1c548c..3618ceb591 100644 --- a/packages/world/src/interfaces/IWorldErrors.sol +++ b/packages/world/src/interfaces/IWorldErrors.sol @@ -12,4 +12,5 @@ interface IWorldErrors { error ModuleAlreadyInstalled(string module); error DelegationNotFound(address delegator, address delegatee); error InsufficientBalance(uint256 balance, uint256 amount); + error InterfaceNotSupported(address contractAddress, bytes4 interfaceId); } diff --git a/packages/world/src/modules/core/CoreModule.sol b/packages/world/src/modules/core/CoreModule.sol index 2a2e44dc7b..ea31e359e0 100644 --- a/packages/world/src/modules/core/CoreModule.sol +++ b/packages/world/src/modules/core/CoreModule.sol @@ -3,11 +3,10 @@ pragma solidity >=0.8.0; import { WorldContextProvider } from "../../WorldContext.sol"; import { ROOT_NAMESPACE } from "../../constants.sol"; -import { WorldContextConsumer } from "../../WorldContext.sol"; import { Resource } from "../../Types.sol"; +import { Module } from "../../Module.sol"; import { IBaseWorld } from "../../interfaces/IBaseWorld.sol"; -import { IModule } from "../../interfaces/IModule.sol"; import { IStoreEphemeral } from "@latticexyz/store/src/IStore.sol"; import { ResourceSelector } from "../../ResourceSelector.sol"; @@ -40,7 +39,7 @@ import { WorldRegistrationSystem } from "./implementations/WorldRegistrationSyst * This module only supports `installRoot` (via `World.registerRootSystem`), * because it needs to install root tables, systems and function selectors. */ -contract CoreModule is IModule, WorldContextConsumer { +contract CoreModule is Module { // Since the CoreSystem only exists once per World and writes to // known tables, we can deploy it once and register it in multiple Worlds. address immutable coreSystem = address(new CoreSystem()); diff --git a/packages/world/src/modules/core/implementations/ModuleInstallationSystem.sol b/packages/world/src/modules/core/implementations/ModuleInstallationSystem.sol index 7346c304a7..ebd21ed856 100644 --- a/packages/world/src/modules/core/implementations/ModuleInstallationSystem.sol +++ b/packages/world/src/modules/core/implementations/ModuleInstallationSystem.sol @@ -1,12 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import { IModule } from "../../../interfaces/IModule.sol"; +import { IModule, MODULE_INTERFACE_ID } from "../../../interfaces/IModule.sol"; import { System } from "../../../System.sol"; import { AccessControl } from "../../../AccessControl.sol"; import { WorldContextProvider } from "../../../WorldContext.sol"; import { ResourceAccess } from "../../../tables/ResourceAccess.sol"; import { InstalledModules } from "../../../tables/InstalledModules.sol"; +import { requireInterface } from "../../../requireInterface.sol"; /** * Installation of (non-root) modules in the World. @@ -16,6 +17,9 @@ contract ModuleInstallationSystem is System { * Install the given module at the given namespace in the World. */ function installModule(IModule module, bytes memory args) public { + // Require the provided address to implement the IModule interface + requireInterface(address(module), MODULE_INTERFACE_ID); + WorldContextProvider.callWithContextOrRevert({ msgSender: _msgSender(), msgValue: 0, diff --git a/packages/world/src/modules/core/implementations/StoreRegistrationSystem.sol b/packages/world/src/modules/core/implementations/StoreRegistrationSystem.sol index bf6a081237..a4ac826eaf 100644 --- a/packages/world/src/modules/core/implementations/StoreRegistrationSystem.sol +++ b/packages/world/src/modules/core/implementations/StoreRegistrationSystem.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import { IStoreHook } from "@latticexyz/store/src/IStore.sol"; +import { IStoreHook, STORE_HOOK_INTERFACE_ID } from "@latticexyz/store/src/IStoreHook.sol"; import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; import { Schema } from "@latticexyz/store/src/Schema.sol"; @@ -10,10 +10,10 @@ import { ResourceSelector } from "../../../ResourceSelector.sol"; import { Resource } from "../../../Types.sol"; import { ROOT_NAMESPACE, ROOT_NAME } from "../../../constants.sol"; import { AccessControl } from "../../../AccessControl.sol"; +import { requireInterface } from "../../../requireInterface.sol"; import { WorldContextProvider } from "../../../WorldContext.sol"; import { NamespaceOwner } from "../../../tables/NamespaceOwner.sol"; import { ResourceAccess } from "../../../tables/ResourceAccess.sol"; -import { ISystemHook } from "../../../interfaces/ISystemHook.sol"; import { IWorldErrors } from "../../../interfaces/IWorldErrors.sol"; import { ResourceType } from "../tables/ResourceType.sol"; @@ -79,6 +79,9 @@ contract StoreRegistrationSystem is System, IWorldErrors { * Requires the caller to own the namespace. */ function registerStoreHook(bytes32 tableId, IStoreHook hookAddress, uint8 enabledHooksBitmap) public virtual { + // Require the hook to implement the store hook interface + requireInterface(address(hookAddress), STORE_HOOK_INTERFACE_ID); + // Require caller to own the namespace AccessControl.requireOwner(tableId, _msgSender()); diff --git a/packages/world/src/modules/core/implementations/WorldRegistrationSystem.sol b/packages/world/src/modules/core/implementations/WorldRegistrationSystem.sol index c64337b454..2d018ae0fb 100644 --- a/packages/world/src/modules/core/implementations/WorldRegistrationSystem.sol +++ b/packages/world/src/modules/core/implementations/WorldRegistrationSystem.sol @@ -4,18 +4,20 @@ pragma solidity >=0.8.0; import { Hook, HookLib } from "@latticexyz/store/src/Hook.sol"; import { System } from "../../../System.sol"; -import { WorldContextConsumer } from "../../../WorldContext.sol"; +import { WorldContextConsumer, WORLD_CONTEXT_CONSUMER_INTERFACE_ID } from "../../../WorldContext.sol"; import { ResourceSelector } from "../../../ResourceSelector.sol"; import { Resource } from "../../../Types.sol"; import { SystemCall } from "../../../SystemCall.sol"; import { SystemHookLib } from "../../../SystemHook.sol"; import { ROOT_NAMESPACE, ROOT_NAME, UNLIMITED_DELEGATION } from "../../../constants.sol"; import { AccessControl } from "../../../AccessControl.sol"; +import { requireInterface } from "../../../requireInterface.sol"; import { NamespaceOwner } from "../../../tables/NamespaceOwner.sol"; import { ResourceAccess } from "../../../tables/ResourceAccess.sol"; import { Delegations } from "../../../tables/Delegations.sol"; -import { ISystemHook } from "../../../interfaces/ISystemHook.sol"; +import { ISystemHook, SYSTEM_HOOK_INTERFACE_ID } from "../../../interfaces/ISystemHook.sol"; import { IWorldErrors } from "../../../interfaces/IWorldErrors.sol"; +import { IDelegationControl, DELEGATION_CONTROL_INTERFACE_ID } from "../../../interfaces/IDelegationControl.sol"; import { ResourceType } from "../tables/ResourceType.sol"; import { SystemHooks, SystemHooksTableId } from "../tables/SystemHooks.sol"; @@ -57,6 +59,9 @@ contract WorldRegistrationSystem is System, IWorldErrors { ISystemHook hookAddress, uint8 enabledHooksBitmap ) public virtual { + // Require the provided address to implement the ISystemHook interface + requireInterface(address(hookAddress), SYSTEM_HOOK_INTERFACE_ID); + // Require caller to own the namespace AccessControl.requireOwner(resourceSelector, _msgSender()); @@ -85,6 +90,9 @@ contract WorldRegistrationSystem is System, IWorldErrors { * making it possible to upgrade systems. */ function registerSystem(bytes32 resourceSelector, WorldContextConsumer system, bool publicAccess) public virtual { + // Require the provided address to implement the WorldContextConsumer interface + requireInterface(address(system), WORLD_CONTEXT_CONSUMER_INTERFACE_ID); + // Require the name to not be the namespace's root name if (resourceSelector.getName() == ROOT_NAME) revert InvalidSelector(resourceSelector.toString()); @@ -203,8 +211,13 @@ contract WorldRegistrationSystem is System, IWorldErrors { // Store the delegation control contract address Delegations.set({ delegator: _msgSender(), delegatee: delegatee, delegationControlId: delegationControlId }); - // If the delegation is not unlimited, call the delegation control contract's init function + // If the delegation is not unlimited... if (delegationControlId != UNLIMITED_DELEGATION && initFuncSelectorAndArgs.length > 0) { + // Require the delegationControl contract to implement the IDelegationControl interface + (address delegationControl, ) = Systems.get(delegationControlId); + requireInterface(delegationControl, DELEGATION_CONTROL_INTERFACE_ID); + + // Call the delegation control contract's init function SystemCall.call({ caller: _msgSender(), resourceSelector: delegationControlId, diff --git a/packages/world/src/modules/keysintable/KeysInTableHook.sol b/packages/world/src/modules/keysintable/KeysInTableHook.sol index 7d55c25b75..79593852b2 100644 --- a/packages/world/src/modules/keysintable/KeysInTableHook.sol +++ b/packages/world/src/modules/keysintable/KeysInTableHook.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import { IStoreHook } from "@latticexyz/store/src/IStore.sol"; +import { StoreHook } from "@latticexyz/store/src/StoreHook.sol"; import { Schema } from "@latticexyz/store/src/Schema.sol"; import { KeysInTable } from "./tables/KeysInTable.sol"; @@ -10,7 +10,7 @@ import { UsedKeysIndex } from "./tables/UsedKeysIndex.sol"; /** * Note: if a table with composite keys is used, only the first key is indexed */ -contract KeysInTableHook is IStoreHook { +contract KeysInTableHook is StoreHook { function handleSet(bytes32 tableId, bytes32[] memory key) internal { bytes32 keysHash = keccak256(abi.encode(key)); diff --git a/packages/world/src/modules/keysintable/KeysInTableModule.sol b/packages/world/src/modules/keysintable/KeysInTableModule.sol index b01cf1ea49..5c18691c58 100644 --- a/packages/world/src/modules/keysintable/KeysInTableModule.sol +++ b/packages/world/src/modules/keysintable/KeysInTableModule.sol @@ -5,11 +5,10 @@ import { StoreHookLib } from "@latticexyz/store/src/StoreHook.sol"; import { ResourceType } from "../core/tables/ResourceType.sol"; import { Resource } from "../../Types.sol"; +import { Module } from "../../Module.sol"; import { IBaseWorld } from "../../interfaces/IBaseWorld.sol"; -import { IModule } from "../../interfaces/IModule.sol"; -import { WorldContextConsumer } from "../../WorldContext.sol"; import { ResourceSelector } from "../../ResourceSelector.sol"; import { revertWithBytes } from "../../revertWithBytes.sol"; @@ -27,7 +26,7 @@ import { UsedKeysIndex, UsedKeysIndexTableId } from "./tables/UsedKeysIndex.sol" * Note: this module currently only supports `installRoot` (via `World.installRootModule`). * TODO: add support for `install` (via `World.installModule`) by using `callFrom` with the `msgSender()` */ -contract KeysInTableModule is IModule, WorldContextConsumer { +contract KeysInTableModule is Module { using ResourceSelector for bytes32; // The KeysInTableHook is deployed once and infers the target table id diff --git a/packages/world/src/modules/keyswithvalue/KeysWithValueHook.sol b/packages/world/src/modules/keyswithvalue/KeysWithValueHook.sol index da2f6e8940..666b8c3644 100644 --- a/packages/world/src/modules/keyswithvalue/KeysWithValueHook.sol +++ b/packages/world/src/modules/keyswithvalue/KeysWithValueHook.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import { IStoreHook } from "@latticexyz/store/src/IStore.sol"; +import { StoreHook } from "@latticexyz/store/src/StoreHook.sol"; import { Bytes } from "@latticexyz/store/src/Bytes.sol"; import { Schema } from "@latticexyz/store/src/Schema.sol"; import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; @@ -21,7 +21,7 @@ import { getTargetTableSelector } from "../utils/getTargetTableSelector.sol"; * * Note: if a table with composite keys is used, only the first key is indexed */ -contract KeysWithValueHook is IStoreHook { +contract KeysWithValueHook is StoreHook { using ArrayLib for bytes32[]; using ResourceSelector for bytes32; diff --git a/packages/world/src/modules/keyswithvalue/KeysWithValueModule.sol b/packages/world/src/modules/keyswithvalue/KeysWithValueModule.sol index dad35bd968..a2b3c6a388 100644 --- a/packages/world/src/modules/keyswithvalue/KeysWithValueModule.sol +++ b/packages/world/src/modules/keyswithvalue/KeysWithValueModule.sol @@ -3,9 +3,9 @@ pragma solidity >=0.8.0; import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; import { StoreHookLib } from "@latticexyz/store/src/StoreHook.sol"; +import { Module } from "../../Module.sol"; import { IBaseWorld } from "../../interfaces/IBaseWorld.sol"; -import { IModule } from "../../interfaces/IModule.sol"; import { WorldContextConsumer } from "../../WorldContext.sol"; import { ResourceSelector } from "../../ResourceSelector.sol"; @@ -27,7 +27,7 @@ import { getTargetTableSelector } from "../utils/getTargetTableSelector.sol"; * Note: this module currently only supports `installRoot` (via `World.installRootModule`). * TODO: add support for `install` (via `World.installModule`) by using `callFrom` with the `msgSender()` */ -contract KeysWithValueModule is IModule, WorldContextConsumer { +contract KeysWithValueModule is Module { using ResourceSelector for bytes32; // The KeysWithValueHook is deployed once and infers the target table id diff --git a/packages/world/src/modules/std-delegations/StandardDelegationsModule.sol b/packages/world/src/modules/std-delegations/StandardDelegationsModule.sol index 74057574dc..d1ba02718d 100644 --- a/packages/world/src/modules/std-delegations/StandardDelegationsModule.sol +++ b/packages/world/src/modules/std-delegations/StandardDelegationsModule.sol @@ -2,8 +2,8 @@ pragma solidity >=0.8.0; import { IBaseWorld } from "../../interfaces/IBaseWorld.sol"; -import { IModule } from "../../interfaces/IModule.sol"; +import { Module } from "../../Module.sol"; import { WorldContextConsumer } from "../../WorldContext.sol"; import { ResourceSelector } from "../../ResourceSelector.sol"; import { revertWithBytes } from "../../revertWithBytes.sol"; @@ -18,7 +18,7 @@ import { TimeboundDelegations } from "./tables/TimeboundDelegations.sol"; /** * This module registers tables and delegation control systems required for standard delegations */ -contract StandardDelegationsModule is IModule, WorldContextConsumer { +contract StandardDelegationsModule is Module { CallboundDelegationControl private immutable callboundDelegationControl = new CallboundDelegationControl(); TimeboundDelegationControl private immutable timeboundDelegationControl = new TimeboundDelegationControl(); diff --git a/packages/world/src/modules/uniqueentity/UniqueEntityModule.sol b/packages/world/src/modules/uniqueentity/UniqueEntityModule.sol index 18d87c7dfe..f404c4b50a 100644 --- a/packages/world/src/modules/uniqueentity/UniqueEntityModule.sol +++ b/packages/world/src/modules/uniqueentity/UniqueEntityModule.sol @@ -2,8 +2,8 @@ pragma solidity >=0.8.0; import { IBaseWorld } from "../../interfaces/IBaseWorld.sol"; -import { IModule } from "../../interfaces/IModule.sol"; +import { Module } from "../../Module.sol"; import { WorldContextConsumer } from "../../WorldContext.sol"; import { ResourceSelector } from "../../ResourceSelector.sol"; @@ -16,7 +16,7 @@ import { NAMESPACE, MODULE_NAME, SYSTEM_NAME, TABLE_NAME } from "./constants.sol * This module creates a table that stores a nonce, and * a public system that returns an incremented nonce each time. */ -contract UniqueEntityModule is IModule, WorldContextConsumer { +contract UniqueEntityModule is Module { // Since the UniqueEntitySystem only exists once per World and writes to // known tables, we can deploy it once and register it in multiple Worlds. UniqueEntitySystem private immutable uniqueEntitySystem = new UniqueEntitySystem(); diff --git a/packages/world/src/requireInterface.sol b/packages/world/src/requireInterface.sol new file mode 100644 index 0000000000..fd8680f731 --- /dev/null +++ b/packages/world/src/requireInterface.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { IERC165 } from "./interfaces/IERC165.sol"; +import { IWorldErrors } from "./interfaces/IWorldErrors.sol"; + +/** + * Require the given contract to support the given interface by calling the ERC-165 supportsInterface function. + */ +function requireInterface(address contractAddress, bytes4 interfaceId) view { + try IERC165(contractAddress).supportsInterface(interfaceId) returns (bool supported) { + if (!supported) { + revert IWorldErrors.InterfaceNotSupported(contractAddress, interfaceId); + } + } catch { + revert IWorldErrors.InterfaceNotSupported(contractAddress, interfaceId); + } +} diff --git a/packages/world/test/StandardDelegationsModule.t.sol b/packages/world/test/StandardDelegationsModule.t.sol index 60258246c2..9ed9a716a3 100644 --- a/packages/world/test/StandardDelegationsModule.t.sol +++ b/packages/world/test/StandardDelegationsModule.t.sol @@ -7,7 +7,9 @@ import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; import { World } from "../src/World.sol"; import { ResourceSelector } from "../src/ResourceSelector.sol"; import { IBaseWorld } from "../src/interfaces/IBaseWorld.sol"; +import { System } from "../src/System.sol"; import { IWorldErrors } from "../src/interfaces/IWorldErrors.sol"; +import { DELEGATION_CONTROL_INTERFACE_ID } from "../src/interfaces/IDelegationControl.sol"; import { CoreModule } from "../src/modules/core/CoreModule.sol"; import { Systems } from "../src/modules/core/tables/Systems.sol"; import { StandardDelegationsModule } from "../src/modules/std-delegations/StandardDelegationsModule.sol"; @@ -111,4 +113,22 @@ contract StandardDelegationsModuleTest is Test, GasReporter { vm.expectRevert(abi.encodeWithSelector(IWorldErrors.DelegationNotFound.selector, delegator, delegatee)); world.callFrom(delegator, systemResourceSelector, abi.encodeWithSelector(WorldTestSystem.msgSender.selector)); } + + function testRegisterDelegationRevertInterfaceNotSupported() public { + // Register a system that is not a delegation control system + System noDelegationControlSystem = new System(); + bytes32 noDelegationControlId = ResourceSelector.from("namespace", "noDelegation"); + world.registerSystem(noDelegationControlId, noDelegationControlSystem, true); + + // Expect the registration to revert if the system does not implement the delegation control interface + vm.prank(delegator); + vm.expectRevert( + abi.encodeWithSelector( + IWorldErrors.InterfaceNotSupported.selector, + address(noDelegationControlSystem), + DELEGATION_CONTROL_INTERFACE_ID + ) + ); + world.registerDelegation(delegatee, noDelegationControlId, new bytes(1)); + } } diff --git a/packages/world/test/World.t.sol b/packages/world/test/World.t.sol index bfe8ee79c5..0ba525d918 100644 --- a/packages/world/test/World.t.sol +++ b/packages/world/test/World.t.sol @@ -6,7 +6,7 @@ import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; -import { IStoreHook } from "@latticexyz/store/src/IStore.sol"; +import { IStoreHook, STORE_HOOK_INTERFACE_ID } from "@latticexyz/store/src/IStoreHook.sol"; import { StoreCore, StoreCoreInternal } from "@latticexyz/store/src/StoreCore.sol"; import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; import { Schema } from "@latticexyz/store/src/Schema.sol"; @@ -23,8 +23,9 @@ import { System } from "../src/System.sol"; import { ResourceSelector } from "../src/ResourceSelector.sol"; import { ROOT_NAMESPACE, ROOT_NAME, UNLIMITED_DELEGATION } from "../src/constants.sol"; import { Resource } from "../src/Types.sol"; -import { SystemHookLib } from "../src/SystemHook.sol"; -import { WorldContextProvider } from "../src/WorldContext.sol"; +import { WorldContextProvider, WORLD_CONTEXT_CONSUMER_INTERFACE_ID } from "../src/WorldContext.sol"; +import { SystemHookLib, SystemHook } from "../src/SystemHook.sol"; +import { Module, MODULE_INTERFACE_ID } from "../src/Module.sol"; import { NamespaceOwner, NamespaceOwnerTableId } from "../src/tables/NamespaceOwner.sol"; import { ResourceAccess } from "../src/tables/ResourceAccess.sol"; @@ -36,7 +37,7 @@ import { ResourceType } from "../src/modules/core/tables/ResourceType.sol"; import { IBaseWorld } from "../src/interfaces/IBaseWorld.sol"; import { IWorldErrors } from "../src/interfaces/IWorldErrors.sol"; -import { ISystemHook } from "../src/interfaces/ISystemHook.sol"; +import { ISystemHook, SYSTEM_HOOK_INTERFACE_ID } from "../src/interfaces/ISystemHook.sol"; import { Bool } from "./tables/Bool.sol"; import { AddressArray } from "./tables/AddressArray.sol"; @@ -114,7 +115,7 @@ contract PayableFallbackSystem is System { fallback() external payable {} } -contract EchoSystemHook is ISystemHook { +contract EchoSystemHook is SystemHook { event SystemHookCalled(bytes data); function onBeforeCallSystem(address msgSender, bytes32 resourceSelector, bytes memory funcSelectorAndArgs) public { @@ -126,7 +127,7 @@ contract EchoSystemHook is ISystemHook { } } -contract RevertSystemHook is ISystemHook { +contract RevertSystemHook is SystemHook { event SystemHookCalled(bytes data); function onBeforeCallSystem(address, bytes32, bytes memory) public pure { @@ -193,6 +194,28 @@ contract WorldTest is Test, GasReporter { assertEq(Tables.getAbiEncodedFieldNames(world, NamespaceOwnerTableId), abi.encode(NamespaceOwner.getFieldNames())); } + function testRegisterModuleRevertInterfaceNotSupported() public { + // Expect an error when trying to register a module that doesn't implement the IModule interface + vm.expectRevert( + abi.encodeWithSelector( + IWorldErrors.InterfaceNotSupported.selector, + Module(address(world)), // The World contract does not implement the IModule interface + MODULE_INTERFACE_ID + ) + ); + world.installModule(Module(address(world)), new bytes(0)); + + // Expect an error when trying to register a root module that doesn't implement the IModule interface + vm.expectRevert( + abi.encodeWithSelector( + IWorldErrors.InterfaceNotSupported.selector, + Module(address(world)), // The World contract does not implement the IModule interface + MODULE_INTERFACE_ID + ) + ); + world.installRootModule(Module(address(world)), new bytes(0)); + } + function testRootNamespace() public { // Owner of root route should be the creator of the World address rootOwner = NamespaceOwner.get(world, ROOT_NAMESPACE); @@ -365,6 +388,16 @@ contract WorldTest is Test, GasReporter { // Expect the registration to fail when coming from the World (since the World address doesn't have access) _expectAccessDenied(address(world), "", ""); world.registerSystem(ResourceSelector.from("", "rootSystem"), yetAnotherSystem, true); + + // Expect the registration to fail if the provided address does not implement the WorldContextConsumer interface + vm.expectRevert( + abi.encodeWithSelector( + IWorldErrors.InterfaceNotSupported.selector, + address(world), + WORLD_CONTEXT_CONSUMER_INTERFACE_ID + ) + ); + world.registerSystem(ResourceSelector.from("someNamespace", "invalidSystem"), System(address(world)), true); } function testUpgradeSystem() public { @@ -775,6 +808,23 @@ contract WorldTest is Test, GasReporter { emit HookCalled(abi.encode(tableId, singletonKey, valueSchema)); world.deleteRecord(tableId, singletonKey, valueSchema); + + // Expect an error when trying to register an address that doesn't implement the IStoreHook interface + vm.expectRevert( + abi.encodeWithSelector(IWorldErrors.InterfaceNotSupported.selector, address(world), STORE_HOOK_INTERFACE_ID) + ); + world.registerStoreHook( + tableId, + IStoreHook(address(world)), // the World contract does not implement the store hook interface + StoreHookLib.encodeBitmap({ + onBeforeSetRecord: true, + onAfterSetRecord: true, + onBeforeSetField: true, + onAfterSetField: true, + onBeforeDeleteRecord: true, + onAfterDeleteRecord: true + }) + ); } function testUnregisterStoreHook() public { @@ -866,6 +916,16 @@ contract WorldTest is Test, GasReporter { WorldTestSystem system = new WorldTestSystem(); world.registerSystem(systemId, system, false); + // Expect the registration to fail if the contract does not implement the system hook interface + vm.expectRevert( + abi.encodeWithSelector(IWorldErrors.InterfaceNotSupported.selector, address(world), SYSTEM_HOOK_INTERFACE_ID) + ); + world.registerSystemHook( + systemId, + ISystemHook(address(world)), // the World contract does not implement the system hook interface + SystemHookLib.encodeBitmap({ onBeforeCallSystem: true, onAfterCallSystem: true }) + ); + // Register a new hook ISystemHook systemHook = new EchoSystemHook(); world.registerSystemHook(