@bgd-labs/cli 0.0.20 → 0.0.21
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 +317 -0
- package/dist/index.js.map +1 -0
- package/package.json +2 -2
package/dist/index.js
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import "dotenv/config";
|
|
5
|
+
import { Command as Command5 } from "@commander-js/extra-typings";
|
|
6
|
+
|
|
7
|
+
// package.json
|
|
8
|
+
var package_default = {
|
|
9
|
+
name: "@bgd-labs/cli",
|
|
10
|
+
version: "0.0.21",
|
|
11
|
+
main: "./dist/index.mjs",
|
|
12
|
+
sideEffects: false,
|
|
13
|
+
license: "MIT",
|
|
14
|
+
files: [
|
|
15
|
+
"dist/**"
|
|
16
|
+
],
|
|
17
|
+
type: "module",
|
|
18
|
+
bin: {
|
|
19
|
+
cli: "dist/index.js"
|
|
20
|
+
},
|
|
21
|
+
scripts: {
|
|
22
|
+
build: "tsup src/index.ts",
|
|
23
|
+
dev: "tsup src/index.ts --watch",
|
|
24
|
+
start: "node dist/index.js",
|
|
25
|
+
clean: "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
|
|
26
|
+
},
|
|
27
|
+
devDependencies: {
|
|
28
|
+
"@types/node": "catalog:",
|
|
29
|
+
tsup: "catalog:",
|
|
30
|
+
typescript: "catalog:"
|
|
31
|
+
},
|
|
32
|
+
publishConfig: {
|
|
33
|
+
access: "public"
|
|
34
|
+
},
|
|
35
|
+
dependencies: {
|
|
36
|
+
"@bgd-labs/aave-address-book": "^4.14.0",
|
|
37
|
+
"@bgd-labs/toolbox": "workspace:*",
|
|
38
|
+
"@commander-js/extra-typings": "^13.1.0",
|
|
39
|
+
"@inquirer/prompts": "^7.3.2",
|
|
40
|
+
dotenv: "^16.4.7",
|
|
41
|
+
viem: "catalog:"
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// src/tasks/code-diff.ts
|
|
46
|
+
import { Option } from "@commander-js/extra-typings";
|
|
47
|
+
import { diffCode, getSourceCode } from "@bgd-labs/toolbox";
|
|
48
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
49
|
+
function registerCodeDiff(program2) {
|
|
50
|
+
program2.command("codeDiff").description("generated the diff between any two addresses").addOption(new Option("--address1 <address>").makeOptionMandatory()).addOption(new Option("--chainId1 <number>").makeOptionMandatory()).addOption(new Option("--address2 <address>").makeOptionMandatory()).addOption(new Option("--chainId2 <number>").makeOptionMandatory()).addOption(new Option("-f, --flatten")).addOption(
|
|
51
|
+
new Option("-o, --output <format>").choices(["stdout", "file"]).default("stdout")
|
|
52
|
+
).addOption(new Option("-p, --path <path>").default("./diffs/code")).action(
|
|
53
|
+
async ({
|
|
54
|
+
address1,
|
|
55
|
+
address2,
|
|
56
|
+
chainId1,
|
|
57
|
+
chainId2,
|
|
58
|
+
flatten,
|
|
59
|
+
output,
|
|
60
|
+
path
|
|
61
|
+
}) => {
|
|
62
|
+
const sources = await Promise.all([
|
|
63
|
+
getSourceCode({
|
|
64
|
+
chainId: Number(chainId1),
|
|
65
|
+
address: address1,
|
|
66
|
+
apiKey: process.env.ETHERSCAN_API_KEY
|
|
67
|
+
}),
|
|
68
|
+
getSourceCode({
|
|
69
|
+
chainId: Number(chainId2),
|
|
70
|
+
address: address2,
|
|
71
|
+
apiKey: process.env.ETHERSCAN_API_KEY
|
|
72
|
+
})
|
|
73
|
+
]);
|
|
74
|
+
const diff = await diffCode(
|
|
75
|
+
sources[0].SourceCode,
|
|
76
|
+
sources[1].SourceCode
|
|
77
|
+
);
|
|
78
|
+
if (flatten || output === "stdout") {
|
|
79
|
+
const flat = Object.keys(diff).reduce((acc, key) => {
|
|
80
|
+
acc += diff[key];
|
|
81
|
+
return acc;
|
|
82
|
+
}, "");
|
|
83
|
+
if (output === "stdout") {
|
|
84
|
+
console.log(flat);
|
|
85
|
+
} else {
|
|
86
|
+
const filePath = `${path}/${chainId1}`;
|
|
87
|
+
mkdirSync(filePath, { recursive: true });
|
|
88
|
+
writeFileSync(`${filePath}/${address1}_${address2}.patch`, flat);
|
|
89
|
+
}
|
|
90
|
+
} else {
|
|
91
|
+
const filePath = `${path}/${chainId1}/${address1}_${address2}`;
|
|
92
|
+
mkdirSync(filePath, { recursive: true });
|
|
93
|
+
Object.keys(diff).map((file) => {
|
|
94
|
+
writeFileSync(`${filePath}/${file}.patch`, diff[file]);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/tasks/aave-vnet.ts
|
|
102
|
+
import { Option as Option2 } from "@commander-js/extra-typings";
|
|
103
|
+
import {
|
|
104
|
+
getNonFinalizedPayloads,
|
|
105
|
+
getPayloadsController,
|
|
106
|
+
makePayloadExecutableOnTestClient,
|
|
107
|
+
tenderly_createVnet
|
|
108
|
+
} from "@bgd-labs/toolbox";
|
|
109
|
+
import { checkbox, select, Separator } from "@inquirer/prompts";
|
|
110
|
+
import * as addresses from "@bgd-labs/aave-address-book";
|
|
111
|
+
function registerAaveVNet(program2) {
|
|
112
|
+
program2.command("aave-vnet").description("creates a tenderly virtual testnet and execute payloads").addOption(new Option2("-c,--chainId <number>").makeOptionMandatory()).addOption(
|
|
113
|
+
new Option2(
|
|
114
|
+
"-t, --tenderlyAccessToken <string>",
|
|
115
|
+
"defaults to env.TENDERLY_ACCESS_TOKEN"
|
|
116
|
+
)
|
|
117
|
+
).addOption(
|
|
118
|
+
new Option2(
|
|
119
|
+
"-a, --tenderlyAccountSlug <string>",
|
|
120
|
+
"defaults to env.TENDERLY_ACCOUNT_SLUG"
|
|
121
|
+
)
|
|
122
|
+
).addOption(
|
|
123
|
+
new Option2(
|
|
124
|
+
"-p, --tenderlyProjectSlug <string>",
|
|
125
|
+
"defaults to env.TENDERLY_PROJECT_SLUG"
|
|
126
|
+
)
|
|
127
|
+
).action(
|
|
128
|
+
async ({
|
|
129
|
+
chainId,
|
|
130
|
+
tenderlyAccessToken,
|
|
131
|
+
tenderlyAccountSlug,
|
|
132
|
+
tenderlyProjectSlug
|
|
133
|
+
}) => {
|
|
134
|
+
const vnet = await tenderly_createVnet(
|
|
135
|
+
{
|
|
136
|
+
baseChainId: Number(chainId),
|
|
137
|
+
forkChainId: 3030,
|
|
138
|
+
slug: `${Math.floor(Math.random() * 1e3)}acli-bgd-labs-vnet-${chainId}`,
|
|
139
|
+
displayName: "bgd-labs cli vnet"
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
accessToken: tenderlyAccessToken || process.env.TENDERLY_ACCESS_TOKEN,
|
|
143
|
+
accountSlug: tenderlyAccountSlug || process.env.TENDERLY_ACCOUNT_SLUG,
|
|
144
|
+
projectSlug: tenderlyProjectSlug || process.env.TENDERLY_PROJECT_SLUG
|
|
145
|
+
}
|
|
146
|
+
);
|
|
147
|
+
console.info("Virtual testnet created!");
|
|
148
|
+
console.info("RPC:", vnet.vnet.rpcs[0].url);
|
|
149
|
+
const controllerAddress = findPayloadsController(Number(chainId));
|
|
150
|
+
const controllerContract = getPayloadsController(
|
|
151
|
+
vnet.walletClient,
|
|
152
|
+
controllerAddress
|
|
153
|
+
);
|
|
154
|
+
while (true) {
|
|
155
|
+
const answer = await select({
|
|
156
|
+
message: "What do you want to do?",
|
|
157
|
+
choices: [
|
|
158
|
+
{
|
|
159
|
+
name: "Execute a registered payload",
|
|
160
|
+
value: 0 /* PAYLOAD_ID */
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
name: "Execute a deployed (but not registered) payload",
|
|
164
|
+
value: 1 /* PAYLOAD_ADDRESS */
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
name: "Execute a local payload.",
|
|
168
|
+
value: 2 /* PAYLOAD_ARTIFACT */
|
|
169
|
+
},
|
|
170
|
+
new Separator(),
|
|
171
|
+
{
|
|
172
|
+
name: "Exit (this will keep the vnet open - you can delete it via tenderly ui)",
|
|
173
|
+
value: 3 /* EXIT */
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
name: "Exit and delete",
|
|
177
|
+
value: 4 /* DELETE */
|
|
178
|
+
}
|
|
179
|
+
]
|
|
180
|
+
});
|
|
181
|
+
switch (answer) {
|
|
182
|
+
case 0 /* PAYLOAD_ID */:
|
|
183
|
+
const payloadIds = await getNonFinalizedPayloads(
|
|
184
|
+
vnet.testClient,
|
|
185
|
+
controllerAddress
|
|
186
|
+
);
|
|
187
|
+
const answer2 = await checkbox({
|
|
188
|
+
message: "Select the payloads you want to execute",
|
|
189
|
+
choices: payloadIds.map((id) => ({
|
|
190
|
+
name: String(id),
|
|
191
|
+
value: String(id)
|
|
192
|
+
}))
|
|
193
|
+
});
|
|
194
|
+
for (const id of answer2) {
|
|
195
|
+
await makePayloadExecutableOnTestClient(
|
|
196
|
+
vnet.testClient,
|
|
197
|
+
controllerAddress,
|
|
198
|
+
Number(id)
|
|
199
|
+
);
|
|
200
|
+
await controllerContract.write.executePayload([Number(id)]);
|
|
201
|
+
console.info(`Payload ${id} executed`);
|
|
202
|
+
}
|
|
203
|
+
break;
|
|
204
|
+
case 3 /* EXIT */:
|
|
205
|
+
process.exit(0);
|
|
206
|
+
case 4 /* DELETE */:
|
|
207
|
+
await vnet.delete();
|
|
208
|
+
console.info("Virtual testnet deleted!");
|
|
209
|
+
process.exit(0);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
function findPayloadsController(chainId) {
|
|
216
|
+
const key = Object.keys(addresses).find(
|
|
217
|
+
(key2) => addresses[key2].CHAIN_ID === chainId && addresses[key2].PAYLOADS_CONTROLLER
|
|
218
|
+
);
|
|
219
|
+
if (key)
|
|
220
|
+
return addresses[key].PAYLOADS_CONTROLLER;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// src/tasks/storage-diff.ts
|
|
224
|
+
import { Option as Option3 } from "@commander-js/extra-typings";
|
|
225
|
+
import {
|
|
226
|
+
diffFoundryStorageLayout,
|
|
227
|
+
foundry_getStorageLayout
|
|
228
|
+
} from "@bgd-labs/toolbox";
|
|
229
|
+
function registerStorageDiff(program2) {
|
|
230
|
+
program2.command("storageDiff").description("generated the storage diff between any two files").addOption(new Option3("--contract1 <Contract|path>").makeOptionMandatory()).addOption(new Option3("--contract2 <Contract|path>").makeOptionMandatory()).action(async ({ contract1, contract2 }) => {
|
|
231
|
+
const storage1 = foundry_getStorageLayout(contract1);
|
|
232
|
+
const storage2 = foundry_getStorageLayout(contract2);
|
|
233
|
+
const result = diffFoundryStorageLayout(storage1, storage2);
|
|
234
|
+
console.log(result);
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// src/tasks/rpcs.ts
|
|
239
|
+
import { Option as Option4 } from "@commander-js/extra-typings";
|
|
240
|
+
import { ChainId, getNetworkEnv, getRPCUrl } from "@bgd-labs/toolbox";
|
|
241
|
+
function registerRpcs(program2) {
|
|
242
|
+
program2.command("rpcs").description("generate a list of rpcs to be used in foundry projects").addOption(
|
|
243
|
+
new Option4("--alchemyApiKey <string>", "defaults to env.ALCHEMY_API_KEY")
|
|
244
|
+
).addOption(
|
|
245
|
+
new Option4(
|
|
246
|
+
"--quicknodeToken <string>",
|
|
247
|
+
"defaults to env.QUICKNODE_TOKEN"
|
|
248
|
+
)
|
|
249
|
+
).addOption(
|
|
250
|
+
new Option4(
|
|
251
|
+
"--quicknodeEndpointName <string>",
|
|
252
|
+
"defaults to env.QUICKNODE_ENDPOINT_NAME"
|
|
253
|
+
)
|
|
254
|
+
).action(
|
|
255
|
+
async ({ alchemyApiKey, quicknodeToken, quicknodeEndpointName }) => {
|
|
256
|
+
let env = "";
|
|
257
|
+
let toml = "";
|
|
258
|
+
Object.entries(ChainId).map(([key, chainId]) => {
|
|
259
|
+
const networkEnv = getNetworkEnv(chainId);
|
|
260
|
+
const rpc = getRPCUrl(chainId, {
|
|
261
|
+
alchemyKey: alchemyApiKey || process.env.ALCHEMY_API_KEY,
|
|
262
|
+
quicknodeToken: quicknodeToken || process.env.QUICKNODE_TOKEN,
|
|
263
|
+
quicknodeEndpointName: quicknodeEndpointName || process.env.QUICKNODE_ENDPOINT_NAME
|
|
264
|
+
});
|
|
265
|
+
env += `${networkEnv}=${rpc || ""}
|
|
266
|
+
`;
|
|
267
|
+
toml += `${key}="\${${networkEnv}}"
|
|
268
|
+
`;
|
|
269
|
+
});
|
|
270
|
+
console.log("### .env ###");
|
|
271
|
+
console.log(env);
|
|
272
|
+
console.log("### foundry toml ###");
|
|
273
|
+
console.log(toml);
|
|
274
|
+
}
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// src/tasks/protocol.ts
|
|
279
|
+
import {
|
|
280
|
+
fetchPoolAddresses,
|
|
281
|
+
getClient,
|
|
282
|
+
getReserveTokens,
|
|
283
|
+
getReserveConfigurations
|
|
284
|
+
} from "@bgd-labs/toolbox";
|
|
285
|
+
import { AaveV3Ethereum } from "@bgd-labs/aave-address-book";
|
|
286
|
+
function registerProtocol(program2) {
|
|
287
|
+
program2.command("protocol").description("generated the storage diff between any two files").action(async () => {
|
|
288
|
+
const mainnetClient = getClient(1, {
|
|
289
|
+
providerConfig: { alchemyKey: process.env.ALCHEMY_API_KEY }
|
|
290
|
+
});
|
|
291
|
+
const contracts = await fetchPoolAddresses(
|
|
292
|
+
mainnetClient,
|
|
293
|
+
AaveV3Ethereum.POOL_ADDRESSES_PROVIDER
|
|
294
|
+
);
|
|
295
|
+
const reserveTokens = await getReserveTokens(
|
|
296
|
+
mainnetClient,
|
|
297
|
+
contracts.pool
|
|
298
|
+
);
|
|
299
|
+
const reserveConfigs = await getReserveConfigurations(
|
|
300
|
+
mainnetClient,
|
|
301
|
+
contracts.pool,
|
|
302
|
+
reserveTokens
|
|
303
|
+
);
|
|
304
|
+
console.log(reserveConfigs);
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// src/index.ts
|
|
309
|
+
var program = new Command5();
|
|
310
|
+
program.name("@bgd-labs/cli").description("A cli to help with web3 / solidity tasks").version(package_default.version).showHelpAfterError();
|
|
311
|
+
registerCodeDiff(program);
|
|
312
|
+
registerAaveVNet(program);
|
|
313
|
+
registerStorageDiff(program);
|
|
314
|
+
registerRpcs(program);
|
|
315
|
+
registerProtocol(program);
|
|
316
|
+
program.parse();
|
|
317
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../package.json","../src/tasks/code-diff.ts","../src/tasks/aave-vnet.ts","../src/tasks/storage-diff.ts","../src/tasks/rpcs.ts","../src/tasks/protocol.ts"],"sourcesContent":["#!/usr/bin/env node\nimport \"dotenv/config\";\nimport { Command, Option } from \"@commander-js/extra-typings\";\nimport packageJson from \"../package.json\";\nimport { registerCodeDiff } from \"./tasks/code-diff\";\nimport { registerAaveVNet } from \"./tasks/aave-vnet\";\nimport { registerStorageDiff } from \"./tasks/storage-diff\";\nimport { registerRpcs } from \"./tasks/rpcs\";\nimport { registerProtocol } from \"./tasks/protocol\";\n\nconst program = new Command();\n\nprogram\n .name(\"@bgd-labs/cli\")\n .description(\"A cli to help with web3 / solidity tasks\")\n .version(packageJson.version)\n .showHelpAfterError();\n\nregisterCodeDiff(program);\nregisterAaveVNet(program);\nregisterStorageDiff(program);\nregisterRpcs(program);\nregisterProtocol(program);\n\nprogram.parse();\n","{\n \"name\": \"@bgd-labs/cli\",\n \"version\": \"0.0.21\",\n \"main\": \"./dist/index.mjs\",\n \"sideEffects\": false,\n \"license\": \"MIT\",\n \"files\": [\n \"dist/**\"\n ],\n \"type\": \"module\",\n \"bin\": {\n \"cli\": \"dist/index.js\"\n },\n \"scripts\": {\n \"build\": \"tsup src/index.ts\",\n \"dev\": \"tsup src/index.ts --watch\",\n \"start\": \"node dist/index.js\",\n \"clean\": \"rm -rf .turbo && rm -rf node_modules && rm -rf dist\"\n },\n \"devDependencies\": {\n \"@types/node\": \"catalog:\",\n \"tsup\": \"catalog:\",\n \"typescript\": \"catalog:\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"dependencies\": {\n \"@bgd-labs/aave-address-book\": \"^4.14.0\",\n \"@bgd-labs/toolbox\": \"workspace:*\",\n \"@commander-js/extra-typings\": \"^13.1.0\",\n \"@inquirer/prompts\": \"^7.3.2\",\n \"dotenv\": \"^16.4.7\",\n \"viem\": \"catalog:\"\n }\n}\n","import { Command, Option } from \"@commander-js/extra-typings\";\nimport { diffCode, getSourceCode } from \"@bgd-labs/toolbox\";\nimport { mkdirSync, writeFileSync } from \"node:fs\";\n\nexport function registerCodeDiff(program: Command) {\n program\n .command(\"codeDiff\")\n .description(\"generated the diff between any two addresses\")\n .addOption(new Option(\"--address1 <address>\").makeOptionMandatory())\n .addOption(new Option(\"--chainId1 <number>\").makeOptionMandatory())\n .addOption(new Option(\"--address2 <address>\").makeOptionMandatory())\n .addOption(new Option(\"--chainId2 <number>\").makeOptionMandatory())\n .addOption(new Option(\"-f, --flatten\"))\n .addOption(\n new Option(\"-o, --output <format>\")\n .choices([\"stdout\", \"file\"])\n .default(\"stdout\"),\n )\n .addOption(new Option(\"-p, --path <path>\").default(\"./diffs/code\"))\n .action(\n async ({\n address1,\n address2,\n chainId1,\n chainId2,\n flatten,\n output,\n path,\n }) => {\n const sources = await Promise.all([\n getSourceCode({\n chainId: Number(chainId1),\n address: address1 as any,\n apiKey: process.env.ETHERSCAN_API_KEY,\n }),\n getSourceCode({\n chainId: Number(chainId2),\n address: address2 as any,\n apiKey: process.env.ETHERSCAN_API_KEY,\n }),\n ]);\n const diff = await diffCode(\n sources[0].SourceCode,\n sources[1].SourceCode,\n );\n if (flatten || output === \"stdout\") {\n const flat = Object.keys(diff).reduce((acc, key) => {\n acc += diff[key];\n return acc;\n }, \"\");\n if (output === \"stdout\") {\n console.log(flat);\n } else {\n const filePath = `${path}/${chainId1}`;\n mkdirSync(filePath, { recursive: true });\n writeFileSync(`${filePath}/${address1}_${address2}.patch`, flat);\n }\n } else {\n const filePath = `${path}/${chainId1}/${address1}_${address2}`;\n mkdirSync(filePath, { recursive: true });\n Object.keys(diff).map((file) => {\n writeFileSync(`${filePath}/${file}.patch`, diff[file]);\n });\n }\n },\n );\n}\n","import { Command, Option } from \"@commander-js/extra-typings\";\nimport {\n getNonFinalizedPayloads,\n getPayloadsController,\n makePayloadExecutableOnTestClient,\n tenderly_createVnet,\n} from \"@bgd-labs/toolbox\";\nimport { checkbox, select, Separator } from \"@inquirer/prompts\";\nimport * as addresses from \"@bgd-labs/aave-address-book\";\nimport { Address } from \"viem\";\n\nenum DialogOptions {\n PAYLOAD_ID,\n PAYLOAD_ADDRESS,\n PAYLOAD_ARTIFACT,\n EXIT,\n DELETE,\n}\n\nexport function registerAaveVNet(program: Command) {\n program\n .command(\"aave-vnet\")\n .description(\"creates a tenderly virtual testnet and execute payloads\")\n .addOption(new Option(\"-c,--chainId <number>\").makeOptionMandatory())\n .addOption(\n new Option(\n \"-t, --tenderlyAccessToken <string>\",\n \"defaults to env.TENDERLY_ACCESS_TOKEN\",\n ),\n )\n .addOption(\n new Option(\n \"-a, --tenderlyAccountSlug <string>\",\n \"defaults to env.TENDERLY_ACCOUNT_SLUG\",\n ),\n )\n .addOption(\n new Option(\n \"-p, --tenderlyProjectSlug <string>\",\n \"defaults to env.TENDERLY_PROJECT_SLUG\",\n ),\n )\n .action(\n async ({\n chainId,\n tenderlyAccessToken,\n tenderlyAccountSlug,\n tenderlyProjectSlug,\n }) => {\n const vnet = await tenderly_createVnet(\n {\n baseChainId: Number(chainId),\n forkChainId: 3030,\n slug: `${Math.floor(Math.random() * 1000)}acli-bgd-labs-vnet-${chainId}`,\n displayName: \"bgd-labs cli vnet\",\n },\n {\n accessToken:\n tenderlyAccessToken || process.env.TENDERLY_ACCESS_TOKEN!,\n accountSlug:\n tenderlyAccountSlug || process.env.TENDERLY_ACCOUNT_SLUG!,\n projectSlug:\n tenderlyProjectSlug || process.env.TENDERLY_PROJECT_SLUG!,\n },\n );\n console.info(\"Virtual testnet created!\");\n console.info(\"RPC:\", vnet.vnet.rpcs[0].url);\n const controllerAddress = findPayloadsController(Number(chainId))!;\n const controllerContract = getPayloadsController(\n vnet.walletClient,\n controllerAddress,\n );\n while (true) {\n const answer = await select({\n message: \"What do you want to do?\",\n choices: [\n {\n name: \"Execute a registered payload\",\n value: DialogOptions.PAYLOAD_ID,\n },\n {\n name: \"Execute a deployed (but not registered) payload\",\n value: DialogOptions.PAYLOAD_ADDRESS,\n },\n {\n name: \"Execute a local payload.\",\n value: DialogOptions.PAYLOAD_ARTIFACT,\n },\n new Separator(),\n {\n name: \"Exit (this will keep the vnet open - you can delete it via tenderly ui)\",\n value: DialogOptions.EXIT,\n },\n {\n name: \"Exit and delete\",\n value: DialogOptions.DELETE,\n },\n ],\n });\n switch (answer) {\n case DialogOptions.PAYLOAD_ID:\n const payloadIds = await getNonFinalizedPayloads(\n vnet.testClient,\n controllerAddress,\n );\n const answer = await checkbox({\n message: \"Select the payloads you want to execute\",\n choices: payloadIds.map((id) => ({\n name: String(id),\n value: String(id),\n })),\n });\n for (const id of answer) {\n await makePayloadExecutableOnTestClient(\n vnet.testClient,\n controllerAddress,\n Number(id),\n );\n await controllerContract.write.executePayload([Number(id)]);\n console.info(`Payload ${id} executed`);\n }\n break;\n case DialogOptions.EXIT:\n process.exit(0);\n case DialogOptions.DELETE:\n await vnet.delete();\n console.info(\"Virtual testnet deleted!\");\n process.exit(0);\n }\n }\n },\n );\n}\n\nexport function findPayloadsController(chainId: number): Address | void {\n const key = Object.keys(addresses).find(\n (key) =>\n (addresses[key as keyof typeof addresses] as any).CHAIN_ID === chainId &&\n (addresses[key as keyof typeof addresses] as any).PAYLOADS_CONTROLLER,\n );\n if (key)\n return (addresses[key as keyof typeof addresses] as any)\n .PAYLOADS_CONTROLLER;\n}\n","import { Command, Option } from \"@commander-js/extra-typings\";\nimport {\n diffFoundryStorageLayout,\n foundry_getStorageLayout,\n} from \"@bgd-labs/toolbox\";\n\nexport function registerStorageDiff(program: Command) {\n program\n .command(\"storageDiff\")\n .description(\"generated the storage diff between any two files\")\n .addOption(new Option(\"--contract1 <Contract|path>\").makeOptionMandatory())\n .addOption(new Option(\"--contract2 <Contract|path>\").makeOptionMandatory())\n .action(async ({ contract1, contract2 }) => {\n const storage1 = foundry_getStorageLayout(contract1);\n const storage2 = foundry_getStorageLayout(contract2);\n const result = diffFoundryStorageLayout(storage1, storage2);\n console.log(result);\n });\n}\n","import { Command, Option } from \"@commander-js/extra-typings\";\nimport { ChainId, getNetworkEnv, getRPCUrl } from \"@bgd-labs/toolbox\";\n\n/**\n * Logs a list of rpcs to be used in your foundry project\n * @param program\n */\nexport function registerRpcs(program: Command) {\n program\n .command(\"rpcs\")\n .description(\"generate a list of rpcs to be used in foundry projects\")\n .addOption(\n new Option(\"--alchemyApiKey <string>\", \"defaults to env.ALCHEMY_API_KEY\"),\n )\n .addOption(\n new Option(\n \"--quicknodeToken <string>\",\n \"defaults to env.QUICKNODE_TOKEN\",\n ),\n )\n .addOption(\n new Option(\n \"--quicknodeEndpointName <string>\",\n \"defaults to env.QUICKNODE_ENDPOINT_NAME\",\n ),\n )\n .action(\n async ({ alchemyApiKey, quicknodeToken, quicknodeEndpointName }) => {\n let env = \"\";\n let toml = \"\";\n Object.entries(ChainId).map(([key, chainId]) => {\n const networkEnv = getNetworkEnv(chainId);\n const rpc = getRPCUrl(chainId, {\n alchemyKey: alchemyApiKey || process.env.ALCHEMY_API_KEY,\n quicknodeToken: quicknodeToken || process.env.QUICKNODE_TOKEN,\n quicknodeEndpointName:\n quicknodeEndpointName || process.env.QUICKNODE_ENDPOINT_NAME,\n });\n env += `${networkEnv}=${rpc || \"\"}\\n`;\n toml += `${key}=\"\\${${networkEnv}}\"\\n`;\n });\n\n console.log(\"### .env ###\");\n console.log(env);\n\n console.log(\"### foundry toml ###\");\n console.log(toml);\n },\n );\n}\n","import { Command, Option } from \"@commander-js/extra-typings\";\nimport {\n fetchPoolAddresses,\n getClient,\n getReserveTokens,\n getReserveConfigurations,\n} from \"@bgd-labs/toolbox\";\nimport { AaveV3Ethereum } from \"@bgd-labs/aave-address-book\";\n\nexport function registerProtocol(program: Command) {\n program\n .command(\"protocol\")\n .description(\"generated the storage diff between any two files\")\n .action(async () => {\n const mainnetClient = getClient(1, {\n providerConfig: { alchemyKey: process.env.ALCHEMY_API_KEY },\n });\n const contracts = await fetchPoolAddresses(\n mainnetClient,\n AaveV3Ethereum.POOL_ADDRESSES_PROVIDER,\n );\n const reserveTokens = await getReserveTokens(\n mainnetClient,\n contracts.pool,\n );\n const reserveConfigs = await getReserveConfigurations(\n mainnetClient,\n contracts.pool,\n reserveTokens,\n );\n console.log(reserveConfigs);\n });\n}\n"],"mappings":"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","names":["Command","program","Option","program","Option","answer","key","Option","program","Option","program","program","Command"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bgd-labs/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.21",
|
|
4
4
|
"main": "./dist/index.mjs",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"@commander-js/extra-typings": "^13.1.0",
|
|
25
25
|
"@inquirer/prompts": "^7.3.2",
|
|
26
26
|
"dotenv": "^16.4.7",
|
|
27
|
-
"viem": "^2.
|
|
27
|
+
"viem": "^2.30.0",
|
|
28
28
|
"@bgd-labs/toolbox": "0.0.15"
|
|
29
29
|
},
|
|
30
30
|
"scripts": {
|