@cartesi/cli 2.0.0-alpha.13 → 2.0.0-alpha.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/base.d.ts +8 -3
  2. package/dist/base.d.ts.map +1 -1
  3. package/dist/base.js +7 -4
  4. package/dist/commands/address-book.d.ts +1 -0
  5. package/dist/commands/address-book.d.ts.map +1 -1
  6. package/dist/commands/address-book.js +6 -3
  7. package/dist/commands/create.d.ts +1 -1
  8. package/dist/commands/create.d.ts.map +1 -1
  9. package/dist/commands/create.js +1 -0
  10. package/dist/commands/deploy.d.ts +1 -16
  11. package/dist/commands/deploy.d.ts.map +1 -1
  12. package/dist/commands/deploy.js +8 -267
  13. package/dist/commands/deposit/erc20.d.ts +11 -0
  14. package/dist/commands/deposit/erc20.d.ts.map +1 -0
  15. package/dist/commands/deposit/erc20.js +126 -0
  16. package/dist/commands/deposit/erc721.d.ts +12 -0
  17. package/dist/commands/deposit/erc721.d.ts.map +1 -0
  18. package/dist/commands/deposit/erc721.js +144 -0
  19. package/dist/commands/deposit/ether.d.ts +10 -0
  20. package/dist/commands/deposit/ether.d.ts.map +1 -0
  21. package/dist/commands/deposit/ether.js +66 -0
  22. package/dist/commands/deposit.d.ts +9 -0
  23. package/dist/commands/deposit.d.ts.map +1 -0
  24. package/dist/commands/deposit.js +36 -0
  25. package/dist/commands/logs.d.ts +1 -1
  26. package/dist/commands/logs.d.ts.map +1 -1
  27. package/dist/commands/logs.js +6 -4
  28. package/dist/commands/run.d.ts +13 -1
  29. package/dist/commands/run.d.ts.map +1 -1
  30. package/dist/commands/run.js +196 -4
  31. package/dist/commands/send.d.ts +6 -17
  32. package/dist/commands/send.d.ts.map +1 -1
  33. package/dist/commands/send.js +122 -59
  34. package/dist/commands/status.d.ts +1 -1
  35. package/dist/commands/status.d.ts.map +1 -1
  36. package/dist/commands/status.js +10 -7
  37. package/dist/compose/default.env +1 -1
  38. package/dist/compose/docker-compose-anvil.yaml +1 -1
  39. package/dist/compose/docker-compose-node.yaml +1 -4
  40. package/dist/config.d.ts +2 -2
  41. package/dist/config.d.ts.map +1 -1
  42. package/dist/config.js +2 -2
  43. package/dist/exec/cartesi-machine.js +1 -1
  44. package/dist/exec/rollups.d.ts +94 -5
  45. package/dist/exec/rollups.d.ts.map +1 -1
  46. package/dist/exec/rollups.js +356 -12
  47. package/dist/index.js +5 -7
  48. package/dist/prompts.d.ts +12 -1
  49. package/dist/prompts.d.ts.map +1 -1
  50. package/dist/prompts.js +58 -23
  51. package/dist/wallet.d.ts +15948 -21
  52. package/dist/wallet.d.ts.map +1 -1
  53. package/dist/wallet.js +33 -221
  54. package/package.json +24 -23
  55. package/dist/commands/send/eip712.d.ts +0 -34
  56. package/dist/commands/send/eip712.d.ts.map +0 -1
  57. package/dist/commands/send/eip712.js +0 -81
  58. package/dist/commands/send/erc20.d.ts +0 -12
  59. package/dist/commands/send/erc20.d.ts.map +0 -1
  60. package/dist/commands/send/erc20.js +0 -75
  61. package/dist/commands/send/erc721.d.ts +0 -12
  62. package/dist/commands/send/erc721.d.ts.map +0 -1
  63. package/dist/commands/send/erc721.js +0 -78
  64. package/dist/commands/send/ether.d.ts +0 -12
  65. package/dist/commands/send/ether.d.ts.map +0 -1
  66. package/dist/commands/send/ether.js +0 -36
  67. package/dist/commands/send/generic.d.ts +0 -15
  68. package/dist/commands/send/generic.d.ts.map +0 -1
  69. package/dist/commands/send/generic.js +0 -122
  70. package/dist/commands/start.d.ts +0 -14
  71. package/dist/commands/start.d.ts.map +0 -1
  72. package/dist/commands/start.js +0 -220
  73. package/dist/commands/stop.d.ts +0 -5
  74. package/dist/commands/stop.d.ts.map +0 -1
  75. package/dist/commands/stop.js +0 -27
  76. package/dist/compose/docker-compose-espresso.yaml +0 -81
@@ -1,25 +1,32 @@
1
+ import chalk from "chalk";
1
2
  import { execa } from "execa";
2
- import { getMachineHash } from "../base.js";
3
+ import { Listr } from "listr2";
4
+ import path from "node:path";
5
+ import pRetry from "p-retry";
6
+ import { getAddress, hexToNumber, } from "viem";
7
+ import { getContextPath, getMachineHash, getProjectName, getServiceHealth, } from "../base.js";
8
+ import { DEFAULT_SDK_IMAGE } from "../config.js";
9
+ const parseDeployment = (deployment) => ({
10
+ address: deployment.iapplication_address,
11
+ consensus: deployment.iconsensus_address,
12
+ epochLength: hexToNumber(deployment.epoch_length),
13
+ name: deployment.name,
14
+ state: deployment.state,
15
+ templateHash: deployment.template_hash,
16
+ });
3
17
  export const getDeployments = async (options) => {
4
- const environmentName = options?.environmentName ?? "cartesi-rollups";
5
18
  try {
6
19
  const { stdout } = await execa("docker", [
7
20
  "compose",
8
21
  "--project-name",
9
- environmentName,
22
+ options.projectName,
10
23
  "exec",
11
24
  "rollups-node",
12
25
  "cartesi-rollups-cli",
13
26
  "app",
14
27
  "list",
15
28
  ]);
16
- return JSON.parse(stdout).map((deployment) => ({
17
- name: deployment.name,
18
- address: deployment.iapplication_address,
19
- templateHash: deployment.template_hash,
20
- epochLength: deployment.epoch_lenght,
21
- state: deployment.state,
22
- }));
29
+ return JSON.parse(stdout).map(parseDeployment);
23
30
  }
24
31
  catch (e) {
25
32
  return [];
@@ -33,7 +40,344 @@ export const getApplicationDeployment = async (options) => {
33
40
  const deployments = await getDeployments(options);
34
41
  return deployments.find((deployment) => deployment.templateHash === machineHash);
35
42
  };
36
- export const getApplicationAddress = async () => {
37
- const deployment = await getApplicationDeployment();
43
+ export const getApplicationAddress = async (options) => {
44
+ const projectName = getProjectName(options ?? {});
45
+ const deployment = await getApplicationDeployment({ projectName });
38
46
  return deployment?.address;
39
47
  };
48
+ const host = "http://127.0.0.1";
49
+ // services configuration
50
+ const baseServices = [
51
+ {
52
+ name: "anvil",
53
+ file: "docker-compose-anvil.yaml",
54
+ healthySemaphore: "anvil",
55
+ healthyTitle: (port) => `${chalk.cyan("anvil")} service ready at ${chalk.cyan(`${host}:${port}/anvil`)}`,
56
+ waitTitle: `${chalk.cyan("anvil")} service starting...`,
57
+ errorTitle: `${chalk.red("anvil")} service failed`,
58
+ },
59
+ {
60
+ name: "proxy",
61
+ file: "docker-compose-proxy.yaml",
62
+ },
63
+ {
64
+ name: "database",
65
+ file: "docker-compose-database.yaml",
66
+ },
67
+ {
68
+ name: "rpc",
69
+ file: "docker-compose-node.yaml",
70
+ healthySemaphore: "rollups-node",
71
+ healthyTitle: (port) => `${chalk.cyan("rpc")} service ready at ${chalk.cyan(`${host}:${port}/rpc`)}`,
72
+ waitTitle: `${chalk.cyan("rpc")} service starting...`,
73
+ errorTitle: `${chalk.red("rpc")} service failed`,
74
+ },
75
+ {
76
+ name: "inspect",
77
+ file: "docker-compose-node.yaml",
78
+ healthySemaphore: "rollups-node",
79
+ healthyTitle: (port, name) => `${chalk.cyan("inspect")} service ready at ${chalk.cyan(`${host}:${port}/inspect/${name ?? "<application_address>"}`)}`,
80
+ waitTitle: `${chalk.cyan("inspect")} service starting...`,
81
+ errorTitle: `${chalk.red("inspect")} service failed`,
82
+ },
83
+ ];
84
+ const availableServices = [
85
+ {
86
+ name: "bundler",
87
+ file: "docker-compose-bundler.yaml",
88
+ healthySemaphore: "bundler",
89
+ healthyTitle: (port) => `${chalk.cyan("bundler")} service ready at ${chalk.cyan(`${host}:${port}/bundler/rpc`)}`,
90
+ waitTitle: `${chalk.cyan("bundler")} service starting...`,
91
+ errorTitle: `${chalk.red("bundler")} service failed`,
92
+ },
93
+ {
94
+ name: "explorer",
95
+ file: "docker-compose-explorer.yaml",
96
+ healthySemaphore: "explorer_api",
97
+ healthyTitle: (port) => `${chalk.cyan("explorer")} service ready at ${chalk.cyan(`${host}:${port}/explorer`)}`,
98
+ waitTitle: `${chalk.cyan("explorer")} service starting...`,
99
+ errorTitle: `${chalk.red("explorer")} service failed`,
100
+ },
101
+ {
102
+ name: "graphql",
103
+ file: "docker-compose-graphql.yaml",
104
+ healthySemaphore: "graphql",
105
+ healthyTitle: (port) => `${chalk.cyan("graphql")} service ready at ${chalk.cyan(`${host}:${port}/graphql`)}`,
106
+ waitTitle: `${chalk.cyan("graphql")} service starting...`,
107
+ errorTitle: `${chalk.red("graphql")} service failed`,
108
+ },
109
+ {
110
+ name: "paymaster",
111
+ file: "docker-compose-paymaster.yaml",
112
+ healthySemaphore: "paymaster",
113
+ healthyTitle: (port) => `${chalk.cyan("paymaster")} service ready at ${chalk.cyan(`${host}:${port}/paymaster`)}`,
114
+ waitTitle: `${chalk.cyan("paymaster")} service starting...`,
115
+ errorTitle: `${chalk.red("paymaster")} service failed`,
116
+ },
117
+ {
118
+ name: "passkey",
119
+ file: "docker-compose-passkey-server.yaml",
120
+ healthySemaphore: "passkey-server",
121
+ healthyTitle: (port) => `${chalk.cyan("passkey")} service ready at ${chalk.cyan(`${host}:${port}/passkey`)}`,
122
+ waitTitle: `${chalk.cyan("passkey")} service starting...`,
123
+ errorTitle: `${chalk.red("passkey")} service failed`,
124
+ },
125
+ ];
126
+ export const AVAILABLE_SERVICES = availableServices.map(({ name }) => name);
127
+ const serviceMonitorTask = (options) => {
128
+ const { errorTitle, healthyTitle, service, waitTitle } = options;
129
+ return {
130
+ task: async (_ctx, task) => {
131
+ await pRetry(async () => {
132
+ const health = await getServiceHealth(options);
133
+ if (health !== "healthy") {
134
+ throw new Error(errorTitle ??
135
+ `Service ${chalk.cyan(service)} is not healthy`);
136
+ }
137
+ }, { retries: 100, minTimeout: 500, factor: 1.1 });
138
+ task.title =
139
+ healthyTitle ?? `Service ${chalk.cyan(service)} is ready`;
140
+ },
141
+ title: waitTitle ?? `Starting ${chalk.cyan(service)}...`,
142
+ };
143
+ };
144
+ export const startEnvironment = async (options) => {
145
+ const { blockTime, cpus, defaultBlock, dryRun, memory, port, projectName, runtimeVersion, services, verbose, } = options;
146
+ const address = `${host}:${port}`;
147
+ // path of the tool instalation
148
+ const binPath = path.join(path.dirname(new URL(import.meta.url).pathname), "..");
149
+ // setup the environment variable used in docker compose
150
+ const env = {
151
+ CARTESI_BIN_PATH: binPath,
152
+ CARTESI_BLOCK_TIME: blockTime.toString(),
153
+ CARTESI_BLOCKCHAIN_DEFAULT_BLOCK: defaultBlock,
154
+ CARTESI_LISTEN_PORT: port.toString(),
155
+ CARTESI_LOG_LEVEL: verbose ? "debug" : "info",
156
+ CARTESI_ROLLUPS_NODE_CPUS: cpus?.toString(),
157
+ CARTESI_ROLLUPS_NODE_MEMORY: memory?.toString(),
158
+ CARTESI_SDK_IMAGE: `${DEFAULT_SDK_IMAGE}:${runtimeVersion}`,
159
+ CARTESI_SDK_VERSION: runtimeVersion,
160
+ };
161
+ // build a list of unique compose files
162
+ const composeFiles = [...new Set(baseServices.map(({ file }) => file))];
163
+ // cpu and memory limits, mostly for testing and debuggingpurposes
164
+ if (cpus) {
165
+ composeFiles.push("docker-compose-node-cpus.yaml");
166
+ }
167
+ if (memory) {
168
+ composeFiles.push("docker-compose-node-memory.yaml");
169
+ }
170
+ // select subset of optional services
171
+ const optionalServices = services.length === 1 && services[0] === "all"
172
+ ? availableServices
173
+ : availableServices.filter(({ name }) => services.includes(name));
174
+ // add to compose files list
175
+ composeFiles.push(...optionalServices.map(({ file }) => file));
176
+ // create the "--file <file>" list
177
+ const files = composeFiles.flatMap((f) => [
178
+ "--file",
179
+ path.join(binPath, "compose", f),
180
+ ]);
181
+ const composeArgs = [
182
+ "compose",
183
+ ...files,
184
+ "--project-directory",
185
+ ".",
186
+ "--project-name",
187
+ projectName,
188
+ ];
189
+ // run in detached mode (background)
190
+ const upArgs = ["--detach"];
191
+ // if only dry run, just return the config
192
+ if (dryRun) {
193
+ // parse, resolve and render compose file in canonical format
194
+ const { stdout: config } = await execa("docker", [...composeArgs, "config", "--format", "yaml"], { env });
195
+ return { address, config };
196
+ }
197
+ // pull images first
198
+ const pullArgs = ["--policy", "missing"];
199
+ await execa("docker", [...composeArgs, "pull", ...pullArgs], {
200
+ env,
201
+ stdio: "inherit",
202
+ });
203
+ // run compose
204
+ await execa("docker", [...composeArgs, "up", ...upArgs], {
205
+ env,
206
+ });
207
+ return { address };
208
+ };
209
+ /**
210
+ * Wait for the environment to be healthy
211
+ * @param options
212
+ */
213
+ export const waitHealthyEnvironment = async (options) => {
214
+ const { name, port, projectName, services } = options;
215
+ // select subset of optional services
216
+ const optionalServices = services.length === 1 && services[0] === "all"
217
+ ? availableServices
218
+ : availableServices.filter(({ name }) => services.includes(name));
219
+ // create tasks to monitor services startup
220
+ const monitorTasks = [...baseServices, ...optionalServices]
221
+ .filter(({ healthySemaphore }) => !!healthySemaphore) // only services with a healthy semaphore
222
+ .map((service) => {
223
+ const healthyTitle = typeof service.healthyTitle === "function"
224
+ ? service.healthyTitle(port, name)
225
+ : service.healthyTitle;
226
+ return serviceMonitorTask({
227
+ projectName,
228
+ service: service.healthySemaphore,
229
+ errorTitle: service.errorTitle,
230
+ waitTitle: service.waitTitle,
231
+ healthyTitle,
232
+ });
233
+ });
234
+ const tasks = new Listr(monitorTasks, { concurrent: true });
235
+ await tasks.run();
236
+ };
237
+ /**
238
+ * Publish machine snapshot to rollups node by copying it to the rollups node container
239
+ * @param options
240
+ * @returns path to the snapshot in the rollups node
241
+ */
242
+ export const publishMachine = async (options) => {
243
+ const { projectName, templateHash } = options;
244
+ const snapshotPath = getContextPath("image");
245
+ const containerSnapshotPath = `/var/lib/cartesi-rollups-node/snapshots/${templateHash}/`;
246
+ await execa("docker", [
247
+ "compose",
248
+ "--project-name",
249
+ projectName,
250
+ "cp",
251
+ snapshotPath,
252
+ `rollups-node:${containerSnapshotPath}`,
253
+ ]);
254
+ return containerSnapshotPath;
255
+ };
256
+ /**
257
+ * Stop an environment by removing the containers and volumes
258
+ * @param options
259
+ * @returns
260
+ */
261
+ export const stopEnvironment = async (options) => {
262
+ const { projectName } = options;
263
+ return execa("docker", [
264
+ "compose",
265
+ "--project-name",
266
+ projectName,
267
+ "down",
268
+ "--volumes",
269
+ ]);
270
+ };
271
+ /**
272
+ * Deploy application to rollups node
273
+ * @param options
274
+ * @returns address of the application
275
+ */
276
+ export const deployAuthority = async (options) => {
277
+ const { epochLength, projectName } = options;
278
+ // deploy application
279
+ const { stdout } = await execa("docker", [
280
+ "compose",
281
+ "--project-name",
282
+ projectName,
283
+ "exec",
284
+ "rollups-node",
285
+ "cartesi-rollups-cli",
286
+ "deploy",
287
+ "authority",
288
+ "--epoch-length",
289
+ epochLength.toString(),
290
+ "--json",
291
+ ]);
292
+ return getAddress(JSON.parse(stdout).address);
293
+ };
294
+ /**
295
+ * Deploy application to rollups node
296
+ * @param options
297
+ * @returns address of the application
298
+ */
299
+ export const deployApplication = async (options) => {
300
+ const { consensus, epochLength, name, projectName, salt, snapshotPath } = options;
301
+ // app deploy args
302
+ const deployArgs = [name, snapshotPath];
303
+ if (consensus) {
304
+ deployArgs.push("--consensus", consensus);
305
+ }
306
+ else {
307
+ deployArgs.push("--epoch-length", epochLength.toString(), "--self-hosted");
308
+ }
309
+ if (salt) {
310
+ deployArgs.push("--salt", salt);
311
+ }
312
+ deployArgs.push("--json");
313
+ // deploy application
314
+ const { stdout } = await execa("docker", [
315
+ "compose",
316
+ "--project-name",
317
+ projectName,
318
+ "exec",
319
+ "rollups-node",
320
+ "cartesi-rollups-cli",
321
+ "deploy",
322
+ "application",
323
+ ...deployArgs,
324
+ ]);
325
+ const deployment = stdout ? parseDeployment(JSON.parse(stdout)) : undefined;
326
+ if (deployment) {
327
+ return deployment;
328
+ }
329
+ throw new Error("Failed to deploy application");
330
+ };
331
+ /**
332
+ * Remove application from rollups node
333
+ * @param options
334
+ * @returns
335
+ */
336
+ export const removeApplication = async (options) => {
337
+ const { application, force, projectName } = options;
338
+ // disable application first so we can remove it
339
+ await execa("docker", [
340
+ "compose",
341
+ "--project-name",
342
+ projectName,
343
+ "exec",
344
+ "rollups-node",
345
+ "cartesi-rollups-cli",
346
+ "app",
347
+ "status",
348
+ application,
349
+ "disabled",
350
+ ]);
351
+ const removeArgs = [application];
352
+ if (force) {
353
+ removeArgs.push("--force");
354
+ }
355
+ return execa("docker", [
356
+ "compose",
357
+ "--project-name",
358
+ projectName,
359
+ "exec",
360
+ "rollups-node",
361
+ "cartesi-rollups-cli",
362
+ "app",
363
+ "remove",
364
+ ...removeArgs,
365
+ ]);
366
+ };
367
+ /**
368
+ * Get the host and port of the docker compose project entrypoint
369
+ * @param options
370
+ * @returns port of the proxy service
371
+ */
372
+ export const getProjectPort = async (options) => {
373
+ const { projectName } = options;
374
+ const { stdout } = await execa("docker", [
375
+ "compose",
376
+ "--project-name",
377
+ projectName,
378
+ "port",
379
+ "proxy",
380
+ "8088",
381
+ ]);
382
+ return stdout;
383
+ };
package/dist/index.js CHANGED
@@ -6,15 +6,14 @@ import { createBuildCommand } from "./commands/build.js";
6
6
  import { createCleanCommand } from "./commands/clean.js";
7
7
  import { createCreateCommand } from "./commands/create.js";
8
8
  import { createDeployCommand } from "./commands/deploy.js";
9
+ import { createDepositCommand } from "./commands/deposit.js";
9
10
  import { createDoctorCommand } from "./commands/doctor.js";
10
11
  import { createHashCommand } from "./commands/hash.js";
11
12
  import { createLogsCommand } from "./commands/logs.js";
12
13
  import { createRunCommand } from "./commands/run.js";
13
14
  import { createSendCommand } from "./commands/send.js";
14
15
  import { createShellCommand } from "./commands/shell.js";
15
- import { createStartCommand } from "./commands/start.js";
16
16
  import { createStatusCommand } from "./commands/status.js";
17
- import { createStopCommand } from "./commands/stop.js";
18
17
  // Use `createRequire` to import JSON in ESM
19
18
  const require = createRequire(import.meta.url);
20
19
  const pkg = require("../package.json");
@@ -35,16 +34,15 @@ const program = new Command()
35
34
  .addCommand(createBuildCommand())
36
35
  .addCommand(createCleanCommand())
37
36
  .addCommand(createCreateCommand())
38
- .addCommand(createDeployCommand())
37
+ .addCommand(createDeployCommand(), { hidden: true })
38
+ .addCommand(createDepositCommand())
39
39
  .addCommand(createDoctorCommand())
40
40
  .addCommand(createLogsCommand())
41
41
  .addCommand(createHashCommand())
42
- .addCommand(createRunCommand(), { hidden: true })
42
+ .addCommand(createRunCommand())
43
43
  .addCommand(createSendCommand())
44
44
  .addCommand(createShellCommand())
45
- .addCommand(createStartCommand())
46
- .addCommand(createStatusCommand())
47
- .addCommand(createStopCommand());
45
+ .addCommand(createStatusCommand());
48
46
  // Global error handling
49
47
  process.on("uncaughtException", (err) => {
50
48
  if (process.env.NODE_ENV === "development") {
package/dist/prompts.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Separator } from "@inquirer/core";
1
+ import { Separator } from "@inquirer/core";
2
2
  import input from "@inquirer/input";
3
3
  import select from "@inquirer/select";
4
4
  import type { Context } from "@inquirer/type";
@@ -34,6 +34,7 @@ export declare const bigintInput: (config: BigintPromptConfig) => Promise<bigint
34
34
  * @returns bytes as hex string
35
35
  */
36
36
  export declare const bytesInput: (config: InputConfig & {
37
+ encoding?: "string" | "hex" | "abi";
37
38
  message: string;
38
39
  }) => Promise<Hex>;
39
40
  /**
@@ -58,5 +59,15 @@ export type SelectAutoConfig<ValueType> = SelectConfig<ValueType> & {
58
59
  export declare const selectAuto: <ValueType>(config: SelectAutoConfig<ValueType> & {
59
60
  discardDisabled?: boolean;
60
61
  }, context?: Context | undefined) => Promise<ValueType>;
62
+ export declare const keySelect: <Value>(config: {
63
+ choices: readonly Choice<Value>[];
64
+ separator?: string | undefined;
65
+ }, context?: Context) => Promise<Value> & {
66
+ cancel: () => void;
67
+ };
68
+ export declare const getInputApplicationAddress: (options: {
69
+ application?: string;
70
+ projectName?: string;
71
+ }) => Promise<Address>;
61
72
  export {};
62
73
  //# sourceMappingURL=prompts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,MAAM,iBAAiB,CAAC;AACpC,OAAO,MAAM,MAAM,kBAAkB,CAAC;AACtC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EACH,KAAK,OAAO,EACZ,KAAK,GAAG,EASX,MAAM,MAAM,CAAC;AAEd,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/C,KAAK,YAAY,CAAC,SAAS,IAAI,UAAU,CAAC,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEvE;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AACtE,eAAO,MAAM,YAAY,GACrB,QAAQ,mBAAmB,KAC5B,OAAO,CAAC,OAAO,CAMjB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG;IAAE,OAAO,CAAC,EAAE,GAAG,CAAA;CAAE,CAAC;AAC9D,eAAO,MAAM,QAAQ,GAAU,QAAQ,eAAe,KAAG,OAAO,CAAC,GAAG,CAMnE,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AACF,eAAO,MAAM,WAAW,GACpB,QAAQ,kBAAkB,KAC3B,OAAO,CAAC,MAAM,CAUhB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,UAAU,GACnB,QAAQ,WAAW,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,KAC1C,OAAO,CAAC,GAAG,CA8Cb,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,GACvB,QAAQ,WAAW,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,KAC1C,OAAO,CAAC,KAAK,MAAM,EAAE,CA+DvB,CAAC;AAGF,MAAM,MAAM,MAAM,CAAC,SAAS,IAAI;IAC5B,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,IAAI,CAAC,EAAE,KAAK,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,gBAAgB,CAAC,SAAS,IAAI,YAAY,CAAC,SAAS,CAAC,GAAG;IAChE,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,SAAS,EAChC,QAAQ,gBAAgB,CAAC,SAAS,CAAC,GAAG;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,EACnE,UAAU,OAAO,GAAG,SAAS,KAC9B,OAAO,CAAC,SAAS,CAsBnB,CAAC"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAA6B,MAAM,gBAAgB,CAAC;AACtE,OAAO,KAAK,MAAM,iBAAiB,CAAC;AACpC,OAAO,MAAM,MAAM,kBAAkB,CAAC;AACtC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EACH,KAAK,OAAO,EACZ,KAAK,GAAG,EASX,MAAM,MAAM,CAAC;AAGd,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/C,KAAK,YAAY,CAAC,SAAS,IAAI,UAAU,CAAC,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEvE;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AACtE,eAAO,MAAM,YAAY,GACrB,QAAQ,mBAAmB,KAC5B,OAAO,CAAC,OAAO,CAMjB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG;IAAE,OAAO,CAAC,EAAE,GAAG,CAAA;CAAE,CAAC;AAC9D,eAAO,MAAM,QAAQ,GAAU,QAAQ,eAAe,KAAG,OAAO,CAAC,GAAG,CAMnE,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AACF,eAAO,MAAM,WAAW,GACpB,QAAQ,kBAAkB,KAC3B,OAAO,CAAC,MAAM,CAUhB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,UAAU,GACnB,QAAQ,WAAW,GAAG;IAClB,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,KAAK,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;CACnB,KACF,OAAO,CAAC,GAAG,CAkDb,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,GACvB,QAAQ,WAAW,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,KAC1C,OAAO,CAAC,KAAK,MAAM,EAAE,CA+DvB,CAAC;AAGF,MAAM,MAAM,MAAM,CAAC,SAAS,IAAI;IAC5B,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,IAAI,CAAC,EAAE,KAAK,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,gBAAgB,CAAC,SAAS,IAAI,YAAY,CAAC,SAAS,CAAC,GAAG;IAChE,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,SAAS,EAChC,QAAQ,gBAAgB,CAAC,SAAS,CAAC,GAAG;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,EACnE,UAAU,OAAO,GAAG,SAAS,KAC9B,OAAO,CAAC,SAAS,CAuBnB,CAAC;AAOF,eAAO,MAAM,SAAS,GACjB,KAAK;;gBAJM,MAAM;;;CAoBrB,CAAC;AAEF,eAAO,MAAM,0BAA0B,GAAU,SAAS;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB,KAAG,OAAO,CAAC,OAAO,CAoBlB,CAAC"}
package/dist/prompts.js CHANGED
@@ -1,8 +1,10 @@
1
1
  import confirm from "@inquirer/confirm";
2
+ import { Separator, createPrompt, useKeypress } from "@inquirer/core";
2
3
  import input from "@inquirer/input";
3
4
  import select from "@inquirer/select";
4
5
  import chalk from "chalk";
5
6
  import { encodeAbiParameters, formatUnits, getAddress, isAddress, isHex, parseAbiParameters, parseUnits, stringToHex, } from "viem";
7
+ import { getApplicationAddress } from "./exec/rollups.js";
6
8
  export const addressInput = async (config) => {
7
9
  const address = await input({
8
10
  ...config,
@@ -33,26 +35,27 @@ export const bigintInput = async (config) => {
33
35
  * @returns bytes as hex string
34
36
  */
35
37
  export const bytesInput = async (config) => {
36
- const encoding = await select({
37
- ...config,
38
- choices: [
39
- {
40
- value: "string",
41
- name: "String encoding",
42
- description: "Convert UTF-8 string to bytes",
43
- },
44
- {
45
- value: "hex",
46
- name: "Hex string encoding",
47
- description: "Convert a hex string to bytes (must start with 0x)",
48
- },
49
- {
50
- value: "abi",
51
- name: "ABI encoding",
52
- description: "Input as ABI encoding parameters https://abitype.dev/api/human.html#parseabiparameters",
53
- },
54
- ],
55
- });
38
+ const encoding = config.encoding ??
39
+ (await select({
40
+ ...config,
41
+ choices: [
42
+ {
43
+ value: "string",
44
+ name: "String encoding",
45
+ description: "Convert UTF-8 string to bytes",
46
+ },
47
+ {
48
+ value: "hex",
49
+ name: "Hex string encoding",
50
+ description: "Convert a hex string to bytes (must start with 0x)",
51
+ },
52
+ {
53
+ value: "abi",
54
+ name: "ABI encoding",
55
+ description: "Input as ABI encoding parameters https://abitype.dev/api/human#parseabiparameters",
56
+ },
57
+ ],
58
+ }));
56
59
  switch (encoding) {
57
60
  case "hex": {
58
61
  const valueHex = await hexInput({
@@ -82,7 +85,7 @@ export const bytesInput = async (config) => {
82
85
  */
83
86
  export const abiParamsInput = async (config) => {
84
87
  const encoding = await input({
85
- message: `${config.message} (as ABI encoded https://abitype.dev/api/human.html#parseabiparameters )`,
88
+ message: `${config.message} (as ABI encoded https://abitype.dev/api/human#parseabiparameters )`,
86
89
  validate: (value) => {
87
90
  try {
88
91
  parseAbiParameters(value);
@@ -142,11 +145,12 @@ export const abiParamsInput = async (config) => {
142
145
  export const selectAuto = (config, context) => {
143
146
  const choices = config.choices;
144
147
  const list = config.discardDisabled
145
- ? choices.filter((c) => c.type !== "separator" && !c.disabled)
148
+ ? choices.filter((c) => !(c instanceof Separator) && !c.disabled)
146
149
  : choices;
150
+ const a = choices.filter((c) => c.type !== "separator");
147
151
  if (list.length === 1) {
148
152
  const choice = list[0];
149
- if (choice.type !== "separator") {
153
+ if (!(choice instanceof Separator)) {
150
154
  const output = context?.output || process.stdout;
151
155
  const prefix = chalk.green("?");
152
156
  const message = chalk.bold(config.message);
@@ -156,3 +160,34 @@ export const selectAuto = (config, context) => {
156
160
  }
157
161
  return select(config, context);
158
162
  };
163
+ export const keySelect = createPrompt((config, done) => {
164
+ const choices = config.choices;
165
+ const separator = config.separator ?? "\t";
166
+ const options = choices
167
+ .map((c) => `(${chalk.cyan(c.value)}) ${c.name ?? ""}`)
168
+ .join(separator);
169
+ useKeypress((key) => {
170
+ const selected = choices.find((c) => c.value === key.name);
171
+ if (selected) {
172
+ done(selected.value);
173
+ }
174
+ });
175
+ return `${options} `;
176
+ });
177
+ export const getInputApplicationAddress = async (options) => {
178
+ const { application, projectName } = options;
179
+ if (application && isAddress(application)) {
180
+ // honor the flag
181
+ return application;
182
+ }
183
+ // get the running container application address
184
+ const nodeAddress = await getApplicationAddress({ projectName });
185
+ if (nodeAddress) {
186
+ return nodeAddress;
187
+ }
188
+ // query for the address
189
+ const applicationAddress = await addressInput({
190
+ message: "Application address",
191
+ });
192
+ return applicationAddress;
193
+ };