@latticexyz/cli 1.40.0 → 1.41.1-alpha.0
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/LICENSE +21 -0
- package/dist/chunk-ATAWDHWC.js +67 -0
- package/dist/{chunk-6AQ6LFVZ.js → chunk-J4DJQNIC.js} +743 -103
- package/dist/chunk-KD354QKC.js +23039 -0
- package/dist/{chunk-S3V3XX7N.js → chunk-SLIMIO4Z.js} +1 -1
- package/dist/config/index.d.ts +746 -8
- package/dist/config/index.js +63 -17
- package/dist/index.d.ts +1 -2
- package/dist/index.js +14 -10
- package/dist/mud.js +1055 -49
- package/dist/utils/deprecated/index.js +2 -2
- package/dist/utils/index.d.ts +56 -7
- package/dist/utils/index.js +17 -3
- package/package.json +16 -11
- package/src/commands/deploy-v2.ts +96 -0
- package/src/commands/deprecated/call-system.ts +1 -1
- package/src/commands/deprecated/deploy-contracts.ts +1 -1
- package/src/commands/deprecated/test.ts +9 -6
- package/src/commands/deprecated/trace.ts +1 -1
- package/src/commands/gas-report.ts +1 -1
- package/src/commands/index.ts +4 -0
- package/src/commands/tablegen.ts +4 -18
- package/src/commands/worldgen.ts +55 -0
- package/src/config/commonSchemas.ts +19 -5
- package/src/config/dynamicResolution.ts +49 -0
- package/src/config/index.ts +20 -0
- package/src/config/loadStoreConfig.ts +3 -89
- package/src/config/parseStoreConfig.test-d.ts +40 -0
- package/src/config/parseStoreConfig.ts +314 -0
- package/src/config/validation.ts +71 -0
- package/src/config/world/index.ts +4 -0
- package/src/config/world/loadWorldConfig.test-d.ts +11 -0
- package/src/config/world/loadWorldConfig.ts +26 -0
- package/src/config/world/parseWorldConfig.ts +55 -0
- package/src/config/world/resolveWorldConfig.ts +80 -0
- package/src/config/world/userTypes.ts +72 -0
- package/src/index.ts +13 -5
- package/src/mud.ts +4 -0
- package/src/render-solidity/common.ts +138 -0
- package/src/render-solidity/field.ts +137 -0
- package/src/render-solidity/index.ts +10 -0
- package/src/render-solidity/record.ts +154 -0
- package/src/render-solidity/renderSystemInterface.ts +31 -0
- package/src/render-solidity/renderTable.ts +164 -0
- package/src/render-solidity/renderTypeHelpers.ts +99 -0
- package/src/render-solidity/renderTypes.ts +19 -0
- package/src/render-solidity/renderTypesFromConfig.ts +13 -0
- package/src/render-solidity/renderWorld.ts +24 -0
- package/src/{render-table/renderTablesFromConfig.ts → render-solidity/tableOptions.ts} +45 -37
- package/src/render-solidity/tablegen.ts +33 -0
- package/src/render-solidity/types.ts +110 -0
- package/src/render-solidity/userType.ts +132 -0
- package/src/render-solidity/worldgen.ts +60 -0
- package/src/utils/contractToInterface.ts +130 -0
- package/src/utils/deploy-v2.ts +512 -0
- package/src/utils/deprecated/build.ts +1 -1
- package/src/utils/deprecated/typegen.ts +1 -1
- package/src/utils/errors.ts +12 -2
- package/src/utils/execLog.ts +22 -0
- package/src/utils/formatAndWrite.ts +12 -0
- package/src/utils/foundry.ts +94 -0
- package/src/utils/getChainId.ts +10 -0
- package/src/utils/index.ts +2 -1
- package/src/utils/typeUtils.ts +17 -0
- package/dist/chunk-B6VWCGHZ.js +0 -199
- package/dist/chunk-JKAA3WMC.js +0 -55
- package/dist/chunk-JNGSW4AP.js +0 -493
- package/dist/chunk-PJ6GS2R4.js +0 -22
- package/dist/chunk-UC3QPOON.js +0 -35
- package/dist/loadStoreConfig-37f99136.d.ts +0 -164
- package/dist/render-table/index.d.ts +0 -29
- package/dist/render-table/index.js +0 -24
- package/dist/renderTable-9e6410c5.d.ts +0 -72
- package/src/config/loadStoreConfig.test-d.ts +0 -11
- package/src/render-table/common.ts +0 -67
- package/src/render-table/field.ts +0 -132
- package/src/render-table/index.ts +0 -6
- package/src/render-table/record.ts +0 -176
- package/src/render-table/renderTable.ts +0 -109
- package/src/render-table/types.ts +0 -51
- package/src/utils/forgeConfig.ts +0 -45
package/dist/mud.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env -S TS_NODE_COMPILER_OPTIONS={\"module\":\"esnext\"} node --loader=ts-node/esm --no-warnings
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import {
|
|
10
|
-
formatSolidity
|
|
11
|
-
} from "./chunk-UC3QPOON.js";
|
|
3
|
+
deploy,
|
|
4
|
+
formatSolidity,
|
|
5
|
+
getSchemaTypeInfo,
|
|
6
|
+
importForAbiOrUserType,
|
|
7
|
+
resolveAbiOrUserType
|
|
8
|
+
} from "./chunk-KD354QKC.js";
|
|
12
9
|
import {
|
|
10
|
+
MUDError,
|
|
11
|
+
SchemaTypeArrayToElement,
|
|
12
|
+
loadStoreConfig,
|
|
13
|
+
loadWorldConfig,
|
|
13
14
|
logError
|
|
14
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-J4DJQNIC.js";
|
|
15
16
|
import {
|
|
16
17
|
JsonRpcProvider,
|
|
17
18
|
componentsDir,
|
|
@@ -25,11 +26,13 @@ import {
|
|
|
25
26
|
keccak256,
|
|
26
27
|
resetLibDeploy,
|
|
27
28
|
systemsDir
|
|
28
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-SLIMIO4Z.js";
|
|
29
30
|
import {
|
|
31
|
+
forge,
|
|
32
|
+
getRpcUrl,
|
|
30
33
|
getSrcDirectory,
|
|
31
34
|
getTestDirectory
|
|
32
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-ATAWDHWC.js";
|
|
33
36
|
import {
|
|
34
37
|
__commonJS,
|
|
35
38
|
__toESM
|
|
@@ -1528,8 +1531,8 @@ var commandModule3 = {
|
|
|
1528
1531
|
systems: { type: "string", desc: "Only generate deploy code for the given systems" }
|
|
1529
1532
|
});
|
|
1530
1533
|
},
|
|
1531
|
-
async handler({ config, out, systems }) {
|
|
1532
|
-
await generateLibDeploy(
|
|
1534
|
+
async handler({ config: config2, out, systems }) {
|
|
1535
|
+
await generateLibDeploy(config2, out, systems);
|
|
1533
1536
|
process.exit(0);
|
|
1534
1537
|
}
|
|
1535
1538
|
};
|
|
@@ -1559,7 +1562,7 @@ var commandModule4 = {
|
|
|
1559
1562
|
});
|
|
1560
1563
|
},
|
|
1561
1564
|
async handler({
|
|
1562
|
-
config,
|
|
1565
|
+
config: config2,
|
|
1563
1566
|
deployerPrivateKey,
|
|
1564
1567
|
worldAddress,
|
|
1565
1568
|
rpc,
|
|
@@ -1578,7 +1581,7 @@ var commandModule4 = {
|
|
|
1578
1581
|
let genDeployResult;
|
|
1579
1582
|
try {
|
|
1580
1583
|
genDeployResult = await generateAndDeploy({
|
|
1581
|
-
config,
|
|
1584
|
+
config: config2,
|
|
1582
1585
|
deployerPrivateKey,
|
|
1583
1586
|
worldAddress,
|
|
1584
1587
|
rpc,
|
|
@@ -1609,7 +1612,7 @@ var commandModule4 = {
|
|
|
1609
1612
|
hsr(srcDir, async (systems2) => {
|
|
1610
1613
|
try {
|
|
1611
1614
|
return await generateAndDeploy({
|
|
1612
|
-
config,
|
|
1615
|
+
config: config2,
|
|
1613
1616
|
deployerPrivateKey,
|
|
1614
1617
|
worldAddress,
|
|
1615
1618
|
rpc,
|
|
@@ -1661,22 +1664,24 @@ var commandModule6 = {
|
|
|
1661
1664
|
v: { type: "number", default: 2, desc: "Verbosity for forge test" }
|
|
1662
1665
|
});
|
|
1663
1666
|
},
|
|
1664
|
-
async handler({ forgeOpts, config, v }) {
|
|
1667
|
+
async handler({ forgeOpts, config: config2, v }) {
|
|
1665
1668
|
const testDir = await getTestDirectory();
|
|
1666
1669
|
console.log("Generate LibDeploy.sol");
|
|
1667
|
-
await generateLibDeploy(
|
|
1670
|
+
await generateLibDeploy(config2, testDir);
|
|
1668
1671
|
const child = execLog("forge", [
|
|
1669
1672
|
"test",
|
|
1670
1673
|
...v ? ["-" + [...new Array(v)].map(() => "v").join("")] : [],
|
|
1671
1674
|
...forgeOpts?.split(" ") || []
|
|
1672
1675
|
]);
|
|
1673
|
-
|
|
1674
|
-
await resetLibDeploy(testDir);
|
|
1675
|
-
process.on("SIGINT", () => {
|
|
1676
|
+
process.on("SIGINT", async () => {
|
|
1676
1677
|
console.log("\ngracefully shutting down from SIGINT (Crtl-C)");
|
|
1677
1678
|
child.kill();
|
|
1679
|
+
await resetLibDeploy(testDir);
|
|
1678
1680
|
process.exit();
|
|
1679
1681
|
});
|
|
1682
|
+
await child;
|
|
1683
|
+
console.log("Reset LibDeploy.sol");
|
|
1684
|
+
await resetLibDeploy(testDir);
|
|
1680
1685
|
}
|
|
1681
1686
|
};
|
|
1682
1687
|
var test_default = commandModule6;
|
|
@@ -9652,9 +9657,9 @@ var commandModule7 = {
|
|
|
9652
9657
|
debug: { type: "boolean", description: "open debugger" }
|
|
9653
9658
|
});
|
|
9654
9659
|
},
|
|
9655
|
-
async handler({ config, world, rpc, tx, debug }) {
|
|
9660
|
+
async handler({ config: config2, world, rpc, tx, debug }) {
|
|
9656
9661
|
const wd = process.cwd();
|
|
9657
|
-
const deployData =
|
|
9662
|
+
const deployData = config2 && JSON.parse(readFileSync(config2, { encoding: "utf8" }));
|
|
9658
9663
|
const labels = [];
|
|
9659
9664
|
const rpcUrl = rpc || "http://localhost:8545";
|
|
9660
9665
|
const provider = new JsonRpcProvider(rpcUrl);
|
|
@@ -11250,9 +11255,9 @@ var commandModule11 = {
|
|
|
11250
11255
|
compare: { type: "string", desc: "Compare to an existing gas report" }
|
|
11251
11256
|
});
|
|
11252
11257
|
},
|
|
11253
|
-
async handler({ path:
|
|
11258
|
+
async handler({ path: path11, save, compare: compare2 }) {
|
|
11254
11259
|
let gasReport = [];
|
|
11255
|
-
for (const file of
|
|
11260
|
+
for (const file of path11) {
|
|
11256
11261
|
gasReport = gasReport.concat(await runGasReport(file));
|
|
11257
11262
|
}
|
|
11258
11263
|
const compareGasReport = [];
|
|
@@ -11284,14 +11289,14 @@ var commandModule11 = {
|
|
|
11284
11289
|
}
|
|
11285
11290
|
};
|
|
11286
11291
|
var gas_report_default = commandModule11;
|
|
11287
|
-
async function runGasReport(
|
|
11288
|
-
if (!
|
|
11289
|
-
console.log("Skipping gas report for", chalk3.bold(
|
|
11292
|
+
async function runGasReport(path11) {
|
|
11293
|
+
if (!path11.endsWith(".t.sol")) {
|
|
11294
|
+
console.log("Skipping gas report for", chalk3.bold(path11), "(not a test file)");
|
|
11290
11295
|
return [];
|
|
11291
11296
|
}
|
|
11292
|
-
console.log("Running gas report for", chalk3.bold(
|
|
11297
|
+
console.log("Running gas report for", chalk3.bold(path11));
|
|
11293
11298
|
const gasReport = [];
|
|
11294
|
-
const fileContents = readFileSync2(
|
|
11299
|
+
const fileContents = readFileSync2(path11, "utf8");
|
|
11295
11300
|
let newFile = fileContents;
|
|
11296
11301
|
const functionRegex = new RegExp(/function (.*){/g);
|
|
11297
11302
|
let functionMatch;
|
|
@@ -11315,7 +11320,7 @@ console.log("GAS REPORT: ${name} [${functionCall.replaceAll('"', '\\"')}]:", _ga
|
|
|
11315
11320
|
);
|
|
11316
11321
|
}
|
|
11317
11322
|
newFile = newFile.replace(/pure/g, "view");
|
|
11318
|
-
const tempFileName =
|
|
11323
|
+
const tempFileName = path11.replace(/\.t\.sol$/, "MudGasReport.t.sol");
|
|
11319
11324
|
writeFileSync(tempFileName, newFile);
|
|
11320
11325
|
const child = execa2("forge", ["test", "--match-path", tempFileName, "-vvv"], {
|
|
11321
11326
|
stdio: ["inherit", "pipe", "inherit"]
|
|
@@ -11336,7 +11341,7 @@ console.log("GAS REPORT: ${name} [${functionCall.replaceAll('"', '\\"')}]:", _ga
|
|
|
11336
11341
|
const name = gasReportMatch[1];
|
|
11337
11342
|
const functionCall = gasReportMatch[2].replace(";", "");
|
|
11338
11343
|
const gasUsed = gasReportMatch[3];
|
|
11339
|
-
gasReport.push({ source:
|
|
11344
|
+
gasReport.push({ source: path11, name, functionCall, gasUsed: parseInt(gasUsed) });
|
|
11340
11345
|
}
|
|
11341
11346
|
return gasReport;
|
|
11342
11347
|
}
|
|
@@ -11360,10 +11365,10 @@ function printGasReport(gasReport, compare2) {
|
|
|
11360
11365
|
const rows = [headers, ...values];
|
|
11361
11366
|
console.log(table(rows, { border: getBorderCharacters("norc") }));
|
|
11362
11367
|
}
|
|
11363
|
-
function saveGasReport(gasReport,
|
|
11364
|
-
console.log(chalk3.bold(`Saving gas report to ${
|
|
11368
|
+
function saveGasReport(gasReport, path11) {
|
|
11369
|
+
console.log(chalk3.bold(`Saving gas report to ${path11}`));
|
|
11365
11370
|
const serializedGasReport = gasReport.map((entry) => `(${entry.source}) | ${entry.name} [${entry.functionCall}]: ${entry.gasUsed}`).join("\n");
|
|
11366
|
-
writeFileSync(
|
|
11371
|
+
writeFileSync(path11, serializedGasReport);
|
|
11367
11372
|
}
|
|
11368
11373
|
|
|
11369
11374
|
// src/commands/hello.ts
|
|
@@ -11383,9 +11388,697 @@ var commandModule12 = {
|
|
|
11383
11388
|
};
|
|
11384
11389
|
var hello_default = commandModule12;
|
|
11385
11390
|
|
|
11386
|
-
// src/
|
|
11391
|
+
// src/render-solidity/tablegen.ts
|
|
11387
11392
|
import { mkdirSync, writeFileSync as writeFileSync2 } from "fs";
|
|
11393
|
+
import path7 from "path";
|
|
11394
|
+
|
|
11395
|
+
// src/render-solidity/tableOptions.ts
|
|
11388
11396
|
import path5 from "path";
|
|
11397
|
+
function getTableOptions(config2) {
|
|
11398
|
+
const storeImportPath = config2.storeImportPath;
|
|
11399
|
+
const options = [];
|
|
11400
|
+
for (const tableName of Object.keys(config2.tables)) {
|
|
11401
|
+
const tableData = config2.tables[tableName];
|
|
11402
|
+
const withStruct = tableData.dataStruct;
|
|
11403
|
+
const withRecordMethods = withStruct || Object.keys(tableData.schema).length > 1;
|
|
11404
|
+
const noFieldMethodSuffix = !withRecordMethods && Object.keys(tableData.schema).length === 1;
|
|
11405
|
+
const imports = [];
|
|
11406
|
+
const primaryKeys = Object.keys(tableData.primaryKeys).map((name) => {
|
|
11407
|
+
const abiOrUserType = tableData.primaryKeys[name];
|
|
11408
|
+
const { renderTableType } = resolveAbiOrUserType(abiOrUserType, config2);
|
|
11409
|
+
const importDatum = importForAbiOrUserType(abiOrUserType, tableData.directory, config2);
|
|
11410
|
+
if (importDatum)
|
|
11411
|
+
imports.push(importDatum);
|
|
11412
|
+
if (renderTableType.isDynamic)
|
|
11413
|
+
throw new Error(`Parsing error: found dynamic primary key ${name} in table ${tableName}`);
|
|
11414
|
+
const primaryKey = {
|
|
11415
|
+
...renderTableType,
|
|
11416
|
+
name,
|
|
11417
|
+
isDynamic: false
|
|
11418
|
+
};
|
|
11419
|
+
return primaryKey;
|
|
11420
|
+
});
|
|
11421
|
+
const fields = Object.keys(tableData.schema).map((name) => {
|
|
11422
|
+
const abiOrUserType = tableData.schema[name];
|
|
11423
|
+
const { renderTableType, schemaType } = resolveAbiOrUserType(abiOrUserType, config2);
|
|
11424
|
+
const importDatum = importForAbiOrUserType(abiOrUserType, tableData.directory, config2);
|
|
11425
|
+
if (importDatum)
|
|
11426
|
+
imports.push(importDatum);
|
|
11427
|
+
const elementType = SchemaTypeArrayToElement[schemaType];
|
|
11428
|
+
const field = {
|
|
11429
|
+
...renderTableType,
|
|
11430
|
+
arrayElement: elementType !== void 0 ? getSchemaTypeInfo(elementType) : void 0,
|
|
11431
|
+
name,
|
|
11432
|
+
methodNameSuffix: noFieldMethodSuffix ? "" : `${name[0].toUpperCase()}${name.slice(1)}`
|
|
11433
|
+
};
|
|
11434
|
+
return field;
|
|
11435
|
+
});
|
|
11436
|
+
const staticFields = fields.filter(({ isDynamic }) => !isDynamic);
|
|
11437
|
+
const dynamicFields = fields.filter(({ isDynamic }) => isDynamic);
|
|
11438
|
+
const staticResourceData = (() => {
|
|
11439
|
+
if (tableData.tableIdArgument) {
|
|
11440
|
+
return;
|
|
11441
|
+
} else {
|
|
11442
|
+
return {
|
|
11443
|
+
tableIdName: tableName + "TableId",
|
|
11444
|
+
namespace: config2.namespace,
|
|
11445
|
+
fileSelector: tableData.fileSelector
|
|
11446
|
+
};
|
|
11447
|
+
}
|
|
11448
|
+
})();
|
|
11449
|
+
options.push({
|
|
11450
|
+
outputPath: path5.join(tableData.directory, `${tableName}.sol`),
|
|
11451
|
+
tableName,
|
|
11452
|
+
renderOptions: {
|
|
11453
|
+
imports,
|
|
11454
|
+
libraryName: tableName,
|
|
11455
|
+
structName: withStruct ? tableName + "Data" : void 0,
|
|
11456
|
+
staticResourceData,
|
|
11457
|
+
storeImportPath,
|
|
11458
|
+
primaryKeys,
|
|
11459
|
+
fields,
|
|
11460
|
+
staticFields,
|
|
11461
|
+
dynamicFields,
|
|
11462
|
+
withRecordMethods,
|
|
11463
|
+
storeArgument: tableData.storeArgument
|
|
11464
|
+
}
|
|
11465
|
+
});
|
|
11466
|
+
}
|
|
11467
|
+
return options;
|
|
11468
|
+
}
|
|
11469
|
+
|
|
11470
|
+
// src/render-solidity/common.ts
|
|
11471
|
+
import path6 from "path";
|
|
11472
|
+
var renderedSolidityHeader = `// SPDX-License-Identifier: MIT
|
|
11473
|
+
pragma solidity >=0.8.0;
|
|
11474
|
+
|
|
11475
|
+
/* Autogenerated file. Do not edit manually. */`;
|
|
11476
|
+
function renderList(list, renderItem) {
|
|
11477
|
+
return internalRenderList("", list, renderItem);
|
|
11478
|
+
}
|
|
11479
|
+
function renderArguments(args) {
|
|
11480
|
+
const filteredArgs = args.filter((arg) => arg !== void 0 && arg !== "");
|
|
11481
|
+
return internalRenderList(",", filteredArgs, (arg) => arg);
|
|
11482
|
+
}
|
|
11483
|
+
function renderCommonData({
|
|
11484
|
+
staticResourceData,
|
|
11485
|
+
primaryKeys
|
|
11486
|
+
}) {
|
|
11487
|
+
const _tableId = staticResourceData ? "" : "_tableId";
|
|
11488
|
+
const _typedTableId = staticResourceData ? "" : "uint256 _tableId";
|
|
11489
|
+
const _keyArgs = renderArguments(primaryKeys.map(({ name }) => name));
|
|
11490
|
+
const _typedKeyArgs = renderArguments(primaryKeys.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`));
|
|
11491
|
+
const _primaryKeysDefinition = `
|
|
11492
|
+
bytes32[] memory _primaryKeys = new bytes32[](${primaryKeys.length});
|
|
11493
|
+
${renderList(
|
|
11494
|
+
primaryKeys,
|
|
11495
|
+
(primaryKey, index) => `_primaryKeys[${index}] = ${renderValueTypeToBytes32(primaryKey.name, primaryKey)};`
|
|
11496
|
+
)}
|
|
11497
|
+
`;
|
|
11498
|
+
return {
|
|
11499
|
+
_tableId,
|
|
11500
|
+
_typedTableId,
|
|
11501
|
+
_keyArgs,
|
|
11502
|
+
_typedKeyArgs,
|
|
11503
|
+
_primaryKeysDefinition
|
|
11504
|
+
};
|
|
11505
|
+
}
|
|
11506
|
+
function solidityRelativeImportPath(fromPath, usedInPath) {
|
|
11507
|
+
return "./" + path6.relative("./" + usedInPath, "./" + fromPath);
|
|
11508
|
+
}
|
|
11509
|
+
function renderImports(imports) {
|
|
11510
|
+
const aggregatedImports = /* @__PURE__ */ new Map();
|
|
11511
|
+
for (const { symbol, fromPath, usedInPath } of imports) {
|
|
11512
|
+
const path11 = solidityRelativeImportPath(fromPath, usedInPath);
|
|
11513
|
+
if (!aggregatedImports.has(path11)) {
|
|
11514
|
+
aggregatedImports.set(path11, /* @__PURE__ */ new Set());
|
|
11515
|
+
}
|
|
11516
|
+
aggregatedImports.get(path11)?.add(symbol);
|
|
11517
|
+
}
|
|
11518
|
+
const renderedImports = [];
|
|
11519
|
+
for (const [path11, symbols] of aggregatedImports) {
|
|
11520
|
+
const renderedSymbols = [...symbols].join(", ");
|
|
11521
|
+
renderedImports.push(`import { ${renderedSymbols} } from "${path11}";`);
|
|
11522
|
+
}
|
|
11523
|
+
return renderedImports.join("\n");
|
|
11524
|
+
}
|
|
11525
|
+
function renderWithStore(storeArgument, callback) {
|
|
11526
|
+
let result = "";
|
|
11527
|
+
result += callback(void 0, "StoreSwitch", "", void 0);
|
|
11528
|
+
if (storeArgument) {
|
|
11529
|
+
result += "\n" + callback("IStore _store", "_store", " (using the specified store)", "_store");
|
|
11530
|
+
}
|
|
11531
|
+
return result;
|
|
11532
|
+
}
|
|
11533
|
+
function renderTableId(staticResourceData) {
|
|
11534
|
+
const hardcodedTableId = `uint256(bytes32(abi.encodePacked(bytes16("${staticResourceData.namespace}"), bytes16("${staticResourceData.fileSelector}"))))`;
|
|
11535
|
+
const tableIdDefinition = `
|
|
11536
|
+
uint256 constant _tableId = ${hardcodedTableId};
|
|
11537
|
+
uint256 constant ${staticResourceData.tableIdName} = _tableId;
|
|
11538
|
+
`;
|
|
11539
|
+
return {
|
|
11540
|
+
hardcodedTableId,
|
|
11541
|
+
tableIdDefinition
|
|
11542
|
+
};
|
|
11543
|
+
}
|
|
11544
|
+
function renderValueTypeToBytes32(name, { staticByteLength, typeUnwrap, internalTypeId }) {
|
|
11545
|
+
const bits = staticByteLength * 8;
|
|
11546
|
+
const innerText = `${typeUnwrap}(${name})`;
|
|
11547
|
+
if (internalTypeId.match(/^uint\d{1,3}$/)) {
|
|
11548
|
+
return `bytes32(uint256(${innerText}))`;
|
|
11549
|
+
} else if (internalTypeId.match(/^int\d{1,3}$/)) {
|
|
11550
|
+
return `bytes32(uint256(uint${bits}(${innerText})))`;
|
|
11551
|
+
} else if (internalTypeId.match(/^bytes\d{1,2}$/)) {
|
|
11552
|
+
return `bytes32(${innerText})`;
|
|
11553
|
+
} else if (internalTypeId === "address") {
|
|
11554
|
+
return `bytes32(bytes20(${innerText}))`;
|
|
11555
|
+
} else if (internalTypeId === "bool") {
|
|
11556
|
+
return `_boolToBytes32(${innerText})`;
|
|
11557
|
+
} else {
|
|
11558
|
+
throw new Error(`Unknown value type id ${internalTypeId}`);
|
|
11559
|
+
}
|
|
11560
|
+
}
|
|
11561
|
+
function internalRenderList(lineTerminator, list, renderItem) {
|
|
11562
|
+
return list.map((item, index) => renderItem(item, index) + (index === list.length - 1 ? "" : lineTerminator)).join("\n");
|
|
11563
|
+
}
|
|
11564
|
+
|
|
11565
|
+
// src/render-solidity/field.ts
|
|
11566
|
+
function renderFieldMethods(options) {
|
|
11567
|
+
const storeArgument = options.storeArgument;
|
|
11568
|
+
const { _typedTableId, _typedKeyArgs, _primaryKeysDefinition } = renderCommonData(options);
|
|
11569
|
+
let result = "";
|
|
11570
|
+
for (const [index, field] of options.fields.entries()) {
|
|
11571
|
+
const _typedFieldName = `${field.typeWithLocation} ${field.name}`;
|
|
11572
|
+
result += renderWithStore(
|
|
11573
|
+
storeArgument,
|
|
11574
|
+
(_typedStore, _store, _commentSuffix) => `
|
|
11575
|
+
/** Get ${field.name}${_commentSuffix} */
|
|
11576
|
+
function get${field.methodNameSuffix}(${renderArguments([
|
|
11577
|
+
_typedStore,
|
|
11578
|
+
_typedTableId,
|
|
11579
|
+
_typedKeyArgs
|
|
11580
|
+
])}) internal view returns (${_typedFieldName}) {
|
|
11581
|
+
${_primaryKeysDefinition}
|
|
11582
|
+
bytes memory _blob = ${_store}.getField(_tableId, _primaryKeys, ${index});
|
|
11583
|
+
return ${renderDecodeFieldSingle(field)};
|
|
11584
|
+
}
|
|
11585
|
+
`
|
|
11586
|
+
);
|
|
11587
|
+
result += renderWithStore(
|
|
11588
|
+
storeArgument,
|
|
11589
|
+
(_typedStore, _store, _commentSuffix) => `
|
|
11590
|
+
/** Set ${field.name}${_commentSuffix} */
|
|
11591
|
+
function set${field.methodNameSuffix}(${renderArguments([
|
|
11592
|
+
_typedStore,
|
|
11593
|
+
_typedTableId,
|
|
11594
|
+
_typedKeyArgs,
|
|
11595
|
+
_typedFieldName
|
|
11596
|
+
])}) internal {
|
|
11597
|
+
${_primaryKeysDefinition}
|
|
11598
|
+
${_store}.setField(_tableId, _primaryKeys, ${index}, ${renderEncodeField(field)});
|
|
11599
|
+
}
|
|
11600
|
+
`
|
|
11601
|
+
);
|
|
11602
|
+
if (field.isDynamic) {
|
|
11603
|
+
const portionData = fieldPortionData(field);
|
|
11604
|
+
result += renderWithStore(
|
|
11605
|
+
storeArgument,
|
|
11606
|
+
(_typedStore, _store, _commentSuffix) => `
|
|
11607
|
+
/** Push ${portionData.title} to ${field.name}${_commentSuffix} */
|
|
11608
|
+
function push${field.methodNameSuffix}(${renderArguments([
|
|
11609
|
+
_typedStore,
|
|
11610
|
+
_typedTableId,
|
|
11611
|
+
_typedKeyArgs,
|
|
11612
|
+
`${portionData.typeWithLocation} ${portionData.name}`
|
|
11613
|
+
])}) internal {
|
|
11614
|
+
${_primaryKeysDefinition}
|
|
11615
|
+
${_store}.pushToField(_tableId, _primaryKeys, ${index}, ${portionData.encoded});
|
|
11616
|
+
}
|
|
11617
|
+
`
|
|
11618
|
+
);
|
|
11619
|
+
}
|
|
11620
|
+
}
|
|
11621
|
+
return result;
|
|
11622
|
+
}
|
|
11623
|
+
function renderEncodeField(field) {
|
|
11624
|
+
let func;
|
|
11625
|
+
if (field.arrayElement) {
|
|
11626
|
+
func = "EncodeArray.encode";
|
|
11627
|
+
} else if (field.isDynamic) {
|
|
11628
|
+
func = "bytes";
|
|
11629
|
+
} else {
|
|
11630
|
+
func = "abi.encodePacked";
|
|
11631
|
+
}
|
|
11632
|
+
return `${func}(${field.typeUnwrap}(${field.name}))`;
|
|
11633
|
+
}
|
|
11634
|
+
function renderDecodeValueType(field, offset) {
|
|
11635
|
+
const { staticByteLength, internalTypeId } = field;
|
|
11636
|
+
const innerSlice = `Bytes.slice${staticByteLength}(_blob, ${offset})`;
|
|
11637
|
+
const bits = staticByteLength * 8;
|
|
11638
|
+
let result;
|
|
11639
|
+
if (internalTypeId.match(/^uint\d{1,3}$/) || internalTypeId === "address") {
|
|
11640
|
+
result = `${internalTypeId}(${innerSlice})`;
|
|
11641
|
+
} else if (internalTypeId.match(/^int\d{1,3}$/)) {
|
|
11642
|
+
result = `${internalTypeId}(uint${bits}(${innerSlice}))`;
|
|
11643
|
+
} else if (internalTypeId.match(/^bytes\d{1,2}$/)) {
|
|
11644
|
+
result = innerSlice;
|
|
11645
|
+
} else if (internalTypeId === "bool") {
|
|
11646
|
+
result = `_toBool(uint8(${innerSlice}))`;
|
|
11647
|
+
} else {
|
|
11648
|
+
throw new Error(`Unknown value type id ${internalTypeId}`);
|
|
11649
|
+
}
|
|
11650
|
+
return `${field.typeWrap}(${result})`;
|
|
11651
|
+
}
|
|
11652
|
+
function fieldPortionData(field) {
|
|
11653
|
+
const methodNameSuffix = "";
|
|
11654
|
+
if (field.arrayElement) {
|
|
11655
|
+
const name = "_element";
|
|
11656
|
+
return {
|
|
11657
|
+
typeWithLocation: field.arrayElement.typeWithLocation,
|
|
11658
|
+
name: "_element",
|
|
11659
|
+
encoded: renderEncodeField({ ...field.arrayElement, arrayElement: void 0, name, methodNameSuffix }),
|
|
11660
|
+
title: "an element"
|
|
11661
|
+
};
|
|
11662
|
+
} else {
|
|
11663
|
+
const name = "_slice";
|
|
11664
|
+
return {
|
|
11665
|
+
typeWithLocation: `${field.typeId} memory`,
|
|
11666
|
+
name,
|
|
11667
|
+
encoded: renderEncodeField({ ...field, name, methodNameSuffix }),
|
|
11668
|
+
title: "a slice"
|
|
11669
|
+
};
|
|
11670
|
+
}
|
|
11671
|
+
}
|
|
11672
|
+
function renderDecodeFieldSingle(field) {
|
|
11673
|
+
const { isDynamic, arrayElement } = field;
|
|
11674
|
+
if (arrayElement) {
|
|
11675
|
+
return `${field.typeWrap}(
|
|
11676
|
+
SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_${arrayElement.internalTypeId}()
|
|
11677
|
+
)`;
|
|
11678
|
+
} else if (isDynamic) {
|
|
11679
|
+
return `${field.typeWrap}(${field.internalTypeId}(_blob))`;
|
|
11680
|
+
} else {
|
|
11681
|
+
return renderDecodeValueType(field, 0);
|
|
11682
|
+
}
|
|
11683
|
+
}
|
|
11684
|
+
|
|
11685
|
+
// src/render-solidity/record.ts
|
|
11686
|
+
function renderRecordMethods(options) {
|
|
11687
|
+
const { structName, storeArgument } = options;
|
|
11688
|
+
const { _tableId, _typedTableId, _keyArgs, _typedKeyArgs, _primaryKeysDefinition } = renderCommonData(options);
|
|
11689
|
+
let result = renderWithStore(
|
|
11690
|
+
storeArgument,
|
|
11691
|
+
(_typedStore, _store, _commentSuffix) => `
|
|
11692
|
+
/** Get the full data${_commentSuffix} */
|
|
11693
|
+
function get(${renderArguments([
|
|
11694
|
+
_typedStore,
|
|
11695
|
+
_typedTableId,
|
|
11696
|
+
_typedKeyArgs
|
|
11697
|
+
])}) internal view returns (${renderDecodedRecord(options)}) {
|
|
11698
|
+
${_primaryKeysDefinition}
|
|
11699
|
+
bytes memory _blob = ${_store}.getRecord(_tableId, _primaryKeys, getSchema());
|
|
11700
|
+
return decode(_blob);
|
|
11701
|
+
}
|
|
11702
|
+
`
|
|
11703
|
+
);
|
|
11704
|
+
result += renderWithStore(
|
|
11705
|
+
storeArgument,
|
|
11706
|
+
(_typedStore, _store, _commentSuffix) => `
|
|
11707
|
+
/** Set the full data using individual values${_commentSuffix} */
|
|
11708
|
+
function set(${renderArguments([
|
|
11709
|
+
_typedStore,
|
|
11710
|
+
_typedTableId,
|
|
11711
|
+
_typedKeyArgs,
|
|
11712
|
+
renderArguments(options.fields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`))
|
|
11713
|
+
])}) internal {
|
|
11714
|
+
bytes memory _data = encode(${renderArguments(options.fields.map(({ name }) => name))});
|
|
11715
|
+
|
|
11716
|
+
${_primaryKeysDefinition}
|
|
11717
|
+
|
|
11718
|
+
${_store}.setRecord(_tableId, _primaryKeys, _data);
|
|
11719
|
+
}
|
|
11720
|
+
`
|
|
11721
|
+
);
|
|
11722
|
+
if (structName !== void 0) {
|
|
11723
|
+
result += renderWithStore(
|
|
11724
|
+
storeArgument,
|
|
11725
|
+
(_typedStore, _store, _commentSuffix, _untypedStore) => `
|
|
11726
|
+
/** Set the full data using the data struct${_commentSuffix} */
|
|
11727
|
+
function set(${renderArguments([
|
|
11728
|
+
_typedStore,
|
|
11729
|
+
_typedTableId,
|
|
11730
|
+
_typedKeyArgs,
|
|
11731
|
+
`${structName} memory _table`
|
|
11732
|
+
])}) internal {
|
|
11733
|
+
set(${renderArguments([
|
|
11734
|
+
_untypedStore,
|
|
11735
|
+
_tableId,
|
|
11736
|
+
_keyArgs,
|
|
11737
|
+
renderArguments(options.fields.map(({ name }) => `_table.${name}`))
|
|
11738
|
+
])});
|
|
11739
|
+
}
|
|
11740
|
+
`
|
|
11741
|
+
);
|
|
11742
|
+
}
|
|
11743
|
+
result += renderDecodeFunction(options);
|
|
11744
|
+
return result;
|
|
11745
|
+
}
|
|
11746
|
+
function renderDecodeFunction({ structName, fields, staticFields, dynamicFields }) {
|
|
11747
|
+
const renderedDecodedRecord = structName ? `${structName} memory _table` : renderArguments(fields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`));
|
|
11748
|
+
const fieldNamePrefix = structName ? "_table." : "";
|
|
11749
|
+
const staticOffsets = staticFields.map(() => 0);
|
|
11750
|
+
let _acc = 0;
|
|
11751
|
+
for (const [index, field] of staticFields.entries()) {
|
|
11752
|
+
staticOffsets[index] = _acc;
|
|
11753
|
+
_acc += field.staticByteLength;
|
|
11754
|
+
}
|
|
11755
|
+
if (dynamicFields.length > 0) {
|
|
11756
|
+
const totalStaticLength = staticFields.reduce((acc, { staticByteLength }) => acc + staticByteLength, 0);
|
|
11757
|
+
return `
|
|
11758
|
+
/** Decode the tightly packed blob using this table's schema */
|
|
11759
|
+
function decode(bytes memory _blob) internal view returns (${renderedDecodedRecord}) {
|
|
11760
|
+
// ${totalStaticLength} is the total byte length of static data
|
|
11761
|
+
PackedCounter _encodedLengths = PackedCounter.wrap(Bytes.slice32(_blob, ${totalStaticLength}));
|
|
11762
|
+
|
|
11763
|
+
${renderList(
|
|
11764
|
+
staticFields,
|
|
11765
|
+
(field, index) => `
|
|
11766
|
+
${fieldNamePrefix}${field.name} = ${renderDecodeValueType(field, staticOffsets[index])};
|
|
11767
|
+
`
|
|
11768
|
+
)}
|
|
11769
|
+
uint256 _start;
|
|
11770
|
+
uint256 _end = ${totalStaticLength + 32};
|
|
11771
|
+
${renderList(
|
|
11772
|
+
dynamicFields,
|
|
11773
|
+
(field, index) => `
|
|
11774
|
+
_start = _end;
|
|
11775
|
+
_end += _encodedLengths.atIndex(${index});
|
|
11776
|
+
${fieldNamePrefix}${field.name} = ${renderDecodeDynamicFieldPartial(field)};
|
|
11777
|
+
`
|
|
11778
|
+
)}
|
|
11779
|
+
}
|
|
11780
|
+
`;
|
|
11781
|
+
} else {
|
|
11782
|
+
return `
|
|
11783
|
+
/** Decode the tightly packed blob using this table's schema */
|
|
11784
|
+
function decode(bytes memory _blob) internal pure returns (${renderedDecodedRecord}) {
|
|
11785
|
+
${renderList(
|
|
11786
|
+
staticFields,
|
|
11787
|
+
(field, index) => `
|
|
11788
|
+
${fieldNamePrefix}${field.name} = ${renderDecodeValueType(field, staticOffsets[index])};
|
|
11789
|
+
`
|
|
11790
|
+
)}
|
|
11791
|
+
}
|
|
11792
|
+
`;
|
|
11793
|
+
}
|
|
11794
|
+
}
|
|
11795
|
+
function renderDecodedRecord({ structName, fields }) {
|
|
11796
|
+
if (structName) {
|
|
11797
|
+
return `${structName} memory _table`;
|
|
11798
|
+
} else {
|
|
11799
|
+
return renderArguments(fields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`));
|
|
11800
|
+
}
|
|
11801
|
+
}
|
|
11802
|
+
function renderDecodeDynamicFieldPartial(field) {
|
|
11803
|
+
const { typeId, arrayElement, typeWrap } = field;
|
|
11804
|
+
if (arrayElement) {
|
|
11805
|
+
return `${typeWrap}(
|
|
11806
|
+
SliceLib.getSubslice(_blob, _start, _end).decodeArray_${arrayElement.typeId}()
|
|
11807
|
+
)`;
|
|
11808
|
+
} else {
|
|
11809
|
+
return `${typeWrap}(
|
|
11810
|
+
${typeId}(
|
|
11811
|
+
SliceLib.getSubslice(_blob, _start, _end).toBytes()
|
|
11812
|
+
)
|
|
11813
|
+
)`;
|
|
11814
|
+
}
|
|
11815
|
+
}
|
|
11816
|
+
|
|
11817
|
+
// src/render-solidity/renderTypeHelpers.ts
|
|
11818
|
+
function renderTypeHelpers(options) {
|
|
11819
|
+
const { fields, primaryKeys } = options;
|
|
11820
|
+
let result = "";
|
|
11821
|
+
for (const wrappingHelper of getWrappingHelpers([...fields, ...primaryKeys])) {
|
|
11822
|
+
result += wrappingHelper;
|
|
11823
|
+
}
|
|
11824
|
+
if (fields.some(({ typeId }) => typeId === "bool")) {
|
|
11825
|
+
result += `
|
|
11826
|
+
function _toBool(uint8 value) pure returns (bool result) {
|
|
11827
|
+
assembly {
|
|
11828
|
+
result := value
|
|
11829
|
+
}
|
|
11830
|
+
}
|
|
11831
|
+
`;
|
|
11832
|
+
}
|
|
11833
|
+
if (primaryKeys.some(({ typeId }) => typeId === "bool")) {
|
|
11834
|
+
result += `
|
|
11835
|
+
function _boolToBytes32(bool value) pure returns (bytes32 result) {
|
|
11836
|
+
assembly {
|
|
11837
|
+
result := value
|
|
11838
|
+
}
|
|
11839
|
+
}
|
|
11840
|
+
`;
|
|
11841
|
+
}
|
|
11842
|
+
return result;
|
|
11843
|
+
}
|
|
11844
|
+
function getWrappingHelpers(array) {
|
|
11845
|
+
const wrappers = /* @__PURE__ */ new Map();
|
|
11846
|
+
const unwrappers = /* @__PURE__ */ new Map();
|
|
11847
|
+
for (const { typeWrappingData, typeWrap, typeUnwrap, internalTypeId } of array) {
|
|
11848
|
+
if (!typeWrappingData)
|
|
11849
|
+
continue;
|
|
11850
|
+
const { kind } = typeWrappingData;
|
|
11851
|
+
if (kind === "staticArray") {
|
|
11852
|
+
const { elementType, staticLength } = typeWrappingData;
|
|
11853
|
+
wrappers.set(typeWrap, renderWrapperStaticArray(typeWrap, elementType, staticLength, internalTypeId));
|
|
11854
|
+
unwrappers.set(typeUnwrap, renderUnwrapperStaticArray(typeUnwrap, elementType, staticLength, internalTypeId));
|
|
11855
|
+
}
|
|
11856
|
+
}
|
|
11857
|
+
return [...wrappers.values(), ...unwrappers.values()];
|
|
11858
|
+
}
|
|
11859
|
+
function renderWrapperStaticArray(functionName, elementType, staticLength, internalTypeId) {
|
|
11860
|
+
return `
|
|
11861
|
+
function ${functionName}(
|
|
11862
|
+
${internalTypeId} memory _value
|
|
11863
|
+
) pure returns (
|
|
11864
|
+
${elementType}[${staticLength}] memory _result
|
|
11865
|
+
) {
|
|
11866
|
+
// in memory static arrays are just dynamic arrays without the length byte
|
|
11867
|
+
assembly {
|
|
11868
|
+
_result := add(_value, 0x20)
|
|
11869
|
+
}
|
|
11870
|
+
}
|
|
11871
|
+
`;
|
|
11872
|
+
}
|
|
11873
|
+
function renderUnwrapperStaticArray(functionName, elementType, staticLength, internalTypeId) {
|
|
11874
|
+
const byteLength = staticLength * 32;
|
|
11875
|
+
return `
|
|
11876
|
+
function ${functionName}(
|
|
11877
|
+
${elementType}[${staticLength}] memory _value
|
|
11878
|
+
) view returns (
|
|
11879
|
+
${internalTypeId} memory _result
|
|
11880
|
+
) {
|
|
11881
|
+
_result = new ${internalTypeId}(${staticLength});
|
|
11882
|
+
uint256 fromPointer;
|
|
11883
|
+
uint256 toPointer;
|
|
11884
|
+
assembly {
|
|
11885
|
+
fromPointer := _value
|
|
11886
|
+
toPointer := add(_result, 0x20)
|
|
11887
|
+
}
|
|
11888
|
+
Memory.copy(fromPointer, toPointer, ${byteLength});
|
|
11889
|
+
}
|
|
11890
|
+
`;
|
|
11891
|
+
}
|
|
11892
|
+
|
|
11893
|
+
// src/render-solidity/renderTable.ts
|
|
11894
|
+
function renderTable(options) {
|
|
11895
|
+
const {
|
|
11896
|
+
imports,
|
|
11897
|
+
libraryName,
|
|
11898
|
+
structName,
|
|
11899
|
+
staticResourceData,
|
|
11900
|
+
storeImportPath,
|
|
11901
|
+
fields,
|
|
11902
|
+
staticFields,
|
|
11903
|
+
dynamicFields,
|
|
11904
|
+
withRecordMethods,
|
|
11905
|
+
storeArgument,
|
|
11906
|
+
primaryKeys
|
|
11907
|
+
} = options;
|
|
11908
|
+
const { _typedTableId, _typedKeyArgs, _primaryKeysDefinition } = renderCommonData(options);
|
|
11909
|
+
return `${renderedSolidityHeader}
|
|
11910
|
+
|
|
11911
|
+
// Import schema type
|
|
11912
|
+
import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol";
|
|
11913
|
+
|
|
11914
|
+
// Import store internals
|
|
11915
|
+
import { IStore } from "${storeImportPath}IStore.sol";
|
|
11916
|
+
import { StoreSwitch } from "${storeImportPath}StoreSwitch.sol";
|
|
11917
|
+
import { StoreCore } from "${storeImportPath}StoreCore.sol";
|
|
11918
|
+
import { Bytes } from "${storeImportPath}Bytes.sol";
|
|
11919
|
+
import { Memory } from "${storeImportPath}Memory.sol";
|
|
11920
|
+
import { SliceLib } from "${storeImportPath}Slice.sol";
|
|
11921
|
+
import { EncodeArray } from "${storeImportPath}tightcoder/EncodeArray.sol";
|
|
11922
|
+
import { Schema, SchemaLib } from "${storeImportPath}Schema.sol";
|
|
11923
|
+
import { PackedCounter, PackedCounterLib } from "${storeImportPath}PackedCounter.sol";
|
|
11924
|
+
|
|
11925
|
+
${imports.length > 0 ? `
|
|
11926
|
+
// Import user types
|
|
11927
|
+
${renderImports(imports)}
|
|
11928
|
+
` : ""}
|
|
11929
|
+
|
|
11930
|
+
${staticResourceData ? renderTableId(staticResourceData).tableIdDefinition : ""}
|
|
11931
|
+
|
|
11932
|
+
${!structName ? "" : `
|
|
11933
|
+
struct ${structName} {
|
|
11934
|
+
${renderList(fields, ({ name, typeId }) => `${typeId} ${name};`)}
|
|
11935
|
+
}
|
|
11936
|
+
`}
|
|
11937
|
+
|
|
11938
|
+
library ${libraryName} {
|
|
11939
|
+
/** Get the table's schema */
|
|
11940
|
+
function getSchema() internal pure returns (Schema) {
|
|
11941
|
+
SchemaType[] memory _schema = new SchemaType[](${fields.length});
|
|
11942
|
+
${renderList(fields, ({ enumName }, index) => `_schema[${index}] = SchemaType.${enumName};`)}
|
|
11943
|
+
|
|
11944
|
+
return SchemaLib.encode(_schema);
|
|
11945
|
+
}
|
|
11946
|
+
|
|
11947
|
+
function getKeySchema() internal pure returns (Schema) {
|
|
11948
|
+
SchemaType[] memory _schema = new SchemaType[](${primaryKeys.length});
|
|
11949
|
+
${renderList(primaryKeys, ({ enumName }, index) => `_schema[${index}] = SchemaType.${enumName};`)}
|
|
11950
|
+
|
|
11951
|
+
return SchemaLib.encode(_schema);
|
|
11952
|
+
}
|
|
11953
|
+
|
|
11954
|
+
/** Get the table's metadata */
|
|
11955
|
+
function getMetadata() internal pure returns (string memory, string[] memory) {
|
|
11956
|
+
string[] memory _fieldNames = new string[](${fields.length});
|
|
11957
|
+
${renderList(fields, (field, index) => `_fieldNames[${index}] = "${field.name}";`)}
|
|
11958
|
+
return ("${libraryName}", _fieldNames);
|
|
11959
|
+
}
|
|
11960
|
+
|
|
11961
|
+
${renderWithStore(
|
|
11962
|
+
storeArgument,
|
|
11963
|
+
(_typedStore, _store, _commentSuffix) => `
|
|
11964
|
+
/** Register the table's schema${_commentSuffix} */
|
|
11965
|
+
function registerSchema(${renderArguments([_typedStore, _typedTableId])}) internal {
|
|
11966
|
+
${_store}.registerSchema(_tableId, getSchema(), getKeySchema());
|
|
11967
|
+
}
|
|
11968
|
+
`
|
|
11969
|
+
)}
|
|
11970
|
+
${renderWithStore(
|
|
11971
|
+
storeArgument,
|
|
11972
|
+
(_typedStore, _store, _commentSuffix) => `
|
|
11973
|
+
/** Set the table's metadata${_commentSuffix} */
|
|
11974
|
+
function setMetadata(${renderArguments([_typedStore, _typedTableId])}) internal {
|
|
11975
|
+
(string memory _tableName, string[] memory _fieldNames) = getMetadata();
|
|
11976
|
+
${_store}.setMetadata(_tableId, _tableName, _fieldNames);
|
|
11977
|
+
}
|
|
11978
|
+
`
|
|
11979
|
+
)}
|
|
11980
|
+
|
|
11981
|
+
${renderFieldMethods(options)}
|
|
11982
|
+
|
|
11983
|
+
${withRecordMethods ? renderRecordMethods(options) : ""}
|
|
11984
|
+
|
|
11985
|
+
/** Tightly pack full data using this table's schema */
|
|
11986
|
+
function encode(${renderArguments(
|
|
11987
|
+
options.fields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`)
|
|
11988
|
+
)}) internal view returns (bytes memory) {
|
|
11989
|
+
${renderEncodedLengths(dynamicFields)}
|
|
11990
|
+
return abi.encodePacked(${renderArguments([
|
|
11991
|
+
renderArguments(staticFields.map(({ name }) => name)),
|
|
11992
|
+
// TODO try gas optimization (preallocate for all, encodePacked statics, and direct encode dynamics)
|
|
11993
|
+
// (see https://github.com/latticexyz/mud/issues/444)
|
|
11994
|
+
...dynamicFields.length === 0 ? [] : ["_encodedLengths.unwrap()", renderArguments(dynamicFields.map((field) => renderEncodeField(field)))]
|
|
11995
|
+
])});
|
|
11996
|
+
}
|
|
11997
|
+
|
|
11998
|
+
${renderWithStore(
|
|
11999
|
+
storeArgument,
|
|
12000
|
+
(_typedStore, _store, _commentSuffix) => `
|
|
12001
|
+
/* Delete all data for given keys${_commentSuffix} */
|
|
12002
|
+
function deleteRecord(${renderArguments([_typedStore, _typedTableId, _typedKeyArgs])}) internal {
|
|
12003
|
+
${_primaryKeysDefinition}
|
|
12004
|
+
${_store}.deleteRecord(_tableId, _primaryKeys);
|
|
12005
|
+
}
|
|
12006
|
+
`
|
|
12007
|
+
)}
|
|
12008
|
+
}
|
|
12009
|
+
|
|
12010
|
+
${renderTypeHelpers(options)}
|
|
12011
|
+
|
|
12012
|
+
`;
|
|
12013
|
+
}
|
|
12014
|
+
function renderEncodedLengths(dynamicFields) {
|
|
12015
|
+
if (dynamicFields.length > 0) {
|
|
12016
|
+
return `
|
|
12017
|
+
uint16[] memory _counters = new uint16[](${dynamicFields.length});
|
|
12018
|
+
${renderList(dynamicFields, ({ name, arrayElement }, index) => {
|
|
12019
|
+
if (arrayElement) {
|
|
12020
|
+
return `_counters[${index}] = uint16(${name}.length * ${arrayElement.staticByteLength});`;
|
|
12021
|
+
} else {
|
|
12022
|
+
return `_counters[${index}] = uint16(bytes(${name}).length);`;
|
|
12023
|
+
}
|
|
12024
|
+
})}
|
|
12025
|
+
PackedCounter _encodedLengths = PackedCounterLib.pack(_counters);
|
|
12026
|
+
`;
|
|
12027
|
+
} else {
|
|
12028
|
+
return "";
|
|
12029
|
+
}
|
|
12030
|
+
}
|
|
12031
|
+
|
|
12032
|
+
// src/render-solidity/renderTypes.ts
|
|
12033
|
+
function renderTypes(options) {
|
|
12034
|
+
const { enums } = options;
|
|
12035
|
+
return `${renderedSolidityHeader}
|
|
12036
|
+
|
|
12037
|
+
${renderList(
|
|
12038
|
+
enums,
|
|
12039
|
+
({ name, memberNames }) => `
|
|
12040
|
+
enum ${name} {
|
|
12041
|
+
${renderArguments(memberNames)}
|
|
12042
|
+
}
|
|
12043
|
+
`
|
|
12044
|
+
)}
|
|
12045
|
+
|
|
12046
|
+
`;
|
|
12047
|
+
}
|
|
12048
|
+
|
|
12049
|
+
// src/render-solidity/renderTypesFromConfig.ts
|
|
12050
|
+
function renderTypesFromConfig(config2) {
|
|
12051
|
+
const enums = Object.keys(config2.enums).map((name) => ({
|
|
12052
|
+
name,
|
|
12053
|
+
memberNames: config2.enums[name]
|
|
12054
|
+
}));
|
|
12055
|
+
return renderTypes({
|
|
12056
|
+
enums
|
|
12057
|
+
});
|
|
12058
|
+
}
|
|
12059
|
+
|
|
12060
|
+
// src/render-solidity/tablegen.ts
|
|
12061
|
+
async function tablegen(config2, outputBaseDirectory) {
|
|
12062
|
+
const allTableOptions = getTableOptions(config2);
|
|
12063
|
+
for (const { outputPath, renderOptions } of allTableOptions) {
|
|
12064
|
+
const fullOutputPath = path7.join(outputBaseDirectory, outputPath);
|
|
12065
|
+
const output = renderTable(renderOptions);
|
|
12066
|
+
formatAndWrite(output, fullOutputPath, "Generated table");
|
|
12067
|
+
}
|
|
12068
|
+
if (Object.keys(config2.enums).length > 0) {
|
|
12069
|
+
const fullOutputPath = path7.join(outputBaseDirectory, `${config2.userTypesPath}.sol`);
|
|
12070
|
+
const output = renderTypesFromConfig(config2);
|
|
12071
|
+
formatAndWrite(output, fullOutputPath, "Generated types file");
|
|
12072
|
+
}
|
|
12073
|
+
}
|
|
12074
|
+
async function formatAndWrite(output, fullOutputPath, logPrefix) {
|
|
12075
|
+
const formattedOutput = await formatSolidity(output);
|
|
12076
|
+
mkdirSync(path7.dirname(fullOutputPath), { recursive: true });
|
|
12077
|
+
writeFileSync2(fullOutputPath, formattedOutput);
|
|
12078
|
+
console.log(`${logPrefix}: ${fullOutputPath}`);
|
|
12079
|
+
}
|
|
12080
|
+
|
|
12081
|
+
// src/commands/tablegen.ts
|
|
11389
12082
|
var commandModule13 = {
|
|
11390
12083
|
command: "tablegen",
|
|
11391
12084
|
describe: "Autogenerate MUD Store table libraries based on the config file",
|
|
@@ -11395,22 +12088,331 @@ var commandModule13 = {
|
|
|
11395
12088
|
});
|
|
11396
12089
|
},
|
|
11397
12090
|
async handler({ configPath }) {
|
|
12091
|
+
const srcDirectory = await getSrcDirectory();
|
|
12092
|
+
const config2 = await loadStoreConfig(configPath);
|
|
12093
|
+
await tablegen(config2, srcDirectory);
|
|
12094
|
+
process.exit(0);
|
|
12095
|
+
}
|
|
12096
|
+
};
|
|
12097
|
+
var tablegen_default = commandModule13;
|
|
12098
|
+
|
|
12099
|
+
// src/commands/deploy-v2.ts
|
|
12100
|
+
import chalk4 from "chalk";
|
|
12101
|
+
import glob from "glob";
|
|
12102
|
+
import path8, { basename } from "path";
|
|
12103
|
+
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
12104
|
+
|
|
12105
|
+
// src/utils/getChainId.ts
|
|
12106
|
+
import { ethers } from "ethers";
|
|
12107
|
+
async function getChainId(rpc) {
|
|
12108
|
+
const { result: chainId } = await ethers.utils.fetchJson(
|
|
12109
|
+
rpc,
|
|
12110
|
+
'{ "id": 42, "jsonrpc": "2.0", "method": "eth_chainId", "params": [ ] }'
|
|
12111
|
+
);
|
|
12112
|
+
return Number(chainId);
|
|
12113
|
+
}
|
|
12114
|
+
|
|
12115
|
+
// src/commands/deploy-v2.ts
|
|
12116
|
+
var commandModule14 = {
|
|
12117
|
+
command: "deploy-v2",
|
|
12118
|
+
describe: "Deploy MUD v2 contracts",
|
|
12119
|
+
builder(yargs2) {
|
|
12120
|
+
return yargs2.options({
|
|
12121
|
+
configPath: { type: "string", desc: "Path to the config file" },
|
|
12122
|
+
clean: { type: "boolean", desc: "Remove the build forge artifacts and cache directories before building" },
|
|
12123
|
+
printConfig: { type: "boolean", desc: "Print the resolved config" },
|
|
12124
|
+
profile: { type: "string", desc: "The foundry profile to use" },
|
|
12125
|
+
debug: { type: "boolean", desc: "Print debug logs, like full error messages" },
|
|
12126
|
+
priorityFeeMultiplier: {
|
|
12127
|
+
type: "number",
|
|
12128
|
+
desc: "Multiply the estimated priority fee by the provided factor",
|
|
12129
|
+
default: 1
|
|
12130
|
+
}
|
|
12131
|
+
});
|
|
12132
|
+
},
|
|
12133
|
+
async handler(args) {
|
|
12134
|
+
args.profile = args.profile ?? process.env.FOUNDRY_PROFILE;
|
|
12135
|
+
const { configPath, printConfig, profile, clean } = args;
|
|
12136
|
+
const rpc = await getRpcUrl(profile);
|
|
12137
|
+
console.log(
|
|
12138
|
+
chalk4.bgBlue(
|
|
12139
|
+
chalk4.whiteBright(`
|
|
12140
|
+
Deploying MUD v2 contracts${profile ? " with profile " + profile : ""} to RPC ${rpc}
|
|
12141
|
+
`)
|
|
12142
|
+
)
|
|
12143
|
+
);
|
|
12144
|
+
if (clean)
|
|
12145
|
+
await forge(["clean"], { profile });
|
|
12146
|
+
await forge(["build"], { profile });
|
|
11398
12147
|
const srcDir = await getSrcDirectory();
|
|
11399
|
-
const
|
|
11400
|
-
const
|
|
11401
|
-
|
|
11402
|
-
|
|
11403
|
-
|
|
11404
|
-
|
|
11405
|
-
|
|
11406
|
-
const
|
|
11407
|
-
|
|
11408
|
-
|
|
12148
|
+
const existingContracts = glob.sync(`${srcDir}/**/*.sol`).map((path11) => basename(path11, ".sol"));
|
|
12149
|
+
const worldConfig = await loadWorldConfig(configPath, existingContracts);
|
|
12150
|
+
const storeConfig = await loadStoreConfig(configPath);
|
|
12151
|
+
const mudConfig = { ...worldConfig, ...storeConfig };
|
|
12152
|
+
if (printConfig)
|
|
12153
|
+
console.log(chalk4.green("\nResolved config:\n"), JSON.stringify(mudConfig, null, 2));
|
|
12154
|
+
try {
|
|
12155
|
+
const privateKey = process.env.PRIVATE_KEY;
|
|
12156
|
+
if (!privateKey)
|
|
12157
|
+
throw new MUDError("Missing PRIVATE_KEY environment variable");
|
|
12158
|
+
const deploymentInfo = await deploy(mudConfig, { ...args, rpc, privateKey });
|
|
12159
|
+
const chainId = await getChainId(rpc);
|
|
12160
|
+
const outputDir = path8.join(mudConfig.deploysDirectory, chainId.toString());
|
|
12161
|
+
mkdirSync2(outputDir, { recursive: true });
|
|
12162
|
+
writeFileSync3(path8.join(outputDir, "latest.json"), JSON.stringify(deploymentInfo, null, 2));
|
|
12163
|
+
writeFileSync3(path8.join(outputDir, Date.now() + ".json"), JSON.stringify(deploymentInfo, null, 2));
|
|
12164
|
+
console.log(chalk4.bgGreen(chalk4.whiteBright(`
|
|
12165
|
+
Deployment result (written to ${outputDir}):
|
|
12166
|
+
`)));
|
|
12167
|
+
console.log(deploymentInfo);
|
|
12168
|
+
} catch (error) {
|
|
12169
|
+
logError(error);
|
|
12170
|
+
process.exit(1);
|
|
11409
12171
|
}
|
|
11410
12172
|
process.exit(0);
|
|
11411
12173
|
}
|
|
11412
12174
|
};
|
|
11413
|
-
var
|
|
12175
|
+
var deploy_v2_default = commandModule14;
|
|
12176
|
+
|
|
12177
|
+
// src/commands/worldgen.ts
|
|
12178
|
+
import glob2 from "glob";
|
|
12179
|
+
import path10, { basename as basename2 } from "path";
|
|
12180
|
+
|
|
12181
|
+
// src/render-solidity/worldgen.ts
|
|
12182
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
12183
|
+
import path9 from "path";
|
|
12184
|
+
|
|
12185
|
+
// src/utils/contractToInterface.ts
|
|
12186
|
+
import { parse, visit } from "@solidity-parser/parser";
|
|
12187
|
+
function contractToInterface(data, contractName) {
|
|
12188
|
+
const ast = parse(data);
|
|
12189
|
+
let withContract = false;
|
|
12190
|
+
let symbols = [];
|
|
12191
|
+
const functions = [];
|
|
12192
|
+
visit(ast, {
|
|
12193
|
+
ContractDefinition({ name }) {
|
|
12194
|
+
if (name === contractName) {
|
|
12195
|
+
withContract = true;
|
|
12196
|
+
}
|
|
12197
|
+
},
|
|
12198
|
+
FunctionDefinition({ name, visibility, parameters, returnParameters, isConstructor, isFallback, isReceiveEther }, parent) {
|
|
12199
|
+
if (parent !== void 0 && parent.type === "ContractDefinition" && parent.name === contractName) {
|
|
12200
|
+
try {
|
|
12201
|
+
if (isConstructor || isFallback || isReceiveEther)
|
|
12202
|
+
return;
|
|
12203
|
+
if (visibility === "default")
|
|
12204
|
+
throw new MUDError(`Visibility is not specified`);
|
|
12205
|
+
if (visibility === "external" || visibility === "public") {
|
|
12206
|
+
functions.push({
|
|
12207
|
+
name: name === null ? "" : name,
|
|
12208
|
+
parameters: parameters.map(parseParameter),
|
|
12209
|
+
returnParameters: returnParameters === null ? [] : returnParameters.map(parseParameter)
|
|
12210
|
+
});
|
|
12211
|
+
for (const { typeName } of parameters.concat(returnParameters ?? [])) {
|
|
12212
|
+
symbols = symbols.concat(typeNameToExternalSymbols(typeName));
|
|
12213
|
+
}
|
|
12214
|
+
}
|
|
12215
|
+
} catch (error) {
|
|
12216
|
+
if (error instanceof MUDError) {
|
|
12217
|
+
error.message = `Function "${name}" in contract "${contractName}": ${error.message}`;
|
|
12218
|
+
}
|
|
12219
|
+
throw error;
|
|
12220
|
+
}
|
|
12221
|
+
}
|
|
12222
|
+
}
|
|
12223
|
+
});
|
|
12224
|
+
if (!withContract) {
|
|
12225
|
+
throw new MUDError(`Contract not found: ${contractName}`);
|
|
12226
|
+
}
|
|
12227
|
+
return {
|
|
12228
|
+
functions,
|
|
12229
|
+
symbols
|
|
12230
|
+
};
|
|
12231
|
+
}
|
|
12232
|
+
function parseParameter({ name, typeName, storageLocation }) {
|
|
12233
|
+
let typedNameWithLocation = "";
|
|
12234
|
+
const { name: flattenedTypeName, stateMutability } = flattenTypeName(typeName);
|
|
12235
|
+
typedNameWithLocation += flattenedTypeName;
|
|
12236
|
+
if (stateMutability !== null) {
|
|
12237
|
+
typedNameWithLocation += ` ${stateMutability}`;
|
|
12238
|
+
}
|
|
12239
|
+
if (storageLocation !== null) {
|
|
12240
|
+
typedNameWithLocation += ` ${storageLocation}`;
|
|
12241
|
+
}
|
|
12242
|
+
if (name !== null) {
|
|
12243
|
+
typedNameWithLocation += ` ${name}`;
|
|
12244
|
+
}
|
|
12245
|
+
return typedNameWithLocation;
|
|
12246
|
+
}
|
|
12247
|
+
function flattenTypeName(typeName) {
|
|
12248
|
+
if (typeName === null) {
|
|
12249
|
+
return {
|
|
12250
|
+
name: "",
|
|
12251
|
+
stateMutability: null
|
|
12252
|
+
};
|
|
12253
|
+
}
|
|
12254
|
+
if (typeName.type === "ElementaryTypeName") {
|
|
12255
|
+
return {
|
|
12256
|
+
name: typeName.name,
|
|
12257
|
+
stateMutability: typeName.stateMutability
|
|
12258
|
+
};
|
|
12259
|
+
} else if (typeName.type === "UserDefinedTypeName") {
|
|
12260
|
+
return {
|
|
12261
|
+
name: typeName.namePath,
|
|
12262
|
+
stateMutability: null
|
|
12263
|
+
};
|
|
12264
|
+
} else if (typeName.type === "ArrayTypeName") {
|
|
12265
|
+
const { name, stateMutability } = flattenTypeName(typeName.baseTypeName);
|
|
12266
|
+
return {
|
|
12267
|
+
name: `${name}[]`,
|
|
12268
|
+
stateMutability
|
|
12269
|
+
};
|
|
12270
|
+
} else {
|
|
12271
|
+
throw new MUDError(`Invalid typeName.type ${typeName.type}`);
|
|
12272
|
+
}
|
|
12273
|
+
}
|
|
12274
|
+
function typeNameToExternalSymbols(typeName) {
|
|
12275
|
+
if (typeName?.type === "UserDefinedTypeName") {
|
|
12276
|
+
const symbol = typeName.namePath.split(".")[0];
|
|
12277
|
+
return [symbol];
|
|
12278
|
+
} else if (typeName?.type === "ArrayTypeName") {
|
|
12279
|
+
return typeNameToExternalSymbols(typeName.baseTypeName);
|
|
12280
|
+
} else {
|
|
12281
|
+
return [];
|
|
12282
|
+
}
|
|
12283
|
+
}
|
|
12284
|
+
|
|
12285
|
+
// src/utils/formatAndWrite.ts
|
|
12286
|
+
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
12287
|
+
import { dirname } from "path";
|
|
12288
|
+
async function formatAndWrite2(output, fullOutputPath, logPrefix) {
|
|
12289
|
+
const formattedOutput = await formatSolidity(output);
|
|
12290
|
+
mkdirSync3(dirname(fullOutputPath), { recursive: true });
|
|
12291
|
+
writeFileSync4(fullOutputPath, formattedOutput);
|
|
12292
|
+
console.log(`${logPrefix}: ${fullOutputPath}`);
|
|
12293
|
+
}
|
|
12294
|
+
|
|
12295
|
+
// src/render-solidity/renderSystemInterface.ts
|
|
12296
|
+
function renderSystemInterface(options) {
|
|
12297
|
+
const { imports, name, functionPrefix, functions } = options;
|
|
12298
|
+
return `${renderedSolidityHeader}
|
|
12299
|
+
|
|
12300
|
+
${renderImports(imports)}
|
|
12301
|
+
|
|
12302
|
+
interface ${name} {
|
|
12303
|
+
${renderList(
|
|
12304
|
+
functions,
|
|
12305
|
+
({ name: name2, parameters, returnParameters }) => `
|
|
12306
|
+
function ${functionPrefix}${name2}(${renderArguments(parameters)}) external ${renderReturnParameters(
|
|
12307
|
+
returnParameters
|
|
12308
|
+
)};
|
|
12309
|
+
`
|
|
12310
|
+
)}
|
|
12311
|
+
}
|
|
12312
|
+
|
|
12313
|
+
`;
|
|
12314
|
+
}
|
|
12315
|
+
function renderReturnParameters(returnParameters) {
|
|
12316
|
+
if (returnParameters.length > 0) {
|
|
12317
|
+
return `returns (${renderArguments(returnParameters)})`;
|
|
12318
|
+
} else {
|
|
12319
|
+
return "";
|
|
12320
|
+
}
|
|
12321
|
+
}
|
|
12322
|
+
|
|
12323
|
+
// src/render-solidity/renderWorld.ts
|
|
12324
|
+
function renderWorld(options) {
|
|
12325
|
+
const { interfaceName, storeImportPath, worldImportPath, imports } = options;
|
|
12326
|
+
return `${renderedSolidityHeader}
|
|
12327
|
+
|
|
12328
|
+
import { IStore } from "${storeImportPath}IStore.sol";
|
|
12329
|
+
|
|
12330
|
+
import { IWorldCore } from "${worldImportPath}interfaces/IWorldCore.sol";
|
|
12331
|
+
|
|
12332
|
+
${renderImports(imports)}
|
|
12333
|
+
|
|
12334
|
+
/**
|
|
12335
|
+
* The ${interfaceName} interface includes all systems dynamically added to the World
|
|
12336
|
+
* during the deploy process.
|
|
12337
|
+
*/
|
|
12338
|
+
interface ${interfaceName} is ${renderArguments(["IStore", "IWorldCore", ...imports.map(({ symbol }) => symbol)])} {
|
|
12339
|
+
|
|
12340
|
+
}
|
|
12341
|
+
|
|
12342
|
+
`;
|
|
12343
|
+
}
|
|
12344
|
+
|
|
12345
|
+
// src/render-solidity/worldgen.ts
|
|
12346
|
+
async function worldgen(config2, existingContracts, outputBaseDirectory) {
|
|
12347
|
+
const worldgenBaseDirectory = path9.join(outputBaseDirectory, config2.worldgenDirectory);
|
|
12348
|
+
const systems = existingContracts.filter(({ basename: basename3 }) => Object.keys(config2.systems).includes(basename3));
|
|
12349
|
+
const systemInterfaceImports = [];
|
|
12350
|
+
for (const system of systems) {
|
|
12351
|
+
const data = readFileSync3(system.path, "utf8");
|
|
12352
|
+
const { functions, symbols } = contractToInterface(data, system.basename);
|
|
12353
|
+
const imports = symbols.map((symbol) => ({
|
|
12354
|
+
symbol,
|
|
12355
|
+
fromPath: system.path,
|
|
12356
|
+
usedInPath: worldgenBaseDirectory
|
|
12357
|
+
}));
|
|
12358
|
+
const systemInterfaceName = `I${system.basename}`;
|
|
12359
|
+
const { fileSelector } = config2.systems[system.basename];
|
|
12360
|
+
const output2 = renderSystemInterface({
|
|
12361
|
+
name: systemInterfaceName,
|
|
12362
|
+
functionPrefix: config2.namespace === "" ? "" : `${config2.namespace}_${fileSelector}_`,
|
|
12363
|
+
functions,
|
|
12364
|
+
imports
|
|
12365
|
+
});
|
|
12366
|
+
const fullOutputPath2 = path9.join(worldgenBaseDirectory, systemInterfaceName + ".sol");
|
|
12367
|
+
await formatAndWrite2(output2, fullOutputPath2, "Generated system interface");
|
|
12368
|
+
systemInterfaceImports.push({
|
|
12369
|
+
symbol: systemInterfaceName,
|
|
12370
|
+
fromPath: `${systemInterfaceName}.sol`,
|
|
12371
|
+
usedInPath: "./"
|
|
12372
|
+
});
|
|
12373
|
+
}
|
|
12374
|
+
const worldInterfaceName = "IWorld";
|
|
12375
|
+
const output = renderWorld({
|
|
12376
|
+
interfaceName: worldInterfaceName,
|
|
12377
|
+
imports: systemInterfaceImports,
|
|
12378
|
+
storeImportPath: config2.storeImportPath,
|
|
12379
|
+
worldImportPath: config2.worldImportPath
|
|
12380
|
+
});
|
|
12381
|
+
const fullOutputPath = path9.join(worldgenBaseDirectory, worldInterfaceName + ".sol");
|
|
12382
|
+
await formatAndWrite2(output, fullOutputPath, "Generated system interface");
|
|
12383
|
+
}
|
|
12384
|
+
|
|
12385
|
+
// src/commands/worldgen.ts
|
|
12386
|
+
import { rmSync as rmSync3 } from "fs";
|
|
12387
|
+
var commandModule15 = {
|
|
12388
|
+
command: "worldgen",
|
|
12389
|
+
describe: "Autogenerate interfaces for Systems and World based on existing contracts and the config file",
|
|
12390
|
+
builder(yargs2) {
|
|
12391
|
+
return yargs2.options({
|
|
12392
|
+
configPath: { type: "string", desc: "Path to the config file" },
|
|
12393
|
+
clean: { type: "boolean", desc: "Clear the worldgen directory before generating new interfaces" }
|
|
12394
|
+
});
|
|
12395
|
+
},
|
|
12396
|
+
async handler(args) {
|
|
12397
|
+
const { configPath, clean } = args;
|
|
12398
|
+
const srcDir = await getSrcDirectory();
|
|
12399
|
+
const existingContracts = glob2.sync(`${srcDir}/**/*.sol`).map((path11) => ({
|
|
12400
|
+
path: path11,
|
|
12401
|
+
basename: basename2(path11, ".sol")
|
|
12402
|
+
}));
|
|
12403
|
+
const worldConfig = await loadWorldConfig(
|
|
12404
|
+
configPath,
|
|
12405
|
+
existingContracts.map(({ basename: basename3 }) => basename3)
|
|
12406
|
+
);
|
|
12407
|
+
const storeConfig = await loadStoreConfig(configPath);
|
|
12408
|
+
const mudConfig = { ...worldConfig, ...storeConfig };
|
|
12409
|
+
if (clean)
|
|
12410
|
+
rmSync3(path10.join(srcDir, worldConfig.worldgenDirectory), { recursive: true, force: true });
|
|
12411
|
+
await worldgen(mudConfig, existingContracts, srcDir);
|
|
12412
|
+
process.exit(0);
|
|
12413
|
+
}
|
|
12414
|
+
};
|
|
12415
|
+
var worldgen_default = commandModule15;
|
|
11414
12416
|
|
|
11415
12417
|
// src/commands/index.ts
|
|
11416
12418
|
var commands = [
|
|
@@ -11418,6 +12420,7 @@ var commands = [
|
|
|
11418
12420
|
call_system_default,
|
|
11419
12421
|
codegen_libdeploy_default,
|
|
11420
12422
|
deploy_contracts_default,
|
|
12423
|
+
deploy_v2_default,
|
|
11421
12424
|
devnode_default,
|
|
11422
12425
|
faucet_default,
|
|
11423
12426
|
gas_report_default,
|
|
@@ -11426,10 +12429,13 @@ var commands = [
|
|
|
11426
12429
|
tablegen_default,
|
|
11427
12430
|
test_default,
|
|
11428
12431
|
trace_default,
|
|
11429
|
-
types_default
|
|
12432
|
+
types_default,
|
|
12433
|
+
worldgen_default
|
|
11430
12434
|
];
|
|
11431
12435
|
|
|
11432
12436
|
// src/mud.ts
|
|
12437
|
+
import * as dotenv from "dotenv";
|
|
12438
|
+
dotenv.config();
|
|
11433
12439
|
yargs(hideBin(process.argv)).scriptName("mud").command(commands).strict().fail((msg, err) => {
|
|
11434
12440
|
console.log("");
|
|
11435
12441
|
logError(err);
|