@latticexyz/cli 2.0.0-next.10 → 2.0.0-next.12
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/index.js +0 -1
- package/dist/mud.js +23 -13
- package/dist/mud.js.map +1 -1
- package/package.json +17 -13
- package/src/commands/deploy.ts +7 -30
- package/src/commands/dev-contracts.ts +74 -138
- package/src/commands/set-version.ts +19 -60
- package/src/commands/test.ts +30 -36
- package/src/commands/trace.ts +7 -5
- package/src/common.ts +1 -0
- package/src/debug.ts +3 -0
- package/src/deploy/assertNamespaceOwner.ts +42 -0
- package/src/deploy/common.ts +72 -0
- package/src/deploy/configToTables.ts +68 -0
- package/src/deploy/create2/README.md +9 -0
- package/src/deploy/create2/deployment.json +7 -0
- package/src/deploy/debug.ts +3 -0
- package/src/deploy/deploy.ts +108 -0
- package/src/deploy/deployWorld.ts +33 -0
- package/src/deploy/ensureContract.ts +49 -0
- package/src/deploy/ensureContractsDeployed.ts +25 -0
- package/src/deploy/ensureDeployer.ts +36 -0
- package/src/deploy/ensureFunctions.ts +86 -0
- package/src/deploy/ensureModules.ts +72 -0
- package/src/deploy/ensureSystems.ts +161 -0
- package/src/deploy/ensureTables.ts +65 -0
- package/src/deploy/ensureWorldFactory.ts +34 -0
- package/src/deploy/getFunctions.ts +58 -0
- package/src/deploy/getResourceAccess.ts +51 -0
- package/src/deploy/getResourceIds.ts +31 -0
- package/src/deploy/getSystems.ts +48 -0
- package/src/deploy/getTableValue.ts +30 -0
- package/src/deploy/getTables.ts +59 -0
- package/src/deploy/getWorldDeploy.ts +39 -0
- package/src/deploy/logsToWorldDeploy.ts +49 -0
- package/src/deploy/resolveConfig.ts +154 -0
- package/src/deploy/resourceLabel.ts +3 -0
- package/src/index.ts +1 -1
- package/src/mudPackages.ts +24 -0
- package/src/runDeploy.ts +128 -0
- package/src/utils/modules/constants.ts +1 -2
- package/src/utils/utils/getContractData.ts +2 -5
- package/dist/chunk-TW3YGZ4D.js +0 -11
- package/dist/chunk-TW3YGZ4D.js.map +0 -1
- package/src/utils/deploy.ts +0 -254
- package/src/utils/deployHandler.ts +0 -93
- package/src/utils/modules/getInstallModuleCallData.ts +0 -27
- package/src/utils/modules/getUserModules.ts +0 -5
- package/src/utils/modules/types.ts +0 -14
- package/src/utils/systems/getGrantAccessCallData.ts +0 -29
- package/src/utils/systems/getRegisterFunctionSelectorsCallData.ts +0 -57
- package/src/utils/systems/getRegisterSystemCallData.ts +0 -17
- package/src/utils/systems/types.ts +0 -9
- package/src/utils/systems/utils.ts +0 -42
- package/src/utils/tables/getRegisterTableCallData.ts +0 -49
- package/src/utils/tables/getTableIds.ts +0 -18
- package/src/utils/tables/types.ts +0 -12
- package/src/utils/utils/confirmNonce.ts +0 -24
- package/src/utils/utils/deployContract.ts +0 -33
- package/src/utils/utils/fastTxExecute.ts +0 -56
- package/src/utils/utils/getChainId.ts +0 -10
- package/src/utils/utils/setInternalFeePerGas.ts +0 -49
- package/src/utils/utils/types.ts +0 -21
- package/src/utils/world.ts +0 -28
package/src/utils/deploy.ts
DELETED
@@ -1,254 +0,0 @@
|
|
1
|
-
import chalk from "chalk";
|
2
|
-
import path from "path";
|
3
|
-
import { ethers } from "ethers";
|
4
|
-
import { getOutDirectory, cast, getSrcDirectory, getRemappings } from "@latticexyz/common/foundry";
|
5
|
-
import { StoreConfig } from "@latticexyz/store";
|
6
|
-
import { WorldConfig, resolveWorldConfig } from "@latticexyz/world";
|
7
|
-
import { deployWorldContract } from "./world";
|
8
|
-
import IBaseWorldAbi from "@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json" assert { type: "json" };
|
9
|
-
import CoreModuleData from "@latticexyz/world/out/CoreModule.sol/CoreModule.json" assert { type: "json" };
|
10
|
-
import { defaultModuleContracts } from "./modules/constants";
|
11
|
-
import { getInstallModuleCallData } from "./modules/getInstallModuleCallData";
|
12
|
-
import { getUserModules } from "./modules/getUserModules";
|
13
|
-
import { getGrantAccessCallData } from "./systems/getGrantAccessCallData";
|
14
|
-
import { getRegisterFunctionSelectorsCallData } from "./systems/getRegisterFunctionSelectorsCallData";
|
15
|
-
import { getRegisterSystemCallData } from "./systems/getRegisterSystemCallData";
|
16
|
-
import { getRegisterTableCallData } from "./tables/getRegisterTableCallData";
|
17
|
-
import { getTableIds } from "./tables/getTableIds";
|
18
|
-
import { confirmNonce } from "./utils/confirmNonce";
|
19
|
-
import { deployContract } from "./utils/deployContract";
|
20
|
-
import { fastTxExecute } from "./utils/fastTxExecute";
|
21
|
-
import { getContractData } from "./utils/getContractData";
|
22
|
-
import { postDeploy } from "./utils/postDeploy";
|
23
|
-
import { setInternalFeePerGas } from "./utils/setInternalFeePerGas";
|
24
|
-
import { ContractCode } from "./utils/types";
|
25
|
-
import { resourceIdToHex } from "@latticexyz/common";
|
26
|
-
|
27
|
-
export interface DeployConfig {
|
28
|
-
profile?: string;
|
29
|
-
rpc: string;
|
30
|
-
privateKey: string;
|
31
|
-
priorityFeeMultiplier: number;
|
32
|
-
debug?: boolean;
|
33
|
-
worldAddress?: string;
|
34
|
-
disableTxWait: boolean;
|
35
|
-
pollInterval: number;
|
36
|
-
}
|
37
|
-
|
38
|
-
export interface DeploymentInfo {
|
39
|
-
blockNumber: number;
|
40
|
-
worldAddress: string;
|
41
|
-
}
|
42
|
-
|
43
|
-
export async function deploy(
|
44
|
-
mudConfig: StoreConfig & WorldConfig,
|
45
|
-
existingContractNames: string[],
|
46
|
-
deployConfig: DeployConfig
|
47
|
-
): Promise<DeploymentInfo> {
|
48
|
-
const startTime = Date.now();
|
49
|
-
const { profile, rpc, privateKey, priorityFeeMultiplier, debug, worldAddress, disableTxWait, pollInterval } =
|
50
|
-
deployConfig;
|
51
|
-
const resolvedConfig = resolveWorldConfig(mudConfig, existingContractNames);
|
52
|
-
const forgeOutDirectory = await getOutDirectory(profile);
|
53
|
-
const remappings = await getRemappings(profile);
|
54
|
-
const outputBaseDirectory = path.join(await getSrcDirectory(profile), mudConfig.codegenDirectory);
|
55
|
-
|
56
|
-
// Set up signer for deployment
|
57
|
-
const provider = new ethers.providers.StaticJsonRpcProvider(rpc);
|
58
|
-
provider.pollingInterval = pollInterval;
|
59
|
-
const signer = new ethers.Wallet(privateKey, provider);
|
60
|
-
console.log("Deploying from", signer.address);
|
61
|
-
|
62
|
-
let nonce = await signer.getTransactionCount();
|
63
|
-
console.log("Initial nonce", nonce);
|
64
|
-
|
65
|
-
const txParams = await setInternalFeePerGas(signer, priorityFeeMultiplier);
|
66
|
-
|
67
|
-
const txConfig = {
|
68
|
-
...txParams,
|
69
|
-
signer,
|
70
|
-
debug: Boolean(debug),
|
71
|
-
disableTxWait,
|
72
|
-
confirmations: disableTxWait ? 0 : 1,
|
73
|
-
};
|
74
|
-
|
75
|
-
// Get block number before deploying
|
76
|
-
const blockNumber = Number(await cast(["block-number", "--rpc-url", rpc], { profile }));
|
77
|
-
console.log("Start deployment at block", blockNumber);
|
78
|
-
|
79
|
-
// Deploy the World contract. Non-blocking.
|
80
|
-
const worldPromise: Promise<string> = worldAddress
|
81
|
-
? Promise.resolve(worldAddress)
|
82
|
-
: deployWorldContract({
|
83
|
-
...txConfig,
|
84
|
-
nonce: nonce++,
|
85
|
-
worldContractName: mudConfig.worldContractName,
|
86
|
-
forgeOutDirectory,
|
87
|
-
});
|
88
|
-
|
89
|
-
// Filters any default modules from config
|
90
|
-
const userModules = getUserModules(defaultModuleContracts, mudConfig.modules);
|
91
|
-
const userModuleContracts = Object.keys(userModules).map((name) => {
|
92
|
-
const { abi, bytecode } = getContractData(name, forgeOutDirectory);
|
93
|
-
return {
|
94
|
-
name,
|
95
|
-
abi,
|
96
|
-
bytecode,
|
97
|
-
} as ContractCode;
|
98
|
-
});
|
99
|
-
|
100
|
-
const systemContracts = Object.keys(resolvedConfig.systems).map((name) => {
|
101
|
-
const { abi, bytecode } = getContractData(name, forgeOutDirectory);
|
102
|
-
return {
|
103
|
-
name,
|
104
|
-
abi,
|
105
|
-
bytecode,
|
106
|
-
} as ContractCode;
|
107
|
-
});
|
108
|
-
|
109
|
-
const contracts: ContractCode[] = [
|
110
|
-
{
|
111
|
-
name: "CoreModule",
|
112
|
-
abi: CoreModuleData.abi,
|
113
|
-
bytecode: CoreModuleData.bytecode,
|
114
|
-
},
|
115
|
-
...defaultModuleContracts,
|
116
|
-
...userModuleContracts,
|
117
|
-
...systemContracts,
|
118
|
-
];
|
119
|
-
|
120
|
-
// Deploy the System and Module contracts
|
121
|
-
const deployedContracts = contracts.reduce<Record<string, Promise<string>>>((acc, contract) => {
|
122
|
-
acc[contract.name] = deployContract({
|
123
|
-
...txConfig,
|
124
|
-
nonce: nonce++,
|
125
|
-
contract,
|
126
|
-
});
|
127
|
-
return acc;
|
128
|
-
}, {});
|
129
|
-
|
130
|
-
// Wait for world to be deployed
|
131
|
-
const deployedWorldAddress = await worldPromise;
|
132
|
-
const worldContract = new ethers.Contract(deployedWorldAddress, IBaseWorldAbi);
|
133
|
-
|
134
|
-
// If an existing World is passed assume its coreModule is already installed - blocking to install if not
|
135
|
-
if (!worldAddress) {
|
136
|
-
console.log(chalk.blue("Installing CoreModule"));
|
137
|
-
await fastTxExecute({
|
138
|
-
...txConfig,
|
139
|
-
nonce: nonce++,
|
140
|
-
contract: worldContract,
|
141
|
-
func: "initialize",
|
142
|
-
args: [await deployedContracts["CoreModule"]],
|
143
|
-
});
|
144
|
-
console.log(chalk.green("Installed CoreModule"));
|
145
|
-
}
|
146
|
-
|
147
|
-
if (mudConfig.namespace) {
|
148
|
-
console.log(chalk.blue("Registering Namespace"));
|
149
|
-
await fastTxExecute({
|
150
|
-
...txConfig,
|
151
|
-
nonce: nonce++,
|
152
|
-
contract: worldContract,
|
153
|
-
func: "registerNamespace",
|
154
|
-
args: [resourceIdToHex({ type: "namespace", namespace: mudConfig.namespace, name: "" })],
|
155
|
-
});
|
156
|
-
console.log(chalk.green("Namespace registered"));
|
157
|
-
}
|
158
|
-
|
159
|
-
const tableIds = getTableIds(mudConfig);
|
160
|
-
|
161
|
-
const registerTableCalls = Object.values(mudConfig.tables).map((table) =>
|
162
|
-
getRegisterTableCallData(table, mudConfig, outputBaseDirectory, remappings)
|
163
|
-
);
|
164
|
-
|
165
|
-
console.log(chalk.blue("Registering tables"));
|
166
|
-
await Promise.all(
|
167
|
-
registerTableCalls.map((call) =>
|
168
|
-
fastTxExecute({
|
169
|
-
...txConfig,
|
170
|
-
nonce: nonce++,
|
171
|
-
contract: worldContract,
|
172
|
-
...call,
|
173
|
-
})
|
174
|
-
)
|
175
|
-
);
|
176
|
-
console.log(chalk.green(`Tables registered`));
|
177
|
-
|
178
|
-
console.log(chalk.blue("Registering Systems and Functions"));
|
179
|
-
const systemCalls = await Promise.all(
|
180
|
-
Object.entries(resolvedConfig.systems).map(([systemKey, system]) =>
|
181
|
-
getRegisterSystemCallData({
|
182
|
-
systemContracts: deployedContracts,
|
183
|
-
systemKey,
|
184
|
-
system,
|
185
|
-
namespace: mudConfig.namespace,
|
186
|
-
})
|
187
|
-
)
|
188
|
-
);
|
189
|
-
const functionCalls = Object.entries(resolvedConfig.systems).flatMap(([systemKey, system]) =>
|
190
|
-
getRegisterFunctionSelectorsCallData({
|
191
|
-
systemContractName: systemKey,
|
192
|
-
system,
|
193
|
-
namespace: mudConfig.namespace,
|
194
|
-
forgeOutDirectory,
|
195
|
-
})
|
196
|
-
);
|
197
|
-
await Promise.all(
|
198
|
-
[...systemCalls, ...functionCalls].map((call) =>
|
199
|
-
fastTxExecute({
|
200
|
-
...txConfig,
|
201
|
-
nonce: nonce++,
|
202
|
-
contract: worldContract,
|
203
|
-
...call,
|
204
|
-
})
|
205
|
-
)
|
206
|
-
);
|
207
|
-
console.log(chalk.green(`Systems and Functions registered`));
|
208
|
-
|
209
|
-
// Wait for System access to be granted before installing modules
|
210
|
-
const grantCalls = await getGrantAccessCallData({
|
211
|
-
systems: Object.values(resolvedConfig.systems),
|
212
|
-
systemContracts: deployedContracts,
|
213
|
-
namespace: mudConfig.namespace,
|
214
|
-
});
|
215
|
-
|
216
|
-
console.log(chalk.blue("Granting Access"));
|
217
|
-
await Promise.all(
|
218
|
-
grantCalls.map((call) =>
|
219
|
-
fastTxExecute({
|
220
|
-
...txConfig,
|
221
|
-
nonce: nonce++,
|
222
|
-
contract: worldContract,
|
223
|
-
...call,
|
224
|
-
})
|
225
|
-
)
|
226
|
-
);
|
227
|
-
console.log(chalk.green(`Access granted`));
|
228
|
-
|
229
|
-
const moduleCalls = await Promise.all(
|
230
|
-
mudConfig.modules.map((m) => getInstallModuleCallData(deployedContracts, m, tableIds))
|
231
|
-
);
|
232
|
-
|
233
|
-
console.log(chalk.blue("Installing User Modules"));
|
234
|
-
await Promise.all(
|
235
|
-
moduleCalls.map((call) =>
|
236
|
-
fastTxExecute({
|
237
|
-
...txConfig,
|
238
|
-
nonce: nonce++,
|
239
|
-
contract: worldContract,
|
240
|
-
...call,
|
241
|
-
})
|
242
|
-
)
|
243
|
-
);
|
244
|
-
console.log(chalk.green(`User Modules Installed`));
|
245
|
-
|
246
|
-
// Double check that all transactions have been included by confirming the current nonce is the expected nonce
|
247
|
-
await confirmNonce(signer, nonce, pollInterval);
|
248
|
-
|
249
|
-
await postDeploy(mudConfig.postDeployScript, deployedWorldAddress, rpc, profile);
|
250
|
-
|
251
|
-
console.log(chalk.green("Deployment completed in", (Date.now() - startTime) / 1000, "seconds"));
|
252
|
-
|
253
|
-
return { worldAddress: deployedWorldAddress, blockNumber };
|
254
|
-
}
|
@@ -1,93 +0,0 @@
|
|
1
|
-
import chalk from "chalk";
|
2
|
-
import path from "path";
|
3
|
-
import { MUDError } from "@latticexyz/common/errors";
|
4
|
-
import { loadConfig } from "@latticexyz/config/node";
|
5
|
-
import { StoreConfig } from "@latticexyz/store";
|
6
|
-
import { WorldConfig } from "@latticexyz/world";
|
7
|
-
import { deploy } from "../utils/deploy";
|
8
|
-
import { forge, getRpcUrl, getSrcDirectory } from "@latticexyz/common/foundry";
|
9
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
10
|
-
import { getExistingContracts } from "./getExistingContracts";
|
11
|
-
import { execa } from "execa";
|
12
|
-
import { getChainId } from "./utils/getChainId";
|
13
|
-
|
14
|
-
export type DeployOptions = {
|
15
|
-
configPath?: string;
|
16
|
-
printConfig?: boolean;
|
17
|
-
profile?: string;
|
18
|
-
priorityFeeMultiplier: number;
|
19
|
-
clean?: boolean;
|
20
|
-
debug?: boolean;
|
21
|
-
saveDeployment: boolean;
|
22
|
-
rpc?: string;
|
23
|
-
worldAddress?: string;
|
24
|
-
srcDir?: string;
|
25
|
-
disableTxWait: boolean;
|
26
|
-
pollInterval: number;
|
27
|
-
skipBuild?: boolean;
|
28
|
-
};
|
29
|
-
|
30
|
-
export async function deployHandler(args: DeployOptions) {
|
31
|
-
args.profile ??= process.env.FOUNDRY_PROFILE;
|
32
|
-
const { configPath, printConfig, profile, clean, skipBuild } = args;
|
33
|
-
|
34
|
-
const rpc = args.rpc ?? (await getRpcUrl(profile));
|
35
|
-
console.log(
|
36
|
-
chalk.bgBlue(
|
37
|
-
chalk.whiteBright(`\n Deploying MUD contracts${profile ? " with profile " + profile : ""} to RPC ${rpc} \n`)
|
38
|
-
)
|
39
|
-
);
|
40
|
-
|
41
|
-
if (clean) {
|
42
|
-
await forge(["clean"], { profile });
|
43
|
-
}
|
44
|
-
|
45
|
-
// Run forge build
|
46
|
-
if (!skipBuild) {
|
47
|
-
await forge(["build", "--skip", "test", "script"], { profile });
|
48
|
-
await execa("mud", ["abi-ts"], { stdio: "inherit" });
|
49
|
-
}
|
50
|
-
|
51
|
-
// Get a list of all contract names
|
52
|
-
const srcDir = args?.srcDir ?? (await getSrcDirectory());
|
53
|
-
const existingContractNames = getExistingContracts(srcDir).map(({ basename }) => basename);
|
54
|
-
|
55
|
-
// Load the config
|
56
|
-
const mudConfig = (await loadConfig(configPath)) as StoreConfig & WorldConfig;
|
57
|
-
|
58
|
-
if (printConfig) console.log(chalk.green("\nResolved config:\n"), JSON.stringify(mudConfig, null, 2));
|
59
|
-
|
60
|
-
const privateKey = process.env.PRIVATE_KEY;
|
61
|
-
if (!privateKey)
|
62
|
-
throw new MUDError(
|
63
|
-
`Missing PRIVATE_KEY environment variable.
|
64
|
-
Run 'echo "PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" > .env'
|
65
|
-
in your contracts directory to use the default anvil private key.`
|
66
|
-
);
|
67
|
-
const deploymentInfo = await deploy(mudConfig, existingContractNames, { ...args, rpc, privateKey });
|
68
|
-
|
69
|
-
if (args.saveDeployment) {
|
70
|
-
// Write deployment result to file (latest and timestamp)
|
71
|
-
const chainId = await getChainId(rpc);
|
72
|
-
const outputDir = path.join(mudConfig.deploysDirectory, chainId.toString());
|
73
|
-
mkdirSync(outputDir, { recursive: true });
|
74
|
-
writeFileSync(path.join(outputDir, "latest.json"), JSON.stringify(deploymentInfo, null, 2));
|
75
|
-
writeFileSync(path.join(outputDir, Date.now() + ".json"), JSON.stringify(deploymentInfo, null, 2));
|
76
|
-
|
77
|
-
const localChains = [1337, 31337];
|
78
|
-
const deploys = existsSync(mudConfig.worldsFile) ? JSON.parse(readFileSync(mudConfig.worldsFile, "utf-8")) : {};
|
79
|
-
deploys[chainId] = {
|
80
|
-
address: deploymentInfo.worldAddress,
|
81
|
-
// We expect the worlds file to be committed and since local deployments are often a consistent address but different block number, we'll ignore the block number.
|
82
|
-
blockNumber: localChains.includes(chainId) ? undefined : deploymentInfo.blockNumber,
|
83
|
-
};
|
84
|
-
writeFileSync(mudConfig.worldsFile, JSON.stringify(deploys, null, 2));
|
85
|
-
|
86
|
-
console.log(
|
87
|
-
chalk.bgGreen(chalk.whiteBright(`\n Deployment result (written to ${mudConfig.worldsFile} and ${outputDir}): \n`))
|
88
|
-
);
|
89
|
-
}
|
90
|
-
|
91
|
-
console.log(deploymentInfo);
|
92
|
-
return deploymentInfo;
|
93
|
-
}
|
@@ -1,27 +0,0 @@
|
|
1
|
-
import { defaultAbiCoder } from "ethers/lib/utils.js";
|
2
|
-
import { resolveWithContext } from "@latticexyz/config";
|
3
|
-
import { Module } from "./types";
|
4
|
-
import { CallData } from "../utils/types";
|
5
|
-
import { TableIds } from "../tables/types";
|
6
|
-
|
7
|
-
export async function getInstallModuleCallData(
|
8
|
-
moduleContracts: Record<string, Promise<string>>,
|
9
|
-
module: Module,
|
10
|
-
tableIds: TableIds
|
11
|
-
): Promise<CallData> {
|
12
|
-
const moduleAddress = await moduleContracts[module.name];
|
13
|
-
if (!moduleAddress) throw new Error(`Module ${module.name} not found`);
|
14
|
-
// Resolve arguments
|
15
|
-
const resolvedArgs = module.args.map((arg) =>
|
16
|
-
resolveWithContext(arg, {
|
17
|
-
tableIds,
|
18
|
-
})
|
19
|
-
);
|
20
|
-
const values = resolvedArgs.map((arg) => arg.value);
|
21
|
-
const types = resolvedArgs.map((arg) => arg.type);
|
22
|
-
|
23
|
-
return {
|
24
|
-
func: module.root ? "installRootModule" : "installModule",
|
25
|
-
args: [moduleAddress, defaultAbiCoder.encode(types, values)],
|
26
|
-
};
|
27
|
-
}
|
@@ -1,29 +0,0 @@
|
|
1
|
-
import { System } from "./types";
|
2
|
-
import { CallData } from "../utils/types";
|
3
|
-
import { resourceIdToHex } from "@latticexyz/common";
|
4
|
-
|
5
|
-
export async function getGrantAccessCallData(input: {
|
6
|
-
systems: System[];
|
7
|
-
systemContracts: Record<string, Promise<string>>;
|
8
|
-
namespace: string;
|
9
|
-
}): Promise<CallData[]> {
|
10
|
-
const { systems, namespace, systemContracts } = input;
|
11
|
-
const calls: CallData[] = [];
|
12
|
-
for (const { name, accessListAddresses, accessListSystems } of systems) {
|
13
|
-
// Grant access to addresses
|
14
|
-
accessListAddresses.map(async (address) => calls.push(getGrantSystemAccessCallData(name, namespace, address)));
|
15
|
-
|
16
|
-
// Grant access to other systems
|
17
|
-
accessListSystems.map(async (granteeSystem) =>
|
18
|
-
calls.push(getGrantSystemAccessCallData(name, namespace, await systemContracts[granteeSystem]))
|
19
|
-
);
|
20
|
-
}
|
21
|
-
return calls;
|
22
|
-
}
|
23
|
-
|
24
|
-
function getGrantSystemAccessCallData(name: string, namespace: string, address: string): CallData {
|
25
|
-
return {
|
26
|
-
func: "grantAccess",
|
27
|
-
args: [resourceIdToHex({ type: "system", namespace, name }), address],
|
28
|
-
};
|
29
|
-
}
|
@@ -1,57 +0,0 @@
|
|
1
|
-
import { resourceIdToHex } from "@latticexyz/common";
|
2
|
-
import { System } from "./types";
|
3
|
-
import { loadFunctionSignatures, toFunctionSelector } from "./utils";
|
4
|
-
import { CallData } from "../utils/types";
|
5
|
-
|
6
|
-
export function getRegisterFunctionSelectorsCallData(input: {
|
7
|
-
systemContractName: string;
|
8
|
-
system: System;
|
9
|
-
namespace: string;
|
10
|
-
forgeOutDirectory: string;
|
11
|
-
}): CallData[] {
|
12
|
-
// Register system at route
|
13
|
-
const callData: CallData[] = [];
|
14
|
-
const { systemContractName, namespace, forgeOutDirectory, system } = input;
|
15
|
-
|
16
|
-
if (system.registerFunctionSelectors) {
|
17
|
-
const baseSystemFunctionSignatures = loadFunctionSignatures("System", forgeOutDirectory);
|
18
|
-
const systemFunctionSignatures = loadFunctionSignatures(systemContractName, forgeOutDirectory).filter(
|
19
|
-
(functionSignature) =>
|
20
|
-
systemContractName === "System" || !baseSystemFunctionSignatures.includes(functionSignature)
|
21
|
-
);
|
22
|
-
const isRoot = namespace === "";
|
23
|
-
for (const systemFunctionSignature of systemFunctionSignatures) {
|
24
|
-
callData.push(
|
25
|
-
getRegisterFunctionSelectorCallData({
|
26
|
-
namespace,
|
27
|
-
name: system.name,
|
28
|
-
systemFunctionSignature,
|
29
|
-
isRoot,
|
30
|
-
})
|
31
|
-
);
|
32
|
-
}
|
33
|
-
}
|
34
|
-
return callData;
|
35
|
-
}
|
36
|
-
|
37
|
-
function getRegisterFunctionSelectorCallData(input: {
|
38
|
-
namespace: string;
|
39
|
-
name: string;
|
40
|
-
systemFunctionSignature: string;
|
41
|
-
isRoot: boolean;
|
42
|
-
}): CallData {
|
43
|
-
const { namespace, name, systemFunctionSignature, isRoot } = input;
|
44
|
-
|
45
|
-
if (isRoot) {
|
46
|
-
const functionSelector = toFunctionSelector(systemFunctionSignature);
|
47
|
-
return {
|
48
|
-
func: "registerRootFunctionSelector",
|
49
|
-
args: [resourceIdToHex({ type: "system", namespace, name }), systemFunctionSignature, functionSelector],
|
50
|
-
};
|
51
|
-
} else {
|
52
|
-
return {
|
53
|
-
func: "registerFunctionSelector",
|
54
|
-
args: [resourceIdToHex({ type: "system", namespace, name }), systemFunctionSignature],
|
55
|
-
};
|
56
|
-
}
|
57
|
-
}
|
@@ -1,17 +0,0 @@
|
|
1
|
-
import { resourceIdToHex } from "@latticexyz/common";
|
2
|
-
import { System } from "./types";
|
3
|
-
import { CallData } from "../utils/types";
|
4
|
-
|
5
|
-
export async function getRegisterSystemCallData(input: {
|
6
|
-
systemContracts: Record<string, Promise<string>>;
|
7
|
-
systemKey: string;
|
8
|
-
system: System;
|
9
|
-
namespace: string;
|
10
|
-
}): Promise<CallData> {
|
11
|
-
const { namespace, systemContracts, systemKey, system } = input;
|
12
|
-
const systemAddress = await systemContracts[systemKey];
|
13
|
-
return {
|
14
|
-
func: "registerSystem",
|
15
|
-
args: [resourceIdToHex({ type: "system", namespace, name: system.name }), systemAddress, system.openAccess],
|
16
|
-
};
|
17
|
-
}
|
@@ -1,42 +0,0 @@
|
|
1
|
-
import { ethers } from "ethers";
|
2
|
-
import { ParamType } from "ethers/lib/utils.js";
|
3
|
-
import { getContractData } from "../utils/getContractData";
|
4
|
-
|
5
|
-
export function loadFunctionSignatures(contractName: string, forgeOutDirectory: string): string[] {
|
6
|
-
const { abi } = getContractData(contractName, forgeOutDirectory);
|
7
|
-
|
8
|
-
return abi
|
9
|
-
.filter((item) => ["fallback", "function"].includes(item.type))
|
10
|
-
.map((item) => {
|
11
|
-
return `${item.name}${parseComponents(item.inputs)}`;
|
12
|
-
});
|
13
|
-
}
|
14
|
-
|
15
|
-
// TODO: move this to utils as soon as utils are usable inside cli
|
16
|
-
// (see https://github.com/latticexyz/mud/issues/499)
|
17
|
-
export function toFunctionSelector(functionSignature: string): string {
|
18
|
-
return sigHash(functionSignature);
|
19
|
-
}
|
20
|
-
|
21
|
-
/**
|
22
|
-
* Recursively turn (nested) structs in signatures into tuples
|
23
|
-
*/
|
24
|
-
function parseComponents(params: ParamType[]): string {
|
25
|
-
const components = params.map((param) => {
|
26
|
-
const tupleMatch = param.type.match(/tuple(.*)/);
|
27
|
-
if (tupleMatch) {
|
28
|
-
// there can be arrays of tuples,
|
29
|
-
// `tupleMatch[1]` preserves the array brackets (or is empty string for non-arrays)
|
30
|
-
return parseComponents(param.components) + tupleMatch[1];
|
31
|
-
} else {
|
32
|
-
return param.type;
|
33
|
-
}
|
34
|
-
});
|
35
|
-
return `(${components})`;
|
36
|
-
}
|
37
|
-
|
38
|
-
// TODO: move this to utils as soon as utils are usable inside cli
|
39
|
-
// (see https://github.com/latticexyz/mud/issues/499)
|
40
|
-
function sigHash(signature: string) {
|
41
|
-
return ethers.utils.hexDataSlice(ethers.utils.keccak256(ethers.utils.toUtf8Bytes(signature)), 0, 4);
|
42
|
-
}
|
@@ -1,49 +0,0 @@
|
|
1
|
-
import { encodeSchema, getStaticByteLength } from "@latticexyz/schema-type/deprecated";
|
2
|
-
import { StoreConfig } from "@latticexyz/store";
|
3
|
-
import { resolveAbiOrUserType } from "@latticexyz/store/codegen";
|
4
|
-
import { resourceIdToHex } from "@latticexyz/common";
|
5
|
-
import { Table } from "./types";
|
6
|
-
import { fieldLayoutToHex } from "@latticexyz/protocol-parser";
|
7
|
-
import { CallData } from "../utils/types";
|
8
|
-
import { loadAndExtractUserTypes } from "@latticexyz/common/codegen";
|
9
|
-
|
10
|
-
export function getRegisterTableCallData(
|
11
|
-
table: Table,
|
12
|
-
storeConfig: StoreConfig,
|
13
|
-
outputBaseDirectory: string,
|
14
|
-
remappings: [string, string][]
|
15
|
-
): CallData {
|
16
|
-
const { name, valueSchema, keySchema } = table;
|
17
|
-
if (!name) throw Error("Table missing name");
|
18
|
-
|
19
|
-
const solidityUserTypes = loadAndExtractUserTypes(storeConfig.userTypes, outputBaseDirectory, remappings);
|
20
|
-
|
21
|
-
const schemaTypes = Object.values(valueSchema).map((abiOrUserType) => {
|
22
|
-
const { schemaType } = resolveAbiOrUserType(abiOrUserType, storeConfig, solidityUserTypes);
|
23
|
-
return schemaType;
|
24
|
-
});
|
25
|
-
|
26
|
-
const schemaTypeLengths = schemaTypes.map((schemaType) => getStaticByteLength(schemaType));
|
27
|
-
const fieldLayout = {
|
28
|
-
staticFieldLengths: schemaTypeLengths.filter((schemaTypeLength) => schemaTypeLength > 0),
|
29
|
-
numDynamicFields: schemaTypeLengths.filter((schemaTypeLength) => schemaTypeLength === 0).length,
|
30
|
-
};
|
31
|
-
|
32
|
-
const keyTypes = Object.values(keySchema).map((abiOrUserType) => {
|
33
|
-
const { schemaType } = resolveAbiOrUserType(abiOrUserType, storeConfig, solidityUserTypes);
|
34
|
-
return schemaType;
|
35
|
-
});
|
36
|
-
|
37
|
-
return {
|
38
|
-
func: "registerTable",
|
39
|
-
args: [
|
40
|
-
// TODO: add support for table namespaces (https://github.com/latticexyz/mud/issues/994)
|
41
|
-
resourceIdToHex({ type: table.offchainOnly ? "offchainTable" : "table", namespace: storeConfig.namespace, name }),
|
42
|
-
fieldLayoutToHex(fieldLayout),
|
43
|
-
encodeSchema(keyTypes),
|
44
|
-
encodeSchema(schemaTypes),
|
45
|
-
Object.keys(keySchema),
|
46
|
-
Object.keys(valueSchema),
|
47
|
-
],
|
48
|
-
};
|
49
|
-
}
|
@@ -1,18 +0,0 @@
|
|
1
|
-
import { StoreConfig } from "@latticexyz/store";
|
2
|
-
import { TableIds } from "./types";
|
3
|
-
import { resourceIdToHex } from "@latticexyz/common";
|
4
|
-
import { hexToBytes } from "viem";
|
5
|
-
|
6
|
-
export function getTableIds(storeConfig: StoreConfig): TableIds {
|
7
|
-
const tableIds: TableIds = {};
|
8
|
-
for (const [tableName, { name, offchainOnly }] of Object.entries(storeConfig.tables)) {
|
9
|
-
tableIds[tableName] = hexToBytes(
|
10
|
-
resourceIdToHex({
|
11
|
-
type: offchainOnly ? "offchainTable" : "table",
|
12
|
-
namespace: storeConfig.namespace,
|
13
|
-
name,
|
14
|
-
})
|
15
|
-
);
|
16
|
-
}
|
17
|
-
return tableIds;
|
18
|
-
}
|
@@ -1,12 +0,0 @@
|
|
1
|
-
export type Table = {
|
2
|
-
valueSchema: Record<string, string>;
|
3
|
-
keySchema: Record<string, string>;
|
4
|
-
directory: string;
|
5
|
-
tableIdArgument: boolean;
|
6
|
-
storeArgument: boolean;
|
7
|
-
offchainOnly: boolean;
|
8
|
-
name?: string | undefined;
|
9
|
-
dataStruct?: boolean | undefined;
|
10
|
-
};
|
11
|
-
|
12
|
-
export type TableIds = { [tableName: string]: Uint8Array };
|
@@ -1,24 +0,0 @@
|
|
1
|
-
import chalk from "chalk";
|
2
|
-
import { Wallet } from "ethers";
|
3
|
-
import { MUDError } from "@latticexyz/common/errors";
|
4
|
-
|
5
|
-
export async function confirmNonce(signer: Wallet, nonce: number, pollInterval: number): Promise<void> {
|
6
|
-
let remoteNonce = await signer.getTransactionCount();
|
7
|
-
let retryCount = 0;
|
8
|
-
const maxRetries = 100;
|
9
|
-
while (remoteNonce !== nonce && retryCount < maxRetries) {
|
10
|
-
console.log(
|
11
|
-
chalk.gray(
|
12
|
-
`Waiting for transactions to be included before executing postDeployScript (local nonce: ${nonce}, remote nonce: ${remoteNonce}, retry number ${retryCount}/${maxRetries})`
|
13
|
-
)
|
14
|
-
);
|
15
|
-
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
16
|
-
retryCount++;
|
17
|
-
remoteNonce = await signer.getTransactionCount();
|
18
|
-
}
|
19
|
-
if (remoteNonce !== nonce) {
|
20
|
-
throw new MUDError(
|
21
|
-
"Remote nonce doesn't match local nonce, indicating that not all deploy transactions were included."
|
22
|
-
);
|
23
|
-
}
|
24
|
-
}
|