@latticexyz/cli 2.2.18-8d0ce55e964e646a1c804c401df01c4deb866f30 → 2.2.18-9fa07c8489f1fbf167d0db01cd9aaa645a29c8e2

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/mud.cjs ADDED
@@ -0,0 +1,3566 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __esm = (fn, res) => function __init() {
10
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
+ };
12
+ var __export = (target, all) => {
13
+ for (var name in all)
14
+ __defProp(target, name, { get: all[name], enumerable: true });
15
+ };
16
+ var __copyProps = (to, from, except, desc) => {
17
+ if (from && typeof from === "object" || typeof from === "function") {
18
+ for (let key of __getOwnPropNames(from))
19
+ if (!__hasOwnProp.call(to, key) && key !== except)
20
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
21
+ }
22
+ return to;
23
+ };
24
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
25
+ // If the importer is in node compatibility mode or this is not an ESM
26
+ // file that has been converted to a CommonJS file using a Babel-
27
+ // compatible transform (i.e. "__esModule" has not been set), then set
28
+ // "default" to the CommonJS "module.exports" for node compatibility.
29
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
30
+ mod
31
+ ));
32
+
33
+ // ../../node_modules/.pnpm/tsup@8.3.0_@microsoft+api-extractor@7.47.7_@types+node@20.17.16__jiti@1.21.6_postcss@8.5.1_ts_rihtmhm6tp3cagz6w7ivhbdyn4/node_modules/tsup/assets/cjs_shims.js
34
+ var init_cjs_shims = __esm({
35
+ "../../node_modules/.pnpm/tsup@8.3.0_@microsoft+api-extractor@7.47.7_@types+node@20.17.16__jiti@1.21.6_postcss@8.5.1_ts_rihtmhm6tp3cagz6w7ivhbdyn4/node_modules/tsup/assets/cjs_shims.js"() {
36
+ "use strict";
37
+ }
38
+ });
39
+
40
+ // src/utils/errors.ts
41
+ var errors_exports = {};
42
+ __export(errors_exports, {
43
+ logError: () => logError
44
+ });
45
+ function logError(error4) {
46
+ if (error4 instanceof import_zod_validation_error.ValidationError) {
47
+ console.log(import_chalk.default.redBright(error4.message));
48
+ } else if (error4 instanceof import_zod.ZodError) {
49
+ const validationError = (0, import_zod_validation_error.fromZodError)(error4, {
50
+ prefixSeparator: "\n- ",
51
+ issueSeparator: "\n- "
52
+ });
53
+ console.log(import_chalk.default.redBright(validationError.message));
54
+ } else if (error4 instanceof import_errors.MUDError) {
55
+ console.log(import_chalk.default.red(error4));
56
+ } else {
57
+ console.log(error4);
58
+ }
59
+ }
60
+ var import_chalk, import_zod, import_zod_validation_error, import_errors;
61
+ var init_errors = __esm({
62
+ "src/utils/errors.ts"() {
63
+ "use strict";
64
+ init_cjs_shims();
65
+ import_chalk = __toESM(require("chalk"), 1);
66
+ import_zod = require("zod");
67
+ import_zod_validation_error = require("zod-validation-error");
68
+ import_errors = require("@latticexyz/common/errors");
69
+ }
70
+ });
71
+
72
+ // src/build.ts
73
+ async function build({ rootDir, config: config2, foundryProfile }) {
74
+ await Promise.all([(0, import_codegen.tablegen)({ rootDir, config: config2 }), (0, import_node.worldgen)({ rootDir, config: config2 })]);
75
+ await (0, import_foundry.forge)(["build"], { profile: foundryProfile });
76
+ await (0, import_node.buildSystemsManifest)({ rootDir, config: config2 });
77
+ await (0, import_execa.execa)("mud", ["abi-ts"], { stdio: "inherit" });
78
+ }
79
+ var import_codegen, import_node, import_foundry, import_execa;
80
+ var init_build = __esm({
81
+ "src/build.ts"() {
82
+ "use strict";
83
+ init_cjs_shims();
84
+ import_codegen = require("@latticexyz/store/codegen");
85
+ import_node = require("@latticexyz/world/node");
86
+ import_foundry = require("@latticexyz/common/foundry");
87
+ import_execa = require("execa");
88
+ }
89
+ });
90
+
91
+ // src/commands/build.ts
92
+ var import_node2, import_node_path, commandModule, build_default;
93
+ var init_build2 = __esm({
94
+ "src/commands/build.ts"() {
95
+ "use strict";
96
+ init_cjs_shims();
97
+ import_node2 = require("@latticexyz/config/node");
98
+ init_build();
99
+ import_node_path = __toESM(require("path"), 1);
100
+ commandModule = {
101
+ command: "build",
102
+ describe: "Build contracts and generate MUD artifacts (table libraries, world interface, ABI)",
103
+ builder(yargs) {
104
+ return yargs.options({
105
+ configPath: { type: "string", desc: "Path to the MUD config file" },
106
+ profile: { type: "string", desc: "The foundry profile to use" }
107
+ });
108
+ },
109
+ async handler(opts) {
110
+ const configPath = await (0, import_node2.resolveConfigPath)(opts.configPath);
111
+ const config2 = await (0, import_node2.loadConfig)(configPath);
112
+ await build({ rootDir: import_node_path.default.dirname(configPath), config: config2, foundryProfile: opts.profile });
113
+ process.exit(0);
114
+ }
115
+ };
116
+ build_default = commandModule;
117
+ }
118
+ });
119
+
120
+ // src/commands/devnode.ts
121
+ var import_fs, import_os, import_path, import_execa2, commandModule2, devnode_default;
122
+ var init_devnode = __esm({
123
+ "src/commands/devnode.ts"() {
124
+ "use strict";
125
+ init_cjs_shims();
126
+ import_fs = require("fs");
127
+ import_os = require("os");
128
+ import_path = __toESM(require("path"), 1);
129
+ import_execa2 = require("execa");
130
+ commandModule2 = {
131
+ command: "devnode",
132
+ describe: "Start a local Ethereum node for development",
133
+ builder(yargs) {
134
+ return yargs.options({
135
+ blocktime: { type: "number", default: 1, decs: "Interval in which new blocks are produced" }
136
+ });
137
+ },
138
+ async handler({ blocktime }) {
139
+ console.log("Clearing devnode history");
140
+ const userHomeDir = (0, import_os.homedir)();
141
+ (0, import_fs.rmSync)(import_path.default.join(userHomeDir, ".foundry", "anvil", "tmp"), { recursive: true, force: true });
142
+ const anvilArgs = ["-b", String(blocktime), "--block-base-fee-per-gas", "0"];
143
+ console.log(`Running: anvil ${anvilArgs.join(" ")}`);
144
+ const child = (0, import_execa2.execa)("anvil", anvilArgs, {
145
+ stdio: ["inherit", "inherit", "inherit"]
146
+ });
147
+ process.on("SIGINT", () => {
148
+ console.log("\ngracefully shutting down from SIGINT (Crtl-C)");
149
+ child.kill();
150
+ process.exit();
151
+ });
152
+ await child;
153
+ }
154
+ };
155
+ devnode_default = commandModule2;
156
+ }
157
+ });
158
+
159
+ // src/commands/hello.ts
160
+ var commandModule3, hello_default;
161
+ var init_hello = __esm({
162
+ "src/commands/hello.ts"() {
163
+ "use strict";
164
+ init_cjs_shims();
165
+ commandModule3 = {
166
+ command: "hello <name>",
167
+ describe: "Greet <name> with Hello",
168
+ builder(yargs) {
169
+ return yargs.options({
170
+ upper: { type: "boolean" }
171
+ }).positional("name", { type: "string", demandOption: true });
172
+ },
173
+ handler({ name }) {
174
+ const greeting = `Gm, ${name}!`;
175
+ console.log(greeting);
176
+ process.exit(0);
177
+ }
178
+ };
179
+ hello_default = commandModule3;
180
+ }
181
+ });
182
+
183
+ // src/commands/tablegen.ts
184
+ var import_node3, import_codegen2, import_node_path2, commandModule4, tablegen_default;
185
+ var init_tablegen = __esm({
186
+ "src/commands/tablegen.ts"() {
187
+ "use strict";
188
+ init_cjs_shims();
189
+ import_node3 = require("@latticexyz/config/node");
190
+ import_codegen2 = require("@latticexyz/store/codegen");
191
+ import_node_path2 = __toESM(require("path"), 1);
192
+ commandModule4 = {
193
+ command: "tablegen",
194
+ describe: "Autogenerate MUD Store table libraries based on the config file",
195
+ builder(yargs) {
196
+ return yargs.options({
197
+ configPath: { type: "string", desc: "Path to the MUD config file" }
198
+ });
199
+ },
200
+ async handler(opts) {
201
+ const configPath = await (0, import_node3.resolveConfigPath)(opts.configPath);
202
+ const config2 = await (0, import_node3.loadConfig)(configPath);
203
+ await (0, import_codegen2.tablegen)({ rootDir: import_node_path2.default.dirname(configPath), config: config2 });
204
+ process.exit(0);
205
+ }
206
+ };
207
+ tablegen_default = commandModule4;
208
+ }
209
+ });
210
+
211
+ // package.json
212
+ var package_default;
213
+ var init_package = __esm({
214
+ "package.json"() {
215
+ package_default = {
216
+ name: "@latticexyz/cli",
217
+ version: "2.2.17",
218
+ description: "Command line interface for mud",
219
+ repository: {
220
+ type: "git",
221
+ url: "https://github.com/latticexyz/mud.git",
222
+ directory: "packages/cli"
223
+ },
224
+ license: "MIT",
225
+ type: "module",
226
+ exports: {
227
+ ".": {
228
+ import: {
229
+ import: "./dist/index.js",
230
+ types: "./dist/index.d.ts"
231
+ },
232
+ require: {
233
+ require: "./dist/index.cjs",
234
+ types: "./dist/index.d.cts"
235
+ }
236
+ }
237
+ },
238
+ typesVersions: {
239
+ "*": {
240
+ index: [
241
+ "./dist/index.d.ts"
242
+ ]
243
+ }
244
+ },
245
+ bin: {
246
+ mud: "./bin/mud.js"
247
+ },
248
+ files: [
249
+ "bin",
250
+ "dist"
251
+ ],
252
+ scripts: {
253
+ build: "pnpm run build:js && pnpm run build:test-tables",
254
+ "build:js": "tsup",
255
+ "build:test-tables": "tsx ./scripts/generate-test-tables.ts",
256
+ clean: "pnpm run clean:js && pnpm run clean:test-tables",
257
+ "clean:js": "shx rm -rf dist",
258
+ "clean:test-tables": "shx rm -rf src/**/codegen",
259
+ dev: "tsup --watch",
260
+ lint: "eslint . --ext .ts",
261
+ test: "tsc --noEmit && forge test",
262
+ "test:ci": "pnpm run test"
263
+ },
264
+ dependencies: {
265
+ "@ark/util": "0.2.2",
266
+ "@aws-sdk/client-kms": "^3.556.0",
267
+ "@latticexyz/abi-ts": "workspace:*",
268
+ "@latticexyz/block-logs-stream": "workspace:*",
269
+ "@latticexyz/common": "workspace:*",
270
+ "@latticexyz/config": "workspace:*",
271
+ "@latticexyz/gas-report": "workspace:*",
272
+ "@latticexyz/protocol-parser": "workspace:*",
273
+ "@latticexyz/schema-type": "workspace:*",
274
+ "@latticexyz/store": "workspace:*",
275
+ "@latticexyz/store-sync": "workspace:*",
276
+ "@latticexyz/utils": "workspace:*",
277
+ "@latticexyz/world": "workspace:*",
278
+ "@latticexyz/world-module-callwithsignature": "workspace:*",
279
+ "@latticexyz/world-module-metadata": "workspace:*",
280
+ abitype: "1.0.6",
281
+ "asn1.js": "^5.4.1",
282
+ chalk: "^5.0.1",
283
+ chokidar: "^3.5.3",
284
+ debug: "^4.3.4",
285
+ dotenv: "^16.0.3",
286
+ execa: "^9.5.2",
287
+ "find-up": "^6.3.0",
288
+ glob: "^10.4.2",
289
+ openurl: "^1.1.1",
290
+ "p-queue": "^7.4.1",
291
+ "p-retry": "^5.1.2",
292
+ path: "^0.12.7",
293
+ rxjs: "7.5.5",
294
+ "throttle-debounce": "^5.0.0",
295
+ toposort: "^2.0.2",
296
+ viem: "2.21.19",
297
+ yargs: "^17.7.1",
298
+ zod: "3.23.8",
299
+ "zod-validation-error": "^1.3.0"
300
+ },
301
+ devDependencies: {
302
+ "@types/debug": "^4.1.7",
303
+ "@types/ejs": "^3.1.1",
304
+ "@types/openurl": "^1.0.0",
305
+ "@types/throttle-debounce": "^5.0.0",
306
+ "@types/toposort": "^2.0.6",
307
+ "@types/yargs": "^17.0.10",
308
+ "ds-test": "https://github.com/dapphub/ds-test.git#e282159d5170298eb2455a6c05280ab5a73a4ef0",
309
+ "forge-std": "https://github.com/foundry-rs/forge-std.git#74cfb77e308dd188d2f58864aaf44963ae6b88b1"
310
+ }
311
+ };
312
+ }
313
+ });
314
+
315
+ // src/deploy/getWorldContracts.ts
316
+ function getWorldContracts(deployerAddress) {
317
+ const accessManagementSystemDeployedBytecodeSize = (0, import_viem.size)(import_AccessManagementSystem.default.deployedBytecode.object);
318
+ const accessManagementSystemBytecode = import_AccessManagementSystem.default.bytecode.object;
319
+ const accessManagementSystem = (0, import_internal.getContractAddress)({
320
+ deployerAddress,
321
+ bytecode: accessManagementSystemBytecode
322
+ });
323
+ const balanceTransferSystemDeployedBytecodeSize = (0, import_viem.size)(import_BalanceTransferSystem.default.deployedBytecode.object);
324
+ const balanceTransferSystemBytecode = import_BalanceTransferSystem.default.bytecode.object;
325
+ const balanceTransferSystem = (0, import_internal.getContractAddress)({
326
+ deployerAddress,
327
+ bytecode: balanceTransferSystemBytecode
328
+ });
329
+ const batchCallSystemDeployedBytecodeSize = (0, import_viem.size)(import_BatchCallSystem.default.deployedBytecode.object);
330
+ const batchCallSystemBytecode = import_BatchCallSystem.default.bytecode.object;
331
+ const batchCallSystem = (0, import_internal.getContractAddress)({ deployerAddress, bytecode: batchCallSystemBytecode });
332
+ const registrationDeployedBytecodeSize = (0, import_viem.size)(import_RegistrationSystem.default.deployedBytecode.object);
333
+ const registrationBytecode = import_RegistrationSystem.default.bytecode.object;
334
+ const registration = (0, import_internal.getContractAddress)({
335
+ deployerAddress,
336
+ bytecode: registrationBytecode
337
+ });
338
+ const initModuleDeployedBytecodeSize = (0, import_viem.size)(import_InitModule.default.deployedBytecode.object);
339
+ const initModuleBytecode = (0, import_viem.encodeDeployData)({
340
+ bytecode: import_InitModule.default.bytecode.object,
341
+ abi: import_InitModule_abi.default,
342
+ args: [accessManagementSystem, balanceTransferSystem, batchCallSystem, registration]
343
+ });
344
+ const initModule = (0, import_internal.getContractAddress)({ deployerAddress, bytecode: initModuleBytecode });
345
+ return {
346
+ AccessManagementSystem: {
347
+ bytecode: accessManagementSystemBytecode,
348
+ deployedBytecodeSize: accessManagementSystemDeployedBytecodeSize,
349
+ debugLabel: "access management system",
350
+ address: accessManagementSystem
351
+ },
352
+ BalanceTransferSystem: {
353
+ bytecode: balanceTransferSystemBytecode,
354
+ deployedBytecodeSize: balanceTransferSystemDeployedBytecodeSize,
355
+ debugLabel: "balance transfer system",
356
+ address: balanceTransferSystem
357
+ },
358
+ BatchCallSystem: {
359
+ bytecode: batchCallSystemBytecode,
360
+ deployedBytecodeSize: batchCallSystemDeployedBytecodeSize,
361
+ debugLabel: "batch call system",
362
+ address: batchCallSystem
363
+ },
364
+ RegistrationSystem: {
365
+ bytecode: registrationBytecode,
366
+ deployedBytecodeSize: registrationDeployedBytecodeSize,
367
+ debugLabel: "core registration system",
368
+ address: registration
369
+ },
370
+ InitModule: {
371
+ bytecode: initModuleBytecode,
372
+ deployedBytecodeSize: initModuleDeployedBytecodeSize,
373
+ debugLabel: "core module",
374
+ address: initModule
375
+ }
376
+ };
377
+ }
378
+ var import_AccessManagementSystem, import_BalanceTransferSystem, import_BatchCallSystem, import_RegistrationSystem, import_InitModule, import_InitModule_abi, import_viem, import_internal;
379
+ var init_getWorldContracts = __esm({
380
+ "src/deploy/getWorldContracts.ts"() {
381
+ "use strict";
382
+ init_cjs_shims();
383
+ import_AccessManagementSystem = __toESM(require("@latticexyz/world/out/AccessManagementSystem.sol/AccessManagementSystem.json"), 1);
384
+ import_BalanceTransferSystem = __toESM(require("@latticexyz/world/out/BalanceTransferSystem.sol/BalanceTransferSystem.json"), 1);
385
+ import_BatchCallSystem = __toESM(require("@latticexyz/world/out/BatchCallSystem.sol/BatchCallSystem.json"), 1);
386
+ import_RegistrationSystem = __toESM(require("@latticexyz/world/out/RegistrationSystem.sol/RegistrationSystem.json"), 1);
387
+ import_InitModule = __toESM(require("@latticexyz/world/out/InitModule.sol/InitModule.json"), 1);
388
+ import_InitModule_abi = __toESM(require("@latticexyz/world/out/InitModule.sol/InitModule.abi.json"), 1);
389
+ import_viem = require("viem");
390
+ import_internal = require("@latticexyz/common/internal");
391
+ }
392
+ });
393
+
394
+ // src/deploy/getWorldFactoryContracts.ts
395
+ function getWorldFactoryContracts(deployerAddress) {
396
+ const worldContracts = getWorldContracts(deployerAddress);
397
+ const worldFactoryDeployedBytecodeSize = (0, import_viem2.size)(import_WorldFactory.default.deployedBytecode.object);
398
+ const worldFactoryBytecode = (0, import_viem2.encodeDeployData)({
399
+ bytecode: import_WorldFactory.default.bytecode.object,
400
+ abi: import_WorldFactory_abi.default,
401
+ args: [worldContracts.InitModule.address]
402
+ });
403
+ const worldFactory = (0, import_internal2.getContractAddress)({ deployerAddress, bytecode: worldFactoryBytecode });
404
+ return {
405
+ ...worldContracts,
406
+ WorldFactory: {
407
+ bytecode: worldFactoryBytecode,
408
+ deployedBytecodeSize: worldFactoryDeployedBytecodeSize,
409
+ debugLabel: "world factory",
410
+ address: worldFactory
411
+ }
412
+ };
413
+ }
414
+ var import_WorldFactory, import_WorldFactory_abi, import_viem2, import_internal2;
415
+ var init_getWorldFactoryContracts = __esm({
416
+ "src/deploy/getWorldFactoryContracts.ts"() {
417
+ "use strict";
418
+ init_cjs_shims();
419
+ import_WorldFactory = __toESM(require("@latticexyz/world/out/WorldFactory.sol/WorldFactory.json"), 1);
420
+ import_WorldFactory_abi = __toESM(require("@latticexyz/world/out/WorldFactory.sol/WorldFactory.abi.json"), 1);
421
+ import_viem2 = require("viem");
422
+ init_getWorldContracts();
423
+ import_internal2 = require("@latticexyz/common/internal");
424
+ }
425
+ });
426
+
427
+ // src/deploy/getWorldProxyFactoryContracts.ts
428
+ function getWorldProxyFactoryContracts(deployerAddress) {
429
+ const worldContracts = getWorldContracts(deployerAddress);
430
+ const worldProxyFactoryDeployedBytecodeSize = (0, import_viem3.size)(import_WorldProxyFactory.default.deployedBytecode.object);
431
+ const worldProxyFactoryBytecode = (0, import_viem3.encodeDeployData)({
432
+ bytecode: import_WorldProxyFactory.default.bytecode.object,
433
+ abi: import_WorldProxyFactory_abi.default,
434
+ args: [worldContracts.InitModule.address]
435
+ });
436
+ const worldProxyFactory = (0, import_internal3.getContractAddress)({ deployerAddress, bytecode: worldProxyFactoryBytecode });
437
+ return {
438
+ ...worldContracts,
439
+ WorldProxyFactory: {
440
+ bytecode: worldProxyFactoryBytecode,
441
+ deployedBytecodeSize: worldProxyFactoryDeployedBytecodeSize,
442
+ debugLabel: "world proxy factory",
443
+ address: worldProxyFactory
444
+ }
445
+ };
446
+ }
447
+ var import_WorldProxyFactory, import_WorldProxyFactory_abi, import_viem3, import_internal3;
448
+ var init_getWorldProxyFactoryContracts = __esm({
449
+ "src/deploy/getWorldProxyFactoryContracts.ts"() {
450
+ "use strict";
451
+ init_cjs_shims();
452
+ import_WorldProxyFactory = __toESM(require("@latticexyz/world/out/WorldProxyFactory.sol/WorldProxyFactory.json"), 1);
453
+ import_WorldProxyFactory_abi = __toESM(require("@latticexyz/world/out/WorldProxyFactory.sol/WorldProxyFactory.abi.json"), 1);
454
+ import_viem3 = require("viem");
455
+ init_getWorldContracts();
456
+ import_internal3 = require("@latticexyz/common/internal");
457
+ }
458
+ });
459
+
460
+ // src/deploy/ensureWorldFactory.ts
461
+ async function ensureWorldFactory(client, deployerAddress, withWorldProxy) {
462
+ if (withWorldProxy) {
463
+ const contracts2 = getWorldProxyFactoryContracts(deployerAddress);
464
+ await (0, import_internal4.ensureContractsDeployed)({
465
+ client,
466
+ deployerAddress,
467
+ contracts: Object.values(contracts2)
468
+ });
469
+ return contracts2.WorldProxyFactory.address;
470
+ }
471
+ const contracts = getWorldFactoryContracts(deployerAddress);
472
+ await (0, import_internal4.ensureContractsDeployed)({
473
+ client,
474
+ deployerAddress,
475
+ contracts: Object.values(contracts)
476
+ });
477
+ return contracts.WorldFactory.address;
478
+ }
479
+ var import_internal4;
480
+ var init_ensureWorldFactory = __esm({
481
+ "src/deploy/ensureWorldFactory.ts"() {
482
+ "use strict";
483
+ init_cjs_shims();
484
+ init_getWorldFactoryContracts();
485
+ init_getWorldProxyFactoryContracts();
486
+ import_internal4 = require("@latticexyz/common/internal");
487
+ }
488
+ });
489
+
490
+ // src/debug.ts
491
+ var import_debug, debug, error;
492
+ var init_debug = __esm({
493
+ "src/debug.ts"() {
494
+ "use strict";
495
+ init_cjs_shims();
496
+ import_debug = __toESM(require("debug"), 1);
497
+ debug = (0, import_debug.default)("mud:cli");
498
+ error = (0, import_debug.default)("mud:cli");
499
+ debug.log = console.debug.bind(console);
500
+ error.log = console.error.bind(console);
501
+ }
502
+ });
503
+
504
+ // src/deploy/debug.ts
505
+ var debug2, error2;
506
+ var init_debug2 = __esm({
507
+ "src/deploy/debug.ts"() {
508
+ "use strict";
509
+ init_cjs_shims();
510
+ init_debug();
511
+ debug2 = debug.extend("deploy");
512
+ error2 = debug.extend("deploy");
513
+ debug2.log = console.debug.bind(console);
514
+ error2.log = console.error.bind(console);
515
+ }
516
+ });
517
+
518
+ // src/deploy/common.ts
519
+ var import_IBaseWorld_abi, import_store, import_world, worldDeployEvents, worldAbi, supportedStoreVersions, supportedWorldVersions;
520
+ var init_common = __esm({
521
+ "src/deploy/common.ts"() {
522
+ "use strict";
523
+ init_cjs_shims();
524
+ import_IBaseWorld_abi = __toESM(require("@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json"), 1);
525
+ import_store = require("@latticexyz/store");
526
+ import_world = require("@latticexyz/world");
527
+ worldDeployEvents = [import_store.helloStoreEvent, import_world.helloWorldEvent];
528
+ worldAbi = import_IBaseWorld_abi.default;
529
+ supportedStoreVersions = ["2.0.0", "2.0.1", "2.0.2"];
530
+ supportedWorldVersions = ["2.0.0", "2.0.1", "2.0.2"];
531
+ }
532
+ });
533
+
534
+ // src/deploy/logsToWorldDeploy.ts
535
+ function logsToWorldDeploy(logs) {
536
+ const deployLogs = logs.map((log) => {
537
+ try {
538
+ return {
539
+ ...log,
540
+ ...(0, import_viem4.decodeEventLog)({
541
+ strict: true,
542
+ abi: (0, import_viem4.parseAbi)(worldDeployEvents),
543
+ topics: log.topics,
544
+ data: log.data
545
+ }),
546
+ // Log addresses are not checksummed, but we want them checksummed before writing to disk.
547
+ // https://github.com/wevm/viem/issues/2207
548
+ address: (0, import_viem4.getAddress)(log.address)
549
+ };
550
+ } catch (error4) {
551
+ if (error4 instanceof import_viem4.AbiEventSignatureNotFoundError) {
552
+ return;
553
+ }
554
+ throw error4;
555
+ }
556
+ }).filter(import_utils.isDefined);
557
+ const { address, deployBlock, worldVersion, storeVersion } = deployLogs.reduce(
558
+ (deploy2, log) => ({
559
+ ...deploy2,
560
+ address: log.address,
561
+ deployBlock: log.blockNumber,
562
+ ...log.eventName === "HelloWorld" ? { worldVersion: (0, import_viem4.hexToString)(log.args.worldVersion).replace(/\0+$/, "") } : null,
563
+ ...log.eventName === "HelloStore" ? { storeVersion: (0, import_viem4.hexToString)(log.args.storeVersion).replace(/\0+$/, "") } : null
564
+ }),
565
+ {}
566
+ );
567
+ if (address == null) throw new Error("could not find world address");
568
+ if (deployBlock == null) throw new Error("could not find world deploy block number");
569
+ if (worldVersion == null) throw new Error("could not find world version");
570
+ if (storeVersion == null) throw new Error("could not find store version");
571
+ return { address, deployBlock, worldVersion, storeVersion };
572
+ }
573
+ var import_viem4, import_utils;
574
+ var init_logsToWorldDeploy = __esm({
575
+ "src/deploy/logsToWorldDeploy.ts"() {
576
+ "use strict";
577
+ init_cjs_shims();
578
+ import_viem4 = require("viem");
579
+ init_common();
580
+ import_utils = require("@latticexyz/common/utils");
581
+ }
582
+ });
583
+
584
+ // src/deploy/deployWorld.ts
585
+ async function deployWorld(client, deployerAddress, salt, withWorldProxy) {
586
+ const worldFactory = await ensureWorldFactory(client, deployerAddress, withWorldProxy);
587
+ debug2("deploying world");
588
+ const tx = await (0, import_common2.writeContract)(client, {
589
+ chain: client.chain ?? null,
590
+ address: worldFactory,
591
+ abi: import_WorldFactory_abi2.default,
592
+ functionName: "deployWorld",
593
+ args: [salt]
594
+ });
595
+ debug2("waiting for world deploy");
596
+ const receipt = await (0, import_actions.waitForTransactionReceipt)(client, { hash: tx });
597
+ if (receipt.status !== "success") {
598
+ console.error("world deploy failed", receipt);
599
+ throw new Error("world deploy failed");
600
+ }
601
+ const deploy2 = logsToWorldDeploy(receipt.logs);
602
+ debug2("deployed world to", deploy2.address, "at block", deploy2.deployBlock);
603
+ return { ...deploy2, stateBlock: deploy2.deployBlock };
604
+ }
605
+ var import_actions, import_WorldFactory_abi2, import_common2;
606
+ var init_deployWorld = __esm({
607
+ "src/deploy/deployWorld.ts"() {
608
+ "use strict";
609
+ init_cjs_shims();
610
+ import_actions = require("viem/actions");
611
+ init_ensureWorldFactory();
612
+ import_WorldFactory_abi2 = __toESM(require("@latticexyz/world/out/WorldFactory.sol/WorldFactory.abi.json"), 1);
613
+ import_common2 = require("@latticexyz/common");
614
+ init_debug2();
615
+ init_logsToWorldDeploy();
616
+ }
617
+ });
618
+
619
+ // src/deploy/getTables.ts
620
+ async function getTables({
621
+ client,
622
+ worldDeploy,
623
+ indexerUrl,
624
+ chainId
625
+ }) {
626
+ debug2("looking up tables for", worldDeploy.address);
627
+ const { records } = await (0, import_store_sync.getRecords)({
628
+ table: import_mud.default.namespaces.store.tables.Tables,
629
+ worldAddress: worldDeploy.address,
630
+ indexerUrl,
631
+ chainId,
632
+ client,
633
+ fromBlock: worldDeploy.deployBlock,
634
+ toBlock: worldDeploy.stateBlock
635
+ });
636
+ const tables = records.map((record) => {
637
+ const { type, namespace, name } = (0, import_common3.hexToResource)(record.tableId);
638
+ const solidityKeySchema = (0, import_internal5.hexToSchema)(record.keySchema);
639
+ const solidityValueSchema = (0, import_internal5.hexToSchema)(record.valueSchema);
640
+ const keyNames = (0, import_viem5.decodeAbiParameters)((0, import_viem5.parseAbiParameters)("string[]"), record.abiEncodedKeyNames)[0];
641
+ const fieldNames = (0, import_viem5.decodeAbiParameters)((0, import_viem5.parseAbiParameters)("string[]"), record.abiEncodedFieldNames)[0];
642
+ const valueAbiTypes = [...solidityValueSchema.staticFields, ...solidityValueSchema.dynamicFields];
643
+ const keySchema = Object.fromEntries(
644
+ solidityKeySchema.staticFields.map((abiType, i) => [keyNames[i], { type: abiType, internalType: abiType }])
645
+ );
646
+ const valueSchema = Object.fromEntries(
647
+ valueAbiTypes.map((abiType, i) => [fieldNames[i], { type: abiType, internalType: abiType }])
648
+ );
649
+ return {
650
+ type,
651
+ namespace,
652
+ name,
653
+ tableId: record.tableId,
654
+ schema: { ...keySchema, ...valueSchema },
655
+ key: Object.keys(keySchema),
656
+ keySchema,
657
+ keySchemaHex: record.keySchema,
658
+ valueSchema,
659
+ valueSchemaHex: record.valueSchema
660
+ };
661
+ });
662
+ debug2("found", tables.length, "tables for", worldDeploy.address);
663
+ return tables;
664
+ }
665
+ var import_viem5, import_common3, import_internal5, import_mud, import_store_sync;
666
+ var init_getTables = __esm({
667
+ "src/deploy/getTables.ts"() {
668
+ "use strict";
669
+ init_cjs_shims();
670
+ import_viem5 = require("viem");
671
+ import_common3 = require("@latticexyz/common");
672
+ init_debug2();
673
+ import_internal5 = require("@latticexyz/protocol-parser/internal");
674
+ import_mud = __toESM(require("@latticexyz/store/mud.config"), 1);
675
+ import_store_sync = require("@latticexyz/store-sync");
676
+ }
677
+ });
678
+
679
+ // src/deploy/ensureTables.ts
680
+ async function ensureTables({
681
+ client,
682
+ worldDeploy,
683
+ tables,
684
+ indexerUrl,
685
+ chainId
686
+ }) {
687
+ const configTables = new Map(
688
+ tables.map((table) => {
689
+ const keySchema = (0, import_internal6.getSchemaTypes)((0, import_internal6.getKeySchema)(table));
690
+ const valueSchema = (0, import_internal6.getSchemaTypes)((0, import_internal6.getValueSchema)(table));
691
+ const keySchemaHex = (0, import_internal6.keySchemaToHex)(keySchema);
692
+ const valueSchemaHex = (0, import_internal6.valueSchemaToHex)(valueSchema);
693
+ return [
694
+ table.tableId,
695
+ {
696
+ ...table,
697
+ keySchema,
698
+ keySchemaHex,
699
+ valueSchema,
700
+ valueSchemaHex
701
+ }
702
+ ];
703
+ })
704
+ );
705
+ const worldTables = await getTables({ client, worldDeploy, indexerUrl, chainId });
706
+ const existingTables = worldTables.filter(({ tableId }) => configTables.has(tableId));
707
+ if (existingTables.length) {
708
+ debug2("existing tables:", existingTables.map(import_common4.resourceToLabel).join(", "));
709
+ const schemaErrors = existingTables.map((table) => {
710
+ const configTable = configTables.get(table.tableId);
711
+ if (table.keySchemaHex !== configTable.keySchemaHex || table.valueSchemaHex !== configTable.valueSchemaHex) {
712
+ return [
713
+ `"${(0, import_common4.resourceToLabel)(table)}" table:`,
714
+ ` Registered schema: ${JSON.stringify({ schema: (0, import_internal6.getSchemaTypes)(table.schema), key: table.key })}`,
715
+ ` Config schema: ${JSON.stringify({ schema: (0, import_internal6.getSchemaTypes)(configTable.schema), key: configTable.key })}`
716
+ ].join("\n");
717
+ }
718
+ }).filter(import_utils2.isDefined);
719
+ if (schemaErrors.length) {
720
+ throw new Error(
721
+ [
722
+ "Table schemas are immutable, but found registered tables with a different schema than what you have configured.",
723
+ ...schemaErrors,
724
+ "You can either update your config with the registered schema or change the table name to register a new table."
725
+ ].join("\n\n") + "\n"
726
+ );
727
+ }
728
+ }
729
+ const existingTableIds = new Set(existingTables.map(({ tableId }) => tableId));
730
+ const missingTables = tables.filter((table) => !existingTableIds.has(table.tableId));
731
+ if (missingTables.length) {
732
+ debug2("registering tables:", missingTables.map(import_common4.resourceToLabel).join(", "));
733
+ return await Promise.all(
734
+ missingTables.map((table) => {
735
+ const keySchema = (0, import_internal6.getSchemaTypes)((0, import_internal6.getKeySchema)(table));
736
+ const valueSchema = (0, import_internal6.getSchemaTypes)((0, import_internal6.getValueSchema)(table));
737
+ return (0, import_p_retry.default)(
738
+ () => (0, import_common4.writeContract)(client, {
739
+ chain: client.chain ?? null,
740
+ address: worldDeploy.address,
741
+ abi: worldAbi,
742
+ // TODO: replace with batchCall (https://github.com/latticexyz/mud/issues/1645)
743
+ functionName: "registerTable",
744
+ args: [
745
+ table.tableId,
746
+ (0, import_internal6.valueSchemaToFieldLayoutHex)(valueSchema),
747
+ (0, import_internal6.keySchemaToHex)(keySchema),
748
+ (0, import_internal6.valueSchemaToHex)(valueSchema),
749
+ Object.keys(keySchema),
750
+ Object.keys(valueSchema)
751
+ ]
752
+ }),
753
+ {
754
+ retries: 3,
755
+ onFailedAttempt: () => debug2(`failed to register table ${(0, import_common4.resourceToLabel)(table)}, retrying...`)
756
+ }
757
+ );
758
+ })
759
+ );
760
+ }
761
+ return [];
762
+ }
763
+ var import_common4, import_internal6, import_p_retry, import_utils2;
764
+ var init_ensureTables = __esm({
765
+ "src/deploy/ensureTables.ts"() {
766
+ "use strict";
767
+ init_cjs_shims();
768
+ import_common4 = require("@latticexyz/common");
769
+ init_common();
770
+ import_internal6 = require("@latticexyz/protocol-parser/internal");
771
+ init_debug2();
772
+ init_getTables();
773
+ import_p_retry = __toESM(require("p-retry"), 1);
774
+ import_utils2 = require("@latticexyz/common/utils");
775
+ }
776
+ });
777
+
778
+ // src/deploy/getResourceIds.ts
779
+ async function getResourceIds({
780
+ client,
781
+ worldDeploy,
782
+ indexerUrl,
783
+ chainId
784
+ }) {
785
+ debug2("looking up resource IDs for", worldDeploy.address);
786
+ const { records } = await (0, import_store_sync2.getRecords)({
787
+ table: import_mud2.default.namespaces.store.tables.ResourceIds,
788
+ worldAddress: worldDeploy.address,
789
+ indexerUrl,
790
+ chainId,
791
+ client,
792
+ fromBlock: worldDeploy.deployBlock,
793
+ toBlock: worldDeploy.stateBlock
794
+ });
795
+ const resourceIds = records.map((record) => record.resourceId);
796
+ debug2("found", resourceIds.length, "resource IDs for", worldDeploy.address);
797
+ return resourceIds;
798
+ }
799
+ var import_mud2, import_store_sync2;
800
+ var init_getResourceIds = __esm({
801
+ "src/deploy/getResourceIds.ts"() {
802
+ "use strict";
803
+ init_cjs_shims();
804
+ init_debug2();
805
+ import_mud2 = __toESM(require("@latticexyz/store/mud.config"), 1);
806
+ import_store_sync2 = require("@latticexyz/store-sync");
807
+ }
808
+ });
809
+
810
+ // src/deploy/getTableValue.ts
811
+ async function getTableValue({
812
+ client,
813
+ worldDeploy,
814
+ table,
815
+ key
816
+ }) {
817
+ const [staticData, encodedLengths, dynamicData] = await (0, import_actions2.readContract)(client, {
818
+ blockNumber: worldDeploy.stateBlock,
819
+ address: worldDeploy.address,
820
+ abi: worldAbi,
821
+ functionName: "getRecord",
822
+ args: [table.tableId, (0, import_internal7.encodeKey)((0, import_internal7.getSchemaTypes)((0, import_internal7.getKeySchema)(table)), key)]
823
+ // TODO: remove cast once https://github.com/wevm/viem/issues/2125 is resolved
824
+ });
825
+ return (0, import_internal7.decodeValueArgs)((0, import_internal7.getSchemaTypes)((0, import_internal7.getValueSchema)(table)), {
826
+ staticData,
827
+ encodedLengths,
828
+ dynamicData
829
+ });
830
+ }
831
+ var import_internal7, import_actions2;
832
+ var init_getTableValue = __esm({
833
+ "src/deploy/getTableValue.ts"() {
834
+ "use strict";
835
+ init_cjs_shims();
836
+ import_internal7 = require("@latticexyz/protocol-parser/internal");
837
+ init_common();
838
+ import_actions2 = require("viem/actions");
839
+ }
840
+ });
841
+
842
+ // src/deploy/getResourceAccess.ts
843
+ async function getResourceAccess({
844
+ client,
845
+ worldDeploy,
846
+ indexerUrl,
847
+ chainId
848
+ }) {
849
+ debug2("looking up resource access for", worldDeploy.address);
850
+ const { records } = await (0, import_store_sync3.getRecords)({
851
+ table: import_mud3.default.namespaces.world.tables.ResourceAccess,
852
+ worldAddress: worldDeploy.address,
853
+ indexerUrl,
854
+ chainId,
855
+ client,
856
+ fromBlock: worldDeploy.deployBlock,
857
+ toBlock: worldDeploy.stateBlock
858
+ });
859
+ const access = records.filter((record) => record.access).map((record) => ({
860
+ resourceId: record.resourceId,
861
+ address: (0, import_viem6.getAddress)(record.caller)
862
+ }));
863
+ debug2("found", access.length, "resource<>address access pairs");
864
+ return access;
865
+ }
866
+ var import_viem6, import_mud3, import_store_sync3;
867
+ var init_getResourceAccess = __esm({
868
+ "src/deploy/getResourceAccess.ts"() {
869
+ "use strict";
870
+ init_cjs_shims();
871
+ import_viem6 = require("viem");
872
+ init_debug2();
873
+ import_mud3 = __toESM(require("@latticexyz/world/mud.config"), 1);
874
+ import_store_sync3 = require("@latticexyz/store-sync");
875
+ }
876
+ });
877
+
878
+ // src/deploy/getSystems.ts
879
+ async function getSystems({
880
+ client,
881
+ worldDeploy,
882
+ indexerUrl,
883
+ chainId
884
+ }) {
885
+ const [resourceIds, functions, resourceAccess] = await Promise.all([
886
+ getResourceIds({ client, worldDeploy, indexerUrl, chainId }),
887
+ (0, import_world2.getFunctions)({
888
+ client,
889
+ worldAddress: worldDeploy.address,
890
+ fromBlock: worldDeploy.deployBlock,
891
+ toBlock: worldDeploy.stateBlock,
892
+ indexerUrl,
893
+ chainId
894
+ }),
895
+ getResourceAccess({ client, worldDeploy, indexerUrl, chainId })
896
+ ]);
897
+ const systems = resourceIds.map(import_common7.hexToResource).filter((resource) => resource.type === "system");
898
+ debug2("looking up systems:", systems.map(import_common7.resourceToLabel).join(", "));
899
+ return await Promise.all(
900
+ systems.map(async (system) => {
901
+ const { system: address, publicAccess } = await getTableValue({
902
+ client,
903
+ worldDeploy,
904
+ table: import_mud4.default.namespaces.world.tables.Systems,
905
+ key: { systemId: system.resourceId }
906
+ });
907
+ const worldFunctions = functions.filter((func) => func.systemId === system.resourceId);
908
+ return {
909
+ address,
910
+ namespace: system.namespace,
911
+ name: system.name,
912
+ systemId: system.resourceId,
913
+ allowAll: publicAccess,
914
+ allowedAddresses: resourceAccess.filter(({ resourceId }) => resourceId === system.resourceId).map(({ address: address2 }) => address2),
915
+ worldFunctions
916
+ };
917
+ })
918
+ );
919
+ }
920
+ var import_common7, import_world2, import_mud4;
921
+ var init_getSystems = __esm({
922
+ "src/deploy/getSystems.ts"() {
923
+ "use strict";
924
+ init_cjs_shims();
925
+ import_common7 = require("@latticexyz/common");
926
+ import_world2 = require("@latticexyz/store-sync/world");
927
+ init_getResourceIds();
928
+ init_getTableValue();
929
+ init_debug2();
930
+ init_getResourceAccess();
931
+ import_mud4 = __toESM(require("@latticexyz/world/mud.config"), 1);
932
+ }
933
+ });
934
+
935
+ // src/deploy/ensureSystems.ts
936
+ async function ensureSystems({
937
+ client,
938
+ deployerAddress,
939
+ libraryMap,
940
+ worldDeploy,
941
+ systems,
942
+ indexerUrl,
943
+ chainId
944
+ }) {
945
+ const [worldSystems, worldAccess] = await Promise.all([
946
+ getSystems({ client, worldDeploy, indexerUrl, chainId }),
947
+ getResourceAccess({ client, worldDeploy, indexerUrl, chainId })
948
+ ]);
949
+ const existingSystems = systems.filter(
950
+ (system) => worldSystems.some(
951
+ (worldSystem) => worldSystem.systemId === system.systemId && (0, import_viem7.getAddress)(worldSystem.address) === (0, import_viem7.getAddress)(system.prepareDeploy(deployerAddress, libraryMap).address)
952
+ )
953
+ );
954
+ if (existingSystems.length) {
955
+ debug2("existing systems:", existingSystems.map(import_common8.resourceToLabel).join(", "));
956
+ }
957
+ const existingSystemIds = existingSystems.map((system) => system.systemId);
958
+ const missingSystems = systems.filter((system) => !existingSystemIds.includes(system.systemId));
959
+ if (!missingSystems.length) return [];
960
+ const systemsToUpgrade = missingSystems.filter(
961
+ (system) => worldSystems.some(
962
+ (worldSystem) => worldSystem.systemId === system.systemId && (0, import_viem7.getAddress)(worldSystem.address) !== (0, import_viem7.getAddress)(system.prepareDeploy(deployerAddress, libraryMap).address)
963
+ )
964
+ );
965
+ if (systemsToUpgrade.length) {
966
+ debug2("upgrading systems:", systemsToUpgrade.map(import_common8.resourceToLabel).join(", "));
967
+ }
968
+ const systemsToAdd = missingSystems.filter(
969
+ (system) => !worldSystems.some((worldSystem) => worldSystem.systemId === system.systemId)
970
+ );
971
+ if (systemsToAdd.length) {
972
+ debug2("registering new systems:", systemsToAdd.map(import_common8.resourceToLabel).join(", "));
973
+ }
974
+ await (0, import_internal8.ensureContractsDeployed)({
975
+ client,
976
+ deployerAddress,
977
+ contracts: missingSystems.map((system) => ({
978
+ bytecode: system.prepareDeploy(deployerAddress, libraryMap).bytecode,
979
+ deployedBytecodeSize: system.deployedBytecodeSize,
980
+ debugLabel: `${(0, import_common8.resourceToLabel)(system)} system`
981
+ }))
982
+ });
983
+ const registerTxs = await Promise.all(
984
+ missingSystems.map(
985
+ (system) => (0, import_p_retry2.default)(
986
+ () => (0, import_common8.writeContract)(client, {
987
+ chain: client.chain ?? null,
988
+ address: worldDeploy.address,
989
+ abi: worldAbi,
990
+ // TODO: replace with batchCall (https://github.com/latticexyz/mud/issues/1645)
991
+ functionName: "registerSystem",
992
+ args: [system.systemId, system.prepareDeploy(deployerAddress, libraryMap).address, system.allowAll]
993
+ }),
994
+ {
995
+ retries: 3,
996
+ onFailedAttempt: () => debug2(`failed to register system ${(0, import_common8.resourceToLabel)(system)}, retrying...`)
997
+ }
998
+ )
999
+ )
1000
+ );
1001
+ const systemIds = systems.map((system) => system.systemId);
1002
+ const currentAccess = worldAccess.filter(({ resourceId }) => systemIds.includes(resourceId));
1003
+ const desiredAccess = [
1004
+ ...systems.flatMap(
1005
+ (system) => system.allowedAddresses.map((address) => ({ resourceId: system.systemId, address }))
1006
+ ),
1007
+ ...systems.flatMap(
1008
+ (system) => system.allowedSystemIds.map((systemId) => ({
1009
+ resourceId: system.systemId,
1010
+ address: worldSystems.find((s) => s.systemId === systemId)?.address ?? systems.find((s) => s.systemId === systemId)?.prepareDeploy(deployerAddress, libraryMap).address
1011
+ })).filter((access) => access.address != null)
1012
+ )
1013
+ ];
1014
+ const accessToAdd = desiredAccess.filter(
1015
+ (access) => !currentAccess.some(
1016
+ ({ resourceId, address }) => resourceId === access.resourceId && (0, import_viem7.getAddress)(address) === (0, import_viem7.getAddress)(access.address)
1017
+ )
1018
+ );
1019
+ const accessToRemove = currentAccess.filter(
1020
+ (access) => !desiredAccess.some(
1021
+ ({ resourceId, address }) => resourceId === access.resourceId && (0, import_viem7.getAddress)(address) === (0, import_viem7.getAddress)(access.address)
1022
+ )
1023
+ );
1024
+ if (accessToRemove.length) {
1025
+ debug2("revoking", accessToRemove.length, "access grants");
1026
+ }
1027
+ if (accessToAdd.length) {
1028
+ debug2("adding", accessToAdd.length, "access grants");
1029
+ }
1030
+ const accessTxs = await Promise.all([
1031
+ ...accessToRemove.map(
1032
+ (access) => (0, import_p_retry2.default)(
1033
+ () => (0, import_common8.writeContract)(client, {
1034
+ chain: client.chain ?? null,
1035
+ address: worldDeploy.address,
1036
+ abi: worldAbi,
1037
+ functionName: "revokeAccess",
1038
+ args: [access.resourceId, access.address]
1039
+ }),
1040
+ {
1041
+ retries: 3,
1042
+ onFailedAttempt: () => debug2("failed to revoke access, retrying...")
1043
+ }
1044
+ )
1045
+ ),
1046
+ ...accessToAdd.map(
1047
+ (access) => (0, import_p_retry2.default)(
1048
+ () => (0, import_common8.writeContract)(client, {
1049
+ chain: client.chain ?? null,
1050
+ address: worldDeploy.address,
1051
+ abi: worldAbi,
1052
+ functionName: "grantAccess",
1053
+ args: [access.resourceId, access.address]
1054
+ }),
1055
+ {
1056
+ retries: 3,
1057
+ onFailedAttempt: () => debug2("failed to grant access, retrying...")
1058
+ }
1059
+ )
1060
+ )
1061
+ ]);
1062
+ return [...registerTxs, ...accessTxs];
1063
+ }
1064
+ var import_viem7, import_common8, import_p_retry2, import_internal8;
1065
+ var init_ensureSystems = __esm({
1066
+ "src/deploy/ensureSystems.ts"() {
1067
+ "use strict";
1068
+ init_cjs_shims();
1069
+ import_viem7 = require("viem");
1070
+ import_common8 = require("@latticexyz/common");
1071
+ init_common();
1072
+ init_debug2();
1073
+ init_getSystems();
1074
+ init_getResourceAccess();
1075
+ import_p_retry2 = __toESM(require("p-retry"), 1);
1076
+ import_internal8 = require("@latticexyz/common/internal");
1077
+ }
1078
+ });
1079
+
1080
+ // src/deploy/getWorldDeploy.ts
1081
+ async function getWorldDeploy(client, worldAddress, deployBlock) {
1082
+ const address = (0, import_viem8.getAddress)(worldAddress);
1083
+ const stateBlock = await (0, import_actions3.getBlock)(client, { blockTag: "latest" });
1084
+ let deploy2 = deploys.get(address);
1085
+ if (deploy2 != null) {
1086
+ return {
1087
+ ...deploy2,
1088
+ stateBlock: stateBlock.number
1089
+ };
1090
+ }
1091
+ debug2("looking up world deploy for", address);
1092
+ const [fromBlock, toBlock] = deployBlock ? [{ number: deployBlock }, { number: deployBlock }] : [await (0, import_actions3.getBlock)(client, { blockTag: "earliest" }), stateBlock];
1093
+ const blockLogs = await (0, import_block_logs_stream.fetchBlockLogs)({
1094
+ publicClient: client,
1095
+ address,
1096
+ events: (0, import_viem8.parseAbi)(worldDeployEvents),
1097
+ fromBlock: fromBlock.number,
1098
+ toBlock: toBlock.number,
1099
+ maxBlockRange: 100000n
1100
+ });
1101
+ if (blockLogs.length === 0) {
1102
+ throw new Error("could not find `HelloWorld` or `HelloStore` event");
1103
+ }
1104
+ deploy2 = {
1105
+ ...logsToWorldDeploy(blockLogs.flatMap((block) => block.logs)),
1106
+ stateBlock: stateBlock.number
1107
+ };
1108
+ deploys.set(address, deploy2);
1109
+ debug2("found world deploy for", address, "at block", deploy2.deployBlock);
1110
+ return deploy2;
1111
+ }
1112
+ var import_viem8, import_actions3, import_block_logs_stream, deploys;
1113
+ var init_getWorldDeploy = __esm({
1114
+ "src/deploy/getWorldDeploy.ts"() {
1115
+ "use strict";
1116
+ init_cjs_shims();
1117
+ import_viem8 = require("viem");
1118
+ import_actions3 = require("viem/actions");
1119
+ import_block_logs_stream = require("@latticexyz/block-logs-stream");
1120
+ init_common();
1121
+ init_debug2();
1122
+ init_logsToWorldDeploy();
1123
+ deploys = /* @__PURE__ */ new Map();
1124
+ }
1125
+ });
1126
+
1127
+ // src/deploy/ensureFunctions.ts
1128
+ async function ensureFunctions({
1129
+ client,
1130
+ worldDeploy,
1131
+ functions,
1132
+ indexerUrl,
1133
+ chainId
1134
+ }) {
1135
+ const worldFunctions = await (0, import_world3.getFunctions)({
1136
+ client,
1137
+ worldAddress: worldDeploy.address,
1138
+ fromBlock: worldDeploy.deployBlock,
1139
+ toBlock: worldDeploy.stateBlock,
1140
+ indexerUrl,
1141
+ chainId
1142
+ });
1143
+ const worldSelectorToFunction = Object.fromEntries(worldFunctions.map((func) => [func.selector, func]));
1144
+ const toSkip = functions.filter((func) => worldSelectorToFunction[func.selector]);
1145
+ const toAdd = functions.filter((func) => !toSkip.includes(func));
1146
+ if (toSkip.length) {
1147
+ debug2("functions already registered:", toSkip.map((func) => func.signature).join(", "));
1148
+ const wrongSystem = toSkip.filter((func) => func.systemId !== worldSelectorToFunction[func.selector]?.systemId);
1149
+ if (wrongSystem.length) {
1150
+ console.warn(
1151
+ "found",
1152
+ wrongSystem.length,
1153
+ "functions already registered but pointing at a different system ID:",
1154
+ wrongSystem.map((func) => func.signature).join(", ")
1155
+ );
1156
+ }
1157
+ }
1158
+ if (!toAdd.length) return [];
1159
+ debug2("registering functions:", toAdd.map((func) => func.signature).join(", "));
1160
+ return Promise.all(
1161
+ toAdd.map((func) => {
1162
+ const { namespace } = (0, import_common11.hexToResource)(func.systemId);
1163
+ const params = namespace === "" ? {
1164
+ functionName: "registerRootFunctionSelector",
1165
+ args: [
1166
+ func.systemId,
1167
+ // use system function signature as world signature
1168
+ func.systemFunctionSignature,
1169
+ func.systemFunctionSignature
1170
+ ]
1171
+ } : {
1172
+ functionName: "registerFunctionSelector",
1173
+ args: [func.systemId, func.systemFunctionSignature]
1174
+ };
1175
+ return (0, import_p_retry3.default)(
1176
+ () => (0, import_common11.writeContract)(client, {
1177
+ chain: client.chain ?? null,
1178
+ address: worldDeploy.address,
1179
+ abi: worldAbi,
1180
+ ...params
1181
+ }),
1182
+ {
1183
+ retries: 3,
1184
+ onFailedAttempt: () => debug2(`failed to register function ${func.signature}, retrying...`)
1185
+ }
1186
+ );
1187
+ })
1188
+ );
1189
+ }
1190
+ var import_common11, import_world3, import_p_retry3;
1191
+ var init_ensureFunctions = __esm({
1192
+ "src/deploy/ensureFunctions.ts"() {
1193
+ "use strict";
1194
+ init_cjs_shims();
1195
+ import_common11 = require("@latticexyz/common");
1196
+ import_world3 = require("@latticexyz/store-sync/world");
1197
+ init_common();
1198
+ init_debug2();
1199
+ import_p_retry3 = __toESM(require("p-retry"), 1);
1200
+ }
1201
+ });
1202
+
1203
+ // src/deploy/ensureModules.ts
1204
+ async function ensureModules({
1205
+ client,
1206
+ deployerAddress,
1207
+ libraryMap,
1208
+ worldDeploy,
1209
+ modules
1210
+ }) {
1211
+ if (!modules.length) return [];
1212
+ await (0, import_internal9.ensureContractsDeployed)({
1213
+ client,
1214
+ deployerAddress,
1215
+ contracts: modules.map((mod) => ({
1216
+ bytecode: mod.prepareDeploy(deployerAddress, libraryMap).bytecode,
1217
+ deployedBytecodeSize: mod.deployedBytecodeSize,
1218
+ debugLabel: `${mod.name} module`
1219
+ }))
1220
+ });
1221
+ debug2("installing modules:", modules.map((mod) => mod.name).join(", "));
1222
+ return (await Promise.all(
1223
+ modules.map(
1224
+ (mod) => (0, import_p_retry4.default)(
1225
+ async () => {
1226
+ try {
1227
+ const abi = [...worldAbi, ...mod.abi];
1228
+ const moduleAddress = mod.prepareDeploy(deployerAddress, libraryMap).address;
1229
+ const params = mod.installAsRoot ? { functionName: "installRootModule", args: [moduleAddress, mod.installData] } : { functionName: "installModule", args: [moduleAddress, mod.installData] };
1230
+ return await (0, import_common13.writeContract)(client, {
1231
+ chain: client.chain ?? null,
1232
+ address: worldDeploy.address,
1233
+ abi,
1234
+ ...params
1235
+ });
1236
+ } catch (error4) {
1237
+ if (error4 instanceof import_viem9.BaseError && error4.message.includes("Module_AlreadyInstalled")) {
1238
+ debug2(`module ${mod.name} already installed`);
1239
+ return;
1240
+ }
1241
+ if (mod.optional) {
1242
+ debug2(`optional module ${mod.name} install failed, skipping`);
1243
+ debug2(error4);
1244
+ return;
1245
+ }
1246
+ throw error4;
1247
+ }
1248
+ },
1249
+ {
1250
+ retries: 3,
1251
+ onFailedAttempt: () => debug2(`failed to install module ${mod.name}, retrying...`)
1252
+ }
1253
+ )
1254
+ )
1255
+ )).filter(import_utils3.isDefined);
1256
+ }
1257
+ var import_viem9, import_common13, import_utils3, import_p_retry4, import_internal9;
1258
+ var init_ensureModules = __esm({
1259
+ "src/deploy/ensureModules.ts"() {
1260
+ "use strict";
1261
+ init_cjs_shims();
1262
+ import_viem9 = require("viem");
1263
+ import_common13 = require("@latticexyz/common");
1264
+ init_common();
1265
+ init_debug2();
1266
+ import_utils3 = require("@latticexyz/common/utils");
1267
+ import_p_retry4 = __toESM(require("p-retry"), 1);
1268
+ import_internal9 = require("@latticexyz/common/internal");
1269
+ }
1270
+ });
1271
+
1272
+ // src/deploy/ensureNamespaceOwner.ts
1273
+ async function ensureNamespaceOwner({
1274
+ client,
1275
+ worldDeploy,
1276
+ resourceIds,
1277
+ indexerUrl,
1278
+ chainId
1279
+ }) {
1280
+ const desiredNamespaces = Array.from(new Set(resourceIds.map((resourceId) => (0, import_common16.hexToResource)(resourceId).namespace)));
1281
+ const existingResourceIds = await getResourceIds({ client, worldDeploy, indexerUrl, chainId });
1282
+ const existingNamespaces = new Set(existingResourceIds.map((resourceId) => (0, import_common16.hexToResource)(resourceId).namespace));
1283
+ if (existingNamespaces.size) {
1284
+ debug2(
1285
+ "found",
1286
+ existingNamespaces.size,
1287
+ "existing namespaces:",
1288
+ Array.from(existingNamespaces).map((namespace) => namespace === "" ? "<root>" : namespace).join(", ")
1289
+ );
1290
+ }
1291
+ const existingDesiredNamespaces = desiredNamespaces.filter((namespace) => existingNamespaces.has(namespace));
1292
+ const namespaceOwners = await Promise.all(
1293
+ existingDesiredNamespaces.map(async (namespace) => {
1294
+ const { owner } = await getTableValue({
1295
+ client,
1296
+ worldDeploy,
1297
+ table: import_mud5.default.namespaces.world.tables.NamespaceOwner,
1298
+ key: { namespaceId: (0, import_common16.resourceToHex)({ type: "namespace", namespace, name: "" }) }
1299
+ });
1300
+ return [namespace, owner];
1301
+ })
1302
+ );
1303
+ const unauthorizedNamespaces = namespaceOwners.filter(([, owner]) => (0, import_viem10.getAddress)(owner) !== (0, import_viem10.getAddress)(client.account.address)).map(([namespace]) => namespace);
1304
+ if (unauthorizedNamespaces.length) {
1305
+ throw new Error(`You are attempting to deploy to namespaces you do not own: ${unauthorizedNamespaces.join(", ")}`);
1306
+ }
1307
+ const missingNamespaces = desiredNamespaces.filter((namespace) => !existingNamespaces.has(namespace));
1308
+ if (missingNamespaces.length > 0) {
1309
+ debug2("registering namespaces:", Array.from(missingNamespaces).join(", "));
1310
+ }
1311
+ const registrationTxs = Promise.all(
1312
+ missingNamespaces.map(
1313
+ (namespace) => (0, import_common16.writeContract)(client, {
1314
+ chain: client.chain ?? null,
1315
+ address: worldDeploy.address,
1316
+ abi: worldAbi,
1317
+ functionName: "registerNamespace",
1318
+ args: [(0, import_common16.resourceToHex)({ namespace, type: "namespace", name: "" })]
1319
+ })
1320
+ )
1321
+ );
1322
+ return registrationTxs;
1323
+ }
1324
+ var import_viem10, import_common16, import_mud5;
1325
+ var init_ensureNamespaceOwner = __esm({
1326
+ "src/deploy/ensureNamespaceOwner.ts"() {
1327
+ "use strict";
1328
+ init_cjs_shims();
1329
+ import_viem10 = require("viem");
1330
+ init_common();
1331
+ import_common16 = require("@latticexyz/common");
1332
+ init_getResourceIds();
1333
+ init_getTableValue();
1334
+ init_debug2();
1335
+ import_mud5 = __toESM(require("@latticexyz/world/mud.config"), 1);
1336
+ }
1337
+ });
1338
+
1339
+ // src/utils/findPlaceholders.ts
1340
+ function findPlaceholders(linkReferences) {
1341
+ return Object.entries(linkReferences).flatMap(
1342
+ ([path16, contracts]) => Object.entries(contracts).flatMap(
1343
+ ([contractName, locations]) => locations.map(
1344
+ (location) => ({
1345
+ path: path16,
1346
+ name: contractName,
1347
+ start: location.start,
1348
+ length: location.length
1349
+ })
1350
+ )
1351
+ )
1352
+ );
1353
+ }
1354
+ var init_findPlaceholders = __esm({
1355
+ "src/utils/findPlaceholders.ts"() {
1356
+ "use strict";
1357
+ init_cjs_shims();
1358
+ }
1359
+ });
1360
+
1361
+ // src/utils/getContractArtifact.ts
1362
+ function isBytecode(value) {
1363
+ return (0, import_viem11.isHex)(value, { strict: false });
1364
+ }
1365
+ function getContractArtifact(artifactJson) {
1366
+ const artifact = artifactSchema.parse(artifactJson);
1367
+ const placeholders = findPlaceholders(artifact.bytecode.linkReferences ?? {});
1368
+ return {
1369
+ abi: artifact.abi,
1370
+ bytecode: artifact.bytecode.object,
1371
+ placeholders,
1372
+ deployedBytecodeSize: (0, import_viem11.size)(artifact.deployedBytecode.object)
1373
+ };
1374
+ }
1375
+ var import_viem11, import_zod2, import_zod3, bytecodeSchema, artifactSchema;
1376
+ var init_getContractArtifact = __esm({
1377
+ "src/utils/getContractArtifact.ts"() {
1378
+ "use strict";
1379
+ init_cjs_shims();
1380
+ import_viem11 = require("viem");
1381
+ init_findPlaceholders();
1382
+ import_zod2 = require("zod");
1383
+ import_zod3 = require("abitype/zod");
1384
+ bytecodeSchema = import_zod2.z.object({
1385
+ object: import_zod2.z.string().refine(isBytecode),
1386
+ linkReferences: import_zod2.z.record(
1387
+ import_zod2.z.record(
1388
+ import_zod2.z.array(
1389
+ import_zod2.z.object({
1390
+ start: import_zod2.z.number(),
1391
+ length: import_zod2.z.number()
1392
+ })
1393
+ )
1394
+ )
1395
+ ).optional()
1396
+ });
1397
+ artifactSchema = import_zod2.z.object({
1398
+ bytecode: bytecodeSchema,
1399
+ deployedBytecode: bytecodeSchema,
1400
+ abi: import_zod3.Abi
1401
+ });
1402
+ }
1403
+ });
1404
+
1405
+ // src/deploy/createPrepareDeploy.ts
1406
+ function createPrepareDeploy(bytecodeWithPlaceholders, placeholders) {
1407
+ return function prepareDeploy(deployerAddress, libraryMap) {
1408
+ let bytecode = bytecodeWithPlaceholders;
1409
+ if (placeholders.length === 0) {
1410
+ return { bytecode, address: (0, import_internal10.getContractAddress)({ deployerAddress, bytecode }) };
1411
+ }
1412
+ if (!libraryMap) {
1413
+ throw new Error("Libraries must be provided if there are placeholders");
1414
+ }
1415
+ for (const placeholder of placeholders) {
1416
+ const address = libraryMap.getAddress({
1417
+ name: placeholder.name,
1418
+ path: placeholder.path,
1419
+ deployer: deployerAddress
1420
+ });
1421
+ bytecode = (0, import_common17.spliceHex)(bytecode, placeholder.start, placeholder.length, address);
1422
+ }
1423
+ return {
1424
+ bytecode,
1425
+ address: (0, import_internal10.getContractAddress)({ deployerAddress, bytecode })
1426
+ };
1427
+ };
1428
+ }
1429
+ var import_common17, import_internal10;
1430
+ var init_createPrepareDeploy = __esm({
1431
+ "src/deploy/createPrepareDeploy.ts"() {
1432
+ "use strict";
1433
+ init_cjs_shims();
1434
+ import_common17 = require("@latticexyz/common");
1435
+ import_internal10 = require("@latticexyz/common/internal");
1436
+ }
1437
+ });
1438
+
1439
+ // src/deploy/ensureResourceTags.ts
1440
+ async function ensureResourceTags({
1441
+ client,
1442
+ deployerAddress,
1443
+ libraryMap,
1444
+ worldDeploy,
1445
+ tags,
1446
+ valueToHex = import_utils4.identity,
1447
+ indexerUrl,
1448
+ chainId
1449
+ }) {
1450
+ debug2("ensuring", tags.length, "resource tags");
1451
+ debug2("looking up existing resource tags");
1452
+ const { records } = await (0, import_store_sync4.getRecords)({
1453
+ table: import_mud6.default.tables.metadata__ResourceTag,
1454
+ worldAddress: worldDeploy.address,
1455
+ chainId,
1456
+ indexerUrl,
1457
+ client,
1458
+ fromBlock: worldDeploy.deployBlock,
1459
+ toBlock: worldDeploy.stateBlock
1460
+ });
1461
+ debug2("found", records.length, "resource tags");
1462
+ const existingTags = new Map(
1463
+ records.map((tag) => {
1464
+ const key = (0, import_viem12.concatHex)((0, import_internal11.getKeyTuple)(import_mud6.default.tables.metadata__ResourceTag, tag));
1465
+ return [key, tag.value];
1466
+ })
1467
+ );
1468
+ const desiredTags = tags.map(
1469
+ (tag) => ({
1470
+ resource: tag.resourceId,
1471
+ tag: (0, import_viem12.stringToHex)(tag.tag, { size: 32 }),
1472
+ value: valueToHex(tag.value)
1473
+ })
1474
+ );
1475
+ const pendingTags = desiredTags.filter((tag) => {
1476
+ const key = (0, import_viem12.concatHex)((0, import_internal11.getKeyTuple)(import_mud6.default.tables.metadata__ResourceTag, tag));
1477
+ return existingTags.get(key) !== tag.value;
1478
+ });
1479
+ if (pendingTags.length === 0) return [];
1480
+ const moduleTxs = await ensureModules({
1481
+ client,
1482
+ deployerAddress,
1483
+ worldDeploy,
1484
+ libraryMap,
1485
+ modules: [
1486
+ {
1487
+ optional: true,
1488
+ name: "MetadataModule",
1489
+ installAsRoot: false,
1490
+ installData: "0x",
1491
+ prepareDeploy: createPrepareDeploy(metadataModuleArtifact.bytecode, metadataModuleArtifact.placeholders),
1492
+ deployedBytecodeSize: metadataModuleArtifact.deployedBytecodeSize,
1493
+ abi: metadataModuleArtifact.abi
1494
+ }
1495
+ ]
1496
+ });
1497
+ await (0, import_internal12.waitForTransactions)({
1498
+ client,
1499
+ hashes: moduleTxs,
1500
+ debugLabel: "metadata module installation"
1501
+ });
1502
+ debug2("setting", pendingTags.length, "resource tags");
1503
+ return (await Promise.all(
1504
+ pendingTags.map(async (tag) => {
1505
+ const resource = (0, import_common18.hexToResource)(tag.resource);
1506
+ const resourceString = `${resource.type}:${resource.namespace}:${resource.name}`;
1507
+ debug2(`tagging ${resourceString} with ${tag.tag}: ${JSON.stringify(tag.value)}`);
1508
+ try {
1509
+ return await (0, import_common18.writeContract)(client, {
1510
+ chain: client.chain ?? null,
1511
+ address: worldDeploy.address,
1512
+ abi: import_IMetadataSystem_abi.default,
1513
+ // TODO: replace with batchCall (https://github.com/latticexyz/mud/issues/1645)
1514
+ functionName: "metadata__setResourceTag",
1515
+ args: [tag.resource, tag.tag, tag.value]
1516
+ });
1517
+ } catch (error4) {
1518
+ debug2(
1519
+ `failed to set resource tag for ${resourceString}, skipping
1520
+ ${error4 instanceof import_viem12.BaseError ? error4.shortMessage : error4}`
1521
+ );
1522
+ }
1523
+ })
1524
+ )).filter(import_utils4.isDefined);
1525
+ }
1526
+ var import_viem12, import_common18, import_utils4, import_mud6, import_IMetadataSystem_abi, import_MetadataModule, import_internal11, import_store_sync4, import_internal12, metadataModuleArtifact;
1527
+ var init_ensureResourceTags = __esm({
1528
+ "src/deploy/ensureResourceTags.ts"() {
1529
+ "use strict";
1530
+ init_cjs_shims();
1531
+ import_viem12 = require("viem");
1532
+ init_debug2();
1533
+ import_common18 = require("@latticexyz/common");
1534
+ import_utils4 = require("@latticexyz/common/utils");
1535
+ import_mud6 = __toESM(require("@latticexyz/world-module-metadata/mud.config"), 1);
1536
+ import_IMetadataSystem_abi = __toESM(require("@latticexyz/world-module-metadata/out/IMetadataSystem.sol/IMetadataSystem.abi.json"), 1);
1537
+ init_ensureModules();
1538
+ import_MetadataModule = __toESM(require("@latticexyz/world-module-metadata/out/MetadataModule.sol/MetadataModule.json"), 1);
1539
+ init_getContractArtifact();
1540
+ init_createPrepareDeploy();
1541
+ import_internal11 = require("@latticexyz/protocol-parser/internal");
1542
+ import_store_sync4 = require("@latticexyz/store-sync");
1543
+ import_internal12 = require("@latticexyz/common/internal");
1544
+ metadataModuleArtifact = getContractArtifact(import_MetadataModule.default);
1545
+ }
1546
+ });
1547
+
1548
+ // src/deploy/deployCustomWorld.ts
1549
+ function findArtifact(ref, artifacts) {
1550
+ const artifact = artifacts.find((a) => a.sourcePath === ref.sourcePath && a.name === ref.name);
1551
+ if (!artifact) throw new Error(`Could not find referenced artifact at "${ref.sourcePath}:${ref.name}".`);
1552
+ return artifact;
1553
+ }
1554
+ function getDependencies(artifact, artifacts) {
1555
+ return artifact.bytecode.filter((part) => !(0, import_viem13.isHex)(part)).flatMap((ref) => {
1556
+ return getDependencies(findArtifact(ref, artifacts), artifacts);
1557
+ });
1558
+ }
1559
+ function getDeployable(deployerAddress, artifact, artifacts) {
1560
+ return (0, import_viem13.concatHex)(
1561
+ artifact.bytecode.map((ref) => {
1562
+ if ((0, import_viem13.isHex)(ref)) return ref;
1563
+ return (0, import_internal13.getContractAddress)({
1564
+ deployerAddress,
1565
+ bytecode: getDeployable(deployerAddress, findArtifact(ref, artifacts), artifacts)
1566
+ });
1567
+ })
1568
+ );
1569
+ }
1570
+ async function deployCustomWorld({
1571
+ client,
1572
+ deployerAddress,
1573
+ artifacts,
1574
+ customWorld
1575
+ }) {
1576
+ const contracts = getWorldContracts(deployerAddress);
1577
+ await (0, import_internal13.ensureContractsDeployed)({
1578
+ client,
1579
+ deployerAddress,
1580
+ contracts: Object.values(contracts)
1581
+ });
1582
+ const worldArtifact = findArtifact(customWorld, artifacts);
1583
+ const deps = getDependencies(worldArtifact, artifacts);
1584
+ if (deps.length) {
1585
+ debug2(`deploying ${deps.length} world dependencies`);
1586
+ await (0, import_internal13.ensureContractsDeployed)({
1587
+ client,
1588
+ deployerAddress,
1589
+ contracts: deps.map((dep) => getDeployable(deployerAddress, dep, artifacts)).reverse().map((bytecode) => ({ bytecode }))
1590
+ });
1591
+ }
1592
+ debug2("deploying custom world");
1593
+ const deployTx = await (0, import_common19.sendTransaction)(client, {
1594
+ chain: client.chain ?? null,
1595
+ data: (0, import_viem13.encodeDeployData)({
1596
+ abi: worldArtifact.abi,
1597
+ args: [],
1598
+ // TODO (https://github.com/latticexyz/mud/issues/3150)
1599
+ bytecode: getDeployable(deployerAddress, worldArtifact, artifacts)
1600
+ })
1601
+ });
1602
+ debug2("waiting for custom world deploy");
1603
+ const receipt = await (0, import_actions4.waitForTransactionReceipt)(client, { hash: deployTx });
1604
+ if (receipt.status !== "success") {
1605
+ console.error("world deploy failed", receipt);
1606
+ throw new Error("world deploy failed");
1607
+ }
1608
+ const deploy2 = logsToWorldDeploy(receipt.logs);
1609
+ debug2("deployed custom world to", deploy2.address, "at block", deploy2.deployBlock);
1610
+ const initTx = await (0, import_common19.writeContract)(client, {
1611
+ chain: client.chain ?? null,
1612
+ address: deploy2.address,
1613
+ abi: worldAbi,
1614
+ functionName: "initialize",
1615
+ args: [contracts.InitModule.address]
1616
+ });
1617
+ await (0, import_internal13.waitForTransactions)({ client, hashes: [initTx], debugLabel: "world init" });
1618
+ const transferOwnershipTx = await (0, import_common19.writeContract)(client, {
1619
+ chain: client.chain ?? null,
1620
+ address: deploy2.address,
1621
+ abi: worldAbi,
1622
+ functionName: "transferOwnership",
1623
+ args: [(0, import_common19.resourceToHex)({ type: "namespace", namespace: "", name: "" }), client.account.address]
1624
+ });
1625
+ await (0, import_internal13.waitForTransactions)({ client, hashes: [transferOwnershipTx], debugLabel: "world ownership transfer" });
1626
+ return { ...deploy2, stateBlock: deploy2.deployBlock };
1627
+ }
1628
+ var import_viem13, import_actions4, import_common19, import_internal13;
1629
+ var init_deployCustomWorld = __esm({
1630
+ "src/deploy/deployCustomWorld.ts"() {
1631
+ "use strict";
1632
+ init_cjs_shims();
1633
+ import_viem13 = require("viem");
1634
+ import_actions4 = require("viem/actions");
1635
+ import_common19 = require("@latticexyz/common");
1636
+ init_debug2();
1637
+ init_logsToWorldDeploy();
1638
+ init_common();
1639
+ init_getWorldContracts();
1640
+ import_internal13 = require("@latticexyz/common/internal");
1641
+ }
1642
+ });
1643
+
1644
+ // src/deploy/getLibraryMap.ts
1645
+ function getLibraryKey({ path: path16, name }) {
1646
+ return `${path16}:${name}`;
1647
+ }
1648
+ function getLibraryMap(libraries) {
1649
+ const cache = Object.fromEntries(libraries.map((library) => [getLibraryKey(library), library]));
1650
+ const libraryMap = {
1651
+ getAddress: ({ path: path16, name, deployer }) => {
1652
+ const library = cache[getLibraryKey({ path: path16, name })];
1653
+ if (!library) {
1654
+ throw new Error(`Could not find library for bytecode placeholder ${path16}:${name}`);
1655
+ }
1656
+ library.address ??= {};
1657
+ library.address[deployer] ??= library.prepareDeploy(deployer, libraryMap).address;
1658
+ return library.address[deployer];
1659
+ }
1660
+ };
1661
+ return libraryMap;
1662
+ }
1663
+ var init_getLibraryMap = __esm({
1664
+ "src/deploy/getLibraryMap.ts"() {
1665
+ "use strict";
1666
+ init_cjs_shims();
1667
+ }
1668
+ });
1669
+
1670
+ // src/deploy/deploy.ts
1671
+ async function deploy({
1672
+ config: config2,
1673
+ client,
1674
+ tables,
1675
+ systems,
1676
+ libraries,
1677
+ modules = [],
1678
+ artifacts,
1679
+ salt,
1680
+ worldAddress: existingWorldAddress,
1681
+ worldDeployBlock,
1682
+ deployerAddress: initialDeployerAddress,
1683
+ indexerUrl,
1684
+ chainId
1685
+ }) {
1686
+ const deployerAddress = initialDeployerAddress ?? await (0, import_internal14.ensureDeployer)(client);
1687
+ const worldDeploy = existingWorldAddress ? await getWorldDeploy(client, existingWorldAddress, worldDeployBlock) : config2.deploy.customWorld ? await deployCustomWorld({
1688
+ client,
1689
+ deployerAddress,
1690
+ artifacts,
1691
+ customWorld: config2.deploy.customWorld
1692
+ }) : await deployWorld(
1693
+ client,
1694
+ deployerAddress,
1695
+ salt ?? `0x${(0, import_crypto.randomBytes)(32).toString("hex")}`,
1696
+ config2.deploy.upgradeableWorldImplementation
1697
+ );
1698
+ const commonDeployOptions = {
1699
+ client,
1700
+ indexerUrl,
1701
+ chainId,
1702
+ worldDeploy
1703
+ };
1704
+ if (!supportedStoreVersions.includes(worldDeploy.storeVersion)) {
1705
+ throw new Error(`Unsupported Store version: ${worldDeploy.storeVersion}`);
1706
+ }
1707
+ if (!supportedWorldVersions.includes(worldDeploy.worldVersion)) {
1708
+ throw new Error(`Unsupported World version: ${worldDeploy.worldVersion}`);
1709
+ }
1710
+ const libraryMap = getLibraryMap(libraries);
1711
+ await (0, import_internal14.ensureContractsDeployed)({
1712
+ ...commonDeployOptions,
1713
+ deployerAddress,
1714
+ contracts: [
1715
+ ...libraries.map((library) => ({
1716
+ bytecode: library.prepareDeploy(deployerAddress, libraryMap).bytecode,
1717
+ deployedBytecodeSize: library.deployedBytecodeSize,
1718
+ debugLabel: `${library.path}:${library.name} library`
1719
+ })),
1720
+ ...systems.map((system) => ({
1721
+ bytecode: system.prepareDeploy(deployerAddress, libraryMap).bytecode,
1722
+ deployedBytecodeSize: system.deployedBytecodeSize,
1723
+ debugLabel: `${(0, import_common22.resourceToLabel)(system)} system`
1724
+ })),
1725
+ ...modules.map((mod) => ({
1726
+ bytecode: mod.prepareDeploy(deployerAddress, libraryMap).bytecode,
1727
+ deployedBytecodeSize: mod.deployedBytecodeSize,
1728
+ debugLabel: `${mod.name} module`
1729
+ }))
1730
+ ]
1731
+ });
1732
+ const namespaceTxs = await ensureNamespaceOwner({
1733
+ ...commonDeployOptions,
1734
+ resourceIds: [...tables.map(({ tableId }) => tableId), ...systems.map(({ systemId }) => systemId)]
1735
+ });
1736
+ await (0, import_internal14.waitForTransactions)({ client, hashes: namespaceTxs, debugLabel: "namespace registrations" });
1737
+ const tableTxs = await ensureTables({
1738
+ ...commonDeployOptions,
1739
+ tables
1740
+ });
1741
+ const systemTxs = await ensureSystems({
1742
+ ...commonDeployOptions,
1743
+ deployerAddress,
1744
+ libraryMap,
1745
+ systems
1746
+ });
1747
+ await (0, import_internal14.waitForTransactions)({
1748
+ client,
1749
+ hashes: [...tableTxs, ...systemTxs],
1750
+ debugLabel: "table and system registrations"
1751
+ });
1752
+ const functionTxs = await ensureFunctions({
1753
+ ...commonDeployOptions,
1754
+ functions: systems.flatMap((system) => system.worldFunctions)
1755
+ });
1756
+ const moduleTxs = await ensureModules({
1757
+ ...commonDeployOptions,
1758
+ deployerAddress,
1759
+ libraryMap,
1760
+ modules
1761
+ });
1762
+ const namespaceTags = (0, import_utils5.uniqueBy)(
1763
+ [...tables, ...systems].filter(({ namespace, namespaceLabel }) => namespaceLabel !== namespace).map(({ namespace, namespaceLabel }) => ({
1764
+ resourceId: (0, import_common22.resourceToHex)({ type: "namespace", namespace, name: "" }),
1765
+ tag: "label",
1766
+ value: namespaceLabel
1767
+ })),
1768
+ (tag) => tag.resourceId
1769
+ );
1770
+ const tableTags = tables.filter((table) => table.label !== table.name).map(({ tableId: resourceId, label }) => ({ resourceId, tag: "label", value: label }));
1771
+ const systemTags = systems.flatMap(({ name, systemId: resourceId, label, metadata }) => [
1772
+ // only register labels if they differ from the resource ID
1773
+ ...label !== name ? [{ resourceId, tag: "label", value: label }] : [],
1774
+ { resourceId, tag: "abi", value: metadata.abi.join("\n") },
1775
+ { resourceId, tag: "worldAbi", value: metadata.worldAbi.join("\n") }
1776
+ ]);
1777
+ const tagTxs = await ensureResourceTags({
1778
+ ...commonDeployOptions,
1779
+ deployerAddress,
1780
+ libraryMap,
1781
+ tags: [...namespaceTags, ...tableTags, ...systemTags],
1782
+ valueToHex: import_viem14.stringToHex
1783
+ });
1784
+ await (0, import_internal14.waitForTransactions)({
1785
+ client,
1786
+ hashes: [...functionTxs, ...moduleTxs, ...tagTxs],
1787
+ debugLabel: "remaining transactions"
1788
+ });
1789
+ debug2("deploy complete");
1790
+ return worldDeploy;
1791
+ }
1792
+ var import_viem14, import_common22, import_crypto, import_utils5, import_internal14;
1793
+ var init_deploy = __esm({
1794
+ "src/deploy/deploy.ts"() {
1795
+ "use strict";
1796
+ init_cjs_shims();
1797
+ import_viem14 = require("viem");
1798
+ init_deployWorld();
1799
+ init_ensureTables();
1800
+ init_common();
1801
+ init_ensureSystems();
1802
+ init_getWorldDeploy();
1803
+ init_ensureFunctions();
1804
+ init_ensureModules();
1805
+ init_ensureNamespaceOwner();
1806
+ init_debug2();
1807
+ import_common22 = require("@latticexyz/common");
1808
+ import_crypto = require("crypto");
1809
+ init_ensureResourceTags();
1810
+ init_deployCustomWorld();
1811
+ import_utils5 = require("@latticexyz/common/utils");
1812
+ init_getLibraryMap();
1813
+ import_internal14 = require("@latticexyz/common/internal");
1814
+ }
1815
+ });
1816
+
1817
+ // src/utils/getContractData.ts
1818
+ function getContractData(filename, contractName, forgeOutDirectory) {
1819
+ let data;
1820
+ const contractDataPath = import_path2.default.join(forgeOutDirectory, filename, contractName + ".json");
1821
+ try {
1822
+ data = JSON.parse((0, import_fs2.readFileSync)(contractDataPath, "utf8"));
1823
+ } catch (error4) {
1824
+ throw new import_errors2.MUDError(`Error reading file at ${contractDataPath}`);
1825
+ }
1826
+ const bytecode = data?.bytecode?.object;
1827
+ if (!bytecode) throw new import_errors2.MUDError(`No bytecode found in ${contractDataPath}`);
1828
+ const deployedBytecode = data?.deployedBytecode?.object;
1829
+ if (!deployedBytecode) throw new import_errors2.MUDError(`No deployed bytecode found in ${contractDataPath}`);
1830
+ const abi = data?.abi;
1831
+ if (!abi) throw new import_errors2.MUDError(`No ABI found in ${contractDataPath}`);
1832
+ const placeholders = findPlaceholders(data?.bytecode?.linkReferences ?? {});
1833
+ return { abi, bytecode, placeholders, deployedBytecodeSize: (0, import_viem15.size)(deployedBytecode) };
1834
+ }
1835
+ var import_fs2, import_path2, import_errors2, import_viem15;
1836
+ var init_getContractData = __esm({
1837
+ "src/utils/getContractData.ts"() {
1838
+ "use strict";
1839
+ init_cjs_shims();
1840
+ import_fs2 = require("fs");
1841
+ import_path2 = __toESM(require("path"), 1);
1842
+ import_errors2 = require("@latticexyz/common/errors");
1843
+ import_viem15 = require("viem");
1844
+ init_findPlaceholders();
1845
+ }
1846
+ });
1847
+
1848
+ // src/deploy/orderByDependencies.ts
1849
+ function orderByDependencies(items, itemKey, dependencyKeys) {
1850
+ const dependencyOrder = (0, import_toposort.default)(
1851
+ items.flatMap((item) => dependencyKeys(item).map((dependency) => [itemKey(item), dependency]))
1852
+ );
1853
+ return [...items].sort((a, b) => dependencyOrder.indexOf(itemKey(a)) - dependencyOrder.indexOf(itemKey(b)));
1854
+ }
1855
+ var import_toposort;
1856
+ var init_orderByDependencies = __esm({
1857
+ "src/deploy/orderByDependencies.ts"() {
1858
+ "use strict";
1859
+ init_cjs_shims();
1860
+ import_toposort = __toESM(require("toposort"), 1);
1861
+ }
1862
+ });
1863
+
1864
+ // src/deploy/findLibraries.ts
1865
+ function findLibraries(forgeOutDir) {
1866
+ const artifacts = (0, import_glob.globSync)(`${forgeOutDir}/**/*.json`, { ignore: "**/*.abi.json" }).sort().map((path16) => JSON.parse((0, import_fs3.readFileSync)(path16, "utf8")));
1867
+ const libraries = artifacts.flatMap((artifact) => {
1868
+ if (!artifact.metadata) return [];
1869
+ const contractPath = Object.keys(artifact.metadata.settings.compilationTarget)[0];
1870
+ const contractName = artifact.metadata.settings.compilationTarget[contractPath];
1871
+ const linkReferences = artifact.bytecode.linkReferences;
1872
+ return Object.entries(linkReferences).flatMap(
1873
+ ([libraryPath, reference]) => Object.keys(reference).map((libraryName) => ({
1874
+ path: libraryPath,
1875
+ name: libraryName,
1876
+ dependentPath: contractPath,
1877
+ dependentName: contractName
1878
+ }))
1879
+ );
1880
+ });
1881
+ return orderByDependencies(
1882
+ libraries,
1883
+ (lib) => `${lib.path}:${lib.name}`,
1884
+ (lib) => [`${lib.dependentPath}:${lib.dependentName}`]
1885
+ );
1886
+ }
1887
+ var import_fs3, import_glob;
1888
+ var init_findLibraries = __esm({
1889
+ "src/deploy/findLibraries.ts"() {
1890
+ "use strict";
1891
+ init_cjs_shims();
1892
+ import_fs3 = require("fs");
1893
+ import_glob = require("glob");
1894
+ init_orderByDependencies();
1895
+ }
1896
+ });
1897
+
1898
+ // src/deploy/compat/excludeUnstableCallWithSignatureModule.ts
1899
+ function excludeCallWithSignatureModule(mod) {
1900
+ if (mod.artifactPath === "@latticexyz/world-modules/out/Unstable_CallWithSignatureModule.sol/Unstable_CallWithSignatureModule.json") {
1901
+ console.warn(
1902
+ [
1903
+ "",
1904
+ `\u26A0\uFE0F Your \`mud.config.ts\` is using \`Unstable_CallWithSignatureModule\`. This module can be removed from your config as it is now installed by default during deploy.`,
1905
+ ""
1906
+ ].join("\n")
1907
+ );
1908
+ return false;
1909
+ }
1910
+ return true;
1911
+ }
1912
+ var init_excludeUnstableCallWithSignatureModule = __esm({
1913
+ "src/deploy/compat/excludeUnstableCallWithSignatureModule.ts"() {
1914
+ "use strict";
1915
+ init_cjs_shims();
1916
+ }
1917
+ });
1918
+
1919
+ // src/deploy/resolveConfig.ts
1920
+ async function resolveConfig({
1921
+ rootDir,
1922
+ config: config2,
1923
+ forgeOutDir
1924
+ }) {
1925
+ const requirePath = await (0, import_find_up.findUp)("package.json");
1926
+ if (!requirePath) throw new Error("Could not find package.json to import relative to.");
1927
+ const require2 = (0, import_node_module.createRequire)(requirePath);
1928
+ const moduleOutDirs = config2.modules.filter(excludeCallWithSignatureModule).flatMap((mod) => {
1929
+ if (mod.artifactPath == void 0) {
1930
+ return [];
1931
+ }
1932
+ const moduleOutDir = import_path3.default.join(require2.resolve(mod.artifactPath), "../../");
1933
+ return [moduleOutDir];
1934
+ });
1935
+ const libraries = [forgeOutDir, ...moduleOutDirs].flatMap(
1936
+ (outDir) => findLibraries(outDir).map((library) => {
1937
+ const contractData = getContractData(import_path3.default.basename(library.path), library.name, outDir);
1938
+ return {
1939
+ path: library.path,
1940
+ name: library.name,
1941
+ abi: contractData.abi,
1942
+ prepareDeploy: createPrepareDeploy(contractData.bytecode, contractData.placeholders),
1943
+ deployedBytecodeSize: contractData.deployedBytecodeSize
1944
+ };
1945
+ })
1946
+ );
1947
+ const baseSystemContractData = getContractData("System.sol", "System", forgeOutDir);
1948
+ const baseSystemFunctions = baseSystemContractData.abi.filter((item) => item.type === "function").map(import_viem16.toFunctionSignature);
1949
+ const configSystems = await (0, import_node4.resolveSystems)({ rootDir, config: config2 });
1950
+ const systemsManifest = await (0, import_node4.loadSystemsManifest)({ rootDir, config: config2 });
1951
+ const systems = configSystems.filter((system) => !system.deploy.disabled).map((system) => {
1952
+ const manifest = systemsManifest.systems.find(({ systemId }) => systemId === system.systemId);
1953
+ if (!manifest) {
1954
+ throw new Error(
1955
+ `System "${system.label}" not found in systems manifest. Run \`mud build\` before trying again.`
1956
+ );
1957
+ }
1958
+ const contractData = getContractData(`${system.label}.sol`, system.label, forgeOutDir);
1959
+ const worldFunctions = system.deploy.registerWorldFunctions ? contractData.abi.filter((item) => item.type === "function").map(import_viem16.toFunctionSignature).filter((sig) => !baseSystemFunctions.includes(sig)).map((sig) => {
1960
+ const worldSignature = system.namespace === "" ? sig : `${system.namespace}__${sig}`;
1961
+ return {
1962
+ signature: worldSignature,
1963
+ selector: (0, import_viem16.toFunctionSelector)(worldSignature),
1964
+ systemId: system.systemId,
1965
+ systemFunctionSignature: sig,
1966
+ systemFunctionSelector: (0, import_viem16.toFunctionSelector)(sig)
1967
+ };
1968
+ }) : [];
1969
+ const allowedAddresses = system.accessList.filter((target) => (0, import_viem16.isHex)(target));
1970
+ const allowedSystemIds = system.accessList.filter((target) => !(0, import_viem16.isHex)(target)).map((label) => {
1971
+ const system2 = configSystems.find((s) => s.label === label);
1972
+ return system2.systemId;
1973
+ });
1974
+ return {
1975
+ ...system,
1976
+ allowAll: system.openAccess,
1977
+ allowedAddresses,
1978
+ allowedSystemIds,
1979
+ prepareDeploy: createPrepareDeploy(contractData.bytecode, contractData.placeholders),
1980
+ deployedBytecodeSize: contractData.deployedBytecodeSize,
1981
+ worldFunctions,
1982
+ abi: contractData.abi,
1983
+ metadata: {
1984
+ abi: manifest.abi,
1985
+ worldAbi: manifest.worldAbi
1986
+ }
1987
+ };
1988
+ });
1989
+ const systemsById = (0, import_utils6.groupBy)(systems, (system) => system.systemId);
1990
+ const overlappingSystems = Array.from(systemsById.values()).filter((matches) => matches.length > 1).flat();
1991
+ if (overlappingSystems.length) {
1992
+ const names = overlappingSystems.map((system) => system.name);
1993
+ throw new Error(
1994
+ `Found systems with overlapping system ID: ${names.join(
1995
+ ", "
1996
+ )}.
1997
+
1998
+ System IDs are generated from the first 16 bytes of the name, so you may need to rename them to avoid the overlap.`
1999
+ );
2000
+ }
2001
+ return {
2002
+ systems,
2003
+ libraries
2004
+ };
2005
+ }
2006
+ var import_path3, import_node4, import_viem16, import_utils6, import_find_up, import_node_module;
2007
+ var init_resolveConfig = __esm({
2008
+ "src/deploy/resolveConfig.ts"() {
2009
+ "use strict";
2010
+ init_cjs_shims();
2011
+ import_path3 = __toESM(require("path"), 1);
2012
+ import_node4 = require("@latticexyz/world/node");
2013
+ import_viem16 = require("viem");
2014
+ init_getContractData();
2015
+ import_utils6 = require("@latticexyz/common/utils");
2016
+ init_findLibraries();
2017
+ init_createPrepareDeploy();
2018
+ import_find_up = require("find-up");
2019
+ import_node_module = require("module");
2020
+ init_excludeUnstableCallWithSignatureModule();
2021
+ }
2022
+ });
2023
+
2024
+ // src/utils/postDeploy.ts
2025
+ async function postDeploy(postDeployScript, worldAddress, rpc, profile, forgeOptions, kms) {
2026
+ const userOptions = forgeOptions?.replaceAll("\\", "").split(" ") ?? [];
2027
+ const postDeployPath = import_path4.default.join(await (0, import_foundry2.getScriptDirectory)(), postDeployScript + ".s.sol");
2028
+ if (!(0, import_fs4.existsSync)(postDeployPath)) {
2029
+ console.log(`No script at ${postDeployPath}, skipping post deploy hook`);
2030
+ return;
2031
+ }
2032
+ console.log(import_chalk2.default.blue(`Executing post deploy script at ${postDeployPath}`));
2033
+ await (0, import_foundry2.forge)(
2034
+ [
2035
+ "script",
2036
+ postDeployScript,
2037
+ "--broadcast",
2038
+ "--sig",
2039
+ "run(address)",
2040
+ worldAddress,
2041
+ "--rpc-url",
2042
+ rpc,
2043
+ "-vvv",
2044
+ kms ? "--aws" : "",
2045
+ ...userOptions
2046
+ ],
2047
+ {
2048
+ profile
2049
+ }
2050
+ );
2051
+ }
2052
+ var import_fs4, import_path4, import_chalk2, import_foundry2;
2053
+ var init_postDeploy = __esm({
2054
+ "src/utils/postDeploy.ts"() {
2055
+ "use strict";
2056
+ init_cjs_shims();
2057
+ import_fs4 = require("fs");
2058
+ import_path4 = __toESM(require("path"), 1);
2059
+ import_chalk2 = __toESM(require("chalk"), 1);
2060
+ import_foundry2 = require("@latticexyz/common/foundry");
2061
+ }
2062
+ });
2063
+
2064
+ // src/utils/importContractArtifact.ts
2065
+ async function importContractArtifact({
2066
+ packageJsonPath,
2067
+ artifactPath
2068
+ }) {
2069
+ let artfactJson;
2070
+ try {
2071
+ const requirePath = packageJsonPath ?? await (0, import_find_up2.findUp)("package.json", { cwd: process.cwd() });
2072
+ if (!requirePath) throw new Error("Could not find package.json to import relative to.");
2073
+ const require2 = (0, import_node_module2.createRequire)(requirePath);
2074
+ artfactJson = require2(artifactPath);
2075
+ } catch (error4) {
2076
+ console.error();
2077
+ console.error("Could not import contract artifact at", artifactPath);
2078
+ console.error();
2079
+ throw error4;
2080
+ }
2081
+ return getContractArtifact(artfactJson);
2082
+ }
2083
+ var import_node_module2, import_find_up2;
2084
+ var init_importContractArtifact = __esm({
2085
+ "src/utils/importContractArtifact.ts"() {
2086
+ "use strict";
2087
+ init_cjs_shims();
2088
+ import_node_module2 = require("module");
2089
+ import_find_up2 = require("find-up");
2090
+ init_getContractArtifact();
2091
+ }
2092
+ });
2093
+
2094
+ // src/deploy/configToModules.ts
2095
+ async function configToModules(config2, forgeOutDir) {
2096
+ const defaultModules = [
2097
+ {
2098
+ // optional for now
2099
+ // TODO: figure out approach to install on existing worlds where deployer may not own root namespace
2100
+ optional: true,
2101
+ name: "CallWithSignatureModule",
2102
+ installAsRoot: true,
2103
+ installData: "0x",
2104
+ prepareDeploy: createPrepareDeploy(
2105
+ callWithSignatureModuleArtifact.bytecode,
2106
+ callWithSignatureModuleArtifact.placeholders
2107
+ ),
2108
+ deployedBytecodeSize: callWithSignatureModuleArtifact.deployedBytecodeSize,
2109
+ abi: callWithSignatureModuleArtifact.abi
2110
+ }
2111
+ ];
2112
+ const modules = await Promise.all(
2113
+ config2.modules.filter(excludeCallWithSignatureModule).map(async (mod) => {
2114
+ let artifactPath = mod.artifactPath;
2115
+ if (!artifactPath) {
2116
+ if (mod.name) {
2117
+ artifactPath = knownModuleArtifacts[mod.name] ?? import_node_path3.default.join(forgeOutDir, `${mod.name}.sol`, `${mod.name}.json`);
2118
+ console.warn(
2119
+ [
2120
+ "",
2121
+ `\u26A0\uFE0F Your \`mud.config.ts\` is using a module with a \`name\`, but this option is deprecated.`,
2122
+ "",
2123
+ "To resolve this, you can replace this:",
2124
+ "",
2125
+ ` name: ${JSON.stringify(mod.name)}`,
2126
+ "",
2127
+ "with this:",
2128
+ "",
2129
+ ` artifactPath: ${JSON.stringify(artifactPath)}`,
2130
+ ""
2131
+ ].join("\n")
2132
+ );
2133
+ } else {
2134
+ throw new Error("No `artifactPath` provided for module.");
2135
+ }
2136
+ }
2137
+ const name = import_node_path3.default.basename(artifactPath, ".json");
2138
+ const artifact = await importContractArtifact({ artifactPath });
2139
+ const installArgs = mod.args.map((arg) => (0, import_internal16.resolveWithContext)(arg, { config: config2 })).map((arg) => {
2140
+ const value = arg.value instanceof Uint8Array ? (0, import_viem17.bytesToHex)(arg.value) : arg.value;
2141
+ return (0, import_internal15.encodeField)(arg.type, value);
2142
+ });
2143
+ if (installArgs.length > 1) {
2144
+ throw new Error(`${name} module should only have 0-1 args, but had ${installArgs.length} args.`);
2145
+ }
2146
+ return {
2147
+ name,
2148
+ installAsRoot: mod.root,
2149
+ installData: installArgs.length === 0 ? "0x" : installArgs[0],
2150
+ prepareDeploy: createPrepareDeploy(artifact.bytecode, artifact.placeholders),
2151
+ deployedBytecodeSize: artifact.deployedBytecodeSize,
2152
+ abi: artifact.abi
2153
+ };
2154
+ })
2155
+ );
2156
+ return [...defaultModules, ...modules];
2157
+ }
2158
+ var import_node_path3, import_internal15, import_viem17, import_internal16, import_CallWithSignatureModule, callWithSignatureModuleArtifact, knownModuleArtifacts;
2159
+ var init_configToModules = __esm({
2160
+ "src/deploy/configToModules.ts"() {
2161
+ "use strict";
2162
+ init_cjs_shims();
2163
+ import_node_path3 = __toESM(require("path"), 1);
2164
+ import_internal15 = require("@latticexyz/protocol-parser/internal");
2165
+ import_viem17 = require("viem");
2166
+ init_createPrepareDeploy();
2167
+ init_importContractArtifact();
2168
+ import_internal16 = require("@latticexyz/world/internal");
2169
+ import_CallWithSignatureModule = __toESM(require("@latticexyz/world-module-callwithsignature/out/CallWithSignatureModule.sol/CallWithSignatureModule.json"), 1);
2170
+ init_getContractArtifact();
2171
+ init_excludeUnstableCallWithSignatureModule();
2172
+ callWithSignatureModuleArtifact = getContractArtifact(import_CallWithSignatureModule.default);
2173
+ knownModuleArtifacts = {
2174
+ KeysWithValueModule: "@latticexyz/world-modules/out/KeysWithValueModule.sol/KeysWithValueModule.json",
2175
+ KeysInTableModule: "@latticexyz/world-modules/out/KeysInTableModule.sol/KeysInTableModule.json",
2176
+ UniqueEntityModule: "@latticexyz/world-modules/out/UniqueEntityModule.sol/UniqueEntityModule.json"
2177
+ };
2178
+ }
2179
+ });
2180
+
2181
+ // src/utils/enableAutomine.ts
2182
+ async function enableAutomine(client) {
2183
+ const miningMode = await getMiningMode(client).catch(() => void 0);
2184
+ if (!miningMode || miningMode.type === "automine") return;
2185
+ debug("Enabling automine");
2186
+ await setMiningMode(client, { type: "automine" });
2187
+ return {
2188
+ reset: () => {
2189
+ debug("Disabling automine");
2190
+ return setMiningMode(client, miningMode);
2191
+ }
2192
+ };
2193
+ }
2194
+ async function getMiningMode(client) {
2195
+ const localClient = { mode: "anvil", ...client };
2196
+ const isAutomine = await (0, import_utils7.getAction)(localClient, import_actions5.getAutomine, "getAutomine")({});
2197
+ if (isAutomine) {
2198
+ return { type: "automine" };
2199
+ }
2200
+ const blockTime = await getBlockTime(client);
2201
+ return { type: "interval", blockTime };
2202
+ }
2203
+ async function setMiningMode(client, miningMode) {
2204
+ if (miningMode.type === "automine") {
2205
+ await (0, import_utils7.getAction)(client, import_actions5.setAutomine, "setAutomine")(true);
2206
+ } else {
2207
+ await (0, import_utils7.getAction)(client, import_actions5.setIntervalMining, "setIntervalMining")({ interval: miningMode.blockTime });
2208
+ }
2209
+ }
2210
+ async function getBlockTime(client) {
2211
+ const latestBlock = await (0, import_utils7.getAction)(client, import_actions5.getBlock, "getBlock")({ blockTag: "latest" });
2212
+ const previousBlock = await (0, import_utils7.getAction)(client, import_actions5.getBlock, "getBlock")({ blockNumber: latestBlock.number - 1n });
2213
+ const blockTime = latestBlock.timestamp - previousBlock.timestamp;
2214
+ return Number(blockTime);
2215
+ }
2216
+ var import_actions5, import_utils7;
2217
+ var init_enableAutomine = __esm({
2218
+ "src/utils/enableAutomine.ts"() {
2219
+ "use strict";
2220
+ init_cjs_shims();
2221
+ import_actions5 = require("viem/actions");
2222
+ init_debug();
2223
+ import_utils7 = require("viem/utils");
2224
+ }
2225
+ });
2226
+
2227
+ // src/defaultChains.ts
2228
+ var import_chains, defaultChains;
2229
+ var init_defaultChains = __esm({
2230
+ "src/defaultChains.ts"() {
2231
+ "use strict";
2232
+ init_cjs_shims();
2233
+ import_chains = require("@latticexyz/common/chains");
2234
+ defaultChains = [import_chains.redstone, import_chains.garnet, import_chains.rhodolite];
2235
+ }
2236
+ });
2237
+
2238
+ // src/runDeploy.ts
2239
+ async function runDeploy(opts) {
2240
+ const salt = opts.salt != null ? (0, import_viem18.isHex)(opts.salt) ? opts.salt : (0, import_viem18.stringToHex)(opts.salt) : void 0;
2241
+ const profile = opts.profile;
2242
+ const configPath = await (0, import_node5.resolveConfigPath)(opts.configPath);
2243
+ const config2 = await (0, import_node5.loadConfig)(configPath);
2244
+ const rootDir = import_node_path4.default.dirname(configPath);
2245
+ console.log(import_chalk3.default.green(`
2246
+ Using ${package_default.name}@${package_default.version}`));
2247
+ if (opts.printConfig) {
2248
+ console.log(import_chalk3.default.green("\nResolved config:\n"), JSON.stringify(config2, null, 2));
2249
+ }
2250
+ const outDir = await (0, import_foundry3.getOutDirectory)(profile);
2251
+ const rpc = opts.rpc ?? await (0, import_foundry3.getRpcUrl)(profile);
2252
+ console.log(
2253
+ import_chalk3.default.bgBlue(
2254
+ import_chalk3.default.whiteBright(`
2255
+ Deploying MUD contracts${profile ? " with profile " + profile : ""} to RPC ${rpc}
2256
+ `)
2257
+ )
2258
+ );
2259
+ if (!opts.skipBuild) {
2260
+ await build({ rootDir, config: config2, foundryProfile: profile });
2261
+ }
2262
+ const { systems, libraries } = await resolveConfig({
2263
+ rootDir,
2264
+ config: config2,
2265
+ forgeOutDir: outDir
2266
+ });
2267
+ const artifacts = await (0, import_node6.findContractArtifacts)({ forgeOutDir: outDir });
2268
+ const modules = await configToModules(config2, outDir);
2269
+ const tables = Object.values(config2.namespaces).flatMap((namespace) => Object.values(namespace.tables)).filter((table) => !table.deploy.disabled);
2270
+ const account = await (async () => {
2271
+ if (opts.kms) {
2272
+ const keyId = process.env.AWS_KMS_KEY_ID;
2273
+ if (!keyId) {
2274
+ throw new import_errors3.MUDError(
2275
+ "Missing `AWS_KMS_KEY_ID` environment variable. This is required when using with `--kms` option."
2276
+ );
2277
+ }
2278
+ return await (0, import_kms.kmsKeyToAccount)({ keyId });
2279
+ } else {
2280
+ const privateKey = process.env.PRIVATE_KEY;
2281
+ if (!privateKey) {
2282
+ throw new import_errors3.MUDError(
2283
+ `Missing PRIVATE_KEY environment variable.
2284
+ Run 'echo "PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" > .env'
2285
+ in your contracts directory to use the default anvil private key.`
2286
+ );
2287
+ }
2288
+ return (0, import_accounts.privateKeyToAccount)(privateKey);
2289
+ }
2290
+ })();
2291
+ const client = (0, import_viem18.createWalletClient)({
2292
+ transport: (0, import_viem18.http)(rpc, {
2293
+ batch: opts.rpcBatch ? {
2294
+ batchSize: 100,
2295
+ wait: 1e3
2296
+ } : void 0
2297
+ }),
2298
+ account
2299
+ });
2300
+ const chainId = await (0, import_actions6.getChainId)(client);
2301
+ const indexerUrl = opts.indexerUrl ?? defaultChains.find((chain) => chain.id === chainId)?.indexerUrl;
2302
+ const worldDeployBlock = opts.worldAddress ? getWorldDeployBlock({
2303
+ worldAddress: opts.worldAddress,
2304
+ worldsFile: config2.deploy.worldsFile,
2305
+ chainId
2306
+ }) : void 0;
2307
+ console.log("Deploying from", client.account.address);
2308
+ const automine = await enableAutomine(client);
2309
+ const startTime = Date.now();
2310
+ const worldDeploy = await deploy({
2311
+ config: config2,
2312
+ deployerAddress: opts.deployerAddress,
2313
+ salt,
2314
+ worldAddress: opts.worldAddress,
2315
+ worldDeployBlock,
2316
+ client,
2317
+ tables,
2318
+ systems,
2319
+ libraries,
2320
+ modules,
2321
+ artifacts,
2322
+ indexerUrl,
2323
+ chainId
2324
+ });
2325
+ if (opts.worldAddress == null || opts.alwaysRunPostDeploy) {
2326
+ await postDeploy(
2327
+ config2.deploy.postDeployScript,
2328
+ worldDeploy.address,
2329
+ rpc,
2330
+ profile,
2331
+ opts.forgeScriptOptions,
2332
+ opts.kms ? true : false
2333
+ );
2334
+ }
2335
+ await automine?.reset();
2336
+ console.log(import_chalk3.default.green("Deployment completed in", (Date.now() - startTime) / 1e3, "seconds"));
2337
+ const deploymentInfo = {
2338
+ worldAddress: worldDeploy.address,
2339
+ blockNumber: Number(worldDeploy.deployBlock)
2340
+ };
2341
+ if (opts.saveDeployment) {
2342
+ const deploysDir = import_node_path4.default.join(config2.deploy.deploysDirectory, chainId.toString());
2343
+ (0, import_node_fs.mkdirSync)(deploysDir, { recursive: true });
2344
+ (0, import_node_fs.writeFileSync)(import_node_path4.default.join(deploysDir, "latest.json"), JSON.stringify(deploymentInfo, null, 2) + "\n");
2345
+ (0, import_node_fs.writeFileSync)(import_node_path4.default.join(deploysDir, Date.now() + ".json"), JSON.stringify(deploymentInfo, null, 2) + "\n");
2346
+ const localChains = [1337, 31337];
2347
+ const deploys2 = (0, import_node_fs.existsSync)(config2.deploy.worldsFile) ? JSON.parse((0, import_node_fs.readFileSync)(config2.deploy.worldsFile, "utf-8")) : {};
2348
+ deploys2[chainId] = {
2349
+ address: deploymentInfo.worldAddress,
2350
+ // We expect the worlds file to be committed and since local deployments are often
2351
+ // a consistent address but different block number, we'll ignore the block number.
2352
+ blockNumber: localChains.includes(chainId) ? void 0 : deploymentInfo.blockNumber
2353
+ };
2354
+ (0, import_node_fs.writeFileSync)(config2.deploy.worldsFile, JSON.stringify(deploys2, null, 2) + "\n");
2355
+ console.log(
2356
+ import_chalk3.default.bgGreen(
2357
+ import_chalk3.default.whiteBright(`
2358
+ Deployment result (written to ${config2.deploy.worldsFile} and ${deploysDir}):
2359
+ `)
2360
+ )
2361
+ );
2362
+ }
2363
+ console.log(deploymentInfo);
2364
+ return worldDeploy;
2365
+ }
2366
+ function getWorldDeployBlock({
2367
+ chainId,
2368
+ worldAddress,
2369
+ worldsFile
2370
+ }) {
2371
+ const deploys2 = (0, import_node_fs.existsSync)(worldsFile) ? JSON.parse((0, import_node_fs.readFileSync)(worldsFile, "utf-8")) : {};
2372
+ const worldDeployBlock = deploys2[chainId]?.address === worldAddress ? deploys2[chainId].blockNumber : void 0;
2373
+ return worldDeployBlock ? BigInt(worldDeployBlock) : void 0;
2374
+ }
2375
+ var import_node_path4, import_node_fs, import_viem18, import_accounts, import_node5, import_foundry3, import_chalk3, import_errors3, import_actions6, import_kms, import_node6, deployOptions;
2376
+ var init_runDeploy = __esm({
2377
+ "src/runDeploy.ts"() {
2378
+ "use strict";
2379
+ init_cjs_shims();
2380
+ import_node_path4 = __toESM(require("path"), 1);
2381
+ import_node_fs = require("fs");
2382
+ init_package();
2383
+ init_deploy();
2384
+ import_viem18 = require("viem");
2385
+ import_accounts = require("viem/accounts");
2386
+ import_node5 = require("@latticexyz/config/node");
2387
+ import_foundry3 = require("@latticexyz/common/foundry");
2388
+ import_chalk3 = __toESM(require("chalk"), 1);
2389
+ import_errors3 = require("@latticexyz/common/errors");
2390
+ init_resolveConfig();
2391
+ import_actions6 = require("viem/actions");
2392
+ init_postDeploy();
2393
+ init_build();
2394
+ import_kms = require("@latticexyz/common/kms");
2395
+ init_configToModules();
2396
+ import_node6 = require("@latticexyz/world/node");
2397
+ init_enableAutomine();
2398
+ init_defaultChains();
2399
+ deployOptions = {
2400
+ configPath: { type: "string", desc: "Path to the MUD config file" },
2401
+ printConfig: { type: "boolean", desc: "Print the resolved config" },
2402
+ profile: { type: "string", desc: "The foundry profile to use" },
2403
+ saveDeployment: { type: "boolean", desc: "Save the deployment info to a file", default: true },
2404
+ rpc: { type: "string", desc: "The RPC URL to use. Defaults to the RPC url from the local foundry.toml" },
2405
+ rpcBatch: {
2406
+ type: "boolean",
2407
+ desc: "Enable batch processing of RPC requests in viem client (defaults to batch size of 100 and wait of 1s)"
2408
+ },
2409
+ deployerAddress: {
2410
+ type: "string",
2411
+ desc: "Deploy using an existing deterministic deployer (https://github.com/Arachnid/deterministic-deployment-proxy)"
2412
+ },
2413
+ worldAddress: { type: "string", desc: "Deploy to an existing World at the given address" },
2414
+ skipBuild: { type: "boolean", desc: "Skip rebuilding the contracts before deploying" },
2415
+ alwaysRunPostDeploy: {
2416
+ type: "boolean",
2417
+ desc: "Always run PostDeploy.s.sol after each deploy (including during upgrades). By default, PostDeploy.s.sol is only run once after a new world is deployed."
2418
+ },
2419
+ forgeScriptOptions: { type: "string", description: "Options to pass to forge script PostDeploy.s.sol" },
2420
+ salt: {
2421
+ type: "string",
2422
+ desc: "The deployment salt to use. Defaults to a random salt."
2423
+ },
2424
+ kms: {
2425
+ type: "boolean",
2426
+ desc: "Deploy the World with an AWS KMS key instead of local private key."
2427
+ },
2428
+ indexerUrl: {
2429
+ type: "string",
2430
+ desc: "The indexer URL to use.",
2431
+ required: false
2432
+ }
2433
+ };
2434
+ }
2435
+ });
2436
+
2437
+ // src/commands/deploy.ts
2438
+ var commandModule5, deploy_default;
2439
+ var init_deploy2 = __esm({
2440
+ "src/commands/deploy.ts"() {
2441
+ "use strict";
2442
+ init_cjs_shims();
2443
+ init_errors();
2444
+ init_runDeploy();
2445
+ commandModule5 = {
2446
+ command: "deploy",
2447
+ describe: "Deploy MUD contracts",
2448
+ builder(yargs) {
2449
+ return yargs.options(deployOptions);
2450
+ },
2451
+ async handler(opts) {
2452
+ try {
2453
+ await runDeploy(opts);
2454
+ } catch (error4) {
2455
+ logError(error4);
2456
+ process.exit(1);
2457
+ }
2458
+ process.exit(0);
2459
+ }
2460
+ };
2461
+ deploy_default = commandModule5;
2462
+ }
2463
+ });
2464
+
2465
+ // src/commands/worldgen.ts
2466
+ async function worldgenHandler(args) {
2467
+ const configPath = await (0, import_node7.resolveConfigPath)(args.configPath);
2468
+ const config2 = await (0, import_node7.loadConfig)(configPath);
2469
+ const rootDir = import_node_path5.default.dirname(configPath);
2470
+ await (0, import_node8.worldgen)({ rootDir, config: config2, clean: args.clean });
2471
+ }
2472
+ var import_node_path5, import_node7, import_node8, commandModule6, worldgen_default;
2473
+ var init_worldgen = __esm({
2474
+ "src/commands/worldgen.ts"() {
2475
+ "use strict";
2476
+ init_cjs_shims();
2477
+ import_node_path5 = __toESM(require("path"), 1);
2478
+ import_node7 = require("@latticexyz/config/node");
2479
+ import_node8 = require("@latticexyz/world/node");
2480
+ commandModule6 = {
2481
+ command: "worldgen",
2482
+ describe: "Autogenerate interfaces for Systems and World based on existing contracts and the config file",
2483
+ builder(yargs) {
2484
+ return yargs.options({
2485
+ configPath: { type: "string", desc: "Path to the MUD config file" },
2486
+ clean: {
2487
+ type: "boolean",
2488
+ desc: "Clear the worldgen directory before generating new interfaces (defaults to true)",
2489
+ default: true
2490
+ }
2491
+ });
2492
+ },
2493
+ async handler(args) {
2494
+ await worldgenHandler(args);
2495
+ process.exit(0);
2496
+ }
2497
+ };
2498
+ worldgen_default = commandModule6;
2499
+ }
2500
+ });
2501
+
2502
+ // src/mudPackages.ts
2503
+ function parseEnv() {
2504
+ try {
2505
+ return envSchema.parse({
2506
+ // tsup replaces the env vars with their values at compile time
2507
+ MUD_PACKAGES: '{"@latticexyz/abi-ts":{"localPath":"packages/abi-ts"},"@latticexyz/block-logs-stream":{"localPath":"packages/block-logs-stream"},"@latticexyz/cli":{"localPath":"packages/cli"},"@latticexyz/common":{"localPath":"packages/common"},"@latticexyz/config":{"localPath":"packages/config"},"create-mud":{"localPath":"packages/create-mud"},"@latticexyz/dev-tools":{"localPath":"packages/dev-tools"},"@latticexyz/entrykit":{"localPath":"packages/entrykit"},"@latticexyz/explorer":{"localPath":"packages/explorer"},"@latticexyz/faucet":{"localPath":"packages/faucet"},"@latticexyz/gas-report":{"localPath":"packages/gas-report"},"@latticexyz/paymaster":{"localPath":"packages/paymaster"},"@latticexyz/protocol-parser":{"localPath":"packages/protocol-parser"},"@latticexyz/react":{"localPath":"packages/react"},"@latticexyz/recs":{"localPath":"packages/recs"},"@latticexyz/schema-type":{"localPath":"packages/schema-type"},"solhint-config-mud":{"localPath":"packages/solhint-config-mud"},"solhint-plugin-mud":{"localPath":"packages/solhint-plugin-mud"},"@latticexyz/stash":{"localPath":"packages/stash"},"@latticexyz/store-consumer":{"localPath":"packages/store-consumer"},"@latticexyz/store-indexer":{"localPath":"packages/store-indexer"},"@latticexyz/store-sync":{"localPath":"packages/store-sync"},"@latticexyz/store":{"localPath":"packages/store"},"@latticexyz/utils":{"localPath":"packages/utils"},"vite-plugin-mud":{"localPath":"packages/vite-plugin-mud"},"@latticexyz/world-module-callwithsignature":{"localPath":"packages/world-module-callwithsignature"},"@latticexyz/world-module-erc20":{"localPath":"packages/world-module-erc20"},"@latticexyz/world-module-metadata":{"localPath":"packages/world-module-metadata"},"@latticexyz/world-modules":{"localPath":"packages/world-modules"},"@latticexyz/world":{"localPath":"packages/world"}}'
2508
+ });
2509
+ } catch (error4) {
2510
+ if (error4 instanceof import_zod4.ZodError) {
2511
+ const { ...invalidEnvVars } = error4.format();
2512
+ console.error(`
2513
+ Missing or invalid environment variables:
2514
+
2515
+ ${Object.keys(invalidEnvVars).join("\n ")}
2516
+ `);
2517
+ process.exit(1);
2518
+ }
2519
+ throw error4;
2520
+ }
2521
+ }
2522
+ var import_zod4, envSchema, mudPackages;
2523
+ var init_mudPackages = __esm({
2524
+ "src/mudPackages.ts"() {
2525
+ "use strict";
2526
+ init_cjs_shims();
2527
+ import_zod4 = require("zod");
2528
+ envSchema = import_zod4.z.object({
2529
+ MUD_PACKAGES: import_zod4.z.string().transform((value) => JSON.parse(value))
2530
+ });
2531
+ mudPackages = parseEnv().MUD_PACKAGES;
2532
+ }
2533
+ });
2534
+
2535
+ // src/commands/set-version.ts
2536
+ async function resolveVersion(options2) {
2537
+ if (options2.mudVersion === "canary") options2.tag = "main";
2538
+ let npmResult;
2539
+ try {
2540
+ console.log(import_chalk4.default.blue(`Fetching available versions`));
2541
+ npmResult = await (await fetch(`https://registry.npmjs.org/${package_default.name}`)).json();
2542
+ } catch (e) {
2543
+ throw new import_errors5.MUDError(`Could not fetch available MUD versions`);
2544
+ }
2545
+ if (options2.tag) {
2546
+ const version = npmResult["dist-tags"][options2.tag];
2547
+ if (!version) {
2548
+ throw new import_errors5.MUDError(`Could not find npm version with tag "${options2.tag}"`);
2549
+ }
2550
+ console.log(import_chalk4.default.green(`Latest version with tag ${options2.tag}: ${version}`));
2551
+ return version;
2552
+ }
2553
+ if (options2.commit) {
2554
+ const commit = options2.commit.substring(0, 8);
2555
+ const version = Object.keys(npmResult["versions"]).find((v) => v.includes(commit));
2556
+ if (!version) {
2557
+ throw new import_errors5.MUDError(`Could not find npm version based on commit "${options2.commit}"`);
2558
+ }
2559
+ console.log(import_chalk4.default.green(`Version from commit ${options2.commit}: ${version}`));
2560
+ return version;
2561
+ }
2562
+ return options2.mudVersion;
2563
+ }
2564
+ function updatePackageJson(filePath, options2) {
2565
+ const { link } = options2;
2566
+ let { mudVersion } = options2;
2567
+ const packageJson = readPackageJson(filePath);
2568
+ const mudPackageNames = Object.keys(mudPackages);
2569
+ const mudDependencies = {};
2570
+ for (const packageName in packageJson.dependencies) {
2571
+ if (mudPackageNames.includes(packageName)) {
2572
+ mudDependencies[packageName] = packageJson.dependencies[packageName];
2573
+ }
2574
+ }
2575
+ const mudDevDependencies = {};
2576
+ for (const packageName in packageJson.devDependencies) {
2577
+ if (mudPackageNames.includes(packageName)) {
2578
+ mudDevDependencies[packageName] = packageJson.devDependencies[packageName];
2579
+ }
2580
+ }
2581
+ for (const packageName in packageJson.dependencies) {
2582
+ if (mudPackageNames.includes(packageName)) {
2583
+ packageJson.dependencies[packageName] = resolveMudVersion(packageName, "dependencies");
2584
+ }
2585
+ }
2586
+ for (const packageName in packageJson.devDependencies) {
2587
+ if (mudPackageNames.includes(packageName)) {
2588
+ packageJson.devDependencies[packageName] = resolveMudVersion(packageName, "devDependencies");
2589
+ }
2590
+ }
2591
+ (0, import_fs5.writeFileSync)(filePath, JSON.stringify(packageJson, null, 2) + "\n");
2592
+ console.log(`Updating ${filePath}`);
2593
+ logComparison(mudDependencies, packageJson.dependencies);
2594
+ logComparison(mudDevDependencies, packageJson.devDependencies);
2595
+ return packageJson;
2596
+ function resolveMudVersion(key, type) {
2597
+ if (link) mudVersion = resolveLinkPath(filePath, link, key);
2598
+ if (!mudVersion) return packageJson[type][key];
2599
+ return mudVersion;
2600
+ }
2601
+ }
2602
+ function readPackageJson(path16) {
2603
+ try {
2604
+ const jsonString = (0, import_fs5.readFileSync)(path16, "utf8");
2605
+ return JSON.parse(jsonString);
2606
+ } catch {
2607
+ throw new import_errors5.MUDError("Could not read JSON at " + path16);
2608
+ }
2609
+ }
2610
+ function logComparison(prev, curr) {
2611
+ for (const key in prev) {
2612
+ if (prev[key] !== curr[key]) {
2613
+ console.log(`${key}: ${import_chalk4.default.red(prev[key])} -> ${import_chalk4.default.green(curr[key])}`);
2614
+ }
2615
+ }
2616
+ }
2617
+ function resolveLinkPath(packageJsonPath, mudLinkPath, packageName) {
2618
+ const packageJsonToRootPath = import_path5.default.relative(import_path5.default.dirname(packageJsonPath), process.cwd());
2619
+ const linkPath = import_path5.default.join(packageJsonToRootPath, mudLinkPath, mudPackages[packageName].localPath);
2620
+ return "link:" + linkPath;
2621
+ }
2622
+ var import_chalk4, import_fs5, import_path5, import_errors5, import_glob2, commandModule7, set_version_default;
2623
+ var init_set_version = __esm({
2624
+ "src/commands/set-version.ts"() {
2625
+ "use strict";
2626
+ init_cjs_shims();
2627
+ import_chalk4 = __toESM(require("chalk"), 1);
2628
+ import_fs5 = require("fs");
2629
+ import_path5 = __toESM(require("path"), 1);
2630
+ import_errors5 = require("@latticexyz/common/errors");
2631
+ init_errors();
2632
+ init_package();
2633
+ import_glob2 = require("glob");
2634
+ init_mudPackages();
2635
+ commandModule7 = {
2636
+ command: "set-version",
2637
+ describe: "Set MUD version in all package.json files and optionally backup the previously installed version",
2638
+ builder(yargs) {
2639
+ return yargs.options({
2640
+ mudVersion: { alias: "v", type: "string", description: "Set MUD to the given version" },
2641
+ tag: {
2642
+ alias: "t",
2643
+ type: "string",
2644
+ description: "Set MUD to the latest version with the given tag from npm"
2645
+ },
2646
+ commit: {
2647
+ alias: "c",
2648
+ type: "string",
2649
+ description: "Set MUD to the version based on a given git commit hash from npm"
2650
+ },
2651
+ link: { alias: "l", type: "string", description: "Relative path to the local MUD root directory to link" }
2652
+ });
2653
+ },
2654
+ async handler(options2) {
2655
+ try {
2656
+ const mutuallyExclusiveOptions = ["mudVersion", "link", "tag", "commit", "restore"];
2657
+ const numMutuallyExclusiveOptions = mutuallyExclusiveOptions.reduce(
2658
+ (acc, opt) => options2[opt] ? acc + 1 : acc,
2659
+ 0
2660
+ );
2661
+ if (numMutuallyExclusiveOptions === 0) {
2662
+ throw new import_errors5.MUDError(`You need to provide one these options: ${mutuallyExclusiveOptions.join(", ")}`);
2663
+ }
2664
+ if (numMutuallyExclusiveOptions > 1) {
2665
+ throw new import_errors5.MUDError(`These options are mutually exclusive: ${mutuallyExclusiveOptions.join(", ")}`);
2666
+ }
2667
+ if (!options2.link) {
2668
+ options2.mudVersion = await resolveVersion(options2);
2669
+ }
2670
+ const packageJsons = (0, import_glob2.globSync)("**/package.json").sort().filter((p) => !p.includes("node_modules"));
2671
+ for (const packageJson of packageJsons) {
2672
+ updatePackageJson(packageJson, options2);
2673
+ }
2674
+ } catch (e) {
2675
+ logError(e);
2676
+ } finally {
2677
+ process.exit(0);
2678
+ }
2679
+ }
2680
+ };
2681
+ set_version_default = commandModule7;
2682
+ }
2683
+ });
2684
+
2685
+ // src/commands/test.ts
2686
+ var import_foundry4, import_chalk5, testOptions, commandModule8, test_default;
2687
+ var init_test = __esm({
2688
+ "src/commands/test.ts"() {
2689
+ "use strict";
2690
+ init_cjs_shims();
2691
+ import_foundry4 = require("@latticexyz/common/foundry");
2692
+ import_chalk5 = __toESM(require("chalk"), 1);
2693
+ init_runDeploy();
2694
+ testOptions = {
2695
+ ...deployOptions,
2696
+ port: { type: "number", description: "Port to run internal node for fork testing on", default: 4242 },
2697
+ worldAddress: {
2698
+ type: "string",
2699
+ description: "Address of an existing world contract. If provided, deployment is skipped and the RPC provided in the foundry.toml is used for fork testing."
2700
+ },
2701
+ forgeOptions: { type: "string", description: "Options to pass to forge test" }
2702
+ };
2703
+ commandModule8 = {
2704
+ command: "test",
2705
+ describe: "Run tests in MUD contracts",
2706
+ builder(yargs) {
2707
+ return yargs.options(testOptions);
2708
+ },
2709
+ async handler(opts) {
2710
+ if (!opts.worldAddress) {
2711
+ const anvilArgs = ["--block-base-fee-per-gas", "0", "--port", String(opts.port)];
2712
+ (0, import_foundry4.anvil)(anvilArgs);
2713
+ }
2714
+ const forkRpc = opts.worldAddress ? await (0, import_foundry4.getRpcUrl)(opts.profile) : `http://127.0.0.1:${opts.port}`;
2715
+ const worldAddress = opts.worldAddress ?? (await runDeploy({
2716
+ ...opts,
2717
+ saveDeployment: false,
2718
+ rpc: forkRpc
2719
+ })).address;
2720
+ console.log(import_chalk5.default.blue("World address", worldAddress));
2721
+ const userOptions = opts.forgeOptions?.replaceAll("\\", "").split(" ") ?? [];
2722
+ try {
2723
+ await (0, import_foundry4.forge)(["test", "--fork-url", forkRpc, ...userOptions], {
2724
+ profile: opts.profile,
2725
+ env: {
2726
+ WORLD_ADDRESS: worldAddress
2727
+ }
2728
+ });
2729
+ process.exit(0);
2730
+ } catch (e) {
2731
+ console.error(e);
2732
+ process.exit(1);
2733
+ }
2734
+ }
2735
+ };
2736
+ test_default = commandModule8;
2737
+ }
2738
+ });
2739
+
2740
+ // src/commands/trace.ts
2741
+ function getWorldAddress(worldsFile, chainId) {
2742
+ if (!import_node_fs2.default.existsSync(worldsFile)) {
2743
+ throw new import_errors7.MUDError(`Missing expected worlds.json file at "${worldsFile}"`);
2744
+ }
2745
+ const deploys2 = JSON.parse(import_node_fs2.default.readFileSync(worldsFile, "utf-8"));
2746
+ if (!deploys2[chainId]) {
2747
+ throw new import_errors7.MUDError(`Missing chain ID ${chainId} in "${worldsFile}"`);
2748
+ }
2749
+ return deploys2[chainId].address;
2750
+ }
2751
+ var import_node_path6, import_node_fs2, import_node9, import_errors7, import_foundry5, import_mud7, import_viem19, import_actions7, import_node10, systemsTableId, commandModule9, trace_default;
2752
+ var init_trace = __esm({
2753
+ "src/commands/trace.ts"() {
2754
+ "use strict";
2755
+ init_cjs_shims();
2756
+ import_node_path6 = __toESM(require("path"), 1);
2757
+ import_node_fs2 = __toESM(require("fs"), 1);
2758
+ import_node9 = require("@latticexyz/config/node");
2759
+ import_errors7 = require("@latticexyz/common/errors");
2760
+ import_foundry5 = require("@latticexyz/common/foundry");
2761
+ import_mud7 = __toESM(require("@latticexyz/world/mud.config"), 1);
2762
+ import_viem19 = require("viem");
2763
+ import_actions7 = require("viem/actions");
2764
+ import_node10 = require("@latticexyz/world/node");
2765
+ init_common();
2766
+ systemsTableId = import_mud7.default.namespaces.world.tables.Systems.tableId;
2767
+ commandModule9 = {
2768
+ command: "trace",
2769
+ describe: "Display the trace of a transaction",
2770
+ builder(yargs) {
2771
+ return yargs.options({
2772
+ tx: { type: "string", required: true, description: "Transaction hash to replay" },
2773
+ worldAddress: {
2774
+ type: "string",
2775
+ description: "World contract address. Defaults to the value from worlds.json, based on rpc's chainId"
2776
+ },
2777
+ configPath: { type: "string", description: "Path to the MUD config file" },
2778
+ profile: { type: "string", description: "The foundry profile to use" },
2779
+ rpc: { type: "string", description: "json rpc endpoint. Defaults to foundry's configured eth_rpc_url" }
2780
+ });
2781
+ },
2782
+ async handler(args) {
2783
+ const configPath = await (0, import_node9.resolveConfigPath)(args.configPath);
2784
+ const rootDir = import_node_path6.default.dirname(configPath);
2785
+ const profile = args.profile;
2786
+ const rpc = args.rpc ?? await (0, import_foundry5.getRpcUrl)(profile);
2787
+ const config2 = await (0, import_node9.loadConfig)(configPath);
2788
+ const client = (0, import_viem19.createClient)({ transport: (0, import_viem19.http)(rpc) });
2789
+ const chainId = await (0, import_actions7.getChainId)(client);
2790
+ const worldAddress = args.worldAddress ?? getWorldAddress(config2.deploy.worldsFile, chainId);
2791
+ const systems = await (0, import_node10.resolveSystems)({ rootDir, config: config2 });
2792
+ const labels = await Promise.all(
2793
+ systems.map(async (system) => ({
2794
+ label: system.label,
2795
+ address: await (0, import_actions7.readContract)(client, {
2796
+ abi: worldAbi,
2797
+ address: worldAddress,
2798
+ functionName: "getField",
2799
+ args: [systemsTableId, [system.systemId], 0]
2800
+ })
2801
+ }))
2802
+ );
2803
+ const result = await (0, import_foundry5.cast)([
2804
+ "run",
2805
+ "--label",
2806
+ `${worldAddress}:World`,
2807
+ ...labels.map(({ label, address }) => ["--label", `${address}:${label}`]).flat(),
2808
+ `${args.tx}`
2809
+ ]);
2810
+ console.log(result);
2811
+ process.exit(0);
2812
+ }
2813
+ };
2814
+ trace_default = commandModule9;
2815
+ }
2816
+ });
2817
+
2818
+ // src/commands/dev-contracts.ts
2819
+ var import_foundry6, import_chalk6, import_chokidar, import_node11, import_path6, import_os2, import_fs6, import_rxjs, import_utils8, devOptions, commandModule10, dev_contracts_default;
2820
+ var init_dev_contracts = __esm({
2821
+ "src/commands/dev-contracts.ts"() {
2822
+ "use strict";
2823
+ init_cjs_shims();
2824
+ import_foundry6 = require("@latticexyz/common/foundry");
2825
+ import_chalk6 = __toESM(require("chalk"), 1);
2826
+ import_chokidar = __toESM(require("chokidar"), 1);
2827
+ import_node11 = require("@latticexyz/config/node");
2828
+ import_path6 = __toESM(require("path"), 1);
2829
+ import_os2 = require("os");
2830
+ import_fs6 = require("fs");
2831
+ init_runDeploy();
2832
+ import_rxjs = require("rxjs");
2833
+ import_utils8 = require("@latticexyz/common/utils");
2834
+ devOptions = {
2835
+ rpc: deployOptions.rpc,
2836
+ configPath: deployOptions.configPath,
2837
+ alwaysRunPostDeploy: deployOptions.alwaysRunPostDeploy,
2838
+ forgeScriptOptions: deployOptions.forgeScriptOptions,
2839
+ worldAddress: deployOptions.worldAddress
2840
+ };
2841
+ commandModule10 = {
2842
+ command: "dev-contracts",
2843
+ describe: "Start a development server for MUD contracts",
2844
+ builder(yargs) {
2845
+ return yargs.options(devOptions);
2846
+ },
2847
+ async handler(opts) {
2848
+ let rpc = opts.rpc;
2849
+ const configPath = opts.configPath ?? await (0, import_node11.resolveConfigPath)(opts.configPath);
2850
+ const srcDir = await (0, import_foundry6.getSrcDirectory)();
2851
+ const scriptDir = await (0, import_foundry6.getScriptDirectory)();
2852
+ const initialConfig = await (0, import_node11.loadConfig)(configPath);
2853
+ if (!opts.rpc) {
2854
+ console.log(import_chalk6.default.gray("Cleaning devnode cache"));
2855
+ const userHomeDir = (0, import_os2.homedir)();
2856
+ (0, import_fs6.rmSync)(import_path6.default.join(userHomeDir, ".foundry", "anvil", "tmp"), { recursive: true, force: true });
2857
+ const anvilArgs = ["--block-time", "1", "--block-base-fee-per-gas", "0"];
2858
+ (0, import_foundry6.anvil)(anvilArgs);
2859
+ rpc = "http://127.0.0.1:8545";
2860
+ }
2861
+ const lastChange$ = new import_rxjs.BehaviorSubject(Date.now());
2862
+ import_chokidar.default.watch([configPath, srcDir, scriptDir], { ignoreInitial: true }).on("all", async (_, updatePath) => {
2863
+ if (updatePath.includes(configPath)) {
2864
+ console.log(import_chalk6.default.blue("Config changed, queuing deploy\u2026"));
2865
+ lastChange$.next(Date.now());
2866
+ }
2867
+ if (updatePath.includes(srcDir) || updatePath.includes(scriptDir)) {
2868
+ if (!updatePath.includes(initialConfig.codegen.outputDirectory)) {
2869
+ console.log(import_chalk6.default.blue("Contracts changed, queuing deploy\u2026"));
2870
+ lastChange$.next(Date.now());
2871
+ }
2872
+ }
2873
+ });
2874
+ let worldAddress = opts.worldAddress;
2875
+ const deploys$ = lastChange$.pipe(
2876
+ // debounce so that a large batch of file changes only triggers a deploy after it settles down, rather than the first change it sees (and then redeploying immediately after)
2877
+ (0, import_rxjs.debounceTime)(200),
2878
+ (0, import_rxjs.exhaustMap)(async (lastChange) => {
2879
+ if (worldAddress) {
2880
+ console.log(import_chalk6.default.blue("Rebuilding and upgrading world\u2026"));
2881
+ }
2882
+ try {
2883
+ const deploy2 = await runDeploy({
2884
+ ...opts,
2885
+ configPath,
2886
+ rpc,
2887
+ rpcBatch: false,
2888
+ skipBuild: false,
2889
+ printConfig: false,
2890
+ profile: void 0,
2891
+ saveDeployment: true,
2892
+ deployerAddress: void 0,
2893
+ worldAddress,
2894
+ salt: "0x",
2895
+ kms: void 0,
2896
+ indexerUrl: void 0
2897
+ });
2898
+ worldAddress = deploy2.address;
2899
+ if (lastChange < lastChange$.value) {
2900
+ lastChange$.next(lastChange$.value);
2901
+ } else {
2902
+ console.log(import_chalk6.default.gray("\nWaiting for file changes\u2026\n"));
2903
+ }
2904
+ return deploy2;
2905
+ } catch (error4) {
2906
+ console.error(import_chalk6.default.bgRed(import_chalk6.default.whiteBright("\n Error while attempting deploy \n")));
2907
+ console.error(error4);
2908
+ console.log(import_chalk6.default.gray("\nWaiting for file changes\u2026\n"));
2909
+ }
2910
+ }),
2911
+ (0, import_rxjs.filter)(import_utils8.isDefined)
2912
+ );
2913
+ deploys$.subscribe();
2914
+ }
2915
+ };
2916
+ dev_contracts_default = commandModule10;
2917
+ }
2918
+ });
2919
+
2920
+ // src/verify/verifyContract.ts
2921
+ async function verifyContract(options2) {
2922
+ const args = ["verify-contract", options2.address, options2.name, "--rpc-url", options2.rpc];
2923
+ if (options2.verifier) {
2924
+ args.push("--verifier", options2.verifier);
2925
+ }
2926
+ if (options2.verifierUrl) {
2927
+ args.push("--verifier-url", options2.verifierUrl);
2928
+ }
2929
+ await (0, import_foundry7.forge)(args, { cwd: options2.cwd });
2930
+ }
2931
+ var import_foundry7;
2932
+ var init_verifyContract = __esm({
2933
+ "src/verify/verifyContract.ts"() {
2934
+ "use strict";
2935
+ init_cjs_shims();
2936
+ import_foundry7 = require("@latticexyz/common/foundry");
2937
+ }
2938
+ });
2939
+
2940
+ // src/verify.ts
2941
+ async function verify({
2942
+ client,
2943
+ rpc,
2944
+ systems,
2945
+ libraries,
2946
+ modules,
2947
+ worldAddress,
2948
+ deployerAddress: initialDeployerAddress,
2949
+ verifier,
2950
+ verifierUrl
2951
+ }) {
2952
+ const deployerAddress = initialDeployerAddress ?? await (0, import_internal17.getDeployer)(client);
2953
+ if (!deployerAddress) {
2954
+ throw new import_errors8.MUDError("No deployer address provided or found.");
2955
+ }
2956
+ const implementationStorage = await (0, import_actions8.getStorageAt)(client, {
2957
+ address: worldAddress,
2958
+ slot: ERC1967_IMPLEMENTATION_SLOT
2959
+ });
2960
+ const usesProxy = implementationStorage && implementationStorage !== import_viem20.zeroHash;
2961
+ const verifyQueue = new import_p_queue.default({ concurrency: 4 });
2962
+ const libraryMap = getLibraryMap(libraries);
2963
+ systems.map(
2964
+ (system) => verifyQueue.add(() => {
2965
+ const address = (0, import_internal17.getContractAddress)({
2966
+ deployerAddress,
2967
+ bytecode: system.prepareDeploy(deployerAddress, libraryMap).bytecode
2968
+ });
2969
+ return verifyContract({
2970
+ name: system.label,
2971
+ rpc,
2972
+ verifier,
2973
+ verifierUrl,
2974
+ address
2975
+ }).catch((error4) => {
2976
+ console.error(`Error verifying system contract ${system.label}:`, error4);
2977
+ });
2978
+ })
2979
+ );
2980
+ if (verifier === "sourcify") {
2981
+ await (0, import_execa3.execa)("npm", ["install"], {
2982
+ cwd: "node_modules/@latticexyz/store"
2983
+ });
2984
+ await (0, import_execa3.execa)("npm", ["install"], {
2985
+ cwd: "node_modules/@latticexyz/world"
2986
+ });
2987
+ await (0, import_execa3.execa)("npm", ["install"], {
2988
+ cwd: "node_modules/@latticexyz/world-modules"
2989
+ });
2990
+ Object.entries(
2991
+ usesProxy ? getWorldProxyFactoryContracts(deployerAddress) : getWorldFactoryContracts(deployerAddress)
2992
+ ).map(
2993
+ ([name, { bytecode }]) => verifyQueue.add(
2994
+ () => verifyContract({
2995
+ cwd: "node_modules/@latticexyz/world",
2996
+ name,
2997
+ rpc,
2998
+ verifier,
2999
+ verifierUrl,
3000
+ address: (0, import_internal17.getContractAddress)({
3001
+ deployerAddress,
3002
+ bytecode
3003
+ })
3004
+ }).catch((error4) => {
3005
+ console.error(`Error verifying world factory contract ${name}:`, error4);
3006
+ })
3007
+ )
3008
+ );
3009
+ modules.map(({ name, prepareDeploy }) => {
3010
+ const { address } = prepareDeploy(deployerAddress);
3011
+ return verifyQueue.add(
3012
+ () => verifyContract({
3013
+ // TODO: figure out dir from artifactPath via import.meta.resolve?
3014
+ cwd: "node_modules/@latticexyz/world-modules",
3015
+ name,
3016
+ rpc,
3017
+ verifier,
3018
+ verifierUrl,
3019
+ address
3020
+ }).catch((error4) => {
3021
+ console.error(`Error verifying module contract ${name}:`, error4);
3022
+ })
3023
+ );
3024
+ });
3025
+ if (usesProxy) {
3026
+ const implementationAddress = (0, import_viem20.sliceHex)(implementationStorage, -20);
3027
+ verifyQueue.add(
3028
+ () => verifyContract({
3029
+ cwd: "node_modules/@latticexyz/world",
3030
+ name: "WorldProxy",
3031
+ rpc,
3032
+ verifier,
3033
+ verifierUrl,
3034
+ address: worldAddress
3035
+ }).catch((error4) => {
3036
+ console.error(`Error verifying WorldProxy contract:`, error4);
3037
+ })
3038
+ );
3039
+ verifyQueue.add(
3040
+ () => verifyContract({
3041
+ cwd: "node_modules/@latticexyz/world",
3042
+ name: "World",
3043
+ rpc,
3044
+ verifier,
3045
+ verifierUrl,
3046
+ address: implementationAddress
3047
+ }).catch((error4) => {
3048
+ console.error(`Error verifying World contract:`, error4);
3049
+ })
3050
+ );
3051
+ } else {
3052
+ verifyQueue.add(
3053
+ () => verifyContract({
3054
+ cwd: "node_modules/@latticexyz/world",
3055
+ name: "World",
3056
+ rpc,
3057
+ verifier,
3058
+ verifierUrl,
3059
+ address: worldAddress
3060
+ }).catch((error4) => {
3061
+ console.error(`Error verifying World contract:`, error4);
3062
+ })
3063
+ );
3064
+ }
3065
+ } else {
3066
+ console.log("");
3067
+ console.log(
3068
+ `Note: MUD is currently unable to verify store, world, and world-modules contracts with ${verifier}. We are planning to expand support in a future version.`
3069
+ );
3070
+ console.log("");
3071
+ }
3072
+ }
3073
+ var import_viem20, import_p_queue, import_errors8, import_actions8, import_execa3, import_internal17, ERC1967_IMPLEMENTATION_SLOT;
3074
+ var init_verify = __esm({
3075
+ "src/verify.ts"() {
3076
+ "use strict";
3077
+ init_cjs_shims();
3078
+ import_viem20 = require("viem");
3079
+ init_getWorldFactoryContracts();
3080
+ init_verifyContract();
3081
+ import_p_queue = __toESM(require("p-queue"), 1);
3082
+ init_getWorldProxyFactoryContracts();
3083
+ import_errors8 = require("@latticexyz/common/errors");
3084
+ import_actions8 = require("viem/actions");
3085
+ import_execa3 = require("execa");
3086
+ import_internal17 = require("@latticexyz/common/internal");
3087
+ init_getLibraryMap();
3088
+ ERC1967_IMPLEMENTATION_SLOT = "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc";
3089
+ }
3090
+ });
3091
+
3092
+ // src/commands/verify.ts
3093
+ var import_node12, import_foundry8, import_viem21, import_chalk7, import_node_path7, verifyOptions, commandModule11, verify_default;
3094
+ var init_verify2 = __esm({
3095
+ "src/commands/verify.ts"() {
3096
+ "use strict";
3097
+ init_cjs_shims();
3098
+ init_verify();
3099
+ import_node12 = require("@latticexyz/config/node");
3100
+ import_foundry8 = require("@latticexyz/common/foundry");
3101
+ import_viem21 = require("viem");
3102
+ import_chalk7 = __toESM(require("chalk"), 1);
3103
+ init_configToModules();
3104
+ import_node_path7 = __toESM(require("path"), 1);
3105
+ init_resolveConfig();
3106
+ verifyOptions = {
3107
+ deployerAddress: {
3108
+ type: "string",
3109
+ desc: "Deploy using an existing deterministic deployer (https://github.com/Arachnid/deterministic-deployment-proxy)"
3110
+ },
3111
+ worldAddress: { type: "string", required: true, desc: "Verify an existing World at the given address" },
3112
+ configPath: { type: "string", desc: "Path to the MUD config file" },
3113
+ profile: { type: "string", desc: "The foundry profile to use" },
3114
+ rpc: { type: "string", desc: "The RPC URL to use. Defaults to the RPC url from the local foundry.toml" },
3115
+ rpcBatch: {
3116
+ type: "boolean",
3117
+ desc: "Enable batch processing of RPC requests in viem client (defaults to batch size of 100 and wait of 1s)"
3118
+ },
3119
+ verifier: { type: "string", desc: "The verifier to use. Defaults to blockscout", default: "blockscout" },
3120
+ verifierUrl: {
3121
+ type: "string",
3122
+ desc: "The verification provider."
3123
+ }
3124
+ };
3125
+ commandModule11 = {
3126
+ command: "verify",
3127
+ describe: "Verify contracts",
3128
+ builder(yargs) {
3129
+ return yargs.options(verifyOptions);
3130
+ },
3131
+ async handler(opts) {
3132
+ const profile = opts.profile;
3133
+ const configPath = await (0, import_node12.resolveConfigPath)(opts.configPath);
3134
+ const rootDir = import_node_path7.default.dirname(configPath);
3135
+ const config2 = await (0, import_node12.loadConfig)(configPath);
3136
+ const outDir = await (0, import_foundry8.getOutDirectory)(profile);
3137
+ const modules = await configToModules(config2, outDir);
3138
+ const { systems, libraries } = await resolveConfig({
3139
+ rootDir,
3140
+ config: config2,
3141
+ forgeOutDir: outDir
3142
+ });
3143
+ const rpc = opts.rpc ?? await (0, import_foundry8.getRpcUrl)(profile);
3144
+ console.log(
3145
+ import_chalk7.default.bgBlue(
3146
+ import_chalk7.default.whiteBright(`
3147
+ Verifying MUD contracts${profile ? " with profile " + profile : ""} to RPC ${rpc}
3148
+ `)
3149
+ )
3150
+ );
3151
+ const client = (0, import_viem21.createWalletClient)({
3152
+ transport: (0, import_viem21.http)(rpc, {
3153
+ batch: opts.rpcBatch ? {
3154
+ batchSize: 100,
3155
+ wait: 1e3
3156
+ } : void 0
3157
+ })
3158
+ });
3159
+ await verify({
3160
+ client,
3161
+ rpc,
3162
+ systems,
3163
+ libraries,
3164
+ modules,
3165
+ deployerAddress: opts.deployerAddress,
3166
+ worldAddress: opts.worldAddress,
3167
+ verifier: opts.verifier,
3168
+ verifierUrl: opts.verifierUrl
3169
+ });
3170
+ }
3171
+ };
3172
+ verify_default = commandModule11;
3173
+ }
3174
+ });
3175
+
3176
+ // src/deploy/getRecord.ts
3177
+ async function getRecord({
3178
+ client,
3179
+ worldDeploy,
3180
+ table,
3181
+ key
3182
+ }) {
3183
+ const [staticData, encodedLengths, dynamicData] = await (0, import_actions9.readContract)(client, {
3184
+ blockNumber: worldDeploy.stateBlock,
3185
+ address: worldDeploy.address,
3186
+ abi: worldAbi,
3187
+ functionName: "getRecord",
3188
+ args: [table.tableId, (0, import_internal18.getKeyTuple)(table, key)]
3189
+ // TODO: remove cast once https://github.com/wevm/viem/issues/2125 is resolved
3190
+ // has something to do function overloads and TS having a hard time inferring which args to use
3191
+ });
3192
+ const record = {
3193
+ ...key,
3194
+ ...(0, import_internal18.decodeValueArgs)((0, import_internal18.getSchemaTypes)((0, import_internal18.getValueSchema)(table)), {
3195
+ staticData,
3196
+ encodedLengths,
3197
+ dynamicData
3198
+ })
3199
+ };
3200
+ return (0, import_utils9.mapObject)(table.schema, (value, key2) => record[key2]);
3201
+ }
3202
+ var import_internal18, import_actions9, import_utils9;
3203
+ var init_getRecord = __esm({
3204
+ "src/deploy/getRecord.ts"() {
3205
+ "use strict";
3206
+ init_cjs_shims();
3207
+ import_internal18 = require("@latticexyz/protocol-parser/internal");
3208
+ init_common();
3209
+ import_actions9 = require("viem/actions");
3210
+ import_utils9 = require("@latticexyz/common/utils");
3211
+ }
3212
+ });
3213
+
3214
+ // src/pull/debug.ts
3215
+ var debug3, error3;
3216
+ var init_debug3 = __esm({
3217
+ "src/pull/debug.ts"() {
3218
+ "use strict";
3219
+ init_cjs_shims();
3220
+ init_debug();
3221
+ debug3 = debug.extend("pull");
3222
+ error3 = debug.extend("pull");
3223
+ debug3.log = console.debug.bind(console);
3224
+ error3.log = console.error.bind(console);
3225
+ }
3226
+ });
3227
+
3228
+ // src/pull/pull.ts
3229
+ function namespaceToHex(namespace) {
3230
+ return (0, import_common25.resourceToHex)({ type: "namespace", namespace, name: "" });
3231
+ }
3232
+ async function pull({ rootDir, client, worldAddress, replace, indexerUrl, chainId }) {
3233
+ const replaceFiles = replace ?? await (0, import_find_up3.findUp)(".git", { cwd: rootDir }) != null;
3234
+ const worldDeploy = await getWorldDeploy(client, worldAddress);
3235
+ const resourceIds = await getResourceIds({ client, worldDeploy, indexerUrl, chainId });
3236
+ const resources = resourceIds.map(import_common25.hexToResource).filter((resource) => !ignoredNamespaces.has(resource.namespace));
3237
+ const tables = await getTables({ client, worldDeploy, indexerUrl, chainId });
3238
+ const labels = Object.fromEntries(
3239
+ (await Promise.all(
3240
+ resourceIds.map(async (resourceId) => {
3241
+ const { value: bytesValue } = await getRecord({
3242
+ client,
3243
+ worldDeploy,
3244
+ table: import_mud8.default.tables.metadata__ResourceTag,
3245
+ key: { resource: resourceId, tag: (0, import_viem22.stringToHex)("label", { size: 32 }) }
3246
+ });
3247
+ const value = (0, import_viem22.hexToString)(bytesValue);
3248
+ return [resourceId, value === "" ? null : value];
3249
+ })
3250
+ )).filter(([, label]) => label != null)
3251
+ );
3252
+ labels[namespaceToHex("")] ??= "root";
3253
+ const worldFunctions = await (0, import_world4.getFunctions)({
3254
+ client,
3255
+ worldAddress: worldDeploy.address,
3256
+ fromBlock: worldDeploy.deployBlock,
3257
+ toBlock: worldDeploy.stateBlock,
3258
+ indexerUrl,
3259
+ chainId
3260
+ });
3261
+ const namespaces = resources.filter((resource) => resource.type === "namespace");
3262
+ const systems = await Promise.all(
3263
+ resources.filter((resource) => resource.type === "system").map(async ({ namespace, name, resourceId: systemId }) => {
3264
+ const namespaceId = namespaceToHex(namespace);
3265
+ const systemLabel = labels[systemId] ?? name.replace(/(S(y(s(t(e(m)?)?)?)?)?)?$/, "System");
3266
+ const [metadataAbi2, metadataWorldAbi] = await Promise.all([
3267
+ getRecord({
3268
+ client,
3269
+ worldDeploy,
3270
+ table: import_mud8.default.tables.metadata__ResourceTag,
3271
+ key: { resource: systemId, tag: (0, import_viem22.stringToHex)("abi", { size: 32 }) }
3272
+ }).then((record) => (0, import_viem22.hexToString)(record.value)).then((value) => value !== "" ? value.split("\n") : []),
3273
+ getRecord({
3274
+ client,
3275
+ worldDeploy,
3276
+ table: import_mud8.default.tables.metadata__ResourceTag,
3277
+ key: { resource: systemId, tag: (0, import_viem22.stringToHex)("worldAbi", { size: 32 }) }
3278
+ }).then((record) => (0, import_viem22.hexToString)(record.value)).then((value) => value !== "" ? value.split("\n") : [])
3279
+ ]);
3280
+ const functions = worldFunctions.filter((func) => func.systemId === systemId);
3281
+ const abi = (metadataAbi2.length ? metadataAbi2 : functions.map((func) => `function ${func.systemFunctionSignature}`)).map((sig) => {
3282
+ try {
3283
+ return (0, import_viem22.parseAbiItem)(sig);
3284
+ } catch {
3285
+ debug3(`Skipping invalid system signature: ${sig}`);
3286
+ }
3287
+ }).filter(import_utils10.isDefined);
3288
+ const worldAbi3 = (metadataWorldAbi.length ? metadataWorldAbi : functions.map((func) => `function ${func.signature}`)).map((sig) => {
3289
+ try {
3290
+ return (0, import_viem22.parseAbiItem)(sig);
3291
+ } catch {
3292
+ debug3(`Skipping invalid world signature: ${sig}`);
3293
+ }
3294
+ }).filter(import_utils10.isDefined);
3295
+ return {
3296
+ namespaceId,
3297
+ namespaceLabel: labels[namespaceId] ?? namespace,
3298
+ label: systemLabel,
3299
+ systemId,
3300
+ namespace,
3301
+ name,
3302
+ abi,
3303
+ worldAbi: worldAbi3
3304
+ };
3305
+ })
3306
+ );
3307
+ debug3("generating config");
3308
+ const configInput = {
3309
+ namespaces: Object.fromEntries(
3310
+ namespaces.map(({ namespace, resourceId: namespaceId }) => {
3311
+ const namespaceLabel = labels[namespaceId] ?? namespace;
3312
+ return [
3313
+ namespaceLabel,
3314
+ {
3315
+ ...namespaceLabel !== namespace ? { namespace } : null,
3316
+ tables: Object.fromEntries(
3317
+ tables.filter((table) => table.namespace === namespace).map((table) => {
3318
+ const tableLabel = labels[table.tableId] ?? table.name;
3319
+ return [
3320
+ tableLabel,
3321
+ {
3322
+ ...tableLabel !== table.name ? { name: table.name } : null,
3323
+ ...table.type !== "table" ? { type: table.type } : null,
3324
+ schema: (0, import_internal19.getSchemaTypes)(table.schema),
3325
+ key: table.key,
3326
+ deploy: { disabled: true }
3327
+ }
3328
+ ];
3329
+ })
3330
+ )
3331
+ }
3332
+ ];
3333
+ })
3334
+ )
3335
+ };
3336
+ debug3("validating config");
3337
+ const config2 = (0, import_world5.defineWorld)(configInput);
3338
+ debug3("writing config");
3339
+ await writeFile(
3340
+ import_node_path8.default.join(rootDir, "mud.config.ts"),
3341
+ await (0, import_codegen3.formatTypescript)(`
3342
+ import { defineWorld } from "@latticexyz/world";
3343
+
3344
+ export default defineWorld(${JSON.stringify(configInput)});
3345
+ `),
3346
+ { overwrite: replaceFiles }
3347
+ );
3348
+ const remoteDir = import_node_path8.default.join(config2.sourceDirectory, "remote");
3349
+ if (replaceFiles) {
3350
+ await import_promises.default.rm(remoteDir, { recursive: true, force: true });
3351
+ }
3352
+ for (const system of systems.filter((system2) => system2.abi.length)) {
3353
+ const interfaceName = `I${system.label}`;
3354
+ const interfaceFile = import_node_path8.default.join(remoteDir, "namespaces", system.namespaceLabel, `${interfaceName}.sol`);
3355
+ debug3("writing system interface", interfaceName, "to", interfaceFile);
3356
+ const source = (0, import_codegen3.abiToInterface)({ name: interfaceName, systemId: system.systemId, abi: system.abi });
3357
+ await writeFile(import_node_path8.default.join(rootDir, interfaceFile), await (0, import_codegen3.formatSolidity)(source), { overwrite: replaceFiles });
3358
+ }
3359
+ const worldAbi2 = systems.flatMap((system) => system.worldAbi);
3360
+ if (worldAbi2.length) {
3361
+ const interfaceName = "IWorldSystems";
3362
+ const interfaceFile = import_node_path8.default.join(remoteDir, `${interfaceName}.sol`);
3363
+ debug3("writing world systems interface to", interfaceFile);
3364
+ const source = (0, import_codegen3.abiToInterface)({ name: interfaceName, abi: worldAbi2 });
3365
+ await writeFile(import_node_path8.default.join(rootDir, interfaceFile), await (0, import_codegen3.formatSolidity)(source), { overwrite: replaceFiles });
3366
+ }
3367
+ return { config: config2 };
3368
+ }
3369
+ async function exists(filename) {
3370
+ return import_promises.default.access(filename).then(
3371
+ () => true,
3372
+ () => false
3373
+ );
3374
+ }
3375
+ async function writeFile(filename, contents, opts = {}) {
3376
+ if (!opts.overwrite && await exists(filename)) {
3377
+ throw new WriteFileExistsError(filename);
3378
+ }
3379
+ await import_promises.default.mkdir(import_node_path8.default.dirname(filename), { recursive: true });
3380
+ await import_promises.default.writeFile(filename, contents);
3381
+ }
3382
+ var import_viem22, import_internal19, import_common25, import_mud8, import_node_path8, import_promises, import_world4, import_codegen3, import_world5, import_find_up3, import_utils10, ignoredNamespaces, WriteFileExistsError;
3383
+ var init_pull = __esm({
3384
+ "src/pull/pull.ts"() {
3385
+ "use strict";
3386
+ init_cjs_shims();
3387
+ import_viem22 = require("viem");
3388
+ init_getTables();
3389
+ init_getWorldDeploy();
3390
+ import_internal19 = require("@latticexyz/protocol-parser/internal");
3391
+ import_common25 = require("@latticexyz/common");
3392
+ import_mud8 = __toESM(require("@latticexyz/world-module-metadata/mud.config"), 1);
3393
+ init_getRecord();
3394
+ import_node_path8 = __toESM(require("path"), 1);
3395
+ import_promises = __toESM(require("fs/promises"), 1);
3396
+ init_getResourceIds();
3397
+ import_world4 = require("@latticexyz/store-sync/world");
3398
+ import_codegen3 = require("@latticexyz/common/codegen");
3399
+ init_debug3();
3400
+ import_world5 = require("@latticexyz/world");
3401
+ import_find_up3 = require("find-up");
3402
+ import_utils10 = require("@latticexyz/common/utils");
3403
+ ignoredNamespaces = /* @__PURE__ */ new Set(["store", "world", "metadata"]);
3404
+ WriteFileExistsError = class extends Error {
3405
+ constructor(filename) {
3406
+ super(`Attempted to write file at "${filename}", but it already exists.`);
3407
+ this.filename = filename;
3408
+ this.name = "WriteFileExistsError";
3409
+ }
3410
+ };
3411
+ }
3412
+ });
3413
+
3414
+ // src/commands/pull.ts
3415
+ var import_foundry9, import_viem23, import_chalk8, import_node_path9, import_actions10, options, commandModule12, pull_default;
3416
+ var init_pull2 = __esm({
3417
+ "src/commands/pull.ts"() {
3418
+ "use strict";
3419
+ init_cjs_shims();
3420
+ import_foundry9 = require("@latticexyz/common/foundry");
3421
+ import_viem23 = require("viem");
3422
+ import_chalk8 = __toESM(require("chalk"), 1);
3423
+ init_pull();
3424
+ import_node_path9 = __toESM(require("path"), 1);
3425
+ init_build();
3426
+ import_actions10 = require("viem/actions");
3427
+ init_defaultChains();
3428
+ options = {
3429
+ worldAddress: { type: "string", required: true, desc: "Remote world address" },
3430
+ profile: { type: "string", desc: "The foundry profile to use" },
3431
+ rpc: { type: "string", desc: "The RPC URL to use. Defaults to the RPC url from the local foundry.toml" },
3432
+ rpcBatch: {
3433
+ type: "boolean",
3434
+ desc: "Enable batch processing of RPC requests in viem client (defaults to batch size of 100 and wait of 1s)"
3435
+ },
3436
+ replace: {
3437
+ type: "boolean",
3438
+ desc: "Replace existing files and directories with data from remote world."
3439
+ },
3440
+ indexerUrl: {
3441
+ type: "string",
3442
+ desc: "The indexer URL to pull from.",
3443
+ required: false
3444
+ }
3445
+ };
3446
+ commandModule12 = {
3447
+ command: "pull",
3448
+ describe: "Pull mud.config.ts and interfaces from an existing world.",
3449
+ builder(yargs) {
3450
+ return yargs.options(options);
3451
+ },
3452
+ async handler(opts) {
3453
+ const profile = opts.profile;
3454
+ const rpc = opts.rpc ?? await (0, import_foundry9.getRpcUrl)(profile);
3455
+ const client = (0, import_viem23.createClient)({
3456
+ transport: (0, import_viem23.http)(rpc, {
3457
+ batch: opts.rpcBatch ? {
3458
+ batchSize: 100,
3459
+ wait: 1e3
3460
+ } : void 0
3461
+ })
3462
+ });
3463
+ const chainId = await (0, import_actions10.getChainId)(client);
3464
+ const indexerUrl = opts.indexerUrl ?? defaultChains.find((chain) => chain.id === chainId)?.indexerUrl;
3465
+ console.log(import_chalk8.default.bgBlue(import_chalk8.default.whiteBright(`
3466
+ Pulling MUD config from world at ${opts.worldAddress}
3467
+ `)));
3468
+ const rootDir = process.cwd();
3469
+ try {
3470
+ const { config: config2 } = await pull({
3471
+ rootDir,
3472
+ client,
3473
+ worldAddress: opts.worldAddress,
3474
+ indexerUrl,
3475
+ chainId,
3476
+ replace: opts.replace
3477
+ });
3478
+ await build({ rootDir, config: config2, foundryProfile: profile });
3479
+ } catch (error4) {
3480
+ if (error4 instanceof WriteFileExistsError) {
3481
+ console.log();
3482
+ console.log(import_chalk8.default.bgRed(import_chalk8.default.whiteBright(" Error ")));
3483
+ console.log(` Attempted to write file at "${import_node_path9.default.relative(rootDir, error4.filename)}", but it already exists.`);
3484
+ console.log();
3485
+ console.log(" To overwrite files, use `--replace` when running this command.");
3486
+ console.log();
3487
+ return;
3488
+ }
3489
+ throw error4;
3490
+ }
3491
+ }
3492
+ };
3493
+ pull_default = commandModule12;
3494
+ }
3495
+ });
3496
+
3497
+ // src/commands/index.ts
3498
+ var commands_exports = {};
3499
+ __export(commands_exports, {
3500
+ commands: () => commands
3501
+ });
3502
+ var import_internal20, import_internal21, commands;
3503
+ var init_commands = __esm({
3504
+ "src/commands/index.ts"() {
3505
+ "use strict";
3506
+ init_cjs_shims();
3507
+ import_internal20 = require("@latticexyz/gas-report/internal");
3508
+ import_internal21 = require("@latticexyz/abi-ts/internal");
3509
+ init_build2();
3510
+ init_devnode();
3511
+ init_hello();
3512
+ init_tablegen();
3513
+ init_deploy2();
3514
+ init_worldgen();
3515
+ init_set_version();
3516
+ init_test();
3517
+ init_trace();
3518
+ init_dev_contracts();
3519
+ init_verify2();
3520
+ init_pull2();
3521
+ commands = [
3522
+ build_default,
3523
+ deploy_default,
3524
+ devnode_default,
3525
+ import_internal20.command,
3526
+ hello_default,
3527
+ tablegen_default,
3528
+ worldgen_default,
3529
+ set_version_default,
3530
+ test_default,
3531
+ trace_default,
3532
+ dev_contracts_default,
3533
+ import_internal21.command,
3534
+ verify_default,
3535
+ pull_default
3536
+ ];
3537
+ }
3538
+ });
3539
+
3540
+ // src/mud.ts
3541
+ init_cjs_shims();
3542
+ var dotenv = __toESM(require("dotenv"), 1);
3543
+ dotenv.config();
3544
+ async function run() {
3545
+ const { default: yargs } = await import("yargs");
3546
+ const { default: chalk9 } = await import("chalk");
3547
+ const { hideBin } = await import("yargs/helpers");
3548
+ const { logError: logError2 } = await Promise.resolve().then(() => (init_errors(), errors_exports));
3549
+ const { commands: commands2 } = await Promise.resolve().then(() => (init_commands(), commands_exports));
3550
+ yargs(hideBin(process.argv)).scriptName("mud").command(commands2).strict().fail((msg, err) => {
3551
+ console.error(chalk9.red(msg));
3552
+ if (msg.includes("Missing required argument")) {
3553
+ console.log(
3554
+ chalk9.yellow(`Run 'pnpm mud ${process.argv[2]} --help' for a list of available and required arguments.`)
3555
+ );
3556
+ }
3557
+ console.log("");
3558
+ if (err != null) {
3559
+ logError2(err);
3560
+ console.log("");
3561
+ }
3562
+ process.exit(1);
3563
+ }).alias({ h: "help" }).argv;
3564
+ }
3565
+ run();
3566
+ //# sourceMappingURL=mud.cjs.map