@latticexyz/cli 2.0.12-main-9be2bb86 → 2.0.12-main-96e7bf43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{commands-F37Q2ISZ.js → commands-265RZEHD.js} +17 -17
- package/dist/commands-265RZEHD.js.map +1 -0
- package/dist/mud.js +1 -1
- package/package.json +13 -11
- package/dist/commands-F37Q2ISZ.js.map +0 -1
- package/src/build.ts +0 -32
- package/src/commands/build.ts +0 -35
- package/src/commands/deploy.ts +0 -26
- package/src/commands/dev-contracts.ts +0 -118
- package/src/commands/devnode.ts +0 -42
- package/src/commands/hello.ts +0 -28
- package/src/commands/index.ts +0 -33
- package/src/commands/set-version.ts +0 -197
- package/src/commands/tablegen.ts +0 -34
- package/src/commands/test.ts +0 -65
- package/src/commands/trace.ts +0 -120
- package/src/commands/verify.ts +0 -100
- package/src/commands/worldgen.ts +0 -58
- package/src/common.ts +0 -1
- package/src/debug.ts +0 -10
- package/src/deploy/common.ts +0 -120
- package/src/deploy/configToModules.ts +0 -75
- package/src/deploy/configToTables.ts +0 -70
- package/src/deploy/create2/README.md +0 -13
- package/src/deploy/create2/deployment.json +0 -8
- package/src/deploy/createPrepareDeploy.ts +0 -28
- package/src/deploy/debug.ts +0 -10
- package/src/deploy/deploy.ts +0 -137
- package/src/deploy/deployWorld.ts +0 -38
- package/src/deploy/ensureContract.ts +0 -66
- package/src/deploy/ensureContractsDeployed.ts +0 -33
- package/src/deploy/ensureDeployer.ts +0 -69
- package/src/deploy/ensureFunctions.ts +0 -86
- package/src/deploy/ensureModules.ts +0 -81
- package/src/deploy/ensureNamespaceOwner.ts +0 -71
- package/src/deploy/ensureSystems.ts +0 -187
- package/src/deploy/ensureTables.ts +0 -64
- package/src/deploy/ensureWorldFactory.ts +0 -30
- package/src/deploy/findLibraries.ts +0 -36
- package/src/deploy/getDeployer.ts +0 -20
- package/src/deploy/getFunctions.ts +0 -64
- package/src/deploy/getResourceAccess.ts +0 -51
- package/src/deploy/getResourceIds.ts +0 -45
- package/src/deploy/getSystems.ts +0 -47
- package/src/deploy/getTableValue.ts +0 -31
- package/src/deploy/getTables.ts +0 -59
- package/src/deploy/getWorldContracts.ts +0 -79
- package/src/deploy/getWorldDeploy.ts +0 -39
- package/src/deploy/getWorldFactoryContracts.ts +0 -27
- package/src/deploy/getWorldProxyFactoryContracts.ts +0 -27
- package/src/deploy/logsToWorldDeploy.ts +0 -49
- package/src/deploy/orderByDependencies.ts +0 -12
- package/src/deploy/resolveConfig.ts +0 -104
- package/src/index.ts +0 -1
- package/src/modules.d.ts +0 -11
- package/src/mud.ts +0 -45
- package/src/mudPackages.ts +0 -24
- package/src/runDeploy.ts +0 -181
- package/src/utils/errors.ts +0 -29
- package/src/utils/findPlaceholders.ts +0 -27
- package/src/utils/getContractArtifact.ts +0 -80
- package/src/utils/getContractData.ts +0 -38
- package/src/utils/getExistingContracts.ts +0 -12
- package/src/utils/knownModuleArtifacts.ts +0 -8
- package/src/utils/postDeploy.ts +0 -42
- package/src/utils/printMUD.ts +0 -14
- package/src/verify/verifyContract.ts +0 -23
- package/src/verify.ts +0 -174
@@ -1,36 +0,0 @@
|
|
1
|
-
import { readFileSync } from "fs";
|
2
|
-
import glob from "glob";
|
3
|
-
import { orderByDependencies } from "./orderByDependencies";
|
4
|
-
import { LinkReferences } from "../utils/findPlaceholders";
|
5
|
-
|
6
|
-
export function findLibraries(forgeOutDir: string): readonly {
|
7
|
-
readonly path: string;
|
8
|
-
readonly name: string;
|
9
|
-
}[] {
|
10
|
-
const artifacts = glob
|
11
|
-
.sync(`${forgeOutDir}/**/*.json`, { ignore: "**/*.abi.json" })
|
12
|
-
.map((path) => JSON.parse(readFileSync(path, "utf8")));
|
13
|
-
|
14
|
-
const libraries = artifacts.flatMap((artifact) => {
|
15
|
-
if (!artifact.metadata) return [];
|
16
|
-
|
17
|
-
const contractPath = Object.keys(artifact.metadata.settings.compilationTarget)[0];
|
18
|
-
const contractName = artifact.metadata.settings.compilationTarget[contractPath];
|
19
|
-
const linkReferences = artifact.bytecode.linkReferences as LinkReferences;
|
20
|
-
|
21
|
-
return Object.entries(linkReferences).flatMap(([libraryPath, reference]) =>
|
22
|
-
Object.keys(reference).map((libraryName) => ({
|
23
|
-
path: libraryPath,
|
24
|
-
name: libraryName,
|
25
|
-
dependentPath: contractPath,
|
26
|
-
dependentName: contractName,
|
27
|
-
})),
|
28
|
-
);
|
29
|
-
});
|
30
|
-
|
31
|
-
return orderByDependencies(
|
32
|
-
libraries,
|
33
|
-
(lib) => `${lib.path}:${lib.name}`,
|
34
|
-
(lib) => [`${lib.dependentPath}:${lib.dependentName}`],
|
35
|
-
);
|
36
|
-
}
|
@@ -1,20 +0,0 @@
|
|
1
|
-
import { Address, Chain, Client, Transport, sliceHex } from "viem";
|
2
|
-
import { getBytecode } from "viem/actions";
|
3
|
-
import deployment from "./create2/deployment.json";
|
4
|
-
import { debug } from "./debug";
|
5
|
-
|
6
|
-
const deployer = `0x${deployment.address}` as const;
|
7
|
-
|
8
|
-
export async function getDeployer(client: Client<Transport, Chain | undefined>): Promise<Address | undefined> {
|
9
|
-
const bytecode = await getBytecode(client, { address: deployer });
|
10
|
-
if (bytecode) {
|
11
|
-
debug("found CREATE2 deployer at", deployer);
|
12
|
-
// check if deployed bytecode is the same as the expected bytecode (minus 14-bytes creation code prefix)
|
13
|
-
if (bytecode !== sliceHex(`0x${deployment.creationCode}`, 14)) {
|
14
|
-
console.warn(
|
15
|
-
`\n ⚠️ Bytecode for deployer at ${deployer} did not match the expected CREATE2 bytecode. You may have unexpected results.\n`,
|
16
|
-
);
|
17
|
-
}
|
18
|
-
return deployer;
|
19
|
-
}
|
20
|
-
}
|
@@ -1,64 +0,0 @@
|
|
1
|
-
import { Client, parseAbiItem } from "viem";
|
2
|
-
import { WorldDeploy, WorldFunction, worldTables } from "./common";
|
3
|
-
import { debug } from "./debug";
|
4
|
-
import { storeSetRecordEvent } from "@latticexyz/store";
|
5
|
-
import { getLogs } from "viem/actions";
|
6
|
-
import { decodeKey, decodeValueArgs } from "@latticexyz/protocol-parser/internal";
|
7
|
-
|
8
|
-
export async function getFunctions({
|
9
|
-
client,
|
10
|
-
worldDeploy,
|
11
|
-
}: {
|
12
|
-
readonly client: Client;
|
13
|
-
readonly worldDeploy: WorldDeploy;
|
14
|
-
}): Promise<readonly WorldFunction[]> {
|
15
|
-
// This assumes we only use `FunctionSelectors._set(...)`, which is true as of this writing.
|
16
|
-
debug("looking up function selectors for", worldDeploy.address);
|
17
|
-
const selectorLogs = await getLogs(client, {
|
18
|
-
strict: true,
|
19
|
-
fromBlock: worldDeploy.deployBlock,
|
20
|
-
toBlock: worldDeploy.stateBlock,
|
21
|
-
address: worldDeploy.address,
|
22
|
-
event: parseAbiItem(storeSetRecordEvent),
|
23
|
-
args: { tableId: worldTables.world_FunctionSelectors.tableId },
|
24
|
-
});
|
25
|
-
|
26
|
-
const selectors = selectorLogs.map((log) => {
|
27
|
-
return {
|
28
|
-
...decodeValueArgs(worldTables.world_FunctionSelectors.valueSchema, log.args),
|
29
|
-
...decodeKey(worldTables.world_FunctionSelectors.keySchema, log.args.keyTuple),
|
30
|
-
};
|
31
|
-
});
|
32
|
-
debug("found", selectors.length, "function selectors for", worldDeploy.address);
|
33
|
-
|
34
|
-
// This assumes we only use `FunctionSignatures._set(...)`, which is true as of this writing.
|
35
|
-
debug("looking up function signatures for", worldDeploy.address);
|
36
|
-
const signatureLogs = await getLogs(client, {
|
37
|
-
strict: true,
|
38
|
-
fromBlock: worldDeploy.deployBlock,
|
39
|
-
toBlock: worldDeploy.stateBlock,
|
40
|
-
address: worldDeploy.address,
|
41
|
-
event: parseAbiItem(storeSetRecordEvent),
|
42
|
-
args: { tableId: worldTables.world_FunctionSignatures.tableId },
|
43
|
-
});
|
44
|
-
|
45
|
-
const selectorToSignature = Object.fromEntries(
|
46
|
-
signatureLogs.map((log) => {
|
47
|
-
return [
|
48
|
-
decodeKey(worldTables.world_FunctionSignatures.keySchema, log.args.keyTuple).functionSelector,
|
49
|
-
decodeValueArgs(worldTables.world_FunctionSignatures.valueSchema, log.args).functionSignature,
|
50
|
-
];
|
51
|
-
}),
|
52
|
-
);
|
53
|
-
debug("found", signatureLogs.length, "function signatures for", worldDeploy.address);
|
54
|
-
|
55
|
-
const functions = selectors.map(({ worldFunctionSelector, systemFunctionSelector, systemId }) => ({
|
56
|
-
selector: worldFunctionSelector,
|
57
|
-
signature: selectorToSignature[worldFunctionSelector],
|
58
|
-
systemFunctionSelector,
|
59
|
-
systemFunctionSignature: selectorToSignature[systemFunctionSelector],
|
60
|
-
systemId,
|
61
|
-
}));
|
62
|
-
|
63
|
-
return functions;
|
64
|
-
}
|
@@ -1,51 +0,0 @@
|
|
1
|
-
import { Client, parseAbiItem, Hex, Address, getAddress } from "viem";
|
2
|
-
import { WorldDeploy, worldTables } from "./common";
|
3
|
-
import { debug } from "./debug";
|
4
|
-
import { storeSpliceStaticDataEvent } from "@latticexyz/store";
|
5
|
-
import { getLogs } from "viem/actions";
|
6
|
-
import { decodeKey } from "@latticexyz/protocol-parser/internal";
|
7
|
-
import { getTableValue } from "./getTableValue";
|
8
|
-
|
9
|
-
export async function getResourceAccess({
|
10
|
-
client,
|
11
|
-
worldDeploy,
|
12
|
-
}: {
|
13
|
-
readonly client: Client;
|
14
|
-
readonly worldDeploy: WorldDeploy;
|
15
|
-
}): Promise<readonly { readonly resourceId: Hex; readonly address: Address }[]> {
|
16
|
-
// This assumes we only use `ResourceAccess._set(...)`, which is true as of this writing.
|
17
|
-
// TODO: PR to viem's getLogs to accept topics array so we can filter on all store events and quickly recreate this table's current state
|
18
|
-
|
19
|
-
debug("looking up resource access for", worldDeploy.address);
|
20
|
-
|
21
|
-
const logs = await getLogs(client, {
|
22
|
-
strict: true,
|
23
|
-
fromBlock: worldDeploy.deployBlock,
|
24
|
-
toBlock: worldDeploy.stateBlock,
|
25
|
-
address: worldDeploy.address,
|
26
|
-
// our usage of `ResourceAccess._set(...)` emits a splice instead of set record
|
27
|
-
// TODO: https://github.com/latticexyz/mud/issues/479
|
28
|
-
event: parseAbiItem(storeSpliceStaticDataEvent),
|
29
|
-
args: { tableId: worldTables.world_ResourceAccess.tableId },
|
30
|
-
});
|
31
|
-
|
32
|
-
const keys = logs.map((log) => decodeKey(worldTables.world_ResourceAccess.keySchema, log.args.keyTuple));
|
33
|
-
|
34
|
-
const access = (
|
35
|
-
await Promise.all(
|
36
|
-
keys.map(
|
37
|
-
async (key) =>
|
38
|
-
[key, await getTableValue({ client, worldDeploy, table: worldTables.world_ResourceAccess, key })] as const,
|
39
|
-
),
|
40
|
-
)
|
41
|
-
)
|
42
|
-
.filter(([, value]) => value.access)
|
43
|
-
.map(([key]) => ({
|
44
|
-
resourceId: key.resourceId,
|
45
|
-
address: getAddress(key.caller),
|
46
|
-
}));
|
47
|
-
|
48
|
-
debug("found", access.length, "resource<>address access pairs");
|
49
|
-
|
50
|
-
return access;
|
51
|
-
}
|
@@ -1,45 +0,0 @@
|
|
1
|
-
import { Client, parseAbiItem, Hex, HttpRequestError } from "viem";
|
2
|
-
import { getLogs } from "viem/actions";
|
3
|
-
import { storeSpliceStaticDataEvent } from "@latticexyz/store";
|
4
|
-
import { WorldDeploy, storeTables } from "./common";
|
5
|
-
import { debug } from "./debug";
|
6
|
-
import pRetry from "p-retry";
|
7
|
-
|
8
|
-
export async function getResourceIds({
|
9
|
-
client,
|
10
|
-
worldDeploy,
|
11
|
-
}: {
|
12
|
-
readonly client: Client;
|
13
|
-
readonly worldDeploy: WorldDeploy;
|
14
|
-
}): Promise<readonly Hex[]> {
|
15
|
-
// This assumes we only use `ResourceIds._setExists(true)`, which is true as of this writing.
|
16
|
-
// TODO: PR to viem's getLogs to accept topics array so we can filter on all store events and quickly recreate this table's current state
|
17
|
-
|
18
|
-
debug("looking up resource IDs for", worldDeploy.address);
|
19
|
-
const logs = await pRetry(
|
20
|
-
() =>
|
21
|
-
getLogs(client, {
|
22
|
-
strict: true,
|
23
|
-
address: worldDeploy.address,
|
24
|
-
fromBlock: worldDeploy.deployBlock,
|
25
|
-
toBlock: worldDeploy.stateBlock,
|
26
|
-
event: parseAbiItem(storeSpliceStaticDataEvent),
|
27
|
-
args: { tableId: storeTables.store_ResourceIds.tableId },
|
28
|
-
}),
|
29
|
-
{
|
30
|
-
retries: 3,
|
31
|
-
onFailedAttempt: async (error) => {
|
32
|
-
const shouldRetry =
|
33
|
-
error instanceof HttpRequestError && error.status === 400 && error.message.includes("block is out of range");
|
34
|
-
|
35
|
-
if (!shouldRetry) {
|
36
|
-
throw error;
|
37
|
-
}
|
38
|
-
},
|
39
|
-
},
|
40
|
-
);
|
41
|
-
const resourceIds = logs.map((log) => log.args.keyTuple[0]);
|
42
|
-
debug("found", resourceIds.length, "resource IDs for", worldDeploy.address);
|
43
|
-
|
44
|
-
return resourceIds;
|
45
|
-
}
|
package/src/deploy/getSystems.ts
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
import { DeployedSystem, WorldDeploy, worldTables } from "./common";
|
2
|
-
import { Client } from "viem";
|
3
|
-
import { getResourceIds } from "./getResourceIds";
|
4
|
-
import { hexToResource, resourceToLabel } from "@latticexyz/common";
|
5
|
-
import { getTableValue } from "./getTableValue";
|
6
|
-
import { debug } from "./debug";
|
7
|
-
import { getFunctions } from "./getFunctions";
|
8
|
-
import { getResourceAccess } from "./getResourceAccess";
|
9
|
-
|
10
|
-
export async function getSystems({
|
11
|
-
client,
|
12
|
-
worldDeploy,
|
13
|
-
}: {
|
14
|
-
readonly client: Client;
|
15
|
-
readonly worldDeploy: WorldDeploy;
|
16
|
-
}): Promise<readonly DeployedSystem[]> {
|
17
|
-
const [resourceIds, functions, resourceAccess] = await Promise.all([
|
18
|
-
getResourceIds({ client, worldDeploy }),
|
19
|
-
getFunctions({ client, worldDeploy }),
|
20
|
-
getResourceAccess({ client, worldDeploy }),
|
21
|
-
]);
|
22
|
-
const systems = resourceIds.map(hexToResource).filter((resource) => resource.type === "system");
|
23
|
-
|
24
|
-
debug("looking up systems", systems.map(resourceToLabel).join(", "));
|
25
|
-
return await Promise.all(
|
26
|
-
systems.map(async (system): Promise<DeployedSystem> => {
|
27
|
-
const { system: address, publicAccess } = await getTableValue({
|
28
|
-
client,
|
29
|
-
worldDeploy,
|
30
|
-
table: worldTables.world_Systems,
|
31
|
-
key: { systemId: system.resourceId },
|
32
|
-
});
|
33
|
-
const systemFunctions = functions.filter((func) => func.systemId === system.resourceId);
|
34
|
-
return {
|
35
|
-
address,
|
36
|
-
namespace: system.namespace,
|
37
|
-
name: system.name,
|
38
|
-
systemId: system.resourceId,
|
39
|
-
allowAll: publicAccess,
|
40
|
-
allowedAddresses: resourceAccess
|
41
|
-
.filter(({ resourceId }) => resourceId === system.resourceId)
|
42
|
-
.map(({ address }) => address),
|
43
|
-
functions: systemFunctions,
|
44
|
-
};
|
45
|
-
}),
|
46
|
-
);
|
47
|
-
}
|
@@ -1,31 +0,0 @@
|
|
1
|
-
import { SchemaToPrimitives, decodeValueArgs, encodeKey } from "@latticexyz/protocol-parser/internal";
|
2
|
-
import { WorldDeploy, worldAbi } from "./common";
|
3
|
-
import { Client, Hex } from "viem";
|
4
|
-
import { readContract } from "viem/actions";
|
5
|
-
import { Table } from "./configToTables";
|
6
|
-
|
7
|
-
export async function getTableValue<table extends Table>({
|
8
|
-
client,
|
9
|
-
worldDeploy,
|
10
|
-
table,
|
11
|
-
key,
|
12
|
-
}: {
|
13
|
-
readonly client: Client;
|
14
|
-
readonly worldDeploy: WorldDeploy;
|
15
|
-
readonly table: table;
|
16
|
-
readonly key: SchemaToPrimitives<table["keySchema"]>;
|
17
|
-
}): Promise<SchemaToPrimitives<table["valueSchema"]>> {
|
18
|
-
const [staticData, encodedLengths, dynamicData] = (await readContract(client, {
|
19
|
-
blockNumber: worldDeploy.stateBlock,
|
20
|
-
address: worldDeploy.address,
|
21
|
-
abi: worldAbi,
|
22
|
-
functionName: "getRecord",
|
23
|
-
args: [table.tableId, encodeKey(table.keySchema, key)],
|
24
|
-
// TODO: remove cast once https://github.com/wevm/viem/issues/2125 is resolved
|
25
|
-
})) as [Hex, Hex, Hex];
|
26
|
-
return decodeValueArgs(table.valueSchema, {
|
27
|
-
staticData,
|
28
|
-
encodedLengths,
|
29
|
-
dynamicData,
|
30
|
-
});
|
31
|
-
}
|
package/src/deploy/getTables.ts
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
import { Client, parseAbiItem, decodeAbiParameters, parseAbiParameters } from "viem";
|
2
|
-
import { Table } from "./configToTables";
|
3
|
-
import { hexToResource } from "@latticexyz/common";
|
4
|
-
import { WorldDeploy, storeTables } from "./common";
|
5
|
-
import { debug } from "./debug";
|
6
|
-
import { storeSetRecordEvent } from "@latticexyz/store";
|
7
|
-
import { getLogs } from "viem/actions";
|
8
|
-
import { KeySchema, ValueSchema, decodeKey, decodeValueArgs, hexToSchema } from "@latticexyz/protocol-parser/internal";
|
9
|
-
|
10
|
-
export async function getTables({
|
11
|
-
client,
|
12
|
-
worldDeploy,
|
13
|
-
}: {
|
14
|
-
readonly client: Client;
|
15
|
-
readonly worldDeploy: WorldDeploy;
|
16
|
-
}): Promise<readonly Table[]> {
|
17
|
-
// This assumes we only use `Tables._set(...)`, which is true as of this writing.
|
18
|
-
// TODO: PR to viem's getLogs to accept topics array so we can filter on all store events and quickly recreate this table's current state
|
19
|
-
// TODO: consider moving this to a batched getRecord for Tables table
|
20
|
-
|
21
|
-
debug("looking up tables for", worldDeploy.address);
|
22
|
-
const logs = await getLogs(client, {
|
23
|
-
strict: true,
|
24
|
-
// this may fail for certain RPC providers with block range limits
|
25
|
-
// if so, could potentially use our fetchLogs helper (which does pagination)
|
26
|
-
fromBlock: worldDeploy.deployBlock,
|
27
|
-
toBlock: worldDeploy.stateBlock,
|
28
|
-
address: worldDeploy.address,
|
29
|
-
event: parseAbiItem(storeSetRecordEvent),
|
30
|
-
args: { tableId: storeTables.store_Tables.tableId },
|
31
|
-
});
|
32
|
-
|
33
|
-
// TODO: combine with store-sync logToTable and export from somewhere
|
34
|
-
const tables = logs.map((log) => {
|
35
|
-
const { tableId } = decodeKey(storeTables.store_Tables.keySchema, log.args.keyTuple);
|
36
|
-
const { namespace, name } = hexToResource(tableId);
|
37
|
-
const value = decodeValueArgs(storeTables.store_Tables.valueSchema, log.args);
|
38
|
-
|
39
|
-
// TODO: migrate to better helper
|
40
|
-
const keySchemaFields = hexToSchema(value.keySchema);
|
41
|
-
const valueSchemaFields = hexToSchema(value.valueSchema);
|
42
|
-
const keyNames = decodeAbiParameters(parseAbiParameters("string[]"), value.abiEncodedKeyNames)[0];
|
43
|
-
const fieldNames = decodeAbiParameters(parseAbiParameters("string[]"), value.abiEncodedFieldNames)[0];
|
44
|
-
|
45
|
-
const valueAbiTypes = [...valueSchemaFields.staticFields, ...valueSchemaFields.dynamicFields];
|
46
|
-
|
47
|
-
const keySchema = Object.fromEntries(
|
48
|
-
keySchemaFields.staticFields.map((abiType, i) => [keyNames[i], abiType]),
|
49
|
-
) as KeySchema;
|
50
|
-
const valueSchema = Object.fromEntries(valueAbiTypes.map((abiType, i) => [fieldNames[i], abiType])) as ValueSchema;
|
51
|
-
|
52
|
-
return { namespace, name, tableId, keySchema, valueSchema } as const;
|
53
|
-
});
|
54
|
-
// TODO: filter/detect duplicates?
|
55
|
-
|
56
|
-
debug("found", tables.length, "tables for", worldDeploy.address);
|
57
|
-
|
58
|
-
return tables;
|
59
|
-
}
|
@@ -1,79 +0,0 @@
|
|
1
|
-
import accessManagementSystemBuild from "@latticexyz/world/out/AccessManagementSystem.sol/AccessManagementSystem.json" assert { type: "json" };
|
2
|
-
import balanceTransferSystemBuild from "@latticexyz/world/out/BalanceTransferSystem.sol/BalanceTransferSystem.json" assert { type: "json" };
|
3
|
-
import batchCallSystemBuild from "@latticexyz/world/out/BatchCallSystem.sol/BatchCallSystem.json" assert { type: "json" };
|
4
|
-
import registrationSystemBuild from "@latticexyz/world/out/RegistrationSystem.sol/RegistrationSystem.json" assert { type: "json" };
|
5
|
-
import initModuleBuild from "@latticexyz/world/out/InitModule.sol/InitModule.json" assert { type: "json" };
|
6
|
-
import initModuleAbi from "@latticexyz/world/out/InitModule.sol/InitModule.abi.json" assert { type: "json" };
|
7
|
-
import { Hex, getCreate2Address, encodeDeployData, size } from "viem";
|
8
|
-
import { salt } from "./common";
|
9
|
-
|
10
|
-
export function getWorldContracts(deployerAddress: Hex) {
|
11
|
-
const accessManagementSystemDeployedBytecodeSize = size(accessManagementSystemBuild.deployedBytecode.object as Hex);
|
12
|
-
const accessManagementSystemBytecode = accessManagementSystemBuild.bytecode.object as Hex;
|
13
|
-
const accessManagementSystem = getCreate2Address({
|
14
|
-
from: deployerAddress,
|
15
|
-
bytecode: accessManagementSystemBytecode,
|
16
|
-
salt,
|
17
|
-
});
|
18
|
-
|
19
|
-
const balanceTransferSystemDeployedBytecodeSize = size(balanceTransferSystemBuild.deployedBytecode.object as Hex);
|
20
|
-
const balanceTransferSystemBytecode = balanceTransferSystemBuild.bytecode.object as Hex;
|
21
|
-
const balanceTransferSystem = getCreate2Address({
|
22
|
-
from: deployerAddress,
|
23
|
-
bytecode: balanceTransferSystemBytecode,
|
24
|
-
salt,
|
25
|
-
});
|
26
|
-
|
27
|
-
const batchCallSystemDeployedBytecodeSize = size(batchCallSystemBuild.deployedBytecode.object as Hex);
|
28
|
-
const batchCallSystemBytecode = batchCallSystemBuild.bytecode.object as Hex;
|
29
|
-
const batchCallSystem = getCreate2Address({ from: deployerAddress, bytecode: batchCallSystemBytecode, salt });
|
30
|
-
|
31
|
-
const registrationDeployedBytecodeSize = size(registrationSystemBuild.deployedBytecode.object as Hex);
|
32
|
-
const registrationBytecode = registrationSystemBuild.bytecode.object as Hex;
|
33
|
-
const registration = getCreate2Address({
|
34
|
-
from: deployerAddress,
|
35
|
-
bytecode: registrationBytecode,
|
36
|
-
salt,
|
37
|
-
});
|
38
|
-
|
39
|
-
const initModuleDeployedBytecodeSize = size(initModuleBuild.deployedBytecode.object as Hex);
|
40
|
-
const initModuleBytecode = encodeDeployData({
|
41
|
-
bytecode: initModuleBuild.bytecode.object as Hex,
|
42
|
-
abi: initModuleAbi,
|
43
|
-
args: [accessManagementSystem, balanceTransferSystem, batchCallSystem, registration],
|
44
|
-
});
|
45
|
-
const initModule = getCreate2Address({ from: deployerAddress, bytecode: initModuleBytecode, salt });
|
46
|
-
|
47
|
-
return {
|
48
|
-
AccessManagementSystem: {
|
49
|
-
bytecode: accessManagementSystemBytecode,
|
50
|
-
deployedBytecodeSize: accessManagementSystemDeployedBytecodeSize,
|
51
|
-
label: "access management system",
|
52
|
-
address: accessManagementSystem,
|
53
|
-
},
|
54
|
-
BalanceTransferSystem: {
|
55
|
-
bytecode: balanceTransferSystemBytecode,
|
56
|
-
deployedBytecodeSize: balanceTransferSystemDeployedBytecodeSize,
|
57
|
-
label: "balance transfer system",
|
58
|
-
address: balanceTransferSystem,
|
59
|
-
},
|
60
|
-
BatchCallSystem: {
|
61
|
-
bytecode: batchCallSystemBytecode,
|
62
|
-
deployedBytecodeSize: batchCallSystemDeployedBytecodeSize,
|
63
|
-
label: "batch call system",
|
64
|
-
address: batchCallSystem,
|
65
|
-
},
|
66
|
-
RegistrationSystem: {
|
67
|
-
bytecode: registrationBytecode,
|
68
|
-
deployedBytecodeSize: registrationDeployedBytecodeSize,
|
69
|
-
label: "core registration system",
|
70
|
-
address: registration,
|
71
|
-
},
|
72
|
-
InitModule: {
|
73
|
-
bytecode: initModuleBytecode,
|
74
|
-
deployedBytecodeSize: initModuleDeployedBytecodeSize,
|
75
|
-
label: "core module",
|
76
|
-
address: initModule,
|
77
|
-
},
|
78
|
-
};
|
79
|
-
}
|
@@ -1,39 +0,0 @@
|
|
1
|
-
import { Client, Address, getAddress, parseAbi } from "viem";
|
2
|
-
import { getBlockNumber, getLogs } from "viem/actions";
|
3
|
-
import { WorldDeploy, worldDeployEvents } from "./common";
|
4
|
-
import { debug } from "./debug";
|
5
|
-
import { logsToWorldDeploy } from "./logsToWorldDeploy";
|
6
|
-
|
7
|
-
const deploys = new Map<Address, WorldDeploy>();
|
8
|
-
|
9
|
-
export async function getWorldDeploy(client: Client, worldAddress: Address): Promise<WorldDeploy> {
|
10
|
-
const address = getAddress(worldAddress);
|
11
|
-
|
12
|
-
let deploy = deploys.get(address);
|
13
|
-
if (deploy != null) {
|
14
|
-
return deploy;
|
15
|
-
}
|
16
|
-
|
17
|
-
debug("looking up world deploy for", address);
|
18
|
-
|
19
|
-
const stateBlock = await getBlockNumber(client);
|
20
|
-
const logs = await getLogs(client, {
|
21
|
-
strict: true,
|
22
|
-
address,
|
23
|
-
events: parseAbi(worldDeployEvents),
|
24
|
-
// this may fail for certain RPC providers with block range limits
|
25
|
-
// if so, could potentially use our fetchLogs helper (which does pagination)
|
26
|
-
fromBlock: "earliest",
|
27
|
-
toBlock: stateBlock,
|
28
|
-
});
|
29
|
-
|
30
|
-
deploy = {
|
31
|
-
...logsToWorldDeploy(logs),
|
32
|
-
stateBlock,
|
33
|
-
};
|
34
|
-
deploys.set(address, deploy);
|
35
|
-
|
36
|
-
debug("found world deploy for", address, "at block", deploy.deployBlock);
|
37
|
-
|
38
|
-
return deploy;
|
39
|
-
}
|
@@ -1,27 +0,0 @@
|
|
1
|
-
import worldFactoryBuild from "@latticexyz/world/out/WorldFactory.sol/WorldFactory.json" assert { type: "json" };
|
2
|
-
import worldFactoryAbi from "@latticexyz/world/out/WorldFactory.sol/WorldFactory.abi.json" assert { type: "json" };
|
3
|
-
import { Hex, getCreate2Address, encodeDeployData, size } from "viem";
|
4
|
-
import { salt } from "./common";
|
5
|
-
import { getWorldContracts } from "./getWorldContracts";
|
6
|
-
|
7
|
-
export function getWorldFactoryContracts(deployerAddress: Hex) {
|
8
|
-
const worldContracts = getWorldContracts(deployerAddress);
|
9
|
-
|
10
|
-
const worldFactoryDeployedBytecodeSize = size(worldFactoryBuild.deployedBytecode.object as Hex);
|
11
|
-
const worldFactoryBytecode = encodeDeployData({
|
12
|
-
bytecode: worldFactoryBuild.bytecode.object as Hex,
|
13
|
-
abi: worldFactoryAbi,
|
14
|
-
args: [worldContracts.InitModule.address],
|
15
|
-
});
|
16
|
-
const worldFactory = getCreate2Address({ from: deployerAddress, bytecode: worldFactoryBytecode, salt });
|
17
|
-
|
18
|
-
return {
|
19
|
-
...worldContracts,
|
20
|
-
WorldFactory: {
|
21
|
-
bytecode: worldFactoryBytecode,
|
22
|
-
deployedBytecodeSize: worldFactoryDeployedBytecodeSize,
|
23
|
-
label: "world factory",
|
24
|
-
address: worldFactory,
|
25
|
-
},
|
26
|
-
};
|
27
|
-
}
|
@@ -1,27 +0,0 @@
|
|
1
|
-
import worldProxyFactoryBuild from "@latticexyz/world/out/WorldProxyFactory.sol/WorldProxyFactory.json" assert { type: "json" };
|
2
|
-
import worldProxyFactoryAbi from "@latticexyz/world/out/WorldProxyFactory.sol/WorldProxyFactory.abi.json" assert { type: "json" };
|
3
|
-
import { Hex, getCreate2Address, encodeDeployData, size } from "viem";
|
4
|
-
import { salt } from "./common";
|
5
|
-
import { getWorldContracts } from "./getWorldContracts";
|
6
|
-
|
7
|
-
export function getWorldProxyFactoryContracts(deployerAddress: Hex) {
|
8
|
-
const worldContracts = getWorldContracts(deployerAddress);
|
9
|
-
|
10
|
-
const worldProxyFactoryDeployedBytecodeSize = size(worldProxyFactoryBuild.deployedBytecode.object as Hex);
|
11
|
-
const worldProxyFactoryBytecode = encodeDeployData({
|
12
|
-
bytecode: worldProxyFactoryBuild.bytecode.object as Hex,
|
13
|
-
abi: worldProxyFactoryAbi,
|
14
|
-
args: [worldContracts.InitModule.address],
|
15
|
-
});
|
16
|
-
const worldProxyFactory = getCreate2Address({ from: deployerAddress, bytecode: worldProxyFactoryBytecode, salt });
|
17
|
-
|
18
|
-
return {
|
19
|
-
...worldContracts,
|
20
|
-
WorldProxyFactory: {
|
21
|
-
bytecode: worldProxyFactoryBytecode,
|
22
|
-
deployedBytecodeSize: worldProxyFactoryDeployedBytecodeSize,
|
23
|
-
label: "world proxy factory",
|
24
|
-
address: worldProxyFactory,
|
25
|
-
},
|
26
|
-
};
|
27
|
-
}
|
@@ -1,49 +0,0 @@
|
|
1
|
-
import { AbiEventSignatureNotFoundError, Log, decodeEventLog, hexToString, parseAbi } from "viem";
|
2
|
-
import { WorldDeploy, worldDeployEvents } from "./common";
|
3
|
-
import { isDefined } from "@latticexyz/common/utils";
|
4
|
-
|
5
|
-
export function logsToWorldDeploy(logs: readonly Log<bigint, number, false>[]): Omit<WorldDeploy, "stateBlock"> {
|
6
|
-
const deployLogs = logs
|
7
|
-
.map((log) => {
|
8
|
-
try {
|
9
|
-
return {
|
10
|
-
...log,
|
11
|
-
...decodeEventLog({
|
12
|
-
strict: true,
|
13
|
-
abi: parseAbi(worldDeployEvents),
|
14
|
-
topics: log.topics,
|
15
|
-
data: log.data,
|
16
|
-
}),
|
17
|
-
};
|
18
|
-
} catch (error: unknown) {
|
19
|
-
if (error instanceof AbiEventSignatureNotFoundError) {
|
20
|
-
return;
|
21
|
-
}
|
22
|
-
throw error;
|
23
|
-
}
|
24
|
-
})
|
25
|
-
.filter(isDefined);
|
26
|
-
|
27
|
-
// TODO: should this test for/validate that only one of each of these events is present? and that the address/block number don't change between each?
|
28
|
-
const { address, deployBlock, worldVersion, storeVersion } = deployLogs.reduce<Partial<WorldDeploy>>(
|
29
|
-
(deploy, log) => ({
|
30
|
-
...deploy,
|
31
|
-
address: log.address,
|
32
|
-
deployBlock: log.blockNumber,
|
33
|
-
...(log.eventName === "HelloWorld"
|
34
|
-
? { worldVersion: hexToString(log.args.worldVersion).replace(/\0+$/, "") }
|
35
|
-
: null),
|
36
|
-
...(log.eventName === "HelloStore"
|
37
|
-
? { storeVersion: hexToString(log.args.storeVersion).replace(/\0+$/, "") }
|
38
|
-
: null),
|
39
|
-
}),
|
40
|
-
{},
|
41
|
-
);
|
42
|
-
|
43
|
-
if (address == null) throw new Error("could not find world address");
|
44
|
-
if (deployBlock == null) throw new Error("could not find world deploy block number");
|
45
|
-
if (worldVersion == null) throw new Error("could not find world version");
|
46
|
-
if (storeVersion == null) throw new Error("could not find store version");
|
47
|
-
|
48
|
-
return { address, deployBlock, worldVersion, storeVersion };
|
49
|
-
}
|
@@ -1,12 +0,0 @@
|
|
1
|
-
import toposort from "toposort";
|
2
|
-
|
3
|
-
export function orderByDependencies<T>(
|
4
|
-
items: readonly T[],
|
5
|
-
itemKey: (item: T) => string,
|
6
|
-
dependencyKeys: (item: T) => string[],
|
7
|
-
): readonly T[] {
|
8
|
-
const dependencyOrder = toposort(
|
9
|
-
items.flatMap((item) => dependencyKeys(item).map((dependency) => [itemKey(item), dependency] as [string, string])),
|
10
|
-
);
|
11
|
-
return [...items].sort((a, b) => dependencyOrder.indexOf(itemKey(a)) - dependencyOrder.indexOf(itemKey(b)));
|
12
|
-
}
|