@layr-labs/ecloud-cli 0.1.0-dev.3 → 0.1.0-rc.2

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 (53) hide show
  1. package/README.md +4 -4
  2. package/VERSION +2 -2
  3. package/dist/commands/auth/generate.js +46 -184
  4. package/dist/commands/auth/generate.js.map +1 -1
  5. package/dist/commands/auth/login.js +93 -234
  6. package/dist/commands/auth/login.js.map +1 -1
  7. package/dist/commands/auth/logout.js +30 -170
  8. package/dist/commands/auth/logout.js.map +1 -1
  9. package/dist/commands/auth/migrate.js +76 -216
  10. package/dist/commands/auth/migrate.js.map +1 -1
  11. package/dist/commands/auth/whoami.js +17 -145
  12. package/dist/commands/auth/whoami.js.map +1 -1
  13. package/dist/commands/billing/cancel.js +30 -164
  14. package/dist/commands/billing/cancel.js.map +1 -1
  15. package/dist/commands/billing/status.js +80 -213
  16. package/dist/commands/billing/status.js.map +1 -1
  17. package/dist/commands/billing/subscribe.js +45 -179
  18. package/dist/commands/billing/subscribe.js.map +1 -1
  19. package/dist/commands/compute/app/create.js +20 -148
  20. package/dist/commands/compute/app/create.js.map +1 -1
  21. package/dist/commands/compute/app/deploy.js +145 -243
  22. package/dist/commands/compute/app/deploy.js.map +1 -1
  23. package/dist/commands/compute/app/info.js +1 -2
  24. package/dist/commands/compute/app/info.js.map +1 -1
  25. package/dist/commands/compute/app/list.js +111 -194
  26. package/dist/commands/compute/app/list.js.map +1 -1
  27. package/dist/commands/compute/app/logs.js +20 -105
  28. package/dist/commands/compute/app/logs.js.map +1 -1
  29. package/dist/commands/compute/app/profile/set.js +64 -153
  30. package/dist/commands/compute/app/profile/set.js.map +1 -1
  31. package/dist/commands/compute/app/start.js +43 -132
  32. package/dist/commands/compute/app/start.js.map +1 -1
  33. package/dist/commands/compute/app/stop.js +43 -132
  34. package/dist/commands/compute/app/stop.js.map +1 -1
  35. package/dist/commands/compute/app/terminate.js +44 -131
  36. package/dist/commands/compute/app/terminate.js.map +1 -1
  37. package/dist/commands/compute/app/upgrade.js +108 -209
  38. package/dist/commands/compute/app/upgrade.js.map +1 -1
  39. package/dist/commands/compute/environment/list.js +12 -104
  40. package/dist/commands/compute/environment/list.js.map +1 -1
  41. package/dist/commands/compute/environment/set.js +18 -103
  42. package/dist/commands/compute/environment/set.js.map +1 -1
  43. package/dist/commands/compute/environment/show.js +30 -122
  44. package/dist/commands/compute/environment/show.js.map +1 -1
  45. package/dist/commands/compute/undelegate.js +18 -112
  46. package/dist/commands/compute/undelegate.js.map +1 -1
  47. package/dist/commands/upgrade.js +19 -159
  48. package/dist/commands/upgrade.js.map +1 -1
  49. package/dist/commands/version.js +23 -163
  50. package/dist/commands/version.js.map +1 -1
  51. package/package.json +2 -2
  52. package/dist/commands/telemetry.js +0 -213
  53. package/dist/commands/telemetry.js.map +0 -1
@@ -11,15 +11,38 @@ import {
11
11
  watchDeployment
12
12
  } from "@layr-labs/ecloud-sdk";
13
13
 
14
- // src/telemetry.ts
14
+ // src/flags.ts
15
+ import { Flags } from "@oclif/core";
16
+
17
+ // src/utils/prompts.ts
18
+ import { input, select, password, confirm as inquirerConfirm } from "@inquirer/prompts";
19
+ import fs3 from "fs";
20
+ import path3 from "path";
21
+ import os3 from "os";
22
+ import { isAddress as isAddress2 } from "viem";
23
+ import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
15
24
  import {
16
- createTelemetryClient,
17
- createAppEnvironment,
18
- createMetricsContext,
19
- addMetric,
20
- addMetricWithDimensions,
21
- emitMetrics,
22
- getBuildType as getBuildType2
25
+ getEnvironmentConfig,
26
+ getAvailableEnvironments,
27
+ isEnvironmentAvailable,
28
+ getAllAppsByDeveloper as getAllAppsByDeveloper2,
29
+ getCategoryDescriptions,
30
+ fetchTemplateCatalog,
31
+ PRIMARY_LANGUAGES,
32
+ validateAppName,
33
+ validateImageReference,
34
+ validateFilePath,
35
+ validatePrivateKeyFormat,
36
+ extractAppNameFromImage,
37
+ UserApiClient as UserApiClient2
38
+ } from "@layr-labs/ecloud-sdk";
39
+
40
+ // src/utils/appResolver.ts
41
+ import { isAddress } from "viem";
42
+ import { privateKeyToAccount } from "viem/accounts";
43
+ import {
44
+ UserApiClient,
45
+ getAllAppsByDeveloper
23
46
  } from "@layr-labs/ecloud-sdk";
24
47
 
25
48
  // src/utils/globalConfig.ts
@@ -28,7 +51,6 @@ import * as path from "path";
28
51
  import * as os from "os";
29
52
  import { load as loadYaml, dump as dumpYaml } from "js-yaml";
30
53
  import { getBuildType } from "@layr-labs/ecloud-sdk";
31
- import * as crypto from "crypto";
32
54
  var GLOBAL_CONFIG_FILE = "config.yaml";
33
55
  var PROFILE_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
34
56
  function getGlobalConfigDir() {
@@ -71,14 +93,6 @@ function saveGlobalConfig(config) {
71
93
  const content = dumpYaml(config, { lineWidth: -1 });
72
94
  fs.writeFileSync(configPath, content, { mode: 420 });
73
95
  }
74
- function getDefaultEnvironment() {
75
- const config = loadGlobalConfig();
76
- return config.default_environment;
77
- }
78
- function getGlobalTelemetryPreference() {
79
- const config = loadGlobalConfig();
80
- return config.telemetry_enabled;
81
- }
82
96
  function invalidateProfileCache(environment) {
83
97
  const config = loadGlobalConfig();
84
98
  if (!config.profile_cache) {
@@ -91,107 +105,6 @@ function invalidateProfileCache(environment) {
91
105
  }
92
106
  saveGlobalConfig(config);
93
107
  }
94
- function getOrCreateUserUUID() {
95
- const config = loadGlobalConfig();
96
- if (config.user_uuid) {
97
- return config.user_uuid;
98
- }
99
- const uuid = generateUUID();
100
- config.user_uuid = uuid;
101
- config.first_run = false;
102
- saveGlobalConfig(config);
103
- return uuid;
104
- }
105
- function generateUUID() {
106
- const bytes = crypto.randomBytes(16);
107
- bytes[6] = bytes[6] & 15 | 64;
108
- bytes[8] = bytes[8] & 63 | 128;
109
- const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0"));
110
- return hex.slice(0, 4).join("") + hex.slice(4, 6).join("") + "-" + hex.slice(6, 8).join("") + "-" + hex.slice(8, 10).join("") + "-" + hex.slice(10, 12).join("") + "-" + hex.slice(12, 16).join("");
111
- }
112
-
113
- // src/telemetry.ts
114
- function createCLITelemetryClient() {
115
- const userUUID = getOrCreateUserUUID();
116
- const environment = createAppEnvironment(userUUID);
117
- const telemetryEnabled = getGlobalTelemetryPreference();
118
- return createTelemetryClient(environment, "ecloud-cli", {
119
- telemetryEnabled: telemetryEnabled === true
120
- // Only enabled if explicitly set to true
121
- });
122
- }
123
- async function withTelemetry(command, action) {
124
- const client = createCLITelemetryClient();
125
- const metrics = createMetricsContext();
126
- metrics.properties["source"] = "ecloud-cli";
127
- metrics.properties["command"] = command.id || command.constructor.name;
128
- const environment = getDefaultEnvironment() || "sepolia";
129
- metrics.properties["environment"] = environment;
130
- const buildType = getBuildType2() || "prod";
131
- metrics.properties["build_type"] = buildType;
132
- const cliVersion = command.config.version;
133
- if (cliVersion) {
134
- metrics.properties["cli_version"] = cliVersion;
135
- }
136
- addMetric(metrics, "Count", 1);
137
- let actionError;
138
- let result;
139
- try {
140
- result = await action();
141
- return result;
142
- } catch (err) {
143
- actionError = err instanceof Error ? err : new Error(String(err));
144
- throw err;
145
- } finally {
146
- const resultValue = actionError ? "Failure" : "Success";
147
- const dimensions = {};
148
- if (actionError) {
149
- dimensions["error"] = actionError.message;
150
- }
151
- addMetricWithDimensions(metrics, resultValue, 1, dimensions);
152
- const duration = Date.now() - metrics.startTime.getTime();
153
- addMetric(metrics, "DurationMilliseconds", duration);
154
- try {
155
- await emitMetrics(client, metrics);
156
- await client.close();
157
- } catch {
158
- }
159
- }
160
- }
161
-
162
- // src/flags.ts
163
- import { Flags } from "@oclif/core";
164
-
165
- // src/utils/prompts.ts
166
- import { input, select, password, confirm as inquirerConfirm } from "@inquirer/prompts";
167
- import fs3 from "fs";
168
- import path3 from "path";
169
- import os3 from "os";
170
- import { isAddress as isAddress2 } from "viem";
171
- import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
172
- import {
173
- getEnvironmentConfig,
174
- getAvailableEnvironments,
175
- isEnvironmentAvailable,
176
- getAllAppsByDeveloper as getAllAppsByDeveloper2,
177
- getCategoryDescriptions,
178
- fetchTemplateCatalog,
179
- PRIMARY_LANGUAGES,
180
- validateAppName,
181
- validateImageReference,
182
- validateFilePath,
183
- validatePrivateKeyFormat,
184
- extractAppNameFromImage,
185
- UserApiClient as UserApiClient2
186
- } from "@layr-labs/ecloud-sdk";
187
-
188
- // src/utils/appResolver.ts
189
- import { isAddress } from "viem";
190
- import { privateKeyToAccount } from "viem/accounts";
191
- import {
192
- UserApiClient,
193
- getAllAppsByDeveloper
194
- } from "@layr-labs/ecloud-sdk";
195
108
 
196
109
  // src/utils/appNames.ts
197
110
  import * as fs2 from "fs";
@@ -256,7 +169,7 @@ function findAvailableName(environment, baseName) {
256
169
 
257
170
  // src/utils/version.ts
258
171
  function getCliVersion() {
259
- return true ? "0.1.0-dev.3" : "0.0.0";
172
+ return true ? "0.1.0-rc.2" : "0.0.0";
260
173
  }
261
174
  function getClientId() {
262
175
  return `ecloud-cli/v${getCliVersion()}`;
@@ -1043,141 +956,130 @@ var AppDeploy = class _AppDeploy extends Command {
1043
956
  })
1044
957
  };
1045
958
  async run() {
1046
- return withTelemetry(this, async () => {
1047
- const { flags } = await this.parse(_AppDeploy);
1048
- const logger = {
1049
- info: (msg) => this.log(msg),
1050
- warn: (msg) => this.warn(msg),
1051
- error: (msg) => this.error(msg),
1052
- debug: (msg) => flags.verbose && this.log(msg)
1053
- };
1054
- const environment = flags.environment || "sepolia";
1055
- const environmentConfig = getEnvironmentConfig2(environment);
1056
- const rpcUrl = flags["rpc-url"] || environmentConfig.defaultRPCURL;
1057
- const privateKey = await getPrivateKeyInteractive(flags["private-key"]);
1058
- const dockerfilePath = await getDockerfileInteractive(flags.dockerfile);
1059
- const buildFromDockerfile = dockerfilePath !== "";
1060
- const imageRef = await getImageReferenceInteractive(flags["image-ref"], buildFromDockerfile);
1061
- const appName = await getOrPromptAppName(flags.name, environment, imageRef);
1062
- const envFilePath = await getEnvFileInteractive(flags["env-file"]);
1063
- const availableTypes = await fetchAvailableInstanceTypes(
1064
- environmentConfig,
959
+ const { flags } = await this.parse(_AppDeploy);
960
+ const logger = {
961
+ info: (msg) => this.log(msg),
962
+ warn: (msg) => this.warn(msg),
963
+ error: (msg) => this.error(msg),
964
+ debug: (msg) => flags.verbose && this.log(msg)
965
+ };
966
+ const environment = flags.environment || "sepolia";
967
+ const environmentConfig = getEnvironmentConfig2(environment);
968
+ const rpcUrl = flags["rpc-url"] || environmentConfig.defaultRPCURL;
969
+ const privateKey = await getPrivateKeyInteractive(flags["private-key"]);
970
+ const dockerfilePath = await getDockerfileInteractive(flags.dockerfile);
971
+ const buildFromDockerfile = dockerfilePath !== "";
972
+ const imageRef = await getImageReferenceInteractive(flags["image-ref"], buildFromDockerfile);
973
+ const appName = await getOrPromptAppName(flags.name, environment, imageRef);
974
+ const envFilePath = await getEnvFileInteractive(flags["env-file"]);
975
+ const availableTypes = await fetchAvailableInstanceTypes(environmentConfig, privateKey, rpcUrl);
976
+ const instanceType = await getInstanceTypeInteractive(
977
+ flags["instance-type"],
978
+ "",
979
+ // No default for new deployments
980
+ availableTypes
981
+ );
982
+ const logSettings = await getLogSettingsInteractive(
983
+ flags["log-visibility"]
984
+ );
985
+ const resourceUsageMonitoring = await getResourceUsageMonitoringInteractive(
986
+ flags["resource-usage-monitoring"]
987
+ );
988
+ const logVisibility = logSettings.publicLogs ? "public" : logSettings.logRedirect ? "private" : "off";
989
+ const { prepared, gasEstimate } = await prepareDeploy(
990
+ {
1065
991
  privateKey,
1066
- rpcUrl
1067
- );
1068
- const instanceType = await getInstanceTypeInteractive(
1069
- flags["instance-type"],
1070
- "",
1071
- // No default for new deployments
1072
- availableTypes
1073
- );
1074
- const logSettings = await getLogSettingsInteractive(
1075
- flags["log-visibility"]
1076
- );
1077
- const resourceUsageMonitoring = await getResourceUsageMonitoringInteractive(
1078
- flags["resource-usage-monitoring"]
1079
- );
1080
- const logVisibility = logSettings.publicLogs ? "public" : logSettings.logRedirect ? "private" : "off";
1081
- const { prepared, gasEstimate } = await prepareDeploy(
1082
- {
1083
- privateKey,
1084
- rpcUrl,
1085
- environment,
1086
- dockerfilePath,
1087
- imageRef,
1088
- envFilePath,
1089
- appName,
1090
- instanceType,
1091
- logVisibility,
1092
- resourceUsageMonitoring,
1093
- skipTelemetry: true
1094
- },
1095
- logger
1096
- );
1097
- this.log(`
992
+ rpcUrl,
993
+ environment,
994
+ dockerfilePath,
995
+ imageRef,
996
+ envFilePath,
997
+ appName,
998
+ instanceType,
999
+ logVisibility,
1000
+ resourceUsageMonitoring
1001
+ },
1002
+ logger
1003
+ );
1004
+ this.log(`
1098
1005
  Estimated transaction cost: ${chalk.cyan(gasEstimate.maxCostEth)} ETH`);
1099
- if (isMainnet(environmentConfig)) {
1100
- const confirmed = await confirm(`Continue with deployment?`);
1101
- if (!confirmed) {
1102
- this.log(`
1006
+ if (isMainnet(environmentConfig)) {
1007
+ const confirmed = await confirm(`Continue with deployment?`);
1008
+ if (!confirmed) {
1009
+ this.log(`
1103
1010
  ${chalk.gray(`Deployment cancelled`)}`);
1104
- return;
1011
+ return;
1012
+ }
1013
+ }
1014
+ const res = await executeDeploy(
1015
+ prepared,
1016
+ {
1017
+ maxFeePerGas: gasEstimate.maxFeePerGas,
1018
+ maxPriorityFeePerGas: gasEstimate.maxPriorityFeePerGas
1019
+ },
1020
+ logger
1021
+ );
1022
+ if (!flags["skip-profile"]) {
1023
+ const hasProfileFlags = flags.website || flags.description || flags["x-url"] || flags.image;
1024
+ let profile = null;
1025
+ if (hasProfileFlags) {
1026
+ profile = {
1027
+ name: appName,
1028
+ website: flags.website,
1029
+ description: flags.description,
1030
+ xURL: flags["x-url"],
1031
+ imagePath: flags.image
1032
+ };
1033
+ } else {
1034
+ this.log(
1035
+ "\nDeployment confirmed onchain. While your instance provisions, set up a public profile:"
1036
+ );
1037
+ try {
1038
+ profile = await getAppProfileInteractive(appName, true) || null;
1039
+ } catch {
1040
+ logger.debug("Profile collection skipped or cancelled");
1105
1041
  }
1106
1042
  }
1107
- const res = await executeDeploy(
1108
- prepared,
1109
- {
1110
- maxFeePerGas: gasEstimate.maxFeePerGas,
1111
- maxPriorityFeePerGas: gasEstimate.maxPriorityFeePerGas
1112
- },
1113
- logger,
1114
- true
1115
- // skipTelemetry
1116
- );
1117
- if (!flags["skip-profile"]) {
1118
- const hasProfileFlags = flags.website || flags.description || flags["x-url"] || flags.image;
1119
- let profile = null;
1120
- if (hasProfileFlags) {
1121
- profile = {
1122
- name: appName,
1123
- website: flags.website,
1124
- description: flags.description,
1125
- xURL: flags["x-url"],
1126
- imagePath: flags.image
1127
- };
1128
- } else {
1129
- this.log(
1130
- "\nDeployment confirmed onchain. While your instance provisions, set up a public profile:"
1043
+ if (profile) {
1044
+ logger.info("Uploading app profile...");
1045
+ try {
1046
+ const userApiClient = new UserApiClient3(
1047
+ environmentConfig,
1048
+ privateKey,
1049
+ rpcUrl,
1050
+ getClientId()
1131
1051
  );
1052
+ await userApiClient.uploadAppProfile(
1053
+ res.appId,
1054
+ profile.name,
1055
+ profile.website,
1056
+ profile.description,
1057
+ profile.xURL,
1058
+ profile.imagePath
1059
+ );
1060
+ logger.info("\u2713 Profile uploaded successfully");
1132
1061
  try {
1133
- profile = await getAppProfileInteractive(appName, true) || null;
1134
- } catch {
1135
- logger.debug("Profile collection skipped or cancelled");
1136
- }
1137
- }
1138
- if (profile) {
1139
- logger.info("Uploading app profile...");
1140
- try {
1141
- const userApiClient = new UserApiClient3(
1142
- environmentConfig,
1143
- privateKey,
1144
- rpcUrl,
1145
- getClientId()
1146
- );
1147
- await userApiClient.uploadAppProfile(
1148
- res.appId,
1149
- profile.name,
1150
- profile.website,
1151
- profile.description,
1152
- profile.xURL,
1153
- profile.imagePath
1154
- );
1155
- logger.info("\u2713 Profile uploaded successfully");
1156
- try {
1157
- invalidateProfileCache(environment);
1158
- } catch (cacheErr) {
1159
- logger.debug(`Failed to invalidate profile cache: ${cacheErr.message}`);
1160
- }
1161
- } catch (uploadErr) {
1162
- logger.warn(`Failed to upload profile: ${uploadErr.message}`);
1062
+ invalidateProfileCache(environment);
1063
+ } catch (cacheErr) {
1064
+ logger.debug(`Failed to invalidate profile cache: ${cacheErr.message}`);
1163
1065
  }
1066
+ } catch (uploadErr) {
1067
+ logger.warn(`Failed to upload profile: ${uploadErr.message}`);
1164
1068
  }
1165
1069
  }
1166
- const ipAddress = await watchDeployment(
1167
- res.appId,
1168
- privateKey,
1169
- rpcUrl,
1170
- environment,
1171
- logger,
1172
- getClientId(),
1173
- true
1174
- // skipTelemetry - CLI already has telemetry
1175
- );
1176
- this.log(
1177
- `
1070
+ }
1071
+ const ipAddress = await watchDeployment(
1072
+ res.appId,
1073
+ privateKey,
1074
+ rpcUrl,
1075
+ environment,
1076
+ logger,
1077
+ getClientId()
1078
+ );
1079
+ this.log(
1080
+ `
1178
1081
  \u2705 ${chalk.green(`App deployed successfully ${chalk.bold(`(id: ${res.appId}, ip: ${ipAddress})`)}`)}`
1179
- );
1180
- });
1082
+ );
1181
1083
  }
1182
1084
  };
1183
1085
  async function fetchAvailableInstanceTypes(environmentConfig, privateKey, rpcUrl) {