@latticexyz/cli 2.0.0-transaction-context-324984c5 → 2.0.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/dist/{chunk-22IIKR4S.js → chunk-QXUPZVZL.js} +2 -2
- package/dist/chunk-QXUPZVZL.js.map +1 -0
- package/dist/commands-WWEJJZV4.js +36 -0
- package/dist/commands-WWEJJZV4.js.map +1 -0
- package/dist/errors-MZURIB7V.js +2 -0
- package/dist/mud.js +1 -1
- package/dist/mud.js.map +1 -1
- package/package.json +16 -15
- package/src/build.ts +9 -5
- package/src/commands/build.ts +2 -3
- package/src/commands/deploy.ts +1 -1
- package/src/commands/dev-contracts.ts +6 -5
- package/src/commands/set-version.ts +1 -1
- package/src/commands/tablegen.ts +2 -2
- package/src/commands/trace.ts +7 -5
- package/src/commands/worldgen.ts +7 -6
- package/src/deploy/common.ts +54 -8
- package/src/deploy/configToTables.ts +8 -6
- package/src/deploy/create2/README.md +4 -0
- package/src/deploy/create2/deployment.json +2 -1
- package/src/deploy/createPrepareDeploy.ts +28 -0
- package/src/deploy/deploy.ts +33 -16
- package/src/deploy/deployWorld.ts +4 -3
- package/src/deploy/ensureContract.ts +12 -7
- package/src/deploy/ensureContractsDeployed.ts +9 -1
- package/src/deploy/ensureDeployer.ts +61 -22
- package/src/deploy/ensureFunctions.ts +5 -5
- package/src/deploy/ensureModules.ts +16 -10
- package/src/deploy/ensureNamespaceOwner.ts +4 -4
- package/src/deploy/ensureSystems.ts +108 -83
- package/src/deploy/ensureTables.ts +8 -9
- package/src/deploy/ensureWorldFactory.ts +79 -92
- package/src/deploy/findLibraries.ts +36 -0
- package/src/deploy/getFunctions.ts +5 -5
- package/src/deploy/getResourceAccess.ts +3 -3
- package/src/deploy/getSystems.ts +6 -7
- package/src/deploy/getTableValue.ts +1 -1
- package/src/deploy/getTables.ts +2 -2
- package/src/deploy/logsToWorldDeploy.ts +4 -4
- package/src/deploy/orderByDependencies.ts +12 -0
- package/src/deploy/resolveConfig.ts +55 -58
- package/src/mud.ts +1 -1
- package/src/mudPackages.ts +1 -1
- package/src/runDeploy.ts +28 -10
- package/src/utils/{modules/constants.ts → defaultModuleContracts.ts} +4 -0
- package/src/utils/errors.ts +1 -1
- package/src/utils/findPlaceholders.ts +27 -0
- package/src/utils/{utils/getContractData.ts → getContractData.ts} +11 -5
- package/src/utils/{utils/postDeploy.ts → postDeploy.ts} +2 -2
- package/src/utils/printMUD.ts +1 -1
- package/dist/chunk-22IIKR4S.js.map +0 -1
- package/dist/commands-3JV3U43E.js +0 -27
- package/dist/commands-3JV3U43E.js.map +0 -1
- package/dist/errors-XGN6V2Y3.js +0 -2
- package/src/deploy/resourceLabel.ts +0 -3
- /package/dist/{errors-XGN6V2Y3.js.map → errors-MZURIB7V.js.map} +0 -0
@@ -6,113 +6,100 @@ import initModuleBuild from "@latticexyz/world/out/InitModule.sol/InitModule.jso
|
|
6
6
|
import initModuleAbi from "@latticexyz/world/out/InitModule.sol/InitModule.abi.json" assert { type: "json" };
|
7
7
|
import worldFactoryBuild from "@latticexyz/world/out/WorldFactory.sol/WorldFactory.json" assert { type: "json" };
|
8
8
|
import worldFactoryAbi from "@latticexyz/world/out/WorldFactory.sol/WorldFactory.abi.json" assert { type: "json" };
|
9
|
-
import { Client, Transport, Chain, Account, Hex, getCreate2Address, encodeDeployData, size } from "viem";
|
10
|
-
import { deployer } from "./ensureDeployer";
|
9
|
+
import { Client, Transport, Chain, Account, Hex, getCreate2Address, encodeDeployData, size, Address } from "viem";
|
11
10
|
import { salt } from "./common";
|
12
11
|
import { ensureContractsDeployed } from "./ensureContractsDeployed";
|
13
12
|
import { Contract } from "./ensureContract";
|
14
13
|
|
15
|
-
export
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
});
|
14
|
+
export async function ensureWorldFactory(
|
15
|
+
client: Client<Transport, Chain | undefined, Account>,
|
16
|
+
deployerAddress: Hex,
|
17
|
+
): Promise<Address> {
|
18
|
+
const accessManagementSystemDeployedBytecodeSize = size(accessManagementSystemBuild.deployedBytecode.object as Hex);
|
19
|
+
const accessManagementSystemBytecode = accessManagementSystemBuild.bytecode.object as Hex;
|
20
|
+
const accessManagementSystem = getCreate2Address({
|
21
|
+
from: deployerAddress,
|
22
|
+
bytecode: accessManagementSystemBytecode,
|
23
|
+
salt,
|
24
|
+
});
|
27
25
|
|
28
|
-
|
29
|
-
balanceTransferSystemBuild.
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
});
|
35
|
-
export const balanceTransferSystem = getCreate2Address({
|
36
|
-
from: deployer,
|
37
|
-
bytecode: balanceTransferSystemBytecode,
|
38
|
-
salt,
|
39
|
-
});
|
26
|
+
const balanceTransferSystemDeployedBytecodeSize = size(balanceTransferSystemBuild.deployedBytecode.object as Hex);
|
27
|
+
const balanceTransferSystemBytecode = balanceTransferSystemBuild.bytecode.object as Hex;
|
28
|
+
const balanceTransferSystem = getCreate2Address({
|
29
|
+
from: deployerAddress,
|
30
|
+
bytecode: balanceTransferSystemBytecode,
|
31
|
+
salt,
|
32
|
+
});
|
40
33
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
abi: [],
|
45
|
-
});
|
46
|
-
export const batchCallSystem = getCreate2Address({ from: deployer, bytecode: batchCallSystemBytecode, salt });
|
34
|
+
const batchCallSystemDeployedBytecodeSize = size(batchCallSystemBuild.deployedBytecode.object as Hex);
|
35
|
+
const batchCallSystemBytecode = batchCallSystemBuild.bytecode.object as Hex;
|
36
|
+
const batchCallSystem = getCreate2Address({ from: deployerAddress, bytecode: batchCallSystemBytecode, salt });
|
47
37
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
bytecode: registrationBytecode,
|
56
|
-
salt,
|
57
|
-
});
|
38
|
+
const registrationDeployedBytecodeSize = size(registrationSystemBuild.deployedBytecode.object as Hex);
|
39
|
+
const registrationBytecode = registrationSystemBuild.bytecode.object as Hex;
|
40
|
+
const registration = getCreate2Address({
|
41
|
+
from: deployerAddress,
|
42
|
+
bytecode: registrationBytecode,
|
43
|
+
salt,
|
44
|
+
});
|
58
45
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
});
|
46
|
+
const initModuleDeployedBytecodeSize = size(initModuleBuild.deployedBytecode.object as Hex);
|
47
|
+
const initModuleBytecode = encodeDeployData({
|
48
|
+
bytecode: initModuleBuild.bytecode.object as Hex,
|
49
|
+
abi: initModuleAbi,
|
50
|
+
args: [accessManagementSystem, balanceTransferSystem, batchCallSystem, registration],
|
51
|
+
});
|
65
52
|
|
66
|
-
|
53
|
+
const initModule = getCreate2Address({ from: deployerAddress, bytecode: initModuleBytecode, salt });
|
67
54
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
});
|
55
|
+
const worldFactoryDeployedBytecodeSize = size(worldFactoryBuild.deployedBytecode.object as Hex);
|
56
|
+
const worldFactoryBytecode = encodeDeployData({
|
57
|
+
bytecode: worldFactoryBuild.bytecode.object as Hex,
|
58
|
+
abi: worldFactoryAbi,
|
59
|
+
args: [initModule],
|
60
|
+
});
|
74
61
|
|
75
|
-
|
62
|
+
const worldFactory = getCreate2Address({ from: deployerAddress, bytecode: worldFactoryBytecode, salt });
|
76
63
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
];
|
64
|
+
const worldFactoryContracts: readonly Contract[] = [
|
65
|
+
{
|
66
|
+
bytecode: accessManagementSystemBytecode,
|
67
|
+
deployedBytecodeSize: accessManagementSystemDeployedBytecodeSize,
|
68
|
+
label: "access management system",
|
69
|
+
},
|
70
|
+
{
|
71
|
+
bytecode: balanceTransferSystemBytecode,
|
72
|
+
deployedBytecodeSize: balanceTransferSystemDeployedBytecodeSize,
|
73
|
+
label: "balance transfer system",
|
74
|
+
},
|
75
|
+
{
|
76
|
+
bytecode: batchCallSystemBytecode,
|
77
|
+
deployedBytecodeSize: batchCallSystemDeployedBytecodeSize,
|
78
|
+
label: "batch call system",
|
79
|
+
},
|
80
|
+
{
|
81
|
+
bytecode: registrationBytecode,
|
82
|
+
deployedBytecodeSize: registrationDeployedBytecodeSize,
|
83
|
+
label: "core registration system",
|
84
|
+
},
|
85
|
+
{
|
86
|
+
bytecode: initModuleBytecode,
|
87
|
+
deployedBytecodeSize: initModuleDeployedBytecodeSize,
|
88
|
+
label: "core module",
|
89
|
+
},
|
90
|
+
{
|
91
|
+
bytecode: worldFactoryBytecode,
|
92
|
+
deployedBytecodeSize: worldFactoryDeployedBytecodeSize,
|
93
|
+
label: "world factory",
|
94
|
+
},
|
95
|
+
];
|
109
96
|
|
110
|
-
export async function ensureWorldFactory(
|
111
|
-
client: Client<Transport, Chain | undefined, Account>
|
112
|
-
): Promise<readonly Hex[]> {
|
113
97
|
// WorldFactory constructor doesn't call InitModule, only sets its address, so we can do these in parallel since the address is deterministic
|
114
|
-
|
98
|
+
await ensureContractsDeployed({
|
115
99
|
client,
|
100
|
+
deployerAddress,
|
116
101
|
contracts: worldFactoryContracts,
|
117
102
|
});
|
103
|
+
|
104
|
+
return worldFactory;
|
118
105
|
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import { readFileSync } from "fs";
|
2
|
+
import glob from "glob";
|
3
|
+
import { orderByDependencies } from "./orderByDependencies";
|
4
|
+
import { LinkReferences } from "../utils/findPlaceholders";
|
5
|
+
|
6
|
+
export function findLibraries(forgeOutDir: string): readonly {
|
7
|
+
readonly path: string;
|
8
|
+
readonly name: string;
|
9
|
+
}[] {
|
10
|
+
const artifacts = glob
|
11
|
+
.sync(`${forgeOutDir}/**/*.json`, { ignore: "**/*.abi.json" })
|
12
|
+
.map((path) => JSON.parse(readFileSync(path, "utf8")));
|
13
|
+
|
14
|
+
const libraries = artifacts.flatMap((artifact) => {
|
15
|
+
if (!artifact.metadata) return [];
|
16
|
+
|
17
|
+
const contractPath = Object.keys(artifact.metadata.settings.compilationTarget)[0];
|
18
|
+
const contractName = artifact.metadata.settings.compilationTarget[contractPath];
|
19
|
+
const linkReferences = artifact.bytecode.linkReferences as LinkReferences;
|
20
|
+
|
21
|
+
return Object.entries(linkReferences).flatMap(([libraryPath, reference]) =>
|
22
|
+
Object.keys(reference).map((libraryName) => ({
|
23
|
+
path: libraryPath,
|
24
|
+
name: libraryName,
|
25
|
+
dependentPath: contractPath,
|
26
|
+
dependentName: contractName,
|
27
|
+
})),
|
28
|
+
);
|
29
|
+
});
|
30
|
+
|
31
|
+
return orderByDependencies(
|
32
|
+
libraries,
|
33
|
+
(lib) => `${lib.path}:${lib.name}`,
|
34
|
+
(lib) => [`${lib.dependentPath}:${lib.dependentName}`],
|
35
|
+
);
|
36
|
+
}
|
@@ -1,9 +1,9 @@
|
|
1
|
-
import { Client,
|
1
|
+
import { Client, toFunctionSelector, parseAbiItem } from "viem";
|
2
2
|
import { WorldDeploy, WorldFunction, worldTables } from "./common";
|
3
3
|
import { debug } from "./debug";
|
4
4
|
import { storeSetRecordEvent } from "@latticexyz/store";
|
5
5
|
import { getLogs } from "viem/actions";
|
6
|
-
import { decodeValueArgs } from "@latticexyz/protocol-parser";
|
6
|
+
import { decodeValueArgs } from "@latticexyz/protocol-parser/internal";
|
7
7
|
import { getTableValue } from "./getTableValue";
|
8
8
|
import { hexToResource } from "@latticexyz/common";
|
9
9
|
|
@@ -34,12 +34,12 @@ export async function getFunctions({
|
|
34
34
|
// TODO: parallelize with a bulk getRecords
|
35
35
|
const functions = await Promise.all(
|
36
36
|
signatures.map(async (signature) => {
|
37
|
-
const selector =
|
37
|
+
const selector = toFunctionSelector(signature);
|
38
38
|
const { systemId, systemFunctionSelector } = await getTableValue({
|
39
39
|
client,
|
40
40
|
worldDeploy,
|
41
41
|
table: worldTables.world_FunctionSelectors,
|
42
|
-
key: {
|
42
|
+
key: { worldFunctionSelector: selector },
|
43
43
|
});
|
44
44
|
const { namespace, name } = hexToResource(systemId);
|
45
45
|
// TODO: find away around undoing contract logic (https://github.com/latticexyz/mud/issues/1708)
|
@@ -51,7 +51,7 @@ export async function getFunctions({
|
|
51
51
|
systemFunctionSignature,
|
52
52
|
systemFunctionSelector,
|
53
53
|
};
|
54
|
-
})
|
54
|
+
}),
|
55
55
|
);
|
56
56
|
|
57
57
|
return functions;
|
@@ -3,7 +3,7 @@ import { WorldDeploy, worldTables } from "./common";
|
|
3
3
|
import { debug } from "./debug";
|
4
4
|
import { storeSpliceStaticDataEvent } from "@latticexyz/store";
|
5
5
|
import { getLogs } from "viem/actions";
|
6
|
-
import { decodeKey } from "@latticexyz/protocol-parser";
|
6
|
+
import { decodeKey } from "@latticexyz/protocol-parser/internal";
|
7
7
|
import { getTableValue } from "./getTableValue";
|
8
8
|
|
9
9
|
export async function getResourceAccess({
|
@@ -35,8 +35,8 @@ export async function getResourceAccess({
|
|
35
35
|
await Promise.all(
|
36
36
|
keys.map(
|
37
37
|
async (key) =>
|
38
|
-
[key, await getTableValue({ client, worldDeploy, table: worldTables.world_ResourceAccess, key })] as const
|
39
|
-
)
|
38
|
+
[key, await getTableValue({ client, worldDeploy, table: worldTables.world_ResourceAccess, key })] as const,
|
39
|
+
),
|
40
40
|
)
|
41
41
|
)
|
42
42
|
.filter(([, value]) => value.access)
|
package/src/deploy/getSystems.ts
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
import {
|
1
|
+
import { DeployedSystem, WorldDeploy, worldTables } from "./common";
|
2
2
|
import { Client } from "viem";
|
3
3
|
import { getResourceIds } from "./getResourceIds";
|
4
|
-
import { hexToResource } from "@latticexyz/common";
|
4
|
+
import { hexToResource, resourceToLabel } from "@latticexyz/common";
|
5
5
|
import { getTableValue } from "./getTableValue";
|
6
6
|
import { debug } from "./debug";
|
7
|
-
import { resourceLabel } from "./resourceLabel";
|
8
7
|
import { getFunctions } from "./getFunctions";
|
9
8
|
import { getResourceAccess } from "./getResourceAccess";
|
10
9
|
|
@@ -14,7 +13,7 @@ export async function getSystems({
|
|
14
13
|
}: {
|
15
14
|
readonly client: Client;
|
16
15
|
readonly worldDeploy: WorldDeploy;
|
17
|
-
}): Promise<readonly
|
16
|
+
}): Promise<readonly DeployedSystem[]> {
|
18
17
|
const [resourceIds, functions, resourceAccess] = await Promise.all([
|
19
18
|
getResourceIds({ client, worldDeploy }),
|
20
19
|
getFunctions({ client, worldDeploy }),
|
@@ -22,9 +21,9 @@ export async function getSystems({
|
|
22
21
|
]);
|
23
22
|
const systems = resourceIds.map(hexToResource).filter((resource) => resource.type === "system");
|
24
23
|
|
25
|
-
debug("looking up systems", systems.map(
|
24
|
+
debug("looking up systems", systems.map(resourceToLabel).join(", "));
|
26
25
|
return await Promise.all(
|
27
|
-
systems.map(async (system) => {
|
26
|
+
systems.map(async (system): Promise<DeployedSystem> => {
|
28
27
|
const { system: address, publicAccess } = await getTableValue({
|
29
28
|
client,
|
30
29
|
worldDeploy,
|
@@ -43,6 +42,6 @@ export async function getSystems({
|
|
43
42
|
.map(({ address }) => address),
|
44
43
|
functions: systemFunctions,
|
45
44
|
};
|
46
|
-
})
|
45
|
+
}),
|
47
46
|
);
|
48
47
|
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { SchemaToPrimitives, decodeValueArgs, encodeKey } from "@latticexyz/protocol-parser";
|
1
|
+
import { SchemaToPrimitives, decodeValueArgs, encodeKey } from "@latticexyz/protocol-parser/internal";
|
2
2
|
import { WorldDeploy, worldAbi } from "./common";
|
3
3
|
import { Client } from "viem";
|
4
4
|
import { readContract } from "viem/actions";
|
package/src/deploy/getTables.ts
CHANGED
@@ -5,7 +5,7 @@ import { WorldDeploy, storeTables } from "./common";
|
|
5
5
|
import { debug } from "./debug";
|
6
6
|
import { storeSetRecordEvent } from "@latticexyz/store";
|
7
7
|
import { getLogs } from "viem/actions";
|
8
|
-
import { KeySchema, ValueSchema, decodeKey, decodeValueArgs, hexToSchema } from "@latticexyz/protocol-parser";
|
8
|
+
import { KeySchema, ValueSchema, decodeKey, decodeValueArgs, hexToSchema } from "@latticexyz/protocol-parser/internal";
|
9
9
|
|
10
10
|
export async function getTables({
|
11
11
|
client,
|
@@ -45,7 +45,7 @@ export async function getTables({
|
|
45
45
|
const valueAbiTypes = [...valueSchemaFields.staticFields, ...valueSchemaFields.dynamicFields];
|
46
46
|
|
47
47
|
const keySchema = Object.fromEntries(
|
48
|
-
keySchemaFields.staticFields.map((abiType, i) => [keyNames[i], abiType])
|
48
|
+
keySchemaFields.staticFields.map((abiType, i) => [keyNames[i], abiType]),
|
49
49
|
) as KeySchema;
|
50
50
|
const valueSchema = Object.fromEntries(valueAbiTypes.map((abiType, i) => [fieldNames[i], abiType])) as ValueSchema;
|
51
51
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { AbiEventSignatureNotFoundError, Log, decodeEventLog, hexToString, parseAbi
|
1
|
+
import { AbiEventSignatureNotFoundError, Log, decodeEventLog, hexToString, parseAbi } from "viem";
|
2
2
|
import { WorldDeploy, worldDeployEvents } from "./common";
|
3
3
|
import { isDefined } from "@latticexyz/common/utils";
|
4
4
|
|
@@ -31,13 +31,13 @@ export function logsToWorldDeploy(logs: readonly Log<bigint, number, false>[]):
|
|
31
31
|
address: log.address,
|
32
32
|
deployBlock: log.blockNumber,
|
33
33
|
...(log.eventName === "HelloWorld"
|
34
|
-
? { worldVersion: hexToString(
|
34
|
+
? { worldVersion: hexToString(log.args.worldVersion).replace(/\0+$/, "") }
|
35
35
|
: null),
|
36
36
|
...(log.eventName === "HelloStore"
|
37
|
-
? { storeVersion: hexToString(
|
37
|
+
? { storeVersion: hexToString(log.args.storeVersion).replace(/\0+$/, "") }
|
38
38
|
: null),
|
39
39
|
}),
|
40
|
-
{}
|
40
|
+
{},
|
41
41
|
);
|
42
42
|
|
43
43
|
if (address == null) throw new Error("could not find world address");
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import toposort from "toposort";
|
2
|
+
|
3
|
+
export function orderByDependencies<T>(
|
4
|
+
items: readonly T[],
|
5
|
+
itemKey: (item: T) => string,
|
6
|
+
dependencyKeys: (item: T) => string[],
|
7
|
+
): readonly T[] {
|
8
|
+
const dependencyOrder = toposort(
|
9
|
+
items.flatMap((item) => dependencyKeys(item).map((dependency) => [itemKey(item), dependency] as [string, string])),
|
10
|
+
);
|
11
|
+
return [...items].sort((a, b) => dependencyOrder.indexOf(itemKey(a)) - dependencyOrder.indexOf(itemKey(b)));
|
12
|
+
}
|
@@ -1,25 +1,18 @@
|
|
1
|
-
import
|
2
|
-
import {
|
3
|
-
import {
|
4
|
-
import {
|
5
|
-
import {
|
6
|
-
import {
|
7
|
-
import {
|
8
|
-
|
9
|
-
Hex,
|
10
|
-
getCreate2Address,
|
11
|
-
getAddress,
|
12
|
-
hexToBytes,
|
13
|
-
Abi,
|
14
|
-
bytesToHex,
|
15
|
-
getFunctionSignature,
|
16
|
-
} from "viem";
|
1
|
+
import path from "path";
|
2
|
+
import { resolveWorldConfig } from "@latticexyz/world/internal";
|
3
|
+
import { Config, ConfigInput, Library, Module, System, WorldFunction } from "./common";
|
4
|
+
import { resourceToHex } from "@latticexyz/common";
|
5
|
+
import { resolveWithContext } from "@latticexyz/config/library";
|
6
|
+
import { encodeField } from "@latticexyz/protocol-parser/internal";
|
7
|
+
import { SchemaAbiType, SchemaAbiTypeToPrimitiveType } from "@latticexyz/schema-type/internal";
|
8
|
+
import { Hex, hexToBytes, bytesToHex, toFunctionSelector, toFunctionSignature } from "viem";
|
17
9
|
import { getExistingContracts } from "../utils/getExistingContracts";
|
18
|
-
import { defaultModuleContracts } from "../utils/
|
19
|
-
import { getContractData } from "../utils/
|
10
|
+
import { defaultModuleContracts } from "../utils/defaultModuleContracts";
|
11
|
+
import { getContractData } from "../utils/getContractData";
|
20
12
|
import { configToTables } from "./configToTables";
|
21
|
-
import {
|
22
|
-
import {
|
13
|
+
import { groupBy } from "@latticexyz/common/utils";
|
14
|
+
import { findLibraries } from "./findLibraries";
|
15
|
+
import { createPrepareDeploy } from "./createPrepareDeploy";
|
23
16
|
|
24
17
|
// TODO: this should be replaced by https://github.com/latticexyz/mud/issues/1668
|
25
18
|
|
@@ -32,35 +25,47 @@ export function resolveConfig<config extends ConfigInput>({
|
|
32
25
|
forgeSourceDir: string;
|
33
26
|
forgeOutDir: string;
|
34
27
|
}): Config<config> {
|
28
|
+
const libraries = findLibraries(forgeOutDir).map((library): Library => {
|
29
|
+
// foundry/solc flattens artifacts, so we just use the path basename
|
30
|
+
const contractData = getContractData(path.basename(library.path), library.name, forgeOutDir);
|
31
|
+
return {
|
32
|
+
path: library.path,
|
33
|
+
name: library.name,
|
34
|
+
abi: contractData.abi,
|
35
|
+
prepareDeploy: createPrepareDeploy(contractData.bytecode, contractData.placeholders),
|
36
|
+
deployedBytecodeSize: contractData.deployedBytecodeSize,
|
37
|
+
};
|
38
|
+
});
|
39
|
+
|
35
40
|
const tables = configToTables(config);
|
36
41
|
|
37
42
|
// TODO: should the config parser/loader help with resolving systems?
|
38
43
|
const contractNames = getExistingContracts(forgeSourceDir).map(({ basename }) => basename);
|
39
44
|
const resolvedConfig = resolveWorldConfig(config, contractNames);
|
40
|
-
const baseSystemContractData = getContractData("System", forgeOutDir);
|
45
|
+
const baseSystemContractData = getContractData("System.sol", "System", forgeOutDir);
|
41
46
|
const baseSystemFunctions = baseSystemContractData.abi
|
42
47
|
.filter((item): item is typeof item & { type: "function" } => item.type === "function")
|
43
|
-
.map(
|
48
|
+
.map(toFunctionSignature);
|
44
49
|
|
45
|
-
const systems = Object.entries(resolvedConfig.systems).map(([systemName, system]) => {
|
50
|
+
const systems = Object.entries(resolvedConfig.systems).map(([systemName, system]): System => {
|
46
51
|
const namespace = config.namespace;
|
47
52
|
const name = system.name;
|
48
53
|
const systemId = resourceToHex({ type: "system", namespace, name });
|
49
|
-
const contractData = getContractData(systemName, forgeOutDir);
|
54
|
+
const contractData = getContractData(`${systemName}.sol`, systemName, forgeOutDir);
|
50
55
|
|
51
56
|
const systemFunctions = contractData.abi
|
52
57
|
.filter((item): item is typeof item & { type: "function" } => item.type === "function")
|
53
|
-
.map(
|
58
|
+
.map(toFunctionSignature)
|
54
59
|
.filter((sig) => !baseSystemFunctions.includes(sig))
|
55
60
|
.map((sig): WorldFunction => {
|
56
61
|
// TODO: figure out how to not duplicate contract behavior (https://github.com/latticexyz/mud/issues/1708)
|
57
62
|
const worldSignature = namespace === "" ? sig : `${namespace}__${sig}`;
|
58
63
|
return {
|
59
64
|
signature: worldSignature,
|
60
|
-
selector:
|
65
|
+
selector: toFunctionSelector(worldSignature),
|
61
66
|
systemId,
|
62
67
|
systemFunctionSignature: sig,
|
63
|
-
systemFunctionSelector:
|
68
|
+
systemFunctionSelector: toFunctionSelector(sig),
|
64
69
|
};
|
65
70
|
});
|
66
71
|
|
@@ -71,37 +76,29 @@ export function resolveConfig<config extends ConfigInput>({
|
|
71
76
|
allowAll: system.openAccess,
|
72
77
|
allowedAddresses: system.accessListAddresses as Hex[],
|
73
78
|
allowedSystemIds: system.accessListSystems.map((name) =>
|
74
|
-
resourceToHex({ type: "system", namespace, name: resolvedConfig.systems[name].name })
|
79
|
+
resourceToHex({ type: "system", namespace, name: resolvedConfig.systems[name].name }),
|
75
80
|
),
|
76
|
-
|
77
|
-
bytecode: contractData.bytecode,
|
81
|
+
prepareDeploy: createPrepareDeploy(contractData.bytecode, contractData.placeholders),
|
78
82
|
deployedBytecodeSize: contractData.deployedBytecodeSize,
|
79
83
|
abi: contractData.abi,
|
80
84
|
functions: systemFunctions,
|
81
85
|
};
|
82
86
|
});
|
83
87
|
|
84
|
-
//
|
85
|
-
// TODO:
|
86
|
-
const
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
}
|
96
|
-
|
97
|
-
|
98
|
-
return {
|
99
|
-
...system,
|
100
|
-
allowedAddresses: Array.from(
|
101
|
-
new Set([...allowedAddresses, ...allowedSystemAddresses].map((addr) => getAddress(addr)))
|
102
|
-
),
|
103
|
-
};
|
104
|
-
});
|
88
|
+
// Check for overlapping system IDs (since names get truncated when turning into IDs)
|
89
|
+
// TODO: move this into the world config resolve step once it resolves system IDs
|
90
|
+
const systemsById = groupBy(systems, (system) => system.systemId);
|
91
|
+
const overlappingSystems = Array.from(systemsById.values())
|
92
|
+
.filter((matches) => matches.length > 1)
|
93
|
+
.flat();
|
94
|
+
if (overlappingSystems.length) {
|
95
|
+
const names = overlappingSystems.map((system) => system.name);
|
96
|
+
throw new Error(
|
97
|
+
`Found systems with overlapping system ID: ${names.join(
|
98
|
+
", ",
|
99
|
+
)}.\n\nSystem IDs are generated from the first 16 bytes of the name, so you may need to rename them to avoid the overlap.`,
|
100
|
+
);
|
101
|
+
}
|
105
102
|
|
106
103
|
// ugh (https://github.com/latticexyz/mud/issues/1668)
|
107
104
|
const resolveContext = {
|
@@ -113,16 +110,16 @@ export function resolveConfig<config extends ConfigInput>({
|
|
113
110
|
type: table.offchainOnly ? "offchainTable" : "table",
|
114
111
|
namespace: config.namespace,
|
115
112
|
name: table.name,
|
116
|
-
})
|
113
|
+
}),
|
117
114
|
),
|
118
|
-
])
|
115
|
+
]),
|
119
116
|
),
|
120
117
|
};
|
121
118
|
|
122
|
-
const modules = config.modules.map((mod) => {
|
119
|
+
const modules = config.modules.map((mod): Module => {
|
123
120
|
const contractData =
|
124
121
|
defaultModuleContracts.find((defaultMod) => defaultMod.name === mod.name) ??
|
125
|
-
getContractData(mod.name, forgeOutDir);
|
122
|
+
getContractData(`${mod.name}.sol`, mod.name, forgeOutDir);
|
126
123
|
const installArgs = mod.args
|
127
124
|
.map((arg) => resolveWithContext(arg, resolveContext))
|
128
125
|
.map((arg) => {
|
@@ -136,8 +133,7 @@ export function resolveConfig<config extends ConfigInput>({
|
|
136
133
|
name: mod.name,
|
137
134
|
installAsRoot: mod.root,
|
138
135
|
installData: installArgs.length === 0 ? "0x" : installArgs[0],
|
139
|
-
|
140
|
-
bytecode: contractData.bytecode,
|
136
|
+
prepareDeploy: createPrepareDeploy(contractData.bytecode, contractData.placeholders),
|
141
137
|
deployedBytecodeSize: contractData.deployedBytecodeSize,
|
142
138
|
abi: contractData.abi,
|
143
139
|
};
|
@@ -145,7 +141,8 @@ export function resolveConfig<config extends ConfigInput>({
|
|
145
141
|
|
146
142
|
return {
|
147
143
|
tables,
|
148
|
-
systems
|
144
|
+
systems,
|
149
145
|
modules,
|
146
|
+
libraries,
|
150
147
|
};
|
151
148
|
}
|
package/src/mud.ts
CHANGED
@@ -26,7 +26,7 @@ async function run() {
|
|
26
26
|
console.error(chalk.red(msg));
|
27
27
|
if (msg.includes("Missing required argument")) {
|
28
28
|
console.log(
|
29
|
-
chalk.yellow(`Run 'pnpm mud ${process.argv[2]} --help' for a list of available and required arguments.`)
|
29
|
+
chalk.yellow(`Run 'pnpm mud ${process.argv[2]} --help' for a list of available and required arguments.`),
|
30
30
|
);
|
31
31
|
}
|
32
32
|
console.log("");
|
package/src/mudPackages.ts
CHANGED
@@ -13,7 +13,7 @@ function parseEnv(): z.infer<typeof envSchema> {
|
|
13
13
|
});
|
14
14
|
} catch (error) {
|
15
15
|
if (error instanceof ZodError) {
|
16
|
-
const {
|
16
|
+
const { ...invalidEnvVars } = error.format();
|
17
17
|
console.error(`\nMissing or invalid environment variables:\n\n ${Object.keys(invalidEnvVars).join("\n ")}\n`);
|
18
18
|
process.exit(1);
|
19
19
|
}
|