@layr-labs/ecloud-sdk 0.2.0-dev.1 → 0.2.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/dist/compute.cjs CHANGED
@@ -40,7 +40,6 @@ module.exports = __toCommonJS(compute_exports);
40
40
 
41
41
  // src/client/modules/compute/app/index.ts
42
42
  var import_viem9 = require("viem");
43
- var import_accounts5 = require("viem/accounts");
44
43
 
45
44
  // src/client/common/config/environment.ts
46
45
  var SEPOLIA_CHAIN_ID = 11155111;
@@ -163,7 +162,6 @@ async function buildDockerImage(buildContext, dockerfilePath, tag, logger) {
163
162
  tag,
164
163
  "-f",
165
164
  dockerfilePath,
166
- "--load",
167
165
  "--progress=plain",
168
166
  buildContext
169
167
  ];
@@ -289,7 +287,7 @@ async function pullDockerImage(docker, imageTag, platform2 = "linux/amd64", logg
289
287
  var child_process2 = __toESM(require("child_process"), 1);
290
288
  var import_child_process = require("child_process");
291
289
  var import_util2 = require("util");
292
- var execFileAsync = (0, import_util2.promisify)(import_child_process.execFile);
290
+ var execAsync = (0, import_util2.promisify)(import_child_process.exec);
293
291
  async function pushDockerImage(docker, imageRef, logger) {
294
292
  logger?.info?.(`Pushing image ${imageRef}...`);
295
293
  return new Promise((resolve2, reject) => {
@@ -330,9 +328,9 @@ async function pushDockerImage(docker, imageRef, logger) {
330
328
  if (!output.includes("digest:") && !output.includes("pushed") && !output.includes("Pushed")) {
331
329
  logger?.debug?.("No clear success indicator in push output, verifying...");
332
330
  }
331
+ logger?.info?.("Image push completed successfully");
333
332
  try {
334
333
  await verifyImageExists(imageRef, logger);
335
- logger?.info?.("Image push completed successfully");
336
334
  resolve2();
337
335
  } catch (error) {
338
336
  reject(error);
@@ -356,7 +354,7 @@ async function verifyImageExists(imageRef, logger) {
356
354
  let retries = 5;
357
355
  while (retries > 0) {
358
356
  try {
359
- await execFileAsync("docker", ["manifest", "inspect", imageRef], {
357
+ await execAsync(`docker manifest inspect ${imageRef}`, {
360
358
  maxBuffer: 10 * 1024 * 1024,
361
359
  timeout: 1e4
362
360
  // 10 second timeout
@@ -830,10 +828,10 @@ async function setupLayeredBuildDirectory(environmentConfig, layeredDockerfileCo
830
828
  // src/client/common/registry/digest.ts
831
829
  var child_process3 = __toESM(require("child_process"), 1);
832
830
  var import_util3 = require("util");
833
- var execFileAsync2 = (0, import_util3.promisify)(child_process3.execFile);
831
+ var execFileAsync = (0, import_util3.promisify)(child_process3.execFile);
834
832
  async function getImageDigestAndName(imageRef) {
835
833
  try {
836
- const { stdout } = await execFileAsync2(
834
+ const { stdout } = await execFileAsync(
837
835
  "docker",
838
836
  ["manifest", "inspect", imageRef],
839
837
  { maxBuffer: 10 * 1024 * 1024 }
@@ -873,7 +871,7 @@ function extractDigestFromMultiPlatform(manifest, imageRef) {
873
871
  }
874
872
  async function extractDigestFromSinglePlatform(manifest, imageRef) {
875
873
  try {
876
- const { stdout } = await execFileAsync2("docker", ["inspect", imageRef], {
874
+ const { stdout } = await execFileAsync("docker", ["inspect", imageRef], {
877
875
  maxBuffer: 10 * 1024 * 1024
878
876
  });
879
877
  const inspectData = JSON.parse(stdout);
@@ -1171,67 +1169,6 @@ Please verify the image exists: docker manifest inspect ${finalImageRef}`
1171
1169
  };
1172
1170
  }
1173
1171
 
1174
- // src/client/common/release/prebuilt.ts
1175
- async function createReleaseFromImageDigest(options, logger) {
1176
- const { imageRef, imageDigest, envFilePath, instanceType, environmentConfig, appId } = options;
1177
- if (!/^sha256:[0-9a-f]{64}$/i.test(imageDigest)) {
1178
- throw new Error(`imageDigest must be in format sha256:<64 hex>, got: ${imageDigest}`);
1179
- }
1180
- let publicEnv = {};
1181
- let privateEnv = {};
1182
- if (envFilePath) {
1183
- logger.info("Parsing environment file...");
1184
- const parsed = parseAndValidateEnvFile(envFilePath);
1185
- publicEnv = parsed.public;
1186
- privateEnv = parsed.private;
1187
- } else {
1188
- logger.info("Continuing without environment file");
1189
- }
1190
- publicEnv["EIGEN_MACHINE_TYPE_PUBLIC"] = instanceType;
1191
- logger.info(`Instance type: ${instanceType}`);
1192
- logger.info("Encrypting environment variables...");
1193
- const { encryptionKey } = getKMSKeysForEnvironment(
1194
- environmentConfig.name,
1195
- environmentConfig.build
1196
- );
1197
- const protectedHeaders = getAppProtectedHeaders(appId);
1198
- const privateEnvBytes = Buffer.from(JSON.stringify(privateEnv));
1199
- const encryptedEnvStr = await encryptRSAOAEPAndAES256GCM(
1200
- encryptionKey,
1201
- privateEnvBytes,
1202
- protectedHeaders
1203
- );
1204
- const digestHex = imageDigest.split(":")[1];
1205
- const digestBytes = new Uint8Array(Buffer.from(digestHex, "hex"));
1206
- if (digestBytes.length !== 32) {
1207
- throw new Error(`Digest must be exactly 32 bytes, got ${digestBytes.length}`);
1208
- }
1209
- const registry = extractRegistryNameNoDocker(imageRef);
1210
- return {
1211
- rmsRelease: {
1212
- artifacts: [{ digest: digestBytes, registry }],
1213
- upgradeByTime: Math.floor(Date.now() / 1e3) + 3600
1214
- },
1215
- publicEnv: new Uint8Array(Buffer.from(JSON.stringify(publicEnv))),
1216
- encryptedEnv: new Uint8Array(Buffer.from(encryptedEnvStr))
1217
- };
1218
- }
1219
- function extractRegistryNameNoDocker(imageRef) {
1220
- let name = imageRef;
1221
- const tagIndex = name.lastIndexOf(":");
1222
- if (tagIndex !== -1 && !name.substring(tagIndex + 1).includes("/")) {
1223
- name = name.substring(0, tagIndex);
1224
- }
1225
- const digestIndex = name.indexOf("@");
1226
- if (digestIndex !== -1) {
1227
- name = name.substring(0, digestIndex);
1228
- }
1229
- if ([...name].filter((c) => c === "/").length === 1) {
1230
- name = `docker.io/${name}`;
1231
- }
1232
- return name;
1233
- }
1234
-
1235
1172
  // src/client/common/contract/caller.ts
1236
1173
  var import_accounts2 = require("viem/accounts");
1237
1174
 
@@ -2268,55 +2205,8 @@ var ERC7702Delegator_default = [
2268
2205
  ];
2269
2206
 
2270
2207
  // src/client/common/contract/eip7702.ts
2271
- var EXECUTE_BATCH_MODE = "0x0100000000000000000000000000000000000000000000000000000000000000";
2272
- var GAS_LIMIT_BUFFER_PERCENTAGE = 20n;
2273
- var GAS_PRICE_BUFFER_PERCENTAGE = 100n;
2274
- function encodeExecuteBatchData(executions) {
2275
- const encodedExecutions = (0, import_viem.encodeAbiParameters)(
2276
- [
2277
- {
2278
- type: "tuple[]",
2279
- components: [
2280
- { name: "target", type: "address" },
2281
- { name: "value", type: "uint256" },
2282
- { name: "callData", type: "bytes" }
2283
- ]
2284
- }
2285
- ],
2286
- [executions]
2287
- );
2288
- return (0, import_viem.encodeFunctionData)({
2289
- abi: ERC7702Delegator_default,
2290
- functionName: "execute",
2291
- args: [EXECUTE_BATCH_MODE, encodedExecutions]
2292
- });
2293
- }
2294
- async function estimateBatchGas(options) {
2295
- const { publicClient, account, executions } = options;
2296
- const executeBatchData = encodeExecuteBatchData(executions);
2297
- const [gasTipCap, block, estimatedGas] = await Promise.all([
2298
- publicClient.estimateMaxPriorityFeePerGas(),
2299
- publicClient.getBlock(),
2300
- publicClient.estimateGas({
2301
- account,
2302
- to: account,
2303
- data: executeBatchData
2304
- })
2305
- ]);
2306
- const baseFee = block.baseFeePerGas ?? 0n;
2307
- const maxFeePerGas = (baseFee + gasTipCap) * (100n + GAS_PRICE_BUFFER_PERCENTAGE) / 100n;
2308
- const gasLimit = estimatedGas * (100n + GAS_LIMIT_BUFFER_PERCENTAGE) / 100n;
2309
- const maxCostWei = gasLimit * maxFeePerGas;
2310
- return {
2311
- gasLimit,
2312
- maxFeePerGas,
2313
- maxPriorityFeePerGas: gasTipCap,
2314
- maxCostWei,
2315
- maxCostEth: formatETH(maxCostWei)
2316
- };
2317
- }
2318
2208
  async function checkERC7702Delegation(publicClient, account, delegatorAddress) {
2319
- const code = await publicClient.getCode({ address: account });
2209
+ const code = await publicClient.getBytecode({ address: account });
2320
2210
  if (!code) {
2321
2211
  return false;
2322
2212
  }
@@ -2333,7 +2223,36 @@ async function executeBatch(options, logger) {
2333
2223
  if (!chain) {
2334
2224
  throw new Error("Wallet client must have a chain");
2335
2225
  }
2336
- const executeBatchData = encodeExecuteBatchData(executions);
2226
+ const encodedExecutions = (0, import_viem.encodeAbiParameters)(
2227
+ [
2228
+ {
2229
+ type: "tuple[]",
2230
+ components: [
2231
+ { name: "target", type: "address" },
2232
+ { name: "value", type: "uint256" },
2233
+ { name: "callData", type: "bytes" }
2234
+ ]
2235
+ }
2236
+ ],
2237
+ [executions]
2238
+ );
2239
+ const executeBatchMode = "0x0100000000000000000000000000000000000000000000000000000000000000";
2240
+ let executeBatchData;
2241
+ try {
2242
+ executeBatchData = (0, import_viem.encodeFunctionData)({
2243
+ abi: ERC7702Delegator_default,
2244
+ functionName: "execute",
2245
+ args: [executeBatchMode, encodedExecutions]
2246
+ });
2247
+ } catch {
2248
+ const functionSignature = "execute(bytes32,bytes)";
2249
+ const selector = (0, import_viem.keccak256)((0, import_viem.toBytes)(functionSignature)).slice(0, 10);
2250
+ const encodedParams = (0, import_viem.encodeAbiParameters)(
2251
+ [{ type: "bytes32" }, { type: "bytes" }],
2252
+ [executeBatchMode, encodedExecutions]
2253
+ );
2254
+ executeBatchData = (0, import_viem.concat)([selector, encodedParams]);
2255
+ }
2337
2256
  const isDelegated2 = await checkERC7702Delegation(
2338
2257
  publicClient,
2339
2258
  account.address,
@@ -2466,23 +2385,12 @@ function stripHexPrefix(value) {
2466
2385
  }
2467
2386
 
2468
2387
  // src/client/common/utils/userapi.ts
2469
- function isJsonObject(value) {
2470
- return typeof value === "object" && value !== null && !Array.isArray(value);
2471
- }
2472
- function readString(obj, key) {
2473
- const v = obj[key];
2474
- return typeof v === "string" ? v : void 0;
2475
- }
2476
- function readNumber(obj, key) {
2477
- const v = obj[key];
2478
- return typeof v === "number" && Number.isFinite(v) ? v : void 0;
2479
- }
2480
2388
  var MAX_ADDRESS_COUNT = 5;
2481
2389
  var CanViewAppLogsPermission = "0x2fd3f2fe";
2482
2390
  var CanViewSensitiveAppInfoPermission = "0x0e67b22f";
2483
2391
  var CanUpdateAppProfilePermission = "0x036fef61";
2484
2392
  function getDefaultClientId() {
2485
- const version = true ? "0.2.0-dev.1" : "0.0.0";
2393
+ const version = true ? "0.2.0-dev.2" : "0.0.0";
2486
2394
  return `ecloud-sdk/v${version}`;
2487
2395
  }
2488
2396
  var UserApiClient = class {
@@ -2516,31 +2424,6 @@ var UserApiClient = class {
2516
2424
  };
2517
2425
  });
2518
2426
  }
2519
- /**
2520
- * Get app details from UserAPI (includes releases and build/provenance info when available).
2521
- *
2522
- * Endpoint: GET /apps/:appAddress
2523
- */
2524
- async getApp(appAddress) {
2525
- const endpoint = `${this.config.userApiServerURL}/apps/${appAddress}`;
2526
- const res = await this.makeAuthenticatedRequest(endpoint);
2527
- const raw = await res.json();
2528
- if (!isJsonObject(raw)) {
2529
- throw new Error("Unexpected /apps/:id response: expected object");
2530
- }
2531
- const id = readString(raw, "id");
2532
- if (!id) {
2533
- throw new Error("Unexpected /apps/:id response: missing 'id'");
2534
- }
2535
- const releasesRaw = raw.releases;
2536
- const releases = Array.isArray(releasesRaw) ? releasesRaw.map((r) => transformAppRelease(r)).filter((r) => !!r) : [];
2537
- return {
2538
- id,
2539
- creator: readString(raw, "creator"),
2540
- contractStatus: readString(raw, "contract_status") ?? readString(raw, "contractStatus"),
2541
- releases
2542
- };
2543
- }
2544
2427
  /**
2545
2428
  * Get available SKUs (instance types) from UserAPI
2546
2429
  */
@@ -2713,48 +2596,6 @@ Please check:
2713
2596
  };
2714
2597
  }
2715
2598
  };
2716
- function transformAppReleaseBuild(raw) {
2717
- if (!isJsonObject(raw)) return void 0;
2718
- const depsRaw = raw.dependencies;
2719
- const deps = isJsonObject(depsRaw) ? Object.fromEntries(
2720
- Object.entries(depsRaw).flatMap(([digest, depRaw]) => {
2721
- const parsed = transformAppReleaseBuild(depRaw);
2722
- return parsed ? [[digest, parsed]] : [];
2723
- })
2724
- ) : void 0;
2725
- return {
2726
- buildId: readString(raw, "build_id") ?? readString(raw, "buildId"),
2727
- billingAddress: readString(raw, "billing_address") ?? readString(raw, "billingAddress"),
2728
- repoUrl: readString(raw, "repo_url") ?? readString(raw, "repoUrl"),
2729
- gitRef: readString(raw, "git_ref") ?? readString(raw, "gitRef"),
2730
- status: readString(raw, "status"),
2731
- buildType: readString(raw, "build_type") ?? readString(raw, "buildType"),
2732
- imageName: readString(raw, "image_name") ?? readString(raw, "imageName"),
2733
- imageDigest: readString(raw, "image_digest") ?? readString(raw, "imageDigest"),
2734
- imageUrl: readString(raw, "image_url") ?? readString(raw, "imageUrl"),
2735
- provenanceJson: raw.provenance_json ?? raw.provenanceJson,
2736
- provenanceSignature: readString(raw, "provenance_signature") ?? readString(raw, "provenanceSignature"),
2737
- createdAt: readString(raw, "created_at") ?? readString(raw, "createdAt"),
2738
- updatedAt: readString(raw, "updated_at") ?? readString(raw, "updatedAt"),
2739
- errorMessage: readString(raw, "error_message") ?? readString(raw, "errorMessage"),
2740
- dependencies: deps
2741
- };
2742
- }
2743
- function transformAppRelease(raw) {
2744
- if (!isJsonObject(raw)) return void 0;
2745
- return {
2746
- appId: readString(raw, "appId") ?? readString(raw, "app_id"),
2747
- rmsReleaseId: readString(raw, "rmsReleaseId") ?? readString(raw, "rms_release_id"),
2748
- imageDigest: readString(raw, "imageDigest") ?? readString(raw, "image_digest"),
2749
- registryUrl: readString(raw, "registryUrl") ?? readString(raw, "registry_url"),
2750
- publicEnv: readString(raw, "publicEnv") ?? readString(raw, "public_env"),
2751
- encryptedEnv: readString(raw, "encryptedEnv") ?? readString(raw, "encrypted_env"),
2752
- upgradeByTime: readNumber(raw, "upgradeByTime") ?? readNumber(raw, "upgrade_by_time"),
2753
- createdAt: readString(raw, "createdAt") ?? readString(raw, "created_at"),
2754
- createdAtBlock: readString(raw, "createdAtBlock") ?? readString(raw, "created_at_block"),
2755
- build: raw.build ? transformAppReleaseBuild(raw.build) : void 0
2756
- };
2757
- }
2758
2599
 
2759
2600
  // src/client/common/abis/AppController.json
2760
2601
  var AppController_default = [
@@ -4301,15 +4142,6 @@ var PermissionController_default = [
4301
4142
  ];
4302
4143
 
4303
4144
  // src/client/common/contract/caller.ts
4304
- function formatETH(wei) {
4305
- const eth = Number(wei) / 1e18;
4306
- const costStr = eth.toFixed(6);
4307
- const trimmed = costStr.replace(/\.?0+$/, "");
4308
- if (trimmed === "0" && wei > 0n) {
4309
- return "<0.000001";
4310
- }
4311
- return trimmed;
4312
- }
4313
4145
  async function calculateAppID(privateKey, rpcUrl, environmentConfig, salt) {
4314
4146
  const privateKeyHex = addHexPrefix(privateKey);
4315
4147
  const account = (0, import_accounts2.privateKeyToAccount)(privateKeyHex);
@@ -4414,20 +4246,20 @@ async function prepareDeployBatch(options, logger) {
4414
4246
  environmentConfig
4415
4247
  };
4416
4248
  }
4417
- async function executeDeployBatch(data, context, gas, logger) {
4249
+ async function executeDeployBatch(prepared, gas, logger) {
4418
4250
  const pendingMessage = "Deploying new app...";
4419
4251
  const txHash = await executeBatch(
4420
4252
  {
4421
- walletClient: context.walletClient,
4422
- publicClient: context.publicClient,
4423
- environmentConfig: context.environmentConfig,
4424
- executions: data.executions,
4253
+ walletClient: prepared.walletClient,
4254
+ publicClient: prepared.publicClient,
4255
+ environmentConfig: prepared.environmentConfig,
4256
+ executions: prepared.executions,
4425
4257
  pendingMessage,
4426
4258
  gas
4427
4259
  },
4428
4260
  logger
4429
4261
  );
4430
- return { appId: data.appId, txHash };
4262
+ return { appId: prepared.appId, txHash };
4431
4263
  }
4432
4264
  async function deployApp(options, logger) {
4433
4265
  const prepared = await prepareDeployBatch(
@@ -4441,17 +4273,7 @@ async function deployApp(options, logger) {
4441
4273
  },
4442
4274
  logger
4443
4275
  );
4444
- const data = {
4445
- appId: prepared.appId,
4446
- salt: prepared.salt,
4447
- executions: prepared.executions
4448
- };
4449
- const context = {
4450
- walletClient: prepared.walletClient,
4451
- publicClient: prepared.publicClient,
4452
- environmentConfig: prepared.environmentConfig
4453
- };
4454
- return executeDeployBatch(data, context, options.gas, logger);
4276
+ return executeDeployBatch(prepared, options.gas, logger);
4455
4277
  }
4456
4278
  async function prepareUpgradeBatch(options) {
4457
4279
  const {
@@ -4547,14 +4369,14 @@ async function prepareUpgradeBatch(options) {
4547
4369
  environmentConfig
4548
4370
  };
4549
4371
  }
4550
- async function executeUpgradeBatch(data, context, gas, logger) {
4551
- const pendingMessage = `Upgrading app ${data.appId}...`;
4372
+ async function executeUpgradeBatch(prepared, gas, logger) {
4373
+ const pendingMessage = `Upgrading app ${prepared.appId}...`;
4552
4374
  const txHash = await executeBatch(
4553
4375
  {
4554
- walletClient: context.walletClient,
4555
- publicClient: context.publicClient,
4556
- environmentConfig: context.environmentConfig,
4557
- executions: data.executions,
4376
+ walletClient: prepared.walletClient,
4377
+ publicClient: prepared.publicClient,
4378
+ environmentConfig: prepared.environmentConfig,
4379
+ executions: prepared.executions,
4558
4380
  pendingMessage,
4559
4381
  gas
4560
4382
  },
@@ -4572,16 +4394,7 @@ async function upgradeApp(options, logger) {
4572
4394
  publicLogs: options.publicLogs,
4573
4395
  needsPermissionChange: options.needsPermissionChange
4574
4396
  });
4575
- const data = {
4576
- appId: prepared.appId,
4577
- executions: prepared.executions
4578
- };
4579
- const context = {
4580
- walletClient: prepared.walletClient,
4581
- publicClient: prepared.publicClient,
4582
- environmentConfig: prepared.environmentConfig
4583
- };
4584
- return executeUpgradeBatch(data, context, options.gas, logger);
4397
+ return executeUpgradeBatch(prepared, options.gas, logger);
4585
4398
  }
4586
4399
  async function sendAndWaitForTransaction(options, logger) {
4587
4400
  const {
@@ -5252,97 +5065,6 @@ async function withSDKTelemetry(options, action) {
5252
5065
  }
5253
5066
 
5254
5067
  // src/client/modules/compute/app/deploy.ts
5255
- async function prepareDeployFromVerifiableBuild(options, logger = defaultLogger) {
5256
- return withSDKTelemetry(
5257
- {
5258
- functionName: "prepareDeployFromVerifiableBuild",
5259
- skipTelemetry: options.skipTelemetry,
5260
- properties: {
5261
- environment: options.environment || "sepolia"
5262
- }
5263
- },
5264
- async () => {
5265
- if (!options.privateKey) throw new Error("privateKey is required for deployment");
5266
- if (!options.imageRef) throw new Error("imageRef is required for deployment");
5267
- if (!options.imageDigest) throw new Error("imageDigest is required for deployment");
5268
- assertValidImageReference(options.imageRef);
5269
- validateAppName(options.appName);
5270
- validateLogVisibility(options.logVisibility);
5271
- if (!/^sha256:[0-9a-f]{64}$/i.test(options.imageDigest)) {
5272
- throw new Error(
5273
- `imageDigest must be in format sha256:<64 hex>, got: ${options.imageDigest}`
5274
- );
5275
- }
5276
- const { publicLogs } = validateLogVisibility(options.logVisibility);
5277
- validateResourceUsageMonitoring(options.resourceUsageMonitoring);
5278
- logger.debug("Performing preflight checks...");
5279
- const preflightCtx = await doPreflightChecks(
5280
- {
5281
- privateKey: options.privateKey,
5282
- rpcUrl: options.rpcUrl,
5283
- environment: options.environment
5284
- },
5285
- logger
5286
- );
5287
- logger.debug("Checking quota availability...");
5288
- await checkQuotaAvailable(preflightCtx);
5289
- const salt = generateRandomSalt();
5290
- logger.debug(`Generated salt: ${Buffer.from(salt).toString("hex")}`);
5291
- logger.debug("Calculating app ID...");
5292
- const appIDToBeDeployed = await calculateAppID(
5293
- preflightCtx.privateKey,
5294
- options.rpcUrl || preflightCtx.rpcUrl,
5295
- preflightCtx.environmentConfig,
5296
- salt
5297
- );
5298
- logger.info(``);
5299
- logger.info(`App ID: ${appIDToBeDeployed}`);
5300
- logger.info(``);
5301
- const release = await createReleaseFromImageDigest(
5302
- {
5303
- imageRef: options.imageRef,
5304
- imageDigest: options.imageDigest,
5305
- envFilePath: options.envFilePath,
5306
- instanceType: options.instanceType,
5307
- environmentConfig: preflightCtx.environmentConfig,
5308
- appId: appIDToBeDeployed
5309
- },
5310
- logger
5311
- );
5312
- logger.debug("Preparing deploy batch...");
5313
- const batch = await prepareDeployBatch(
5314
- {
5315
- privateKey: preflightCtx.privateKey,
5316
- rpcUrl: options.rpcUrl || preflightCtx.rpcUrl,
5317
- environmentConfig: preflightCtx.environmentConfig,
5318
- salt,
5319
- release,
5320
- publicLogs
5321
- },
5322
- logger
5323
- );
5324
- logger.debug("Estimating gas...");
5325
- const gasEstimate = await estimateBatchGas({
5326
- publicClient: batch.publicClient,
5327
- account: batch.walletClient.account.address,
5328
- executions: batch.executions
5329
- });
5330
- const data = {
5331
- appId: batch.appId,
5332
- salt: batch.salt,
5333
- executions: batch.executions
5334
- };
5335
- return {
5336
- prepared: {
5337
- data,
5338
- appName: options.appName,
5339
- imageRef: options.imageRef
5340
- },
5341
- gasEstimate
5342
- };
5343
- }
5344
- );
5345
- }
5346
5068
  function validateDeployOptions(options) {
5347
5069
  if (!options.privateKey) {
5348
5070
  throw new Error("privateKey is required for deployment");
@@ -5491,141 +5213,6 @@ function generateRandomSalt() {
5491
5213
  crypto.getRandomValues(salt);
5492
5214
  return salt;
5493
5215
  }
5494
- async function prepareDeploy(options, logger = defaultLogger) {
5495
- return withSDKTelemetry(
5496
- {
5497
- functionName: "prepareDeploy",
5498
- skipTelemetry: options.skipTelemetry,
5499
- properties: {
5500
- environment: options.environment || "sepolia"
5501
- }
5502
- },
5503
- async () => {
5504
- validateDeployOptions(options);
5505
- const { logRedirect, publicLogs } = validateLogVisibility(options.logVisibility);
5506
- const resourceUsageAllow = validateResourceUsageMonitoring(options.resourceUsageMonitoring);
5507
- logger.debug("Performing preflight checks...");
5508
- const preflightCtx = await doPreflightChecks(
5509
- {
5510
- privateKey: options.privateKey,
5511
- rpcUrl: options.rpcUrl,
5512
- environment: options.environment
5513
- },
5514
- logger
5515
- );
5516
- logger.debug("Checking quota availability...");
5517
- await checkQuotaAvailable(preflightCtx);
5518
- logger.debug("Checking Docker...");
5519
- await ensureDockerIsRunning();
5520
- const dockerfilePath = options.dockerfilePath || "";
5521
- const imageRef = options.imageRef || "";
5522
- const appName = options.appName;
5523
- const envFilePath = options.envFilePath || "";
5524
- const instanceType = options.instanceType;
5525
- const salt = generateRandomSalt();
5526
- logger.debug(`Generated salt: ${Buffer.from(salt).toString("hex")}`);
5527
- logger.debug("Calculating app ID...");
5528
- const appIDToBeDeployed = await calculateAppID(
5529
- preflightCtx.privateKey,
5530
- options.rpcUrl || preflightCtx.rpcUrl,
5531
- preflightCtx.environmentConfig,
5532
- salt
5533
- );
5534
- logger.info(``);
5535
- logger.info(`App ID: ${appIDToBeDeployed}`);
5536
- logger.info(``);
5537
- logger.info("Preparing release...");
5538
- const { release, finalImageRef } = await prepareRelease(
5539
- {
5540
- dockerfilePath,
5541
- imageRef,
5542
- envFilePath,
5543
- logRedirect,
5544
- resourceUsageAllow,
5545
- instanceType,
5546
- environmentConfig: preflightCtx.environmentConfig,
5547
- appId: appIDToBeDeployed
5548
- },
5549
- logger
5550
- );
5551
- logger.debug("Preparing deploy batch...");
5552
- const batch = await prepareDeployBatch(
5553
- {
5554
- privateKey: preflightCtx.privateKey,
5555
- rpcUrl: options.rpcUrl || preflightCtx.rpcUrl,
5556
- environmentConfig: preflightCtx.environmentConfig,
5557
- salt,
5558
- release,
5559
- publicLogs
5560
- },
5561
- logger
5562
- );
5563
- logger.debug("Estimating gas...");
5564
- const gasEstimate = await estimateBatchGas({
5565
- publicClient: batch.publicClient,
5566
- account: batch.walletClient.account.address,
5567
- executions: batch.executions
5568
- });
5569
- const data = {
5570
- appId: batch.appId,
5571
- salt: batch.salt,
5572
- executions: batch.executions
5573
- };
5574
- return {
5575
- prepared: {
5576
- data,
5577
- appName,
5578
- imageRef: finalImageRef
5579
- },
5580
- gasEstimate
5581
- };
5582
- }
5583
- );
5584
- }
5585
- async function executeDeploy(options) {
5586
- const { prepared, context, gas, logger = defaultLogger, skipTelemetry } = options;
5587
- return withSDKTelemetry(
5588
- {
5589
- functionName: "executeDeploy",
5590
- skipTelemetry
5591
- },
5592
- async () => {
5593
- logger.info("Deploying on-chain...");
5594
- const { appId, txHash } = await executeDeployBatch(prepared.data, context, gas, logger);
5595
- return {
5596
- appId,
5597
- txHash,
5598
- appName: prepared.appName,
5599
- imageRef: prepared.imageRef
5600
- };
5601
- }
5602
- );
5603
- }
5604
- async function watchDeployment(appId, privateKey, rpcUrl, environment, logger = defaultLogger, clientId, skipTelemetry) {
5605
- return withSDKTelemetry(
5606
- {
5607
- functionName: "watchDeployment",
5608
- skipTelemetry,
5609
- properties: {
5610
- environment
5611
- }
5612
- },
5613
- async () => {
5614
- const environmentConfig = getEnvironmentConfig(environment);
5615
- logger.info("Waiting for app to start...");
5616
- return watchUntilRunning(
5617
- {
5618
- privateKey,
5619
- rpcUrl,
5620
- environmentConfig,
5621
- appId,
5622
- clientId
5623
- },
5624
- logger
5625
- );
5626
- }
5627
- );
5628
- }
5629
5216
 
5630
5217
  // src/client/common/utils/permissions.ts
5631
5218
  var import_viem8 = require("viem");
@@ -5653,81 +5240,6 @@ async function checkAppLogPermission(preflightCtx, appAddress, logger) {
5653
5240
  }
5654
5241
 
5655
5242
  // src/client/modules/compute/app/upgrade.ts
5656
- async function prepareUpgradeFromVerifiableBuild(options, logger = defaultLogger) {
5657
- return withSDKTelemetry(
5658
- {
5659
- functionName: "prepareUpgradeFromVerifiableBuild",
5660
- skipTelemetry: options.skipTelemetry,
5661
- properties: {
5662
- environment: options.environment || "sepolia"
5663
- }
5664
- },
5665
- async () => {
5666
- logger.debug("Performing preflight checks...");
5667
- const preflightCtx = await doPreflightChecks(
5668
- {
5669
- privateKey: options.privateKey,
5670
- rpcUrl: options.rpcUrl,
5671
- environment: options.environment
5672
- },
5673
- logger
5674
- );
5675
- const appID = validateUpgradeOptions(options);
5676
- assertValidImageReference(options.imageRef);
5677
- if (!/^sha256:[0-9a-f]{64}$/i.test(options.imageDigest)) {
5678
- throw new Error(
5679
- `imageDigest must be in format sha256:<64 hex>, got: ${options.imageDigest}`
5680
- );
5681
- }
5682
- const { publicLogs } = validateLogVisibility(options.logVisibility);
5683
- validateResourceUsageMonitoring(options.resourceUsageMonitoring);
5684
- const envFilePath = options.envFilePath || "";
5685
- logger.info("Preparing release (verifiable build, no local layering)...");
5686
- const release = await createReleaseFromImageDigest(
5687
- {
5688
- imageRef: options.imageRef,
5689
- imageDigest: options.imageDigest,
5690
- envFilePath,
5691
- instanceType: options.instanceType,
5692
- environmentConfig: preflightCtx.environmentConfig,
5693
- appId: appID
5694
- },
5695
- logger
5696
- );
5697
- logger.debug("Checking current log permission state...");
5698
- const currentlyPublic = await checkAppLogPermission(preflightCtx, appID, logger);
5699
- const needsPermissionChange = currentlyPublic !== publicLogs;
5700
- logger.debug("Preparing upgrade batch...");
5701
- const batch = await prepareUpgradeBatch({
5702
- privateKey: preflightCtx.privateKey,
5703
- rpcUrl: options.rpcUrl || preflightCtx.rpcUrl,
5704
- environmentConfig: preflightCtx.environmentConfig,
5705
- appId: appID,
5706
- release,
5707
- publicLogs,
5708
- needsPermissionChange
5709
- });
5710
- logger.debug("Estimating gas...");
5711
- const gasEstimate = await estimateBatchGas({
5712
- publicClient: batch.publicClient,
5713
- account: batch.walletClient.account.address,
5714
- executions: batch.executions
5715
- });
5716
- const data = {
5717
- appId: batch.appId,
5718
- executions: batch.executions
5719
- };
5720
- return {
5721
- prepared: {
5722
- data,
5723
- appId: appID,
5724
- imageRef: options.imageRef
5725
- },
5726
- gasEstimate
5727
- };
5728
- }
5729
- );
5730
- }
5731
5243
  function validateUpgradeOptions(options) {
5732
5244
  if (!options.privateKey) {
5733
5245
  throw new Error("privateKey is required for upgrade");
@@ -5832,125 +5344,6 @@ async function upgrade(options, logger = defaultLogger) {
5832
5344
  }
5833
5345
  );
5834
5346
  }
5835
- async function prepareUpgrade(options, logger = defaultLogger) {
5836
- return withSDKTelemetry(
5837
- {
5838
- functionName: "prepareUpgrade",
5839
- skipTelemetry: options.skipTelemetry,
5840
- properties: {
5841
- environment: options.environment || "sepolia"
5842
- }
5843
- },
5844
- async () => {
5845
- logger.debug("Performing preflight checks...");
5846
- const preflightCtx = await doPreflightChecks(
5847
- {
5848
- privateKey: options.privateKey,
5849
- rpcUrl: options.rpcUrl,
5850
- environment: options.environment
5851
- },
5852
- logger
5853
- );
5854
- const appID = validateUpgradeOptions(options);
5855
- const { logRedirect, publicLogs } = validateLogVisibility(options.logVisibility);
5856
- const resourceUsageAllow = validateResourceUsageMonitoring(options.resourceUsageMonitoring);
5857
- logger.debug("Checking Docker...");
5858
- await ensureDockerIsRunning();
5859
- const dockerfilePath = options.dockerfilePath || "";
5860
- const imageRef = options.imageRef || "";
5861
- const envFilePath = options.envFilePath || "";
5862
- const instanceType = options.instanceType;
5863
- logger.info("Preparing release...");
5864
- const { release, finalImageRef } = await prepareRelease(
5865
- {
5866
- dockerfilePath,
5867
- imageRef,
5868
- envFilePath,
5869
- logRedirect,
5870
- resourceUsageAllow,
5871
- instanceType,
5872
- environmentConfig: preflightCtx.environmentConfig,
5873
- appId: appID
5874
- },
5875
- logger
5876
- );
5877
- logger.debug("Checking current log permission state...");
5878
- const currentlyPublic = await checkAppLogPermission(preflightCtx, appID, logger);
5879
- const needsPermissionChange = currentlyPublic !== publicLogs;
5880
- logger.debug("Preparing upgrade batch...");
5881
- const batch = await prepareUpgradeBatch({
5882
- privateKey: preflightCtx.privateKey,
5883
- rpcUrl: options.rpcUrl || preflightCtx.rpcUrl,
5884
- environmentConfig: preflightCtx.environmentConfig,
5885
- appId: appID,
5886
- release,
5887
- publicLogs,
5888
- needsPermissionChange
5889
- });
5890
- logger.debug("Estimating gas...");
5891
- const gasEstimate = await estimateBatchGas({
5892
- publicClient: batch.publicClient,
5893
- account: batch.walletClient.account.address,
5894
- executions: batch.executions
5895
- });
5896
- const data = {
5897
- appId: batch.appId,
5898
- executions: batch.executions
5899
- };
5900
- return {
5901
- prepared: {
5902
- data,
5903
- appId: appID,
5904
- imageRef: finalImageRef
5905
- },
5906
- gasEstimate
5907
- };
5908
- }
5909
- );
5910
- }
5911
- async function executeUpgrade(options) {
5912
- const { prepared, context, gas, logger = defaultLogger, skipTelemetry } = options;
5913
- return withSDKTelemetry(
5914
- {
5915
- functionName: "executeUpgrade",
5916
- skipTelemetry
5917
- },
5918
- async () => {
5919
- logger.info("Upgrading on-chain...");
5920
- const txHash = await executeUpgradeBatch(prepared.data, context, gas, logger);
5921
- return {
5922
- appId: prepared.appId,
5923
- imageRef: prepared.imageRef,
5924
- txHash
5925
- };
5926
- }
5927
- );
5928
- }
5929
- async function watchUpgrade(appId, privateKey, rpcUrl, environment, logger = defaultLogger, clientId, skipTelemetry) {
5930
- return withSDKTelemetry(
5931
- {
5932
- functionName: "watchUpgrade",
5933
- skipTelemetry,
5934
- properties: {
5935
- environment
5936
- }
5937
- },
5938
- async () => {
5939
- const environmentConfig = getEnvironmentConfig(environment);
5940
- logger.info("Waiting for upgrade to complete...");
5941
- await watchUntilUpgradeComplete(
5942
- {
5943
- privateKey,
5944
- rpcUrl,
5945
- environmentConfig,
5946
- appId,
5947
- clientId
5948
- },
5949
- logger
5950
- );
5951
- }
5952
- );
5953
- }
5954
5347
 
5955
5348
  // src/client/modules/compute/app/create.ts
5956
5349
  var fs7 = __toESM(require("fs"), 1);
@@ -6048,8 +5441,8 @@ var path4 = __toESM(require("path"), 1);
6048
5441
  var os3 = __toESM(require("os"), 1);
6049
5442
  var import_child_process2 = require("child_process");
6050
5443
  var import_util4 = require("util");
6051
- var execAsync = (0, import_util4.promisify)(import_child_process2.exec);
6052
- var execFileAsync3 = (0, import_util4.promisify)(import_child_process2.execFile);
5444
+ var execAsync2 = (0, import_util4.promisify)(import_child_process2.exec);
5445
+ var execFileAsync2 = (0, import_util4.promisify)(import_child_process2.execFile);
6053
5446
  async function fetchTemplate(repoURL, ref, targetDir, config, logger) {
6054
5447
  if (!repoURL) {
6055
5448
  throw new Error("repoURL is required");
@@ -6058,13 +5451,13 @@ async function fetchTemplate(repoURL, ref, targetDir, config, logger) {
6058
5451
  Cloning repo: ${repoURL} \u2192 ${targetDir}
6059
5452
  `);
6060
5453
  try {
6061
- await execAsync(`git clone --no-checkout --progress ${repoURL} ${targetDir}`, {
5454
+ await execAsync2(`git clone --no-checkout --progress ${repoURL} ${targetDir}`, {
6062
5455
  maxBuffer: 10 * 1024 * 1024
6063
5456
  });
6064
- await execFileAsync3("git", ["-C", targetDir, "checkout", "--quiet", ref], {
5457
+ await execFileAsync2("git", ["-C", targetDir, "checkout", "--quiet", ref], {
6065
5458
  maxBuffer: 10 * 1024 * 1024
6066
5459
  });
6067
- await execFileAsync3(
5460
+ await execFileAsync2(
6068
5461
  "git",
6069
5462
  ["-C", targetDir, "submodule", "update", "--init", "--recursive", "--progress"],
6070
5463
  { maxBuffer: 10 * 1024 * 1024 }
@@ -6109,14 +5502,14 @@ Cloning template: ${repoURL} \u2192 extracting ${subPath}
6109
5502
  }
6110
5503
  async function cloneSparse(repoURL, ref, subPath, tempDir) {
6111
5504
  try {
6112
- await execFileAsync3("git", ["init", tempDir]);
6113
- await execFileAsync3("git", ["-C", tempDir, "remote", "add", "origin", repoURL]);
6114
- await execFileAsync3("git", ["-C", tempDir, "config", "core.sparseCheckout", "true"]);
5505
+ await execFileAsync2("git", ["init", tempDir]);
5506
+ await execFileAsync2("git", ["-C", tempDir, "remote", "add", "origin", repoURL]);
5507
+ await execFileAsync2("git", ["-C", tempDir, "config", "core.sparseCheckout", "true"]);
6115
5508
  const sparseCheckoutPath = path4.join(tempDir, ".git/info/sparse-checkout");
6116
5509
  fs5.writeFileSync(sparseCheckoutPath, `${subPath}
6117
5510
  `);
6118
- await execFileAsync3("git", ["-C", tempDir, "fetch", "origin", ref]);
6119
- await execFileAsync3("git", ["-C", tempDir, "checkout", ref]);
5511
+ await execFileAsync2("git", ["-C", tempDir, "fetch", "origin", ref]);
5512
+ await execFileAsync2("git", ["-C", tempDir, "checkout", ref]);
6120
5513
  } catch (error) {
6121
5514
  throw new Error(`Failed to clone sparse repository: ${error.message}`);
6122
5515
  }
@@ -6691,187 +6084,6 @@ function createAppModule(ctx) {
6691
6084
  imageRef: result.imageRef
6692
6085
  };
6693
6086
  },
6694
- // Granular deploy control
6695
- async prepareDeploy(opts) {
6696
- return prepareDeploy(
6697
- {
6698
- privateKey,
6699
- rpcUrl: ctx.rpcUrl,
6700
- environment: ctx.environment,
6701
- appName: opts.name,
6702
- instanceType: opts.instanceType,
6703
- dockerfilePath: opts.dockerfile,
6704
- envFilePath: opts.envFile,
6705
- imageRef: opts.imageRef,
6706
- logVisibility: opts.logVisibility,
6707
- resourceUsageMonitoring: opts.resourceUsageMonitoring,
6708
- skipTelemetry
6709
- },
6710
- logger
6711
- );
6712
- },
6713
- async prepareDeployFromVerifiableBuild(opts) {
6714
- return prepareDeployFromVerifiableBuild(
6715
- {
6716
- privateKey,
6717
- rpcUrl: ctx.rpcUrl,
6718
- environment: ctx.environment,
6719
- appName: opts.name,
6720
- instanceType: opts.instanceType,
6721
- envFilePath: opts.envFile,
6722
- imageRef: opts.imageRef,
6723
- imageDigest: opts.imageDigest,
6724
- logVisibility: opts.logVisibility,
6725
- resourceUsageMonitoring: opts.resourceUsageMonitoring,
6726
- skipTelemetry
6727
- },
6728
- logger
6729
- );
6730
- },
6731
- async executeDeploy(prepared, gas) {
6732
- const account = (0, import_accounts5.privateKeyToAccount)(privateKey);
6733
- const chain = getChainFromID(environment.chainID);
6734
- const publicClient = (0, import_viem9.createPublicClient)({
6735
- chain,
6736
- transport: (0, import_viem9.http)(ctx.rpcUrl)
6737
- });
6738
- const walletClient = (0, import_viem9.createWalletClient)({
6739
- account,
6740
- chain,
6741
- transport: (0, import_viem9.http)(ctx.rpcUrl)
6742
- });
6743
- const result = await executeDeploy({
6744
- prepared,
6745
- context: {
6746
- walletClient,
6747
- publicClient,
6748
- environmentConfig: environment
6749
- },
6750
- gas,
6751
- logger,
6752
- skipTelemetry
6753
- });
6754
- return {
6755
- appId: result.appId,
6756
- txHash: result.txHash,
6757
- appName: result.appName,
6758
- imageRef: result.imageRef
6759
- };
6760
- },
6761
- async watchDeployment(appId) {
6762
- return watchDeployment(
6763
- appId,
6764
- privateKey,
6765
- ctx.rpcUrl,
6766
- ctx.environment,
6767
- logger,
6768
- ctx.clientId,
6769
- skipTelemetry
6770
- );
6771
- },
6772
- // Granular upgrade control
6773
- async prepareUpgrade(appId, opts) {
6774
- return prepareUpgrade(
6775
- {
6776
- appId,
6777
- privateKey,
6778
- rpcUrl: ctx.rpcUrl,
6779
- environment: ctx.environment,
6780
- instanceType: opts.instanceType,
6781
- dockerfilePath: opts.dockerfile,
6782
- envFilePath: opts.envFile,
6783
- imageRef: opts.imageRef,
6784
- logVisibility: opts.logVisibility,
6785
- resourceUsageMonitoring: opts.resourceUsageMonitoring,
6786
- skipTelemetry
6787
- },
6788
- logger
6789
- );
6790
- },
6791
- async prepareUpgradeFromVerifiableBuild(appId, opts) {
6792
- return prepareUpgradeFromVerifiableBuild(
6793
- {
6794
- appId,
6795
- privateKey,
6796
- rpcUrl: ctx.rpcUrl,
6797
- environment: ctx.environment,
6798
- instanceType: opts.instanceType,
6799
- envFilePath: opts.envFile,
6800
- imageRef: opts.imageRef,
6801
- imageDigest: opts.imageDigest,
6802
- logVisibility: opts.logVisibility,
6803
- resourceUsageMonitoring: opts.resourceUsageMonitoring,
6804
- skipTelemetry
6805
- },
6806
- logger
6807
- );
6808
- },
6809
- async executeUpgrade(prepared, gas) {
6810
- const account = (0, import_accounts5.privateKeyToAccount)(privateKey);
6811
- const chain = getChainFromID(environment.chainID);
6812
- const publicClient = (0, import_viem9.createPublicClient)({
6813
- chain,
6814
- transport: (0, import_viem9.http)(ctx.rpcUrl)
6815
- });
6816
- const walletClient = (0, import_viem9.createWalletClient)({
6817
- account,
6818
- chain,
6819
- transport: (0, import_viem9.http)(ctx.rpcUrl)
6820
- });
6821
- const result = await executeUpgrade({
6822
- prepared,
6823
- context: {
6824
- walletClient,
6825
- publicClient,
6826
- environmentConfig: environment
6827
- },
6828
- gas,
6829
- logger,
6830
- skipTelemetry
6831
- });
6832
- return {
6833
- appId: result.appId,
6834
- txHash: result.txHash,
6835
- imageRef: result.imageRef
6836
- };
6837
- },
6838
- async watchUpgrade(appId) {
6839
- return watchUpgrade(
6840
- appId,
6841
- privateKey,
6842
- ctx.rpcUrl,
6843
- ctx.environment,
6844
- logger,
6845
- ctx.clientId,
6846
- skipTelemetry
6847
- );
6848
- },
6849
- // Profile management
6850
- async setProfile(appId, profile) {
6851
- return withSDKTelemetry(
6852
- {
6853
- functionName: "setProfile",
6854
- skipTelemetry,
6855
- properties: { environment: ctx.environment }
6856
- },
6857
- async () => {
6858
- const userApiClient = new UserApiClient(
6859
- environment,
6860
- privateKey,
6861
- ctx.rpcUrl,
6862
- ctx.clientId
6863
- );
6864
- return userApiClient.uploadAppProfile(
6865
- appId,
6866
- profile.name,
6867
- profile.website,
6868
- profile.description,
6869
- profile.xURL,
6870
- profile.imagePath
6871
- );
6872
- }
6873
- );
6874
- },
6875
6087
  async logs(opts) {
6876
6088
  return logs(
6877
6089
  {