Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(guides / extending): update for the app namespace 🚗 #2860

Merged
merged 4 commits into from
May 23, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 24 additions & 27 deletions docs/pages/guides/extending-a-world/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ The easiest way to create the Solidity code is to use the MUD template:
import { Messages } from "../codegen/index.sol";

interface WorldWithIncrement {
function increment() external returns (uint32);
function app__increment() external returns (uint32);
}

contract MessageSystem is System {
function incrementMessage(string memory message) public returns (uint32) {
uint32 newVal = WorldWithIncrement(_world()).increment();
uint32 newVal = WorldWithIncrement(_world()).app__increment();
Messages.set(newVal, message);
return newVal;
}
Expand All @@ -102,26 +102,26 @@ The easiest way to create the Solidity code is to use the MUD template:

```solidity
interface WorldWithIncrement {
function increment() external returns (uint32);
function app__increment() external returns (uint32);
}
```

This `System` needs to call `increment` on the `World` where it is implemented.
However, as an extension author you might not have access to the source code of any `System` that isn't part of your extension.
This `System` needs to call `increment` on the `World` where it is implemented, which is in the `app` namespace.
However, as an extension author, you might not have access to the source code of any `System` that isn't part of your extension.

If you define your own interface for `World` you can add whatever function signatures are supported.
Note that [an Ethereum function selector](https://docs.soliditylang.org/en/latest/abi-spec.html#function-selector) is based on the function name and its parameter types, it does not include the return type.
Note that [the Ethereum function selector](https://docs.soliditylang.org/en/latest/abi-spec.html#function-selector) is based on the function name and its parameter types, it does not include the return type.
So if you are unsure of the return type that is not a huge problem.

```solidity
contract MessageSystem is System {
function incrementMessage(string memory message) public returns (uint32) {
uint32 newVal = WorldWithIncrement(_world()).increment();
uint32 newVal = WorldWithIncrement(_world()).app__increment();
```

This is how we use the `WorldWithIncrement` interface we created.
The [`_world()`](https://github.com/latticexyz/mud/blob/main/packages/world/src/WorldContext.sol#L38-L44) call gives us the address of the `World` that called us.
When we specify `WorldWithIncrement(<address>)`, we are telling Solidity that there is already a `WorldWithIncrement` at that address, and therefore we can use functions that are supported by `WorldWithIncrement`, such as `increment()`.
When we specify `WorldWithIncrement(<address>)`, we are telling Solidity that there is already a `WorldWithIncrement` at that address, and therefore we can use functions that are supported by `WorldWithIncrement`, such as `app__increment()`.

```solidity
Messages.set(newVal, message);
Expand Down Expand Up @@ -160,15 +160,15 @@ The easiest way to create the Solidity code is to use the MUD template:
Preferably, _not_ the one that deployed the `World`.
- `WORLD_ADDRESS` - the address of the `World` to which you add the namespace.

If you are using the template with a fresh `pnpm dev`, then you can use this `.env`:
If you are using the template with a fresh `pnpm dev`, then you can use this `.env` (verify that `WORLD_ADDRESS` is correct using the MUD Dev Tools):

```sh filename=".env" copy
# Anvil default private key for the second account
# (NOT the account that deployed the World)
PRIVATE_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d

# Address for the world we are extending
WORLD_ADDRESS=0xc14fbdb7808d9e2a37c1a45b635c8c3ff64a1cc1
WORLD_ADDRESS=0x8d8b6b8414e1e3dcfd4168561b9be6bd3bf6ec4b
```

1. Create this script in `script/MessagingExtension.s.sol`.
Expand Down Expand Up @@ -533,19 +533,17 @@ Here we modify the template UI.
```

1. Open the application at [http://localhost:3001](http://localhost:3001).
The client will throw errors because we didn't update the client code to work with the new contracts yet - we'll fix that in the next steps.
The client will throw errors because we haven't updated the client code to work with the new contracts yet - we'll fix that in the next steps.

1. The network configuration does not have the correct `World` address.
Get the `World` address from the application being extended.
By default, you can see this value on the application at URL [http://localhost:3000](http://localhost:3000).
Edit `../contracts/worlds.json` to set the `World` address for the chain ID (`31337`).
You need it in `../contracts/worlds.json`.

Note: If you followed the directions above to create `extendMe`, the `World` address is `0xc14fbdb7808d9e2a37c1a45b635c8c3ff64a1cc1`.
You can either copy `...extendMe/packages/contracts/worlds.json` into `../contracts/worlds.json`, or get it from the MUD Dev Tools of the applications you extend typically at [http://localhost:3000](http://localhost:3000) and edit the value manually.

```json copy {3}
{
"31337": {
"address": "0xc14fbdb7808d9e2a37c1a45b635c8c3ff64a1cc1"
"address": "0x8d8b6b8414e1e3dcfd4168561b9be6bd3bf6ec4b"
}
}
```
Expand All @@ -559,7 +557,7 @@ We will fix these problems now.

<CollapseCode>

```ts filename="createSystemCalls.ts" copy showLineNumbers {43-44}
```ts filename="createSystemCalls.ts" copy showLineNumbers {43}
/*
* Create the system calls that the client can use to ask
* for changes in the World state (using the System contracts).
Expand Down Expand Up @@ -631,13 +629,13 @@ We will fix these problems now.
} = await setup();

// Components expose a stream that triggers when the component is updated.
components.Counter && components.Counter.update$.subscribe((update) => {
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"$
document.getElementById("counter")!.innerHTML = String(nextValue?.value ?? "unset");
});

// Attach the increment function to the html element with ID `incrementButton` (if i$
// Attach the increment function to the html element with ID `incrementButton` (if it exists)
document.querySelector("#incrementButton")?.addEventListener("click", increment);

// https://vitejs.dev/guide/env-and-mode.html
Expand Down Expand Up @@ -666,16 +664,16 @@ We will fix these problems now.

### Read the counter

We still don't have the `Counter` value available, because the definition in `mud.config.ts` is in the `messaging` namespace, not the root one.
We still don't have the `Counter` value available, because the definition in `mud.config.ts` is in the `messaging` namespace, not the `app` one.
We will now fix this.

1. Add the `@latticexyz/store` package.

```sh copy
pnpm add @latticexyz/store
pnpm add @latticexyz/store@latest
```

1. Copy the `mud.config.ts` from the application being extended (`extendMe`) to `src/mud/counter.config.ts`.
1. Copy the `mud.config.ts` from the application being extended (`extendMe/packages/contracts`) to `src/mud/counter.config.ts`.

```ts filename="counter.config.ts" copy
import { defineWorld } from "@latticexyz/world";
Expand All @@ -698,7 +696,7 @@ We will now fix this.

<CollapseCode>

```ts filename="setupNetwork.ts" copy showLineNumbers {25-26,39,96}
```ts filename="setupNetwork.ts" copy showLineNumbers {24-25,38,96}
/*
* The MUD client code is built on top of viem
* (https://viem.sh/docs/getting-started.html).
Expand All @@ -711,7 +709,6 @@ We will now fix this.
http,
createWalletClient,
Hex,
parseEther,
ClientConfig,
getContract,
} from "viem";
Expand Down Expand Up @@ -794,8 +791,8 @@ We will now fix this.
config: mudConfig,
address: networkConfig.worldAddress as Hex,
publicClient,
tables: resolveConfig(storeToV1(counterConfig)).tables,
startBlock: BigInt(networkConfig.initialBlockNumber),
tables: resolveConfig(storeToV1(counterConfig)).tables,
});

return {
Expand All @@ -816,4 +813,4 @@ We will now fix this.
</CollapseCode>

Now you can click **Increment** and see the update.
Also, you can look in **Components > Counter** and see the counter value.
Also, you can look in **Components > app\_\_Counter** and see the counter value.
Loading