@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/deploy.ts
4
4
  import { Command, Flags as Flags2 } from "@oclif/core";
5
- import { getEnvironmentConfig as getEnvironmentConfig3, UserApiClient as UserApiClient3, isMainnet } from "@layr-labs/ecloud-sdk";
5
+ import { getEnvironmentConfig as getEnvironmentConfig4, UserApiClient as UserApiClient3, isMainnet } from "@layr-labs/ecloud-sdk";
6
6
 
7
7
  // src/telemetry.ts
8
8
  import {
@@ -185,9 +185,9 @@ import fs3 from "fs";
185
185
  import path3 from "path";
186
186
  import os3 from "os";
187
187
  import { isAddress as isAddress2 } from "viem";
188
- import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
188
+ import { privateKeyToAccount as privateKeyToAccount3 } from "viem/accounts";
189
189
  import {
190
- getEnvironmentConfig,
190
+ getEnvironmentConfig as getEnvironmentConfig2,
191
191
  getAvailableEnvironments,
192
192
  isEnvironmentAvailable,
193
193
  getAllAppsByDeveloper as getAllAppsByDeveloper2,
@@ -204,12 +204,43 @@ import {
204
204
 
205
205
  // src/utils/appResolver.ts
206
206
  import { isAddress } from "viem";
207
- import { privateKeyToAccount } from "viem/accounts";
207
+ import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
208
208
  import {
209
209
  UserApiClient,
210
210
  getAllAppsByDeveloper
211
211
  } from "@layr-labs/ecloud-sdk";
212
212
 
213
+ // src/utils/viemClients.ts
214
+ import {
215
+ createPublicClient,
216
+ http
217
+ } from "viem";
218
+ import { privateKeyToAccount } from "viem/accounts";
219
+ import {
220
+ getEnvironmentConfig,
221
+ addHexPrefix,
222
+ createViemClients as sdkCreateViemClients,
223
+ getChainFromID
224
+ } from "@layr-labs/ecloud-sdk";
225
+ function createViemClients(options) {
226
+ const privateKey = addHexPrefix(options.privateKey);
227
+ const environmentConfig = getEnvironmentConfig(options.environment);
228
+ const rpcUrl = options.rpcUrl || environmentConfig.defaultRPCURL;
229
+ const chain = getChainFromID(environmentConfig.chainID);
230
+ const { publicClient, walletClient } = sdkCreateViemClients({
231
+ privateKey,
232
+ rpcUrl,
233
+ chainId: environmentConfig.chainID
234
+ });
235
+ const account = privateKeyToAccount(privateKey);
236
+ return {
237
+ publicClient,
238
+ walletClient,
239
+ chain,
240
+ address: account.address
241
+ };
242
+ }
243
+
213
244
  // src/utils/appNames.ts
214
245
  import * as fs2 from "fs";
215
246
  import * as path2 from "path";
@@ -273,7 +304,7 @@ function findAvailableName(environment, baseName) {
273
304
 
274
305
  // src/utils/version.ts
275
306
  function getCliVersion() {
276
- return true ? "0.2.0" : "0.0.0";
307
+ return true ? "0.2.2-dev" : "0.0.0";
277
308
  }
278
309
  function getClientId() {
279
310
  return `ecloud-cli/v${getCliVersion()}`;
@@ -694,7 +725,12 @@ async function getOrPromptAppName(appName, environment, imageRef, suggestedBaseN
694
725
  return appName;
695
726
  }
696
727
  console.log(`Warning: App name '${appName}' is already taken.`);
697
- return getAvailableAppNameInteractive(environment, imageRef, suggestedBaseName, skipDefaultName);
728
+ return getAvailableAppNameInteractive(
729
+ environment,
730
+ imageRef,
731
+ suggestedBaseName,
732
+ skipDefaultName
733
+ );
698
734
  }
699
735
  return getAvailableAppNameInteractive(environment, imageRef, suggestedBaseName, skipDefaultName);
700
736
  }
@@ -857,7 +893,7 @@ async function getPrivateKeyInteractive(privateKey) {
857
893
  async function getEnvironmentInteractive(environment) {
858
894
  if (environment) {
859
895
  try {
860
- getEnvironmentConfig(environment);
896
+ getEnvironmentConfig2(environment);
861
897
  if (!isEnvironmentAvailable(environment)) {
862
898
  throw new Error(`Environment ${environment} is not available in this build`);
863
899
  }
@@ -870,7 +906,7 @@ async function getEnvironmentInteractive(environment) {
870
906
  const configDefaultEnv = getDefaultEnvironment();
871
907
  if (configDefaultEnv && availableEnvs.includes(configDefaultEnv)) {
872
908
  try {
873
- getEnvironmentConfig(configDefaultEnv);
909
+ getEnvironmentConfig2(configDefaultEnv);
874
910
  defaultEnv = configDefaultEnv;
875
911
  } catch {
876
912
  }
@@ -973,12 +1009,14 @@ async function getAppProfileInteractive(defaultName = "", allowRetry = true) {
973
1009
  const description = await getAppDescriptionInteractive();
974
1010
  const xURL = await getAppXURLInteractive();
975
1011
  const imagePath = await getAppImageInteractive();
1012
+ const { image, imageName } = imagePathToBlob(imagePath);
976
1013
  const profile = {
977
1014
  name,
978
1015
  website,
979
1016
  description,
980
1017
  xURL,
981
- imagePath
1018
+ image,
1019
+ imageName
982
1020
  };
983
1021
  console.log("\n" + formatProfileForDisplay(profile));
984
1022
  const confirmed = await inquirerConfirm({
@@ -1113,12 +1151,25 @@ function formatProfileForDisplay(profile) {
1113
1151
  output += ` X URL: ${profile.xURL}
1114
1152
  `;
1115
1153
  }
1116
- if (profile.imagePath) {
1117
- output += ` Image: ${profile.imagePath}
1154
+ if (profile.imageName) {
1155
+ output += ` Image: ${profile.imageName}
1118
1156
  `;
1119
1157
  }
1120
1158
  return output;
1121
1159
  }
1160
+ function imagePathToBlob(imagePath) {
1161
+ if (!imagePath) {
1162
+ return { image: void 0, imageName: void 0 };
1163
+ }
1164
+ try {
1165
+ const fileBuffer = fs3.readFileSync(imagePath);
1166
+ const imageName = path3.basename(imagePath);
1167
+ return { image: new Blob([fileBuffer]), imageName };
1168
+ } catch (err) {
1169
+ console.error(`Failed to read image file: ${err}`);
1170
+ return { image: void 0, imageName: void 0 };
1171
+ }
1172
+ }
1122
1173
 
1123
1174
  // src/flags.ts
1124
1175
  var commonFlags = {
@@ -1157,14 +1208,14 @@ import {
1157
1208
  createComputeModule,
1158
1209
  createBillingModule,
1159
1210
  createBuildModule,
1160
- getEnvironmentConfig as getEnvironmentConfig2,
1211
+ getEnvironmentConfig as getEnvironmentConfig3,
1161
1212
  requirePrivateKey,
1162
1213
  getPrivateKeyWithSource
1163
1214
  } from "@layr-labs/ecloud-sdk";
1164
1215
  async function createComputeClient(flags) {
1165
1216
  flags = await validateCommonFlags(flags);
1166
1217
  const environment = flags.environment;
1167
- const environmentConfig = getEnvironmentConfig2(environment);
1218
+ const environmentConfig = getEnvironmentConfig3(environment);
1168
1219
  const rpcUrl = flags["rpc-url"] || environmentConfig.defaultRPCURL;
1169
1220
  const { key: privateKey, source } = await requirePrivateKey({
1170
1221
  privateKey: flags["private-key"]
@@ -1172,10 +1223,15 @@ async function createComputeClient(flags) {
1172
1223
  if (flags.verbose) {
1173
1224
  console.log(`Using private key from: ${source}`);
1174
1225
  }
1175
- return createComputeModule({
1176
- verbose: flags.verbose,
1226
+ const { walletClient, publicClient } = createViemClients({
1177
1227
  privateKey,
1178
1228
  rpcUrl,
1229
+ environment
1230
+ });
1231
+ return createComputeModule({
1232
+ verbose: flags.verbose,
1233
+ walletClient,
1234
+ publicClient,
1179
1235
  environment,
1180
1236
  clientId: getClientId(),
1181
1237
  skipTelemetry: true
@@ -1184,10 +1240,21 @@ async function createComputeClient(flags) {
1184
1240
  }
1185
1241
  async function createBuildClient(flags) {
1186
1242
  flags = await validateCommonFlags(flags, { requirePrivateKey: false });
1243
+ const environment = flags.environment || "mainnet";
1244
+ const environmentConfig = getEnvironmentConfig3(environment);
1245
+ const rpcUrl = flags["rpc-url"] || environmentConfig.defaultRPCURL;
1246
+ let walletClient;
1247
+ if (flags["private-key"]) {
1248
+ walletClient = createViemClients({
1249
+ privateKey: flags["private-key"],
1250
+ rpcUrl,
1251
+ environment
1252
+ }).walletClient;
1253
+ }
1187
1254
  return createBuildModule({
1188
1255
  verbose: flags.verbose,
1189
- privateKey: flags["private-key"],
1190
- environment: flags.environment,
1256
+ walletClient,
1257
+ environment,
1191
1258
  clientId: getClientId(),
1192
1259
  skipTelemetry: true
1193
1260
  // CLI already has telemetry, skip SDK telemetry
@@ -1272,6 +1339,17 @@ async function runVerifiableBuildAndVerify(client, request, options = {}) {
1272
1339
  return { build, verified: verify };
1273
1340
  }
1274
1341
 
1342
+ // src/utils/dashboard.ts
1343
+ var DASHBOARD_URLS = {
1344
+ "sepolia-dev": "https://compute-dashboard-sepolia-dev.vercel.app",
1345
+ sepolia: "https://verify-sepolia.eigencloud.xyz",
1346
+ "mainnet-alpha": "https://verify.eigencloud.xyz"
1347
+ };
1348
+ function getDashboardUrl(environment, appAddress) {
1349
+ const baseUrl = DASHBOARD_URLS[environment] || DASHBOARD_URLS["sepolia"];
1350
+ return `${baseUrl}/app/${appAddress}`;
1351
+ }
1352
+
1275
1353
  // src/utils/dockerhub.ts
1276
1354
  var DOCKERHUB_OWNER = "eigenlayer";
1277
1355
  var DOCKERHUB_REPO = "eigencloud-containers";
@@ -1454,6 +1532,11 @@ var AppDeploy = class _AppDeploy extends Command {
1454
1532
  "build-dependencies": Flags2.string({
1455
1533
  description: "Dependency digests for verifiable build (git source mode) (sha256:...)",
1456
1534
  multiple: true
1535
+ }),
1536
+ "build-caddyfile": Flags2.string({
1537
+ description: "Optional path to Caddyfile inside the repo (relative to build context). If omitted, auto-detected from env file TLS settings",
1538
+ required: false,
1539
+ env: "ECLOUD_BUILD_CADDYFILE"
1457
1540
  })
1458
1541
  };
1459
1542
  async run() {
@@ -1461,7 +1544,7 @@ var AppDeploy = class _AppDeploy extends Command {
1461
1544
  const { flags } = await this.parse(_AppDeploy);
1462
1545
  const compute = await createComputeClient(flags);
1463
1546
  const environment = flags.environment;
1464
- const environmentConfig = getEnvironmentConfig3(environment);
1547
+ const environmentConfig = getEnvironmentConfig4(environment);
1465
1548
  const rpcUrl = flags["rpc-url"] || environmentConfig.defaultRPCURL;
1466
1549
  const privateKey = flags["private-key"];
1467
1550
  let buildClient;
@@ -1528,7 +1611,7 @@ var AppDeploy = class _AppDeploy extends Command {
1528
1611
  repoUrl: flags.repo,
1529
1612
  gitRef: flags.commit,
1530
1613
  dockerfilePath: flags["build-dockerfile"],
1531
- caddyfilePath: void 0,
1614
+ caddyfilePath: flags["build-caddyfile"],
1532
1615
  buildContextPath: flags["build-context"],
1533
1616
  dependencies: flags["build-dependencies"]
1534
1617
  } : await promptVerifiableGitSourceInputs();
@@ -1650,20 +1733,19 @@ ${chalk.gray(`Deployment cancelled`)}`);
1650
1733
  return;
1651
1734
  }
1652
1735
  }
1653
- const res = await compute.app.executeDeploy(prepared, {
1654
- maxFeePerGas: gasEstimate.maxFeePerGas,
1655
- maxPriorityFeePerGas: gasEstimate.maxPriorityFeePerGas
1656
- });
1736
+ const res = await compute.app.executeDeploy(prepared, gasEstimate);
1657
1737
  if (!flags["skip-profile"]) {
1658
1738
  const hasProfileFlags = flags.website || flags.description || flags["x-url"] || flags.image;
1659
1739
  let profile = null;
1660
1740
  if (hasProfileFlags) {
1741
+ const { image, imageName } = imagePathToBlob(flags.image);
1661
1742
  profile = {
1662
1743
  name: appName,
1663
1744
  website: flags.website,
1664
1745
  description: flags.description,
1665
1746
  xURL: flags["x-url"],
1666
- imagePath: flags.image
1747
+ image,
1748
+ imageName
1667
1749
  };
1668
1750
  } else {
1669
1751
  this.log(
@@ -1705,12 +1787,25 @@ ${chalk.gray(`Deployment cancelled`)}`);
1705
1787
  `
1706
1788
  \u2705 ${chalk.green(`App deployed successfully ${chalk.bold(`(id: ${res.appId}, ip: ${ipAddress})`)}`)}`
1707
1789
  );
1790
+ const dashboardUrl = getDashboardUrl(environment, res.appId);
1791
+ this.log(`
1792
+ ${chalk.gray("View your app:")} ${chalk.blue.underline(dashboardUrl)}`);
1708
1793
  });
1709
1794
  }
1710
1795
  };
1711
1796
  async function fetchAvailableInstanceTypes(environmentConfig, privateKey, rpcUrl) {
1712
1797
  try {
1713
- const userApiClient = new UserApiClient3(environmentConfig, privateKey, rpcUrl, getClientId());
1798
+ const { publicClient, walletClient } = createViemClients({
1799
+ privateKey,
1800
+ rpcUrl,
1801
+ environment: environmentConfig.name
1802
+ });
1803
+ const userApiClient = new UserApiClient3(
1804
+ environmentConfig,
1805
+ walletClient,
1806
+ publicClient,
1807
+ { clientId: getClientId() }
1808
+ );
1714
1809
  const skuList = await userApiClient.getSKUs();
1715
1810
  if (skuList.skus.length === 0) {
1716
1811
  throw new Error("No instance types available from server");