From df85e0c078c1ae0a12b925b3e7395b6cb893c9f1 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Wed, 19 Jul 2023 09:42:01 +0100 Subject: [PATCH] docs: prettier mdx (#1181) --- docs/pages/tutorials/minimal/add_system.mdx | 295 +++++++++--------- docs/pages/tutorials/walkthrough.mdx | 2 +- .../tutorials/walkthrough/minimal-onchain.mdx | 236 +++++++------- docs/pages/world/config.mdx | 2 +- package.json | 2 +- 5 files changed, 261 insertions(+), 276 deletions(-) diff --git a/docs/pages/tutorials/minimal/add_system.mdx b/docs/pages/tutorials/minimal/add_system.mdx index 98b61de450..526e034eaf 100644 --- a/docs/pages/tutorials/minimal/add_system.mdx +++ b/docs/pages/tutorials/minimal/add_system.mdx @@ -43,7 +43,6 @@ uint32 counter = Counter.get(); Get the counter value. - ```solidity Counter.set(newValue); ``` @@ -52,188 +51,184 @@ Set the counter to a new value. - ## Add `decrement` to the application Having a system be able to do something doesn't help anybody unless it is called from somewhere. In this case, the vanilla getting started front end. -1. Edit `packages/client/src/mud/createSystemCalls.ts` to include `decrement`. +1. Edit `packages/client/src/mud/createSystemCalls.ts` to include `decrement`. This is the file after the changes: - - ```typescript - import { ClientComponents } from "./createClientComponents"; - import { SetupNetworkResult } from "./setupNetwork"; - - export type SystemCalls = ReturnType; - - export function createSystemCalls( - { worldSend, txReduced$, singletonEntity }: SetupNetworkResult, - { Counter }: ClientComponents - ) { - const increment = async () => { + + ```typescript + import { ClientComponents } from "./createClientComponents"; + import { SetupNetworkResult } from "./setupNetwork"; + + export type SystemCalls = ReturnType; + + export function createSystemCalls( + { worldSend, txReduced$, singletonEntity }: SetupNetworkResult, + { Counter }: ClientComponents + ) { + const increment = async () => { const tx = await worldSend("increment", []); await awaitStreamValue(txReduced$, (txHash) => txHash === tx.hash); return getComponentValue(Counter, singletonEntity); - }; + }; + + const decrement = async () => { + const tx = await worldSend("decrement", []); + await awaitStreamValue(txReduced$, (txHash) => txHash === tx.hash); + return getComponentValue(Counter, singletonEntity); + }; + return { + increment, + decrement, + }; + } + ``` + +
+ + Explanation + + {" "} +

+ + The new function is `decrement`. + + ```typescript const decrement = async () => { - const tx = await worldSend("decrement", []) - await awaitStreamValue(txReduced$, (txHash) => txHash === tx.hash) + ``` + + This function involves sending a transaction, which is a slow process, so it needs to be [asynchronous](https://www.w3schools.com/js/js_async.asp). + + ```typescript + const tx = await worldSend("decrement", []); + ``` + + This is the way we call functions in top-level systems in a world. + The second parameter, the list, is for the function parameters. + In this case there aren't any, so it is empty. + + ```typescript + await awaitStreamValue(txReduced$, (txHash) => txHash === tx.hash); + ``` + + Await until we receive confirmation that the transaction has been added to a block. + + ```typescript return getComponentValue(Counter, singletonEntity) }; + ``` + + Get the value of `Counter` to return it. + It should already be the updated value. + ```typescript return { - increment, - decrement, + increment, + decrement, }; - } - ``` - -
- - Explanation - + ``` -

+ Of course, we also need to return `decrement` so it can be used elsewhere. - The new function is `decrement`. +
- ```typescript - const decrement = async () => { - ``` +1. Update `packages/client/src/index.ts` to include `decrement`. + This is the file after the changes: - This function involves sending a transaction, which is a slow process, so it needs to be [asynchronous](https://www.w3schools.com/js/js_async.asp). + ```typescript + import { mount as mountDevTools } from "@latticexyz/dev-tools"; + import { setup } from "./mud/setup"; + + const { + components, + systemCalls: { decrement, increment }, + } = await setup(); + + // Components expose a stream that triggers when the component is updated. + components.Counter.update$.subscribe((update) => { + const [nextValue, prevValue] = update.value; + console.log("Counter updated", update, { nextValue, prevValue }); + document.getElementById("counter")!.innerHTML = String(nextValue?.value ?? "unset"); + }); + + // Just for demonstration purposes: we create a global function that can be + // called to invoke the Increment system contract via the world. (See IncrementSystem.sol.) + (window as any).increment = async () => { + console.log("new counter value:", await increment()); + }; - ```typescript - const tx = await worldSend("decrement", []) - ``` + (window as any).decrement = async () => { + console.log("new counter value:", await decrement()); + }; - This is the way we call functions in top-level systems in a world. - The second parameter, the list, is for the function parameters. - In this case there aren't any, so it is empty. + mountDevTools(); + ``` - ```typescript - await awaitStreamValue(txReduced$, (txHash) => txHash === tx.hash) - ``` +
- Await until we receive confirmation that the transaction has been added to a block. + Explanation - ```typescript - return getComponentValue(Counter, singletonEntity) - }; - ``` + {" "} +

- Get the value of `Counter` to return it. - It should already be the updated value. + ```typescript + const { + components, + systemCalls: { decrement, increment }, + } = await setup(); + ``` - ```typescript - return { - increment, - decrement, - }; - ``` + This syntax means the we call [`setup()`](https://github.com/latticexyz/mud/blob/main/examples/minimal/packages/client-vanilla/src/mud/setup.ts), and then set `components`, `systemCalls.increment`, and `systemCalls.decrement` to the values provided in the hash returned by this function. + `systemCalls` comes from `createSystemCalls()`, which we modified in the previous step. - Of course, we also need to return `decrement` so it can be used elsewhere. + ```typescript + (window as any).decrement = async () => { + console.log("new counter value:", await decrement()); + }; + ``` -
+ We need to make `decrement` available to our application code. + Most frameworks have a standard mechanism to do this, but we are using `vanilla`, which doesn't - so we add it to `window` which is a global variable. -1. Update `packages/client/src/index.ts` to include `decrement`. - This is the file after the changes: +
- ```typescript - import { mount as mountDevTools } from "@latticexyz/dev-tools"; - import { setup } from "./mud/setup"; +1. Modify `packages/client/index.html` to add a decrement button. + This is the file after the changes: - const { - components, - systemCalls: { - decrement, - increment - }, - } = await setup(); - - // Components expose a stream that triggers when the component is updated. - components.Counter.update$.subscribe((update) => { - const [nextValue, prevValue] = update.value; - console.log("Counter updated", update, { nextValue, prevValue }); - document.getElementById("counter")!.innerHTML = String(nextValue?.value ?? "unset"); - }); - - // Just for demonstration purposes: we create a global function that can be - // called to invoke the Increment system contract via the world. (See IncrementSystem.sol.) - (window as any).increment = async () => { - console.log("new counter value:", await increment()); - }; - - (window as any).decrement = async () => { - console.log("new counter value:", await decrement()); - }; - - mountDevTools(); - ``` - -
- Explanation - -

- - ```typescript - const { - components, - systemCalls: { - decrement, - increment - }, - } = await setup(); - ``` - - This syntax means the we call [`setup()`](https://github.com/latticexyz/mud/blob/main/examples/minimal/packages/client-vanilla/src/mud/setup.ts), and then set `components`, `systemCalls.increment`, and `systemCalls.decrement` to the values provided in the hash returned by this function. - `systemCalls` comes from `createSystemCalls()`, which we modified in the previous step. - - ```typescript - (window as any).decrement = async () => { - console.log("new counter value:", await decrement()); - }; - ``` - - We need to make `decrement` available to our application code. - Most frameworks have a standard mechanism to do this, but we are using `vanilla`, which doesn't - so we add it to `window` which is a global variable. - -
- - -1. Modify `packages/client/index.html` to add a decrement button. - This is the file after the changes: - - ```html - - - - - - a minimal MUD client - - - -
Counter: 0
- + ```html + + + + + + a minimal MUD client + + + +
Counter: 0
+ + + + + ``` + +
+ + Explanation + + {" "} +

+ + ```html - - - ``` - -
- Explanation - -

- - ```html - - ``` + ``` - Create a [`button`](https://www.w3schools.com/tags/tag_button.asp) with an [`onClick`](https://www.w3schools.com/tags/ev_onclick.asp) property. + Create a [`button`](https://www.w3schools.com/tags/tag_button.asp) with an [`onClick`](https://www.w3schools.com/tags/ev_onclick.asp) property. -
+
-1. Reload the application to see that there is a decrement button and that you can use it. \ No newline at end of file +1. Reload the application to see that there is a decrement button and that you can use it. diff --git a/docs/pages/tutorials/walkthrough.mdx b/docs/pages/tutorials/walkthrough.mdx index 24075eb4cd..29c520fd76 100644 --- a/docs/pages/tutorials/walkthrough.mdx +++ b/docs/pages/tutorials/walkthrough.mdx @@ -2,4 +2,4 @@ These tutorials are deep dives into various sections of code. -1. [Onchain parts of the getting started](walkthrough/minimal-onchain) \ No newline at end of file +1. [Onchain parts of the getting started](walkthrough/minimal-onchain) diff --git a/docs/pages/tutorials/walkthrough/minimal-onchain.mdx b/docs/pages/tutorials/walkthrough/minimal-onchain.mdx index e17349aa98..aa1a09e5c0 100644 --- a/docs/pages/tutorials/walkthrough/minimal-onchain.mdx +++ b/docs/pages/tutorials/walkthrough/minimal-onchain.mdx @@ -4,17 +4,18 @@ You [installed the getting started code](/quick-start), and now you can incremen Unfortunately, when you tried to figure out what is happening, it is as clear as mud. Have no fear, in this tutorial you learn how to understand the onchain components of the minimal template. -The onchain components are stored in `packages/contracts`. +The onchain components are stored in `packages/contracts`. The onchain components can be divided into two types of functionality: + - **Data**, the part of the system that stores the information. - **Logic**, the part of the system that can be called to read or modify the data. - ## Data ### The data schema #### `mud.config.ts` + The data schema is declared in `packages/contracts/mud.config.ts`. [Read more details about the schema definition here](/world/config#global-configuration-keys). @@ -47,7 +48,6 @@ This definition is roughly equivalent to this Solidity code: ```solidity contract Example { - uint32 Counter; struct User { @@ -67,6 +67,7 @@ pnpm mud tablegen ``` When you update the schema, you get three files (one for each table and one that imports the data from them): + - `packages/contracts/src/codegen/Tables.sol` - `packages/contracts/src/codegen/tables/Counter.sol` - `packages/contracts/src/codegen/tables/Users.sol` @@ -90,7 +91,6 @@ import { Users, UsersData, UsersTableId } from "./tables/Users.sol"; This file just imports the definitions of all the tables defined in the schema. - #### `Counter.sol` ```solidity @@ -114,7 +114,7 @@ import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; ``` -These are various definitions required for a mud table. +These are various definitions required for a mud table. You don't typically need to worry about them. ```solidity @@ -122,7 +122,7 @@ bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Count bytes32 constant CounterTableId = _tableId; ``` -One advantage of mud is that the metadata, the information that describes the data we are managing, is available onchain. +One advantage of mud is that the metadata, the information that describes the data we are managing, is available onchain. For table IDs the first sixteen characters are the namespace of the table, followed by sixteen characters of the name of the table itself. The default namespace is empty. @@ -149,97 +149,96 @@ In this case, there is nothing in the key because the table only has a single ro [The list of field types is available here](https://github.com/latticexyz/mud/blob/main/packages/schema-type/src/solidity/SchemaType.sol#L9). ```solidity - /** Get the table's metadata */ - function getMetadata() internal pure returns (string memory, string[] memory) { - string[] memory _fieldNames = new string[](1); - _fieldNames[0] = "value"; - return ("Counter", _fieldNames); - } +/** Get the table's metadata */ +function getMetadata() internal pure returns (string memory, string[] memory) { + string[] memory _fieldNames = new string[](1); + _fieldNames[0] = "value"; + return ("Counter", _fieldNames); +} ``` This function returns the name of the table and the names of the fields in it. In this case there is only one, and as we didn't specify the name in `mud.config.ts` it is called by the default, `value`. - ```solidity - /** Register the table's schema */ - function registerSchema() internal { - StoreSwitch.registerSchema(_tableId, getSchema(), getKeySchema()); - } +/** Register the table's schema */ +function registerSchema() internal { + StoreSwitch.registerSchema(_tableId, getSchema(), getKeySchema()); +} - /** Register the table's schema (using the specified store) */ - function registerSchema(IStore _store) internal { - _store.registerSchema(_tableId, getSchema(), getKeySchema()); - } +/** Register the table's schema (using the specified store) */ +function registerSchema(IStore _store) internal { + _store.registerSchema(_tableId, getSchema(), getKeySchema()); +} ``` These two functions register the schema, either to the default `Store` (`StoreSwitch`) or to one given as a parameter. ```solidity - /** Set the table's metadata */ - function setMetadata() internal { - (string memory _tableName, string[] memory _fieldNames) = getMetadata(); - StoreSwitch.setMetadata(_tableId, _tableName, _fieldNames); - } +/** Set the table's metadata */ +function setMetadata() internal { + (string memory _tableName, string[] memory _fieldNames) = getMetadata(); + StoreSwitch.setMetadata(_tableId, _tableName, _fieldNames); +} - /** Set the table's metadata (using the specified store) */ - function setMetadata(IStore _store) internal { - (string memory _tableName, string[] memory _fieldNames) = getMetadata(); - _store.setMetadata(_tableId, _tableName, _fieldNames); - } +/** Set the table's metadata (using the specified store) */ +function setMetadata(IStore _store) internal { + (string memory _tableName, string[] memory _fieldNames) = getMetadata(); + _store.setMetadata(_tableId, _tableName, _fieldNames); +} ``` These two functions register the metadata, the table and column names, either to the default `Store` (`StoreSwitch`) or to one given as a parameter. ```solidity - /** Get value */ - function get() internal view returns (uint32 value) { - bytes32[] memory _keyTuple = new bytes32[](0); +/** Get value */ +function get() internal view returns (uint32 value) { + bytes32[] memory _keyTuple = new bytes32[](0); - bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 0); - return (uint32(Bytes.slice4(_blob, 0))); - } + bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 0); + return (uint32(Bytes.slice4(_blob, 0))); +} - /** Get value (using the specified store) */ - function get(IStore _store) internal view returns (uint32 value) { - bytes32[] memory _keyTuple = new bytes32[](0); +/** Get value (using the specified store) */ +function get(IStore _store) internal view returns (uint32 value) { + bytes32[] memory _keyTuple = new bytes32[](0); - bytes memory _blob = _store.getField(_tableId, _keyTuple, 0); - return (uint32(Bytes.slice4(_blob, 0))); - } + bytes memory _blob = _store.getField(_tableId, _keyTuple, 0); + return (uint32(Bytes.slice4(_blob, 0))); +} ``` -These two functions read the value. +These two functions read the value. In this case there is only one value and there are no keys, so they just get the first entry, the one with index zero. ```solidity - /** Set value */ - function set(uint32 value) internal { - bytes32[] memory _keyTuple = new bytes32[](0); +/** Set value */ +function set(uint32 value) internal { + bytes32[] memory _keyTuple = new bytes32[](0); - StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((value))); - } + StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((value))); +} - /** Set value (using the specified store) */ - function set(IStore _store, uint32 value) internal { - bytes32[] memory _keyTuple = new bytes32[](0); +/** Set value (using the specified store) */ +function set(IStore _store, uint32 value) internal { + bytes32[] memory _keyTuple = new bytes32[](0); - _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value))); - } + _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value))); +} ``` These two functions overwrite the value. ```solidity - /** Tightly pack full data using this table's schema */ - function encode(uint32 value) internal view returns (bytes memory) { - return abi.encodePacked(value); - } +/** Tightly pack full data using this table's schema */ +function encode(uint32 value) internal view returns (bytes memory) { + return abi.encodePacked(value); +} - /** Encode keys as a bytes32 array using this table's schema */ - function encodeKeyTuple() internal pure returns (bytes32[] memory _keyTuple) { - _keyTuple = new bytes32[](0); - } +/** Encode keys as a bytes32 array using this table's schema */ +function encodeKeyTuple() internal pure returns (bytes32[] memory _keyTuple) { + _keyTuple = new bytes32[](0); +} ``` Utility functions to encode a value. @@ -262,14 +261,13 @@ Utility functions to encode a value. } ``` -These functions delete the value. +These functions delete the value. Normally it would be the value associated with the a key provided as a paramter, but in this case there is no parameter. #### `Users.sol` This file is very similar to `Counter.sol`, so I will only explain the parts that are different. - ```solidity struct UsersData { uint32 score; @@ -277,21 +275,20 @@ struct UsersData { } ``` -A struct to hold all the schema fields. +A struct to hold all the schema fields. By default this struct is created whenever there are multiple input fields. ```solidity - function getKeySchema() internal pure returns (Schema) { - SchemaType[] memory _schema = new SchemaType[](1); - _schema[0] = SchemaType.ADDRESS; +function getKeySchema() internal pure returns (Schema) { + SchemaType[] memory _schema = new SchemaType[](1); + _schema[0] = SchemaType.ADDRESS; - return SchemaLib.encode(_schema); - } + return SchemaLib.encode(_schema); +} ``` In contrast to `Counter`, this table does have a key, so it has a real key schema. - ```solidity /** Get score */ function getScore(address user) internal view returns (uint32 score) { @@ -361,7 +358,7 @@ When there are multiple fields in the record, `get` and `set` functions are prov } ``` -A string is an array, so `Name` also gets the functions that arrays get - for example, the function to get the array length. +A string is an array, so `Name` also gets the functions that arrays get - for example, the function to get the array length. The division by one is because strings are one byte per character. ```solidity @@ -435,7 +432,6 @@ Add and remove items from the end of the array. Update a slice of the "array". - ```solidity /** Get the full data */ function get(address user) internal view returns (UsersData memory _table) { @@ -483,65 +479,60 @@ le) { Get and set the entire row of user data. - ```solidity - /** Decode the tightly packed blob using this table's schema */ - function decode(bytes memory _blob) internal view returns (UsersData memory _table) { - // 4 is the total byte length of static data - PackedCounter _encodedLengths = PackedCounter.wrap(Bytes.slice32(_blob, 4)); +/** Decode the tightly packed blob using this table's schema */ +function decode(bytes memory _blob) internal view returns (UsersData memory _table) { + // 4 is the total byte length of static data + PackedCounter _encodedLengths = PackedCounter.wrap(Bytes.slice32(_blob, 4)); - _table.score = (uint32(Bytes.slice4(_blob, 0))); + _table.score = (uint32(Bytes.slice4(_blob, 0))); - // Store trims the blob if dynamic fields are all empty - if (_blob.length > 4) { - uint256 _start; - // skip static data length + dynamic lengths word - uint256 _end = 36; + // Store trims the blob if dynamic fields are all empty + if (_blob.length > 4) { + uint256 _start; + // skip static data length + dynamic lengths word + uint256 _end = 36; - _start = _end; - _end += _encodedLengths.atIndex(0); - _table.name = (string(SliceLib.getSubslice(_blob, _start, _end).toBytes())); - } + _start = _end; + _end += _encodedLengths.atIndex(0); + _table.name = (string(SliceLib.getSubslice(_blob, _start, _end).toBytes())); } +} ``` The first four bytes are the `uint32` score, which is always present. The `string` name, however, might be empty, in which case nothing will be returned there. If there is a name, it is encoded in the standard Ethereum manner for strings, a 32 byte length followed by the data. - ```solidity - /** Tightly pack full data using this table's schema */ - function encode(uint32 score, string memory name) internal view returns (bytes memory) - { - uint40[] memory _counters = new uint40[](1); - _counters[0] = uint40(bytes(name).length); - PackedCounter _encodedLengths = PackedCounterLib.pack(_counters); - - return abi.encodePacked(score, _encodedLengths.unwrap(), bytes((name))); - } +/** Tightly pack full data using this table's schema */ +function encode(uint32 score, string memory name) internal view returns (bytes memory) { + uint40[] memory _counters = new uint40[](1); + _counters[0] = uint40(bytes(name).length); + PackedCounter _encodedLengths = PackedCounterLib.pack(_counters); + return abi.encodePacked(score, _encodedLengths.unwrap(), bytes((name))); +} - /** Encode keys as a bytes32 array using this table's schema */ - function encodeKeyTuple(address user) internal pure returns (bytes32[] memory _keyTuple) { - _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(uint256(uint160(user))); - } +/** Encode keys as a bytes32 array using this table's schema */ +function encodeKeyTuple(address user) internal pure returns (bytes32[] memory _keyTuple) { + _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(uint160(user))); +} ``` -These functions encode data so it can be treated as an array of Ethereum values (256 bits = 32 bytes). - +These functions encode data so it can be treated as an array of Ethereum values (256 bits = 32 bytes). ## Logic The way mud works, onchain logic is implemented by one or more `System`s. -Those systems are typically called by a central `World`, +Those systems are typically called by a central `World`, #### `IncrementSystem.sol` -This is the system that is provided by the demo (`packages/contracts/src/systems/IncrementSystem.sol`). +This is the system that is provided by the demo (`packages/contracts/src/systems/IncrementSystem.sol`). As the name suggests, it includes a single function that increments `Counter`. ```solidity @@ -581,38 +572,37 @@ Update the value. } ``` -Return the new value. +Return the new value. #### `System.sol` and `WorldContext.sol`. -To see what else systems can do, let's look at [`@latticexyz/world/src/System.sol`](https://github.com/latticexyz/mud/blob/main/packages/world/src/System.sol). +To see what else systems can do, let's look at [`@latticexyz/world/src/System.sol`](https://github.com/latticexyz/mud/blob/main/packages/world/src/System.sol). At present, it is just an alias to [`@latticexyz/world/src/WorldContext.sol`](https://github.com/latticexyz/mud/blob/main/packages/world/src/WorldContext.sol). That contract has two functions: `_msgSender` and `_world`. ```solidity - // Extract the trusted msg.sender value appended to the calldata - function _msgSender() internal view returns (address sender) { - assembly { - // 96 = 256 - 20 * 8 - sender := shr(96, calldataload(sub(calldatasize(), 20))) - } - if (sender == address(0)) sender = msg.sender; +// Extract the trusted msg.sender value appended to the calldata +function _msgSender() internal view returns (address sender) { + assembly { + // 96 = 256 - 20 * 8 + sender := shr(96, calldataload(sub(calldatasize(), 20))) } + if (sender == address(0)) sender = msg.sender; +} ``` Systems are typically called from a `World` contract, so that would typically be `msg.sender`. -To get the user identity and make access control decisions this `World` contract provides its own `msg.sender` +To get the user identity and make access control decisions this `World` contract provides its own `msg.sender` is the last 20 bytes of the calldata. - ```solidity - function _world() internal view returns (address) { - return StoreSwitch.inferStoreAddress(); - } +function _world() internal view returns (address) { + return StoreSwitch.inferStoreAddress(); +} ``` This function gives us the identity of the `World` which called us. -Under certain circumstances the `System` contract is called through [`CALL`](https://mirror.xyz/frimoldi.eth/5RObAeE1sPNeEzyGU9gU0olBtVJqnj0MYkJCVtVNGV0) (in which case the calling `World` is `msg.sender`), and in other cases [`DELEGATECALL`](https://mirror.xyz/frimoldi.eth/5RObAeE1sPNeEzyGU9gU0olBtVJqnj0MYkJCVtVNGV0) (in which case the calling `World` is `address(this)`). +Under certain circumstances the `System` contract is called through [`CALL`](https://mirror.xyz/frimoldi.eth/5RObAeE1sPNeEzyGU9gU0olBtVJqnj0MYkJCVtVNGV0) (in which case the calling `World` is `msg.sender`), and in other cases [`DELEGATECALL`](https://mirror.xyz/frimoldi.eth/5RObAeE1sPNeEzyGU9gU0olBtVJqnj0MYkJCVtVNGV0) (in which case the calling `World` is `address(this)`). -Note that the identity of the world is *not* specified in the system. +Note that the identity of the world is _not_ specified in the system. This allows the same `System`, the same application logic, to be shared between multiple different worlds. diff --git a/docs/pages/world/config.mdx b/docs/pages/world/config.mdx index f702343de1..c19c526867 100644 --- a/docs/pages/world/config.mdx +++ b/docs/pages/world/config.mdx @@ -68,6 +68,7 @@ All of these global configuration keys are optional. - **`systems`**: a dictionary of system definitions. The keys in the array are file names without the `.sol` extension. For example, if your system is named `SystemA.sol`, use `SystemA` as the. The value is a dictionary of system configuration properties: + - `fileSelector` (optional): a `string`: the file selector for the system. - `openAccess` (optional, default `true`): a `bool`: if set to `false`, only the systems in the same namespace and the addresses or systems listed from the accessList. @@ -88,4 +89,3 @@ All of these global configuration keys are optional. tables: {}, }); ``` - diff --git a/package.json b/package.json index ccdf9a8a9f..ce617d7df6 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "lint": "pnpm prettier:check && eslint . --ext .ts --ext .tsx", "prepare": "husky install && (forge --version || pnpm foundryup)", "prettier": "prettier --write '**/*.{ts,tsx,css,md,mdx,sol}'", - "prettier:check": "prettier --check '**/*.{ts,tsx,css,md,sol}'", + "prettier:check": "prettier --check '**/*.{ts,tsx,css,md,mdx,sol}'", "release:check": "changeset status --verbose --since=origin/main", "release:publish": "pnpm install && pnpm build && changeset publish", "release:version": "changeset version && pnpm install --lockfile-only",