@layr-labs/ecloud-cli 0.2.0 → 0.2.2-dev

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 (48) hide show
  1. package/VERSION +2 -2
  2. package/dist/commands/auth/whoami.js +16 -3
  3. package/dist/commands/auth/whoami.js.map +1 -1
  4. package/dist/commands/billing/cancel.js +44 -5
  5. package/dist/commands/billing/cancel.js.map +1 -1
  6. package/dist/commands/billing/status.js +44 -5
  7. package/dist/commands/billing/status.js.map +1 -1
  8. package/dist/commands/billing/subscribe.js +44 -5
  9. package/dist/commands/billing/subscribe.js.map +1 -1
  10. package/dist/commands/compute/app/create.js +16 -3
  11. package/dist/commands/compute/app/create.js.map +1 -1
  12. package/dist/commands/compute/app/deploy.js +120 -25
  13. package/dist/commands/compute/app/deploy.js.map +1 -1
  14. package/dist/commands/compute/app/info.js +124 -35
  15. package/dist/commands/compute/app/info.js.map +1 -1
  16. package/dist/commands/compute/app/list.js +78 -17
  17. package/dist/commands/compute/app/list.js.map +1 -1
  18. package/dist/commands/compute/app/logs.js +69 -28
  19. package/dist/commands/compute/app/logs.js.map +1 -1
  20. package/dist/commands/compute/app/profile/set.js +109 -40
  21. package/dist/commands/compute/app/profile/set.js.map +1 -1
  22. package/dist/commands/compute/app/releases.js +82 -120
  23. package/dist/commands/compute/app/releases.js.map +1 -1
  24. package/dist/commands/compute/app/start.js +77 -35
  25. package/dist/commands/compute/app/start.js.map +1 -1
  26. package/dist/commands/compute/app/stop.js +77 -35
  27. package/dist/commands/compute/app/stop.js.map +1 -1
  28. package/dist/commands/compute/app/terminate.js +77 -35
  29. package/dist/commands/compute/app/terminate.js.map +1 -1
  30. package/dist/commands/compute/app/upgrade.js +117 -39
  31. package/dist/commands/compute/app/upgrade.js.map +1 -1
  32. package/dist/commands/compute/build/info.js +56 -16
  33. package/dist/commands/compute/build/info.js.map +1 -1
  34. package/dist/commands/compute/build/list.js +72 -67
  35. package/dist/commands/compute/build/list.js.map +1 -1
  36. package/dist/commands/compute/build/logs.js +55 -13
  37. package/dist/commands/compute/build/logs.js.map +1 -1
  38. package/dist/commands/compute/build/status.js +55 -13
  39. package/dist/commands/compute/build/status.js.map +1 -1
  40. package/dist/commands/compute/build/submit.js +68 -9
  41. package/dist/commands/compute/build/submit.js.map +1 -1
  42. package/dist/commands/compute/build/verify.js +55 -13
  43. package/dist/commands/compute/build/verify.js.map +1 -1
  44. package/dist/commands/compute/environment/set.js +20 -7
  45. package/dist/commands/compute/environment/set.js.map +1 -1
  46. package/dist/commands/compute/undelegate.js +46 -10
  47. package/dist/commands/compute/undelegate.js.map +1 -1
  48. package/package.json +2 -2
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/commands/compute/app/releases.ts
4
4
  import { Command, Args, Flags as Flags2 } from "@oclif/core";
5
- import { getEnvironmentConfig as getEnvironmentConfig2, UserApiClient as UserApiClient3 } from "@layr-labs/ecloud-sdk";
5
+ import { getEnvironmentConfig as getEnvironmentConfig3, UserApiClient as UserApiClient3 } from "@layr-labs/ecloud-sdk";
6
6
 
7
7
  // src/flags.ts
8
8
  import { Flags } from "@oclif/core";
@@ -14,9 +14,9 @@ import fs3 from "fs";
14
14
  import path3 from "path";
15
15
  import os3 from "os";
16
16
  import { isAddress as isAddress2 } from "viem";
17
- import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
17
+ import { privateKeyToAccount as privateKeyToAccount3 } from "viem/accounts";
18
18
  import {
19
- getEnvironmentConfig,
19
+ getEnvironmentConfig as getEnvironmentConfig2,
20
20
  getAvailableEnvironments,
21
21
  isEnvironmentAvailable,
22
22
  getAllAppsByDeveloper as getAllAppsByDeveloper2,
@@ -33,12 +33,43 @@ import {
33
33
 
34
34
  // src/utils/appResolver.ts
35
35
  import { isAddress } from "viem";
36
- import { privateKeyToAccount } from "viem/accounts";
36
+ import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
37
37
  import {
38
38
  UserApiClient,
39
39
  getAllAppsByDeveloper
40
40
  } from "@layr-labs/ecloud-sdk";
41
41
 
42
+ // src/utils/viemClients.ts
43
+ import {
44
+ createPublicClient,
45
+ http
46
+ } from "viem";
47
+ import { privateKeyToAccount } from "viem/accounts";
48
+ import {
49
+ getEnvironmentConfig,
50
+ addHexPrefix,
51
+ createViemClients as sdkCreateViemClients,
52
+ getChainFromID
53
+ } from "@layr-labs/ecloud-sdk";
54
+ function createViemClients(options) {
55
+ const privateKey = addHexPrefix(options.privateKey);
56
+ const environmentConfig = getEnvironmentConfig(options.environment);
57
+ const rpcUrl = options.rpcUrl || environmentConfig.defaultRPCURL;
58
+ const chain = getChainFromID(environmentConfig.chainID);
59
+ const { publicClient, walletClient } = sdkCreateViemClients({
60
+ privateKey,
61
+ rpcUrl,
62
+ chainId: environmentConfig.chainID
63
+ });
64
+ const account = privateKeyToAccount(privateKey);
65
+ return {
66
+ publicClient,
67
+ walletClient,
68
+ chain,
69
+ address: account.address
70
+ };
71
+ }
72
+
42
73
  // src/utils/globalConfig.ts
43
74
  import * as fs from "fs";
44
75
  import * as path from "path";
@@ -205,7 +236,7 @@ function listApps(environment) {
205
236
 
206
237
  // src/utils/version.ts
207
238
  function getCliVersion() {
208
- return true ? "0.2.0" : "0.0.0";
239
+ return true ? "0.2.2-dev" : "0.0.0";
209
240
  }
210
241
  function getClientId() {
211
242
  return `ecloud-cli/v${getCliVersion()}`;
@@ -228,7 +259,7 @@ async function getAppInfosChunked(userApiClient, appIds, addressCount) {
228
259
  }
229
260
 
230
261
  // src/utils/prompts.ts
231
- function addHexPrefix(value) {
262
+ function addHexPrefix2(value) {
232
263
  if (value.startsWith("0x")) {
233
264
  return value;
234
265
  }
@@ -292,7 +323,7 @@ async function getOrPromptAppID(appIDOrOptions, environment) {
292
323
  };
293
324
  }
294
325
  if (options.appID) {
295
- const normalized = typeof options.appID === "string" ? addHexPrefix(options.appID) : options.appID;
326
+ const normalized = typeof options.appID === "string" ? addHexPrefix2(options.appID) : options.appID;
296
327
  if (isAddress2(normalized)) {
297
328
  return normalized;
298
329
  }
@@ -308,7 +339,7 @@ async function getOrPromptAppID(appIDOrOptions, environment) {
308
339
  const apps = listApps(options.environment);
309
340
  const foundAppID = apps[options.appID];
310
341
  if (foundAppID) {
311
- return addHexPrefix(foundAppID);
342
+ return addHexPrefix2(foundAppID);
312
343
  }
313
344
  throw new Error(
314
345
  `App name '${options.appID}' not found in environment '${options.environment}'`
@@ -319,18 +350,23 @@ async function getOrPromptAppID(appIDOrOptions, environment) {
319
350
  async function getAppIDInteractive(options) {
320
351
  const action = options.action || "view";
321
352
  const environment = options.environment || "sepolia";
322
- const environmentConfig = getEnvironmentConfig(environment);
353
+ const environmentConfig = getEnvironmentConfig2(environment);
323
354
  if (!options.privateKey || !options.rpcUrl) {
324
355
  return getAppIDInteractiveFromRegistry(environment, action);
325
356
  }
326
357
  console.log(`
327
358
  Select an app to ${action}:
328
359
  `);
329
- const privateKeyHex = addHexPrefix(options.privateKey);
330
- const account = privateKeyToAccount2(privateKeyHex);
360
+ const privateKeyHex = addHexPrefix2(options.privateKey);
361
+ const account = privateKeyToAccount3(privateKeyHex);
331
362
  const developerAddr = account.address;
363
+ const { publicClient, walletClient } = createViemClients({
364
+ privateKey: options.privateKey,
365
+ rpcUrl: options.rpcUrl,
366
+ environment
367
+ });
332
368
  const { apps, appConfigs } = await getAllAppsByDeveloper2(
333
- options.rpcUrl,
369
+ publicClient,
334
370
  environmentConfig,
335
371
  developerAddr
336
372
  );
@@ -343,9 +379,9 @@ Select an app to ${action}:
343
379
  try {
344
380
  const userApiClient = new UserApiClient2(
345
381
  environmentConfig,
346
- options.privateKey,
347
- options.rpcUrl,
348
- getClientId()
382
+ walletClient,
383
+ publicClient,
384
+ { clientId: getClientId() }
349
385
  );
350
386
  const appInfos = await getAppInfosChunked(userApiClient, apps);
351
387
  const freshProfiles = {};
@@ -469,14 +505,14 @@ async function getAppIDInteractiveFromRegistry(environment, action) {
469
505
  if (!value) {
470
506
  return "App ID or name cannot be empty";
471
507
  }
472
- const normalized2 = addHexPrefix(value);
508
+ const normalized2 = addHexPrefix2(value);
473
509
  if (isAddress2(normalized2)) {
474
510
  return true;
475
511
  }
476
512
  return "Invalid app ID address";
477
513
  }
478
514
  });
479
- const normalized = addHexPrefix(appIDInput);
515
+ const normalized = addHexPrefix2(appIDInput);
480
516
  if (isAddress2(normalized)) {
481
517
  return normalized;
482
518
  }
@@ -512,7 +548,7 @@ Select an app to ${action}:`);
512
548
  if (!value) {
513
549
  return "App ID or name cannot be empty";
514
550
  }
515
- const normalized2 = addHexPrefix(value);
551
+ const normalized2 = addHexPrefix2(value);
516
552
  if (isAddress2(normalized2)) {
517
553
  return true;
518
554
  }
@@ -522,17 +558,17 @@ Select an app to ${action}:`);
522
558
  return "Invalid app ID or name not found";
523
559
  }
524
560
  });
525
- const normalized = addHexPrefix(appIDInput);
561
+ const normalized = addHexPrefix2(appIDInput);
526
562
  if (isAddress2(normalized)) {
527
563
  return normalized;
528
564
  }
529
565
  const foundAppID = allApps[appIDInput];
530
566
  if (foundAppID) {
531
- return addHexPrefix(foundAppID);
567
+ return addHexPrefix2(foundAppID);
532
568
  }
533
569
  throw new Error(`Failed to resolve app ID from input: ${appIDInput}`);
534
570
  }
535
- return addHexPrefix(selected);
571
+ return addHexPrefix2(selected);
536
572
  }
537
573
  async function getPrivateKeyInteractive(privateKey) {
538
574
  if (privateKey) {
@@ -564,7 +600,7 @@ async function getPrivateKeyInteractive(privateKey) {
564
600
  async function getEnvironmentInteractive(environment) {
565
601
  if (environment) {
566
602
  try {
567
- getEnvironmentConfig(environment);
603
+ getEnvironmentConfig2(environment);
568
604
  if (!isEnvironmentAvailable(environment)) {
569
605
  throw new Error(`Environment ${environment} is not available in this build`);
570
606
  }
@@ -577,7 +613,7 @@ async function getEnvironmentInteractive(environment) {
577
613
  const configDefaultEnv = getDefaultEnvironment();
578
614
  if (configDefaultEnv && availableEnvs.includes(configDefaultEnv)) {
579
615
  try {
580
- getEnvironmentConfig(configDefaultEnv);
616
+ getEnvironmentConfig2(configDefaultEnv);
581
617
  defaultEnv = configDefaultEnv;
582
618
  } catch {
583
619
  }
@@ -835,15 +871,7 @@ function formatAppRelease(release, index) {
835
871
  return lines;
836
872
  }
837
873
 
838
- // src/commands/compute/app/releases.ts
839
- import { isAddress as isAddress3 } from "viem";
840
- import Table from "cli-table3";
841
-
842
874
  // src/utils/cliFormat.ts
843
- function terminalWidth(fallback = 120) {
844
- const cols = typeof process.stdout.columns === "number" ? process.stdout.columns : void 0;
845
- return cols && cols > 0 ? cols : fallback;
846
- }
847
875
  function formatHumanTime(value) {
848
876
  const raw = String(value ?? "").trim();
849
877
  if (!raw) return "-";
@@ -958,13 +986,9 @@ var AppReleases = class _AppReleases extends Command {
958
986
  async run() {
959
987
  return withTelemetry(this, async () => {
960
988
  const { args, flags } = await this.parse(_AppReleases);
961
- const rawAppId = args["app-id"];
962
- const needsPrivateKey = !rawAppId || !isAddress3(rawAppId);
963
- const validatedFlags = await validateCommonFlags(flags, {
964
- requirePrivateKey: needsPrivateKey
965
- });
989
+ const validatedFlags = await validateCommonFlags(flags);
966
990
  const environment = validatedFlags.environment || "sepolia";
967
- const environmentConfig = getEnvironmentConfig2(environment);
991
+ const environmentConfig = getEnvironmentConfig3(environment);
968
992
  const rpcUrl = validatedFlags["rpc-url"] || environmentConfig.defaultRPCURL;
969
993
  const privateKey = validatedFlags["private-key"];
970
994
  const appID = await getOrPromptAppID({
@@ -974,7 +998,14 @@ var AppReleases = class _AppReleases extends Command {
974
998
  rpcUrl,
975
999
  action: "view releases for"
976
1000
  });
977
- const userApiClient = new UserApiClient3(environmentConfig, privateKey, rpcUrl, getClientId());
1001
+ const { publicClient, walletClient } = createViemClients({
1002
+ privateKey,
1003
+ rpcUrl,
1004
+ environment
1005
+ });
1006
+ const userApiClient = new UserApiClient3(environmentConfig, walletClient, publicClient, {
1007
+ clientId: getClientId()
1008
+ });
978
1009
  const data = await userApiClient.getApp(appID);
979
1010
  const releases = sortReleasesOldestFirst(data.releases);
980
1011
  if (releases.length === 0) {
@@ -999,7 +1030,8 @@ ${separator()}
999
1030
  }
1000
1031
  return;
1001
1032
  }
1002
- const rows = releases.map((r, i) => {
1033
+ for (let i = 0; i < releases.length; i++) {
1034
+ const r = releases[i];
1003
1035
  const rel = r.rmsReleaseId ?? String(i);
1004
1036
  const block = r.createdAtBlock ? String(r.createdAtBlock) : "-";
1005
1037
  const created = r.createdAt ? formatHumanTime(r.createdAt) : "-";
@@ -1009,89 +1041,19 @@ ${separator()}
1009
1041
  const image = formatImageDisplay(r.build?.imageUrl ?? r.registryUrl ?? "-");
1010
1042
  const build = r.build?.buildId ?? "-";
1011
1043
  const prov = provenanceSummaryFromBuild(r.build);
1012
- const depCount = r.build?.dependencies ? Object.keys(r.build.dependencies).length : 0;
1013
- const deps = depCount > 0 ? `deps:${depCount}` : "-";
1014
- return { rel, block, created, repo, commit, digest, image, build, prov, deps };
1015
- });
1016
- const headers = {
1017
- rel: chalk2.bold("Rel"),
1018
- block: chalk2.bold("Block"),
1019
- created: chalk2.bold("Created"),
1020
- repo: chalk2.bold("Repo"),
1021
- commit: chalk2.bold("Commit"),
1022
- digest: chalk2.bold("Digest"),
1023
- image: chalk2.bold("Image"),
1024
- build: chalk2.bold("Build"),
1025
- prov: chalk2.bold("Prov"),
1026
- deps: chalk2.bold("Deps")
1027
- };
1028
- const tw = terminalWidth();
1029
- const shouldStack = tw < 140;
1030
- if (shouldStack) {
1031
- for (const r of rows) {
1032
- this.log(`${chalk2.cyan(r.rel)} ${r.created} (block ${r.block})`);
1033
- this.log(` Repo: ${r.repo}`);
1034
- this.log(` Commit: ${r.commit}`);
1035
- this.log(` Digest: ${r.digest}`);
1036
- this.log(` Image: ${r.image}`);
1037
- this.log(` Build: ${r.build}`);
1038
- this.log(` Provenance: ${r.prov}`);
1039
- const relObj = releases.find((x, idx) => (x.rmsReleaseId ?? String(idx)) === r.rel);
1040
- const depLines = formatDepLines(relObj?.build?.dependencies);
1041
- if (depLines.length) {
1042
- for (const l of depLines) this.log(l);
1043
- }
1044
- this.log(chalk2.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
1044
+ this.log(`${chalk2.cyan(rel)} ${created} (block ${block})`);
1045
+ this.log(` Repo: ${repo}`);
1046
+ this.log(` Commit: ${commit}`);
1047
+ this.log(` Digest: ${digest}`);
1048
+ this.log(` Image: ${image}`);
1049
+ this.log(` Build: ${build}`);
1050
+ this.log(` Provenance: ${prov}`);
1051
+ const depLines = formatDepLines(r.build?.dependencies);
1052
+ if (depLines.length) {
1053
+ for (const l of depLines) this.log(l);
1045
1054
  }
1046
- this.log("");
1047
- this.log(
1048
- chalk2.gray(
1049
- `Tip: use ${chalk2.yellow("--full")} for detailed release output, ${chalk2.yellow(
1050
- "--json"
1051
- )} to copy/paste, and ${chalk2.yellow(
1052
- "ecloud compute build info <buildId>"
1053
- )} for full build/provenance details.`
1054
- )
1055
- );
1056
- return;
1057
- }
1058
- const fixed = 6 + 10 + 20 + 36 + 12 + 8 + 10;
1059
- const remaining = Math.max(60, tw - fixed);
1060
- const repoW = Math.max(18, Math.floor(remaining * 0.25));
1061
- const digestW = Math.max(18, Math.floor(remaining * 0.35));
1062
- const imageW = Math.max(18, remaining - repoW - digestW);
1063
- const table = new Table({
1064
- head: [
1065
- headers.rel,
1066
- headers.block,
1067
- headers.created,
1068
- headers.repo,
1069
- headers.commit,
1070
- headers.digest,
1071
- headers.image,
1072
- headers.build,
1073
- headers.prov,
1074
- headers.deps
1075
- ],
1076
- colWidths: [6, 10, 20, repoW, 10, digestW, imageW, 36, 12, 8],
1077
- wordWrap: true,
1078
- style: { "padding-left": 0, "padding-right": 1, head: [], border: [] }
1079
- });
1080
- for (const r of rows) {
1081
- table.push([
1082
- r.rel,
1083
- r.block,
1084
- r.created,
1085
- r.repo,
1086
- r.commit,
1087
- r.digest,
1088
- r.image,
1089
- r.build,
1090
- r.prov,
1091
- r.deps
1092
- ]);
1055
+ this.log(chalk2.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
1093
1056
  }
1094
- this.log(table.toString());
1095
1057
  this.log("");
1096
1058
  this.log(
1097
1059
  chalk2.gray(