@layr-labs/ecloud-sdk 0.2.0-dev → 0.2.0-dev.1
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 -2
- package/dist/billing.cjs +19 -0
- package/dist/billing.cjs.map +1 -1
- package/dist/billing.d.cts +3 -2
- package/dist/billing.d.ts +3 -2
- package/dist/billing.js +2 -2
- package/dist/{chunk-34DXGQ35.js → chunk-FY7UU55U.js} +2 -2
- package/dist/chunk-FY7UU55U.js.map +1 -0
- package/dist/chunk-GB4GM4C2.js +434 -0
- package/dist/chunk-GB4GM4C2.js.map +1 -0
- package/dist/{chunk-HLH3AMQF.js → chunk-O7EU5JL7.js} +328 -123
- package/dist/chunk-O7EU5JL7.js.map +1 -0
- package/dist/{compute-B_ibIORD.d.cts → compute-CF2HOXed.d.ts} +101 -15
- package/dist/{compute-gpepEsn3.d.ts → compute-CbmjA8kJ.d.cts} +101 -15
- package/dist/compute.cjs +772 -62
- package/dist/compute.cjs.map +1 -1
- package/dist/compute.d.cts +2 -2
- package/dist/compute.d.ts +2 -2
- package/dist/compute.js +2 -2
- package/dist/{index-D-SUX3IG.d.ts → index-D2QufVB9.d.cts} +130 -6
- package/dist/{index-D-SUX3IG.d.cts → index-D2QufVB9.d.ts} +130 -6
- package/dist/index.cjs +646 -438
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +52 -166
- package/dist/index.d.ts +52 -166
- package/dist/index.js +17 -243
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/dist/chunk-34DXGQ35.js.map +0 -1
- package/dist/chunk-HLH3AMQF.js.map +0 -1
- package/dist/chunk-LINGJMAS.js +0 -180
- package/dist/chunk-LINGJMAS.js.map +0 -1
package/dist/compute.cjs
CHANGED
|
@@ -40,6 +40,7 @@ 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");
|
|
43
44
|
|
|
44
45
|
// src/client/common/config/environment.ts
|
|
45
46
|
var SEPOLIA_CHAIN_ID = 11155111;
|
|
@@ -162,6 +163,7 @@ async function buildDockerImage(buildContext, dockerfilePath, tag, logger) {
|
|
|
162
163
|
tag,
|
|
163
164
|
"-f",
|
|
164
165
|
dockerfilePath,
|
|
166
|
+
"--load",
|
|
165
167
|
"--progress=plain",
|
|
166
168
|
buildContext
|
|
167
169
|
];
|
|
@@ -287,7 +289,7 @@ async function pullDockerImage(docker, imageTag, platform2 = "linux/amd64", logg
|
|
|
287
289
|
var child_process2 = __toESM(require("child_process"), 1);
|
|
288
290
|
var import_child_process = require("child_process");
|
|
289
291
|
var import_util2 = require("util");
|
|
290
|
-
var
|
|
292
|
+
var execFileAsync = (0, import_util2.promisify)(import_child_process.execFile);
|
|
291
293
|
async function pushDockerImage(docker, imageRef, logger) {
|
|
292
294
|
logger?.info?.(`Pushing image ${imageRef}...`);
|
|
293
295
|
return new Promise((resolve2, reject) => {
|
|
@@ -328,9 +330,9 @@ async function pushDockerImage(docker, imageRef, logger) {
|
|
|
328
330
|
if (!output.includes("digest:") && !output.includes("pushed") && !output.includes("Pushed")) {
|
|
329
331
|
logger?.debug?.("No clear success indicator in push output, verifying...");
|
|
330
332
|
}
|
|
331
|
-
logger?.info?.("Image push completed successfully");
|
|
332
333
|
try {
|
|
333
334
|
await verifyImageExists(imageRef, logger);
|
|
335
|
+
logger?.info?.("Image push completed successfully");
|
|
334
336
|
resolve2();
|
|
335
337
|
} catch (error) {
|
|
336
338
|
reject(error);
|
|
@@ -354,7 +356,7 @@ async function verifyImageExists(imageRef, logger) {
|
|
|
354
356
|
let retries = 5;
|
|
355
357
|
while (retries > 0) {
|
|
356
358
|
try {
|
|
357
|
-
await
|
|
359
|
+
await execFileAsync("docker", ["manifest", "inspect", imageRef], {
|
|
358
360
|
maxBuffer: 10 * 1024 * 1024,
|
|
359
361
|
timeout: 1e4
|
|
360
362
|
// 10 second timeout
|
|
@@ -828,10 +830,10 @@ async function setupLayeredBuildDirectory(environmentConfig, layeredDockerfileCo
|
|
|
828
830
|
// src/client/common/registry/digest.ts
|
|
829
831
|
var child_process3 = __toESM(require("child_process"), 1);
|
|
830
832
|
var import_util3 = require("util");
|
|
831
|
-
var
|
|
833
|
+
var execFileAsync2 = (0, import_util3.promisify)(child_process3.execFile);
|
|
832
834
|
async function getImageDigestAndName(imageRef) {
|
|
833
835
|
try {
|
|
834
|
-
const { stdout } = await
|
|
836
|
+
const { stdout } = await execFileAsync2(
|
|
835
837
|
"docker",
|
|
836
838
|
["manifest", "inspect", imageRef],
|
|
837
839
|
{ maxBuffer: 10 * 1024 * 1024 }
|
|
@@ -871,7 +873,7 @@ function extractDigestFromMultiPlatform(manifest, imageRef) {
|
|
|
871
873
|
}
|
|
872
874
|
async function extractDigestFromSinglePlatform(manifest, imageRef) {
|
|
873
875
|
try {
|
|
874
|
-
const { stdout } = await
|
|
876
|
+
const { stdout } = await execFileAsync2("docker", ["inspect", imageRef], {
|
|
875
877
|
maxBuffer: 10 * 1024 * 1024
|
|
876
878
|
});
|
|
877
879
|
const inspectData = JSON.parse(stdout);
|
|
@@ -1169,6 +1171,67 @@ Please verify the image exists: docker manifest inspect ${finalImageRef}`
|
|
|
1169
1171
|
};
|
|
1170
1172
|
}
|
|
1171
1173
|
|
|
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
|
+
|
|
1172
1235
|
// src/client/common/contract/caller.ts
|
|
1173
1236
|
var import_accounts2 = require("viem/accounts");
|
|
1174
1237
|
|
|
@@ -2205,8 +2268,55 @@ var ERC7702Delegator_default = [
|
|
|
2205
2268
|
];
|
|
2206
2269
|
|
|
2207
2270
|
// 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
|
+
}
|
|
2208
2318
|
async function checkERC7702Delegation(publicClient, account, delegatorAddress) {
|
|
2209
|
-
const code = await publicClient.
|
|
2319
|
+
const code = await publicClient.getCode({ address: account });
|
|
2210
2320
|
if (!code) {
|
|
2211
2321
|
return false;
|
|
2212
2322
|
}
|
|
@@ -2223,36 +2333,7 @@ async function executeBatch(options, logger) {
|
|
|
2223
2333
|
if (!chain) {
|
|
2224
2334
|
throw new Error("Wallet client must have a chain");
|
|
2225
2335
|
}
|
|
2226
|
-
const
|
|
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
|
-
}
|
|
2336
|
+
const executeBatchData = encodeExecuteBatchData(executions);
|
|
2256
2337
|
const isDelegated2 = await checkERC7702Delegation(
|
|
2257
2338
|
publicClient,
|
|
2258
2339
|
account.address,
|
|
@@ -2401,7 +2482,7 @@ var CanViewAppLogsPermission = "0x2fd3f2fe";
|
|
|
2401
2482
|
var CanViewSensitiveAppInfoPermission = "0x0e67b22f";
|
|
2402
2483
|
var CanUpdateAppProfilePermission = "0x036fef61";
|
|
2403
2484
|
function getDefaultClientId() {
|
|
2404
|
-
const version = true ? "0.2.0-dev" : "0.0.0";
|
|
2485
|
+
const version = true ? "0.2.0-dev.1" : "0.0.0";
|
|
2405
2486
|
return `ecloud-sdk/v${version}`;
|
|
2406
2487
|
}
|
|
2407
2488
|
var UserApiClient = class {
|
|
@@ -4220,6 +4301,15 @@ var PermissionController_default = [
|
|
|
4220
4301
|
];
|
|
4221
4302
|
|
|
4222
4303
|
// 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
|
+
}
|
|
4223
4313
|
async function calculateAppID(privateKey, rpcUrl, environmentConfig, salt) {
|
|
4224
4314
|
const privateKeyHex = addHexPrefix(privateKey);
|
|
4225
4315
|
const account = (0, import_accounts2.privateKeyToAccount)(privateKeyHex);
|
|
@@ -4324,20 +4414,20 @@ async function prepareDeployBatch(options, logger) {
|
|
|
4324
4414
|
environmentConfig
|
|
4325
4415
|
};
|
|
4326
4416
|
}
|
|
4327
|
-
async function executeDeployBatch(
|
|
4417
|
+
async function executeDeployBatch(data, context, gas, logger) {
|
|
4328
4418
|
const pendingMessage = "Deploying new app...";
|
|
4329
4419
|
const txHash = await executeBatch(
|
|
4330
4420
|
{
|
|
4331
|
-
walletClient:
|
|
4332
|
-
publicClient:
|
|
4333
|
-
environmentConfig:
|
|
4334
|
-
executions:
|
|
4421
|
+
walletClient: context.walletClient,
|
|
4422
|
+
publicClient: context.publicClient,
|
|
4423
|
+
environmentConfig: context.environmentConfig,
|
|
4424
|
+
executions: data.executions,
|
|
4335
4425
|
pendingMessage,
|
|
4336
4426
|
gas
|
|
4337
4427
|
},
|
|
4338
4428
|
logger
|
|
4339
4429
|
);
|
|
4340
|
-
return { appId:
|
|
4430
|
+
return { appId: data.appId, txHash };
|
|
4341
4431
|
}
|
|
4342
4432
|
async function deployApp(options, logger) {
|
|
4343
4433
|
const prepared = await prepareDeployBatch(
|
|
@@ -4351,7 +4441,17 @@ async function deployApp(options, logger) {
|
|
|
4351
4441
|
},
|
|
4352
4442
|
logger
|
|
4353
4443
|
);
|
|
4354
|
-
|
|
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);
|
|
4355
4455
|
}
|
|
4356
4456
|
async function prepareUpgradeBatch(options) {
|
|
4357
4457
|
const {
|
|
@@ -4447,14 +4547,14 @@ async function prepareUpgradeBatch(options) {
|
|
|
4447
4547
|
environmentConfig
|
|
4448
4548
|
};
|
|
4449
4549
|
}
|
|
4450
|
-
async function executeUpgradeBatch(
|
|
4451
|
-
const pendingMessage = `Upgrading app ${
|
|
4550
|
+
async function executeUpgradeBatch(data, context, gas, logger) {
|
|
4551
|
+
const pendingMessage = `Upgrading app ${data.appId}...`;
|
|
4452
4552
|
const txHash = await executeBatch(
|
|
4453
4553
|
{
|
|
4454
|
-
walletClient:
|
|
4455
|
-
publicClient:
|
|
4456
|
-
environmentConfig:
|
|
4457
|
-
executions:
|
|
4554
|
+
walletClient: context.walletClient,
|
|
4555
|
+
publicClient: context.publicClient,
|
|
4556
|
+
environmentConfig: context.environmentConfig,
|
|
4557
|
+
executions: data.executions,
|
|
4458
4558
|
pendingMessage,
|
|
4459
4559
|
gas
|
|
4460
4560
|
},
|
|
@@ -4472,7 +4572,16 @@ async function upgradeApp(options, logger) {
|
|
|
4472
4572
|
publicLogs: options.publicLogs,
|
|
4473
4573
|
needsPermissionChange: options.needsPermissionChange
|
|
4474
4574
|
});
|
|
4475
|
-
|
|
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);
|
|
4476
4585
|
}
|
|
4477
4586
|
async function sendAndWaitForTransaction(options, logger) {
|
|
4478
4587
|
const {
|
|
@@ -5143,6 +5252,97 @@ async function withSDKTelemetry(options, action) {
|
|
|
5143
5252
|
}
|
|
5144
5253
|
|
|
5145
5254
|
// 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
|
+
}
|
|
5146
5346
|
function validateDeployOptions(options) {
|
|
5147
5347
|
if (!options.privateKey) {
|
|
5148
5348
|
throw new Error("privateKey is required for deployment");
|
|
@@ -5291,6 +5491,141 @@ function generateRandomSalt() {
|
|
|
5291
5491
|
crypto.getRandomValues(salt);
|
|
5292
5492
|
return salt;
|
|
5293
5493
|
}
|
|
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
|
+
}
|
|
5294
5629
|
|
|
5295
5630
|
// src/client/common/utils/permissions.ts
|
|
5296
5631
|
var import_viem8 = require("viem");
|
|
@@ -5318,6 +5653,81 @@ async function checkAppLogPermission(preflightCtx, appAddress, logger) {
|
|
|
5318
5653
|
}
|
|
5319
5654
|
|
|
5320
5655
|
// 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
|
+
}
|
|
5321
5731
|
function validateUpgradeOptions(options) {
|
|
5322
5732
|
if (!options.privateKey) {
|
|
5323
5733
|
throw new Error("privateKey is required for upgrade");
|
|
@@ -5422,6 +5832,125 @@ async function upgrade(options, logger = defaultLogger) {
|
|
|
5422
5832
|
}
|
|
5423
5833
|
);
|
|
5424
5834
|
}
|
|
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
|
+
}
|
|
5425
5954
|
|
|
5426
5955
|
// src/client/modules/compute/app/create.ts
|
|
5427
5956
|
var fs7 = __toESM(require("fs"), 1);
|
|
@@ -5519,8 +6048,8 @@ var path4 = __toESM(require("path"), 1);
|
|
|
5519
6048
|
var os3 = __toESM(require("os"), 1);
|
|
5520
6049
|
var import_child_process2 = require("child_process");
|
|
5521
6050
|
var import_util4 = require("util");
|
|
5522
|
-
var
|
|
5523
|
-
var
|
|
6051
|
+
var execAsync = (0, import_util4.promisify)(import_child_process2.exec);
|
|
6052
|
+
var execFileAsync3 = (0, import_util4.promisify)(import_child_process2.execFile);
|
|
5524
6053
|
async function fetchTemplate(repoURL, ref, targetDir, config, logger) {
|
|
5525
6054
|
if (!repoURL) {
|
|
5526
6055
|
throw new Error("repoURL is required");
|
|
@@ -5529,13 +6058,13 @@ async function fetchTemplate(repoURL, ref, targetDir, config, logger) {
|
|
|
5529
6058
|
Cloning repo: ${repoURL} \u2192 ${targetDir}
|
|
5530
6059
|
`);
|
|
5531
6060
|
try {
|
|
5532
|
-
await
|
|
6061
|
+
await execAsync(`git clone --no-checkout --progress ${repoURL} ${targetDir}`, {
|
|
5533
6062
|
maxBuffer: 10 * 1024 * 1024
|
|
5534
6063
|
});
|
|
5535
|
-
await
|
|
6064
|
+
await execFileAsync3("git", ["-C", targetDir, "checkout", "--quiet", ref], {
|
|
5536
6065
|
maxBuffer: 10 * 1024 * 1024
|
|
5537
6066
|
});
|
|
5538
|
-
await
|
|
6067
|
+
await execFileAsync3(
|
|
5539
6068
|
"git",
|
|
5540
6069
|
["-C", targetDir, "submodule", "update", "--init", "--recursive", "--progress"],
|
|
5541
6070
|
{ maxBuffer: 10 * 1024 * 1024 }
|
|
@@ -5580,14 +6109,14 @@ Cloning template: ${repoURL} \u2192 extracting ${subPath}
|
|
|
5580
6109
|
}
|
|
5581
6110
|
async function cloneSparse(repoURL, ref, subPath, tempDir) {
|
|
5582
6111
|
try {
|
|
5583
|
-
await
|
|
5584
|
-
await
|
|
5585
|
-
await
|
|
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"]);
|
|
5586
6115
|
const sparseCheckoutPath = path4.join(tempDir, ".git/info/sparse-checkout");
|
|
5587
6116
|
fs5.writeFileSync(sparseCheckoutPath, `${subPath}
|
|
5588
6117
|
`);
|
|
5589
|
-
await
|
|
5590
|
-
await
|
|
6118
|
+
await execFileAsync3("git", ["-C", tempDir, "fetch", "origin", ref]);
|
|
6119
|
+
await execFileAsync3("git", ["-C", tempDir, "checkout", ref]);
|
|
5591
6120
|
} catch (error) {
|
|
5592
6121
|
throw new Error(`Failed to clone sparse repository: ${error.message}`);
|
|
5593
6122
|
}
|
|
@@ -6162,6 +6691,187 @@ function createAppModule(ctx) {
|
|
|
6162
6691
|
imageRef: result.imageRef
|
|
6163
6692
|
};
|
|
6164
6693
|
},
|
|
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
|
+
},
|
|
6165
6875
|
async logs(opts) {
|
|
6166
6876
|
return logs(
|
|
6167
6877
|
{
|