@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,104 +0,0 @@
|
|
1
|
-
import path from "path";
|
2
|
-
import { resolveWorldConfig } from "@latticexyz/world/internal";
|
3
|
-
import { Config, ConfigInput, Library, System, WorldFunction } from "./common";
|
4
|
-
import { resourceToHex } from "@latticexyz/common";
|
5
|
-
import { Hex, toFunctionSelector, toFunctionSignature } from "viem";
|
6
|
-
import { getExistingContracts } from "../utils/getExistingContracts";
|
7
|
-
import { getContractData } from "../utils/getContractData";
|
8
|
-
import { configToTables } from "./configToTables";
|
9
|
-
import { groupBy } from "@latticexyz/common/utils";
|
10
|
-
import { findLibraries } from "./findLibraries";
|
11
|
-
import { createPrepareDeploy } from "./createPrepareDeploy";
|
12
|
-
|
13
|
-
// TODO: this should be replaced by https://github.com/latticexyz/mud/issues/1668
|
14
|
-
|
15
|
-
export function resolveConfig<config extends ConfigInput>({
|
16
|
-
config,
|
17
|
-
forgeSourceDir,
|
18
|
-
forgeOutDir,
|
19
|
-
}: {
|
20
|
-
config: config;
|
21
|
-
forgeSourceDir: string;
|
22
|
-
forgeOutDir: string;
|
23
|
-
}): Config<config> {
|
24
|
-
const libraries = findLibraries(forgeOutDir).map((library): Library => {
|
25
|
-
// foundry/solc flattens artifacts, so we just use the path basename
|
26
|
-
const contractData = getContractData(path.basename(library.path), library.name, forgeOutDir);
|
27
|
-
return {
|
28
|
-
path: library.path,
|
29
|
-
name: library.name,
|
30
|
-
abi: contractData.abi,
|
31
|
-
prepareDeploy: createPrepareDeploy(contractData.bytecode, contractData.placeholders),
|
32
|
-
deployedBytecodeSize: contractData.deployedBytecodeSize,
|
33
|
-
};
|
34
|
-
});
|
35
|
-
|
36
|
-
const tables = configToTables(config);
|
37
|
-
|
38
|
-
// TODO: should the config parser/loader help with resolving systems?
|
39
|
-
const contractNames = getExistingContracts(forgeSourceDir).map(({ basename }) => basename);
|
40
|
-
const resolvedConfig = resolveWorldConfig(config, contractNames);
|
41
|
-
const baseSystemContractData = getContractData("System.sol", "System", forgeOutDir);
|
42
|
-
const baseSystemFunctions = baseSystemContractData.abi
|
43
|
-
.filter((item): item is typeof item & { type: "function" } => item.type === "function")
|
44
|
-
.map(toFunctionSignature);
|
45
|
-
|
46
|
-
const systems = Object.entries(resolvedConfig.systems).map(([systemName, system]): System => {
|
47
|
-
const namespace = config.namespace;
|
48
|
-
const name = system.name;
|
49
|
-
const systemId = resourceToHex({ type: "system", namespace, name });
|
50
|
-
const contractData = getContractData(`${systemName}.sol`, systemName, forgeOutDir);
|
51
|
-
|
52
|
-
const systemFunctions = contractData.abi
|
53
|
-
.filter((item): item is typeof item & { type: "function" } => item.type === "function")
|
54
|
-
.map(toFunctionSignature)
|
55
|
-
.filter((sig) => !baseSystemFunctions.includes(sig))
|
56
|
-
.map((sig): WorldFunction => {
|
57
|
-
// TODO: figure out how to not duplicate contract behavior (https://github.com/latticexyz/mud/issues/1708)
|
58
|
-
const worldSignature = namespace === "" ? sig : `${namespace}__${sig}`;
|
59
|
-
return {
|
60
|
-
signature: worldSignature,
|
61
|
-
selector: toFunctionSelector(worldSignature),
|
62
|
-
systemId,
|
63
|
-
systemFunctionSignature: sig,
|
64
|
-
systemFunctionSelector: toFunctionSelector(sig),
|
65
|
-
};
|
66
|
-
});
|
67
|
-
|
68
|
-
return {
|
69
|
-
namespace,
|
70
|
-
name,
|
71
|
-
systemId,
|
72
|
-
allowAll: system.openAccess,
|
73
|
-
allowedAddresses: system.accessListAddresses as Hex[],
|
74
|
-
allowedSystemIds: system.accessListSystems.map((name) =>
|
75
|
-
resourceToHex({ type: "system", namespace, name: resolvedConfig.systems[name].name }),
|
76
|
-
),
|
77
|
-
prepareDeploy: createPrepareDeploy(contractData.bytecode, contractData.placeholders),
|
78
|
-
deployedBytecodeSize: contractData.deployedBytecodeSize,
|
79
|
-
abi: contractData.abi,
|
80
|
-
functions: systemFunctions,
|
81
|
-
};
|
82
|
-
});
|
83
|
-
|
84
|
-
// Check for overlapping system IDs (since names get truncated when turning into IDs)
|
85
|
-
// TODO: move this into the world config resolve step once it resolves system IDs
|
86
|
-
const systemsById = groupBy(systems, (system) => system.systemId);
|
87
|
-
const overlappingSystems = Array.from(systemsById.values())
|
88
|
-
.filter((matches) => matches.length > 1)
|
89
|
-
.flat();
|
90
|
-
if (overlappingSystems.length) {
|
91
|
-
const names = overlappingSystems.map((system) => system.name);
|
92
|
-
throw new Error(
|
93
|
-
`Found systems with overlapping system ID: ${names.join(
|
94
|
-
", ",
|
95
|
-
)}.\n\nSystem IDs are generated from the first 16 bytes of the name, so you may need to rename them to avoid the overlap.`,
|
96
|
-
);
|
97
|
-
}
|
98
|
-
|
99
|
-
return {
|
100
|
-
tables,
|
101
|
-
systems,
|
102
|
-
libraries,
|
103
|
-
};
|
104
|
-
}
|
package/src/index.ts
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
// nothing to export
|
package/src/modules.d.ts
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
// adding .js to minimal would break clients down the line because it probably won't get a synthetic default import
|
2
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
3
|
-
declare module "protobufjs/minimal" {
|
4
|
-
export const configure: any;
|
5
|
-
export const util: any;
|
6
|
-
export const Reader: any;
|
7
|
-
export type Reader = any;
|
8
|
-
export const Writer: any;
|
9
|
-
export type Writer = any;
|
10
|
-
}
|
11
|
-
declare module "rollup-plugin-preserve-shebang";
|
package/src/mud.ts
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
#!/usr/bin/env node
|
2
|
-
|
3
|
-
// Load .env file into process.env
|
4
|
-
import * as dotenv from "dotenv";
|
5
|
-
dotenv.config();
|
6
|
-
|
7
|
-
async function run() {
|
8
|
-
// Import everything else async so they can pick up env vars in .env
|
9
|
-
const { default: yargs } = await import("yargs");
|
10
|
-
const { default: chalk } = await import("chalk");
|
11
|
-
const { hideBin } = await import("yargs/helpers");
|
12
|
-
const { logError } = await import("./utils/errors");
|
13
|
-
const { commands } = await import("./commands");
|
14
|
-
|
15
|
-
yargs(hideBin(process.argv))
|
16
|
-
// Explicit name to display in help (by default it's the entry file, which may not be "mud" for e.g. ts-node)
|
17
|
-
.scriptName("mud")
|
18
|
-
// Use the commands directory to scaffold
|
19
|
-
// command array overload isn't typed, see https://github.com/yargs/yargs/blob/main/docs/advanced.md#esm-hierarchy
|
20
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
21
|
-
.command(commands as any)
|
22
|
-
// Enable strict mode.
|
23
|
-
.strict()
|
24
|
-
// Custom error handler
|
25
|
-
.fail((msg, err) => {
|
26
|
-
console.error(chalk.red(msg));
|
27
|
-
if (msg.includes("Missing required argument")) {
|
28
|
-
console.log(
|
29
|
-
chalk.yellow(`Run 'pnpm mud ${process.argv[2]} --help' for a list of available and required arguments.`),
|
30
|
-
);
|
31
|
-
}
|
32
|
-
console.log("");
|
33
|
-
// Even though `.fail` type says we should get an `Error`, this can sometimes be undefined
|
34
|
-
if (err != null) {
|
35
|
-
logError(err);
|
36
|
-
console.log("");
|
37
|
-
}
|
38
|
-
|
39
|
-
process.exit(1);
|
40
|
-
})
|
41
|
-
// Useful aliases.
|
42
|
-
.alias({ h: "help" }).argv;
|
43
|
-
}
|
44
|
-
|
45
|
-
run();
|
package/src/mudPackages.ts
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
import { ZodError, z } from "zod";
|
2
|
-
import { MudPackages } from "./common";
|
3
|
-
|
4
|
-
const envSchema = z.object({
|
5
|
-
MUD_PACKAGES: z.string().transform((value) => JSON.parse(value) as MudPackages),
|
6
|
-
});
|
7
|
-
|
8
|
-
function parseEnv(): z.infer<typeof envSchema> {
|
9
|
-
try {
|
10
|
-
return envSchema.parse({
|
11
|
-
// tsup replaces the env vars with their values at compile time
|
12
|
-
MUD_PACKAGES: process.env.MUD_PACKAGES,
|
13
|
-
});
|
14
|
-
} catch (error) {
|
15
|
-
if (error instanceof ZodError) {
|
16
|
-
const { ...invalidEnvVars } = error.format();
|
17
|
-
console.error(`\nMissing or invalid environment variables:\n\n ${Object.keys(invalidEnvVars).join("\n ")}\n`);
|
18
|
-
process.exit(1);
|
19
|
-
}
|
20
|
-
throw error;
|
21
|
-
}
|
22
|
-
}
|
23
|
-
|
24
|
-
export const mudPackages = parseEnv().MUD_PACKAGES;
|
package/src/runDeploy.ts
DELETED
@@ -1,181 +0,0 @@
|
|
1
|
-
import path from "node:path";
|
2
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
3
|
-
import { InferredOptionTypes, Options } from "yargs";
|
4
|
-
import { deploy } from "./deploy/deploy";
|
5
|
-
import { createWalletClient, http, Hex, isHex } from "viem";
|
6
|
-
import { privateKeyToAccount } from "viem/accounts";
|
7
|
-
import { loadConfig } from "@latticexyz/config/node";
|
8
|
-
import { World as WorldConfig } from "@latticexyz/world";
|
9
|
-
import { worldToV1 } from "@latticexyz/world/config/v2";
|
10
|
-
import { getOutDirectory, getRpcUrl, getSrcDirectory } from "@latticexyz/common/foundry";
|
11
|
-
import chalk from "chalk";
|
12
|
-
import { MUDError } from "@latticexyz/common/errors";
|
13
|
-
import { resolveConfig } from "./deploy/resolveConfig";
|
14
|
-
import { getChainId } from "viem/actions";
|
15
|
-
import { postDeploy } from "./utils/postDeploy";
|
16
|
-
import { WorldDeploy } from "./deploy/common";
|
17
|
-
import { build } from "./build";
|
18
|
-
import { kmsKeyToAccount } from "@latticexyz/common/kms";
|
19
|
-
import { configToModules } from "./deploy/configToModules";
|
20
|
-
|
21
|
-
export const deployOptions = {
|
22
|
-
configPath: { type: "string", desc: "Path to the MUD config file" },
|
23
|
-
printConfig: { type: "boolean", desc: "Print the resolved config" },
|
24
|
-
profile: { type: "string", desc: "The foundry profile to use" },
|
25
|
-
saveDeployment: { type: "boolean", desc: "Save the deployment info to a file", default: true },
|
26
|
-
rpc: { type: "string", desc: "The RPC URL to use. Defaults to the RPC url from the local foundry.toml" },
|
27
|
-
rpcBatch: {
|
28
|
-
type: "boolean",
|
29
|
-
desc: "Enable batch processing of RPC requests in viem client (defaults to batch size of 100 and wait of 1s)",
|
30
|
-
},
|
31
|
-
deployerAddress: {
|
32
|
-
type: "string",
|
33
|
-
desc: "Deploy using an existing deterministic deployer (https://github.com/Arachnid/deterministic-deployment-proxy)",
|
34
|
-
},
|
35
|
-
worldAddress: { type: "string", desc: "Deploy to an existing World at the given address" },
|
36
|
-
srcDir: { type: "string", desc: "Source directory. Defaults to foundry src directory." },
|
37
|
-
skipBuild: { type: "boolean", desc: "Skip rebuilding the contracts before deploying" },
|
38
|
-
alwaysRunPostDeploy: {
|
39
|
-
type: "boolean",
|
40
|
-
desc: "Always run PostDeploy.s.sol after each deploy (including during upgrades). By default, PostDeploy.s.sol is only run once after a new world is deployed.",
|
41
|
-
},
|
42
|
-
forgeScriptOptions: { type: "string", description: "Options to pass to forge script PostDeploy.s.sol" },
|
43
|
-
salt: {
|
44
|
-
type: "string",
|
45
|
-
desc: "The deployment salt to use. Defaults to a random salt.",
|
46
|
-
},
|
47
|
-
kms: {
|
48
|
-
type: "boolean",
|
49
|
-
desc: "Deploy the World with an AWS KMS key instead of local private key.",
|
50
|
-
},
|
51
|
-
} as const satisfies Record<string, Options>;
|
52
|
-
|
53
|
-
export type DeployOptions = InferredOptionTypes<typeof deployOptions>;
|
54
|
-
|
55
|
-
/**
|
56
|
-
* Given some CLI arguments, finds and resolves a MUD config, foundry profile, and runs a deploy.
|
57
|
-
* This is used by the deploy, test, and dev-contracts CLI commands.
|
58
|
-
*/
|
59
|
-
export async function runDeploy(opts: DeployOptions): Promise<WorldDeploy> {
|
60
|
-
const salt = opts.salt;
|
61
|
-
if (salt != null && !isHex(salt)) {
|
62
|
-
throw new MUDError("Expected hex string for salt");
|
63
|
-
}
|
64
|
-
|
65
|
-
const profile = opts.profile ?? process.env.FOUNDRY_PROFILE;
|
66
|
-
|
67
|
-
const configV2 = (await loadConfig(opts.configPath)) as WorldConfig;
|
68
|
-
const config = worldToV1(configV2);
|
69
|
-
if (opts.printConfig) {
|
70
|
-
console.log(chalk.green("\nResolved config:\n"), JSON.stringify(config, null, 2));
|
71
|
-
}
|
72
|
-
|
73
|
-
const srcDir = opts.srcDir ?? (await getSrcDirectory(profile));
|
74
|
-
const outDir = await getOutDirectory(profile);
|
75
|
-
|
76
|
-
const rpc = opts.rpc ?? (await getRpcUrl(profile));
|
77
|
-
console.log(
|
78
|
-
chalk.bgBlue(
|
79
|
-
chalk.whiteBright(`\n Deploying MUD contracts${profile ? " with profile " + profile : ""} to RPC ${rpc} \n`),
|
80
|
-
),
|
81
|
-
);
|
82
|
-
|
83
|
-
// Run build
|
84
|
-
if (!opts.skipBuild) {
|
85
|
-
await build({ config: configV2, srcDir, foundryProfile: profile });
|
86
|
-
}
|
87
|
-
|
88
|
-
const resolvedConfig = resolveConfig({ config, forgeSourceDir: srcDir, forgeOutDir: outDir });
|
89
|
-
const modules = await configToModules(configV2, outDir);
|
90
|
-
|
91
|
-
const account = await (async () => {
|
92
|
-
if (opts.kms) {
|
93
|
-
const keyId = process.env.AWS_KMS_KEY_ID;
|
94
|
-
if (!keyId) {
|
95
|
-
throw new MUDError(
|
96
|
-
"Missing `AWS_KMS_KEY_ID` environment variable. This is required when using with `--kms` option.",
|
97
|
-
);
|
98
|
-
}
|
99
|
-
|
100
|
-
return await kmsKeyToAccount({ keyId });
|
101
|
-
} else {
|
102
|
-
const privateKey = process.env.PRIVATE_KEY;
|
103
|
-
if (!privateKey) {
|
104
|
-
throw new MUDError(
|
105
|
-
`Missing PRIVATE_KEY environment variable.
|
106
|
-
Run 'echo "PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" > .env'
|
107
|
-
in your contracts directory to use the default anvil private key.`,
|
108
|
-
);
|
109
|
-
}
|
110
|
-
|
111
|
-
return privateKeyToAccount(privateKey as Hex);
|
112
|
-
}
|
113
|
-
})();
|
114
|
-
|
115
|
-
const client = createWalletClient({
|
116
|
-
transport: http(rpc, {
|
117
|
-
batch: opts.rpcBatch
|
118
|
-
? {
|
119
|
-
batchSize: 100,
|
120
|
-
wait: 1000,
|
121
|
-
}
|
122
|
-
: undefined,
|
123
|
-
}),
|
124
|
-
account,
|
125
|
-
});
|
126
|
-
|
127
|
-
console.log("Deploying from", client.account.address);
|
128
|
-
|
129
|
-
const startTime = Date.now();
|
130
|
-
const worldDeploy = await deploy({
|
131
|
-
deployerAddress: opts.deployerAddress as Hex | undefined,
|
132
|
-
salt,
|
133
|
-
worldAddress: opts.worldAddress as Hex | undefined,
|
134
|
-
client,
|
135
|
-
config: resolvedConfig,
|
136
|
-
modules,
|
137
|
-
withWorldProxy: configV2.deploy.upgradeableWorldImplementation,
|
138
|
-
});
|
139
|
-
if (opts.worldAddress == null || opts.alwaysRunPostDeploy) {
|
140
|
-
await postDeploy(
|
141
|
-
config.postDeployScript,
|
142
|
-
worldDeploy.address,
|
143
|
-
rpc,
|
144
|
-
profile,
|
145
|
-
opts.forgeScriptOptions,
|
146
|
-
opts.kms ? true : false,
|
147
|
-
);
|
148
|
-
}
|
149
|
-
console.log(chalk.green("Deployment completed in", (Date.now() - startTime) / 1000, "seconds"));
|
150
|
-
|
151
|
-
const deploymentInfo = {
|
152
|
-
worldAddress: worldDeploy.address,
|
153
|
-
blockNumber: Number(worldDeploy.deployBlock),
|
154
|
-
};
|
155
|
-
|
156
|
-
if (opts.saveDeployment) {
|
157
|
-
const chainId = await getChainId(client);
|
158
|
-
const deploysDir = path.join(config.deploysDirectory, chainId.toString());
|
159
|
-
mkdirSync(deploysDir, { recursive: true });
|
160
|
-
writeFileSync(path.join(deploysDir, "latest.json"), JSON.stringify(deploymentInfo, null, 2));
|
161
|
-
writeFileSync(path.join(deploysDir, Date.now() + ".json"), JSON.stringify(deploymentInfo, null, 2));
|
162
|
-
|
163
|
-
const localChains = [1337, 31337];
|
164
|
-
const deploys = existsSync(config.worldsFile) ? JSON.parse(readFileSync(config.worldsFile, "utf-8")) : {};
|
165
|
-
deploys[chainId] = {
|
166
|
-
address: deploymentInfo.worldAddress,
|
167
|
-
// We expect the worlds file to be committed and since local deployments are often
|
168
|
-
// a consistent address but different block number, we'll ignore the block number.
|
169
|
-
blockNumber: localChains.includes(chainId) ? undefined : deploymentInfo.blockNumber,
|
170
|
-
};
|
171
|
-
writeFileSync(config.worldsFile, JSON.stringify(deploys, null, 2));
|
172
|
-
|
173
|
-
console.log(
|
174
|
-
chalk.bgGreen(chalk.whiteBright(`\n Deployment result (written to ${config.worldsFile} and ${deploysDir}): \n`)),
|
175
|
-
);
|
176
|
-
}
|
177
|
-
|
178
|
-
console.log(deploymentInfo);
|
179
|
-
|
180
|
-
return worldDeploy;
|
181
|
-
}
|
package/src/utils/errors.ts
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
import chalk from "chalk";
|
2
|
-
import { ZodError } from "zod";
|
3
|
-
import { fromZodError, ValidationError } from "zod-validation-error";
|
4
|
-
import { NotInsideProjectError } from "@latticexyz/config/library";
|
5
|
-
import { MUDError } from "@latticexyz/common/errors";
|
6
|
-
|
7
|
-
export function logError(error: unknown) {
|
8
|
-
if (error instanceof ValidationError) {
|
9
|
-
console.log(chalk.redBright(error.message));
|
10
|
-
} else if (error instanceof ZodError) {
|
11
|
-
// TODO currently this error shouldn't happen, use `fromZodErrorCustom`
|
12
|
-
// (see https://github.com/latticexyz/mud/issues/438)
|
13
|
-
const validationError = fromZodError(error, {
|
14
|
-
prefixSeparator: "\n- ",
|
15
|
-
issueSeparator: "\n- ",
|
16
|
-
});
|
17
|
-
console.log(chalk.redBright(validationError.message));
|
18
|
-
} else if (error instanceof NotInsideProjectError) {
|
19
|
-
console.log(chalk.red(error.message));
|
20
|
-
console.log("");
|
21
|
-
// TODO add docs to the website and update the link to the specific page
|
22
|
-
// (see https://github.com/latticexyz/mud/issues/445)
|
23
|
-
console.log(chalk.blue(`To learn more about MUD's configuration, please go to https://mud.dev/packages/cli/`));
|
24
|
-
} else if (error instanceof MUDError) {
|
25
|
-
console.log(chalk.red(error));
|
26
|
-
} else {
|
27
|
-
console.log(error);
|
28
|
-
}
|
29
|
-
}
|
@@ -1,27 +0,0 @@
|
|
1
|
-
import { LibraryPlaceholder } from "../deploy/common";
|
2
|
-
|
3
|
-
// TODO: move this to a broader solc artifact type
|
4
|
-
/** From `artifact.bytecode.linkReferences` where `artifact` is the solc JSON output of a compiled Solidity contract */
|
5
|
-
export type LinkReferences = {
|
6
|
-
[filename: string]: {
|
7
|
-
[name: string]: {
|
8
|
-
start: number;
|
9
|
-
length: number;
|
10
|
-
}[];
|
11
|
-
};
|
12
|
-
};
|
13
|
-
|
14
|
-
export function findPlaceholders(linkReferences: LinkReferences): readonly LibraryPlaceholder[] {
|
15
|
-
return Object.entries(linkReferences).flatMap(([path, contracts]) =>
|
16
|
-
Object.entries(contracts).flatMap(([contractName, locations]) =>
|
17
|
-
locations.map(
|
18
|
-
(location): LibraryPlaceholder => ({
|
19
|
-
path,
|
20
|
-
name: contractName,
|
21
|
-
start: location.start,
|
22
|
-
length: location.length,
|
23
|
-
}),
|
24
|
-
),
|
25
|
-
),
|
26
|
-
);
|
27
|
-
}
|
@@ -1,80 +0,0 @@
|
|
1
|
-
import { Abi, Hex, isHex, size } from "viem";
|
2
|
-
import { LibraryPlaceholder } from "../deploy/common";
|
3
|
-
import { findPlaceholders } from "./findPlaceholders";
|
4
|
-
import { z } from "zod";
|
5
|
-
import { Abi as abiSchema } from "abitype/zod";
|
6
|
-
import { createRequire } from "node:module";
|
7
|
-
import { findUp } from "find-up";
|
8
|
-
|
9
|
-
export type GetContractArtifactOptions = {
|
10
|
-
/**
|
11
|
-
* Path to `package.json` where `artifactPath`s are resolved relative to.
|
12
|
-
*
|
13
|
-
* Defaults to nearest `package.json` relative to `process.cwd()`.
|
14
|
-
*/
|
15
|
-
packageJsonPath?: string;
|
16
|
-
/**
|
17
|
-
* Import path to contract's forge/solc JSON artifact with the contract's compiled bytecode.
|
18
|
-
*
|
19
|
-
* This path is resolved using node's module resolution relative to `configPath`, so this supports both
|
20
|
-
* relative file paths (`../path/to/MyModule.json`) as well as JS import paths (`@latticexyz/world-contracts/out/CallWithSignatureModule.sol/CallWithSignatureModule.json`).
|
21
|
-
*/
|
22
|
-
artifactPath: string;
|
23
|
-
};
|
24
|
-
|
25
|
-
export type GetContractArtifactResult = {
|
26
|
-
bytecode: Hex;
|
27
|
-
placeholders: readonly LibraryPlaceholder[];
|
28
|
-
abi: Abi;
|
29
|
-
deployedBytecodeSize: number;
|
30
|
-
};
|
31
|
-
|
32
|
-
const bytecodeSchema = z.object({
|
33
|
-
object: z.string().refine(isHex),
|
34
|
-
linkReferences: z.record(
|
35
|
-
z.record(
|
36
|
-
z.array(
|
37
|
-
z.object({
|
38
|
-
start: z.number(),
|
39
|
-
length: z.number(),
|
40
|
-
}),
|
41
|
-
),
|
42
|
-
),
|
43
|
-
),
|
44
|
-
});
|
45
|
-
|
46
|
-
const artifactSchema = z.object({
|
47
|
-
bytecode: bytecodeSchema,
|
48
|
-
deployedBytecode: bytecodeSchema,
|
49
|
-
abi: abiSchema,
|
50
|
-
});
|
51
|
-
|
52
|
-
export async function getContractArtifact({
|
53
|
-
packageJsonPath,
|
54
|
-
artifactPath,
|
55
|
-
}: GetContractArtifactOptions): Promise<GetContractArtifactResult> {
|
56
|
-
let importedArtifact;
|
57
|
-
try {
|
58
|
-
const requirePath = packageJsonPath ?? (await findUp("package.json", { cwd: process.cwd() }));
|
59
|
-
if (!requirePath) throw new Error("Could not find package.json to import relative to.");
|
60
|
-
|
61
|
-
const require = createRequire(requirePath);
|
62
|
-
importedArtifact = require(artifactPath);
|
63
|
-
} catch (error) {
|
64
|
-
console.error();
|
65
|
-
console.error("Could not import contract artifact at", artifactPath);
|
66
|
-
console.error();
|
67
|
-
throw error;
|
68
|
-
}
|
69
|
-
|
70
|
-
// TODO: improve errors or replace with arktype?
|
71
|
-
const artifact = artifactSchema.parse(importedArtifact);
|
72
|
-
const placeholders = findPlaceholders(artifact.bytecode.linkReferences);
|
73
|
-
|
74
|
-
return {
|
75
|
-
abi: artifact.abi,
|
76
|
-
bytecode: artifact.bytecode.object,
|
77
|
-
placeholders,
|
78
|
-
deployedBytecodeSize: size(artifact.deployedBytecode.object),
|
79
|
-
};
|
80
|
-
}
|
@@ -1,38 +0,0 @@
|
|
1
|
-
import { readFileSync } from "fs";
|
2
|
-
import path from "path";
|
3
|
-
import { MUDError } from "@latticexyz/common/errors";
|
4
|
-
import { Abi, Hex, size } from "viem";
|
5
|
-
import { LibraryPlaceholder } from "../deploy/common";
|
6
|
-
import { findPlaceholders } from "./findPlaceholders";
|
7
|
-
|
8
|
-
/**
|
9
|
-
* Load the contract's abi and bytecode from the file system
|
10
|
-
* @param contractName: Name of the contract to load
|
11
|
-
*/
|
12
|
-
export function getContractData(
|
13
|
-
filename: string,
|
14
|
-
contractName: string,
|
15
|
-
forgeOutDirectory: string,
|
16
|
-
): { bytecode: Hex; placeholders: readonly LibraryPlaceholder[]; abi: Abi; deployedBytecodeSize: number } {
|
17
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
18
|
-
let data: any;
|
19
|
-
const contractDataPath = path.join(forgeOutDirectory, filename, contractName + ".json");
|
20
|
-
try {
|
21
|
-
data = JSON.parse(readFileSync(contractDataPath, "utf8"));
|
22
|
-
} catch (error) {
|
23
|
-
throw new MUDError(`Error reading file at ${contractDataPath}`);
|
24
|
-
}
|
25
|
-
|
26
|
-
const bytecode = data?.bytecode?.object;
|
27
|
-
if (!bytecode) throw new MUDError(`No bytecode found in ${contractDataPath}`);
|
28
|
-
|
29
|
-
const deployedBytecode = data?.deployedBytecode?.object;
|
30
|
-
if (!deployedBytecode) throw new MUDError(`No deployed bytecode found in ${contractDataPath}`);
|
31
|
-
|
32
|
-
const abi = data?.abi;
|
33
|
-
if (!abi) throw new MUDError(`No ABI found in ${contractDataPath}`);
|
34
|
-
|
35
|
-
const placeholders = findPlaceholders(data?.bytecode?.linkReferences ?? {});
|
36
|
-
|
37
|
-
return { abi, bytecode, placeholders, deployedBytecodeSize: size(deployedBytecode as Hex) };
|
38
|
-
}
|
@@ -1,12 +0,0 @@
|
|
1
|
-
import glob from "glob";
|
2
|
-
import { basename } from "path";
|
3
|
-
|
4
|
-
/**
|
5
|
-
* Get a list of all contract paths/names within the provided src directory
|
6
|
-
*/
|
7
|
-
export function getExistingContracts(srcDir: string) {
|
8
|
-
return glob.sync(`${srcDir}/**/*.sol`).map((path) => ({
|
9
|
-
path,
|
10
|
-
basename: basename(path, ".sol"),
|
11
|
-
}));
|
12
|
-
}
|
@@ -1,8 +0,0 @@
|
|
1
|
-
/** @deprecated Please don't add to this list! These are kept for backwards compatibility and assumes the downstream project has this module installed as a dependency. */
|
2
|
-
export const knownModuleArtifacts = {
|
3
|
-
KeysWithValueModule: "@latticexyz/world-modules/out/KeysWithValueModule.sol/KeysWithValueModule.json",
|
4
|
-
KeysInTableModule: "@latticexyz/world-modules/out/KeysInTableModule.sol/KeysInTableModule.json",
|
5
|
-
UniqueEntityModule: "@latticexyz/world-modules/out/UniqueEntityModule.sol/UniqueEntityModule.json",
|
6
|
-
Unstable_CallWithSignatureModule:
|
7
|
-
"@latticexyz/world-modules/out/Unstable_CallWithSignatureModule.sol/Unstable_CallWithSignatureModule.json",
|
8
|
-
};
|
package/src/utils/postDeploy.ts
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
import { existsSync } from "fs";
|
2
|
-
import path from "path";
|
3
|
-
import chalk from "chalk";
|
4
|
-
import { getScriptDirectory, forge } from "@latticexyz/common/foundry";
|
5
|
-
|
6
|
-
export async function postDeploy(
|
7
|
-
postDeployScript: string,
|
8
|
-
worldAddress: string,
|
9
|
-
rpc: string,
|
10
|
-
profile: string | undefined,
|
11
|
-
forgeOptions: string | undefined,
|
12
|
-
kms: boolean,
|
13
|
-
): Promise<void> {
|
14
|
-
// TODO: make this more robust as it is likely to fail for any args that have a space in them
|
15
|
-
const userOptions = forgeOptions?.replaceAll("\\", "").split(" ") ?? [];
|
16
|
-
const postDeployPath = path.join(await getScriptDirectory(), postDeployScript + ".s.sol");
|
17
|
-
if (!existsSync(postDeployPath)) {
|
18
|
-
console.log(`No script at ${postDeployPath}, skipping post deploy hook`);
|
19
|
-
return;
|
20
|
-
}
|
21
|
-
|
22
|
-
console.log(chalk.blue(`Executing post deploy script at ${postDeployPath}`));
|
23
|
-
|
24
|
-
await forge(
|
25
|
-
[
|
26
|
-
"script",
|
27
|
-
postDeployScript,
|
28
|
-
"--broadcast",
|
29
|
-
"--sig",
|
30
|
-
"run(address)",
|
31
|
-
worldAddress,
|
32
|
-
"--rpc-url",
|
33
|
-
rpc,
|
34
|
-
"-vvv",
|
35
|
-
kms ? "--aws" : "",
|
36
|
-
...userOptions,
|
37
|
-
],
|
38
|
-
{
|
39
|
-
profile: profile,
|
40
|
-
},
|
41
|
-
);
|
42
|
-
}
|
package/src/utils/printMUD.ts
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
import chalk from "chalk";
|
2
|
-
|
3
|
-
export function printMUD() {
|
4
|
-
console.log(
|
5
|
-
chalk.yellow(`
|
6
|
-
.------..------..------.
|
7
|
-
|M.--. ||U.--. ||D.--. |
|
8
|
-
| (\\/) || (\\/) || :/\\: |
|
9
|
-
| :\\/: || :\\/: || (__) |
|
10
|
-
| '--'M|| '--'U|| '--'D|
|
11
|
-
'------''------''------'
|
12
|
-
`),
|
13
|
-
);
|
14
|
-
}
|
@@ -1,23 +0,0 @@
|
|
1
|
-
import { forge } from "@latticexyz/common/foundry";
|
2
|
-
import { Address } from "viem";
|
3
|
-
|
4
|
-
type VerifyContractOptions = {
|
5
|
-
name: string;
|
6
|
-
rpc: string;
|
7
|
-
verifier?: string;
|
8
|
-
verifierUrl?: string;
|
9
|
-
address: Address;
|
10
|
-
cwd?: string;
|
11
|
-
};
|
12
|
-
|
13
|
-
export async function verifyContract(options: VerifyContractOptions) {
|
14
|
-
const args = ["verify-contract", options.address, options.name, "--rpc-url", options.rpc];
|
15
|
-
|
16
|
-
if (options.verifier) {
|
17
|
-
args.push("--verifier", options.verifier);
|
18
|
-
}
|
19
|
-
if (options.verifierUrl) {
|
20
|
-
args.push("--verifier-url", options.verifierUrl);
|
21
|
-
}
|
22
|
-
await forge(args, { cwd: options.cwd });
|
23
|
-
}
|