Skip to content

Commit

Permalink
refactor(cli,world): move helper functions into world package, add ge…
Browse files Browse the repository at this point in the history
…tWorldAbi (#3012)
  • Loading branch information
karooolis authored Aug 7, 2024
1 parent 0b282ad commit 1b7004b
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 24 deletions.
9 changes: 7 additions & 2 deletions packages/cli/src/deploy/ensureFunctions.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Client, Transport, Chain, Account, Hex } from "viem";
import { hexToResource, writeContract } from "@latticexyz/common";
import { getFunctions } from "@latticexyz/world/internal";
import { WorldDeploy, WorldFunction, worldAbi } from "./common";
import { debug } from "./debug";
import { getFunctions } from "./getFunctions";
import pRetry from "p-retry";
import { wait } from "@latticexyz/common/utils";

Expand All @@ -15,7 +15,12 @@ export async function ensureFunctions({
readonly worldDeploy: WorldDeploy;
readonly functions: readonly WorldFunction[];
}): Promise<readonly Hex[]> {
const worldFunctions = await getFunctions({ client, worldDeploy });
const worldFunctions = await getFunctions({
client,
worldAddress: worldDeploy.address,
fromBlock: worldDeploy.deployBlock,
toBlock: worldDeploy.stateBlock,
});
const worldSelectorToFunction = Object.fromEntries(worldFunctions.map((func) => [func.selector, func]));

const toSkip = functions.filter((func) => worldSelectorToFunction[func.selector]);
Expand Down
11 changes: 8 additions & 3 deletions packages/cli/src/deploy/getSystems.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { DeployedSystem, WorldDeploy } from "./common";
import { Client } from "viem";
import { getResourceIds } from "./getResourceIds";
import { hexToResource, resourceToLabel } from "@latticexyz/common";
import { getFunctions } from "@latticexyz/world/internal";
import { getResourceIds } from "./getResourceIds";
import { getTableValue } from "./getTableValue";
import { debug } from "./debug";
import { getFunctions } from "./getFunctions";
import { getResourceAccess } from "./getResourceAccess";
import worldConfig from "@latticexyz/world/mud.config";

Expand All @@ -17,7 +17,12 @@ export async function getSystems({
}): Promise<readonly DeployedSystem[]> {
const [resourceIds, functions, resourceAccess] = await Promise.all([
getResourceIds({ client, worldDeploy }),
getFunctions({ client, worldDeploy }),
getFunctions({
client,
worldAddress: worldDeploy.address,
fromBlock: worldDeploy.deployBlock,
toBlock: worldDeploy.stateBlock,
}),
getResourceAccess({ client, worldDeploy }),
]);
const systems = resourceIds.map(hexToResource).filter((resource) => resource.type === "system");
Expand Down
2 changes: 2 additions & 0 deletions packages/world/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,13 @@
"@latticexyz/store": "workspace:*",
"abitype": "1.0.0",
"arktype": "1.0.29-alpha",
"debug": "^4.3.4",
"viem": "2.9.20"
},
"devDependencies": {
"@latticexyz/abi-ts": "workspace:*",
"@latticexyz/gas-report": "workspace:*",
"@types/debug": "^4.1.7",
"@types/ejs": "^3.1.1",
"@types/mocha": "^9.1.1",
"@types/node": "^18.15.11",
Expand Down
9 changes: 9 additions & 0 deletions packages/world/ts/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Hex } from "viem";

export type WorldFunction = {
readonly signature: string;
readonly selector: Hex;
readonly systemId: Hex;
readonly systemFunctionSignature: string;
readonly systemFunctionSelector: Hex;
};
10 changes: 10 additions & 0 deletions packages/world/ts/debug.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import createDebug from "debug";

export const debug = createDebug("mud:world");
export const error = createDebug("mud:world");

// Pipe debug output to stdout instead of stderr
debug.log = console.debug.bind(console);

// Pipe error output to stderr
error.log = console.error.bind(console);
3 changes: 3 additions & 0 deletions packages/world/ts/exports/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ export * from "../actions/callFrom";

export * from "../callWithSignatureTypes";

export * from "../getFunctions";
export * from "../getWorldAbi";

export { resolveTableId, resolveWithContext } from "../config/v2/dynamicResolution";
6 changes: 6 additions & 0 deletions packages/world/ts/functionSignatureToAbiItem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { AbiItem, parseAbiItem } from "viem";

export function functionSignatureToAbiItem(functionSignature: string): AbiItem {
const formattedSignature = `function ${functionSignature}`;
return parseAbiItem(formattedSignature);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Client, parseAbiItem } from "viem";
import { WorldDeploy, WorldFunction } from "./common";
import { Client, parseAbiItem, Address } from "viem";
import { WorldFunction } from "./common";
import { debug } from "./debug";
import { storeSetRecordEvent } from "@latticexyz/store";
import { getLogs } from "viem/actions";
Expand All @@ -10,22 +10,26 @@ import {
getSchemaTypes,
getValueSchema,
} from "@latticexyz/protocol-parser/internal";
import worldConfig from "@latticexyz/world/mud.config";
import worldConfig from "../mud.config";

export async function getFunctions({
client,
worldDeploy,
worldAddress,
fromBlock,
toBlock,
}: {
readonly client: Client;
readonly worldDeploy: WorldDeploy;
readonly worldAddress: Address;
readonly fromBlock: bigint;
readonly toBlock: bigint;
}): Promise<readonly WorldFunction[]> {
// This assumes we only use `FunctionSelectors._set(...)`, which is true as of this writing.
debug("looking up function selectors for", worldDeploy.address);
debug("looking up function selectors for", worldAddress);
const selectorLogs = await getLogs(client, {
strict: true,
fromBlock: worldDeploy.deployBlock,
toBlock: worldDeploy.stateBlock,
address: worldDeploy.address,
fromBlock,
toBlock,
address: worldAddress,
event: parseAbiItem(storeSetRecordEvent),
args: { tableId: worldConfig.namespaces.world.tables.FunctionSelectors.tableId },
});
Expand All @@ -42,15 +46,15 @@ export async function getFunctions({
),
};
});
debug("found", selectors.length, "function selectors for", worldDeploy.address);
debug("found", selectors.length, "function selectors for", worldAddress);

// This assumes we only use `FunctionSignatures._set(...)`, which is true as of this writing.
debug("looking up function signatures for", worldDeploy.address);
debug("looking up function signatures for", worldAddress);
const signatureLogs = await getLogs(client, {
strict: true,
fromBlock: worldDeploy.deployBlock,
toBlock: worldDeploy.stateBlock,
address: worldDeploy.address,
fromBlock,
toBlock,
address: worldAddress,
event: parseAbiItem(storeSetRecordEvent),
args: { tableId: worldConfig.namespaces.world.tables.FunctionSignatures.tableId },
});
Expand All @@ -69,7 +73,7 @@ export async function getFunctions({
];
}),
);
debug("found", signatureLogs.length, "function signatures for", worldDeploy.address);
debug("found", signatureLogs.length, "function signatures for", worldAddress);

const functions = selectors.map(({ worldFunctionSelector, systemFunctionSelector, systemId }) => ({
selector: worldFunctionSelector,
Expand Down
27 changes: 27 additions & 0 deletions packages/world/ts/getWorldAbi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Client, Abi, Address, getAddress } from "viem";
import IBaseWorldAbi from "../out/IBaseWorld.sol/IBaseWorld.abi.json";
import { functionSignatureToAbiItem } from "./functionSignatureToAbiItem";
import { getFunctions } from "./getFunctions";

export async function getWorldAbi({
client,
worldAddress,
fromBlock,
toBlock,
}: {
readonly client: Client;
readonly worldAddress: Address;
readonly fromBlock: bigint;
readonly toBlock: bigint;
}): Promise<Abi> {
const worldFunctions = await getFunctions({
client,
worldAddress: getAddress(worldAddress),
fromBlock,
toBlock,
});
const worldFunctionsAbi = worldFunctions.map((func) => functionSignatureToAbiItem(func.signature));
const abi = [...IBaseWorldAbi, ...worldFunctionsAbi];

return abi;
}
25 changes: 21 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 1b7004b

Please sign in to comment.