@latticexyz/cli 2.0.0-next.1 → 2.0.0-next.3
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-YDUX555R.js +11 -0
- package/dist/chunk-YDUX555R.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/mud.js +7 -7
- package/dist/mud.js.map +1 -1
- package/package.json +12 -11
- package/src/commands/dev-contracts.ts +0 -10
- package/src/commands/index.ts +0 -2
- package/src/commands/trace.ts +8 -4
- package/src/index.ts +0 -1
- package/src/utils/deploy.ts +14 -26
- package/dist/chunk-P7JIR52V.js +0 -32
- package/dist/chunk-P7JIR52V.js.map +0 -1
- package/src/commands/tsgen.ts +0 -34
- package/src/render-ts/index.ts +0 -5
- package/src/render-ts/recsV1TableOptions.ts +0 -57
- package/src/render-ts/renderRecsV1Tables.ts +0 -35
- package/src/render-ts/schemaTypesToRecsTypeStrings.ts +0 -202
- package/src/render-ts/tsgen.ts +0 -12
- package/src/render-ts/types.ts +0 -17
package/dist/mud.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/mud.ts","../src/commands/index.ts","../src/commands/devnode.ts","../src/commands/faucet.ts","../src/commands/hello.ts","../src/commands/tablegen.ts","../src/commands/tsgen.ts","../src/utils/errors.ts","../src/utils/printMUD.ts","../src/utils/worldtypes.ts","../src/commands/deploy.ts","../src/commands/worldgen.ts","../src/commands/set-version.ts","../package.json","../src/commands/test.ts","../src/commands/trace.ts","../src/commands/dev-contracts.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\nimport { commands } from \"./commands\";\nimport { logError } from \"./utils/errors\";\n\n// Load .env file into process.env\nimport * as dotenv from \"dotenv\";\nimport chalk from \"chalk\";\ndotenv.config();\n\nyargs(hideBin(process.argv))\n // Explicit name to display in help (by default it's the entry file, which may not be \"mud\" for e.g. ts-node)\n .scriptName(\"mud\")\n // Use the commands directory to scaffold\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- command array overload isn't typed, see https://github.com/yargs/yargs/blob/main/docs/advanced.md#esm-hierarchy\n .command(commands as any)\n // Enable strict mode.\n .strict()\n // Custom error handler\n .fail((msg, err) => {\n console.error(chalk.red(msg));\n if (msg.includes(\"Missing required argument\")) {\n console.log(\n chalk.yellow(`Run 'pnpm mud ${process.argv[2]} --help' for a list of available and required arguments.`)\n );\n }\n console.log(\"\");\n logError(err);\n console.log(\"\");\n\n process.exit(1);\n })\n // Useful aliases.\n .alias({ h: \"help\" }).argv;\n","import { CommandModule } from \"yargs\";\n\nimport gasReport from \"@latticexyz/gas-report\";\n\nimport devnode from \"./devnode\";\nimport faucet from \"./faucet\";\nimport hello from \"./hello\";\nimport tablegen from \"./tablegen\";\nimport tsgen from \"./tsgen\";\nimport deploy from \"./deploy\";\nimport worldgen from \"./worldgen\";\nimport setVersion from \"./set-version\";\nimport test from \"./test\";\nimport trace from \"./trace\";\nimport devContracts from \"./dev-contracts\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Each command has different options\nexport const commands: CommandModule<any, any>[] = [\n deploy,\n devnode,\n faucet,\n gasReport as CommandModule,\n hello,\n tablegen,\n tsgen,\n worldgen,\n setVersion,\n test,\n trace,\n devContracts,\n];\n","import { rmSync } from \"fs\";\nimport { homedir } from \"os\";\nimport path from \"path\";\nimport type { CommandModule } from \"yargs\";\nimport { execa } from \"execa\";\n\ntype Options = {\n blocktime: number;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"devnode\",\n\n describe: \"Start a local Ethereum node for development\",\n\n builder(yargs) {\n return yargs.options({\n blocktime: { type: \"number\", default: 1, decs: \"Interval in which new blocks are produced\" },\n });\n },\n\n async handler({ blocktime }) {\n console.log(\"Clearing devnode history\");\n const userHomeDir = homedir();\n rmSync(path.join(userHomeDir, \".foundry\", \"anvil\", \"tmp\"), { recursive: true, force: true });\n\n const anvilArgs = [\"-b\", String(blocktime), \"--block-base-fee-per-gas\", \"0\"];\n console.log(`Running: anvil ${anvilArgs.join(\" \")}`);\n const child = execa(\"anvil\", anvilArgs, {\n stdio: [\"inherit\", \"inherit\", \"inherit\"],\n });\n\n process.on(\"SIGINT\", () => {\n console.log(\"\\ngracefully shutting down from SIGINT (Crtl-C)\");\n child.kill();\n process.exit();\n });\n await child;\n },\n};\n\nexport default commandModule;\n","import type { CommandModule } from \"yargs\";\nimport { FaucetServiceDefinition } from \"@latticexyz/services/faucet\";\nimport { createChannel, createClient } from \"nice-grpc-web\";\nimport chalk from \"chalk\";\nimport { NodeHttpTransport } from \"@improbable-eng/grpc-web-node-http-transport\";\n\ntype Options = {\n dripDev?: boolean;\n faucetUrl: string;\n address: string;\n};\n\n/**\n * Create a FaucetServiceClient\n * @param url FaucetService URL\n * @returns FaucetServiceClient\n */\nfunction createFaucetService(url: string) {\n return createClient(FaucetServiceDefinition, createChannel(url, NodeHttpTransport()));\n}\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"faucet\",\n\n describe: \"Interact with a MUD faucet\",\n\n builder(yargs) {\n return yargs.options({\n dripDev: {\n type: \"boolean\",\n desc: \"Request a drip from the dev endpoint (requires faucet to have dev mode enabled)\",\n default: true,\n },\n faucetUrl: {\n type: \"string\",\n desc: \"URL of the MUD faucet\",\n default: \"https://faucet.testnet-mud-services.linfra.xyz\",\n },\n address: {\n type: \"string\",\n desc: \"Ethereum address to fund\",\n required: true,\n },\n });\n },\n\n async handler({ dripDev, faucetUrl, address }) {\n const faucet = createFaucetService(faucetUrl);\n\n if (dripDev) {\n console.log(chalk.yellow(\"Dripping to\", address));\n await faucet.dripDev({ address });\n console.log(chalk.yellow(\"Success\"));\n }\n\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","import type { CommandModule } from \"yargs\";\n\ntype Options = {\n name: string;\n upper: boolean | undefined;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"hello <name>\",\n\n describe: \"Greet <name> with Hello\",\n\n builder(yargs) {\n return yargs\n .options({\n upper: { type: \"boolean\" },\n })\n .positional(\"name\", { type: \"string\", demandOption: true });\n },\n\n handler({ name }) {\n const greeting = `Gm, ${name}!`;\n console.log(greeting);\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","import path from \"path\";\nimport type { CommandModule } from \"yargs\";\nimport { loadConfig } from \"@latticexyz/config/node\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { tablegen } from \"@latticexyz/store/codegen\";\nimport { getSrcDirectory } from \"@latticexyz/common/foundry\";\n\ntype Options = {\n configPath?: string;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"tablegen\",\n\n describe: \"Autogenerate MUD Store table libraries based on the config file\",\n\n builder(yargs) {\n return yargs.options({\n configPath: { type: \"string\", desc: \"Path to the config file\" },\n });\n },\n\n async handler({ configPath }) {\n const config = (await loadConfig(configPath)) as StoreConfig;\n const srcDir = await getSrcDirectory();\n\n await tablegen(config, path.join(srcDir, config.codegenDirectory));\n\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","import type { CommandModule } from \"yargs\";\nimport { loadConfig } from \"@latticexyz/config/node\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { tsgen } from \"../render-ts/tsgen\";\n\ntype Options = {\n configPath: string;\n out: string;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"tsgen\",\n\n describe: \"Autogenerate MUD typescript definitions based on the config file\",\n\n builder(yargs) {\n return yargs.options({\n configPath: { type: \"string\", demandOption: true, desc: \"Path to the config file\" },\n out: { type: \"string\", demandOption: true, desc: \"Directory to output MUD typescript definition files\" },\n });\n },\n\n async handler(args) {\n const { configPath, out } = args;\n\n const config = (await loadConfig(configPath)) as StoreConfig;\n\n await tsgen(config, out);\n\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","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","import chalk from \"chalk\";\n\nexport function printMUD() {\n console.log(\n chalk.yellow(`\n.------..------..------.\n|M.--. ||U.--. ||D.--. |\n| (\\\\/) || (\\\\/) || :/\\\\: |\n| :\\\\/: || :\\\\/: || (__) |\n| '--'M|| '--'U|| '--'D|\n'------''------''------'\n`)\n );\n}\n","import { getOutDirectory } from \"@latticexyz/common/foundry\";\nimport path from \"path\";\nimport { runTypeChain } from \"typechain\";\n\n/**\n * Generate IWorld typescript bindings\n */\nexport async function worldtypes() {\n const cwd = process.cwd();\n const forgeOurDir = await getOutDirectory();\n const IWorldPath = path.join(process.cwd(), forgeOurDir, \"IWorld.sol/IWorld.json\");\n\n await runTypeChain({\n cwd,\n filesToProcess: [IWorldPath],\n allFiles: [IWorldPath],\n target: \"ethers-v5\",\n });\n\n console.log(\"Typechain generated IWorld interface\");\n}\n","import type { CommandModule, Options } from \"yargs\";\nimport { logError } from \"../utils/errors\";\nimport { deployHandler, DeployOptions } from \"../utils\";\n\nexport const yDeployOptions = {\n configPath: { type: \"string\", desc: \"Path to the config file\" },\n clean: { type: \"boolean\", desc: \"Remove the build forge artifacts and cache directories before building\" },\n printConfig: { type: \"boolean\", desc: \"Print the resolved config\" },\n profile: { type: \"string\", desc: \"The foundry profile to use\" },\n debug: { type: \"boolean\", desc: \"Print debug logs, like full error messages\" },\n priorityFeeMultiplier: {\n type: \"number\",\n desc: \"Multiply the estimated priority fee by the provided factor\",\n default: 1,\n },\n saveDeployment: { type: \"boolean\", desc: \"Save the deployment info to a file\", default: true },\n rpc: { type: \"string\", desc: \"The RPC URL to use. Defaults to the RPC url from the local foundry.toml\" },\n worldAddress: { type: \"string\", desc: \"Deploy to an existing World at the given address\" },\n srcDir: { type: \"string\", desc: \"Source directory. Defaults to foundry src directory.\" },\n disableTxWait: { type: \"boolean\", desc: \"Disable waiting for transactions to be confirmed.\", default: false },\n pollInterval: {\n type: \"number\",\n desc: \"Interval in miliseconds to use to poll for transaction receipts / block inclusion\",\n default: 1000,\n },\n skipBuild: { type: \"boolean\", desc: \"Skip rebuilding the contracts before deploying\" },\n} satisfies Record<keyof DeployOptions, Options>;\n\nconst commandModule: CommandModule<DeployOptions, DeployOptions> = {\n command: \"deploy\",\n\n describe: \"Deploy MUD contracts\",\n\n builder(yargs) {\n return yargs.options(yDeployOptions);\n },\n\n async handler(args) {\n try {\n await deployHandler(args);\n } catch (error: any) {\n logError(error);\n process.exit(1);\n }\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","import type { CommandModule } from \"yargs\";\nimport { loadConfig } from \"@latticexyz/config/node\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { WorldConfig } from \"@latticexyz/world\";\nimport { worldgen } from \"@latticexyz/world/node\";\nimport { getSrcDirectory } from \"@latticexyz/common/foundry\";\nimport path from \"path\";\nimport { rmSync } from \"fs\";\nimport { getExistingContracts } from \"../utils\";\n\ntype Options = {\n configPath?: string;\n clean?: boolean;\n srcDir?: string;\n config?: StoreConfig & WorldConfig;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"worldgen\",\n\n describe: \"Autogenerate interfaces for Systems and World based on existing contracts and the config file\",\n\n builder(yargs) {\n return yargs.options({\n configPath: { type: \"string\", desc: \"Path to the config file\" },\n clean: {\n type: \"boolean\",\n desc: \"Clear the worldgen directory before generating new interfaces (defaults to true)\",\n default: true,\n },\n });\n },\n\n async handler(args) {\n await worldgenHandler(args);\n process.exit(0);\n },\n};\n\nexport async function worldgenHandler(args: Options) {\n const srcDir = args.srcDir ?? (await getSrcDirectory());\n\n const existingContracts = getExistingContracts(srcDir);\n\n // Load the config\n const mudConfig = args.config ?? ((await loadConfig(args.configPath)) as StoreConfig & WorldConfig);\n\n const outputBaseDirectory = path.join(srcDir, mudConfig.codegenDirectory);\n\n // clear the worldgen directory\n if (args.clean) rmSync(path.join(outputBaseDirectory, mudConfig.worldgenDirectory), { recursive: true, force: true });\n\n // generate new interfaces\n await worldgen(mudConfig, existingContracts, outputBaseDirectory);\n}\n\nexport default commandModule;\n","import chalk from \"chalk\";\nimport { existsSync, readFileSync, rmSync, writeFileSync } from \"fs\";\nimport path from \"path\";\nimport type { CommandModule } from \"yargs\";\nimport { MUDError } from \"@latticexyz/common/errors\";\nimport { logError } from \"../utils/errors\";\nimport localPackageJson from \"../../package.json\" assert { type: \"json\" };\nimport glob from \"glob\";\n\ntype Options = {\n backup?: boolean;\n force?: boolean;\n restore?: boolean;\n mudVersion?: string;\n tag?: string;\n commit?: string;\n link?: string;\n};\n\nconst BACKUP_FILE = \".mudbackup\";\nconst MUD_PREFIX = \"@latticexyz\";\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"set-version\",\n\n describe: \"Set MUD version in all package.json files and optionally backup the previously installed version\",\n\n builder(yargs) {\n return yargs.options({\n backup: { type: \"boolean\", description: `Back up the current MUD versions to \"${BACKUP_FILE}\"` },\n force: {\n type: \"boolean\",\n description: `Backup fails if a \"${BACKUP_FILE}\" file is found, unless --force is provided`,\n },\n restore: { type: \"boolean\", description: `Restore the previous MUD versions from \"${BACKUP_FILE}\"` },\n mudVersion: { alias: \"v\", type: \"string\", description: \"Set MUD to the given version\" },\n tag: {\n alias: \"t\",\n type: \"string\",\n description: \"Set MUD to the latest version with the given tag from npm\",\n },\n commit: {\n alias: \"c\",\n type: \"string\",\n description: \"Set MUD to the version based on a given git commit hash from npm\",\n },\n link: { alias: \"l\", type: \"string\", description: \"Relative path to the local MUD root directory to link\" },\n });\n },\n\n async handler(options) {\n try {\n const mutuallyExclusiveOptions = [\"mudVersion\", \"link\", \"tag\", \"commit\", \"restore\"];\n const numMutuallyExclusiveOptions = mutuallyExclusiveOptions.reduce(\n (acc, opt) => (options[opt] ? acc + 1 : acc),\n 0\n );\n\n if (numMutuallyExclusiveOptions === 0) {\n throw new MUDError(`You need to provide one these options: ${mutuallyExclusiveOptions.join(\", \")}`);\n }\n\n if (numMutuallyExclusiveOptions > 1) {\n throw new MUDError(`These options are mutually exclusive: ${mutuallyExclusiveOptions.join(\", \")}`);\n }\n\n // Resolve the version number from available options like `tag` or `commit`\n options.mudVersion = await resolveVersion(options);\n\n // Update all package.json below the current working directory (except in node_modules)\n const packageJsons = glob.sync(\"**/package.json\").filter((p) => !p.includes(\"node_modules\"));\n for (const packageJson of packageJsons) {\n updatePackageJson(packageJson, options);\n }\n } catch (e) {\n logError(e);\n } finally {\n process.exit(0);\n }\n },\n};\n\nasync function resolveVersion(options: Options) {\n // Backwards compatibility to previous behavior of this script where passing \"canary\" as the version resolved to the latest commit on main\n if (options.mudVersion === \"canary\") options.tag = \"main\";\n\n let npmResult;\n try {\n console.log(chalk.blue(`Fetching available versions`));\n npmResult = await (await fetch(`https://registry.npmjs.org/${localPackageJson.name}`)).json();\n } catch (e) {\n throw new MUDError(`Could not fetch available MUD versions`);\n }\n\n if (options.tag) {\n const version = npmResult[\"dist-tags\"][options.tag];\n if (!version) {\n throw new MUDError(`Could not find npm version with tag \"${options.tag}\"`);\n }\n console.log(chalk.green(`Latest version with tag ${options.tag}: ${version}`));\n return version;\n }\n\n if (options.commit) {\n // Find a version with this commit hash\n const commit = options.commit.substring(0, 8); // changesets uses the first 8 characters of the commit hash as version for prereleases/snapshot releases\n const version = Object.keys(npmResult[\"versions\"]).find((v) => (v as string).includes(commit));\n if (!version) {\n throw new MUDError(`Could not find npm version based on commit \"${options.commit}\"`);\n }\n console.log(chalk.green(`Version from commit ${options.commit}: ${version}`));\n return version;\n }\n\n // If neither a tag nor a commit option is given, return the `mudVersion`\n return options.mudVersion;\n}\n\nfunction updatePackageJson(filePath: string, options: Options): { workspaces?: string[] } {\n const { restore, force, link } = options;\n let { backup, mudVersion } = options;\n\n const backupFilePath = path.join(path.dirname(filePath), BACKUP_FILE);\n const backupFileExists = existsSync(backupFilePath);\n\n // Create a backup file for previous MUD versions by default if linking to local MUD\n if (link && !backupFileExists) backup = true;\n\n // If `backup` is true and force not set, check if a backup file already exists and throw an error if it does\n if (backup && !force && backupFileExists) {\n throw new MUDError(\n `A backup file already exists at ${backupFilePath}.\\nUse --force to overwrite it or --restore to restore it.`\n );\n }\n\n const packageJson = readPackageJson(filePath);\n\n // Load .mudbackup if `restore` is true\n const backupJson = restore ? readPackageJson(backupFilePath) : undefined;\n\n // Find all MUD dependencies\n const mudDependencies: Record<string, string> = {};\n for (const key in packageJson.dependencies) {\n if (key.startsWith(MUD_PREFIX)) {\n mudDependencies[key] = packageJson.dependencies[key];\n }\n }\n\n // Find all MUD devDependencies\n const mudDevDependencies: Record<string, string> = {};\n for (const key in packageJson.devDependencies) {\n if (key.startsWith(MUD_PREFIX)) {\n mudDevDependencies[key] = packageJson.devDependencies[key];\n }\n }\n\n // Back up the current dependencies if `backup` is true\n if (backup) {\n writeFileSync(\n backupFilePath,\n JSON.stringify({ dependencies: mudDependencies, devDependencies: mudDevDependencies }, null, 2)\n );\n console.log(chalk.green(`Backed up MUD dependencies from ${filePath} to ${backupFilePath}`));\n }\n\n // Update the dependencies\n for (const key in packageJson.dependencies) {\n if (key.startsWith(MUD_PREFIX)) {\n packageJson.dependencies[key] = resolveMudVersion(key, \"dependencies\");\n }\n }\n\n // Update the devDependencies\n for (const key in packageJson.devDependencies) {\n if (key.startsWith(MUD_PREFIX)) {\n packageJson.devDependencies[key] = resolveMudVersion(key, \"devDependencies\");\n }\n }\n\n // Write the updated package.json\n writeFileSync(filePath, JSON.stringify(packageJson, null, 2) + \"\\n\");\n\n console.log(`Updating ${filePath}`);\n logComparison(mudDependencies, packageJson.dependencies);\n logComparison(mudDevDependencies, packageJson.devDependencies);\n\n // Remove the backup file if `restore` is true and `backup` is false\n // because the old backup file is no longer needed\n if (restore && !backup) {\n rmSync(backupFilePath);\n console.log(chalk.green(`Cleaned up ${backupFilePath}`));\n }\n\n return packageJson;\n\n function resolveMudVersion(key: string, type: \"dependencies\" | \"devDependencies\") {\n if (restore && backupJson) return backupJson[type][key];\n if (link) mudVersion = resolveLinkPath(filePath, link, key);\n if (!mudVersion) return packageJson[type][key];\n return mudVersion;\n }\n}\n\nfunction readPackageJson(path: string): {\n workspaces?: string[];\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n} {\n try {\n const jsonString = readFileSync(path, \"utf8\");\n return JSON.parse(jsonString);\n } catch {\n throw new MUDError(\"Could not read JSON at \" + path);\n }\n}\n\nfunction logComparison(prev: Record<string, string>, curr: Record<string, string>) {\n for (const key in prev) {\n if (prev[key] !== curr[key]) {\n console.log(`${key}: ${chalk.red(prev[key])} -> ${chalk.green(curr[key])}`);\n }\n }\n}\n\n/**\n * Returns path of the package to link, given a path to a local MUD clone and a package\n */\nfunction resolveLinkPath(packageJsonPath: string, mudLinkPath: string, pkg: string) {\n const pkgName = pkg.replace(MUD_PREFIX, \"\");\n const packageJsonToRootPath = path.relative(path.dirname(packageJsonPath), process.cwd());\n const linkPath = path.join(packageJsonToRootPath, mudLinkPath, \"packages\", pkgName);\n return \"link:\" + linkPath;\n}\n\nexport default commandModule;\n","{\n \"name\": \"@latticexyz/cli\",\n \"version\": \"2.0.0-next.1\",\n \"description\": \"Command line interface for mud\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/latticexyz/mud.git\",\n \"directory\": \"packages/cli\"\n },\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"exports\": {\n \".\": \"./dist/index.js\"\n },\n \"types\": \"src/index.ts\",\n \"bin\": {\n \"mud\": \"./dist/mud.js\"\n },\n \"scripts\": {\n \"build\": \"pnpm run build:js && pnpm run build:test-tables\",\n \"build:js\": \"tsup && chmod +x ./dist/mud.js\",\n \"build:test-tables\": \"tsx ./scripts/generate-test-tables.ts\",\n \"clean\": \"pnpm run clean:js\",\n \"clean:js\": \"rimraf dist\",\n \"dev\": \"tsup --watch\",\n \"lint\": \"eslint . --ext .ts\",\n \"test\": \"tsc --noEmit && forge test\"\n },\n \"dependencies\": {\n \"@ethersproject/abi\": \"^5.7.0\",\n \"@ethersproject/providers\": \"^5.7.2\",\n \"@improbable-eng/grpc-web\": \"^0.15.0\",\n \"@improbable-eng/grpc-web-node-http-transport\": \"^0.15.0\",\n \"@latticexyz/common\": \"workspace:*\",\n \"@latticexyz/config\": \"workspace:*\",\n \"@latticexyz/gas-report\": \"workspace:*\",\n \"@latticexyz/schema-type\": \"workspace:*\",\n \"@latticexyz/services\": \"workspace:*\",\n \"@latticexyz/solecs\": \"workspace:*\",\n \"@latticexyz/std-contracts\": \"workspace:*\",\n \"@latticexyz/store\": \"workspace:*\",\n \"@latticexyz/utils\": \"workspace:*\",\n \"@latticexyz/world\": \"workspace:*\",\n \"@typechain/ethers-v5\": \"^10.2.0\",\n \"chalk\": \"^5.0.1\",\n \"chokidar\": \"^3.5.3\",\n \"dotenv\": \"^16.0.3\",\n \"ejs\": \"^3.1.8\",\n \"ethers\": \"^5.7.2\",\n \"execa\": \"^7.0.0\",\n \"glob\": \"^8.0.3\",\n \"nice-grpc-web\": \"^2.0.1\",\n \"openurl\": \"^1.1.1\",\n \"path\": \"^0.12.7\",\n \"throttle-debounce\": \"^5.0.0\",\n \"typechain\": \"^8.1.1\",\n \"typescript\": \"5.1.6\",\n \"yargs\": \"^17.7.1\",\n \"zod\": \"^3.21.4\",\n \"zod-validation-error\": \"^1.3.0\"\n },\n \"devDependencies\": {\n \"@types/ejs\": \"^3.1.1\",\n \"@types/glob\": \"^7.2.0\",\n \"@types/node\": \"^18.15.11\",\n \"@types/openurl\": \"^1.0.0\",\n \"@types/throttle-debounce\": \"^5.0.0\",\n \"@types/yargs\": \"^17.0.10\",\n \"ds-test\": \"https://github.com/dapphub/ds-test.git#e282159d5170298eb2455a6c05280ab5a73a4ef0\",\n \"forge-std\": \"https://github.com/foundry-rs/forge-std.git#74cfb77e308dd188d2f58864aaf44963ae6b88b1\",\n \"tsup\": \"^6.7.0\",\n \"tsx\": \"^3.12.6\",\n \"vitest\": \"0.31.4\"\n },\n \"gitHead\": \"914a1e0ae4a573d685841ca2ea921435057deb8f\"\n}\n","import type { CommandModule } from \"yargs\";\nimport { anvil, forge, getRpcUrl } from \"@latticexyz/common/foundry\";\nimport chalk from \"chalk\";\nimport { rmSync, writeFileSync } from \"fs\";\nimport { yDeployOptions } from \"./deploy\";\nimport { deployHandler, DeployOptions } from \"../utils\";\n\ntype Options = DeployOptions & { port?: number; worldAddress?: string; forgeOptions?: string };\n\nconst WORLD_ADDRESS_FILE = \".mudtest\";\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"test\",\n\n describe: \"Run tests in MUD contracts\",\n\n builder(yargs) {\n return yargs.options({\n ...yDeployOptions,\n port: { type: \"number\", description: \"Port to run internal node for fork testing on\", default: 4242 },\n worldAddress: {\n type: \"string\",\n description:\n \"Address of an existing world contract. If provided, deployment is skipped and the RPC provided in the foundry.toml is used for fork testing.\",\n },\n forgeOptions: { type: \"string\", description: \"Options to pass to forge test\" },\n });\n },\n\n async handler(args) {\n // Start an internal anvil process if no world address is provided\n if (!args.worldAddress) {\n const anvilArgs = [\"--block-base-fee-per-gas\", \"0\", \"--port\", String(args.port)];\n anvil(anvilArgs);\n }\n\n const forkRpc = args.worldAddress ? await getRpcUrl(args.profile) : `http://127.0.0.1:${args.port}`;\n\n const worldAddress =\n args.worldAddress ??\n (\n await deployHandler({\n ...args,\n saveDeployment: false,\n rpc: forkRpc,\n })\n ).worldAddress;\n\n console.log(chalk.blue(\"World address\", worldAddress));\n\n // Create a temporary file to pass the world address to the tests\n writeFileSync(WORLD_ADDRESS_FILE, worldAddress);\n\n const userOptions = args.forgeOptions?.replaceAll(\"\\\\\", \"\").split(\" \") ?? [];\n try {\n const testResult = await forge([\"test\", \"--fork-url\", forkRpc, ...userOptions], {\n profile: args.profile,\n });\n console.log(testResult);\n } catch (e) {\n console.error(e);\n }\n\n rmSync(WORLD_ADDRESS_FILE);\n\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","import { existsSync, readFileSync } from \"fs\";\nimport type { CommandModule } from \"yargs\";\nimport { ethers } from \"ethers\";\n\nimport { loadConfig } from \"@latticexyz/config/node\";\nimport { MUDError } from \"@latticexyz/common/errors\";\nimport { cast, getRpcUrl, getSrcDirectory } from \"@latticexyz/common/foundry\";\nimport { TableId } from \"@latticexyz/common/deprecated\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { resolveWorldConfig, WorldConfig } from \"@latticexyz/world\";\nimport { IBaseWorld } from \"@latticexyz/world/types/ethers-contracts/IBaseWorld\";\nimport IBaseWorldData from \"@latticexyz/world/abi/IBaseWorld.sol/IBaseWorld.json\" assert { type: \"json\" };\nimport { getChainId, getExistingContracts } from \"../utils\";\n\nconst systemsTableId = new TableId(\"\", \"Systems\");\n\ntype Options = {\n tx: string;\n worldAddress?: string;\n configPath?: string;\n profile?: string;\n srcDir?: string;\n rpc?: string;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"trace\",\n\n describe: \"Display the trace of a transaction\",\n\n builder(yargs) {\n return yargs.options({\n tx: { type: \"string\", required: true, description: \"Transaction hash to replay\" },\n worldAddress: {\n type: \"string\",\n description: \"World contract address. Defaults to the value from worlds.json, based on rpc's chainId\",\n },\n configPath: { type: \"string\", description: \"Path to the config file\" },\n profile: { type: \"string\", description: \"The foundry profile to use\" },\n srcDir: { type: \"string\", description: \"Source directory. Defaults to foundry src directory.\" },\n rpc: { type: \"string\", description: \"json rpc endpoint. Defaults to foundry's configured eth_rpc_url\" },\n });\n },\n\n async handler(args) {\n args.profile ??= process.env.FOUNDRY_PROFILE;\n const { profile } = args;\n args.srcDir ??= await getSrcDirectory(profile);\n args.rpc ??= await getRpcUrl(profile);\n const { tx, configPath, srcDir, rpc } = args;\n\n const existingContracts = getExistingContracts(srcDir);\n\n // Load the config\n const mudConfig = (await loadConfig(configPath)) as StoreConfig & WorldConfig;\n\n const resolvedConfig = resolveWorldConfig(\n mudConfig,\n existingContracts.map(({ basename }) => basename)\n );\n\n // Get worldAddress either from args or from worldsFile\n const worldAddress = args.worldAddress ?? (await getWorldAddress(mudConfig.worldsFile, rpc));\n\n // Create World contract instance from deployed address\n const provider = new ethers.providers.StaticJsonRpcProvider(rpc);\n const WorldContract = new ethers.Contract(worldAddress, IBaseWorldData.abi, provider) as IBaseWorld;\n\n // TODO account for multiple namespaces (https://github.com/latticexyz/mud/issues/994)\n const namespace = mudConfig.namespace;\n const names = Object.values(resolvedConfig.systems).map(({ name }) => name);\n\n const labels: { name: string; address: string }[] = [];\n for (const name of names) {\n const systemSelector = new TableId(namespace, name);\n // Get the first field of `Systems` table (the table maps system name to its address and other data)\n const address = await WorldContract.getField(systemsTableId.toHex(), [systemSelector.toHex()], 0);\n labels.push({ name, address });\n }\n\n const result = await cast([\n \"run\",\n \"--label\",\n `${worldAddress}:World`,\n ...labels.map(({ name, address }) => [\"--label\", `${address}:${name}`]).flat(),\n `${tx}`,\n ]);\n console.log(result);\n\n process.exit(0);\n },\n};\n\nexport default commandModule;\n\nasync function getWorldAddress(worldsFile: string, rpc: string) {\n if (existsSync(worldsFile)) {\n const chainId = await getChainId(rpc);\n const deploys = JSON.parse(readFileSync(worldsFile, \"utf-8\"));\n\n if (!deploys[chainId]) {\n throw new MUDError(`chainId ${chainId} is missing in worldsFile \"${worldsFile}\"`);\n }\n return deploys[chainId].address as string;\n } else {\n throw new MUDError(\"worldAddress is not specified and worldsFile is missing\");\n }\n}\n","import type { CommandModule } from \"yargs\";\nimport { anvil, forge, getRpcUrl, getScriptDirectory, getSrcDirectory } from \"@latticexyz/common/foundry\";\nimport chalk from \"chalk\";\nimport chokidar from \"chokidar\";\nimport { loadConfig, resolveConfigPath } from \"@latticexyz/config/node\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { tablegen } from \"@latticexyz/store/codegen\";\nimport path from \"path\";\nimport { tsgen } from \"../render-ts\";\nimport { debounce } from \"throttle-debounce\";\nimport { worldgenHandler } from \"./worldgen\";\nimport { WorldConfig } from \"@latticexyz/world\";\nimport { deployHandler, logError, printMUD, worldtypes } from \"../utils\";\nimport { homedir } from \"os\";\nimport { rmSync } from \"fs\";\n\ntype Options = {\n rpc?: string;\n configPath?: string;\n tsgenOutput: string;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"dev-contracts\",\n\n describe: \"Start a development server for MUD contracts\",\n\n builder(yargs) {\n return yargs.options({\n rpc: {\n type: \"string\",\n decs: \"RPC endpoint of the development node. If none is provided, an anvil instance is spawned in the background on port 8545.\",\n },\n configPath: {\n type: \"string\",\n decs: \"Path to MUD config\",\n },\n tsgenOutput: { type: \"string\", demandOption: true, desc: \"Directory to output MUD typescript definition files\" },\n });\n },\n\n async handler(args) {\n if (!args.tsgenOutputDir) {\n console.error(\"No output provided\");\n }\n\n // Initial cleanup\n await forge([\"clean\"]);\n\n const rpc = args.rpc ?? (await getRpcUrl());\n const configPath = args.configPath ?? (await resolveConfigPath(args.configPath));\n const srcDirectory = await getSrcDirectory();\n const scriptDirectory = await getScriptDirectory();\n const initialConfig = (await loadConfig(configPath)) as StoreConfig & WorldConfig;\n\n // Initial run of all codegen steps before starting anvil\n // (so clients can wait for everything to be ready before starting)\n await handleConfigChange(initialConfig);\n await handleContractsChange(initialConfig);\n\n // Start an anvil instance in the background if no RPC url is provided\n if (!args.rpc) {\n console.log(chalk.gray(\"Cleaning devnode cache\"));\n const userHomeDir = homedir();\n rmSync(path.join(userHomeDir, \".foundry\", \"anvil\", \"tmp\"), { recursive: true, force: true });\n\n const anvilArgs = [\"--block-time\", \"1\", \"--block-base-fee-per-gas\", \"0\"];\n anvil(anvilArgs);\n }\n\n const changedSinceLastHandled = {\n config: false,\n contracts: false,\n };\n\n const changeInProgress = {\n current: false,\n };\n\n // Watch for changes\n const configWatcher = chokidar.watch([configPath, srcDirectory]);\n configWatcher.on(\"all\", async (_, updatePath) => {\n if (updatePath.includes(configPath)) {\n changedSinceLastHandled.config = true;\n // We trigger contract changes if the config changed here instead of\n // listening to changes in the codegen directory to avoid an infinite loop\n changedSinceLastHandled.contracts = true;\n }\n\n if (updatePath.includes(srcDirectory) || updatePath.includes(scriptDirectory)) {\n // Ignore changes to codegen files to avoid an infinite loop\n if (updatePath.includes(initialConfig.codegenDirectory)) return;\n changedSinceLastHandled.contracts = true;\n }\n\n // Trigger debounced onChange\n handleChange();\n });\n\n const handleChange = debounce(100, async () => {\n // Avoid handling changes multiple times in parallel\n if (changeInProgress.current) return;\n changeInProgress.current = true;\n\n // Reset dirty flags\n const { config, contracts } = changedSinceLastHandled;\n changedSinceLastHandled.config = false;\n changedSinceLastHandled.contracts = false;\n\n try {\n // Load latest config\n const mudConfig = (await loadConfig(configPath)) as StoreConfig & WorldConfig;\n\n // Handle changes\n if (config) await handleConfigChange(mudConfig);\n if (contracts) await handleContractsChange(mudConfig);\n\n await deploy();\n } catch (error) {\n console.error(chalk.red(\"MUD dev-contracts watcher failed to deploy config or contracts changes\\n\"));\n logError(error);\n }\n\n changeInProgress.current = false;\n if (changedSinceLastHandled.config || changedSinceLastHandled.contracts) {\n console.log(\"Detected change while handling the previous change\");\n handleChange();\n }\n\n printMUD();\n console.log(\"MUD watching for changes...\");\n });\n\n /** Codegen to run if config changes */\n async function handleConfigChange(config: StoreConfig & WorldConfig) {\n console.log(chalk.blue(\"mud.config.ts changed - regenerating tables and recs types\"));\n // Run tablegen to generate tables based on the config\n const outPath = path.join(srcDirectory, config.codegenDirectory);\n await tablegen(config, outPath);\n\n // Run tsgen to regenerate recs types based on the mud config\n await tsgen(config, args.tsgenOutput);\n }\n\n /** Codegen to run if contracts changed */\n async function handleContractsChange(config: StoreConfig & WorldConfig) {\n console.log(chalk.blue(\"contracts changed - regenerating interfaces and contract types\"));\n\n // Run worldgen to generate interfaces based on the systems\n await worldgenHandler({ config, clean: true, srcDir: srcDirectory });\n\n // Build the contracts\n await forge([\"build\"]);\n\n // Run typechain to rebuild typescript types for the contracts\n await worldtypes();\n }\n\n /** Run after codegen if either mud config or contracts changed */\n async function deploy() {\n console.log(chalk.blue(\"redeploying World\"));\n await deployHandler({\n configPath,\n skipBuild: true,\n priorityFeeMultiplier: 1,\n disableTxWait: true,\n pollInterval: 1000,\n saveDeployment: true,\n srcDir: srcDirectory,\n rpc,\n });\n }\n },\n};\n\nexport default commandModule;\n"],"mappings":"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","names":["yargs","hideBin","gasReport","rmSync","homedir","path","execa","commandModule","yargs","blocktime","userHomeDir","anvilArgs","child","devnode_default","FaucetServiceDefinition","createChannel","createClient","chalk","NodeHttpTransport","createFaucetService","url","commandModule","yargs","dripDev","faucetUrl","address","faucet","faucet_default","commandModule","yargs","name","greeting","hello_default","path","loadConfig","tablegen","getSrcDirectory","commandModule","yargs","configPath","config","srcDir","tablegen_default","loadConfig","commandModule","yargs","args","configPath","out","config","loadConfig","tsgen","tsgen_default","chalk","ZodError","fromZodError","ValidationError","NotInsideProjectError","MUDError","logError","error","validationError","chalk","printMUD","getOutDirectory","path","runTypeChain","worldtypes","cwd","forgeOurDir","IWorldPath","yDeployOptions","commandModule","yargs","args","deployHandler","error","logError","deploy_default","loadConfig","worldgen","getSrcDirectory","path","rmSync","commandModule","yargs","args","worldgenHandler","srcDir","getSrcDirectory","existingContracts","getExistingContracts","mudConfig","loadConfig","outputBaseDirectory","path","rmSync","worldgen","worldgen_default","chalk","existsSync","readFileSync","rmSync","writeFileSync","path","MUDError","package_default","glob","BACKUP_FILE","MUD_PREFIX","commandModule","yargs","options","mutuallyExclusiveOptions","numMutuallyExclusiveOptions","acc","opt","MUDError","resolveVersion","packageJsons","p","packageJson","updatePackageJson","e","logError","npmResult","chalk","package_default","version","commit","v","filePath","restore","force","link","backup","mudVersion","backupFilePath","path","backupFileExists","existsSync","readPackageJson","backupJson","mudDependencies","key","mudDevDependencies","writeFileSync","resolveMudVersion","logComparison","rmSync","type","resolveLinkPath","jsonString","readFileSync","prev","curr","packageJsonPath","mudLinkPath","pkg","pkgName","packageJsonToRootPath","set_version_default","anvil","forge","getRpcUrl","chalk","rmSync","writeFileSync","WORLD_ADDRESS_FILE","commandModule","yargs","yDeployOptions","args","anvilArgs","anvil","forkRpc","getRpcUrl","worldAddress","deployHandler","chalk","writeFileSync","userOptions","testResult","forge","e","rmSync","test_default","existsSync","readFileSync","ethers","loadConfig","MUDError","cast","getRpcUrl","getSrcDirectory","TableId","resolveWorldConfig","IBaseWorldData","systemsTableId","TableId","commandModule","yargs","args","profile","getSrcDirectory","getRpcUrl","tx","configPath","srcDir","rpc","existingContracts","getExistingContracts","mudConfig","loadConfig","resolvedConfig","resolveWorldConfig","basename","worldAddress","getWorldAddress","provider","ethers","WorldContract","IBaseWorldData","namespace","names","name","labels","systemSelector","address","result","cast","trace_default","worldsFile","existsSync","chainId","getChainId","deploys","readFileSync","MUDError","anvil","forge","getRpcUrl","getScriptDirectory","getSrcDirectory","chalk","chokidar","loadConfig","resolveConfigPath","tablegen","path","debounce","homedir","rmSync","commandModule","yargs","args","forge","rpc","getRpcUrl","configPath","resolveConfigPath","srcDirectory","getSrcDirectory","scriptDirectory","getScriptDirectory","initialConfig","loadConfig","handleConfigChange","handleContractsChange","chalk","userHomeDir","path","anvil","changedSinceLastHandled","changeInProgress","chokidar","_","updatePath","handleChange","debounce","config","contracts","mudConfig","deploy","error","logError","printMUD","outPath","tablegen","tsgen","worldgenHandler","worldtypes","deployHandler","dev_contracts_default","commands","deploy_default","devnode_default","faucet_default","gasReport","hello_default","tablegen_default","tsgen_default","worldgen_default","set_version_default","test_default","trace_default","dev_contracts_default","dotenv","chalk","yargs","hideBin","commands","msg","err","logError"]}
|
1
|
+
{"version":3,"sources":["../src/mud.ts","../src/commands/index.ts","../src/commands/devnode.ts","../src/commands/faucet.ts","../src/commands/hello.ts","../src/commands/tablegen.ts","../src/utils/errors.ts","../src/utils/printMUD.ts","../src/utils/worldtypes.ts","../src/commands/deploy.ts","../src/commands/worldgen.ts","../src/commands/set-version.ts","../package.json","../src/commands/test.ts","../src/commands/trace.ts","../src/commands/dev-contracts.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\nimport { commands } from \"./commands\";\nimport { logError } from \"./utils/errors\";\n\n// Load .env file into process.env\nimport * as dotenv from \"dotenv\";\nimport chalk from \"chalk\";\ndotenv.config();\n\nyargs(hideBin(process.argv))\n // Explicit name to display in help (by default it's the entry file, which may not be \"mud\" for e.g. ts-node)\n .scriptName(\"mud\")\n // Use the commands directory to scaffold\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- command array overload isn't typed, see https://github.com/yargs/yargs/blob/main/docs/advanced.md#esm-hierarchy\n .command(commands as any)\n // Enable strict mode.\n .strict()\n // Custom error handler\n .fail((msg, err) => {\n console.error(chalk.red(msg));\n if (msg.includes(\"Missing required argument\")) {\n console.log(\n chalk.yellow(`Run 'pnpm mud ${process.argv[2]} --help' for a list of available and required arguments.`)\n );\n }\n console.log(\"\");\n logError(err);\n console.log(\"\");\n\n process.exit(1);\n })\n // Useful aliases.\n .alias({ h: \"help\" }).argv;\n","import { CommandModule } from \"yargs\";\n\nimport gasReport from \"@latticexyz/gas-report\";\n\nimport devnode from \"./devnode\";\nimport faucet from \"./faucet\";\nimport hello from \"./hello\";\nimport tablegen from \"./tablegen\";\nimport deploy from \"./deploy\";\nimport worldgen from \"./worldgen\";\nimport setVersion from \"./set-version\";\nimport test from \"./test\";\nimport trace from \"./trace\";\nimport devContracts from \"./dev-contracts\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Each command has different options\nexport const commands: CommandModule<any, any>[] = [\n deploy,\n devnode,\n faucet,\n gasReport as CommandModule,\n hello,\n tablegen,\n worldgen,\n setVersion,\n test,\n trace,\n devContracts,\n];\n","import { rmSync } from \"fs\";\nimport { homedir } from \"os\";\nimport path from \"path\";\nimport type { CommandModule } from \"yargs\";\nimport { execa } from \"execa\";\n\ntype Options = {\n blocktime: number;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"devnode\",\n\n describe: \"Start a local Ethereum node for development\",\n\n builder(yargs) {\n return yargs.options({\n blocktime: { type: \"number\", default: 1, decs: \"Interval in which new blocks are produced\" },\n });\n },\n\n async handler({ blocktime }) {\n console.log(\"Clearing devnode history\");\n const userHomeDir = homedir();\n rmSync(path.join(userHomeDir, \".foundry\", \"anvil\", \"tmp\"), { recursive: true, force: true });\n\n const anvilArgs = [\"-b\", String(blocktime), \"--block-base-fee-per-gas\", \"0\"];\n console.log(`Running: anvil ${anvilArgs.join(\" \")}`);\n const child = execa(\"anvil\", anvilArgs, {\n stdio: [\"inherit\", \"inherit\", \"inherit\"],\n });\n\n process.on(\"SIGINT\", () => {\n console.log(\"\\ngracefully shutting down from SIGINT (Crtl-C)\");\n child.kill();\n process.exit();\n });\n await child;\n },\n};\n\nexport default commandModule;\n","import type { CommandModule } from \"yargs\";\nimport { FaucetServiceDefinition } from \"@latticexyz/services/faucet\";\nimport { createChannel, createClient } from \"nice-grpc-web\";\nimport chalk from \"chalk\";\nimport { NodeHttpTransport } from \"@improbable-eng/grpc-web-node-http-transport\";\n\ntype Options = {\n dripDev?: boolean;\n faucetUrl: string;\n address: string;\n};\n\n/**\n * Create a FaucetServiceClient\n * @param url FaucetService URL\n * @returns FaucetServiceClient\n */\nfunction createFaucetService(url: string) {\n return createClient(FaucetServiceDefinition, createChannel(url, NodeHttpTransport()));\n}\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"faucet\",\n\n describe: \"Interact with a MUD faucet\",\n\n builder(yargs) {\n return yargs.options({\n dripDev: {\n type: \"boolean\",\n desc: \"Request a drip from the dev endpoint (requires faucet to have dev mode enabled)\",\n default: true,\n },\n faucetUrl: {\n type: \"string\",\n desc: \"URL of the MUD faucet\",\n default: \"https://faucet.testnet-mud-services.linfra.xyz\",\n },\n address: {\n type: \"string\",\n desc: \"Ethereum address to fund\",\n required: true,\n },\n });\n },\n\n async handler({ dripDev, faucetUrl, address }) {\n const faucet = createFaucetService(faucetUrl);\n\n if (dripDev) {\n console.log(chalk.yellow(\"Dripping to\", address));\n await faucet.dripDev({ address });\n console.log(chalk.yellow(\"Success\"));\n }\n\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","import type { CommandModule } from \"yargs\";\n\ntype Options = {\n name: string;\n upper: boolean | undefined;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"hello <name>\",\n\n describe: \"Greet <name> with Hello\",\n\n builder(yargs) {\n return yargs\n .options({\n upper: { type: \"boolean\" },\n })\n .positional(\"name\", { type: \"string\", demandOption: true });\n },\n\n handler({ name }) {\n const greeting = `Gm, ${name}!`;\n console.log(greeting);\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","import path from \"path\";\nimport type { CommandModule } from \"yargs\";\nimport { loadConfig } from \"@latticexyz/config/node\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { tablegen } from \"@latticexyz/store/codegen\";\nimport { getSrcDirectory } from \"@latticexyz/common/foundry\";\n\ntype Options = {\n configPath?: string;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"tablegen\",\n\n describe: \"Autogenerate MUD Store table libraries based on the config file\",\n\n builder(yargs) {\n return yargs.options({\n configPath: { type: \"string\", desc: \"Path to the config file\" },\n });\n },\n\n async handler({ configPath }) {\n const config = (await loadConfig(configPath)) as StoreConfig;\n const srcDir = await getSrcDirectory();\n\n await tablegen(config, path.join(srcDir, config.codegenDirectory));\n\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","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","import chalk from \"chalk\";\n\nexport function printMUD() {\n console.log(\n chalk.yellow(`\n.------..------..------.\n|M.--. ||U.--. ||D.--. |\n| (\\\\/) || (\\\\/) || :/\\\\: |\n| :\\\\/: || :\\\\/: || (__) |\n| '--'M|| '--'U|| '--'D|\n'------''------''------'\n`)\n );\n}\n","import { getOutDirectory } from \"@latticexyz/common/foundry\";\nimport path from \"path\";\nimport { runTypeChain } from \"typechain\";\n\n/**\n * Generate IWorld typescript bindings\n */\nexport async function worldtypes() {\n const cwd = process.cwd();\n const forgeOurDir = await getOutDirectory();\n const IWorldPath = path.join(process.cwd(), forgeOurDir, \"IWorld.sol/IWorld.json\");\n\n await runTypeChain({\n cwd,\n filesToProcess: [IWorldPath],\n allFiles: [IWorldPath],\n target: \"ethers-v5\",\n });\n\n console.log(\"Typechain generated IWorld interface\");\n}\n","import type { CommandModule, Options } from \"yargs\";\nimport { logError } from \"../utils/errors\";\nimport { deployHandler, DeployOptions } from \"../utils\";\n\nexport const yDeployOptions = {\n configPath: { type: \"string\", desc: \"Path to the config file\" },\n clean: { type: \"boolean\", desc: \"Remove the build forge artifacts and cache directories before building\" },\n printConfig: { type: \"boolean\", desc: \"Print the resolved config\" },\n profile: { type: \"string\", desc: \"The foundry profile to use\" },\n debug: { type: \"boolean\", desc: \"Print debug logs, like full error messages\" },\n priorityFeeMultiplier: {\n type: \"number\",\n desc: \"Multiply the estimated priority fee by the provided factor\",\n default: 1,\n },\n saveDeployment: { type: \"boolean\", desc: \"Save the deployment info to a file\", default: true },\n rpc: { type: \"string\", desc: \"The RPC URL to use. Defaults to the RPC url from the local foundry.toml\" },\n worldAddress: { type: \"string\", desc: \"Deploy to an existing World at the given address\" },\n srcDir: { type: \"string\", desc: \"Source directory. Defaults to foundry src directory.\" },\n disableTxWait: { type: \"boolean\", desc: \"Disable waiting for transactions to be confirmed.\", default: false },\n pollInterval: {\n type: \"number\",\n desc: \"Interval in miliseconds to use to poll for transaction receipts / block inclusion\",\n default: 1000,\n },\n skipBuild: { type: \"boolean\", desc: \"Skip rebuilding the contracts before deploying\" },\n} satisfies Record<keyof DeployOptions, Options>;\n\nconst commandModule: CommandModule<DeployOptions, DeployOptions> = {\n command: \"deploy\",\n\n describe: \"Deploy MUD contracts\",\n\n builder(yargs) {\n return yargs.options(yDeployOptions);\n },\n\n async handler(args) {\n try {\n await deployHandler(args);\n } catch (error: any) {\n logError(error);\n process.exit(1);\n }\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","import type { CommandModule } from \"yargs\";\nimport { loadConfig } from \"@latticexyz/config/node\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { WorldConfig } from \"@latticexyz/world\";\nimport { worldgen } from \"@latticexyz/world/node\";\nimport { getSrcDirectory } from \"@latticexyz/common/foundry\";\nimport path from \"path\";\nimport { rmSync } from \"fs\";\nimport { getExistingContracts } from \"../utils\";\n\ntype Options = {\n configPath?: string;\n clean?: boolean;\n srcDir?: string;\n config?: StoreConfig & WorldConfig;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"worldgen\",\n\n describe: \"Autogenerate interfaces for Systems and World based on existing contracts and the config file\",\n\n builder(yargs) {\n return yargs.options({\n configPath: { type: \"string\", desc: \"Path to the config file\" },\n clean: {\n type: \"boolean\",\n desc: \"Clear the worldgen directory before generating new interfaces (defaults to true)\",\n default: true,\n },\n });\n },\n\n async handler(args) {\n await worldgenHandler(args);\n process.exit(0);\n },\n};\n\nexport async function worldgenHandler(args: Options) {\n const srcDir = args.srcDir ?? (await getSrcDirectory());\n\n const existingContracts = getExistingContracts(srcDir);\n\n // Load the config\n const mudConfig = args.config ?? ((await loadConfig(args.configPath)) as StoreConfig & WorldConfig);\n\n const outputBaseDirectory = path.join(srcDir, mudConfig.codegenDirectory);\n\n // clear the worldgen directory\n if (args.clean) rmSync(path.join(outputBaseDirectory, mudConfig.worldgenDirectory), { recursive: true, force: true });\n\n // generate new interfaces\n await worldgen(mudConfig, existingContracts, outputBaseDirectory);\n}\n\nexport default commandModule;\n","import chalk from \"chalk\";\nimport { existsSync, readFileSync, rmSync, writeFileSync } from \"fs\";\nimport path from \"path\";\nimport type { CommandModule } from \"yargs\";\nimport { MUDError } from \"@latticexyz/common/errors\";\nimport { logError } from \"../utils/errors\";\nimport localPackageJson from \"../../package.json\" assert { type: \"json\" };\nimport glob from \"glob\";\n\ntype Options = {\n backup?: boolean;\n force?: boolean;\n restore?: boolean;\n mudVersion?: string;\n tag?: string;\n commit?: string;\n link?: string;\n};\n\nconst BACKUP_FILE = \".mudbackup\";\nconst MUD_PREFIX = \"@latticexyz\";\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"set-version\",\n\n describe: \"Set MUD version in all package.json files and optionally backup the previously installed version\",\n\n builder(yargs) {\n return yargs.options({\n backup: { type: \"boolean\", description: `Back up the current MUD versions to \"${BACKUP_FILE}\"` },\n force: {\n type: \"boolean\",\n description: `Backup fails if a \"${BACKUP_FILE}\" file is found, unless --force is provided`,\n },\n restore: { type: \"boolean\", description: `Restore the previous MUD versions from \"${BACKUP_FILE}\"` },\n mudVersion: { alias: \"v\", type: \"string\", description: \"Set MUD to the given version\" },\n tag: {\n alias: \"t\",\n type: \"string\",\n description: \"Set MUD to the latest version with the given tag from npm\",\n },\n commit: {\n alias: \"c\",\n type: \"string\",\n description: \"Set MUD to the version based on a given git commit hash from npm\",\n },\n link: { alias: \"l\", type: \"string\", description: \"Relative path to the local MUD root directory to link\" },\n });\n },\n\n async handler(options) {\n try {\n const mutuallyExclusiveOptions = [\"mudVersion\", \"link\", \"tag\", \"commit\", \"restore\"];\n const numMutuallyExclusiveOptions = mutuallyExclusiveOptions.reduce(\n (acc, opt) => (options[opt] ? acc + 1 : acc),\n 0\n );\n\n if (numMutuallyExclusiveOptions === 0) {\n throw new MUDError(`You need to provide one these options: ${mutuallyExclusiveOptions.join(\", \")}`);\n }\n\n if (numMutuallyExclusiveOptions > 1) {\n throw new MUDError(`These options are mutually exclusive: ${mutuallyExclusiveOptions.join(\", \")}`);\n }\n\n // Resolve the version number from available options like `tag` or `commit`\n options.mudVersion = await resolveVersion(options);\n\n // Update all package.json below the current working directory (except in node_modules)\n const packageJsons = glob.sync(\"**/package.json\").filter((p) => !p.includes(\"node_modules\"));\n for (const packageJson of packageJsons) {\n updatePackageJson(packageJson, options);\n }\n } catch (e) {\n logError(e);\n } finally {\n process.exit(0);\n }\n },\n};\n\nasync function resolveVersion(options: Options) {\n // Backwards compatibility to previous behavior of this script where passing \"canary\" as the version resolved to the latest commit on main\n if (options.mudVersion === \"canary\") options.tag = \"main\";\n\n let npmResult;\n try {\n console.log(chalk.blue(`Fetching available versions`));\n npmResult = await (await fetch(`https://registry.npmjs.org/${localPackageJson.name}`)).json();\n } catch (e) {\n throw new MUDError(`Could not fetch available MUD versions`);\n }\n\n if (options.tag) {\n const version = npmResult[\"dist-tags\"][options.tag];\n if (!version) {\n throw new MUDError(`Could not find npm version with tag \"${options.tag}\"`);\n }\n console.log(chalk.green(`Latest version with tag ${options.tag}: ${version}`));\n return version;\n }\n\n if (options.commit) {\n // Find a version with this commit hash\n const commit = options.commit.substring(0, 8); // changesets uses the first 8 characters of the commit hash as version for prereleases/snapshot releases\n const version = Object.keys(npmResult[\"versions\"]).find((v) => (v as string).includes(commit));\n if (!version) {\n throw new MUDError(`Could not find npm version based on commit \"${options.commit}\"`);\n }\n console.log(chalk.green(`Version from commit ${options.commit}: ${version}`));\n return version;\n }\n\n // If neither a tag nor a commit option is given, return the `mudVersion`\n return options.mudVersion;\n}\n\nfunction updatePackageJson(filePath: string, options: Options): { workspaces?: string[] } {\n const { restore, force, link } = options;\n let { backup, mudVersion } = options;\n\n const backupFilePath = path.join(path.dirname(filePath), BACKUP_FILE);\n const backupFileExists = existsSync(backupFilePath);\n\n // Create a backup file for previous MUD versions by default if linking to local MUD\n if (link && !backupFileExists) backup = true;\n\n // If `backup` is true and force not set, check if a backup file already exists and throw an error if it does\n if (backup && !force && backupFileExists) {\n throw new MUDError(\n `A backup file already exists at ${backupFilePath}.\\nUse --force to overwrite it or --restore to restore it.`\n );\n }\n\n const packageJson = readPackageJson(filePath);\n\n // Load .mudbackup if `restore` is true\n const backupJson = restore ? readPackageJson(backupFilePath) : undefined;\n\n // Find all MUD dependencies\n const mudDependencies: Record<string, string> = {};\n for (const key in packageJson.dependencies) {\n if (key.startsWith(MUD_PREFIX)) {\n mudDependencies[key] = packageJson.dependencies[key];\n }\n }\n\n // Find all MUD devDependencies\n const mudDevDependencies: Record<string, string> = {};\n for (const key in packageJson.devDependencies) {\n if (key.startsWith(MUD_PREFIX)) {\n mudDevDependencies[key] = packageJson.devDependencies[key];\n }\n }\n\n // Back up the current dependencies if `backup` is true\n if (backup) {\n writeFileSync(\n backupFilePath,\n JSON.stringify({ dependencies: mudDependencies, devDependencies: mudDevDependencies }, null, 2)\n );\n console.log(chalk.green(`Backed up MUD dependencies from ${filePath} to ${backupFilePath}`));\n }\n\n // Update the dependencies\n for (const key in packageJson.dependencies) {\n if (key.startsWith(MUD_PREFIX)) {\n packageJson.dependencies[key] = resolveMudVersion(key, \"dependencies\");\n }\n }\n\n // Update the devDependencies\n for (const key in packageJson.devDependencies) {\n if (key.startsWith(MUD_PREFIX)) {\n packageJson.devDependencies[key] = resolveMudVersion(key, \"devDependencies\");\n }\n }\n\n // Write the updated package.json\n writeFileSync(filePath, JSON.stringify(packageJson, null, 2) + \"\\n\");\n\n console.log(`Updating ${filePath}`);\n logComparison(mudDependencies, packageJson.dependencies);\n logComparison(mudDevDependencies, packageJson.devDependencies);\n\n // Remove the backup file if `restore` is true and `backup` is false\n // because the old backup file is no longer needed\n if (restore && !backup) {\n rmSync(backupFilePath);\n console.log(chalk.green(`Cleaned up ${backupFilePath}`));\n }\n\n return packageJson;\n\n function resolveMudVersion(key: string, type: \"dependencies\" | \"devDependencies\") {\n if (restore && backupJson) return backupJson[type][key];\n if (link) mudVersion = resolveLinkPath(filePath, link, key);\n if (!mudVersion) return packageJson[type][key];\n return mudVersion;\n }\n}\n\nfunction readPackageJson(path: string): {\n workspaces?: string[];\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n} {\n try {\n const jsonString = readFileSync(path, \"utf8\");\n return JSON.parse(jsonString);\n } catch {\n throw new MUDError(\"Could not read JSON at \" + path);\n }\n}\n\nfunction logComparison(prev: Record<string, string>, curr: Record<string, string>) {\n for (const key in prev) {\n if (prev[key] !== curr[key]) {\n console.log(`${key}: ${chalk.red(prev[key])} -> ${chalk.green(curr[key])}`);\n }\n }\n}\n\n/**\n * Returns path of the package to link, given a path to a local MUD clone and a package\n */\nfunction resolveLinkPath(packageJsonPath: string, mudLinkPath: string, pkg: string) {\n const pkgName = pkg.replace(MUD_PREFIX, \"\");\n const packageJsonToRootPath = path.relative(path.dirname(packageJsonPath), process.cwd());\n const linkPath = path.join(packageJsonToRootPath, mudLinkPath, \"packages\", pkgName);\n return \"link:\" + linkPath;\n}\n\nexport default commandModule;\n","{\n \"name\": \"@latticexyz/cli\",\n \"version\": \"2.0.0-next.3\",\n \"description\": \"Command line interface for mud\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/latticexyz/mud.git\",\n \"directory\": \"packages/cli\"\n },\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"exports\": {\n \".\": \"./dist/index.js\"\n },\n \"types\": \"src/index.ts\",\n \"bin\": {\n \"mud\": \"./dist/mud.js\"\n },\n \"scripts\": {\n \"build\": \"pnpm run build:js && pnpm run build:test-tables\",\n \"build:js\": \"tsup && chmod +x ./dist/mud.js\",\n \"build:test-tables\": \"tsx ./scripts/generate-test-tables.ts\",\n \"clean\": \"pnpm run clean:js\",\n \"clean:js\": \"rimraf dist\",\n \"dev\": \"tsup --watch\",\n \"lint\": \"eslint . --ext .ts\",\n \"test\": \"tsc --noEmit && forge test\"\n },\n \"dependencies\": {\n \"@ethersproject/abi\": \"^5.7.0\",\n \"@ethersproject/providers\": \"^5.7.2\",\n \"@improbable-eng/grpc-web\": \"^0.15.0\",\n \"@improbable-eng/grpc-web-node-http-transport\": \"^0.15.0\",\n \"@latticexyz/common\": \"workspace:*\",\n \"@latticexyz/config\": \"workspace:*\",\n \"@latticexyz/gas-report\": \"workspace:*\",\n \"@latticexyz/protocol-parser\": \"workspace:*\",\n \"@latticexyz/schema-type\": \"workspace:*\",\n \"@latticexyz/services\": \"workspace:*\",\n \"@latticexyz/solecs\": \"workspace:*\",\n \"@latticexyz/std-contracts\": \"workspace:*\",\n \"@latticexyz/store\": \"workspace:*\",\n \"@latticexyz/utils\": \"workspace:*\",\n \"@latticexyz/world\": \"workspace:*\",\n \"@typechain/ethers-v5\": \"^10.2.0\",\n \"chalk\": \"^5.0.1\",\n \"chokidar\": \"^3.5.3\",\n \"dotenv\": \"^16.0.3\",\n \"ejs\": \"^3.1.8\",\n \"ethers\": \"^5.7.2\",\n \"execa\": \"^7.0.0\",\n \"glob\": \"^8.0.3\",\n \"nice-grpc-web\": \"^2.0.1\",\n \"openurl\": \"^1.1.1\",\n \"path\": \"^0.12.7\",\n \"throttle-debounce\": \"^5.0.0\",\n \"typechain\": \"^8.1.1\",\n \"typescript\": \"5.1.6\",\n \"yargs\": \"^17.7.1\",\n \"zod\": \"^3.21.4\",\n \"zod-validation-error\": \"^1.3.0\"\n },\n \"devDependencies\": {\n \"@types/ejs\": \"^3.1.1\",\n \"@types/glob\": \"^7.2.0\",\n \"@types/node\": \"^18.15.11\",\n \"@types/openurl\": \"^1.0.0\",\n \"@types/throttle-debounce\": \"^5.0.0\",\n \"@types/yargs\": \"^17.0.10\",\n \"ds-test\": \"https://github.com/dapphub/ds-test.git#e282159d5170298eb2455a6c05280ab5a73a4ef0\",\n \"forge-std\": \"https://github.com/foundry-rs/forge-std.git#74cfb77e308dd188d2f58864aaf44963ae6b88b1\",\n \"tsup\": \"^6.7.0\",\n \"tsx\": \"^3.12.6\",\n \"vitest\": \"0.31.4\"\n },\n \"gitHead\": \"914a1e0ae4a573d685841ca2ea921435057deb8f\"\n}\n","import type { CommandModule } from \"yargs\";\nimport { anvil, forge, getRpcUrl } from \"@latticexyz/common/foundry\";\nimport chalk from \"chalk\";\nimport { rmSync, writeFileSync } from \"fs\";\nimport { yDeployOptions } from \"./deploy\";\nimport { deployHandler, DeployOptions } from \"../utils\";\n\ntype Options = DeployOptions & { port?: number; worldAddress?: string; forgeOptions?: string };\n\nconst WORLD_ADDRESS_FILE = \".mudtest\";\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"test\",\n\n describe: \"Run tests in MUD contracts\",\n\n builder(yargs) {\n return yargs.options({\n ...yDeployOptions,\n port: { type: \"number\", description: \"Port to run internal node for fork testing on\", default: 4242 },\n worldAddress: {\n type: \"string\",\n description:\n \"Address of an existing world contract. If provided, deployment is skipped and the RPC provided in the foundry.toml is used for fork testing.\",\n },\n forgeOptions: { type: \"string\", description: \"Options to pass to forge test\" },\n });\n },\n\n async handler(args) {\n // Start an internal anvil process if no world address is provided\n if (!args.worldAddress) {\n const anvilArgs = [\"--block-base-fee-per-gas\", \"0\", \"--port\", String(args.port)];\n anvil(anvilArgs);\n }\n\n const forkRpc = args.worldAddress ? await getRpcUrl(args.profile) : `http://127.0.0.1:${args.port}`;\n\n const worldAddress =\n args.worldAddress ??\n (\n await deployHandler({\n ...args,\n saveDeployment: false,\n rpc: forkRpc,\n })\n ).worldAddress;\n\n console.log(chalk.blue(\"World address\", worldAddress));\n\n // Create a temporary file to pass the world address to the tests\n writeFileSync(WORLD_ADDRESS_FILE, worldAddress);\n\n const userOptions = args.forgeOptions?.replaceAll(\"\\\\\", \"\").split(\" \") ?? [];\n try {\n const testResult = await forge([\"test\", \"--fork-url\", forkRpc, ...userOptions], {\n profile: args.profile,\n });\n console.log(testResult);\n } catch (e) {\n console.error(e);\n }\n\n rmSync(WORLD_ADDRESS_FILE);\n\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","import { existsSync, readFileSync } from \"fs\";\nimport type { CommandModule } from \"yargs\";\nimport { ethers } from \"ethers\";\n\nimport { loadConfig } from \"@latticexyz/config/node\";\nimport { MUDError } from \"@latticexyz/common/errors\";\nimport { cast, getRpcUrl, getSrcDirectory } from \"@latticexyz/common/foundry\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { resolveWorldConfig, WorldConfig } from \"@latticexyz/world\";\nimport { IBaseWorld } from \"@latticexyz/world/types/ethers-contracts/IBaseWorld\";\nimport IBaseWorldData from \"@latticexyz/world/abi/IBaseWorld.sol/IBaseWorld.json\" assert { type: \"json\" };\nimport worldConfig from \"@latticexyz/world/mud.config.js\";\nimport { tableIdToHex } from \"@latticexyz/common\";\nimport { getChainId, getExistingContracts } from \"../utils\";\n\n// TODO account for multiple namespaces (https://github.com/latticexyz/mud/issues/994)\nconst systemsTableId = tableIdToHex(worldConfig.namespace, worldConfig.tables.Systems.name);\n\ntype Options = {\n tx: string;\n worldAddress?: string;\n configPath?: string;\n profile?: string;\n srcDir?: string;\n rpc?: string;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"trace\",\n\n describe: \"Display the trace of a transaction\",\n\n builder(yargs) {\n return yargs.options({\n tx: { type: \"string\", required: true, description: \"Transaction hash to replay\" },\n worldAddress: {\n type: \"string\",\n description: \"World contract address. Defaults to the value from worlds.json, based on rpc's chainId\",\n },\n configPath: { type: \"string\", description: \"Path to the config file\" },\n profile: { type: \"string\", description: \"The foundry profile to use\" },\n srcDir: { type: \"string\", description: \"Source directory. Defaults to foundry src directory.\" },\n rpc: { type: \"string\", description: \"json rpc endpoint. Defaults to foundry's configured eth_rpc_url\" },\n });\n },\n\n async handler(args) {\n args.profile ??= process.env.FOUNDRY_PROFILE;\n const { profile } = args;\n args.srcDir ??= await getSrcDirectory(profile);\n args.rpc ??= await getRpcUrl(profile);\n const { tx, configPath, srcDir, rpc } = args;\n\n const existingContracts = getExistingContracts(srcDir);\n\n // Load the config\n const mudConfig = (await loadConfig(configPath)) as StoreConfig & WorldConfig;\n\n const resolvedConfig = resolveWorldConfig(\n mudConfig,\n existingContracts.map(({ basename }) => basename)\n );\n\n // Get worldAddress either from args or from worldsFile\n const worldAddress = args.worldAddress ?? (await getWorldAddress(mudConfig.worldsFile, rpc));\n\n // Create World contract instance from deployed address\n const provider = new ethers.providers.StaticJsonRpcProvider(rpc);\n const WorldContract = new ethers.Contract(worldAddress, IBaseWorldData.abi, provider) as IBaseWorld;\n\n // TODO account for multiple namespaces (https://github.com/latticexyz/mud/issues/994)\n const namespace = mudConfig.namespace;\n const names = Object.values(resolvedConfig.systems).map(({ name }) => name);\n\n // Fetch system table schema from chain\n const systemTableSchema = await WorldContract.getValueSchema(systemsTableId);\n const labels: { name: string; address: string }[] = [];\n for (const name of names) {\n const systemSelector = tableIdToHex(namespace, name);\n // Get the first field of `Systems` table (the table maps system name to its address and other data)\n const address = await WorldContract.getField(systemsTableId, [systemSelector], 0, systemTableSchema);\n labels.push({ name, address });\n }\n\n const result = await cast([\n \"run\",\n \"--label\",\n `${worldAddress}:World`,\n ...labels.map(({ name, address }) => [\"--label\", `${address}:${name}`]).flat(),\n `${tx}`,\n ]);\n console.log(result);\n\n process.exit(0);\n },\n};\n\nexport default commandModule;\n\nasync function getWorldAddress(worldsFile: string, rpc: string) {\n if (existsSync(worldsFile)) {\n const chainId = await getChainId(rpc);\n const deploys = JSON.parse(readFileSync(worldsFile, \"utf-8\"));\n\n if (!deploys[chainId]) {\n throw new MUDError(`chainId ${chainId} is missing in worldsFile \"${worldsFile}\"`);\n }\n return deploys[chainId].address as string;\n } else {\n throw new MUDError(\"worldAddress is not specified and worldsFile is missing\");\n }\n}\n","import type { CommandModule } from \"yargs\";\nimport { anvil, forge, getRpcUrl, getScriptDirectory, getSrcDirectory } from \"@latticexyz/common/foundry\";\nimport chalk from \"chalk\";\nimport chokidar from \"chokidar\";\nimport { loadConfig, resolveConfigPath } from \"@latticexyz/config/node\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { tablegen } from \"@latticexyz/store/codegen\";\nimport path from \"path\";\nimport { debounce } from \"throttle-debounce\";\nimport { worldgenHandler } from \"./worldgen\";\nimport { WorldConfig } from \"@latticexyz/world\";\nimport { deployHandler, logError, printMUD, worldtypes } from \"../utils\";\nimport { homedir } from \"os\";\nimport { rmSync } from \"fs\";\n\ntype Options = {\n rpc?: string;\n configPath?: string;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"dev-contracts\",\n\n describe: \"Start a development server for MUD contracts\",\n\n builder(yargs) {\n return yargs.options({\n rpc: {\n type: \"string\",\n decs: \"RPC endpoint of the development node. If none is provided, an anvil instance is spawned in the background on port 8545.\",\n },\n configPath: {\n type: \"string\",\n decs: \"Path to MUD config\",\n },\n });\n },\n\n async handler(args) {\n // Initial cleanup\n await forge([\"clean\"]);\n\n const rpc = args.rpc ?? (await getRpcUrl());\n const configPath = args.configPath ?? (await resolveConfigPath(args.configPath));\n const srcDirectory = await getSrcDirectory();\n const scriptDirectory = await getScriptDirectory();\n const initialConfig = (await loadConfig(configPath)) as StoreConfig & WorldConfig;\n\n // Initial run of all codegen steps before starting anvil\n // (so clients can wait for everything to be ready before starting)\n await handleConfigChange(initialConfig);\n await handleContractsChange(initialConfig);\n\n // Start an anvil instance in the background if no RPC url is provided\n if (!args.rpc) {\n console.log(chalk.gray(\"Cleaning devnode cache\"));\n const userHomeDir = homedir();\n rmSync(path.join(userHomeDir, \".foundry\", \"anvil\", \"tmp\"), { recursive: true, force: true });\n\n const anvilArgs = [\"--block-time\", \"1\", \"--block-base-fee-per-gas\", \"0\"];\n anvil(anvilArgs);\n }\n\n const changedSinceLastHandled = {\n config: false,\n contracts: false,\n };\n\n const changeInProgress = {\n current: false,\n };\n\n // Watch for changes\n const configWatcher = chokidar.watch([configPath, srcDirectory]);\n configWatcher.on(\"all\", async (_, updatePath) => {\n if (updatePath.includes(configPath)) {\n changedSinceLastHandled.config = true;\n // We trigger contract changes if the config changed here instead of\n // listening to changes in the codegen directory to avoid an infinite loop\n changedSinceLastHandled.contracts = true;\n }\n\n if (updatePath.includes(srcDirectory) || updatePath.includes(scriptDirectory)) {\n // Ignore changes to codegen files to avoid an infinite loop\n if (updatePath.includes(initialConfig.codegenDirectory)) return;\n changedSinceLastHandled.contracts = true;\n }\n\n // Trigger debounced onChange\n handleChange();\n });\n\n const handleChange = debounce(100, async () => {\n // Avoid handling changes multiple times in parallel\n if (changeInProgress.current) return;\n changeInProgress.current = true;\n\n // Reset dirty flags\n const { config, contracts } = changedSinceLastHandled;\n changedSinceLastHandled.config = false;\n changedSinceLastHandled.contracts = false;\n\n try {\n // Load latest config\n const mudConfig = (await loadConfig(configPath)) as StoreConfig & WorldConfig;\n\n // Handle changes\n if (config) await handleConfigChange(mudConfig);\n if (contracts) await handleContractsChange(mudConfig);\n\n await deploy();\n } catch (error) {\n console.error(chalk.red(\"MUD dev-contracts watcher failed to deploy config or contracts changes\\n\"));\n logError(error);\n }\n\n changeInProgress.current = false;\n if (changedSinceLastHandled.config || changedSinceLastHandled.contracts) {\n console.log(\"Detected change while handling the previous change\");\n handleChange();\n }\n\n printMUD();\n console.log(\"MUD watching for changes...\");\n });\n\n /** Codegen to run if config changes */\n async function handleConfigChange(config: StoreConfig & WorldConfig) {\n console.log(chalk.blue(\"mud.config.ts changed - regenerating tables and recs types\"));\n // Run tablegen to generate tables based on the config\n const outPath = path.join(srcDirectory, config.codegenDirectory);\n await tablegen(config, outPath);\n }\n\n /** Codegen to run if contracts changed */\n async function handleContractsChange(config: StoreConfig & WorldConfig) {\n console.log(chalk.blue(\"contracts changed - regenerating interfaces and contract types\"));\n\n // Run worldgen to generate interfaces based on the systems\n await worldgenHandler({ config, clean: true, srcDir: srcDirectory });\n\n // Build the contracts\n await forge([\"build\"]);\n\n // Run typechain to rebuild typescript types for the contracts\n await worldtypes();\n }\n\n /** Run after codegen if either mud config or contracts changed */\n async function deploy() {\n console.log(chalk.blue(\"redeploying World\"));\n await deployHandler({\n configPath,\n skipBuild: true,\n priorityFeeMultiplier: 1,\n disableTxWait: true,\n pollInterval: 1000,\n saveDeployment: true,\n srcDir: srcDirectory,\n rpc,\n });\n }\n },\n};\n\nexport default commandModule;\n"],"mappings":"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","names":["yargs","hideBin","gasReport","rmSync","homedir","path","execa","commandModule","yargs","blocktime","userHomeDir","anvilArgs","child","devnode_default","FaucetServiceDefinition","createChannel","createClient","chalk","NodeHttpTransport","createFaucetService","url","commandModule","yargs","dripDev","faucetUrl","address","faucet","faucet_default","commandModule","yargs","name","greeting","hello_default","path","loadConfig","tablegen","getSrcDirectory","commandModule","yargs","configPath","config","srcDir","tablegen_default","chalk","ZodError","fromZodError","ValidationError","NotInsideProjectError","MUDError","logError","error","validationError","chalk","printMUD","getOutDirectory","path","runTypeChain","worldtypes","cwd","forgeOurDir","IWorldPath","yDeployOptions","commandModule","yargs","args","deployHandler","error","logError","deploy_default","loadConfig","worldgen","getSrcDirectory","path","rmSync","commandModule","yargs","args","worldgenHandler","srcDir","getSrcDirectory","existingContracts","getExistingContracts","mudConfig","loadConfig","outputBaseDirectory","path","rmSync","worldgen","worldgen_default","chalk","existsSync","readFileSync","rmSync","writeFileSync","path","MUDError","package_default","glob","BACKUP_FILE","MUD_PREFIX","commandModule","yargs","options","mutuallyExclusiveOptions","numMutuallyExclusiveOptions","acc","opt","MUDError","resolveVersion","packageJsons","p","packageJson","updatePackageJson","e","logError","npmResult","chalk","package_default","version","commit","v","filePath","restore","force","link","backup","mudVersion","backupFilePath","path","backupFileExists","existsSync","readPackageJson","backupJson","mudDependencies","key","mudDevDependencies","writeFileSync","resolveMudVersion","logComparison","rmSync","type","resolveLinkPath","jsonString","readFileSync","prev","curr","packageJsonPath","mudLinkPath","pkg","pkgName","packageJsonToRootPath","set_version_default","anvil","forge","getRpcUrl","chalk","rmSync","writeFileSync","WORLD_ADDRESS_FILE","commandModule","yargs","yDeployOptions","args","anvilArgs","anvil","forkRpc","getRpcUrl","worldAddress","deployHandler","chalk","writeFileSync","userOptions","testResult","forge","e","rmSync","test_default","existsSync","readFileSync","ethers","loadConfig","MUDError","cast","getRpcUrl","getSrcDirectory","resolveWorldConfig","IBaseWorldData","worldConfig","tableIdToHex","systemsTableId","tableIdToHex","worldConfig","commandModule","yargs","args","profile","getSrcDirectory","getRpcUrl","tx","configPath","srcDir","rpc","existingContracts","getExistingContracts","mudConfig","loadConfig","resolvedConfig","resolveWorldConfig","basename","worldAddress","getWorldAddress","provider","ethers","WorldContract","IBaseWorldData","namespace","names","name","systemTableSchema","labels","systemSelector","address","result","cast","trace_default","worldsFile","existsSync","chainId","getChainId","deploys","readFileSync","MUDError","anvil","forge","getRpcUrl","getScriptDirectory","getSrcDirectory","chalk","chokidar","loadConfig","resolveConfigPath","tablegen","path","debounce","homedir","rmSync","commandModule","yargs","args","forge","rpc","getRpcUrl","configPath","resolveConfigPath","srcDirectory","getSrcDirectory","scriptDirectory","getScriptDirectory","initialConfig","loadConfig","handleConfigChange","handleContractsChange","chalk","userHomeDir","path","anvil","changedSinceLastHandled","changeInProgress","chokidar","_","updatePath","handleChange","debounce","config","contracts","mudConfig","deploy","error","logError","printMUD","outPath","tablegen","worldgenHandler","worldtypes","deployHandler","dev_contracts_default","commands","deploy_default","devnode_default","faucet_default","gasReport","hello_default","tablegen_default","worldgen_default","set_version_default","test_default","trace_default","dev_contracts_default","dotenv","chalk","yargs","hideBin","commands","msg","err","logError"]}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@latticexyz/cli",
|
3
|
-
"version": "2.0.0-next.
|
3
|
+
"version": "2.0.0-next.3",
|
4
4
|
"description": "Command line interface for mud",
|
5
5
|
"repository": {
|
6
6
|
"type": "git",
|
@@ -38,16 +38,17 @@
|
|
38
38
|
"yargs": "^17.7.1",
|
39
39
|
"zod": "^3.21.4",
|
40
40
|
"zod-validation-error": "^1.3.0",
|
41
|
-
"@latticexyz/common": "2.0.0-next.
|
42
|
-
"@latticexyz/config": "2.0.0-next.
|
43
|
-
"@latticexyz/gas-report": "2.0.0-next.
|
44
|
-
"@latticexyz/
|
45
|
-
"@latticexyz/
|
46
|
-
"@latticexyz/
|
47
|
-
"@latticexyz/
|
48
|
-
"@latticexyz/
|
49
|
-
"@latticexyz/
|
50
|
-
"@latticexyz/
|
41
|
+
"@latticexyz/common": "2.0.0-next.3",
|
42
|
+
"@latticexyz/config": "2.0.0-next.3",
|
43
|
+
"@latticexyz/gas-report": "2.0.0-next.3",
|
44
|
+
"@latticexyz/protocol-parser": "2.0.0-next.3",
|
45
|
+
"@latticexyz/schema-type": "2.0.0-next.3",
|
46
|
+
"@latticexyz/services": "2.0.0-next.3",
|
47
|
+
"@latticexyz/solecs": "2.0.0-next.3",
|
48
|
+
"@latticexyz/std-contracts": "2.0.0-next.3",
|
49
|
+
"@latticexyz/store": "2.0.0-next.3",
|
50
|
+
"@latticexyz/utils": "2.0.0-next.3",
|
51
|
+
"@latticexyz/world": "2.0.0-next.3"
|
51
52
|
},
|
52
53
|
"devDependencies": {
|
53
54
|
"@types/ejs": "^3.1.1",
|
@@ -6,7 +6,6 @@ import { loadConfig, resolveConfigPath } from "@latticexyz/config/node";
|
|
6
6
|
import { StoreConfig } from "@latticexyz/store";
|
7
7
|
import { tablegen } from "@latticexyz/store/codegen";
|
8
8
|
import path from "path";
|
9
|
-
import { tsgen } from "../render-ts";
|
10
9
|
import { debounce } from "throttle-debounce";
|
11
10
|
import { worldgenHandler } from "./worldgen";
|
12
11
|
import { WorldConfig } from "@latticexyz/world";
|
@@ -17,7 +16,6 @@ import { rmSync } from "fs";
|
|
17
16
|
type Options = {
|
18
17
|
rpc?: string;
|
19
18
|
configPath?: string;
|
20
|
-
tsgenOutput: string;
|
21
19
|
};
|
22
20
|
|
23
21
|
const commandModule: CommandModule<Options, Options> = {
|
@@ -35,15 +33,10 @@ const commandModule: CommandModule<Options, Options> = {
|
|
35
33
|
type: "string",
|
36
34
|
decs: "Path to MUD config",
|
37
35
|
},
|
38
|
-
tsgenOutput: { type: "string", demandOption: true, desc: "Directory to output MUD typescript definition files" },
|
39
36
|
});
|
40
37
|
},
|
41
38
|
|
42
39
|
async handler(args) {
|
43
|
-
if (!args.tsgenOutputDir) {
|
44
|
-
console.error("No output provided");
|
45
|
-
}
|
46
|
-
|
47
40
|
// Initial cleanup
|
48
41
|
await forge(["clean"]);
|
49
42
|
|
@@ -137,9 +130,6 @@ const commandModule: CommandModule<Options, Options> = {
|
|
137
130
|
// Run tablegen to generate tables based on the config
|
138
131
|
const outPath = path.join(srcDirectory, config.codegenDirectory);
|
139
132
|
await tablegen(config, outPath);
|
140
|
-
|
141
|
-
// Run tsgen to regenerate recs types based on the mud config
|
142
|
-
await tsgen(config, args.tsgenOutput);
|
143
133
|
}
|
144
134
|
|
145
135
|
/** Codegen to run if contracts changed */
|
package/src/commands/index.ts
CHANGED
@@ -6,7 +6,6 @@ import devnode from "./devnode";
|
|
6
6
|
import faucet from "./faucet";
|
7
7
|
import hello from "./hello";
|
8
8
|
import tablegen from "./tablegen";
|
9
|
-
import tsgen from "./tsgen";
|
10
9
|
import deploy from "./deploy";
|
11
10
|
import worldgen from "./worldgen";
|
12
11
|
import setVersion from "./set-version";
|
@@ -22,7 +21,6 @@ export const commands: CommandModule<any, any>[] = [
|
|
22
21
|
gasReport as CommandModule,
|
23
22
|
hello,
|
24
23
|
tablegen,
|
25
|
-
tsgen,
|
26
24
|
worldgen,
|
27
25
|
setVersion,
|
28
26
|
test,
|
package/src/commands/trace.ts
CHANGED
@@ -5,14 +5,16 @@ import { ethers } from "ethers";
|
|
5
5
|
import { loadConfig } from "@latticexyz/config/node";
|
6
6
|
import { MUDError } from "@latticexyz/common/errors";
|
7
7
|
import { cast, getRpcUrl, getSrcDirectory } from "@latticexyz/common/foundry";
|
8
|
-
import { TableId } from "@latticexyz/common/deprecated";
|
9
8
|
import { StoreConfig } from "@latticexyz/store";
|
10
9
|
import { resolveWorldConfig, WorldConfig } from "@latticexyz/world";
|
11
10
|
import { IBaseWorld } from "@latticexyz/world/types/ethers-contracts/IBaseWorld";
|
12
11
|
import IBaseWorldData from "@latticexyz/world/abi/IBaseWorld.sol/IBaseWorld.json" assert { type: "json" };
|
12
|
+
import worldConfig from "@latticexyz/world/mud.config.js";
|
13
|
+
import { tableIdToHex } from "@latticexyz/common";
|
13
14
|
import { getChainId, getExistingContracts } from "../utils";
|
14
15
|
|
15
|
-
|
16
|
+
// TODO account for multiple namespaces (https://github.com/latticexyz/mud/issues/994)
|
17
|
+
const systemsTableId = tableIdToHex(worldConfig.namespace, worldConfig.tables.Systems.name);
|
16
18
|
|
17
19
|
type Options = {
|
18
20
|
tx: string;
|
@@ -70,11 +72,13 @@ const commandModule: CommandModule<Options, Options> = {
|
|
70
72
|
const namespace = mudConfig.namespace;
|
71
73
|
const names = Object.values(resolvedConfig.systems).map(({ name }) => name);
|
72
74
|
|
75
|
+
// Fetch system table schema from chain
|
76
|
+
const systemTableSchema = await WorldContract.getValueSchema(systemsTableId);
|
73
77
|
const labels: { name: string; address: string }[] = [];
|
74
78
|
for (const name of names) {
|
75
|
-
const systemSelector =
|
79
|
+
const systemSelector = tableIdToHex(namespace, name);
|
76
80
|
// Get the first field of `Systems` table (the table maps system name to its address and other data)
|
77
|
-
const address = await WorldContract.getField(systemsTableId
|
81
|
+
const address = await WorldContract.getField(systemsTableId, [systemSelector], 0, systemTableSchema);
|
78
82
|
labels.push({ name, address });
|
79
83
|
}
|
80
84
|
|
package/src/index.ts
CHANGED
package/src/utils/deploy.ts
CHANGED
@@ -18,7 +18,8 @@ import CoreModuleData from "@latticexyz/world/abi/CoreModule.sol/CoreModule.json
|
|
18
18
|
import KeysWithValueModuleData from "@latticexyz/world/abi/KeysWithValueModule.sol/KeysWithValueModule.json" assert { type: "json" };
|
19
19
|
import KeysInTableModuleData from "@latticexyz/world/abi/KeysInTableModule.sol/KeysInTableModule.json" assert { type: "json" };
|
20
20
|
import UniqueEntityModuleData from "@latticexyz/world/abi/UniqueEntityModule.sol/UniqueEntityModule.json" assert { type: "json" };
|
21
|
-
import
|
21
|
+
import { tableIdToHex } from "@latticexyz/common";
|
22
|
+
import { abiTypesToSchema, schemaToHex } from "@latticexyz/protocol-parser";
|
22
23
|
|
23
24
|
export interface DeployConfig {
|
24
25
|
profile?: string;
|
@@ -113,12 +114,6 @@ export async function deploy(
|
|
113
114
|
disableTxWait,
|
114
115
|
"UniqueEntityModule"
|
115
116
|
),
|
116
|
-
SnapSyncModule: deployContract(
|
117
|
-
SnapSyncModuleData.abi,
|
118
|
-
SnapSyncModuleData.bytecode,
|
119
|
-
disableTxWait,
|
120
|
-
"SnapSyncModule"
|
121
|
-
),
|
122
117
|
};
|
123
118
|
|
124
119
|
// Deploy user Modules
|
@@ -171,15 +166,13 @@ export async function deploy(
|
|
171
166
|
await fastTxExecute(
|
172
167
|
WorldContract,
|
173
168
|
"registerTable",
|
174
|
-
[
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
"setMetadata(bytes16,bytes16,string,string[])",
|
182
|
-
[toBytes16(namespace), toBytes16(name), tableName, Object.keys(schema)],
|
169
|
+
[
|
170
|
+
tableIdToHex(namespace, name),
|
171
|
+
encodeSchema(keyTypes),
|
172
|
+
encodeSchema(schemaTypes),
|
173
|
+
Object.keys(keySchema),
|
174
|
+
Object.keys(schema),
|
175
|
+
],
|
183
176
|
confirmations
|
184
177
|
);
|
185
178
|
|
@@ -197,7 +190,7 @@ export async function deploy(
|
|
197
190
|
await fastTxExecute(
|
198
191
|
WorldContract,
|
199
192
|
"registerSystem",
|
200
|
-
[
|
193
|
+
[tableIdToHex(namespace, name), await contractPromises[systemName], openAccess],
|
201
194
|
confirmations
|
202
195
|
);
|
203
196
|
console.log(chalk.green(`Registered system ${systemName} at ${namespace}/${name}`));
|
@@ -224,14 +217,14 @@ export async function deploy(
|
|
224
217
|
await fastTxExecute(
|
225
218
|
WorldContract,
|
226
219
|
"registerRootFunctionSelector",
|
227
|
-
[
|
220
|
+
[tableIdToHex(namespace, name), worldFunctionSelector, systemFunctionSelector],
|
228
221
|
confirmations
|
229
222
|
);
|
230
223
|
} else {
|
231
224
|
await fastTxExecute(
|
232
225
|
WorldContract,
|
233
226
|
"registerFunctionSelector",
|
234
|
-
[
|
227
|
+
[tableIdToHex(namespace, name), functionName, functionArgs],
|
235
228
|
confirmations
|
236
229
|
);
|
237
230
|
}
|
@@ -256,12 +249,7 @@ export async function deploy(
|
|
256
249
|
...promises,
|
257
250
|
...accessListAddresses.map(async (address) => {
|
258
251
|
console.log(chalk.blue(`Grant ${address} access to ${systemName} (${resourceSelector})`));
|
259
|
-
await fastTxExecute(
|
260
|
-
WorldContract,
|
261
|
-
"grantAccess",
|
262
|
-
[toBytes16(namespace), toBytes16(name), address],
|
263
|
-
confirmations
|
264
|
-
);
|
252
|
+
await fastTxExecute(WorldContract, "grantAccess", [tableIdToHex(namespace, name), address], confirmations);
|
265
253
|
console.log(chalk.green(`Granted ${address} access to ${systemName} (${namespace}/${name})`));
|
266
254
|
}),
|
267
255
|
];
|
@@ -274,7 +262,7 @@ export async function deploy(
|
|
274
262
|
await fastTxExecute(
|
275
263
|
WorldContract,
|
276
264
|
"grantAccess",
|
277
|
-
[
|
265
|
+
[tableIdToHex(namespace, name), await contractPromises[granteeSystem]],
|
278
266
|
confirmations
|
279
267
|
);
|
280
268
|
console.log(chalk.green(`Granted ${granteeSystem} access to ${systemName} (${resourceSelector})`));
|
package/dist/chunk-P7JIR52V.js
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
import{SchemaType as e}from"@latticexyz/schema-type/deprecated";var oe={[e.UINT8]:"RecsType.Number",[e.UINT16]:"RecsType.Number",[e.UINT24]:"RecsType.Number",[e.UINT32]:"RecsType.Number",[e.UINT40]:"RecsType.Number",[e.UINT48]:"RecsType.Number",[e.UINT56]:"RecsType.BigInt",[e.UINT64]:"RecsType.BigInt",[e.UINT72]:"RecsType.BigInt",[e.UINT80]:"RecsType.BigInt",[e.UINT88]:"RecsType.BigInt",[e.UINT96]:"RecsType.BigInt",[e.UINT104]:"RecsType.BigInt",[e.UINT112]:"RecsType.BigInt",[e.UINT120]:"RecsType.BigInt",[e.UINT128]:"RecsType.BigInt",[e.UINT136]:"RecsType.BigInt",[e.UINT144]:"RecsType.BigInt",[e.UINT152]:"RecsType.BigInt",[e.UINT160]:"RecsType.BigInt",[e.UINT168]:"RecsType.BigInt",[e.UINT176]:"RecsType.BigInt",[e.UINT184]:"RecsType.BigInt",[e.UINT192]:"RecsType.BigInt",[e.UINT200]:"RecsType.BigInt",[e.UINT208]:"RecsType.BigInt",[e.UINT216]:"RecsType.BigInt",[e.UINT224]:"RecsType.BigInt",[e.UINT232]:"RecsType.BigInt",[e.UINT240]:"RecsType.BigInt",[e.UINT248]:"RecsType.BigInt",[e.UINT256]:"RecsType.BigInt",[e.INT8]:"RecsType.Number",[e.INT16]:"RecsType.Number",[e.INT24]:"RecsType.Number",[e.INT32]:"RecsType.Number",[e.INT40]:"RecsType.Number",[e.INT48]:"RecsType.Number",[e.INT56]:"RecsType.BigInt",[e.INT64]:"RecsType.BigInt",[e.INT72]:"RecsType.BigInt",[e.INT80]:"RecsType.BigInt",[e.INT88]:"RecsType.BigInt",[e.INT96]:"RecsType.BigInt",[e.INT104]:"RecsType.BigInt",[e.INT112]:"RecsType.BigInt",[e.INT120]:"RecsType.BigInt",[e.INT128]:"RecsType.BigInt",[e.INT136]:"RecsType.BigInt",[e.INT144]:"RecsType.BigInt",[e.INT152]:"RecsType.BigInt",[e.INT160]:"RecsType.BigInt",[e.INT168]:"RecsType.BigInt",[e.INT176]:"RecsType.BigInt",[e.INT184]:"RecsType.BigInt",[e.INT192]:"RecsType.BigInt",[e.INT200]:"RecsType.BigInt",[e.INT208]:"RecsType.BigInt",[e.INT216]:"RecsType.BigInt",[e.INT224]:"RecsType.BigInt",[e.INT232]:"RecsType.BigInt",[e.INT240]:"RecsType.BigInt",[e.INT248]:"RecsType.BigInt",[e.INT256]:"RecsType.BigInt",[e.BYTES1]:"RecsType.String",[e.BYTES2]:"RecsType.String",[e.BYTES3]:"RecsType.String",[e.BYTES4]:"RecsType.String",[e.BYTES5]:"RecsType.String",[e.BYTES6]:"RecsType.String",[e.BYTES7]:"RecsType.String",[e.BYTES8]:"RecsType.String",[e.BYTES9]:"RecsType.String",[e.BYTES10]:"RecsType.String",[e.BYTES11]:"RecsType.String",[e.BYTES12]:"RecsType.String",[e.BYTES13]:"RecsType.String",[e.BYTES14]:"RecsType.String",[e.BYTES15]:"RecsType.String",[e.BYTES16]:"RecsType.String",[e.BYTES17]:"RecsType.String",[e.BYTES18]:"RecsType.String",[e.BYTES19]:"RecsType.String",[e.BYTES20]:"RecsType.String",[e.BYTES21]:"RecsType.String",[e.BYTES22]:"RecsType.String",[e.BYTES23]:"RecsType.String",[e.BYTES24]:"RecsType.String",[e.BYTES25]:"RecsType.String",[e.BYTES26]:"RecsType.String",[e.BYTES27]:"RecsType.String",[e.BYTES28]:"RecsType.String",[e.BYTES29]:"RecsType.String",[e.BYTES30]:"RecsType.String",[e.BYTES31]:"RecsType.String",[e.BYTES32]:"RecsType.String",[e.BOOL]:"RecsType.Boolean",[e.ADDRESS]:"RecsType.String",[e.UINT8_ARRAY]:"RecsType.NumberArray",[e.UINT16_ARRAY]:"RecsType.NumberArray",[e.UINT24_ARRAY]:"RecsType.NumberArray",[e.UINT32_ARRAY]:"RecsType.NumberArray",[e.UINT40_ARRAY]:"RecsType.NumberArray",[e.UINT48_ARRAY]:"RecsType.NumberArray",[e.UINT56_ARRAY]:"RecsType.BigIntArray",[e.UINT64_ARRAY]:"RecsType.BigIntArray",[e.UINT72_ARRAY]:"RecsType.BigIntArray",[e.UINT80_ARRAY]:"RecsType.BigIntArray",[e.UINT88_ARRAY]:"RecsType.BigIntArray",[e.UINT96_ARRAY]:"RecsType.BigIntArray",[e.UINT104_ARRAY]:"RecsType.BigIntArray",[e.UINT112_ARRAY]:"RecsType.BigIntArray",[e.UINT120_ARRAY]:"RecsType.BigIntArray",[e.UINT128_ARRAY]:"RecsType.BigIntArray",[e.UINT136_ARRAY]:"RecsType.BigIntArray",[e.UINT144_ARRAY]:"RecsType.BigIntArray",[e.UINT152_ARRAY]:"RecsType.BigIntArray",[e.UINT160_ARRAY]:"RecsType.BigIntArray",[e.UINT168_ARRAY]:"RecsType.BigIntArray",[e.UINT176_ARRAY]:"RecsType.BigIntArray",[e.UINT184_ARRAY]:"RecsType.BigIntArray",[e.UINT192_ARRAY]:"RecsType.BigIntArray",[e.UINT200_ARRAY]:"RecsType.BigIntArray",[e.UINT208_ARRAY]:"RecsType.BigIntArray",[e.UINT216_ARRAY]:"RecsType.BigIntArray",[e.UINT224_ARRAY]:"RecsType.BigIntArray",[e.UINT232_ARRAY]:"RecsType.BigIntArray",[e.UINT240_ARRAY]:"RecsType.BigIntArray",[e.UINT248_ARRAY]:"RecsType.BigIntArray",[e.UINT256_ARRAY]:"RecsType.BigIntArray",[e.INT8_ARRAY]:"RecsType.NumberArray",[e.INT16_ARRAY]:"RecsType.NumberArray",[e.INT24_ARRAY]:"RecsType.NumberArray",[e.INT32_ARRAY]:"RecsType.NumberArray",[e.INT40_ARRAY]:"RecsType.NumberArray",[e.INT48_ARRAY]:"RecsType.NumberArray",[e.INT56_ARRAY]:"RecsType.BigIntArray",[e.INT64_ARRAY]:"RecsType.BigIntArray",[e.INT72_ARRAY]:"RecsType.BigIntArray",[e.INT80_ARRAY]:"RecsType.BigIntArray",[e.INT88_ARRAY]:"RecsType.BigIntArray",[e.INT96_ARRAY]:"RecsType.BigIntArray",[e.INT104_ARRAY]:"RecsType.BigIntArray",[e.INT112_ARRAY]:"RecsType.BigIntArray",[e.INT120_ARRAY]:"RecsType.BigIntArray",[e.INT128_ARRAY]:"RecsType.BigIntArray",[e.INT136_ARRAY]:"RecsType.BigIntArray",[e.INT144_ARRAY]:"RecsType.BigIntArray",[e.INT152_ARRAY]:"RecsType.BigIntArray",[e.INT160_ARRAY]:"RecsType.BigIntArray",[e.INT168_ARRAY]:"RecsType.BigIntArray",[e.INT176_ARRAY]:"RecsType.BigIntArray",[e.INT184_ARRAY]:"RecsType.BigIntArray",[e.INT192_ARRAY]:"RecsType.BigIntArray",[e.INT200_ARRAY]:"RecsType.BigIntArray",[e.INT208_ARRAY]:"RecsType.BigIntArray",[e.INT216_ARRAY]:"RecsType.BigIntArray",[e.INT224_ARRAY]:"RecsType.BigIntArray",[e.INT232_ARRAY]:"RecsType.BigIntArray",[e.INT240_ARRAY]:"RecsType.BigIntArray",[e.INT248_ARRAY]:"RecsType.BigIntArray",[e.INT256_ARRAY]:"RecsType.BigIntArray",[e.BYTES1_ARRAY]:"RecsType.StringArray",[e.BYTES2_ARRAY]:"RecsType.StringArray",[e.BYTES3_ARRAY]:"RecsType.StringArray",[e.BYTES4_ARRAY]:"RecsType.StringArray",[e.BYTES5_ARRAY]:"RecsType.StringArray",[e.BYTES6_ARRAY]:"RecsType.StringArray",[e.BYTES7_ARRAY]:"RecsType.StringArray",[e.BYTES8_ARRAY]:"RecsType.StringArray",[e.BYTES9_ARRAY]:"RecsType.StringArray",[e.BYTES10_ARRAY]:"RecsType.StringArray",[e.BYTES11_ARRAY]:"RecsType.StringArray",[e.BYTES12_ARRAY]:"RecsType.StringArray",[e.BYTES13_ARRAY]:"RecsType.StringArray",[e.BYTES14_ARRAY]:"RecsType.StringArray",[e.BYTES15_ARRAY]:"RecsType.StringArray",[e.BYTES16_ARRAY]:"RecsType.StringArray",[e.BYTES17_ARRAY]:"RecsType.StringArray",[e.BYTES18_ARRAY]:"RecsType.StringArray",[e.BYTES19_ARRAY]:"RecsType.StringArray",[e.BYTES20_ARRAY]:"RecsType.StringArray",[e.BYTES21_ARRAY]:"RecsType.StringArray",[e.BYTES22_ARRAY]:"RecsType.StringArray",[e.BYTES23_ARRAY]:"RecsType.StringArray",[e.BYTES24_ARRAY]:"RecsType.StringArray",[e.BYTES25_ARRAY]:"RecsType.StringArray",[e.BYTES26_ARRAY]:"RecsType.StringArray",[e.BYTES27_ARRAY]:"RecsType.StringArray",[e.BYTES28_ARRAY]:"RecsType.StringArray",[e.BYTES29_ARRAY]:"RecsType.StringArray",[e.BYTES30_ARRAY]:"RecsType.StringArray",[e.BYTES31_ARRAY]:"RecsType.StringArray",[e.BYTES32_ARRAY]:"RecsType.StringArray",[e.BOOL_ARRAY]:"RecsType.T",[e.ADDRESS_ARRAY]:"RecsType.StringArray",[e.BYTES]:"RecsType.String",[e.STRING]:"RecsType.String"};import{resolveAbiOrUserType as q}from"@latticexyz/store/codegen";import{SchemaTypeToAbiType as se}from"@latticexyz/schema-type/deprecated";function ie(n){let a=[];for(let i of Object.keys(n.tables)){let p=n.tables[i],u=Object.keys(p.schema).map(d=>{let A=p.schema[d],{schemaType:x}=q(A,n);return{recsTypeString:oe[x],name:d}});if(p.tableIdArgument)continue;let h={namespace:n.namespace,name:p.name},y=Object.fromEntries(Object.entries(p.keySchema).map(([d,A])=>[d,se[q(A,n).schemaType]])),D=Object.fromEntries(Object.entries(p.schema).map(([d,A])=>[d,se[q(A,n).schemaType]]));a.push({tableName:i,keySchema:y,valueSchema:D,fields:u,staticResourceData:h})}return{tables:a}}import{TableId as he}from"@latticexyz/common/deprecated";function ae(n){let{tables:a}=n;return`/* Autogenerated file. Do not edit manually. */
|
2
|
-
|
3
|
-
import { defineComponent, Type as RecsType, type World } from "@latticexyz/recs";
|
4
|
-
|
5
|
-
export function defineContractComponents(world: World) {
|
6
|
-
return {
|
7
|
-
${a.map(i=>`${i.tableName}: ${Ee(i)},`).join("")}
|
8
|
-
}
|
9
|
-
}
|
10
|
-
`}function Ee(n){let{namespace:a,name:i}=n.staticResourceData,p=new he(a,i);return`
|
11
|
-
defineComponent(world, {
|
12
|
-
${n.fields.map(({name:u,recsTypeString:h})=>`${u}: ${h}`).join(",")}
|
13
|
-
}, {
|
14
|
-
id: ${JSON.stringify(p.toHex())},
|
15
|
-
metadata: {
|
16
|
-
componentName: ${JSON.stringify(i)},
|
17
|
-
tableName: ${JSON.stringify([a,i].join(":"))},
|
18
|
-
keySchema: ${JSON.stringify(n.keySchema)},
|
19
|
-
valueSchema: ${JSON.stringify(n.valueSchema)},
|
20
|
-
},
|
21
|
-
} as const)
|
22
|
-
`}import Ue from"path";import{formatAndWriteTypescript as $e}from"@latticexyz/common/codegen";async function Rt(n,a){let i=Ue.join(a,"contractComponents.ts"),p=ie(n),u=ae(p);$e(u,i,"Generated ts definition files")}import F from"chalk";import z from"path";import{MUDError as Le}from"@latticexyz/common/errors";import{loadConfig as qe}from"@latticexyz/config/node";import{existsSync as Ce,readFileSync as De}from"fs";import ce from"path";import T from"chalk";import{ethers as O}from"ethers";import{defaultAbiCoder as Pe}from"ethers/lib/utils.js";import{getOutDirectory as Oe,getScriptDirectory as xe,cast as ve,forge as Fe}from"@latticexyz/common/foundry";import{resolveWithContext as je}from"@latticexyz/config";import{MUDError as Y}from"@latticexyz/common/errors";import{encodeSchema as ye}from"@latticexyz/schema-type/deprecated";import{resolveAbiOrUserType as pe}from"@latticexyz/store/codegen";import{resolveWorldConfig as ke}from"@latticexyz/world";import Me from"@latticexyz/world/abi/World.sol/World.json"assert{type:"json"};import Te from"@latticexyz/world/abi/IBaseWorld.sol/IBaseWorld.json"assert{type:"json"};import Re from"@latticexyz/world/abi/CoreModule.sol/CoreModule.json"assert{type:"json"};import le from"@latticexyz/world/abi/KeysWithValueModule.sol/KeysWithValueModule.json"assert{type:"json"};import ge from"@latticexyz/world/abi/KeysInTableModule.sol/KeysInTableModule.json"assert{type:"json"};import Ae from"@latticexyz/world/abi/UniqueEntityModule.sol/UniqueEntityModule.json"assert{type:"json"};import me from"@latticexyz/world/abi/SnapSyncModule.sol/SnapSyncModule.json"assert{type:"json"};async function ue(n,a,i){let p=ke(n,a),u=Date.now(),{worldContractName:h,namespace:y,postDeployScript:D}=n,{profile:d,rpc:A,privateKey:x,priorityFeeMultiplier:S,debug:E,worldAddress:U,disableTxWait:f,pollInterval:v}=i,Be=await Oe(d),M=new O.providers.StaticJsonRpcProvider(A);M.pollingInterval=v;let w=new O.Wallet(x,M);console.log("Deploying from",w.address);let $=await w.getTransactionCount();console.log("Initial nonce",$);let j,W,G;await L(S);let g=[],Q=Number(await ve(["block-number","--rpc-url",A],{profile:d}));console.log("Start deployment at block",Q);let Ne={World:U?Promise.resolve(U):h?K(h,f):C(Te.abi,Me.bytecode,f,"World")},be=Object.keys(p.systems).reduce((t,r)=>(t[r]=K(r,f),t),{}),X={CoreModule:C(Re.abi,Re.bytecode,f,"CoreModule"),KeysWithValueModule:C(le.abi,le.bytecode,f,"KeysWithValueModule"),KeysInTableModule:C(ge.abi,ge.bytecode,f,"KeysInTableModule"),UniqueEntityModule:C(Ae.abi,Ae.bytecode,f,"UniqueEntityModule"),SnapSyncModule:C(me.abi,me.bytecode,f,"SnapSyncModule")},Z=n.modules.filter(t=>!X[t.name]).reduce((t,r)=>(t[r.name]=K(r.name,f),t),X),P={...Ne,...be,...Z},N=new O.Contract(await P.World,Te.abi,w),b=f?0:1;U||(console.log(T.blue("Installing core World modules")),await B(N,"installRootModule",[await Z.CoreModule,"0x"],b),console.log(T.green("Installed core World modules"))),y&&await B(N,"registerNamespace",[m(y)],b);let ee={};g=[...g,...Object.entries(n.tables).map(async([t,{name:r,schema:o,keySchema:c}])=>{console.log(T.blue(`Registering table ${t} at ${y}/${r}`)),ee[t]=We(y,r);let l=Object.values(o).map(R=>{let{schemaType:I}=pe(R,n);return I}),s=Object.values(c).map(R=>{let{schemaType:I}=pe(R,n);return I});await B(N,"registerTable",[m(y),m(r),ye(l),ye(s)],b),await B(N,"setMetadata(bytes16,bytes16,string,string[])",[m(y),m(r),t,Object.keys(o)],b),console.log(T.green(`Registered table ${t} at ${r}`))})],g=[...g,...Object.entries(p.systems).map(async([t,{name:r,openAccess:o,registerFunctionSelectors:c}])=>{if(console.log(T.blue(`Registering system ${t} at ${y}/${r}`)),await B(N,"registerSystem",[m(y),m(r),await P[t],o],b),console.log(T.green(`Registered system ${t} at ${y}/${r}`)),c){let l=await Ye(t),s=y==="";await Promise.all(l.map(async({functionName:R,functionArgs:I})=>{let _=s?R+I:`${y}_${r}_${R}${I}`;if(console.log(T.blue(`Registering function "${_}"`)),s){let we=Ie(_===""?{functionName:t,functionArgs:I}:{functionName:R,functionArgs:I}),_e=Ie({functionName:R,functionArgs:I});await B(N,"registerRootFunctionSelector",[m(y),m(r),we,_e],b)}else await B(N,"registerFunctionSelector",[m(y),m(r),R,I],b);console.log(T.green(`Registered function "${_}"`))}))}})],await Promise.all(g),g=[];for(let[t,{name:r,accessListAddresses:o,accessListSystems:c}]of Object.entries(p.systems)){let l=`${y}/${r}`;g=[...g,...o.map(async s=>{console.log(T.blue(`Grant ${s} access to ${t} (${l})`)),await B(N,"grantAccess",[m(y),m(r),s],b),console.log(T.green(`Granted ${s} access to ${t} (${y}/${r})`))})],g=[...g,...c.map(async s=>{console.log(T.blue(`Grant ${s} access to ${t} (${l})`)),await B(N,"grantAccess",[m(y),m(r),await P[s]],b),console.log(T.green(`Granted ${s} access to ${t} (${l})`))})]}await Promise.all(g),g=[],g=[...g,...n.modules.map(async t=>{console.log(T.blue(`Installing${t.root?" root ":" "}module ${t.name}`));let r=await Promise.all(t.args.map(s=>je(s,{tableIds:ee,systemAddresses:P}))),o=r.map(s=>s.value),c=r.map(s=>s.type),l=await P[t.name];if(!l)throw new Error(`Module ${t.name} not found`);await B(N,t.root?"installRootModule":"installModule",[l,Pe.encode(c,o)],b),console.log(T.green(`Installed${t.root?" root ":" "}module ${t.name}`))})],await Promise.all(g);let k=await w.getTransactionCount(),V=0,te=100;for(;k!==$&&V<te;)console.log(T.gray(`Waiting for transactions to be included before executing ${D} (local nonce: ${$}, remote nonce: ${k}, retry number ${V}/${te})`)),await new Promise(t=>setTimeout(t,v)),V++,k=await w.getTransactionCount();if(k!==$)throw new Y("Remote nonce doesn't match local nonce, indicating that not all deploy transactions were included.");g=[];let J=ce.join(await xe(),D+".s.sol");return Ce(J)?(console.log(T.blue(`Executing post deploy script at ${J}`)),await Fe(["script",D,"--sig","run(address)",await P.World,"--broadcast","--rpc-url",A,"-vvv"],{profile:d})):console.log(`No script at ${J}, skipping post deploy hook`),console.log(T.green("Deployment completed in",(Date.now()-u)/1e3,"seconds")),{worldAddress:await P.World,blockNumber:Q};async function K(t,r){console.log(T.blue("Deploying",t));let{abi:o,bytecode:c}=await ne(t);return C(o,c,r,t)}async function C(t,r,o,c,l=0){try{let s=new O.ContractFactory(t,r,w);console.log(T.gray(`executing deployment of ${c} with nonce ${$}`));let R=s.deploy({nonce:$++,maxPriorityFeePerGas:j,maxFeePerGas:W,gasPrice:G}).then(_=>o?_:_.deployed());g.push(R);let{address:I}=await R;return console.log(T.green("Deployed",c,"to",I)),I}catch(s){if(E&&console.error(s),l===0&&s?.message.includes("transaction already imported"))return L(S*1.1),C(t,r,o,c,l++);throw s?.message.includes("invalid bytecode")?new Y(`Error deploying ${c}: invalid bytecode. Note that linking of public libraries is not supported yet, make sure none of your libraries use "external" functions.`):s?.message.includes("CreateContractLimit")?new Y(`Error deploying ${c}: CreateContractLimit exceeded.`):s}}async function Ye(t){let{abi:r}=await ne(t);return r.filter(o=>["fallback","function"].includes(o.type)).map(o=>o.type==="fallback"?{functionName:"",functionArgs:""}:{functionName:o.name,functionArgs:re(o.inputs)})}function re(t){return`(${t.map(o=>{let c=o.type.match(/tuple(.*)/);return c?re(o.components)+c[1]:o.type})})`}async function B(t,r,o,c=1,l=0){let s=`${r}(${o.map(R=>`'${R}'`).join(",")})`;try{let R=await t.estimateGas[r].apply(null,o);console.log(T.gray(`executing transaction: ${s} with nonce ${$}`));let I=t[r].apply(null,[...o,{gasLimit:R,nonce:$++,maxPriorityFeePerGas:j,maxFeePerGas:W,gasPrice:G}]).then(_=>c===0?_:_.wait(c));return g.push(I),I}catch(R){if(E&&console.error(R),l===0&&R?.message.includes("transaction already imported"))return L(S*1.1),B(t,r,o,c,l++);throw new Y(`Gas estimation error for ${s}: ${R?.reason}`)}}async function ne(t){let r,o=ce.join(Be,t+".sol",t+".json");try{r=JSON.parse(De(o,"utf8"))}catch{throw new Y(`Error reading file at ${o}`)}let c=r?.bytecode?.object;if(!c)throw new Y(`No bytecode found in ${o}`);let l=r?.abi;if(!l)throw new Y(`No ABI found in ${o}`);return{abi:l,bytecode:c}}async function L(t){let r=await M.getFeeData();if(r.lastBaseFeePerGas){if(!r.lastBaseFeePerGas.eq(0)&&(await w.getBalance()).eq(0))throw new Y(`Attempting to deploy to a chain with non-zero base fee with an account that has no balance.
|
23
|
-
If you're deploying to the Lattice testnet, you can fund your account by running 'pnpm mud faucet --address ${await w.getAddress()}'`);j=r.lastBaseFeePerGas.eq(0)?0:Math.floor(15e8*t),W=r.lastBaseFeePerGas.mul(2).add(j)}else if(r.gasPrice){if(!r.gasPrice.eq(0)&&(await w.getBalance()).eq(0))throw new Y("Attempting to deploy to a chain with non-zero gas price with an account that has no balance.");G=r.gasPrice}else throw new Y("Can not fetch fee data from RPC")}}function m(n){if(n.length>16)throw new Error("String does not fit into 16 bytes");let a=new Uint8Array(16);for(let i=0;i<n.length;i++)a[i]=n.charCodeAt(i);for(let i=n.length;i<16;i++)a[i]=0;return a}function We(n,a){let i=m(n),p=m(a),u=new Uint8Array(32);return u.set(i),u.set(p,16),u}function Ie({functionName:n,functionArgs:a}){let i=n+a;return i===""?"0x":Ge(i)}function Ge(n){return O.utils.hexDataSlice(O.utils.keccak256(O.utils.toUtf8Bytes(n)),0,4)}import{forge as Se,getRpcUrl as ze,getSrcDirectory as He}from"@latticexyz/common/foundry";import{existsSync as Qe,mkdirSync as Xe,readFileSync as Ze,writeFileSync as H}from"fs";import{ethers as Ve}from"ethers";async function de(n){let{result:a}=await Ve.utils.fetchJson(n,'{ "id": 42, "jsonrpc": "2.0", "method": "eth_chainId", "params": [ ] }');return Number(a)}import Je from"glob";import{basename as Ke}from"path";function fe(n){return Je.sync(`${n}/**/*.sol`).map(a=>({path:a,basename:Ke(a,".sol")}))}async function or(n){n.profile??=process.env.FOUNDRY_PROFILE;let{configPath:a,printConfig:i,profile:p,clean:u,skipBuild:h}=n,y=n.rpc??await ze(p);console.log(F.bgBlue(F.whiteBright(`
|
24
|
-
Deploying MUD contracts${p?" with profile "+p:""} to RPC ${y}
|
25
|
-
`))),u&&await Se(["clean"],{profile:p}),h||await Se(["build"],{profile:p});let D=n?.srcDir??await He(),d=fe(D).map(({basename:E})=>E),A=await qe(a);i&&console.log(F.green(`
|
26
|
-
Resolved config:
|
27
|
-
`),JSON.stringify(A,null,2));let x=process.env.PRIVATE_KEY;if(!x)throw new Le(`Missing PRIVATE_KEY environment variable.
|
28
|
-
Run 'echo "PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" > .env'
|
29
|
-
in your contracts directory to use the default anvil private key.`);let S=await ue(A,d,{...n,rpc:y,privateKey:x});if(n.saveDeployment){let E=await de(y),U=z.join(A.deploysDirectory,E.toString());Xe(U,{recursive:!0}),H(z.join(U,"latest.json"),JSON.stringify(S,null,2)),H(z.join(U,Date.now()+".json"),JSON.stringify(S,null,2));let f=[1337,31337],v=Qe(A.worldsFile)?JSON.parse(Ze(A.worldsFile,"utf-8")):{};v[E]={address:S.worldAddress,blockNumber:f.includes(E)?void 0:S.blockNumber},H(A.worldsFile,JSON.stringify(v,null,2)),console.log(F.bgGreen(F.whiteBright(`
|
30
|
-
Deployment result (written to ${A.worldsFile} and ${U}):
|
31
|
-
`)))}return console.log(S),S}export{oe as a,ie as b,ae as c,Rt as d,de as e,fe as f,or as g};
|
32
|
-
//# sourceMappingURL=chunk-P7JIR52V.js.map
|