@latticexyz/cli 2.0.0-alpha.0 → 2.0.0-alpha.1

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.
Files changed (82) hide show
  1. package/dist/chunk-6V563IAZ.js +283 -0
  2. package/dist/{chunk-ATAWDHWC.js → chunk-FPG73MVN.js} +5 -1
  3. package/dist/{chunk-O6HOO6WA.js → chunk-L4YLJHLJ.js} +1 -9
  4. package/dist/{chunk-J4DJQNIC.js → chunk-SKNB74MT.js} +129 -568
  5. package/dist/chunk-VQTZJIFF.js +353 -0
  6. package/dist/chunk-WZFXLDPK.js +761 -0
  7. package/dist/chunk-YL4GJLLL.js +26139 -0
  8. package/dist/chunk-ZSZDPSLH.js +3841 -0
  9. package/dist/index.d.ts +2 -3
  10. package/dist/index.js +0 -21
  11. package/dist/mud.d.ts +1 -1
  12. package/dist/mud.js +326 -4452
  13. package/dist/mud2.d.ts +1 -0
  14. package/dist/mud2.js +25 -0
  15. package/dist/render-solidity/index.d.ts +171 -0
  16. package/dist/render-solidity/index.js +49 -0
  17. package/dist/render-ts/index.d.ts +26 -0
  18. package/dist/render-ts/index.js +14 -0
  19. package/dist/utils/deprecated/index.js +3 -3
  20. package/dist/utils/index.d.ts +13 -18
  21. package/dist/utils/index.js +14 -16
  22. package/package.json +20 -21
  23. package/src/commands/deploy-v2.ts +80 -64
  24. package/src/commands/deprecated/index.ts +22 -0
  25. package/src/commands/deprecated/test.ts +1 -1
  26. package/src/commands/gas-report.ts +54 -55
  27. package/src/commands/index.ts +6 -17
  28. package/src/commands/set-version.ts +172 -0
  29. package/src/commands/tablegen.ts +5 -5
  30. package/src/commands/test-v2.ts +71 -0
  31. package/src/commands/tsgen.ts +33 -0
  32. package/src/commands/worldgen.ts +5 -4
  33. package/src/contracts/BulkUpload.sol +13 -20
  34. package/src/contracts/Deploy.sol +3 -3
  35. package/src/contracts/LibDeploy.sol +1 -1
  36. package/src/contracts/LibDeployStub.sol +1 -1
  37. package/src/index.ts +1 -15
  38. package/src/mud.ts +4 -3
  39. package/src/mud2.ts +29 -0
  40. package/src/render-solidity/common.ts +4 -4
  41. package/src/render-solidity/field.ts +25 -2
  42. package/src/render-solidity/record.ts +14 -10
  43. package/src/render-solidity/renderSystemInterface.ts +4 -4
  44. package/src/render-solidity/renderTableIndex.ts +15 -0
  45. package/src/render-solidity/renderTypesFromConfig.ts +1 -1
  46. package/src/render-solidity/tableOptions.ts +2 -2
  47. package/src/render-solidity/tablegen.ts +15 -13
  48. package/src/render-solidity/types.ts +2 -1
  49. package/src/render-solidity/userType.ts +1 -2
  50. package/src/render-solidity/worldgen.ts +8 -9
  51. package/src/render-ts/index.ts +5 -0
  52. package/src/render-ts/recsV1TableOptions.ts +39 -0
  53. package/src/render-ts/renderRecsV1Tables.ts +31 -0
  54. package/src/render-ts/schemaTypesToRecsTypeStrings.ts +202 -0
  55. package/src/render-ts/tsgen.ts +12 -0
  56. package/src/render-ts/types.ts +13 -0
  57. package/src/utils/contractToInterface.ts +5 -3
  58. package/src/utils/deploy-v2.ts +90 -84
  59. package/src/utils/errors.ts +3 -34
  60. package/src/utils/format.ts +6 -0
  61. package/src/utils/formatAndWrite.ts +11 -2
  62. package/src/utils/foundry.ts +9 -0
  63. package/src/utils/index.ts +1 -0
  64. package/dist/chunk-O57QENJ6.js +0 -23039
  65. package/dist/chunk-SLIMIO4Z.js +0 -14358
  66. package/dist/config/index.d.ts +0 -763
  67. package/dist/config/index.js +0 -83
  68. package/src/config/commonSchemas.ts +0 -34
  69. package/src/config/dynamicResolution.ts +0 -49
  70. package/src/config/index.ts +0 -24
  71. package/src/config/loadConfig.ts +0 -39
  72. package/src/config/loadStoreConfig.ts +0 -18
  73. package/src/config/parseStoreConfig.test-d.ts +0 -40
  74. package/src/config/parseStoreConfig.ts +0 -314
  75. package/src/config/validation.ts +0 -163
  76. package/src/config/world/index.ts +0 -4
  77. package/src/config/world/loadWorldConfig.test-d.ts +0 -11
  78. package/src/config/world/loadWorldConfig.ts +0 -26
  79. package/src/config/world/parseWorldConfig.ts +0 -55
  80. package/src/config/world/resolveWorldConfig.ts +0 -80
  81. package/src/config/world/userTypes.ts +0 -72
  82. package/src/utils/typeUtils.ts +0 -17
@@ -0,0 +1,31 @@
1
+ import { RecsV1TableOptions } from "./types.js";
2
+
3
+ export function renderRecsV1Tables(options: RecsV1TableOptions) {
4
+ const { tables } = options;
5
+
6
+ return `/* Autogenerated file. Do not edit manually. */
7
+
8
+ import { TableId } from "@latticexyz/utils";
9
+ import { defineComponent, Type as RecsType, World } from "@latticexyz/recs";
10
+
11
+ export function defineContractComponents(world: World) {
12
+ return {
13
+ ${tables.map((table) => `${table.tableName}: ${renderDefineComponent(table)},`).join("")}
14
+ }
15
+ }
16
+ `;
17
+ }
18
+
19
+ function renderDefineComponent(table: RecsV1TableOptions["tables"][number]) {
20
+ const { namespace, name } = table.staticResourceData;
21
+ return `
22
+ (() => {
23
+ const tableId = new TableId("${namespace}", "${name}");
24
+ return defineComponent(world, {
25
+ ${table.fields.map(({ name, recsTypeString }) => `${name}: ${recsTypeString},`).join("")}
26
+ }, {
27
+ metadata: { contractId: tableId.toHexString(), tableId: tableId.toString() },
28
+ });
29
+ })()
30
+ `;
31
+ }
@@ -0,0 +1,202 @@
1
+ import { SchemaType } from "@latticexyz/schema-type";
2
+
3
+ export const schemaTypesToRecsTypeStrings: Record<SchemaType, string> = {
4
+ [SchemaType.UINT8]: "RecsType.Number",
5
+ [SchemaType.UINT16]: "RecsType.Number",
6
+ [SchemaType.UINT24]: "RecsType.Number",
7
+ [SchemaType.UINT32]: "RecsType.Number",
8
+ [SchemaType.UINT40]: "RecsType.Number",
9
+ [SchemaType.UINT48]: "RecsType.Number",
10
+ [SchemaType.UINT56]: "RecsType.BigInt",
11
+ [SchemaType.UINT64]: "RecsType.BigInt",
12
+ [SchemaType.UINT72]: "RecsType.BigInt",
13
+ [SchemaType.UINT80]: "RecsType.BigInt",
14
+ [SchemaType.UINT88]: "RecsType.BigInt",
15
+ [SchemaType.UINT96]: "RecsType.BigInt",
16
+ [SchemaType.UINT104]: "RecsType.BigInt",
17
+ [SchemaType.UINT112]: "RecsType.BigInt",
18
+ [SchemaType.UINT120]: "RecsType.BigInt",
19
+ [SchemaType.UINT128]: "RecsType.BigInt",
20
+ [SchemaType.UINT136]: "RecsType.BigInt",
21
+ [SchemaType.UINT144]: "RecsType.BigInt",
22
+ [SchemaType.UINT152]: "RecsType.BigInt",
23
+ [SchemaType.UINT160]: "RecsType.BigInt",
24
+ [SchemaType.UINT168]: "RecsType.BigInt",
25
+ [SchemaType.UINT176]: "RecsType.BigInt",
26
+ [SchemaType.UINT184]: "RecsType.BigInt",
27
+ [SchemaType.UINT192]: "RecsType.BigInt",
28
+ [SchemaType.UINT200]: "RecsType.BigInt",
29
+ [SchemaType.UINT208]: "RecsType.BigInt",
30
+ [SchemaType.UINT216]: "RecsType.BigInt",
31
+ [SchemaType.UINT224]: "RecsType.BigInt",
32
+ [SchemaType.UINT232]: "RecsType.BigInt",
33
+ [SchemaType.UINT240]: "RecsType.BigInt",
34
+ [SchemaType.UINT248]: "RecsType.BigInt",
35
+ [SchemaType.UINT256]: "RecsType.BigInt",
36
+ [SchemaType.INT8]: "RecsType.Number",
37
+ [SchemaType.INT16]: "RecsType.Number",
38
+ [SchemaType.INT24]: "RecsType.Number",
39
+ [SchemaType.INT32]: "RecsType.Number",
40
+ [SchemaType.INT40]: "RecsType.Number",
41
+ [SchemaType.INT48]: "RecsType.Number",
42
+ [SchemaType.INT56]: "RecsType.BigInt",
43
+ [SchemaType.INT64]: "RecsType.BigInt",
44
+ [SchemaType.INT72]: "RecsType.BigInt",
45
+ [SchemaType.INT80]: "RecsType.BigInt",
46
+ [SchemaType.INT88]: "RecsType.BigInt",
47
+ [SchemaType.INT96]: "RecsType.BigInt",
48
+ [SchemaType.INT104]: "RecsType.BigInt",
49
+ [SchemaType.INT112]: "RecsType.BigInt",
50
+ [SchemaType.INT120]: "RecsType.BigInt",
51
+ [SchemaType.INT128]: "RecsType.BigInt",
52
+ [SchemaType.INT136]: "RecsType.BigInt",
53
+ [SchemaType.INT144]: "RecsType.BigInt",
54
+ [SchemaType.INT152]: "RecsType.BigInt",
55
+ [SchemaType.INT160]: "RecsType.BigInt",
56
+ [SchemaType.INT168]: "RecsType.BigInt",
57
+ [SchemaType.INT176]: "RecsType.BigInt",
58
+ [SchemaType.INT184]: "RecsType.BigInt",
59
+ [SchemaType.INT192]: "RecsType.BigInt",
60
+ [SchemaType.INT200]: "RecsType.BigInt",
61
+ [SchemaType.INT208]: "RecsType.BigInt",
62
+ [SchemaType.INT216]: "RecsType.BigInt",
63
+ [SchemaType.INT224]: "RecsType.BigInt",
64
+ [SchemaType.INT232]: "RecsType.BigInt",
65
+ [SchemaType.INT240]: "RecsType.BigInt",
66
+ [SchemaType.INT248]: "RecsType.BigInt",
67
+ [SchemaType.INT256]: "RecsType.BigInt",
68
+ [SchemaType.BYTES1]: "RecsType.String",
69
+ [SchemaType.BYTES2]: "RecsType.String",
70
+ [SchemaType.BYTES3]: "RecsType.String",
71
+ [SchemaType.BYTES4]: "RecsType.String",
72
+ [SchemaType.BYTES5]: "RecsType.String",
73
+ [SchemaType.BYTES6]: "RecsType.String",
74
+ [SchemaType.BYTES7]: "RecsType.String",
75
+ [SchemaType.BYTES8]: "RecsType.String",
76
+ [SchemaType.BYTES9]: "RecsType.String",
77
+ [SchemaType.BYTES10]: "RecsType.String",
78
+ [SchemaType.BYTES11]: "RecsType.String",
79
+ [SchemaType.BYTES12]: "RecsType.String",
80
+ [SchemaType.BYTES13]: "RecsType.String",
81
+ [SchemaType.BYTES14]: "RecsType.String",
82
+ [SchemaType.BYTES15]: "RecsType.String",
83
+ [SchemaType.BYTES16]: "RecsType.String",
84
+ [SchemaType.BYTES17]: "RecsType.String",
85
+ [SchemaType.BYTES18]: "RecsType.String",
86
+ [SchemaType.BYTES19]: "RecsType.String",
87
+ [SchemaType.BYTES20]: "RecsType.String",
88
+ [SchemaType.BYTES21]: "RecsType.String",
89
+ [SchemaType.BYTES22]: "RecsType.String",
90
+ [SchemaType.BYTES23]: "RecsType.String",
91
+ [SchemaType.BYTES24]: "RecsType.String",
92
+ [SchemaType.BYTES25]: "RecsType.String",
93
+ [SchemaType.BYTES26]: "RecsType.String",
94
+ [SchemaType.BYTES27]: "RecsType.String",
95
+ [SchemaType.BYTES28]: "RecsType.String",
96
+ [SchemaType.BYTES29]: "RecsType.String",
97
+ [SchemaType.BYTES30]: "RecsType.String",
98
+ [SchemaType.BYTES31]: "RecsType.String",
99
+ [SchemaType.BYTES32]: "RecsType.String",
100
+ [SchemaType.BOOL]: "RecsType.Boolean",
101
+ [SchemaType.ADDRESS]: "RecsType.String",
102
+ [SchemaType.UINT8_ARRAY]: "RecsType.NumberArray",
103
+ [SchemaType.UINT16_ARRAY]: "RecsType.NumberArray",
104
+ [SchemaType.UINT24_ARRAY]: "RecsType.NumberArray",
105
+ [SchemaType.UINT32_ARRAY]: "RecsType.NumberArray",
106
+ [SchemaType.UINT40_ARRAY]: "RecsType.NumberArray",
107
+ [SchemaType.UINT48_ARRAY]: "RecsType.NumberArray",
108
+ [SchemaType.UINT56_ARRAY]: "RecsType.BigIntArray",
109
+ [SchemaType.UINT64_ARRAY]: "RecsType.BigIntArray",
110
+ [SchemaType.UINT72_ARRAY]: "RecsType.BigIntArray",
111
+ [SchemaType.UINT80_ARRAY]: "RecsType.BigIntArray",
112
+ [SchemaType.UINT88_ARRAY]: "RecsType.BigIntArray",
113
+ [SchemaType.UINT96_ARRAY]: "RecsType.BigIntArray",
114
+ [SchemaType.UINT104_ARRAY]: "RecsType.BigIntArray",
115
+ [SchemaType.UINT112_ARRAY]: "RecsType.BigIntArray",
116
+ [SchemaType.UINT120_ARRAY]: "RecsType.BigIntArray",
117
+ [SchemaType.UINT128_ARRAY]: "RecsType.BigIntArray",
118
+ [SchemaType.UINT136_ARRAY]: "RecsType.BigIntArray",
119
+ [SchemaType.UINT144_ARRAY]: "RecsType.BigIntArray",
120
+ [SchemaType.UINT152_ARRAY]: "RecsType.BigIntArray",
121
+ [SchemaType.UINT160_ARRAY]: "RecsType.BigIntArray",
122
+ [SchemaType.UINT168_ARRAY]: "RecsType.BigIntArray",
123
+ [SchemaType.UINT176_ARRAY]: "RecsType.BigIntArray",
124
+ [SchemaType.UINT184_ARRAY]: "RecsType.BigIntArray",
125
+ [SchemaType.UINT192_ARRAY]: "RecsType.BigIntArray",
126
+ [SchemaType.UINT200_ARRAY]: "RecsType.BigIntArray",
127
+ [SchemaType.UINT208_ARRAY]: "RecsType.BigIntArray",
128
+ [SchemaType.UINT216_ARRAY]: "RecsType.BigIntArray",
129
+ [SchemaType.UINT224_ARRAY]: "RecsType.BigIntArray",
130
+ [SchemaType.UINT232_ARRAY]: "RecsType.BigIntArray",
131
+ [SchemaType.UINT240_ARRAY]: "RecsType.BigIntArray",
132
+ [SchemaType.UINT248_ARRAY]: "RecsType.BigIntArray",
133
+ [SchemaType.UINT256_ARRAY]: "RecsType.BigIntArray",
134
+ [SchemaType.INT8_ARRAY]: "RecsType.NumberArray",
135
+ [SchemaType.INT16_ARRAY]: "RecsType.NumberArray",
136
+ [SchemaType.INT24_ARRAY]: "RecsType.NumberArray",
137
+ [SchemaType.INT32_ARRAY]: "RecsType.NumberArray",
138
+ [SchemaType.INT40_ARRAY]: "RecsType.NumberArray",
139
+ [SchemaType.INT48_ARRAY]: "RecsType.NumberArray",
140
+ [SchemaType.INT56_ARRAY]: "RecsType.BigIntArray",
141
+ [SchemaType.INT64_ARRAY]: "RecsType.BigIntArray",
142
+ [SchemaType.INT72_ARRAY]: "RecsType.BigIntArray",
143
+ [SchemaType.INT80_ARRAY]: "RecsType.BigIntArray",
144
+ [SchemaType.INT88_ARRAY]: "RecsType.BigIntArray",
145
+ [SchemaType.INT96_ARRAY]: "RecsType.BigIntArray",
146
+ [SchemaType.INT104_ARRAY]: "RecsType.BigIntArray",
147
+ [SchemaType.INT112_ARRAY]: "RecsType.BigIntArray",
148
+ [SchemaType.INT120_ARRAY]: "RecsType.BigIntArray",
149
+ [SchemaType.INT128_ARRAY]: "RecsType.BigIntArray",
150
+ [SchemaType.INT136_ARRAY]: "RecsType.BigIntArray",
151
+ [SchemaType.INT144_ARRAY]: "RecsType.BigIntArray",
152
+ [SchemaType.INT152_ARRAY]: "RecsType.BigIntArray",
153
+ [SchemaType.INT160_ARRAY]: "RecsType.BigIntArray",
154
+ [SchemaType.INT168_ARRAY]: "RecsType.BigIntArray",
155
+ [SchemaType.INT176_ARRAY]: "RecsType.BigIntArray",
156
+ [SchemaType.INT184_ARRAY]: "RecsType.BigIntArray",
157
+ [SchemaType.INT192_ARRAY]: "RecsType.BigIntArray",
158
+ [SchemaType.INT200_ARRAY]: "RecsType.BigIntArray",
159
+ [SchemaType.INT208_ARRAY]: "RecsType.BigIntArray",
160
+ [SchemaType.INT216_ARRAY]: "RecsType.BigIntArray",
161
+ [SchemaType.INT224_ARRAY]: "RecsType.BigIntArray",
162
+ [SchemaType.INT232_ARRAY]: "RecsType.BigIntArray",
163
+ [SchemaType.INT240_ARRAY]: "RecsType.BigIntArray",
164
+ [SchemaType.INT248_ARRAY]: "RecsType.BigIntArray",
165
+ [SchemaType.INT256_ARRAY]: "RecsType.BigIntArray",
166
+ [SchemaType.BYTES1_ARRAY]: "RecsType.BigIntArray",
167
+ [SchemaType.BYTES2_ARRAY]: "RecsType.BigIntArray",
168
+ [SchemaType.BYTES3_ARRAY]: "RecsType.BigIntArray",
169
+ [SchemaType.BYTES4_ARRAY]: "RecsType.BigIntArray",
170
+ [SchemaType.BYTES5_ARRAY]: "RecsType.BigIntArray",
171
+ [SchemaType.BYTES6_ARRAY]: "RecsType.BigIntArray",
172
+ [SchemaType.BYTES7_ARRAY]: "RecsType.BigIntArray",
173
+ [SchemaType.BYTES8_ARRAY]: "RecsType.BigIntArray",
174
+ [SchemaType.BYTES9_ARRAY]: "RecsType.BigIntArray",
175
+ [SchemaType.BYTES10_ARRAY]: "RecsType.BigIntArray",
176
+ [SchemaType.BYTES11_ARRAY]: "RecsType.BigIntArray",
177
+ [SchemaType.BYTES12_ARRAY]: "RecsType.BigIntArray",
178
+ [SchemaType.BYTES13_ARRAY]: "RecsType.BigIntArray",
179
+ [SchemaType.BYTES14_ARRAY]: "RecsType.BigIntArray",
180
+ [SchemaType.BYTES15_ARRAY]: "RecsType.BigIntArray",
181
+ [SchemaType.BYTES16_ARRAY]: "RecsType.BigIntArray",
182
+ [SchemaType.BYTES17_ARRAY]: "RecsType.BigIntArray",
183
+ [SchemaType.BYTES18_ARRAY]: "RecsType.BigIntArray",
184
+ [SchemaType.BYTES19_ARRAY]: "RecsType.BigIntArray",
185
+ [SchemaType.BYTES20_ARRAY]: "RecsType.BigIntArray",
186
+ [SchemaType.BYTES21_ARRAY]: "RecsType.BigIntArray",
187
+ [SchemaType.BYTES22_ARRAY]: "RecsType.BigIntArray",
188
+ [SchemaType.BYTES23_ARRAY]: "RecsType.BigIntArray",
189
+ [SchemaType.BYTES24_ARRAY]: "RecsType.BigIntArray",
190
+ [SchemaType.BYTES25_ARRAY]: "RecsType.BigIntArray",
191
+ [SchemaType.BYTES26_ARRAY]: "RecsType.BigIntArray",
192
+ [SchemaType.BYTES27_ARRAY]: "RecsType.BigIntArray",
193
+ [SchemaType.BYTES28_ARRAY]: "RecsType.BigIntArray",
194
+ [SchemaType.BYTES29_ARRAY]: "RecsType.BigIntArray",
195
+ [SchemaType.BYTES30_ARRAY]: "RecsType.BigIntArray",
196
+ [SchemaType.BYTES31_ARRAY]: "RecsType.BigIntArray",
197
+ [SchemaType.BYTES32_ARRAY]: "RecsType.BigIntArray",
198
+ [SchemaType.BOOL_ARRAY]: "RecsType.T", // no boolean array
199
+ [SchemaType.ADDRESS_ARRAY]: "RecsType.StringArray",
200
+ [SchemaType.BYTES]: "RecsType.String",
201
+ [SchemaType.STRING]: "RecsType.String",
202
+ };
@@ -0,0 +1,12 @@
1
+ import path from "path";
2
+ import { StoreConfig } from "@latticexyz/config";
3
+ import { getRecsV1TableOptions } from "../render-ts/recsV1TableOptions.js";
4
+ import { renderRecsV1Tables } from "../render-ts/renderRecsV1Tables.js";
5
+ import { formatAndWriteTypescript } from "../utils/formatAndWrite.js";
6
+
7
+ export async function tsgen(config: StoreConfig, outDirectory: string) {
8
+ const fullOutputPath = path.join(outDirectory, `contractComponents.ts`);
9
+ const options = getRecsV1TableOptions(config);
10
+ const output = renderRecsV1Tables(options);
11
+ formatAndWriteTypescript(output, fullOutputPath, "Generated ts definition files");
12
+ }
@@ -0,0 +1,13 @@
1
+ export interface RecsV1TableOptions {
2
+ tables: {
3
+ tableName: string;
4
+ fields: {
5
+ recsTypeString: string;
6
+ name: string;
7
+ }[];
8
+ staticResourceData: {
9
+ namespace: string;
10
+ name: string;
11
+ };
12
+ }[];
13
+ }
@@ -1,7 +1,7 @@
1
1
  import { parse, visit } from "@solidity-parser/parser";
2
2
  import { TypeName, VariableDeclaration } from "@solidity-parser/parser/dist/src/ast-types.js";
3
+ import { MUDError } from "@latticexyz/config";
3
4
  import { RenderSystemInterfaceFunction } from "../render-solidity/types.js";
4
- import { MUDError } from "./errors.js";
5
5
 
6
6
  /**
7
7
  * Parse the contract data to get the functions necessary to generate an interface,
@@ -24,7 +24,7 @@ export function contractToInterface(data: string, contractName: string) {
24
24
  }
25
25
  },
26
26
  FunctionDefinition(
27
- { name, visibility, parameters, returnParameters, isConstructor, isFallback, isReceiveEther },
27
+ { name, visibility, parameters, stateMutability, returnParameters, isConstructor, isFallback, isReceiveEther },
28
28
  parent
29
29
  ) {
30
30
  if (parent !== undefined && parent.type === "ContractDefinition" && parent.name === contractName) {
@@ -38,6 +38,7 @@ export function contractToInterface(data: string, contractName: string) {
38
38
  functions.push({
39
39
  name: name === null ? "" : name,
40
40
  parameters: parameters.map(parseParameter),
41
+ stateMutability: stateMutability || "",
41
42
  returnParameters: returnParameters === null ? [] : returnParameters.map(parseParameter),
42
43
  });
43
44
 
@@ -105,9 +106,10 @@ function flattenTypeName(typeName: TypeName | null): { name: string; stateMutabi
105
106
  stateMutability: null,
106
107
  };
107
108
  } else if (typeName.type === "ArrayTypeName") {
109
+ const length = typeName.length?.type === "NumberLiteral" ? typeName.length.number : "";
108
110
  const { name, stateMutability } = flattenTypeName(typeName.baseTypeName);
109
111
  return {
110
- name: `${name}[]`,
112
+ name: `${name}[${length}]`,
111
113
  stateMutability,
112
114
  };
113
115
  } else {
@@ -1,21 +1,21 @@
1
1
  import { existsSync, readFileSync } from "fs";
2
2
  import path from "path";
3
- import { MUDConfig, resolveWithContext } from "../config/index.js";
4
- import { MUDError } from "./errors.js";
3
+ import { MUDConfig, resolveWithContext } from "@latticexyz/config";
4
+ import { MUDError } from "@latticexyz/config";
5
5
  import { getOutDirectory, getScriptDirectory, cast, forge } from "./foundry.js";
6
6
  import { BigNumber, ContractInterface, ethers } from "ethers";
7
- import { IWorld } from "@latticexyz/world/types/ethers-contracts/IWorld.js";
8
- import { ArgumentsType } from "vitest";
7
+ import { IBaseWorld } from "@latticexyz/world/types/ethers-contracts/IBaseWorld.js";
9
8
  import chalk from "chalk";
10
9
  import { encodeSchema } from "@latticexyz/schema-type";
11
10
  import { resolveAbiOrUserType } from "../render-solidity/userType.js";
12
11
  import { defaultAbiCoder as abi, Fragment } from "ethers/lib/utils.js";
13
12
 
14
13
  import WorldData from "@latticexyz/world/abi/World.json" assert { type: "json" };
15
- import IWorldData from "@latticexyz/world/abi/IWorld.json" assert { type: "json" };
14
+ import IBaseWorldData from "@latticexyz/world/abi/IBaseWorld.json" assert { type: "json" };
16
15
  import CoreModuleData from "@latticexyz/world/abi/CoreModule.json" assert { type: "json" };
17
16
  import RegistrationModuleData from "@latticexyz/world/abi/RegistrationModule.json" assert { type: "json" };
18
17
  import KeysWithValueModuleData from "@latticexyz/world/abi/KeysWithValueModule.json" assert { type: "json" };
18
+ import UniqueEntityModuleData from "@latticexyz/world/abi/UniqueEntityModule.json" assert { type: "json" };
19
19
 
20
20
  export interface DeployConfig {
21
21
  profile?: string;
@@ -23,6 +23,7 @@ export interface DeployConfig {
23
23
  privateKey: string;
24
24
  priorityFeeMultiplier: number;
25
25
  debug?: boolean;
26
+ worldAddress?: string;
26
27
  }
27
28
 
28
29
  export interface DeploymentInfo {
@@ -33,7 +34,7 @@ export interface DeploymentInfo {
33
34
  export async function deploy(mudConfig: MUDConfig, deployConfig: DeployConfig): Promise<DeploymentInfo> {
34
35
  const startTime = Date.now();
35
36
  const { worldContractName, namespace, postDeployScript } = mudConfig;
36
- const { profile, rpc, privateKey, priorityFeeMultiplier, debug } = deployConfig;
37
+ const { profile, rpc, privateKey, priorityFeeMultiplier, debug, worldAddress } = deployConfig;
37
38
  const forgeOutDirectory = await getOutDirectory(profile);
38
39
 
39
40
  // Set up signer for deployment
@@ -58,9 +59,11 @@ export async function deploy(mudConfig: MUDConfig, deployConfig: DeployConfig):
58
59
 
59
60
  // Deploy World
60
61
  const worldPromise = {
61
- World: worldContractName
62
+ World: worldAddress
63
+ ? Promise.resolve(worldAddress)
64
+ : worldContractName
62
65
  ? deployContractByName(worldContractName)
63
- : deployContract(IWorldData.abi, WorldData.bytecode, "World"),
66
+ : deployContract(IBaseWorldData.abi, WorldData.bytecode, "World"),
64
67
  };
65
68
 
66
69
  // Deploy Systems
@@ -83,6 +86,11 @@ export async function deploy(mudConfig: MUDConfig, deployConfig: DeployConfig):
83
86
  KeysWithValueModuleData.bytecode,
84
87
  "KeysWithValueModule"
85
88
  ),
89
+ UniqueEntityModule: deployContract(
90
+ UniqueEntityModuleData.abi,
91
+ UniqueEntityModuleData.bytecode,
92
+ "UniqueEntityModule"
93
+ ),
86
94
  };
87
95
 
88
96
  // Deploy user Modules
@@ -97,13 +105,15 @@ export async function deploy(mudConfig: MUDConfig, deployConfig: DeployConfig):
97
105
  const contractPromises: Record<string, Promise<string>> = { ...worldPromise, ...systemPromises, ...modulePromises };
98
106
 
99
107
  // Create World contract instance from deployed address
100
- const WorldContract = new ethers.Contract(await contractPromises.World, IWorldData.abi, signer) as IWorld;
108
+ const WorldContract = new ethers.Contract(await contractPromises.World, IBaseWorldData.abi, signer) as IBaseWorld;
101
109
 
102
110
  // Install core Modules
103
- console.log(chalk.blue("Installing core World modules"));
104
- await fastTxExecute(WorldContract, "installRootModule", [await modulePromises.CoreModule, "0x"]);
105
- await fastTxExecute(WorldContract, "installRootModule", [await modulePromises.RegistrationModule, "0x"]);
106
- console.log(chalk.green("Installed core World modules"));
111
+ if (!worldAddress) {
112
+ console.log(chalk.blue("Installing core World modules"));
113
+ await fastTxExecute(WorldContract, "installRootModule", [await modulePromises.CoreModule, "0x"]);
114
+ await fastTxExecute(WorldContract, "installRootModule", [await modulePromises.RegistrationModule, "0x"]);
115
+ console.log(chalk.green("Installed core World modules"));
116
+ }
107
117
 
108
118
  // Register namespace
109
119
  if (namespace) await fastTxExecute(WorldContract, "registerNamespace", [toBytes16(namespace)]);
@@ -112,11 +122,11 @@ export async function deploy(mudConfig: MUDConfig, deployConfig: DeployConfig):
112
122
  const tableIds: { [tableName: string]: Uint8Array } = {};
113
123
  promises = [
114
124
  ...promises,
115
- ...Object.entries(mudConfig.tables).map(async ([tableName, { fileSelector, schema, primaryKeys }]) => {
116
- console.log(chalk.blue(`Registering table ${tableName} at ${namespace}/${fileSelector}`));
125
+ ...Object.entries(mudConfig.tables).map(async ([tableName, { name, schema, primaryKeys }]) => {
126
+ console.log(chalk.blue(`Registering table ${tableName} at ${namespace}/${name}`));
117
127
 
118
128
  // Store the tableId for later use
119
- tableIds[tableName] = toResourceSelector(namespace, fileSelector);
129
+ tableIds[tableName] = toResourceSelector(namespace, name);
120
130
 
121
131
  // Register table
122
132
  const schemaTypes = Object.values(schema).map((abiOrUserType) => {
@@ -131,7 +141,7 @@ export async function deploy(mudConfig: MUDConfig, deployConfig: DeployConfig):
131
141
 
132
142
  await fastTxExecute(WorldContract, "registerTable", [
133
143
  toBytes16(namespace),
134
- toBytes16(fileSelector),
144
+ toBytes16(name),
135
145
  encodeSchema(schemaTypes),
136
146
  encodeSchema(keyTypes),
137
147
  ]);
@@ -139,69 +149,67 @@ export async function deploy(mudConfig: MUDConfig, deployConfig: DeployConfig):
139
149
  // Register table metadata
140
150
  await fastTxExecute(WorldContract, "setMetadata(bytes16,bytes16,string,string[])", [
141
151
  toBytes16(namespace),
142
- toBytes16(fileSelector),
152
+ toBytes16(name),
143
153
  tableName,
144
154
  Object.keys(schema),
145
155
  ]);
146
156
 
147
- console.log(chalk.green(`Registered table ${tableName} at ${fileSelector}`));
157
+ console.log(chalk.green(`Registered table ${tableName} at ${name}`));
148
158
  }),
149
159
  ];
150
160
 
151
161
  // Register systems (using forEach instead of for..of to avoid blocking on async calls)
152
162
  promises = [
153
163
  ...promises,
154
- ...Object.entries(mudConfig.systems).map(
155
- async ([systemName, { fileSelector, openAccess, registerFunctionSelectors }]) => {
156
- // Register system at route
157
- console.log(chalk.blue(`Registering system ${systemName} at ${namespace}/${fileSelector}`));
158
- await fastTxExecute(WorldContract, "registerSystem", [
159
- toBytes16(namespace),
160
- toBytes16(fileSelector),
161
- await contractPromises[systemName],
162
- openAccess,
163
- ]);
164
- console.log(chalk.green(`Registered system ${systemName} at ${namespace}/${fileSelector}`));
165
-
166
- // Register function selectors for the system
167
- if (registerFunctionSelectors) {
168
- const functionSignatures: FunctionSignature[] = await loadFunctionSignatures(systemName);
169
- const isRoot = namespace === "";
170
- // Using Promise.all to avoid blocking on async calls
171
- await Promise.all(
172
- functionSignatures.map(async ({ functionName, functionArgs }) => {
173
- const functionSignature = isRoot
174
- ? functionName + functionArgs
175
- : `${namespace}_${fileSelector}_${functionName}${functionArgs}`;
176
-
177
- console.log(chalk.blue(`Registering function "${functionSignature}"`));
178
- if (isRoot) {
179
- const worldFunctionSelector = toFunctionSelector(
180
- functionSignature === ""
181
- ? { functionName: systemName, functionArgs } // Register the system's fallback function as `<systemName>(<args>)`
182
- : { functionName, functionArgs }
183
- );
184
- const systemFunctionSelector = toFunctionSelector({ functionName, functionArgs });
185
- await fastTxExecute(WorldContract, "registerRootFunctionSelector", [
186
- toBytes16(namespace),
187
- toBytes16(fileSelector),
188
- worldFunctionSelector,
189
- systemFunctionSelector,
190
- ]);
191
- } else {
192
- await fastTxExecute(WorldContract, "registerFunctionSelector", [
193
- toBytes16(namespace),
194
- toBytes16(fileSelector),
195
- functionName,
196
- functionArgs,
197
- ]);
198
- }
199
- console.log(chalk.green(`Registered function "${functionSignature}"`));
200
- })
201
- );
202
- }
164
+ ...Object.entries(mudConfig.systems).map(async ([systemName, { name, openAccess, registerFunctionSelectors }]) => {
165
+ // Register system at route
166
+ console.log(chalk.blue(`Registering system ${systemName} at ${namespace}/${name}`));
167
+ await fastTxExecute(WorldContract, "registerSystem", [
168
+ toBytes16(namespace),
169
+ toBytes16(name),
170
+ await contractPromises[systemName],
171
+ openAccess,
172
+ ]);
173
+ console.log(chalk.green(`Registered system ${systemName} at ${namespace}/${name}`));
174
+
175
+ // Register function selectors for the system
176
+ if (registerFunctionSelectors) {
177
+ const functionSignatures: FunctionSignature[] = await loadFunctionSignatures(systemName);
178
+ const isRoot = namespace === "";
179
+ // Using Promise.all to avoid blocking on async calls
180
+ await Promise.all(
181
+ functionSignatures.map(async ({ functionName, functionArgs }) => {
182
+ const functionSignature = isRoot
183
+ ? functionName + functionArgs
184
+ : `${namespace}_${name}_${functionName}${functionArgs}`;
185
+
186
+ console.log(chalk.blue(`Registering function "${functionSignature}"`));
187
+ if (isRoot) {
188
+ const worldFunctionSelector = toFunctionSelector(
189
+ functionSignature === ""
190
+ ? { functionName: systemName, functionArgs } // Register the system's fallback function as `<systemName>(<args>)`
191
+ : { functionName, functionArgs }
192
+ );
193
+ const systemFunctionSelector = toFunctionSelector({ functionName, functionArgs });
194
+ await fastTxExecute(WorldContract, "registerRootFunctionSelector", [
195
+ toBytes16(namespace),
196
+ toBytes16(name),
197
+ worldFunctionSelector,
198
+ systemFunctionSelector,
199
+ ]);
200
+ } else {
201
+ await fastTxExecute(WorldContract, "registerFunctionSelector", [
202
+ toBytes16(namespace),
203
+ toBytes16(name),
204
+ functionName,
205
+ functionArgs,
206
+ ]);
207
+ }
208
+ console.log(chalk.green(`Registered function "${functionSignature}"`));
209
+ })
210
+ );
203
211
  }
204
- ),
212
+ }),
205
213
  ];
206
214
 
207
215
  // Wait for resources to be registered before granting access to them
@@ -209,10 +217,8 @@ export async function deploy(mudConfig: MUDConfig, deployConfig: DeployConfig):
209
217
  promises = [];
210
218
 
211
219
  // Grant access to systems
212
- for (const [systemName, { fileSelector, accessListAddresses, accessListSystems }] of Object.entries(
213
- mudConfig.systems
214
- )) {
215
- const resourceSelector = `${namespace}/${fileSelector}`;
220
+ for (const [systemName, { name, accessListAddresses, accessListSystems }] of Object.entries(mudConfig.systems)) {
221
+ const resourceSelector = `${namespace}/${name}`;
216
222
 
217
223
  // Grant access to addresses
218
224
  promises = [
@@ -221,10 +227,10 @@ export async function deploy(mudConfig: MUDConfig, deployConfig: DeployConfig):
221
227
  console.log(chalk.blue(`Grant ${address} access to ${systemName} (${resourceSelector})`));
222
228
  await fastTxExecute(WorldContract, "grantAccess(bytes16,bytes16,address)", [
223
229
  toBytes16(namespace),
224
- toBytes16(fileSelector),
230
+ toBytes16(name),
225
231
  address,
226
232
  ]);
227
- console.log(chalk.green(`Granted ${address} access to ${systemName} (${namespace}/${fileSelector})`));
233
+ console.log(chalk.green(`Granted ${address} access to ${systemName} (${namespace}/${name})`));
228
234
  }),
229
235
  ];
230
236
 
@@ -235,7 +241,7 @@ export async function deploy(mudConfig: MUDConfig, deployConfig: DeployConfig):
235
241
  console.log(chalk.blue(`Grant ${granteeSystem} access to ${systemName} (${resourceSelector})`));
236
242
  await fastTxExecute(WorldContract, "grantAccess(bytes16,bytes16,address)", [
237
243
  toBytes16(namespace),
238
- toBytes16(fileSelector),
244
+ toBytes16(name),
239
245
  await contractPromises[granteeSystem],
240
246
  ]);
241
247
  console.log(chalk.green(`Granted ${granteeSystem} access to ${systemName} (${resourceSelector})`));
@@ -402,17 +408,17 @@ export async function deploy(mudConfig: MUDConfig, deployConfig: DeployConfig):
402
408
  async function fastTxExecute<C extends { estimateGas: any; [key: string]: any }, F extends keyof C>(
403
409
  contract: C,
404
410
  func: F,
405
- args: ArgumentsType<C[F]>,
406
- retryCount = 0
407
- ): Promise<Awaited<ReturnType<C[F]>>> {
411
+ args: Parameters<C[F]>,
412
+ retryCount = 0,
413
+ confirmations = 1
414
+ ): Promise<Awaited<ReturnType<Awaited<ReturnType<C[F]>>["wait"]>>> {
408
415
  const functionName = `${func as string}(${args.map((arg) => `'${arg}'`).join(",")})`;
409
416
  try {
410
417
  const gasLimit = await contract.estimateGas[func].apply(null, args);
411
418
  console.log(chalk.gray(`executing transaction: ${functionName} with nonce ${nonce}`));
412
- const txPromise = contract[func].apply(null, [
413
- ...args,
414
- { gasLimit, nonce: nonce++, maxPriorityFeePerGas, maxFeePerGas },
415
- ]);
419
+ const txPromise = contract[func]
420
+ .apply(null, [...args, { gasLimit, nonce: nonce++, maxPriorityFeePerGas, maxFeePerGas }])
421
+ .then((tx: any) => tx.wait(confirmations));
416
422
  promises.push(txPromise);
417
423
  return txPromise;
418
424
  } catch (error: any) {
@@ -421,7 +427,7 @@ export async function deploy(mudConfig: MUDConfig, deployConfig: DeployConfig):
421
427
  // If the deployment failed because the transaction was already imported,
422
428
  // retry with a higher priority fee
423
429
  setInternalFeePerGas(priorityFeeMultiplier * 1.1);
424
- return fastTxExecute(contract, func, args, retryCount++);
430
+ return fastTxExecute(contract, func, args, retryCount++, confirmations);
425
431
  } else throw new MUDError(`Gas estimation error for ${functionName}: ${error?.reason}`);
426
432
  }
427
433
  }
@@ -1,33 +1,8 @@
1
1
  import chalk from "chalk";
2
- import { z, ZodError, ZodIssueCode } from "zod";
2
+ import { ZodError } from "zod";
3
3
  import { fromZodError, ValidationError } from "zod-validation-error";
4
-
5
- // Wrapper with preset styles, only requires a `prefix`
6
- export function fromZodErrorCustom(error: ZodError, prefix: string) {
7
- return fromZodError(error, {
8
- prefix: chalk.red(prefix),
9
- prefixSeparator: "\n- ",
10
- issueSeparator: "\n- ",
11
- });
12
- }
13
-
14
- export class NotInsideProjectError extends Error {
15
- name = "NotInsideProjectError";
16
- message = "You are not inside a MUD project";
17
- }
18
-
19
- export class NotESMConfigError extends Error {
20
- name = "NotESMConfigError";
21
- message = "MUD config must be an ES module";
22
- }
23
-
24
- export class MUDError extends Error {
25
- name = "MUDError";
26
- }
27
-
28
- export function UnrecognizedSystemErrorFactory(path: string[], systemName: string) {
29
- return new z.ZodError([{ code: ZodIssueCode.custom, path: path, message: `Unrecognized system: "${systemName}"` }]);
30
- }
4
+ import { NotInsideProjectError } from "@latticexyz/config";
5
+ import { MUDError } from "@latticexyz/config";
31
6
 
32
7
  export function logError(error: unknown) {
33
8
  if (error instanceof ValidationError) {
@@ -46,12 +21,6 @@ export function logError(error: unknown) {
46
21
  // TODO add docs to the website and update the link to the specific page
47
22
  // (see https://github.com/latticexyz/mud/issues/445)
48
23
  console.log(chalk.blue(`To learn more about MUD's configuration, please go to https://mud.dev/packages/cli/`));
49
- } else if (error instanceof NotESMConfigError) {
50
- console.log(chalk.red(error.message));
51
- console.log("");
52
- console.log(
53
- chalk.blue(`Please name your config file \`mud.config.mts\`, or use \`type: "module"\` in package.json`)
54
- );
55
24
  } else if (error instanceof MUDError) {
56
25
  console.log(chalk.red(error));
57
26
  } else {