@latticexyz/cli 2.0.0-next.16 → 2.0.0-next.18
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/{chunk-22IIKR4S.js → chunk-QXUPZVZL.js} +2 -2
- package/dist/chunk-QXUPZVZL.js.map +1 -0
- package/dist/commands-MGE24C7Z.js +36 -0
- package/dist/commands-MGE24C7Z.js.map +1 -0
- package/dist/errors-MZURIB7V.js +2 -0
- package/dist/mud.js +1 -1
- package/dist/mud.js.map +1 -1
- package/package.json +17 -16
- package/src/build.ts +9 -5
- package/src/commands/build.ts +2 -3
- package/src/commands/deploy.ts +1 -1
- package/src/commands/dev-contracts.ts +7 -5
- package/src/commands/set-version.ts +1 -1
- package/src/commands/tablegen.ts +2 -2
- package/src/commands/trace.ts +7 -5
- package/src/commands/worldgen.ts +7 -6
- package/src/deploy/common.ts +54 -8
- package/src/deploy/configToTables.ts +8 -6
- package/src/deploy/create2/README.md +4 -0
- package/src/deploy/create2/deployment.json +2 -1
- package/src/deploy/createPrepareDeploy.ts +28 -0
- package/src/deploy/deploy.ts +36 -16
- package/src/deploy/deployWorld.ts +9 -4
- package/src/deploy/ensureContract.ts +12 -7
- package/src/deploy/ensureContractsDeployed.ts +9 -1
- package/src/deploy/ensureDeployer.ts +61 -22
- package/src/deploy/ensureFunctions.ts +5 -5
- package/src/deploy/ensureModules.ts +16 -10
- package/src/deploy/ensureNamespaceOwner.ts +4 -4
- package/src/deploy/ensureSystems.ts +108 -83
- package/src/deploy/ensureTables.ts +8 -9
- package/src/deploy/ensureWorldFactory.ts +83 -98
- package/src/deploy/findLibraries.ts +36 -0
- package/src/deploy/getFunctions.ts +5 -5
- package/src/deploy/getResourceAccess.ts +3 -3
- package/src/deploy/getSystems.ts +6 -7
- package/src/deploy/getTableValue.ts +1 -1
- package/src/deploy/getTables.ts +2 -2
- package/src/deploy/logsToWorldDeploy.ts +4 -4
- package/src/deploy/orderByDependencies.ts +12 -0
- package/src/deploy/resolveConfig.ts +56 -59
- package/src/mud.ts +1 -1
- package/src/mudPackages.ts +1 -1
- package/src/runDeploy.ts +39 -11
- package/src/utils/{modules/constants.ts → defaultModuleContracts.ts} +4 -0
- package/src/utils/errors.ts +1 -1
- package/src/utils/findPlaceholders.ts +27 -0
- package/src/utils/{utils/getContractData.ts → getContractData.ts} +11 -5
- package/src/utils/{utils/postDeploy.ts → postDeploy.ts} +2 -2
- package/src/utils/printMUD.ts +1 -1
- package/dist/chunk-22IIKR4S.js.map +0 -1
- package/dist/commands-DSIRJZEM.js +0 -27
- package/dist/commands-DSIRJZEM.js.map +0 -1
- package/dist/errors-XGN6V2Y3.js +0 -2
- package/src/deploy/resourceLabel.ts +0 -3
- /package/dist/{errors-XGN6V2Y3.js.map → errors-MZURIB7V.js.map} +0 -0
package/src/runDeploy.ts
CHANGED
@@ -2,17 +2,17 @@ import path from "node:path";
|
|
2
2
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
3
3
|
import { InferredOptionTypes, Options } from "yargs";
|
4
4
|
import { deploy } from "./deploy/deploy";
|
5
|
-
import { createWalletClient, http, Hex } from "viem";
|
5
|
+
import { createWalletClient, http, Hex, isHex } from "viem";
|
6
6
|
import { privateKeyToAccount } from "viem/accounts";
|
7
7
|
import { loadConfig } from "@latticexyz/config/node";
|
8
|
-
import {
|
9
|
-
import {
|
8
|
+
import { World as WorldConfig } from "@latticexyz/world";
|
9
|
+
import { worldToV1 } from "@latticexyz/world/config/v2";
|
10
10
|
import { getOutDirectory, getRpcUrl, getSrcDirectory } from "@latticexyz/common/foundry";
|
11
11
|
import chalk from "chalk";
|
12
12
|
import { MUDError } from "@latticexyz/common/errors";
|
13
13
|
import { resolveConfig } from "./deploy/resolveConfig";
|
14
14
|
import { getChainId } from "viem/actions";
|
15
|
-
import { postDeploy } from "./utils/
|
15
|
+
import { postDeploy } from "./utils/postDeploy";
|
16
16
|
import { WorldDeploy } from "./deploy/common";
|
17
17
|
import { build } from "./build";
|
18
18
|
|
@@ -22,6 +22,14 @@ export const deployOptions = {
|
|
22
22
|
profile: { type: "string", desc: "The foundry profile to use" },
|
23
23
|
saveDeployment: { type: "boolean", desc: "Save the deployment info to a file", default: true },
|
24
24
|
rpc: { type: "string", desc: "The RPC URL to use. Defaults to the RPC url from the local foundry.toml" },
|
25
|
+
rpcBatch: {
|
26
|
+
type: "boolean",
|
27
|
+
desc: "Enable batch processing of RPC requests in viem client (defaults to batch size of 100 and wait of 1s)",
|
28
|
+
},
|
29
|
+
deployerAddress: {
|
30
|
+
type: "string",
|
31
|
+
desc: "Deploy using an existing deterministic deployer (https://github.com/Arachnid/deterministic-deployment-proxy)",
|
32
|
+
},
|
25
33
|
worldAddress: { type: "string", desc: "Deploy to an existing World at the given address" },
|
26
34
|
srcDir: { type: "string", desc: "Source directory. Defaults to foundry src directory." },
|
27
35
|
skipBuild: { type: "boolean", desc: "Skip rebuilding the contracts before deploying" },
|
@@ -29,6 +37,10 @@ export const deployOptions = {
|
|
29
37
|
type: "boolean",
|
30
38
|
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.",
|
31
39
|
},
|
40
|
+
salt: {
|
41
|
+
type: "string",
|
42
|
+
desc: "The deployment salt to use. Defaults to a random salt.",
|
43
|
+
},
|
32
44
|
} as const satisfies Record<string, Options>;
|
33
45
|
|
34
46
|
export type DeployOptions = InferredOptionTypes<typeof deployOptions>;
|
@@ -38,9 +50,15 @@ export type DeployOptions = InferredOptionTypes<typeof deployOptions>;
|
|
38
50
|
* This is used by the deploy, test, and dev-contracts CLI commands.
|
39
51
|
*/
|
40
52
|
export async function runDeploy(opts: DeployOptions): Promise<WorldDeploy> {
|
53
|
+
const salt = opts.salt;
|
54
|
+
if (salt != null && !isHex(salt)) {
|
55
|
+
throw new MUDError("Expected hex string for salt");
|
56
|
+
}
|
57
|
+
|
41
58
|
const profile = opts.profile ?? process.env.FOUNDRY_PROFILE;
|
42
59
|
|
43
|
-
const
|
60
|
+
const configV2 = (await loadConfig(opts.configPath)) as WorldConfig;
|
61
|
+
const config = worldToV1(configV2);
|
44
62
|
if (opts.printConfig) {
|
45
63
|
console.log(chalk.green("\nResolved config:\n"), JSON.stringify(config, null, 2));
|
46
64
|
}
|
@@ -51,13 +69,13 @@ export async function runDeploy(opts: DeployOptions): Promise<WorldDeploy> {
|
|
51
69
|
const rpc = opts.rpc ?? (await getRpcUrl(profile));
|
52
70
|
console.log(
|
53
71
|
chalk.bgBlue(
|
54
|
-
chalk.whiteBright(`\n Deploying MUD contracts${profile ? " with profile " + profile : ""} to RPC ${rpc} \n`)
|
55
|
-
)
|
72
|
+
chalk.whiteBright(`\n Deploying MUD contracts${profile ? " with profile " + profile : ""} to RPC ${rpc} \n`),
|
73
|
+
),
|
56
74
|
);
|
57
75
|
|
58
76
|
// Run build
|
59
77
|
if (!opts.skipBuild) {
|
60
|
-
await build({ config, srcDir, foundryProfile: profile });
|
78
|
+
await build({ config: configV2, srcDir, foundryProfile: profile });
|
61
79
|
}
|
62
80
|
|
63
81
|
const privateKey = process.env.PRIVATE_KEY as Hex;
|
@@ -65,20 +83,30 @@ export async function runDeploy(opts: DeployOptions): Promise<WorldDeploy> {
|
|
65
83
|
throw new MUDError(
|
66
84
|
`Missing PRIVATE_KEY environment variable.
|
67
85
|
Run 'echo "PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" > .env'
|
68
|
-
in your contracts directory to use the default anvil private key
|
86
|
+
in your contracts directory to use the default anvil private key.`,
|
69
87
|
);
|
70
88
|
}
|
71
89
|
|
72
90
|
const resolvedConfig = resolveConfig({ config, forgeSourceDir: srcDir, forgeOutDir: outDir });
|
73
91
|
|
74
92
|
const client = createWalletClient({
|
75
|
-
transport: http(rpc
|
93
|
+
transport: http(rpc, {
|
94
|
+
batch: opts.rpcBatch
|
95
|
+
? {
|
96
|
+
batchSize: 100,
|
97
|
+
wait: 1000,
|
98
|
+
}
|
99
|
+
: undefined,
|
100
|
+
}),
|
76
101
|
account: privateKeyToAccount(privateKey),
|
77
102
|
});
|
103
|
+
|
78
104
|
console.log("Deploying from", client.account.address);
|
79
105
|
|
80
106
|
const startTime = Date.now();
|
81
107
|
const worldDeploy = await deploy({
|
108
|
+
deployerAddress: opts.deployerAddress as Hex | undefined,
|
109
|
+
salt,
|
82
110
|
worldAddress: opts.worldAddress as Hex | undefined,
|
83
111
|
client,
|
84
112
|
config: resolvedConfig,
|
@@ -111,7 +139,7 @@ in your contracts directory to use the default anvil private key.`
|
|
111
139
|
writeFileSync(config.worldsFile, JSON.stringify(deploys, null, 2));
|
112
140
|
|
113
141
|
console.log(
|
114
|
-
chalk.bgGreen(chalk.whiteBright(`\n Deployment result (written to ${config.worldsFile} and ${deploysDir}): \n`))
|
142
|
+
chalk.bgGreen(chalk.whiteBright(`\n Deployment result (written to ${config.worldsFile} and ${deploysDir}): \n`)),
|
115
143
|
);
|
116
144
|
}
|
117
145
|
|
@@ -2,6 +2,7 @@ import KeysWithValueModuleData from "@latticexyz/world-modules/out/KeysWithValue
|
|
2
2
|
import KeysInTableModuleData from "@latticexyz/world-modules/out/KeysInTableModule.sol/KeysInTableModule.json" assert { type: "json" };
|
3
3
|
import UniqueEntityModuleData from "@latticexyz/world-modules/out/UniqueEntityModule.sol/UniqueEntityModule.json" assert { type: "json" };
|
4
4
|
import { Abi, Hex, size } from "viem";
|
5
|
+
import { findPlaceholders } from "./findPlaceholders";
|
5
6
|
|
6
7
|
// These modules are always deployed
|
7
8
|
export const defaultModuleContracts = [
|
@@ -9,18 +10,21 @@ export const defaultModuleContracts = [
|
|
9
10
|
name: "KeysWithValueModule",
|
10
11
|
abi: KeysWithValueModuleData.abi as Abi,
|
11
12
|
bytecode: KeysWithValueModuleData.bytecode.object as Hex,
|
13
|
+
placeholders: findPlaceholders(KeysWithValueModuleData.bytecode.linkReferences),
|
12
14
|
deployedBytecodeSize: size(KeysWithValueModuleData.deployedBytecode.object as Hex),
|
13
15
|
},
|
14
16
|
{
|
15
17
|
name: "KeysInTableModule",
|
16
18
|
abi: KeysInTableModuleData.abi as Abi,
|
17
19
|
bytecode: KeysInTableModuleData.bytecode.object as Hex,
|
20
|
+
placeholders: findPlaceholders(KeysInTableModuleData.bytecode.linkReferences),
|
18
21
|
deployedBytecodeSize: size(KeysInTableModuleData.deployedBytecode.object as Hex),
|
19
22
|
},
|
20
23
|
{
|
21
24
|
name: "UniqueEntityModule",
|
22
25
|
abi: UniqueEntityModuleData.abi as Abi,
|
23
26
|
bytecode: UniqueEntityModuleData.bytecode.object as Hex,
|
27
|
+
placeholders: findPlaceholders(UniqueEntityModuleData.bytecode.linkReferences),
|
24
28
|
deployedBytecodeSize: size(UniqueEntityModuleData.deployedBytecode.object as Hex),
|
25
29
|
},
|
26
30
|
];
|
package/src/utils/errors.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import chalk from "chalk";
|
2
2
|
import { ZodError } from "zod";
|
3
3
|
import { fromZodError, ValidationError } from "zod-validation-error";
|
4
|
-
import { NotInsideProjectError } from "@latticexyz/config";
|
4
|
+
import { NotInsideProjectError } from "@latticexyz/config/library";
|
5
5
|
import { MUDError } from "@latticexyz/common/errors";
|
6
6
|
|
7
7
|
export function logError(error: unknown) {
|
@@ -0,0 +1,27 @@
|
|
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
|
+
}
|
@@ -2,20 +2,24 @@ import { readFileSync } from "fs";
|
|
2
2
|
import path from "path";
|
3
3
|
import { MUDError } from "@latticexyz/common/errors";
|
4
4
|
import { Abi, Hex, size } from "viem";
|
5
|
+
import { LibraryPlaceholder } from "../deploy/common";
|
6
|
+
import { findPlaceholders } from "./findPlaceholders";
|
5
7
|
|
6
8
|
/**
|
7
9
|
* Load the contract's abi and bytecode from the file system
|
8
10
|
* @param contractName: Name of the contract to load
|
9
11
|
*/
|
10
12
|
export function getContractData(
|
13
|
+
filename: string,
|
11
14
|
contractName: string,
|
12
|
-
forgeOutDirectory: string
|
13
|
-
): { bytecode: Hex; abi: Abi; deployedBytecodeSize: number } {
|
15
|
+
forgeOutDirectory: string,
|
16
|
+
): { bytecode: Hex; placeholders: readonly LibraryPlaceholder[]; abi: Abi; deployedBytecodeSize: number } {
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
14
18
|
let data: any;
|
15
|
-
const contractDataPath = path.join(forgeOutDirectory,
|
19
|
+
const contractDataPath = path.join(forgeOutDirectory, filename, contractName + ".json");
|
16
20
|
try {
|
17
21
|
data = JSON.parse(readFileSync(contractDataPath, "utf8"));
|
18
|
-
} catch (error
|
22
|
+
} catch (error) {
|
19
23
|
throw new MUDError(`Error reading file at ${contractDataPath}`);
|
20
24
|
}
|
21
25
|
|
@@ -28,5 +32,7 @@ export function getContractData(
|
|
28
32
|
const abi = data?.abi;
|
29
33
|
if (!abi) throw new MUDError(`No ABI found in ${contractDataPath}`);
|
30
34
|
|
31
|
-
|
35
|
+
const placeholders = findPlaceholders(data?.bytecode?.linkReferences ?? {});
|
36
|
+
|
37
|
+
return { abi, bytecode, placeholders, deployedBytecodeSize: size(deployedBytecode as Hex) };
|
32
38
|
}
|
@@ -7,7 +7,7 @@ export async function postDeploy(
|
|
7
7
|
postDeployScript: string,
|
8
8
|
worldAddress: string,
|
9
9
|
rpc: string,
|
10
|
-
profile: string | undefined
|
10
|
+
profile: string | undefined,
|
11
11
|
): Promise<void> {
|
12
12
|
// Execute postDeploy forge script
|
13
13
|
const postDeployPath = path.join(await getScriptDirectory(), postDeployScript + ".s.sol");
|
@@ -17,7 +17,7 @@ export async function postDeploy(
|
|
17
17
|
["script", postDeployScript, "--sig", "run(address)", worldAddress, "--broadcast", "--rpc-url", rpc, "-vvv"],
|
18
18
|
{
|
19
19
|
profile: profile,
|
20
|
-
}
|
20
|
+
},
|
21
21
|
);
|
22
22
|
} else {
|
23
23
|
console.log(`No script at ${postDeployPath}, skipping post deploy hook`);
|
package/src/utils/printMUD.ts
CHANGED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"sources":["../src/utils/errors.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport { ZodError } from \"zod\";\nimport { fromZodError, ValidationError } from \"zod-validation-error\";\nimport { NotInsideProjectError } from \"@latticexyz/config\";\nimport { MUDError } from \"@latticexyz/common/errors\";\n\nexport function logError(error: unknown) {\n if (error instanceof ValidationError) {\n console.log(chalk.redBright(error.message));\n } else if (error instanceof ZodError) {\n // TODO currently this error shouldn't happen, use `fromZodErrorCustom`\n // (see https://github.com/latticexyz/mud/issues/438)\n const validationError = fromZodError(error, {\n prefixSeparator: \"\\n- \",\n issueSeparator: \"\\n- \",\n });\n console.log(chalk.redBright(validationError.message));\n } else if (error instanceof NotInsideProjectError) {\n console.log(chalk.red(error.message));\n console.log(\"\");\n // TODO add docs to the website and update the link to the specific page\n // (see https://github.com/latticexyz/mud/issues/445)\n console.log(chalk.blue(`To learn more about MUD's configuration, please go to https://mud.dev/packages/cli/`));\n } else if (error instanceof MUDError) {\n console.log(chalk.red(error));\n } else {\n console.log(error);\n }\n}\n"],"mappings":"AAAA,OAAOA,MAAW,QAClB,OAAS,YAAAC,MAAgB,MACzB,OAAS,gBAAAC,EAAc,mBAAAC,MAAuB,uBAC9C,OAAS,yBAAAC,MAA6B,qBACtC,OAAS,YAAAC,MAAgB,4BAElB,SAASC,EAASC,EAAgB,CACvC,GAAIA,aAAiBJ,EACnB,QAAQ,IAAIH,EAAM,UAAUO,EAAM,OAAO,CAAC,UACjCA,aAAiBN,EAAU,CAGpC,IAAMO,EAAkBN,EAAaK,EAAO,CAC1C,gBAAiB;AAAA,IACjB,eAAgB;AAAA,GAClB,CAAC,EACD,QAAQ,IAAIP,EAAM,UAAUQ,EAAgB,OAAO,CAAC,OAC3CD,aAAiBH,GAC1B,QAAQ,IAAIJ,EAAM,IAAIO,EAAM,OAAO,CAAC,EACpC,QAAQ,IAAI,EAAE,EAGd,QAAQ,IAAIP,EAAM,KAAK,qFAAqF,CAAC,GACpGO,aAAiBF,EAC1B,QAAQ,IAAIL,EAAM,IAAIO,CAAK,CAAC,EAE5B,QAAQ,IAAIA,CAAK,CAErB","names":["chalk","ZodError","fromZodError","ValidationError","NotInsideProjectError","MUDError","logError","error","validationError"]}
|
@@ -1,27 +0,0 @@
|
|
1
|
-
import{a as _}from"./chunk-22IIKR4S.js";import hs from"@latticexyz/gas-report";import ws from"@latticexyz/abi-ts";import{loadConfig as qo}from"@latticexyz/config/node";import{getSrcDirectory as Go}from"@latticexyz/common/foundry";import{existsSync as Ho,readFileSync as Eo,writeFileSync as No}from"node:fs";import X from"node:path";import{tablegen as zo}from"@latticexyz/store/codegen";import{worldgen as Uo}from"@latticexyz/world/node";import{forge as Vo,getForgeConfig as _o,getRemappings as Lo}from"@latticexyz/common/foundry";import Wo from"glob";import{basename as Ro}from"path";function I(e){return Wo.sync(`${e}/**/*.sol`).map(o=>({path:o,basename:Ro(o,".sol")}))}import ye from"debug";var M=ye("mud:cli"),$o=ye("mud:cli");M.log=console.debug.bind(console);$o.log=console.error.bind(console);import{execa as Ko}from"execa";var Jo=M.extend("runDeploy");async function L({config:e,srcDir:o,foundryProfile:r=process.env.FOUNDRY_PROFILE}){let t=X.join(o,e.codegenDirectory),n=await Lo(r);await Promise.all([zo(e,t,n),Uo(e,I(o),t)]);let s=await _o(r);if(s.cache){let c=X.join(s.cache_path,"solidity-files-cache.json");if(Ho(c)){Jo("Unsetting cached content hash of IWorld.sol to force it to regenerate");let i=JSON.parse(Eo(c,"utf8")),p=X.join(t,"world","IWorld.sol");i.files[p].contentHash="",No(c,JSON.stringify(i,null,2))}}await Vo(["build"],{profile:r}),await Ko("mud",["abi-ts"],{stdio:"inherit"})}var Yo={command:"build",describe:"Build contracts and generate MUD artifacts (table libraries, world interface, ABI)",builder(e){return e.options({configPath:{type:"string",desc:"Path to the config file"},profile:{type:"string",desc:"The foundry profile to use"}})},async handler({configPath:e,profile:o}){let r=await qo(e),t=await Go();await L({config:r,srcDir:t,foundryProfile:o}),process.exit(0)}},ue=Yo;import{rmSync as Zo}from"fs";import{homedir as Qo}from"os";import Xo from"path";import{execa as et}from"execa";var ot={command:"devnode",describe:"Start a local Ethereum node for development",builder(e){return e.options({blocktime:{type:"number",default:1,decs:"Interval in which new blocks are produced"}})},async handler({blocktime:e}){console.log("Clearing devnode history");let o=Qo();Zo(Xo.join(o,".foundry","anvil","tmp"),{recursive:!0,force:!0});let r=["-b",String(e),"--block-base-fee-per-gas","0"];console.log(`Running: anvil ${r.join(" ")}`);let t=et("anvil",r,{stdio:["inherit","inherit","inherit"]});process.on("SIGINT",()=>{console.log(`
|
2
|
-
gracefully shutting down from SIGINT (Crtl-C)`),t.kill(),process.exit()}),await t}},ge=ot;import{FaucetServiceDefinition as tt}from"@latticexyz/services/faucet";import{createChannel as rt,createClient as nt}from"nice-grpc-web";import be from"chalk";import{NodeHttpTransport as st}from"@improbable-eng/grpc-web-node-http-transport";function it(e){return nt(tt,rt(e,st()))}var at={command:"faucet",describe:"Interact with a MUD faucet",builder(e){return e.options({dripDev:{type:"boolean",desc:"Request a drip from the dev endpoint (requires faucet to have dev mode enabled)",default:!0},faucetUrl:{type:"string",desc:"URL of the MUD faucet",default:"https://faucet.testnet-mud-services.linfra.xyz"},address:{type:"string",desc:"Ethereum address to fund",required:!0}})},async handler({dripDev:e,faucetUrl:o,address:r}){let t=it(o);e&&(console.log(be.yellow("Dripping to",r)),await t.dripDev({address:r}),console.log(be.yellow("Success"))),process.exit(0)}},he=at;var ct={command:"hello <name>",describe:"Greet <name> with Hello",builder(e){return e.options({upper:{type:"boolean"}}).positional("name",{type:"string",demandOption:!0})},handler({name:e}){let o=`Gm, ${e}!`;console.log(o),process.exit(0)}},we=ct;import dt from"path";import{loadConfig as lt}from"@latticexyz/config/node";import{tablegen as mt}from"@latticexyz/store/codegen";import{getRemappings as pt,getSrcDirectory as ft}from"@latticexyz/common/foundry";var yt={command:"tablegen",describe:"Autogenerate MUD Store table libraries based on the config file",builder(e){return e.options({configPath:{type:"string",desc:"Path to the config file"}})},async handler({configPath:e}){let o=await lt(e),r=await ft(),t=await pt();await mt(o,dt.join(r,o.codegenDirectory),t),process.exit(0)}},xe=yt;import de from"node:path";import{existsSync as sn,mkdirSync as an,readFileSync as cn,writeFileSync as le}from"node:fs";import{getAddress as lo}from"viem";import{getBytecode as bt,sendRawTransaction as ht,sendTransaction as wt,waitForTransactionReceipt as Se}from"viem/actions";var P={gasPrice:1e11,gasLimit:1e5,signerAddress:"3fab184622dc19b6109349b94811493bf2a45362",transaction:"f8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222",address:"4e59b44847b379578588920ca78fbf26c0b4956c"};var d=M.extend("deploy"),gt=M.extend("deploy");d.log=console.debug.bind(console);gt.log=console.error.bind(console);var S=`0x${P.address}`;async function Ce(e){if(await bt(e,{address:S})){d("found create2 deployer at",S);return}d("sending gas for create2 deployer to signer at",P.signerAddress);let r=await wt(e,{chain:e.chain??null,to:`0x${P.signerAddress}`,value:BigInt(P.gasLimit)*BigInt(P.gasPrice)}),t=await Se(e,{hash:r});if(t.status!=="success")throw console.error("failed to send gas to deployer signer",t),new Error("failed to send gas to deployer signer");d("deploying create2 deployer at",S);let n=await ht(e,{serializedTransaction:`0x${P.transaction}`}),s=await Se(e,{hash:n});if(s.contractAddress!==S)throw console.error("unexpected contract address for deployer",s),new Error("unexpected contract address for deployer")}import{waitForTransactionReceipt as Qt}from"viem/actions";import ke from"@latticexyz/world/out/AccessManagementSystem.sol/AccessManagementSystem.json"assert{type:"json"};import Ie from"@latticexyz/world/out/BalanceTransferSystem.sol/BalanceTransferSystem.json"assert{type:"json"};import Oe from"@latticexyz/world/out/BatchCallSystem.sol/BatchCallSystem.json"assert{type:"json"};import je from"@latticexyz/world/out/CoreRegistrationSystem.sol/CoreRegistrationSystem.json"assert{type:"json"};import Be from"@latticexyz/world/out/CoreModule.sol/CoreModule.json"assert{type:"json"};import Wt from"@latticexyz/world/out/CoreModule.sol/CoreModule.abi.json"assert{type:"json"};import Pe from"@latticexyz/world/out/WorldFactory.sol/WorldFactory.json"assert{type:"json"};import Rt from"@latticexyz/world/out/WorldFactory.sol/WorldFactory.abi.json"assert{type:"json"};import{getCreate2Address as W,encodeDeployData as R,size as $}from"viem";import{padHex as St}from"viem";import Ct from"@latticexyz/store/mud.config";import vt from"@latticexyz/world/mud.config";import Dt from"@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json"assert{type:"json"};import Tt from"@latticexyz/world-modules/out/IModule.sol/IModule.abi.json"assert{type:"json"};import{resourceToHex as xt}from"@latticexyz/common";import{resolveUserTypes as ve}from"@latticexyz/store";function z(e){let o={...e.userTypes,...Object.fromEntries(Object.entries(e.enums).map(([r])=>[r,{internalType:"uint8"}]))};return Object.fromEntries(Object.entries(e.tables).map(([r,t])=>[`${e.namespace}_${r}`,{namespace:e.namespace,name:t.name,tableId:xt({type:t.offchainOnly?"offchainTable":"table",namespace:e.namespace,name:t.name}),keySchema:ve(t.keySchema,o),valueSchema:ve(t.valueSchema,o)}]))}import{helloStoreEvent as At}from"@latticexyz/store";import{helloWorldEvent as kt}from"@latticexyz/world";var D=St("0x",{size:32}),U=parseInt("6000",16),F=z(Ct),T=z(vt),K=[At,kt],v=[...Dt,...Tt],De=["1.0.0-unaudited"],Te=["1.0.0-unaudited"];import{waitForTransactionReceipt as Ft}from"viem/actions";import{concatHex as It,getCreate2Address as Ot}from"viem";import{getBytecode as jt}from"viem/actions";import{sendTransaction as Bt}from"@latticexyz/common";import Pt from"p-retry";import{wait as Mt}from"@latticexyz/common/utils";async function Ae({client:e,bytecode:o,deployedBytecodeSize:r,label:t="contract"}){let n=Ot({from:S,salt:D,bytecode:o});return await jt(e,{address:n,blockTag:"pending"})?(d("found",t,"at",n),[]):(r>U?console.warn(`
|
3
|
-
Bytecode for ${t} (${r} bytes) is over the contract size limit (${U} bytes). Run \`forge build --sizes\` for more info.
|
4
|
-
`):r>U*.95&&console.warn(`
|
5
|
-
Bytecode for ${t} (${r} bytes) is almost over the contract size limit (${U} bytes). Run \`forge build --sizes\` for more info.
|
6
|
-
`),d("deploying",t,"at",n),[await Pt(()=>Bt(e,{chain:e.chain??null,to:S,data:It([D,o])}),{retries:3,onFailedAttempt:async c=>{let i=c.attemptNumber*500;d(`failed to deploy ${t}, retrying in ${i}ms...`),await Mt(i)}})])}async function O({client:e,contracts:o}){let r=(await Promise.all(o.map(t=>Ae({client:e,...t})))).flat();if(r.length){d("waiting for contracts");for(let t of r)await Ft(e,{hash:t})}return r}var $t=$(ke.deployedBytecode.object),Me=R({bytecode:ke.bytecode.object,abi:[]}),Ht=W({from:S,bytecode:Me,salt:D}),Et=$(Ie.deployedBytecode.object),Fe=R({bytecode:Ie.bytecode.object,abi:[]}),Nt=W({from:S,bytecode:Fe,salt:D}),zt=$(Oe.deployedBytecode.object),We=R({bytecode:Oe.bytecode.object,abi:[]}),Ut=W({from:S,bytecode:We,salt:D}),Vt=$(je.deployedBytecode.object),Re=R({bytecode:je.bytecode.object,abi:[]}),_t=W({from:S,bytecode:Re,salt:D}),Lt=$(Be.deployedBytecode.object),$e=R({bytecode:Be.bytecode.object,abi:Wt,args:[Ht,Nt,Ut,_t]}),Kt=W({from:S,bytecode:$e,salt:D}),Jt=$(Pe.deployedBytecode.object),He=R({bytecode:Pe.bytecode.object,abi:Rt,args:[Kt]}),Ee=W({from:S,bytecode:He,salt:D}),ee=[{bytecode:Me,deployedBytecodeSize:$t,label:"access management system"},{bytecode:Fe,deployedBytecodeSize:Et,label:"balance transfer system"},{bytecode:We,deployedBytecodeSize:zt,label:"batch call system"},{bytecode:Re,deployedBytecodeSize:Vt,label:"core registration system"},{bytecode:$e,deployedBytecodeSize:Lt,label:"core module"},{bytecode:He,deployedBytecodeSize:Jt,label:"world factory"}];async function Ne(e){return await O({client:e,contracts:ee})}import Xt from"@latticexyz/world/out/WorldFactory.sol/WorldFactory.abi.json"assert{type:"json"};import{writeContract as er}from"@latticexyz/common";import{AbiEventSignatureNotFoundError as qt,decodeEventLog as Gt,hexToString as ze,parseAbi as Yt,trim as Ue}from"viem";import{isDefined as Zt}from"@latticexyz/common/utils";function J(e){let o=e.map(c=>{try{return{...c,...Gt({strict:!0,abi:Yt(K),topics:c.topics,data:c.data})}}catch(i){if(i instanceof qt)return;throw i}}).filter(Zt),{address:r,deployBlock:t,worldVersion:n,storeVersion:s}=o.reduce((c,i)=>({...c,address:i.address,deployBlock:i.blockNumber,...i.eventName==="HelloWorld"?{worldVersion:ze(Ue(i.args.worldVersion,{dir:"right"}))}:null,...i.eventName==="HelloStore"?{storeVersion:ze(Ue(i.args.storeVersion,{dir:"right"}))}:null}),{});if(r==null)throw new Error("could not find world address");if(t==null)throw new Error("could not find world deploy block number");if(n==null)throw new Error("could not find world version");if(s==null)throw new Error("could not find store version");return{address:r,deployBlock:t,worldVersion:n,storeVersion:s}}async function Ve(e){await Ne(e),d("deploying world");let o=await er(e,{chain:e.chain??null,address:Ee,abi:Xt,functionName:"deployWorld"});d("waiting for world deploy");let r=await Qt(e,{hash:o});if(r.status!=="success")throw console.error("world deploy failed",r),new Error("world deploy failed");let t=J(r.logs.map(n=>n));return d("deployed world to",t.address,"at block",t.deployBlock),{...t,stateBlock:t.deployBlock}}import{writeContract as ar}from"@latticexyz/common";import{valueSchemaToFieldLayoutHex as cr,keySchemaToHex as dr,valueSchemaToHex as lr}from"@latticexyz/protocol-parser";function C({namespace:e,name:o}){return`${e}:${o}`}import{parseAbiItem as or,decodeAbiParameters as _e,parseAbiParameters as Le}from"viem";import{hexToResource as tr}from"@latticexyz/common";import{storeSetRecordEvent as rr}from"@latticexyz/store";import{getLogs as nr}from"viem/actions";import{decodeKey as sr,decodeValueArgs as ir,hexToSchema as Ke}from"@latticexyz/protocol-parser";async function Je({client:e,worldDeploy:o}){d("looking up tables for",o.address);let t=(await nr(e,{strict:!0,fromBlock:o.deployBlock,toBlock:o.stateBlock,address:o.address,event:or(rr),args:{tableId:F.store_Tables.tableId}})).map(n=>{let{tableId:s}=sr(F.store_Tables.keySchema,n.args.keyTuple),{namespace:c,name:i}=tr(s),p=ir(F.store_Tables.valueSchema,n.args),l=Ke(p.keySchema),f=Ke(p.valueSchema),y=_e(Le("string[]"),p.abiEncodedKeyNames)[0],m=_e(Le("string[]"),p.abiEncodedFieldNames)[0],u=[...f.staticFields,...f.dynamicFields],w=Object.fromEntries(l.staticFields.map((x,a)=>[y[a],x])),b=Object.fromEntries(u.map((x,a)=>[m[a],x]));return{namespace:c,name:i,tableId:s,keySchema:w,valueSchema:b}});return d("found",t.length,"tables for",o.address),t}import mr from"p-retry";import{wait as pr}from"@latticexyz/common/utils";async function qe({client:e,worldDeploy:o,tables:r}){let n=(await Je({client:e,worldDeploy:o})).map(i=>i.tableId),s=r.filter(i=>n.includes(i.tableId));s.length&&d("existing tables",s.map(C).join(", "));let c=r.filter(i=>!n.includes(i.tableId));return c.length?(d("registering tables",c.map(C).join(", ")),await Promise.all(c.map(i=>mr(()=>ar(e,{chain:e.chain??null,address:o.address,abi:v,functionName:"registerTable",args:[i.tableId,cr(i.valueSchema),dr(i.keySchema),lr(i.valueSchema),Object.keys(i.keySchema),Object.keys(i.valueSchema)]}),{retries:3,onFailedAttempt:async p=>{let l=p.attemptNumber*500;d(`failed to register table ${C(i)}, retrying in ${l}ms...`),await pr(l)}})))):[]}import{getAddress as A}from"viem";import{writeContract as oe}from"@latticexyz/common";import{parseAbiItem as fr}from"viem";import{getLogs as yr}from"viem/actions";import{storeSpliceStaticDataEvent as ur}from"@latticexyz/store";async function q({client:e,worldDeploy:o}){d("looking up resource IDs for",o.address);let t=(await yr(e,{strict:!0,address:o.address,fromBlock:o.deployBlock,toBlock:o.stateBlock,event:fr(ur),args:{tableId:F.store_ResourceIds.tableId}})).map(n=>n.args.keyTuple[0]);return d("found",t.length,"resource IDs for",o.address),t}import{hexToResource as jr}from"@latticexyz/common";import{decodeValueArgs as gr,encodeKey as br}from"@latticexyz/protocol-parser";import{readContract as hr}from"viem/actions";async function j({client:e,worldDeploy:o,table:r,key:t}){let[n,s,c]=await hr(e,{blockNumber:o.stateBlock,address:o.address,abi:v,functionName:"getRecord",args:[r.tableId,br(r.keySchema,t)]});return gr(r.valueSchema,{staticData:n,encodedLengths:s,dynamicData:c})}import{getFunctionSelector as wr,parseAbiItem as xr}from"viem";import{storeSetRecordEvent as Sr}from"@latticexyz/store";import{getLogs as Cr}from"viem/actions";import{decodeValueArgs as vr}from"@latticexyz/protocol-parser";import{hexToResource as Dr}from"@latticexyz/common";async function G({client:e,worldDeploy:o}){d("looking up function signatures for",o.address);let t=(await Cr(e,{strict:!0,fromBlock:o.deployBlock,toBlock:o.stateBlock,address:o.address,event:xr(Sr),args:{tableId:T.world_FunctionSignatures.tableId}})).map(s=>vr(T.world_FunctionSignatures.valueSchema,s.args).functionSignature);return d("found",t.length,"function signatures for",o.address),await Promise.all(t.map(async s=>{let c=wr(s),{systemId:i,systemFunctionSelector:p}=await j({client:e,worldDeploy:o,table:T.world_FunctionSelectors,key:{functionSelector:c}}),{namespace:l,name:f}=Dr(i),y=l===""?s:s.replace(`${l}_${f}_`,"");return{signature:s,selector:c,systemId:i,systemFunctionSignature:y,systemFunctionSelector:p}}))}import{parseAbiItem as Tr,getAddress as Ar}from"viem";import{storeSpliceStaticDataEvent as kr}from"@latticexyz/store";import{getLogs as Ir}from"viem/actions";import{decodeKey as Or}from"@latticexyz/protocol-parser";async function Y({client:e,worldDeploy:o}){d("looking up resource access for",o.address);let t=(await Ir(e,{strict:!0,fromBlock:o.deployBlock,toBlock:o.stateBlock,address:o.address,event:Tr(kr),args:{tableId:T.world_ResourceAccess.tableId}})).map(s=>Or(T.world_ResourceAccess.keySchema,s.args.keyTuple)),n=(await Promise.all(t.map(async s=>[s,await j({client:e,worldDeploy:o,table:T.world_ResourceAccess,key:s})]))).filter(([,s])=>s.access).map(([s])=>({resourceId:s.resourceId,address:Ar(s.caller)}));return d("found",n.length,"resource<>address access pairs"),n}async function Ge({client:e,worldDeploy:o}){let[r,t,n]=await Promise.all([q({client:e,worldDeploy:o}),G({client:e,worldDeploy:o}),Y({client:e,worldDeploy:o})]),s=r.map(jr).filter(c=>c.type==="system");return d("looking up systems",s.map(C).join(", ")),await Promise.all(s.map(async c=>{let{system:i,publicAccess:p}=await j({client:e,worldDeploy:o,table:T.world_Systems,key:{systemId:c.resourceId}}),l=t.filter(f=>f.systemId===c.resourceId);return{address:i,namespace:c.namespace,name:c.name,systemId:c.resourceId,allowAll:p,allowedAddresses:n.filter(({resourceId:f})=>f===c.resourceId).map(({address:f})=>f),functions:l}}))}import{uniqueBy as Br,wait as te}from"@latticexyz/common/utils";import re from"p-retry";async function Ye({client:e,worldDeploy:o,systems:r}){let[t,n]=await Promise.all([Ge({client:e,worldDeploy:o}),Y({client:e,worldDeploy:o})]),s=r.map(a=>a.systemId),c=n.filter(({resourceId:a})=>s.includes(a)),i=r.flatMap(a=>a.allowedAddresses.map(g=>({resourceId:a.systemId,address:g}))),p=i.filter(a=>!c.some(({resourceId:g,address:h})=>g===a.resourceId&&A(h)===A(a.address))),l=c.filter(a=>!i.some(({resourceId:g,address:h})=>g===a.resourceId&&A(h)===A(a.address)));l.length&&d("revoking",l.length,"access grants"),p.length&&d("adding",p.length,"access grants");let f=[...l.map(a=>re(()=>oe(e,{chain:e.chain??null,address:o.address,abi:v,functionName:"revokeAccess",args:[a.resourceId,a.address]}),{retries:3,onFailedAttempt:async g=>{let h=g.attemptNumber*500;d(`failed to revoke access, retrying in ${h}ms...`),await te(h)}})),...p.map(a=>re(()=>oe(e,{chain:e.chain??null,address:o.address,abi:v,functionName:"grantAccess",args:[a.resourceId,a.address]}),{retries:3,onFailedAttempt:async g=>{let h=g.attemptNumber*500;d(`failed to grant access, retrying in ${h}ms...`),await te(h)}}))],y=r.filter(a=>t.some(g=>g.systemId===a.systemId&&A(g.address)===A(a.address)));y.length&&d("existing systems",y.map(C).join(", "));let m=y.map(a=>a.systemId),u=r.filter(a=>!m.includes(a.systemId));if(!u.length)return[];let w=u.filter(a=>t.some(g=>g.systemId===a.systemId&&A(g.address)!==A(a.address)));w.length&&d("upgrading systems",w.map(C).join(", "));let b=u.filter(a=>!t.some(g=>g.systemId===a.systemId));b.length&&d("registering new systems",b.map(C).join(", ")),await O({client:e,contracts:Br(u,a=>A(a.address)).map(a=>({bytecode:a.bytecode,deployedBytecodeSize:a.deployedBytecodeSize,label:`${C(a)} system`}))});let x=u.map(a=>re(()=>oe(e,{chain:e.chain??null,address:o.address,abi:v,functionName:"registerSystem",args:[a.systemId,a.address,a.allowAll]}),{retries:3,onFailedAttempt:async g=>{let h=g.attemptNumber*500;d(`failed to register system ${C(a)}, retrying in ${h}ms...`),await te(h)}}));return await Promise.all([...f,...x])}import{waitForTransactionReceipt as mo}from"viem/actions";import{getAddress as Pr,parseAbi as Mr}from"viem";import{getBlockNumber as Fr,getLogs as Wr}from"viem/actions";var Ze=new Map;async function Qe(e,o){let r=Pr(o),t=Ze.get(r);if(t!=null)return t;d("looking up world deploy for",r);let n=await Fr(e),s=await Wr(e,{strict:!0,address:r,events:Mr(K),fromBlock:"earliest",toBlock:n});return t={...J(s),stateBlock:n},Ze.set(r,t),d("found world deploy for",r,"at block",t.deployBlock),t}import{hexToResource as Rr,writeContract as Xe}from"@latticexyz/common";import eo from"p-retry";import{wait as oo}from"@latticexyz/common/utils";async function to({client:e,worldDeploy:o,functions:r}){let t=await G({client:e,worldDeploy:o}),n=Object.fromEntries(t.map(i=>[i.selector,i])),s=r.filter(i=>n[i.selector]),c=r.filter(i=>!s.includes(i));if(s.length){d("functions already registered:",s.map(p=>p.signature).join(", "));let i=s.filter(p=>p.systemId!==n[p.selector]?.systemId);i.length&&console.warn("found",i.length,"functions already registered but pointing at a different system ID:",i.map(p=>p.signature).join(", "))}return c.length?(d("registering functions:",c.map(i=>i.signature).join(", ")),Promise.all(c.map(i=>{let{namespace:p}=Rr(i.systemId);return p===""?eo(()=>Xe(e,{chain:e.chain??null,address:o.address,abi:v,functionName:"registerRootFunctionSelector",args:[i.systemId,i.systemFunctionSignature,i.systemFunctionSelector]}),{retries:3,onFailedAttempt:async l=>{let f=l.attemptNumber*500;d(`failed to register function ${i.signature}, retrying in ${f}ms...`),await oo(f)}}):eo(()=>Xe(e,{chain:e.chain??null,address:o.address,abi:v,functionName:"registerFunctionSelector",args:[i.systemId,i.systemFunctionSignature]}),{retries:3,onFailedAttempt:async l=>{let f=l.attemptNumber*500;d(`failed to register function ${i.signature}, retrying in ${f}ms...`),await oo(f)}})}))):[]}import{BaseError as $r,getAddress as Hr}from"viem";import{writeContract as ro}from"@latticexyz/common";import{isDefined as Er,uniqueBy as Nr,wait as zr}from"@latticexyz/common/utils";import Ur from"p-retry";async function no({client:e,worldDeploy:o,modules:r}){return r.length?(await O({client:e,contracts:Nr(r,t=>Hr(t.address)).map(t=>({bytecode:t.bytecode,deployedBytecodeSize:t.deployedBytecodeSize,label:`${t.name} module`}))}),d("installing modules:",r.map(t=>t.name).join(", ")),(await Promise.all(r.map(t=>Ur(async()=>{try{return t.installAsRoot?await ro(e,{chain:e.chain??null,address:o.address,abi:v,functionName:"installRootModule",args:[t.address,t.installData]}):await ro(e,{chain:e.chain??null,address:o.address,abi:v,functionName:"installModule",args:[t.address,t.installData]})}catch(n){if(n instanceof $r&&n.message.includes("Module_AlreadyInstalled")){d(`module ${t.name} already installed`);return}throw n}},{retries:3,onFailedAttempt:async n=>{let s=n.attemptNumber*500;d(`failed to install module ${t.name}, retrying in ${s}ms...`),await zr(s)}})))).filter(Er)):[]}import{getAddress as so}from"viem";import{hexToResource as io,resourceToHex as ao,writeContract as Vr}from"@latticexyz/common";async function co({client:e,worldDeploy:o,resourceIds:r}){let t=Array.from(new Set(r.map(y=>io(y).namespace))),n=await q({client:e,worldDeploy:o}),s=new Set(n.map(y=>io(y).namespace));s.size&&d("found",s.size,"existing namespaces:",Array.from(s).map(y=>y===""?"<root>":y).join(", "));let c=t.filter(y=>s.has(y)),p=(await Promise.all(c.map(async y=>{let{owner:m}=await j({client:e,worldDeploy:o,table:T.world_NamespaceOwner,key:{namespaceId:ao({type:"namespace",namespace:y,name:""})}});return[y,m]}))).filter(([,y])=>so(y)!==so(e.account.address)).map(([y])=>y);if(p.length)throw new Error(`You are attempting to deploy to namespaces you do not own: ${p.join(", ")}`);let l=t.filter(y=>!s.has(y));return l.length>0&&d("registering namespaces",Array.from(l).join(", ")),Promise.all(l.map(y=>Vr(e,{chain:e.chain??null,address:o.address,abi:v,functionName:"registerNamespace",args:[ao({namespace:y,type:"namespace",name:""})]})))}import{uniqueBy as po}from"@latticexyz/common/utils";async function fo({client:e,config:o,worldAddress:r}){let t=Object.values(o.tables),n=Object.values(o.systems);await Ce(e),await O({client:e,contracts:[...ee,...po(n,m=>lo(m.address)).map(m=>({bytecode:m.bytecode,deployedBytecodeSize:m.deployedBytecodeSize,label:`${C(m)} system`})),...po(o.modules,m=>lo(m.address)).map(m=>({bytecode:m.bytecode,deployedBytecodeSize:m.deployedBytecodeSize,label:`${m.name} module`}))]});let s=r?await Qe(e,r):await Ve(e);if(!De.includes(s.storeVersion))throw new Error(`Unsupported Store version: ${s.storeVersion}`);if(!Te.includes(s.worldVersion))throw new Error(`Unsupported World version: ${s.worldVersion}`);let c=await co({client:e,worldDeploy:s,resourceIds:[...t.map(m=>m.tableId),...n.map(m=>m.systemId)]});d("waiting for all namespace registration transactions to confirm");for(let m of c)await mo(e,{hash:m});let i=await qe({client:e,worldDeploy:s,tables:t}),p=await Ye({client:e,worldDeploy:s,systems:n}),l=await to({client:e,worldDeploy:s,functions:n.flatMap(m=>m.functions)}),f=await no({client:e,worldDeploy:s,modules:o.modules}),y=[...i,...p,...l,...f];d("waiting for all transactions to confirm");for(let m of y)await mo(e,{hash:m});return d("deploy complete"),s}import{createWalletClient as dn,http as ln}from"viem";import{privateKeyToAccount as mn}from"viem/accounts";import{loadConfig as pn}from"@latticexyz/config/node";import{getOutDirectory as fn,getRpcUrl as yn,getSrcDirectory as un}from"@latticexyz/common/foundry";import H from"chalk";import{MUDError as gn}from"@latticexyz/common/errors";import{resolveWorldConfig as Jr}from"@latticexyz/world";import{resourceToHex as ce,hexToResource as qr}from"@latticexyz/common";import{resolveWithContext as Gr}from"@latticexyz/config";import{encodeField as Yr}from"@latticexyz/protocol-parser";import{getFunctionSelector as uo,getCreate2Address as go,getAddress as Zr,hexToBytes as Qr,bytesToHex as Xr,getFunctionSignature as bo}from"viem";import ne from"@latticexyz/world-modules/out/KeysWithValueModule.sol/KeysWithValueModule.json"assert{type:"json"};import se from"@latticexyz/world-modules/out/KeysInTableModule.sol/KeysInTableModule.json"assert{type:"json"};import ie from"@latticexyz/world-modules/out/UniqueEntityModule.sol/UniqueEntityModule.json"assert{type:"json"};import{size as ae}from"viem";var yo=[{name:"KeysWithValueModule",abi:ne.abi,bytecode:ne.bytecode.object,deployedBytecodeSize:ae(ne.deployedBytecode.object)},{name:"KeysInTableModule",abi:se.abi,bytecode:se.bytecode.object,deployedBytecodeSize:ae(se.deployedBytecode.object)},{name:"UniqueEntityModule",abi:ie.abi,bytecode:ie.bytecode.object,deployedBytecodeSize:ae(ie.deployedBytecode.object)}];import{readFileSync as _r}from"fs";import Lr from"path";import{MUDError as Z}from"@latticexyz/common/errors";import{size as Kr}from"viem";function Q(e,o){let r,t=Lr.join(o,e+".sol",e+".json");try{r=JSON.parse(_r(t,"utf8"))}catch{throw new Z(`Error reading file at ${t}`)}let n=r?.bytecode?.object;if(!n)throw new Z(`No bytecode found in ${t}`);let s=r?.deployedBytecode?.object;if(!s)throw new Z(`No deployed bytecode found in ${t}`);let c=r?.abi;if(!c)throw new Z(`No ABI found in ${t}`);return{abi:c,bytecode:n,deployedBytecodeSize:Kr(s)}}function ho({config:e,forgeSourceDir:o,forgeOutDir:r}){let t=z(e),n=I(o).map(({basename:m})=>m),s=Jr(e,n),i=Q("System",r).abi.filter(m=>m.type==="function").map(bo),p=Object.entries(s.systems).map(([m,u])=>{let w=e.namespace,b=u.name,x=ce({type:"system",namespace:w,name:b}),a=Q(m,r),g=a.abi.filter(h=>h.type==="function").map(bo).filter(h=>!i.includes(h)).map(h=>{let fe=w===""?h:`${w}_${b}_${h}`;return{signature:fe,selector:uo(fe),systemId:x,systemFunctionSignature:h,systemFunctionSelector:uo(h)}});return{namespace:w,name:b,systemId:x,allowAll:u.openAccess,allowedAddresses:u.accessListAddresses,allowedSystemIds:u.accessListSystems.map(h=>ce({type:"system",namespace:w,name:s.systems[h].name})),address:go({from:S,bytecode:a.bytecode,salt:D}),bytecode:a.bytecode,deployedBytecodeSize:a.deployedBytecodeSize,abi:a.abi,functions:g}}),l=p.map(({allowedAddresses:m,allowedSystemIds:u,...w})=>{let b=u.map(x=>{let a=p.find(g=>g.systemId===x);if(!a)throw new Error(`System ${C(w)} wanted access to ${C(qr(x))}, but it wasn't found in the config.`);return a.address});return{...w,allowedAddresses:Array.from(new Set([...m,...b].map(x=>Zr(x))))}}),f={tableIds:Object.fromEntries(Object.entries(e.tables).map(([m,u])=>[m,Qr(ce({type:u.offchainOnly?"offchainTable":"table",namespace:e.namespace,name:u.name}))]))},y=e.modules.map(m=>{let u=yo.find(b=>b.name===m.name)??Q(m.name,r),w=m.args.map(b=>Gr(b,f)).map(b=>{let x=b.value instanceof Uint8Array?Xr(b.value):b.value;return Yr(b.type,x)});if(w.length>1)throw new Error(`${m.name} module should only have 0-1 args, but had ${w.length} args.`);return{name:m.name,installAsRoot:m.root,installData:w.length===0?"0x":w[0],address:go({from:S,bytecode:u.bytecode,salt:D}),bytecode:u.bytecode,deployedBytecodeSize:u.deployedBytecodeSize,abi:u.abi}});return{tables:t,systems:l,modules:y}}import{getChainId as bn}from"viem/actions";import{existsSync as en}from"fs";import on from"path";import tn from"chalk";import{getScriptDirectory as rn,forge as nn}from"@latticexyz/common/foundry";async function wo(e,o,r,t){let n=on.join(await rn(),e+".s.sol");en(n)?(console.log(tn.blue(`Executing post deploy script at ${n}`)),await nn(["script",e,"--sig","run(address)",o,"--broadcast","--rpc-url",r,"-vvv"],{profile:t})):console.log(`No script at ${n}, skipping post deploy hook`)}var k={configPath:{type:"string",desc:"Path to the config file"},printConfig:{type:"boolean",desc:"Print the resolved config"},profile:{type:"string",desc:"The foundry profile to use"},saveDeployment:{type:"boolean",desc:"Save the deployment info to a file",default:!0},rpc:{type:"string",desc:"The RPC URL to use. Defaults to the RPC url from the local foundry.toml"},worldAddress:{type:"string",desc:"Deploy to an existing World at the given address"},srcDir:{type:"string",desc:"Source directory. Defaults to foundry src directory."},skipBuild:{type:"boolean",desc:"Skip rebuilding the contracts before deploying"},alwaysRunPostDeploy:{type:"boolean",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."}};async function E(e){let o=e.profile??process.env.FOUNDRY_PROFILE,r=await pn(e.configPath);e.printConfig&&console.log(H.green(`
|
7
|
-
Resolved config:
|
8
|
-
`),JSON.stringify(r,null,2));let t=e.srcDir??await un(o),n=await fn(o),s=e.rpc??await yn(o);console.log(H.bgBlue(H.whiteBright(`
|
9
|
-
Deploying MUD contracts${o?" with profile "+o:""} to RPC ${s}
|
10
|
-
`))),e.skipBuild||await L({config:r,srcDir:t,foundryProfile:o});let c=process.env.PRIVATE_KEY;if(!c)throw new gn(`Missing PRIVATE_KEY environment variable.
|
11
|
-
Run 'echo "PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" > .env'
|
12
|
-
in your contracts directory to use the default anvil private key.`);let i=ho({config:r,forgeSourceDir:t,forgeOutDir:n}),p=dn({transport:ln(s),account:mn(c)});console.log("Deploying from",p.account.address);let l=Date.now(),f=await fo({worldAddress:e.worldAddress,client:p,config:i});(e.worldAddress==null||e.alwaysRunPostDeploy)&&await wo(r.postDeployScript,f.address,s,o),console.log(H.green("Deployment completed in",(Date.now()-l)/1e3,"seconds"));let y={worldAddress:f.address,blockNumber:Number(f.deployBlock)};if(e.saveDeployment){let m=await bn(p),u=de.join(r.deploysDirectory,m.toString());an(u,{recursive:!0}),le(de.join(u,"latest.json"),JSON.stringify(y,null,2)),le(de.join(u,Date.now()+".json"),JSON.stringify(y,null,2));let w=[1337,31337],b=sn(r.worldsFile)?JSON.parse(cn(r.worldsFile,"utf-8")):{};b[m]={address:y.worldAddress,blockNumber:w.includes(m)?void 0:y.blockNumber},le(r.worldsFile,JSON.stringify(b,null,2)),console.log(H.bgGreen(H.whiteBright(`
|
13
|
-
Deployment result (written to ${r.worldsFile} and ${u}):
|
14
|
-
`)))}return console.log(y),f}var hn={command:"deploy",describe:"Deploy MUD contracts",builder(e){return e.options(k)},async handler(e){try{await E(e)}catch(o){_(o),process.exit(1)}process.exit(0)}},xo=hn;import{loadConfig as wn}from"@latticexyz/config/node";import{worldgen as xn}from"@latticexyz/world/node";import{getSrcDirectory as Sn}from"@latticexyz/common/foundry";import So from"path";import{rmSync as Cn}from"fs";var vn={command:"worldgen",describe:"Autogenerate interfaces for Systems and World based on existing contracts and the config file",builder(e){return e.options({configPath:{type:"string",desc:"Path to the config file"},clean:{type:"boolean",desc:"Clear the worldgen directory before generating new interfaces (defaults to true)",default:!0}})},async handler(e){await Dn(e),process.exit(0)}};async function Dn(e){let o=e.srcDir??await Sn(),r=I(o),t=e.config??await wn(e.configPath),n=So.join(o,t.codegenDirectory);e.clean&&Cn(So.join(n,t.worldgenDirectory),{recursive:!0,force:!0}),await xn(t,r,n)}var Co=vn;import V from"chalk";import{readFileSync as On,writeFileSync as jn}from"fs";import pe from"path";import{MUDError as N}from"@latticexyz/common/errors";var vo={name:"@latticexyz/cli",version:"2.0.0-next.16",description:"Command line interface for mud",repository:{type:"git",url:"https://github.com/latticexyz/mud.git",directory:"packages/cli"},license:"MIT",type:"module",exports:{".":"./dist/index.js"},types:"src/index.ts",bin:{mud:"./dist/mud.js"},scripts:{build:"pnpm run build:js && pnpm run build:test-tables","build:js":"tsup && chmod +x ./dist/mud.js","build:test-tables":"tsx ./scripts/generate-test-tables.ts",clean:"pnpm run clean:js && pnpm run clean:test-tables","clean:js":"rimraf dist","clean:test-tables":"rimraf src/codegen",dev:"tsup --watch",lint:"eslint . --ext .ts",prepare:"mkdir -p ./dist && touch ./dist/mud.js",test:"tsc --noEmit && forge test","test:ci":"pnpm run test"},dependencies:{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@improbable-eng/grpc-web-node-http-transport":"^0.15.0","@latticexyz/abi-ts":"workspace:*","@latticexyz/common":"workspace:*","@latticexyz/config":"workspace:*","@latticexyz/gas-report":"workspace:*","@latticexyz/protocol-parser":"workspace:*","@latticexyz/schema-type":"workspace:*","@latticexyz/services":"workspace:*","@latticexyz/store":"workspace:*","@latticexyz/utils":"workspace:*","@latticexyz/world":"workspace:*","@latticexyz/world-modules":"workspace:*",chalk:"^5.0.1",chokidar:"^3.5.3",debug:"^4.3.4",dotenv:"^16.0.3",ejs:"^3.1.8",ethers:"^5.7.2",execa:"^7.0.0",glob:"^8.0.3","nice-grpc-web":"^2.0.1",openurl:"^1.1.1","p-retry":"^5.1.2",path:"^0.12.7",rxjs:"7.5.5","throttle-debounce":"^5.0.0",typescript:"5.1.6",viem:"1.14.0",yargs:"^17.7.1",zod:"^3.21.4","zod-validation-error":"^1.3.0"},devDependencies:{"@types/debug":"^4.1.7","@types/ejs":"^3.1.1","@types/glob":"^7.2.0","@types/node":"^18.15.11","@types/openurl":"^1.0.0","@types/throttle-debounce":"^5.0.0","@types/yargs":"^17.0.10","ds-test":"https://github.com/dapphub/ds-test.git#e282159d5170298eb2455a6c05280ab5a73a4ef0","forge-std":"https://github.com/foundry-rs/forge-std.git#74cfb77e308dd188d2f58864aaf44963ae6b88b1",tsup:"^6.7.0",tsx:"^3.12.6",vitest:"0.31.4"},gitHead:"914a1e0ae4a573d685841ca2ea921435057deb8f"};import Bn from"glob";import{ZodError as An,z as Do}from"zod";var kn=Do.object({MUD_PACKAGES:Do.string().transform(e=>JSON.parse(e))});function In(){try{return kn.parse({MUD_PACKAGES:'{"@latticexyz/abi-ts":{"localPath":"packages/abi-ts"},"@latticexyz/block-logs-stream":{"localPath":"packages/block-logs-stream"},"@latticexyz/cli":{"localPath":"packages/cli"},"@latticexyz/common":{"localPath":"packages/common"},"@latticexyz/config":{"localPath":"packages/config"},"create-mud":{"localPath":"packages/create-mud"},"@latticexyz/dev-tools":{"localPath":"packages/dev-tools"},"@latticexyz/faucet":{"localPath":"packages/faucet"},"@latticexyz/gas-report":{"localPath":"packages/gas-report"},"@latticexyz/noise":{"localPath":"packages/noise"},"@latticexyz/phaserx":{"localPath":"packages/phaserx"},"@latticexyz/protocol-parser":{"localPath":"packages/protocol-parser"},"@latticexyz/react":{"localPath":"packages/react"},"@latticexyz/recs":{"localPath":"packages/recs"},"@latticexyz/schema-type":{"localPath":"packages/schema-type"},"@latticexyz/services":{"localPath":"packages/services"},"solhint-config-mud":{"localPath":"packages/solhint-config-mud"},"solhint-plugin-mud":{"localPath":"packages/solhint-plugin-mud"},"@latticexyz/store-indexer":{"localPath":"packages/store-indexer"},"@latticexyz/store-sync":{"localPath":"packages/store-sync"},"@latticexyz/store":{"localPath":"packages/store"},"@latticexyz/utils":{"localPath":"packages/utils"},"@latticexyz/world-modules":{"localPath":"packages/world-modules"},"@latticexyz/world":{"localPath":"packages/world"}}'})}catch(e){if(e instanceof An){let{_errors:o,...r}=e.format();console.error(`
|
15
|
-
Missing or invalid environment variables:
|
16
|
-
|
17
|
-
${Object.keys(r).join(`
|
18
|
-
`)}
|
19
|
-
`),process.exit(1)}throw e}}var me=In().MUD_PACKAGES;var Pn={command:"set-version",describe:"Set MUD version in all package.json files and optionally backup the previously installed version",builder(e){return e.options({mudVersion:{alias:"v",type:"string",description:"Set MUD to the given version"},tag:{alias:"t",type:"string",description:"Set MUD to the latest version with the given tag from npm"},commit:{alias:"c",type:"string",description:"Set MUD to the version based on a given git commit hash from npm"},link:{alias:"l",type:"string",description:"Relative path to the local MUD root directory to link"}})},async handler(e){try{let o=["mudVersion","link","tag","commit","restore"],r=o.reduce((n,s)=>e[s]?n+1:n,0);if(r===0)throw new N(`You need to provide one these options: ${o.join(", ")}`);if(r>1)throw new N(`These options are mutually exclusive: ${o.join(", ")}`);e.link||(e.mudVersion=await Mn(e));let t=Bn.sync("**/package.json").filter(n=>!n.includes("node_modules"));for(let n of t)Fn(n,e)}catch(o){_(o)}finally{process.exit(0)}}};async function Mn(e){e.mudVersion==="canary"&&(e.tag="main");let o;try{console.log(V.blue("Fetching available versions")),o=await(await fetch(`https://registry.npmjs.org/${vo.name}`)).json()}catch{throw new N("Could not fetch available MUD versions")}if(e.tag){let r=o["dist-tags"][e.tag];if(!r)throw new N(`Could not find npm version with tag "${e.tag}"`);return console.log(V.green(`Latest version with tag ${e.tag}: ${r}`)),r}if(e.commit){let r=e.commit.substring(0,8),t=Object.keys(o.versions).find(n=>n.includes(r));if(!t)throw new N(`Could not find npm version based on commit "${e.commit}"`);return console.log(V.green(`Version from commit ${e.commit}: ${t}`)),t}return e.mudVersion}function Fn(e,o){let{link:r}=o,{mudVersion:t}=o,n=Wn(e),s=Object.keys(me),c={};for(let l in n.dependencies)s.includes(l)&&(c[l]=n.dependencies[l]);let i={};for(let l in n.devDependencies)s.includes(l)&&(i[l]=n.devDependencies[l]);for(let l in n.dependencies)s.includes(l)&&(n.dependencies[l]=p(l,"dependencies"));for(let l in n.devDependencies)s.includes(l)&&(n.devDependencies[l]=p(l,"devDependencies"));return jn(e,JSON.stringify(n,null,2)+`
|
20
|
-
`),console.log(`Updating ${e}`),To(c,n.dependencies),To(i,n.devDependencies),n;function p(l,f){return r&&(t=Rn(e,r,l)),t||n[f][l]}}function Wn(e){try{let o=On(e,"utf8");return JSON.parse(o)}catch{throw new N("Could not read JSON at "+e)}}function To(e,o){for(let r in e)e[r]!==o[r]&&console.log(`${r}: ${V.red(e[r])} -> ${V.green(o[r])}`)}function Rn(e,o,r){let t=pe.relative(pe.dirname(e),process.cwd());return"link:"+pe.join(t,o,me[r].localPath)}var Ao=Pn;import{anvil as $n,forge as Hn,getRpcUrl as En}from"@latticexyz/common/foundry";import Nn from"chalk";var zn={...k,port:{type:"number",description:"Port to run internal node for fork testing on",default:4242},worldAddress:{type:"string",description:"Address of an existing world contract. If provided, deployment is skipped and the RPC provided in the foundry.toml is used for fork testing."},forgeOptions:{type:"string",description:"Options to pass to forge test"}},Un={command:"test",describe:"Run tests in MUD contracts",builder(e){return e.options(zn)},async handler(e){if(!e.worldAddress){let n=["--block-base-fee-per-gas","0","--port",String(e.port)];$n(n)}let o=e.worldAddress?await En(e.profile):`http://127.0.0.1:${e.port}`,r=e.worldAddress??(await E({...e,saveDeployment:!1,rpc:o})).address;console.log(Nn.blue("World address",r));let t=e.forgeOptions?.replaceAll("\\","").split(" ")??[];try{await Hn(["test","--fork-url",o,...t],{profile:e.profile,env:{WORLD_ADDRESS:r}}),process.exit(0)}catch(n){console.error(n),process.exit(1)}}},ko=Un;import{existsSync as Vn,readFileSync as _n}from"fs";import{ethers as Io}from"ethers";import{loadConfig as Ln}from"@latticexyz/config/node";import{MUDError as Oo}from"@latticexyz/common/errors";import{cast as Kn,getRpcUrl as Jn,getSrcDirectory as qn}from"@latticexyz/common/foundry";import{resolveWorldConfig as Gn}from"@latticexyz/world";import Yn from"@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json"assert{type:"json"};import jo from"@latticexyz/world/mud.config";import{resourceToHex as Po}from"@latticexyz/common";import{createClient as Zn,http as Qn}from"viem";import{getChainId as Xn}from"viem/actions";var Bo=Po({type:"system",namespace:jo.namespace,name:jo.tables.Systems.name}),es={command:"trace",describe:"Display the trace of a transaction",builder(e){return e.options({tx:{type:"string",required:!0,description:"Transaction hash to replay"},worldAddress:{type:"string",description:"World contract address. Defaults to the value from worlds.json, based on rpc's chainId"},configPath:{type:"string",description:"Path to the config file"},profile:{type:"string",description:"The foundry profile to use"},srcDir:{type:"string",description:"Source directory. Defaults to foundry src directory."},rpc:{type:"string",description:"json rpc endpoint. Defaults to foundry's configured eth_rpc_url"}})},async handler(e){e.profile??=process.env.FOUNDRY_PROFILE;let{profile:o}=e;e.srcDir??=await qn(o),e.rpc??=await Jn(o);let{tx:r,configPath:t,srcDir:n,rpc:s}=e,c=I(n),i=await Ln(t),p=Gn(i,c.map(({basename:a})=>a)),l=e.worldAddress??await os(i.worldsFile,s),f=new Io.providers.StaticJsonRpcProvider(s),y=new Io.Contract(l,Yn,f),m=i.namespace,u=Object.values(p.systems).map(({name:a})=>a),w=await y.getFieldLayout(Bo),b=[];for(let a of u){let g=Po({type:"system",namespace:m,name:a}),h=await y.getField(Bo,[g],0,w);b.push({name:a,address:h})}let x=await Kn(["run","--label",`${l}:World`,...b.map(({name:a,address:g})=>["--label",`${g}:${a}`]).flat(),`${r}`]);console.log(x),process.exit(0)}},Mo=es;async function os(e,o){if(Vn(e)){let r=Zn({transport:Qn(o)}),t=await Xn(r),n=JSON.parse(_n(e,"utf-8"));if(!n[t])throw new Oo(`chainId ${t} is missing in worldsFile "${e}"`);return n[t].address}else throw new Oo("worldAddress is not specified and worldsFile is missing")}import{anvil as ts,getScriptDirectory as rs,getSrcDirectory as ns}from"@latticexyz/common/foundry";import B from"chalk";import ss from"chokidar";import{loadConfig as is,resolveConfigPath as as}from"@latticexyz/config/node";import cs from"path";import{homedir as ds}from"os";import{rmSync as ls}from"fs";import{BehaviorSubject as ms,debounceTime as ps,exhaustMap as fs,filter as ys}from"rxjs";import{isDefined as us}from"@latticexyz/common/utils";var gs={rpc:k.rpc,configPath:k.configPath,alwaysRunPostDeploy:k.alwaysRunPostDeploy,worldAddress:k.worldAddress},bs={command:"dev-contracts",describe:"Start a development server for MUD contracts",builder(e){return e.options(gs)},async handler(e){let o=e.rpc,r=e.configPath??await as(e.configPath),t=await ns(),n=await rs(),s=await is(r);if(!e.rpc){console.log(B.gray("Cleaning devnode cache"));let l=ds();ls(cs.join(l,".foundry","anvil","tmp"),{recursive:!0,force:!0}),ts(["--block-time","1","--block-base-fee-per-gas","0"]),o="http://127.0.0.1:8545"}let c=new ms(Date.now());ss.watch([r,t,n],{ignoreInitial:!0}).on("all",async(l,f)=>{f.includes(r)&&(console.log(B.blue("Config changed, queuing deploy\u2026")),c.next(Date.now())),(f.includes(t)||f.includes(n))&&(f.includes(s.codegenDirectory)||(console.log(B.blue("Contracts changed, queuing deploy\u2026")),c.next(Date.now())))});let i=e.worldAddress;c.pipe(ps(200),fs(async l=>{i&&console.log(B.blue("Rebuilding and upgrading world\u2026"));try{let f=await E({...e,configPath:r,rpc:o,skipBuild:!1,printConfig:!1,profile:void 0,saveDeployment:!0,worldAddress:i,srcDir:t});return i=f.address,l<c.value?c.next(c.value):console.log(B.gray(`
|
21
|
-
Waiting for file changes\u2026
|
22
|
-
`)),f}catch(f){console.error(B.bgRed(B.whiteBright(`
|
23
|
-
Error while attempting deploy
|
24
|
-
`))),console.error(f),console.log(B.gray(`
|
25
|
-
Waiting for file changes\u2026
|
26
|
-
`))}}),ys(us)).subscribe()}},Fo=bs;var Pp=[ue,xo,ge,he,hs,we,xe,Co,Ao,ko,Mo,Fo,ws];export{Pp as commands};
|
27
|
-
//# sourceMappingURL=commands-DSIRJZEM.js.map
|