diff --git a/.changeset/afraid-hotels-bathe.md b/.changeset/afraid-hotels-bathe.md deleted file mode 100644 index 15ef0d2c31..0000000000 --- a/.changeset/afraid-hotels-bathe.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": patch ---- - -Add support for legacy transactions in deploy script by falling back to `gasPrice` if `lastBaseFeePerGas` is not available diff --git a/.changeset/angry-buses-dress.md b/.changeset/angry-buses-dress.md deleted file mode 100644 index ac7b4e2238..0000000000 --- a/.changeset/angry-buses-dress.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": minor ---- - -Added an `--rpcBatch` option to `mud deploy` command to batch RPC calls for rate limited RPCs. diff --git a/.changeset/angry-ladybugs-invent.md b/.changeset/angry-ladybugs-invent.md deleted file mode 100644 index 1b41fb1613..0000000000 --- a/.changeset/angry-ladybugs-invent.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/store": major -"@latticexyz/world-modules": patch -"@latticexyz/world": patch -"create-mud": patch ---- - -Store config now defaults `storeArgument: false` for all tables. This means that table libraries, by default, will no longer include the extra functions with the `_store` argument. This default was changed to clear up the confusion around using table libraries in tests, `PostDeploy` scripts, etc. - -If you are sure you need to manually specify a store when interacting with tables, you can still manually toggle it back on with `storeArgument: true` in the table settings of your MUD config. - -If you want to use table libraries in `PostDeploy.s.sol`, you can add the following lines: - -```diff - import { Script } from "forge-std/Script.sol"; - import { console } from "forge-std/console.sol"; - import { IWorld } from "../src/codegen/world/IWorld.sol"; -+ import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; - - contract PostDeploy is Script { - function run(address worldAddress) external { -+ StoreSwitch.setStoreAddress(worldAddress); -+ -+ SomeTable.get(someKey); -``` diff --git a/.changeset/angry-peas-heal.md b/.changeset/angry-peas-heal.md deleted file mode 100644 index 9aa4513d05..0000000000 --- a/.changeset/angry-peas-heal.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -"@latticexyz/store-sync": minor ---- - -Refactored how we fetch snapshots from an indexer, preferring the new `getLogs` endpoint and falling back to the previous `findAll` if it isn't available. This refactor also prepares for an easier entry point for adding client caching of snapshots. - -The `initialState` option for various sync methods (`syncToPostgres`, `syncToRecs`, etc.) is now deprecated in favor of `initialBlockLogs`. For now, we'll automatically convert `initialState` into `initialBlockLogs`, but if you want to update your code, you can do: - -```ts -import { tablesWithRecordsToLogs } from "@latticexyz/store-sync"; - -const initialBlockLogs = { - blockNumber: initialState.blockNumber, - logs: tablesWithRecordsToLogs(initialState.tables), -}; -``` diff --git a/.changeset/angry-pigs-compare.md b/.changeset/angry-pigs-compare.md deleted file mode 100644 index a37cebcbee..0000000000 --- a/.changeset/angry-pigs-compare.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/store": patch -"@latticexyz/world": patch ---- - -Exclude ERC165 interface ID from custom interface ID's. diff --git a/.changeset/beige-ads-melt.md b/.changeset/beige-ads-melt.md deleted file mode 100644 index 01846b4024..0000000000 --- a/.changeset/beige-ads-melt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Storage events are now emitted after "before" hooks, so that the resulting logs are now correctly ordered and reflect onchain logic. This resolves issues with store writes and event emissions happening in "before" hooks. diff --git a/.changeset/beige-badgers-smile.md b/.changeset/beige-badgers-smile.md deleted file mode 100644 index 28964dafaf..0000000000 --- a/.changeset/beige-badgers-smile.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -"@latticexyz/world": major ---- - -Moves World interfaces and factories files for consistency with our other packages. - -If you import any World interfaces or factories directly, you'll need to update the import path: - -```diff -- import { IBaseWorld } from "@latticexyz/world/src/interfaces/IBaseWorld.sol"; -+ import { IBaseWorld } from "@latticexyz/world/src/IBaseWorld.sol"; -``` - -```diff -- import { IBaseWorld } from "@latticexyz/world/src/factories/WorldFactory.sol"; -+ import { IBaseWorld } from "@latticexyz/world/src/WorldFactory.sol"; -``` diff --git a/.changeset/beige-radios-drop.md b/.changeset/beige-radios-drop.md deleted file mode 100644 index c821afbfe4..0000000000 --- a/.changeset/beige-radios-drop.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -"@latticexyz/world": minor ---- - -It is now possible to upgrade systems by calling `registerSystem` again with an existing system id (resource selector). - -```solidity -// Register a system -world.registerSystem(systemId, systemAddress, publicAccess); - -// Upgrade the system by calling `registerSystem` with the -// same system id but a new system address or publicAccess flag -world.registerSystem(systemId, newSystemAddress, newPublicAccess); -``` diff --git a/.changeset/beige-rockets-return.md b/.changeset/beige-rockets-return.md deleted file mode 100644 index da0afa8b3a..0000000000 --- a/.changeset/beige-rockets-return.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-indexer": patch ---- - -Records are now ordered by `lastUpdatedBlockNumber` at the Postgres SQL query level diff --git a/.changeset/big-goats-prove.md b/.changeset/big-goats-prove.md deleted file mode 100644 index 049248db7b..0000000000 --- a/.changeset/big-goats-prove.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/services": patch ---- - -protocol-parser in Go diff --git a/.changeset/blue-forks-move.md b/.changeset/blue-forks-move.md deleted file mode 100644 index 59dee73733..0000000000 --- a/.changeset/blue-forks-move.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Changed the type of the output variable in the `slice4` function to `bytes4`. diff --git a/.changeset/blue-roses-listen.md b/.changeset/blue-roses-listen.md deleted file mode 100644 index d9dcf6f08b..0000000000 --- a/.changeset/blue-roses-listen.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/common": patch -"@latticexyz/store": patch -"@latticexyz/world-modules": patch -"@latticexyz/world": patch -"create-mud": patch ---- - -Table libraries now hardcode the `bytes32` table ID value rather than computing it in Solidity. This saves a bit of gas across all storage operations. diff --git a/.changeset/blue-seals-relate.md b/.changeset/blue-seals-relate.md deleted file mode 100644 index 84b94339ee..0000000000 --- a/.changeset/blue-seals-relate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/dev-tools": minor ---- - -Improved rendering of transactions that make calls via World's `call` and `callFrom` methods diff --git a/.changeset/brave-dodos-relate.md b/.changeset/brave-dodos-relate.md deleted file mode 100644 index ff1ba8ed7d..0000000000 --- a/.changeset/brave-dodos-relate.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -"@latticexyz/store": major -"@latticexyz/world": major ---- - -Store and World configs have been rebuilt with strong types. The shape of these configs have also changed slightly for clarity, the biggest change of which is merging of `keySchema` and `valueSchema` into a single `schema` with a separate `key` for a table's primary key. - -To migrate, first update the imported config method: - -```diff filename="mud.config.ts" --import { mudConfig } from "@latticexyz/world/register"; -+import { defineWorld } from "@latticexyz/world"; - --export default mudConfig({ -+export default defineWorld({ -``` - -_Note that if you are only using Store, you will need to import `defineStore` from `@latticexyz/store`._ - -Then migrate the table key by renaming `keySchema` to `schema` and define the table `key` with each field name from your key schema: - -```diff filename="mud.config.ts" - export default defineWorld({ - tables: { - Position: { -- keySchema: { -+ schema: { - player: "address", - }, - valueSchema: { - x: "int32", - y: "int32", - }, -+ key: ['player'], - }, - }, - }); -``` - -Now we can merge the `valueSchema` into `schema`. - -```diff filename="mud.config.ts" - export default defineWorld({ - tables: { - Position: { - schema: { - player: "address", -- }, -- valueSchema: { - x: "int32", - y: "int32", - }, - key: ['player'], - }, - }, - }); -``` - -If you previously used the table config shorthand without the full `keySchema` and `valueSchema`, some of the defaults have changed. Shorthands now use an `id: "bytes32"` field by default rather than `key: "bytes32"` and corresponding `key: ["id"]`. To keep previous behavior, you may have to manually define your `schema` with the previous `key` and `value` fields. - -```diff filename="mud.config.ts" - export default defineWorld({ - tables: { -- OwnedBy: "address", -+ OwnedBy: { -+ schema: { -+ key: "bytes32", -+ value: "address", -+ }, -+ key: ["key"], -+ }, - }, - }); -``` - -Singleton tables are defined similarly, where an empty `key` rather than `keySchema` is provided: - -```diff filename="mud.config.ts" --keySchema: {} -+key: [] -``` - -Offchain tables are now defined as a table `type` instead an `offchainOnly` boolean: - -```diff filename="mud.config.ts" --offchainOnly: true -+type: 'offchainTable' -``` - -All codegen options have moved under `codegen`: - -```diff filename="mud.config.ts" - export default defineWorld({ -- codegenDirectory: "…", -+ codegen: { -+ outputDirectory: "…", -+ }, - tables: { - Position: { - schema: { - player: "address", - x: "int32", - y: "int32", - }, - key: ['player'], -- directory: "…", -- dataStruct: false, -+ codegen: { -+ outputDirectory: "…", -+ dataStruct: false, -+ }, - }, - }, - }); -``` diff --git a/.changeset/brave-ghosts-walk.md b/.changeset/brave-ghosts-walk.md deleted file mode 100644 index 6efe4e189c..0000000000 --- a/.changeset/brave-ghosts-walk.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@latticexyz/store-indexer": minor -"@latticexyz/store-sync": minor ---- - -Added a `followBlockTag` option to configure which block number to follow when running `createStoreSync`. It defaults to `latest` (current behavior), which is recommended for individual clients so that you always have the latest chain state. - -Indexers now default to `safe` to avoid issues with reorgs and load-balanced RPCs being out of sync. This means indexers will be slightly behind the latest block number, but clients can quickly catch up. Indexers can override this setting using `FOLLOW_BLOCK_TAG` environment variable. diff --git a/.changeset/brave-islands-wash.md b/.changeset/brave-islands-wash.md deleted file mode 100644 index b5ed025eb9..0000000000 --- a/.changeset/brave-islands-wash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": minor ---- - -Deploys now validate contract size before deploying and warns when a contract is over or close to the size limit (24kb). This should help identify the most common cause of "evm revert" errors during system and module contract deploys. diff --git a/.changeset/brave-needles-love.md b/.changeset/brave-needles-love.md deleted file mode 100644 index 00edffbeee..0000000000 --- a/.changeset/brave-needles-love.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/network": major ---- - -Removes `network` package. Please see the [changelog](https://mud.dev/changelog) for how to migrate your app to the new `store-sync` package. Or create a new project from an up-to-date template with `pnpm create mud@next your-app-name`. diff --git a/.changeset/brave-rings-tickle.md b/.changeset/brave-rings-tickle.md deleted file mode 100644 index bd9baaf30d..0000000000 --- a/.changeset/brave-rings-tickle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Optimize storage library diff --git a/.changeset/breezy-cameras-switch.md b/.changeset/breezy-cameras-switch.md deleted file mode 100644 index 412b298936..0000000000 --- a/.changeset/breezy-cameras-switch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-sync": patch ---- - -Export postgres column type helpers from `@latticexyz/store-sync`. diff --git a/.changeset/breezy-days-greet.md b/.changeset/breezy-days-greet.md deleted file mode 100644 index 5c8d5f97fc..0000000000 --- a/.changeset/breezy-days-greet.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Fixed a race condition when registering core tables, where we would set a record in the `ResourceIds` table before the table was registered. diff --git a/.changeset/breezy-garlics-decide.md b/.changeset/breezy-garlics-decide.md deleted file mode 100644 index 72e994ed4f..0000000000 --- a/.changeset/breezy-garlics-decide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world-modules": patch ---- - -Removed `IUniqueEntitySystem` in favor of calling `getUniqueEntity` via `world.call` instead of the world function selector. This had a small gas improvement. diff --git a/.changeset/breezy-seahorses-prove.md b/.changeset/breezy-seahorses-prove.md deleted file mode 100644 index 247d96d090..0000000000 --- a/.changeset/breezy-seahorses-prove.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -"@latticexyz/utils": major ---- - -Removed `keccak256` and `keccak256Coord` hash utils in favor of [viem's `keccak256`](https://viem.sh/docs/utilities/keccak256.html#keccak256). - -```diff -- import { keccak256 } from "@latticexyz/utils"; -+ import { keccak256, toHex } from "viem"; - -- const hash = keccak256("some string"); -+ const hash = keccak256(toHex("some string")); -``` - -```diff -- import { keccak256Coord } from "@latticexyz/utils"; -+ import { encodeAbiParameters, keccak256, parseAbiParameters } from "viem"; - - const coord = { x: 1, y: 1 }; -- const hash = keccak256Coord(coord); -+ const hash = keccak256(encodeAbiParameters(parseAbiParameters("int32, int32"), [coord.x, coord.y])); -``` diff --git a/.changeset/bright-flies-hug.md b/.changeset/bright-flies-hug.md deleted file mode 100644 index 615a6eb4c5..0000000000 --- a/.changeset/bright-flies-hug.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": patch ---- - -`dev-contracts` will no longer bail when there was an issue with deploying (e.g. typo in contracts) and instead wait for file changes before retrying. diff --git a/.changeset/bright-kangaroos-battle.md b/.changeset/bright-kangaroos-battle.md deleted file mode 100644 index bbbc1880c1..0000000000 --- a/.changeset/bright-kangaroos-battle.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@latticexyz/world-modules": patch -"@latticexyz/world": major ---- - -World function signatures for namespaced systems have changed from `{namespace}_{systemName}_{functionName}` to `{namespace}__{functionName}` (double underscore, no system name). This is more ergonomic and is more consistent with namespaced resources in other parts of the codebase (e.g. MUD config types, table names in the schemaful indexer). - -If you have a project using the `namespace` key in your `mud.config.ts` or are manually registering systems and function selectors on a namespace, you will likely need to codegen your system interfaces (`pnpm build`) and update any calls to these systems through the world's namespaced function signatures. diff --git a/.changeset/brown-garlics-lie.md b/.changeset/brown-garlics-lie.md deleted file mode 100644 index b8c963d98f..0000000000 --- a/.changeset/brown-garlics-lie.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -"@latticexyz/world": major ---- - -All `World` methods now revert if the `World` calls itself. -The `World` should never need to externally call itself, since all internal table operations happen via library calls, and all root system operations happen via delegate call. - -It should not be possible to make the `World` call itself as an external actor. -If it were possible to make the `World` call itself, it would be possible to write to internal tables that only the `World` should have access to. -As this is a very important invariance, we made it explicit in a requirement check in every `World` method, rather than just relying on making it impossible to trigger the `World` to call itself. - -This is a breaking change for modules that previously used external calls to the `World` in the `installRoot` method. -In the `installRoot` method, the `World` can only be called via `delegatecall`, and table operations should be performed via the internal table methods (e.g. `_set` instead of `set`). - -Example for how to replace external calls to `world` in root systems / root modules (`installRoot`) with `delegatecall`: - -```diff -+ import { revertWithBytes } from "@latticexyz/world/src/revertWithBytes.sol"; - -- world.grantAccess(tableId, address(hook)); -+ (bool success, bytes memory returnData) = address(world).delegatecall( -+ abi.encodeCall(world.grantAccess, (tableId, address(hook))) -+ ); - -+ if (!success) revertWithBytes(returnData); -``` diff --git a/.changeset/brown-icons-burn.md b/.changeset/brown-icons-burn.md deleted file mode 100644 index 5752af611d..0000000000 --- a/.changeset/brown-icons-burn.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/std-contracts": major ---- - -Removes `std-contracts` package. These were v1 contracts, now entirely replaced by our v2 tooling. See the [MUD docs](https://mud.dev/) for building with v2 or create a new project from our v2 templates with `pnpm create mud@next your-app-name`. diff --git a/.changeset/calm-clocks-add.md b/.changeset/calm-clocks-add.md deleted file mode 100644 index 38eefa6981..0000000000 --- a/.changeset/calm-clocks-add.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/world": major -"@latticexyz/world-modules": major ---- - -Refactored `InstalledModules` to key modules by addresses instead of pre-defined names. Previously, modules could report arbitrary names, meaning misconfigured modules could be installed under a name intended for another module. diff --git a/.changeset/calm-drinks-dance.md b/.changeset/calm-drinks-dance.md deleted file mode 100644 index 0a893bb917..0000000000 --- a/.changeset/calm-drinks-dance.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/world": patch ---- - -Attempting to deploy multiple systems where there are overlapping system IDs now throws an error. diff --git a/.changeset/chatty-planets-heal.md b/.changeset/chatty-planets-heal.md deleted file mode 100644 index c1270e5d4b..0000000000 --- a/.changeset/chatty-planets-heal.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -"@latticexyz/world": minor ---- - -Added TS helpers for calling systems dynamically via the World. - -- `encodeSystemCall` for `world.call` - - ```ts - worldContract.write.call(encodeSystemCall({ - abi: worldContract.abi, - systemId: resourceToHex({ ... }), - functionName: "registerDelegation", - args: [ ... ], - })); - ``` - -- `encodeSystemCallFrom` for `world.callFrom` - - ```ts - worldContract.write.callFrom(encodeSystemCallFrom({ - abi: worldContract.abi, - from: "0x...", - systemId: resourceToHex({ ... }), - functionName: "registerDelegation", - args: [ ... ], - })); - ``` - -- `encodeSystemCalls` for `world.batchCall` - - ```ts - worldContract.write.batchCall(encodeSystemCalls(abi, [{ - systemId: resourceToHex({ ... }), - functionName: "registerDelegation", - args: [ ... ], - }])); - ``` - -- `encodeSystemCallsFrom` for `world.batchCallFrom` - ```ts - worldContract.write.batchCallFrom(encodeSystemCallsFrom(abi, "0x...", [{ - systemId: resourceToHex({ ... }), - functionName: "registerDelegation", - args: [ ... ], - }])); - ``` diff --git a/.changeset/chilled-chicken-repair.md b/.changeset/chilled-chicken-repair.md deleted file mode 100644 index 36e6a4fc90..0000000000 --- a/.changeset/chilled-chicken-repair.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/recs": patch -"@latticexyz/solecs": major -"@latticexyz/std-client": patch ---- - -Removes `solecs` package. These were v1 contracts, now entirely replaced by our v2 tooling. See the [MUD docs](https://mud.dev/) for building with v2 or create a new project from our v2 templates with `pnpm create mud@next your-app-name`. diff --git a/.changeset/chilled-cougars-smash.md b/.changeset/chilled-cougars-smash.md deleted file mode 100644 index 0356ce2c82..0000000000 --- a/.changeset/chilled-cougars-smash.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -"@latticexyz/faucet": minor ---- - -New package to run your own faucet service. We'll use this soon for our testnet in place of `@latticexyz/services`. - -To run the faucet server: - -- Add the package with `pnpm add @latticexyz/faucet` -- Add a `.env` file that has a `RPC_HTTP_URL` and `FAUCET_PRIVATE_KEY` (or pass the environment variables into the next command) -- Run `pnpm faucet-server` to start the server - -You can also adjust the server's `HOST` (defaults to `0.0.0.0`) and `PORT` (defaults to `3002`). The tRPC routes are accessible under `/trpc`. - -To connect a tRPC client, add the package with `pnpm add @latticexyz/faucet` and then use `createClient`: - -```ts -import { createClient } from "@latticexyz/faucet"; - -const faucet = createClient({ url: "http://localhost:3002/trpc" }); - -await faucet.mutate.drip({ address: burnerAccount.address }); -``` diff --git a/.changeset/chilled-kangaroos-dream.md b/.changeset/chilled-kangaroos-dream.md deleted file mode 100644 index a1edaf3719..0000000000 --- a/.changeset/chilled-kangaroos-dream.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-indexer": patch ---- - -Fixes postgres indexer stopping sync after it catches up to the latest block. diff --git a/.changeset/chilly-fishes-speak.md b/.changeset/chilly-fishes-speak.md deleted file mode 100644 index 98d11e7d70..0000000000 --- a/.changeset/chilly-fishes-speak.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Updated `WorldRegistrationSystem` to check that systems exist before registering system hooks. diff --git a/.changeset/chilly-kangaroos-clap.md b/.changeset/chilly-kangaroos-clap.md deleted file mode 100644 index 0d98706e68..0000000000 --- a/.changeset/chilly-kangaroos-clap.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/common": patch ---- - -Adds viem workaround for zero base fee used by MUD's anvil config diff --git a/.changeset/clean-bananas-hug.md b/.changeset/clean-bananas-hug.md deleted file mode 100644 index 0420d43372..0000000000 --- a/.changeset/clean-bananas-hug.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": patch ---- - -Using `mud set-version --link` will no longer attempt to fetch the latest version from npm. diff --git a/.changeset/clever-icons-cough.md b/.changeset/clever-icons-cough.md deleted file mode 100644 index ce9ce2361e..0000000000 --- a/.changeset/clever-icons-cough.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-mud": minor ---- - -Updated templates to use [mprocs](https://github.com/pvolok/mprocs) instead of [concurrently](https://github.com/open-cli-tools/concurrently) for running dev scripts. diff --git a/.changeset/clever-items-appear.md b/.changeset/clever-items-appear.md deleted file mode 100644 index 4dee214dca..0000000000 --- a/.changeset/clever-items-appear.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/store": patch -"@latticexyz/world": patch ---- - -Include bytecode for `World` and `Store` in npm packages. diff --git a/.changeset/clever-rats-sip.md b/.changeset/clever-rats-sip.md deleted file mode 100644 index 4af48d921d..0000000000 --- a/.changeset/clever-rats-sip.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/services": patch ---- - -Fixed an issue where the TypeScript types for createFaucetService were not exported correctly from the @latticexyz/services package diff --git a/.changeset/cold-books-love.md b/.changeset/cold-books-love.md deleted file mode 100644 index 4d46d1de61..0000000000 --- a/.changeset/cold-books-love.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/common": patch ---- - -`waitForIdle` now falls back to `setTimeout` for environments without `requestIdleCallback`. diff --git a/.changeset/cold-years-itch.md b/.changeset/cold-years-itch.md deleted file mode 100644 index b132da0085..0000000000 --- a/.changeset/cold-years-itch.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -"@latticexyz/cli": major -"@latticexyz/protocol-parser": major -"@latticexyz/store-sync": major -"@latticexyz/store": major -"create-mud": minor ---- - -Renamed all occurrences of `schema` where it is used as "value schema" to `valueSchema` to clearly distinguish it from "key schema". -The only breaking change for users is the change from `schema` to `valueSchema` in `mud.config.ts`. - -```diff -// mud.config.ts -export default mudConfig({ - tables: { - CounterTable: { - keySchema: {}, -- schema: { -+ valueSchema: { - value: "uint32", - }, - }, - } -} -``` diff --git a/.changeset/cool-snakes-reply.md b/.changeset/cool-snakes-reply.md deleted file mode 100644 index 663f002645..0000000000 --- a/.changeset/cool-snakes-reply.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -"@latticexyz/recs": minor -"@latticexyz/std-client": major ---- - -- Moved `createActionSystem` from `std-client` to `recs` package and updated it to better support v2 sync stack. - - If you want to use `createActionSystem` alongside `syncToRecs`, you'll need to pass in arguments like so: - - ```ts - import { syncToRecs } from "@latticexyz/store-sync/recs"; - import { createActionSystem } from "@latticexyz/recs/deprecated"; - import { from, mergeMap } from "rxjs"; - - const { blockLogsStorage$, waitForTransaction } = syncToRecs({ - world, - ... - }); - - const txReduced$ = blockLogsStorage$.pipe( - mergeMap(({ operations }) => from(operations.map((op) => op.log?.transactionHash).filter(isDefined))) - ); - - const actionSystem = createActionSystem(world, txReduced$, waitForTransaction); - ``` - -- Fixed a bug in `waitForComponentValueIn` that caused the promise to not resolve if the component value was already set when the function was called. - -- Fixed a bug in `createActionSystem` that caused optimistic updates to be incorrectly propagated to requirement checks. To fix the bug, you must now pass in the full component object to the action's `updates` instead of just the component name. - - ```diff - actions.add({ - updates: () => [ - { - - component: "Resource", - + component: Resource, - ... - } - ], - ... - }); - ``` diff --git a/.changeset/curly-countries-obey.md b/.changeset/curly-countries-obey.md deleted file mode 100644 index 1e2dbae332..0000000000 --- a/.changeset/curly-countries-obey.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/world-modules": patch -"@latticexyz/world": major ---- - -Tables and interfaces in the `world` package are now generated to the `codegen` folder. -This is only a breaking change if you imported tables or codegenerated interfaces from `@latticexyz/world` directly. -If you're using the MUD CLI, the changed import paths are already integrated and no further changes are necessary. - -```diff -- import { IBaseWorld } from "@latticexyz/world/src/interfaces/IBaseWorld.sol"; -+ import { IBaseWorld } from "@latticexyz/world/src/codegen/interfaces/IBaseWorld.sol"; - -``` diff --git a/.changeset/curly-numbers-talk.md b/.changeset/curly-numbers-talk.md deleted file mode 100644 index 928e66945f..0000000000 --- a/.changeset/curly-numbers-talk.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/store": patch -"@latticexyz/world": patch ---- - -Moved the test tables out of the main config in `world` and `store` and into their own separate config. diff --git a/.changeset/curvy-dingos-draw.md b/.changeset/curvy-dingos-draw.md deleted file mode 100644 index 8ca6af4d16..0000000000 --- a/.changeset/curvy-dingos-draw.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"@latticexyz/world-modules": major -"@latticexyz/schema-type": major -"@latticexyz/gas-report": major -"@latticexyz/common": minor -"@latticexyz/noise": major -"@latticexyz/store": major -"@latticexyz/world": major -"@latticexyz/cli": minor -"create-mud": minor ---- - -Bumped Solidity version to 0.8.24. diff --git a/.changeset/curvy-tables-melt.md b/.changeset/curvy-tables-melt.md deleted file mode 100644 index d974279b9e..0000000000 --- a/.changeset/curvy-tables-melt.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/common": major ---- - -- Add `renderWithFieldSuffix` helper method to always render a field function with a suffix, and optionally render the same function without a suffix. -- Remove `methodNameSuffix` from `RenderField` interface, because the suffix is now computed as part of `renderWithFieldSuffix`. diff --git a/.changeset/cyan-baboons-breathe.md b/.changeset/cyan-baboons-breathe.md deleted file mode 100644 index cb44b6fba1..0000000000 --- a/.changeset/cyan-baboons-breathe.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": minor ---- - -Added a `Module_AlreadyInstalled` error to `IModule`. diff --git a/.changeset/cyan-hats-try.md b/.changeset/cyan-hats-try.md deleted file mode 100644 index 877a795bba..0000000000 --- a/.changeset/cyan-hats-try.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -"@latticexyz/store": major -"@latticexyz/world": major ---- - -We've updated Store events to be "schemaless", meaning there is enough information in each event to only need to operate on the bytes of each record to make an update to that record without having to first decode the record by its schema. This enables new kinds of indexers and sync strategies. - -If you've written your own sync logic or are interacting with Store calls directly, this is a breaking change. We have a few more breaking protocol changes upcoming, so you may hold off on upgrading until those land. - -If you are using MUD's built-in tooling (table codegen, indexer, store sync, etc.), you don't have to make any changes except upgrading to the latest versions and deploying a fresh World. - -- The `data` field in each `StoreSetRecord` and `StoreEphemeralRecord` has been replaced with three new fields: `staticData`, `encodedLengths`, and `dynamicData`. This better reflects the on-chain state and makes it easier to perform modifications to the raw bytes. We recommend storing each of these fields individually in your off-chain storage of choice (indexer, client, etc.). - - ```diff - - event StoreSetRecord(bytes32 tableId, bytes32[] keyTuple, bytes data); - + event StoreSetRecord(bytes32 tableId, bytes32[] keyTuple, bytes staticData, bytes32 encodedLengths, bytes dynamicData); - - - event StoreEphemeralRecord(bytes32 tableId, bytes32[] keyTuple, bytes data); - + event StoreEphemeralRecord(bytes32 tableId, bytes32[] keyTuple, bytes staticData, bytes32 encodedLengths, bytes dynamicData); - ``` - -- The `StoreSetField` event is now replaced by two new events: `StoreSpliceStaticData` and `StoreSpliceDynamicData`. Splicing allows us to perform efficient operations like push and pop, in addition to replacing a field value. We use two events because updating a dynamic-length field also requires updating the record's `encodedLengths` (aka PackedCounter). - - ```diff - - event StoreSetField(bytes32 tableId, bytes32[] keyTuple, uint8 fieldIndex, bytes data); - + event StoreSpliceStaticData(bytes32 tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data); - + event StoreSpliceDynamicData(bytes32 tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data, bytes32 encodedLengths); - ``` - -Similarly, Store setter methods (e.g. `setRecord`) have been updated to reflect the `data` to `staticData`, `encodedLengths`, and `dynamicData` changes. We'll be following up shortly with Store getter method changes for more gas efficient storage reads. diff --git a/.changeset/cyan-timers-tan.md b/.changeset/cyan-timers-tan.md deleted file mode 100644 index 27c2dd5fa9..0000000000 --- a/.changeset/cyan-timers-tan.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": patch ---- - -Fix table IDs for module install step of deploy diff --git a/.changeset/cyan-vans-pay.md b/.changeset/cyan-vans-pay.md deleted file mode 100644 index 09ef90d5ea..0000000000 --- a/.changeset/cyan-vans-pay.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-sync": major ---- - -`lastUpdatedBlockNumber` columns in Postgres storage adapters are no longer nullable diff --git a/.changeset/dirty-items-retire.md b/.changeset/dirty-items-retire.md deleted file mode 100644 index 8dddcc5625..0000000000 --- a/.changeset/dirty-items-retire.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -"@latticexyz/store-indexer": major -"@latticexyz/store-sync": major ---- - -Adds store indexer service package with utils to query the indexer service. - -You can run the indexer locally by checking out the MUD monorepo, installing/building everything, and running `pnpm start:local` from `packages/store-indexer`. - -To query the indexer in the client, you can create a tRPC client with a URL pointing to the indexer service and call the available tRPC methods: - -```ts -import { createIndexerClient } from "@latticexyz/store-sync/trpc-indexer"; - -const indexer = createIndexerClient({ url: indexerUrl }); -const result = await indexer.findAll.query({ - chainId: publicClient.chain.id, - address, -}); -``` - -If you're using `syncToRecs`, you can just pass in the `indexerUrl` option as a shortcut to the above: - -```ts -import { syncToRecs } from "@latticexyz/store-sync/recs"; - -syncToRecs({ - ... - indexerUrl: "https://your.indexer.service", -}); -``` diff --git a/.changeset/dirty-lizards-tell.md b/.changeset/dirty-lizards-tell.md deleted file mode 100644 index 61413b2043..0000000000 --- a/.changeset/dirty-lizards-tell.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@latticexyz/store-sync": patch -"@latticexyz/dev-tools": patch -"@latticexyz/common": patch -"@latticexyz/cli": patch ---- - -Updated all human-readable resource IDs to use `{namespace}__{name}` for consistency with world function signatures. diff --git a/.changeset/dry-chicken-love.md b/.changeset/dry-chicken-love.md deleted file mode 100644 index 5dd3fc13c2..0000000000 --- a/.changeset/dry-chicken-love.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -"@latticexyz/store": minor -"@latticexyz/world": minor ---- - -It is now possible to unregister Store hooks and System hooks. - -```solidity -interface IStore { - function unregisterStoreHook(bytes32 table, IStoreHook hookAddress) external; - // ... -} - -interface IWorld { - function unregisterSystemHook(bytes32 resourceSelector, ISystemHook hookAddress) external; - // ... -} -``` diff --git a/.changeset/dry-flowers-shave.md b/.changeset/dry-flowers-shave.md deleted file mode 100644 index 3c767b80fc..0000000000 --- a/.changeset/dry-flowers-shave.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/common": patch -"@latticexyz/react": patch ---- - -Removed some unused files, namely `curry` in `@latticexyz/common` and `useDeprecatedComputedValue` from `@latticexyz/react`. diff --git a/.changeset/dull-otters-smash.md b/.changeset/dull-otters-smash.md deleted file mode 100644 index d53d909197..0000000000 --- a/.changeset/dull-otters-smash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world-modules": patch ---- - -ERC20 and ERC721 implementations now always register the token namespace, instead of checking if it has already been registered. This prevents issues with registering the namespace beforehand, namely that only the owner of a system can create a puppet for it. diff --git a/.changeset/eight-deers-confess.md b/.changeset/eight-deers-confess.md deleted file mode 100644 index 2be39f1b3d..0000000000 --- a/.changeset/eight-deers-confess.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Register the `store` namespace in the `CoreModule`. -Since namespaces are a World concept, registering the Store's internal tables does not automatically register the Store's namespace, so we do this manually during initialization in the `CoreModule`. diff --git a/.changeset/eighty-pots-report.md b/.changeset/eighty-pots-report.md deleted file mode 100644 index 9178b9aa75..0000000000 --- a/.changeset/eighty-pots-report.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -"@latticexyz/store": major ---- - -The argument order on `Store_SpliceDynamicData`, `onBeforeSpliceDynamicData` and `onAfterSpliceDynamicData` has been changed to match the argument order on `Store_SetRecord`, -where the `PackedCounter encodedLength` field comes before the `bytes dynamicData` field. - -```diff -IStore { - event Store_SpliceDynamicData( - ResourceId indexed tableId, - bytes32[] keyTuple, - uint48 start, - uint40 deleteCount, -+ PackedCounter encodedLengths, - bytes data, -- PackedCounter encodedLengths - ); -} - -IStoreHook { - function onBeforeSpliceDynamicData( - ResourceId tableId, - bytes32[] memory keyTuple, - uint8 dynamicFieldIndex, - uint40 startWithinField, - uint40 deleteCount, -+ PackedCounter encodedLengths, - bytes memory data, -- PackedCounter encodedLengths - ) external; - - function onAfterSpliceDynamicData( - ResourceId tableId, - bytes32[] memory keyTuple, - uint8 dynamicFieldIndex, - uint40 startWithinField, - uint40 deleteCount, -+ PackedCounter encodedLengths, - bytes memory data, -- PackedCounter encodedLengths - ) external; -} -``` diff --git a/.changeset/eighty-tigers-argue.md b/.changeset/eighty-tigers-argue.md deleted file mode 100644 index 83d56a7457..0000000000 --- a/.changeset/eighty-tigers-argue.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@latticexyz/block-logs-stream": patch -"@latticexyz/protocol-parser": patch -"@latticexyz/store-sync": minor -"@latticexyz/store": patch ---- - -Add store sync package diff --git a/.changeset/eleven-zebras-travel.md b/.changeset/eleven-zebras-travel.md deleted file mode 100644 index 5eac8b38c4..0000000000 --- a/.changeset/eleven-zebras-travel.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/store": patch -"@latticexyz/world": patch ---- - -Renamed the `requireNoCallback` modifier to `prohibitDirectCallback`. diff --git a/.changeset/empty-planes-kiss.md b/.changeset/empty-planes-kiss.md deleted file mode 100644 index e35cdc50e8..0000000000 --- a/.changeset/empty-planes-kiss.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/std-client": major ---- - -Removes `std-client` package. Please see the [changelog](https://mud.dev/changelog) for how to migrate your app to the new `store-sync` package. Or create a new project from an up-to-date template with `pnpm create mud@next your-app-name`. diff --git a/.changeset/empty-starfishes-lick.md b/.changeset/empty-starfishes-lick.md deleted file mode 100644 index e6830d943d..0000000000 --- a/.changeset/empty-starfishes-lick.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -"@latticexyz/store-indexer": major ---- - -Removed `tableIds` filter option in favor of the more flexible `filters` option that accepts `tableId` and an optional `key0` and/or `key1` to filter data by tables and keys. - -If you were using an indexer client directly, you'll need to update your query: - -```diff - await indexer.findAll.query({ - chainId, - address, -- tableIds: ['0x...'], -+ filters: [{ tableId: '0x...' }], - }); -``` diff --git a/.changeset/fair-baboons-compare.md b/.changeset/fair-baboons-compare.md deleted file mode 100644 index 4e3705afff..0000000000 --- a/.changeset/fair-baboons-compare.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/store": patch -"@latticexyz/world": patch ---- - -Fixed an issue where `mud.config.ts` source file was not included in the package, causing TS errors downstream. diff --git a/.changeset/fair-buckets-dress.md b/.changeset/fair-buckets-dress.md deleted file mode 100644 index 6f1d41576c..0000000000 --- a/.changeset/fair-buckets-dress.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -"@latticexyz/store-sync": minor ---- - -Added an optional `tables` option to `syncToRecs` to allow you to sync from tables that may not be expressed by your MUD config. This will be useful for namespaced tables used by [ERC20](https://github.com/latticexyz/mud/pull/1789) and [ERC721](https://github.com/latticexyz/mud/pull/1844) token modules until the MUD config gains [namespace support](https://github.com/latticexyz/mud/issues/994). - -Here's how we use this in our example project with the `KeysWithValue` module: - -```ts -syncToRecs({ - ... - tables: { - KeysWithValue: { - namespace: "keywval", - name: "Inventory", - tableId: resourceToHex({ type: "table", namespace: "keywval", name: "Inventory" }), - keySchema: { - valueHash: { type: "bytes32" }, - }, - valueSchema: { - keysWithValue: { type: "bytes32[]" }, - }, - }, - }, - ... -}); -``` diff --git a/.changeset/fair-bulldogs-decide.md b/.changeset/fair-bulldogs-decide.md deleted file mode 100644 index 33fe835910..0000000000 --- a/.changeset/fair-bulldogs-decide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-sync": major ---- - -Renamed singleton `chain` table to `config` table for clarity. diff --git a/.changeset/fair-pillows-poke.md b/.changeset/fair-pillows-poke.md deleted file mode 100644 index db9e19076b..0000000000 --- a/.changeset/fair-pillows-poke.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-indexer": patch ---- - -Added a script to run the decoded postgres indexer. diff --git a/.changeset/famous-carrots-marry.md b/.changeset/famous-carrots-marry.md deleted file mode 100644 index 56f1199381..0000000000 --- a/.changeset/famous-carrots-marry.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"create-mud": major ---- - -Replaced the `react` template with a basic task list app using the new Zustand storage adapter and sync method. This new template better demonstrates the different ways of building with MUD and has fewer concepts to learn (i.e. just tables and records, no more ECS). - -For ECS-based React apps, you can use `react-ecs` template for the previous RECS storage adapter. diff --git a/.changeset/famous-feet-suffer.md b/.changeset/famous-feet-suffer.md deleted file mode 100644 index e42174b4d9..0000000000 --- a/.changeset/famous-feet-suffer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Refactored `StoreCore` to import `IStoreEvents` instead of defining the events twice. diff --git a/.changeset/fast-ears-hug.md b/.changeset/fast-ears-hug.md deleted file mode 100644 index 635e8bc42c..0000000000 --- a/.changeset/fast-ears-hug.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/protocol-parser": minor ---- - -feat: add abiTypesToSchema, a util to turn a list of abi types into a Schema by separating static and dynamic types diff --git a/.changeset/fast-pandas-explain.md b/.changeset/fast-pandas-explain.md deleted file mode 100644 index 4be8ed82ac..0000000000 --- a/.changeset/fast-pandas-explain.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@latticexyz/store-indexer": patch -"@latticexyz/store-sync": patch ---- - -Added explicit error logs for unexpected situations. -Previously all `debug` logs were going to `stderr`, which made it hard to find the unexpected errors. -Now `debug` logs go to `stdout` and we can add explicit `stderr` logs. diff --git a/.changeset/fast-zebras-drum.md b/.changeset/fast-zebras-drum.md deleted file mode 100644 index 4fd1653e07..0000000000 --- a/.changeset/fast-zebras-drum.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -"@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/.changeset/fast-zebras-promise.md b/.changeset/fast-zebras-promise.md deleted file mode 100644 index f7d1cef47e..0000000000 --- a/.changeset/fast-zebras-promise.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/common": minor -"@latticexyz/protocol-parser": major ---- - -`readHex` was moved from `@latticexyz/protocol-parser` to `@latticexyz/common` diff --git a/.changeset/few-berries-tickle.md b/.changeset/few-berries-tickle.md deleted file mode 100644 index dcbf3602a1..0000000000 --- a/.changeset/few-berries-tickle.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -"create-mud": patch -"@latticexyz/cli": major -"@latticexyz/common": major -"@latticexyz/store": patch -"@latticexyz/world": patch -"@latticexyz/world-modules": patch ---- - -Moved table ID and field layout constants in code-generated table libraries from the file level into the library, for clearer access and cleaner imports. - -```diff --import { SomeTable, SomeTableTableId } from "./codegen/tables/SomeTable.sol"; -+import { SomeTable } from "./codegen/tables/SomeTable.sol"; - --console.log(SomeTableTableId); -+console.log(SomeTable._tableId); - --console.log(SomeTable.getFieldLayout()); -+console.log(SomeTable._fieldLayout); -``` diff --git a/.changeset/few-brooms-accept.md b/.changeset/few-brooms-accept.md deleted file mode 100644 index 3084ca6a8e..0000000000 --- a/.changeset/few-brooms-accept.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/common": minor ---- - -- Added a `sendTransaction` helper to mirror viem's `sendTransaction`, but with our nonce manager -- Added an internal mempool queue to `sendTransaction` and `writeContract` for better nonce handling -- Defaults block tag to `pending` for transaction simulation and transaction count (when initializing the nonce manager) diff --git a/.changeset/few-jars-turn.md b/.changeset/few-jars-turn.md deleted file mode 100644 index 93c3488d5f..0000000000 --- a/.changeset/few-jars-turn.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -"@latticexyz/store": major -"@latticexyz/world": major ---- - -Moved the registration of store hooks and systems hooks to bitmaps with bitwise operator instead of a struct. - -```diff -- import { StoreHookLib } from "@latticexyz/src/StoreHook.sol"; -+ import { -+ BEFORE_SET_RECORD, -+ BEFORE_SET_FIELD, -+ BEFORE_DELETE_RECORD -+ } from "@latticexyz/store/storeHookTypes.sol"; - - StoreCore.registerStoreHook( - tableId, - subscriber, -- StoreHookLib.encodeBitmap({ -- onBeforeSetRecord: true, -- onAfterSetRecord: false, -- onBeforeSetField: true, -- onAfterSetField: false, -- onBeforeDeleteRecord: true, -- onAfterDeleteRecord: false -- }) -+ BEFORE_SET_RECORD | BEFORE_SET_FIELD | BEFORE_DELETE_RECORD - ); -``` - -```diff -- import { SystemHookLib } from "../src/SystemHook.sol"; -+ import { BEFORE_CALL_SYSTEM, AFTER_CALL_SYSTEM } from "../src/systemHookTypes.sol"; - - world.registerSystemHook( - systemId, - subscriber, -- SystemHookLib.encodeBitmap({ onBeforeCallSystem: true, onAfterCallSystem: true }) -+ BEFORE_CALL_SYSTEM | AFTER_CALL_SYSTEM - ); - -``` diff --git a/.changeset/few-mirrors-reflect.md b/.changeset/few-mirrors-reflect.md deleted file mode 100644 index 01bd719f55..0000000000 --- a/.changeset/few-mirrors-reflect.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -"@latticexyz/cli": major -"@latticexyz/store": major -"@latticexyz/world": major -"create-mud": patch ---- - -All `Store` methods now require the table's value schema to be passed in as an argument instead of loading it from storage. -This decreases gas cost and removes circular dependencies of the Schema table (where it was not possible to write to the Schema table before the Schema table was registered). - -```diff - function setRecord( - bytes32 table, - bytes32[] calldata key, - bytes calldata data, -+ Schema valueSchema - ) external; -``` - -The same diff applies to `getRecord`, `getField`, `setField`, `pushToField`, `popFromField`, `updateInField`, and `deleteRecord`. - -This change only requires changes in downstream projects if the `Store` methods were accessed directly. In most cases it is fully abstracted in the generated table libraries, -so downstream projects only need to regenerate their table libraries after updating MUD. diff --git a/.changeset/few-papayas-leave.md b/.changeset/few-papayas-leave.md deleted file mode 100644 index 27a1cfa787..0000000000 --- a/.changeset/few-papayas-leave.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -"@latticexyz/store": major -"@latticexyz/world": major ---- - -- The `IStoreHook` interface was changed to replace `onBeforeSetField` and `onAfterSetField` with `onBeforeSpliceStaticData`, `onAfterSpliceStaticData`, `onBeforeSpliceDynamicData` and `onAfterSpliceDynamicData`. - - This new interface matches the new `StoreSpliceStaticData` and `StoreSpliceDynamicData` events, and avoids having to read the entire field from storage when only a subset of the field was updated - (e.g. when pushing elements to a field). - - ```diff - interface IStoreHook { - - function onBeforeSetField( - - bytes32 tableId, - - bytes32[] memory keyTuple, - - uint8 fieldIndex, - - bytes memory data, - - FieldLayout fieldLayout - - ) external; - - - function onAfterSetField( - - bytes32 tableId, - - bytes32[] memory keyTuple, - - uint8 fieldIndex, - - bytes memory data, - - FieldLayout fieldLayout - - ) external; - - + function onBeforeSpliceStaticData( - + bytes32 tableId, - + bytes32[] memory keyTuple, - + uint48 start, - + uint40 deleteCount, - + bytes memory data - + ) external; - - + function onAfterSpliceStaticData( - + bytes32 tableId, - + bytes32[] memory keyTuple, - + uint48 start, - + uint40 deleteCount, - + bytes memory data - + ) external; - - + function onBeforeSpliceDynamicData( - + bytes32 tableId, - + bytes32[] memory keyTuple, - + uint8 dynamicFieldIndex, - + uint40 startWithinField, - + uint40 deleteCount, - + bytes memory data, - + PackedCounter encodedLengths - + ) external; - - + function onAfterSpliceDynamicData( - + bytes32 tableId, - + bytes32[] memory keyTuple, - + uint8 dynamicFieldIndex, - + uint40 startWithinField, - + uint40 deleteCount, - + bytes memory data, - + PackedCounter encodedLengths - + ) external; - } - ``` - -- All `calldata` parameters on the `IStoreHook` interface were changed to `memory`, since the functions are called with `memory` from the `World`. - -- `IStore` exposes two new functions: `spliceStaticData` and `spliceDynamicData`. - - These functions provide lower level access to the operations happening under the hood in `setField`, `pushToField`, `popFromField` and `updateInField` and simplify handling - the new splice hooks. - - `StoreCore`'s internal logic was simplified to use the `spliceStaticData` and `spliceDynamicData` functions instead of duplicating similar logic in different functions. - - ```solidity - interface IStore { - // Splice data in the static part of the record - function spliceStaticData( - bytes32 tableId, - bytes32[] calldata keyTuple, - uint48 start, - uint40 deleteCount, - bytes calldata data - ) external; - - // Splice data in the dynamic part of the record - function spliceDynamicData( - bytes32 tableId, - bytes32[] calldata keyTuple, - uint8 dynamicFieldIndex, - uint40 startWithinField, - uint40 deleteCount, - bytes calldata data - ) external; - } - ``` diff --git a/.changeset/fifty-guests-rescue.md b/.changeset/fifty-guests-rescue.md deleted file mode 100644 index 8e2c718762..0000000000 --- a/.changeset/fifty-guests-rescue.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-sync": patch ---- - -Bumped the Postgres column size for `int32`, `uint32`, `int64`, and `uint64` types to avoid overflows diff --git a/.changeset/fifty-squids-eat.md b/.changeset/fifty-squids-eat.md deleted file mode 100644 index e16c747cd6..0000000000 --- a/.changeset/fifty-squids-eat.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -"@latticexyz/common": minor ---- - -Add utils for using viem with MUD - -- `mudFoundry` chain with a transaction request formatter that temporarily removes max fees to work better with anvil `--base-fee 0` -- `createBurnerAccount` that also temporarily removes max fees during transaction signing to work better with anvil `--base-fee 0` -- `mudTransportObserver` that will soon let MUD Dev Tools observe transactions - -You can use them like: - -```ts -import { createBurnerAccount, mudTransportObserver } from "@latticexyz/common"; -import { mudFoundry } from "@latticexyz/common/chains"; - -createWalletClient({ - account: createBurnerAccount(privateKey), - chain: mudFoundry, - transport: mudTransportObserver(http()), - pollingInterval: 1000, -}); -``` diff --git a/.changeset/fifty-suits-itch.md b/.changeset/fifty-suits-itch.md deleted file mode 100644 index a21a542d11..0000000000 --- a/.changeset/fifty-suits-itch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-mud": patch ---- - -Updated templates' PostDeploy script to set store address so that tables can be used directly inside PostDeploy. diff --git a/.changeset/fifty-suits-shout.md b/.changeset/fifty-suits-shout.md deleted file mode 100644 index 734283b030..0000000000 --- a/.changeset/fifty-suits-shout.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -"@latticexyz/store-indexer": major ---- - -Adds a [Fastify](https://fastify.dev/) server in front of tRPC and puts tRPC endpoints under `/trpc` to make way for other top-level endpoints (e.g. [tRPC panel](https://github.com/iway1/trpc-panel) or other API frontends like REST or gRPC). - -If you're using `@latticexyz/store-sync` packages with an indexer (either `createIndexerClient` or `indexerUrl` argument of `syncToRecs`), then you'll want to update your indexer URL: - -```diff - createIndexerClient({ -- url: "https://indexer.dev.linfra.xyz", -+ url: "https://indexer.dev.linfra.xyz/trpc", - }); -``` - -```diff - syncToRecs({ - ... -- indexerUrl: "https://indexer.dev.linfra.xyz", -+ indexerUrl: "https://indexer.dev.linfra.xyz/trpc", - }); -``` diff --git a/.changeset/five-emus-battle.md b/.changeset/five-emus-battle.md deleted file mode 100644 index 809894564e..0000000000 --- a/.changeset/five-emus-battle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Optimised `StoreRegistrationSystem` and `WorldRegistrationSystem` by fetching individual fields instead of entire records where possible. diff --git a/.changeset/five-vans-try.md b/.changeset/five-vans-try.md deleted file mode 100644 index 25991056af..0000000000 --- a/.changeset/five-vans-try.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": major ---- - -Renamed `CoreModule` to `InitModule` and `CoreRegistrationSystem` to `RegistrationSystem`. diff --git a/.changeset/flat-trainers-marry.md b/.changeset/flat-trainers-marry.md deleted file mode 100644 index 54ff1653ea..0000000000 --- a/.changeset/flat-trainers-marry.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -"@latticexyz/common": patch -"@latticexyz/store-sync": patch ---- - -Initial sync from indexer no longer blocks the promise returning from `createStoreSync`, `syncToRecs`, and `syncToSqlite`. This should help with rendering loading screens using the `SyncProgress` RECS component and avoid the long flashes of no content in templates. - -By default, `syncToRecs` and `syncToSqlite` will start syncing (via observable subscription) immediately after called. - -If your app needs to control when syncing starts, you can use the `startSync: false` option and then `blockStoreOperations$.subscribe()` to start the sync yourself. Just be sure to unsubscribe to avoid memory leaks. - -```ts -const { blockStorageOperations$ } = syncToRecs({ - ... - startSync: false, -}); - -// start sync manually by subscribing to `blockStorageOperation$` -const subcription = blockStorageOperation$.subscribe(); - -// clean up subscription -subscription.unsubscribe(); -``` diff --git a/.changeset/fluffy-days-carry.md b/.changeset/fluffy-days-carry.md deleted file mode 100644 index fa98b7b4fe..0000000000 --- a/.changeset/fluffy-days-carry.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/store-indexer": major -"@latticexyz/store-sync": major ---- - -The postgres indexer is now storing the `logIndex` of the last update of a record to be able to return the snapshot logs in the order they were emitted onchain. diff --git a/.changeset/fluffy-moles-march.md b/.changeset/fluffy-moles-march.md deleted file mode 100644 index 1e7bb14fa0..0000000000 --- a/.changeset/fluffy-moles-march.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/common": patch ---- - -- Remove need for tx queue in `createContract` diff --git a/.changeset/forty-weeks-laugh.md b/.changeset/forty-weeks-laugh.md deleted file mode 100644 index 138c16494f..0000000000 --- a/.changeset/forty-weeks-laugh.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Added salt to the `WorldDeployed` event. diff --git a/.changeset/four-coats-pull.md b/.changeset/four-coats-pull.md deleted file mode 100644 index 51578c77f9..0000000000 --- a/.changeset/four-coats-pull.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": major ---- - -Remove `TableId` library to simplify `store` package diff --git a/.changeset/four-hotels-serve.md b/.changeset/four-hotels-serve.md deleted file mode 100644 index b54a90adc6..0000000000 --- a/.changeset/four-hotels-serve.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/store-sync": major ---- - -Previously, all `store-sync` strategies were susceptible to a potential memory leak where the stream that fetches logs from the RPC would get ahead of the stream that stores the logs in the provided storage adapter. We saw this most often when syncing to remote Postgres servers, where inserting records was much slower than we retrieving them from the RPC. In these cases, the stream would build up a backlog of items until the machine ran out of memory. - -This is now fixed by waiting for logs to be stored before fetching the next batch of logs from the RPC. To make this strategy work, we no longer return `blockLogs$` (stream of logs fetched from RPC but before they're stored) and instead just return `storedBlockLogs$` (stream of logs fetched from RPC after they're stored). diff --git a/.changeset/fresh-scissors-unite.md b/.changeset/fresh-scissors-unite.md deleted file mode 100644 index bc4cc8fe8b..0000000000 --- a/.changeset/fresh-scissors-unite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/common": patch ---- - -Minor fix to resolving user types: `solc` doesn't like relative imports without `./`, but is fine with relative imports from `./../`, so we always append `./` to the relative path. diff --git a/.changeset/fresh-seals-compare.md b/.changeset/fresh-seals-compare.md deleted file mode 100644 index c52b85b20e..0000000000 --- a/.changeset/fresh-seals-compare.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/common": patch ---- - -The benchmark util now logs to `stdout` instead of `stderr`. diff --git a/.changeset/friendly-chefs-tease.md b/.changeset/friendly-chefs-tease.md deleted file mode 100644 index 225e3a69bc..0000000000 --- a/.changeset/friendly-chefs-tease.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/cli": patch -"create-mud": patch ---- - -Bumped `typescript` to `5.4.2`, `eslint` to `8.57.0`, and both `@typescript-eslint/eslint-plugin` and `@typescript-eslint/parser` to `7.1.1`. diff --git a/.changeset/funny-countries-hang.md b/.changeset/funny-countries-hang.md deleted file mode 100644 index 344273b83d..0000000000 --- a/.changeset/funny-countries-hang.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": minor ---- - -`registerRootFunctionSelector` now expects a `systemFunctionSignature` instead of a `systemFunctionSelector`. Internally, we compute the selector from the signature. This allows us to track system function signatures that are registered at the root so we can later generate ABIs for these systems. diff --git a/.changeset/funny-paws-admire.md b/.changeset/funny-paws-admire.md deleted file mode 100644 index 6cba8148f8..0000000000 --- a/.changeset/funny-paws-admire.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/services": patch ---- - -The build phase of services now works on machines with older protobuf compilers diff --git a/.changeset/fuzzy-cars-stare.md b/.changeset/fuzzy-cars-stare.md deleted file mode 100644 index 6ea8e90cf7..0000000000 --- a/.changeset/fuzzy-cars-stare.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -"@latticexyz/store": major -"@latticexyz/world": major ---- - -- The `onSetRecord` hook is split into `onBeforeSetRecord` and `onAfterSetRecord` and the `onDeleteRecord` hook is split into `onBeforeDeleteRecord` and `onAfterDeleteRecord`. - The purpose of this change is to allow more fine-grained control over the point in the lifecycle at which hooks are executed. - - The previous hooks were executed before modifying data, so they can be replaced with the respective `onBefore` hooks. - - ```diff - - function onSetRecord( - + function onBeforeSetRecord( - bytes32 table, - bytes32[] memory key, - bytes memory data, - Schema valueSchema - ) public; - - - function onDeleteRecord( - + function onBeforeDeleteRecord( - bytes32 table, - bytes32[] memory key, - Schema valueSchema - ) public; - ``` - -- It is now possible to specify which methods of a hook contract should be called when registering a hook. The purpose of this change is to save gas by avoiding to call no-op hook methods. - - ```diff - function registerStoreHook( - bytes32 tableId, - - IStoreHook hookAddress - + IStoreHook hookAddress, - + uint8 enabledHooksBitmap - ) public; - - function registerSystemHook( - bytes32 systemId, - - ISystemHook hookAddress - + ISystemHook hookAddress, - + uint8 enabledHooksBitmap - ) public; - ``` - - There are `StoreHookLib` and `SystemHookLib` with helper functions to encode the bitmap of enabled hooks. - - ```solidity - import { StoreHookLib } from "@latticexyz/store/src/StoreHook.sol"; - - uint8 storeHookBitmap = StoreBookLib.encodeBitmap({ - onBeforeSetRecord: true, - onAfterSetRecord: true, - onBeforeSetField: true, - onAfterSetField: true, - onBeforeDeleteRecord: true, - onAfterDeleteRecord: true - }); - ``` - - ```solidity - import { SystemHookLib } from "@latticexyz/world/src/SystemHook.sol"; - - uint8 systemHookBitmap = SystemHookLib.encodeBitmap({ - onBeforeCallSystem: true, - onAfterCallSystem: true - }); - ``` - -- The `onSetRecord` hook call for `emitEphemeralRecord` has been removed to save gas and to more clearly distinguish ephemeral tables as offchain tables. diff --git a/.changeset/fuzzy-chefs-wait.md b/.changeset/fuzzy-chefs-wait.md deleted file mode 100644 index 68ba41172e..0000000000 --- a/.changeset/fuzzy-chefs-wait.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Added explicit `internal` visibility to the `coreSystem` variable in `CoreModule`. diff --git a/.changeset/fuzzy-wombats-dream.md b/.changeset/fuzzy-wombats-dream.md deleted file mode 100644 index 6e789d5e94..0000000000 --- a/.changeset/fuzzy-wombats-dream.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Fixed `requireInterface` to correctly specify ERC165. diff --git a/.changeset/giant-masks-carry.md b/.changeset/giant-masks-carry.md deleted file mode 100644 index a29cb17c25..0000000000 --- a/.changeset/giant-masks-carry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-sync": patch ---- - -Adds `latestBlockNumber` and `lastBlockNumberProcessed` to internal `SyncProgress` component diff --git a/.changeset/gold-rings-switch.md b/.changeset/gold-rings-switch.md deleted file mode 100644 index 619de8ba77..0000000000 --- a/.changeset/gold-rings-switch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Parallelized table codegen. Also put logs behind debug flag, which can be enabled using the `DEBUG=mud:*` environment variable. diff --git a/.changeset/gold-wombats-add.md b/.changeset/gold-wombats-add.md deleted file mode 100644 index b1d4e32ea9..0000000000 --- a/.changeset/gold-wombats-add.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Removed `ROOT_NAMESPACE_STRING` and `ROOT_NAME_STRING` exports in favor of inlining these constants, to avoid reuse as they're meant for internal error messages and debugging. diff --git a/.changeset/gorgeous-swans-hide.md b/.changeset/gorgeous-swans-hide.md deleted file mode 100644 index 152184065c..0000000000 --- a/.changeset/gorgeous-swans-hide.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -"@latticexyz/world-modules": minor ---- - -Added the `ERC721Module` to `@latticexyz/world-modules`. -This module allows the registration of `ERC721` tokens in an existing World. - -Important note: this module has not been audited yet, so any production use is discouraged for now. - -````solidity -import { PuppetModule } from "@latticexyz/world-modules/src/modules/puppet/PuppetModule.sol"; -import { ERC721MetadataData } from "@latticexyz/world-modules/src/modules/erc721-puppet/tables/ERC721Metadata.sol"; -import { IERC721Mintable } from "@latticexyz/world-modules/src/modules/erc721-puppet/IERC721Mintable.sol"; -import { registerERC721 } from "@latticexyz/world-modules/src/modules/erc721-puppet/registerERC721.sol"; - -// The ERC721 module requires the Puppet module to be installed first -world.installModule(new PuppetModule(), new bytes(0)); - -// After the Puppet module is installed, new ERC721 tokens can be registered -IERC721Mintable token = registerERC721(world, "myERC721", ERC721MetadataData({ name: "Token", symbol: "TKN", baseURI: "" }));``` -```` diff --git a/.changeset/great-cooks-dream.md b/.changeset/great-cooks-dream.md deleted file mode 100644 index 60ae359c8e..0000000000 --- a/.changeset/great-cooks-dream.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -"@latticexyz/store-sync": patch ---- - -Add RECS sync strategy and corresponding utils - -```ts -import { createPublicClient, http } from 'viem'; -import { syncToRecs } from '@latticexyz/store-sync'; -import storeConfig from 'contracts/mud.config'; -import { defineContractComponents } from './defineContractComponents'; - -const publicClient = createPublicClient({ - chain, - transport: http(), - pollingInterval: 1000, -}); - -const { components, singletonEntity, latestBlock$, blockStorageOperations$, waitForTransaction } = await syncToRecs({ - world, - config: storeConfig, - address: '0x...', - publicClient, - components: defineContractComponents(...), -}); -``` diff --git a/.changeset/green-eggs-end.md b/.changeset/green-eggs-end.md deleted file mode 100644 index a72504825d..0000000000 --- a/.changeset/green-eggs-end.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/store": major -"@latticexyz/world": major ---- - -Set the protocol version to `2.0.0` for each Store and World. diff --git a/.changeset/green-moles-camp.md b/.changeset/green-moles-camp.md deleted file mode 100644 index 991eb247b5..0000000000 --- a/.changeset/green-moles-camp.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/common": patch ---- - -`resourceToLabel` now correctly returns just the resource name if its in the root namespace. diff --git a/.changeset/grumpy-files-heal.md b/.changeset/grumpy-files-heal.md deleted file mode 100644 index 1e72cd4b72..0000000000 --- a/.changeset/grumpy-files-heal.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -"@latticexyz/cli": major -"@latticexyz/protocol-parser": minor -"@latticexyz/store": major -"@latticexyz/world": major ---- - -- Add `FieldLayout`, which is a `bytes32` user-type similar to `Schema`. - - Both `FieldLayout` and `Schema` have the same kind of data in the first 4 bytes. - - - 2 bytes for total length of all static fields - - 1 byte for number of static size fields - - 1 byte for number of dynamic size fields - - But whereas `Schema` has `SchemaType` enum in each of the other 28 bytes, `FieldLayout` has static byte lengths in each of the other 28 bytes. - -- Replace `Schema valueSchema` with `FieldLayout fieldLayout` in Store and World contracts. - - `FieldLayout` is more gas-efficient because it already has lengths, and `Schema` has types which need to be converted to lengths. - -- Add `getFieldLayout` to `IStore` interface. - - There is no `FieldLayout` for keys, only for values, because key byte lengths aren't usually relevant on-chain. You can still use `getKeySchema` if you need key types. - -- Add `fieldLayoutToHex` utility to `protocol-parser` package. - -- Add `constants.sol` for constants shared between `FieldLayout`, `Schema` and `PackedCounter`. diff --git a/.changeset/grumpy-geckos-raise.md b/.changeset/grumpy-geckos-raise.md deleted file mode 100644 index 7a39454259..0000000000 --- a/.changeset/grumpy-geckos-raise.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"@latticexyz/cli": major -"@latticexyz/world": major ---- - -- All `World` function selectors that previously had `bytes16 namespace, bytes16 name` arguments now use `bytes32 resourceSelector` instead. - This includes `setRecord`, `setField`, `pushToField`, `popFromField`, `updateInField`, `deleteRecord`, `call`, `grantAccess`, `revokeAccess`, `registerTable`, - `registerStoreHook`, `registerSystemHook`, `registerFunctionSelector`, `registerSystem` and `registerRootFunctionSelector`. - This change aligns the `World` function selectors with the `Store` function selectors, reduces clutter, reduces gas cost and reduces the `World`'s contract size. - -- The `World`'s `registerHook` function is removed. Use `registerStoreHook` or `registerSystemHook` instead. - -- The `deploy` script is updated to integrate the World interface changes diff --git a/.changeset/grumpy-icons-sleep.md b/.changeset/grumpy-icons-sleep.md deleted file mode 100644 index c2fdabc713..0000000000 --- a/.changeset/grumpy-icons-sleep.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/world-modules": patch -"@latticexyz/world": patch ---- - -Added `isInstalled` and `requireNotInstalled` helpers to `Module` base contract. diff --git a/.changeset/happy-ants-lay.md b/.changeset/happy-ants-lay.md deleted file mode 100644 index 1f1ecb5a8d..0000000000 --- a/.changeset/happy-ants-lay.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/store": patch -"@latticexyz/world": patch ---- - -Refactored various files to specify integers in a hex base instead of decimals. diff --git a/.changeset/happy-pants-try.md b/.changeset/happy-pants-try.md deleted file mode 100644 index 3f2a70fc4d..0000000000 --- a/.changeset/happy-pants-try.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -"@latticexyz/world-modules": minor ---- - -Added the `PuppetModule` to `@latticexyz/world-modules`. The puppet pattern allows an external contract to be registered as an external interface for a MUD system. -This allows standards like `ERC20` (that require a specific interface and events to be emitted by a unique contract) to be implemented inside a MUD World. - -The puppet serves as a proxy, forwarding all calls to the implementation system (also called the "puppet master"). -The "puppet master" system can emit events from the puppet contract. - -```solidity -import { PuppetModule } from "@latticexyz/world-modules/src/modules/puppet/PuppetModule.sol"; -import { createPuppet } from "@latticexyz/world-modules/src/modules/puppet/createPuppet.sol"; - -// Install the puppet module -world.installModule(new PuppetModule(), new bytes(0)); - -// Register a new puppet for any system -// The system must implement the `CustomInterface`, -// and the caller must own the system's namespace -CustomInterface puppet = CustomInterface(createPuppet(world, )); -``` diff --git a/.changeset/happy-snails-sleep.md b/.changeset/happy-snails-sleep.md deleted file mode 100644 index 802b24b1f1..0000000000 --- a/.changeset/happy-snails-sleep.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@latticexyz/cli": minor -"@latticexyz/world": major ---- - -`WorldFactory` now expects a user-provided `salt` when calling `deployWorld(...)` (instead of the previous globally incrementing counter). This enables deterministic world addresses across different chains. - -When using `mud deploy`, you can provide a `bytes32` hex-encoded salt using the `--salt` option, otherwise it defaults to a random hex value. diff --git a/.changeset/healthy-items-deliver.md b/.changeset/healthy-items-deliver.md deleted file mode 100644 index 4844fd22ab..0000000000 --- a/.changeset/healthy-items-deliver.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/noise": patch ---- - -Removed the @latticexyz/noise package. diff --git a/.changeset/heavy-eyes-smile.md b/.changeset/heavy-eyes-smile.md deleted file mode 100644 index f5508a6445..0000000000 --- a/.changeset/heavy-eyes-smile.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": patch ---- - -Deploys now continue if they detect a `Module_AlreadyInstalled` revert error. diff --git a/.changeset/heavy-rings-punch.md b/.changeset/heavy-rings-punch.md deleted file mode 100644 index 15681411a7..0000000000 --- a/.changeset/heavy-rings-punch.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/common": patch -"create-mud": patch ---- - -Pinned prettier-plugin-solidity version to 1.1.3 diff --git a/.changeset/heavy-shirts-dance.md b/.changeset/heavy-shirts-dance.md deleted file mode 100644 index 6317deb7f4..0000000000 --- a/.changeset/heavy-shirts-dance.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Added interfaces for all errors that are used by `StoreCore`, which includes `FieldLayout`, `PackedCounter`, `Schema`, and `Slice`. This interfaces are inherited by `IStore`, ensuring that all possible errors are included in the `IStore` ABI for proper decoding in the frontend. diff --git a/.changeset/hip-files-sin.md b/.changeset/hip-files-sin.md deleted file mode 100644 index d23a2f6866..0000000000 --- a/.changeset/hip-files-sin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-sync": major ---- - -`syncToZustand` now uses `tables` argument to populate the Zustand store's `tables` key, rather than the on-chain table registration events. This means we'll no longer store data into Zustand you haven't opted into receiving (e.g. other namespaces). diff --git a/.changeset/hip-tables-check.md b/.changeset/hip-tables-check.md deleted file mode 100644 index 704341d407..0000000000 --- a/.changeset/hip-tables-check.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"@latticexyz/store": major -"@latticexyz/world": major ---- - -Store's `getRecord` has been updated to return `staticData`, `encodedLengths`, and `dynamicData` instead of a single `data` blob, to match the new behaviour of Store setter methods. - -If you use codegenerated libraries, you will only need to update `encode` calls. - -```diff -- bytes memory data = Position.encode(x, y); -+ (bytes memory staticData, PackedCounter encodedLengths, bytes memory dynamicData) = Position.encode(x, y); -``` diff --git a/.changeset/honest-geckos-refuse.md b/.changeset/honest-geckos-refuse.md deleted file mode 100644 index b8b8932dd1..0000000000 --- a/.changeset/honest-geckos-refuse.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Updated codegen to not render `push` and `pop` methods for static arrays. The `length` method now returns the hardcoded known length instead of calculating it like with a dynamic array. diff --git a/.changeset/honest-months-boil.md b/.changeset/honest-months-boil.md deleted file mode 100644 index 613cd6e4e2..0000000000 --- a/.changeset/honest-months-boil.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -"@latticexyz/cli": major -"@latticexyz/world": major ---- - -The `registerRootFunctionSelector` function's signature was changed to accept a `string functionSignature` parameter instead of a `bytes4 functionSelector` parameter. -This change enables the `World` to store the function signatures of all registered functions in a `FunctionSignatures` offchain table, which will allow for the automatic generation of interfaces for a given `World` address in the future. - -```diff -IBaseWorld { - function registerRootFunctionSelector( - ResourceId systemId, -- bytes4 worldFunctionSelector, -+ string memory worldFunctionSignature, - bytes4 systemFunctionSelector - ) external returns (bytes4 worldFunctionSelector); -} -``` diff --git a/.changeset/honest-singers-tickle.md b/.changeset/honest-singers-tickle.md deleted file mode 100644 index fe5e6a9cdb..0000000000 --- a/.changeset/honest-singers-tickle.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/protocol-parser": major -"@latticexyz/schema-type": major ---- - -Moved all existing exports to a `/internal` import path to indicate that these are now internal-only and deprecated. We'll be replacing these types and functions with new ones that are compatible with our new, strongly-typed config. diff --git a/.changeset/hot-mice-play.md b/.changeset/hot-mice-play.md deleted file mode 100644 index defaa99a25..0000000000 --- a/.changeset/hot-mice-play.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/store": patch -"@latticexyz/world": patch ---- - -The `FieldLayout` in table libraries is now generated at compile time instead of dynamically in a table library function. -This significantly reduces gas cost in all table library functions. diff --git a/.changeset/hungry-rings-doubt.md b/.changeset/hungry-rings-doubt.md deleted file mode 100644 index d5d3ac9263..0000000000 --- a/.changeset/hungry-rings-doubt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Added `Storage.loadField` to optimize loading 32 bytes or less from storage (which is always the case when loading data for static fields). diff --git a/.changeset/itchy-kids-relax.md b/.changeset/itchy-kids-relax.md deleted file mode 100644 index efe5c84533..0000000000 --- a/.changeset/itchy-kids-relax.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/protocol-parser": patch ---- - -`decodeRecord` now properly decodes empty records diff --git a/.changeset/itchy-shoes-appear.md b/.changeset/itchy-shoes-appear.md deleted file mode 100644 index c6e862d475..0000000000 --- a/.changeset/itchy-shoes-appear.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/store-indexer": minor -"@latticexyz/store-sync": minor ---- - -- Accept a plain viem `PublicClient` (instead of requiring a `Chain` to be set) in `store-sync` and `store-indexer` functions. These functions now fetch chain ID using `publicClient.getChainId()` when no `publicClient.chain.id` is present. -- Allow configuring `store-indexer` with a set of RPC URLs (`RPC_HTTP_URL` and `RPC_WS_URL`) instead of `CHAIN_ID`. diff --git a/.changeset/khaki-cars-suffer.md b/.changeset/khaki-cars-suffer.md deleted file mode 100644 index 84ded1f01e..0000000000 --- a/.changeset/khaki-cars-suffer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-mud": minor ---- - -Replaced usage of `window` global in vanilla JS template with an event listener on the button. diff --git a/.changeset/khaki-doors-refuse.md b/.changeset/khaki-doors-refuse.md deleted file mode 100644 index 5220a732db..0000000000 --- a/.changeset/khaki-doors-refuse.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/ecs-browser": major ---- - -Removes `ecs-browser` package. This has now been replaced by `dev-tools`, which comes out-of-the-box when creating a new MUD app from the templates (`pnpm create mud@next your-app-name`). We'll be adding deeper RECS support (querying for entities) in a future release. diff --git a/.changeset/khaki-houses-whisper.md b/.changeset/khaki-houses-whisper.md deleted file mode 100644 index ff2aa39534..0000000000 --- a/.changeset/khaki-houses-whisper.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -"@latticexyz/world": minor ---- - -It is now possible for namespace owners to register a fallback delegation control system for the namespace. -This fallback delegation control system is used to verify a delegation in `IBaseWorld.callFrom`, after the user's individual and fallback delegations have been checked. - -```solidity -IBaseWorld { - function registerNamespaceDelegation( - ResourceId namespaceId, - ResourceId delegationControlId, - bytes memory initCallData - ) external; -} -``` diff --git a/.changeset/khaki-months-add.md b/.changeset/khaki-months-add.md deleted file mode 100644 index 6fc17eed60..0000000000 --- a/.changeset/khaki-months-add.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-sync": patch ---- - -`createStoreSync` now correctly creates table registration logs from indexer records. diff --git a/.changeset/large-drinks-sell.md b/.changeset/large-drinks-sell.md deleted file mode 100644 index eaa9b5c5f2..0000000000 --- a/.changeset/large-drinks-sell.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/store": patch -"@latticexyz/world": patch ---- - -Prefixed all errors with their respective library/contract for improved debugging. diff --git a/.changeset/large-hats-walk.md b/.changeset/large-hats-walk.md deleted file mode 100644 index f8485a09aa..0000000000 --- a/.changeset/large-hats-walk.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Align Store events parameter naming between IStoreWrite and StoreCore diff --git a/.changeset/large-hounds-type.md b/.changeset/large-hounds-type.md deleted file mode 100644 index 16996091bb..0000000000 --- a/.changeset/large-hounds-type.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@latticexyz/store-indexer": major ---- - -Separated frontend server and indexer service for Postgres indexer. Now you can run the Postgres indexer with one writer and many readers. - -If you were previously using the `postgres-indexer` binary, you'll now need to run both `postgres-indexer` and `postgres-frontend`. - -For consistency, the Postgres database logs are now disabled by default. If you were using these, please let us know so we can add them back in with an environment variable flag. diff --git a/.changeset/large-nails-suffer.md b/.changeset/large-nails-suffer.md deleted file mode 100644 index 2c62989f95..0000000000 --- a/.changeset/large-nails-suffer.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -"@latticexyz/block-logs-stream": patch -"@latticexyz/cli": patch -"@latticexyz/common": patch -"@latticexyz/dev-tools": patch -"@latticexyz/faucet": patch -"@latticexyz/protocol-parser": patch -"@latticexyz/schema-type": patch -"@latticexyz/store-indexer": patch -"@latticexyz/store-sync": patch -"@latticexyz/store": patch -"create-mud": patch ---- - -Bump viem to 1.14.0 and abitype to 0.9.8 diff --git a/.changeset/large-schools-grow.md b/.changeset/large-schools-grow.md deleted file mode 100644 index 187ba97b21..0000000000 --- a/.changeset/large-schools-grow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-indexer": patch ---- - -Added a Sentry middleware and `SENTRY_DNS` environment variable to the postgres indexer. diff --git a/.changeset/large-sloths-camp.md b/.changeset/large-sloths-camp.md deleted file mode 100644 index 7113467253..0000000000 --- a/.changeset/large-sloths-camp.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -"@latticexyz/common": minor ---- - -`createContract` now has an `onWrite` callback so you can observe writes. This is useful for wiring up the transanction log in MUD dev tools. - -```ts -import { createContract, ContractWrite } from "@latticexyz/common"; -import { Subject } from "rxjs"; - -const write$ = new Subject(); -creactContract({ - ... - onWrite: (write) => write$.next(write), -}); -``` diff --git a/.changeset/late-cobras-ring.md b/.changeset/late-cobras-ring.md deleted file mode 100644 index bcbc955d10..0000000000 --- a/.changeset/late-cobras-ring.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -`World` now correctly registers the `FunctionSignatures` table. diff --git a/.changeset/late-geese-guess.md b/.changeset/late-geese-guess.md deleted file mode 100644 index 2b75a94590..0000000000 --- a/.changeset/late-geese-guess.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/world": major ---- - -The `SnapSyncModule` is removed. The recommended way of loading the initial state of a MUD app is via the new [`store-indexer`](https://mud.dev/indexer). Loading state via contract getter functions is not recommended, as it's computationally heavy on the RPC, can't be cached, and is an easy way to shoot yourself in the foot with exploding RPC costs. - -The `@latticexyz/network` package was deprecated and is now removed. All consumers should upgrade to the new sync stack from `@latticexyz/store-sync`. diff --git a/.changeset/late-rats-hide.md b/.changeset/late-rats-hide.md deleted file mode 100644 index 32b4d451ec..0000000000 --- a/.changeset/late-rats-hide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Added the WorldContextConsumer interface ID to `supportsInterface` in the Module contract. diff --git a/.changeset/late-spies-cover.md b/.changeset/late-spies-cover.md deleted file mode 100644 index 08f509a719..0000000000 --- a/.changeset/late-spies-cover.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Optimize autogenerated table libraries diff --git a/.changeset/lazy-chicken-happen.md b/.changeset/lazy-chicken-happen.md deleted file mode 100644 index 1929ec7175..0000000000 --- a/.changeset/lazy-chicken-happen.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/common": patch ---- - -Moved the transaction simulation step to just before sending the transaction in our transaction queue actions (`sendTransaction` and `writeContract`). - -This helps avoid cascading transaction failures for deep queues or when a transaction succeeding depends on the value of the previous. diff --git a/.changeset/lazy-foxes-applaud.md b/.changeset/lazy-foxes-applaud.md deleted file mode 100644 index 9713f4a8bb..0000000000 --- a/.changeset/lazy-foxes-applaud.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Systems are expected to be always called via the central World contract. -Depending on whether it is a root or non-root system, the call is performed via `delegatecall` or `call`. -Since Systems are expected to be stateless and only interact with the World state, it is not necessary to prevent direct calls to the systems. -However, since the `CoreSystem` is known to always be registered as a root system in the World, it is always expected to be delegatecalled, -so we made this expectation explicit by reverting if it is not delegatecalled. diff --git a/.changeset/lazy-ladybugs-return.md b/.changeset/lazy-ladybugs-return.md deleted file mode 100644 index d02d9e3454..0000000000 --- a/.changeset/lazy-ladybugs-return.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/common": minor ---- - -- adds `defaultPriorityFee` to `mudFoundry` for better support with MUD's default anvil config and removes workaround in `createContract` -- improves nonce error detection using viem's custom errors diff --git a/.changeset/lemon-falcons-arrive.md b/.changeset/lemon-falcons-arrive.md deleted file mode 100644 index 4a5987f7d3..0000000000 --- a/.changeset/lemon-falcons-arrive.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Restored `Bytes.sliceN` helpers that were previously (mistakenly) removed and renamed them to `Bytes.getBytesN`. - -If you're upgrading an existing MUD project, you can rerun codegen with `mud build` to update your table libraries to the new function names. diff --git a/.changeset/lemon-numbers-design.md b/.changeset/lemon-numbers-design.md deleted file mode 100644 index 4834070a8f..0000000000 --- a/.changeset/lemon-numbers-design.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-sync": patch ---- - -Moved boolean array types to use array column types (instead of JSON columns) for the Postgres decoded indexer diff --git a/.changeset/lemon-zoos-mate.md b/.changeset/lemon-zoos-mate.md deleted file mode 100644 index bd9a2948c5..0000000000 --- a/.changeset/lemon-zoos-mate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-mud": minor ---- - -Enabled MUD CLI debug logs for all templates. diff --git a/.changeset/light-bananas-deny.md b/.changeset/light-bananas-deny.md deleted file mode 100644 index eb5a52e83f..0000000000 --- a/.changeset/light-bananas-deny.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": patch ---- - -Added `--worldAddress` argument to `dev-contracts` CLI command so that you can develop against an existing world. diff --git a/.changeset/light-carrots-applaud.md b/.changeset/light-carrots-applaud.md deleted file mode 100644 index fc90e67cbb..0000000000 --- a/.changeset/light-carrots-applaud.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world-modules": minor ---- - -Fixed `SystemSwitch` to properly call non-root systems from root systems. diff --git a/.changeset/little-cherries-rule.md b/.changeset/little-cherries-rule.md deleted file mode 100644 index 58bc920e71..0000000000 --- a/.changeset/little-cherries-rule.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Made the `coreModule` variable in `WorldFactory` immutable. diff --git a/.changeset/little-cobras-yell.md b/.changeset/little-cobras-yell.md deleted file mode 100644 index 0f2a769f5e..0000000000 --- a/.changeset/little-cobras-yell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Removed the unnecessary `extcodesize` check from the `Create2` library. diff --git a/.changeset/little-ravens-yawn.md b/.changeset/little-ravens-yawn.md deleted file mode 100644 index b099e16722..0000000000 --- a/.changeset/little-ravens-yawn.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/protocol-parser": major -"@latticexyz/services": major -"@latticexyz/store-sync": major -"@latticexyz/store": major -"@latticexyz/world": patch ---- - -Reverse PackedCounter encoding, to optimize gas for bitshifts. -Ints are right-aligned, shifting using an index is straightforward if they are indexed right-to-left. - -- Previous encoding: (7 bytes | accumulator),(5 bytes | counter 1),...,(5 bytes | counter 5) -- New encoding: (5 bytes | counter 5),...,(5 bytes | counter 1),(7 bytes | accumulator) diff --git a/.changeset/long-dots-think.md b/.changeset/long-dots-think.md deleted file mode 100644 index 01466a1e42..0000000000 --- a/.changeset/long-dots-think.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-sync": patch ---- - -Moved numerical array types to use array column types (instead of JSON columns) for the Postgres decoded indexer diff --git a/.changeset/long-lizards-admire.md b/.changeset/long-lizards-admire.md deleted file mode 100644 index c9dd656258..0000000000 --- a/.changeset/long-lizards-admire.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/abi-ts": patch ---- - -Let `glob` handle resolving the glob against the current working directory. diff --git a/.changeset/long-tips-marry.md b/.changeset/long-tips-marry.md deleted file mode 100644 index 0c56ca0825..0000000000 --- a/.changeset/long-tips-marry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-indexer": patch ---- - -Replaced Fastify with Koa for store-indexer frontends diff --git a/.changeset/loud-mayflies-divide.md b/.changeset/loud-mayflies-divide.md deleted file mode 100644 index a255e5539b..0000000000 --- a/.changeset/loud-mayflies-divide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": patch ---- - -Changed deploy order so that system/module contracts are fully deployed before registering/installing them on the world. diff --git a/.changeset/loud-rockets-switch.md b/.changeset/loud-rockets-switch.md deleted file mode 100644 index 2e80de7d69..0000000000 --- a/.changeset/loud-rockets-switch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/common": patch ---- - -Upgraded prettier version to 3.2.5 and prettier-plugin-solidity version to 1.3.1. diff --git a/.changeset/lovely-bobcats-joke.md b/.changeset/lovely-bobcats-joke.md deleted file mode 100644 index d7a8ef0c62..0000000000 --- a/.changeset/lovely-bobcats-joke.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/store": patch -"@latticexyz/world": patch ---- - -Added an explicit package export for `mud.config` diff --git a/.changeset/lovely-buses-boil.md b/.changeset/lovely-buses-boil.md deleted file mode 100644 index 497c52749c..0000000000 --- a/.changeset/lovely-buses-boil.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Remove a workaround for the internal `InstalledModules` table that is not needed anymore. diff --git a/.changeset/lovely-fireants-behave.md b/.changeset/lovely-fireants-behave.md deleted file mode 100644 index 6e6968e1ca..0000000000 --- a/.changeset/lovely-fireants-behave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Renamed all `funcSelectorAndArgs` arguments to `callData` for clarity. diff --git a/.changeset/lucky-clocks-love.md b/.changeset/lucky-clocks-love.md deleted file mode 100644 index f2475d3d8f..0000000000 --- a/.changeset/lucky-clocks-love.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/cli": major ---- - -Removes `.mudbackup` file handling and `--backup`, `--restore`, and `--force` options from `mud set-version` command. - -To revert to a previous MUD version, use `git diff` to find the version that you changed from and want to revert to and run `pnpm mud set-version ` again. diff --git a/.changeset/many-phones-study.md b/.changeset/many-phones-study.md deleted file mode 100644 index 4c0f87d7f6..0000000000 --- a/.changeset/many-phones-study.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -"@latticexyz/protocol-parser": minor ---- - -feat: add `encodeKeyTuple`, a util to encode key tuples in Typescript (equivalent to key tuple encoding in Solidity and inverse of `decodeKeyTuple`). -Example: - -```ts -encodeKeyTuple({ staticFields: ["uint256", "int32", "bytes16", "address", "bool", "int8"], dynamicFields: [] }, [ - 42n, - -42, - "0x12340000000000000000000000000000", - "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF", - true, - 3, -]); -// [ -// "0x000000000000000000000000000000000000000000000000000000000000002a", -// "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd6", -// "0x1234000000000000000000000000000000000000000000000000000000000000", -// "0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff", -// "0x0000000000000000000000000000000000000000000000000000000000000001", -// "0x0000000000000000000000000000000000000000000000000000000000000003", -// ] -``` diff --git a/.changeset/many-pumpkins-cry.md b/.changeset/many-pumpkins-cry.md deleted file mode 100644 index f8df074d2e..0000000000 --- a/.changeset/many-pumpkins-cry.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -"@latticexyz/store": major -"@latticexyz/world": major ---- - -Store and World contract ABIs are now exported from the `out` directory. You'll need to update your imports like: - -```diff -- import IBaseWorldAbi from "@latticexyz/world/abi/IBaseWorld.sol/IBaseWorldAbi.json"; -+ import IBaseWorldAbi from "@latticexyz/world/out/IBaseWorld.sol/IBaseWorldAbi.json"; -``` - -`MudTest.sol` was also moved to the World package. You can update your import like: - -```diff -- import { MudTest } from "@latticexyz/store/src/MudTest.sol"; -+ import { MudTest } from "@latticexyz/world/test/MudTest.t.sol"; -``` diff --git a/.changeset/mean-islands-brake.md b/.changeset/mean-islands-brake.md deleted file mode 100644 index 10d43a1386..0000000000 --- a/.changeset/mean-islands-brake.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/faucet": patch -"@latticexyz/store-indexer": patch ---- - -Improves error message when parsing env variables diff --git a/.changeset/mean-pans-study.md b/.changeset/mean-pans-study.md deleted file mode 100644 index 96f3a51a21..0000000000 --- a/.changeset/mean-pans-study.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/std-client": patch ---- - -Generated `contractComponents` now properly import `World` as type diff --git a/.changeset/mean-seals-nail.md b/.changeset/mean-seals-nail.md deleted file mode 100644 index 7ac373d827..0000000000 --- a/.changeset/mean-seals-nail.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -"@latticexyz/world": patch -"@latticexyz/store": patch ---- - -The `ResourceType` table is removed. -It was previously used to store the resource type for each resource ID in a `World`. This is no longer necessary as the [resource type is now encoded in the resource ID](https://github.com/latticexyz/mud/pull/1544). - -To still be able to determine whether a given resource ID exists, a `ResourceIds` table has been added. -The previous `ResourceType` table was part of `World` and missed tables that were registered directly via `StoreCore.registerTable` instead of via `World.registerTable` (e.g. when a table was registered as part of a root module). -This problem is solved by the new table `ResourceIds` being part of `Store`. - -`StoreCore`'s `hasTable` function was removed in favor of using `ResourceIds.getExists(tableId)` directly. - -```diff -- import { ResourceType } from "@latticexyz/world/src/tables/ResourceType.sol"; -- import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; -+ import { ResourceIds } from "@latticexyz/store/src/codegen/tables/ResourceIds.sol"; - -- bool tableExists = StoreCore.hasTable(tableId); -+ bool tableExists = ResourceIds.getExists(tableId); - -- bool systemExists = ResourceType.get(systemId) != Resource.NONE; -+ bool systemExists = ResourceIds.getExists(systemId); -``` diff --git a/.changeset/metal-cats-double.md b/.changeset/metal-cats-double.md deleted file mode 100644 index 12b14bbca5..0000000000 --- a/.changeset/metal-cats-double.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -"@latticexyz/store-sync": patch ---- - -Add `startBlock` option to `syncToRecs`. - -```ts -import { syncToRecs } from "@latticexyz/store-sync/recs"; -import worlds from "contracts/worlds.json"; - -syncToRecs({ - startBlock: worlds['31337'].blockNumber, - ... -}); -``` diff --git a/.changeset/metal-hounds-drum.md b/.changeset/metal-hounds-drum.md deleted file mode 100644 index f041da2353..0000000000 --- a/.changeset/metal-hounds-drum.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -"@latticexyz/block-logs-stream": patch -"@latticexyz/store-sync": patch -"@latticexyz/store": patch ---- - -Renamed all occurrences of `table` where it is used as "table ID" to `tableId`. -This is only a breaking change for consumers who manually decode `Store` events, but not for consumers who use the MUD libraries. - -```diff -event StoreSetRecord( -- bytes32 table, -+ bytes32 tableId, - bytes32[] key, - bytes data -); - -event StoreSetField( -- bytes32 table, -+ bytes32 tableId, - bytes32[] key, - uint8 fieldIndex, - bytes data -); - -event StoreDeleteRecord( -- bytes32 table, -+ bytes32 tableId, - bytes32[] key -); - -event StoreEphemeralRecord( -- bytes32 table, -+ bytes32 tableId, - bytes32[] key, - bytes data -); -``` diff --git a/.changeset/metal-pots-notice.md b/.changeset/metal-pots-notice.md deleted file mode 100644 index 37e977d7bc..0000000000 --- a/.changeset/metal-pots-notice.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/cli": minor ---- - -Added a `--alwaysRunPostDeploy` flag to deploys (`deploy`, `test`, `dev-contracts` commands) to always run `PostDeploy.s.sol` script after each deploy. By default, `PostDeploy.s.sol` is only run once after a new world is deployed. - -This is helpful if you want to continue a deploy that may not have finished (due to an error or otherwise) or to run deploys with an idempotent `PostDeploy.s.sol` script. diff --git a/.changeset/metal-wombats-judge.md b/.changeset/metal-wombats-judge.md deleted file mode 100644 index dadfcaf8ed..0000000000 --- a/.changeset/metal-wombats-judge.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/store-cache": major ---- - -Removes `store-cache` package. Please see the [changelog](https://mud.dev/changelog) for how to migrate your app to the new `store-sync` package. Or create a new project from an up-to-date template with `pnpm create mud@next your-app-name`. - -If you need reactivity, we recommend using `recs` package and `syncToRecs`. We'll be adding reactivity to `syncToSqlite` in a future release. diff --git a/.changeset/mighty-eels-type.md b/.changeset/mighty-eels-type.md deleted file mode 100644 index dd807d4bae..0000000000 --- a/.changeset/mighty-eels-type.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -"@latticexyz/world": major ---- - -- The access control library no longer allows calls by the `World` contract to itself to bypass the ownership check. - This is a breaking change for root modules that relied on this mechanism to register root tables, systems or function selectors. - To upgrade, root modules must use `delegatecall` instead of a regular `call` to install root tables, systems or function selectors. - - ```diff - - world.registerSystem(rootSystemId, rootSystemAddress); - + address(world).delegatecall(abi.encodeCall(world.registerSystem, (rootSystemId, rootSystemAddress))); - ``` - -- An `installRoot` method was added to the `IModule` interface. - This method is now called when installing a root module via `world.installRootModule`. - When installing non-root modules via `world.installModule`, the module's `install` function continues to be called. diff --git a/.changeset/mighty-points-study.md b/.changeset/mighty-points-study.md deleted file mode 100644 index 7d9844fffe..0000000000 --- a/.changeset/mighty-points-study.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": patch ---- - -Fixed registration of world signatures/selectors for namespaced systems. We changed these signatures in [#2160](https://github.com/latticexyz/mud/pull/2160), but missed updating part of the deploy step. diff --git a/.changeset/mighty-years-whisper.md b/.changeset/mighty-years-whisper.md deleted file mode 100644 index 5f684cdebf..0000000000 --- a/.changeset/mighty-years-whisper.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-mud": patch ---- - -Templates now correctly include their respective `.gitignore` files diff --git a/.changeset/modern-bikes-build.md b/.changeset/modern-bikes-build.md deleted file mode 100644 index 62245c397a..0000000000 --- a/.changeset/modern-bikes-build.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/block-logs-stream": minor -"@latticexyz/store-sync": minor ---- - -- Replace `blockEventsToStorage` with `blockLogsToStorage` that exposes a `storeOperations` callback to perform database writes from store operations. This helps encapsulates database adapters into a single wrapper/instance of `blockLogsToStorage` and allows for wrapping a block of store operations in a database transaction. -- Add `toBlock` option to `groupLogsByBlockNumber` and remove `blockHash` from results. This helps track the last block number for a given set of logs when used in the context of RxJS streams. diff --git a/.changeset/modern-brooms-rule.md b/.changeset/modern-brooms-rule.md deleted file mode 100644 index ecc2abe9f9..0000000000 --- a/.changeset/modern-brooms-rule.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/world-modules": patch -"@latticexyz/world": major ---- - -Previously `registerSystem` and `registerTable` had a side effect of registering namespaces if the system or table's namespace didn't exist yet. -This caused a possible frontrunning issue, where an attacker could detect a `registerSystem`/`registerTable` transaction in the mempool, -insert a `registerNamespace` transaction before it, grant themselves access to the namespace, transfer ownership of the namespace to the victim, -so that the `registerSystem`/`registerTable` transactions still went through successfully. -To mitigate this issue, the side effect of registering a namespace in `registerSystem` and `registerTable` has been removed. -Calls to these functions now expect the respective namespace to exist and the caller to own the namespace, otherwise they revert. - -Changes in consuming projects are only necessary if tables or systems are registered manually. -If only the MUD deployer is used to register tables and systems, no changes are necessary, as the MUD deployer has been updated accordingly. - -```diff -+ world.registerNamespace(namespaceId); - world.registerSystem(systemId, system, true); -``` - -```diff -+ world.registerNamespace(namespaceId); - MyTable.register(); -``` diff --git a/.changeset/modern-hornets-jam.md b/.changeset/modern-hornets-jam.md deleted file mode 100644 index 3b4440ce83..0000000000 --- a/.changeset/modern-hornets-jam.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -"@latticexyz/cli": major -"@latticexyz/store": major -"@latticexyz/world": major -"@latticexyz/store-sync": major -"create-mud": patch ---- - -- `Store`'s internal schema table is now a normal table instead of using special code paths. It is renamed to Tables, and the table ID changed from `mudstore:schema` to `mudstore:Tables` -- `Store`'s `registerSchema` and `setMetadata` are combined into a single `registerTable` method. This means metadata (key names, field names) is immutable and indexers can create tables with this metadata when a new table is registered on-chain. - - ```diff - - function registerSchema(bytes32 table, Schema schema, Schema keySchema) external; - - - - function setMetadata(bytes32 table, string calldata tableName, string[] calldata fieldNames) external; - - + function registerTable( - + bytes32 table, - + Schema keySchema, - + Schema valueSchema, - + string[] calldata keyNames, - + string[] calldata fieldNames - + ) external; - ``` - -- `World`'s `registerTable` method is updated to match the `Store` interface, `setMetadata` is removed -- The `getSchema` method is renamed to `getValueSchema` on all interfaces - ```diff - - function getSchema(bytes32 table) external view returns (Schema schema); - + function getValueSchema(bytes32 table) external view returns (Schema valueSchema); - ``` -- The `store-sync` and `cli` packages are updated to integrate the breaking protocol changes. Downstream projects only need to manually integrate these changes if they access low level `Store` or `World` functions. Otherwise, a fresh deploy with the latest MUD will get you these changes. diff --git a/.changeset/modern-impalas-stare.md b/.changeset/modern-impalas-stare.md deleted file mode 100644 index 25eaa7c27f..0000000000 --- a/.changeset/modern-impalas-stare.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/world-modules": patch -"@latticexyz/store": patch -"@latticexyz/world": patch ---- - -Refactored `ResourceId` to use a global Solidity `using` statement. diff --git a/.changeset/modern-stingrays-kneel.md b/.changeset/modern-stingrays-kneel.md deleted file mode 100644 index 1784852178..0000000000 --- a/.changeset/modern-stingrays-kneel.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -"@latticexyz/world-modules": minor ---- - -Since [#1564](https://github.com/latticexyz/mud/pull/1564) the World can no longer call itself via an external call. -This made the developer experience of calling other systems via root systems worse, since calls from root systems are executed from the context of the World. -The recommended approach is to use `delegatecall` to the system if in the context of a root system, and an external call via the World if in the context of a non-root system. -To bring back the developer experience of calling systems from other sysyems without caring about the context in which the call is executed, we added the `SystemSwitch` util. - -```diff -- // Instead of calling the system via an external call to world... -- uint256 value = IBaseWorld(_world()).callMySystem(); - -+ // ...you can now use the `SystemSwitch` util. -+ // This works independent of whether used in a root system or non-root system. -+ uint256 value = abi.decode(SystemSwitch.call(abi.encodeCall(IBaseWorld.callMySystem, ()), (uint256)); -``` - -Note that if you already know your system is always executed as non-root system, you can continue to use the approach of calling other systems via the `IBaseWorld(world)`. diff --git a/.changeset/modern-trains-remain.md b/.changeset/modern-trains-remain.md deleted file mode 100644 index 8e5ad16e7c..0000000000 --- a/.changeset/modern-trains-remain.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -"create-mud": minor ---- - -Templates now use `out` for their `forge build` artifacts, including ABIs. If you have a project created from a previous template, you can update your `packages/contracts/package.json` with: - -```diff -- "build:abi": "rimraf abi && forge build --extra-output-files abi --out abi --skip test script MudTest.sol", -- "build:abi-ts": "mud abi-ts --input 'abi/IWorld.sol/IWorld.abi.json' && prettier --write '**/*.abi.json.d.ts'", -+ "build:abi": "forge clean && forge build --skip test script", -+ "build:abi-ts": "mud abi-ts && prettier --write '**/*.abi.json.d.ts'", -``` - -And your `packages/client/src/mud/setupNetwork` with: - -```diff -- import IWorldAbi from "contracts/abi/IWorld.sol/IWorld.abi.json"; -+ import IWorldAbi from "contracts/out/IWorld.sol/IWorld.abi.json"; -``` diff --git a/.changeset/moody-shirts-carry.md b/.changeset/moody-shirts-carry.md deleted file mode 100644 index c6f1943f1b..0000000000 --- a/.changeset/moody-shirts-carry.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -"@latticexyz/common": minor -"create-mud": minor ---- - -Added viem custom client actions that work the same as MUD's now-deprecated `getContract`, `writeContract`, and `sendTransaction` wrappers. Templates have been updated to reflect the new patterns. - -You can migrate your own code like this: - -```diff --import { createWalletClient } from "viem"; --import { getContract, writeContract, sendTransaction } from "@latticexyz/common"; -+import { createWalletClient, getContract } from "viem"; -+import { transactionQueue, writeObserver } from "@latticexyz/common/actions"; - --const walletClient = createWalletClient(...); -+const walletClient = createWalletClient(...) -+ .extend(transactionQueue()) -+ .extend(writeObserver({ onWrite }); - - const worldContract = getContract({ - client: { publicClient, walletClient }, -- onWrite, - }); -``` diff --git a/.changeset/nasty-crabs-explode.md b/.changeset/nasty-crabs-explode.md deleted file mode 100644 index ace769e3b6..0000000000 --- a/.changeset/nasty-crabs-explode.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": patch ---- - -Deploy commands (`deploy`, `dev-contracts`, `test`) now correctly run `worldgen` to generate system interfaces before deploying. diff --git a/.changeset/nasty-owls-sneeze.md b/.changeset/nasty-owls-sneeze.md deleted file mode 100644 index 1903b2aa4c..0000000000 --- a/.changeset/nasty-owls-sneeze.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/world-modules": patch -"@latticexyz/store": patch -"@latticexyz/world": patch ---- - -Refactored EIP165 usages to use the built-in interfaceId property instead of pre-defined constants. diff --git a/.changeset/nasty-rice-pull.md b/.changeset/nasty-rice-pull.md deleted file mode 100644 index d45fe7daea..0000000000 --- a/.changeset/nasty-rice-pull.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-sync": minor ---- - -`createStoreSync` now [waits for idle](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback) between each chunk of logs in a block to allow for downstream render cycles to trigger. This means that hydrating logs from an indexer will no longer block until hydration completes, but rather allow for `onProgress` callbacks to trigger. diff --git a/.changeset/nasty-trains-drop.md b/.changeset/nasty-trains-drop.md deleted file mode 100644 index 59f010c24e..0000000000 --- a/.changeset/nasty-trains-drop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": patch ---- - -Refactor `deploy` command to break up logic into modules diff --git a/.changeset/nasty-waves-divide.md b/.changeset/nasty-waves-divide.md deleted file mode 100644 index 61ac31054c..0000000000 --- a/.changeset/nasty-waves-divide.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -"@latticexyz/block-logs-stream": minor ---- - -Add block logs stream package - -```ts -import { filter, map, mergeMap } from "rxjs"; -import { createPublicClient, parseAbi } from "viem"; -import { - createBlockStream, - isNonPendingBlock, - groupLogsByBlockNumber, - blockRangeToLogs, -} from "@latticexyz/block-logs-stream"; - -const publicClient = createPublicClient({ - // your viem public client config here -}); - -const latestBlock$ = await createBlockStream({ publicClient, blockTag: "latest" }); - -const latestBlockNumber$ = latestBlock$.pipe( - filter(isNonPendingBlock), - map((block) => block.number), -); - -latestBlockNumber$ - .pipe( - map((latestBlockNumber) => ({ startBlock: 0n, endBlock: latestBlockNumber })), - blockRangeToLogs({ - publicClient, - address, - events: parseAbi([ - "event StoreDeleteRecord(bytes32 table, bytes32[] key)", - "event StoreSetField(bytes32 table, bytes32[] key, uint8 schemaIndex, bytes data)", - "event StoreSetRecord(bytes32 table, bytes32[] key, bytes data)", - "event StoreEphemeralRecord(bytes32 table, bytes32[] key, bytes data)", - ]), - }), - mergeMap(({ logs }) => from(groupLogsByBlockNumber(logs))), - ) - .subscribe((block) => { - console.log("got events for block", block); - }); -``` diff --git a/.changeset/neat-tools-check.md b/.changeset/neat-tools-check.md deleted file mode 100644 index f8d4fa1924..0000000000 --- a/.changeset/neat-tools-check.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Added a table to track the `CoreModule` address the world was initialised with. diff --git a/.changeset/nervous-walls-knock.md b/.changeset/nervous-walls-knock.md deleted file mode 100644 index 22d52c545f..0000000000 --- a/.changeset/nervous-walls-knock.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -"@latticexyz/world": minor ---- - -The `World` has a new `callFrom` entry point which allows systems to be called on behalf of other addresses if those addresses have registered a delegation. -If there is a delegation, the call is forwarded to the system with `delegator` as `msgSender`. - -```solidity -interface IBaseWorld { - function callFrom( - address delegator, - bytes32 resourceSelector, - bytes memory funcSelectorAndArgs - ) external payable virtual returns (bytes memory); -} -``` - -A delegation can be registered via the `World`'s `registerDelegation` function. -If `delegatee` is `address(0)`, the delegation is considered to be a "fallback" delegation and is used in `callFrom` if there is no delegation is found for the specific caller. -Otherwise the delegation is registered for the specific `delegatee`. - -```solidity -interface IBaseWorld { - function registerDelegation( - address delegatee, - bytes32 delegationControl, - bytes memory initFuncSelectorAndArgs - ) external; -} -``` - -The `delegationControl` refers to the resource selector of a `DelegationControl` system that must have been registered beforehand. -As part of registering the delegation, the `DelegationControl` system is called with the provided `initFuncSelectorAndArgs`. -This can be used to initialize data in the given `DelegationControl` system. - -The `DelegationControl` system must implement the `IDelegationControl` interface: - -```solidity -interface IDelegationControl { - function verify(address delegator, bytes32 systemId, bytes calldata funcSelectorAndArgs) external returns (bool); -} -``` - -When `callFrom` is called, the `World` checks if a delegation is registered for the given caller, and if so calls the delegation control's `verify` function with the same same arguments as `callFrom`. -If the call to `verify` is successful and returns `true`, the delegation is valid and the call is forwarded to the system with `delegator` as `msgSender`. - -Note: if `UNLIMITED_DELEGATION` (from `@latticexyz/world/src/constants.sol`) is passed as `delegationControl`, the external call to the delegation control contract is skipped and the delegation is considered valid. - -For examples of `DelegationControl` systems, check out the `CallboundDelegationControl` or `TimeboundDelegationControl` systems in the `std-delegations` module. -See `StandardDelegations.t.sol` for usage examples. diff --git a/.changeset/new-falcons-fail.md b/.changeset/new-falcons-fail.md deleted file mode 100644 index 4d6a43f6ef..0000000000 --- a/.changeset/new-falcons-fail.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/abi-ts": minor ---- - -Moves log output behind a debug flag. You can enable logging with `DEBUG=abi-ts` environment variable. diff --git a/.changeset/nice-avocados-poke.md b/.changeset/nice-avocados-poke.md deleted file mode 100644 index f822112a56..0000000000 --- a/.changeset/nice-avocados-poke.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/gas-report": patch ---- - -Pass through `stdin` logs in `gas-report`. Since the script piping in logs to `gas-report` can be long-running, it is useful to see its logs to know if it's stalling. diff --git a/.changeset/nice-bikes-double.md b/.changeset/nice-bikes-double.md deleted file mode 100644 index c8f8997ec9..0000000000 --- a/.changeset/nice-bikes-double.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -"@latticexyz/store-indexer": minor -"@latticexyz/store-sync": minor ---- - -Added a `tableIds` parameter to store sync methods and indexer to allow filtering data streams by table IDs. Store sync methods automatically include all internal table IDs from Store and World. - -```ts -import { syncToRecs } from "@latticexyz/store-sync/recs"; -import { resourceIdToHex } from "@latticexyz/common"; - -syncToRecs({ - ... - tableIds: [resourceIdToHex(...)], -}); -``` - -```ts -import { createIndexerClient } from "@latticexyz/store-sync/trpc-indexer"; -import { resourceIdToHex } from "@latticexyz/common"; - -const client = createIndexerClient({ ... }); -client.findAll({ - ... - tableIds: [resourceIdToHex(...)], -}); -``` diff --git a/.changeset/nice-fishes-perform.md b/.changeset/nice-fishes-perform.md deleted file mode 100644 index 5ae4ad1356..0000000000 --- a/.changeset/nice-fishes-perform.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@latticexyz/store": major ---- - -These breaking changes only affect store utilities, you aren't affected if you use `@latticexyz/cli` codegen scripts. - -- Add `remappings` argument to the `tablegen` codegen function, so that it can read user-provided files. -- In `RenderTableOptions` change the type of `imports` from `RelativeImportDatum` to `ImportDatum`, to allow passing absolute imports to the table renderer. -- Add `solidityUserTypes` argument to several functions that need to resolve user or abi types: `resolveAbiOrUserType`, `importForAbiOrUserType`, `getUserTypeInfo`. -- Add `userTypes` config option to MUD config, which takes user types mapped to file paths from which to import them. diff --git a/.changeset/nice-glasses-begin.md b/.changeset/nice-glasses-begin.md deleted file mode 100644 index 3ea9e5290d..0000000000 --- a/.changeset/nice-glasses-begin.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -"@latticexyz/block-logs-stream": patch -"@latticexyz/store-sync": patch -"@latticexyz/store": patch -"@latticexyz/world": patch ---- - -Renamed all occurrences of `key` where it is used as "key tuple" to `keyTuple`. -This is only a breaking change for consumers who manually decode `Store` events, but not for consumers who use the MUD libraries. - -```diff -event StoreSetRecord( - bytes32 tableId, -- bytes32[] key, -+ bytes32[] keyTuple, - bytes data -); - -event StoreSetField( - bytes32 tableId, -- bytes32[] key, -+ bytes32[] keyTuple, - uint8 fieldIndex, - bytes data -); - -event StoreDeleteRecord( - bytes32 tableId, -- bytes32[] key, -+ bytes32[] keyTuple, -); - -event StoreEphemeralRecord( - bytes32 tableId, -- bytes32[] key, -+ bytes32[] keyTuple, - bytes data -); -``` diff --git a/.changeset/nice-moose-love.md b/.changeset/nice-moose-love.md deleted file mode 100644 index f5c22dd5fa..0000000000 --- a/.changeset/nice-moose-love.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"@latticexyz/store-sync": minor ---- - -Export `singletonEntity` as const rather than within the `syncToRecs` result. - -```diff -- const { singletonEntity, ... } = syncToRecs({ ... }); -+ import { singletonEntity, syncToRecs } from "@latticexyz/store-sync/recs"; -+ const { ... } = syncToRecs({ ... }); -``` diff --git a/.changeset/nice-pandas-knock.md b/.changeset/nice-pandas-knock.md deleted file mode 100644 index 3c3fd9ccd7..0000000000 --- a/.changeset/nice-pandas-knock.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/common": patch -"@latticexyz/store": patch -"@latticexyz/world": patch ---- - -Clean up Memory.sol, make mcopy pure diff --git a/.changeset/nine-plants-carry.md b/.changeset/nine-plants-carry.md deleted file mode 100644 index 827086f06d..0000000000 --- a/.changeset/nine-plants-carry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/common": patch ---- - -Prevented errors not included in the contract (but present in the file) from being included in the interface by `contractToInterface` diff --git a/.changeset/ninety-lions-double.md b/.changeset/ninety-lions-double.md deleted file mode 100644 index f6475fa292..0000000000 --- a/.changeset/ninety-lions-double.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": minor ---- - -Added a `mud build` command that generates table libraries, system interfaces, and typed ABIs. diff --git a/.changeset/odd-bags-compete.md b/.changeset/odd-bags-compete.md deleted file mode 100644 index e0899b05a0..0000000000 --- a/.changeset/odd-bags-compete.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": patch ---- - -Deploys will now always rebuild `IWorld.sol` interface (a workaround for https://github.com/foundry-rs/foundry/issues/6241) diff --git a/.changeset/olive-bugs-add.md b/.changeset/olive-bugs-add.md deleted file mode 100644 index 93164051f9..0000000000 --- a/.changeset/olive-bugs-add.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-sync": patch ---- - -Improved `syncToZustand` speed of hydrating from snapshot by only applying block logs once per block instead of once per log. diff --git a/.changeset/olive-foxes-shop.md b/.changeset/olive-foxes-shop.md deleted file mode 100644 index 5ad83f87fe..0000000000 --- a/.changeset/olive-foxes-shop.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/world-modules": patch -"@latticexyz/world": major ---- - -We now expose a `WorldContextConsumerLib` library with the same functionality as the `WorldContextConsumer` contract, but the ability to be used inside of internal libraries. -We also renamed the `WorldContextProvider` library to `WorldContextProviderLib` for consistency. diff --git a/.changeset/olive-parrots-move.md b/.changeset/olive-parrots-move.md deleted file mode 100644 index ac155d594a..0000000000 --- a/.changeset/olive-parrots-move.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/recs": patch ---- - -improve RECS error messages for v2 components diff --git a/.changeset/olive-pigs-fold.md b/.changeset/olive-pigs-fold.md deleted file mode 100644 index f7f06156af..0000000000 --- a/.changeset/olive-pigs-fold.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/store": major ---- - -- Always render field methods with a suffix in tablegen (they used to not be rendered if field methods without a suffix were rendered). -- Add `withSuffixlessFieldMethods` to `RenderTableOptions`, which indicates that field methods without a suffix should be rendered. diff --git a/.changeset/perfect-mangos-cry.md b/.changeset/perfect-mangos-cry.md deleted file mode 100644 index 3cd0d59245..0000000000 --- a/.changeset/perfect-mangos-cry.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/gas-report": patch -"@latticexyz/noise": patch -"@latticexyz/schema-type": patch -"@latticexyz/solecs": patch -"@latticexyz/std-contracts": patch -"@latticexyz/store": patch -"@latticexyz/world": patch -"create-mud": patch ---- - -bump forge-std and ds-test dependencies diff --git a/.changeset/perfect-windows-reply.md b/.changeset/perfect-windows-reply.md deleted file mode 100644 index 66b8aa664a..0000000000 --- a/.changeset/perfect-windows-reply.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Added a custom error `Store_InvalidBounds` for when the `start:end` slice in `getDynamicFieldSlice` is invalid (it used to revert with the default overflow error) diff --git a/.changeset/pink-buses-look.md b/.changeset/pink-buses-look.md deleted file mode 100644 index 441d2f0a1e..0000000000 --- a/.changeset/pink-buses-look.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/protocol-parser": patch ---- - -Export `valueSchemaToFieldLayoutHex` helper diff --git a/.changeset/pink-fans-nail.md b/.changeset/pink-fans-nail.md deleted file mode 100644 index 4c84c50347..0000000000 --- a/.changeset/pink-fans-nail.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-sync": patch ---- - -add retry attempts and more logging to `waitForTransaction` diff --git a/.changeset/pink-horses-deny.md b/.changeset/pink-horses-deny.md deleted file mode 100644 index 509fcf69a3..0000000000 --- a/.changeset/pink-horses-deny.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/schema-type": minor ---- - -add type narrowing `isStaticAbiType` diff --git a/.changeset/pink-tips-give.md b/.changeset/pink-tips-give.md deleted file mode 100644 index cff922f8d4..0000000000 --- a/.changeset/pink-tips-give.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -"@latticexyz/world": major ---- - -The World now maintains a balance per namespace. -When a system is called with value, the value stored in the World contract and credited to the system's namespace. - -Previously, the World contract did not store value, but passed it on to the system contracts. -However, as systems are expected to be stateless (reading/writing state only via the calling World) and can be registered in multiple Worlds, this could have led to exploits. - -Any address with access to a namespace can use the balance of that namespace. -This allows all systems registered in the same namespace to work with the same balance. - -There are two new World methods to transfer balance between namespaces (`transferBalanceToNamespace`) or to an address (`transferBalanceToAddress`). - -```solidity -interface IBaseWorld { - function transferBalanceToNamespace(bytes16 fromNamespace, bytes16 toNamespace, uint256 amount) external; - - function transferBalanceToAddress(bytes16 fromNamespace, address toAddress, uint256 amount) external; -} -``` diff --git a/.changeset/plenty-guests-hunt.md b/.changeset/plenty-guests-hunt.md deleted file mode 100644 index ae00b2d0c3..0000000000 --- a/.changeset/plenty-guests-hunt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/common": patch ---- - -Moved some codegen to use `fs/promises` for better parallelism. diff --git a/.changeset/plenty-rules-pull.md b/.changeset/plenty-rules-pull.md deleted file mode 100644 index 4ca13996f0..0000000000 --- a/.changeset/plenty-rules-pull.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/schema-type": minor ---- - -Added `isSchemaAbiType` helper function to check and narrow an unknown string to the `SchemaAbiType` type diff --git a/.changeset/poor-bags-stare.md b/.changeset/poor-bags-stare.md deleted file mode 100644 index d6744e4455..0000000000 --- a/.changeset/poor-bags-stare.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -"@latticexyz/cli": major ---- - -`deploy`, `test`, `dev-contracts` were overhauled using a declarative deployment approach under the hood. Deploys are now idempotent and re-running them will introspect the world and figure out the minimal changes necessary to bring the world into alignment with its config: adding tables, adding/upgrading systems, changing access control, etc. - -The following CLI arguments are now removed from these commands: - -- `--debug` (you can now adjust CLI output with `DEBUG` environment variable, e.g. `DEBUG=mud:*`) -- `--priorityFeeMultiplier` (now calculated automatically) -- `--disableTxWait` (everything is now parallelized with smarter nonce management) -- `--pollInterval` (we now lean on viem defaults and we don't wait/poll until the very end of the deploy) - -Most deployment-in-progress logs are now behind a [debug](https://github.com/debug-js/debug) flag, which you can enable with a `DEBUG=mud:*` environment variable. diff --git a/.changeset/poor-beans-beg.md b/.changeset/poor-beans-beg.md deleted file mode 100644 index f6e3e38427..0000000000 --- a/.changeset/poor-beans-beg.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -"@latticexyz/abi-ts": patch -"@latticexyz/block-logs-stream": patch -"@latticexyz/common": patch -"@latticexyz/config": patch -"@latticexyz/dev-tools": patch -"@latticexyz/faucet": patch -"@latticexyz/gas-report": patch -"@latticexyz/noise": patch -"@latticexyz/phaserx": patch -"@latticexyz/protocol-parser": patch -"@latticexyz/react": patch -"@latticexyz/recs": patch -"@latticexyz/schema-type": patch -"@latticexyz/services": patch -"@latticexyz/store-sync": patch -"@latticexyz/store": patch -"@latticexyz/utils": patch -"@latticexyz/world-modules": patch -"@latticexyz/world": patch ---- - -TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages. diff --git a/.changeset/poor-fishes-pretend.md b/.changeset/poor-fishes-pretend.md deleted file mode 100644 index 5bee4bc37b..0000000000 --- a/.changeset/poor-fishes-pretend.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Added system signatures to the `FunctionSignatures` table, so they can be used to generate system ABIs and decode system calls made via the world. diff --git a/.changeset/poor-waves-occur.md b/.changeset/poor-waves-occur.md deleted file mode 100644 index 10b5d563f8..0000000000 --- a/.changeset/poor-waves-occur.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -"@latticexyz/common": minor ---- - -Added `unique` and `groupBy` array helpers to `@latticexyz/common/utils`. - -```ts -import { unique } from "@latticexyz/common/utils"; - -unique([1, 2, 1, 4, 3, 2]); -// [1, 2, 4, 3] -``` - -```ts -import { groupBy } from "@latticexyz/common/utils"; - -const records = [ - { type: "cat", name: "Bob" }, - { type: "cat", name: "Spot" }, - { type: "dog", name: "Rover" }, -]; -Object.fromEntries(groupBy(records, (record) => record.type)); -// { -// "cat": [{ type: "cat", name: "Bob" }, { type: "cat", name: "Spot" }], -// "dog: [{ type: "dog", name: "Rover" }] -// } -``` diff --git a/.changeset/popular-coins-invent.md b/.changeset/popular-coins-invent.md deleted file mode 100644 index 6d1f32a09d..0000000000 --- a/.changeset/popular-coins-invent.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/common": minor ---- - -- Add `getRemappings` to get foundry remappings as an array of `[to, from]` tuples. -- Add `extractUserTypes` solidity parser utility to extract user-defined types. -- Add `loadAndExtractUserTypes` helper to load and parse a solidity file, extracting user-defined types. diff --git a/.changeset/pre.json b/.changeset/pre.json deleted file mode 100644 index 2a711bb01a..0000000000 --- a/.changeset/pre.json +++ /dev/null @@ -1,410 +0,0 @@ -{ - "mode": "exit", - "tag": "next", - "initialVersions": { - "@latticexyz/block-logs-stream": "1.42.0", - "@latticexyz/cli": "1.42.0", - "@latticexyz/common": "1.42.0", - "@latticexyz/config": "1.42.0", - "create-mud": "1.42.0", - "@latticexyz/dev-tools": "1.42.0", - "@latticexyz/ecs-browser": "1.42.0", - "@latticexyz/gas-report": "1.42.0", - "@latticexyz/network": "1.42.0", - "@latticexyz/noise": "1.42.0", - "@latticexyz/phaserx": "1.42.0", - "@latticexyz/protocol-parser": "1.42.0", - "@latticexyz/react": "1.42.0", - "@latticexyz/recs": "1.42.0", - "@latticexyz/schema-type": "1.42.0", - "@latticexyz/services": "1.42.0", - "@latticexyz/solecs": "1.42.0", - "solhint-config-mud": "1.42.0", - "solhint-plugin-mud": "1.42.0", - "@latticexyz/std-client": "1.42.0", - "@latticexyz/std-contracts": "1.42.0", - "@latticexyz/store": "1.42.0", - "@latticexyz/store-cache": "1.42.0", - "@latticexyz/store-indexer": "1.42.0", - "@latticexyz/store-sync": "1.42.0", - "@latticexyz/utils": "1.42.0", - "@latticexyz/world": "1.42.0", - "@latticexyz/abi-ts": "2.0.0-next.5", - "@latticexyz/faucet": "2.0.0-next.8", - "@latticexyz/world-modules": "2.0.0-next.8", - "@latticexyz/query": "2.0.0-next.17", - "mock-game-contracts": "0.0.0" - }, - "changesets": [ - "afraid-hotels-bathe", - "angry-buses-dress", - "angry-ladybugs-invent", - "angry-peas-heal", - "angry-pigs-compare", - "beige-ads-melt", - "beige-badgers-smile", - "beige-radios-drop", - "beige-rockets-return", - "big-goats-prove", - "blue-forks-move", - "blue-roses-listen", - "blue-seals-relate", - "brave-dodos-relate", - "brave-ghosts-walk", - "brave-islands-wash", - "brave-needles-love", - "brave-rings-tickle", - "breezy-cameras-switch", - "breezy-days-greet", - "breezy-garlics-decide", - "breezy-seahorses-prove", - "bright-flies-hug", - "bright-kangaroos-battle", - "brown-garlics-lie", - "brown-icons-burn", - "calm-clocks-add", - "calm-drinks-dance", - "chatty-planets-heal", - "chilled-chicken-repair", - "chilled-cougars-smash", - "chilled-kangaroos-dream", - "chilly-fishes-speak", - "chilly-kangaroos-clap", - "clean-bananas-hug", - "clever-icons-cough", - "clever-items-appear", - "clever-rats-sip", - "cold-books-love", - "cold-years-itch", - "cool-snakes-reply", - "curly-countries-obey", - "curly-numbers-talk", - "curvy-dingos-draw", - "curvy-tables-melt", - "cyan-baboons-breathe", - "cyan-hats-try", - "cyan-timers-tan", - "cyan-vans-pay", - "dirty-items-retire", - "dirty-lizards-tell", - "dry-chicken-love", - "dry-flowers-shave", - "dull-otters-smash", - "eight-deers-confess", - "eighty-pots-report", - "eighty-tigers-argue", - "eleven-zebras-travel", - "empty-planes-kiss", - "empty-starfishes-lick", - "fair-baboons-compare", - "fair-buckets-dress", - "fair-bulldogs-decide", - "fair-pillows-poke", - "famous-carrots-marry", - "famous-feet-suffer", - "fast-ears-hug", - "fast-pandas-explain", - "fast-zebras-drum", - "fast-zebras-promise", - "few-berries-tickle", - "few-brooms-accept", - "few-jars-turn", - "few-mirrors-reflect", - "few-papayas-leave", - "fifty-guests-rescue", - "fifty-squids-eat", - "fifty-suits-itch", - "fifty-suits-shout", - "five-emus-battle", - "five-vans-try", - "flat-trainers-marry", - "fluffy-days-carry", - "fluffy-moles-march", - "forty-weeks-laugh", - "four-coats-pull", - "four-hotels-serve", - "fresh-scissors-unite", - "fresh-seals-compare", - "friendly-chefs-tease", - "funny-countries-hang", - "funny-paws-admire", - "fuzzy-cars-stare", - "fuzzy-chefs-wait", - "fuzzy-wombats-dream", - "giant-masks-carry", - "gold-rings-switch", - "gold-wombats-add", - "gorgeous-swans-hide", - "great-cooks-dream", - "green-eggs-end", - "green-moles-camp", - "grumpy-files-heal", - "grumpy-geckos-raise", - "grumpy-icons-sleep", - "happy-ants-lay", - "happy-pants-try", - "happy-snails-sleep", - "healthy-items-deliver", - "heavy-eyes-smile", - "heavy-rings-punch", - "heavy-shirts-dance", - "hip-files-sin", - "hip-tables-check", - "honest-geckos-refuse", - "honest-months-boil", - "honest-singers-tickle", - "hot-mice-play", - "hungry-rings-doubt", - "itchy-kids-relax", - "itchy-shoes-appear", - "khaki-cars-suffer", - "khaki-doors-refuse", - "khaki-houses-whisper", - "khaki-months-add", - "large-drinks-sell", - "large-hats-walk", - "large-hounds-type", - "large-nails-suffer", - "large-schools-grow", - "large-sloths-camp", - "late-cobras-ring", - "late-geese-guess", - "late-rats-hide", - "late-spies-cover", - "lazy-chicken-happen", - "lazy-foxes-applaud", - "lazy-ladybugs-return", - "lemon-falcons-arrive", - "lemon-numbers-design", - "lemon-zoos-mate", - "light-bananas-deny", - "light-carrots-applaud", - "little-cherries-rule", - "little-cobras-yell", - "little-ravens-yawn", - "long-dots-think", - "long-lizards-admire", - "long-tips-marry", - "loud-mayflies-divide", - "loud-rockets-switch", - "lovely-bobcats-joke", - "lovely-buses-boil", - "lovely-fireants-behave", - "lucky-clocks-love", - "many-phones-study", - "many-pumpkins-cry", - "mean-islands-brake", - "mean-pans-study", - "mean-seals-nail", - "metal-cats-double", - "metal-hounds-drum", - "metal-pots-notice", - "metal-wombats-judge", - "mighty-eels-type", - "mighty-points-study", - "mighty-years-whisper", - "modern-bikes-build", - "modern-brooms-rule", - "modern-hornets-jam", - "modern-impalas-stare", - "modern-stingrays-kneel", - "modern-trains-remain", - "moody-shirts-carry", - "nasty-crabs-explode", - "nasty-owls-sneeze", - "nasty-rice-pull", - "nasty-trains-drop", - "nasty-waves-divide", - "neat-tools-check", - "nervous-walls-knock", - "new-falcons-fail", - "nice-avocados-poke", - "nice-bikes-double", - "nice-fishes-perform", - "nice-glasses-begin", - "nice-moose-love", - "nice-pandas-knock", - "nine-plants-carry", - "ninety-lions-double", - "odd-bags-compete", - "olive-bugs-add", - "olive-foxes-shop", - "olive-parrots-move", - "olive-pigs-fold", - "perfect-mangos-cry", - "perfect-windows-reply", - "pink-buses-look", - "pink-fans-nail", - "pink-horses-deny", - "pink-tips-give", - "plenty-guests-hunt", - "plenty-rules-pull", - "poor-bags-stare", - "poor-beans-beg", - "poor-fishes-pretend", - "poor-waves-occur", - "popular-coins-invent", - "pretty-hotels-drop", - "pretty-toys-rescue", - "proud-insects-perform", - "proud-turkeys-compete", - "purple-cooks-remember", - "purple-ghosts-hear", - "quick-numbers-flash", - "quick-years-juggle", - "quiet-dancers-prove", - "quiet-guests-approve", - "quiet-squids-share", - "rare-dragons-walk", - "rare-lizards-sleep", - "rare-planes-draw", - "rare-trainers-fry", - "real-crews-hide", - "real-ducks-hope", - "real-students-exercise", - "red-falcons-do", - "red-sheep-confess", - "red-turkeys-develop", - "rich-carpets-remember", - "rich-deers-doubt", - "rich-experts-hope", - "rich-penguins-film", - "rich-rockets-jog", - "rich-worms-deliver", - "rotten-beers-learn", - "rotten-cats-lay", - "rude-cycles-travel", - "selfish-cycles-retire", - "selfish-pears-marry", - "selfish-weeks-explode", - "serious-ads-trade", - "serious-plants-itch", - "seven-carpets-develop", - "seven-flies-chew", - "seven-mangos-roll", - "seven-pears-walk", - "seven-points-mate", - "seven-rice-dance", - "shaggy-pianos-fetch", - "sharp-falcons-tie", - "sharp-students-compare", - "sharp-worms-kneel", - "short-ads-jog", - "short-dragons-shout", - "shy-monkeys-wonder", - "shy-sheep-wait", - "silent-buttons-peel", - "silent-carrots-glow", - "silent-rice-argue", - "silly-mirrors-marry", - "silly-snakes-fold", - "silver-adults-sip", - "silver-dolls-shave", - "silver-ligers-grin", - "silver-mangos-thank", - "silver-nails-explain", - "silver-wasps-count", - "six-cats-agree", - "six-kangaroos-sneeze", - "sixty-crabs-itch", - "sixty-queens-brake", - "slimy-glasses-tickle", - "small-boxes-rush", - "small-brooms-prove", - "small-chicken-repair", - "small-dots-poke", - "small-pots-press", - "smart-actors-refuse", - "smart-fireants-play", - "smart-games-taste", - "smooth-elephants-wave", - "smooth-pots-nail", - "soft-boxes-smile", - "soft-dryers-invite", - "soft-fans-wink", - "soft-panthers-develop", - "sour-cycles-warn", - "sour-rivers-grow", - "spicy-bees-teach", - "spicy-waves-wait", - "spotty-balloons-itch", - "spotty-cups-destroy", - "spotty-geese-yawn", - "spotty-sheep-warn", - "stale-cooks-reflect", - "stale-schools-wait", - "stale-seahorses-pay", - "stale-worms-hunt", - "strange-candles-shout", - "strange-cheetahs-drop", - "strange-ducks-float", - "strong-geckos-shake", - "strong-months-push", - "sweet-kiwis-unite", - "tall-buses-kick", - "tame-lemons-play", - "tasty-balloons-collect", - "tasty-cows-pay", - "thick-masks-wait", - "thin-boxes-sparkle", - "thin-buses-reply", - "thin-chairs-compare", - "thin-days-sparkle", - "thin-rice-trade", - "thin-terms-lay", - "thirty-cups-provide", - "thirty-shoes-run", - "three-lizards-shave", - "three-llamas-sin", - "three-scissors-smile", - "tidy-ants-ring", - "tidy-stingrays-think", - "tiny-lions-listen", - "tough-dolphins-bathe", - "tough-flowers-breathe", - "tough-moose-pay", - "tough-pumpkins-reply", - "tricky-beds-kiss", - "tricky-carrots-talk", - "tricky-comics-remain", - "tricky-frogs-beam", - "tricky-gifts-compare", - "tricky-kangaroos-love", - "tricky-olives-stare", - "tricky-oranges-pump", - "twelve-boats-kick", - "twelve-gorillas-learn", - "twelve-monkeys-juggle", - "twelve-terms-lay", - "twenty-birds-scream", - "two-feet-jam", - "unlucky-cups-fetch", - "unlucky-guests-cover", - "violet-insects-press", - "warm-colts-sleep", - "warm-mails-cheat", - "weak-mails-cross", - "weak-otters-turn", - "weak-rules-lick", - "wet-crabs-punch", - "wicked-cheetahs-cough", - "wicked-donuts-cheat", - "wicked-pens-promise", - "wicked-squids-do", - "wicked-tigers-return", - "wild-gorillas-care", - "wild-moose-smile", - "wild-nails-wonder", - "wild-squids-bathe", - "wild-years-search", - "wise-bees-repair", - "wise-cheetahs-add", - "witty-jokes-serve", - "witty-tigers-rest", - "yellow-bags-learn", - "yellow-bulldogs-boil", - "young-crabs-rest", - "young-pandas-explode", - "young-poets-beam" - ] -} diff --git a/.changeset/pretty-hotels-drop.md b/.changeset/pretty-hotels-drop.md deleted file mode 100644 index bf2bc965f2..0000000000 --- a/.changeset/pretty-hotels-drop.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -"@latticexyz/cli": major -"@latticexyz/std-client": major -"@latticexyz/store-sync": major -"@latticexyz/store": patch -"@latticexyz/world": patch -"create-mud": major ---- - -RECS components are now dynamically created and inferred from your MUD config when using `syncToRecs`. - -To migrate existing projects after upgrading to this MUD version: - -1. Remove `contractComponents.ts` from `client/src/mud` -2. Remove `components` argument from `syncToRecs` -3. Update `build:mud` and `dev` scripts in `contracts/package.json` to remove tsgen - - ```diff - - "build:mud": "mud tablegen && mud worldgen && mud tsgen --configPath mud.config.ts --out ../client/src/mud", - + "build:mud": "mud tablegen && mud worldgen", - ``` - - ```diff - - "dev": "pnpm mud dev-contracts --tsgenOutput ../client/src/mud", - + "dev": "pnpm mud dev-contracts", - ``` diff --git a/.changeset/pretty-toys-rescue.md b/.changeset/pretty-toys-rescue.md deleted file mode 100644 index 45878e9dcc..0000000000 --- a/.changeset/pretty-toys-rescue.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Aligned the order of function arguments in the `Storage` library. - -```solidity -store(uint256 storagePointer, uint256 offset, bytes memory data) -store(uint256 storagePointer, uint256 offset, uint256 length, uint256 memoryPointer) -load(uint256 storagePointer, uint256 offset, uint256 length) -load(uint256 storagePointer, uint256 offset, uint256 length, uint256 memoryPointer) -``` diff --git a/.changeset/proud-insects-perform.md b/.changeset/proud-insects-perform.md deleted file mode 100644 index 69d515d7ed..0000000000 --- a/.changeset/proud-insects-perform.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -"@latticexyz/store-indexer": minor ---- - -You can now install and run `@latticexyz/store-indexer` from the npm package itself, without having to clone/build the MUD repo: - -```sh -npm install @latticexyz/store-indexer - -npm sqlite-indexer -# or -npm postgres-indexer -``` - -or - -```sh -npx -p @latticexyz/store-indexer sqlite-indexer -# or -npx -p @latticexyz/store-indexer postgres-indexer -``` - -The binary will also load the nearby `.env` file for easier local configuration. - -We've removed the `CHAIN_ID` requirement and instead require just a `RPC_HTTP_URL` or `RPC_WS_URL` or both. You can now also adjust the polling interval with `POLLING_INTERVAL` (defaults to 1000ms, which corresponds to MUD's default block time). diff --git a/.changeset/proud-turkeys-compete.md b/.changeset/proud-turkeys-compete.md deleted file mode 100644 index 4713d60bc9..0000000000 --- a/.changeset/proud-turkeys-compete.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -"@latticexyz/dev-tools": minor -"create-mud": minor ---- - -Added Zustand support to Dev Tools: - -```ts -const { syncToZustand } from "@latticexyz/store-sync"; -const { mount as mountDevTools } from "@latticexyz/dev-tools"; - -const { useStore } = syncToZustand({ ... }); - -mountDevTools({ - ... - useStore, -}); -``` diff --git a/.changeset/purple-cooks-remember.md b/.changeset/purple-cooks-remember.md deleted file mode 100644 index 734bc468fb..0000000000 --- a/.changeset/purple-cooks-remember.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/gas-report": patch ---- - -Fixed gas report parsing for foundry versions released after 2024-02-15. diff --git a/.changeset/purple-ghosts-hear.md b/.changeset/purple-ghosts-hear.md deleted file mode 100644 index 23bdeb82f6..0000000000 --- a/.changeset/purple-ghosts-hear.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-mud": patch ---- - -Fixed an issue when creating a new project from the `react` app, where React's expressions were overlapping with Handlebars expressions (used by our template command). diff --git a/.changeset/quick-numbers-flash.md b/.changeset/quick-numbers-flash.md deleted file mode 100644 index 6dc2200e1a..0000000000 --- a/.changeset/quick-numbers-flash.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/cli": minor -"@latticexyz/gas-report": minor -"@latticexyz/store": minor ---- - -Create gas-report package, move gas-report cli command and GasReporter contract to it diff --git a/.changeset/quick-years-juggle.md b/.changeset/quick-years-juggle.md deleted file mode 100644 index 6415e1c24b..0000000000 --- a/.changeset/quick-years-juggle.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@latticexyz/store": major -"@latticexyz/world": minor ---- - -- Moves Store events into its own `IStoreEvents` interface -- Moves Store interfaces to their own files -- Adds a `StoreData` abstract contract to initialize a Store and expose the Store version - -If you're using MUD out of the box, you won't have to make any changes. You will only need to update if you're using any of the base Store interfaces. diff --git a/.changeset/quiet-dancers-prove.md b/.changeset/quiet-dancers-prove.md deleted file mode 100644 index 993b6fcd2c..0000000000 --- a/.changeset/quiet-dancers-prove.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Register `Delegations` table in the `CoreModule` diff --git a/.changeset/quiet-guests-approve.md b/.changeset/quiet-guests-approve.md deleted file mode 100644 index 79b08e487c..0000000000 --- a/.changeset/quiet-guests-approve.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": major ---- - -Separated core systems deployment from `CoreModule`, and added the systems as arguments to `CoreModule` diff --git a/.changeset/quiet-squids-share.md b/.changeset/quiet-squids-share.md deleted file mode 100644 index 34aed7b320..0000000000 --- a/.changeset/quiet-squids-share.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -"@latticexyz/world": major ---- - -- The previous `Call.withSender` util is replaced with `WorldContextProvider`, since the usecase of appending the `msg.sender` to the calldata is tightly coupled with `WorldContextConsumer` (which extracts the appended context from the calldata). - - The previous `Call.withSender` utility reverted if the call failed and only returned the returndata on success. This is replaced with `callWithContextOrRevert`/`delegatecallWithContextOrRevert` - - ```diff - -import { Call } from "@latticexyz/world/src/Call.sol"; - +import { WorldContextProvider } from "@latticexyz/world/src/WorldContext.sol"; - - -Call.withSender({ - - delegate: false, - - value: 0, - - ... - -}); - +WorldContextProvider.callWithContextOrRevert({ - + value: 0, - + ... - +}); - - -Call.withSender({ - - delegate: true, - - value: 0, - - ... - -}); - +WorldContextProvider.delegatecallWithContextOrRevert({ - + ... - +}); - ``` - - In addition there are utils that return a `bool success` flag instead of reverting on errors. This mirrors the behavior of Solidity's low level `call`/`delegatecall` functions and is useful in situations where additional logic should be executed in case of a reverting external call. - - ```solidity - library WorldContextProvider { - function callWithContext( - address target, // Address to call - bytes memory funcSelectorAndArgs, // Abi encoded function selector and arguments to pass to pass to the contract - address msgSender, // Address to append to the calldata as context for msgSender - uint256 value // Value to pass with the call - ) internal returns (bool success, bytes memory data); - - function delegatecallWithContext( - address target, // Address to call - bytes memory funcSelectorAndArgs, // Abi encoded function selector and arguments to pass to pass to the contract - address msgSender // Address to append to the calldata as context for msgSender - ) internal returns (bool success, bytes memory data); - } - ``` - -- `WorldContext` is renamed to `WorldContextConsumer` to clarify the relationship between `WorldContextProvider` (appending context to the calldata) and `WorldContextConsumer` (extracting context from the calldata) - - ```diff - -import { WorldContext } from "@latticexyz/world/src/WorldContext.sol"; - -import { WorldContextConsumer } from "@latticexyz/world/src/WorldContext.sol"; - ``` - -- The `World` contract previously had a `_call` method to handle calling systems via their resource selector, performing accesss control checks and call hooks registered for the system. - - ```solidity - library SystemCall { - /** - * Calls a system via its resource selector and perform access control checks. - * Does not revert if the call fails, but returns a `success` flag along with the returndata. - */ - function call( - address caller, - bytes32 resourceSelector, - bytes memory funcSelectorAndArgs, - uint256 value - ) internal returns (bool success, bytes memory data); - - /** - * Calls a system via its resource selector, perform access control checks and trigger hooks registered for the system. - * Does not revert if the call fails, but returns a `success` flag along with the returndata. - */ - function callWithHooks( - address caller, - bytes32 resourceSelector, - bytes memory funcSelectorAndArgs, - uint256 value - ) internal returns (bool success, bytes memory data); - - /** - * Calls a system via its resource selector, perform access control checks and trigger hooks registered for the system. - * Reverts if the call fails. - */ - function callWithHooksOrRevert( - address caller, - bytes32 resourceSelector, - bytes memory funcSelectorAndArgs, - uint256 value - ) internal returns (bytes memory data); - } - ``` - -- System hooks now are called with the system's resource selector instead of its address. The system's address can still easily obtained within the hook via `Systems.get(resourceSelector)` if necessary. - - ```diff - interface ISystemHook { - function onBeforeCallSystem( - address msgSender, - - address systemAddress, - + bytes32 resourceSelector, - bytes memory funcSelectorAndArgs - ) external; - - function onAfterCallSystem( - address msgSender, - - address systemAddress, - + bytes32 resourceSelector, - bytes memory funcSelectorAndArgs - ) external; - } - ``` diff --git a/.changeset/rare-dragons-walk.md b/.changeset/rare-dragons-walk.md deleted file mode 100644 index 7dd50548f9..0000000000 --- a/.changeset/rare-dragons-walk.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Refactored `StoreCore.registerStoreHook` to use `StoreHooks._push` for gas efficiency. diff --git a/.changeset/rare-lizards-sleep.md b/.changeset/rare-lizards-sleep.md deleted file mode 100644 index ac297a57bf..0000000000 --- a/.changeset/rare-lizards-sleep.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-sync": patch ---- - -Catch errors when parsing logs to tables and storage operations, log and skip diff --git a/.changeset/rare-planes-draw.md b/.changeset/rare-planes-draw.md deleted file mode 100644 index 9c651355fd..0000000000 --- a/.changeset/rare-planes-draw.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/schema-type": patch ---- - -Fix byte lengths for `uint64` and `int64`. diff --git a/.changeset/rare-trainers-fry.md b/.changeset/rare-trainers-fry.md deleted file mode 100644 index 4394fcd616..0000000000 --- a/.changeset/rare-trainers-fry.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -"@latticexyz/world": minor ---- - -It is now possible to transfer ownership of namespaces! - -```solidity -// Register a new namespace -world.registerNamespace("namespace"); -// It's owned by the caller of the function (address(this)) - -// Transfer ownership of the namespace to address(42) -world.transferOwnership("namespace", address(42)); -// It's now owned by address(42) -``` diff --git a/.changeset/real-crews-hide.md b/.changeset/real-crews-hide.md deleted file mode 100644 index 11aecc8d70..0000000000 --- a/.changeset/real-crews-hide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": patch ---- - -We fixed a bug in the deploy script that would cause the deployment to fail if a non-root namespace was used in the config. diff --git a/.changeset/real-ducks-hope.md b/.changeset/real-ducks-hope.md deleted file mode 100644 index ab8fb19d0e..0000000000 --- a/.changeset/real-ducks-hope.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -"@latticexyz/cli": major -"@latticexyz/world": major ---- - -The `registerFunctionSelector` function now accepts a single `functionSignature` string paramemer instead of separating function name and function arguments into separate parameters. - -```diff -IBaseWorld { - function registerFunctionSelector( - ResourceId systemId, -- string memory systemFunctionName, -- string memory systemFunctionArguments -+ string memory systemFunctionSignature - ) external returns (bytes4 worldFunctionSelector); -} -``` - -This is a breaking change if you were manually registering function selectors, e.g. in a `PostDeploy.s.sol` script or a module. -To upgrade, simply replace the separate `systemFunctionName` and `systemFunctionArguments` parameters with a single `systemFunctionSignature` parameter. - -```diff - world.registerFunctionSelector( - systemId, -- systemFunctionName, -- systemFunctionArguments, -+ string(abi.encodePacked(systemFunctionName, systemFunctionArguments)) - ); -``` diff --git a/.changeset/real-students-exercise.md b/.changeset/real-students-exercise.md deleted file mode 100644 index 25ac8a1a75..0000000000 --- a/.changeset/real-students-exercise.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -"@latticexyz/world": major ---- - -All `World` methods acting on namespaces as resources have been updated to use `ResourceId namespaceId` as parameter instead of `bytes14 namespace`. -The reason for this change is to make it clearer when a namespace is used as resource, as opposed to being part of another resource's ID. - -```diff -+ import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; - -IBaseWorld { -- function registerNamespace(bytes14 namespace) external; -+ function registerNamespace(ResourceId namespaceId) external; - -- function transferOwnership(bytes14 namespace, address newOwner) external; -+ function transferOwnership(ResourceId namespaceId, address newOwner) external; - -- function transferBalanceToNamespace(bytes14 fromNamespace, bytes14 toNamespace, uint256 amount) external; -+ function transferBalanceToNamespace(ResourceId fromNamespaceId, ResourceId toNamespaceId, uint256 amount) external; - -- function transferBalanceToAddress(bytes14 fromNamespace, address toAddress, uint256 amount) external; -+ function transferBalanceToAddress(ResourceId fromNamespaceId, address toAddress, uint256 amount) external; -} - -``` diff --git a/.changeset/red-falcons-do.md b/.changeset/red-falcons-do.md deleted file mode 100644 index 052cf2fcc4..0000000000 --- a/.changeset/red-falcons-do.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Minor `Store` cleanups: renamed `Utils.sol` to `leftMask.sol` since it only contains a single free function, and removed a leftover sanity check. diff --git a/.changeset/red-sheep-confess.md b/.changeset/red-sheep-confess.md deleted file mode 100644 index fdf59148f8..0000000000 --- a/.changeset/red-sheep-confess.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@latticexyz/cli": patch ---- - -Fixed a few issues with deploys: - -- properly handle enums in MUD config -- only deploy each unique module/system once -- waits for transactions serially instead of in parallel, to avoid RPC errors diff --git a/.changeset/red-turkeys-develop.md b/.changeset/red-turkeys-develop.md deleted file mode 100644 index f85cf4eb12..0000000000 --- a/.changeset/red-turkeys-develop.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -"@latticexyz/block-logs-stream": patch -"@latticexyz/common": patch -"@latticexyz/dev-tools": patch -"@latticexyz/network": patch -"@latticexyz/protocol-parser": patch -"@latticexyz/schema-type": patch -"@latticexyz/std-client": patch -"@latticexyz/store-indexer": patch -"@latticexyz/store-sync": patch -"create-mud": patch ---- - -bump viem to 1.6.0 diff --git a/.changeset/rich-carpets-remember.md b/.changeset/rich-carpets-remember.md deleted file mode 100644 index 5ecc17e2ea..0000000000 --- a/.changeset/rich-carpets-remember.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Fixed `StoreCore` to pass `previousEncodedLengths` into `onBeforeSpliceDynamicData`. diff --git a/.changeset/rich-deers-doubt.md b/.changeset/rich-deers-doubt.md deleted file mode 100644 index e72da4e15a..0000000000 --- a/.changeset/rich-deers-doubt.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/store": major -"@latticexyz/store-sync": major ---- - -Added `dynamicFieldIndex` to the `Store_SpliceDynamicData` event. This enables indexers to store dynamic data as a blob per dynamic field without a schema lookup. diff --git a/.changeset/rich-experts-hope.md b/.changeset/rich-experts-hope.md deleted file mode 100644 index 8adc040361..0000000000 --- a/.changeset/rich-experts-hope.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-indexer": patch ---- - -Disabled prepared statements for the postgres indexer, which led to issues in combination with `pgBouncer`. diff --git a/.changeset/rich-penguins-film.md b/.changeset/rich-penguins-film.md deleted file mode 100644 index 818f79565b..0000000000 --- a/.changeset/rich-penguins-film.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-mud": patch ---- - -Added `dbaeumer.vscode-eslint` and `esbenp.prettier-vscode` to recommended VSCode extensions. diff --git a/.changeset/rich-rockets-jog.md b/.changeset/rich-rockets-jog.md deleted file mode 100644 index 413cb83f59..0000000000 --- a/.changeset/rich-rockets-jog.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": patch ---- - -Changed `mud` CLI import order so that environment variables from the `.env` file are loaded before other imports. diff --git a/.changeset/rich-worms-deliver.md b/.changeset/rich-worms-deliver.md deleted file mode 100644 index 5fb443d46f..0000000000 --- a/.changeset/rich-worms-deliver.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@latticexyz/abi-ts": patch -"@latticexyz/block-logs-stream": patch -"@latticexyz/cli": patch -"@latticexyz/common": patch -"@latticexyz/faucet": patch -"@latticexyz/store-indexer": patch -"@latticexyz/store-sync": patch -"@latticexyz/store": patch ---- - -Updated the `debug` util to pipe to `stdout` and added an additional util to explicitly pipe to `stderr` when needed. diff --git a/.changeset/rotten-beers-learn.md b/.changeset/rotten-beers-learn.md deleted file mode 100644 index b566ca4250..0000000000 --- a/.changeset/rotten-beers-learn.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -"@latticexyz/common": minor ---- - -- Moves contract write logic out of `createContract` into its own `writeContract` method so that it can be used outside of the contract instance, and for consistency with viem. -- Deprecates `createContract` in favor of `getContract` for consistency with viem. -- Reworks `createNonceManager`'s `BroadcastChannel` setup and moves out the notion of a "nonce manager ID" to `getNonceManagerId` so we can create an internal cache with `getNonceManager` for use in `writeContract`. - -If you were using the `createNonceManager` before, you'll just need to rename `publicClient` argument to `client`: - -```diff - const publicClient = createPublicClient({ ... }); -- const nonceManager = createNonceManager({ publicClient, ... }); -+ const nonceManager = createNonceManager({ client: publicClient, ... }); -``` diff --git a/.changeset/rotten-cats-lay.md b/.changeset/rotten-cats-lay.md deleted file mode 100644 index 021154c423..0000000000 --- a/.changeset/rotten-cats-lay.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@latticexyz/common": minor ---- - -`spliceHex` was added, which has a similar API as JavaScript's [`Array.prototype.splice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice), but for `Hex` strings. - -```ts -spliceHex("0x123456", 1, 1, "0x0000"); // "0x12000056" -``` diff --git a/.changeset/rude-cycles-travel.md b/.changeset/rude-cycles-travel.md deleted file mode 100644 index 8b57b96da2..0000000000 --- a/.changeset/rude-cycles-travel.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/world-modules": major ---- - -Modules now revert with `Module_AlreadyInstalled` if attempting to install more than once with the same calldata. - -This is a temporary workaround for our deploy pipeline. We'll make these install steps more idempotent in the future. diff --git a/.changeset/selfish-cycles-retire.md b/.changeset/selfish-cycles-retire.md deleted file mode 100644 index e00c8d3b07..0000000000 --- a/.changeset/selfish-cycles-retire.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -"@latticexyz/std-contracts": minor -"@latticexyz/store": minor -"@latticexyz/world": minor ---- - -Rename `MudV2Test` to `MudTest` and move from `@latticexyz/std-contracts` to `@latticexyz/store`. - -```solidity -// old import -import { MudV2Test } from "@latticexyz/std-contracts/src/test/MudV2Test.t.sol"; -// new import -import { MudTest } from "@latticexyz/store/src/MudTest.sol"; -``` - -Refactor `StoreSwitch` to use a storage slot instead of `function isStore()` to determine which contract is Store: - -- Previously `StoreSwitch` called `isStore()` on `msg.sender` to determine if `msg.sender` is a `Store` contract. If the call succeeded, the `Store` methods were called on `msg.sender`, otherwise the data was written to the own storage. -- With this change `StoreSwitch` instead checks for an `address` in a known storage slot. If the address equals the own address, data is written to the own storage. If it is an external address, `Store` methods are called on this address. If it is unset (`address(0)`), store methods are called on `msg.sender`. -- In practice this has the same effect as before: By default the `World` contracts sets its own address in `StoreSwitch`, while `System` contracts keep the Store address undefined, so `Systems` write to their caller (`World`) if they are executed via `call` or directly to the `World` storage if they are executed via `delegatecall`. -- Besides gas savings, this change has two additional benefits: - 1. it is now possible for `Systems` to explicitly set a `Store` address to make them exclusive to that `Store` and - 2. table libraries can now be used in tests without having to provide an explicit `Store` argument, because the `MudTest` base contract redirects reads and writes to the internal `World` contract. diff --git a/.changeset/selfish-pears-marry.md b/.changeset/selfish-pears-marry.md deleted file mode 100644 index 449be6f339..0000000000 --- a/.changeset/selfish-pears-marry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": minor ---- - -`WorldFactory` now derives a salt based on number of worlds deployed by `msg.sender`, which should help with predictable world deployments across chains. diff --git a/.changeset/selfish-weeks-explode.md b/.changeset/selfish-weeks-explode.md deleted file mode 100644 index b770713de0..0000000000 --- a/.changeset/selfish-weeks-explode.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Created an `IWorldEvents` interface with `HelloStore`, so all World events are defined in a single interface. diff --git a/.changeset/serious-ads-trade.md b/.changeset/serious-ads-trade.md deleted file mode 100644 index 256b526641..0000000000 --- a/.changeset/serious-ads-trade.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@latticexyz/cli": minor -"@latticexyz/common": minor -"@latticexyz/gas-report": major -"@latticexyz/noise": major -"@latticexyz/schema-type": major -"@latticexyz/store": major -"@latticexyz/world": major -"create-mud": minor ---- - -Bump Solidity version to 0.8.21 diff --git a/.changeset/serious-plants-itch.md b/.changeset/serious-plants-itch.md deleted file mode 100644 index b6fbe7134b..0000000000 --- a/.changeset/serious-plants-itch.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -"@latticexyz/world": major ---- - -- `IBaseWorld` now has a `batchCallFrom` method, which allows system calls via `callFrom` to be executed in batch. - -```solidity -import { SystemCallFromData } from "@latticexyz/world/modules/core/types.sol"; - -interface IBaseWorld { - function batchCallFrom(SystemCallFromData[] calldata systemCalls) external returns (bytes[] memory returnDatas); -} -``` - -- The `callBatch` method of `IBaseWorld` has been renamed to `batchCall` to align better with the `batchCallFrom` method. - -```diff -interface IBaseWorld { -- function callBatch(SystemCallData[] calldata systemCalls) external returns (bytes[] memory returnDatas); -+ function batchCall(SystemCallData[] calldata systemCalls) external returns (bytes[] memory returnDatas); -} -``` diff --git a/.changeset/seven-carpets-develop.md b/.changeset/seven-carpets-develop.md deleted file mode 100644 index c1ab18bf56..0000000000 --- a/.changeset/seven-carpets-develop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Namespace balances can no longer be transferred to non-existent namespaces. diff --git a/.changeset/seven-flies-chew.md b/.changeset/seven-flies-chew.md deleted file mode 100644 index ba2e7776cf..0000000000 --- a/.changeset/seven-flies-chew.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"@latticexyz/services": major -"create-mud": patch ---- - -Move `createFaucetService` from `@latticexyz/network` to `@latticexyz/services/faucet`. - -```diff -- import { createFaucetService } from "@latticexyz/network"; -+ import { createFaucetService } from "@latticexyz/services/faucet"; -``` diff --git a/.changeset/seven-mangos-roll.md b/.changeset/seven-mangos-roll.md deleted file mode 100644 index dad7550c9e..0000000000 --- a/.changeset/seven-mangos-roll.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/store-sync": patch -"@latticexyz/store": patch -"@latticexyz/world": patch ---- - -All `Store` and `World` tables now use the appropriate user-types for `ResourceId`, `FieldLayout` and `Schema` to avoid manual `wrap`/`unwrap`. diff --git a/.changeset/seven-pears-walk.md b/.changeset/seven-pears-walk.md deleted file mode 100644 index fc4694d54f..0000000000 --- a/.changeset/seven-pears-walk.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/world-modules": patch -"@latticexyz/world": patch ---- - -Renamed the Module `args` parameter to `encodedArgs` to better reflect that it is ABI-encoded arguments. diff --git a/.changeset/seven-points-mate.md b/.changeset/seven-points-mate.md deleted file mode 100644 index d359485104..0000000000 --- a/.changeset/seven-points-mate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-sync": patch ---- - -Fixed `syncToZustand` types so that non-existent tables give an error and `never` type instead of a generic `Table` type. diff --git a/.changeset/seven-rice-dance.md b/.changeset/seven-rice-dance.md deleted file mode 100644 index 22442dedd2..0000000000 --- a/.changeset/seven-rice-dance.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/store-indexer": minor ---- - -The `findAll` method is now considered deprecated in favor of a new `getLogs` method. This is only implemented in the Postgres indexer for now, with SQLite coming soon. The new `getLogs` method will be an easier and more robust data source to hydrate the client and other indexers and will allow us to add streaming updates from the indexer in the near future. - -For backwards compatibility, `findAll` is now implemented on top of `getLogs`, with record key/value decoding done in memory at request time. This may not scale for large databases, so use wisely. diff --git a/.changeset/shaggy-pianos-fetch.md b/.changeset/shaggy-pianos-fetch.md deleted file mode 100644 index 0061d93089..0000000000 --- a/.changeset/shaggy-pianos-fetch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Added more validation checks for `FieldLayout` and `Schema`. diff --git a/.changeset/sharp-falcons-tie.md b/.changeset/sharp-falcons-tie.md deleted file mode 100644 index ee662e49c7..0000000000 --- a/.changeset/sharp-falcons-tie.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -"@latticexyz/store-sync": minor ---- - -Added a `filters` option to store sync to allow filtering client data on tables and keys. Previously, it was only possible to filter on `tableIds`, but the new filter option allows for more flexible filtering by key. - -If you are building a large MUD application, you can use positional keys as a way to shard data and make it possible to load only the data needed in the client for a particular section of your app. We're using this already in Sky Strife to load match-specific data into match pages without having to load data for all matches, greatly improving load time and client performance. - -```ts -syncToRecs({ - ... - filters: [{ tableId: '0x...', key0: '0x...' }], -}); -``` - -The `tableIds` option is now deprecated and will be removed in the future, but is kept here for backwards compatibility. diff --git a/.changeset/sharp-students-compare.md b/.changeset/sharp-students-compare.md deleted file mode 100644 index e4e59de3c1..0000000000 --- a/.changeset/sharp-students-compare.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-sync": patch ---- - -Fixes an issue with Zustand store sync where multiple updates to a record for a key in the same block did not get tracked and applied properly. diff --git a/.changeset/sharp-worms-kneel.md b/.changeset/sharp-worms-kneel.md deleted file mode 100644 index 4ba018ceba..0000000000 --- a/.changeset/sharp-worms-kneel.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/block-logs-stream": major ---- - -- removes our own `getLogs` function now that viem's `getLogs` supports using multiple `events` per RPC call. -- removes `isNonPendingBlock` and `isNonPendingLog` helpers now that viem narrows `Block` and `Log` types based on inputs -- simplifies `groupLogsByBlockNumber` types and tests diff --git a/.changeset/short-ads-jog.md b/.changeset/short-ads-jog.md deleted file mode 100644 index 7e72bc90de..0000000000 --- a/.changeset/short-ads-jog.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -"@latticexyz/abi-ts": minor -"@latticexyz/cli": minor ---- - -Added a new `@latticexyz/abi-ts` package to generate TS type declaration files (`.d.ts`) for each ABI JSON file. - -This allows you to import your JSON ABI and use it directly with libraries like [viem](https://npmjs.com/package/viem) and [abitype](https://npmjs.com/package/abitype). - -``` -pnpm add @latticexyz/abi-ts -pnpm abi-ts -``` - -By default, `abi-ts` looks for files with the glob `**/*.abi.json`, but you can customize this glob with the `--input` argument, e.g. - -```console -pnpm abi-ts --input 'abi/IWorld.sol/IWorld.abi.json' -``` diff --git a/.changeset/short-dragons-shout.md b/.changeset/short-dragons-shout.md deleted file mode 100644 index d2c8abe6f1..0000000000 --- a/.changeset/short-dragons-shout.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/store": patch -"@latticexyz/world": patch ---- - -Optimized the `StoreCore` hash function determining the data location to use less gas. diff --git a/.changeset/shy-monkeys-wonder.md b/.changeset/shy-monkeys-wonder.md deleted file mode 100644 index 9105087ee5..0000000000 --- a/.changeset/shy-monkeys-wonder.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -"@latticexyz/cli": major -"@latticexyz/store": major -"create-mud": patch ---- - -Renamed the default filename of generated user types from `Types.sol` to `common.sol` and the default filename of the generated table index file from `Tables.sol` to `index.sol`. - -Both can be overridden via the MUD config: - -```ts -export default mudConfig({ - /** Filename where common user types will be generated and imported from. */ - userTypesFilename: "common.sol", - /** Filename where codegen index will be generated. */ - codegenIndexFilename: "index.sol", -}); -``` - -Note: `userTypesFilename` was renamed from `userTypesPath` and `.sol` is not appended automatically anymore but needs to be part of the provided filename. - -To update your existing project, update all imports from `Tables.sol` to `index.sol` and all imports from `Types.sol` to `common.sol`, or override the defaults in your MUD config to the previous values. - -```diff -- import { Counter } from "../src/codegen/Tables.sol"; -+ import { Counter } from "../src/codegen/index.sol"; -- import { ExampleEnum } from "../src/codegen/Types.sol"; -+ import { ExampleEnum } from "../src/codegen/common.sol"; -``` diff --git a/.changeset/shy-sheep-wait.md b/.changeset/shy-sheep-wait.md deleted file mode 100644 index baabf2b946..0000000000 --- a/.changeset/shy-sheep-wait.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@latticexyz/dev-tools": major -"@latticexyz/store-sync": major -"create-mud": minor ---- - -We've updated Store events to be "schemaless", meaning there is enough information in each event to only need to operate on the bytes of each record to make an update to that record without having to first decode the record by its schema. This enables new kinds of indexers and sync strategies. - -As such, we've replaced `blockStorageOperations$` with `storedBlockLogs$`, a stream of simplified Store event logs after they've been synced to the configured storage adapter. These logs may not reflect exactly the events that are on chain when e.g. hydrating from an indexer, but they will still allow the client to "catch up" to the on-chain state of your tables. diff --git a/.changeset/silent-buttons-peel.md b/.changeset/silent-buttons-peel.md deleted file mode 100644 index 2a3d20e384..0000000000 --- a/.changeset/silent-buttons-peel.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -"@latticexyz/world-modules": minor ---- - -Added the `ERC20Module` to `@latticexyz/world-modules`. -This module allows the registration of `ERC20` tokens in an existing World. - -Important note: this module has not been audited yet, so any production use is discouraged for now. - -```solidity -import { PuppetModule } from "@latticexyz/world-modules/src/modules/puppet/PuppetModule.sol"; -import { IERC20Mintable } from "@latticexyz/world-modules/src/modules/erc20-puppet/IERC20Mintable.sol"; -import { registerERC20 } from "@latticexyz/world-modules/src/modules/erc20-puppet/registerERC20.sol"; - -// The ERC20 module requires the Puppet module to be installed first -world.installModule(new PuppetModule(), new bytes(0)); - -// After the Puppet module is installed, new ERC20 tokens can be registered -IERC20Mintable token = registerERC20(world, "myERC20", ERC20MetadataData({ decimals: 18, name: "Token", symbol: "TKN" })); -``` diff --git a/.changeset/silent-carrots-glow.md b/.changeset/silent-carrots-glow.md deleted file mode 100644 index faf0c8f660..0000000000 --- a/.changeset/silent-carrots-glow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": minor ---- - -CLI `deploy`, `test`, `dev-contracts` no longer run `forge clean` before each deploy. We previously cleaned to ensure no outdated artifacts were checked into git (ABIs, typechain types, etc.). Now that all artifacts are gitignored, we can let forge use its cache again. diff --git a/.changeset/silent-rice-argue.md b/.changeset/silent-rice-argue.md deleted file mode 100644 index dfa242b1d2..0000000000 --- a/.changeset/silent-rice-argue.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/protocol-parser": minor ---- - -Adds `valueSchemaToFieldLayoutHex` helper diff --git a/.changeset/silly-mirrors-marry.md b/.changeset/silly-mirrors-marry.md deleted file mode 100644 index 130fbf959c..0000000000 --- a/.changeset/silly-mirrors-marry.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/store": minor -"@latticexyz/world": patch ---- - -Added an `abstract` `StoreKernel` contract, which includes all Store interfaces except for registration, and implements write methods, `protocolVersion` and initializes `StoreCore`. `Store` extends `StoreKernel` with the `IStoreRegistration` interface. `StoreData` is removed as a separate interface/contract. `World` now extends `StoreKernel` (since the registration methods are added via the `InitModule`). diff --git a/.changeset/silly-snakes-fold.md b/.changeset/silly-snakes-fold.md deleted file mode 100644 index 63ebfcc221..0000000000 --- a/.changeset/silly-snakes-fold.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/dev-tools": patch ---- - -Updates store event `key` reference to `keyTuple` diff --git a/.changeset/silver-adults-sip.md b/.changeset/silver-adults-sip.md deleted file mode 100644 index b9b68abb97..0000000000 --- a/.changeset/silver-adults-sip.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": patch ---- - -Updated deployer with world's new `InitModule` naming. diff --git a/.changeset/silver-dolls-shave.md b/.changeset/silver-dolls-shave.md deleted file mode 100644 index 4cb44e330f..0000000000 --- a/.changeset/silver-dolls-shave.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@latticexyz/gas-report": minor ---- - -Allow the `gas-report` CLI to parse logs via `stdin`, so it can be used with custom test commands (e.g. `mud test`). - -Usage: - -```sh -# replace `forge test -vvv` with the custom test command -GAS_REPORTER_ENABLED=true forge test -vvv | pnpm gas-report --stdin -``` diff --git a/.changeset/silver-ligers-grin.md b/.changeset/silver-ligers-grin.md deleted file mode 100644 index 7296243015..0000000000 --- a/.changeset/silver-ligers-grin.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@latticexyz/world": major ---- - -- Split `CoreSystem` into `AccessManagementSystem`, `BalanceTransferSystem`, `BatchCallSystem`, `CoreRegistrationSystem` -- Changed `CoreModule` to receive the addresses of these systems as arguments, instead of deploying them -- Replaced `CORE_SYSTEM_ID` constant with `ACCESS_MANAGEMENT_SYSTEM_ID`, `BALANCE_TRANSFER_SYSTEM_ID`, `BATCH_CALL_SYSTEM_ID`, `CORE_REGISTRATION_SYSTEM_ID`, for each respective system - -These changes separate the initcode of `CoreModule` from the bytecode of core systems, which effectively removes a limit on the total bytecode of all core systems. diff --git a/.changeset/silver-mangos-thank.md b/.changeset/silver-mangos-thank.md deleted file mode 100644 index aec6ac4051..0000000000 --- a/.changeset/silver-mangos-thank.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Allow `callFrom` with the own address as `delegator` without requiring an explicit delegation diff --git a/.changeset/silver-nails-explain.md b/.changeset/silver-nails-explain.md deleted file mode 100644 index 593e518a95..0000000000 --- a/.changeset/silver-nails-explain.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -"@latticexyz/store-sync": minor ---- - -Added a Zustand storage adapter and corresponding `syncToZustand` method for use in vanilla and React apps. It's used much like the other sync methods, except it returns a bound store and set of typed tables. - -```ts -import { syncToZustand } from "@latticexyz/store-sync/zustand"; -import config from "contracts/mud.config"; - -const { tables, useStore, latestBlock$, storedBlockLogs$, waitForTransaction } = await syncToZustand({ - config, - ... -}); - -// in vanilla apps -const positions = useStore.getState().getRecords(tables.Position); - -// in React apps -const positions = useStore((state) => state.getRecords(tables.Position)); -``` - -This change will be shortly followed by an update to our templates that uses Zustand as the default client data store and sync method. diff --git a/.changeset/silver-wasps-count.md b/.changeset/silver-wasps-count.md deleted file mode 100644 index 2fdac237e4..0000000000 --- a/.changeset/silver-wasps-count.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-indexer": patch ---- - -The error log if no data is found in `/api/logs` is now stringifying the filter instead of logging `[object Object]`. diff --git a/.changeset/six-cats-agree.md b/.changeset/six-cats-agree.md deleted file mode 100644 index 37a38ecd61..0000000000 --- a/.changeset/six-cats-agree.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -"create-mud": minor ---- - -We now use `@latticexyz/abi-ts` to generate TS type declaration files (`.d.ts`) for each ABI JSON file. This replaces our usage TypeChain everywhere. - -If you have a MUD project created from an older template, you can replace TypeChain with `abi-ts` by first updating your contracts' `package.json`: - -```diff --"build": "pnpm run build:mud && pnpm run build:abi && pnpm run build:typechain", -+"build": "pnpm run build:mud && pnpm run build:abi && pnpm run build:abi-ts", --"build:abi": "forge clean && forge build", -+"build:abi": "rimraf abi && forge build --extra-output-files abi --out abi --skip test script MudTest.sol", -+"build:abi-ts": "mud abi-ts --input 'abi/IWorld.sol/IWorld.abi.json' && prettier --write '**/*.abi.json.d.ts'", - "build:mud": "mud tablegen && mud worldgen", --"build:typechain": "rimraf types && typechain --target=ethers-v5 out/IWorld.sol/IWorld.json", -``` - -And update your client's `setupNetwork.ts` with: - -```diff --import { IWorld__factory } from "contracts/types/ethers-contracts/factories/IWorld__factory"; -+import IWorldAbi from "contracts/abi/IWorld.sol/IWorld.abi.json"; - - const worldContract = createContract({ - address: networkConfig.worldAddress as Hex, -- abi: IWorld__factory.abi, -+ abi: IWorldAbi, -``` diff --git a/.changeset/six-kangaroos-sneeze.md b/.changeset/six-kangaroos-sneeze.md deleted file mode 100644 index 3557002a21..0000000000 --- a/.changeset/six-kangaroos-sneeze.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": minor ---- - -Return address of the newly created World from `WorldFactory.deployWorld`. diff --git a/.changeset/sixty-crabs-itch.md b/.changeset/sixty-crabs-itch.md deleted file mode 100644 index 86a083cb62..0000000000 --- a/.changeset/sixty-crabs-itch.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Fixed `resolveUserTypes` for static arrays. -`resolveUserTypes` is used by `deploy`, which prevented deploying tables with static arrays. diff --git a/.changeset/sixty-queens-brake.md b/.changeset/sixty-queens-brake.md deleted file mode 100644 index 0d77ecb2d8..0000000000 --- a/.changeset/sixty-queens-brake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": minor ---- - -Replaced the static array length getters in table libraries with constants. diff --git a/.changeset/slimy-glasses-tickle.md b/.changeset/slimy-glasses-tickle.md deleted file mode 100644 index afff6974d1..0000000000 --- a/.changeset/slimy-glasses-tickle.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@latticexyz/cli": patch -"create-mud": patch ---- - -Sped up builds by using more of forge's cache. - -Previously we'd build only what we needed because we would check in ABIs and other build artifacts into git, but that meant that we'd get a lot of forge cache misses. Now that we no longer need these files visible, we can take advantage of forge's caching and greatly speed up builds, especially incremental ones. diff --git a/.changeset/small-boxes-rush.md b/.changeset/small-boxes-rush.md deleted file mode 100644 index 2371c17af4..0000000000 --- a/.changeset/small-boxes-rush.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/dev-tools": patch ---- - -Updates `table` reference to `tableId` diff --git a/.changeset/small-brooms-prove.md b/.changeset/small-brooms-prove.md deleted file mode 100644 index 7207ef0911..0000000000 --- a/.changeset/small-brooms-prove.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Fixed M-04 Memory Corruption on Load From Storage -It only affected external use of `Storage.load` with a `memoryPointer` argument diff --git a/.changeset/small-chicken-repair.md b/.changeset/small-chicken-repair.md deleted file mode 100644 index f41b8e9190..0000000000 --- a/.changeset/small-chicken-repair.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -"@latticexyz/block-logs-stream": patch -"@latticexyz/cli": patch -"@latticexyz/common": major -"@latticexyz/dev-tools": patch -"@latticexyz/store-sync": patch -"@latticexyz/store": major -"create-mud": minor ---- - -What used to be known as `ephemeral` table is now called `offchain` table. -The previous `ephemeral` tables only supported an `emitEphemeral` method, which emitted a `StoreSetEphemeralRecord` event. - -Now `offchain` tables support all regular table methods, except partial operations on dynamic fields (`push`, `pop`, `update`). -Unlike regular tables they don't store data on-chain but emit the same events as regular tables (`StoreSetRecord`, `StoreSpliceStaticData`, `StoreDeleteRecord`), so their data can be indexed by offchain indexers/clients. - -```diff -- EphemeralTable.emitEphemeral(value); -+ OffchainTable.set(value); -``` diff --git a/.changeset/small-dots-poke.md b/.changeset/small-dots-poke.md deleted file mode 100644 index b77247857c..0000000000 --- a/.changeset/small-dots-poke.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/common": patch -"@latticexyz/config": patch ---- - -Removed chalk usage from modules imported in client fix downstream client builds (vite in particular). diff --git a/.changeset/small-pots-press.md b/.changeset/small-pots-press.md deleted file mode 100644 index 9cfd156b45..0000000000 --- a/.changeset/small-pots-press.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@latticexyz/store-sync": patch -"@latticexyz/store": major -"@latticexyz/world-modules": patch -"@latticexyz/world": major ---- - -Moved `store` tables to the `"store"` namespace (previously "mudstore") and `world` tables to the `"world"` namespace (previously root namespace). diff --git a/.changeset/smart-actors-refuse.md b/.changeset/smart-actors-refuse.md deleted file mode 100644 index 2a8a688d3e..0000000000 --- a/.changeset/smart-actors-refuse.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/gas-report": minor ---- - -Now uses `--isolate` flag in `forge test` for more accurate gas measurement. diff --git a/.changeset/smart-fireants-play.md b/.changeset/smart-fireants-play.md deleted file mode 100644 index 17aecdb385..0000000000 --- a/.changeset/smart-fireants-play.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/store": patch -"@latticexyz/world": patch ---- - -Removed unused imports from various files in the `store` and `world` packages. diff --git a/.changeset/smart-games-taste.md b/.changeset/smart-games-taste.md deleted file mode 100644 index 7de3a638ed..0000000000 --- a/.changeset/smart-games-taste.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Prevented invalid delegations by performing full validation regardless of whether `initCallData` is empty. Added an `unregisterDelegation` function which allows explicit unregistration, as opposed of passing in zero bytes into `registerDelegation`. diff --git a/.changeset/smooth-elephants-wave.md b/.changeset/smooth-elephants-wave.md deleted file mode 100644 index 63b368bfe4..0000000000 --- a/.changeset/smooth-elephants-wave.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@latticexyz/dev-tools": patch -"@latticexyz/store-indexer": minor -"@latticexyz/store-sync": minor ---- - -Store sync logic is now consolidated into a `createStoreSync` function exported from `@latticexyz/store-sync`. This simplifies each storage sync strategy to just a simple wrapper around the storage adapter. You can now sync to RECS with `syncToRecs` or SQLite with `syncToSqlite` and PostgreSQL support coming soon. - -There are no breaking changes if you were just using `syncToRecs` from `@latticexyz/store-sync` or running the `sqlite-indexer` binary from `@latticexyz/store-indexer`. diff --git a/.changeset/smooth-pots-nail.md b/.changeset/smooth-pots-nail.md deleted file mode 100644 index 54a707713d..0000000000 --- a/.changeset/smooth-pots-nail.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/dev-tools": patch -"@latticexyz/store-sync": patch ---- - -Improves support for internal/client-only RECS components diff --git a/.changeset/soft-boxes-smile.md b/.changeset/soft-boxes-smile.md deleted file mode 100644 index 98dd773a9d..0000000000 --- a/.changeset/soft-boxes-smile.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -"@latticexyz/store-sync": minor ---- - -`blockLogsToStorage(sqliteStorage(...))` converts block logs to SQLite operations. You can use it like: - -```ts -import { drizzle } from "drizzle-orm/better-sqlite3"; -import Database from "better-sqlite3"; -import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core"; -import { createPublicClient } from "viem"; -import { blockLogsToStorage } from "@latticexyz/store-sync"; -import { sqliteStorage } from "@latticexyz/store-sync/sqlite"; - -const database = drizzle(new Database('store.db')) as any as BaseSQLiteDatabase<"sync", void>; -const publicClient = createPublicClient({ ... }); - -blockLogs$ - .pipe( - concatMap(blockLogsToStorage(sqliteStorage({ database, publicClient }))), - tap(({ blockNumber, operations }) => { - console.log("stored", operations.length, "operations for block", blockNumber); - }) - ) - .subscribe(); -``` diff --git a/.changeset/soft-dryers-invite.md b/.changeset/soft-dryers-invite.md deleted file mode 100644 index 34fcc37c14..0000000000 --- a/.changeset/soft-dryers-invite.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -"@latticexyz/dev-tools": major -"create-mud": major ---- - -MUD dev tools is updated to latest sync stack. You must now pass in all of its data requirements rather than relying on magic globals. - -```diff -import { mount as mountDevTools } from "@latticexyz/dev-tools"; - -- mountDevTools(); -+ mountDevTools({ -+ config, -+ publicClient, -+ walletClient, -+ latestBlock$, -+ blockStorageOperations$, -+ worldAddress, -+ worldAbi, -+ write$, -+ // if you're using recs -+ recsWorld, -+ }); -``` - -It's also advised to wrap dev tools so that it is only mounted during development mode. Here's how you do this with Vite: - -```ts -// https://vitejs.dev/guide/env-and-mode.html -if (import.meta.env.DEV) { - mountDevTools({ ... }); -} -``` diff --git a/.changeset/soft-fans-wink.md b/.changeset/soft-fans-wink.md deleted file mode 100644 index add3beb520..0000000000 --- a/.changeset/soft-fans-wink.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -"@latticexyz/store": minor -"@latticexyz/world": minor ---- - -Add protocol version with corresponding getter and event on deploy - -```solidity -world.worldVersion(); -world.storeVersion(); // a World is also a Store -``` - -```solidity -event HelloWorld(bytes32 indexed worldVersion); -event HelloStore(bytes32 indexed storeVersion); -``` diff --git a/.changeset/soft-panthers-develop.md b/.changeset/soft-panthers-develop.md deleted file mode 100644 index c4b0f65d32..0000000000 --- a/.changeset/soft-panthers-develop.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/world-modules": patch -"@latticexyz/store": patch -"@latticexyz/world": patch ---- - -Refactored various Solidity files to not explicitly initialise variables to zero. diff --git a/.changeset/sour-cycles-warn.md b/.changeset/sour-cycles-warn.md deleted file mode 100644 index 1a79d508c5..0000000000 --- a/.changeset/sour-cycles-warn.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/store": minor -"@latticexyz/world": patch ---- - -`StoreCore` and `IStore` now expose specific functions for `getStaticField` and `getDynamicField` in addition to the general `getField`. -Using the specific functions reduces gas overhead because more optimized logic can be executed. - -```solidity -interface IStore { - /** - * Get a single static field from the given tableId and key tuple, with the given value field layout. - * Note: the field value is left-aligned in the returned bytes32, the rest of the word is not zeroed out. - * Consumers are expected to truncate the returned value as needed. - */ - function getStaticField( - bytes32 tableId, - bytes32[] calldata keyTuple, - uint8 fieldIndex, - FieldLayout fieldLayout - ) external view returns (bytes32); - - /** - * Get a single dynamic field from the given tableId and key tuple at the given dynamic field index. - * (Dynamic field index = field index - number of static fields) - */ - function getDynamicField( - bytes32 tableId, - bytes32[] memory keyTuple, - uint8 dynamicFieldIndex - ) external view returns (bytes memory); -} -``` diff --git a/.changeset/sour-rivers-grow.md b/.changeset/sour-rivers-grow.md deleted file mode 100644 index 811507bc2c..0000000000 --- a/.changeset/sour-rivers-grow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-indexer": patch ---- - -Added a binary for the `postgres-decoded` indexer. diff --git a/.changeset/spicy-bees-teach.md b/.changeset/spicy-bees-teach.md deleted file mode 100644 index 83d920fc8e..0000000000 --- a/.changeset/spicy-bees-teach.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/react": major ---- - -Removes `useRow` and `useRows` hooks, previously powered by `store-cache`, which is now deprecated. Please use `recs` and the corresponding `useEntityQuery` and `useComponentValue` hooks. We'll have more hooks soon for SQL.js sync backends. diff --git a/.changeset/spicy-waves-wait.md b/.changeset/spicy-waves-wait.md deleted file mode 100644 index 9c070fdd64..0000000000 --- a/.changeset/spicy-waves-wait.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Moved the `HelloStore` to `IStoreEvents` so all Store events are defined in the same interface. diff --git a/.changeset/spotty-balloons-itch.md b/.changeset/spotty-balloons-itch.md deleted file mode 100644 index bc704d667c..0000000000 --- a/.changeset/spotty-balloons-itch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Refactored some Store functions to use a right bit mask instead of left. diff --git a/.changeset/spotty-cups-destroy.md b/.changeset/spotty-cups-destroy.md deleted file mode 100644 index 0681b6969e..0000000000 --- a/.changeset/spotty-cups-destroy.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-sync": patch ---- - -remove usages of `isNonPendingBlock` and `isNonPendingLog` (fixed with more specific viem types) diff --git a/.changeset/spotty-geese-yawn.md b/.changeset/spotty-geese-yawn.md deleted file mode 100644 index c8198a9ac3..0000000000 --- a/.changeset/spotty-geese-yawn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world-modules": patch ---- - -Renamed token address fields in ERC20 and ERC721 modules to `tokenAddress` diff --git a/.changeset/spotty-sheep-warn.md b/.changeset/spotty-sheep-warn.md deleted file mode 100644 index a5bef0d676..0000000000 --- a/.changeset/spotty-sheep-warn.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@latticexyz/cli": patch -"create-mud": patch -"@latticexyz/utils": patch -"@latticexyz/world": patch ---- - -bump to latest TS version (5.1.6) diff --git a/.changeset/stale-cooks-reflect.md b/.changeset/stale-cooks-reflect.md deleted file mode 100644 index 3e5fb19dd5..0000000000 --- a/.changeset/stale-cooks-reflect.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -"@latticexyz/block-logs-stream": patch -"@latticexyz/cli": patch -"@latticexyz/common": patch -"@latticexyz/dev-tools": patch -"@latticexyz/network": patch -"@latticexyz/protocol-parser": patch -"@latticexyz/schema-type": patch -"@latticexyz/std-client": patch -"@latticexyz/store-cache": patch -"@latticexyz/store-sync": patch -"@latticexyz/store": patch -create-mud: patch ---- - -- bump to viem 1.3.0 and abitype 0.9.3 -- move `@wagmi/chains` imports to `viem/chains` -- refine a few types diff --git a/.changeset/stale-schools-wait.md b/.changeset/stale-schools-wait.md deleted file mode 100644 index 64ba5fab72..0000000000 --- a/.changeset/stale-schools-wait.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -"@latticexyz/block-logs-stream": patch -"@latticexyz/dev-tools": patch -"@latticexyz/store-sync": patch -"@latticexyz/store": major ---- - -`Store` events have been renamed for consistency and readability. -If you're parsing `Store` events manually, you need to update your ABI. -If you're using the MUD sync stack, the new events are already integrated and no further changes are necessary. - -```diff -- event StoreSetRecord( -+ event Store_SetRecord( - ResourceId indexed tableId, - bytes32[] keyTuple, - bytes staticData, - bytes32 encodedLengths, - bytes dynamicData - ); -- event StoreSpliceStaticData( -+ event Store_SpliceStaticData( - ResourceId indexed tableId, - bytes32[] keyTuple, - uint48 start, - uint40 deleteCount, - bytes data - ); -- event StoreSpliceDynamicData( -+ event Store_SpliceDynamicData( - ResourceId indexed tableId, - bytes32[] keyTuple, - uint48 start, - uint40 deleteCount, - bytes data, - bytes32 encodedLengths - ); -- event StoreDeleteRecord( -+ event Store_DeleteRecord( - ResourceId indexed tableId, - bytes32[] keyTuple - ); -``` diff --git a/.changeset/stale-seahorses-pay.md b/.changeset/stale-seahorses-pay.md deleted file mode 100644 index 8bd942565b..0000000000 --- a/.changeset/stale-seahorses-pay.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -"@latticexyz/cli": major -"@latticexyz/common": major -"@latticexyz/config": major -"@latticexyz/store": major ---- - -- `ResourceSelector` is replaced with `ResourceId`, `ResourceIdLib`, `ResourceIdInstance`, `WorldResourceIdLib` and `WorldResourceIdInstance`. - - Previously a "resource selector" was a `bytes32` value with the first 16 bytes reserved for the resource's namespace, and the last 16 bytes reserved for the resource's name. - Now a "resource ID" is a `bytes32` value with the first 2 bytes reserved for the resource type, the next 14 bytes reserved for the resource's namespace, and the last 16 bytes reserved for the resource's name. - - Previously `ResouceSelector` was a library and the resource selector type was a plain `bytes32`. - Now `ResourceId` is a user type, and the functionality is implemented in the `ResourceIdInstance` (for type) and `WorldResourceIdInstance` (for namespace and name) libraries. - We split the logic into two libraries, because `Store` now also uses `ResourceId` and needs to be aware of resource types, but not of namespaces/names. - - ```diff - - import { ResourceSelector } from "@latticexyz/world/src/ResourceSelector.sol"; - + import { ResourceId, ResourceIdInstance } from "@latticexyz/store/src/ResourceId.sol"; - + import { WorldResourceIdLib, WorldResourceIdInstance } from "@latticexyz/world/src/WorldResourceId.sol"; - + import { RESOURCE_SYSTEM } from "@latticexyz/world/src/worldResourceTypes.sol"; - - - bytes32 systemId = ResourceSelector.from("namespace", "name"); - + ResourceId systemId = WorldResourceIdLib.encode(RESOURCE_SYSTEM, "namespace", "name"); - - - using ResourceSelector for bytes32; - + using WorldResourceIdInstance for ResourceId; - + using ResourceIdInstance for ResourceId; - - systemId.getName(); - systemId.getNamespace(); - + systemId.getType(); - - ``` - -- All `Store` and `World` methods now use the `ResourceId` type for `tableId`, `systemId`, `moduleId` and `namespaceId`. - All mentions of `resourceSelector` were renamed to `resourceId` or the more specific type (e.g. `tableId`, `systemId`) - - ```diff - import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; - - IStore { - function setRecord( - - bytes32 tableId, - + ResourceId tableId, - bytes32[] calldata keyTuple, - bytes calldata staticData, - PackedCounter encodedLengths, - bytes calldata dynamicData, - FieldLayout fieldLayout - ) external; - - // Same for all other methods - } - ``` - - ```diff - import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; - - IBaseWorld { - function callFrom( - address delegator, - - bytes32 resourceSelector, - + ResourceId systemId, - bytes memory callData - ) external payable returns (bytes memory); - - // Same for all other methods - } - ``` diff --git a/.changeset/stale-worms-hunt.md b/.changeset/stale-worms-hunt.md deleted file mode 100644 index 07e7c2fb16..0000000000 --- a/.changeset/stale-worms-hunt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": major ---- - -Store events now use an `indexed` `tableId`. This adds ~100 gas per write, but means we our sync stack can filter events by table. diff --git a/.changeset/strange-candles-shout.md b/.changeset/strange-candles-shout.md deleted file mode 100644 index a68835c468..0000000000 --- a/.changeset/strange-candles-shout.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/services": patch ---- - -fix a bug related to encoding negative bigints in MODE diff --git a/.changeset/strange-cheetahs-drop.md b/.changeset/strange-cheetahs-drop.md deleted file mode 100644 index dfe0fcc63d..0000000000 --- a/.changeset/strange-cheetahs-drop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -`IWorldKernel` now inherits `IModuleErrors` so it can render the correct errors if the World reverts when delegatecalled with Module code. diff --git a/.changeset/strange-ducks-float.md b/.changeset/strange-ducks-float.md deleted file mode 100644 index 39ff32f010..0000000000 --- a/.changeset/strange-ducks-float.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"@latticexyz/common": minor ---- - -`TableId.toHex()` now truncates name/namespace to 16 bytes each, to properly fit into a `bytes32` hex string. - -Also adds a few utils we'll need in the indexer: - -- `bigIntMin` is similar to `Math.min` but for `bigint`s -- `bigIntMax` is similar to `Math.max` but for `bigint`s -- `bigIntSort` for sorting an array of `bigint`s -- `chunk` to split an array into chunks -- `wait` returns a `Promise` that resolves after specified number of milliseconds diff --git a/.changeset/strong-geckos-shake.md b/.changeset/strong-geckos-shake.md deleted file mode 100644 index 88111ad99b..0000000000 --- a/.changeset/strong-geckos-shake.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/store": patch -"@latticexyz/world": patch ---- - -Optimize Schema methods. -Return `uint256` instead of `uint8` in SchemaInstance numFields methods diff --git a/.changeset/strong-months-push.md b/.changeset/strong-months-push.md deleted file mode 100644 index 42b321ce1c..0000000000 --- a/.changeset/strong-months-push.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@latticexyz/store": major ---- - -- `StoreCore`'s `initialize` function is split into `initialize` (to set the `StoreSwitch`'s `storeAddress`) and `registerCoreTables` (to register the `Tables` and `StoreHooks` tables). - The purpose of this is to give consumers more granular control over the setup flow. - -- The `StoreRead` contract no longer calls `StoreCore.initialize` in its constructor. - `StoreCore` consumers are expected to call `StoreCore.initialize` and `StoreCore.registerCoreTable` in their own setup logic. diff --git a/.changeset/sweet-kiwis-unite.md b/.changeset/sweet-kiwis-unite.md deleted file mode 100644 index 9326587779..0000000000 --- a/.changeset/sweet-kiwis-unite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": patch ---- - -`deploy` and `dev-contracts` CLI commands now use `forge build --skip test script` before deploying and run `mud abi-ts` to generate strong types for ABIs. diff --git a/.changeset/tall-buses-kick.md b/.changeset/tall-buses-kick.md deleted file mode 100644 index 834b2478cc..0000000000 --- a/.changeset/tall-buses-kick.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": minor ---- - -Add an optional `namePrefix` argument to `renderRecordData`, to support inlined logic in codegenned `set` method which uses a struct. diff --git a/.changeset/tame-lemons-play.md b/.changeset/tame-lemons-play.md deleted file mode 100644 index 17de0f9339..0000000000 --- a/.changeset/tame-lemons-play.md +++ /dev/null @@ -1,194 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/common": major -"@latticexyz/recs": patch -"@latticexyz/store-indexer": patch -"create-mud": major ---- - -Templates and examples now use MUD's new sync packages, all built on top of [viem](https://viem.sh/). This greatly speeds up and stabilizes our networking code and improves types throughout. - -These new sync packages come with support for our `recs` package, including `encodeEntity` and `decodeEntity` utilities for composite keys. - -If you're using `store-cache` and `useRow`/`useRows`, you should wait to upgrade until we have a suitable replacement for those libraries. We're working on a [sql.js](https://github.com/sql-js/sql.js/)-powered sync module that will replace `store-cache`. - -**Migrate existing RECS apps to new sync packages** - -As you migrate, you may find some features replaced, removed, or not included by default. Please [open an issue](https://github.com/latticexyz/mud/issues/new) and let us know if we missed anything. - -1. Add `@latticexyz/store-sync` package to your app's `client` package and make sure `viem` is pinned to version `1.3.1` (otherwise you may get type errors) - -2. In your `supportedChains.ts`, replace `foundry` chain with our new `mudFoundry` chain. - - ```diff - - import { foundry } from "viem/chains"; - - import { MUDChain, latticeTestnet } from "@latticexyz/common/chains"; - + import { MUDChain, latticeTestnet, mudFoundry } from "@latticexyz/common/chains"; - - - export const supportedChains: MUDChain[] = [foundry, latticeTestnet]; - + export const supportedChains: MUDChain[] = [mudFoundry, latticeTestnet]; - ``` - -3. In `getNetworkConfig.ts`, remove the return type (to let TS infer it for now), remove now-unused config values, and add the viem `chain` object. - - ```diff - - export async function getNetworkConfig(): Promise { - + export async function getNetworkConfig() { - ``` - - ```diff - const initialBlockNumber = params.has("initialBlockNumber") - ? Number(params.get("initialBlockNumber")) - - : world?.blockNumber ?? -1; // -1 will attempt to find the block number from RPC - + : world?.blockNumber ?? 0n; - ``` - - ```diff - + return { - + privateKey: getBurnerWallet().value, - + chain, - + worldAddress, - + initialBlockNumber, - + faucetServiceUrl: params.get("faucet") ?? chain.faucetUrl, - + }; - ``` - -4. In `setupNetwork.ts`, replace `setupMUDV2Network` with `syncToRecs`. - - ```diff - - import { setupMUDV2Network } from "@latticexyz/std-client"; - - import { createFastTxExecutor, createFaucetService, getSnapSyncRecords } from "@latticexyz/network"; - + import { createFaucetService } from "@latticexyz/network"; - + import { createPublicClient, fallback, webSocket, http, createWalletClient, getContract, Hex, parseEther, ClientConfig } from "viem"; - + import { encodeEntity, syncToRecs } from "@latticexyz/store-sync/recs"; - + import { createBurnerAccount, createContract, transportObserver } from "@latticexyz/common"; - ``` - - ```diff - - const result = await setupMUDV2Network({ - - ... - - }); - - + const clientOptions = { - + chain: networkConfig.chain, - + transport: transportObserver(fallback([webSocket(), http()])), - + pollingInterval: 1000, - + } as const satisfies ClientConfig; - - + const publicClient = createPublicClient(clientOptions); - - + const burnerAccount = createBurnerAccount(networkConfig.privateKey as Hex); - + const burnerWalletClient = createWalletClient({ - + ...clientOptions, - + account: burnerAccount, - + }); - - + const { components, latestBlock$, blockStorageOperations$, waitForTransaction } = await syncToRecs({ - + world, - + config: storeConfig, - + address: networkConfig.worldAddress as Hex, - + publicClient, - + components: contractComponents, - + startBlock: BigInt(networkConfig.initialBlockNumber), - + indexerUrl: networkConfig.indexerUrl ?? undefined, - + }); - - + const worldContract = createContract({ - + address: networkConfig.worldAddress as Hex, - + abi: IWorld__factory.abi, - + publicClient, - + walletClient: burnerWalletClient, - + }); - ``` - - ```diff - // Request drip from faucet - - const signer = result.network.signer.get(); - - if (networkConfig.faucetServiceUrl && signer) { - - const address = await signer.getAddress(); - + if (networkConfig.faucetServiceUrl) { - + const address = burnerAccount.address; - ``` - - ```diff - const requestDrip = async () => { - - const balance = await signer.getBalance(); - + const balance = await publicClient.getBalance({ address }); - console.info(`[Dev Faucet]: Player balance -> ${balance}`); - - const lowBalance = balance?.lte(utils.parseEther("1")); - + const lowBalance = balance < parseEther("1"); - ``` - - You can remove the previous ethers `worldContract`, snap sync code, and fast transaction executor. - - The return of `setupNetwork` is a bit different than before, so you may have to do corresponding app changes. - - ```diff - + return { - + world, - + components, - + playerEntity: encodeEntity({ address: "address" }, { address: burnerWalletClient.account.address }), - + publicClient, - + walletClient: burnerWalletClient, - + latestBlock$, - + blockStorageOperations$, - + waitForTransaction, - + worldContract, - + }; - ``` - -5. Update `createSystemCalls` with the new return type of `setupNetwork`. - - ```diff - export function createSystemCalls( - - { worldSend, txReduced$, singletonEntity }: SetupNetworkResult, - + { worldContract, waitForTransaction }: SetupNetworkResult, - { Counter }: ClientComponents - ) { - const increment = async () => { - - const tx = await worldSend("increment", []); - - await awaitStreamValue(txReduced$, (txHash) => txHash === tx.hash); - + const tx = await worldContract.write.increment(); - + await waitForTransaction(tx); - return getComponentValue(Counter, singletonEntity); - }; - ``` - -6. (optional) If you still need a clock, you can create it with: - - ```ts - import { map, filter } from "rxjs"; - import { createClock } from "@latticexyz/network"; - - const clock = createClock({ - period: 1000, - initialTime: 0, - syncInterval: 5000, - }); - - world.registerDisposer(() => clock.dispose()); - - latestBlock$ - .pipe( - map((block) => Number(block.timestamp) * 1000), // Map to timestamp in ms - filter((blockTimestamp) => blockTimestamp !== clock.lastUpdateTime), // Ignore if the clock was already refreshed with this block - filter((blockTimestamp) => blockTimestamp !== clock.currentTime), // Ignore if the current local timestamp is correct - ) - .subscribe(clock.update); // Update the local clock - ``` - -If you're using the previous `LoadingState` component, you'll want to migrate to the new `SyncProgress`: - -```ts -import { SyncStep, singletonEntity } from "@latticexyz/store-sync/recs"; - -const syncProgress = useComponentValue(SyncProgress, singletonEntity, { - message: "Connecting", - percentage: 0, - step: SyncStep.INITIALIZE, -}); - -if (syncProgress.step === SyncStep.LIVE) { - // we're live! -} -``` diff --git a/.changeset/tasty-balloons-collect.md b/.changeset/tasty-balloons-collect.md deleted file mode 100644 index d6401790b5..0000000000 --- a/.changeset/tasty-balloons-collect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/react": patch ---- - -Fixed an issue where `useComponentValue` would not detect a change and re-render if the component value was immediately removed. diff --git a/.changeset/tasty-cows-pay.md b/.changeset/tasty-cows-pay.md deleted file mode 100644 index 4099aaee5a..0000000000 --- a/.changeset/tasty-cows-pay.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-indexer": minor ---- - -When the Postgres indexer starts up, it will now attempt to detect if the database is outdated and, if so, cleans up all MUD-related schemas and tables before proceeding. diff --git a/.changeset/thick-masks-wait.md b/.changeset/thick-masks-wait.md deleted file mode 100644 index 50baa2f850..0000000000 --- a/.changeset/thick-masks-wait.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-sync": patch ---- - -Fixed invalid value when decoding records in `postgres-decoded` storage adapter diff --git a/.changeset/thin-boxes-sparkle.md b/.changeset/thin-boxes-sparkle.md deleted file mode 100644 index c03d8c9227..0000000000 --- a/.changeset/thin-boxes-sparkle.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@latticexyz/cli": minor ---- - -`mud deploy` now supports public/linked libraries. - -This helps with cases where system contracts would exceed the EVM bytecode size limit and logic would need to be split into many smaller systems. - -Instead of the overhead and complexity of system-to-system calls, this logic can now be moved into public libraries that will be deployed alongside your systems and automatically `delegatecall`ed. diff --git a/.changeset/thin-buses-reply.md b/.changeset/thin-buses-reply.md deleted file mode 100644 index 8e4726cbdc..0000000000 --- a/.changeset/thin-buses-reply.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -"@latticexyz/cli": minor ---- - -- update the `set-version` cli command to work with the new release process by adding two new options: - - `--tag`: install the latest version of the given tag. For snapshot releases tags correspond to the branch name, commits to `main` result in an automatic snapshot release, so `--tag main` is equivalent to what used to be `-v canary` - - `--commit`: install a version based on a given commit hash. Since commits from `main` result in an automatic snapshot release it works for all commits on main, and it works for manual snapshot releases from branches other than main -- `set-version` now updates all `package.json` nested below the current working directory (expect `node_modules`), so no need for running it each workspace of a monorepo separately. - -Example: - -```bash -pnpm mud set-version --tag main && pnpm install -pnpm mud set-version --commit db19ea39 && pnpm install -``` diff --git a/.changeset/thin-chairs-compare.md b/.changeset/thin-chairs-compare.md deleted file mode 100644 index 6d76a5ab99..0000000000 --- a/.changeset/thin-chairs-compare.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/common": patch -"@latticexyz/store": major ---- - -Changed the `userTypes` property to accept `{ filePath: string, internalType: SchemaAbiType }` to enable strong type inference from the config. diff --git a/.changeset/thin-days-sparkle.md b/.changeset/thin-days-sparkle.md deleted file mode 100644 index c174f8de3b..0000000000 --- a/.changeset/thin-days-sparkle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Simplified a check in `Slice.getSubslice`. diff --git a/.changeset/thin-rice-trade.md b/.changeset/thin-rice-trade.md deleted file mode 100644 index 13d4781cbe..0000000000 --- a/.changeset/thin-rice-trade.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-indexer": patch ---- - -Added README and refactored handling of common environment variables diff --git a/.changeset/thin-terms-lay.md b/.changeset/thin-terms-lay.md deleted file mode 100644 index 5f71ab8524..0000000000 --- a/.changeset/thin-terms-lay.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/common": minor -"@latticexyz/store": minor -"@latticexyz/world": patch ---- - -Generated table libraries now have a set of functions prefixed with `_` that always use their own storage for read/write. -This saves gas for use cases where the functionality to dynamically determine which `Store` to use for read/write is not needed, e.g. root systems in a `World`, or when using `Store` without `World`. - -We decided to continue to always generate a set of functions that dynamically decide which `Store` to use, so that the generated table libraries can still be imported by non-root systems. - -```solidity -library Counter { - // Dynamically determine which store to write to based on the context - function set(uint32 value) internal; - - // Always write to own storage - function _set(uint32 value) internal; - - // ... equivalent functions for all other Store methods -} -``` diff --git a/.changeset/thirty-cups-provide.md b/.changeset/thirty-cups-provide.md deleted file mode 100644 index 04d79df7f2..0000000000 --- a/.changeset/thirty-cups-provide.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -"@latticexyz/common": minor ---- - -Renames `resourceIdToHex` to `resourceToHex` and `hexToResourceId` to `hexToResource`, to better distinguish between a resource ID (hex value) and a resource reference (type, namespace, name). - -```diff -- resourceIdToHex({ type: 'table', namespace: '', name: 'Position' }); -+ resourceToHex({ type: 'table', namespace: '', name: 'Position' }); -``` - -```diff -- hexToResourceId('0x...'); -+ hexToResource('0x...'); -``` - -Previous methods still exist but are now deprecated to ease migration and reduce breaking changes. These will be removed in a future version. - -Also removes the previously deprecated and unused table ID utils (replaced by these resource ID utils). diff --git a/.changeset/thirty-shoes-run.md b/.changeset/thirty-shoes-run.md deleted file mode 100644 index 833f76aded..0000000000 --- a/.changeset/thirty-shoes-run.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Added a check to prevent namespaces from ending with an underscore (which could cause problems with world function signatures). diff --git a/.changeset/three-lizards-shave.md b/.changeset/three-lizards-shave.md deleted file mode 100644 index 66466f5cc8..0000000000 --- a/.changeset/three-lizards-shave.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/common": patch -"@latticexyz/world": minor ---- - -Replaced temporary `.mudtest` file in favor of `WORLD_ADDRESS` environment variable when running tests with `MudTest` contract diff --git a/.changeset/three-llamas-sin.md b/.changeset/three-llamas-sin.md deleted file mode 100644 index 75d44607b3..0000000000 --- a/.changeset/three-llamas-sin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Refactored `WorldContext` to get the world address from `WorldContextConsumerLib` instead of `StoreSwitch`. diff --git a/.changeset/three-scissors-smile.md b/.changeset/three-scissors-smile.md deleted file mode 100644 index 6626fe6a83..0000000000 --- a/.changeset/three-scissors-smile.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/common": minor ---- - -Added a `mapObject` helper to map the value of each property of an object to a new value. diff --git a/.changeset/tidy-ants-ring.md b/.changeset/tidy-ants-ring.md deleted file mode 100644 index 5e2615edbb..0000000000 --- a/.changeset/tidy-ants-ring.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": minor ---- - -Removed `allowEmpty` option from `FieldLayout.validate()` as field layouts should never be empty. diff --git a/.changeset/tidy-stingrays-think.md b/.changeset/tidy-stingrays-think.md deleted file mode 100644 index 2bbee42817..0000000000 --- a/.changeset/tidy-stingrays-think.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@latticexyz/world": major ---- - -Namespaces are not allowed to contain double underscores ("\_\_") anymore, as this sequence of characters is used to [separate the namespace and function selector](https://github.com/latticexyz/mud/pull/2168) in namespaced systems. -This is to prevent signature clashes of functions in different namespaces. - -(Example: If namespaces were allowed to contain this separator string, a function "function" in namespace "namespace\_\_my" would result in the namespaced function selector "namespace\_\_my\_\_function", -and would clash with a function "my\_\_function" in namespace "namespace".) diff --git a/.changeset/tiny-lions-listen.md b/.changeset/tiny-lions-listen.md deleted file mode 100644 index 0c22e706b2..0000000000 --- a/.changeset/tiny-lions-listen.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/faucet": patch ---- - -Updated to use MUD's `sendTransaction`, which does a better of managing nonces for higher volumes of transactions. diff --git a/.changeset/tough-dolphins-bathe.md b/.changeset/tough-dolphins-bathe.md deleted file mode 100644 index f212e587cc..0000000000 --- a/.changeset/tough-dolphins-bathe.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/cli": patch ---- - -Added a non-deterministic fallback for deploying to chains that have replay protection on and do not support pre-EIP-155 transactions (no chain ID). - -If you're using `mud deploy` and there's already a [deterministic deployer](https://github.com/Arachnid/deterministic-deployment-proxy) on your target chain, you can provide the address with `--deployerAddress 0x...` to still get some determinism. diff --git a/.changeset/tough-flowers-breathe.md b/.changeset/tough-flowers-breathe.md deleted file mode 100644 index 73480b8afd..0000000000 --- a/.changeset/tough-flowers-breathe.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/store": patch -"@latticexyz/world": patch ---- - -Simplified a couple internal constants used for bitshifting. diff --git a/.changeset/tough-moose-pay.md b/.changeset/tough-moose-pay.md deleted file mode 100644 index 42ced06f9f..0000000000 --- a/.changeset/tough-moose-pay.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/common": minor ---- - -- Added a `Result` type for more explicit and typesafe error handling ([inspired by Rust](https://doc.rust-lang.org/std/result/)). - -- Added a `includes` util as typesafe alternative to [`Array.prototype.includes()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes). diff --git a/.changeset/tough-pumpkins-reply.md b/.changeset/tough-pumpkins-reply.md deleted file mode 100644 index 559c3ef6d5..0000000000 --- a/.changeset/tough-pumpkins-reply.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -"create-mud": patch -"@latticexyz/store": minor -"@latticexyz/world": minor -"@latticexyz/world-modules": minor ---- - -Moved key schema and value schema methods to constants in code-generated table libraries for less bytecode and less gas in register/install methods. - -```diff --console.log(SomeTable.getKeySchema()); -+console.log(SomeTable._keySchema); - --console.log(SomeTable.getValueSchema()); -+console.log(SomeTable._valueSchema); -``` diff --git a/.changeset/tricky-beds-kiss.md b/.changeset/tricky-beds-kiss.md deleted file mode 100644 index 151ec9202a..0000000000 --- a/.changeset/tricky-beds-kiss.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/world": minor ---- - -- The `World` contract now has an `initialize` function, which can be called once by the creator of the World to install the core module. - This change allows the registration of all core tables to happen in the `CoreModule`, so no table metadata has to be included in the `World`'s bytecode. - - ```solidity - interface IBaseWorld { - function initialize(IModule coreModule) public; - } - ``` - -- The `World` contract now stores the original creator of the `World` in an immutable state variable. - It is used internally to only allow the original creator to initialize the `World` in a separate transaction. - - ```solidity - interface IBaseWorld { - function creator() external view returns (address); - } - ``` - -- The deploy script is updated to use the `World`'s `initialize` function to install the `CoreModule` instead of `registerRootModule` as before. diff --git a/.changeset/tricky-carrots-talk.md b/.changeset/tricky-carrots-talk.md deleted file mode 100644 index 30626fbad7..0000000000 --- a/.changeset/tricky-carrots-talk.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/gas-report": major ---- - -Renames `mud-gas-report` binary to `gas-report`, since it's no longer MUD specific. diff --git a/.changeset/tricky-comics-remain.md b/.changeset/tricky-comics-remain.md deleted file mode 100644 index 99495e47a8..0000000000 --- a/.changeset/tricky-comics-remain.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": minor ---- - -Moved `KeySchema`, `ValueSchema`, `SchemaToPrimitives` and `TableRecord` types into `@latticexyz/protocol-parser` diff --git a/.changeset/tricky-frogs-beam.md b/.changeset/tricky-frogs-beam.md deleted file mode 100644 index cbff4e5c78..0000000000 --- a/.changeset/tricky-frogs-beam.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/network": patch ---- - -Remove devEmit function when sending network events from SyncWorker because they can't be serialized across the web worker boundary. diff --git a/.changeset/tricky-gifts-compare.md b/.changeset/tricky-gifts-compare.md deleted file mode 100644 index c4737e7eae..0000000000 --- a/.changeset/tricky-gifts-compare.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"@latticexyz/store-sync": minor ---- - -Added and populated `syncProgress` key in Zustand store for sync progress, like we do for RECS sync. This will let apps using `syncToZustand` render a loading state while initial client hydration is in progress. - -```tsx -const syncProgress = useStore((state) => state.syncProgress); - -if (syncProgress.step !== SyncStep.LIVE) { - return <>Loading ({Math.floor(syncProgress.percentage)}%); -} -``` diff --git a/.changeset/tricky-kangaroos-love.md b/.changeset/tricky-kangaroos-love.md deleted file mode 100644 index c97a573e2d..0000000000 --- a/.changeset/tricky-kangaroos-love.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/common": minor ---- - -- Moves zero gas fee override to `createContract` until https://github.com/wagmi-dev/viem/pull/963 or similar feature lands -- Skip simulation if `gas` is provided diff --git a/.changeset/tricky-olives-stare.md b/.changeset/tricky-olives-stare.md deleted file mode 100644 index ad1fdd711b..0000000000 --- a/.changeset/tricky-olives-stare.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/common": major -"@latticexyz/dev-tools": patch -"@latticexyz/network": patch -"@latticexyz/std-client": patch -"@latticexyz/store-sync": patch ---- - -Add `tableIdToHex` and `hexToTableId` pure functions and move/deprecate `TableId`. diff --git a/.changeset/tricky-oranges-pump.md b/.changeset/tricky-oranges-pump.md deleted file mode 100644 index 4cd982b9c3..0000000000 --- a/.changeset/tricky-oranges-pump.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@latticexyz/common": major ---- - -Add utils for using viem with MUD - -- `createContract` is a wrapper around [viem's `getContract`](https://viem.sh/docs/contract/getContract.html) but with better nonce handling for faster executing of transactions. It has the same arguments and return type as `getContract`. -- `createNonceManager` helps track local nonces, used by `createContract`. - -Also renames `mudTransportObserver` to `transportObserver`. diff --git a/.changeset/twelve-boats-kick.md b/.changeset/twelve-boats-kick.md deleted file mode 100644 index 2b66cb19f4..0000000000 --- a/.changeset/twelve-boats-kick.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/faucet": minor -"@latticexyz/store-indexer": minor ---- - -Added `/healthz` and `/readyz` healthcheck endpoints for Kubernetes diff --git a/.changeset/twelve-gorillas-learn.md b/.changeset/twelve-gorillas-learn.md deleted file mode 100644 index 156b854945..0000000000 --- a/.changeset/twelve-gorillas-learn.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -"@latticexyz/block-logs-stream": minor -"@latticexyz/cli": minor -"@latticexyz/common": minor -"@latticexyz/config": minor -"@latticexyz/dev-tools": minor -"@latticexyz/faucet": minor -"@latticexyz/protocol-parser": minor -"@latticexyz/schema-type": minor -"@latticexyz/store-indexer": minor -"@latticexyz/store-sync": minor -"@latticexyz/store": minor -"@latticexyz/world": minor -"create-mud": minor ---- - -Upgraded all packages and templates to viem v2.7.12 and abitype v1.0.0. - -Some viem APIs have changed and we've updated `getContract` to reflect those changes and keep it aligned with viem. It's one small code change: - -```diff - const worldContract = getContract({ - address: worldAddress, - abi: IWorldAbi, -- publicClient, -- walletClient, -+ client: { public: publicClient, wallet: walletClient }, - }); -``` diff --git a/.changeset/twelve-monkeys-juggle.md b/.changeset/twelve-monkeys-juggle.md deleted file mode 100644 index 203bfe6c37..0000000000 --- a/.changeset/twelve-monkeys-juggle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/faucet": patch ---- - -Added README diff --git a/.changeset/twelve-terms-lay.md b/.changeset/twelve-terms-lay.md deleted file mode 100644 index 9846e51637..0000000000 --- a/.changeset/twelve-terms-lay.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/store": major -"@latticexyz/world": patch ---- - -Renamed `StoreCore`'s `registerCoreTables` method to `registerInternalTables`. diff --git a/.changeset/twenty-birds-scream.md b/.changeset/twenty-birds-scream.md deleted file mode 100644 index 60f766164e..0000000000 --- a/.changeset/twenty-birds-scream.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -"@latticexyz/react": minor ---- - -Adds a `usePromise` hook that returns a [native `PromiseSettledResult` object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled). - -```tsx -const promise = fetch(url); -const result = usePromise(promise); - -if (result.status === "idle" || result.status === "pending") { - return <>fetching; -} - -if (result.status === "rejected") { - return <>error fetching: {String(result.reason)}; -} - -if (result.status === "fulfilled") { - return <>fetch status: {result.value.status}; -} -``` diff --git a/.changeset/two-feet-jam.md b/.changeset/two-feet-jam.md deleted file mode 100644 index 100f26ca35..0000000000 --- a/.changeset/two-feet-jam.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world-modules": minor ---- - -Added a new delegation control called `SystemboundDelegationControl` that delegates control of a specific system for some maximum number of calls. It is almost identical to `CallboundDelegationControl` except the delegatee can call the system with any function and args. diff --git a/.changeset/unlucky-cups-fetch.md b/.changeset/unlucky-cups-fetch.md deleted file mode 100644 index 237f8fe266..0000000000 --- a/.changeset/unlucky-cups-fetch.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/world": major -"@latticexyz/world-modules": major ---- - -All optional modules have been moved from `@latticexyz/world` to `@latticexyz/world-modules`. -If you're using the MUD CLI, the import is already updated and no changes are necessary. diff --git a/.changeset/unlucky-guests-cover.md b/.changeset/unlucky-guests-cover.md deleted file mode 100644 index 65ba957d11..0000000000 --- a/.changeset/unlucky-guests-cover.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -"@latticexyz/store": minor -"@latticexyz/world": minor ---- - -We now use `@latticexyz/abi-ts` to generate TS type declaration files (`.d.ts`) for each ABI JSON file. This replaces our usage TypeChain everywhere. - -If you previously relied on TypeChain types from `@latticexyz/store` or `@latticexyz/world`, you will either need to migrate to viem or abitype using ABI JSON imports or generate TypeChain types from our exported ABI JSON files. - -```ts -import { getContract } from "viem"; -import IStoreAbi from "@latticexyz/store/abi/IStore.sol/IStore.abi.json"; - -const storeContract = getContract({ - abi: IStoreAbi, - ... -}); - -await storeContract.write.setRecord(...); -``` diff --git a/.changeset/violet-insects-press.md b/.changeset/violet-insects-press.md deleted file mode 100644 index 26b2084017..0000000000 --- a/.changeset/violet-insects-press.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/common": patch ---- - -Table libraries now correctly handle uninitialized fixed length arrays. diff --git a/.changeset/warm-colts-sleep.md b/.changeset/warm-colts-sleep.md deleted file mode 100644 index e2c3144d54..0000000000 --- a/.changeset/warm-colts-sleep.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Updated `StoreCore` to check that tables exist before registering store hooks. diff --git a/.changeset/warm-mails-cheat.md b/.changeset/warm-mails-cheat.md deleted file mode 100644 index 79d91ee726..0000000000 --- a/.changeset/warm-mails-cheat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -Renamed the `functionSelector` key in the `FunctionSelectors` table to `worldFunctionSelector`. This clarifies that `FunctionSelectors` is for world function selectors and can be used to generate the world ABI. diff --git a/.changeset/weak-mails-cross.md b/.changeset/weak-mails-cross.md deleted file mode 100644 index 6d42241d47..0000000000 --- a/.changeset/weak-mails-cross.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/recs": patch -"@latticexyz/std-client": patch ---- - -Update RECS components with v2 key/value schemas. This helps with encoding/decoding composite keys and strong types for keys/values. - -This may break if you were previously dependent on `component.id`, `component.metadata.componentId`, or `component.metadata.tableId`: - -- `component.id` is now the on-chain `bytes32` hex representation of the table ID -- `component.metadata.componentName` is the table name (e.g. `Position`) -- `component.metadata.tableName` is the namespaced table name (e.g. `myworld:Position`) -- `component.metadata.keySchema` is an object with key names and their corresponding ABI types -- `component.metadata.valueSchema` is an object with field names and their corresponding ABI types diff --git a/.changeset/weak-otters-turn.md b/.changeset/weak-otters-turn.md deleted file mode 100644 index 8adae50a53..0000000000 --- a/.changeset/weak-otters-turn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store": patch ---- - -Optimised the `Schema.validate` function to decrease gas use. diff --git a/.changeset/weak-rules-lick.md b/.changeset/weak-rules-lick.md deleted file mode 100644 index 337be70298..0000000000 --- a/.changeset/weak-rules-lick.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/protocol-parser": patch -"@latticexyz/store": major -"@latticexyz/world-modules": patch -"@latticexyz/world": major -"create-mud": patch ---- - -Renamed `PackedCounter` to `EncodedLengths` for consistency. diff --git a/.changeset/wet-crabs-punch.md b/.changeset/wet-crabs-punch.md deleted file mode 100644 index eda8919841..0000000000 --- a/.changeset/wet-crabs-punch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/common": minor ---- - -Updated `chunk` types to use readonly arrays diff --git a/.changeset/wicked-cheetahs-cough.md b/.changeset/wicked-cheetahs-cough.md deleted file mode 100644 index acaced9bfb..0000000000 --- a/.changeset/wicked-cheetahs-cough.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/protocol-parser": patch ---- - -Allow arbitrary key order when encoding values diff --git a/.changeset/wicked-donuts-cheat.md b/.changeset/wicked-donuts-cheat.md deleted file mode 100644 index cb82c2abbc..0000000000 --- a/.changeset/wicked-donuts-cheat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-indexer": minor ---- - -Added `getLogs` query support to sqlite indexer diff --git a/.changeset/wicked-pens-promise.md b/.changeset/wicked-pens-promise.md deleted file mode 100644 index 41297a0bc2..0000000000 --- a/.changeset/wicked-pens-promise.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/world": patch ---- - -With [resource types in resource IDs](https://github.com/latticexyz/mud/pull/1544), the World config no longer requires table and system names to be unique. diff --git a/.changeset/wicked-squids-do.md b/.changeset/wicked-squids-do.md deleted file mode 100644 index 039fb58cb8..0000000000 --- a/.changeset/wicked-squids-do.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -"@latticexyz/block-logs-stream": patch -"@latticexyz/cli": patch -"@latticexyz/common": minor -"@latticexyz/dev-tools": patch -"@latticexyz/store-sync": patch -"@latticexyz/store": major -"@latticexyz/world": major -"create-mud": patch ---- - -- The external `setRecord` and `deleteRecord` methods of `IStore` no longer accept a `FieldLayout` as input, but load it from storage instead. - This is to prevent invalid `FieldLayout` values being passed, which could cause the onchain state to diverge from the indexer state. - However, the internal `StoreCore` library still exposes a `setRecord` and `deleteRecord` method that allows a `FieldLayout` to be passed. - This is because `StoreCore` can only be used internally, so the `FieldLayout` value can be trusted and we can save the gas for accessing storage. - - ```diff - interface IStore { - function setRecord( - ResourceId tableId, - bytes32[] calldata keyTuple, - bytes calldata staticData, - PackedCounter encodedLengths, - bytes calldata dynamicData, - - FieldLayout fieldLayout - ) external; - - function deleteRecord( - ResourceId tableId, - bytes32[] memory keyTuple, - - FieldLayout fieldLayout - ) external; - } - ``` - -- The `spliceStaticData` method and `Store_SpliceStaticData` event of `IStore` and `StoreCore` no longer include `deleteCount` in their signature. - This is because when splicing static data, the data after `start` is always overwritten with `data` instead of being shifted, so `deleteCount` is always the length of the data to be written. - - ```diff - - event Store_SpliceStaticData( - ResourceId indexed tableId, - bytes32[] keyTuple, - uint48 start, - - uint40 deleteCount, - bytes data - ); - - interface IStore { - function spliceStaticData( - ResourceId tableId, - bytes32[] calldata keyTuple, - uint48 start, - - uint40 deleteCount, - bytes calldata data - ) external; - } - ``` - -- The `updateInField` method has been removed from `IStore`, as it's almost identical to the more general `spliceDynamicData`. - If you're manually calling `updateInField`, here is how to upgrade to `spliceDynamicData`: - - ```diff - - store.updateInField(tableId, keyTuple, fieldIndex, startByteIndex, dataToSet, fieldLayout); - + uint8 dynamicFieldIndex = fieldIndex - fieldLayout.numStaticFields(); - + store.spliceDynamicData(tableId, keyTuple, dynamicFieldIndex, uint40(startByteIndex), uint40(dataToSet.length), dataToSet); - ``` - -- All other methods that are only valid for dynamic fields (`pushToField`, `popFromField`, `getFieldSlice`) - have been renamed to make this more explicit (`pushToDynamicField`, `popFromDynamicField`, `getDynamicFieldSlice`). - - Their `fieldIndex` parameter has been replaced by a `dynamicFieldIndex` parameter, which is the index relative to the first dynamic field (i.e. `dynamicFieldIndex` = `fieldIndex` - `numStaticFields`). - The `FieldLayout` parameter has been removed, as it was only used to calculate the `dynamicFieldIndex` in the method. - - ```diff - interface IStore { - - function pushToField( - + function pushToDynamicField( - ResourceId tableId, - bytes32[] calldata keyTuple, - - uint8 fieldIndex, - + uint8 dynamicFieldIndex, - bytes calldata dataToPush, - - FieldLayout fieldLayout - ) external; - - - function popFromField( - + function popFromDynamicField( - ResourceId tableId, - bytes32[] calldata keyTuple, - - uint8 fieldIndex, - + uint8 dynamicFieldIndex, - uint256 byteLengthToPop, - - FieldLayout fieldLayout - ) external; - - - function getFieldSlice( - + function getDynamicFieldSlice( - ResourceId tableId, - bytes32[] memory keyTuple, - - uint8 fieldIndex, - + uint8 dynamicFieldIndex, - - FieldLayout fieldLayout, - uint256 start, - uint256 end - ) external view returns (bytes memory data); - } - ``` - -- `IStore` has a new `getDynamicFieldLength` length method, which returns the byte length of the given dynamic field and doesn't require the `FieldLayout`. - - ```diff - IStore { - + function getDynamicFieldLength( - + ResourceId tableId, - + bytes32[] memory keyTuple, - + uint8 dynamicFieldIndex - + ) external view returns (uint256); - } - - ``` - -- `IStore` now has additional overloads for `getRecord`, `getField`, `getFieldLength` and `setField` that don't require a `FieldLength` to be passed, but instead load it from storage. - -- `IStore` now exposes `setStaticField` and `setDynamicField` to save gas by avoiding the dynamic inference of whether the field is static or dynamic. - -- The `getDynamicFieldSlice` method no longer accepts reading outside the bounds of the dynamic field. - This is to avoid returning invalid data, as the data of a dynamic field is not deleted when the record is deleted, but only its length is set to zero. diff --git a/.changeset/wicked-tigers-return.md b/.changeset/wicked-tigers-return.md deleted file mode 100644 index 0a191f7399..0000000000 --- a/.changeset/wicked-tigers-return.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/protocol-parser": minor ---- - -Adds `decodeKey`, `decodeValue`, `encodeKey`, and `encodeValue` helpers to decode/encode from key/value schemas. Deprecates previous methods that use a schema object with static/dynamic field arrays, originally attempting to model our on-chain behavior but ended up not very ergonomic when working with table configs. diff --git a/.changeset/wild-gorillas-care.md b/.changeset/wild-gorillas-care.md deleted file mode 100644 index d14f2d542e..0000000000 --- a/.changeset/wild-gorillas-care.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -"@latticexyz/std-client": major -"@latticexyz/common": minor -"create-mud": patch ---- - -Deprecate `@latticexyz/std-client` and remove v1 network dependencies. - -- `getBurnerWallet` is replaced by `getBurnerPrivateKey` from `@latticexyz/common`. It now returns a `Hex` string instead of an `rxjs` `BehaviorSubject`. - - ``` - - import { getBurnerWallet } from "@latticexyz/std-client"; - + import { getBurnerPrivateKey } from "@latticexyz/common"; - - - const privateKey = getBurnerWallet().value; - - const privateKey = getBurnerPrivateKey(); - ``` - -- All functions from `std-client` that depended on v1 network code are removed (most notably `setupMUDNetwork` and `setupMUDV2Network`). Consumers should upgrade to v2 networking code from `@latticexyz/store-sync`. - -- The following functions are removed from `std-client` because they are very use-case specific and depend on deprecated code: `getCurrentTurn`, `getTurnAtTime`, `getGameConfig`, `isUntraversable`, `getPlayerEntity`, `resolveRelationshipChain`, `findEntityWithComponentInRelationshipChain`, `findInRelationshipChain`. Consumers should vendor these functions if they are still needed. - -- Remaining exports from `std-client` are moved to `/deprecated`. The package will be removed in a future release (once there are replacements for the deprecated exports). - - ```diff - - import { ... } from "@latticexyz/std-client"; - + import { ... } from "@latticexyz/std-client/deprecated"; - ``` diff --git a/.changeset/wild-moose-smile.md b/.changeset/wild-moose-smile.md deleted file mode 100644 index a9128187f2..0000000000 --- a/.changeset/wild-moose-smile.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@latticexyz/store-sync": major ---- - -`syncToPostgres` from `@latticexyz/store-sync/postgres` now uses a single table to store all records in their bytes form (`staticData`, `encodedLengths`, and `dynamicData`), more closely mirroring onchain state and enabling more scalability and stability for automatic indexing of many worlds. - -The previous behavior, where schemaful SQL tables are created and populated for each MUD table, has been moved to a separate `@latticexyz/store-sync/postgres-decoded` export bundle. This approach is considered less stable and is intended to be used for analytics purposes rather than hydrating clients. Some previous metadata columns on these tables have been removed in favor of the bytes records table as the source of truth for onchain state. - -This overhaul is considered breaking and we recommend starting a fresh database when syncing with either of these strategies. diff --git a/.changeset/wild-nails-wonder.md b/.changeset/wild-nails-wonder.md deleted file mode 100644 index 3543079a4f..0000000000 --- a/.changeset/wild-nails-wonder.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"@latticexyz/world": minor ---- - -The `World` now has a `callBatch` method which allows multiple system calls to be batched into a single transaction. - -```solidity -import { SystemCallData } from "@latticexyz/world/modules/core/types.sol"; - -interface IBaseWorld { - function callBatch(SystemCallData[] calldata systemCalls) external returns (bytes[] memory returnDatas); -} -``` diff --git a/.changeset/wild-squids-bathe.md b/.changeset/wild-squids-bathe.md deleted file mode 100644 index ff062dd16b..0000000000 --- a/.changeset/wild-squids-bathe.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/cli": patch -"@latticexyz/dev-tools": patch -"@latticexyz/store-sync": patch ---- - -Moved to new resource ID utils. diff --git a/.changeset/wild-years-search.md b/.changeset/wild-years-search.md deleted file mode 100644 index 2ca0461a39..0000000000 --- a/.changeset/wild-years-search.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -"@latticexyz/store-indexer": minor -"@latticexyz/store-sync": minor ---- - -- Improved query performance by 10x by moving from drizzle ORM to handcrafted SQL. -- Moved away from `trpc` for more granular control over the transport layer. - Added an `/api/logs` endpoint using the new query and gzip compression for 40x less data transferred over the wire. - Deprecated the `/trpc/getLogs` and `/trpc/findAll` endpoints. -- Added a `createIndexerClient` client for the new `/api` indexer API exported from `@latticexyz/store-sync/indexer-client`. - The `createIndexerClient` export from `@latticexyz/store-sync/trpc-indexer` is deprecated. - -```diff -- import { createIndexerClient } from "@latticexyz/store-sync/trpc-indexer"; -+ import { createIndexerClient } from "@latticexyz/store-sync/indexer-client"; - -- const indexer = createIndexerClient({ url: "https://indexer.holesky.redstone.xyz/trpc" }); -+ const indexer = createIndexerClient({ url: "https://indexer.holesky.redstone.xyz" }); - -- const snapshot = indexer.getLogs.query(options); -+ const snapshot = indexer.getLogs(options); -``` diff --git a/.changeset/wise-bees-repair.md b/.changeset/wise-bees-repair.md deleted file mode 100644 index c8ec0537d8..0000000000 --- a/.changeset/wise-bees-repair.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -"@latticexyz/store-indexer": major -"@latticexyz/store-sync": major ---- - -PostgreSQL sync/indexer now uses `{storeAddress}` for its database schema names and `{namespace}__{tableName}` for its database table names (or just `{tableName}` for root namespace), to be more consistent with the rest of the MUD codebase. - -For namespaced tables: - -```diff -- SELECT * FROM 0xfff__some_ns.some_table -+ SELECT * FROM 0xfff.some_ns__some_table -``` - -For root tables: - -```diff -- SELECT * FROM 0xfff__.some_table -+ SELECT * FROM 0xfff.some_table -``` - -SQLite sync/indexer now uses snake case for its table names and column names for easier writing of queries and to better match PostgreSQL sync/indexer naming. - -```diff -- SELECT * FROM 0xfFf__someNS__someTable -+ SELECT * FROM 0xfff__some_ns__some_table -``` diff --git a/.changeset/wise-cheetahs-add.md b/.changeset/wise-cheetahs-add.md deleted file mode 100644 index 1a93a30180..0000000000 --- a/.changeset/wise-cheetahs-add.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": minor ---- - -Transactions sent via deploy will now be retried a few times before giving up. This hopefully helps with large deploys on some chains. diff --git a/.changeset/witty-jokes-serve.md b/.changeset/witty-jokes-serve.md deleted file mode 100644 index e37e695d91..0000000000 --- a/.changeset/witty-jokes-serve.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@latticexyz/common": patch -"@latticexyz/store": patch -"@latticexyz/world": patch ---- - -- Refactor tightcoder to use typescript functions instead of ejs -- Optimize `TightCoder` library -- Add `isLeftAligned` and `getLeftPaddingBits` common codegen helpers diff --git a/.changeset/witty-tigers-rest.md b/.changeset/witty-tigers-rest.md deleted file mode 100644 index c548a802b9..0000000000 --- a/.changeset/witty-tigers-rest.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/cli": patch ---- - -The `mud test` cli now exits with code 1 on test failure. It used to exit with code 0, which meant that CIs didn't notice test failures. diff --git a/.changeset/yellow-bags-learn.md b/.changeset/yellow-bags-learn.md deleted file mode 100644 index 585812d694..0000000000 --- a/.changeset/yellow-bags-learn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-indexer": minor ---- - -The `/api/logs` indexer endpoint is now returning a `404` snapshot not found error when no snapshot is found for the provided filter instead of an empty `200` response. diff --git a/.changeset/yellow-bulldogs-boil.md b/.changeset/yellow-bulldogs-boil.md deleted file mode 100644 index cd53942b7c..0000000000 --- a/.changeset/yellow-bulldogs-boil.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"@latticexyz/cli": major -"@latticexyz/dev-tools": major -"@latticexyz/store-sync": major -"@latticexyz/store": major -"@latticexyz/world-modules": major -"@latticexyz/world": major -"create-mud": major ---- - -Migrated to new config format. diff --git a/.changeset/young-crabs-rest.md b/.changeset/young-crabs-rest.md deleted file mode 100644 index d6cc11ce9b..0000000000 --- a/.changeset/young-crabs-rest.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@latticexyz/store-indexer": minor ---- - -Added `STORE_ADDRESS` environment variable to index only a specific MUD Store. diff --git a/.changeset/young-pandas-explode.md b/.changeset/young-pandas-explode.md deleted file mode 100644 index 4ad3b4e674..0000000000 --- a/.changeset/young-pandas-explode.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@latticexyz/store-sync": major ---- - -Postgres storage adapter now uses snake case for decoded table names and column names. This allows for better SQL ergonomics when querying these tables. - -To avoid naming conflicts for now, schemas are still case-sensitive and need to be queried with double quotes. We may change this in the future with [namespace validation](https://github.com/latticexyz/mud/issues/1991). diff --git a/.changeset/young-poets-beam.md b/.changeset/young-poets-beam.md deleted file mode 100644 index 0430659a3c..0000000000 --- a/.changeset/young-poets-beam.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@latticexyz/store": minor ---- - -Improved error messages for invalid `FieldLayout`s - -```diff --error FieldLayoutLib_InvalidLength(uint256 length); -+error FieldLayoutLib_TooManyFields(uint256 numFields, uint256 maxFields); -+error FieldLayoutLib_TooManyDynamicFields(uint256 numFields, uint256 maxFields); -+error FieldLayoutLib_Empty(); -``` diff --git a/packages/abi-ts/CHANGELOG.md b/packages/abi-ts/CHANGELOG.md index 6812680c78..0289559240 100644 --- a/packages/abi-ts/CHANGELOG.md +++ b/packages/abi-ts/CHANGELOG.md @@ -1,5 +1,31 @@ # @latticexyz/abi-ts +## 2.0.0 + +### Minor Changes + +- ca3291751: Moves log output behind a debug flag. You can enable logging with `DEBUG=abi-ts` environment variable. +- 8025c3505: Added a new `@latticexyz/abi-ts` package to generate TS type declaration files (`.d.ts`) for each ABI JSON file. + + This allows you to import your JSON ABI and use it directly with libraries like [viem](https://npmjs.com/package/viem) and [abitype](https://npmjs.com/package/abitype). + + ``` + pnpm add @latticexyz/abi-ts + pnpm abi-ts + ``` + + By default, `abi-ts` looks for files with the glob `**/*.abi.json`, but you can customize this glob with the `--input` argument, e.g. + + ```console + pnpm abi-ts --input 'abi/IWorld.sol/IWorld.abi.json' + ``` + +### Patch Changes + +- 2459e15fc: Let `glob` handle resolving the glob against the current working directory. +- 590542030: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages. +- 5d737cf2e: Updated the `debug` util to pipe to `stdout` and added an additional util to explicitly pipe to `stderr` when needed. + ## 2.0.0-next.18 ## 2.0.0-next.17 diff --git a/packages/abi-ts/package.json b/packages/abi-ts/package.json index fce629425f..f273aefd8e 100644 --- a/packages/abi-ts/package.json +++ b/packages/abi-ts/package.json @@ -1,6 +1,6 @@ { "name": "@latticexyz/abi-ts", - "version": "2.0.0-next.18", + "version": "2.0.0", "description": "Create TypeScript type declaration files (`.d.ts`) for your ABI JSON files.", "repository": { "type": "git", diff --git a/packages/block-logs-stream/CHANGELOG.md b/packages/block-logs-stream/CHANGELOG.md index f5d86e0ff3..fd266c4b83 100644 --- a/packages/block-logs-stream/CHANGELOG.md +++ b/packages/block-logs-stream/CHANGELOG.md @@ -1,5 +1,377 @@ # @latticexyz/block-logs-stream +## 2.0.0 + +### Major Changes + +- b8a6158d6: - removes our own `getLogs` function now that viem's `getLogs` supports using multiple `events` per RPC call. + - removes `isNonPendingBlock` and `isNonPendingLog` helpers now that viem narrows `Block` and `Log` types based on inputs + - simplifies `groupLogsByBlockNumber` types and tests + +### Minor Changes + +- eeb15cc06: - Replace `blockEventsToStorage` with `blockLogsToStorage` that exposes a `storeOperations` callback to perform database writes from store operations. This helps encapsulates database adapters into a single wrapper/instance of `blockLogsToStorage` and allows for wrapping a block of store operations in a database transaction. + - Add `toBlock` option to `groupLogsByBlockNumber` and remove `blockHash` from results. This helps track the last block number for a given set of logs when used in the context of RxJS streams. +- 72b806979: Add block logs stream package + + ```ts + import { filter, map, mergeMap } from "rxjs"; + import { createPublicClient, parseAbi } from "viem"; + import { + createBlockStream, + isNonPendingBlock, + groupLogsByBlockNumber, + blockRangeToLogs, + } from "@latticexyz/block-logs-stream"; + + const publicClient = createPublicClient({ + // your viem public client config here + }); + + const latestBlock$ = await createBlockStream({ + publicClient, + blockTag: "latest", + }); + + const latestBlockNumber$ = latestBlock$.pipe( + filter(isNonPendingBlock), + map((block) => block.number), + ); + + latestBlockNumber$ + .pipe( + map((latestBlockNumber) => ({ + startBlock: 0n, + endBlock: latestBlockNumber, + })), + blockRangeToLogs({ + publicClient, + address, + events: parseAbi([ + "event StoreDeleteRecord(bytes32 table, bytes32[] key)", + "event StoreSetField(bytes32 table, bytes32[] key, uint8 schemaIndex, bytes data)", + "event StoreSetRecord(bytes32 table, bytes32[] key, bytes data)", + "event StoreEphemeralRecord(bytes32 table, bytes32[] key, bytes data)", + ]), + }), + mergeMap(({ logs }) => from(groupLogsByBlockNumber(logs))), + ) + .subscribe((block) => { + console.log("got events for block", block); + }); + ``` + +- d7b1c588a: Upgraded all packages and templates to viem v2.7.12 and abitype v1.0.0. + + Some viem APIs have changed and we've updated `getContract` to reflect those changes and keep it aligned with viem. It's one small code change: + + ```diff + const worldContract = getContract({ + address: worldAddress, + abi: IWorldAbi, + - publicClient, + - walletClient, + + client: { public: publicClient, wallet: walletClient }, + }); + ``` + +### Patch Changes + +- 904fd7d4e: Add store sync package +- f99e88987: Bump viem to 1.14.0 and abitype to 0.9.8 +- 6573e38e9: Renamed all occurrences of `table` where it is used as "table ID" to `tableId`. + This is only a breaking change for consumers who manually decode `Store` events, but not for consumers who use the MUD libraries. + + ```diff + event StoreSetRecord( + - bytes32 table, + + bytes32 tableId, + bytes32[] key, + bytes data + ); + + event StoreSetField( + - bytes32 table, + + bytes32 tableId, + bytes32[] key, + uint8 fieldIndex, + bytes data + ); + + event StoreDeleteRecord( + - bytes32 table, + + bytes32 tableId, + bytes32[] key + ); + + event StoreEphemeralRecord( + - bytes32 table, + + bytes32 tableId, + bytes32[] key, + bytes data + ); + ``` + +- 6e66c5b74: Renamed all occurrences of `key` where it is used as "key tuple" to `keyTuple`. + This is only a breaking change for consumers who manually decode `Store` events, but not for consumers who use the MUD libraries. + + ```diff + event StoreSetRecord( + bytes32 tableId, + - bytes32[] key, + + bytes32[] keyTuple, + bytes data + ); + + event StoreSetField( + bytes32 tableId, + - bytes32[] key, + + bytes32[] keyTuple, + uint8 fieldIndex, + bytes data + ); + + event StoreDeleteRecord( + bytes32 tableId, + - bytes32[] key, + + bytes32[] keyTuple, + ); + + event StoreEphemeralRecord( + bytes32 tableId, + - bytes32[] key, + + bytes32[] keyTuple, + bytes data + ); + ``` + +- 590542030: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages. +- b8a6158d6: bump viem to 1.6.0 +- 5d737cf2e: Updated the `debug` util to pipe to `stdout` and added an additional util to explicitly pipe to `stderr` when needed. +- bfcb293d1: What used to be known as `ephemeral` table is now called `offchain` table. + The previous `ephemeral` tables only supported an `emitEphemeral` method, which emitted a `StoreSetEphemeralRecord` event. + + Now `offchain` tables support all regular table methods, except partial operations on dynamic fields (`push`, `pop`, `update`). + Unlike regular tables they don't store data on-chain but emit the same events as regular tables (`StoreSetRecord`, `StoreSpliceStaticData`, `StoreDeleteRecord`), so their data can be indexed by offchain indexers/clients. + + ```diff + - EphemeralTable.emitEphemeral(value); + + OffchainTable.set(value); + ``` + +- 535229984: - bump to viem 1.3.0 and abitype 0.9.3 + - move `@wagmi/chains` imports to `viem/chains` + - refine a few types +- af639a264: `Store` events have been renamed for consistency and readability. + If you're parsing `Store` events manually, you need to update your ABI. + If you're using the MUD sync stack, the new events are already integrated and no further changes are necessary. + + ```diff + - event StoreSetRecord( + + event Store_SetRecord( + ResourceId indexed tableId, + bytes32[] keyTuple, + bytes staticData, + bytes32 encodedLengths, + bytes dynamicData + ); + - event StoreSpliceStaticData( + + event Store_SpliceStaticData( + ResourceId indexed tableId, + bytes32[] keyTuple, + uint48 start, + uint40 deleteCount, + bytes data + ); + - event StoreSpliceDynamicData( + + event Store_SpliceDynamicData( + ResourceId indexed tableId, + bytes32[] keyTuple, + uint48 start, + uint40 deleteCount, + bytes data, + bytes32 encodedLengths + ); + - event StoreDeleteRecord( + + event Store_DeleteRecord( + ResourceId indexed tableId, + bytes32[] keyTuple + ); + ``` + +- cea754dde: - The external `setRecord` and `deleteRecord` methods of `IStore` no longer accept a `FieldLayout` as input, but load it from storage instead. + This is to prevent invalid `FieldLayout` values being passed, which could cause the onchain state to diverge from the indexer state. + However, the internal `StoreCore` library still exposes a `setRecord` and `deleteRecord` method that allows a `FieldLayout` to be passed. + This is because `StoreCore` can only be used internally, so the `FieldLayout` value can be trusted and we can save the gas for accessing storage. + + ```diff + interface IStore { + function setRecord( + ResourceId tableId, + bytes32[] calldata keyTuple, + bytes calldata staticData, + PackedCounter encodedLengths, + bytes calldata dynamicData, + - FieldLayout fieldLayout + ) external; + + function deleteRecord( + ResourceId tableId, + bytes32[] memory keyTuple, + - FieldLayout fieldLayout + ) external; + } + ``` + + - The `spliceStaticData` method and `Store_SpliceStaticData` event of `IStore` and `StoreCore` no longer include `deleteCount` in their signature. + This is because when splicing static data, the data after `start` is always overwritten with `data` instead of being shifted, so `deleteCount` is always the length of the data to be written. + + ```diff + + event Store_SpliceStaticData( + ResourceId indexed tableId, + bytes32[] keyTuple, + uint48 start, + - uint40 deleteCount, + bytes data + ); + + interface IStore { + function spliceStaticData( + ResourceId tableId, + bytes32[] calldata keyTuple, + uint48 start, + - uint40 deleteCount, + bytes calldata data + ) external; + } + ``` + + - The `updateInField` method has been removed from `IStore`, as it's almost identical to the more general `spliceDynamicData`. + If you're manually calling `updateInField`, here is how to upgrade to `spliceDynamicData`: + + ```diff + - store.updateInField(tableId, keyTuple, fieldIndex, startByteIndex, dataToSet, fieldLayout); + + uint8 dynamicFieldIndex = fieldIndex - fieldLayout.numStaticFields(); + + store.spliceDynamicData(tableId, keyTuple, dynamicFieldIndex, uint40(startByteIndex), uint40(dataToSet.length), dataToSet); + ``` + + - All other methods that are only valid for dynamic fields (`pushToField`, `popFromField`, `getFieldSlice`) + have been renamed to make this more explicit (`pushToDynamicField`, `popFromDynamicField`, `getDynamicFieldSlice`). + + Their `fieldIndex` parameter has been replaced by a `dynamicFieldIndex` parameter, which is the index relative to the first dynamic field (i.e. `dynamicFieldIndex` = `fieldIndex` - `numStaticFields`). + The `FieldLayout` parameter has been removed, as it was only used to calculate the `dynamicFieldIndex` in the method. + + ```diff + interface IStore { + - function pushToField( + + function pushToDynamicField( + ResourceId tableId, + bytes32[] calldata keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + bytes calldata dataToPush, + - FieldLayout fieldLayout + ) external; + + - function popFromField( + + function popFromDynamicField( + ResourceId tableId, + bytes32[] calldata keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + uint256 byteLengthToPop, + - FieldLayout fieldLayout + ) external; + + - function getFieldSlice( + + function getDynamicFieldSlice( + ResourceId tableId, + bytes32[] memory keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + - FieldLayout fieldLayout, + uint256 start, + uint256 end + ) external view returns (bytes memory data); + } + ``` + + - `IStore` has a new `getDynamicFieldLength` length method, which returns the byte length of the given dynamic field and doesn't require the `FieldLayout`. + + ```diff + IStore { + + function getDynamicFieldLength( + + ResourceId tableId, + + bytes32[] memory keyTuple, + + uint8 dynamicFieldIndex + + ) external view returns (uint256); + } + + ``` + + - `IStore` now has additional overloads for `getRecord`, `getField`, `getFieldLength` and `setField` that don't require a `FieldLength` to be passed, but instead load it from storage. + - `IStore` now exposes `setStaticField` and `setDynamicField` to save gas by avoiding the dynamic inference of whether the field is static or dynamic. + - The `getDynamicFieldSlice` method no longer accepts reading outside the bounds of the dynamic field. + This is to avoid returning invalid data, as the data of a dynamic field is not deleted when the record is deleted, but only its length is set to zero. + +- Updated dependencies [a35c05ea9] +- Updated dependencies [16b13ea8f] +- Updated dependencies [82693072] +- Updated dependencies [aabd30767] +- Updated dependencies [65c9546c4] +- Updated dependencies [d5c0682fb] +- Updated dependencies [01e46d99] +- Updated dependencies [331dbfdcb] +- Updated dependencies [44236041f] +- Updated dependencies [066056154] +- Updated dependencies [3fb9ce283] +- Updated dependencies [bb6ada740] +- Updated dependencies [35c9f33df] +- Updated dependencies [0b8ce3f2c] +- Updated dependencies [933b54b5f] +- Updated dependencies [307abab3] +- Updated dependencies [aacffcb59] +- Updated dependencies [f99e88987] +- Updated dependencies [939916bcd] +- Updated dependencies [e34d1170] +- Updated dependencies [b8a6158d6] +- Updated dependencies [db314a74] +- Updated dependencies [59267655] +- Updated dependencies [8d51a0348] +- Updated dependencies [c162ad5a5] +- Updated dependencies [f62c767e7] +- Updated dependencies [590542030] +- Updated dependencies [1b5eb0d07] +- Updated dependencies [44a5432ac] +- Updated dependencies [b8a6158d6] +- Updated dependencies [5d737cf2e] +- Updated dependencies [d075f82f3] +- Updated dependencies [331dbfdcb] +- Updated dependencies [92de59982] +- Updated dependencies [bfcb293d1] +- Updated dependencies [3e057061d] +- Updated dependencies [535229984] +- Updated dependencies [5e723b90e] +- Updated dependencies [0c4f9fea9] +- Updated dependencies [60cfd089f] +- Updated dependencies [24a6cd536] +- Updated dependencies [708b49c50] +- Updated dependencies [d2f8e9400] +- Updated dependencies [25086be5f] +- Updated dependencies [b1d41727d] +- Updated dependencies [4c1dcd81e] +- Updated dependencies [6071163f7] +- Updated dependencies [6c6733256] +- Updated dependencies [cd5abcc3b] +- Updated dependencies [d7b1c588a] +- Updated dependencies [c4f49240d] +- Updated dependencies [5df1f31bc] +- Updated dependencies [cea754dde] +- Updated dependencies [331f0d636] +- Updated dependencies [cc2c8da00] + - @latticexyz/common@2.0.0 + ## 2.0.0-next.18 ### Minor Changes diff --git a/packages/block-logs-stream/package.json b/packages/block-logs-stream/package.json index a967d55c8b..387311ccdc 100644 --- a/packages/block-logs-stream/package.json +++ b/packages/block-logs-stream/package.json @@ -1,6 +1,6 @@ { "name": "@latticexyz/block-logs-stream", - "version": "2.0.0-next.18", + "version": "2.0.0", "description": "Create a stream of EVM block logs for events", "repository": { "type": "git", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index c7bcab286c..04f28083f6 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,1098 @@ # Change Log +## 2.0.0 + +### Major Changes + +- 07dd6f32c: Renamed all occurrences of `schema` where it is used as "value schema" to `valueSchema` to clearly distinguish it from "key schema". + The only breaking change for users is the change from `schema` to `valueSchema` in `mud.config.ts`. + + ```diff + // mud.config.ts + export default mudConfig({ + tables: { + CounterTable: { + keySchema: {}, + - schema: { + + valueSchema: { + value: "uint32", + }, + }, + } + } + ``` + +- 44236041f: Moved table ID and field layout constants in code-generated table libraries from the file level into the library, for clearer access and cleaner imports. + + ```diff + -import { SomeTable, SomeTableTableId } from "./codegen/tables/SomeTable.sol"; + +import { SomeTable } from "./codegen/tables/SomeTable.sol"; + + -console.log(SomeTableTableId); + +console.log(SomeTable._tableId); + + -console.log(SomeTable.getFieldLayout()); + +console.log(SomeTable._fieldLayout); + ``` + +- 952cd5344: All `Store` methods now require the table's value schema to be passed in as an argument instead of loading it from storage. + This decreases gas cost and removes circular dependencies of the Schema table (where it was not possible to write to the Schema table before the Schema table was registered). + + ```diff + function setRecord( + bytes32 table, + bytes32[] calldata key, + bytes calldata data, + + Schema valueSchema + ) external; + ``` + + The same diff applies to `getRecord`, `getField`, `setField`, `pushToField`, `popFromField`, `updateInField`, and `deleteRecord`. + + This change only requires changes in downstream projects if the `Store` methods were accessed directly. In most cases it is fully abstracted in the generated table libraries, + so downstream projects only need to regenerate their table libraries after updating MUD. + +- de151fec0: - Add `FieldLayout`, which is a `bytes32` user-type similar to `Schema`. + + Both `FieldLayout` and `Schema` have the same kind of data in the first 4 bytes. + + - 2 bytes for total length of all static fields + - 1 byte for number of static size fields + - 1 byte for number of dynamic size fields + + But whereas `Schema` has `SchemaType` enum in each of the other 28 bytes, `FieldLayout` has static byte lengths in each of the other 28 bytes. + + - Replace `Schema valueSchema` with `FieldLayout fieldLayout` in Store and World contracts. + + `FieldLayout` is more gas-efficient because it already has lengths, and `Schema` has types which need to be converted to lengths. + + - Add `getFieldLayout` to `IStore` interface. + + There is no `FieldLayout` for keys, only for values, because key byte lengths aren't usually relevant on-chain. You can still use `getKeySchema` if you need key types. + + - Add `fieldLayoutToHex` utility to `protocol-parser` package. + - Add `constants.sol` for constants shared between `FieldLayout`, `Schema` and `PackedCounter`. + +- c32a9269a: - All `World` function selectors that previously had `bytes16 namespace, bytes16 name` arguments now use `bytes32 resourceSelector` instead. + This includes `setRecord`, `setField`, `pushToField`, `popFromField`, `updateInField`, `deleteRecord`, `call`, `grantAccess`, `revokeAccess`, `registerTable`, + `registerStoreHook`, `registerSystemHook`, `registerFunctionSelector`, `registerSystem` and `registerRootFunctionSelector`. + This change aligns the `World` function selectors with the `Store` function selectors, reduces clutter, reduces gas cost and reduces the `World`'s contract size. + + - The `World`'s `registerHook` function is removed. Use `registerStoreHook` or `registerSystemHook` instead. + - The `deploy` script is updated to integrate the World interface changes + +- e5d208e40: The `registerRootFunctionSelector` function's signature was changed to accept a `string functionSignature` parameter instead of a `bytes4 functionSelector` parameter. + This change enables the `World` to store the function signatures of all registered functions in a `FunctionSignatures` offchain table, which will allow for the automatic generation of interfaces for a given `World` address in the future. + + ```diff + IBaseWorld { + function registerRootFunctionSelector( + ResourceId systemId, + - bytes4 worldFunctionSelector, + + string memory worldFunctionSignature, + bytes4 systemFunctionSelector + ) external returns (bytes4 worldFunctionSelector); + } + ``` + +- 3d0b3edb4: Removes `.mudbackup` file handling and `--backup`, `--restore`, and `--force` options from `mud set-version` command. + + To revert to a previous MUD version, use `git diff` to find the version that you changed from and want to revert to and run `pnpm mud set-version ` again. + +- afaf2f5ff: - `Store`'s internal schema table is now a normal table instead of using special code paths. It is renamed to Tables, and the table ID changed from `mudstore:schema` to `mudstore:Tables` + + - `Store`'s `registerSchema` and `setMetadata` are combined into a single `registerTable` method. This means metadata (key names, field names) is immutable and indexers can create tables with this metadata when a new table is registered on-chain. + + ```diff + - function registerSchema(bytes32 table, Schema schema, Schema keySchema) external; + - + - function setMetadata(bytes32 table, string calldata tableName, string[] calldata fieldNames) external; + + + function registerTable( + + bytes32 table, + + Schema keySchema, + + Schema valueSchema, + + string[] calldata keyNames, + + string[] calldata fieldNames + + ) external; + ``` + + - `World`'s `registerTable` method is updated to match the `Store` interface, `setMetadata` is removed + - The `getSchema` method is renamed to `getValueSchema` on all interfaces + ```diff + - function getSchema(bytes32 table) external view returns (Schema schema); + + function getValueSchema(bytes32 table) external view returns (Schema valueSchema); + ``` + - The `store-sync` and `cli` packages are updated to integrate the breaking protocol changes. Downstream projects only need to manually integrate these changes if they access low level `Store` or `World` functions. Otherwise, a fresh deploy with the latest MUD will get you these changes. + +- 29c3f5087: `deploy`, `test`, `dev-contracts` were overhauled using a declarative deployment approach under the hood. Deploys are now idempotent and re-running them will introspect the world and figure out the minimal changes necessary to bring the world into alignment with its config: adding tables, adding/upgrading systems, changing access control, etc. + + The following CLI arguments are now removed from these commands: + + - `--debug` (you can now adjust CLI output with `DEBUG` environment variable, e.g. `DEBUG=mud:*`) + - `--priorityFeeMultiplier` (now calculated automatically) + - `--disableTxWait` (everything is now parallelized with smarter nonce management) + - `--pollInterval` (we now lean on viem defaults and we don't wait/poll until the very end of the deploy) + + Most deployment-in-progress logs are now behind a [debug](https://github.com/debug-js/debug) flag, which you can enable with a `DEBUG=mud:*` environment variable. + +- 48c51b52a: RECS components are now dynamically created and inferred from your MUD config when using `syncToRecs`. + + To migrate existing projects after upgrading to this MUD version: + + 1. Remove `contractComponents.ts` from `client/src/mud` + 2. Remove `components` argument from `syncToRecs` + 3. Update `build:mud` and `dev` scripts in `contracts/package.json` to remove tsgen + + ```diff + - "build:mud": "mud tablegen && mud worldgen && mud tsgen --configPath mud.config.ts --out ../client/src/mud", + + "build:mud": "mud tablegen && mud worldgen", + ``` + + ```diff + - "dev": "pnpm mud dev-contracts --tsgenOutput ../client/src/mud", + + "dev": "pnpm mud dev-contracts", + ``` + +- 57d8965df: Separated core systems deployment from `CoreModule`, and added the systems as arguments to `CoreModule` +- 31ffc9d5d: The `registerFunctionSelector` function now accepts a single `functionSignature` string paramemer instead of separating function name and function arguments into separate parameters. + + ```diff + IBaseWorld { + function registerFunctionSelector( + ResourceId systemId, + - string memory systemFunctionName, + - string memory systemFunctionArguments + + string memory systemFunctionSignature + ) external returns (bytes4 worldFunctionSelector); + } + ``` + + This is a breaking change if you were manually registering function selectors, e.g. in a `PostDeploy.s.sol` script or a module. + To upgrade, simply replace the separate `systemFunctionName` and `systemFunctionArguments` parameters with a single `systemFunctionSignature` parameter. + + ```diff + world.registerFunctionSelector( + systemId, + - systemFunctionName, + - systemFunctionArguments, + + string(abi.encodePacked(systemFunctionName, systemFunctionArguments)) + ); + ``` + +- ac508bf18: Renamed the default filename of generated user types from `Types.sol` to `common.sol` and the default filename of the generated table index file from `Tables.sol` to `index.sol`. + + Both can be overridden via the MUD config: + + ```ts + export default mudConfig({ + /** Filename where common user types will be generated and imported from. */ + userTypesFilename: "common.sol", + /** Filename where codegen index will be generated. */ + codegenIndexFilename: "index.sol", + }); + ``` + + Note: `userTypesFilename` was renamed from `userTypesPath` and `.sol` is not appended automatically anymore but needs to be part of the provided filename. + + To update your existing project, update all imports from `Tables.sol` to `index.sol` and all imports from `Types.sol` to `common.sol`, or override the defaults in your MUD config to the previous values. + + ```diff + - import { Counter } from "../src/codegen/Tables.sol"; + + import { Counter } from "../src/codegen/index.sol"; + - import { ExampleEnum } from "../src/codegen/Types.sol"; + + import { ExampleEnum } from "../src/codegen/common.sol"; + ``` + +- 5e723b90e: - `ResourceSelector` is replaced with `ResourceId`, `ResourceIdLib`, `ResourceIdInstance`, `WorldResourceIdLib` and `WorldResourceIdInstance`. + + Previously a "resource selector" was a `bytes32` value with the first 16 bytes reserved for the resource's namespace, and the last 16 bytes reserved for the resource's name. + Now a "resource ID" is a `bytes32` value with the first 2 bytes reserved for the resource type, the next 14 bytes reserved for the resource's namespace, and the last 16 bytes reserved for the resource's name. + + Previously `ResouceSelector` was a library and the resource selector type was a plain `bytes32`. + Now `ResourceId` is a user type, and the functionality is implemented in the `ResourceIdInstance` (for type) and `WorldResourceIdInstance` (for namespace and name) libraries. + We split the logic into two libraries, because `Store` now also uses `ResourceId` and needs to be aware of resource types, but not of namespaces/names. + + ```diff + - import { ResourceSelector } from "@latticexyz/world/src/ResourceSelector.sol"; + + import { ResourceId, ResourceIdInstance } from "@latticexyz/store/src/ResourceId.sol"; + + import { WorldResourceIdLib, WorldResourceIdInstance } from "@latticexyz/world/src/WorldResourceId.sol"; + + import { RESOURCE_SYSTEM } from "@latticexyz/world/src/worldResourceTypes.sol"; + + - bytes32 systemId = ResourceSelector.from("namespace", "name"); + + ResourceId systemId = WorldResourceIdLib.encode(RESOURCE_SYSTEM, "namespace", "name"); + + - using ResourceSelector for bytes32; + + using WorldResourceIdInstance for ResourceId; + + using ResourceIdInstance for ResourceId; + + systemId.getName(); + systemId.getNamespace(); + + systemId.getType(); + + ``` + + - All `Store` and `World` methods now use the `ResourceId` type for `tableId`, `systemId`, `moduleId` and `namespaceId`. + All mentions of `resourceSelector` were renamed to `resourceId` or the more specific type (e.g. `tableId`, `systemId`) + + ```diff + import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; + + IStore { + function setRecord( + - bytes32 tableId, + + ResourceId tableId, + bytes32[] calldata keyTuple, + bytes calldata staticData, + PackedCounter encodedLengths, + bytes calldata dynamicData, + FieldLayout fieldLayout + ) external; + + // Same for all other methods + } + ``` + + ```diff + import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; + + IBaseWorld { + function callFrom( + address delegator, + - bytes32 resourceSelector, + + ResourceId systemId, + bytes memory callData + ) external payable returns (bytes memory); + + // Same for all other methods + } + ``` + +- 252a1852: Migrated to new config format. + +### Minor Changes + +- 645736df: Added an `--rpcBatch` option to `mud deploy` command to batch RPC calls for rate limited RPCs. +- bdb46fe3a: Deploys now validate contract size before deploying and warns when a contract is over or close to the size limit (24kb). This should help identify the most common cause of "evm revert" errors during system and module contract deploys. +- aabd30767: Bumped Solidity version to 0.8.24. +- 618dd0e89: `WorldFactory` now expects a user-provided `salt` when calling `deployWorld(...)` (instead of the previous globally incrementing counter). This enables deterministic world addresses across different chains. + + When using `mud deploy`, you can provide a `bytes32` hex-encoded salt using the `--salt` option, otherwise it defaults to a random hex value. + +- ccc21e913: Added a `--alwaysRunPostDeploy` flag to deploys (`deploy`, `test`, `dev-contracts` commands) to always run `PostDeploy.s.sol` script after each deploy. By default, `PostDeploy.s.sol` is only run once after a new world is deployed. + + This is helpful if you want to continue a deploy that may not have finished (due to an error or otherwise) or to run deploys with an idempotent `PostDeploy.s.sol` script. + +- 59d78c93b: Added a `mud build` command that generates table libraries, system interfaces, and typed ABIs. +- 66cc35a8c: Create gas-report package, move gas-report cli command and GasReporter contract to it +- 92de59982: Bump Solidity version to 0.8.21 +- 8025c3505: Added a new `@latticexyz/abi-ts` package to generate TS type declaration files (`.d.ts`) for each ABI JSON file. + + This allows you to import your JSON ABI and use it directly with libraries like [viem](https://npmjs.com/package/viem) and [abitype](https://npmjs.com/package/abitype). + + ``` + pnpm add @latticexyz/abi-ts + pnpm abi-ts + ``` + + By default, `abi-ts` looks for files with the glob `**/*.abi.json`, but you can customize this glob with the `--input` argument, e.g. + + ```console + pnpm abi-ts --input 'abi/IWorld.sol/IWorld.abi.json' + ``` + +- e667ee808: CLI `deploy`, `test`, `dev-contracts` no longer run `forge clean` before each deploy. We previously cleaned to ensure no outdated artifacts were checked into git (ABIs, typechain types, etc.). Now that all artifacts are gitignored, we can let forge use its cache again. +- 5554b197: `mud deploy` now supports public/linked libraries. + + This helps with cases where system contracts would exceed the EVM bytecode size limit and logic would need to be split into many smaller systems. + + Instead of the overhead and complexity of system-to-system calls, this logic can now be moved into public libraries that will be deployed alongside your systems and automatically `delegatecall`ed. + +- c36ffd13c: - update the `set-version` cli command to work with the new release process by adding two new options: + + - `--tag`: install the latest version of the given tag. For snapshot releases tags correspond to the branch name, commits to `main` result in an automatic snapshot release, so `--tag main` is equivalent to what used to be `-v canary` + - `--commit`: install a version based on a given commit hash. Since commits from `main` result in an automatic snapshot release it works for all commits on main, and it works for manual snapshot releases from branches other than main + - `set-version` now updates all `package.json` nested below the current working directory (expect `node_modules`), so no need for running it each workspace of a monorepo separately. + + Example: + + ```bash + pnpm mud set-version --tag main && pnpm install + pnpm mud set-version --commit db19ea39 && pnpm install + ``` + +- d7b1c588a: Upgraded all packages and templates to viem v2.7.12 and abitype v1.0.0. + + Some viem APIs have changed and we've updated `getContract` to reflect those changes and keep it aligned with viem. It's one small code change: + + ```diff + const worldContract = getContract({ + address: worldAddress, + abi: IWorldAbi, + - publicClient, + - walletClient, + + client: { public: publicClient, wallet: walletClient }, + }); + ``` + +- e1dc88ebe: Transactions sent via deploy will now be retried a few times before giving up. This hopefully helps with large deploys on some chains. + +### Patch Changes + +- 168a4cb43: Add support for legacy transactions in deploy script by falling back to `gasPrice` if `lastBaseFeePerGas` is not available +- 7ce82b6fc: Store config now defaults `storeArgument: false` for all tables. This means that table libraries, by default, will no longer include the extra functions with the `_store` argument. This default was changed to clear up the confusion around using table libraries in tests, `PostDeploy` scripts, etc. + + If you are sure you need to manually specify a store when interacting with tables, you can still manually toggle it back on with `storeArgument: true` in the table settings of your MUD config. + + If you want to use table libraries in `PostDeploy.s.sol`, you can add the following lines: + + ```diff + import { Script } from "forge-std/Script.sol"; + import { console } from "forge-std/console.sol"; + import { IWorld } from "../src/codegen/world/IWorld.sol"; + + import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; + + contract PostDeploy is Script { + function run(address worldAddress) external { + + StoreSwitch.setStoreAddress(worldAddress); + + + + SomeTable.get(someKey); + ``` + +- a35c05ea9: Table libraries now hardcode the `bytes32` table ID value rather than computing it in Solidity. This saves a bit of gas across all storage operations. +- 3bfee32cf: `dev-contracts` will no longer bail when there was an issue with deploying (e.g. typo in contracts) and instead wait for file changes before retrying. +- c32c8e8f2: Removes `std-contracts` package. These were v1 contracts, now entirely replaced by our v2 tooling. See the [MUD docs](https://mud.dev/) for building with v2 or create a new project from our v2 templates with `pnpm create mud@next your-app-name`. +- 8f49c277d: Attempting to deploy multiple systems where there are overlapping system IDs now throws an error. +- ce7125a1b: Removes `solecs` package. These were v1 contracts, now entirely replaced by our v2 tooling. See the [MUD docs](https://mud.dev/) for building with v2 or create a new project from our v2 templates with `pnpm create mud@next your-app-name`. +- 854de0761: Using `mud set-version --link` will no longer attempt to fetch the latest version from npm. +- aea67c580: Include bytecode for `World` and `Store` in npm packages. +- c07fa0215: Tables and interfaces in the `world` package are now generated to the `codegen` folder. + This is only a breaking change if you imported tables or codegenerated interfaces from `@latticexyz/world` directly. + If you're using the MUD CLI, the changed import paths are already integrated and no further changes are necessary. + + ```diff + - import { IBaseWorld } from "@latticexyz/world/src/interfaces/IBaseWorld.sol"; + + import { IBaseWorld } from "@latticexyz/world/src/codegen/interfaces/IBaseWorld.sol"; + + ``` + +- 87235a21b: Fix table IDs for module install step of deploy +- d5c0682fb: Updated all human-readable resource IDs to use `{namespace}__{name}` for consistency with world function signatures. +- 257a0afc: Bumped `typescript` to `5.4.2`, `eslint` to `8.57.0`, and both `@typescript-eslint/eslint-plugin` and `@typescript-eslint/parser` to `7.1.1`. +- 4e2a170f9: Deploys now continue if they detect a `Module_AlreadyInstalled` revert error. +- 211be2a1e: The `FieldLayout` in table libraries is now generated at compile time instead of dynamically in a table library function. + This significantly reduces gas cost in all table library functions. +- f99e88987: Bump viem to 1.14.0 and abitype to 0.9.8 +- 1feecf495: Added `--worldAddress` argument to `dev-contracts` CLI command so that you can develop against an existing world. +- 433078c54: Reverse PackedCounter encoding, to optimize gas for bitshifts. + Ints are right-aligned, shifting using an index is straightforward if they are indexed right-to-left. + + - Previous encoding: (7 bytes | accumulator),(5 bytes | counter 1),...,(5 bytes | counter 5) + - New encoding: (5 bytes | counter 5),...,(5 bytes | counter 1),(7 bytes | accumulator) + +- 61c6ab705: Changed deploy order so that system/module contracts are fully deployed before registering/installing them on the world. +- e259ef79f: Generated `contractComponents` now properly import `World` as type +- 78a837167: Fixed registration of world signatures/selectors for namespaced systems. We changed these signatures in [#2160](https://github.com/latticexyz/mud/pull/2160), but missed updating part of the deploy step. +- 063daf80e: Previously `registerSystem` and `registerTable` had a side effect of registering namespaces if the system or table's namespace didn't exist yet. + This caused a possible frontrunning issue, where an attacker could detect a `registerSystem`/`registerTable` transaction in the mempool, + insert a `registerNamespace` transaction before it, grant themselves access to the namespace, transfer ownership of the namespace to the victim, + so that the `registerSystem`/`registerTable` transactions still went through successfully. + To mitigate this issue, the side effect of registering a namespace in `registerSystem` and `registerTable` has been removed. + Calls to these functions now expect the respective namespace to exist and the caller to own the namespace, otherwise they revert. + + Changes in consuming projects are only necessary if tables or systems are registered manually. + If only the MUD deployer is used to register tables and systems, no changes are necessary, as the MUD deployer has been updated accordingly. + + ```diff + + world.registerNamespace(namespaceId); + world.registerSystem(systemId, system, true); + ``` + + ```diff + + world.registerNamespace(namespaceId); + MyTable.register(); + ``` + +- 69d55ce32: Deploy commands (`deploy`, `dev-contracts`, `test`) now correctly run `worldgen` to generate system interfaces before deploying. +- bd9cc8ec2: Refactor `deploy` command to break up logic into modules +- 8d51a0348: Clean up Memory.sol, make mcopy pure +- 2699630c0: Deploys will now always rebuild `IWorld.sol` interface (a workaround for https://github.com/foundry-rs/foundry/issues/6241) +- 48909d151: bump forge-std and ds-test dependencies +- 1d4039622: We fixed a bug in the deploy script that would cause the deployment to fail if a non-root namespace was used in the config. +- 4fe079309: Fixed a few issues with deploys: + + - properly handle enums in MUD config + - only deploy each unique module/system once + - waits for transactions serially instead of in parallel, to avoid RPC errors + +- 21a626ae9: Changed `mud` CLI import order so that environment variables from the `.env` file are loaded before other imports. +- 5d737cf2e: Updated the `debug` util to pipe to `stdout` and added an additional util to explicitly pipe to `stderr` when needed. +- db7798be2: Updated deployer with world's new `InitModule` naming. +- d844cd441: Sped up builds by using more of forge's cache. + + Previously we'd build only what we needed because we would check in ABIs and other build artifacts into git, but that meant that we'd get a lot of forge cache misses. Now that we no longer need these files visible, we can take advantage of forge's caching and greatly speed up builds, especially incremental ones. + +- bfcb293d1: What used to be known as `ephemeral` table is now called `offchain` table. + The previous `ephemeral` tables only supported an `emitEphemeral` method, which emitted a `StoreSetEphemeralRecord` event. + + Now `offchain` tables support all regular table methods, except partial operations on dynamic fields (`push`, `pop`, `update`). + Unlike regular tables they don't store data on-chain but emit the same events as regular tables (`StoreSetRecord`, `StoreSpliceStaticData`, `StoreDeleteRecord`), so their data can be indexed by offchain indexers/clients. + + ```diff + - EphemeralTable.emitEphemeral(value); + + OffchainTable.set(value); + ``` + +- 55ab88a60: `StoreCore` and `IStore` now expose specific functions for `getStaticField` and `getDynamicField` in addition to the general `getField`. + Using the specific functions reduces gas overhead because more optimized logic can be executed. + + ```solidity + interface IStore { + /** + * Get a single static field from the given tableId and key tuple, with the given value field layout. + * Note: the field value is left-aligned in the returned bytes32, the rest of the word is not zeroed out. + * Consumers are expected to truncate the returned value as needed. + */ + function getStaticField( + bytes32 tableId, + bytes32[] calldata keyTuple, + uint8 fieldIndex, + FieldLayout fieldLayout + ) external view returns (bytes32); + + /** + * Get a single dynamic field from the given tableId and key tuple at the given dynamic field index. + * (Dynamic field index = field index - number of static fields) + */ + function getDynamicField( + bytes32 tableId, + bytes32[] memory keyTuple, + uint8 dynamicFieldIndex + ) external view returns (bytes memory); + } + ``` + +- 4e4a34150: bump to latest TS version (5.1.6) +- 535229984: - bump to viem 1.3.0 and abitype 0.9.3 + - move `@wagmi/chains` imports to `viem/chains` + - refine a few types +- 83583a505: `deploy` and `dev-contracts` CLI commands now use `forge build --skip test script` before deploying and run `mud abi-ts` to generate strong types for ABIs. +- 60cfd089f: Templates and examples now use MUD's new sync packages, all built on top of [viem](https://viem.sh/). This greatly speeds up and stabilizes our networking code and improves types throughout. + + These new sync packages come with support for our `recs` package, including `encodeEntity` and `decodeEntity` utilities for composite keys. + + If you're using `store-cache` and `useRow`/`useRows`, you should wait to upgrade until we have a suitable replacement for those libraries. We're working on a [sql.js](https://github.com/sql-js/sql.js/)-powered sync module that will replace `store-cache`. + + **Migrate existing RECS apps to new sync packages** + + As you migrate, you may find some features replaced, removed, or not included by default. Please [open an issue](https://github.com/latticexyz/mud/issues/new) and let us know if we missed anything. + + 1. Add `@latticexyz/store-sync` package to your app's `client` package and make sure `viem` is pinned to version `1.3.1` (otherwise you may get type errors) + 2. In your `supportedChains.ts`, replace `foundry` chain with our new `mudFoundry` chain. + + ```diff + - import { foundry } from "viem/chains"; + - import { MUDChain, latticeTestnet } from "@latticexyz/common/chains"; + + import { MUDChain, latticeTestnet, mudFoundry } from "@latticexyz/common/chains"; + + - export const supportedChains: MUDChain[] = [foundry, latticeTestnet]; + + export const supportedChains: MUDChain[] = [mudFoundry, latticeTestnet]; + ``` + + 3. In `getNetworkConfig.ts`, remove the return type (to let TS infer it for now), remove now-unused config values, and add the viem `chain` object. + + ```diff + - export async function getNetworkConfig(): Promise { + + export async function getNetworkConfig() { + ``` + + ```diff + const initialBlockNumber = params.has("initialBlockNumber") + ? Number(params.get("initialBlockNumber")) + - : world?.blockNumber ?? -1; // -1 will attempt to find the block number from RPC + + : world?.blockNumber ?? 0n; + ``` + + ```diff + + return { + + privateKey: getBurnerWallet().value, + + chain, + + worldAddress, + + initialBlockNumber, + + faucetServiceUrl: params.get("faucet") ?? chain.faucetUrl, + + }; + ``` + + 4. In `setupNetwork.ts`, replace `setupMUDV2Network` with `syncToRecs`. + + ```diff + - import { setupMUDV2Network } from "@latticexyz/std-client"; + - import { createFastTxExecutor, createFaucetService, getSnapSyncRecords } from "@latticexyz/network"; + + import { createFaucetService } from "@latticexyz/network"; + + import { createPublicClient, fallback, webSocket, http, createWalletClient, getContract, Hex, parseEther, ClientConfig } from "viem"; + + import { encodeEntity, syncToRecs } from "@latticexyz/store-sync/recs"; + + import { createBurnerAccount, createContract, transportObserver } from "@latticexyz/common"; + ``` + + ```diff + - const result = await setupMUDV2Network({ + - ... + - }); + + + const clientOptions = { + + chain: networkConfig.chain, + + transport: transportObserver(fallback([webSocket(), http()])), + + pollingInterval: 1000, + + } as const satisfies ClientConfig; + + + const publicClient = createPublicClient(clientOptions); + + + const burnerAccount = createBurnerAccount(networkConfig.privateKey as Hex); + + const burnerWalletClient = createWalletClient({ + + ...clientOptions, + + account: burnerAccount, + + }); + + + const { components, latestBlock$, blockStorageOperations$, waitForTransaction } = await syncToRecs({ + + world, + + config: storeConfig, + + address: networkConfig.worldAddress as Hex, + + publicClient, + + components: contractComponents, + + startBlock: BigInt(networkConfig.initialBlockNumber), + + indexerUrl: networkConfig.indexerUrl ?? undefined, + + }); + + + const worldContract = createContract({ + + address: networkConfig.worldAddress as Hex, + + abi: IWorld__factory.abi, + + publicClient, + + walletClient: burnerWalletClient, + + }); + ``` + + ```diff + // Request drip from faucet + - const signer = result.network.signer.get(); + - if (networkConfig.faucetServiceUrl && signer) { + - const address = await signer.getAddress(); + + if (networkConfig.faucetServiceUrl) { + + const address = burnerAccount.address; + ``` + + ```diff + const requestDrip = async () => { + - const balance = await signer.getBalance(); + + const balance = await publicClient.getBalance({ address }); + console.info(`[Dev Faucet]: Player balance -> ${balance}`); + - const lowBalance = balance?.lte(utils.parseEther("1")); + + const lowBalance = balance < parseEther("1"); + ``` + + You can remove the previous ethers `worldContract`, snap sync code, and fast transaction executor. + + The return of `setupNetwork` is a bit different than before, so you may have to do corresponding app changes. + + ```diff + + return { + + world, + + components, + + playerEntity: encodeEntity({ address: "address" }, { address: burnerWalletClient.account.address }), + + publicClient, + + walletClient: burnerWalletClient, + + latestBlock$, + + blockStorageOperations$, + + waitForTransaction, + + worldContract, + + }; + ``` + + 5. Update `createSystemCalls` with the new return type of `setupNetwork`. + + ```diff + export function createSystemCalls( + - { worldSend, txReduced$, singletonEntity }: SetupNetworkResult, + + { worldContract, waitForTransaction }: SetupNetworkResult, + { Counter }: ClientComponents + ) { + const increment = async () => { + - const tx = await worldSend("increment", []); + - await awaitStreamValue(txReduced$, (txHash) => txHash === tx.hash); + + const tx = await worldContract.write.increment(); + + await waitForTransaction(tx); + return getComponentValue(Counter, singletonEntity); + }; + ``` + + 6. (optional) If you still need a clock, you can create it with: + + ```ts + import { map, filter } from "rxjs"; + import { createClock } from "@latticexyz/network"; + + const clock = createClock({ + period: 1000, + initialTime: 0, + syncInterval: 5000, + }); + + world.registerDisposer(() => clock.dispose()); + + latestBlock$ + .pipe( + map((block) => Number(block.timestamp) * 1000), // Map to timestamp in ms + filter((blockTimestamp) => blockTimestamp !== clock.lastUpdateTime), // Ignore if the clock was already refreshed with this block + filter((blockTimestamp) => blockTimestamp !== clock.currentTime), // Ignore if the current local timestamp is correct + ) + .subscribe(clock.update); // Update the local clock + ``` + + If you're using the previous `LoadingState` component, you'll want to migrate to the new `SyncProgress`: + + ```ts + import { SyncStep, singletonEntity } from "@latticexyz/store-sync/recs"; + + const syncProgress = useComponentValue(SyncProgress, singletonEntity, { + message: "Connecting", + percentage: 0, + step: SyncStep.INITIALIZE, + }); + + if (syncProgress.step === SyncStep.LIVE) { + // we're live! + } + ``` + +- 24a6cd536: Changed the `userTypes` property to accept `{ filePath: string, internalType: SchemaAbiType }` to enable strong type inference from the config. +- 708b49c50: Generated table libraries now have a set of functions prefixed with `_` that always use their own storage for read/write. + This saves gas for use cases where the functionality to dynamically determine which `Store` to use for read/write is not needed, e.g. root systems in a `World`, or when using `Store` without `World`. + + We decided to continue to always generate a set of functions that dynamically decide which `Store` to use, so that the generated table libraries can still be imported by non-root systems. + + ```solidity + library Counter { + // Dynamically determine which store to write to based on the context + function set(uint32 value) internal; + + // Always write to own storage + function _set(uint32 value) internal; + + // ... equivalent functions for all other Store methods + } + ``` + +- 25086be5f: Replaced temporary `.mudtest` file in favor of `WORLD_ADDRESS` environment variable when running tests with `MudTest` contract +- 9c83adc01: Added a non-deterministic fallback for deploying to chains that have replay protection on and do not support pre-EIP-155 transactions (no chain ID). + + If you're using `mud deploy` and there's already a [deterministic deployer](https://github.com/Arachnid/deterministic-deployment-proxy) on your target chain, you can provide the address with `--deployerAddress 0x...` to still get some determinism. + +- c049c23f4: - The `World` contract now has an `initialize` function, which can be called once by the creator of the World to install the core module. + This change allows the registration of all core tables to happen in the `CoreModule`, so no table metadata has to be included in the `World`'s bytecode. + + ```solidity + interface IBaseWorld { + function initialize(IModule coreModule) public; + } + ``` + + - The `World` contract now stores the original creator of the `World` in an immutable state variable. + It is used internally to only allow the original creator to initialize the `World` in a separate transaction. + + ```solidity + interface IBaseWorld { + function creator() external view returns (address); + } + ``` + + - The deploy script is updated to use the `World`'s `initialize` function to install the `CoreModule` instead of `registerRootModule` as before. + +- 6c6733256: Add `tableIdToHex` and `hexToTableId` pure functions and move/deprecate `TableId`. +- 251170e1e: All optional modules have been moved from `@latticexyz/world` to `@latticexyz/world-modules`. + If you're using the MUD CLI, the import is already updated and no changes are necessary. +- c4f49240d: Table libraries now correctly handle uninitialized fixed length arrays. +- afdba793f: Update RECS components with v2 key/value schemas. This helps with encoding/decoding composite keys and strong types for keys/values. + + This may break if you were previously dependent on `component.id`, `component.metadata.componentId`, or `component.metadata.tableId`: + + - `component.id` is now the on-chain `bytes32` hex representation of the table ID + - `component.metadata.componentName` is the table name (e.g. `Position`) + - `component.metadata.tableName` is the namespaced table name (e.g. `myworld:Position`) + - `component.metadata.keySchema` is an object with key names and their corresponding ABI types + - `component.metadata.valueSchema` is an object with field names and their corresponding ABI types + +- 3e7d83d0: Renamed `PackedCounter` to `EncodedLengths` for consistency. +- cea754dde: - The external `setRecord` and `deleteRecord` methods of `IStore` no longer accept a `FieldLayout` as input, but load it from storage instead. + This is to prevent invalid `FieldLayout` values being passed, which could cause the onchain state to diverge from the indexer state. + However, the internal `StoreCore` library still exposes a `setRecord` and `deleteRecord` method that allows a `FieldLayout` to be passed. + This is because `StoreCore` can only be used internally, so the `FieldLayout` value can be trusted and we can save the gas for accessing storage. + + ```diff + interface IStore { + function setRecord( + ResourceId tableId, + bytes32[] calldata keyTuple, + bytes calldata staticData, + PackedCounter encodedLengths, + bytes calldata dynamicData, + - FieldLayout fieldLayout + ) external; + + function deleteRecord( + ResourceId tableId, + bytes32[] memory keyTuple, + - FieldLayout fieldLayout + ) external; + } + ``` + + - The `spliceStaticData` method and `Store_SpliceStaticData` event of `IStore` and `StoreCore` no longer include `deleteCount` in their signature. + This is because when splicing static data, the data after `start` is always overwritten with `data` instead of being shifted, so `deleteCount` is always the length of the data to be written. + + ```diff + + event Store_SpliceStaticData( + ResourceId indexed tableId, + bytes32[] keyTuple, + uint48 start, + - uint40 deleteCount, + bytes data + ); + + interface IStore { + function spliceStaticData( + ResourceId tableId, + bytes32[] calldata keyTuple, + uint48 start, + - uint40 deleteCount, + bytes calldata data + ) external; + } + ``` + + - The `updateInField` method has been removed from `IStore`, as it's almost identical to the more general `spliceDynamicData`. + If you're manually calling `updateInField`, here is how to upgrade to `spliceDynamicData`: + + ```diff + - store.updateInField(tableId, keyTuple, fieldIndex, startByteIndex, dataToSet, fieldLayout); + + uint8 dynamicFieldIndex = fieldIndex - fieldLayout.numStaticFields(); + + store.spliceDynamicData(tableId, keyTuple, dynamicFieldIndex, uint40(startByteIndex), uint40(dataToSet.length), dataToSet); + ``` + + - All other methods that are only valid for dynamic fields (`pushToField`, `popFromField`, `getFieldSlice`) + have been renamed to make this more explicit (`pushToDynamicField`, `popFromDynamicField`, `getDynamicFieldSlice`). + + Their `fieldIndex` parameter has been replaced by a `dynamicFieldIndex` parameter, which is the index relative to the first dynamic field (i.e. `dynamicFieldIndex` = `fieldIndex` - `numStaticFields`). + The `FieldLayout` parameter has been removed, as it was only used to calculate the `dynamicFieldIndex` in the method. + + ```diff + interface IStore { + - function pushToField( + + function pushToDynamicField( + ResourceId tableId, + bytes32[] calldata keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + bytes calldata dataToPush, + - FieldLayout fieldLayout + ) external; + + - function popFromField( + + function popFromDynamicField( + ResourceId tableId, + bytes32[] calldata keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + uint256 byteLengthToPop, + - FieldLayout fieldLayout + ) external; + + - function getFieldSlice( + + function getDynamicFieldSlice( + ResourceId tableId, + bytes32[] memory keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + - FieldLayout fieldLayout, + uint256 start, + uint256 end + ) external view returns (bytes memory data); + } + ``` + + - `IStore` has a new `getDynamicFieldLength` length method, which returns the byte length of the given dynamic field and doesn't require the `FieldLayout`. + + ```diff + IStore { + + function getDynamicFieldLength( + + ResourceId tableId, + + bytes32[] memory keyTuple, + + uint8 dynamicFieldIndex + + ) external view returns (uint256); + } + + ``` + + - `IStore` now has additional overloads for `getRecord`, `getField`, `getFieldLength` and `setField` that don't require a `FieldLength` to be passed, but instead load it from storage. + - `IStore` now exposes `setStaticField` and `setDynamicField` to save gas by avoiding the dynamic inference of whether the field is static or dynamic. + - The `getDynamicFieldSlice` method no longer accepts reading outside the bounds of the dynamic field. + This is to avoid returning invalid data, as the data of a dynamic field is not deleted when the record is deleted, but only its length is set to zero. + +- d2f8e9400: Moved to new resource ID utils. +- dc258e686: The `mud test` cli now exits with code 1 on test failure. It used to exit with code 0, which meant that CIs didn't notice test failures. +- Updated dependencies [7ce82b6fc] +- Updated dependencies [d8c8f66bf] +- Updated dependencies [c6c13f2ea] +- Updated dependencies [77dce993a] +- Updated dependencies [ce97426c0] +- Updated dependencies [3236f799e] +- Updated dependencies [1b86eac05] +- Updated dependencies [a35c05ea9] +- Updated dependencies [c9ee5e4a] +- Updated dependencies [c963b46c7] +- Updated dependencies [05b3e8882] +- Updated dependencies [eaa766ef7] +- Updated dependencies [52182f70d] +- Updated dependencies [0f27afddb] +- Updated dependencies [748f4588a] +- Updated dependencies [865253dba] +- Updated dependencies [8f49c277d] +- Updated dependencies [7fa2ca183] +- Updated dependencies [745485cda] +- Updated dependencies [16b13ea8f] +- Updated dependencies [aea67c580] +- Updated dependencies [33f50f8a4] +- Updated dependencies [82693072] +- Updated dependencies [07dd6f32c] +- Updated dependencies [c07fa0215] +- Updated dependencies [90e4161bb] +- Updated dependencies [aabd30767] +- Updated dependencies [65c9546c4] +- Updated dependencies [6ca1874e0] +- Updated dependencies [331dbfdcb] +- Updated dependencies [d5c0682fb] +- Updated dependencies [1d60930d6] +- Updated dependencies [01e46d99] +- Updated dependencies [4be22ba4] +- Updated dependencies [430e6b29a] +- Updated dependencies [f9f9609ef] +- Updated dependencies [904fd7d4e] +- Updated dependencies [e6c03a87a] +- Updated dependencies [1077c7f53] +- Updated dependencies [2c920de7] +- Updated dependencies [b98e51808] +- Updated dependencies [b9e562d8f] +- Updated dependencies [331dbfdcb] +- Updated dependencies [44236041f] +- Updated dependencies [066056154] +- Updated dependencies [759514d8b] +- Updated dependencies [952cd5344] +- Updated dependencies [d5094a242] +- Updated dependencies [3fb9ce283] +- Updated dependencies [c207d35e8] +- Updated dependencies [db7798be2] +- Updated dependencies [bb6ada740] +- Updated dependencies [35c9f33df] +- Updated dependencies [3be4deecf] +- Updated dependencies [a25881160] +- Updated dependencies [0b8ce3f2c] +- Updated dependencies [933b54b5f] +- Updated dependencies [5debcca8] +- Updated dependencies [80a26419f] +- Updated dependencies [c4d5eb4e4] +- Updated dependencies [f8dab7334] +- Updated dependencies [1a0fa7974] +- Updated dependencies [f62c767e7] +- Updated dependencies [d00c4a9af] +- Updated dependencies [d7325e517] +- Updated dependencies [9aa5e786] +- Updated dependencies [307abab3] +- Updated dependencies [de151fec0] +- Updated dependencies [c32a9269a] +- Updated dependencies [eb384bb0e] +- Updated dependencies [37c228c63] +- Updated dependencies [35348f831] +- Updated dependencies [618dd0e89] +- Updated dependencies [aacffcb59] +- Updated dependencies [c991c71a] +- Updated dependencies [ae340b2bf] +- Updated dependencies [1bf2e9087] +- Updated dependencies [e5d208e40] +- Updated dependencies [b38c096d] +- Updated dependencies [211be2a1e] +- Updated dependencies [0f3e2e02b] +- Updated dependencies [4bb7e8cbf] +- Updated dependencies [1f80a0b52] +- Updated dependencies [d08789282] +- Updated dependencies [5c965a919] +- Updated dependencies [f99e88987] +- Updated dependencies [939916bcd] +- Updated dependencies [e5a962bc3] +- Updated dependencies [331f0d636] +- Updated dependencies [f6f402896] +- Updated dependencies [d5b73b126] +- Updated dependencies [e34d1170] +- Updated dependencies [08b422171] +- Updated dependencies [b8a6158d6] +- Updated dependencies [190fdd11] +- Updated dependencies [c4fc85041] +- Updated dependencies [37c228c63] +- Updated dependencies [37c228c63] +- Updated dependencies [433078c54] +- Updated dependencies [2459e15fc] +- Updated dependencies [db314a74] +- Updated dependencies [b2d2aa715] +- Updated dependencies [4c7fd3eb2] +- Updated dependencies [a0341daf9] +- Updated dependencies [ca50fef81] +- Updated dependencies [83583a505] +- Updated dependencies [5e723b90e] +- Updated dependencies [6573e38e9] +- Updated dependencies [51914d656] +- Updated dependencies [063daf80e] +- Updated dependencies [afaf2f5ff] +- Updated dependencies [37c228c63] +- Updated dependencies [9352648b1] +- Updated dependencies [59267655] +- Updated dependencies [37c228c63] +- Updated dependencies [2bfee9217] +- Updated dependencies [1ca35e9a1] +- Updated dependencies [ca3291751] +- Updated dependencies [ba17bdab5] +- Updated dependencies [44a5432ac] +- Updated dependencies [6e66c5b74] +- Updated dependencies [8d51a0348] +- Updated dependencies [c162ad5a5] +- Updated dependencies [88b1a5a19] +- Updated dependencies [65c9546c4] +- Updated dependencies [48909d151] +- Updated dependencies [7b28d32e5] +- Updated dependencies [f8a01a047] +- Updated dependencies [b02f9d0e4] +- Updated dependencies [2ca75f9b9] +- Updated dependencies [f62c767e7] +- Updated dependencies [bb91edaa0] +- Updated dependencies [590542030] +- Updated dependencies [1a82c278] +- Updated dependencies [1b5eb0d07] +- Updated dependencies [44a5432ac] +- Updated dependencies [48c51b52a] +- Updated dependencies [9f8b84e73] +- Updated dependencies [a02da555b] +- Updated dependencies [66cc35a8c] +- Updated dependencies [672d05ca1] +- Updated dependencies [f1cd43bf9] +- Updated dependencies [9d0f492a9] +- Updated dependencies [55a05fd7a] +- Updated dependencies [f03531d97] +- Updated dependencies [c583f3cd0] +- Updated dependencies [31ffc9d5d] +- Updated dependencies [5e723b90e] +- Updated dependencies [63831a264] +- Updated dependencies [b8a6158d6] +- Updated dependencies [6db95ce15] +- Updated dependencies [8193136a9] +- Updated dependencies [5d737cf2e] +- Updated dependencies [d075f82f3] +- Updated dependencies [331dbfdcb] +- Updated dependencies [6ca1874e0] +- Updated dependencies [a7b30c79b] +- Updated dependencies [6470fe1fd] +- Updated dependencies [86766ce1] +- Updated dependencies [92de59982] +- Updated dependencies [5741d53d0] +- Updated dependencies [aee8020a6] +- Updated dependencies [331f0d636] +- Updated dependencies [22ee44700] +- Updated dependencies [e2d089c6d] +- Updated dependencies [ad4ac4459] +- Updated dependencies [8025c3505] +- Updated dependencies [be313068b] +- Updated dependencies [ac508bf18] +- Updated dependencies [836383734] +- Updated dependencies [9ff4dd955] +- Updated dependencies [93390d89] +- Updated dependencies [4385c5a4c] +- Updated dependencies [57d8965df] +- Updated dependencies [18d3aea55] +- Updated dependencies [7987c94d6] +- Updated dependencies [bb91edaa0] +- Updated dependencies [144c0d8d] +- Updated dependencies [5ac4c97f4] +- Updated dependencies [bfcb293d1] +- Updated dependencies [3e057061d] +- Updated dependencies [1890f1a06] +- Updated dependencies [90d0d79c] +- Updated dependencies [e48171741] +- Updated dependencies [e4a6189df] +- Updated dependencies [9b43029c3] +- Updated dependencies [37c228c63] +- Updated dependencies [55ab88a60] +- Updated dependencies [c58da9ad] +- Updated dependencies [37c228c63] +- Updated dependencies [747d8d1b8] +- Updated dependencies [4e4a34150] +- Updated dependencies [535229984] +- Updated dependencies [af639a264] +- Updated dependencies [5e723b90e] +- Updated dependencies [99ab9cd6f] +- Updated dependencies [086be4ef4] +- Updated dependencies [be18b75b] +- Updated dependencies [0c4f9fea9] +- Updated dependencies [0d12db8c2] +- Updated dependencies [c049c23f4] +- Updated dependencies [80dd6992e] +- Updated dependencies [60cfd089f] +- Updated dependencies [24a6cd536] +- Updated dependencies [37c228c63] +- Updated dependencies [708b49c50] +- Updated dependencies [d2f8e9400] +- Updated dependencies [17f987209] +- Updated dependencies [25086be5f] +- Updated dependencies [37c228c63] +- Updated dependencies [b1d41727d] +- Updated dependencies [3ac68ade6] +- Updated dependencies [c642ff3a0] +- Updated dependencies [22ba7b675] +- Updated dependencies [4c1dcd81e] +- Updated dependencies [3042f86e] +- Updated dependencies [c049c23f4] +- Updated dependencies [9af542d3e] +- Updated dependencies [5e71e1cb5] +- Updated dependencies [6071163f7] +- Updated dependencies [6c6733256] +- Updated dependencies [cd5abcc3b] +- Updated dependencies [d7b1c588a] +- Updated dependencies [5c52bee09] +- Updated dependencies [fdbba6d88] +- Updated dependencies [251170e1e] +- Updated dependencies [8025c3505] +- Updated dependencies [c4f49240d] +- Updated dependencies [745485cda] +- Updated dependencies [95f64c85] +- Updated dependencies [37c228c63] +- Updated dependencies [3e7d83d0] +- Updated dependencies [5df1f31bc] +- Updated dependencies [a2f41ade9] +- Updated dependencies [29c3f5087] +- Updated dependencies [cea754dde] +- Updated dependencies [5e71e1cb5] +- Updated dependencies [331f0d636] +- Updated dependencies [95c59b203] +- Updated dependencies [cc2c8da00] +- Updated dependencies [252a1852] +- Updated dependencies [103f635eb] + - @latticexyz/store@2.0.0 + - @latticexyz/world-modules@2.0.0 + - @latticexyz/world@2.0.0 + - @latticexyz/services@2.0.0 + - @latticexyz/common@2.0.0 + - @latticexyz/utils@2.0.0 + - @latticexyz/protocol-parser@2.0.0 + - @latticexyz/schema-type@2.0.0 + - @latticexyz/gas-report@2.0.0 + - @latticexyz/abi-ts@2.0.0 + - @latticexyz/config@2.0.0 + ## 2.0.0-next.18 ### Major Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 62e2676bcb..5d89993c24 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@latticexyz/cli", - "version": "2.0.0-next.18", + "version": "2.0.0", "description": "Command line interface for mud", "repository": { "type": "git", diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index 870abe761b..aaf8b8c9c3 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -1,5 +1,672 @@ # Change Log +## 2.0.0 + +### Major Changes + +- 65c9546c4: - Add `renderWithFieldSuffix` helper method to always render a field function with a suffix, and optionally render the same function without a suffix. + - Remove `methodNameSuffix` from `RenderField` interface, because the suffix is now computed as part of `renderWithFieldSuffix`. +- 44236041f: Moved table ID and field layout constants in code-generated table libraries from the file level into the library, for clearer access and cleaner imports. + + ```diff + -import { SomeTable, SomeTableTableId } from "./codegen/tables/SomeTable.sol"; + +import { SomeTable } from "./codegen/tables/SomeTable.sol"; + + -console.log(SomeTableTableId); + +console.log(SomeTable._tableId); + + -console.log(SomeTable.getFieldLayout()); + +console.log(SomeTable._fieldLayout); + ``` + +- bfcb293d1: What used to be known as `ephemeral` table is now called `offchain` table. + The previous `ephemeral` tables only supported an `emitEphemeral` method, which emitted a `StoreSetEphemeralRecord` event. + + Now `offchain` tables support all regular table methods, except partial operations on dynamic fields (`push`, `pop`, `update`). + Unlike regular tables they don't store data on-chain but emit the same events as regular tables (`StoreSetRecord`, `StoreSpliceStaticData`, `StoreDeleteRecord`), so their data can be indexed by offchain indexers/clients. + + ```diff + - EphemeralTable.emitEphemeral(value); + + OffchainTable.set(value); + ``` + +- 5e723b90e: - `ResourceSelector` is replaced with `ResourceId`, `ResourceIdLib`, `ResourceIdInstance`, `WorldResourceIdLib` and `WorldResourceIdInstance`. + + Previously a "resource selector" was a `bytes32` value with the first 16 bytes reserved for the resource's namespace, and the last 16 bytes reserved for the resource's name. + Now a "resource ID" is a `bytes32` value with the first 2 bytes reserved for the resource type, the next 14 bytes reserved for the resource's namespace, and the last 16 bytes reserved for the resource's name. + + Previously `ResouceSelector` was a library and the resource selector type was a plain `bytes32`. + Now `ResourceId` is a user type, and the functionality is implemented in the `ResourceIdInstance` (for type) and `WorldResourceIdInstance` (for namespace and name) libraries. + We split the logic into two libraries, because `Store` now also uses `ResourceId` and needs to be aware of resource types, but not of namespaces/names. + + ```diff + - import { ResourceSelector } from "@latticexyz/world/src/ResourceSelector.sol"; + + import { ResourceId, ResourceIdInstance } from "@latticexyz/store/src/ResourceId.sol"; + + import { WorldResourceIdLib, WorldResourceIdInstance } from "@latticexyz/world/src/WorldResourceId.sol"; + + import { RESOURCE_SYSTEM } from "@latticexyz/world/src/worldResourceTypes.sol"; + + - bytes32 systemId = ResourceSelector.from("namespace", "name"); + + ResourceId systemId = WorldResourceIdLib.encode(RESOURCE_SYSTEM, "namespace", "name"); + + - using ResourceSelector for bytes32; + + using WorldResourceIdInstance for ResourceId; + + using ResourceIdInstance for ResourceId; + + systemId.getName(); + systemId.getNamespace(); + + systemId.getType(); + + ``` + + - All `Store` and `World` methods now use the `ResourceId` type for `tableId`, `systemId`, `moduleId` and `namespaceId`. + All mentions of `resourceSelector` were renamed to `resourceId` or the more specific type (e.g. `tableId`, `systemId`) + + ```diff + import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; + + IStore { + function setRecord( + - bytes32 tableId, + + ResourceId tableId, + bytes32[] calldata keyTuple, + bytes calldata staticData, + PackedCounter encodedLengths, + bytes calldata dynamicData, + FieldLayout fieldLayout + ) external; + + // Same for all other methods + } + ``` + + ```diff + import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; + + IBaseWorld { + function callFrom( + address delegator, + - bytes32 resourceSelector, + + ResourceId systemId, + bytes memory callData + ) external payable returns (bytes memory); + + // Same for all other methods + } + ``` + +- 60cfd089f: Templates and examples now use MUD's new sync packages, all built on top of [viem](https://viem.sh/). This greatly speeds up and stabilizes our networking code and improves types throughout. + + These new sync packages come with support for our `recs` package, including `encodeEntity` and `decodeEntity` utilities for composite keys. + + If you're using `store-cache` and `useRow`/`useRows`, you should wait to upgrade until we have a suitable replacement for those libraries. We're working on a [sql.js](https://github.com/sql-js/sql.js/)-powered sync module that will replace `store-cache`. + + **Migrate existing RECS apps to new sync packages** + + As you migrate, you may find some features replaced, removed, or not included by default. Please [open an issue](https://github.com/latticexyz/mud/issues/new) and let us know if we missed anything. + + 1. Add `@latticexyz/store-sync` package to your app's `client` package and make sure `viem` is pinned to version `1.3.1` (otherwise you may get type errors) + 2. In your `supportedChains.ts`, replace `foundry` chain with our new `mudFoundry` chain. + + ```diff + - import { foundry } from "viem/chains"; + - import { MUDChain, latticeTestnet } from "@latticexyz/common/chains"; + + import { MUDChain, latticeTestnet, mudFoundry } from "@latticexyz/common/chains"; + + - export const supportedChains: MUDChain[] = [foundry, latticeTestnet]; + + export const supportedChains: MUDChain[] = [mudFoundry, latticeTestnet]; + ``` + + 3. In `getNetworkConfig.ts`, remove the return type (to let TS infer it for now), remove now-unused config values, and add the viem `chain` object. + + ```diff + - export async function getNetworkConfig(): Promise { + + export async function getNetworkConfig() { + ``` + + ```diff + const initialBlockNumber = params.has("initialBlockNumber") + ? Number(params.get("initialBlockNumber")) + - : world?.blockNumber ?? -1; // -1 will attempt to find the block number from RPC + + : world?.blockNumber ?? 0n; + ``` + + ```diff + + return { + + privateKey: getBurnerWallet().value, + + chain, + + worldAddress, + + initialBlockNumber, + + faucetServiceUrl: params.get("faucet") ?? chain.faucetUrl, + + }; + ``` + + 4. In `setupNetwork.ts`, replace `setupMUDV2Network` with `syncToRecs`. + + ```diff + - import { setupMUDV2Network } from "@latticexyz/std-client"; + - import { createFastTxExecutor, createFaucetService, getSnapSyncRecords } from "@latticexyz/network"; + + import { createFaucetService } from "@latticexyz/network"; + + import { createPublicClient, fallback, webSocket, http, createWalletClient, getContract, Hex, parseEther, ClientConfig } from "viem"; + + import { encodeEntity, syncToRecs } from "@latticexyz/store-sync/recs"; + + import { createBurnerAccount, createContract, transportObserver } from "@latticexyz/common"; + ``` + + ```diff + - const result = await setupMUDV2Network({ + - ... + - }); + + + const clientOptions = { + + chain: networkConfig.chain, + + transport: transportObserver(fallback([webSocket(), http()])), + + pollingInterval: 1000, + + } as const satisfies ClientConfig; + + + const publicClient = createPublicClient(clientOptions); + + + const burnerAccount = createBurnerAccount(networkConfig.privateKey as Hex); + + const burnerWalletClient = createWalletClient({ + + ...clientOptions, + + account: burnerAccount, + + }); + + + const { components, latestBlock$, blockStorageOperations$, waitForTransaction } = await syncToRecs({ + + world, + + config: storeConfig, + + address: networkConfig.worldAddress as Hex, + + publicClient, + + components: contractComponents, + + startBlock: BigInt(networkConfig.initialBlockNumber), + + indexerUrl: networkConfig.indexerUrl ?? undefined, + + }); + + + const worldContract = createContract({ + + address: networkConfig.worldAddress as Hex, + + abi: IWorld__factory.abi, + + publicClient, + + walletClient: burnerWalletClient, + + }); + ``` + + ```diff + // Request drip from faucet + - const signer = result.network.signer.get(); + - if (networkConfig.faucetServiceUrl && signer) { + - const address = await signer.getAddress(); + + if (networkConfig.faucetServiceUrl) { + + const address = burnerAccount.address; + ``` + + ```diff + const requestDrip = async () => { + - const balance = await signer.getBalance(); + + const balance = await publicClient.getBalance({ address }); + console.info(`[Dev Faucet]: Player balance -> ${balance}`); + - const lowBalance = balance?.lte(utils.parseEther("1")); + + const lowBalance = balance < parseEther("1"); + ``` + + You can remove the previous ethers `worldContract`, snap sync code, and fast transaction executor. + + The return of `setupNetwork` is a bit different than before, so you may have to do corresponding app changes. + + ```diff + + return { + + world, + + components, + + playerEntity: encodeEntity({ address: "address" }, { address: burnerWalletClient.account.address }), + + publicClient, + + walletClient: burnerWalletClient, + + latestBlock$, + + blockStorageOperations$, + + waitForTransaction, + + worldContract, + + }; + ``` + + 5. Update `createSystemCalls` with the new return type of `setupNetwork`. + + ```diff + export function createSystemCalls( + - { worldSend, txReduced$, singletonEntity }: SetupNetworkResult, + + { worldContract, waitForTransaction }: SetupNetworkResult, + { Counter }: ClientComponents + ) { + const increment = async () => { + - const tx = await worldSend("increment", []); + - await awaitStreamValue(txReduced$, (txHash) => txHash === tx.hash); + + const tx = await worldContract.write.increment(); + + await waitForTransaction(tx); + return getComponentValue(Counter, singletonEntity); + }; + ``` + + 6. (optional) If you still need a clock, you can create it with: + + ```ts + import { map, filter } from "rxjs"; + import { createClock } from "@latticexyz/network"; + + const clock = createClock({ + period: 1000, + initialTime: 0, + syncInterval: 5000, + }); + + world.registerDisposer(() => clock.dispose()); + + latestBlock$ + .pipe( + map((block) => Number(block.timestamp) * 1000), // Map to timestamp in ms + filter((blockTimestamp) => blockTimestamp !== clock.lastUpdateTime), // Ignore if the clock was already refreshed with this block + filter((blockTimestamp) => blockTimestamp !== clock.currentTime), // Ignore if the current local timestamp is correct + ) + .subscribe(clock.update); // Update the local clock + ``` + + If you're using the previous `LoadingState` component, you'll want to migrate to the new `SyncProgress`: + + ```ts + import { SyncStep, singletonEntity } from "@latticexyz/store-sync/recs"; + + const syncProgress = useComponentValue(SyncProgress, singletonEntity, { + message: "Connecting", + percentage: 0, + step: SyncStep.INITIALIZE, + }); + + if (syncProgress.step === SyncStep.LIVE) { + // we're live! + } + ``` + +- 6c6733256: Add `tableIdToHex` and `hexToTableId` pure functions and move/deprecate `TableId`. +- cd5abcc3b: Add utils for using viem with MUD + + - `createContract` is a wrapper around [viem's `getContract`](https://viem.sh/docs/contract/getContract.html) but with better nonce handling for faster executing of transactions. It has the same arguments and return type as `getContract`. + - `createNonceManager` helps track local nonces, used by `createContract`. + + Also renames `mudTransportObserver` to `transportObserver`. + +### Minor Changes + +- aabd30767: Bumped Solidity version to 0.8.24. +- 331dbfdcb: `readHex` was moved from `@latticexyz/protocol-parser` to `@latticexyz/common` +- 066056154: - Added a `sendTransaction` helper to mirror viem's `sendTransaction`, but with our nonce manager + - Added an internal mempool queue to `sendTransaction` and `writeContract` for better nonce handling + - Defaults block tag to `pending` for transaction simulation and transaction count (when initializing the nonce manager) +- 3fb9ce283: Add utils for using viem with MUD + + - `mudFoundry` chain with a transaction request formatter that temporarily removes max fees to work better with anvil `--base-fee 0` + - `createBurnerAccount` that also temporarily removes max fees during transaction signing to work better with anvil `--base-fee 0` + - `mudTransportObserver` that will soon let MUD Dev Tools observe transactions + + You can use them like: + + ```ts + import { createBurnerAccount, mudTransportObserver } from "@latticexyz/common"; + import { mudFoundry } from "@latticexyz/common/chains"; + + createWalletClient({ + account: createBurnerAccount(privateKey), + chain: mudFoundry, + transport: mudTransportObserver(http()), + pollingInterval: 1000, + }); + ``` + +- 939916bcd: `createContract` now has an `onWrite` callback so you can observe writes. This is useful for wiring up the transanction log in MUD dev tools. + + ```ts + import { createContract, ContractWrite } from "@latticexyz/common"; + import { Subject } from "rxjs"; + + const write$ = new Subject(); + creactContract({ + ... + onWrite: (write) => write$.next(write), + }); + ``` + +- b8a6158d6: - adds `defaultPriorityFee` to `mudFoundry` for better support with MUD's default anvil config and removes workaround in `createContract` + - improves nonce error detection using viem's custom errors +- 59267655: Added viem custom client actions that work the same as MUD's now-deprecated `getContract`, `writeContract`, and `sendTransaction` wrappers. Templates have been updated to reflect the new patterns. + + You can migrate your own code like this: + + ```diff + -import { createWalletClient } from "viem"; + -import { getContract, writeContract, sendTransaction } from "@latticexyz/common"; + +import { createWalletClient, getContract } from "viem"; + +import { transactionQueue, writeObserver } from "@latticexyz/common/actions"; + + -const walletClient = createWalletClient(...); + +const walletClient = createWalletClient(...) + + .extend(transactionQueue()) + + .extend(writeObserver({ onWrite }); + + const worldContract = getContract({ + client: { publicClient, walletClient }, + - onWrite, + }); + ``` + +- 1b5eb0d07: Added `unique` and `groupBy` array helpers to `@latticexyz/common/utils`. + + ```ts + import { unique } from "@latticexyz/common/utils"; + + unique([1, 2, 1, 4, 3, 2]); + // [1, 2, 4, 3] + ``` + + ```ts + import { groupBy } from "@latticexyz/common/utils"; + + const records = [ + { type: "cat", name: "Bob" }, + { type: "cat", name: "Spot" }, + { type: "dog", name: "Rover" }, + ]; + Object.fromEntries(groupBy(records, (record) => record.type)); + // { + // "cat": [{ type: "cat", name: "Bob" }, { type: "cat", name: "Spot" }], + // "dog: [{ type: "dog", name: "Rover" }] + // } + ``` + +- 44a5432ac: - Add `getRemappings` to get foundry remappings as an array of `[to, from]` tuples. + - Add `extractUserTypes` solidity parser utility to extract user-defined types. + - Add `loadAndExtractUserTypes` helper to load and parse a solidity file, extracting user-defined types. +- d075f82f3: - Moves contract write logic out of `createContract` into its own `writeContract` method so that it can be used outside of the contract instance, and for consistency with viem. + + - Deprecates `createContract` in favor of `getContract` for consistency with viem. + - Reworks `createNonceManager`'s `BroadcastChannel` setup and moves out the notion of a "nonce manager ID" to `getNonceManagerId` so we can create an internal cache with `getNonceManager` for use in `writeContract`. + + If you were using the `createNonceManager` before, you'll just need to rename `publicClient` argument to `client`: + + ```diff + const publicClient = createPublicClient({ ... }); + - const nonceManager = createNonceManager({ publicClient, ... }); + + const nonceManager = createNonceManager({ client: publicClient, ... }); + ``` + +- 331dbfdcb: `spliceHex` was added, which has a similar API as JavaScript's [`Array.prototype.splice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice), but for `Hex` strings. + + ```ts + spliceHex("0x123456", 1, 1, "0x0000"); // "0x12000056" + ``` + +- 92de59982: Bump Solidity version to 0.8.21 +- 0c4f9fea9: `TableId.toHex()` now truncates name/namespace to 16 bytes each, to properly fit into a `bytes32` hex string. + + Also adds a few utils we'll need in the indexer: + + - `bigIntMin` is similar to `Math.min` but for `bigint`s + - `bigIntMax` is similar to `Math.max` but for `bigint`s + - `bigIntSort` for sorting an array of `bigint`s + - `chunk` to split an array into chunks + - `wait` returns a `Promise` that resolves after specified number of milliseconds + +- 708b49c50: Generated table libraries now have a set of functions prefixed with `_` that always use their own storage for read/write. + This saves gas for use cases where the functionality to dynamically determine which `Store` to use for read/write is not needed, e.g. root systems in a `World`, or when using `Store` without `World`. + + We decided to continue to always generate a set of functions that dynamically decide which `Store` to use, so that the generated table libraries can still be imported by non-root systems. + + ```solidity + library Counter { + // Dynamically determine which store to write to based on the context + function set(uint32 value) internal; + + // Always write to own storage + function _set(uint32 value) internal; + + // ... equivalent functions for all other Store methods + } + ``` + +- d2f8e9400: Renames `resourceIdToHex` to `resourceToHex` and `hexToResourceId` to `hexToResource`, to better distinguish between a resource ID (hex value) and a resource reference (type, namespace, name). + + ```diff + - resourceIdToHex({ type: 'table', namespace: '', name: 'Position' }); + + resourceToHex({ type: 'table', namespace: '', name: 'Position' }); + ``` + + ```diff + - hexToResourceId('0x...'); + + hexToResource('0x...'); + ``` + + Previous methods still exist but are now deprecated to ease migration and reduce breaking changes. These will be removed in a future version. + + Also removes the previously deprecated and unused table ID utils (replaced by these resource ID utils). + +- b1d41727d: Added a `mapObject` helper to map the value of each property of an object to a new value. +- 4c1dcd81e: - Added a `Result` type for more explicit and typesafe error handling ([inspired by Rust](https://doc.rust-lang.org/std/result/)). + + - Added a `includes` util as typesafe alternative to [`Array.prototype.includes()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes). + +- 6071163f7: - Moves zero gas fee override to `createContract` until https://github.com/wagmi-dev/viem/pull/963 or similar feature lands + - Skip simulation if `gas` is provided +- d7b1c588a: Upgraded all packages and templates to viem v2.7.12 and abitype v1.0.0. + + Some viem APIs have changed and we've updated `getContract` to reflect those changes and keep it aligned with viem. It's one small code change: + + ```diff + const worldContract = getContract({ + address: worldAddress, + abi: IWorldAbi, + - publicClient, + - walletClient, + + client: { public: publicClient, wallet: walletClient }, + }); + ``` + +- 5df1f31bc: Updated `chunk` types to use readonly arrays +- cea754dde: - The external `setRecord` and `deleteRecord` methods of `IStore` no longer accept a `FieldLayout` as input, but load it from storage instead. + This is to prevent invalid `FieldLayout` values being passed, which could cause the onchain state to diverge from the indexer state. + However, the internal `StoreCore` library still exposes a `setRecord` and `deleteRecord` method that allows a `FieldLayout` to be passed. + This is because `StoreCore` can only be used internally, so the `FieldLayout` value can be trusted and we can save the gas for accessing storage. + + ```diff + interface IStore { + function setRecord( + ResourceId tableId, + bytes32[] calldata keyTuple, + bytes calldata staticData, + PackedCounter encodedLengths, + bytes calldata dynamicData, + - FieldLayout fieldLayout + ) external; + + function deleteRecord( + ResourceId tableId, + bytes32[] memory keyTuple, + - FieldLayout fieldLayout + ) external; + } + ``` + + - The `spliceStaticData` method and `Store_SpliceStaticData` event of `IStore` and `StoreCore` no longer include `deleteCount` in their signature. + This is because when splicing static data, the data after `start` is always overwritten with `data` instead of being shifted, so `deleteCount` is always the length of the data to be written. + + ```diff + + event Store_SpliceStaticData( + ResourceId indexed tableId, + bytes32[] keyTuple, + uint48 start, + - uint40 deleteCount, + bytes data + ); + + interface IStore { + function spliceStaticData( + ResourceId tableId, + bytes32[] calldata keyTuple, + uint48 start, + - uint40 deleteCount, + bytes calldata data + ) external; + } + ``` + + - The `updateInField` method has been removed from `IStore`, as it's almost identical to the more general `spliceDynamicData`. + If you're manually calling `updateInField`, here is how to upgrade to `spliceDynamicData`: + + ```diff + - store.updateInField(tableId, keyTuple, fieldIndex, startByteIndex, dataToSet, fieldLayout); + + uint8 dynamicFieldIndex = fieldIndex - fieldLayout.numStaticFields(); + + store.spliceDynamicData(tableId, keyTuple, dynamicFieldIndex, uint40(startByteIndex), uint40(dataToSet.length), dataToSet); + ``` + + - All other methods that are only valid for dynamic fields (`pushToField`, `popFromField`, `getFieldSlice`) + have been renamed to make this more explicit (`pushToDynamicField`, `popFromDynamicField`, `getDynamicFieldSlice`). + + Their `fieldIndex` parameter has been replaced by a `dynamicFieldIndex` parameter, which is the index relative to the first dynamic field (i.e. `dynamicFieldIndex` = `fieldIndex` - `numStaticFields`). + The `FieldLayout` parameter has been removed, as it was only used to calculate the `dynamicFieldIndex` in the method. + + ```diff + interface IStore { + - function pushToField( + + function pushToDynamicField( + ResourceId tableId, + bytes32[] calldata keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + bytes calldata dataToPush, + - FieldLayout fieldLayout + ) external; + + - function popFromField( + + function popFromDynamicField( + ResourceId tableId, + bytes32[] calldata keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + uint256 byteLengthToPop, + - FieldLayout fieldLayout + ) external; + + - function getFieldSlice( + + function getDynamicFieldSlice( + ResourceId tableId, + bytes32[] memory keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + - FieldLayout fieldLayout, + uint256 start, + uint256 end + ) external view returns (bytes memory data); + } + ``` + + - `IStore` has a new `getDynamicFieldLength` length method, which returns the byte length of the given dynamic field and doesn't require the `FieldLayout`. + + ```diff + IStore { + + function getDynamicFieldLength( + + ResourceId tableId, + + bytes32[] memory keyTuple, + + uint8 dynamicFieldIndex + + ) external view returns (uint256); + } + + ``` + + - `IStore` now has additional overloads for `getRecord`, `getField`, `getFieldLength` and `setField` that don't require a `FieldLength` to be passed, but instead load it from storage. + - `IStore` now exposes `setStaticField` and `setDynamicField` to save gas by avoiding the dynamic inference of whether the field is static or dynamic. + - The `getDynamicFieldSlice` method no longer accepts reading outside the bounds of the dynamic field. + This is to avoid returning invalid data, as the data of a dynamic field is not deleted when the record is deleted, but only its length is set to zero. + +- 331f0d636: Deprecate `@latticexyz/std-client` and remove v1 network dependencies. + + - `getBurnerWallet` is replaced by `getBurnerPrivateKey` from `@latticexyz/common`. It now returns a `Hex` string instead of an `rxjs` `BehaviorSubject`. + + ``` + - import { getBurnerWallet } from "@latticexyz/std-client"; + + import { getBurnerPrivateKey } from "@latticexyz/common"; + + - const privateKey = getBurnerWallet().value; + - const privateKey = getBurnerPrivateKey(); + ``` + + - All functions from `std-client` that depended on v1 network code are removed (most notably `setupMUDNetwork` and `setupMUDV2Network`). Consumers should upgrade to v2 networking code from `@latticexyz/store-sync`. + - The following functions are removed from `std-client` because they are very use-case specific and depend on deprecated code: `getCurrentTurn`, `getTurnAtTime`, `getGameConfig`, `isUntraversable`, `getPlayerEntity`, `resolveRelationshipChain`, `findEntityWithComponentInRelationshipChain`, `findInRelationshipChain`. Consumers should vendor these functions if they are still needed. + - Remaining exports from `std-client` are moved to `/deprecated`. The package will be removed in a future release (once there are replacements for the deprecated exports). + + ```diff + - import { ... } from "@latticexyz/std-client"; + + import { ... } from "@latticexyz/std-client/deprecated"; + ``` + +### Patch Changes + +- a35c05ea9: Table libraries now hardcode the `bytes32` table ID value rather than computing it in Solidity. This saves a bit of gas across all storage operations. +- 16b13ea8f: Adds viem workaround for zero base fee used by MUD's anvil config +- 82693072: `waitForIdle` now falls back to `setTimeout` for environments without `requestIdleCallback`. +- d5c0682fb: Updated all human-readable resource IDs to use `{namespace}__{name}` for consistency with world function signatures. +- 01e46d99: Removed some unused files, namely `curry` in `@latticexyz/common` and `useDeprecatedComputedValue` from `@latticexyz/react`. +- bb6ada740: Initial sync from indexer no longer blocks the promise returning from `createStoreSync`, `syncToRecs`, and `syncToSqlite`. This should help with rendering loading screens using the `SyncProgress` RECS component and avoid the long flashes of no content in templates. + + By default, `syncToRecs` and `syncToSqlite` will start syncing (via observable subscription) immediately after called. + + If your app needs to control when syncing starts, you can use the `startSync: false` option and then `blockStoreOperations$.subscribe()` to start the sync yourself. Just be sure to unsubscribe to avoid memory leaks. + + ```ts + const { blockStorageOperations$ } = syncToRecs({ + ... + startSync: false, + }); + + // start sync manually by subscribing to `blockStorageOperation# Change Log + const subcription = blockStorageOperation$.subscribe(); + + // clean up subscription + subscription.unsubscribe(); + ``` + +- 35c9f33df: - Remove need for tx queue in `createContract` +- 0b8ce3f2c: Minor fix to resolving user types: `solc` doesn't like relative imports without `./`, but is fine with relative imports from `./../`, so we always append `./` to the relative path. +- 933b54b5f: The benchmark util now logs to `stdout` instead of `stderr`. +- 307abab3: `resourceToLabel` now correctly returns just the resource name if its in the root namespace. +- aacffcb59: Pinned prettier-plugin-solidity version to 1.1.3 +- f99e88987: Bump viem to 1.14.0 and abitype to 0.9.8 +- e34d1170: Moved the transaction simulation step to just before sending the transaction in our transaction queue actions (`sendTransaction` and `writeContract`). + + This helps avoid cascading transaction failures for deep queues or when a transaction succeeding depends on the value of the previous. + +- db314a74: Upgraded prettier version to 3.2.5 and prettier-plugin-solidity version to 1.3.1. +- 8d51a0348: Clean up Memory.sol, make mcopy pure +- c162ad5a5: Prevented errors not included in the contract (but present in the file) from being included in the interface by `contractToInterface` +- f62c767e7: Moved some codegen to use `fs/promises` for better parallelism. +- 590542030: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages. +- b8a6158d6: bump viem to 1.6.0 +- 5d737cf2e: Updated the `debug` util to pipe to `stdout` and added an additional util to explicitly pipe to `stderr` when needed. +- 3e057061d: Removed chalk usage from modules imported in client fix downstream client builds (vite in particular). +- 535229984: - bump to viem 1.3.0 and abitype 0.9.3 + - move `@wagmi/chains` imports to `viem/chains` + - refine a few types +- 24a6cd536: Changed the `userTypes` property to accept `{ filePath: string, internalType: SchemaAbiType }` to enable strong type inference from the config. +- 25086be5f: Replaced temporary `.mudtest` file in favor of `WORLD_ADDRESS` environment variable when running tests with `MudTest` contract +- c4f49240d: Table libraries now correctly handle uninitialized fixed length arrays. +- cc2c8da00: - Refactor tightcoder to use typescript functions instead of ejs + - Optimize `TightCoder` library + - Add `isLeftAligned` and `getLeftPaddingBits` common codegen helpers +- Updated dependencies [aabd30767] +- Updated dependencies [b38c096d] +- Updated dependencies [f99e88987] +- Updated dependencies [48909d151] +- Updated dependencies [b02f9d0e4] +- Updated dependencies [bb91edaa0] +- Updated dependencies [590542030] +- Updated dependencies [f03531d97] +- Updated dependencies [b8a6158d6] +- Updated dependencies [92de59982] +- Updated dependencies [535229984] +- Updated dependencies [d7b1c588a] + - @latticexyz/schema-type@2.0.0 + ## 2.0.0-next.18 ### Major Changes diff --git a/packages/common/package.json b/packages/common/package.json index 06bcc71707..299b3770fc 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -1,6 +1,6 @@ { "name": "@latticexyz/common", - "version": "2.0.0-next.18", + "version": "2.0.0", "description": "Common low level logic shared between packages", "repository": { "type": "git", diff --git a/packages/config/CHANGELOG.md b/packages/config/CHANGELOG.md index 0a16a99128..3597dd2996 100644 --- a/packages/config/CHANGELOG.md +++ b/packages/config/CHANGELOG.md @@ -1,5 +1,156 @@ # Change Log +## 2.0.0 + +### Major Changes + +- 5e723b90e: - `ResourceSelector` is replaced with `ResourceId`, `ResourceIdLib`, `ResourceIdInstance`, `WorldResourceIdLib` and `WorldResourceIdInstance`. + + Previously a "resource selector" was a `bytes32` value with the first 16 bytes reserved for the resource's namespace, and the last 16 bytes reserved for the resource's name. + Now a "resource ID" is a `bytes32` value with the first 2 bytes reserved for the resource type, the next 14 bytes reserved for the resource's namespace, and the last 16 bytes reserved for the resource's name. + + Previously `ResouceSelector` was a library and the resource selector type was a plain `bytes32`. + Now `ResourceId` is a user type, and the functionality is implemented in the `ResourceIdInstance` (for type) and `WorldResourceIdInstance` (for namespace and name) libraries. + We split the logic into two libraries, because `Store` now also uses `ResourceId` and needs to be aware of resource types, but not of namespaces/names. + + ```diff + - import { ResourceSelector } from "@latticexyz/world/src/ResourceSelector.sol"; + + import { ResourceId, ResourceIdInstance } from "@latticexyz/store/src/ResourceId.sol"; + + import { WorldResourceIdLib, WorldResourceIdInstance } from "@latticexyz/world/src/WorldResourceId.sol"; + + import { RESOURCE_SYSTEM } from "@latticexyz/world/src/worldResourceTypes.sol"; + + - bytes32 systemId = ResourceSelector.from("namespace", "name"); + + ResourceId systemId = WorldResourceIdLib.encode(RESOURCE_SYSTEM, "namespace", "name"); + + - using ResourceSelector for bytes32; + + using WorldResourceIdInstance for ResourceId; + + using ResourceIdInstance for ResourceId; + + systemId.getName(); + systemId.getNamespace(); + + systemId.getType(); + + ``` + + - All `Store` and `World` methods now use the `ResourceId` type for `tableId`, `systemId`, `moduleId` and `namespaceId`. + All mentions of `resourceSelector` were renamed to `resourceId` or the more specific type (e.g. `tableId`, `systemId`) + + ```diff + import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; + + IStore { + function setRecord( + - bytes32 tableId, + + ResourceId tableId, + bytes32[] calldata keyTuple, + bytes calldata staticData, + PackedCounter encodedLengths, + bytes calldata dynamicData, + FieldLayout fieldLayout + ) external; + + // Same for all other methods + } + ``` + + ```diff + import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; + + IBaseWorld { + function callFrom( + address delegator, + - bytes32 resourceSelector, + + ResourceId systemId, + bytes memory callData + ) external payable returns (bytes memory); + + // Same for all other methods + } + ``` + +### Minor Changes + +- d7b1c588a: Upgraded all packages and templates to viem v2.7.12 and abitype v1.0.0. + + Some viem APIs have changed and we've updated `getContract` to reflect those changes and keep it aligned with viem. It's one small code change: + + ```diff + const worldContract = getContract({ + address: worldAddress, + abi: IWorldAbi, + - publicClient, + - walletClient, + + client: { public: publicClient, wallet: walletClient }, + }); + ``` + +### Patch Changes + +- 590542030: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages. +- 3e057061d: Removed chalk usage from modules imported in client fix downstream client builds (vite in particular). +- Updated dependencies [a35c05ea9] +- Updated dependencies [16b13ea8f] +- Updated dependencies [82693072] +- Updated dependencies [aabd30767] +- Updated dependencies [65c9546c4] +- Updated dependencies [d5c0682fb] +- Updated dependencies [01e46d99] +- Updated dependencies [331dbfdcb] +- Updated dependencies [44236041f] +- Updated dependencies [066056154] +- Updated dependencies [3fb9ce283] +- Updated dependencies [bb6ada740] +- Updated dependencies [35c9f33df] +- Updated dependencies [0b8ce3f2c] +- Updated dependencies [933b54b5f] +- Updated dependencies [307abab3] +- Updated dependencies [aacffcb59] +- Updated dependencies [b38c096d] +- Updated dependencies [f99e88987] +- Updated dependencies [939916bcd] +- Updated dependencies [e34d1170] +- Updated dependencies [b8a6158d6] +- Updated dependencies [db314a74] +- Updated dependencies [59267655] +- Updated dependencies [8d51a0348] +- Updated dependencies [c162ad5a5] +- Updated dependencies [48909d151] +- Updated dependencies [b02f9d0e4] +- Updated dependencies [f62c767e7] +- Updated dependencies [bb91edaa0] +- Updated dependencies [590542030] +- Updated dependencies [1b5eb0d07] +- Updated dependencies [44a5432ac] +- Updated dependencies [f03531d97] +- Updated dependencies [b8a6158d6] +- Updated dependencies [5d737cf2e] +- Updated dependencies [d075f82f3] +- Updated dependencies [331dbfdcb] +- Updated dependencies [92de59982] +- Updated dependencies [bfcb293d1] +- Updated dependencies [3e057061d] +- Updated dependencies [535229984] +- Updated dependencies [5e723b90e] +- Updated dependencies [0c4f9fea9] +- Updated dependencies [60cfd089f] +- Updated dependencies [24a6cd536] +- Updated dependencies [708b49c50] +- Updated dependencies [d2f8e9400] +- Updated dependencies [25086be5f] +- Updated dependencies [b1d41727d] +- Updated dependencies [4c1dcd81e] +- Updated dependencies [6071163f7] +- Updated dependencies [6c6733256] +- Updated dependencies [cd5abcc3b] +- Updated dependencies [d7b1c588a] +- Updated dependencies [c4f49240d] +- Updated dependencies [5df1f31bc] +- Updated dependencies [cea754dde] +- Updated dependencies [331f0d636] +- Updated dependencies [cc2c8da00] + - @latticexyz/common@2.0.0 + - @latticexyz/schema-type@2.0.0 + ## 2.0.0-next.18 ### Minor Changes diff --git a/packages/config/package.json b/packages/config/package.json index 62f5b05c71..16cd258076 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -1,6 +1,6 @@ { "name": "@latticexyz/config", - "version": "2.0.0-next.18", + "version": "2.0.0", "description": "Config for Store and World", "repository": { "type": "git", diff --git a/packages/create-mud/CHANGELOG.md b/packages/create-mud/CHANGELOG.md index c1ca6868c7..41488844c4 100644 --- a/packages/create-mud/CHANGELOG.md +++ b/packages/create-mud/CHANGELOG.md @@ -1,5 +1,653 @@ # Change Log +## 2.0.0 + +### Major Changes + +- 78949f2c9: Replaced the `react` template with a basic task list app using the new Zustand storage adapter and sync method. This new template better demonstrates the different ways of building with MUD and has fewer concepts to learn (i.e. just tables and records, no more ECS). + + For ECS-based React apps, you can use `react-ecs` template for the previous RECS storage adapter. + +- 48c51b52a: RECS components are now dynamically created and inferred from your MUD config when using `syncToRecs`. + + To migrate existing projects after upgrading to this MUD version: + + 1. Remove `contractComponents.ts` from `client/src/mud` + 2. Remove `components` argument from `syncToRecs` + 3. Update `build:mud` and `dev` scripts in `contracts/package.json` to remove tsgen + + ```diff + - "build:mud": "mud tablegen && mud worldgen && mud tsgen --configPath mud.config.ts --out ../client/src/mud", + + "build:mud": "mud tablegen && mud worldgen", + ``` + + ```diff + - "dev": "pnpm mud dev-contracts --tsgenOutput ../client/src/mud", + + "dev": "pnpm mud dev-contracts", + ``` + +- 939916bcd: MUD dev tools is updated to latest sync stack. You must now pass in all of its data requirements rather than relying on magic globals. + + ```diff + import { mount as mountDevTools } from "@latticexyz/dev-tools"; + + - mountDevTools(); + + mountDevTools({ + + config, + + publicClient, + + walletClient, + + latestBlock$, + + blockStorageOperations$, + + worldAddress, + + worldAbi, + + write$, + + // if you're using recs + + recsWorld, + + }); + ``` + + It's also advised to wrap dev tools so that it is only mounted during development mode. Here's how you do this with Vite: + + ```ts + // https://vitejs.dev/guide/env-and-mode.html + if (import.meta.env.DEV) { + mountDevTools({ ... }); + } + ``` + +- 60cfd089f: Templates and examples now use MUD's new sync packages, all built on top of [viem](https://viem.sh/). This greatly speeds up and stabilizes our networking code and improves types throughout. + + These new sync packages come with support for our `recs` package, including `encodeEntity` and `decodeEntity` utilities for composite keys. + + If you're using `store-cache` and `useRow`/`useRows`, you should wait to upgrade until we have a suitable replacement for those libraries. We're working on a [sql.js](https://github.com/sql-js/sql.js/)-powered sync module that will replace `store-cache`. + + **Migrate existing RECS apps to new sync packages** + + As you migrate, you may find some features replaced, removed, or not included by default. Please [open an issue](https://github.com/latticexyz/mud/issues/new) and let us know if we missed anything. + + 1. Add `@latticexyz/store-sync` package to your app's `client` package and make sure `viem` is pinned to version `1.3.1` (otherwise you may get type errors) + 2. In your `supportedChains.ts`, replace `foundry` chain with our new `mudFoundry` chain. + + ```diff + - import { foundry } from "viem/chains"; + - import { MUDChain, latticeTestnet } from "@latticexyz/common/chains"; + + import { MUDChain, latticeTestnet, mudFoundry } from "@latticexyz/common/chains"; + + - export const supportedChains: MUDChain[] = [foundry, latticeTestnet]; + + export const supportedChains: MUDChain[] = [mudFoundry, latticeTestnet]; + ``` + + 3. In `getNetworkConfig.ts`, remove the return type (to let TS infer it for now), remove now-unused config values, and add the viem `chain` object. + + ```diff + - export async function getNetworkConfig(): Promise { + + export async function getNetworkConfig() { + ``` + + ```diff + const initialBlockNumber = params.has("initialBlockNumber") + ? Number(params.get("initialBlockNumber")) + - : world?.blockNumber ?? -1; // -1 will attempt to find the block number from RPC + + : world?.blockNumber ?? 0n; + ``` + + ```diff + + return { + + privateKey: getBurnerWallet().value, + + chain, + + worldAddress, + + initialBlockNumber, + + faucetServiceUrl: params.get("faucet") ?? chain.faucetUrl, + + }; + ``` + + 4. In `setupNetwork.ts`, replace `setupMUDV2Network` with `syncToRecs`. + + ```diff + - import { setupMUDV2Network } from "@latticexyz/std-client"; + - import { createFastTxExecutor, createFaucetService, getSnapSyncRecords } from "@latticexyz/network"; + + import { createFaucetService } from "@latticexyz/network"; + + import { createPublicClient, fallback, webSocket, http, createWalletClient, getContract, Hex, parseEther, ClientConfig } from "viem"; + + import { encodeEntity, syncToRecs } from "@latticexyz/store-sync/recs"; + + import { createBurnerAccount, createContract, transportObserver } from "@latticexyz/common"; + ``` + + ```diff + - const result = await setupMUDV2Network({ + - ... + - }); + + + const clientOptions = { + + chain: networkConfig.chain, + + transport: transportObserver(fallback([webSocket(), http()])), + + pollingInterval: 1000, + + } as const satisfies ClientConfig; + + + const publicClient = createPublicClient(clientOptions); + + + const burnerAccount = createBurnerAccount(networkConfig.privateKey as Hex); + + const burnerWalletClient = createWalletClient({ + + ...clientOptions, + + account: burnerAccount, + + }); + + + const { components, latestBlock$, blockStorageOperations$, waitForTransaction } = await syncToRecs({ + + world, + + config: storeConfig, + + address: networkConfig.worldAddress as Hex, + + publicClient, + + components: contractComponents, + + startBlock: BigInt(networkConfig.initialBlockNumber), + + indexerUrl: networkConfig.indexerUrl ?? undefined, + + }); + + + const worldContract = createContract({ + + address: networkConfig.worldAddress as Hex, + + abi: IWorld__factory.abi, + + publicClient, + + walletClient: burnerWalletClient, + + }); + ``` + + ```diff + // Request drip from faucet + - const signer = result.network.signer.get(); + - if (networkConfig.faucetServiceUrl && signer) { + - const address = await signer.getAddress(); + + if (networkConfig.faucetServiceUrl) { + + const address = burnerAccount.address; + ``` + + ```diff + const requestDrip = async () => { + - const balance = await signer.getBalance(); + + const balance = await publicClient.getBalance({ address }); + console.info(`[Dev Faucet]: Player balance -> ${balance}`); + - const lowBalance = balance?.lte(utils.parseEther("1")); + + const lowBalance = balance < parseEther("1"); + ``` + + You can remove the previous ethers `worldContract`, snap sync code, and fast transaction executor. + + The return of `setupNetwork` is a bit different than before, so you may have to do corresponding app changes. + + ```diff + + return { + + world, + + components, + + playerEntity: encodeEntity({ address: "address" }, { address: burnerWalletClient.account.address }), + + publicClient, + + walletClient: burnerWalletClient, + + latestBlock$, + + blockStorageOperations$, + + waitForTransaction, + + worldContract, + + }; + ``` + + 5. Update `createSystemCalls` with the new return type of `setupNetwork`. + + ```diff + export function createSystemCalls( + - { worldSend, txReduced$, singletonEntity }: SetupNetworkResult, + + { worldContract, waitForTransaction }: SetupNetworkResult, + { Counter }: ClientComponents + ) { + const increment = async () => { + - const tx = await worldSend("increment", []); + - await awaitStreamValue(txReduced$, (txHash) => txHash === tx.hash); + + const tx = await worldContract.write.increment(); + + await waitForTransaction(tx); + return getComponentValue(Counter, singletonEntity); + }; + ``` + + 6. (optional) If you still need a clock, you can create it with: + + ```ts + import { map, filter } from "rxjs"; + import { createClock } from "@latticexyz/network"; + + const clock = createClock({ + period: 1000, + initialTime: 0, + syncInterval: 5000, + }); + + world.registerDisposer(() => clock.dispose()); + + latestBlock$ + .pipe( + map((block) => Number(block.timestamp) * 1000), // Map to timestamp in ms + filter((blockTimestamp) => blockTimestamp !== clock.lastUpdateTime), // Ignore if the clock was already refreshed with this block + filter((blockTimestamp) => blockTimestamp !== clock.currentTime), // Ignore if the current local timestamp is correct + ) + .subscribe(clock.update); // Update the local clock + ``` + + If you're using the previous `LoadingState` component, you'll want to migrate to the new `SyncProgress`: + + ```ts + import { SyncStep, singletonEntity } from "@latticexyz/store-sync/recs"; + + const syncProgress = useComponentValue(SyncProgress, singletonEntity, { + message: "Connecting", + percentage: 0, + step: SyncStep.INITIALIZE, + }); + + if (syncProgress.step === SyncStep.LIVE) { + // we're live! + } + ``` + +- 252a1852: Migrated to new config format. + +### Minor Changes + +- 6288f9033: Updated templates to use [mprocs](https://github.com/pvolok/mprocs) instead of [concurrently](https://github.com/open-cli-tools/concurrently) for running dev scripts. +- 07dd6f32c: Renamed all occurrences of `schema` where it is used as "value schema" to `valueSchema` to clearly distinguish it from "key schema". + The only breaking change for users is the change from `schema` to `valueSchema` in `mud.config.ts`. + + ```diff + // mud.config.ts + export default mudConfig({ + tables: { + CounterTable: { + keySchema: {}, + - schema: { + + valueSchema: { + value: "uint32", + }, + }, + } + } + ``` + +- aabd30767: Bumped Solidity version to 0.8.24. +- f6133591a: Replaced usage of `window` global in vanilla JS template with an event listener on the button. +- b68e1699b: Enabled MUD CLI debug logs for all templates. +- 83583a505: Templates now use `out` for their `forge build` artifacts, including ABIs. If you have a project created from a previous template, you can update your `packages/contracts/package.json` with: + + ```diff + - "build:abi": "rimraf abi && forge build --extra-output-files abi --out abi --skip test script MudTest.sol", + - "build:abi-ts": "mud abi-ts --input 'abi/IWorld.sol/IWorld.abi.json' && prettier --write '**/*.abi.json.d.ts'", + + "build:abi": "forge clean && forge build --skip test script", + + "build:abi-ts": "mud abi-ts && prettier --write '**/*.abi.json.d.ts'", + ``` + + And your `packages/client/src/mud/setupNetwork` with: + + ```diff + - import IWorldAbi from "contracts/abi/IWorld.sol/IWorld.abi.json"; + + import IWorldAbi from "contracts/out/IWorld.sol/IWorld.abi.json"; + ``` + +- 59267655: Added viem custom client actions that work the same as MUD's now-deprecated `getContract`, `writeContract`, and `sendTransaction` wrappers. Templates have been updated to reflect the new patterns. + + You can migrate your own code like this: + + ```diff + -import { createWalletClient } from "viem"; + -import { getContract, writeContract, sendTransaction } from "@latticexyz/common"; + +import { createWalletClient, getContract } from "viem"; + +import { transactionQueue, writeObserver } from "@latticexyz/common/actions"; + + -const walletClient = createWalletClient(...); + +const walletClient = createWalletClient(...) + + .extend(transactionQueue()) + + .extend(writeObserver({ onWrite }); + + const worldContract = getContract({ + client: { publicClient, walletClient }, + - onWrite, + }); + ``` + +- 1faf7f697: Added Zustand support to Dev Tools: + + ```ts + const { syncToZustand } from "@latticexyz/store-sync"; + const { mount as mountDevTools } from "@latticexyz/dev-tools"; + + const { useStore } = syncToZustand({ ... }); + + mountDevTools({ + ... + useStore, + }); + ``` + +- 92de59982: Bump Solidity version to 0.8.21 +- 331dbfdcb: We've updated Store events to be "schemaless", meaning there is enough information in each event to only need to operate on the bytes of each record to make an update to that record without having to first decode the record by its schema. This enables new kinds of indexers and sync strategies. + + As such, we've replaced `blockStorageOperations# Change Log with `storedBlockLogs# Change Log, a stream of simplified Store event logs after they've been synced to the configured storage adapter. These logs may not reflect exactly the events that are on chain when e.g. hydrating from an indexer, but they will still allow the client to "catch up" to the on-chain state of your tables. + +- 55377ffe6: We now use `@latticexyz/abi-ts` to generate TS type declaration files (`.d.ts`) for each ABI JSON file. This replaces our usage TypeChain everywhere. + + If you have a MUD project created from an older template, you can replace TypeChain with `abi-ts` by first updating your contracts' `package.json`: + + ```diff + -"build": "pnpm run build:mud && pnpm run build:abi && pnpm run build:typechain", + +"build": "pnpm run build:mud && pnpm run build:abi && pnpm run build:abi-ts", + -"build:abi": "forge clean && forge build", + +"build:abi": "rimraf abi && forge build --extra-output-files abi --out abi --skip test script MudTest.sol", + +"build:abi-ts": "mud abi-ts --input 'abi/IWorld.sol/IWorld.abi.json' && prettier --write '**/*.abi.json.d.ts'", + "build:mud": "mud tablegen && mud worldgen", + -"build:typechain": "rimraf types && typechain --target=ethers-v5 out/IWorld.sol/IWorld.json", + ``` + + And update your client's `setupNetwork.ts` with: + + ```diff + -import { IWorld__factory } from "contracts/types/ethers-contracts/factories/IWorld__factory"; + +import IWorldAbi from "contracts/abi/IWorld.sol/IWorld.abi.json"; + + const worldContract = createContract({ + address: networkConfig.worldAddress as Hex, + - abi: IWorld__factory.abi, + + abi: IWorldAbi, + ``` + +- bfcb293d1: What used to be known as `ephemeral` table is now called `offchain` table. + The previous `ephemeral` tables only supported an `emitEphemeral` method, which emitted a `StoreSetEphemeralRecord` event. + + Now `offchain` tables support all regular table methods, except partial operations on dynamic fields (`push`, `pop`, `update`). + Unlike regular tables they don't store data on-chain but emit the same events as regular tables (`StoreSetRecord`, `StoreSpliceStaticData`, `StoreDeleteRecord`), so their data can be indexed by offchain indexers/clients. + + ```diff + - EphemeralTable.emitEphemeral(value); + + OffchainTable.set(value); + ``` + +- d7b1c588a: Upgraded all packages and templates to viem v2.7.12 and abitype v1.0.0. + + Some viem APIs have changed and we've updated `getContract` to reflect those changes and keep it aligned with viem. It's one small code change: + + ```diff + const worldContract = getContract({ + address: worldAddress, + abi: IWorldAbi, + - publicClient, + - walletClient, + + client: { public: publicClient, wallet: walletClient }, + }); + ``` + +### Patch Changes + +- 7ce82b6fc: Store config now defaults `storeArgument: false` for all tables. This means that table libraries, by default, will no longer include the extra functions with the `_store` argument. This default was changed to clear up the confusion around using table libraries in tests, `PostDeploy` scripts, etc. + + If you are sure you need to manually specify a store when interacting with tables, you can still manually toggle it back on with `storeArgument: true` in the table settings of your MUD config. + + If you want to use table libraries in `PostDeploy.s.sol`, you can add the following lines: + + ```diff + import { Script } from "forge-std/Script.sol"; + import { console } from "forge-std/console.sol"; + import { IWorld } from "../src/codegen/world/IWorld.sol"; + + import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; + + contract PostDeploy is Script { + function run(address worldAddress) external { + + StoreSwitch.setStoreAddress(worldAddress); + + + + SomeTable.get(someKey); + ``` + +- a35c05ea9: Table libraries now hardcode the `bytes32` table ID value rather than computing it in Solidity. This saves a bit of gas across all storage operations. +- 44236041f: Moved table ID and field layout constants in code-generated table libraries from the file level into the library, for clearer access and cleaner imports. + + ```diff + -import { SomeTable, SomeTableTableId } from "./codegen/tables/SomeTable.sol"; + +import { SomeTable } from "./codegen/tables/SomeTable.sol"; + + -console.log(SomeTableTableId); + +console.log(SomeTable._tableId); + + -console.log(SomeTable.getFieldLayout()); + +console.log(SomeTable._fieldLayout); + ``` + +- 952cd5344: All `Store` methods now require the table's value schema to be passed in as an argument instead of loading it from storage. + This decreases gas cost and removes circular dependencies of the Schema table (where it was not possible to write to the Schema table before the Schema table was registered). + + ```diff + function setRecord( + bytes32 table, + bytes32[] calldata key, + bytes calldata data, + + Schema valueSchema + ) external; + ``` + + The same diff applies to `getRecord`, `getField`, `setField`, `pushToField`, `popFromField`, `updateInField`, and `deleteRecord`. + + This change only requires changes in downstream projects if the `Store` methods were accessed directly. In most cases it is fully abstracted in the generated table libraries, + so downstream projects only need to regenerate their table libraries after updating MUD. + +- c5148da76: Updated templates' PostDeploy script to set store address so that tables can be used directly inside PostDeploy. +- 257a0afc: Bumped `typescript` to `5.4.2`, `eslint` to `8.57.0`, and both `@typescript-eslint/eslint-plugin` and `@typescript-eslint/parser` to `7.1.1`. +- aacffcb59: Pinned prettier-plugin-solidity version to 1.1.3 +- f99e88987: Bump viem to 1.14.0 and abitype to 0.9.8 +- 6963a9e85: Templates now correctly include their respective `.gitignore` files +- afaf2f5ff: - `Store`'s internal schema table is now a normal table instead of using special code paths. It is renamed to Tables, and the table ID changed from `mudstore:schema` to `mudstore:Tables` + + - `Store`'s `registerSchema` and `setMetadata` are combined into a single `registerTable` method. This means metadata (key names, field names) is immutable and indexers can create tables with this metadata when a new table is registered on-chain. + + ```diff + - function registerSchema(bytes32 table, Schema schema, Schema keySchema) external; + - + - function setMetadata(bytes32 table, string calldata tableName, string[] calldata fieldNames) external; + + + function registerTable( + + bytes32 table, + + Schema keySchema, + + Schema valueSchema, + + string[] calldata keyNames, + + string[] calldata fieldNames + + ) external; + ``` + + - `World`'s `registerTable` method is updated to match the `Store` interface, `setMetadata` is removed + - The `getSchema` method is renamed to `getValueSchema` on all interfaces + ```diff + - function getSchema(bytes32 table) external view returns (Schema schema); + + function getValueSchema(bytes32 table) external view returns (Schema valueSchema); + ``` + - The `store-sync` and `cli` packages are updated to integrate the breaking protocol changes. Downstream projects only need to manually integrate these changes if they access low level `Store` or `World` functions. Otherwise, a fresh deploy with the latest MUD will get you these changes. + +- 48909d151: bump forge-std and ds-test dependencies +- 1b33a915c: Fixed an issue when creating a new project from the `react` app, where React's expressions were overlapping with Handlebars expressions (used by our template command). +- b8a6158d6: bump viem to 1.6.0 +- 5237e320: Added `dbaeumer.vscode-eslint` and `esbenp.prettier-vscode` to recommended VSCode extensions. +- 331f0d636: Move `createFaucetService` from `@latticexyz/network` to `@latticexyz/services/faucet`. + + ```diff + - import { createFaucetService } from "@latticexyz/network"; + + import { createFaucetService } from "@latticexyz/services/faucet"; + ``` + +- ac508bf18: Renamed the default filename of generated user types from `Types.sol` to `common.sol` and the default filename of the generated table index file from `Tables.sol` to `index.sol`. + + Both can be overridden via the MUD config: + + ```ts + export default mudConfig({ + /** Filename where common user types will be generated and imported from. */ + userTypesFilename: "common.sol", + /** Filename where codegen index will be generated. */ + codegenIndexFilename: "index.sol", + }); + ``` + + Note: `userTypesFilename` was renamed from `userTypesPath` and `.sol` is not appended automatically anymore but needs to be part of the provided filename. + + To update your existing project, update all imports from `Tables.sol` to `index.sol` and all imports from `Types.sol` to `common.sol`, or override the defaults in your MUD config to the previous values. + + ```diff + - import { Counter } from "../src/codegen/Tables.sol"; + + import { Counter } from "../src/codegen/index.sol"; + - import { ExampleEnum } from "../src/codegen/Types.sol"; + + import { ExampleEnum } from "../src/codegen/common.sol"; + ``` + +- d844cd441: Sped up builds by using more of forge's cache. + + Previously we'd build only what we needed because we would check in ABIs and other build artifacts into git, but that meant that we'd get a lot of forge cache misses. Now that we no longer need these files visible, we can take advantage of forge's caching and greatly speed up builds, especially incremental ones. + +- 4e4a34150: bump to latest TS version (5.1.6) +- 535229984: - bump to viem 1.3.0 and abitype 0.9.3 + - move `@wagmi/chains` imports to `viem/chains` + - refine a few types +- 3042f86e: Moved key schema and value schema methods to constants in code-generated table libraries for less bytecode and less gas in register/install methods. + + ```diff + -console.log(SomeTable.getKeySchema()); + +console.log(SomeTable._keySchema); + + -console.log(SomeTable.getValueSchema()); + +console.log(SomeTable._valueSchema); + ``` + +- 3e7d83d0: Renamed `PackedCounter` to `EncodedLengths` for consistency. +- cea754dde: - The external `setRecord` and `deleteRecord` methods of `IStore` no longer accept a `FieldLayout` as input, but load it from storage instead. + This is to prevent invalid `FieldLayout` values being passed, which could cause the onchain state to diverge from the indexer state. + However, the internal `StoreCore` library still exposes a `setRecord` and `deleteRecord` method that allows a `FieldLayout` to be passed. + This is because `StoreCore` can only be used internally, so the `FieldLayout` value can be trusted and we can save the gas for accessing storage. + + ```diff + interface IStore { + function setRecord( + ResourceId tableId, + bytes32[] calldata keyTuple, + bytes calldata staticData, + PackedCounter encodedLengths, + bytes calldata dynamicData, + - FieldLayout fieldLayout + ) external; + + function deleteRecord( + ResourceId tableId, + bytes32[] memory keyTuple, + - FieldLayout fieldLayout + ) external; + } + ``` + + - The `spliceStaticData` method and `Store_SpliceStaticData` event of `IStore` and `StoreCore` no longer include `deleteCount` in their signature. + This is because when splicing static data, the data after `start` is always overwritten with `data` instead of being shifted, so `deleteCount` is always the length of the data to be written. + + ```diff + + event Store_SpliceStaticData( + ResourceId indexed tableId, + bytes32[] keyTuple, + uint48 start, + - uint40 deleteCount, + bytes data + ); + + interface IStore { + function spliceStaticData( + ResourceId tableId, + bytes32[] calldata keyTuple, + uint48 start, + - uint40 deleteCount, + bytes calldata data + ) external; + } + ``` + + - The `updateInField` method has been removed from `IStore`, as it's almost identical to the more general `spliceDynamicData`. + If you're manually calling `updateInField`, here is how to upgrade to `spliceDynamicData`: + + ```diff + - store.updateInField(tableId, keyTuple, fieldIndex, startByteIndex, dataToSet, fieldLayout); + + uint8 dynamicFieldIndex = fieldIndex - fieldLayout.numStaticFields(); + + store.spliceDynamicData(tableId, keyTuple, dynamicFieldIndex, uint40(startByteIndex), uint40(dataToSet.length), dataToSet); + ``` + + - All other methods that are only valid for dynamic fields (`pushToField`, `popFromField`, `getFieldSlice`) + have been renamed to make this more explicit (`pushToDynamicField`, `popFromDynamicField`, `getDynamicFieldSlice`). + + Their `fieldIndex` parameter has been replaced by a `dynamicFieldIndex` parameter, which is the index relative to the first dynamic field (i.e. `dynamicFieldIndex` = `fieldIndex` - `numStaticFields`). + The `FieldLayout` parameter has been removed, as it was only used to calculate the `dynamicFieldIndex` in the method. + + ```diff + interface IStore { + - function pushToField( + + function pushToDynamicField( + ResourceId tableId, + bytes32[] calldata keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + bytes calldata dataToPush, + - FieldLayout fieldLayout + ) external; + + - function popFromField( + + function popFromDynamicField( + ResourceId tableId, + bytes32[] calldata keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + uint256 byteLengthToPop, + - FieldLayout fieldLayout + ) external; + + - function getFieldSlice( + + function getDynamicFieldSlice( + ResourceId tableId, + bytes32[] memory keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + - FieldLayout fieldLayout, + uint256 start, + uint256 end + ) external view returns (bytes memory data); + } + ``` + + - `IStore` has a new `getDynamicFieldLength` length method, which returns the byte length of the given dynamic field and doesn't require the `FieldLayout`. + + ```diff + IStore { + + function getDynamicFieldLength( + + ResourceId tableId, + + bytes32[] memory keyTuple, + + uint8 dynamicFieldIndex + + ) external view returns (uint256); + } + + ``` + + - `IStore` now has additional overloads for `getRecord`, `getField`, `getFieldLength` and `setField` that don't require a `FieldLength` to be passed, but instead load it from storage. + - `IStore` now exposes `setStaticField` and `setDynamicField` to save gas by avoiding the dynamic inference of whether the field is static or dynamic. + - The `getDynamicFieldSlice` method no longer accepts reading outside the bounds of the dynamic field. + This is to avoid returning invalid data, as the data of a dynamic field is not deleted when the record is deleted, but only its length is set to zero. + +- 331f0d636: Deprecate `@latticexyz/std-client` and remove v1 network dependencies. + + - `getBurnerWallet` is replaced by `getBurnerPrivateKey` from `@latticexyz/common`. It now returns a `Hex` string instead of an `rxjs` `BehaviorSubject`. + + ``` + - import { getBurnerWallet } from "@latticexyz/std-client"; + + import { getBurnerPrivateKey } from "@latticexyz/common"; + + - const privateKey = getBurnerWallet().value; + - const privateKey = getBurnerPrivateKey(); + ``` + + - All functions from `std-client` that depended on v1 network code are removed (most notably `setupMUDNetwork` and `setupMUDV2Network`). Consumers should upgrade to v2 networking code from `@latticexyz/store-sync`. + - The following functions are removed from `std-client` because they are very use-case specific and depend on deprecated code: `getCurrentTurn`, `getTurnAtTime`, `getGameConfig`, `isUntraversable`, `getPlayerEntity`, `resolveRelationshipChain`, `findEntityWithComponentInRelationshipChain`, `findInRelationshipChain`. Consumers should vendor these functions if they are still needed. + - Remaining exports from `std-client` are moved to `/deprecated`. The package will be removed in a future release (once there are replacements for the deprecated exports). + + ```diff + - import { ... } from "@latticexyz/std-client"; + + import { ... } from "@latticexyz/std-client/deprecated"; + ``` + ## 2.0.0-next.18 ### Major Changes diff --git a/packages/create-mud/package.json b/packages/create-mud/package.json index 9ada86701c..1e1ec00d15 100644 --- a/packages/create-mud/package.json +++ b/packages/create-mud/package.json @@ -1,6 +1,6 @@ { "name": "create-mud", - "version": "2.0.0-next.18", + "version": "2.0.0", "description": "Create a new MUD project", "license": "MIT", "author": "Lattice ", diff --git a/packages/dev-tools/CHANGELOG.md b/packages/dev-tools/CHANGELOG.md index 30416f499f..d664969723 100644 --- a/packages/dev-tools/CHANGELOG.md +++ b/packages/dev-tools/CHANGELOG.md @@ -1,5 +1,527 @@ # @latticexyz/dev-tools +## 2.0.0 + +### Major Changes + +- 331dbfdcb: We've updated Store events to be "schemaless", meaning there is enough information in each event to only need to operate on the bytes of each record to make an update to that record without having to first decode the record by its schema. This enables new kinds of indexers and sync strategies. + + As such, we've replaced `blockStorageOperations# @latticexyz/dev-tools with `storedBlockLogs# @latticexyz/dev-tools, a stream of simplified Store event logs after they've been synced to the configured storage adapter. These logs may not reflect exactly the events that are on chain when e.g. hydrating from an indexer, but they will still allow the client to "catch up" to the on-chain state of your tables. + +- 939916bcd: MUD dev tools is updated to latest sync stack. You must now pass in all of its data requirements rather than relying on magic globals. + + ```diff + import { mount as mountDevTools } from "@latticexyz/dev-tools"; + + - mountDevTools(); + + mountDevTools({ + + config, + + publicClient, + + walletClient, + + latestBlock$, + + blockStorageOperations$, + + worldAddress, + + worldAbi, + + write$, + + // if you're using recs + + recsWorld, + + }); + ``` + + It's also advised to wrap dev tools so that it is only mounted during development mode. Here's how you do this with Vite: + + ```ts + // https://vitejs.dev/guide/env-and-mode.html + if (import.meta.env.DEV) { + mountDevTools({ ... }); + } + ``` + +- 252a1852: Migrated to new config format. + +### Minor Changes + +- 24a0dd444: Improved rendering of transactions that make calls via World's `call` and `callFrom` methods +- 1faf7f697: Added Zustand support to Dev Tools: + + ```ts + const { syncToZustand } from "@latticexyz/store-sync"; + const { mount as mountDevTools } from "@latticexyz/dev-tools"; + + const { useStore } = syncToZustand({ ... }); + + mountDevTools({ + ... + useStore, + }); + ``` + +- d7b1c588a: Upgraded all packages and templates to viem v2.7.12 and abitype v1.0.0. + + Some viem APIs have changed and we've updated `getContract` to reflect those changes and keep it aligned with viem. It's one small code change: + + ```diff + const worldContract = getContract({ + address: worldAddress, + abi: IWorldAbi, + - publicClient, + - walletClient, + + client: { public: publicClient, wallet: walletClient }, + }); + ``` + +### Patch Changes + +- d5c0682fb: Updated all human-readable resource IDs to use `{namespace}__{name}` for consistency with world function signatures. +- f99e88987: Bump viem to 1.14.0 and abitype to 0.9.8 +- 590542030: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages. +- b8a6158d6: bump viem to 1.6.0 +- e0193e573: Updates store event `key` reference to `keyTuple` +- e0377761c: Updates `table` reference to `tableId` +- bfcb293d1: What used to be known as `ephemeral` table is now called `offchain` table. + The previous `ephemeral` tables only supported an `emitEphemeral` method, which emitted a `StoreSetEphemeralRecord` event. + + Now `offchain` tables support all regular table methods, except partial operations on dynamic fields (`push`, `pop`, `update`). + Unlike regular tables they don't store data on-chain but emit the same events as regular tables (`StoreSetRecord`, `StoreSpliceStaticData`, `StoreDeleteRecord`), so their data can be indexed by offchain indexers/clients. + + ```diff + - EphemeralTable.emitEphemeral(value); + + OffchainTable.set(value); + ``` + +- 753bdce41: Store sync logic is now consolidated into a `createStoreSync` function exported from `@latticexyz/store-sync`. This simplifies each storage sync strategy to just a simple wrapper around the storage adapter. You can now sync to RECS with `syncToRecs` or SQLite with `syncToSqlite` and PostgreSQL support coming soon. + + There are no breaking changes if you were just using `syncToRecs` from `@latticexyz/store-sync` or running the `sqlite-indexer` binary from `@latticexyz/store-indexer`. + +- 5294a7d59: Improves support for internal/client-only RECS components +- 535229984: - bump to viem 1.3.0 and abitype 0.9.3 + - move `@wagmi/chains` imports to `viem/chains` + - refine a few types +- af639a264: `Store` events have been renamed for consistency and readability. + If you're parsing `Store` events manually, you need to update your ABI. + If you're using the MUD sync stack, the new events are already integrated and no further changes are necessary. + + ```diff + - event StoreSetRecord( + + event Store_SetRecord( + ResourceId indexed tableId, + bytes32[] keyTuple, + bytes staticData, + bytes32 encodedLengths, + bytes dynamicData + ); + - event StoreSpliceStaticData( + + event Store_SpliceStaticData( + ResourceId indexed tableId, + bytes32[] keyTuple, + uint48 start, + uint40 deleteCount, + bytes data + ); + - event StoreSpliceDynamicData( + + event Store_SpliceDynamicData( + ResourceId indexed tableId, + bytes32[] keyTuple, + uint48 start, + uint40 deleteCount, + bytes data, + bytes32 encodedLengths + ); + - event StoreDeleteRecord( + + event Store_DeleteRecord( + ResourceId indexed tableId, + bytes32[] keyTuple + ); + ``` + +- 6c6733256: Add `tableIdToHex` and `hexToTableId` pure functions and move/deprecate `TableId`. +- cea754dde: - The external `setRecord` and `deleteRecord` methods of `IStore` no longer accept a `FieldLayout` as input, but load it from storage instead. + This is to prevent invalid `FieldLayout` values being passed, which could cause the onchain state to diverge from the indexer state. + However, the internal `StoreCore` library still exposes a `setRecord` and `deleteRecord` method that allows a `FieldLayout` to be passed. + This is because `StoreCore` can only be used internally, so the `FieldLayout` value can be trusted and we can save the gas for accessing storage. + + ```diff + interface IStore { + function setRecord( + ResourceId tableId, + bytes32[] calldata keyTuple, + bytes calldata staticData, + PackedCounter encodedLengths, + bytes calldata dynamicData, + - FieldLayout fieldLayout + ) external; + + function deleteRecord( + ResourceId tableId, + bytes32[] memory keyTuple, + - FieldLayout fieldLayout + ) external; + } + ``` + + - The `spliceStaticData` method and `Store_SpliceStaticData` event of `IStore` and `StoreCore` no longer include `deleteCount` in their signature. + This is because when splicing static data, the data after `start` is always overwritten with `data` instead of being shifted, so `deleteCount` is always the length of the data to be written. + + ```diff + + event Store_SpliceStaticData( + ResourceId indexed tableId, + bytes32[] keyTuple, + uint48 start, + - uint40 deleteCount, + bytes data + ); + + interface IStore { + function spliceStaticData( + ResourceId tableId, + bytes32[] calldata keyTuple, + uint48 start, + - uint40 deleteCount, + bytes calldata data + ) external; + } + ``` + + - The `updateInField` method has been removed from `IStore`, as it's almost identical to the more general `spliceDynamicData`. + If you're manually calling `updateInField`, here is how to upgrade to `spliceDynamicData`: + + ```diff + - store.updateInField(tableId, keyTuple, fieldIndex, startByteIndex, dataToSet, fieldLayout); + + uint8 dynamicFieldIndex = fieldIndex - fieldLayout.numStaticFields(); + + store.spliceDynamicData(tableId, keyTuple, dynamicFieldIndex, uint40(startByteIndex), uint40(dataToSet.length), dataToSet); + ``` + + - All other methods that are only valid for dynamic fields (`pushToField`, `popFromField`, `getFieldSlice`) + have been renamed to make this more explicit (`pushToDynamicField`, `popFromDynamicField`, `getDynamicFieldSlice`). + + Their `fieldIndex` parameter has been replaced by a `dynamicFieldIndex` parameter, which is the index relative to the first dynamic field (i.e. `dynamicFieldIndex` = `fieldIndex` - `numStaticFields`). + The `FieldLayout` parameter has been removed, as it was only used to calculate the `dynamicFieldIndex` in the method. + + ```diff + interface IStore { + - function pushToField( + + function pushToDynamicField( + ResourceId tableId, + bytes32[] calldata keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + bytes calldata dataToPush, + - FieldLayout fieldLayout + ) external; + + - function popFromField( + + function popFromDynamicField( + ResourceId tableId, + bytes32[] calldata keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + uint256 byteLengthToPop, + - FieldLayout fieldLayout + ) external; + + - function getFieldSlice( + + function getDynamicFieldSlice( + ResourceId tableId, + bytes32[] memory keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + - FieldLayout fieldLayout, + uint256 start, + uint256 end + ) external view returns (bytes memory data); + } + ``` + + - `IStore` has a new `getDynamicFieldLength` length method, which returns the byte length of the given dynamic field and doesn't require the `FieldLayout`. + + ```diff + IStore { + + function getDynamicFieldLength( + + ResourceId tableId, + + bytes32[] memory keyTuple, + + uint8 dynamicFieldIndex + + ) external view returns (uint256); + } + + ``` + + - `IStore` now has additional overloads for `getRecord`, `getField`, `getFieldLength` and `setField` that don't require a `FieldLength` to be passed, but instead load it from storage. + - `IStore` now exposes `setStaticField` and `setDynamicField` to save gas by avoiding the dynamic inference of whether the field is static or dynamic. + - The `getDynamicFieldSlice` method no longer accepts reading outside the bounds of the dynamic field. + This is to avoid returning invalid data, as the data of a dynamic field is not deleted when the record is deleted, but only its length is set to zero. + +- d2f8e9400: Moved to new resource ID utils. +- Updated dependencies [7ce82b6fc] +- Updated dependencies [5df1f31bc] +- Updated dependencies [d8c8f66bf] +- Updated dependencies [c6c13f2ea] +- Updated dependencies [77dce993a] +- Updated dependencies [ce97426c0] +- Updated dependencies [1b86eac05] +- Updated dependencies [a35c05ea9] +- Updated dependencies [c9ee5e4a] +- Updated dependencies [3622e39dd] +- Updated dependencies [c963b46c7] +- Updated dependencies [08d7c471f] +- Updated dependencies [05b3e8882] +- Updated dependencies [52182f70d] +- Updated dependencies [0f27afddb] +- Updated dependencies [748f4588a] +- Updated dependencies [865253dba] +- Updated dependencies [8f49c277d] +- Updated dependencies [7fa2ca183] +- Updated dependencies [ce7125a1b] +- Updated dependencies [745485cda] +- Updated dependencies [16b13ea8f] +- Updated dependencies [aea67c580] +- Updated dependencies [82693072] +- Updated dependencies [07dd6f32c] +- Updated dependencies [c14f8bf1e] +- Updated dependencies [c07fa0215] +- Updated dependencies [90e4161bb] +- Updated dependencies [aabd30767] +- Updated dependencies [65c9546c4] +- Updated dependencies [6ca1874e0] +- Updated dependencies [331dbfdcb] +- Updated dependencies [504e25dc8] +- Updated dependencies [e86fbc126] +- Updated dependencies [d5c0682fb] +- Updated dependencies [1d60930d6] +- Updated dependencies [01e46d99] +- Updated dependencies [430e6b29a] +- Updated dependencies [f9f9609ef] +- Updated dependencies [904fd7d4e] +- Updated dependencies [e6c03a87a] +- Updated dependencies [1077c7f53] +- Updated dependencies [de47d698f] +- Updated dependencies [e48fb3b03] +- Updated dependencies [2c920de7] +- Updated dependencies [0a3b9b1c9] +- Updated dependencies [b9e562d8f] +- Updated dependencies [331dbfdcb] +- Updated dependencies [44236041f] +- Updated dependencies [066056154] +- Updated dependencies [759514d8b] +- Updated dependencies [952cd5344] +- Updated dependencies [d5094a242] +- Updated dependencies [6c615b608] +- Updated dependencies [3fb9ce283] +- Updated dependencies [c207d35e8] +- Updated dependencies [db7798be2] +- Updated dependencies [bb6ada740] +- Updated dependencies [85b94614b] +- Updated dependencies [35c9f33df] +- Updated dependencies [3be4deecf] +- Updated dependencies [a25881160] +- Updated dependencies [a4aff73c5] +- Updated dependencies [0b8ce3f2c] +- Updated dependencies [933b54b5f] +- Updated dependencies [5debcca8] +- Updated dependencies [c4d5eb4e4] +- Updated dependencies [f8dab7334] +- Updated dependencies [1a0fa7974] +- Updated dependencies [57a526083] +- Updated dependencies [f62c767e7] +- Updated dependencies [d00c4a9af] +- Updated dependencies [9e5baf4ff] +- Updated dependencies [9aa5e786] +- Updated dependencies [307abab3] +- Updated dependencies [de151fec0] +- Updated dependencies [c32a9269a] +- Updated dependencies [eb384bb0e] +- Updated dependencies [37c228c63] +- Updated dependencies [618dd0e89] +- Updated dependencies [aacffcb59] +- Updated dependencies [c991c71a] +- Updated dependencies [1faf7f697] +- Updated dependencies [ae340b2bf] +- Updated dependencies [1bf2e9087] +- Updated dependencies [e5d208e40] +- Updated dependencies [b38c096d] +- Updated dependencies [211be2a1e] +- Updated dependencies [0f3e2e02b] +- Updated dependencies [131c63e53] +- Updated dependencies [1f80a0b52] +- Updated dependencies [712866f5f] +- Updated dependencies [d08789282] +- Updated dependencies [5c965a919] +- Updated dependencies [f99e88987] +- Updated dependencies [939916bcd] +- Updated dependencies [e5a962bc3] +- Updated dependencies [331f0d636] +- Updated dependencies [f6f402896] +- Updated dependencies [d5b73b126] +- Updated dependencies [e34d1170] +- Updated dependencies [08b422171] +- Updated dependencies [b8a6158d6] +- Updated dependencies [190fdd11] +- Updated dependencies [4e445a1ab] +- Updated dependencies [37c228c63] +- Updated dependencies [37c228c63] +- Updated dependencies [433078c54] +- Updated dependencies [669fa43e5] +- Updated dependencies [db314a74] +- Updated dependencies [b2d2aa715] +- Updated dependencies [4c7fd3eb2] +- Updated dependencies [a0341daf9] +- Updated dependencies [83583a505] +- Updated dependencies [5e723b90e] +- Updated dependencies [582388ba5] +- Updated dependencies [6573e38e9] +- Updated dependencies [51914d656] +- Updated dependencies [eeb15cc06] +- Updated dependencies [063daf80e] +- Updated dependencies [afaf2f5ff] +- Updated dependencies [37c228c63] +- Updated dependencies [59267655] +- Updated dependencies [37c228c63] +- Updated dependencies [997286bac] +- Updated dependencies [2bfee9217] +- Updated dependencies [1ca35e9a1] +- Updated dependencies [4081493b8] +- Updated dependencies [44a5432ac] +- Updated dependencies [6e66c5b74] +- Updated dependencies [582388ba5] +- Updated dependencies [8d51a0348] +- Updated dependencies [c162ad5a5] +- Updated dependencies [a735e14b4] +- Updated dependencies [88b1a5a19] +- Updated dependencies [1e2ad78e2] +- Updated dependencies [65c9546c4] +- Updated dependencies [48909d151] +- Updated dependencies [7b28d32e5] +- Updated dependencies [3e024fcf3] +- Updated dependencies [b02f9d0e4] +- Updated dependencies [2ca75f9b9] +- Updated dependencies [f62c767e7] +- Updated dependencies [bb91edaa0] +- Updated dependencies [590542030] +- Updated dependencies [1a82c278] +- Updated dependencies [1b5eb0d07] +- Updated dependencies [44a5432ac] +- Updated dependencies [48c51b52a] +- Updated dependencies [9f8b84e73] +- Updated dependencies [66cc35a8c] +- Updated dependencies [672d05ca1] +- Updated dependencies [f1cd43bf9] +- Updated dependencies [9d0f492a9] +- Updated dependencies [55a05fd7a] +- Updated dependencies [7e6e5157b] +- Updated dependencies [f03531d97] +- Updated dependencies [c583f3cd0] +- Updated dependencies [31ffc9d5d] +- Updated dependencies [5e723b90e] +- Updated dependencies [63831a264] +- Updated dependencies [b8a6158d6] +- Updated dependencies [6db95ce15] +- Updated dependencies [8193136a9] +- Updated dependencies [5d737cf2e] +- Updated dependencies [d075f82f3] +- Updated dependencies [331dbfdcb] +- Updated dependencies [a7b30c79b] +- Updated dependencies [6470fe1fd] +- Updated dependencies [86766ce1] +- Updated dependencies [92de59982] +- Updated dependencies [5741d53d0] +- Updated dependencies [aee8020a6] +- Updated dependencies [22ee44700] +- Updated dependencies [e2d089c6d] +- Updated dependencies [1327ea8c8] +- Updated dependencies [ad4ac4459] +- Updated dependencies [f6d214e3d] +- Updated dependencies [3f5d33af] +- Updated dependencies [be313068b] +- Updated dependencies [ac508bf18] +- Updated dependencies [331dbfdcb] +- Updated dependencies [93390d89] +- Updated dependencies [57d8965df] +- Updated dependencies [18d3aea55] +- Updated dependencies [fa7763583] +- Updated dependencies [7987c94d6] +- Updated dependencies [bb91edaa0] +- Updated dependencies [144c0d8d] +- Updated dependencies [5ac4c97f4] +- Updated dependencies [bfcb293d1] +- Updated dependencies [3e057061d] +- Updated dependencies [1890f1a06] +- Updated dependencies [e48171741] +- Updated dependencies [e4a6189df] +- Updated dependencies [753bdce41] +- Updated dependencies [5294a7d59] +- Updated dependencies [69a96f109] +- Updated dependencies [9b43029c3] +- Updated dependencies [37c228c63] +- Updated dependencies [55ab88a60] +- Updated dependencies [e3de1a338] +- Updated dependencies [c58da9ad] +- Updated dependencies [37c228c63] +- Updated dependencies [b8a6158d6] +- Updated dependencies [4e4a34150] +- Updated dependencies [535229984] +- Updated dependencies [af639a264] +- Updated dependencies [5e723b90e] +- Updated dependencies [99ab9cd6f] +- Updated dependencies [be18b75b] +- Updated dependencies [0c4f9fea9] +- Updated dependencies [0d12db8c2] +- Updated dependencies [c049c23f4] +- Updated dependencies [80dd6992e] +- Updated dependencies [60cfd089f] +- Updated dependencies [9ef3f9a7c] +- Updated dependencies [34203e4ed] +- Updated dependencies [24a6cd536] +- Updated dependencies [37c228c63] +- Updated dependencies [708b49c50] +- Updated dependencies [d2f8e9400] +- Updated dependencies [17f987209] +- Updated dependencies [25086be5f] +- Updated dependencies [37c228c63] +- Updated dependencies [b1d41727d] +- Updated dependencies [3ac68ade6] +- Updated dependencies [c642ff3a0] +- Updated dependencies [22ba7b675] +- Updated dependencies [4c1dcd81e] +- Updated dependencies [3042f86e] +- Updated dependencies [c049c23f4] +- Updated dependencies [5e71e1cb5] +- Updated dependencies [7eabd06f7] +- Updated dependencies [6071163f7] +- Updated dependencies [6c6733256] +- Updated dependencies [cd5abcc3b] +- Updated dependencies [d7b1c588a] +- Updated dependencies [5c52bee09] +- Updated dependencies [939916bcd] +- Updated dependencies [251170e1e] +- Updated dependencies [8025c3505] +- Updated dependencies [c4f49240d] +- Updated dependencies [745485cda] +- Updated dependencies [95f64c85] +- Updated dependencies [afdba793f] +- Updated dependencies [37c228c63] +- Updated dependencies [3e7d83d0] +- Updated dependencies [5df1f31bc] +- Updated dependencies [29c3f5087] +- Updated dependencies [cea754dde] +- Updated dependencies [331f0d636] +- Updated dependencies [1b5eb0d07] +- Updated dependencies [95c59b203] +- Updated dependencies [d2f8e9400] +- Updated dependencies [4c1dcd81e] +- Updated dependencies [adc68225] +- Updated dependencies [cc2c8da00] +- Updated dependencies [252a1852] +- Updated dependencies [7b73f44d9] +- Updated dependencies [103f635eb] + - @latticexyz/store@2.0.0 + - @latticexyz/world@2.0.0 + - @latticexyz/store-sync@2.0.0 + - @latticexyz/common@2.0.0 + - @latticexyz/utils@2.0.0 + - @latticexyz/recs@2.0.0 + - @latticexyz/schema-type@2.0.0 + - @latticexyz/react@2.0.0 + ## 2.0.0-next.18 ### Major Changes diff --git a/packages/dev-tools/package.json b/packages/dev-tools/package.json index 018e0c11fc..545985be29 100644 --- a/packages/dev-tools/package.json +++ b/packages/dev-tools/package.json @@ -1,6 +1,6 @@ { "name": "@latticexyz/dev-tools", - "version": "2.0.0-next.18", + "version": "2.0.0", "description": "MUD developer tools", "repository": { "type": "git", @@ -51,12 +51,12 @@ "vitest": "0.34.6" }, "peerDependencies": { - "@latticexyz/common": "2.0.0-next.18", - "@latticexyz/recs": "2.0.0-next.18", - "@latticexyz/store": "2.0.0-next.18", - "@latticexyz/store-sync": "2.0.0-next.18", - "@latticexyz/utils": "2.0.0-next.18", - "@latticexyz/world": "2.0.0-next.18" + "@latticexyz/common": "2.0.0", + "@latticexyz/recs": "2.0.0", + "@latticexyz/store": "2.0.0", + "@latticexyz/store-sync": "2.0.0", + "@latticexyz/utils": "2.0.0", + "@latticexyz/world": "2.0.0" }, "publishConfig": { "access": "public" diff --git a/packages/ecs-browser/CHANGELOG.md b/packages/ecs-browser/CHANGELOG.md index c9761acefc..974f89f1c7 100644 --- a/packages/ecs-browser/CHANGELOG.md +++ b/packages/ecs-browser/CHANGELOG.md @@ -1,5 +1,11 @@ # @latticexyz/ecs-browser +## 2.0.0 + +### Major Changes + +- 6255a3142: Removes `ecs-browser` package. This has now been replaced by `dev-tools`, which comes out-of-the-box when creating a new MUD app from the templates (`pnpm create mud@next your-app-name`). We'll be adding deeper RECS support (querying for entities) in a future release. + ## 2.0.0-next.18 ## 2.0.0-next.17 diff --git a/packages/ecs-browser/package.json b/packages/ecs-browser/package.json index 87406f5729..4cd4b0733b 100644 --- a/packages/ecs-browser/package.json +++ b/packages/ecs-browser/package.json @@ -1,5 +1,5 @@ { "name": "@latticexyz/ecs-browser", - "version": "2.0.0-next.18", + "version": "2.0.0", "private": true } diff --git a/packages/faucet/CHANGELOG.md b/packages/faucet/CHANGELOG.md index e081d73119..879c0491e5 100644 --- a/packages/faucet/CHANGELOG.md +++ b/packages/faucet/CHANGELOG.md @@ -1,5 +1,109 @@ # @latticexyz/faucet +## 2.0.0 + +### Minor Changes + +- 9940fdb3e: New package to run your own faucet service. We'll use this soon for our testnet in place of `@latticexyz/services`. + + To run the faucet server: + + - Add the package with `pnpm add @latticexyz/faucet` + - Add a `.env` file that has a `RPC_HTTP_URL` and `FAUCET_PRIVATE_KEY` (or pass the environment variables into the next command) + - Run `pnpm faucet-server` to start the server + + You can also adjust the server's `HOST` (defaults to `0.0.0.0`) and `PORT` (defaults to `3002`). The tRPC routes are accessible under `/trpc`. + + To connect a tRPC client, add the package with `pnpm add @latticexyz/faucet` and then use `createClient`: + + ```ts + import { createClient } from "@latticexyz/faucet"; + + const faucet = createClient({ url: "http://localhost:3002/trpc" }); + + await faucet.mutate.drip({ address: burnerAccount.address }); + ``` + +- 1d0f7e22b: Added `/healthz` and `/readyz` healthcheck endpoints for Kubernetes +- d7b1c588a: Upgraded all packages and templates to viem v2.7.12 and abitype v1.0.0. + + Some viem APIs have changed and we've updated `getContract` to reflect those changes and keep it aligned with viem. It's one small code change: + + ```diff + const worldContract = getContract({ + address: worldAddress, + abi: IWorldAbi, + - publicClient, + - walletClient, + + client: { public: publicClient, wallet: walletClient }, + }); + ``` + +### Patch Changes + +- f99e88987: Bump viem to 1.14.0 and abitype to 0.9.8 +- 301bcb75d: Improves error message when parsing env variables +- 590542030: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages. +- 5d737cf2e: Updated the `debug` util to pipe to `stdout` and added an additional util to explicitly pipe to `stderr` when needed. +- 9082c179c: Updated to use MUD's `sendTransaction`, which does a better of managing nonces for higher volumes of transactions. +- fa409e83d: Added README +- Updated dependencies [a35c05ea9] +- Updated dependencies [16b13ea8f] +- Updated dependencies [82693072] +- Updated dependencies [aabd30767] +- Updated dependencies [65c9546c4] +- Updated dependencies [d5c0682fb] +- Updated dependencies [01e46d99] +- Updated dependencies [331dbfdcb] +- Updated dependencies [44236041f] +- Updated dependencies [066056154] +- Updated dependencies [3fb9ce283] +- Updated dependencies [bb6ada740] +- Updated dependencies [35c9f33df] +- Updated dependencies [0b8ce3f2c] +- Updated dependencies [933b54b5f] +- Updated dependencies [307abab3] +- Updated dependencies [aacffcb59] +- Updated dependencies [f99e88987] +- Updated dependencies [939916bcd] +- Updated dependencies [e34d1170] +- Updated dependencies [b8a6158d6] +- Updated dependencies [db314a74] +- Updated dependencies [59267655] +- Updated dependencies [8d51a0348] +- Updated dependencies [c162ad5a5] +- Updated dependencies [f62c767e7] +- Updated dependencies [590542030] +- Updated dependencies [1b5eb0d07] +- Updated dependencies [44a5432ac] +- Updated dependencies [b8a6158d6] +- Updated dependencies [5d737cf2e] +- Updated dependencies [d075f82f3] +- Updated dependencies [331dbfdcb] +- Updated dependencies [92de59982] +- Updated dependencies [bfcb293d1] +- Updated dependencies [3e057061d] +- Updated dependencies [535229984] +- Updated dependencies [5e723b90e] +- Updated dependencies [0c4f9fea9] +- Updated dependencies [60cfd089f] +- Updated dependencies [24a6cd536] +- Updated dependencies [708b49c50] +- Updated dependencies [d2f8e9400] +- Updated dependencies [25086be5f] +- Updated dependencies [b1d41727d] +- Updated dependencies [4c1dcd81e] +- Updated dependencies [6071163f7] +- Updated dependencies [6c6733256] +- Updated dependencies [cd5abcc3b] +- Updated dependencies [d7b1c588a] +- Updated dependencies [c4f49240d] +- Updated dependencies [5df1f31bc] +- Updated dependencies [cea754dde] +- Updated dependencies [331f0d636] +- Updated dependencies [cc2c8da00] + - @latticexyz/common@2.0.0 + ## 2.0.0-next.18 ### Minor Changes diff --git a/packages/faucet/package.json b/packages/faucet/package.json index 61fa3bf0a8..813adffbfc 100644 --- a/packages/faucet/package.json +++ b/packages/faucet/package.json @@ -1,6 +1,6 @@ { "name": "@latticexyz/faucet", - "version": "2.0.0-next.18", + "version": "2.0.0", "description": "Faucet API for Lattice testnet", "repository": { "type": "git", diff --git a/packages/gas-report/CHANGELOG.md b/packages/gas-report/CHANGELOG.md index ed2077d950..d938c4994b 100644 --- a/packages/gas-report/CHANGELOG.md +++ b/packages/gas-report/CHANGELOG.md @@ -1,5 +1,34 @@ # Change Log +## 2.0.0 + +### Major Changes + +- aabd30767: Bumped Solidity version to 0.8.24. +- 92de59982: Bump Solidity version to 0.8.21 +- 9af542d3e: Renames `mud-gas-report` binary to `gas-report`, since it's no longer MUD specific. + +### Minor Changes + +- 66cc35a8c: Create gas-report package, move gas-report cli command and GasReporter contract to it +- 4385c5a4c: Allow the `gas-report` CLI to parse logs via `stdin`, so it can be used with custom test commands (e.g. `mud test`). + + Usage: + + ```sh + # replace `forge test -vvv` with the custom test command + GAS_REPORTER_ENABLED=true forge test -vvv | pnpm gas-report --stdin + ``` + +- 90d0d79c: Now uses `--isolate` flag in `forge test` for more accurate gas measurement. + +### Patch Changes + +- ba17bdab5: Pass through `stdin` logs in `gas-report`. Since the script piping in logs to `gas-report` can be long-running, it is useful to see its logs to know if it's stalling. +- 48909d151: bump forge-std and ds-test dependencies +- 590542030: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages. +- a02da555b: Fixed gas report parsing for foundry versions released after 2024-02-15. + ## 2.0.0-next.18 ### Minor Changes diff --git a/packages/gas-report/package.json b/packages/gas-report/package.json index b672961095..1664a200d6 100644 --- a/packages/gas-report/package.json +++ b/packages/gas-report/package.json @@ -1,6 +1,6 @@ { "name": "@latticexyz/gas-report", - "version": "2.0.0-next.18", + "version": "2.0.0", "description": "Gas reporter for specific lines within forge tests", "repository": { "type": "git", diff --git a/packages/network/CHANGELOG.md b/packages/network/CHANGELOG.md index 678c94bfcd..74dd3af677 100644 --- a/packages/network/CHANGELOG.md +++ b/packages/network/CHANGELOG.md @@ -1,5 +1,20 @@ # @latticexyz/network +## 2.0.0 + +### Major Changes + +- 42c7d8986: Removes `network` package. Please see the [changelog](https://mud.dev/changelog) for how to migrate your app to the new `store-sync` package. Or create a new project from an up-to-date template with `pnpm create mud@next your-app-name`. + +### Patch Changes + +- b8a6158d6: bump viem to 1.6.0 +- 535229984: - bump to viem 1.3.0 and abitype 0.9.3 + - move `@wagmi/chains` imports to `viem/chains` + - refine a few types +- e019c7761: Remove devEmit function when sending network events from SyncWorker because they can't be serialized across the web worker boundary. +- 6c6733256: Add `tableIdToHex` and `hexToTableId` pure functions and move/deprecate `TableId`. + ## 2.0.0-next.18 ## 2.0.0-next.17 diff --git a/packages/network/package.json b/packages/network/package.json index 77fa846e62..f87ebc6066 100644 --- a/packages/network/package.json +++ b/packages/network/package.json @@ -1,5 +1,5 @@ { "name": "@latticexyz/network", - "version": "2.0.0-next.18", + "version": "2.0.0", "private": true } diff --git a/packages/noise/CHANGELOG.md b/packages/noise/CHANGELOG.md index 300ea3f6d8..9b4ea15fad 100644 --- a/packages/noise/CHANGELOG.md +++ b/packages/noise/CHANGELOG.md @@ -1,5 +1,18 @@ # Change Log +## 2.0.0 + +### Major Changes + +- aabd30767: Bumped Solidity version to 0.8.24. +- 92de59982: Bump Solidity version to 0.8.21 + +### Patch Changes + +- 5a8dfc857: Removed the @latticexyz/noise package. +- 48909d151: bump forge-std and ds-test dependencies +- 590542030: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages. + ## 2.0.0-next.18 ### Patch Changes diff --git a/packages/noise/package.json b/packages/noise/package.json index 7b0bac8894..82f439ce34 100644 --- a/packages/noise/package.json +++ b/packages/noise/package.json @@ -1,5 +1,5 @@ { "name": "@latticexyz/noise", - "version": "2.0.0-next.18", + "version": "2.0.0", "private": true } diff --git a/packages/phaserx/CHANGELOG.md b/packages/phaserx/CHANGELOG.md index 26e933cf2c..6a3f3b6f69 100644 --- a/packages/phaserx/CHANGELOG.md +++ b/packages/phaserx/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## 2.0.0 + +### Patch Changes + +- 590542030: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages. + ## 2.0.0-next.18 ## 2.0.0-next.17 diff --git a/packages/phaserx/package.json b/packages/phaserx/package.json index c38f4686dd..442f776bcc 100644 --- a/packages/phaserx/package.json +++ b/packages/phaserx/package.json @@ -1,5 +1,5 @@ { "name": "@latticexyz/phaserx", - "version": "2.0.0-next.18", + "version": "2.0.0", "private": true } diff --git a/packages/protocol-parser/CHANGELOG.md b/packages/protocol-parser/CHANGELOG.md index 85cdb88734..a657f5264b 100644 --- a/packages/protocol-parser/CHANGELOG.md +++ b/packages/protocol-parser/CHANGELOG.md @@ -1,5 +1,174 @@ # @latticexyz/protocol-parser +## 2.0.0 + +### Major Changes + +- 07dd6f32c: Renamed all occurrences of `schema` where it is used as "value schema" to `valueSchema` to clearly distinguish it from "key schema". + The only breaking change for users is the change from `schema` to `valueSchema` in `mud.config.ts`. + + ```diff + // mud.config.ts + export default mudConfig({ + tables: { + CounterTable: { + keySchema: {}, + - schema: { + + valueSchema: { + value: "uint32", + }, + }, + } + } + ``` + +- 331dbfdcb: `readHex` was moved from `@latticexyz/protocol-parser` to `@latticexyz/common` +- b38c096d: Moved all existing exports to a `/internal` import path to indicate that these are now internal-only and deprecated. We'll be replacing these types and functions with new ones that are compatible with our new, strongly-typed config. +- 433078c54: Reverse PackedCounter encoding, to optimize gas for bitshifts. + Ints are right-aligned, shifting using an index is straightforward if they are indexed right-to-left. + + - Previous encoding: (7 bytes | accumulator),(5 bytes | counter 1),...,(5 bytes | counter 5) + - New encoding: (5 bytes | counter 5),...,(5 bytes | counter 1),(7 bytes | accumulator) + +### Minor Changes + +- b98e51808: feat: add abiTypesToSchema, a util to turn a list of abi types into a Schema by separating static and dynamic types +- de151fec0: - Add `FieldLayout`, which is a `bytes32` user-type similar to `Schema`. + + Both `FieldLayout` and `Schema` have the same kind of data in the first 4 bytes. + + - 2 bytes for total length of all static fields + - 1 byte for number of static size fields + - 1 byte for number of dynamic size fields + + But whereas `Schema` has `SchemaType` enum in each of the other 28 bytes, `FieldLayout` has static byte lengths in each of the other 28 bytes. + + - Replace `Schema valueSchema` with `FieldLayout fieldLayout` in Store and World contracts. + + `FieldLayout` is more gas-efficient because it already has lengths, and `Schema` has types which need to be converted to lengths. + + - Add `getFieldLayout` to `IStore` interface. + + There is no `FieldLayout` for keys, only for values, because key byte lengths aren't usually relevant on-chain. You can still use `getKeySchema` if you need key types. + + - Add `fieldLayoutToHex` utility to `protocol-parser` package. + - Add `constants.sol` for constants shared between `FieldLayout`, `Schema` and `PackedCounter`. + +- ca50fef81: feat: add `encodeKeyTuple`, a util to encode key tuples in Typescript (equivalent to key tuple encoding in Solidity and inverse of `decodeKeyTuple`). + Example: + + ```ts + encodeKeyTuple( + { + staticFields: ["uint256", "int32", "bytes16", "address", "bool", "int8"], + dynamicFields: [], + }, + [42n, -42, "0x12340000000000000000000000000000", "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF", true, 3], + ); + // [ + // "0x000000000000000000000000000000000000000000000000000000000000002a", + // "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd6", + // "0x1234000000000000000000000000000000000000000000000000000000000000", + // "0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff", + // "0x0000000000000000000000000000000000000000000000000000000000000001", + // "0x0000000000000000000000000000000000000000000000000000000000000003", + // ] + ``` + +- 9ff4dd955: Adds `valueSchemaToFieldLayoutHex` helper +- d7b1c588a: Upgraded all packages and templates to viem v2.7.12 and abitype v1.0.0. + + Some viem APIs have changed and we've updated `getContract` to reflect those changes and keep it aligned with viem. It's one small code change: + + ```diff + const worldContract = getContract({ + address: worldAddress, + abi: IWorldAbi, + - publicClient, + - walletClient, + + client: { public: publicClient, wallet: walletClient }, + }); + ``` + +- 5e71e1cb5: Adds `decodeKey`, `decodeValue`, `encodeKey`, and `encodeValue` helpers to decode/encode from key/value schemas. Deprecates previous methods that use a schema object with static/dynamic field arrays, originally attempting to model our on-chain behavior but ended up not very ergonomic when working with table configs. + +### Patch Changes + +- 904fd7d4e: Add store sync package +- 4bb7e8cbf: `decodeRecord` now properly decodes empty records +- f99e88987: Bump viem to 1.14.0 and abitype to 0.9.8 +- f8a01a047: Export `valueSchemaToFieldLayoutHex` helper +- 590542030: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages. +- b8a6158d6: bump viem to 1.6.0 +- 535229984: - bump to viem 1.3.0 and abitype 0.9.3 + - move `@wagmi/chains` imports to `viem/chains` + - refine a few types +- 3e7d83d0: Renamed `PackedCounter` to `EncodedLengths` for consistency. +- a2f41ade9: Allow arbitrary key order when encoding values +- Updated dependencies [a35c05ea9] +- Updated dependencies [16b13ea8f] +- Updated dependencies [82693072] +- Updated dependencies [aabd30767] +- Updated dependencies [65c9546c4] +- Updated dependencies [d5c0682fb] +- Updated dependencies [01e46d99] +- Updated dependencies [331dbfdcb] +- Updated dependencies [44236041f] +- Updated dependencies [066056154] +- Updated dependencies [3fb9ce283] +- Updated dependencies [bb6ada740] +- Updated dependencies [35c9f33df] +- Updated dependencies [0b8ce3f2c] +- Updated dependencies [933b54b5f] +- Updated dependencies [307abab3] +- Updated dependencies [aacffcb59] +- Updated dependencies [b38c096d] +- Updated dependencies [f99e88987] +- Updated dependencies [939916bcd] +- Updated dependencies [e34d1170] +- Updated dependencies [b8a6158d6] +- Updated dependencies [db314a74] +- Updated dependencies [59267655] +- Updated dependencies [8d51a0348] +- Updated dependencies [c162ad5a5] +- Updated dependencies [48909d151] +- Updated dependencies [b02f9d0e4] +- Updated dependencies [f62c767e7] +- Updated dependencies [bb91edaa0] +- Updated dependencies [590542030] +- Updated dependencies [1b5eb0d07] +- Updated dependencies [44a5432ac] +- Updated dependencies [f03531d97] +- Updated dependencies [b8a6158d6] +- Updated dependencies [5d737cf2e] +- Updated dependencies [d075f82f3] +- Updated dependencies [331dbfdcb] +- Updated dependencies [92de59982] +- Updated dependencies [bfcb293d1] +- Updated dependencies [3e057061d] +- Updated dependencies [535229984] +- Updated dependencies [5e723b90e] +- Updated dependencies [0c4f9fea9] +- Updated dependencies [60cfd089f] +- Updated dependencies [24a6cd536] +- Updated dependencies [708b49c50] +- Updated dependencies [d2f8e9400] +- Updated dependencies [25086be5f] +- Updated dependencies [b1d41727d] +- Updated dependencies [4c1dcd81e] +- Updated dependencies [6071163f7] +- Updated dependencies [6c6733256] +- Updated dependencies [cd5abcc3b] +- Updated dependencies [d7b1c588a] +- Updated dependencies [c4f49240d] +- Updated dependencies [5df1f31bc] +- Updated dependencies [cea754dde] +- Updated dependencies [331f0d636] +- Updated dependencies [cc2c8da00] + - @latticexyz/common@2.0.0 + - @latticexyz/schema-type@2.0.0 + - @latticexyz/config@2.0.0 + ## 2.0.0-next.18 ### Major Changes diff --git a/packages/protocol-parser/package.json b/packages/protocol-parser/package.json index 951683a3bc..c7a4e0da31 100644 --- a/packages/protocol-parser/package.json +++ b/packages/protocol-parser/package.json @@ -1,6 +1,6 @@ { "name": "@latticexyz/protocol-parser", - "version": "2.0.0-next.18", + "version": "2.0.0", "description": "Parser utilities for the MUD protocol", "repository": { "type": "git", diff --git a/packages/query/CHANGELOG.md b/packages/query/CHANGELOG.md index 88d7610485..93ce581ced 100644 --- a/packages/query/CHANGELOG.md +++ b/packages/query/CHANGELOG.md @@ -1,5 +1,163 @@ # @latticexyz/query +## 2.0.0 + +### Patch Changes + +- Updated dependencies [7ce82b6fc] +- Updated dependencies [d8c8f66bf] +- Updated dependencies [c6c13f2ea] +- Updated dependencies [1b86eac05] +- Updated dependencies [a35c05ea9] +- Updated dependencies [c9ee5e4a] +- Updated dependencies [c963b46c7] +- Updated dependencies [05b3e8882] +- Updated dependencies [16b13ea8f] +- Updated dependencies [aea67c580] +- Updated dependencies [82693072] +- Updated dependencies [07dd6f32c] +- Updated dependencies [90e4161bb] +- Updated dependencies [aabd30767] +- Updated dependencies [65c9546c4] +- Updated dependencies [331dbfdcb] +- Updated dependencies [d5c0682fb] +- Updated dependencies [1d60930d6] +- Updated dependencies [01e46d99] +- Updated dependencies [f9f9609ef] +- Updated dependencies [904fd7d4e] +- Updated dependencies [e6c03a87a] +- Updated dependencies [1077c7f53] +- Updated dependencies [2c920de7] +- Updated dependencies [b9e562d8f] +- Updated dependencies [331dbfdcb] +- Updated dependencies [44236041f] +- Updated dependencies [066056154] +- Updated dependencies [759514d8b] +- Updated dependencies [952cd5344] +- Updated dependencies [d5094a242] +- Updated dependencies [3fb9ce283] +- Updated dependencies [bb6ada740] +- Updated dependencies [35c9f33df] +- Updated dependencies [a25881160] +- Updated dependencies [0b8ce3f2c] +- Updated dependencies [933b54b5f] +- Updated dependencies [c4d5eb4e4] +- Updated dependencies [f62c767e7] +- Updated dependencies [9aa5e786] +- Updated dependencies [307abab3] +- Updated dependencies [de151fec0] +- Updated dependencies [37c228c63] +- Updated dependencies [aacffcb59] +- Updated dependencies [c991c71a] +- Updated dependencies [ae340b2bf] +- Updated dependencies [1bf2e9087] +- Updated dependencies [b38c096d] +- Updated dependencies [211be2a1e] +- Updated dependencies [0f3e2e02b] +- Updated dependencies [d08789282] +- Updated dependencies [5c965a919] +- Updated dependencies [f99e88987] +- Updated dependencies [939916bcd] +- Updated dependencies [d5b73b126] +- Updated dependencies [e34d1170] +- Updated dependencies [b8a6158d6] +- Updated dependencies [190fdd11] +- Updated dependencies [433078c54] +- Updated dependencies [db314a74] +- Updated dependencies [b2d2aa715] +- Updated dependencies [83583a505] +- Updated dependencies [5e723b90e] +- Updated dependencies [6573e38e9] +- Updated dependencies [afaf2f5ff] +- Updated dependencies [37c228c63] +- Updated dependencies [59267655] +- Updated dependencies [37c228c63] +- Updated dependencies [44a5432ac] +- Updated dependencies [6e66c5b74] +- Updated dependencies [8d51a0348] +- Updated dependencies [c162ad5a5] +- Updated dependencies [65c9546c4] +- Updated dependencies [48909d151] +- Updated dependencies [7b28d32e5] +- Updated dependencies [b02f9d0e4] +- Updated dependencies [f62c767e7] +- Updated dependencies [bb91edaa0] +- Updated dependencies [590542030] +- Updated dependencies [1b5eb0d07] +- Updated dependencies [44a5432ac] +- Updated dependencies [48c51b52a] +- Updated dependencies [9f8b84e73] +- Updated dependencies [66cc35a8c] +- Updated dependencies [672d05ca1] +- Updated dependencies [55a05fd7a] +- Updated dependencies [f03531d97] +- Updated dependencies [63831a264] +- Updated dependencies [b8a6158d6] +- Updated dependencies [6db95ce15] +- Updated dependencies [8193136a9] +- Updated dependencies [5d737cf2e] +- Updated dependencies [d075f82f3] +- Updated dependencies [331dbfdcb] +- Updated dependencies [a7b30c79b] +- Updated dependencies [92de59982] +- Updated dependencies [22ee44700] +- Updated dependencies [ad4ac4459] +- Updated dependencies [be313068b] +- Updated dependencies [ac508bf18] +- Updated dependencies [93390d89] +- Updated dependencies [bb91edaa0] +- Updated dependencies [144c0d8d] +- Updated dependencies [5ac4c97f4] +- Updated dependencies [bfcb293d1] +- Updated dependencies [3e057061d] +- Updated dependencies [1890f1a06] +- Updated dependencies [e48171741] +- Updated dependencies [9b43029c3] +- Updated dependencies [37c228c63] +- Updated dependencies [55ab88a60] +- Updated dependencies [c58da9ad] +- Updated dependencies [37c228c63] +- Updated dependencies [535229984] +- Updated dependencies [af639a264] +- Updated dependencies [5e723b90e] +- Updated dependencies [99ab9cd6f] +- Updated dependencies [0c4f9fea9] +- Updated dependencies [0d12db8c2] +- Updated dependencies [c049c23f4] +- Updated dependencies [80dd6992e] +- Updated dependencies [60cfd089f] +- Updated dependencies [24a6cd536] +- Updated dependencies [37c228c63] +- Updated dependencies [708b49c50] +- Updated dependencies [d2f8e9400] +- Updated dependencies [25086be5f] +- Updated dependencies [b1d41727d] +- Updated dependencies [3ac68ade6] +- Updated dependencies [22ba7b675] +- Updated dependencies [4c1dcd81e] +- Updated dependencies [3042f86e] +- Updated dependencies [5e71e1cb5] +- Updated dependencies [6071163f7] +- Updated dependencies [6c6733256] +- Updated dependencies [cd5abcc3b] +- Updated dependencies [d7b1c588a] +- Updated dependencies [5c52bee09] +- Updated dependencies [8025c3505] +- Updated dependencies [c4f49240d] +- Updated dependencies [745485cda] +- Updated dependencies [37c228c63] +- Updated dependencies [3e7d83d0] +- Updated dependencies [5df1f31bc] +- Updated dependencies [cea754dde] +- Updated dependencies [331f0d636] +- Updated dependencies [cc2c8da00] +- Updated dependencies [252a1852] +- Updated dependencies [103f635eb] + - @latticexyz/store@2.0.0 + - @latticexyz/common@2.0.0 + - @latticexyz/schema-type@2.0.0 + - @latticexyz/config@2.0.0 + ## 2.0.0-next.18 ### Patch Changes diff --git a/packages/query/package.json b/packages/query/package.json index becfb214bb..5a69b9f42b 100644 --- a/packages/query/package.json +++ b/packages/query/package.json @@ -1,6 +1,6 @@ { "name": "@latticexyz/query", - "version": "2.0.0-next.18", + "version": "2.0.0", "description": "Tools for interacting with the MUD query API", "repository": { "type": "git", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 0f9a63e571..3ba8ec87c9 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,151 @@ # Change Log +## 2.0.0 + +### Major Changes + +- e3de1a338: Removes `useRow` and `useRows` hooks, previously powered by `store-cache`, which is now deprecated. Please use `recs` and the corresponding `useEntityQuery` and `useComponentValue` hooks. We'll have more hooks soon for SQL.js sync backends. + +### Minor Changes + +- 939916bcd: Adds a `usePromise` hook that returns a [native `PromiseSettledResult` object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled). + + ```tsx + const promise = fetch(url); + const result = usePromise(promise); + + if (result.status === "idle" || result.status === "pending") { + return <>fetching; + } + + if (result.status === "rejected") { + return <>error fetching: {String(result.reason)}; + } + + if (result.status === "fulfilled") { + return <>fetch status: {result.value.status}; + } + ``` + +### Patch Changes + +- 01e46d99: Removed some unused files, namely `curry` in `@latticexyz/common` and `useDeprecatedComputedValue` from `@latticexyz/react`. +- 590542030: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages. +- 9ef3f9a7c: Fixed an issue where `useComponentValue` would not detect a change and re-render if the component value was immediately removed. +- Updated dependencies [7ce82b6fc] +- Updated dependencies [d8c8f66bf] +- Updated dependencies [c6c13f2ea] +- Updated dependencies [1b86eac05] +- Updated dependencies [a35c05ea9] +- Updated dependencies [c9ee5e4a] +- Updated dependencies [c963b46c7] +- Updated dependencies [05b3e8882] +- Updated dependencies [ce7125a1b] +- Updated dependencies [aea67c580] +- Updated dependencies [07dd6f32c] +- Updated dependencies [c14f8bf1e] +- Updated dependencies [90e4161bb] +- Updated dependencies [aabd30767] +- Updated dependencies [331dbfdcb] +- Updated dependencies [1d60930d6] +- Updated dependencies [f9f9609ef] +- Updated dependencies [904fd7d4e] +- Updated dependencies [e6c03a87a] +- Updated dependencies [1077c7f53] +- Updated dependencies [2c920de7] +- Updated dependencies [b9e562d8f] +- Updated dependencies [44236041f] +- Updated dependencies [759514d8b] +- Updated dependencies [952cd5344] +- Updated dependencies [d5094a242] +- Updated dependencies [a25881160] +- Updated dependencies [c4d5eb4e4] +- Updated dependencies [f62c767e7] +- Updated dependencies [9aa5e786] +- Updated dependencies [de151fec0] +- Updated dependencies [37c228c63] +- Updated dependencies [c991c71a] +- Updated dependencies [ae340b2bf] +- Updated dependencies [1bf2e9087] +- Updated dependencies [211be2a1e] +- Updated dependencies [0f3e2e02b] +- Updated dependencies [d08789282] +- Updated dependencies [5c965a919] +- Updated dependencies [f99e88987] +- Updated dependencies [d5b73b126] +- Updated dependencies [190fdd11] +- Updated dependencies [433078c54] +- Updated dependencies [b2d2aa715] +- Updated dependencies [83583a505] +- Updated dependencies [5e723b90e] +- Updated dependencies [6573e38e9] +- Updated dependencies [afaf2f5ff] +- Updated dependencies [37c228c63] +- Updated dependencies [37c228c63] +- Updated dependencies [44a5432ac] +- Updated dependencies [6e66c5b74] +- Updated dependencies [8d51a0348] +- Updated dependencies [1e2ad78e2] +- Updated dependencies [65c9546c4] +- Updated dependencies [48909d151] +- Updated dependencies [7b28d32e5] +- Updated dependencies [590542030] +- Updated dependencies [48c51b52a] +- Updated dependencies [9f8b84e73] +- Updated dependencies [66cc35a8c] +- Updated dependencies [672d05ca1] +- Updated dependencies [55a05fd7a] +- Updated dependencies [63831a264] +- Updated dependencies [6db95ce15] +- Updated dependencies [8193136a9] +- Updated dependencies [5d737cf2e] +- Updated dependencies [a7b30c79b] +- Updated dependencies [92de59982] +- Updated dependencies [22ee44700] +- Updated dependencies [ad4ac4459] +- Updated dependencies [be313068b] +- Updated dependencies [ac508bf18] +- Updated dependencies [93390d89] +- Updated dependencies [bb91edaa0] +- Updated dependencies [144c0d8d] +- Updated dependencies [5ac4c97f4] +- Updated dependencies [bfcb293d1] +- Updated dependencies [1890f1a06] +- Updated dependencies [e48171741] +- Updated dependencies [9b43029c3] +- Updated dependencies [37c228c63] +- Updated dependencies [55ab88a60] +- Updated dependencies [c58da9ad] +- Updated dependencies [37c228c63] +- Updated dependencies [535229984] +- Updated dependencies [af639a264] +- Updated dependencies [5e723b90e] +- Updated dependencies [99ab9cd6f] +- Updated dependencies [0d12db8c2] +- Updated dependencies [c049c23f4] +- Updated dependencies [80dd6992e] +- Updated dependencies [60cfd089f] +- Updated dependencies [24a6cd536] +- Updated dependencies [37c228c63] +- Updated dependencies [708b49c50] +- Updated dependencies [3ac68ade6] +- Updated dependencies [22ba7b675] +- Updated dependencies [3042f86e] +- Updated dependencies [5e71e1cb5] +- Updated dependencies [d7b1c588a] +- Updated dependencies [5c52bee09] +- Updated dependencies [8025c3505] +- Updated dependencies [745485cda] +- Updated dependencies [afdba793f] +- Updated dependencies [37c228c63] +- Updated dependencies [3e7d83d0] +- Updated dependencies [cea754dde] +- Updated dependencies [cc2c8da00] +- Updated dependencies [252a1852] +- Updated dependencies [103f635eb] + - @latticexyz/store@2.0.0 + - @latticexyz/recs@2.0.0 + ## 2.0.0-next.18 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index 4e361ad66d..fee5a8c8a5 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@latticexyz/react", - "version": "2.0.0-next.18", + "version": "2.0.0", "description": "React tools for MUD client.", "repository": { "type": "git", diff --git a/packages/recs/CHANGELOG.md b/packages/recs/CHANGELOG.md index e2738a8c2b..d2222bb2b0 100644 --- a/packages/recs/CHANGELOG.md +++ b/packages/recs/CHANGELOG.md @@ -1,5 +1,264 @@ # Change Log +## 2.0.0 + +### Minor Changes + +- c14f8bf1e: - Moved `createActionSystem` from `std-client` to `recs` package and updated it to better support v2 sync stack. + + If you want to use `createActionSystem` alongside `syncToRecs`, you'll need to pass in arguments like so: + + ```ts + import { syncToRecs } from "@latticexyz/store-sync/recs"; + import { createActionSystem } from "@latticexyz/recs/deprecated"; + import { from, mergeMap } from "rxjs"; + + const { blockLogsStorage$, waitForTransaction } = syncToRecs({ + world, + ... + }); + + const txReduced$ = blockLogsStorage$.pipe( + mergeMap(({ operations }) => from(operations.map((op) => op.log?.transactionHash).filter(isDefined))) + ); + + const actionSystem = createActionSystem(world, txReduced$, waitForTransaction); + ``` + + - Fixed a bug in `waitForComponentValueIn` that caused the promise to not resolve if the component value was already set when the function was called. + - Fixed a bug in `createActionSystem` that caused optimistic updates to be incorrectly propagated to requirement checks. To fix the bug, you must now pass in the full component object to the action's `updates` instead of just the component name. + + ```diff + actions.add({ + updates: () => [ + { + - component: "Resource", + + component: Resource, + ... + } + ], + ... + }); + ``` + +### Patch Changes + +- ce7125a1b: Removes `solecs` package. These were v1 contracts, now entirely replaced by our v2 tooling. See the [MUD docs](https://mud.dev/) for building with v2 or create a new project from our v2 templates with `pnpm create mud@next your-app-name`. +- 1e2ad78e2: improve RECS error messages for v2 components +- 590542030: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages. +- 60cfd089f: Templates and examples now use MUD's new sync packages, all built on top of [viem](https://viem.sh/). This greatly speeds up and stabilizes our networking code and improves types throughout. + + These new sync packages come with support for our `recs` package, including `encodeEntity` and `decodeEntity` utilities for composite keys. + + If you're using `store-cache` and `useRow`/`useRows`, you should wait to upgrade until we have a suitable replacement for those libraries. We're working on a [sql.js](https://github.com/sql-js/sql.js/)-powered sync module that will replace `store-cache`. + + **Migrate existing RECS apps to new sync packages** + + As you migrate, you may find some features replaced, removed, or not included by default. Please [open an issue](https://github.com/latticexyz/mud/issues/new) and let us know if we missed anything. + + 1. Add `@latticexyz/store-sync` package to your app's `client` package and make sure `viem` is pinned to version `1.3.1` (otherwise you may get type errors) + 2. In your `supportedChains.ts`, replace `foundry` chain with our new `mudFoundry` chain. + + ```diff + - import { foundry } from "viem/chains"; + - import { MUDChain, latticeTestnet } from "@latticexyz/common/chains"; + + import { MUDChain, latticeTestnet, mudFoundry } from "@latticexyz/common/chains"; + + - export const supportedChains: MUDChain[] = [foundry, latticeTestnet]; + + export const supportedChains: MUDChain[] = [mudFoundry, latticeTestnet]; + ``` + + 3. In `getNetworkConfig.ts`, remove the return type (to let TS infer it for now), remove now-unused config values, and add the viem `chain` object. + + ```diff + - export async function getNetworkConfig(): Promise { + + export async function getNetworkConfig() { + ``` + + ```diff + const initialBlockNumber = params.has("initialBlockNumber") + ? Number(params.get("initialBlockNumber")) + - : world?.blockNumber ?? -1; // -1 will attempt to find the block number from RPC + + : world?.blockNumber ?? 0n; + ``` + + ```diff + + return { + + privateKey: getBurnerWallet().value, + + chain, + + worldAddress, + + initialBlockNumber, + + faucetServiceUrl: params.get("faucet") ?? chain.faucetUrl, + + }; + ``` + + 4. In `setupNetwork.ts`, replace `setupMUDV2Network` with `syncToRecs`. + + ```diff + - import { setupMUDV2Network } from "@latticexyz/std-client"; + - import { createFastTxExecutor, createFaucetService, getSnapSyncRecords } from "@latticexyz/network"; + + import { createFaucetService } from "@latticexyz/network"; + + import { createPublicClient, fallback, webSocket, http, createWalletClient, getContract, Hex, parseEther, ClientConfig } from "viem"; + + import { encodeEntity, syncToRecs } from "@latticexyz/store-sync/recs"; + + import { createBurnerAccount, createContract, transportObserver } from "@latticexyz/common"; + ``` + + ```diff + - const result = await setupMUDV2Network({ + - ... + - }); + + + const clientOptions = { + + chain: networkConfig.chain, + + transport: transportObserver(fallback([webSocket(), http()])), + + pollingInterval: 1000, + + } as const satisfies ClientConfig; + + + const publicClient = createPublicClient(clientOptions); + + + const burnerAccount = createBurnerAccount(networkConfig.privateKey as Hex); + + const burnerWalletClient = createWalletClient({ + + ...clientOptions, + + account: burnerAccount, + + }); + + + const { components, latestBlock$, blockStorageOperations$, waitForTransaction } = await syncToRecs({ + + world, + + config: storeConfig, + + address: networkConfig.worldAddress as Hex, + + publicClient, + + components: contractComponents, + + startBlock: BigInt(networkConfig.initialBlockNumber), + + indexerUrl: networkConfig.indexerUrl ?? undefined, + + }); + + + const worldContract = createContract({ + + address: networkConfig.worldAddress as Hex, + + abi: IWorld__factory.abi, + + publicClient, + + walletClient: burnerWalletClient, + + }); + ``` + + ```diff + // Request drip from faucet + - const signer = result.network.signer.get(); + - if (networkConfig.faucetServiceUrl && signer) { + - const address = await signer.getAddress(); + + if (networkConfig.faucetServiceUrl) { + + const address = burnerAccount.address; + ``` + + ```diff + const requestDrip = async () => { + - const balance = await signer.getBalance(); + + const balance = await publicClient.getBalance({ address }); + console.info(`[Dev Faucet]: Player balance -> ${balance}`); + - const lowBalance = balance?.lte(utils.parseEther("1")); + + const lowBalance = balance < parseEther("1"); + ``` + + You can remove the previous ethers `worldContract`, snap sync code, and fast transaction executor. + + The return of `setupNetwork` is a bit different than before, so you may have to do corresponding app changes. + + ```diff + + return { + + world, + + components, + + playerEntity: encodeEntity({ address: "address" }, { address: burnerWalletClient.account.address }), + + publicClient, + + walletClient: burnerWalletClient, + + latestBlock$, + + blockStorageOperations$, + + waitForTransaction, + + worldContract, + + }; + ``` + + 5. Update `createSystemCalls` with the new return type of `setupNetwork`. + + ```diff + export function createSystemCalls( + - { worldSend, txReduced$, singletonEntity }: SetupNetworkResult, + + { worldContract, waitForTransaction }: SetupNetworkResult, + { Counter }: ClientComponents + ) { + const increment = async () => { + - const tx = await worldSend("increment", []); + - await awaitStreamValue(txReduced$, (txHash) => txHash === tx.hash); + + const tx = await worldContract.write.increment(); + + await waitForTransaction(tx); + return getComponentValue(Counter, singletonEntity); + }; + ``` + + 6. (optional) If you still need a clock, you can create it with: + + ```ts + import { map, filter } from "rxjs"; + import { createClock } from "@latticexyz/network"; + + const clock = createClock({ + period: 1000, + initialTime: 0, + syncInterval: 5000, + }); + + world.registerDisposer(() => clock.dispose()); + + latestBlock$ + .pipe( + map((block) => Number(block.timestamp) * 1000), // Map to timestamp in ms + filter((blockTimestamp) => blockTimestamp !== clock.lastUpdateTime), // Ignore if the clock was already refreshed with this block + filter((blockTimestamp) => blockTimestamp !== clock.currentTime), // Ignore if the current local timestamp is correct + ) + .subscribe(clock.update); // Update the local clock + ``` + + If you're using the previous `LoadingState` component, you'll want to migrate to the new `SyncProgress`: + + ```ts + import { SyncStep, singletonEntity } from "@latticexyz/store-sync/recs"; + + const syncProgress = useComponentValue(SyncProgress, singletonEntity, { + message: "Connecting", + percentage: 0, + step: SyncStep.INITIALIZE, + }); + + if (syncProgress.step === SyncStep.LIVE) { + // we're live! + } + ``` + +- afdba793f: Update RECS components with v2 key/value schemas. This helps with encoding/decoding composite keys and strong types for keys/values. + + This may break if you were previously dependent on `component.id`, `component.metadata.componentId`, or `component.metadata.tableId`: + + - `component.id` is now the on-chain `bytes32` hex representation of the table ID + - `component.metadata.componentName` is the table name (e.g. `Position`) + - `component.metadata.tableName` is the namespaced table name (e.g. `myworld:Position`) + - `component.metadata.keySchema` is an object with key names and their corresponding ABI types + - `component.metadata.valueSchema` is an object with field names and their corresponding ABI types + +- Updated dependencies [52182f70d] +- Updated dependencies [aabd30767] +- Updated dependencies [b38c096d] +- Updated dependencies [f99e88987] +- Updated dependencies [48909d151] +- Updated dependencies [b02f9d0e4] +- Updated dependencies [bb91edaa0] +- Updated dependencies [590542030] +- Updated dependencies [f03531d97] +- Updated dependencies [b8a6158d6] +- Updated dependencies [92de59982] +- Updated dependencies [4e4a34150] +- Updated dependencies [535229984] +- Updated dependencies [d7b1c588a] + - @latticexyz/utils@2.0.0 + - @latticexyz/schema-type@2.0.0 + ## 2.0.0-next.18 ### Patch Changes diff --git a/packages/recs/package.json b/packages/recs/package.json index 0d94852b24..05e5fd68c8 100644 --- a/packages/recs/package.json +++ b/packages/recs/package.json @@ -1,6 +1,6 @@ { "name": "@latticexyz/recs", - "version": "2.0.0-next.18", + "version": "2.0.0", "repository": { "type": "git", "url": "https://github.com/latticexyz/mud.git", diff --git a/packages/schema-type/CHANGELOG.md b/packages/schema-type/CHANGELOG.md index d6ae65281c..a56627acc1 100644 --- a/packages/schema-type/CHANGELOG.md +++ b/packages/schema-type/CHANGELOG.md @@ -1,5 +1,42 @@ # Change Log +## 2.0.0 + +### Major Changes + +- aabd30767: Bumped Solidity version to 0.8.24. +- b38c096d: Moved all existing exports to a `/internal` import path to indicate that these are now internal-only and deprecated. We'll be replacing these types and functions with new ones that are compatible with our new, strongly-typed config. +- 92de59982: Bump Solidity version to 0.8.21 + +### Minor Changes + +- b02f9d0e4: add type narrowing `isStaticAbiType` +- bb91edaa0: Added `isSchemaAbiType` helper function to check and narrow an unknown string to the `SchemaAbiType` type +- d7b1c588a: Upgraded all packages and templates to viem v2.7.12 and abitype v1.0.0. + + Some viem APIs have changed and we've updated `getContract` to reflect those changes and keep it aligned with viem. It's one small code change: + + ```diff + const worldContract = getContract({ + address: worldAddress, + abi: IWorldAbi, + - publicClient, + - walletClient, + + client: { public: publicClient, wallet: walletClient }, + }); + ``` + +### Patch Changes + +- f99e88987: Bump viem to 1.14.0 and abitype to 0.9.8 +- 48909d151: bump forge-std and ds-test dependencies +- 590542030: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages. +- f03531d97: Fix byte lengths for `uint64` and `int64`. +- b8a6158d6: bump viem to 1.6.0 +- 535229984: - bump to viem 1.3.0 and abitype 0.9.3 + - move `@wagmi/chains` imports to `viem/chains` + - refine a few types + ## 2.0.0-next.18 ### Major Changes diff --git a/packages/schema-type/package.json b/packages/schema-type/package.json index b841c78779..2e33250b01 100644 --- a/packages/schema-type/package.json +++ b/packages/schema-type/package.json @@ -1,6 +1,6 @@ { "name": "@latticexyz/schema-type", - "version": "2.0.0-next.18", + "version": "2.0.0", "description": "SchemaType enum for various languages", "repository": { "type": "git", diff --git a/packages/services/CHANGELOG.md b/packages/services/CHANGELOG.md index dfc396e0a9..10355559fe 100644 --- a/packages/services/CHANGELOG.md +++ b/packages/services/CHANGELOG.md @@ -1,5 +1,30 @@ # Change Log +## 2.0.0 + +### Major Changes + +- 433078c54: Reverse PackedCounter encoding, to optimize gas for bitshifts. + Ints are right-aligned, shifting using an index is straightforward if they are indexed right-to-left. + + - Previous encoding: (7 bytes | accumulator),(5 bytes | counter 1),...,(5 bytes | counter 5) + - New encoding: (5 bytes | counter 5),...,(5 bytes | counter 1),(7 bytes | accumulator) + +- 331f0d636: Move `createFaucetService` from `@latticexyz/network` to `@latticexyz/services/faucet`. + + ```diff + - import { createFaucetService } from "@latticexyz/network"; + + import { createFaucetService } from "@latticexyz/services/faucet"; + ``` + +### Patch Changes + +- 3236f799e: protocol-parser in Go +- 33f50f8a4: Fixed an issue where the TypeScript types for createFaucetService were not exported correctly from the @latticexyz/services package +- 80a26419f: The build phase of services now works on machines with older protobuf compilers +- 590542030: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages. +- 086be4ef4: fix a bug related to encoding negative bigints in MODE + ## 2.0.0-next.18 ## 2.0.0-next.17 diff --git a/packages/services/package.json b/packages/services/package.json index 25569c486e..487d8c8ea5 100644 --- a/packages/services/package.json +++ b/packages/services/package.json @@ -1,6 +1,6 @@ { "name": "@latticexyz/services", - "version": "2.0.0-next.18", + "version": "2.0.0", "description": "MUD services for enhanced interactions with on-chain ECS state", "repository": { "type": "git", diff --git a/packages/solecs/CHANGELOG.md b/packages/solecs/CHANGELOG.md index 2e999c3bde..3e9a04ab1f 100644 --- a/packages/solecs/CHANGELOG.md +++ b/packages/solecs/CHANGELOG.md @@ -1,5 +1,15 @@ # @latticexyz/solecs +## 2.0.0 + +### Major Changes + +- ce7125a1b: Removes `solecs` package. These were v1 contracts, now entirely replaced by our v2 tooling. See the [MUD docs](https://mud.dev/) for building with v2 or create a new project from our v2 templates with `pnpm create mud@next your-app-name`. + +### Patch Changes + +- 48909d151: bump forge-std and ds-test dependencies + ## 2.0.0-next.18 ## 2.0.0-next.17 diff --git a/packages/solecs/package.json b/packages/solecs/package.json index 110f487e27..56c338cea6 100644 --- a/packages/solecs/package.json +++ b/packages/solecs/package.json @@ -1,5 +1,5 @@ { "name": "@latticexyz/solecs", - "version": "2.0.0-next.18", + "version": "2.0.0", "private": true } diff --git a/packages/solhint-config-mud/CHANGELOG.md b/packages/solhint-config-mud/CHANGELOG.md index 7a7653ec6e..d987fa286d 100644 --- a/packages/solhint-config-mud/CHANGELOG.md +++ b/packages/solhint-config-mud/CHANGELOG.md @@ -1,5 +1,7 @@ # Change Log +## 2.0.0 + ## 2.0.0-next.18 ## 2.0.0-next.17 diff --git a/packages/solhint-config-mud/package.json b/packages/solhint-config-mud/package.json index 390931f6e5..8f83d92777 100644 --- a/packages/solhint-config-mud/package.json +++ b/packages/solhint-config-mud/package.json @@ -1,6 +1,6 @@ { "name": "solhint-config-mud", - "version": "2.0.0-next.18", + "version": "2.0.0", "repository": { "type": "git", "url": "https://github.com/latticexyz/mud.git", diff --git a/packages/solhint-plugin-mud/CHANGELOG.md b/packages/solhint-plugin-mud/CHANGELOG.md index 7a7653ec6e..d987fa286d 100644 --- a/packages/solhint-plugin-mud/CHANGELOG.md +++ b/packages/solhint-plugin-mud/CHANGELOG.md @@ -1,5 +1,7 @@ # Change Log +## 2.0.0 + ## 2.0.0-next.18 ## 2.0.0-next.17 diff --git a/packages/solhint-plugin-mud/package.json b/packages/solhint-plugin-mud/package.json index 08742b9760..d780146cbb 100644 --- a/packages/solhint-plugin-mud/package.json +++ b/packages/solhint-plugin-mud/package.json @@ -1,6 +1,6 @@ { "name": "solhint-plugin-mud", - "version": "2.0.0-next.18", + "version": "2.0.0", "repository": { "type": "git", "url": "https://github.com/latticexyz/mud.git", diff --git a/packages/std-client/CHANGELOG.md b/packages/std-client/CHANGELOG.md index 92c7a96edf..49a8e35e90 100644 --- a/packages/std-client/CHANGELOG.md +++ b/packages/std-client/CHANGELOG.md @@ -1,5 +1,105 @@ # @latticexyz/std-client +## 2.0.0 + +### Major Changes + +- c14f8bf1e: - Moved `createActionSystem` from `std-client` to `recs` package and updated it to better support v2 sync stack. + + If you want to use `createActionSystem` alongside `syncToRecs`, you'll need to pass in arguments like so: + + ```ts + import { syncToRecs } from "@latticexyz/store-sync/recs"; + import { createActionSystem } from "@latticexyz/recs/deprecated"; + import { from, mergeMap } from "rxjs"; + + const { blockLogsStorage$, waitForTransaction } = syncToRecs({ + world, + ... + }); + + const txReduced$ = blockLogsStorage$.pipe( + mergeMap(({ operations }) => from(operations.map((op) => op.log?.transactionHash).filter(isDefined))) + ); + + const actionSystem = createActionSystem(world, txReduced$, waitForTransaction); + ``` + + - Fixed a bug in `waitForComponentValueIn` that caused the promise to not resolve if the component value was already set when the function was called. + - Fixed a bug in `createActionSystem` that caused optimistic updates to be incorrectly propagated to requirement checks. To fix the bug, you must now pass in the full component object to the action's `updates` instead of just the component name. + + ```diff + actions.add({ + updates: () => [ + { + - component: "Resource", + + component: Resource, + ... + } + ], + ... + }); + ``` + +- c03aff39e: Removes `std-client` package. Please see the [changelog](https://mud.dev/changelog) for how to migrate your app to the new `store-sync` package. Or create a new project from an up-to-date template with `pnpm create mud@next your-app-name`. +- 48c51b52a: RECS components are now dynamically created and inferred from your MUD config when using `syncToRecs`. + + To migrate existing projects after upgrading to this MUD version: + + 1. Remove `contractComponents.ts` from `client/src/mud` + 2. Remove `components` argument from `syncToRecs` + 3. Update `build:mud` and `dev` scripts in `contracts/package.json` to remove tsgen + + ```diff + - "build:mud": "mud tablegen && mud worldgen && mud tsgen --configPath mud.config.ts --out ../client/src/mud", + + "build:mud": "mud tablegen && mud worldgen", + ``` + + ```diff + - "dev": "pnpm mud dev-contracts --tsgenOutput ../client/src/mud", + + "dev": "pnpm mud dev-contracts", + ``` + +- 331f0d636: Deprecate `@latticexyz/std-client` and remove v1 network dependencies. + + - `getBurnerWallet` is replaced by `getBurnerPrivateKey` from `@latticexyz/common`. It now returns a `Hex` string instead of an `rxjs` `BehaviorSubject`. + + ``` + - import { getBurnerWallet } from "@latticexyz/std-client"; + + import { getBurnerPrivateKey } from "@latticexyz/common"; + + - const privateKey = getBurnerWallet().value; + - const privateKey = getBurnerPrivateKey(); + ``` + + - All functions from `std-client` that depended on v1 network code are removed (most notably `setupMUDNetwork` and `setupMUDV2Network`). Consumers should upgrade to v2 networking code from `@latticexyz/store-sync`. + - The following functions are removed from `std-client` because they are very use-case specific and depend on deprecated code: `getCurrentTurn`, `getTurnAtTime`, `getGameConfig`, `isUntraversable`, `getPlayerEntity`, `resolveRelationshipChain`, `findEntityWithComponentInRelationshipChain`, `findInRelationshipChain`. Consumers should vendor these functions if they are still needed. + - Remaining exports from `std-client` are moved to `/deprecated`. The package will be removed in a future release (once there are replacements for the deprecated exports). + + ```diff + - import { ... } from "@latticexyz/std-client"; + + import { ... } from "@latticexyz/std-client/deprecated"; + ``` + +### Patch Changes + +- ce7125a1b: Removes `solecs` package. These were v1 contracts, now entirely replaced by our v2 tooling. See the [MUD docs](https://mud.dev/) for building with v2 or create a new project from our v2 templates with `pnpm create mud@next your-app-name`. +- e259ef79f: Generated `contractComponents` now properly import `World` as type +- b8a6158d6: bump viem to 1.6.0 +- 535229984: - bump to viem 1.3.0 and abitype 0.9.3 + - move `@wagmi/chains` imports to `viem/chains` + - refine a few types +- 6c6733256: Add `tableIdToHex` and `hexToTableId` pure functions and move/deprecate `TableId`. +- afdba793f: Update RECS components with v2 key/value schemas. This helps with encoding/decoding composite keys and strong types for keys/values. + + This may break if you were previously dependent on `component.id`, `component.metadata.componentId`, or `component.metadata.tableId`: + + - `component.id` is now the on-chain `bytes32` hex representation of the table ID + - `component.metadata.componentName` is the table name (e.g. `Position`) + - `component.metadata.tableName` is the namespaced table name (e.g. `myworld:Position`) + - `component.metadata.keySchema` is an object with key names and their corresponding ABI types + - `component.metadata.valueSchema` is an object with field names and their corresponding ABI types + ## 2.0.0-next.18 ## 2.0.0-next.17 diff --git a/packages/std-client/package.json b/packages/std-client/package.json index 771bf2cad4..b02be1c423 100644 --- a/packages/std-client/package.json +++ b/packages/std-client/package.json @@ -1,5 +1,5 @@ { "name": "@latticexyz/std-client", - "version": "2.0.0-next.18", + "version": "2.0.0", "private": true } diff --git a/packages/std-contracts/CHANGELOG.md b/packages/std-contracts/CHANGELOG.md index a6c1f53309..d24f3d883c 100644 --- a/packages/std-contracts/CHANGELOG.md +++ b/packages/std-contracts/CHANGELOG.md @@ -1,5 +1,35 @@ # @latticexyz/std-contracts +## 2.0.0 + +### Major Changes + +- c32c8e8f2: Removes `std-contracts` package. These were v1 contracts, now entirely replaced by our v2 tooling. See the [MUD docs](https://mud.dev/) for building with v2 or create a new project from our v2 templates with `pnpm create mud@next your-app-name`. + +### Minor Changes + +- a7b30c79b: Rename `MudV2Test` to `MudTest` and move from `@latticexyz/std-contracts` to `@latticexyz/store`. + + ```solidity + // old import + import { MudV2Test } from "@latticexyz/std-contracts/src/test/MudV2Test.t.sol"; + // new import + import { MudTest } from "@latticexyz/store/src/MudTest.sol"; + ``` + + Refactor `StoreSwitch` to use a storage slot instead of `function isStore()` to determine which contract is Store: + + - Previously `StoreSwitch` called `isStore()` on `msg.sender` to determine if `msg.sender` is a `Store` contract. If the call succeeded, the `Store` methods were called on `msg.sender`, otherwise the data was written to the own storage. + - With this change `StoreSwitch` instead checks for an `address` in a known storage slot. If the address equals the own address, data is written to the own storage. If it is an external address, `Store` methods are called on this address. If it is unset (`address(0)`), store methods are called on `msg.sender`. + - In practice this has the same effect as before: By default the `World` contracts sets its own address in `StoreSwitch`, while `System` contracts keep the Store address undefined, so `Systems` write to their caller (`World`) if they are executed via `call` or directly to the `World` storage if they are executed via `delegatecall`. + - Besides gas savings, this change has two additional benefits: + 1. it is now possible for `Systems` to explicitly set a `Store` address to make them exclusive to that `Store` and + 2. table libraries can now be used in tests without having to provide an explicit `Store` argument, because the `MudTest` base contract redirects reads and writes to the internal `World` contract. + +### Patch Changes + +- 48909d151: bump forge-std and ds-test dependencies + ## 2.0.0-next.18 ## 2.0.0-next.17 diff --git a/packages/std-contracts/package.json b/packages/std-contracts/package.json index f47139b41d..bffec8f40f 100644 --- a/packages/std-contracts/package.json +++ b/packages/std-contracts/package.json @@ -1,5 +1,5 @@ { "name": "@latticexyz/std-contracts", - "version": "2.0.0-next.18", + "version": "2.0.0", "private": true } diff --git a/packages/store-cache/CHANGELOG.md b/packages/store-cache/CHANGELOG.md index 590df1a769..f8df1fc9bb 100644 --- a/packages/store-cache/CHANGELOG.md +++ b/packages/store-cache/CHANGELOG.md @@ -1,5 +1,19 @@ # @latticexyz/store-cache +## 2.0.0 + +### Major Changes + +- e3de1a338: Removes `store-cache` package. Please see the [changelog](https://mud.dev/changelog) for how to migrate your app to the new `store-sync` package. Or create a new project from an up-to-date template with `pnpm create mud@next your-app-name`. + + If you need reactivity, we recommend using `recs` package and `syncToRecs`. We'll be adding reactivity to `syncToSqlite` in a future release. + +### Patch Changes + +- 535229984: - bump to viem 1.3.0 and abitype 0.9.3 + - move `@wagmi/chains` imports to `viem/chains` + - refine a few types + ## 2.0.0-next.18 ## 2.0.0-next.17 diff --git a/packages/store-cache/package.json b/packages/store-cache/package.json index 9391df4fc2..5a85159f6a 100644 --- a/packages/store-cache/package.json +++ b/packages/store-cache/package.json @@ -1,5 +1,5 @@ { "name": "@latticexyz/store-cache", - "version": "2.0.0-next.18", + "version": "2.0.0", "private": true } diff --git a/packages/store-indexer/CHANGELOG.md b/packages/store-indexer/CHANGELOG.md index 57fdcfb495..e19b0e8308 100644 --- a/packages/store-indexer/CHANGELOG.md +++ b/packages/store-indexer/CHANGELOG.md @@ -1,5 +1,605 @@ # @latticexyz/store-indexer +## 2.0.0 + +### Major Changes + +- e86fbc126: Adds store indexer service package with utils to query the indexer service. + + You can run the indexer locally by checking out the MUD monorepo, installing/building everything, and running `pnpm start:local` from `packages/store-indexer`. + + To query the indexer in the client, you can create a tRPC client with a URL pointing to the indexer service and call the available tRPC methods: + + ```ts + import { createIndexerClient } from "@latticexyz/store-sync/trpc-indexer"; + + const indexer = createIndexerClient({ url: indexerUrl }); + const result = await indexer.findAll.query({ + chainId: publicClient.chain.id, + address, + }); + ``` + + If you're using `syncToRecs`, you can just pass in the `indexerUrl` option as a shortcut to the above: + + ```ts + import { syncToRecs } from "@latticexyz/store-sync/recs"; + + syncToRecs({ + ... + indexerUrl: "https://your.indexer.service", + }); + ``` + +- f6d214e3d: Removed `tableIds` filter option in favor of the more flexible `filters` option that accepts `tableId` and an optional `key0` and/or `key1` to filter data by tables and keys. + + If you were using an indexer client directly, you'll need to update your query: + + ```diff + await indexer.findAll.query({ + chainId, + address, + - tableIds: ['0x...'], + + filters: [{ tableId: '0x...' }], + }); + ``` + +- b621fb977: Adds a [Fastify](https://fastify.dev/) server in front of tRPC and puts tRPC endpoints under `/trpc` to make way for other top-level endpoints (e.g. [tRPC panel](https://github.com/iway1/trpc-panel) or other API frontends like REST or gRPC). + + If you're using `@latticexyz/store-sync` packages with an indexer (either `createIndexerClient` or `indexerUrl` argument of `syncToRecs`), then you'll want to update your indexer URL: + + ```diff + createIndexerClient({ + - url: "https://indexer.dev.linfra.xyz", + + url: "https://indexer.dev.linfra.xyz/trpc", + }); + ``` + + ```diff + syncToRecs({ + ... + - indexerUrl: "https://indexer.dev.linfra.xyz", + + indexerUrl: "https://indexer.dev.linfra.xyz/trpc", + }); + ``` + +- 85b94614b: The postgres indexer is now storing the `logIndex` of the last update of a record to be able to return the snapshot logs in the order they were emitted onchain. +- 5ecccfe75: Separated frontend server and indexer service for Postgres indexer. Now you can run the Postgres indexer with one writer and many readers. + + If you were previously using the `postgres-indexer` binary, you'll now need to run both `postgres-indexer` and `postgres-frontend`. + + For consistency, the Postgres database logs are now disabled by default. If you were using these, please let us know so we can add them back in with an environment variable flag. + +- adc68225: PostgreSQL sync/indexer now uses `{storeAddress}` for its database schema names and `{namespace}__{tableName}` for its database table names (or just `{tableName}` for root namespace), to be more consistent with the rest of the MUD codebase. + + For namespaced tables: + + ```diff + - SELECT * FROM 0xfff__some_ns.some_table + + SELECT * FROM 0xfff.some_ns__some_table + ``` + + For root tables: + + ```diff + - SELECT * FROM 0xfff__.some_table + + SELECT * FROM 0xfff.some_table + ``` + + SQLite sync/indexer now uses snake case for its table names and column names for easier writing of queries and to better match PostgreSQL sync/indexer naming. + + ```diff + - SELECT * FROM 0xfFf__someNS__someTable + + SELECT * FROM 0xfff__some_ns__some_table + ``` + +### Minor Changes + +- 3622e39dd: Added a `followBlockTag` option to configure which block number to follow when running `createStoreSync`. It defaults to `latest` (current behavior), which is recommended for individual clients so that you always have the latest chain state. + + Indexers now default to `safe` to avoid issues with reorgs and load-balanced RPCs being out of sync. This means indexers will be slightly behind the latest block number, but clients can quickly catch up. Indexers can override this setting using `FOLLOW_BLOCK_TAG` environment variable. + +- 131c63e53: - Accept a plain viem `PublicClient` (instead of requiring a `Chain` to be set) in `store-sync` and `store-indexer` functions. These functions now fetch chain ID using `publicClient.getChainId()` when no `publicClient.chain.id` is present. + - Allow configuring `store-indexer` with a set of RPC URLs (`RPC_HTTP_URL` and `RPC_WS_URL`) instead of `CHAIN_ID`. +- 4081493b8: Added a `tableIds` parameter to store sync methods and indexer to allow filtering data streams by table IDs. Store sync methods automatically include all internal table IDs from Store and World. + + ```ts + import { syncToRecs } from "@latticexyz/store-sync/recs"; + import { resourceIdToHex } from "@latticexyz/common"; + + syncToRecs({ + ... + tableIds: [resourceIdToHex(...)], + }); + ``` + + ```ts + import { createIndexerClient } from "@latticexyz/store-sync/trpc-indexer"; + import { resourceIdToHex } from "@latticexyz/common"; + + const client = createIndexerClient({ ... }); + client.findAll({ + ... + tableIds: [resourceIdToHex(...)], + }); + ``` + +- 498d05e36: You can now install and run `@latticexyz/store-indexer` from the npm package itself, without having to clone/build the MUD repo: + + ```sh + npm install @latticexyz/store-indexer + + npm sqlite-indexer + # or + npm postgres-indexer + ``` + + or + + ```sh + npx -p @latticexyz/store-indexer sqlite-indexer + # or + npx -p @latticexyz/store-indexer postgres-indexer + ``` + + The binary will also load the nearby `.env` file for easier local configuration. + + We've removed the `CHAIN_ID` requirement and instead require just a `RPC_HTTP_URL` or `RPC_WS_URL` or both. You can now also adjust the polling interval with `POLLING_INTERVAL` (defaults to 1000ms, which corresponds to MUD's default block time). + +- 1b5eb0d07: The `findAll` method is now considered deprecated in favor of a new `getLogs` method. This is only implemented in the Postgres indexer for now, with SQLite coming soon. The new `getLogs` method will be an easier and more robust data source to hydrate the client and other indexers and will allow us to add streaming updates from the indexer in the near future. + + For backwards compatibility, `findAll` is now implemented on top of `getLogs`, with record key/value decoding done in memory at request time. This may not scale for large databases, so use wisely. + +- 753bdce41: Store sync logic is now consolidated into a `createStoreSync` function exported from `@latticexyz/store-sync`. This simplifies each storage sync strategy to just a simple wrapper around the storage adapter. You can now sync to RECS with `syncToRecs` or SQLite with `syncToSqlite` and PostgreSQL support coming soon. + + There are no breaking changes if you were just using `syncToRecs` from `@latticexyz/store-sync` or running the `sqlite-indexer` binary from `@latticexyz/store-indexer`. + +- e48fb3b03: When the Postgres indexer starts up, it will now attempt to detect if the database is outdated and, if so, cleans up all MUD-related schemas and tables before proceeding. +- 1d0f7e22b: Added `/healthz` and `/readyz` healthcheck endpoints for Kubernetes +- d7b1c588a: Upgraded all packages and templates to viem v2.7.12 and abitype v1.0.0. + + Some viem APIs have changed and we've updated `getContract` to reflect those changes and keep it aligned with viem. It's one small code change: + + ```diff + const worldContract = getContract({ + address: worldAddress, + abi: IWorldAbi, + - publicClient, + - walletClient, + + client: { public: publicClient, wallet: walletClient }, + }); + ``` + +- 5df1f31bc: Added `getLogs` query support to sqlite indexer +- 4c1dcd81e: - Improved query performance by 10x by moving from drizzle ORM to handcrafted SQL. + + - Moved away from `trpc` for more granular control over the transport layer. + Added an `/api/logs` endpoint using the new query and gzip compression for 40x less data transferred over the wire. + Deprecated the `/trpc/getLogs` and `/trpc/findAll` endpoints. + - Added a `createIndexerClient` client for the new `/api` indexer API exported from `@latticexyz/store-sync/indexer-client`. + The `createIndexerClient` export from `@latticexyz/store-sync/trpc-indexer` is deprecated. + + ```diff + - import { createIndexerClient } from "@latticexyz/store-sync/trpc-indexer"; + + import { createIndexerClient } from "@latticexyz/store-sync/indexer-client"; + + - const indexer = createIndexerClient({ url: "https://indexer.holesky.redstone.xyz/trpc" }); + + const indexer = createIndexerClient({ url: "https://indexer.holesky.redstone.xyz" }); + + - const snapshot = indexer.getLogs.query(options); + + const snapshot = indexer.getLogs(options); + ``` + +- f61b4bc09: The `/api/logs` indexer endpoint is now returning a `404` snapshot not found error when no snapshot is found for the provided filter instead of an empty `200` response. +- f318f2fe7: Added `STORE_ADDRESS` environment variable to index only a specific MUD Store. + +### Patch Changes + +- 504e25dc8: Records are now ordered by `lastUpdatedBlockNumber` at the Postgres SQL query level +- ed07018b8: Fixes postgres indexer stopping sync after it catches up to the latest block. +- b00550cef: Added a script to run the decoded postgres indexer. +- 0a3b9b1c9: Added explicit error logs for unexpected situations. + Previously all `debug` logs were going to `stderr`, which made it hard to find the unexpected errors. + Now `debug` logs go to `stdout` and we can add explicit `stderr` logs. +- f99e88987: Bump viem to 1.14.0 and abitype to 0.9.8 +- 85d16e48b: Added a Sentry middleware and `SENTRY_DNS` environment variable to the postgres indexer. +- c314badd1: Replaced Fastify with Koa for store-indexer frontends +- 301bcb75d: Improves error message when parsing env variables +- b8a6158d6: bump viem to 1.6.0 +- 392c4b88d: Disabled prepared statements for the postgres indexer, which led to issues in combination with `pgBouncer`. +- 5d737cf2e: Updated the `debug` util to pipe to `stdout` and added an additional util to explicitly pipe to `stderr` when needed. +- 5ab67e335: The error log if no data is found in `/api/logs` is now stringifying the filter instead of logging `[object Object]`. +- 735d957c6: Added a binary for the `postgres-decoded` indexer. +- 60cfd089f: Templates and examples now use MUD's new sync packages, all built on top of [viem](https://viem.sh/). This greatly speeds up and stabilizes our networking code and improves types throughout. + + These new sync packages come with support for our `recs` package, including `encodeEntity` and `decodeEntity` utilities for composite keys. + + If you're using `store-cache` and `useRow`/`useRows`, you should wait to upgrade until we have a suitable replacement for those libraries. We're working on a [sql.js](https://github.com/sql-js/sql.js/)-powered sync module that will replace `store-cache`. + + **Migrate existing RECS apps to new sync packages** + + As you migrate, you may find some features replaced, removed, or not included by default. Please [open an issue](https://github.com/latticexyz/mud/issues/new) and let us know if we missed anything. + + 1. Add `@latticexyz/store-sync` package to your app's `client` package and make sure `viem` is pinned to version `1.3.1` (otherwise you may get type errors) + 2. In your `supportedChains.ts`, replace `foundry` chain with our new `mudFoundry` chain. + + ```diff + - import { foundry } from "viem/chains"; + - import { MUDChain, latticeTestnet } from "@latticexyz/common/chains"; + + import { MUDChain, latticeTestnet, mudFoundry } from "@latticexyz/common/chains"; + + - export const supportedChains: MUDChain[] = [foundry, latticeTestnet]; + + export const supportedChains: MUDChain[] = [mudFoundry, latticeTestnet]; + ``` + + 3. In `getNetworkConfig.ts`, remove the return type (to let TS infer it for now), remove now-unused config values, and add the viem `chain` object. + + ```diff + - export async function getNetworkConfig(): Promise { + + export async function getNetworkConfig() { + ``` + + ```diff + const initialBlockNumber = params.has("initialBlockNumber") + ? Number(params.get("initialBlockNumber")) + - : world?.blockNumber ?? -1; // -1 will attempt to find the block number from RPC + + : world?.blockNumber ?? 0n; + ``` + + ```diff + + return { + + privateKey: getBurnerWallet().value, + + chain, + + worldAddress, + + initialBlockNumber, + + faucetServiceUrl: params.get("faucet") ?? chain.faucetUrl, + + }; + ``` + + 4. In `setupNetwork.ts`, replace `setupMUDV2Network` with `syncToRecs`. + + ```diff + - import { setupMUDV2Network } from "@latticexyz/std-client"; + - import { createFastTxExecutor, createFaucetService, getSnapSyncRecords } from "@latticexyz/network"; + + import { createFaucetService } from "@latticexyz/network"; + + import { createPublicClient, fallback, webSocket, http, createWalletClient, getContract, Hex, parseEther, ClientConfig } from "viem"; + + import { encodeEntity, syncToRecs } from "@latticexyz/store-sync/recs"; + + import { createBurnerAccount, createContract, transportObserver } from "@latticexyz/common"; + ``` + + ```diff + - const result = await setupMUDV2Network({ + - ... + - }); + + + const clientOptions = { + + chain: networkConfig.chain, + + transport: transportObserver(fallback([webSocket(), http()])), + + pollingInterval: 1000, + + } as const satisfies ClientConfig; + + + const publicClient = createPublicClient(clientOptions); + + + const burnerAccount = createBurnerAccount(networkConfig.privateKey as Hex); + + const burnerWalletClient = createWalletClient({ + + ...clientOptions, + + account: burnerAccount, + + }); + + + const { components, latestBlock$, blockStorageOperations$, waitForTransaction } = await syncToRecs({ + + world, + + config: storeConfig, + + address: networkConfig.worldAddress as Hex, + + publicClient, + + components: contractComponents, + + startBlock: BigInt(networkConfig.initialBlockNumber), + + indexerUrl: networkConfig.indexerUrl ?? undefined, + + }); + + + const worldContract = createContract({ + + address: networkConfig.worldAddress as Hex, + + abi: IWorld__factory.abi, + + publicClient, + + walletClient: burnerWalletClient, + + }); + ``` + + ```diff + // Request drip from faucet + - const signer = result.network.signer.get(); + - if (networkConfig.faucetServiceUrl && signer) { + - const address = await signer.getAddress(); + + if (networkConfig.faucetServiceUrl) { + + const address = burnerAccount.address; + ``` + + ```diff + const requestDrip = async () => { + - const balance = await signer.getBalance(); + + const balance = await publicClient.getBalance({ address }); + console.info(`[Dev Faucet]: Player balance -> ${balance}`); + - const lowBalance = balance?.lte(utils.parseEther("1")); + + const lowBalance = balance < parseEther("1"); + ``` + + You can remove the previous ethers `worldContract`, snap sync code, and fast transaction executor. + + The return of `setupNetwork` is a bit different than before, so you may have to do corresponding app changes. + + ```diff + + return { + + world, + + components, + + playerEntity: encodeEntity({ address: "address" }, { address: burnerWalletClient.account.address }), + + publicClient, + + walletClient: burnerWalletClient, + + latestBlock$, + + blockStorageOperations$, + + waitForTransaction, + + worldContract, + + }; + ``` + + 5. Update `createSystemCalls` with the new return type of `setupNetwork`. + + ```diff + export function createSystemCalls( + - { worldSend, txReduced$, singletonEntity }: SetupNetworkResult, + + { worldContract, waitForTransaction }: SetupNetworkResult, + { Counter }: ClientComponents + ) { + const increment = async () => { + - const tx = await worldSend("increment", []); + - await awaitStreamValue(txReduced$, (txHash) => txHash === tx.hash); + + const tx = await worldContract.write.increment(); + + await waitForTransaction(tx); + return getComponentValue(Counter, singletonEntity); + }; + ``` + + 6. (optional) If you still need a clock, you can create it with: + + ```ts + import { map, filter } from "rxjs"; + import { createClock } from "@latticexyz/network"; + + const clock = createClock({ + period: 1000, + initialTime: 0, + syncInterval: 5000, + }); + + world.registerDisposer(() => clock.dispose()); + + latestBlock$ + .pipe( + map((block) => Number(block.timestamp) * 1000), // Map to timestamp in ms + filter((blockTimestamp) => blockTimestamp !== clock.lastUpdateTime), // Ignore if the clock was already refreshed with this block + filter((blockTimestamp) => blockTimestamp !== clock.currentTime), // Ignore if the current local timestamp is correct + ) + .subscribe(clock.update); // Update the local clock + ``` + + If you're using the previous `LoadingState` component, you'll want to migrate to the new `SyncProgress`: + + ```ts + import { SyncStep, singletonEntity } from "@latticexyz/store-sync/recs"; + + const syncProgress = useComponentValue(SyncProgress, singletonEntity, { + message: "Connecting", + percentage: 0, + step: SyncStep.INITIALIZE, + }); + + if (syncProgress.step === SyncStep.LIVE) { + // we're live! + } + ``` + +- b3c22a183: Added README and refactored handling of common environment variables +- Updated dependencies [7ce82b6fc] +- Updated dependencies [5df1f31bc] +- Updated dependencies [d8c8f66bf] +- Updated dependencies [c6c13f2ea] +- Updated dependencies [1b86eac05] +- Updated dependencies [a35c05ea9] +- Updated dependencies [c9ee5e4a] +- Updated dependencies [3622e39dd] +- Updated dependencies [c963b46c7] +- Updated dependencies [08d7c471f] +- Updated dependencies [05b3e8882] +- Updated dependencies [16b13ea8f] +- Updated dependencies [aea67c580] +- Updated dependencies [82693072] +- Updated dependencies [07dd6f32c] +- Updated dependencies [90e4161bb] +- Updated dependencies [aabd30767] +- Updated dependencies [65c9546c4] +- Updated dependencies [331dbfdcb] +- Updated dependencies [504e25dc8] +- Updated dependencies [e86fbc126] +- Updated dependencies [d5c0682fb] +- Updated dependencies [1d60930d6] +- Updated dependencies [01e46d99] +- Updated dependencies [f9f9609ef] +- Updated dependencies [904fd7d4e] +- Updated dependencies [e6c03a87a] +- Updated dependencies [1077c7f53] +- Updated dependencies [de47d698f] +- Updated dependencies [e48fb3b03] +- Updated dependencies [2c920de7] +- Updated dependencies [b98e51808] +- Updated dependencies [0a3b9b1c9] +- Updated dependencies [b9e562d8f] +- Updated dependencies [331dbfdcb] +- Updated dependencies [44236041f] +- Updated dependencies [066056154] +- Updated dependencies [759514d8b] +- Updated dependencies [952cd5344] +- Updated dependencies [d5094a242] +- Updated dependencies [6c615b608] +- Updated dependencies [3fb9ce283] +- Updated dependencies [bb6ada740] +- Updated dependencies [85b94614b] +- Updated dependencies [35c9f33df] +- Updated dependencies [a25881160] +- Updated dependencies [a4aff73c5] +- Updated dependencies [0b8ce3f2c] +- Updated dependencies [933b54b5f] +- Updated dependencies [c4d5eb4e4] +- Updated dependencies [57a526083] +- Updated dependencies [f62c767e7] +- Updated dependencies [9e5baf4ff] +- Updated dependencies [9aa5e786] +- Updated dependencies [307abab3] +- Updated dependencies [de151fec0] +- Updated dependencies [37c228c63] +- Updated dependencies [aacffcb59] +- Updated dependencies [c991c71a] +- Updated dependencies [1faf7f697] +- Updated dependencies [ae340b2bf] +- Updated dependencies [1bf2e9087] +- Updated dependencies [b38c096d] +- Updated dependencies [211be2a1e] +- Updated dependencies [0f3e2e02b] +- Updated dependencies [4bb7e8cbf] +- Updated dependencies [131c63e53] +- Updated dependencies [712866f5f] +- Updated dependencies [d08789282] +- Updated dependencies [5c965a919] +- Updated dependencies [f99e88987] +- Updated dependencies [939916bcd] +- Updated dependencies [d5b73b126] +- Updated dependencies [e34d1170] +- Updated dependencies [b8a6158d6] +- Updated dependencies [190fdd11] +- Updated dependencies [4e445a1ab] +- Updated dependencies [433078c54] +- Updated dependencies [669fa43e5] +- Updated dependencies [db314a74] +- Updated dependencies [b2d2aa715] +- Updated dependencies [ca50fef81] +- Updated dependencies [83583a505] +- Updated dependencies [5e723b90e] +- Updated dependencies [582388ba5] +- Updated dependencies [6573e38e9] +- Updated dependencies [eeb15cc06] +- Updated dependencies [afaf2f5ff] +- Updated dependencies [37c228c63] +- Updated dependencies [59267655] +- Updated dependencies [37c228c63] +- Updated dependencies [997286bac] +- Updated dependencies [72b806979] +- Updated dependencies [4081493b8] +- Updated dependencies [44a5432ac] +- Updated dependencies [6e66c5b74] +- Updated dependencies [582388ba5] +- Updated dependencies [8d51a0348] +- Updated dependencies [c162ad5a5] +- Updated dependencies [a735e14b4] +- Updated dependencies [65c9546c4] +- Updated dependencies [48909d151] +- Updated dependencies [7b28d32e5] +- Updated dependencies [f8a01a047] +- Updated dependencies [3e024fcf3] +- Updated dependencies [f62c767e7] +- Updated dependencies [590542030] +- Updated dependencies [1b5eb0d07] +- Updated dependencies [44a5432ac] +- Updated dependencies [48c51b52a] +- Updated dependencies [9f8b84e73] +- Updated dependencies [66cc35a8c] +- Updated dependencies [672d05ca1] +- Updated dependencies [55a05fd7a] +- Updated dependencies [7e6e5157b] +- Updated dependencies [63831a264] +- Updated dependencies [b8a6158d6] +- Updated dependencies [6db95ce15] +- Updated dependencies [8193136a9] +- Updated dependencies [5d737cf2e] +- Updated dependencies [d075f82f3] +- Updated dependencies [331dbfdcb] +- Updated dependencies [a7b30c79b] +- Updated dependencies [92de59982] +- Updated dependencies [22ee44700] +- Updated dependencies [1327ea8c8] +- Updated dependencies [ad4ac4459] +- Updated dependencies [f6d214e3d] +- Updated dependencies [3f5d33af] +- Updated dependencies [b8a6158d6] +- Updated dependencies [be313068b] +- Updated dependencies [ac508bf18] +- Updated dependencies [331dbfdcb] +- Updated dependencies [9ff4dd955] +- Updated dependencies [93390d89] +- Updated dependencies [fa7763583] +- Updated dependencies [bb91edaa0] +- Updated dependencies [144c0d8d] +- Updated dependencies [5ac4c97f4] +- Updated dependencies [bfcb293d1] +- Updated dependencies [3e057061d] +- Updated dependencies [1890f1a06] +- Updated dependencies [e48171741] +- Updated dependencies [753bdce41] +- Updated dependencies [5294a7d59] +- Updated dependencies [69a96f109] +- Updated dependencies [9b43029c3] +- Updated dependencies [37c228c63] +- Updated dependencies [55ab88a60] +- Updated dependencies [c58da9ad] +- Updated dependencies [37c228c63] +- Updated dependencies [b8a6158d6] +- Updated dependencies [535229984] +- Updated dependencies [af639a264] +- Updated dependencies [5e723b90e] +- Updated dependencies [99ab9cd6f] +- Updated dependencies [0c4f9fea9] +- Updated dependencies [0d12db8c2] +- Updated dependencies [c049c23f4] +- Updated dependencies [80dd6992e] +- Updated dependencies [60cfd089f] +- Updated dependencies [34203e4ed] +- Updated dependencies [24a6cd536] +- Updated dependencies [37c228c63] +- Updated dependencies [708b49c50] +- Updated dependencies [d2f8e9400] +- Updated dependencies [25086be5f] +- Updated dependencies [b1d41727d] +- Updated dependencies [3ac68ade6] +- Updated dependencies [22ba7b675] +- Updated dependencies [4c1dcd81e] +- Updated dependencies [3042f86e] +- Updated dependencies [5e71e1cb5] +- Updated dependencies [7eabd06f7] +- Updated dependencies [6071163f7] +- Updated dependencies [6c6733256] +- Updated dependencies [cd5abcc3b] +- Updated dependencies [d7b1c588a] +- Updated dependencies [5c52bee09] +- Updated dependencies [8025c3505] +- Updated dependencies [c4f49240d] +- Updated dependencies [745485cda] +- Updated dependencies [37c228c63] +- Updated dependencies [3e7d83d0] +- Updated dependencies [5df1f31bc] +- Updated dependencies [a2f41ade9] +- Updated dependencies [cea754dde] +- Updated dependencies [5e71e1cb5] +- Updated dependencies [331f0d636] +- Updated dependencies [1b5eb0d07] +- Updated dependencies [d2f8e9400] +- Updated dependencies [4c1dcd81e] +- Updated dependencies [adc68225] +- Updated dependencies [cc2c8da00] +- Updated dependencies [252a1852] +- Updated dependencies [7b73f44d9] +- Updated dependencies [103f635eb] + - @latticexyz/store@2.0.0 + - @latticexyz/store-sync@2.0.0 + - @latticexyz/common@2.0.0 + - @latticexyz/protocol-parser@2.0.0 + - @latticexyz/block-logs-stream@2.0.0 + ## 2.0.0-next.18 ### Major Changes diff --git a/packages/store-indexer/package.json b/packages/store-indexer/package.json index 1ae1a75ff4..76ef8fad35 100644 --- a/packages/store-indexer/package.json +++ b/packages/store-indexer/package.json @@ -1,6 +1,6 @@ { "name": "@latticexyz/store-indexer", - "version": "2.0.0-next.18", + "version": "2.0.0", "description": "Minimal Typescript indexer for Store", "repository": { "type": "git", diff --git a/packages/store-sync/CHANGELOG.md b/packages/store-sync/CHANGELOG.md index a4370cae05..9442ac0ca1 100644 --- a/packages/store-sync/CHANGELOG.md +++ b/packages/store-sync/CHANGELOG.md @@ -1,5 +1,884 @@ # @latticexyz/store-sync +## 2.0.0 + +### Major Changes + +- 07dd6f32c: Renamed all occurrences of `schema` where it is used as "value schema" to `valueSchema` to clearly distinguish it from "key schema". + The only breaking change for users is the change from `schema` to `valueSchema` in `mud.config.ts`. + + ```diff + // mud.config.ts + export default mudConfig({ + tables: { + CounterTable: { + keySchema: {}, + - schema: { + + valueSchema: { + value: "uint32", + }, + }, + } + } + ``` + +- 504e25dc8: `lastUpdatedBlockNumber` columns in Postgres storage adapters are no longer nullable +- e86fbc126: Adds store indexer service package with utils to query the indexer service. + + You can run the indexer locally by checking out the MUD monorepo, installing/building everything, and running `pnpm start:local` from `packages/store-indexer`. + + To query the indexer in the client, you can create a tRPC client with a URL pointing to the indexer service and call the available tRPC methods: + + ```ts + import { createIndexerClient } from "@latticexyz/store-sync/trpc-indexer"; + + const indexer = createIndexerClient({ url: indexerUrl }); + const result = await indexer.findAll.query({ + chainId: publicClient.chain.id, + address, + }); + ``` + + If you're using `syncToRecs`, you can just pass in the `indexerUrl` option as a shortcut to the above: + + ```ts + import { syncToRecs } from "@latticexyz/store-sync/recs"; + + syncToRecs({ + ... + indexerUrl: "https://your.indexer.service", + }); + ``` + +- e48fb3b03: Renamed singleton `chain` table to `config` table for clarity. +- 85b94614b: The postgres indexer is now storing the `logIndex` of the last update of a record to be able to return the snapshot logs in the order they were emitted onchain. +- a4aff73c5: Previously, all `store-sync` strategies were susceptible to a potential memory leak where the stream that fetches logs from the RPC would get ahead of the stream that stores the logs in the provided storage adapter. We saw this most often when syncing to remote Postgres servers, where inserting records was much slower than we retrieving them from the RPC. In these cases, the stream would build up a backlog of items until the machine ran out of memory. + + This is now fixed by waiting for logs to be stored before fetching the next batch of logs from the RPC. To make this strategy work, we no longer return `blockLogs# @latticexyz/store-sync (stream of logs fetched from RPC but before they're stored) and instead just return `storedBlockLogs# @latticexyz/store-sync (stream of logs fetched from RPC after they're stored). + +- 1faf7f697: `syncToZustand` now uses `tables` argument to populate the Zustand store's `tables` key, rather than the on-chain table registration events. This means we'll no longer store data into Zustand you haven't opted into receiving (e.g. other namespaces). +- 433078c54: Reverse PackedCounter encoding, to optimize gas for bitshifts. + Ints are right-aligned, shifting using an index is straightforward if they are indexed right-to-left. + + - Previous encoding: (7 bytes | accumulator),(5 bytes | counter 1),...,(5 bytes | counter 5) + - New encoding: (5 bytes | counter 5),...,(5 bytes | counter 1),(7 bytes | accumulator) + +- afaf2f5ff: - `Store`'s internal schema table is now a normal table instead of using special code paths. It is renamed to Tables, and the table ID changed from `mudstore:schema` to `mudstore:Tables` + + - `Store`'s `registerSchema` and `setMetadata` are combined into a single `registerTable` method. This means metadata (key names, field names) is immutable and indexers can create tables with this metadata when a new table is registered on-chain. + + ```diff + - function registerSchema(bytes32 table, Schema schema, Schema keySchema) external; + - + - function setMetadata(bytes32 table, string calldata tableName, string[] calldata fieldNames) external; + + + function registerTable( + + bytes32 table, + + Schema keySchema, + + Schema valueSchema, + + string[] calldata keyNames, + + string[] calldata fieldNames + + ) external; + ``` + + - `World`'s `registerTable` method is updated to match the `Store` interface, `setMetadata` is removed + - The `getSchema` method is renamed to `getValueSchema` on all interfaces + ```diff + - function getSchema(bytes32 table) external view returns (Schema schema); + + function getValueSchema(bytes32 table) external view returns (Schema valueSchema); + ``` + - The `store-sync` and `cli` packages are updated to integrate the breaking protocol changes. Downstream projects only need to manually integrate these changes if they access low level `Store` or `World` functions. Otherwise, a fresh deploy with the latest MUD will get you these changes. + +- 48c51b52a: RECS components are now dynamically created and inferred from your MUD config when using `syncToRecs`. + + To migrate existing projects after upgrading to this MUD version: + + 1. Remove `contractComponents.ts` from `client/src/mud` + 2. Remove `components` argument from `syncToRecs` + 3. Update `build:mud` and `dev` scripts in `contracts/package.json` to remove tsgen + + ```diff + - "build:mud": "mud tablegen && mud worldgen && mud tsgen --configPath mud.config.ts --out ../client/src/mud", + + "build:mud": "mud tablegen && mud worldgen", + ``` + + ```diff + - "dev": "pnpm mud dev-contracts --tsgenOutput ../client/src/mud", + + "dev": "pnpm mud dev-contracts", + ``` + +- 8193136a9: Added `dynamicFieldIndex` to the `Store_SpliceDynamicData` event. This enables indexers to store dynamic data as a blob per dynamic field without a schema lookup. +- 331dbfdcb: We've updated Store events to be "schemaless", meaning there is enough information in each event to only need to operate on the bytes of each record to make an update to that record without having to first decode the record by its schema. This enables new kinds of indexers and sync strategies. + + As such, we've replaced `blockStorageOperations# @latticexyz/store-sync with `storedBlockLogs# @latticexyz/store-sync, a stream of simplified Store event logs after they've been synced to the configured storage adapter. These logs may not reflect exactly the events that are on chain when e.g. hydrating from an indexer, but they will still allow the client to "catch up" to the on-chain state of your tables. + +- 1b5eb0d07: `syncToPostgres` from `@latticexyz/store-sync/postgres` now uses a single table to store all records in their bytes form (`staticData`, `encodedLengths`, and `dynamicData`), more closely mirroring onchain state and enabling more scalability and stability for automatic indexing of many worlds. + + The previous behavior, where schemaful SQL tables are created and populated for each MUD table, has been moved to a separate `@latticexyz/store-sync/postgres-decoded` export bundle. This approach is considered less stable and is intended to be used for analytics purposes rather than hydrating clients. Some previous metadata columns on these tables have been removed in favor of the bytes records table as the source of truth for onchain state. + + This overhaul is considered breaking and we recommend starting a fresh database when syncing with either of these strategies. + +- adc68225: PostgreSQL sync/indexer now uses `{storeAddress}` for its database schema names and `{namespace}__{tableName}` for its database table names (or just `{tableName}` for root namespace), to be more consistent with the rest of the MUD codebase. + + For namespaced tables: + + ```diff + - SELECT * FROM 0xfff__some_ns.some_table + + SELECT * FROM 0xfff.some_ns__some_table + ``` + + For root tables: + + ```diff + - SELECT * FROM 0xfff__.some_table + + SELECT * FROM 0xfff.some_table + ``` + + SQLite sync/indexer now uses snake case for its table names and column names for easier writing of queries and to better match PostgreSQL sync/indexer naming. + + ```diff + - SELECT * FROM 0xfFf__someNS__someTable + + SELECT * FROM 0xfff__some_ns__some_table + ``` + +- 252a1852: Migrated to new config format. +- 7b73f44d9: Postgres storage adapter now uses snake case for decoded table names and column names. This allows for better SQL ergonomics when querying these tables. + + To avoid naming conflicts for now, schemas are still case-sensitive and need to be queried with double quotes. We may change this in the future with [namespace validation](https://github.com/latticexyz/mud/issues/1991). + +### Minor Changes + +- 5df1f31bc: Refactored how we fetch snapshots from an indexer, preferring the new `getLogs` endpoint and falling back to the previous `findAll` if it isn't available. This refactor also prepares for an easier entry point for adding client caching of snapshots. + + The `initialState` option for various sync methods (`syncToPostgres`, `syncToRecs`, etc.) is now deprecated in favor of `initialBlockLogs`. For now, we'll automatically convert `initialState` into `initialBlockLogs`, but if you want to update your code, you can do: + + ```ts + import { tablesWithRecordsToLogs } from "@latticexyz/store-sync"; + + const initialBlockLogs = { + blockNumber: initialState.blockNumber, + logs: tablesWithRecordsToLogs(initialState.tables), + }; + ``` + +- 3622e39dd: Added a `followBlockTag` option to configure which block number to follow when running `createStoreSync`. It defaults to `latest` (current behavior), which is recommended for individual clients so that you always have the latest chain state. + + Indexers now default to `safe` to avoid issues with reorgs and load-balanced RPCs being out of sync. This means indexers will be slightly behind the latest block number, but clients can quickly catch up. Indexers can override this setting using `FOLLOW_BLOCK_TAG` environment variable. + +- 904fd7d4e: Add store sync package +- de47d698f: Added an optional `tables` option to `syncToRecs` to allow you to sync from tables that may not be expressed by your MUD config. This will be useful for namespaced tables used by [ERC20](https://github.com/latticexyz/mud/pull/1789) and [ERC721](https://github.com/latticexyz/mud/pull/1844) token modules until the MUD config gains [namespace support](https://github.com/latticexyz/mud/issues/994). + + Here's how we use this in our example project with the `KeysWithValue` module: + + ```ts + syncToRecs({ + ... + tables: { + KeysWithValue: { + namespace: "keywval", + name: "Inventory", + tableId: resourceToHex({ type: "table", namespace: "keywval", name: "Inventory" }), + keySchema: { + valueHash: { type: "bytes32" }, + }, + valueSchema: { + keysWithValue: { type: "bytes32[]" }, + }, + }, + }, + ... + }); + ``` + +- 131c63e53: - Accept a plain viem `PublicClient` (instead of requiring a `Chain` to be set) in `store-sync` and `store-indexer` functions. These functions now fetch chain ID using `publicClient.getChainId()` when no `publicClient.chain.id` is present. + - Allow configuring `store-indexer` with a set of RPC URLs (`RPC_HTTP_URL` and `RPC_WS_URL`) instead of `CHAIN_ID`. +- eeb15cc06: - Replace `blockEventsToStorage` with `blockLogsToStorage` that exposes a `storeOperations` callback to perform database writes from store operations. This helps encapsulates database adapters into a single wrapper/instance of `blockLogsToStorage` and allows for wrapping a block of store operations in a database transaction. + - Add `toBlock` option to `groupLogsByBlockNumber` and remove `blockHash` from results. This helps track the last block number for a given set of logs when used in the context of RxJS streams. +- 997286bac: `createStoreSync` now [waits for idle](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback) between each chunk of logs in a block to allow for downstream render cycles to trigger. This means that hydrating logs from an indexer will no longer block until hydration completes, but rather allow for `onProgress` callbacks to trigger. +- 4081493b8: Added a `tableIds` parameter to store sync methods and indexer to allow filtering data streams by table IDs. Store sync methods automatically include all internal table IDs from Store and World. + + ```ts + import { syncToRecs } from "@latticexyz/store-sync/recs"; + import { resourceIdToHex } from "@latticexyz/common"; + + syncToRecs({ + ... + tableIds: [resourceIdToHex(...)], + }); + ``` + + ```ts + import { createIndexerClient } from "@latticexyz/store-sync/trpc-indexer"; + import { resourceIdToHex } from "@latticexyz/common"; + + const client = createIndexerClient({ ... }); + client.findAll({ + ... + tableIds: [resourceIdToHex(...)], + }); + ``` + +- 582388ba5: Export `singletonEntity` as const rather than within the `syncToRecs` result. + + ```diff + - const { singletonEntity, ... } = syncToRecs({ ... }); + + import { singletonEntity, syncToRecs } from "@latticexyz/store-sync/recs"; + + const { ... } = syncToRecs({ ... }); + ``` + +- f6d214e3d: Added a `filters` option to store sync to allow filtering client data on tables and keys. Previously, it was only possible to filter on `tableIds`, but the new filter option allows for more flexible filtering by key. + + If you are building a large MUD application, you can use positional keys as a way to shard data and make it possible to load only the data needed in the client for a particular section of your app. We're using this already in Sky Strife to load match-specific data into match pages without having to load data for all matches, greatly improving load time and client performance. + + ```ts + syncToRecs({ + ... + filters: [{ tableId: '0x...', key0: '0x...' }], + }); + ``` + + The `tableIds` option is now deprecated and will be removed in the future, but is kept here for backwards compatibility. + +- fa7763583: Added a Zustand storage adapter and corresponding `syncToZustand` method for use in vanilla and React apps. It's used much like the other sync methods, except it returns a bound store and set of typed tables. + + ```ts + import { syncToZustand } from "@latticexyz/store-sync/zustand"; + import config from "contracts/mud.config"; + + const { tables, useStore, latestBlock$, storedBlockLogs$, waitForTransaction } = await syncToZustand({ + config, + ... + }); + + // in vanilla apps + const positions = useStore.getState().getRecords(tables.Position); + + // in React apps + const positions = useStore((state) => state.getRecords(tables.Position)); + ``` + + This change will be shortly followed by an update to our templates that uses Zustand as the default client data store and sync method. + +- 753bdce41: Store sync logic is now consolidated into a `createStoreSync` function exported from `@latticexyz/store-sync`. This simplifies each storage sync strategy to just a simple wrapper around the storage adapter. You can now sync to RECS with `syncToRecs` or SQLite with `syncToSqlite` and PostgreSQL support coming soon. + + There are no breaking changes if you were just using `syncToRecs` from `@latticexyz/store-sync` or running the `sqlite-indexer` binary from `@latticexyz/store-indexer`. + +- 69a96f109: `blockLogsToStorage(sqliteStorage(...))` converts block logs to SQLite operations. You can use it like: + + ```ts + import { drizzle } from "drizzle-orm/better-sqlite3"; + import Database from "better-sqlite3"; + import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core"; + import { createPublicClient } from "viem"; + import { blockLogsToStorage } from "@latticexyz/store-sync"; + import { sqliteStorage } from "@latticexyz/store-sync/sqlite"; + + const database = drizzle(new Database('store.db')) as any as BaseSQLiteDatabase<"sync", void>; + const publicClient = createPublicClient({ ... }); + + blockLogs$ + .pipe( + concatMap(blockLogsToStorage(sqliteStorage({ database, publicClient }))), + tap(({ blockNumber, operations }) => { + console.log("stored", operations.length, "operations for block", blockNumber); + }) + ) + .subscribe(); + ``` + +- 7eabd06f7: Added and populated `syncProgress` key in Zustand store for sync progress, like we do for RECS sync. This will let apps using `syncToZustand` render a loading state while initial client hydration is in progress. + + ```tsx + const syncProgress = useStore((state) => state.syncProgress); + + if (syncProgress.step !== SyncStep.LIVE) { + return <>Loading ({Math.floor(syncProgress.percentage)}%); + } + ``` + +- d7b1c588a: Upgraded all packages and templates to viem v2.7.12 and abitype v1.0.0. + + Some viem APIs have changed and we've updated `getContract` to reflect those changes and keep it aligned with viem. It's one small code change: + + ```diff + const worldContract = getContract({ + address: worldAddress, + abi: IWorldAbi, + - publicClient, + - walletClient, + + client: { public: publicClient, wallet: walletClient }, + }); + ``` + +- 4c1dcd81e: - Improved query performance by 10x by moving from drizzle ORM to handcrafted SQL. + + - Moved away from `trpc` for more granular control over the transport layer. + Added an `/api/logs` endpoint using the new query and gzip compression for 40x less data transferred over the wire. + Deprecated the `/trpc/getLogs` and `/trpc/findAll` endpoints. + - Added a `createIndexerClient` client for the new `/api` indexer API exported from `@latticexyz/store-sync/indexer-client`. + The `createIndexerClient` export from `@latticexyz/store-sync/trpc-indexer` is deprecated. + + ```diff + - import { createIndexerClient } from "@latticexyz/store-sync/trpc-indexer"; + + import { createIndexerClient } from "@latticexyz/store-sync/indexer-client"; + + - const indexer = createIndexerClient({ url: "https://indexer.holesky.redstone.xyz/trpc" }); + + const indexer = createIndexerClient({ url: "https://indexer.holesky.redstone.xyz" }); + + - const snapshot = indexer.getLogs.query(options); + + const snapshot = indexer.getLogs(options); + ``` + +### Patch Changes + +- 08d7c471f: Export postgres column type helpers from `@latticexyz/store-sync`. +- d5c0682fb: Updated all human-readable resource IDs to use `{namespace}__{name}` for consistency with world function signatures. +- 0a3b9b1c9: Added explicit error logs for unexpected situations. + Previously all `debug` logs were going to `stderr`, which made it hard to find the unexpected errors. + Now `debug` logs go to `stdout` and we can add explicit `stderr` logs. +- 6c615b608: Bumped the Postgres column size for `int32`, `uint32`, `int64`, and `uint64` types to avoid overflows +- bb6ada740: Initial sync from indexer no longer blocks the promise returning from `createStoreSync`, `syncToRecs`, and `syncToSqlite`. This should help with rendering loading screens using the `SyncProgress` RECS component and avoid the long flashes of no content in templates. + + By default, `syncToRecs` and `syncToSqlite` will start syncing (via observable subscription) immediately after called. + + If your app needs to control when syncing starts, you can use the `startSync: false` option and then `blockStoreOperations$.subscribe()` to start the sync yourself. Just be sure to unsubscribe to avoid memory leaks. + + ```ts + const { blockStorageOperations$ } = syncToRecs({ + ... + startSync: false, + }); + + // start sync manually by subscribing to `blockStorageOperation# @latticexyz/store-sync + const subcription = blockStorageOperation$.subscribe(); + + // clean up subscription + subscription.unsubscribe(); + ``` + +- 57a526083: Adds `latestBlockNumber` and `lastBlockNumberProcessed` to internal `SyncProgress` component +- 9e5baf4ff: Add RECS sync strategy and corresponding utils + + ```ts + import { createPublicClient, http } from 'viem'; + import { syncToRecs } from '@latticexyz/store-sync'; + import storeConfig from 'contracts/mud.config'; + import { defineContractComponents } from './defineContractComponents'; + + const publicClient = createPublicClient({ + chain, + transport: http(), + pollingInterval: 1000, + }); + + const { components, singletonEntity, latestBlock$, blockStorageOperations$, waitForTransaction } = await syncToRecs({ + world, + config: storeConfig, + address: '0x...', + publicClient, + components: defineContractComponents(...), + }); + ``` + +- 712866f5f: `createStoreSync` now correctly creates table registration logs from indexer records. +- f99e88987: Bump viem to 1.14.0 and abitype to 0.9.8 +- 4e445a1ab: Moved boolean array types to use array column types (instead of JSON columns) for the Postgres decoded indexer +- 669fa43e5: Moved numerical array types to use array column types (instead of JSON columns) for the Postgres decoded indexer +- 582388ba5: Add `startBlock` option to `syncToRecs`. + + ```ts + import { syncToRecs } from "@latticexyz/store-sync/recs"; + import worlds from "contracts/worlds.json"; + + syncToRecs({ + startBlock: worlds['31337'].blockNumber, + ... + }); + ``` + +- 6573e38e9: Renamed all occurrences of `table` where it is used as "table ID" to `tableId`. + This is only a breaking change for consumers who manually decode `Store` events, but not for consumers who use the MUD libraries. + + ```diff + event StoreSetRecord( + - bytes32 table, + + bytes32 tableId, + bytes32[] key, + bytes data + ); + + event StoreSetField( + - bytes32 table, + + bytes32 tableId, + bytes32[] key, + uint8 fieldIndex, + bytes data + ); + + event StoreDeleteRecord( + - bytes32 table, + + bytes32 tableId, + bytes32[] key + ); + + event StoreEphemeralRecord( + - bytes32 table, + + bytes32 tableId, + bytes32[] key, + bytes data + ); + ``` + +- 6e66c5b74: Renamed all occurrences of `key` where it is used as "key tuple" to `keyTuple`. + This is only a breaking change for consumers who manually decode `Store` events, but not for consumers who use the MUD libraries. + + ```diff + event StoreSetRecord( + bytes32 tableId, + - bytes32[] key, + + bytes32[] keyTuple, + bytes data + ); + + event StoreSetField( + bytes32 tableId, + - bytes32[] key, + + bytes32[] keyTuple, + uint8 fieldIndex, + bytes data + ); + + event StoreDeleteRecord( + bytes32 tableId, + - bytes32[] key, + + bytes32[] keyTuple, + ); + + event StoreEphemeralRecord( + bytes32 tableId, + - bytes32[] key, + + bytes32[] keyTuple, + bytes data + ); + ``` + +- a735e14b4: Improved `syncToZustand` speed of hydrating from snapshot by only applying block logs once per block instead of once per log. +- 3e024fcf3: add retry attempts and more logging to `waitForTransaction` +- 590542030: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages. +- 7e6e5157b: Catch errors when parsing logs to tables and storage operations, log and skip +- b8a6158d6: bump viem to 1.6.0 +- 5d737cf2e: Updated the `debug` util to pipe to `stdout` and added an additional util to explicitly pipe to `stderr` when needed. +- 22ee44700: All `Store` and `World` tables now use the appropriate user-types for `ResourceId`, `FieldLayout` and `Schema` to avoid manual `wrap`/`unwrap`. +- 1327ea8c8: Fixed `syncToZustand` types so that non-existent tables give an error and `never` type instead of a generic `Table` type. +- 3f5d33af: Fixes an issue with Zustand store sync where multiple updates to a record for a key in the same block did not get tracked and applied properly. +- bfcb293d1: What used to be known as `ephemeral` table is now called `offchain` table. + The previous `ephemeral` tables only supported an `emitEphemeral` method, which emitted a `StoreSetEphemeralRecord` event. + + Now `offchain` tables support all regular table methods, except partial operations on dynamic fields (`push`, `pop`, `update`). + Unlike regular tables they don't store data on-chain but emit the same events as regular tables (`StoreSetRecord`, `StoreSpliceStaticData`, `StoreDeleteRecord`), so their data can be indexed by offchain indexers/clients. + + ```diff + - EphemeralTable.emitEphemeral(value); + + OffchainTable.set(value); + ``` + +- 1890f1a06: Moved `store` tables to the `"store"` namespace (previously "mudstore") and `world` tables to the `"world"` namespace (previously root namespace). +- 5294a7d59: Improves support for internal/client-only RECS components +- b8a6158d6: remove usages of `isNonPendingBlock` and `isNonPendingLog` (fixed with more specific viem types) +- 535229984: - bump to viem 1.3.0 and abitype 0.9.3 + - move `@wagmi/chains` imports to `viem/chains` + - refine a few types +- af639a264: `Store` events have been renamed for consistency and readability. + If you're parsing `Store` events manually, you need to update your ABI. + If you're using the MUD sync stack, the new events are already integrated and no further changes are necessary. + + ```diff + - event StoreSetRecord( + + event Store_SetRecord( + ResourceId indexed tableId, + bytes32[] keyTuple, + bytes staticData, + bytes32 encodedLengths, + bytes dynamicData + ); + - event StoreSpliceStaticData( + + event Store_SpliceStaticData( + ResourceId indexed tableId, + bytes32[] keyTuple, + uint48 start, + uint40 deleteCount, + bytes data + ); + - event StoreSpliceDynamicData( + + event Store_SpliceDynamicData( + ResourceId indexed tableId, + bytes32[] keyTuple, + uint48 start, + uint40 deleteCount, + bytes data, + bytes32 encodedLengths + ); + - event StoreDeleteRecord( + + event Store_DeleteRecord( + ResourceId indexed tableId, + bytes32[] keyTuple + ); + ``` + +- 34203e4ed: Fixed invalid value when decoding records in `postgres-decoded` storage adapter +- 6c6733256: Add `tableIdToHex` and `hexToTableId` pure functions and move/deprecate `TableId`. +- cea754dde: - The external `setRecord` and `deleteRecord` methods of `IStore` no longer accept a `FieldLayout` as input, but load it from storage instead. + This is to prevent invalid `FieldLayout` values being passed, which could cause the onchain state to diverge from the indexer state. + However, the internal `StoreCore` library still exposes a `setRecord` and `deleteRecord` method that allows a `FieldLayout` to be passed. + This is because `StoreCore` can only be used internally, so the `FieldLayout` value can be trusted and we can save the gas for accessing storage. + + ```diff + interface IStore { + function setRecord( + ResourceId tableId, + bytes32[] calldata keyTuple, + bytes calldata staticData, + PackedCounter encodedLengths, + bytes calldata dynamicData, + - FieldLayout fieldLayout + ) external; + + function deleteRecord( + ResourceId tableId, + bytes32[] memory keyTuple, + - FieldLayout fieldLayout + ) external; + } + ``` + + - The `spliceStaticData` method and `Store_SpliceStaticData` event of `IStore` and `StoreCore` no longer include `deleteCount` in their signature. + This is because when splicing static data, the data after `start` is always overwritten with `data` instead of being shifted, so `deleteCount` is always the length of the data to be written. + + ```diff + + event Store_SpliceStaticData( + ResourceId indexed tableId, + bytes32[] keyTuple, + uint48 start, + - uint40 deleteCount, + bytes data + ); + + interface IStore { + function spliceStaticData( + ResourceId tableId, + bytes32[] calldata keyTuple, + uint48 start, + - uint40 deleteCount, + bytes calldata data + ) external; + } + ``` + + - The `updateInField` method has been removed from `IStore`, as it's almost identical to the more general `spliceDynamicData`. + If you're manually calling `updateInField`, here is how to upgrade to `spliceDynamicData`: + + ```diff + - store.updateInField(tableId, keyTuple, fieldIndex, startByteIndex, dataToSet, fieldLayout); + + uint8 dynamicFieldIndex = fieldIndex - fieldLayout.numStaticFields(); + + store.spliceDynamicData(tableId, keyTuple, dynamicFieldIndex, uint40(startByteIndex), uint40(dataToSet.length), dataToSet); + ``` + + - All other methods that are only valid for dynamic fields (`pushToField`, `popFromField`, `getFieldSlice`) + have been renamed to make this more explicit (`pushToDynamicField`, `popFromDynamicField`, `getDynamicFieldSlice`). + + Their `fieldIndex` parameter has been replaced by a `dynamicFieldIndex` parameter, which is the index relative to the first dynamic field (i.e. `dynamicFieldIndex` = `fieldIndex` - `numStaticFields`). + The `FieldLayout` parameter has been removed, as it was only used to calculate the `dynamicFieldIndex` in the method. + + ```diff + interface IStore { + - function pushToField( + + function pushToDynamicField( + ResourceId tableId, + bytes32[] calldata keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + bytes calldata dataToPush, + - FieldLayout fieldLayout + ) external; + + - function popFromField( + + function popFromDynamicField( + ResourceId tableId, + bytes32[] calldata keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + uint256 byteLengthToPop, + - FieldLayout fieldLayout + ) external; + + - function getFieldSlice( + + function getDynamicFieldSlice( + ResourceId tableId, + bytes32[] memory keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + - FieldLayout fieldLayout, + uint256 start, + uint256 end + ) external view returns (bytes memory data); + } + ``` + + - `IStore` has a new `getDynamicFieldLength` length method, which returns the byte length of the given dynamic field and doesn't require the `FieldLayout`. + + ```diff + IStore { + + function getDynamicFieldLength( + + ResourceId tableId, + + bytes32[] memory keyTuple, + + uint8 dynamicFieldIndex + + ) external view returns (uint256); + } + + ``` + + - `IStore` now has additional overloads for `getRecord`, `getField`, `getFieldLength` and `setField` that don't require a `FieldLength` to be passed, but instead load it from storage. + - `IStore` now exposes `setStaticField` and `setDynamicField` to save gas by avoiding the dynamic inference of whether the field is static or dynamic. + - The `getDynamicFieldSlice` method no longer accepts reading outside the bounds of the dynamic field. + This is to avoid returning invalid data, as the data of a dynamic field is not deleted when the record is deleted, but only its length is set to zero. + +- d2f8e9400: Moved to new resource ID utils. +- Updated dependencies [7ce82b6fc] +- Updated dependencies [d8c8f66bf] +- Updated dependencies [c6c13f2ea] +- Updated dependencies [77dce993a] +- Updated dependencies [ce97426c0] +- Updated dependencies [1b86eac05] +- Updated dependencies [a35c05ea9] +- Updated dependencies [c9ee5e4a] +- Updated dependencies [c963b46c7] +- Updated dependencies [05b3e8882] +- Updated dependencies [0f27afddb] +- Updated dependencies [748f4588a] +- Updated dependencies [865253dba] +- Updated dependencies [8f49c277d] +- Updated dependencies [7fa2ca183] +- Updated dependencies [ce7125a1b] +- Updated dependencies [745485cda] +- Updated dependencies [16b13ea8f] +- Updated dependencies [aea67c580] +- Updated dependencies [82693072] +- Updated dependencies [07dd6f32c] +- Updated dependencies [c14f8bf1e] +- Updated dependencies [c07fa0215] +- Updated dependencies [90e4161bb] +- Updated dependencies [aabd30767] +- Updated dependencies [65c9546c4] +- Updated dependencies [6ca1874e0] +- Updated dependencies [331dbfdcb] +- Updated dependencies [d5c0682fb] +- Updated dependencies [1d60930d6] +- Updated dependencies [01e46d99] +- Updated dependencies [430e6b29a] +- Updated dependencies [f9f9609ef] +- Updated dependencies [904fd7d4e] +- Updated dependencies [e6c03a87a] +- Updated dependencies [1077c7f53] +- Updated dependencies [2c920de7] +- Updated dependencies [b98e51808] +- Updated dependencies [b9e562d8f] +- Updated dependencies [331dbfdcb] +- Updated dependencies [44236041f] +- Updated dependencies [066056154] +- Updated dependencies [759514d8b] +- Updated dependencies [952cd5344] +- Updated dependencies [d5094a242] +- Updated dependencies [3fb9ce283] +- Updated dependencies [c207d35e8] +- Updated dependencies [db7798be2] +- Updated dependencies [bb6ada740] +- Updated dependencies [35c9f33df] +- Updated dependencies [3be4deecf] +- Updated dependencies [a25881160] +- Updated dependencies [0b8ce3f2c] +- Updated dependencies [933b54b5f] +- Updated dependencies [5debcca8] +- Updated dependencies [c4d5eb4e4] +- Updated dependencies [f8dab7334] +- Updated dependencies [1a0fa7974] +- Updated dependencies [f62c767e7] +- Updated dependencies [d00c4a9af] +- Updated dependencies [9aa5e786] +- Updated dependencies [307abab3] +- Updated dependencies [de151fec0] +- Updated dependencies [c32a9269a] +- Updated dependencies [eb384bb0e] +- Updated dependencies [37c228c63] +- Updated dependencies [618dd0e89] +- Updated dependencies [aacffcb59] +- Updated dependencies [c991c71a] +- Updated dependencies [ae340b2bf] +- Updated dependencies [1bf2e9087] +- Updated dependencies [e5d208e40] +- Updated dependencies [b38c096d] +- Updated dependencies [211be2a1e] +- Updated dependencies [0f3e2e02b] +- Updated dependencies [4bb7e8cbf] +- Updated dependencies [1f80a0b52] +- Updated dependencies [d08789282] +- Updated dependencies [5c965a919] +- Updated dependencies [f99e88987] +- Updated dependencies [939916bcd] +- Updated dependencies [e5a962bc3] +- Updated dependencies [331f0d636] +- Updated dependencies [f6f402896] +- Updated dependencies [d5b73b126] +- Updated dependencies [e34d1170] +- Updated dependencies [08b422171] +- Updated dependencies [b8a6158d6] +- Updated dependencies [190fdd11] +- Updated dependencies [37c228c63] +- Updated dependencies [37c228c63] +- Updated dependencies [433078c54] +- Updated dependencies [db314a74] +- Updated dependencies [b2d2aa715] +- Updated dependencies [4c7fd3eb2] +- Updated dependencies [a0341daf9] +- Updated dependencies [ca50fef81] +- Updated dependencies [83583a505] +- Updated dependencies [5e723b90e] +- Updated dependencies [6573e38e9] +- Updated dependencies [51914d656] +- Updated dependencies [eeb15cc06] +- Updated dependencies [063daf80e] +- Updated dependencies [afaf2f5ff] +- Updated dependencies [37c228c63] +- Updated dependencies [59267655] +- Updated dependencies [37c228c63] +- Updated dependencies [72b806979] +- Updated dependencies [2bfee9217] +- Updated dependencies [1ca35e9a1] +- Updated dependencies [44a5432ac] +- Updated dependencies [6e66c5b74] +- Updated dependencies [8d51a0348] +- Updated dependencies [c162ad5a5] +- Updated dependencies [88b1a5a19] +- Updated dependencies [1e2ad78e2] +- Updated dependencies [65c9546c4] +- Updated dependencies [48909d151] +- Updated dependencies [7b28d32e5] +- Updated dependencies [f8a01a047] +- Updated dependencies [b02f9d0e4] +- Updated dependencies [2ca75f9b9] +- Updated dependencies [f62c767e7] +- Updated dependencies [bb91edaa0] +- Updated dependencies [590542030] +- Updated dependencies [1a82c278] +- Updated dependencies [1b5eb0d07] +- Updated dependencies [44a5432ac] +- Updated dependencies [48c51b52a] +- Updated dependencies [9f8b84e73] +- Updated dependencies [66cc35a8c] +- Updated dependencies [672d05ca1] +- Updated dependencies [f1cd43bf9] +- Updated dependencies [9d0f492a9] +- Updated dependencies [55a05fd7a] +- Updated dependencies [f03531d97] +- Updated dependencies [c583f3cd0] +- Updated dependencies [31ffc9d5d] +- Updated dependencies [5e723b90e] +- Updated dependencies [63831a264] +- Updated dependencies [b8a6158d6] +- Updated dependencies [6db95ce15] +- Updated dependencies [8193136a9] +- Updated dependencies [5d737cf2e] +- Updated dependencies [d075f82f3] +- Updated dependencies [331dbfdcb] +- Updated dependencies [a7b30c79b] +- Updated dependencies [6470fe1fd] +- Updated dependencies [86766ce1] +- Updated dependencies [92de59982] +- Updated dependencies [5741d53d0] +- Updated dependencies [aee8020a6] +- Updated dependencies [22ee44700] +- Updated dependencies [e2d089c6d] +- Updated dependencies [ad4ac4459] +- Updated dependencies [b8a6158d6] +- Updated dependencies [be313068b] +- Updated dependencies [ac508bf18] +- Updated dependencies [9ff4dd955] +- Updated dependencies [93390d89] +- Updated dependencies [57d8965df] +- Updated dependencies [18d3aea55] +- Updated dependencies [7987c94d6] +- Updated dependencies [bb91edaa0] +- Updated dependencies [144c0d8d] +- Updated dependencies [5ac4c97f4] +- Updated dependencies [bfcb293d1] +- Updated dependencies [3e057061d] +- Updated dependencies [1890f1a06] +- Updated dependencies [e48171741] +- Updated dependencies [e4a6189df] +- Updated dependencies [9b43029c3] +- Updated dependencies [37c228c63] +- Updated dependencies [55ab88a60] +- Updated dependencies [c58da9ad] +- Updated dependencies [37c228c63] +- Updated dependencies [4e4a34150] +- Updated dependencies [535229984] +- Updated dependencies [af639a264] +- Updated dependencies [5e723b90e] +- Updated dependencies [99ab9cd6f] +- Updated dependencies [be18b75b] +- Updated dependencies [0c4f9fea9] +- Updated dependencies [0d12db8c2] +- Updated dependencies [c049c23f4] +- Updated dependencies [80dd6992e] +- Updated dependencies [60cfd089f] +- Updated dependencies [24a6cd536] +- Updated dependencies [37c228c63] +- Updated dependencies [708b49c50] +- Updated dependencies [d2f8e9400] +- Updated dependencies [17f987209] +- Updated dependencies [25086be5f] +- Updated dependencies [37c228c63] +- Updated dependencies [b1d41727d] +- Updated dependencies [3ac68ade6] +- Updated dependencies [c642ff3a0] +- Updated dependencies [22ba7b675] +- Updated dependencies [4c1dcd81e] +- Updated dependencies [3042f86e] +- Updated dependencies [c049c23f4] +- Updated dependencies [5e71e1cb5] +- Updated dependencies [6071163f7] +- Updated dependencies [6c6733256] +- Updated dependencies [cd5abcc3b] +- Updated dependencies [d7b1c588a] +- Updated dependencies [5c52bee09] +- Updated dependencies [251170e1e] +- Updated dependencies [8025c3505] +- Updated dependencies [c4f49240d] +- Updated dependencies [745485cda] +- Updated dependencies [95f64c85] +- Updated dependencies [afdba793f] +- Updated dependencies [37c228c63] +- Updated dependencies [3e7d83d0] +- Updated dependencies [5df1f31bc] +- Updated dependencies [a2f41ade9] +- Updated dependencies [29c3f5087] +- Updated dependencies [cea754dde] +- Updated dependencies [5e71e1cb5] +- Updated dependencies [331f0d636] +- Updated dependencies [95c59b203] +- Updated dependencies [cc2c8da00] +- Updated dependencies [252a1852] +- Updated dependencies [103f635eb] + - @latticexyz/store@2.0.0 + - @latticexyz/world@2.0.0 + - @latticexyz/common@2.0.0 + - @latticexyz/recs@2.0.0 + - @latticexyz/protocol-parser@2.0.0 + - @latticexyz/schema-type@2.0.0 + - @latticexyz/block-logs-stream@2.0.0 + - @latticexyz/config@2.0.0 + - @latticexyz/query@2.0.0 + ## 2.0.0-next.18 ### Major Changes diff --git a/packages/store-sync/package.json b/packages/store-sync/package.json index 6b5d622e2f..9a60a97bbb 100644 --- a/packages/store-sync/package.json +++ b/packages/store-sync/package.json @@ -1,6 +1,6 @@ { "name": "@latticexyz/store-sync", - "version": "2.0.0-next.18", + "version": "2.0.0", "description": "Utilities to sync MUD Store events with a client or cache", "repository": { "type": "git", diff --git a/packages/store/CHANGELOG.md b/packages/store/CHANGELOG.md index cb9fb714cf..367c7aed23 100644 --- a/packages/store/CHANGELOG.md +++ b/packages/store/CHANGELOG.md @@ -1,5 +1,1250 @@ # Change Log +## 2.0.0 + +### Major Changes + +- 7ce82b6fc: Store config now defaults `storeArgument: false` for all tables. This means that table libraries, by default, will no longer include the extra functions with the `_store` argument. This default was changed to clear up the confusion around using table libraries in tests, `PostDeploy` scripts, etc. + + If you are sure you need to manually specify a store when interacting with tables, you can still manually toggle it back on with `storeArgument: true` in the table settings of your MUD config. + + If you want to use table libraries in `PostDeploy.s.sol`, you can add the following lines: + + ```diff + import { Script } from "forge-std/Script.sol"; + import { console } from "forge-std/console.sol"; + import { IWorld } from "../src/codegen/world/IWorld.sol"; + + import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; + + contract PostDeploy is Script { + function run(address worldAddress) external { + + StoreSwitch.setStoreAddress(worldAddress); + + + + SomeTable.get(someKey); + ``` + +- c9ee5e4a: Store and World configs have been rebuilt with strong types. The shape of these configs have also changed slightly for clarity, the biggest change of which is merging of `keySchema` and `valueSchema` into a single `schema` with a separate `key` for a table's primary key. + + To migrate, first update the imported config method: + + ```diff filename="mud.config.ts" + -import { mudConfig } from "@latticexyz/world/register"; + +import { defineWorld } from "@latticexyz/world"; + + -export default mudConfig({ + +export default defineWorld({ + ``` + + _Note that if you are only using Store, you will need to import `defineStore` from `@latticexyz/store`._ + + Then migrate the table key by renaming `keySchema` to `schema` and define the table `key` with each field name from your key schema: + + ```diff filename="mud.config.ts" + export default defineWorld({ + tables: { + Position: { + - keySchema: { + + schema: { + player: "address", + }, + valueSchema: { + x: "int32", + y: "int32", + }, + + key: ['player'], + }, + }, + }); + ``` + + Now we can merge the `valueSchema` into `schema`. + + ```diff filename="mud.config.ts" + export default defineWorld({ + tables: { + Position: { + schema: { + player: "address", + - }, + - valueSchema: { + x: "int32", + y: "int32", + }, + key: ['player'], + }, + }, + }); + ``` + + If you previously used the table config shorthand without the full `keySchema` and `valueSchema`, some of the defaults have changed. Shorthands now use an `id: "bytes32"` field by default rather than `key: "bytes32"` and corresponding `key: ["id"]`. To keep previous behavior, you may have to manually define your `schema` with the previous `key` and `value` fields. + + ```diff filename="mud.config.ts" + export default defineWorld({ + tables: { + - OwnedBy: "address", + + OwnedBy: { + + schema: { + + key: "bytes32", + + value: "address", + + }, + + key: ["key"], + + }, + }, + }); + ``` + + Singleton tables are defined similarly, where an empty `key` rather than `keySchema` is provided: + + ```diff filename="mud.config.ts" + -keySchema: {} + +key: [] + ``` + + Offchain tables are now defined as a table `type` instead an `offchainOnly` boolean: + + ```diff filename="mud.config.ts" + -offchainOnly: true + +type: 'offchainTable' + ``` + + All codegen options have moved under `codegen`: + + ```diff filename="mud.config.ts" + export default defineWorld({ + - codegenDirectory: "…", + + codegen: { + + outputDirectory: "…", + + }, + tables: { + Position: { + schema: { + player: "address", + x: "int32", + y: "int32", + }, + key: ['player'], + - directory: "…", + - dataStruct: false, + + codegen: { + + outputDirectory: "…", + + dataStruct: false, + + }, + }, + }, + }); + ``` + +- 07dd6f32c: Renamed all occurrences of `schema` where it is used as "value schema" to `valueSchema` to clearly distinguish it from "key schema". + The only breaking change for users is the change from `schema` to `valueSchema` in `mud.config.ts`. + + ```diff + // mud.config.ts + export default mudConfig({ + tables: { + CounterTable: { + keySchema: {}, + - schema: { + + valueSchema: { + value: "uint32", + }, + }, + } + } + ``` + +- aabd30767: Bumped Solidity version to 0.8.24. +- 331dbfdcb: We've updated Store events to be "schemaless", meaning there is enough information in each event to only need to operate on the bytes of each record to make an update to that record without having to first decode the record by its schema. This enables new kinds of indexers and sync strategies. + + If you've written your own sync logic or are interacting with Store calls directly, this is a breaking change. We have a few more breaking protocol changes upcoming, so you may hold off on upgrading until those land. + + If you are using MUD's built-in tooling (table codegen, indexer, store sync, etc.), you don't have to make any changes except upgrading to the latest versions and deploying a fresh World. + + - The `data` field in each `StoreSetRecord` and `StoreEphemeralRecord` has been replaced with three new fields: `staticData`, `encodedLengths`, and `dynamicData`. This better reflects the on-chain state and makes it easier to perform modifications to the raw bytes. We recommend storing each of these fields individually in your off-chain storage of choice (indexer, client, etc.). + + ```diff + - event StoreSetRecord(bytes32 tableId, bytes32[] keyTuple, bytes data); + + event StoreSetRecord(bytes32 tableId, bytes32[] keyTuple, bytes staticData, bytes32 encodedLengths, bytes dynamicData); + + - event StoreEphemeralRecord(bytes32 tableId, bytes32[] keyTuple, bytes data); + + event StoreEphemeralRecord(bytes32 tableId, bytes32[] keyTuple, bytes staticData, bytes32 encodedLengths, bytes dynamicData); + ``` + + - The `StoreSetField` event is now replaced by two new events: `StoreSpliceStaticData` and `StoreSpliceDynamicData`. Splicing allows us to perform efficient operations like push and pop, in addition to replacing a field value. We use two events because updating a dynamic-length field also requires updating the record's `encodedLengths` (aka PackedCounter). + + ```diff + - event StoreSetField(bytes32 tableId, bytes32[] keyTuple, uint8 fieldIndex, bytes data); + + event StoreSpliceStaticData(bytes32 tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data); + + event StoreSpliceDynamicData(bytes32 tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data, bytes32 encodedLengths); + ``` + + Similarly, Store setter methods (e.g. `setRecord`) have been updated to reflect the `data` to `staticData`, `encodedLengths`, and `dynamicData` changes. We'll be following up shortly with Store getter method changes for more gas efficient storage reads. + +- f9f9609ef: The argument order on `Store_SpliceDynamicData`, `onBeforeSpliceDynamicData` and `onAfterSpliceDynamicData` has been changed to match the argument order on `Store_SetRecord`, + where the `PackedCounter encodedLength` field comes before the `bytes dynamicData` field. + + ```diff + IStore { + event Store_SpliceDynamicData( + ResourceId indexed tableId, + bytes32[] keyTuple, + uint48 start, + uint40 deleteCount, + + PackedCounter encodedLengths, + bytes data, + - PackedCounter encodedLengths + ); + } + + IStoreHook { + function onBeforeSpliceDynamicData( + ResourceId tableId, + bytes32[] memory keyTuple, + uint8 dynamicFieldIndex, + uint40 startWithinField, + uint40 deleteCount, + + PackedCounter encodedLengths, + bytes memory data, + - PackedCounter encodedLengths + ) external; + + function onAfterSpliceDynamicData( + ResourceId tableId, + bytes32[] memory keyTuple, + uint8 dynamicFieldIndex, + uint40 startWithinField, + uint40 deleteCount, + + PackedCounter encodedLengths, + bytes memory data, + - PackedCounter encodedLengths + ) external; + } + ``` + +- b9e562d8f: 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 {} + ``` + +- 759514d8b: Moved the registration of store hooks and systems hooks to bitmaps with bitwise operator instead of a struct. + + ```diff + - import { StoreHookLib } from "@latticexyz/src/StoreHook.sol"; + + import { + + BEFORE_SET_RECORD, + + BEFORE_SET_FIELD, + + BEFORE_DELETE_RECORD + + } from "@latticexyz/store/storeHookTypes.sol"; + + StoreCore.registerStoreHook( + tableId, + subscriber, + - StoreHookLib.encodeBitmap({ + - onBeforeSetRecord: true, + - onAfterSetRecord: false, + - onBeforeSetField: true, + - onAfterSetField: false, + - onBeforeDeleteRecord: true, + - onAfterDeleteRecord: false + - }) + + BEFORE_SET_RECORD | BEFORE_SET_FIELD | BEFORE_DELETE_RECORD + ); + ``` + + ```diff + - import { SystemHookLib } from "../src/SystemHook.sol"; + + import { BEFORE_CALL_SYSTEM, AFTER_CALL_SYSTEM } from "../src/systemHookTypes.sol"; + + world.registerSystemHook( + systemId, + subscriber, + - SystemHookLib.encodeBitmap({ onBeforeCallSystem: true, onAfterCallSystem: true }) + + BEFORE_CALL_SYSTEM | AFTER_CALL_SYSTEM + ); + + ``` + +- 952cd5344: All `Store` methods now require the table's value schema to be passed in as an argument instead of loading it from storage. + This decreases gas cost and removes circular dependencies of the Schema table (where it was not possible to write to the Schema table before the Schema table was registered). + + ```diff + function setRecord( + bytes32 table, + bytes32[] calldata key, + bytes calldata data, + + Schema valueSchema + ) external; + ``` + + The same diff applies to `getRecord`, `getField`, `setField`, `pushToField`, `popFromField`, `updateInField`, and `deleteRecord`. + + This change only requires changes in downstream projects if the `Store` methods were accessed directly. In most cases it is fully abstracted in the generated table libraries, + so downstream projects only need to regenerate their table libraries after updating MUD. + +- d5094a242: - The `IStoreHook` interface was changed to replace `onBeforeSetField` and `onAfterSetField` with `onBeforeSpliceStaticData`, `onAfterSpliceStaticData`, `onBeforeSpliceDynamicData` and `onAfterSpliceDynamicData`. + + This new interface matches the new `StoreSpliceStaticData` and `StoreSpliceDynamicData` events, and avoids having to read the entire field from storage when only a subset of the field was updated + (e.g. when pushing elements to a field). + + ```diff + interface IStoreHook { + - function onBeforeSetField( + - bytes32 tableId, + - bytes32[] memory keyTuple, + - uint8 fieldIndex, + - bytes memory data, + - FieldLayout fieldLayout + - ) external; + + - function onAfterSetField( + - bytes32 tableId, + - bytes32[] memory keyTuple, + - uint8 fieldIndex, + - bytes memory data, + - FieldLayout fieldLayout + - ) external; + + + function onBeforeSpliceStaticData( + + bytes32 tableId, + + bytes32[] memory keyTuple, + + uint48 start, + + uint40 deleteCount, + + bytes memory data + + ) external; + + + function onAfterSpliceStaticData( + + bytes32 tableId, + + bytes32[] memory keyTuple, + + uint48 start, + + uint40 deleteCount, + + bytes memory data + + ) external; + + + function onBeforeSpliceDynamicData( + + bytes32 tableId, + + bytes32[] memory keyTuple, + + uint8 dynamicFieldIndex, + + uint40 startWithinField, + + uint40 deleteCount, + + bytes memory data, + + PackedCounter encodedLengths + + ) external; + + + function onAfterSpliceDynamicData( + + bytes32 tableId, + + bytes32[] memory keyTuple, + + uint8 dynamicFieldIndex, + + uint40 startWithinField, + + uint40 deleteCount, + + bytes memory data, + + PackedCounter encodedLengths + + ) external; + } + ``` + + - All `calldata` parameters on the `IStoreHook` interface were changed to `memory`, since the functions are called with `memory` from the `World`. + - `IStore` exposes two new functions: `spliceStaticData` and `spliceDynamicData`. + + These functions provide lower level access to the operations happening under the hood in `setField`, `pushToField`, `popFromField` and `updateInField` and simplify handling + the new splice hooks. + + `StoreCore`'s internal logic was simplified to use the `spliceStaticData` and `spliceDynamicData` functions instead of duplicating similar logic in different functions. + + ```solidity + interface IStore { + // Splice data in the static part of the record + function spliceStaticData( + bytes32 tableId, + bytes32[] calldata keyTuple, + uint48 start, + uint40 deleteCount, + bytes calldata data + ) external; + + // Splice data in the dynamic part of the record + function spliceDynamicData( + bytes32 tableId, + bytes32[] calldata keyTuple, + uint8 dynamicFieldIndex, + uint40 startWithinField, + uint40 deleteCount, + bytes calldata data + ) external; + } + ``` + +- a25881160: Remove `TableId` library to simplify `store` package +- c4d5eb4e4: - The `onSetRecord` hook is split into `onBeforeSetRecord` and `onAfterSetRecord` and the `onDeleteRecord` hook is split into `onBeforeDeleteRecord` and `onAfterDeleteRecord`. + The purpose of this change is to allow more fine-grained control over the point in the lifecycle at which hooks are executed. + + The previous hooks were executed before modifying data, so they can be replaced with the respective `onBefore` hooks. + + ```diff + - function onSetRecord( + + function onBeforeSetRecord( + bytes32 table, + bytes32[] memory key, + bytes memory data, + Schema valueSchema + ) public; + + - function onDeleteRecord( + + function onBeforeDeleteRecord( + bytes32 table, + bytes32[] memory key, + Schema valueSchema + ) public; + ``` + + - It is now possible to specify which methods of a hook contract should be called when registering a hook. The purpose of this change is to save gas by avoiding to call no-op hook methods. + + ```diff + function registerStoreHook( + bytes32 tableId, + - IStoreHook hookAddress + + IStoreHook hookAddress, + + uint8 enabledHooksBitmap + ) public; + + function registerSystemHook( + bytes32 systemId, + - ISystemHook hookAddress + + ISystemHook hookAddress, + + uint8 enabledHooksBitmap + ) public; + ``` + + There are `StoreHookLib` and `SystemHookLib` with helper functions to encode the bitmap of enabled hooks. + + ```solidity + import { StoreHookLib } from "@latticexyz/store/src/StoreHook.sol"; + + uint8 storeHookBitmap = StoreBookLib.encodeBitmap({ + onBeforeSetRecord: true, + onAfterSetRecord: true, + onBeforeSetField: true, + onAfterSetField: true, + onBeforeDeleteRecord: true, + onAfterDeleteRecord: true + }); + ``` + + ```solidity + import { SystemHookLib } from "@latticexyz/world/src/SystemHook.sol"; + + uint8 systemHookBitmap = SystemHookLib.encodeBitmap({ + onBeforeCallSystem: true, + onAfterCallSystem: true + }); + ``` + + - The `onSetRecord` hook call for `emitEphemeralRecord` has been removed to save gas and to more clearly distinguish ephemeral tables as offchain tables. + +- 9aa5e786: Set the protocol version to `2.0.0` for each Store and World. +- de151fec0: - Add `FieldLayout`, which is a `bytes32` user-type similar to `Schema`. + + Both `FieldLayout` and `Schema` have the same kind of data in the first 4 bytes. + + - 2 bytes for total length of all static fields + - 1 byte for number of static size fields + - 1 byte for number of dynamic size fields + + But whereas `Schema` has `SchemaType` enum in each of the other 28 bytes, `FieldLayout` has static byte lengths in each of the other 28 bytes. + + - Replace `Schema valueSchema` with `FieldLayout fieldLayout` in Store and World contracts. + + `FieldLayout` is more gas-efficient because it already has lengths, and `Schema` has types which need to be converted to lengths. + + - Add `getFieldLayout` to `IStore` interface. + + There is no `FieldLayout` for keys, only for values, because key byte lengths aren't usually relevant on-chain. You can still use `getKeySchema` if you need key types. + + - Add `fieldLayoutToHex` utility to `protocol-parser` package. + - Add `constants.sol` for constants shared between `FieldLayout`, `Schema` and `PackedCounter`. + +- ae340b2bf: Store's `getRecord` has been updated to return `staticData`, `encodedLengths`, and `dynamicData` instead of a single `data` blob, to match the new behaviour of Store setter methods. + + If you use codegenerated libraries, you will only need to update `encode` calls. + + ```diff + - bytes memory data = Position.encode(x, y); + + (bytes memory staticData, PackedCounter encodedLengths, bytes memory dynamicData) = Position.encode(x, y); + ``` + +- 433078c54: Reverse PackedCounter encoding, to optimize gas for bitshifts. + Ints are right-aligned, shifting using an index is straightforward if they are indexed right-to-left. + + - Previous encoding: (7 bytes | accumulator),(5 bytes | counter 1),...,(5 bytes | counter 5) + - New encoding: (5 bytes | counter 5),...,(5 bytes | counter 1),(7 bytes | accumulator) + +- 83583a505: Store and World contract ABIs are now exported from the `out` directory. You'll need to update your imports like: + + ```diff + - import IBaseWorldAbi from "@latticexyz/world/abi/IBaseWorld.sol/IBaseWorldAbi.json"; + + import IBaseWorldAbi from "@latticexyz/world/out/IBaseWorld.sol/IBaseWorldAbi.json"; + ``` + + `MudTest.sol` was also moved to the World package. You can update your import like: + + ```diff + - import { MudTest } from "@latticexyz/store/src/MudTest.sol"; + + import { MudTest } from "@latticexyz/world/test/MudTest.t.sol"; + ``` + +- afaf2f5ff: - `Store`'s internal schema table is now a normal table instead of using special code paths. It is renamed to Tables, and the table ID changed from `mudstore:schema` to `mudstore:Tables` + + - `Store`'s `registerSchema` and `setMetadata` are combined into a single `registerTable` method. This means metadata (key names, field names) is immutable and indexers can create tables with this metadata when a new table is registered on-chain. + + ```diff + - function registerSchema(bytes32 table, Schema schema, Schema keySchema) external; + - + - function setMetadata(bytes32 table, string calldata tableName, string[] calldata fieldNames) external; + + + function registerTable( + + bytes32 table, + + Schema keySchema, + + Schema valueSchema, + + string[] calldata keyNames, + + string[] calldata fieldNames + + ) external; + ``` + + - `World`'s `registerTable` method is updated to match the `Store` interface, `setMetadata` is removed + - The `getSchema` method is renamed to `getValueSchema` on all interfaces + ```diff + - function getSchema(bytes32 table) external view returns (Schema schema); + + function getValueSchema(bytes32 table) external view returns (Schema valueSchema); + ``` + - The `store-sync` and `cli` packages are updated to integrate the breaking protocol changes. Downstream projects only need to manually integrate these changes if they access low level `Store` or `World` functions. Otherwise, a fresh deploy with the latest MUD will get you these changes. + +- 44a5432ac: These breaking changes only affect store utilities, you aren't affected if you use `@latticexyz/cli` codegen scripts. + + - Add `remappings` argument to the `tablegen` codegen function, so that it can read user-provided files. + - In `RenderTableOptions` change the type of `imports` from `RelativeImportDatum` to `ImportDatum`, to allow passing absolute imports to the table renderer. + - Add `solidityUserTypes` argument to several functions that need to resolve user or abi types: `resolveAbiOrUserType`, `importForAbiOrUserType`, `getUserTypeInfo`. + - Add `userTypes` config option to MUD config, which takes user types mapped to file paths from which to import them. + +- 65c9546c4: - Always render field methods with a suffix in tablegen (they used to not be rendered if field methods without a suffix were rendered). + - Add `withSuffixlessFieldMethods` to `RenderTableOptions`, which indicates that field methods without a suffix should be rendered. +- 672d05ca1: - Moves Store events into its own `IStoreEvents` interface + + - Moves Store interfaces to their own files + - Adds a `StoreData` abstract contract to initialize a Store and expose the Store version + + If you're using MUD out of the box, you won't have to make any changes. You will only need to update if you're using any of the base Store interfaces. + +- 8193136a9: Added `dynamicFieldIndex` to the `Store_SpliceDynamicData` event. This enables indexers to store dynamic data as a blob per dynamic field without a schema lookup. +- 92de59982: Bump Solidity version to 0.8.21 +- ac508bf18: Renamed the default filename of generated user types from `Types.sol` to `common.sol` and the default filename of the generated table index file from `Tables.sol` to `index.sol`. + + Both can be overridden via the MUD config: + + ```ts + export default mudConfig({ + /** Filename where common user types will be generated and imported from. */ + userTypesFilename: "common.sol", + /** Filename where codegen index will be generated. */ + codegenIndexFilename: "index.sol", + }); + ``` + + Note: `userTypesFilename` was renamed from `userTypesPath` and `.sol` is not appended automatically anymore but needs to be part of the provided filename. + + To update your existing project, update all imports from `Tables.sol` to `index.sol` and all imports from `Types.sol` to `common.sol`, or override the defaults in your MUD config to the previous values. + + ```diff + - import { Counter } from "../src/codegen/Tables.sol"; + + import { Counter } from "../src/codegen/index.sol"; + - import { ExampleEnum } from "../src/codegen/Types.sol"; + + import { ExampleEnum } from "../src/codegen/common.sol"; + ``` + +- bfcb293d1: What used to be known as `ephemeral` table is now called `offchain` table. + The previous `ephemeral` tables only supported an `emitEphemeral` method, which emitted a `StoreSetEphemeralRecord` event. + + Now `offchain` tables support all regular table methods, except partial operations on dynamic fields (`push`, `pop`, `update`). + Unlike regular tables they don't store data on-chain but emit the same events as regular tables (`StoreSetRecord`, `StoreSpliceStaticData`, `StoreDeleteRecord`), so their data can be indexed by offchain indexers/clients. + + ```diff + - EphemeralTable.emitEphemeral(value); + + OffchainTable.set(value); + ``` + +- 1890f1a06: Moved `store` tables to the `"store"` namespace (previously "mudstore") and `world` tables to the `"world"` namespace (previously root namespace). +- af639a264: `Store` events have been renamed for consistency and readability. + If you're parsing `Store` events manually, you need to update your ABI. + If you're using the MUD sync stack, the new events are already integrated and no further changes are necessary. + + ```diff + - event StoreSetRecord( + + event Store_SetRecord( + ResourceId indexed tableId, + bytes32[] keyTuple, + bytes staticData, + bytes32 encodedLengths, + bytes dynamicData + ); + - event StoreSpliceStaticData( + + event Store_SpliceStaticData( + ResourceId indexed tableId, + bytes32[] keyTuple, + uint48 start, + uint40 deleteCount, + bytes data + ); + - event StoreSpliceDynamicData( + + event Store_SpliceDynamicData( + ResourceId indexed tableId, + bytes32[] keyTuple, + uint48 start, + uint40 deleteCount, + bytes data, + bytes32 encodedLengths + ); + - event StoreDeleteRecord( + + event Store_DeleteRecord( + ResourceId indexed tableId, + bytes32[] keyTuple + ); + ``` + +- 5e723b90e: - `ResourceSelector` is replaced with `ResourceId`, `ResourceIdLib`, `ResourceIdInstance`, `WorldResourceIdLib` and `WorldResourceIdInstance`. + + Previously a "resource selector" was a `bytes32` value with the first 16 bytes reserved for the resource's namespace, and the last 16 bytes reserved for the resource's name. + Now a "resource ID" is a `bytes32` value with the first 2 bytes reserved for the resource type, the next 14 bytes reserved for the resource's namespace, and the last 16 bytes reserved for the resource's name. + + Previously `ResouceSelector` was a library and the resource selector type was a plain `bytes32`. + Now `ResourceId` is a user type, and the functionality is implemented in the `ResourceIdInstance` (for type) and `WorldResourceIdInstance` (for namespace and name) libraries. + We split the logic into two libraries, because `Store` now also uses `ResourceId` and needs to be aware of resource types, but not of namespaces/names. + + ```diff + - import { ResourceSelector } from "@latticexyz/world/src/ResourceSelector.sol"; + + import { ResourceId, ResourceIdInstance } from "@latticexyz/store/src/ResourceId.sol"; + + import { WorldResourceIdLib, WorldResourceIdInstance } from "@latticexyz/world/src/WorldResourceId.sol"; + + import { RESOURCE_SYSTEM } from "@latticexyz/world/src/worldResourceTypes.sol"; + + - bytes32 systemId = ResourceSelector.from("namespace", "name"); + + ResourceId systemId = WorldResourceIdLib.encode(RESOURCE_SYSTEM, "namespace", "name"); + + - using ResourceSelector for bytes32; + + using WorldResourceIdInstance for ResourceId; + + using ResourceIdInstance for ResourceId; + + systemId.getName(); + systemId.getNamespace(); + + systemId.getType(); + + ``` + + - All `Store` and `World` methods now use the `ResourceId` type for `tableId`, `systemId`, `moduleId` and `namespaceId`. + All mentions of `resourceSelector` were renamed to `resourceId` or the more specific type (e.g. `tableId`, `systemId`) + + ```diff + import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; + + IStore { + function setRecord( + - bytes32 tableId, + + ResourceId tableId, + bytes32[] calldata keyTuple, + bytes calldata staticData, + PackedCounter encodedLengths, + bytes calldata dynamicData, + FieldLayout fieldLayout + ) external; + + // Same for all other methods + } + ``` + + ```diff + import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; + + IBaseWorld { + function callFrom( + address delegator, + - bytes32 resourceSelector, + + ResourceId systemId, + bytes memory callData + ) external payable returns (bytes memory); + + // Same for all other methods + } + ``` + +- 99ab9cd6f: Store events now use an `indexed` `tableId`. This adds ~100 gas per write, but means we our sync stack can filter events by table. +- c049c23f4: - `StoreCore`'s `initialize` function is split into `initialize` (to set the `StoreSwitch`'s `storeAddress`) and `registerCoreTables` (to register the `Tables` and `StoreHooks` tables). + The purpose of this is to give consumers more granular control over the setup flow. + + - The `StoreRead` contract no longer calls `StoreCore.initialize` in its constructor. + `StoreCore` consumers are expected to call `StoreCore.initialize` and `StoreCore.registerCoreTable` in their own setup logic. + +- 24a6cd536: Changed the `userTypes` property to accept `{ filePath: string, internalType: SchemaAbiType }` to enable strong type inference from the config. +- 5c52bee09: Renamed `StoreCore`'s `registerCoreTables` method to `registerInternalTables`. +- 3e7d83d0: Renamed `PackedCounter` to `EncodedLengths` for consistency. +- cea754dde: - The external `setRecord` and `deleteRecord` methods of `IStore` no longer accept a `FieldLayout` as input, but load it from storage instead. + This is to prevent invalid `FieldLayout` values being passed, which could cause the onchain state to diverge from the indexer state. + However, the internal `StoreCore` library still exposes a `setRecord` and `deleteRecord` method that allows a `FieldLayout` to be passed. + This is because `StoreCore` can only be used internally, so the `FieldLayout` value can be trusted and we can save the gas for accessing storage. + + ```diff + interface IStore { + function setRecord( + ResourceId tableId, + bytes32[] calldata keyTuple, + bytes calldata staticData, + PackedCounter encodedLengths, + bytes calldata dynamicData, + - FieldLayout fieldLayout + ) external; + + function deleteRecord( + ResourceId tableId, + bytes32[] memory keyTuple, + - FieldLayout fieldLayout + ) external; + } + ``` + + - The `spliceStaticData` method and `Store_SpliceStaticData` event of `IStore` and `StoreCore` no longer include `deleteCount` in their signature. + This is because when splicing static data, the data after `start` is always overwritten with `data` instead of being shifted, so `deleteCount` is always the length of the data to be written. + + ```diff + + event Store_SpliceStaticData( + ResourceId indexed tableId, + bytes32[] keyTuple, + uint48 start, + - uint40 deleteCount, + bytes data + ); + + interface IStore { + function spliceStaticData( + ResourceId tableId, + bytes32[] calldata keyTuple, + uint48 start, + - uint40 deleteCount, + bytes calldata data + ) external; + } + ``` + + - The `updateInField` method has been removed from `IStore`, as it's almost identical to the more general `spliceDynamicData`. + If you're manually calling `updateInField`, here is how to upgrade to `spliceDynamicData`: + + ```diff + - store.updateInField(tableId, keyTuple, fieldIndex, startByteIndex, dataToSet, fieldLayout); + + uint8 dynamicFieldIndex = fieldIndex - fieldLayout.numStaticFields(); + + store.spliceDynamicData(tableId, keyTuple, dynamicFieldIndex, uint40(startByteIndex), uint40(dataToSet.length), dataToSet); + ``` + + - All other methods that are only valid for dynamic fields (`pushToField`, `popFromField`, `getFieldSlice`) + have been renamed to make this more explicit (`pushToDynamicField`, `popFromDynamicField`, `getDynamicFieldSlice`). + + Their `fieldIndex` parameter has been replaced by a `dynamicFieldIndex` parameter, which is the index relative to the first dynamic field (i.e. `dynamicFieldIndex` = `fieldIndex` - `numStaticFields`). + The `FieldLayout` parameter has been removed, as it was only used to calculate the `dynamicFieldIndex` in the method. + + ```diff + interface IStore { + - function pushToField( + + function pushToDynamicField( + ResourceId tableId, + bytes32[] calldata keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + bytes calldata dataToPush, + - FieldLayout fieldLayout + ) external; + + - function popFromField( + + function popFromDynamicField( + ResourceId tableId, + bytes32[] calldata keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + uint256 byteLengthToPop, + - FieldLayout fieldLayout + ) external; + + - function getFieldSlice( + + function getDynamicFieldSlice( + ResourceId tableId, + bytes32[] memory keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + - FieldLayout fieldLayout, + uint256 start, + uint256 end + ) external view returns (bytes memory data); + } + ``` + + - `IStore` has a new `getDynamicFieldLength` length method, which returns the byte length of the given dynamic field and doesn't require the `FieldLayout`. + + ```diff + IStore { + + function getDynamicFieldLength( + + ResourceId tableId, + + bytes32[] memory keyTuple, + + uint8 dynamicFieldIndex + + ) external view returns (uint256); + } + + ``` + + - `IStore` now has additional overloads for `getRecord`, `getField`, `getFieldLength` and `setField` that don't require a `FieldLength` to be passed, but instead load it from storage. + - `IStore` now exposes `setStaticField` and `setDynamicField` to save gas by avoiding the dynamic inference of whether the field is static or dynamic. + - The `getDynamicFieldSlice` method no longer accepts reading outside the bounds of the dynamic field. + This is to avoid returning invalid data, as the data of a dynamic field is not deleted when the record is deleted, but only its length is set to zero. + +- 252a1852: Migrated to new config format. + +### Minor Changes + +- 1d60930d6: It is now possible to unregister Store hooks and System hooks. + + ```solidity + interface IStore { + function unregisterStoreHook(bytes32 table, IStoreHook hookAddress) external; + // ... + } + + interface IWorld { + function unregisterSystemHook(bytes32 resourceSelector, ISystemHook hookAddress) external; + // ... + } + ``` + +- 66cc35a8c: Create gas-report package, move gas-report cli command and GasReporter contract to it +- a7b30c79b: Rename `MudV2Test` to `MudTest` and move from `@latticexyz/std-contracts` to `@latticexyz/store`. + + ```solidity + // old import + import { MudV2Test } from "@latticexyz/std-contracts/src/test/MudV2Test.t.sol"; + // new import + import { MudTest } from "@latticexyz/store/src/MudTest.sol"; + ``` + + Refactor `StoreSwitch` to use a storage slot instead of `function isStore()` to determine which contract is Store: + + - Previously `StoreSwitch` called `isStore()` on `msg.sender` to determine if `msg.sender` is a `Store` contract. If the call succeeded, the `Store` methods were called on `msg.sender`, otherwise the data was written to the own storage. + - With this change `StoreSwitch` instead checks for an `address` in a known storage slot. If the address equals the own address, data is written to the own storage. If it is an external address, `Store` methods are called on this address. If it is unset (`address(0)`), store methods are called on `msg.sender`. + - In practice this has the same effect as before: By default the `World` contracts sets its own address in `StoreSwitch`, while `System` contracts keep the Store address undefined, so `Systems` write to their caller (`World`) if they are executed via `call` or directly to the `World` storage if they are executed via `delegatecall`. + - Besides gas savings, this change has two additional benefits: + 1. it is now possible for `Systems` to explicitly set a `Store` address to make them exclusive to that `Store` and + 2. table libraries can now be used in tests without having to provide an explicit `Store` argument, because the `MudTest` base contract redirects reads and writes to the internal `World` contract. + +- 93390d89: Added an `abstract` `StoreKernel` contract, which includes all Store interfaces except for registration, and implements write methods, `protocolVersion` and initializes `StoreCore`. `Store` extends `StoreKernel` with the `IStoreRegistration` interface. `StoreData` is removed as a separate interface/contract. `World` now extends `StoreKernel` (since the registration methods are added via the `InitModule`). +- 144c0d8d: Replaced the static array length getters in table libraries with constants. +- 9b43029c3: Add protocol version with corresponding getter and event on deploy + + ```solidity + world.worldVersion(); + world.storeVersion(); // a World is also a Store + ``` + + ```solidity + event HelloWorld(bytes32 indexed worldVersion); + event HelloStore(bytes32 indexed storeVersion); + ``` + +- 55ab88a60: `StoreCore` and `IStore` now expose specific functions for `getStaticField` and `getDynamicField` in addition to the general `getField`. + Using the specific functions reduces gas overhead because more optimized logic can be executed. + + ```solidity + interface IStore { + /** + * Get a single static field from the given tableId and key tuple, with the given value field layout. + * Note: the field value is left-aligned in the returned bytes32, the rest of the word is not zeroed out. + * Consumers are expected to truncate the returned value as needed. + */ + function getStaticField( + bytes32 tableId, + bytes32[] calldata keyTuple, + uint8 fieldIndex, + FieldLayout fieldLayout + ) external view returns (bytes32); + + /** + * Get a single dynamic field from the given tableId and key tuple at the given dynamic field index. + * (Dynamic field index = field index - number of static fields) + */ + function getDynamicField( + bytes32 tableId, + bytes32[] memory keyTuple, + uint8 dynamicFieldIndex + ) external view returns (bytes memory); + } + ``` + +- 80dd6992e: Add an optional `namePrefix` argument to `renderRecordData`, to support inlined logic in codegenned `set` method which uses a struct. +- 708b49c50: Generated table libraries now have a set of functions prefixed with `_` that always use their own storage for read/write. + This saves gas for use cases where the functionality to dynamically determine which `Store` to use for read/write is not needed, e.g. root systems in a `World`, or when using `Store` without `World`. + + We decided to continue to always generate a set of functions that dynamically decide which `Store` to use, so that the generated table libraries can still be imported by non-root systems. + + ```solidity + library Counter { + // Dynamically determine which store to write to based on the context + function set(uint32 value) internal; + + // Always write to own storage + function _set(uint32 value) internal; + + // ... equivalent functions for all other Store methods + } + ``` + +- 3ac68ade6: Removed `allowEmpty` option from `FieldLayout.validate()` as field layouts should never be empty. +- 3042f86e: Moved key schema and value schema methods to constants in code-generated table libraries for less bytecode and less gas in register/install methods. + + ```diff + -console.log(SomeTable.getKeySchema()); + +console.log(SomeTable._keySchema); + + -console.log(SomeTable.getValueSchema()); + +console.log(SomeTable._valueSchema); + ``` + +- 5e71e1cb5: Moved `KeySchema`, `ValueSchema`, `SchemaToPrimitives` and `TableRecord` types into `@latticexyz/protocol-parser` +- d7b1c588a: Upgraded all packages and templates to viem v2.7.12 and abitype v1.0.0. + + Some viem APIs have changed and we've updated `getContract` to reflect those changes and keep it aligned with viem. It's one small code change: + + ```diff + const worldContract = getContract({ + address: worldAddress, + abi: IWorldAbi, + - publicClient, + - walletClient, + + client: { public: publicClient, wallet: walletClient }, + }); + ``` + +- 8025c3505: We now use `@latticexyz/abi-ts` to generate TS type declaration files (`.d.ts`) for each ABI JSON file. This replaces our usage TypeChain everywhere. + + If you previously relied on TypeChain types from `@latticexyz/store` or `@latticexyz/world`, you will either need to migrate to viem or abitype using ABI JSON imports or generate TypeChain types from our exported ABI JSON files. + + ```ts + import { getContract } from "viem"; + import IStoreAbi from "@latticexyz/store/abi/IStore.sol/IStore.abi.json"; + + const storeContract = getContract({ + abi: IStoreAbi, + ... + }); + + await storeContract.write.setRecord(...); + ``` + +- 103f635eb: Improved error messages for invalid `FieldLayout`s + + ```diff + -error FieldLayoutLib_InvalidLength(uint256 length); + +error FieldLayoutLib_TooManyFields(uint256 numFields, uint256 maxFields); + +error FieldLayoutLib_TooManyDynamicFields(uint256 numFields, uint256 maxFields); + +error FieldLayoutLib_Empty(); + ``` + +### Patch Changes + +- d8c8f66bf: Exclude ERC165 interface ID from custom interface ID's. +- c6c13f2ea: Storage events are now emitted after "before" hooks, so that the resulting logs are now correctly ordered and reflect onchain logic. This resolves issues with store writes and event emissions happening in "before" hooks. +- 1b86eac05: Changed the type of the output variable in the `slice4` function to `bytes4`. +- a35c05ea9: Table libraries now hardcode the `bytes32` table ID value rather than computing it in Solidity. This saves a bit of gas across all storage operations. +- c963b46c7: Optimize storage library +- 05b3e8882: Fixed a race condition when registering core tables, where we would set a record in the `ResourceIds` table before the table was registered. +- aea67c580: Include bytecode for `World` and `Store` in npm packages. +- 90e4161bb: Moved the test tables out of the main config in `world` and `store` and into their own separate config. +- 904fd7d4e: Add store sync package +- e6c03a87a: Renamed the `requireNoCallback` modifier to `prohibitDirectCallback`. +- 1077c7f53: Fixed an issue where `mud.config.ts` source file was not included in the package, causing TS errors downstream. +- 2c920de7: Refactored `StoreCore` to import `IStoreEvents` instead of defining the events twice. +- 44236041f: Moved table ID and field layout constants in code-generated table libraries from the file level into the library, for clearer access and cleaner imports. + + ```diff + -import { SomeTable, SomeTableTableId } from "./codegen/tables/SomeTable.sol"; + +import { SomeTable } from "./codegen/tables/SomeTable.sol"; + + -console.log(SomeTableTableId); + +console.log(SomeTable._tableId); + + -console.log(SomeTable.getFieldLayout()); + +console.log(SomeTable._fieldLayout); + ``` + +- f62c767e7: Parallelized table codegen. Also put logs behind debug flag, which can be enabled using the `DEBUG=mud:*` environment variable. +- 37c228c63: Refactored various files to specify integers in a hex base instead of decimals. +- c991c71a: Added interfaces for all errors that are used by `StoreCore`, which includes `FieldLayout`, `PackedCounter`, `Schema`, and `Slice`. This interfaces are inherited by `IStore`, ensuring that all possible errors are included in the `IStore` ABI for proper decoding in the frontend. +- 1bf2e9087: Updated codegen to not render `push` and `pop` methods for static arrays. The `length` method now returns the hardcoded known length instead of calculating it like with a dynamic array. +- 211be2a1e: The `FieldLayout` in table libraries is now generated at compile time instead of dynamically in a table library function. + This significantly reduces gas cost in all table library functions. +- 0f3e2e02b: Added `Storage.loadField` to optimize loading 32 bytes or less from storage (which is always the case when loading data for static fields). +- d08789282: Prefixed all errors with their respective library/contract for improved debugging. +- 5c965a919: Align Store events parameter naming between IStoreWrite and StoreCore +- f99e88987: Bump viem to 1.14.0 and abitype to 0.9.8 +- d5b73b126: Optimize autogenerated table libraries +- 190fdd11: Restored `Bytes.sliceN` helpers that were previously (mistakenly) removed and renamed them to `Bytes.getBytesN`. + + If you're upgrading an existing MUD project, you can rerun codegen with `mud build` to update your table libraries to the new function names. + +- b2d2aa715: Added an explicit package export for `mud.config` +- 5e723b90e: The `ResourceType` table is removed. + It was previously used to store the resource type for each resource ID in a `World`. This is no longer necessary as the [resource type is now encoded in the resource ID](https://github.com/latticexyz/mud/pull/1544). + + To still be able to determine whether a given resource ID exists, a `ResourceIds` table has been added. + The previous `ResourceType` table was part of `World` and missed tables that were registered directly via `StoreCore.registerTable` instead of via `World.registerTable` (e.g. when a table was registered as part of a root module). + This problem is solved by the new table `ResourceIds` being part of `Store`. + + `StoreCore`'s `hasTable` function was removed in favor of using `ResourceIds.getExists(tableId)` directly. + + ```diff + - import { ResourceType } from "@latticexyz/world/src/tables/ResourceType.sol"; + - import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; + + import { ResourceIds } from "@latticexyz/store/src/codegen/tables/ResourceIds.sol"; + + - bool tableExists = StoreCore.hasTable(tableId); + + bool tableExists = ResourceIds.getExists(tableId); + + - bool systemExists = ResourceType.get(systemId) != Resource.NONE; + + bool systemExists = ResourceIds.getExists(systemId); + ``` + +- 6573e38e9: Renamed all occurrences of `table` where it is used as "table ID" to `tableId`. + This is only a breaking change for consumers who manually decode `Store` events, but not for consumers who use the MUD libraries. + + ```diff + event StoreSetRecord( + - bytes32 table, + + bytes32 tableId, + bytes32[] key, + bytes data + ); + + event StoreSetField( + - bytes32 table, + + bytes32 tableId, + bytes32[] key, + uint8 fieldIndex, + bytes data + ); + + event StoreDeleteRecord( + - bytes32 table, + + bytes32 tableId, + bytes32[] key + ); + + event StoreEphemeralRecord( + - bytes32 table, + + bytes32 tableId, + bytes32[] key, + bytes data + ); + ``` + +- 37c228c63: Refactored `ResourceId` to use a global Solidity `using` statement. +- 37c228c63: Refactored EIP165 usages to use the built-in interfaceId property instead of pre-defined constants. +- 6e66c5b74: Renamed all occurrences of `key` where it is used as "key tuple" to `keyTuple`. + This is only a breaking change for consumers who manually decode `Store` events, but not for consumers who use the MUD libraries. + + ```diff + event StoreSetRecord( + bytes32 tableId, + - bytes32[] key, + + bytes32[] keyTuple, + bytes data + ); + + event StoreSetField( + bytes32 tableId, + - bytes32[] key, + + bytes32[] keyTuple, + uint8 fieldIndex, + bytes data + ); + + event StoreDeleteRecord( + bytes32 tableId, + - bytes32[] key, + + bytes32[] keyTuple, + ); + + event StoreEphemeralRecord( + bytes32 tableId, + - bytes32[] key, + + bytes32[] keyTuple, + bytes data + ); + ``` + +- 8d51a0348: Clean up Memory.sol, make mcopy pure +- 48909d151: bump forge-std and ds-test dependencies +- 7b28d32e5: Added a custom error `Store_InvalidBounds` for when the `start:end` slice in `getDynamicFieldSlice` is invalid (it used to revert with the default overflow error) +- 590542030: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages. +- 48c51b52a: RECS components are now dynamically created and inferred from your MUD config when using `syncToRecs`. + + To migrate existing projects after upgrading to this MUD version: + + 1. Remove `contractComponents.ts` from `client/src/mud` + 2. Remove `components` argument from `syncToRecs` + 3. Update `build:mud` and `dev` scripts in `contracts/package.json` to remove tsgen + + ```diff + - "build:mud": "mud tablegen && mud worldgen && mud tsgen --configPath mud.config.ts --out ../client/src/mud", + + "build:mud": "mud tablegen && mud worldgen", + ``` + + ```diff + - "dev": "pnpm mud dev-contracts --tsgenOutput ../client/src/mud", + + "dev": "pnpm mud dev-contracts", + ``` + +- 9f8b84e73: Aligned the order of function arguments in the `Storage` library. + + ```solidity + store(uint256 storagePointer, uint256 offset, bytes memory data) + store(uint256 storagePointer, uint256 offset, uint256 length, uint256 memoryPointer) + load(uint256 storagePointer, uint256 offset, uint256 length) + load(uint256 storagePointer, uint256 offset, uint256 length, uint256 memoryPointer) + ``` + +- 55a05fd7a: Refactored `StoreCore.registerStoreHook` to use `StoreHooks._push` for gas efficiency. +- 63831a264: Minor `Store` cleanups: renamed `Utils.sol` to `leftMask.sol` since it only contains a single free function, and removed a leftover sanity check. +- 6db95ce15: Fixed `StoreCore` to pass `previousEncodedLengths` into `onBeforeSpliceDynamicData`. +- 5d737cf2e: Updated the `debug` util to pipe to `stdout` and added an additional util to explicitly pipe to `stderr` when needed. +- 22ee44700: All `Store` and `World` tables now use the appropriate user-types for `ResourceId`, `FieldLayout` and `Schema` to avoid manual `wrap`/`unwrap`. +- ad4ac4459: Added more validation checks for `FieldLayout` and `Schema`. +- be313068b: Optimized the `StoreCore` hash function determining the data location to use less gas. +- bb91edaa0: Fixed `resolveUserTypes` for static arrays. + `resolveUserTypes` is used by `deploy`, which prevented deploying tables with static arrays. +- 5ac4c97f4: Fixed M-04 Memory Corruption on Load From Storage + It only affected external use of `Storage.load` with a `memoryPointer` argument +- e48171741: Removed unused imports from various files in the `store` and `world` packages. +- 37c228c63: Refactored various Solidity files to not explicitly initialise variables to zero. +- c58da9ad: Moved the `HelloStore` to `IStoreEvents` so all Store events are defined in the same interface. +- 37c228c63: Refactored some Store functions to use a right bit mask instead of left. +- 535229984: - bump to viem 1.3.0 and abitype 0.9.3 + - move `@wagmi/chains` imports to `viem/chains` + - refine a few types +- 0d12db8c2: Optimize Schema methods. + Return `uint256` instead of `uint8` in SchemaInstance numFields methods +- 37c228c63: Simplified a check in `Slice.getSubslice`. +- 22ba7b675: Simplified a couple internal constants used for bitshifting. +- 745485cda: Updated `StoreCore` to check that tables exist before registering store hooks. +- 37c228c63: Optimised the `Schema.validate` function to decrease gas use. +- cc2c8da00: - Refactor tightcoder to use typescript functions instead of ejs + - Optimize `TightCoder` library + - Add `isLeftAligned` and `getLeftPaddingBits` common codegen helpers +- Updated dependencies [a35c05ea9] +- Updated dependencies [16b13ea8f] +- Updated dependencies [82693072] +- Updated dependencies [07dd6f32c] +- Updated dependencies [aabd30767] +- Updated dependencies [65c9546c4] +- Updated dependencies [d5c0682fb] +- Updated dependencies [01e46d99] +- Updated dependencies [904fd7d4e] +- Updated dependencies [b98e51808] +- Updated dependencies [331dbfdcb] +- Updated dependencies [44236041f] +- Updated dependencies [066056154] +- Updated dependencies [3fb9ce283] +- Updated dependencies [bb6ada740] +- Updated dependencies [35c9f33df] +- Updated dependencies [0b8ce3f2c] +- Updated dependencies [933b54b5f] +- Updated dependencies [307abab3] +- Updated dependencies [de151fec0] +- Updated dependencies [aacffcb59] +- Updated dependencies [b38c096d] +- Updated dependencies [4bb7e8cbf] +- Updated dependencies [f99e88987] +- Updated dependencies [939916bcd] +- Updated dependencies [e34d1170] +- Updated dependencies [b8a6158d6] +- Updated dependencies [433078c54] +- Updated dependencies [db314a74] +- Updated dependencies [ca50fef81] +- Updated dependencies [59267655] +- Updated dependencies [8d51a0348] +- Updated dependencies [c162ad5a5] +- Updated dependencies [48909d151] +- Updated dependencies [f8a01a047] +- Updated dependencies [b02f9d0e4] +- Updated dependencies [f62c767e7] +- Updated dependencies [bb91edaa0] +- Updated dependencies [590542030] +- Updated dependencies [1b5eb0d07] +- Updated dependencies [44a5432ac] +- Updated dependencies [f03531d97] +- Updated dependencies [b8a6158d6] +- Updated dependencies [5d737cf2e] +- Updated dependencies [d075f82f3] +- Updated dependencies [331dbfdcb] +- Updated dependencies [92de59982] +- Updated dependencies [9ff4dd955] +- Updated dependencies [bfcb293d1] +- Updated dependencies [3e057061d] +- Updated dependencies [535229984] +- Updated dependencies [5e723b90e] +- Updated dependencies [0c4f9fea9] +- Updated dependencies [60cfd089f] +- Updated dependencies [24a6cd536] +- Updated dependencies [708b49c50] +- Updated dependencies [d2f8e9400] +- Updated dependencies [25086be5f] +- Updated dependencies [b1d41727d] +- Updated dependencies [4c1dcd81e] +- Updated dependencies [6071163f7] +- Updated dependencies [6c6733256] +- Updated dependencies [cd5abcc3b] +- Updated dependencies [d7b1c588a] +- Updated dependencies [c4f49240d] +- Updated dependencies [3e7d83d0] +- Updated dependencies [5df1f31bc] +- Updated dependencies [a2f41ade9] +- Updated dependencies [cea754dde] +- Updated dependencies [5e71e1cb5] +- Updated dependencies [331f0d636] +- Updated dependencies [cc2c8da00] + - @latticexyz/common@2.0.0 + - @latticexyz/protocol-parser@2.0.0 + - @latticexyz/schema-type@2.0.0 + - @latticexyz/config@2.0.0 + ## 2.0.0-next.18 ### Major Changes diff --git a/packages/store/package.json b/packages/store/package.json index 8e6606a4f4..26da6936b7 100644 --- a/packages/store/package.json +++ b/packages/store/package.json @@ -1,6 +1,6 @@ { "name": "@latticexyz/store", - "version": "2.0.0-next.18", + "version": "2.0.0", "description": "Store", "repository": { "type": "git", diff --git a/packages/utils/CHANGELOG.md b/packages/utils/CHANGELOG.md index c56a286ebb..bdc9006d29 100644 --- a/packages/utils/CHANGELOG.md +++ b/packages/utils/CHANGELOG.md @@ -1,5 +1,33 @@ # Change Log +## 2.0.0 + +### Major Changes + +- 52182f70d: Removed `keccak256` and `keccak256Coord` hash utils in favor of [viem's `keccak256`](https://viem.sh/docs/utilities/keccak256.html#keccak256). + + ```diff + - import { keccak256 } from "@latticexyz/utils"; + + import { keccak256, toHex } from "viem"; + + - const hash = keccak256("some string"); + + const hash = keccak256(toHex("some string")); + ``` + + ```diff + - import { keccak256Coord } from "@latticexyz/utils"; + + import { encodeAbiParameters, keccak256, parseAbiParameters } from "viem"; + + const coord = { x: 1, y: 1 }; + - const hash = keccak256Coord(coord); + + const hash = keccak256(encodeAbiParameters(parseAbiParameters("int32, int32"), [coord.x, coord.y])); + ``` + +### Patch Changes + +- 590542030: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages. +- 4e4a34150: bump to latest TS version (5.1.6) + ## 2.0.0-next.18 ## 2.0.0-next.17 diff --git a/packages/utils/package.json b/packages/utils/package.json index c2c76433d5..3e719d0da4 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@latticexyz/utils", - "version": "2.0.0-next.18", + "version": "2.0.0", "repository": { "type": "git", "url": "https://github.com/latticexyz/mud.git", diff --git a/packages/world-modules/CHANGELOG.md b/packages/world-modules/CHANGELOG.md index 4e3397f077..a64d8e2bd6 100644 --- a/packages/world-modules/CHANGELOG.md +++ b/packages/world-modules/CHANGELOG.md @@ -1,5 +1,403 @@ # Change Log +## 2.0.0 + +### Major Changes + +- 865253dba: Refactored `InstalledModules` to key modules by addresses instead of pre-defined names. Previously, modules could report arbitrary names, meaning misconfigured modules could be installed under a name intended for another module. +- aabd30767: Bumped Solidity version to 0.8.24. +- 6ca1874e0: Modules now revert with `Module_AlreadyInstalled` if attempting to install more than once with the same calldata. + + This is a temporary workaround for our deploy pipeline. We'll make these install steps more idempotent in the future. + +- 251170e1e: All optional modules have been moved from `@latticexyz/world` to `@latticexyz/world-modules`. + If you're using the MUD CLI, the import is already updated and no changes are necessary. +- 252a1852: Migrated to new config format. + +### Minor Changes + +- d7325e517: Added the `ERC721Module` to `@latticexyz/world-modules`. + This module allows the registration of `ERC721` tokens in an existing World. + + Important note: this module has not been audited yet, so any production use is discouraged for now. + + ````solidity + import { PuppetModule } from "@latticexyz/world-modules/src/modules/puppet/PuppetModule.sol"; + import { ERC721MetadataData } from "@latticexyz/world-modules/src/modules/erc721-puppet/tables/ERC721Metadata.sol"; + import { IERC721Mintable } from "@latticexyz/world-modules/src/modules/erc721-puppet/IERC721Mintable.sol"; + import { registerERC721 } from "@latticexyz/world-modules/src/modules/erc721-puppet/registerERC721.sol"; + + // The ERC721 module requires the Puppet module to be installed first + world.installModule(new PuppetModule(), new bytes(0)); + + // After the Puppet module is installed, new ERC721 tokens can be registered + IERC721Mintable token = registerERC721(world, "myERC721", ERC721MetadataData({ name: "Token", symbol: "TKN", baseURI: "" }));``` + ```` + +- 35348f831: Added the `PuppetModule` to `@latticexyz/world-modules`. The puppet pattern allows an external contract to be registered as an external interface for a MUD system. + This allows standards like `ERC20` (that require a specific interface and events to be emitted by a unique contract) to be implemented inside a MUD World. + + The puppet serves as a proxy, forwarding all calls to the implementation system (also called the "puppet master"). + The "puppet master" system can emit events from the puppet contract. + + ```solidity + import { PuppetModule } from "@latticexyz/world-modules/src/modules/puppet/PuppetModule.sol"; + import { createPuppet } from "@latticexyz/world-modules/src/modules/puppet/createPuppet.sol"; + + // Install the puppet module + world.installModule(new PuppetModule(), new bytes(0)); + + // Register a new puppet for any system + // The system must implement the `CustomInterface`, + // and the caller must own the system's namespace + CustomInterface puppet = CustomInterface(createPuppet(world, )); + ``` + +- c4fc85041: Fixed `SystemSwitch` to properly call non-root systems from root systems. +- 9352648b1: Since [#1564](https://github.com/latticexyz/mud/pull/1564) the World can no longer call itself via an external call. + This made the developer experience of calling other systems via root systems worse, since calls from root systems are executed from the context of the World. + The recommended approach is to use `delegatecall` to the system if in the context of a root system, and an external call via the World if in the context of a non-root system. + To bring back the developer experience of calling systems from other sysyems without caring about the context in which the call is executed, we added the `SystemSwitch` util. + + ```diff + - // Instead of calling the system via an external call to world... + - uint256 value = IBaseWorld(_world()).callMySystem(); + + + // ...you can now use the `SystemSwitch` util. + + // This works independent of whether used in a root system or non-root system. + + uint256 value = abi.decode(SystemSwitch.call(abi.encodeCall(IBaseWorld.callMySystem, ()), (uint256)); + ``` + + Note that if you already know your system is always executed as non-root system, you can continue to use the approach of calling other systems via the `IBaseWorld(world)`. + +- 836383734: Added the `ERC20Module` to `@latticexyz/world-modules`. + This module allows the registration of `ERC20` tokens in an existing World. + + Important note: this module has not been audited yet, so any production use is discouraged for now. + + ```solidity + import { PuppetModule } from "@latticexyz/world-modules/src/modules/puppet/PuppetModule.sol"; + import { IERC20Mintable } from "@latticexyz/world-modules/src/modules/erc20-puppet/IERC20Mintable.sol"; + import { registerERC20 } from "@latticexyz/world-modules/src/modules/erc20-puppet/registerERC20.sol"; + + // The ERC20 module requires the Puppet module to be installed first + world.installModule(new PuppetModule(), new bytes(0)); + + // After the Puppet module is installed, new ERC20 tokens can be registered + IERC20Mintable token = registerERC20(world, "myERC20", ERC20MetadataData({ decimals: 18, name: "Token", symbol: "TKN" })); + ``` + +- 3042f86e: Moved key schema and value schema methods to constants in code-generated table libraries for less bytecode and less gas in register/install methods. + + ```diff + -console.log(SomeTable.getKeySchema()); + +console.log(SomeTable._keySchema); + + -console.log(SomeTable.getValueSchema()); + +console.log(SomeTable._valueSchema); + ``` + +- fdbba6d88: Added a new delegation control called `SystemboundDelegationControl` that delegates control of a specific system for some maximum number of calls. It is almost identical to `CallboundDelegationControl` except the delegatee can call the system with any function and args. + +### Patch Changes + +- 7ce82b6fc: Store config now defaults `storeArgument: false` for all tables. This means that table libraries, by default, will no longer include the extra functions with the `_store` argument. This default was changed to clear up the confusion around using table libraries in tests, `PostDeploy` scripts, etc. + + If you are sure you need to manually specify a store when interacting with tables, you can still manually toggle it back on with `storeArgument: true` in the table settings of your MUD config. + + If you want to use table libraries in `PostDeploy.s.sol`, you can add the following lines: + + ```diff + import { Script } from "forge-std/Script.sol"; + import { console } from "forge-std/console.sol"; + import { IWorld } from "../src/codegen/world/IWorld.sol"; + + import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; + + contract PostDeploy is Script { + function run(address worldAddress) external { + + StoreSwitch.setStoreAddress(worldAddress); + + + + SomeTable.get(someKey); + ``` + +- a35c05ea9: Table libraries now hardcode the `bytes32` table ID value rather than computing it in Solidity. This saves a bit of gas across all storage operations. +- eaa766ef7: Removed `IUniqueEntitySystem` in favor of calling `getUniqueEntity` via `world.call` instead of the world function selector. This had a small gas improvement. +- 0f27afddb: World function signatures for namespaced systems have changed from `{namespace}_{systemName}_{functionName}` to `{namespace}__{functionName}` (double underscore, no system name). This is more ergonomic and is more consistent with namespaced resources in other parts of the codebase (e.g. MUD config types, table names in the schemaful indexer). + + If you have a project using the `namespace` key in your `mud.config.ts` or are manually registering systems and function selectors on a namespace, you will likely need to codegen your system interfaces (`pnpm build`) and update any calls to these systems through the world's namespaced function signatures. + +- c07fa0215: Tables and interfaces in the `world` package are now generated to the `codegen` folder. + This is only a breaking change if you imported tables or codegenerated interfaces from `@latticexyz/world` directly. + If you're using the MUD CLI, the changed import paths are already integrated and no further changes are necessary. + + ```diff + - import { IBaseWorld } from "@latticexyz/world/src/interfaces/IBaseWorld.sol"; + + import { IBaseWorld } from "@latticexyz/world/src/codegen/interfaces/IBaseWorld.sol"; + + ``` + +- 4be22ba4: ERC20 and ERC721 implementations now always register the token namespace, instead of checking if it has already been registered. This prevents issues with registering the namespace beforehand, namely that only the owner of a system can create a puppet for it. +- 44236041f: Moved table ID and field layout constants in code-generated table libraries from the file level into the library, for clearer access and cleaner imports. + + ```diff + -import { SomeTable, SomeTableTableId } from "./codegen/tables/SomeTable.sol"; + +import { SomeTable } from "./codegen/tables/SomeTable.sol"; + + -console.log(SomeTableTableId); + +console.log(SomeTable._tableId); + + -console.log(SomeTable.getFieldLayout()); + +console.log(SomeTable._fieldLayout); + ``` + +- eb384bb0e: Added `isInstalled` and `requireNotInstalled` helpers to `Module` base contract. +- 063daf80e: Previously `registerSystem` and `registerTable` had a side effect of registering namespaces if the system or table's namespace didn't exist yet. + This caused a possible frontrunning issue, where an attacker could detect a `registerSystem`/`registerTable` transaction in the mempool, + insert a `registerNamespace` transaction before it, grant themselves access to the namespace, transfer ownership of the namespace to the victim, + so that the `registerSystem`/`registerTable` transactions still went through successfully. + To mitigate this issue, the side effect of registering a namespace in `registerSystem` and `registerTable` has been removed. + Calls to these functions now expect the respective namespace to exist and the caller to own the namespace, otherwise they revert. + + Changes in consuming projects are only necessary if tables or systems are registered manually. + If only the MUD deployer is used to register tables and systems, no changes are necessary, as the MUD deployer has been updated accordingly. + + ```diff + + world.registerNamespace(namespaceId); + world.registerSystem(systemId, system, true); + ``` + + ```diff + + world.registerNamespace(namespaceId); + MyTable.register(); + ``` + +- 37c228c63: Refactored `ResourceId` to use a global Solidity `using` statement. +- 37c228c63: Refactored EIP165 usages to use the built-in interfaceId property instead of pre-defined constants. +- 88b1a5a19: We now expose a `WorldContextConsumerLib` library with the same functionality as the `WorldContextConsumer` contract, but the ability to be used inside of internal libraries. + We also renamed the `WorldContextProvider` library to `WorldContextProviderLib` for consistency. +- 590542030: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages. +- e2d089c6d: Renamed the Module `args` parameter to `encodedArgs` to better reflect that it is ABI-encoded arguments. +- 1890f1a06: Moved `store` tables to the `"store"` namespace (previously "mudstore") and `world` tables to the `"world"` namespace (previously root namespace). +- 37c228c63: Refactored various Solidity files to not explicitly initialise variables to zero. +- 747d8d1b8: Renamed token address fields in ERC20 and ERC721 modules to `tokenAddress` +- 3e7d83d0: Renamed `PackedCounter` to `EncodedLengths` for consistency. +- Updated dependencies [7ce82b6fc] +- Updated dependencies [d8c8f66bf] +- Updated dependencies [c6c13f2ea] +- Updated dependencies [77dce993a] +- Updated dependencies [ce97426c0] +- Updated dependencies [1b86eac05] +- Updated dependencies [a35c05ea9] +- Updated dependencies [c9ee5e4a] +- Updated dependencies [c963b46c7] +- Updated dependencies [05b3e8882] +- Updated dependencies [0f27afddb] +- Updated dependencies [748f4588a] +- Updated dependencies [865253dba] +- Updated dependencies [8f49c277d] +- Updated dependencies [7fa2ca183] +- Updated dependencies [745485cda] +- Updated dependencies [16b13ea8f] +- Updated dependencies [aea67c580] +- Updated dependencies [82693072] +- Updated dependencies [07dd6f32c] +- Updated dependencies [c07fa0215] +- Updated dependencies [90e4161bb] +- Updated dependencies [aabd30767] +- Updated dependencies [65c9546c4] +- Updated dependencies [6ca1874e0] +- Updated dependencies [331dbfdcb] +- Updated dependencies [d5c0682fb] +- Updated dependencies [1d60930d6] +- Updated dependencies [01e46d99] +- Updated dependencies [430e6b29a] +- Updated dependencies [f9f9609ef] +- Updated dependencies [904fd7d4e] +- Updated dependencies [e6c03a87a] +- Updated dependencies [1077c7f53] +- Updated dependencies [2c920de7] +- Updated dependencies [b9e562d8f] +- Updated dependencies [331dbfdcb] +- Updated dependencies [44236041f] +- Updated dependencies [066056154] +- Updated dependencies [759514d8b] +- Updated dependencies [952cd5344] +- Updated dependencies [d5094a242] +- Updated dependencies [3fb9ce283] +- Updated dependencies [c207d35e8] +- Updated dependencies [db7798be2] +- Updated dependencies [bb6ada740] +- Updated dependencies [35c9f33df] +- Updated dependencies [3be4deecf] +- Updated dependencies [a25881160] +- Updated dependencies [0b8ce3f2c] +- Updated dependencies [933b54b5f] +- Updated dependencies [5debcca8] +- Updated dependencies [c4d5eb4e4] +- Updated dependencies [f8dab7334] +- Updated dependencies [1a0fa7974] +- Updated dependencies [f62c767e7] +- Updated dependencies [d00c4a9af] +- Updated dependencies [9aa5e786] +- Updated dependencies [307abab3] +- Updated dependencies [de151fec0] +- Updated dependencies [c32a9269a] +- Updated dependencies [eb384bb0e] +- Updated dependencies [37c228c63] +- Updated dependencies [618dd0e89] +- Updated dependencies [aacffcb59] +- Updated dependencies [c991c71a] +- Updated dependencies [ae340b2bf] +- Updated dependencies [1bf2e9087] +- Updated dependencies [e5d208e40] +- Updated dependencies [b38c096d] +- Updated dependencies [211be2a1e] +- Updated dependencies [0f3e2e02b] +- Updated dependencies [1f80a0b52] +- Updated dependencies [d08789282] +- Updated dependencies [5c965a919] +- Updated dependencies [f99e88987] +- Updated dependencies [939916bcd] +- Updated dependencies [e5a962bc3] +- Updated dependencies [331f0d636] +- Updated dependencies [f6f402896] +- Updated dependencies [d5b73b126] +- Updated dependencies [e34d1170] +- Updated dependencies [08b422171] +- Updated dependencies [b8a6158d6] +- Updated dependencies [190fdd11] +- Updated dependencies [37c228c63] +- Updated dependencies [37c228c63] +- Updated dependencies [433078c54] +- Updated dependencies [db314a74] +- Updated dependencies [b2d2aa715] +- Updated dependencies [4c7fd3eb2] +- Updated dependencies [a0341daf9] +- Updated dependencies [83583a505] +- Updated dependencies [5e723b90e] +- Updated dependencies [6573e38e9] +- Updated dependencies [51914d656] +- Updated dependencies [063daf80e] +- Updated dependencies [afaf2f5ff] +- Updated dependencies [37c228c63] +- Updated dependencies [59267655] +- Updated dependencies [37c228c63] +- Updated dependencies [2bfee9217] +- Updated dependencies [1ca35e9a1] +- Updated dependencies [44a5432ac] +- Updated dependencies [6e66c5b74] +- Updated dependencies [8d51a0348] +- Updated dependencies [c162ad5a5] +- Updated dependencies [88b1a5a19] +- Updated dependencies [65c9546c4] +- Updated dependencies [48909d151] +- Updated dependencies [7b28d32e5] +- Updated dependencies [b02f9d0e4] +- Updated dependencies [2ca75f9b9] +- Updated dependencies [f62c767e7] +- Updated dependencies [bb91edaa0] +- Updated dependencies [590542030] +- Updated dependencies [1a82c278] +- Updated dependencies [1b5eb0d07] +- Updated dependencies [44a5432ac] +- Updated dependencies [48c51b52a] +- Updated dependencies [9f8b84e73] +- Updated dependencies [66cc35a8c] +- Updated dependencies [672d05ca1] +- Updated dependencies [f1cd43bf9] +- Updated dependencies [9d0f492a9] +- Updated dependencies [55a05fd7a] +- Updated dependencies [f03531d97] +- Updated dependencies [c583f3cd0] +- Updated dependencies [31ffc9d5d] +- Updated dependencies [5e723b90e] +- Updated dependencies [63831a264] +- Updated dependencies [b8a6158d6] +- Updated dependencies [6db95ce15] +- Updated dependencies [8193136a9] +- Updated dependencies [5d737cf2e] +- Updated dependencies [d075f82f3] +- Updated dependencies [331dbfdcb] +- Updated dependencies [a7b30c79b] +- Updated dependencies [6470fe1fd] +- Updated dependencies [86766ce1] +- Updated dependencies [92de59982] +- Updated dependencies [5741d53d0] +- Updated dependencies [aee8020a6] +- Updated dependencies [22ee44700] +- Updated dependencies [e2d089c6d] +- Updated dependencies [ad4ac4459] +- Updated dependencies [be313068b] +- Updated dependencies [ac508bf18] +- Updated dependencies [93390d89] +- Updated dependencies [57d8965df] +- Updated dependencies [18d3aea55] +- Updated dependencies [7987c94d6] +- Updated dependencies [bb91edaa0] +- Updated dependencies [144c0d8d] +- Updated dependencies [5ac4c97f4] +- Updated dependencies [bfcb293d1] +- Updated dependencies [3e057061d] +- Updated dependencies [1890f1a06] +- Updated dependencies [e48171741] +- Updated dependencies [e4a6189df] +- Updated dependencies [9b43029c3] +- Updated dependencies [37c228c63] +- Updated dependencies [55ab88a60] +- Updated dependencies [c58da9ad] +- Updated dependencies [37c228c63] +- Updated dependencies [4e4a34150] +- Updated dependencies [535229984] +- Updated dependencies [af639a264] +- Updated dependencies [5e723b90e] +- Updated dependencies [99ab9cd6f] +- Updated dependencies [be18b75b] +- Updated dependencies [0c4f9fea9] +- Updated dependencies [0d12db8c2] +- Updated dependencies [c049c23f4] +- Updated dependencies [80dd6992e] +- Updated dependencies [60cfd089f] +- Updated dependencies [24a6cd536] +- Updated dependencies [37c228c63] +- Updated dependencies [708b49c50] +- Updated dependencies [d2f8e9400] +- Updated dependencies [17f987209] +- Updated dependencies [25086be5f] +- Updated dependencies [37c228c63] +- Updated dependencies [b1d41727d] +- Updated dependencies [3ac68ade6] +- Updated dependencies [c642ff3a0] +- Updated dependencies [22ba7b675] +- Updated dependencies [4c1dcd81e] +- Updated dependencies [3042f86e] +- Updated dependencies [c049c23f4] +- Updated dependencies [5e71e1cb5] +- Updated dependencies [6071163f7] +- Updated dependencies [6c6733256] +- Updated dependencies [cd5abcc3b] +- Updated dependencies [d7b1c588a] +- Updated dependencies [5c52bee09] +- Updated dependencies [251170e1e] +- Updated dependencies [8025c3505] +- Updated dependencies [c4f49240d] +- Updated dependencies [745485cda] +- Updated dependencies [95f64c85] +- Updated dependencies [37c228c63] +- Updated dependencies [3e7d83d0] +- Updated dependencies [5df1f31bc] +- Updated dependencies [29c3f5087] +- Updated dependencies [cea754dde] +- Updated dependencies [331f0d636] +- Updated dependencies [95c59b203] +- Updated dependencies [cc2c8da00] +- Updated dependencies [252a1852] +- Updated dependencies [103f635eb] + - @latticexyz/store@2.0.0 + - @latticexyz/world@2.0.0 + - @latticexyz/common@2.0.0 + - @latticexyz/schema-type@2.0.0 + - @latticexyz/config@2.0.0 + ## 2.0.0-next.18 ### Major Changes diff --git a/packages/world-modules/package.json b/packages/world-modules/package.json index ad5fb14c29..d16d886893 100644 --- a/packages/world-modules/package.json +++ b/packages/world-modules/package.json @@ -1,6 +1,6 @@ { "name": "@latticexyz/world-modules", - "version": "2.0.0-next.18", + "version": "2.0.0", "description": "World modules", "repository": { "type": "git", diff --git a/packages/world/CHANGELOG.md b/packages/world/CHANGELOG.md index 732d599c3e..bc7a31a71d 100644 --- a/packages/world/CHANGELOG.md +++ b/packages/world/CHANGELOG.md @@ -1,5 +1,1550 @@ # Change Log +## 2.0.0 + +### Major Changes + +- 77dce993a: Moves World interfaces and factories files for consistency with our other packages. + + If you import any World interfaces or factories directly, you'll need to update the import path: + + ```diff + - import { IBaseWorld } from "@latticexyz/world/src/interfaces/IBaseWorld.sol"; + + import { IBaseWorld } from "@latticexyz/world/src/IBaseWorld.sol"; + ``` + + ```diff + - import { IBaseWorld } from "@latticexyz/world/src/factories/WorldFactory.sol"; + + import { IBaseWorld } from "@latticexyz/world/src/WorldFactory.sol"; + ``` + +- c9ee5e4a: Store and World configs have been rebuilt with strong types. The shape of these configs have also changed slightly for clarity, the biggest change of which is merging of `keySchema` and `valueSchema` into a single `schema` with a separate `key` for a table's primary key. + + To migrate, first update the imported config method: + + ```diff filename="mud.config.ts" + -import { mudConfig } from "@latticexyz/world/register"; + +import { defineWorld } from "@latticexyz/world"; + + -export default mudConfig({ + +export default defineWorld({ + ``` + + _Note that if you are only using Store, you will need to import `defineStore` from `@latticexyz/store`._ + + Then migrate the table key by renaming `keySchema` to `schema` and define the table `key` with each field name from your key schema: + + ```diff filename="mud.config.ts" + export default defineWorld({ + tables: { + Position: { + - keySchema: { + + schema: { + player: "address", + }, + valueSchema: { + x: "int32", + y: "int32", + }, + + key: ['player'], + }, + }, + }); + ``` + + Now we can merge the `valueSchema` into `schema`. + + ```diff filename="mud.config.ts" + export default defineWorld({ + tables: { + Position: { + schema: { + player: "address", + - }, + - valueSchema: { + x: "int32", + y: "int32", + }, + key: ['player'], + }, + }, + }); + ``` + + If you previously used the table config shorthand without the full `keySchema` and `valueSchema`, some of the defaults have changed. Shorthands now use an `id: "bytes32"` field by default rather than `key: "bytes32"` and corresponding `key: ["id"]`. To keep previous behavior, you may have to manually define your `schema` with the previous `key` and `value` fields. + + ```diff filename="mud.config.ts" + export default defineWorld({ + tables: { + - OwnedBy: "address", + + OwnedBy: { + + schema: { + + key: "bytes32", + + value: "address", + + }, + + key: ["key"], + + }, + }, + }); + ``` + + Singleton tables are defined similarly, where an empty `key` rather than `keySchema` is provided: + + ```diff filename="mud.config.ts" + -keySchema: {} + +key: [] + ``` + + Offchain tables are now defined as a table `type` instead an `offchainOnly` boolean: + + ```diff filename="mud.config.ts" + -offchainOnly: true + +type: 'offchainTable' + ``` + + All codegen options have moved under `codegen`: + + ```diff filename="mud.config.ts" + export default defineWorld({ + - codegenDirectory: "…", + + codegen: { + + outputDirectory: "…", + + }, + tables: { + Position: { + schema: { + player: "address", + x: "int32", + y: "int32", + }, + key: ['player'], + - directory: "…", + - dataStruct: false, + + codegen: { + + outputDirectory: "…", + + dataStruct: false, + + }, + }, + }, + }); + ``` + +- 0f27afddb: World function signatures for namespaced systems have changed from `{namespace}_{systemName}_{functionName}` to `{namespace}__{functionName}` (double underscore, no system name). This is more ergonomic and is more consistent with namespaced resources in other parts of the codebase (e.g. MUD config types, table names in the schemaful indexer). + + If you have a project using the `namespace` key in your `mud.config.ts` or are manually registering systems and function selectors on a namespace, you will likely need to codegen your system interfaces (`pnpm build`) and update any calls to these systems through the world's namespaced function signatures. + +- 748f4588a: All `World` methods now revert if the `World` calls itself. + The `World` should never need to externally call itself, since all internal table operations happen via library calls, and all root system operations happen via delegate call. + + It should not be possible to make the `World` call itself as an external actor. + If it were possible to make the `World` call itself, it would be possible to write to internal tables that only the `World` should have access to. + As this is a very important invariance, we made it explicit in a requirement check in every `World` method, rather than just relying on making it impossible to trigger the `World` to call itself. + + This is a breaking change for modules that previously used external calls to the `World` in the `installRoot` method. + In the `installRoot` method, the `World` can only be called via `delegatecall`, and table operations should be performed via the internal table methods (e.g. `_set` instead of `set`). + + Example for how to replace external calls to `world` in root systems / root modules (`installRoot`) with `delegatecall`: + + ```diff + + import { revertWithBytes } from "@latticexyz/world/src/revertWithBytes.sol"; + + - world.grantAccess(tableId, address(hook)); + + (bool success, bytes memory returnData) = address(world).delegatecall( + + abi.encodeCall(world.grantAccess, (tableId, address(hook))) + + ); + + + if (!success) revertWithBytes(returnData); + ``` + +- 865253dba: Refactored `InstalledModules` to key modules by addresses instead of pre-defined names. Previously, modules could report arbitrary names, meaning misconfigured modules could be installed under a name intended for another module. +- c07fa0215: Tables and interfaces in the `world` package are now generated to the `codegen` folder. + This is only a breaking change if you imported tables or codegenerated interfaces from `@latticexyz/world` directly. + If you're using the MUD CLI, the changed import paths are already integrated and no further changes are necessary. + + ```diff + - import { IBaseWorld } from "@latticexyz/world/src/interfaces/IBaseWorld.sol"; + + import { IBaseWorld } from "@latticexyz/world/src/codegen/interfaces/IBaseWorld.sol"; + + ``` + +- aabd30767: Bumped Solidity version to 0.8.24. +- 331dbfdcb: We've updated Store events to be "schemaless", meaning there is enough information in each event to only need to operate on the bytes of each record to make an update to that record without having to first decode the record by its schema. This enables new kinds of indexers and sync strategies. + + If you've written your own sync logic or are interacting with Store calls directly, this is a breaking change. We have a few more breaking protocol changes upcoming, so you may hold off on upgrading until those land. + + If you are using MUD's built-in tooling (table codegen, indexer, store sync, etc.), you don't have to make any changes except upgrading to the latest versions and deploying a fresh World. + + - The `data` field in each `StoreSetRecord` and `StoreEphemeralRecord` has been replaced with three new fields: `staticData`, `encodedLengths`, and `dynamicData`. This better reflects the on-chain state and makes it easier to perform modifications to the raw bytes. We recommend storing each of these fields individually in your off-chain storage of choice (indexer, client, etc.). + + ```diff + - event StoreSetRecord(bytes32 tableId, bytes32[] keyTuple, bytes data); + + event StoreSetRecord(bytes32 tableId, bytes32[] keyTuple, bytes staticData, bytes32 encodedLengths, bytes dynamicData); + + - event StoreEphemeralRecord(bytes32 tableId, bytes32[] keyTuple, bytes data); + + event StoreEphemeralRecord(bytes32 tableId, bytes32[] keyTuple, bytes staticData, bytes32 encodedLengths, bytes dynamicData); + ``` + + - The `StoreSetField` event is now replaced by two new events: `StoreSpliceStaticData` and `StoreSpliceDynamicData`. Splicing allows us to perform efficient operations like push and pop, in addition to replacing a field value. We use two events because updating a dynamic-length field also requires updating the record's `encodedLengths` (aka PackedCounter). + + ```diff + - event StoreSetField(bytes32 tableId, bytes32[] keyTuple, uint8 fieldIndex, bytes data); + + event StoreSpliceStaticData(bytes32 tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data); + + event StoreSpliceDynamicData(bytes32 tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data, bytes32 encodedLengths); + ``` + + Similarly, Store setter methods (e.g. `setRecord`) have been updated to reflect the `data` to `staticData`, `encodedLengths`, and `dynamicData` changes. We'll be following up shortly with Store getter method changes for more gas efficient storage reads. + +- b9e562d8f: 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 {} + ``` + +- 759514d8b: Moved the registration of store hooks and systems hooks to bitmaps with bitwise operator instead of a struct. + + ```diff + - import { StoreHookLib } from "@latticexyz/src/StoreHook.sol"; + + import { + + BEFORE_SET_RECORD, + + BEFORE_SET_FIELD, + + BEFORE_DELETE_RECORD + + } from "@latticexyz/store/storeHookTypes.sol"; + + StoreCore.registerStoreHook( + tableId, + subscriber, + - StoreHookLib.encodeBitmap({ + - onBeforeSetRecord: true, + - onAfterSetRecord: false, + - onBeforeSetField: true, + - onAfterSetField: false, + - onBeforeDeleteRecord: true, + - onAfterDeleteRecord: false + - }) + + BEFORE_SET_RECORD | BEFORE_SET_FIELD | BEFORE_DELETE_RECORD + ); + ``` + + ```diff + - import { SystemHookLib } from "../src/SystemHook.sol"; + + import { BEFORE_CALL_SYSTEM, AFTER_CALL_SYSTEM } from "../src/systemHookTypes.sol"; + + world.registerSystemHook( + systemId, + subscriber, + - SystemHookLib.encodeBitmap({ onBeforeCallSystem: true, onAfterCallSystem: true }) + + BEFORE_CALL_SYSTEM | AFTER_CALL_SYSTEM + ); + + ``` + +- 952cd5344: All `Store` methods now require the table's value schema to be passed in as an argument instead of loading it from storage. + This decreases gas cost and removes circular dependencies of the Schema table (where it was not possible to write to the Schema table before the Schema table was registered). + + ```diff + function setRecord( + bytes32 table, + bytes32[] calldata key, + bytes calldata data, + + Schema valueSchema + ) external; + ``` + + The same diff applies to `getRecord`, `getField`, `setField`, `pushToField`, `popFromField`, `updateInField`, and `deleteRecord`. + + This change only requires changes in downstream projects if the `Store` methods were accessed directly. In most cases it is fully abstracted in the generated table libraries, + so downstream projects only need to regenerate their table libraries after updating MUD. + +- d5094a242: - The `IStoreHook` interface was changed to replace `onBeforeSetField` and `onAfterSetField` with `onBeforeSpliceStaticData`, `onAfterSpliceStaticData`, `onBeforeSpliceDynamicData` and `onAfterSpliceDynamicData`. + + This new interface matches the new `StoreSpliceStaticData` and `StoreSpliceDynamicData` events, and avoids having to read the entire field from storage when only a subset of the field was updated + (e.g. when pushing elements to a field). + + ```diff + interface IStoreHook { + - function onBeforeSetField( + - bytes32 tableId, + - bytes32[] memory keyTuple, + - uint8 fieldIndex, + - bytes memory data, + - FieldLayout fieldLayout + - ) external; + + - function onAfterSetField( + - bytes32 tableId, + - bytes32[] memory keyTuple, + - uint8 fieldIndex, + - bytes memory data, + - FieldLayout fieldLayout + - ) external; + + + function onBeforeSpliceStaticData( + + bytes32 tableId, + + bytes32[] memory keyTuple, + + uint48 start, + + uint40 deleteCount, + + bytes memory data + + ) external; + + + function onAfterSpliceStaticData( + + bytes32 tableId, + + bytes32[] memory keyTuple, + + uint48 start, + + uint40 deleteCount, + + bytes memory data + + ) external; + + + function onBeforeSpliceDynamicData( + + bytes32 tableId, + + bytes32[] memory keyTuple, + + uint8 dynamicFieldIndex, + + uint40 startWithinField, + + uint40 deleteCount, + + bytes memory data, + + PackedCounter encodedLengths + + ) external; + + + function onAfterSpliceDynamicData( + + bytes32 tableId, + + bytes32[] memory keyTuple, + + uint8 dynamicFieldIndex, + + uint40 startWithinField, + + uint40 deleteCount, + + bytes memory data, + + PackedCounter encodedLengths + + ) external; + } + ``` + + - All `calldata` parameters on the `IStoreHook` interface were changed to `memory`, since the functions are called with `memory` from the `World`. + - `IStore` exposes two new functions: `spliceStaticData` and `spliceDynamicData`. + + These functions provide lower level access to the operations happening under the hood in `setField`, `pushToField`, `popFromField` and `updateInField` and simplify handling + the new splice hooks. + + `StoreCore`'s internal logic was simplified to use the `spliceStaticData` and `spliceDynamicData` functions instead of duplicating similar logic in different functions. + + ```solidity + interface IStore { + // Splice data in the static part of the record + function spliceStaticData( + bytes32 tableId, + bytes32[] calldata keyTuple, + uint48 start, + uint40 deleteCount, + bytes calldata data + ) external; + + // Splice data in the dynamic part of the record + function spliceDynamicData( + bytes32 tableId, + bytes32[] calldata keyTuple, + uint8 dynamicFieldIndex, + uint40 startWithinField, + uint40 deleteCount, + bytes calldata data + ) external; + } + ``` + +- db7798be2: Renamed `CoreModule` to `InitModule` and `CoreRegistrationSystem` to `RegistrationSystem`. +- c4d5eb4e4: - The `onSetRecord` hook is split into `onBeforeSetRecord` and `onAfterSetRecord` and the `onDeleteRecord` hook is split into `onBeforeDeleteRecord` and `onAfterDeleteRecord`. + The purpose of this change is to allow more fine-grained control over the point in the lifecycle at which hooks are executed. + + The previous hooks were executed before modifying data, so they can be replaced with the respective `onBefore` hooks. + + ```diff + - function onSetRecord( + + function onBeforeSetRecord( + bytes32 table, + bytes32[] memory key, + bytes memory data, + Schema valueSchema + ) public; + + - function onDeleteRecord( + + function onBeforeDeleteRecord( + bytes32 table, + bytes32[] memory key, + Schema valueSchema + ) public; + ``` + + - It is now possible to specify which methods of a hook contract should be called when registering a hook. The purpose of this change is to save gas by avoiding to call no-op hook methods. + + ```diff + function registerStoreHook( + bytes32 tableId, + - IStoreHook hookAddress + + IStoreHook hookAddress, + + uint8 enabledHooksBitmap + ) public; + + function registerSystemHook( + bytes32 systemId, + - ISystemHook hookAddress + + ISystemHook hookAddress, + + uint8 enabledHooksBitmap + ) public; + ``` + + There are `StoreHookLib` and `SystemHookLib` with helper functions to encode the bitmap of enabled hooks. + + ```solidity + import { StoreHookLib } from "@latticexyz/store/src/StoreHook.sol"; + + uint8 storeHookBitmap = StoreBookLib.encodeBitmap({ + onBeforeSetRecord: true, + onAfterSetRecord: true, + onBeforeSetField: true, + onAfterSetField: true, + onBeforeDeleteRecord: true, + onAfterDeleteRecord: true + }); + ``` + + ```solidity + import { SystemHookLib } from "@latticexyz/world/src/SystemHook.sol"; + + uint8 systemHookBitmap = SystemHookLib.encodeBitmap({ + onBeforeCallSystem: true, + onAfterCallSystem: true + }); + ``` + + - The `onSetRecord` hook call for `emitEphemeralRecord` has been removed to save gas and to more clearly distinguish ephemeral tables as offchain tables. + +- 9aa5e786: Set the protocol version to `2.0.0` for each Store and World. +- de151fec0: - Add `FieldLayout`, which is a `bytes32` user-type similar to `Schema`. + + Both `FieldLayout` and `Schema` have the same kind of data in the first 4 bytes. + + - 2 bytes for total length of all static fields + - 1 byte for number of static size fields + - 1 byte for number of dynamic size fields + + But whereas `Schema` has `SchemaType` enum in each of the other 28 bytes, `FieldLayout` has static byte lengths in each of the other 28 bytes. + + - Replace `Schema valueSchema` with `FieldLayout fieldLayout` in Store and World contracts. + + `FieldLayout` is more gas-efficient because it already has lengths, and `Schema` has types which need to be converted to lengths. + + - Add `getFieldLayout` to `IStore` interface. + + There is no `FieldLayout` for keys, only for values, because key byte lengths aren't usually relevant on-chain. You can still use `getKeySchema` if you need key types. + + - Add `fieldLayoutToHex` utility to `protocol-parser` package. + - Add `constants.sol` for constants shared between `FieldLayout`, `Schema` and `PackedCounter`. + +- c32a9269a: - All `World` function selectors that previously had `bytes16 namespace, bytes16 name` arguments now use `bytes32 resourceSelector` instead. + This includes `setRecord`, `setField`, `pushToField`, `popFromField`, `updateInField`, `deleteRecord`, `call`, `grantAccess`, `revokeAccess`, `registerTable`, + `registerStoreHook`, `registerSystemHook`, `registerFunctionSelector`, `registerSystem` and `registerRootFunctionSelector`. + This change aligns the `World` function selectors with the `Store` function selectors, reduces clutter, reduces gas cost and reduces the `World`'s contract size. + + - The `World`'s `registerHook` function is removed. Use `registerStoreHook` or `registerSystemHook` instead. + - The `deploy` script is updated to integrate the World interface changes + +- 618dd0e89: `WorldFactory` now expects a user-provided `salt` when calling `deployWorld(...)` (instead of the previous globally incrementing counter). This enables deterministic world addresses across different chains. + + When using `mud deploy`, you can provide a `bytes32` hex-encoded salt using the `--salt` option, otherwise it defaults to a random hex value. + +- ae340b2bf: Store's `getRecord` has been updated to return `staticData`, `encodedLengths`, and `dynamicData` instead of a single `data` blob, to match the new behaviour of Store setter methods. + + If you use codegenerated libraries, you will only need to update `encode` calls. + + ```diff + - bytes memory data = Position.encode(x, y); + + (bytes memory staticData, PackedCounter encodedLengths, bytes memory dynamicData) = Position.encode(x, y); + ``` + +- e5d208e40: The `registerRootFunctionSelector` function's signature was changed to accept a `string functionSignature` parameter instead of a `bytes4 functionSelector` parameter. + This change enables the `World` to store the function signatures of all registered functions in a `FunctionSignatures` offchain table, which will allow for the automatic generation of interfaces for a given `World` address in the future. + + ```diff + IBaseWorld { + function registerRootFunctionSelector( + ResourceId systemId, + - bytes4 worldFunctionSelector, + + string memory worldFunctionSignature, + bytes4 systemFunctionSelector + ) external returns (bytes4 worldFunctionSelector); + } + ``` + +- 331f0d636: The `SnapSyncModule` is removed. The recommended way of loading the initial state of a MUD app is via the new [`store-indexer`](https://mud.dev/indexer). Loading state via contract getter functions is not recommended, as it's computationally heavy on the RPC, can't be cached, and is an easy way to shoot yourself in the foot with exploding RPC costs. + + The `@latticexyz/network` package was deprecated and is now removed. All consumers should upgrade to the new sync stack from `@latticexyz/store-sync`. + +- 83583a505: Store and World contract ABIs are now exported from the `out` directory. You'll need to update your imports like: + + ```diff + - import IBaseWorldAbi from "@latticexyz/world/abi/IBaseWorld.sol/IBaseWorldAbi.json"; + + import IBaseWorldAbi from "@latticexyz/world/out/IBaseWorld.sol/IBaseWorldAbi.json"; + ``` + + `MudTest.sol` was also moved to the World package. You can update your import like: + + ```diff + - import { MudTest } from "@latticexyz/store/src/MudTest.sol"; + + import { MudTest } from "@latticexyz/world/test/MudTest.t.sol"; + ``` + +- 51914d656: - The access control library no longer allows calls by the `World` contract to itself to bypass the ownership check. + This is a breaking change for root modules that relied on this mechanism to register root tables, systems or function selectors. + To upgrade, root modules must use `delegatecall` instead of a regular `call` to install root tables, systems or function selectors. + + ```diff + - world.registerSystem(rootSystemId, rootSystemAddress); + + address(world).delegatecall(abi.encodeCall(world.registerSystem, (rootSystemId, rootSystemAddress))); + ``` + + - An `installRoot` method was added to the `IModule` interface. + This method is now called when installing a root module via `world.installRootModule`. + When installing non-root modules via `world.installModule`, the module's `install` function continues to be called. + +- 063daf80e: Previously `registerSystem` and `registerTable` had a side effect of registering namespaces if the system or table's namespace didn't exist yet. + This caused a possible frontrunning issue, where an attacker could detect a `registerSystem`/`registerTable` transaction in the mempool, + insert a `registerNamespace` transaction before it, grant themselves access to the namespace, transfer ownership of the namespace to the victim, + so that the `registerSystem`/`registerTable` transactions still went through successfully. + To mitigate this issue, the side effect of registering a namespace in `registerSystem` and `registerTable` has been removed. + Calls to these functions now expect the respective namespace to exist and the caller to own the namespace, otherwise they revert. + + Changes in consuming projects are only necessary if tables or systems are registered manually. + If only the MUD deployer is used to register tables and systems, no changes are necessary, as the MUD deployer has been updated accordingly. + + ```diff + + world.registerNamespace(namespaceId); + world.registerSystem(systemId, system, true); + ``` + + ```diff + + world.registerNamespace(namespaceId); + MyTable.register(); + ``` + +- afaf2f5ff: - `Store`'s internal schema table is now a normal table instead of using special code paths. It is renamed to Tables, and the table ID changed from `mudstore:schema` to `mudstore:Tables` + + - `Store`'s `registerSchema` and `setMetadata` are combined into a single `registerTable` method. This means metadata (key names, field names) is immutable and indexers can create tables with this metadata when a new table is registered on-chain. + + ```diff + - function registerSchema(bytes32 table, Schema schema, Schema keySchema) external; + - + - function setMetadata(bytes32 table, string calldata tableName, string[] calldata fieldNames) external; + + + function registerTable( + + bytes32 table, + + Schema keySchema, + + Schema valueSchema, + + string[] calldata keyNames, + + string[] calldata fieldNames + + ) external; + ``` + + - `World`'s `registerTable` method is updated to match the `Store` interface, `setMetadata` is removed + - The `getSchema` method is renamed to `getValueSchema` on all interfaces + ```diff + - function getSchema(bytes32 table) external view returns (Schema schema); + + function getValueSchema(bytes32 table) external view returns (Schema valueSchema); + ``` + - The `store-sync` and `cli` packages are updated to integrate the breaking protocol changes. Downstream projects only need to manually integrate these changes if they access low level `Store` or `World` functions. Otherwise, a fresh deploy with the latest MUD will get you these changes. + +- 88b1a5a19: We now expose a `WorldContextConsumerLib` library with the same functionality as the `WorldContextConsumer` contract, but the ability to be used inside of internal libraries. + We also renamed the `WorldContextProvider` library to `WorldContextProviderLib` for consistency. +- 2ca75f9b9: The World now maintains a balance per namespace. + When a system is called with value, the value stored in the World contract and credited to the system's namespace. + + Previously, the World contract did not store value, but passed it on to the system contracts. + However, as systems are expected to be stateless (reading/writing state only via the calling World) and can be registered in multiple Worlds, this could have led to exploits. + + Any address with access to a namespace can use the balance of that namespace. + This allows all systems registered in the same namespace to work with the same balance. + + There are two new World methods to transfer balance between namespaces (`transferBalanceToNamespace`) or to an address (`transferBalanceToAddress`). + + ```solidity + interface IBaseWorld { + function transferBalanceToNamespace(bytes16 fromNamespace, bytes16 toNamespace, uint256 amount) external; + + function transferBalanceToAddress(bytes16 fromNamespace, address toAddress, uint256 amount) external; + } + ``` + +- 9d0f492a9: - The previous `Call.withSender` util is replaced with `WorldContextProvider`, since the usecase of appending the `msg.sender` to the calldata is tightly coupled with `WorldContextConsumer` (which extracts the appended context from the calldata). + + The previous `Call.withSender` utility reverted if the call failed and only returned the returndata on success. This is replaced with `callWithContextOrRevert`/`delegatecallWithContextOrRevert` + + ```diff + -import { Call } from "@latticexyz/world/src/Call.sol"; + +import { WorldContextProvider } from "@latticexyz/world/src/WorldContext.sol"; + + -Call.withSender({ + - delegate: false, + - value: 0, + - ... + -}); + +WorldContextProvider.callWithContextOrRevert({ + + value: 0, + + ... + +}); + + -Call.withSender({ + - delegate: true, + - value: 0, + - ... + -}); + +WorldContextProvider.delegatecallWithContextOrRevert({ + + ... + +}); + ``` + + In addition there are utils that return a `bool success` flag instead of reverting on errors. This mirrors the behavior of Solidity's low level `call`/`delegatecall` functions and is useful in situations where additional logic should be executed in case of a reverting external call. + + ```solidity + library WorldContextProvider { + function callWithContext( + address target, // Address to call + bytes memory funcSelectorAndArgs, // Abi encoded function selector and arguments to pass to pass to the contract + address msgSender, // Address to append to the calldata as context for msgSender + uint256 value // Value to pass with the call + ) internal returns (bool success, bytes memory data); + + function delegatecallWithContext( + address target, // Address to call + bytes memory funcSelectorAndArgs, // Abi encoded function selector and arguments to pass to pass to the contract + address msgSender // Address to append to the calldata as context for msgSender + ) internal returns (bool success, bytes memory data); + } + ``` + + - `WorldContext` is renamed to `WorldContextConsumer` to clarify the relationship between `WorldContextProvider` (appending context to the calldata) and `WorldContextConsumer` (extracting context from the calldata) + + ```diff + -import { WorldContext } from "@latticexyz/world/src/WorldContext.sol"; + -import { WorldContextConsumer } from "@latticexyz/world/src/WorldContext.sol"; + ``` + + - The `World` contract previously had a `_call` method to handle calling systems via their resource selector, performing accesss control checks and call hooks registered for the system. + + ```solidity + library SystemCall { + /** + * Calls a system via its resource selector and perform access control checks. + * Does not revert if the call fails, but returns a `success` flag along with the returndata. + */ + function call( + address caller, + bytes32 resourceSelector, + bytes memory funcSelectorAndArgs, + uint256 value + ) internal returns (bool success, bytes memory data); + + /** + * Calls a system via its resource selector, perform access control checks and trigger hooks registered for the system. + * Does not revert if the call fails, but returns a `success` flag along with the returndata. + */ + function callWithHooks( + address caller, + bytes32 resourceSelector, + bytes memory funcSelectorAndArgs, + uint256 value + ) internal returns (bool success, bytes memory data); + + /** + * Calls a system via its resource selector, perform access control checks and trigger hooks registered for the system. + * Reverts if the call fails. + */ + function callWithHooksOrRevert( + address caller, + bytes32 resourceSelector, + bytes memory funcSelectorAndArgs, + uint256 value + ) internal returns (bytes memory data); + } + ``` + + - System hooks now are called with the system's resource selector instead of its address. The system's address can still easily obtained within the hook via `Systems.get(resourceSelector)` if necessary. + + ```diff + interface ISystemHook { + function onBeforeCallSystem( + address msgSender, + - address systemAddress, + + bytes32 resourceSelector, + bytes memory funcSelectorAndArgs + ) external; + + function onAfterCallSystem( + address msgSender, + - address systemAddress, + + bytes32 resourceSelector, + bytes memory funcSelectorAndArgs + ) external; + } + ``` + +- 31ffc9d5d: The `registerFunctionSelector` function now accepts a single `functionSignature` string paramemer instead of separating function name and function arguments into separate parameters. + + ```diff + IBaseWorld { + function registerFunctionSelector( + ResourceId systemId, + - string memory systemFunctionName, + - string memory systemFunctionArguments + + string memory systemFunctionSignature + ) external returns (bytes4 worldFunctionSelector); + } + ``` + + This is a breaking change if you were manually registering function selectors, e.g. in a `PostDeploy.s.sol` script or a module. + To upgrade, simply replace the separate `systemFunctionName` and `systemFunctionArguments` parameters with a single `systemFunctionSignature` parameter. + + ```diff + world.registerFunctionSelector( + systemId, + - systemFunctionName, + - systemFunctionArguments, + + string(abi.encodePacked(systemFunctionName, systemFunctionArguments)) + ); + ``` + +- 5e723b90e: All `World` methods acting on namespaces as resources have been updated to use `ResourceId namespaceId` as parameter instead of `bytes14 namespace`. + The reason for this change is to make it clearer when a namespace is used as resource, as opposed to being part of another resource's ID. + + ```diff + + import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; + + IBaseWorld { + - function registerNamespace(bytes14 namespace) external; + + function registerNamespace(ResourceId namespaceId) external; + + - function transferOwnership(bytes14 namespace, address newOwner) external; + + function transferOwnership(ResourceId namespaceId, address newOwner) external; + + - function transferBalanceToNamespace(bytes14 fromNamespace, bytes14 toNamespace, uint256 amount) external; + + function transferBalanceToNamespace(ResourceId fromNamespaceId, ResourceId toNamespaceId, uint256 amount) external; + + - function transferBalanceToAddress(bytes14 fromNamespace, address toAddress, uint256 amount) external; + + function transferBalanceToAddress(ResourceId fromNamespaceId, address toAddress, uint256 amount) external; + } + + ``` + +- 92de59982: Bump Solidity version to 0.8.21 +- 5741d53d0: - `IBaseWorld` now has a `batchCallFrom` method, which allows system calls via `callFrom` to be executed in batch. + + ```solidity + import { SystemCallFromData } from "@latticexyz/world/modules/core/types.sol"; + + interface IBaseWorld { + function batchCallFrom(SystemCallFromData[] calldata systemCalls) external returns (bytes[] memory returnDatas); + } + ``` + + - The `callBatch` method of `IBaseWorld` has been renamed to `batchCall` to align better with the `batchCallFrom` method. + + ```diff + interface IBaseWorld { + - function callBatch(SystemCallData[] calldata systemCalls) external returns (bytes[] memory returnDatas); + + function batchCall(SystemCallData[] calldata systemCalls) external returns (bytes[] memory returnDatas); + } + ``` + +- 57d8965df: - Split `CoreSystem` into `AccessManagementSystem`, `BalanceTransferSystem`, `BatchCallSystem`, `CoreRegistrationSystem` + + - Changed `CoreModule` to receive the addresses of these systems as arguments, instead of deploying them + - Replaced `CORE_SYSTEM_ID` constant with `ACCESS_MANAGEMENT_SYSTEM_ID`, `BALANCE_TRANSFER_SYSTEM_ID`, `BATCH_CALL_SYSTEM_ID`, `CORE_REGISTRATION_SYSTEM_ID`, for each respective system + + These changes separate the initcode of `CoreModule` from the bytecode of core systems, which effectively removes a limit on the total bytecode of all core systems. + +- 1890f1a06: Moved `store` tables to the `"store"` namespace (previously "mudstore") and `world` tables to the `"world"` namespace (previously root namespace). +- c642ff3a0: Namespaces are not allowed to contain double underscores ("\_\_") anymore, as this sequence of characters is used to [separate the namespace and function selector](https://github.com/latticexyz/mud/pull/2168) in namespaced systems. + This is to prevent signature clashes of functions in different namespaces. + + (Example: If namespaces were allowed to contain this separator string, a function "function" in namespace "namespace\_\_my" would result in the namespaced function selector "namespace\_\_my\_\_function", + and would clash with a function "my\_\_function" in namespace "namespace".) + +- 251170e1e: All optional modules have been moved from `@latticexyz/world` to `@latticexyz/world-modules`. + If you're using the MUD CLI, the import is already updated and no changes are necessary. +- 3e7d83d0: Renamed `PackedCounter` to `EncodedLengths` for consistency. +- cea754dde: - The external `setRecord` and `deleteRecord` methods of `IStore` no longer accept a `FieldLayout` as input, but load it from storage instead. + This is to prevent invalid `FieldLayout` values being passed, which could cause the onchain state to diverge from the indexer state. + However, the internal `StoreCore` library still exposes a `setRecord` and `deleteRecord` method that allows a `FieldLayout` to be passed. + This is because `StoreCore` can only be used internally, so the `FieldLayout` value can be trusted and we can save the gas for accessing storage. + + ```diff + interface IStore { + function setRecord( + ResourceId tableId, + bytes32[] calldata keyTuple, + bytes calldata staticData, + PackedCounter encodedLengths, + bytes calldata dynamicData, + - FieldLayout fieldLayout + ) external; + + function deleteRecord( + ResourceId tableId, + bytes32[] memory keyTuple, + - FieldLayout fieldLayout + ) external; + } + ``` + + - The `spliceStaticData` method and `Store_SpliceStaticData` event of `IStore` and `StoreCore` no longer include `deleteCount` in their signature. + This is because when splicing static data, the data after `start` is always overwritten with `data` instead of being shifted, so `deleteCount` is always the length of the data to be written. + + ```diff + + event Store_SpliceStaticData( + ResourceId indexed tableId, + bytes32[] keyTuple, + uint48 start, + - uint40 deleteCount, + bytes data + ); + + interface IStore { + function spliceStaticData( + ResourceId tableId, + bytes32[] calldata keyTuple, + uint48 start, + - uint40 deleteCount, + bytes calldata data + ) external; + } + ``` + + - The `updateInField` method has been removed from `IStore`, as it's almost identical to the more general `spliceDynamicData`. + If you're manually calling `updateInField`, here is how to upgrade to `spliceDynamicData`: + + ```diff + - store.updateInField(tableId, keyTuple, fieldIndex, startByteIndex, dataToSet, fieldLayout); + + uint8 dynamicFieldIndex = fieldIndex - fieldLayout.numStaticFields(); + + store.spliceDynamicData(tableId, keyTuple, dynamicFieldIndex, uint40(startByteIndex), uint40(dataToSet.length), dataToSet); + ``` + + - All other methods that are only valid for dynamic fields (`pushToField`, `popFromField`, `getFieldSlice`) + have been renamed to make this more explicit (`pushToDynamicField`, `popFromDynamicField`, `getDynamicFieldSlice`). + + Their `fieldIndex` parameter has been replaced by a `dynamicFieldIndex` parameter, which is the index relative to the first dynamic field (i.e. `dynamicFieldIndex` = `fieldIndex` - `numStaticFields`). + The `FieldLayout` parameter has been removed, as it was only used to calculate the `dynamicFieldIndex` in the method. + + ```diff + interface IStore { + - function pushToField( + + function pushToDynamicField( + ResourceId tableId, + bytes32[] calldata keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + bytes calldata dataToPush, + - FieldLayout fieldLayout + ) external; + + - function popFromField( + + function popFromDynamicField( + ResourceId tableId, + bytes32[] calldata keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + uint256 byteLengthToPop, + - FieldLayout fieldLayout + ) external; + + - function getFieldSlice( + + function getDynamicFieldSlice( + ResourceId tableId, + bytes32[] memory keyTuple, + - uint8 fieldIndex, + + uint8 dynamicFieldIndex, + - FieldLayout fieldLayout, + uint256 start, + uint256 end + ) external view returns (bytes memory data); + } + ``` + + - `IStore` has a new `getDynamicFieldLength` length method, which returns the byte length of the given dynamic field and doesn't require the `FieldLayout`. + + ```diff + IStore { + + function getDynamicFieldLength( + + ResourceId tableId, + + bytes32[] memory keyTuple, + + uint8 dynamicFieldIndex + + ) external view returns (uint256); + } + + ``` + + - `IStore` now has additional overloads for `getRecord`, `getField`, `getFieldLength` and `setField` that don't require a `FieldLength` to be passed, but instead load it from storage. + - `IStore` now exposes `setStaticField` and `setDynamicField` to save gas by avoiding the dynamic inference of whether the field is static or dynamic. + - The `getDynamicFieldSlice` method no longer accepts reading outside the bounds of the dynamic field. + This is to avoid returning invalid data, as the data of a dynamic field is not deleted when the record is deleted, but only its length is set to zero. + +- 252a1852: Migrated to new config format. + +### Minor Changes + +- ce97426c0: It is now possible to upgrade systems by calling `registerSystem` again with an existing system id (resource selector). + + ```solidity + // Register a system + world.registerSystem(systemId, systemAddress, publicAccess); + + // Upgrade the system by calling `registerSystem` with the + // same system id but a new system address or publicAccess flag + world.registerSystem(systemId, newSystemAddress, newPublicAccess); + ``` + +- 7fa2ca183: Added TS helpers for calling systems dynamically via the World. + + - `encodeSystemCall` for `world.call` + + ```ts + worldContract.write.call(encodeSystemCall({ + abi: worldContract.abi, + systemId: resourceToHex({ ... }), + functionName: "registerDelegation", + args: [ ... ], + })); + ``` + + - `encodeSystemCallFrom` for `world.callFrom` + + ```ts + worldContract.write.callFrom(encodeSystemCallFrom({ + abi: worldContract.abi, + from: "0x...", + systemId: resourceToHex({ ... }), + functionName: "registerDelegation", + args: [ ... ], + })); + ``` + + - `encodeSystemCalls` for `world.batchCall` + + ```ts + worldContract.write.batchCall(encodeSystemCalls(abi, [{ + systemId: resourceToHex({ ... }), + functionName: "registerDelegation", + args: [ ... ], + }])); + ``` + + - `encodeSystemCallsFrom` for `world.batchCallFrom` + ```ts + worldContract.write.batchCallFrom(encodeSystemCallsFrom(abi, "0x...", [{ + systemId: resourceToHex({ ... }), + functionName: "registerDelegation", + args: [ ... ], + }])); + ``` + +- 6ca1874e0: Added a `Module_AlreadyInstalled` error to `IModule`. +- 1d60930d6: It is now possible to unregister Store hooks and System hooks. + + ```solidity + interface IStore { + function unregisterStoreHook(bytes32 table, IStoreHook hookAddress) external; + // ... + } + + interface IWorld { + function unregisterSystemHook(bytes32 resourceSelector, ISystemHook hookAddress) external; + // ... + } + ``` + +- 5debcca8: `registerRootFunctionSelector` now expects a `systemFunctionSignature` instead of a `systemFunctionSelector`. Internally, we compute the selector from the signature. This allows us to track system function signatures that are registered at the root so we can later generate ABIs for these systems. +- 1f80a0b52: It is now possible for namespace owners to register a fallback delegation control system for the namespace. + This fallback delegation control system is used to verify a delegation in `IBaseWorld.callFrom`, after the user's individual and fallback delegations have been checked. + + ```solidity + IBaseWorld { + function registerNamespaceDelegation( + ResourceId namespaceId, + ResourceId delegationControlId, + bytes memory initCallData + ) external; + } + ``` + +- 1ca35e9a1: The `World` has a new `callFrom` entry point which allows systems to be called on behalf of other addresses if those addresses have registered a delegation. + If there is a delegation, the call is forwarded to the system with `delegator` as `msgSender`. + + ```solidity + interface IBaseWorld { + function callFrom( + address delegator, + bytes32 resourceSelector, + bytes memory funcSelectorAndArgs + ) external payable virtual returns (bytes memory); + } + ``` + + A delegation can be registered via the `World`'s `registerDelegation` function. + If `delegatee` is `address(0)`, the delegation is considered to be a "fallback" delegation and is used in `callFrom` if there is no delegation is found for the specific caller. + Otherwise the delegation is registered for the specific `delegatee`. + + ```solidity + interface IBaseWorld { + function registerDelegation( + address delegatee, + bytes32 delegationControl, + bytes memory initFuncSelectorAndArgs + ) external; + } + ``` + + The `delegationControl` refers to the resource selector of a `DelegationControl` system that must have been registered beforehand. + As part of registering the delegation, the `DelegationControl` system is called with the provided `initFuncSelectorAndArgs`. + This can be used to initialize data in the given `DelegationControl` system. + + The `DelegationControl` system must implement the `IDelegationControl` interface: + + ```solidity + interface IDelegationControl { + function verify(address delegator, bytes32 systemId, bytes calldata funcSelectorAndArgs) external returns (bool); + } + ``` + + When `callFrom` is called, the `World` checks if a delegation is registered for the given caller, and if so calls the delegation control's `verify` function with the same same arguments as `callFrom`. + If the call to `verify` is successful and returns `true`, the delegation is valid and the call is forwarded to the system with `delegator` as `msgSender`. + + Note: if `UNLIMITED_DELEGATION` (from `@latticexyz/world/src/constants.sol`) is passed as `delegationControl`, the external call to the delegation control contract is skipped and the delegation is considered valid. + + For examples of `DelegationControl` systems, check out the `CallboundDelegationControl` or `TimeboundDelegationControl` systems in the `std-delegations` module. + See `StandardDelegations.t.sol` for usage examples. + +- 672d05ca1: - Moves Store events into its own `IStoreEvents` interface + + - Moves Store interfaces to their own files + - Adds a `StoreData` abstract contract to initialize a Store and expose the Store version + + If you're using MUD out of the box, you won't have to make any changes. You will only need to update if you're using any of the base Store interfaces. + +- c583f3cd0: It is now possible to transfer ownership of namespaces! + + ```solidity + // Register a new namespace + world.registerNamespace("namespace"); + // It's owned by the caller of the function (address(this)) + + // Transfer ownership of the namespace to address(42) + world.transferOwnership("namespace", address(42)); + // It's now owned by address(42) + ``` + +- a7b30c79b: Rename `MudV2Test` to `MudTest` and move from `@latticexyz/std-contracts` to `@latticexyz/store`. + + ```solidity + // old import + import { MudV2Test } from "@latticexyz/std-contracts/src/test/MudV2Test.t.sol"; + // new import + import { MudTest } from "@latticexyz/store/src/MudTest.sol"; + ``` + + Refactor `StoreSwitch` to use a storage slot instead of `function isStore()` to determine which contract is Store: + + - Previously `StoreSwitch` called `isStore()` on `msg.sender` to determine if `msg.sender` is a `Store` contract. If the call succeeded, the `Store` methods were called on `msg.sender`, otherwise the data was written to the own storage. + - With this change `StoreSwitch` instead checks for an `address` in a known storage slot. If the address equals the own address, data is written to the own storage. If it is an external address, `Store` methods are called on this address. If it is unset (`address(0)`), store methods are called on `msg.sender`. + - In practice this has the same effect as before: By default the `World` contracts sets its own address in `StoreSwitch`, while `System` contracts keep the Store address undefined, so `Systems` write to their caller (`World`) if they are executed via `call` or directly to the `World` storage if they are executed via `delegatecall`. + - Besides gas savings, this change has two additional benefits: + 1. it is now possible for `Systems` to explicitly set a `Store` address to make them exclusive to that `Store` and + 2. table libraries can now be used in tests without having to provide an explicit `Store` argument, because the `MudTest` base contract redirects reads and writes to the internal `World` contract. + +- 6470fe1fd: `WorldFactory` now derives a salt based on number of worlds deployed by `msg.sender`, which should help with predictable world deployments across chains. +- 7987c94d6: Return address of the newly created World from `WorldFactory.deployWorld`. +- 9b43029c3: Add protocol version with corresponding getter and event on deploy + + ```solidity + world.worldVersion(); + world.storeVersion(); // a World is also a Store + ``` + + ```solidity + event HelloWorld(bytes32 indexed worldVersion); + event HelloStore(bytes32 indexed storeVersion); + ``` + +- 25086be5f: Replaced temporary `.mudtest` file in favor of `WORLD_ADDRESS` environment variable when running tests with `MudTest` contract +- 3042f86e: Moved key schema and value schema methods to constants in code-generated table libraries for less bytecode and less gas in register/install methods. + + ```diff + -console.log(SomeTable.getKeySchema()); + +console.log(SomeTable._keySchema); + + -console.log(SomeTable.getValueSchema()); + +console.log(SomeTable._valueSchema); + ``` + +- c049c23f4: - The `World` contract now has an `initialize` function, which can be called once by the creator of the World to install the core module. + This change allows the registration of all core tables to happen in the `CoreModule`, so no table metadata has to be included in the `World`'s bytecode. + + ```solidity + interface IBaseWorld { + function initialize(IModule coreModule) public; + } + ``` + + - The `World` contract now stores the original creator of the `World` in an immutable state variable. + It is used internally to only allow the original creator to initialize the `World` in a separate transaction. + + ```solidity + interface IBaseWorld { + function creator() external view returns (address); + } + ``` + + - The deploy script is updated to use the `World`'s `initialize` function to install the `CoreModule` instead of `registerRootModule` as before. + +- d7b1c588a: Upgraded all packages and templates to viem v2.7.12 and abitype v1.0.0. + + Some viem APIs have changed and we've updated `getContract` to reflect those changes and keep it aligned with viem. It's one small code change: + + ```diff + const worldContract = getContract({ + address: worldAddress, + abi: IWorldAbi, + - publicClient, + - walletClient, + + client: { public: publicClient, wallet: walletClient }, + }); + ``` + +- 8025c3505: We now use `@latticexyz/abi-ts` to generate TS type declaration files (`.d.ts`) for each ABI JSON file. This replaces our usage TypeChain everywhere. + + If you previously relied on TypeChain types from `@latticexyz/store` or `@latticexyz/world`, you will either need to migrate to viem or abitype using ABI JSON imports or generate TypeChain types from our exported ABI JSON files. + + ```ts + import { getContract } from "viem"; + import IStoreAbi from "@latticexyz/store/abi/IStore.sol/IStore.abi.json"; + + const storeContract = getContract({ + abi: IStoreAbi, + ... + }); + + await storeContract.write.setRecord(...); + ``` + +- 95c59b203: The `World` now has a `callBatch` method which allows multiple system calls to be batched into a single transaction. + + ```solidity + import { SystemCallData } from "@latticexyz/world/modules/core/types.sol"; + + interface IBaseWorld { + function callBatch(SystemCallData[] calldata systemCalls) external returns (bytes[] memory returnDatas); + } + ``` + +### Patch Changes + +- 7ce82b6fc: Store config now defaults `storeArgument: false` for all tables. This means that table libraries, by default, will no longer include the extra functions with the `_store` argument. This default was changed to clear up the confusion around using table libraries in tests, `PostDeploy` scripts, etc. + + If you are sure you need to manually specify a store when interacting with tables, you can still manually toggle it back on with `storeArgument: true` in the table settings of your MUD config. + + If you want to use table libraries in `PostDeploy.s.sol`, you can add the following lines: + + ```diff + import { Script } from "forge-std/Script.sol"; + import { console } from "forge-std/console.sol"; + import { IWorld } from "../src/codegen/world/IWorld.sol"; + + import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; + + contract PostDeploy is Script { + function run(address worldAddress) external { + + StoreSwitch.setStoreAddress(worldAddress); + + + + SomeTable.get(someKey); + ``` + +- d8c8f66bf: Exclude ERC165 interface ID from custom interface ID's. +- a35c05ea9: Table libraries now hardcode the `bytes32` table ID value rather than computing it in Solidity. This saves a bit of gas across all storage operations. +- 8f49c277d: Attempting to deploy multiple systems where there are overlapping system IDs now throws an error. +- 745485cda: Updated `WorldRegistrationSystem` to check that systems exist before registering system hooks. +- aea67c580: Include bytecode for `World` and `Store` in npm packages. +- 90e4161bb: Moved the test tables out of the main config in `world` and `store` and into their own separate config. +- 430e6b29a: Register the `store` namespace in the `CoreModule`. + Since namespaces are a World concept, registering the Store's internal tables does not automatically register the Store's namespace, so we do this manually during initialization in the `CoreModule`. +- e6c03a87a: Renamed the `requireNoCallback` modifier to `prohibitDirectCallback`. +- 1077c7f53: Fixed an issue where `mud.config.ts` source file was not included in the package, causing TS errors downstream. +- 44236041f: Moved table ID and field layout constants in code-generated table libraries from the file level into the library, for clearer access and cleaner imports. + + ```diff + -import { SomeTable, SomeTableTableId } from "./codegen/tables/SomeTable.sol"; + +import { SomeTable } from "./codegen/tables/SomeTable.sol"; + + -console.log(SomeTableTableId); + +console.log(SomeTable._tableId); + + -console.log(SomeTable.getFieldLayout()); + +console.log(SomeTable._fieldLayout); + ``` + +- c207d35e8: Optimised `StoreRegistrationSystem` and `WorldRegistrationSystem` by fetching individual fields instead of entire records where possible. +- 3be4deecf: Added salt to the `WorldDeployed` event. +- f8dab7334: Added explicit `internal` visibility to the `coreSystem` variable in `CoreModule`. +- 1a0fa7974: Fixed `requireInterface` to correctly specify ERC165. +- d00c4a9af: Removed `ROOT_NAMESPACE_STRING` and `ROOT_NAME_STRING` exports in favor of inlining these constants, to avoid reuse as they're meant for internal error messages and debugging. +- eb384bb0e: Added `isInstalled` and `requireNotInstalled` helpers to `Module` base contract. +- 37c228c63: Refactored various files to specify integers in a hex base instead of decimals. +- 211be2a1e: The `FieldLayout` in table libraries is now generated at compile time instead of dynamically in a table library function. + This significantly reduces gas cost in all table library functions. +- d08789282: Prefixed all errors with their respective library/contract for improved debugging. +- e5a962bc3: `World` now correctly registers the `FunctionSignatures` table. +- f6f402896: Added the WorldContextConsumer interface ID to `supportsInterface` in the Module contract. +- 08b422171: Systems are expected to be always called via the central World contract. + Depending on whether it is a root or non-root system, the call is performed via `delegatecall` or `call`. + Since Systems are expected to be stateless and only interact with the World state, it is not necessary to prevent direct calls to the systems. + However, since the `CoreSystem` is known to always be registered as a root system in the World, it is always expected to be delegatecalled, + so we made this expectation explicit by reverting if it is not delegatecalled. +- 37c228c63: Made the `coreModule` variable in `WorldFactory` immutable. +- 37c228c63: Removed the unnecessary `extcodesize` check from the `Create2` library. +- 433078c54: Reverse PackedCounter encoding, to optimize gas for bitshifts. + Ints are right-aligned, shifting using an index is straightforward if they are indexed right-to-left. + + - Previous encoding: (7 bytes | accumulator),(5 bytes | counter 1),...,(5 bytes | counter 5) + - New encoding: (5 bytes | counter 5),...,(5 bytes | counter 1),(7 bytes | accumulator) + +- b2d2aa715: Added an explicit package export for `mud.config` +- 4c7fd3eb2: Remove a workaround for the internal `InstalledModules` table that is not needed anymore. +- a0341daf9: Renamed all `funcSelectorAndArgs` arguments to `callData` for clarity. +- 5e723b90e: The `ResourceType` table is removed. + It was previously used to store the resource type for each resource ID in a `World`. This is no longer necessary as the [resource type is now encoded in the resource ID](https://github.com/latticexyz/mud/pull/1544). + + To still be able to determine whether a given resource ID exists, a `ResourceIds` table has been added. + The previous `ResourceType` table was part of `World` and missed tables that were registered directly via `StoreCore.registerTable` instead of via `World.registerTable` (e.g. when a table was registered as part of a root module). + This problem is solved by the new table `ResourceIds` being part of `Store`. + + `StoreCore`'s `hasTable` function was removed in favor of using `ResourceIds.getExists(tableId)` directly. + + ```diff + - import { ResourceType } from "@latticexyz/world/src/tables/ResourceType.sol"; + - import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; + + import { ResourceIds } from "@latticexyz/store/src/codegen/tables/ResourceIds.sol"; + + - bool tableExists = StoreCore.hasTable(tableId); + + bool tableExists = ResourceIds.getExists(tableId); + + - bool systemExists = ResourceType.get(systemId) != Resource.NONE; + + bool systemExists = ResourceIds.getExists(systemId); + ``` + +- 37c228c63: Refactored `ResourceId` to use a global Solidity `using` statement. +- 37c228c63: Refactored EIP165 usages to use the built-in interfaceId property instead of pre-defined constants. +- 2bfee9217: Added a table to track the `CoreModule` address the world was initialised with. +- 6e66c5b74: Renamed all occurrences of `key` where it is used as "key tuple" to `keyTuple`. + This is only a breaking change for consumers who manually decode `Store` events, but not for consumers who use the MUD libraries. + + ```diff + event StoreSetRecord( + bytes32 tableId, + - bytes32[] key, + + bytes32[] keyTuple, + bytes data + ); + + event StoreSetField( + bytes32 tableId, + - bytes32[] key, + + bytes32[] keyTuple, + uint8 fieldIndex, + bytes data + ); + + event StoreDeleteRecord( + bytes32 tableId, + - bytes32[] key, + + bytes32[] keyTuple, + ); + + event StoreEphemeralRecord( + bytes32 tableId, + - bytes32[] key, + + bytes32[] keyTuple, + bytes data + ); + ``` + +- 8d51a0348: Clean up Memory.sol, make mcopy pure +- 48909d151: bump forge-std and ds-test dependencies +- 590542030: TS packages now generate their respective `.d.ts` type definition files for better compatibility when using MUD with `moduleResolution` set to `bundler` or `node16` and fixes issues around missing type declarations for dependent packages. +- 1a82c278: Added system signatures to the `FunctionSignatures` table, so they can be used to generate system ABIs and decode system calls made via the world. +- 48c51b52a: RECS components are now dynamically created and inferred from your MUD config when using `syncToRecs`. + + To migrate existing projects after upgrading to this MUD version: + + 1. Remove `contractComponents.ts` from `client/src/mud` + 2. Remove `components` argument from `syncToRecs` + 3. Update `build:mud` and `dev` scripts in `contracts/package.json` to remove tsgen + + ```diff + - "build:mud": "mud tablegen && mud worldgen && mud tsgen --configPath mud.config.ts --out ../client/src/mud", + + "build:mud": "mud tablegen && mud worldgen", + ``` + + ```diff + - "dev": "pnpm mud dev-contracts --tsgenOutput ../client/src/mud", + + "dev": "pnpm mud dev-contracts", + ``` + +- f1cd43bf9: Register `Delegations` table in the `CoreModule` +- 86766ce1: Created an `IWorldEvents` interface with `HelloStore`, so all World events are defined in a single interface. +- aee8020a6: Namespace balances can no longer be transferred to non-existent namespaces. +- 22ee44700: All `Store` and `World` tables now use the appropriate user-types for `ResourceId`, `FieldLayout` and `Schema` to avoid manual `wrap`/`unwrap`. +- e2d089c6d: Renamed the Module `args` parameter to `encodedArgs` to better reflect that it is ABI-encoded arguments. +- be313068b: Optimized the `StoreCore` hash function determining the data location to use less gas. +- 93390d89: Added an `abstract` `StoreKernel` contract, which includes all Store interfaces except for registration, and implements write methods, `protocolVersion` and initializes `StoreCore`. `Store` extends `StoreKernel` with the `IStoreRegistration` interface. `StoreData` is removed as a separate interface/contract. `World` now extends `StoreKernel` (since the registration methods are added via the `InitModule`). +- 18d3aea55: Allow `callFrom` with the own address as `delegator` without requiring an explicit delegation +- e48171741: Removed unused imports from various files in the `store` and `world` packages. +- e4a6189df: Prevented invalid delegations by performing full validation regardless of whether `initCallData` is empty. Added an `unregisterDelegation` function which allows explicit unregistration, as opposed of passing in zero bytes into `registerDelegation`. +- 37c228c63: Refactored various Solidity files to not explicitly initialise variables to zero. +- 55ab88a60: `StoreCore` and `IStore` now expose specific functions for `getStaticField` and `getDynamicField` in addition to the general `getField`. + Using the specific functions reduces gas overhead because more optimized logic can be executed. + + ```solidity + interface IStore { + /** + * Get a single static field from the given tableId and key tuple, with the given value field layout. + * Note: the field value is left-aligned in the returned bytes32, the rest of the word is not zeroed out. + * Consumers are expected to truncate the returned value as needed. + */ + function getStaticField( + bytes32 tableId, + bytes32[] calldata keyTuple, + uint8 fieldIndex, + FieldLayout fieldLayout + ) external view returns (bytes32); + + /** + * Get a single dynamic field from the given tableId and key tuple at the given dynamic field index. + * (Dynamic field index = field index - number of static fields) + */ + function getDynamicField( + bytes32 tableId, + bytes32[] memory keyTuple, + uint8 dynamicFieldIndex + ) external view returns (bytes memory); + } + ``` + +- 4e4a34150: bump to latest TS version (5.1.6) +- be18b75b: `IWorldKernel` now inherits `IModuleErrors` so it can render the correct errors if the World reverts when delegatecalled with Module code. +- 0d12db8c2: Optimize Schema methods. + Return `uint256` instead of `uint8` in SchemaInstance numFields methods +- 708b49c50: Generated table libraries now have a set of functions prefixed with `_` that always use their own storage for read/write. + This saves gas for use cases where the functionality to dynamically determine which `Store` to use for read/write is not needed, e.g. root systems in a `World`, or when using `Store` without `World`. + + We decided to continue to always generate a set of functions that dynamically decide which `Store` to use, so that the generated table libraries can still be imported by non-root systems. + + ```solidity + library Counter { + // Dynamically determine which store to write to based on the context + function set(uint32 value) internal; + + // Always write to own storage + function _set(uint32 value) internal; + + // ... equivalent functions for all other Store methods + } + ``` + +- 17f987209: Added a check to prevent namespaces from ending with an underscore (which could cause problems with world function signatures). +- 37c228c63: Refactored `WorldContext` to get the world address from `WorldContextConsumerLib` instead of `StoreSwitch`. +- 22ba7b675: Simplified a couple internal constants used for bitshifting. +- 5c52bee09: Renamed `StoreCore`'s `registerCoreTables` method to `registerInternalTables`. +- 95f64c85: Renamed the `functionSelector` key in the `FunctionSelectors` table to `worldFunctionSelector`. This clarifies that `FunctionSelectors` is for world function selectors and can be used to generate the world ABI. +- 29c3f5087: With [resource types in resource IDs](https://github.com/latticexyz/mud/pull/1544), the World config no longer requires table and system names to be unique. +- cc2c8da00: - Refactor tightcoder to use typescript functions instead of ejs + - Optimize `TightCoder` library + - Add `isLeftAligned` and `getLeftPaddingBits` common codegen helpers +- Updated dependencies [7ce82b6fc] +- Updated dependencies [d8c8f66bf] +- Updated dependencies [c6c13f2ea] +- Updated dependencies [1b86eac05] +- Updated dependencies [a35c05ea9] +- Updated dependencies [c9ee5e4a] +- Updated dependencies [c963b46c7] +- Updated dependencies [05b3e8882] +- Updated dependencies [16b13ea8f] +- Updated dependencies [aea67c580] +- Updated dependencies [82693072] +- Updated dependencies [07dd6f32c] +- Updated dependencies [90e4161bb] +- Updated dependencies [aabd30767] +- Updated dependencies [65c9546c4] +- Updated dependencies [331dbfdcb] +- Updated dependencies [d5c0682fb] +- Updated dependencies [1d60930d6] +- Updated dependencies [01e46d99] +- Updated dependencies [f9f9609ef] +- Updated dependencies [904fd7d4e] +- Updated dependencies [e6c03a87a] +- Updated dependencies [1077c7f53] +- Updated dependencies [2c920de7] +- Updated dependencies [b9e562d8f] +- Updated dependencies [331dbfdcb] +- Updated dependencies [44236041f] +- Updated dependencies [066056154] +- Updated dependencies [759514d8b] +- Updated dependencies [952cd5344] +- Updated dependencies [d5094a242] +- Updated dependencies [3fb9ce283] +- Updated dependencies [bb6ada740] +- Updated dependencies [35c9f33df] +- Updated dependencies [a25881160] +- Updated dependencies [0b8ce3f2c] +- Updated dependencies [933b54b5f] +- Updated dependencies [c4d5eb4e4] +- Updated dependencies [f62c767e7] +- Updated dependencies [9aa5e786] +- Updated dependencies [307abab3] +- Updated dependencies [de151fec0] +- Updated dependencies [37c228c63] +- Updated dependencies [aacffcb59] +- Updated dependencies [c991c71a] +- Updated dependencies [ae340b2bf] +- Updated dependencies [1bf2e9087] +- Updated dependencies [b38c096d] +- Updated dependencies [211be2a1e] +- Updated dependencies [0f3e2e02b] +- Updated dependencies [d08789282] +- Updated dependencies [5c965a919] +- Updated dependencies [f99e88987] +- Updated dependencies [939916bcd] +- Updated dependencies [d5b73b126] +- Updated dependencies [e34d1170] +- Updated dependencies [b8a6158d6] +- Updated dependencies [190fdd11] +- Updated dependencies [433078c54] +- Updated dependencies [db314a74] +- Updated dependencies [b2d2aa715] +- Updated dependencies [83583a505] +- Updated dependencies [5e723b90e] +- Updated dependencies [6573e38e9] +- Updated dependencies [afaf2f5ff] +- Updated dependencies [37c228c63] +- Updated dependencies [59267655] +- Updated dependencies [37c228c63] +- Updated dependencies [44a5432ac] +- Updated dependencies [6e66c5b74] +- Updated dependencies [8d51a0348] +- Updated dependencies [c162ad5a5] +- Updated dependencies [65c9546c4] +- Updated dependencies [48909d151] +- Updated dependencies [7b28d32e5] +- Updated dependencies [b02f9d0e4] +- Updated dependencies [f62c767e7] +- Updated dependencies [bb91edaa0] +- Updated dependencies [590542030] +- Updated dependencies [1b5eb0d07] +- Updated dependencies [44a5432ac] +- Updated dependencies [48c51b52a] +- Updated dependencies [9f8b84e73] +- Updated dependencies [66cc35a8c] +- Updated dependencies [672d05ca1] +- Updated dependencies [55a05fd7a] +- Updated dependencies [f03531d97] +- Updated dependencies [63831a264] +- Updated dependencies [b8a6158d6] +- Updated dependencies [6db95ce15] +- Updated dependencies [8193136a9] +- Updated dependencies [5d737cf2e] +- Updated dependencies [d075f82f3] +- Updated dependencies [331dbfdcb] +- Updated dependencies [a7b30c79b] +- Updated dependencies [92de59982] +- Updated dependencies [22ee44700] +- Updated dependencies [ad4ac4459] +- Updated dependencies [be313068b] +- Updated dependencies [ac508bf18] +- Updated dependencies [93390d89] +- Updated dependencies [bb91edaa0] +- Updated dependencies [144c0d8d] +- Updated dependencies [5ac4c97f4] +- Updated dependencies [bfcb293d1] +- Updated dependencies [3e057061d] +- Updated dependencies [1890f1a06] +- Updated dependencies [e48171741] +- Updated dependencies [9b43029c3] +- Updated dependencies [37c228c63] +- Updated dependencies [55ab88a60] +- Updated dependencies [c58da9ad] +- Updated dependencies [37c228c63] +- Updated dependencies [535229984] +- Updated dependencies [af639a264] +- Updated dependencies [5e723b90e] +- Updated dependencies [99ab9cd6f] +- Updated dependencies [0c4f9fea9] +- Updated dependencies [0d12db8c2] +- Updated dependencies [c049c23f4] +- Updated dependencies [80dd6992e] +- Updated dependencies [60cfd089f] +- Updated dependencies [24a6cd536] +- Updated dependencies [37c228c63] +- Updated dependencies [708b49c50] +- Updated dependencies [d2f8e9400] +- Updated dependencies [25086be5f] +- Updated dependencies [b1d41727d] +- Updated dependencies [3ac68ade6] +- Updated dependencies [22ba7b675] +- Updated dependencies [4c1dcd81e] +- Updated dependencies [3042f86e] +- Updated dependencies [5e71e1cb5] +- Updated dependencies [6071163f7] +- Updated dependencies [6c6733256] +- Updated dependencies [cd5abcc3b] +- Updated dependencies [d7b1c588a] +- Updated dependencies [5c52bee09] +- Updated dependencies [8025c3505] +- Updated dependencies [c4f49240d] +- Updated dependencies [745485cda] +- Updated dependencies [37c228c63] +- Updated dependencies [3e7d83d0] +- Updated dependencies [5df1f31bc] +- Updated dependencies [cea754dde] +- Updated dependencies [331f0d636] +- Updated dependencies [cc2c8da00] +- Updated dependencies [252a1852] +- Updated dependencies [103f635eb] + - @latticexyz/store@2.0.0 + - @latticexyz/common@2.0.0 + - @latticexyz/schema-type@2.0.0 + - @latticexyz/config@2.0.0 + ## 2.0.0-next.18 ### Major Changes diff --git a/packages/world/package.json b/packages/world/package.json index 32dfac74be..7c977c1064 100644 --- a/packages/world/package.json +++ b/packages/world/package.json @@ -1,6 +1,6 @@ { "name": "@latticexyz/world", - "version": "2.0.0-next.18", + "version": "2.0.0", "description": "World framework", "repository": { "type": "git", diff --git a/test/mock-game-contracts/CHANGELOG.md b/test/mock-game-contracts/CHANGELOG.md index a108c42918..17255bc95b 100644 --- a/test/mock-game-contracts/CHANGELOG.md +++ b/test/mock-game-contracts/CHANGELOG.md @@ -1,3 +1,5 @@ # mock-game-contracts +## 2.0.0 + ## 2.0.0-next.18 diff --git a/test/mock-game-contracts/package.json b/test/mock-game-contracts/package.json index 71848697a2..cf676e86d0 100644 --- a/test/mock-game-contracts/package.json +++ b/test/mock-game-contracts/package.json @@ -1,6 +1,6 @@ { "name": "mock-game-contracts", - "version": "2.0.0-next.18", + "version": "2.0.0", "private": true, "license": "MIT", "scripts": {