diff --git a/.changeset/selfish-weeks-explode.md b/.changeset/selfish-weeks-explode.md new file mode 100644 index 0000000000..b770713de0 --- /dev/null +++ b/.changeset/selfish-weeks-explode.md @@ -0,0 +1,5 @@ +--- +"@latticexyz/world": patch +--- + +Created an `IWorldEvents` interface with `HelloStore`, so all World events are defined in a single interface. diff --git a/docs/pages/world/reference/world-external.mdx b/docs/pages/world/reference/world-external.mdx index 4e5d2dc854..9c7bbd883c 100644 --- a/docs/pages/world/reference/world-external.mdx +++ b/docs/pages/world/reference/world-external.mdx @@ -591,7 +591,7 @@ function callFrom( [Git Source](https://github.com/latticexyz/mud/blob/main/packages/world/src/IWorldKernel.sol) **Inherits:** -[IWorldModuleInstallation](/world/reference/world-external#iworldmoduleinstallation), [IWorldCall](/world/reference/world-external#iworldcall), [IWorldErrors](/world/reference/world-external#iworlderrors) +[IWorldModuleInstallation](/world/reference/world-external#iworldmoduleinstallation), [IWorldCall](/world/reference/world-external#iworldcall), [IWorldErrors](/world/reference/world-external#iworlderrors), [IWorldEvents](/src/IWorldEvents.sol/interface.IWorldEvents.md) The IWorldKernel interface includes all methods that are part of the World contract's internal bytecode. Consumers should use the `IBaseWorld` interface instead, which includes dynamically @@ -643,22 +643,6 @@ function initialize(IModule initModule) external; | ------------ | --------- | ----------------------------------------------------- | | `initModule` | `IModule` | The InitModule to be installed during initialization. | -### Events - -#### HelloWorld - -_Emitted upon successful World initialization._ - -```solidity -event HelloWorld(bytes32 indexed worldVersion); -``` - -**Parameters** - -| Name | Type | Description | -| -------------- | --------- | ------------------------------------------- | -| `worldVersion` | `bytes32` | The version of the World being initialized. | - ## IWorldModuleInstallation [Git Source](https://github.com/latticexyz/mud/blob/main/packages/world/src/IWorldKernel.sol) diff --git a/packages/world/src/IWorldEvents.sol b/packages/world/src/IWorldEvents.sol new file mode 100644 index 0000000000..2e5d0c7fec --- /dev/null +++ b/packages/world/src/IWorldEvents.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.24; + +import { IWorldErrors } from "./IWorldErrors.sol"; +import { IModule } from "./IModule.sol"; +import { ResourceId } from "./WorldResourceId.sol"; + +/** + * @title IWorldEvents + * @author MUD (https://mud.dev) by Lattice (https://lattice.xyz) + * @dev We bundle these events in an interface (instead of at the file-level or in their corresponding library) so they can be inherited by IWorldKernel. + * This ensures that all events are included in the IWorldKernel ABI for proper decoding in the frontend. + */ +interface IWorldEvents { + /** + * @dev Emitted upon successful World initialization. + * @param worldVersion The version of the World being initialized. + */ + event HelloWorld(bytes32 indexed worldVersion); +} diff --git a/packages/world/src/IWorldKernel.sol b/packages/world/src/IWorldKernel.sol index cfd3a2f455..a7c13dde7b 100644 --- a/packages/world/src/IWorldKernel.sol +++ b/packages/world/src/IWorldKernel.sol @@ -4,6 +4,7 @@ pragma solidity >=0.8.24; import { IWorldErrors } from "./IWorldErrors.sol"; import { IModule } from "./IModule.sol"; import { ResourceId } from "./WorldResourceId.sol"; +import { IWorldEvents } from "./IWorldEvents.sol"; /** * @title World Module Installation Interface @@ -59,13 +60,7 @@ interface IWorldCall { * internal bytecode. Consumers should use the `IBaseWorld` interface instead, which includes dynamically * registered functions selectors from the `InitModule`. */ -interface IWorldKernel is IWorldModuleInstallation, IWorldCall, IWorldErrors { - /** - * @dev Emitted upon successful World initialization. - * @param worldVersion The version of the World being initialized. - */ - event HelloWorld(bytes32 indexed worldVersion); - +interface IWorldKernel is IWorldModuleInstallation, IWorldCall, IWorldErrors, IWorldEvents { /** * @notice Retrieve the version of the World. * @return The version identifier of the World. diff --git a/packages/world/src/World.sol b/packages/world/src/World.sol index d75a755218..7f9508a958 100644 --- a/packages/world/src/World.sol +++ b/packages/world/src/World.sol @@ -23,6 +23,7 @@ import { InitModuleAddress } from "./codegen/tables/InitModuleAddress.sol"; import { IModule, IModule } from "./IModule.sol"; import { IWorldKernel } from "./IWorldKernel.sol"; +import { IWorldEvents } from "./IWorldEvents.sol"; import { FunctionSelectors } from "./codegen/tables/FunctionSelectors.sol"; import { Balances } from "./codegen/tables/Balances.sol"; @@ -47,7 +48,7 @@ contract World is StoreData, IWorldKernel { /// @dev Event emitted when the World contract is created. constructor() { creator = msg.sender; - emit HelloWorld(WORLD_VERSION); + emit IWorldEvents.HelloWorld(WORLD_VERSION); } /** diff --git a/packages/world/test/Factories.t.sol b/packages/world/test/Factories.t.sol index e96950dd39..73f68ae4cd 100644 --- a/packages/world/test/Factories.t.sol +++ b/packages/world/test/Factories.t.sol @@ -12,6 +12,7 @@ import { InitModule } from "../src/modules/init/InitModule.sol"; import { Create2Factory } from "../src/Create2Factory.sol"; import { WorldFactory } from "../src/WorldFactory.sol"; import { IWorldFactory } from "../src/IWorldFactory.sol"; +import { IWorldEvents } from "../src/IWorldEvents.sol"; import { InstalledModules } from "../src/codegen/tables/InstalledModules.sol"; import { NamespaceOwner } from "../src/codegen/tables/NamespaceOwner.sol"; import { ROOT_NAMESPACE_ID } from "../src/constants.sol"; @@ -20,7 +21,6 @@ import { createInitModule } from "./createInitModule.sol"; contract FactoriesTest is Test, GasReporter { event ContractDeployed(address addr, uint256 salt); event WorldDeployed(address indexed newContract, uint256 salt); - event HelloWorld(bytes32 indexed version); function calculateAddress( address deployingAddress, @@ -71,7 +71,7 @@ contract FactoriesTest is Test, GasReporter { // Check for HelloWorld event from World vm.expectEmit(true, true, true, true); - emit HelloWorld(WORLD_VERSION); + emit IWorldEvents.HelloWorld(WORLD_VERSION); // Check for WorldDeployed event from Factory vm.expectEmit(true, false, false, false); @@ -104,7 +104,7 @@ contract FactoriesTest is Test, GasReporter { // Check for HelloWorld event from World vm.expectEmit(true, true, true, true); - emit HelloWorld(WORLD_VERSION); + emit IWorldEvents.HelloWorld(WORLD_VERSION); // Check for WorldDeployed event from Factory vm.expectEmit(true, false, false, false); diff --git a/packages/world/test/World.t.sol b/packages/world/test/World.t.sol index c1149e28db..6688964a57 100644 --- a/packages/world/test/World.t.sol +++ b/packages/world/test/World.t.sol @@ -31,6 +31,7 @@ import { WorldContextProviderLib, IWorldContextConsumer } from "../src/WorldCont import { SystemHook } from "../src/SystemHook.sol"; import { BEFORE_CALL_SYSTEM, AFTER_CALL_SYSTEM } from "../src/systemHookTypes.sol"; import { Module, IModule } from "../src/Module.sol"; +import { IWorldEvents } from "../src/IWorldEvents.sol"; import { NamespaceOwner } from "../src/codegen/tables/NamespaceOwner.sol"; import { ResourceAccess } from "../src/codegen/tables/ResourceAccess.sol"; @@ -162,7 +163,6 @@ contract RevertSystemHook is SystemHook { contract WorldTest is Test, GasReporter { using WorldResourceIdInstance for ResourceId; - event HelloWorld(bytes32 indexed worldVersion); event HookCalled(bytes data); event SystemHookCalled(bytes data); event WorldTestSystemLog(string log); @@ -200,7 +200,7 @@ contract WorldTest is Test, GasReporter { InitModule initModule = createInitModule(); vm.expectEmit(true, true, true, true); - emit HelloWorld(WORLD_VERSION); + emit IWorldEvents.HelloWorld(WORLD_VERSION); IBaseWorld newWorld = IBaseWorld(address(new World())); StoreSwitch.setStoreAddress(address(newWorld));