@layr-labs/ecloud-cli 0.4.0-dev.0 → 0.4.0-dev.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.
- package/VERSION +2 -0
- package/dist/commands/auth/whoami.js +1 -0
- package/dist/commands/auth/whoami.js.map +1 -1
- package/dist/commands/billing/__tests__/status.test.js +89 -22
- package/dist/commands/billing/__tests__/status.test.js.map +1 -1
- package/dist/commands/billing/__tests__/subscribe.test.js +88 -20
- package/dist/commands/billing/__tests__/subscribe.test.js.map +1 -1
- package/dist/commands/billing/__tests__/top-up.test.js +139 -201
- package/dist/commands/billing/__tests__/top-up.test.js.map +1 -1
- package/dist/commands/billing/cancel.js +88 -19
- package/dist/commands/billing/cancel.js.map +1 -1
- package/dist/commands/billing/status.js +89 -21
- package/dist/commands/billing/status.js.map +1 -1
- package/dist/commands/billing/subscribe.js +88 -19
- package/dist/commands/billing/subscribe.js.map +1 -1
- package/dist/commands/billing/top-up.js +102 -91
- package/dist/commands/billing/top-up.js.map +1 -1
- package/dist/commands/compute/app/create.js +1 -0
- package/dist/commands/compute/app/create.js.map +1 -1
- package/dist/commands/compute/app/deploy.js +38 -24
- package/dist/commands/compute/app/deploy.js.map +1 -1
- package/dist/commands/compute/app/info.js +2 -1
- package/dist/commands/compute/app/info.js.map +1 -1
- package/dist/commands/compute/app/list.js +2 -1
- package/dist/commands/compute/app/list.js.map +1 -1
- package/dist/commands/compute/app/logs.js +5 -8
- package/dist/commands/compute/app/logs.js.map +1 -1
- package/dist/commands/compute/app/profile/set.js +5 -8
- package/dist/commands/compute/app/profile/set.js.map +1 -1
- package/dist/commands/compute/app/releases.js +2 -1
- package/dist/commands/compute/app/releases.js.map +1 -1
- package/dist/commands/compute/app/start.js +5 -8
- package/dist/commands/compute/app/start.js.map +1 -1
- package/dist/commands/compute/app/stop.js +5 -8
- package/dist/commands/compute/app/stop.js.map +1 -1
- package/dist/commands/compute/app/terminate.js +5 -8
- package/dist/commands/compute/app/terminate.js.map +1 -1
- package/dist/commands/compute/app/upgrade.js +36 -14
- package/dist/commands/compute/app/upgrade.js.map +1 -1
- package/dist/commands/compute/build/info.js +9 -12
- package/dist/commands/compute/build/info.js.map +1 -1
- package/dist/commands/compute/build/list.js +9 -12
- package/dist/commands/compute/build/list.js.map +1 -1
- package/dist/commands/compute/build/logs.js +9 -12
- package/dist/commands/compute/build/logs.js.map +1 -1
- package/dist/commands/compute/build/status.js +9 -12
- package/dist/commands/compute/build/status.js.map +1 -1
- package/dist/commands/compute/build/submit.js +32 -10
- package/dist/commands/compute/build/submit.js.map +1 -1
- package/dist/commands/compute/build/verify.js +9 -12
- package/dist/commands/compute/build/verify.js.map +1 -1
- package/dist/commands/compute/environment/set.js +1 -0
- package/dist/commands/compute/environment/set.js.map +1 -1
- package/dist/commands/compute/undelegate.js +5 -8
- package/dist/commands/compute/undelegate.js.map +1 -1
- package/package.json +2 -2
|
@@ -9,9 +9,7 @@ import {
|
|
|
9
9
|
createBillingModule,
|
|
10
10
|
createBuildModule,
|
|
11
11
|
getEnvironmentConfig as getEnvironmentConfig3,
|
|
12
|
-
requirePrivateKey
|
|
13
|
-
getPrivateKeyWithSource,
|
|
14
|
-
addHexPrefix as addHexPrefix2
|
|
12
|
+
requirePrivateKey
|
|
15
13
|
} from "@layr-labs/ecloud-sdk";
|
|
16
14
|
|
|
17
15
|
// src/flags.ts
|
|
@@ -166,6 +164,7 @@ var CONFIG_DIR = path2.join(os2.homedir(), ".eigenx");
|
|
|
166
164
|
var APPS_DIR = path2.join(CONFIG_DIR, "apps");
|
|
167
165
|
|
|
168
166
|
// src/utils/prompts.ts
|
|
167
|
+
import { execSync } from "child_process";
|
|
169
168
|
async function getPrivateKeyInteractive(privateKey) {
|
|
170
169
|
if (privateKey) {
|
|
171
170
|
if (!validatePrivateKeyFormat(privateKey)) {
|
|
@@ -173,8 +172,8 @@ async function getPrivateKeyInteractive(privateKey) {
|
|
|
173
172
|
}
|
|
174
173
|
return privateKey;
|
|
175
174
|
}
|
|
176
|
-
const { getPrivateKeyWithSource
|
|
177
|
-
const result = await
|
|
175
|
+
const { getPrivateKeyWithSource } = await import("@layr-labs/ecloud-sdk");
|
|
176
|
+
const result = await getPrivateKeyWithSource({ privateKey: void 0 });
|
|
178
177
|
if (result) {
|
|
179
178
|
return result.key;
|
|
180
179
|
}
|
|
@@ -193,6 +192,50 @@ async function getPrivateKeyInteractive(privateKey) {
|
|
|
193
192
|
});
|
|
194
193
|
return key.trim();
|
|
195
194
|
}
|
|
195
|
+
async function getEnvironmentInteractive(environment) {
|
|
196
|
+
if (environment) {
|
|
197
|
+
try {
|
|
198
|
+
getEnvironmentConfig2(environment);
|
|
199
|
+
if (!isEnvironmentAvailable(environment)) {
|
|
200
|
+
throw new Error(`Environment ${environment} is not available in this build`);
|
|
201
|
+
}
|
|
202
|
+
return environment;
|
|
203
|
+
} catch {
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
const availableEnvs = getAvailableEnvironments();
|
|
207
|
+
let defaultEnv;
|
|
208
|
+
const configDefaultEnv = getDefaultEnvironment();
|
|
209
|
+
if (configDefaultEnv && availableEnvs.includes(configDefaultEnv)) {
|
|
210
|
+
try {
|
|
211
|
+
getEnvironmentConfig2(configDefaultEnv);
|
|
212
|
+
defaultEnv = configDefaultEnv;
|
|
213
|
+
} catch {
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
const choices = [];
|
|
217
|
+
if (availableEnvs.includes("sepolia")) {
|
|
218
|
+
choices.push({ name: "sepolia - Ethereum Sepolia testnet", value: "sepolia" });
|
|
219
|
+
}
|
|
220
|
+
if (availableEnvs.includes("sepolia-dev")) {
|
|
221
|
+
choices.push({ name: "sepolia-dev - Ethereum Sepolia testnet (dev)", value: "sepolia-dev" });
|
|
222
|
+
}
|
|
223
|
+
if (availableEnvs.includes("mainnet-alpha")) {
|
|
224
|
+
choices.push({
|
|
225
|
+
name: "mainnet-alpha - Ethereum mainnet (\u26A0\uFE0F uses real funds)",
|
|
226
|
+
value: "mainnet-alpha"
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
if (choices.length === 0) {
|
|
230
|
+
throw new Error("No environments available in this build");
|
|
231
|
+
}
|
|
232
|
+
const env = await select({
|
|
233
|
+
message: "Select environment:",
|
|
234
|
+
choices,
|
|
235
|
+
default: defaultEnv
|
|
236
|
+
});
|
|
237
|
+
return env;
|
|
238
|
+
}
|
|
196
239
|
var MAX_IMAGE_SIZE = 4 * 1024 * 1024;
|
|
197
240
|
|
|
198
241
|
// src/flags.ts
|
|
@@ -219,38 +262,41 @@ var commonFlags = {
|
|
|
219
262
|
default: false
|
|
220
263
|
})
|
|
221
264
|
};
|
|
265
|
+
async function validateCommonFlags(flags, options) {
|
|
266
|
+
flags["environment"] = await getEnvironmentInteractive(flags["environment"]);
|
|
267
|
+
if (options?.requirePrivateKey !== false) {
|
|
268
|
+
flags["private-key"] = await getPrivateKeyInteractive(flags["private-key"]);
|
|
269
|
+
}
|
|
270
|
+
return flags;
|
|
271
|
+
}
|
|
222
272
|
|
|
223
273
|
// src/client.ts
|
|
224
|
-
import { createWalletClient, custom } from "viem";
|
|
225
|
-
import { privateKeyToAccount as privateKeyToAccount4 } from "viem/accounts";
|
|
226
274
|
async function createBillingClient(flags) {
|
|
227
|
-
|
|
275
|
+
flags = await validateCommonFlags(flags);
|
|
276
|
+
const environment = flags.environment;
|
|
277
|
+
const environmentConfig = getEnvironmentConfig3(environment);
|
|
278
|
+
const rpcUrl = flags["rpc-url"] || environmentConfig.billingRPCURL || environmentConfig.defaultRPCURL;
|
|
279
|
+
const { key: privateKey, source } = await requirePrivateKey({
|
|
228
280
|
privateKey: flags["private-key"]
|
|
229
281
|
});
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
}
|
|
238
|
-
})
|
|
282
|
+
if (flags.verbose) {
|
|
283
|
+
console.log(`Using private key from: ${source}`);
|
|
284
|
+
}
|
|
285
|
+
const { walletClient, publicClient } = createViemClients({
|
|
286
|
+
privateKey,
|
|
287
|
+
rpcUrl,
|
|
288
|
+
environment
|
|
239
289
|
});
|
|
240
290
|
return createBillingModule({
|
|
241
|
-
verbose: flags.verbose
|
|
291
|
+
verbose: flags.verbose,
|
|
242
292
|
walletClient,
|
|
293
|
+
publicClient,
|
|
294
|
+
environment,
|
|
243
295
|
skipTelemetry: true
|
|
244
|
-
// CLI already has telemetry, skip SDK telemetry
|
|
245
296
|
});
|
|
246
297
|
}
|
|
247
298
|
|
|
248
299
|
// src/commands/billing/top-up.ts
|
|
249
|
-
import {
|
|
250
|
-
getEnvironmentConfig as getEnvironmentConfig4,
|
|
251
|
-
USDCCreditsABI,
|
|
252
|
-
ERC20ABI
|
|
253
|
-
} from "@layr-labs/ecloud-sdk";
|
|
254
300
|
import { formatUnits } from "viem";
|
|
255
301
|
import chalk2 from "chalk";
|
|
256
302
|
import { input as input2 } from "@inquirer/prompts";
|
|
@@ -340,19 +386,7 @@ var BillingTopUp = class _BillingTopUp extends Command {
|
|
|
340
386
|
return withTelemetry(this, async () => {
|
|
341
387
|
const { flags } = await this.parse(_BillingTopUp);
|
|
342
388
|
const billing = await createBillingClient(flags);
|
|
343
|
-
const
|
|
344
|
-
const { publicClient, walletClient, address: walletAddress } = createViemClients({
|
|
345
|
-
privateKey,
|
|
346
|
-
rpcUrl: flags["rpc-url"],
|
|
347
|
-
environment: flags.environment
|
|
348
|
-
});
|
|
349
|
-
const environmentConfig = getEnvironmentConfig4(flags.environment);
|
|
350
|
-
const usdcCreditsAddress = environmentConfig.usdcCreditsAddress;
|
|
351
|
-
if (!usdcCreditsAddress) {
|
|
352
|
-
this.error(
|
|
353
|
-
`USDCCredits contract is not configured for environment "${flags.environment}". USDC credit purchasing is only available on environments with a deployed USDCCredits contract.`
|
|
354
|
-
);
|
|
355
|
-
}
|
|
389
|
+
const walletAddress = billing.address;
|
|
356
390
|
const targetAccount = flags.account ?? walletAddress;
|
|
357
391
|
this.log(`
|
|
358
392
|
${chalk2.bold("Purchase EigenCompute credits")}`);
|
|
@@ -362,34 +396,22 @@ ${chalk2.bold("Purchase EigenCompute credits")}`);
|
|
|
362
396
|
if (targetAccount !== walletAddress) {
|
|
363
397
|
this.log(` ${chalk2.bold("Target:")} ${targetAccount}`);
|
|
364
398
|
}
|
|
365
|
-
let
|
|
399
|
+
let baselineTotal;
|
|
366
400
|
try {
|
|
367
401
|
const status = await billing.getStatus({
|
|
368
402
|
productId: flags.product
|
|
369
403
|
});
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
404
|
+
const remaining = status.remainingCredits ?? 0;
|
|
405
|
+
const applied = status.creditsApplied ?? 0;
|
|
406
|
+
baselineTotal = remaining + applied;
|
|
407
|
+
if (status.remainingCredits !== void 0) {
|
|
408
|
+
this.log(` ${chalk2.bold("Credits:")} ${chalk2.cyan(`$${status.remainingCredits.toFixed(2)}`)}`);
|
|
373
409
|
}
|
|
374
410
|
} catch {
|
|
375
411
|
this.debug("Could not fetch current credit balance");
|
|
376
412
|
}
|
|
377
|
-
const
|
|
378
|
-
|
|
379
|
-
abi: USDCCreditsABI,
|
|
380
|
-
functionName: "usdc"
|
|
381
|
-
});
|
|
382
|
-
const minimumPurchase = await publicClient.readContract({
|
|
383
|
-
address: usdcCreditsAddress,
|
|
384
|
-
abi: USDCCreditsABI,
|
|
385
|
-
functionName: "minimumPurchase"
|
|
386
|
-
});
|
|
387
|
-
const usdcBalance = await publicClient.readContract({
|
|
388
|
-
address: usdcAddress,
|
|
389
|
-
abi: ERC20ABI,
|
|
390
|
-
functionName: "balanceOf",
|
|
391
|
-
args: [walletAddress]
|
|
392
|
-
});
|
|
413
|
+
const onChainState = await billing.getTopUpInfo();
|
|
414
|
+
const { usdcBalance, minimumPurchase } = onChainState;
|
|
393
415
|
const balanceFormatted = formatUnits(usdcBalance, 6);
|
|
394
416
|
this.log(` ${chalk2.bold("USDC:")} ${balanceFormatted} USDC`);
|
|
395
417
|
if (usdcBalance === BigInt(0)) {
|
|
@@ -426,36 +448,11 @@ ${chalk2.yellow(" No USDC in wallet.")}`);
|
|
|
426
448
|
}
|
|
427
449
|
this.log(`
|
|
428
450
|
Purchasing ${chalk2.bold(`$${amountFloat.toFixed(2)}`)} in credits...`);
|
|
429
|
-
const
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
functionName: "allowance",
|
|
433
|
-
args: [walletAddress, usdcCreditsAddress]
|
|
434
|
-
});
|
|
435
|
-
if (currentAllowance < amountRaw) {
|
|
436
|
-
this.log(chalk2.gray(" Approving USDC spend..."));
|
|
437
|
-
const approveTx = await walletClient.writeContract({
|
|
438
|
-
address: usdcAddress,
|
|
439
|
-
abi: ERC20ABI,
|
|
440
|
-
functionName: "approve",
|
|
441
|
-
args: [usdcCreditsAddress, amountRaw],
|
|
442
|
-
chain: walletClient.chain,
|
|
443
|
-
account: walletClient.account
|
|
444
|
-
});
|
|
445
|
-
await publicClient.waitForTransactionReceipt({ hash: approveTx });
|
|
446
|
-
this.log(` ${chalk2.green("\u2713")} Approved`);
|
|
447
|
-
}
|
|
448
|
-
this.log(chalk2.gray(" Submitting credit purchase..."));
|
|
449
|
-
const purchaseTx = await walletClient.writeContract({
|
|
450
|
-
address: usdcCreditsAddress,
|
|
451
|
-
abi: USDCCreditsABI,
|
|
452
|
-
functionName: "purchaseCreditsFor",
|
|
453
|
-
args: [amountRaw, targetAccount],
|
|
454
|
-
chain: walletClient.chain,
|
|
455
|
-
account: walletClient.account
|
|
451
|
+
const { txHash } = await billing.topUp({
|
|
452
|
+
amount: amountRaw,
|
|
453
|
+
account: targetAccount
|
|
456
454
|
});
|
|
457
|
-
|
|
458
|
-
this.log(` ${chalk2.green("\u2713")} Transaction confirmed: ${receipt.transactionHash}`);
|
|
455
|
+
this.log(` ${chalk2.green("\u2713")} Transaction confirmed: ${txHash}`);
|
|
459
456
|
this.log(chalk2.gray("\n Waiting for credits to appear..."));
|
|
460
457
|
const startTime = Date.now();
|
|
461
458
|
while (Date.now() - startTime < POLL_TIMEOUT_MS) {
|
|
@@ -464,11 +461,25 @@ ${chalk2.yellow(" No USDC in wallet.")}`);
|
|
|
464
461
|
const status = await billing.getStatus({
|
|
465
462
|
productId: flags.product
|
|
466
463
|
});
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
464
|
+
const remaining = status.remainingCredits ?? 0;
|
|
465
|
+
const applied = status.creditsApplied ?? 0;
|
|
466
|
+
const currentTotal = remaining + applied;
|
|
467
|
+
this.debug(`Poll: remaining=${remaining}, applied=${applied}, total=${currentTotal}, baseline=${baselineTotal}`);
|
|
468
|
+
if (baselineTotal === void 0 || currentTotal > baselineTotal) {
|
|
469
|
+
const creditsAdded = baselineTotal !== void 0 ? currentTotal - baselineTotal : void 0;
|
|
470
|
+
const isMatched = creditsAdded !== void 0 && Math.abs(creditsAdded - amountFloat * 2) < 0.01;
|
|
471
|
+
const appliedFromTopUp = creditsAdded !== void 0 ? creditsAdded - remaining : 0;
|
|
472
|
+
this.log(`
|
|
473
|
+
${chalk2.green("\u2713")} Credits received: ${chalk2.cyan(`$${(creditsAdded ?? amountFloat).toFixed(2)}`)}`);
|
|
474
|
+
if (isMatched) {
|
|
475
|
+
this.log(` ${chalk2.green("\u2713")} Includes $${amountFloat.toFixed(2)} match bonus!`);
|
|
476
|
+
}
|
|
477
|
+
if (remaining > 0) {
|
|
478
|
+
this.log(` Remaining balance: ${chalk2.cyan(`$${remaining.toFixed(2)}`)}`);
|
|
479
|
+
}
|
|
480
|
+
if (appliedFromTopUp > 0) {
|
|
481
|
+
this.log(` ${chalk2.gray(`$${appliedFromTopUp.toFixed(2)} applied to current bill`)}`);
|
|
482
|
+
}
|
|
472
483
|
this.log();
|
|
473
484
|
return;
|
|
474
485
|
}
|