@layr-labs/ecloud-sdk 0.2.0-dev.3 → 0.2.1-dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/VERSION +2 -2
- package/dist/billing.cjs +34 -37
- package/dist/billing.cjs.map +1 -1
- package/dist/billing.d.cts +6 -3
- package/dist/billing.d.ts +6 -3
- package/dist/billing.js +511 -4
- package/dist/billing.js.map +1 -1
- package/dist/browser.cjs +2990 -0
- package/dist/browser.cjs.map +1 -0
- package/dist/browser.d.cts +42 -0
- package/dist/browser.d.ts +42 -0
- package/dist/browser.js +2922 -0
- package/dist/browser.js.map +1 -0
- package/dist/{compute-CF2HOXed.d.ts → compute-B85ikS78.d.ts} +15 -96
- package/dist/{compute-CbmjA8kJ.d.cts → compute-CC0R7HEu.d.cts} +15 -96
- package/dist/compute.cjs +655 -841
- 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 +6797 -7
- package/dist/compute.js.map +1 -1
- package/dist/eip7702-CXCYfOnk.d.ts +400 -0
- package/dist/eip7702-DeqoCP5b.d.cts +400 -0
- package/dist/{index-D2QufVB9.d.ts → index-D5oW73Dx.d.cts} +105 -15
- package/dist/{index-D2QufVB9.d.cts → index-D5oW73Dx.d.ts} +105 -15
- package/dist/index.cjs +1404 -1554
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +123 -388
- package/dist/index.d.ts +123 -388
- package/dist/index.js +7632 -124
- package/dist/index.js.map +1 -1
- package/package.json +6 -1
- package/dist/chunk-OUCNETHL.js +0 -434
- package/dist/chunk-OUCNETHL.js.map +0 -1
- package/dist/chunk-QN7KAUOB.js +0 -744
- package/dist/chunk-QN7KAUOB.js.map +0 -1
- package/dist/chunk-R44OVMCY.js +0 -6719
- package/dist/chunk-R44OVMCY.js.map +0 -1
package/dist/compute.cjs
CHANGED
|
@@ -39,100 +39,7 @@ __export(compute_exports, {
|
|
|
39
39
|
module.exports = __toCommonJS(compute_exports);
|
|
40
40
|
|
|
41
41
|
// src/client/modules/compute/app/index.ts
|
|
42
|
-
var
|
|
43
|
-
var import_accounts5 = require("viem/accounts");
|
|
44
|
-
|
|
45
|
-
// src/client/common/config/environment.ts
|
|
46
|
-
var SEPOLIA_CHAIN_ID = 11155111;
|
|
47
|
-
var MAINNET_CHAIN_ID = 1;
|
|
48
|
-
var CommonAddresses = {
|
|
49
|
-
ERC7702Delegator: "0x63c0c19a282a1b52b07dd5a65b58948a07dae32b"
|
|
50
|
-
};
|
|
51
|
-
var ChainAddresses = {
|
|
52
|
-
[MAINNET_CHAIN_ID]: {
|
|
53
|
-
PermissionController: "0x25E5F8B1E7aDf44518d35D5B2271f114e081f0E5"
|
|
54
|
-
},
|
|
55
|
-
[SEPOLIA_CHAIN_ID]: {
|
|
56
|
-
PermissionController: "0x44632dfBdCb6D3E21EF613B0ca8A6A0c618F5a37"
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
var ENVIRONMENTS = {
|
|
60
|
-
"sepolia-dev": {
|
|
61
|
-
name: "sepolia",
|
|
62
|
-
build: "dev",
|
|
63
|
-
appControllerAddress: "0xa86DC1C47cb2518327fB4f9A1627F51966c83B92",
|
|
64
|
-
permissionControllerAddress: ChainAddresses[SEPOLIA_CHAIN_ID].PermissionController,
|
|
65
|
-
erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,
|
|
66
|
-
kmsServerURL: "http://10.128.0.57:8080",
|
|
67
|
-
userApiServerURL: "https://userapi-compute-sepolia-dev.eigencloud.xyz",
|
|
68
|
-
defaultRPCURL: "https://ethereum-sepolia-rpc.publicnode.com"
|
|
69
|
-
},
|
|
70
|
-
sepolia: {
|
|
71
|
-
name: "sepolia",
|
|
72
|
-
build: "prod",
|
|
73
|
-
appControllerAddress: "0x0dd810a6ffba6a9820a10d97b659f07d8d23d4E2",
|
|
74
|
-
permissionControllerAddress: ChainAddresses[SEPOLIA_CHAIN_ID].PermissionController,
|
|
75
|
-
erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,
|
|
76
|
-
kmsServerURL: "http://10.128.15.203:8080",
|
|
77
|
-
userApiServerURL: "https://userapi-compute-sepolia-prod.eigencloud.xyz",
|
|
78
|
-
defaultRPCURL: "https://ethereum-sepolia-rpc.publicnode.com"
|
|
79
|
-
},
|
|
80
|
-
"mainnet-alpha": {
|
|
81
|
-
name: "mainnet-alpha",
|
|
82
|
-
build: "prod",
|
|
83
|
-
appControllerAddress: "0xc38d35Fc995e75342A21CBd6D770305b142Fbe67",
|
|
84
|
-
permissionControllerAddress: ChainAddresses[MAINNET_CHAIN_ID].PermissionController,
|
|
85
|
-
erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,
|
|
86
|
-
kmsServerURL: "http://10.128.0.2:8080",
|
|
87
|
-
userApiServerURL: "https://userapi-compute.eigencloud.xyz",
|
|
88
|
-
defaultRPCURL: "https://ethereum-rpc.publicnode.com"
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
var CHAIN_ID_TO_ENVIRONMENT = {
|
|
92
|
-
[SEPOLIA_CHAIN_ID.toString()]: "sepolia",
|
|
93
|
-
[MAINNET_CHAIN_ID.toString()]: "mainnet-alpha"
|
|
94
|
-
};
|
|
95
|
-
function getEnvironmentConfig(environment, chainID) {
|
|
96
|
-
const env = ENVIRONMENTS[environment];
|
|
97
|
-
if (!env) {
|
|
98
|
-
throw new Error(`Unknown environment: ${environment}`);
|
|
99
|
-
}
|
|
100
|
-
if (!isEnvironmentAvailable(environment)) {
|
|
101
|
-
throw new Error(
|
|
102
|
-
`Environment ${environment} is not available in this build type. Available environments: ${getAvailableEnvironments().join(", ")}`
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
if (chainID) {
|
|
106
|
-
const expectedEnv = CHAIN_ID_TO_ENVIRONMENT[chainID.toString()];
|
|
107
|
-
if (expectedEnv && expectedEnv !== environment) {
|
|
108
|
-
throw new Error(`Environment ${environment} does not match chain ID ${chainID}`);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
const resolvedChainID = chainID || (environment === "sepolia" || environment === "sepolia-dev" ? SEPOLIA_CHAIN_ID : MAINNET_CHAIN_ID);
|
|
112
|
-
return {
|
|
113
|
-
...env,
|
|
114
|
-
chainID: BigInt(resolvedChainID)
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
function getBuildType() {
|
|
118
|
-
const buildTimeType = true ? "dev"?.toLowerCase() : void 0;
|
|
119
|
-
const runtimeType = process.env.BUILD_TYPE?.toLowerCase();
|
|
120
|
-
const buildType = buildTimeType || runtimeType;
|
|
121
|
-
if (buildType === "dev") {
|
|
122
|
-
return "dev";
|
|
123
|
-
}
|
|
124
|
-
return "prod";
|
|
125
|
-
}
|
|
126
|
-
function getAvailableEnvironments() {
|
|
127
|
-
const buildType = getBuildType();
|
|
128
|
-
if (buildType === "dev") {
|
|
129
|
-
return ["sepolia-dev"];
|
|
130
|
-
}
|
|
131
|
-
return ["sepolia", "mainnet-alpha"];
|
|
132
|
-
}
|
|
133
|
-
function isEnvironmentAvailable(environment) {
|
|
134
|
-
return getAvailableEnvironments().includes(environment);
|
|
135
|
-
}
|
|
42
|
+
var import_viem6 = require("viem");
|
|
136
43
|
|
|
137
44
|
// src/client/common/docker/build.ts
|
|
138
45
|
var child_process = __toESM(require("child_process"), 1);
|
|
@@ -1232,9 +1139,6 @@ function extractRegistryNameNoDocker(imageRef) {
|
|
|
1232
1139
|
return name;
|
|
1233
1140
|
}
|
|
1234
1141
|
|
|
1235
|
-
// src/client/common/contract/caller.ts
|
|
1236
|
-
var import_accounts2 = require("viem/accounts");
|
|
1237
|
-
|
|
1238
1142
|
// src/client/common/contract/eip7702.ts
|
|
1239
1143
|
var import_viem = require("viem");
|
|
1240
1144
|
|
|
@@ -2347,11 +2251,12 @@ async function executeBatch(options, logger) {
|
|
|
2347
2251
|
});
|
|
2348
2252
|
const chainId = await publicClient.getChainId();
|
|
2349
2253
|
const authorizationNonce = transactionNonce + 1;
|
|
2254
|
+
logger.debug("Using wallet client signing for EIP-7702 authorization");
|
|
2350
2255
|
const signedAuthorization = await walletClient.signAuthorization({
|
|
2351
|
-
account,
|
|
2256
|
+
account: account.address,
|
|
2352
2257
|
contractAddress: environmentConfig.erc7702DelegatorAddress,
|
|
2353
|
-
chainId
|
|
2354
|
-
nonce: authorizationNonce
|
|
2258
|
+
chainId,
|
|
2259
|
+
nonce: Number(authorizationNonce)
|
|
2355
2260
|
});
|
|
2356
2261
|
authorizationList = [signedAuthorization];
|
|
2357
2262
|
}
|
|
@@ -2406,57 +2311,15 @@ async function executeBatch(options, logger) {
|
|
|
2406
2311
|
}
|
|
2407
2312
|
|
|
2408
2313
|
// src/client/common/contract/caller.ts
|
|
2409
|
-
var
|
|
2410
|
-
var import_utils = require("viem/utils");
|
|
2411
|
-
var import_accounts3 = require("viem/accounts");
|
|
2412
|
-
|
|
2413
|
-
// src/client/common/utils/logger.ts
|
|
2414
|
-
var defaultLogger = {
|
|
2415
|
-
info: (...args) => console.info(...args),
|
|
2416
|
-
warn: (...args) => console.warn(...args),
|
|
2417
|
-
error: (...args) => console.error(...args),
|
|
2418
|
-
debug: (...args) => console.debug(...args)
|
|
2419
|
-
};
|
|
2420
|
-
var getLogger = (verbose) => ({
|
|
2421
|
-
info: (...args) => console.info(...args),
|
|
2422
|
-
warn: (...args) => console.warn(...args),
|
|
2423
|
-
error: (...args) => console.error(...args),
|
|
2424
|
-
debug: (...args) => verbose && console.debug(...args)
|
|
2425
|
-
});
|
|
2426
|
-
|
|
2427
|
-
// src/client/common/utils/userapi.ts
|
|
2428
|
-
var import_axios = __toESM(require("axios"), 1);
|
|
2429
|
-
var import_form_data = __toESM(require("form-data"), 1);
|
|
2430
|
-
var import_viem4 = require("viem");
|
|
2431
|
-
|
|
2432
|
-
// src/client/common/utils/auth.ts
|
|
2433
|
-
var import_viem2 = require("viem");
|
|
2434
|
-
var APP_CONTROLLER_ABI = (0, import_viem2.parseAbi)([
|
|
2435
|
-
"function calculateApiPermissionDigestHash(bytes4 permission, uint256 expiry) view returns (bytes32)"
|
|
2436
|
-
]);
|
|
2437
|
-
async function calculatePermissionSignature(options) {
|
|
2438
|
-
const { permission, expiry, appControllerAddress, publicClient, account } = options;
|
|
2439
|
-
const digest = await publicClient.readContract({
|
|
2440
|
-
address: appControllerAddress,
|
|
2441
|
-
abi: APP_CONTROLLER_ABI,
|
|
2442
|
-
functionName: "calculateApiPermissionDigestHash",
|
|
2443
|
-
args: [permission, expiry]
|
|
2444
|
-
});
|
|
2445
|
-
const signature = await account.signMessage({
|
|
2446
|
-
message: { raw: digest }
|
|
2447
|
-
});
|
|
2448
|
-
return { signature, digest };
|
|
2449
|
-
}
|
|
2450
|
-
|
|
2451
|
-
// src/client/common/utils/userapi.ts
|
|
2452
|
-
var import_accounts = require("viem/accounts");
|
|
2314
|
+
var import_viem3 = require("viem");
|
|
2453
2315
|
|
|
2454
2316
|
// src/client/common/utils/helpers.ts
|
|
2455
|
-
var
|
|
2317
|
+
var import_viem2 = require("viem");
|
|
2456
2318
|
var import_chains2 = require("viem/chains");
|
|
2319
|
+
var import_accounts = require("viem/accounts");
|
|
2457
2320
|
function getChainFromID(chainID, fallback = import_chains2.sepolia) {
|
|
2458
2321
|
const id = Number(chainID);
|
|
2459
|
-
return (0,
|
|
2322
|
+
return (0, import_viem2.extractChain)({ chains: SUPPORTED_CHAINS, id }) || fallback;
|
|
2460
2323
|
}
|
|
2461
2324
|
function addHexPrefix(value) {
|
|
2462
2325
|
return value.startsWith("0x") ? value : `0x${value}`;
|
|
@@ -2465,297 +2328,6 @@ function stripHexPrefix(value) {
|
|
|
2465
2328
|
return value.startsWith("0x") ? value.slice(2) : value;
|
|
2466
2329
|
}
|
|
2467
2330
|
|
|
2468
|
-
// 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
|
-
var MAX_ADDRESS_COUNT = 5;
|
|
2481
|
-
var CanViewAppLogsPermission = "0x2fd3f2fe";
|
|
2482
|
-
var CanViewSensitiveAppInfoPermission = "0x0e67b22f";
|
|
2483
|
-
var CanUpdateAppProfilePermission = "0x036fef61";
|
|
2484
|
-
function getDefaultClientId() {
|
|
2485
|
-
const version = true ? "0.2.0-dev.3" : "0.0.0";
|
|
2486
|
-
return `ecloud-sdk/v${version}`;
|
|
2487
|
-
}
|
|
2488
|
-
var UserApiClient = class {
|
|
2489
|
-
constructor(config, privateKey, rpcUrl, clientId) {
|
|
2490
|
-
this.config = config;
|
|
2491
|
-
if (privateKey) {
|
|
2492
|
-
const privateKeyHex = addHexPrefix(privateKey);
|
|
2493
|
-
this.account = (0, import_accounts.privateKeyToAccount)(privateKeyHex);
|
|
2494
|
-
}
|
|
2495
|
-
this.rpcUrl = rpcUrl;
|
|
2496
|
-
this.clientId = clientId || getDefaultClientId();
|
|
2497
|
-
}
|
|
2498
|
-
async getInfos(appIDs, addressCount = 1) {
|
|
2499
|
-
const count = Math.min(addressCount, MAX_ADDRESS_COUNT);
|
|
2500
|
-
const endpoint = `${this.config.userApiServerURL}/info`;
|
|
2501
|
-
const url = `${endpoint}?${new URLSearchParams({ apps: appIDs.join(",") })}`;
|
|
2502
|
-
const res = await this.makeAuthenticatedRequest(url, CanViewSensitiveAppInfoPermission);
|
|
2503
|
-
const result = await res.json();
|
|
2504
|
-
return result.apps.map((app, i) => {
|
|
2505
|
-
const evmAddresses = app.addresses?.data?.evmAddresses?.slice(0, count) || [];
|
|
2506
|
-
const solanaAddresses = app.addresses?.data?.solanaAddresses?.slice(0, count) || [];
|
|
2507
|
-
return {
|
|
2508
|
-
address: appIDs[i],
|
|
2509
|
-
status: app.app_status,
|
|
2510
|
-
ip: app.ip,
|
|
2511
|
-
machineType: app.machine_type,
|
|
2512
|
-
profile: app.profile,
|
|
2513
|
-
metrics: app.metrics,
|
|
2514
|
-
evmAddresses,
|
|
2515
|
-
solanaAddresses
|
|
2516
|
-
};
|
|
2517
|
-
});
|
|
2518
|
-
}
|
|
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
|
-
/**
|
|
2545
|
-
* Get available SKUs (instance types) from UserAPI
|
|
2546
|
-
*/
|
|
2547
|
-
async getSKUs() {
|
|
2548
|
-
const endpoint = `${this.config.userApiServerURL}/skus`;
|
|
2549
|
-
const response = await this.makeAuthenticatedRequest(endpoint);
|
|
2550
|
-
const result = await response.json();
|
|
2551
|
-
return {
|
|
2552
|
-
skus: result.skus || result.SKUs || []
|
|
2553
|
-
};
|
|
2554
|
-
}
|
|
2555
|
-
/**
|
|
2556
|
-
* Get logs for an app
|
|
2557
|
-
*/
|
|
2558
|
-
async getLogs(appID) {
|
|
2559
|
-
const endpoint = `${this.config.userApiServerURL}/logs/${appID}`;
|
|
2560
|
-
const response = await this.makeAuthenticatedRequest(endpoint, CanViewAppLogsPermission);
|
|
2561
|
-
return await response.text();
|
|
2562
|
-
}
|
|
2563
|
-
/**
|
|
2564
|
-
* Get statuses for apps
|
|
2565
|
-
*/
|
|
2566
|
-
async getStatuses(appIDs) {
|
|
2567
|
-
const endpoint = `${this.config.userApiServerURL}/status`;
|
|
2568
|
-
const url = `${endpoint}?${new URLSearchParams({ apps: appIDs.join(",") })}`;
|
|
2569
|
-
const response = await this.makeAuthenticatedRequest(url);
|
|
2570
|
-
const result = await response.json();
|
|
2571
|
-
const apps = result.apps || result.Apps || [];
|
|
2572
|
-
return apps.map((app, i) => ({
|
|
2573
|
-
address: app.address || appIDs[i],
|
|
2574
|
-
status: app.status || app.Status || ""
|
|
2575
|
-
}));
|
|
2576
|
-
}
|
|
2577
|
-
/**
|
|
2578
|
-
* Upload app profile information with optional image
|
|
2579
|
-
*/
|
|
2580
|
-
async uploadAppProfile(appAddress, name, website, description, xURL, imagePath) {
|
|
2581
|
-
const endpoint = `${this.config.userApiServerURL}/apps/${appAddress}/profile`;
|
|
2582
|
-
const formData = new import_form_data.default();
|
|
2583
|
-
formData.append("name", name);
|
|
2584
|
-
if (website) {
|
|
2585
|
-
formData.append("website", website);
|
|
2586
|
-
}
|
|
2587
|
-
if (description) {
|
|
2588
|
-
formData.append("description", description);
|
|
2589
|
-
}
|
|
2590
|
-
if (xURL) {
|
|
2591
|
-
formData.append("xURL", xURL);
|
|
2592
|
-
}
|
|
2593
|
-
if (imagePath) {
|
|
2594
|
-
const fs8 = await import("fs");
|
|
2595
|
-
const path7 = await import("path");
|
|
2596
|
-
const fileName = path7.basename(imagePath);
|
|
2597
|
-
const fileBuffer = fs8.readFileSync(imagePath);
|
|
2598
|
-
formData.append("image", fileBuffer, fileName);
|
|
2599
|
-
}
|
|
2600
|
-
const headers = {
|
|
2601
|
-
"x-client-id": this.clientId,
|
|
2602
|
-
...formData.getHeaders()
|
|
2603
|
-
};
|
|
2604
|
-
if (this.account) {
|
|
2605
|
-
const expiry = BigInt(Math.floor(Date.now() / 1e3) + 5 * 60);
|
|
2606
|
-
const authHeaders = await this.generateAuthHeaders(CanUpdateAppProfilePermission, expiry);
|
|
2607
|
-
Object.assign(headers, authHeaders);
|
|
2608
|
-
}
|
|
2609
|
-
try {
|
|
2610
|
-
const response = await import_axios.default.post(endpoint, formData, {
|
|
2611
|
-
headers,
|
|
2612
|
-
maxRedirects: 0,
|
|
2613
|
-
validateStatus: () => true,
|
|
2614
|
-
// Don't throw on any status
|
|
2615
|
-
maxContentLength: Infinity,
|
|
2616
|
-
// Allow large file uploads
|
|
2617
|
-
maxBodyLength: Infinity
|
|
2618
|
-
// Allow large file uploads
|
|
2619
|
-
});
|
|
2620
|
-
const status = response.status;
|
|
2621
|
-
if (status !== 200 && status !== 201) {
|
|
2622
|
-
const body = typeof response.data === "string" ? response.data : JSON.stringify(response.data);
|
|
2623
|
-
if (status === 403 && body.includes("Cloudflare") && body.includes("challenge-platform")) {
|
|
2624
|
-
throw new Error(
|
|
2625
|
-
`Cloudflare protection is blocking the request. This is likely due to bot detection.
|
|
2626
|
-
Status: ${status}`
|
|
2627
|
-
);
|
|
2628
|
-
}
|
|
2629
|
-
throw new Error(
|
|
2630
|
-
`UserAPI request failed: ${status} ${status >= 200 && status < 300 ? "OK" : "Error"} - ${body.substring(0, 500)}${body.length > 500 ? "..." : ""}`
|
|
2631
|
-
);
|
|
2632
|
-
}
|
|
2633
|
-
return response.data;
|
|
2634
|
-
} catch (error) {
|
|
2635
|
-
if (error.message?.includes("fetch failed") || error.message?.includes("ECONNREFUSED") || error.message?.includes("ENOTFOUND") || error.cause) {
|
|
2636
|
-
const cause = error.cause?.message || error.cause || error.message;
|
|
2637
|
-
throw new Error(
|
|
2638
|
-
`Failed to connect to UserAPI at ${endpoint}: ${cause}
|
|
2639
|
-
Please check:
|
|
2640
|
-
1. Your internet connection
|
|
2641
|
-
2. The API server is accessible: ${this.config.userApiServerURL}
|
|
2642
|
-
3. Firewall/proxy settings`
|
|
2643
|
-
);
|
|
2644
|
-
}
|
|
2645
|
-
throw error;
|
|
2646
|
-
}
|
|
2647
|
-
}
|
|
2648
|
-
async makeAuthenticatedRequest(url, permission) {
|
|
2649
|
-
const headers = {
|
|
2650
|
-
"x-client-id": this.clientId
|
|
2651
|
-
};
|
|
2652
|
-
if (permission && this.account) {
|
|
2653
|
-
const expiry = BigInt(Math.floor(Date.now() / 1e3) + 5 * 60);
|
|
2654
|
-
const authHeaders = await this.generateAuthHeaders(permission, expiry);
|
|
2655
|
-
Object.assign(headers, authHeaders);
|
|
2656
|
-
}
|
|
2657
|
-
try {
|
|
2658
|
-
const response = await import_axios.default.get(url, {
|
|
2659
|
-
headers,
|
|
2660
|
-
maxRedirects: 0,
|
|
2661
|
-
validateStatus: () => true
|
|
2662
|
-
// Don't throw on any status
|
|
2663
|
-
});
|
|
2664
|
-
const status = response.status;
|
|
2665
|
-
const statusText = status >= 200 && status < 300 ? "OK" : "Error";
|
|
2666
|
-
if (status < 200 || status >= 300) {
|
|
2667
|
-
const body = typeof response.data === "string" ? response.data : JSON.stringify(response.data);
|
|
2668
|
-
throw new Error(`UserAPI request failed: ${status} ${statusText} - ${body}`);
|
|
2669
|
-
}
|
|
2670
|
-
return {
|
|
2671
|
-
json: async () => response.data,
|
|
2672
|
-
text: async () => typeof response.data === "string" ? response.data : JSON.stringify(response.data)
|
|
2673
|
-
};
|
|
2674
|
-
} catch (error) {
|
|
2675
|
-
if (error.message?.includes("fetch failed") || error.message?.includes("ECONNREFUSED") || error.message?.includes("ENOTFOUND") || error.cause) {
|
|
2676
|
-
const cause = error.cause?.message || error.cause || error.message;
|
|
2677
|
-
throw new Error(
|
|
2678
|
-
`Failed to connect to UserAPI at ${url}: ${cause}
|
|
2679
|
-
Please check:
|
|
2680
|
-
1. Your internet connection
|
|
2681
|
-
2. The API server is accessible: ${this.config.userApiServerURL}
|
|
2682
|
-
3. Firewall/proxy settings`
|
|
2683
|
-
);
|
|
2684
|
-
}
|
|
2685
|
-
throw error;
|
|
2686
|
-
}
|
|
2687
|
-
}
|
|
2688
|
-
/**
|
|
2689
|
-
* Generate authentication headers for UserAPI requests
|
|
2690
|
-
*/
|
|
2691
|
-
async generateAuthHeaders(permission, expiry) {
|
|
2692
|
-
if (!this.account) {
|
|
2693
|
-
throw new Error("Private key required for authenticated requests");
|
|
2694
|
-
}
|
|
2695
|
-
if (!this.rpcUrl) {
|
|
2696
|
-
throw new Error("RPC URL required for authenticated requests");
|
|
2697
|
-
}
|
|
2698
|
-
const chain = getChainFromID(this.config.chainID);
|
|
2699
|
-
const publicClient = (0, import_viem4.createPublicClient)({
|
|
2700
|
-
chain,
|
|
2701
|
-
transport: (0, import_viem4.http)(this.rpcUrl)
|
|
2702
|
-
});
|
|
2703
|
-
const { signature } = await calculatePermissionSignature({
|
|
2704
|
-
permission,
|
|
2705
|
-
expiry,
|
|
2706
|
-
appControllerAddress: this.config.appControllerAddress,
|
|
2707
|
-
publicClient,
|
|
2708
|
-
account: this.account
|
|
2709
|
-
});
|
|
2710
|
-
return {
|
|
2711
|
-
Authorization: `Bearer ${stripHexPrefix(signature)}`,
|
|
2712
|
-
"X-eigenx-expiry": expiry.toString()
|
|
2713
|
-
};
|
|
2714
|
-
}
|
|
2715
|
-
};
|
|
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
|
-
|
|
2759
2331
|
// src/client/common/abis/AppController.json
|
|
2760
2332
|
var AppController_default = [
|
|
2761
2333
|
{
|
|
@@ -4310,65 +3882,54 @@ function formatETH(wei) {
|
|
|
4310
3882
|
}
|
|
4311
3883
|
return trimmed;
|
|
4312
3884
|
}
|
|
4313
|
-
async function calculateAppID(
|
|
4314
|
-
const
|
|
4315
|
-
const
|
|
4316
|
-
const chain = getChainFromID(environmentConfig.chainID);
|
|
4317
|
-
const publicClient = (0, import_viem5.createPublicClient)({
|
|
4318
|
-
chain,
|
|
4319
|
-
transport: (0, import_viem5.http)(rpcUrl)
|
|
4320
|
-
});
|
|
4321
|
-
const saltHexString = Buffer.from(salt).toString("hex");
|
|
3885
|
+
async function calculateAppID(options) {
|
|
3886
|
+
const { publicClient, environmentConfig, ownerAddress, salt } = options;
|
|
3887
|
+
const saltHexString = (0, import_viem3.bytesToHex)(salt).slice(2);
|
|
4322
3888
|
const paddedSaltHex = saltHexString.padStart(64, "0");
|
|
4323
3889
|
const saltHex = `0x${paddedSaltHex}`;
|
|
4324
|
-
const accountAddress = typeof account.address === "string" ? account.address : account.address.toString();
|
|
4325
3890
|
const appID = await publicClient.readContract({
|
|
4326
3891
|
address: environmentConfig.appControllerAddress,
|
|
4327
3892
|
abi: AppController_default,
|
|
4328
3893
|
functionName: "calculateAppId",
|
|
4329
|
-
args: [
|
|
3894
|
+
args: [ownerAddress, saltHex]
|
|
4330
3895
|
});
|
|
4331
3896
|
return appID;
|
|
4332
3897
|
}
|
|
4333
3898
|
async function prepareDeployBatch(options, logger) {
|
|
4334
|
-
const {
|
|
4335
|
-
const
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
chain,
|
|
4340
|
-
transport: (0, import_viem5.http)(rpcUrl)
|
|
4341
|
-
});
|
|
4342
|
-
const walletClient = (0, import_viem5.createWalletClient)({
|
|
4343
|
-
account,
|
|
4344
|
-
chain,
|
|
4345
|
-
transport: (0, import_viem5.http)(rpcUrl)
|
|
4346
|
-
});
|
|
3899
|
+
const { walletClient, publicClient, environmentConfig, salt, release, publicLogs } = options;
|
|
3900
|
+
const account = walletClient.account;
|
|
3901
|
+
if (!account) {
|
|
3902
|
+
throw new Error("WalletClient must have an account attached");
|
|
3903
|
+
}
|
|
4347
3904
|
logger.info("Calculating app ID...");
|
|
4348
|
-
const appId = await calculateAppID(
|
|
4349
|
-
|
|
3905
|
+
const appId = await calculateAppID({
|
|
3906
|
+
publicClient,
|
|
3907
|
+
environmentConfig,
|
|
3908
|
+
ownerAddress: account.address,
|
|
3909
|
+
salt
|
|
3910
|
+
});
|
|
4350
3911
|
logger.debug(`App ID calculated: ${appId}`);
|
|
4351
3912
|
logger.debug(`This address will be used for acceptAdmin call`);
|
|
4352
|
-
const saltHexString =
|
|
3913
|
+
const saltHexString = (0, import_viem3.bytesToHex)(salt).slice(2);
|
|
4353
3914
|
const paddedSaltHex = saltHexString.padStart(64, "0");
|
|
4354
3915
|
const saltHex = `0x${paddedSaltHex}`;
|
|
4355
3916
|
const releaseForViem = {
|
|
4356
3917
|
rmsRelease: {
|
|
4357
3918
|
artifacts: release.rmsRelease.artifacts.map((artifact) => ({
|
|
4358
|
-
digest: `0x${
|
|
3919
|
+
digest: `0x${(0, import_viem3.bytesToHex)(artifact.digest).slice(2).padStart(64, "0")}`,
|
|
4359
3920
|
registry: artifact.registry
|
|
4360
3921
|
})),
|
|
4361
3922
|
upgradeByTime: release.rmsRelease.upgradeByTime
|
|
4362
3923
|
},
|
|
4363
|
-
publicEnv:
|
|
4364
|
-
encryptedEnv:
|
|
3924
|
+
publicEnv: (0, import_viem3.bytesToHex)(release.publicEnv),
|
|
3925
|
+
encryptedEnv: (0, import_viem3.bytesToHex)(release.encryptedEnv)
|
|
4365
3926
|
};
|
|
4366
|
-
const createData = (0,
|
|
3927
|
+
const createData = (0, import_viem3.encodeFunctionData)({
|
|
4367
3928
|
abi: AppController_default,
|
|
4368
3929
|
functionName: "createApp",
|
|
4369
3930
|
args: [saltHex, releaseForViem]
|
|
4370
3931
|
});
|
|
4371
|
-
const acceptAdminData = (0,
|
|
3932
|
+
const acceptAdminData = (0, import_viem3.encodeFunctionData)({
|
|
4372
3933
|
abi: PermissionController_default,
|
|
4373
3934
|
functionName: "acceptAdmin",
|
|
4374
3935
|
args: [appId]
|
|
@@ -4386,7 +3947,7 @@ async function prepareDeployBatch(options, logger) {
|
|
|
4386
3947
|
}
|
|
4387
3948
|
];
|
|
4388
3949
|
if (publicLogs) {
|
|
4389
|
-
const anyoneCanViewLogsData = (0,
|
|
3950
|
+
const anyoneCanViewLogsData = (0, import_viem3.encodeFunctionData)({
|
|
4390
3951
|
abi: PermissionController_default,
|
|
4391
3952
|
functionName: "setAppointee",
|
|
4392
3953
|
args: [
|
|
@@ -4430,17 +3991,7 @@ async function executeDeployBatch(data, context, gas, logger) {
|
|
|
4430
3991
|
return { appId: data.appId, txHash };
|
|
4431
3992
|
}
|
|
4432
3993
|
async function deployApp(options, logger) {
|
|
4433
|
-
const prepared = await prepareDeployBatch(
|
|
4434
|
-
{
|
|
4435
|
-
privateKey: options.privateKey,
|
|
4436
|
-
rpcUrl: options.rpcUrl,
|
|
4437
|
-
environmentConfig: options.environmentConfig,
|
|
4438
|
-
salt: options.salt,
|
|
4439
|
-
release: options.release,
|
|
4440
|
-
publicLogs: options.publicLogs
|
|
4441
|
-
},
|
|
4442
|
-
logger
|
|
4443
|
-
);
|
|
3994
|
+
const prepared = await prepareDeployBatch(options, logger);
|
|
4444
3995
|
const data = {
|
|
4445
3996
|
appId: prepared.appId,
|
|
4446
3997
|
salt: prepared.salt,
|
|
@@ -4454,42 +4005,22 @@ async function deployApp(options, logger) {
|
|
|
4454
4005
|
return executeDeployBatch(data, context, options.gas, logger);
|
|
4455
4006
|
}
|
|
4456
4007
|
async function prepareUpgradeBatch(options) {
|
|
4457
|
-
const {
|
|
4458
|
-
privateKey,
|
|
4459
|
-
rpcUrl,
|
|
4460
|
-
environmentConfig,
|
|
4461
|
-
appId,
|
|
4462
|
-
release,
|
|
4463
|
-
publicLogs,
|
|
4464
|
-
needsPermissionChange
|
|
4465
|
-
} = options;
|
|
4466
|
-
const privateKeyHex = addHexPrefix(privateKey);
|
|
4467
|
-
const account = (0, import_accounts2.privateKeyToAccount)(privateKeyHex);
|
|
4468
|
-
const chain = getChainFromID(environmentConfig.chainID);
|
|
4469
|
-
const publicClient = (0, import_viem5.createPublicClient)({
|
|
4470
|
-
chain,
|
|
4471
|
-
transport: (0, import_viem5.http)(rpcUrl)
|
|
4472
|
-
});
|
|
4473
|
-
const walletClient = (0, import_viem5.createWalletClient)({
|
|
4474
|
-
account,
|
|
4475
|
-
chain,
|
|
4476
|
-
transport: (0, import_viem5.http)(rpcUrl)
|
|
4477
|
-
});
|
|
4008
|
+
const { walletClient, publicClient, environmentConfig, appID, release, publicLogs, needsPermissionChange } = options;
|
|
4478
4009
|
const releaseForViem = {
|
|
4479
4010
|
rmsRelease: {
|
|
4480
4011
|
artifacts: release.rmsRelease.artifacts.map((artifact) => ({
|
|
4481
|
-
digest: `0x${
|
|
4012
|
+
digest: `0x${(0, import_viem3.bytesToHex)(artifact.digest).slice(2).padStart(64, "0")}`,
|
|
4482
4013
|
registry: artifact.registry
|
|
4483
4014
|
})),
|
|
4484
4015
|
upgradeByTime: release.rmsRelease.upgradeByTime
|
|
4485
4016
|
},
|
|
4486
|
-
publicEnv:
|
|
4487
|
-
encryptedEnv:
|
|
4017
|
+
publicEnv: (0, import_viem3.bytesToHex)(release.publicEnv),
|
|
4018
|
+
encryptedEnv: (0, import_viem3.bytesToHex)(release.encryptedEnv)
|
|
4488
4019
|
};
|
|
4489
|
-
const upgradeData = (0,
|
|
4020
|
+
const upgradeData = (0, import_viem3.encodeFunctionData)({
|
|
4490
4021
|
abi: AppController_default,
|
|
4491
4022
|
functionName: "upgradeApp",
|
|
4492
|
-
args: [
|
|
4023
|
+
args: [appID, releaseForViem]
|
|
4493
4024
|
});
|
|
4494
4025
|
const executions = [
|
|
4495
4026
|
{
|
|
@@ -4500,11 +4031,11 @@ async function prepareUpgradeBatch(options) {
|
|
|
4500
4031
|
];
|
|
4501
4032
|
if (needsPermissionChange) {
|
|
4502
4033
|
if (publicLogs) {
|
|
4503
|
-
const addLogsData = (0,
|
|
4034
|
+
const addLogsData = (0, import_viem3.encodeFunctionData)({
|
|
4504
4035
|
abi: PermissionController_default,
|
|
4505
4036
|
functionName: "setAppointee",
|
|
4506
4037
|
args: [
|
|
4507
|
-
|
|
4038
|
+
appID,
|
|
4508
4039
|
"0x493219d9949348178af1f58740655951a8cd110c",
|
|
4509
4040
|
// AnyoneCanCallAddress
|
|
4510
4041
|
"0x57ee1fb74c1087e26446abc4fb87fd8f07c43d8d",
|
|
@@ -4519,11 +4050,11 @@ async function prepareUpgradeBatch(options) {
|
|
|
4519
4050
|
callData: addLogsData
|
|
4520
4051
|
});
|
|
4521
4052
|
} else {
|
|
4522
|
-
const removeLogsData = (0,
|
|
4053
|
+
const removeLogsData = (0, import_viem3.encodeFunctionData)({
|
|
4523
4054
|
abi: PermissionController_default,
|
|
4524
4055
|
functionName: "removeAppointee",
|
|
4525
4056
|
args: [
|
|
4526
|
-
|
|
4057
|
+
appID,
|
|
4527
4058
|
"0x493219d9949348178af1f58740655951a8cd110c",
|
|
4528
4059
|
// AnyoneCanCallAddress
|
|
4529
4060
|
"0x57ee1fb74c1087e26446abc4fb87fd8f07c43d8d",
|
|
@@ -4540,7 +4071,7 @@ async function prepareUpgradeBatch(options) {
|
|
|
4540
4071
|
}
|
|
4541
4072
|
}
|
|
4542
4073
|
return {
|
|
4543
|
-
appId,
|
|
4074
|
+
appId: appID,
|
|
4544
4075
|
executions,
|
|
4545
4076
|
walletClient,
|
|
4546
4077
|
publicClient,
|
|
@@ -4563,15 +4094,7 @@ async function executeUpgradeBatch(data, context, gas, logger) {
|
|
|
4563
4094
|
return txHash;
|
|
4564
4095
|
}
|
|
4565
4096
|
async function upgradeApp(options, logger) {
|
|
4566
|
-
const prepared = await prepareUpgradeBatch(
|
|
4567
|
-
privateKey: options.privateKey,
|
|
4568
|
-
rpcUrl: options.rpcUrl,
|
|
4569
|
-
environmentConfig: options.environmentConfig,
|
|
4570
|
-
appId: options.appId,
|
|
4571
|
-
release: options.release,
|
|
4572
|
-
publicLogs: options.publicLogs,
|
|
4573
|
-
needsPermissionChange: options.needsPermissionChange
|
|
4574
|
-
});
|
|
4097
|
+
const prepared = await prepareUpgradeBatch(options);
|
|
4575
4098
|
const data = {
|
|
4576
4099
|
appId: prepared.appId,
|
|
4577
4100
|
executions: prepared.executions
|
|
@@ -4584,29 +4107,12 @@ async function upgradeApp(options, logger) {
|
|
|
4584
4107
|
return executeUpgradeBatch(data, context, options.gas, logger);
|
|
4585
4108
|
}
|
|
4586
4109
|
async function sendAndWaitForTransaction(options, logger) {
|
|
4587
|
-
const {
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
data,
|
|
4593
|
-
value = 0n,
|
|
4594
|
-
pendingMessage,
|
|
4595
|
-
txDescription,
|
|
4596
|
-
gas
|
|
4597
|
-
} = options;
|
|
4598
|
-
const privateKeyHex = addHexPrefix(privateKey);
|
|
4599
|
-
const account = (0, import_accounts2.privateKeyToAccount)(privateKeyHex);
|
|
4110
|
+
const { walletClient, publicClient, environmentConfig, to, data, value = 0n, pendingMessage, txDescription, gas } = options;
|
|
4111
|
+
const account = walletClient.account;
|
|
4112
|
+
if (!account) {
|
|
4113
|
+
throw new Error("WalletClient must have an account attached");
|
|
4114
|
+
}
|
|
4600
4115
|
const chain = getChainFromID(environmentConfig.chainID);
|
|
4601
|
-
const publicClient = (0, import_viem5.createPublicClient)({
|
|
4602
|
-
chain,
|
|
4603
|
-
transport: (0, import_viem5.http)(rpcUrl)
|
|
4604
|
-
});
|
|
4605
|
-
const walletClient = (0, import_viem5.createWalletClient)({
|
|
4606
|
-
account,
|
|
4607
|
-
chain,
|
|
4608
|
-
transport: (0, import_viem5.http)(rpcUrl)
|
|
4609
|
-
});
|
|
4610
4116
|
if (pendingMessage) {
|
|
4611
4117
|
logger.info(`
|
|
4612
4118
|
${pendingMessage}`);
|
|
@@ -4617,7 +4123,10 @@ ${pendingMessage}`);
|
|
|
4617
4123
|
data,
|
|
4618
4124
|
value,
|
|
4619
4125
|
...gas?.maxFeePerGas && { maxFeePerGas: gas.maxFeePerGas },
|
|
4620
|
-
...gas?.maxPriorityFeePerGas && {
|
|
4126
|
+
...gas?.maxPriorityFeePerGas && {
|
|
4127
|
+
maxPriorityFeePerGas: gas.maxPriorityFeePerGas
|
|
4128
|
+
},
|
|
4129
|
+
chain
|
|
4621
4130
|
});
|
|
4622
4131
|
logger.info(`Transaction sent: ${hash}`);
|
|
4623
4132
|
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
@@ -4632,7 +4141,7 @@ ${pendingMessage}`);
|
|
|
4632
4141
|
} catch (callError) {
|
|
4633
4142
|
if (callError.data) {
|
|
4634
4143
|
try {
|
|
4635
|
-
const decoded = (0,
|
|
4144
|
+
const decoded = (0, import_viem3.decodeErrorResult)({
|
|
4636
4145
|
abi: AppController_default,
|
|
4637
4146
|
data: callError.data
|
|
4638
4147
|
});
|
|
@@ -4683,12 +4192,7 @@ function formatAppControllerError(decoded) {
|
|
|
4683
4192
|
return new Error(`contract error: ${errorName}`);
|
|
4684
4193
|
}
|
|
4685
4194
|
}
|
|
4686
|
-
async function getActiveAppCount(
|
|
4687
|
-
const chain = getChainFromID(environmentConfig.chainID);
|
|
4688
|
-
const publicClient = (0, import_viem5.createPublicClient)({
|
|
4689
|
-
chain,
|
|
4690
|
-
transport: (0, import_viem5.http)(rpcUrl)
|
|
4691
|
-
});
|
|
4195
|
+
async function getActiveAppCount(publicClient, environmentConfig, user) {
|
|
4692
4196
|
const count = await publicClient.readContract({
|
|
4693
4197
|
address: environmentConfig.appControllerAddress,
|
|
4694
4198
|
abi: AppController_default,
|
|
@@ -4697,12 +4201,7 @@ async function getActiveAppCount(rpcUrl, environmentConfig, user) {
|
|
|
4697
4201
|
});
|
|
4698
4202
|
return Number(count);
|
|
4699
4203
|
}
|
|
4700
|
-
async function getMaxActiveAppsPerUser(
|
|
4701
|
-
const chain = getChainFromID(environmentConfig.chainID);
|
|
4702
|
-
const publicClient = (0, import_viem5.createPublicClient)({
|
|
4703
|
-
chain,
|
|
4704
|
-
transport: (0, import_viem5.http)(rpcUrl)
|
|
4705
|
-
});
|
|
4204
|
+
async function getMaxActiveAppsPerUser(publicClient, environmentConfig, user) {
|
|
4706
4205
|
const quota = await publicClient.readContract({
|
|
4707
4206
|
address: environmentConfig.appControllerAddress,
|
|
4708
4207
|
abi: AppController_default,
|
|
@@ -4712,83 +4211,365 @@ async function getMaxActiveAppsPerUser(rpcUrl, environmentConfig, user) {
|
|
|
4712
4211
|
return Number(quota);
|
|
4713
4212
|
}
|
|
4714
4213
|
async function isDelegated(options) {
|
|
4715
|
-
const {
|
|
4716
|
-
const privateKeyHex = addHexPrefix(privateKey);
|
|
4717
|
-
const account = (0, import_accounts2.privateKeyToAccount)(privateKeyHex);
|
|
4718
|
-
const chain = getChainFromID(environmentConfig.chainID);
|
|
4719
|
-
const publicClient = (0, import_viem5.createPublicClient)({
|
|
4720
|
-
chain,
|
|
4721
|
-
transport: (0, import_viem5.http)(rpcUrl)
|
|
4722
|
-
});
|
|
4214
|
+
const { publicClient, environmentConfig, address } = options;
|
|
4723
4215
|
return checkERC7702Delegation(
|
|
4724
4216
|
publicClient,
|
|
4725
|
-
|
|
4217
|
+
address,
|
|
4726
4218
|
environmentConfig.erc7702DelegatorAddress
|
|
4727
4219
|
);
|
|
4728
4220
|
}
|
|
4729
4221
|
async function undelegate(options, logger) {
|
|
4730
|
-
const {
|
|
4731
|
-
const
|
|
4732
|
-
|
|
4222
|
+
const { walletClient, publicClient, environmentConfig } = options;
|
|
4223
|
+
const account = walletClient.account;
|
|
4224
|
+
if (!account) {
|
|
4225
|
+
throw new Error("WalletClient must have an account attached");
|
|
4226
|
+
}
|
|
4733
4227
|
const chain = getChainFromID(environmentConfig.chainID);
|
|
4734
|
-
const publicClient = (0, import_viem5.createPublicClient)({
|
|
4735
|
-
chain,
|
|
4736
|
-
transport: (0, import_viem5.http)(rpcUrl)
|
|
4737
|
-
});
|
|
4738
|
-
const walletClient = (0, import_viem5.createWalletClient)({
|
|
4739
|
-
account,
|
|
4740
|
-
chain,
|
|
4741
|
-
transport: (0, import_viem5.http)(rpcUrl)
|
|
4742
|
-
});
|
|
4743
4228
|
const transactionNonce = await publicClient.getTransactionCount({
|
|
4744
4229
|
address: account.address,
|
|
4745
4230
|
blockTag: "pending"
|
|
4746
4231
|
});
|
|
4747
4232
|
const chainId = await publicClient.getChainId();
|
|
4748
4233
|
const authorizationNonce = BigInt(transactionNonce) + 1n;
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
nonce: authorizationNonce
|
|
4754
|
-
|
|
4755
|
-
const sighash = (0, import_utils.hashAuthorization)({
|
|
4756
|
-
chainId: authorization.chainId,
|
|
4757
|
-
contractAddress: authorization.address,
|
|
4758
|
-
nonce: Number(authorization.nonce)
|
|
4234
|
+
logger.debug("Signing undelegate authorization");
|
|
4235
|
+
const signedAuthorization = await walletClient.signAuthorization({
|
|
4236
|
+
contractAddress: "0x0000000000000000000000000000000000000000",
|
|
4237
|
+
chainId,
|
|
4238
|
+
nonce: Number(authorizationNonce),
|
|
4239
|
+
account
|
|
4759
4240
|
});
|
|
4760
|
-
const
|
|
4761
|
-
|
|
4762
|
-
|
|
4241
|
+
const authorizationList = [signedAuthorization];
|
|
4242
|
+
const hash = await walletClient.sendTransaction({
|
|
4243
|
+
account,
|
|
4244
|
+
to: account.address,
|
|
4245
|
+
// Send to self
|
|
4246
|
+
data: "0x",
|
|
4247
|
+
// Empty data
|
|
4248
|
+
value: 0n,
|
|
4249
|
+
authorizationList,
|
|
4250
|
+
chain
|
|
4763
4251
|
});
|
|
4764
|
-
|
|
4765
|
-
const
|
|
4766
|
-
|
|
4767
|
-
{
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4252
|
+
logger.info(`Transaction sent: ${hash}`);
|
|
4253
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
4254
|
+
if (receipt.status === "reverted") {
|
|
4255
|
+
logger.error(`Undelegate transaction (hash: ${hash}) reverted`);
|
|
4256
|
+
throw new Error(`Undelegate transaction (hash: ${hash}) reverted`);
|
|
4257
|
+
}
|
|
4258
|
+
return hash;
|
|
4259
|
+
}
|
|
4260
|
+
|
|
4261
|
+
// src/client/common/utils/userapi.ts
|
|
4262
|
+
var import_axios = __toESM(require("axios"), 1);
|
|
4263
|
+
|
|
4264
|
+
// src/client/common/utils/auth.ts
|
|
4265
|
+
var import_viem4 = require("viem");
|
|
4266
|
+
var APP_CONTROLLER_ABI = (0, import_viem4.parseAbi)([
|
|
4267
|
+
"function calculateApiPermissionDigestHash(bytes4 permission, uint256 expiry) view returns (bytes32)"
|
|
4268
|
+
]);
|
|
4269
|
+
async function calculatePermissionSignature(options) {
|
|
4270
|
+
const { permission, expiry, appControllerAddress, publicClient, walletClient } = options;
|
|
4271
|
+
const digest = await publicClient.readContract({
|
|
4272
|
+
address: appControllerAddress,
|
|
4273
|
+
abi: APP_CONTROLLER_ABI,
|
|
4274
|
+
functionName: "calculateApiPermissionDigestHash",
|
|
4275
|
+
args: [permission, expiry]
|
|
4276
|
+
});
|
|
4277
|
+
const account = walletClient.account;
|
|
4278
|
+
if (!account) {
|
|
4279
|
+
throw new Error("WalletClient must have an account attached");
|
|
4280
|
+
}
|
|
4281
|
+
const signature = await walletClient.signMessage({
|
|
4282
|
+
account,
|
|
4283
|
+
message: { raw: digest }
|
|
4284
|
+
});
|
|
4285
|
+
return { signature, digest };
|
|
4286
|
+
}
|
|
4287
|
+
|
|
4288
|
+
// src/client/common/utils/userapi.ts
|
|
4289
|
+
function isJsonObject(value) {
|
|
4290
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4291
|
+
}
|
|
4292
|
+
function readString(obj, key) {
|
|
4293
|
+
const v = obj[key];
|
|
4294
|
+
return typeof v === "string" ? v : void 0;
|
|
4295
|
+
}
|
|
4296
|
+
function readNumber(obj, key) {
|
|
4297
|
+
const v = obj[key];
|
|
4298
|
+
return typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
4299
|
+
}
|
|
4300
|
+
var MAX_ADDRESS_COUNT = 5;
|
|
4301
|
+
var CanViewAppLogsPermission = "0x2fd3f2fe";
|
|
4302
|
+
var CanViewSensitiveAppInfoPermission = "0x0e67b22f";
|
|
4303
|
+
var CanUpdateAppProfilePermission = "0x036fef61";
|
|
4304
|
+
function getDefaultClientId() {
|
|
4305
|
+
const version = true ? "0.2.1-dev" : "0.0.0";
|
|
4306
|
+
return `ecloud-sdk/v${version}`;
|
|
4307
|
+
}
|
|
4308
|
+
var UserApiClient = class {
|
|
4309
|
+
constructor(config, walletClient, publicClient, clientId) {
|
|
4310
|
+
this.config = config;
|
|
4311
|
+
this.walletClient = walletClient;
|
|
4312
|
+
this.publicClient = publicClient;
|
|
4313
|
+
this.clientId = clientId || getDefaultClientId();
|
|
4314
|
+
}
|
|
4315
|
+
/**
|
|
4316
|
+
* Get the address of the connected wallet
|
|
4317
|
+
*/
|
|
4318
|
+
get address() {
|
|
4319
|
+
const account = this.walletClient.account;
|
|
4320
|
+
if (!account) {
|
|
4321
|
+
throw new Error("WalletClient must have an account attached");
|
|
4322
|
+
}
|
|
4323
|
+
return account.address;
|
|
4324
|
+
}
|
|
4325
|
+
async getInfos(appIDs, addressCount = 1) {
|
|
4326
|
+
const count = Math.min(addressCount, MAX_ADDRESS_COUNT);
|
|
4327
|
+
const endpoint = `${this.config.userApiServerURL}/info`;
|
|
4328
|
+
const url = `${endpoint}?${new URLSearchParams({ apps: appIDs.join(",") })}`;
|
|
4329
|
+
const res = await this.makeAuthenticatedRequest(url, CanViewSensitiveAppInfoPermission);
|
|
4330
|
+
const result = await res.json();
|
|
4331
|
+
return result.apps.map((app, i) => {
|
|
4332
|
+
const evmAddresses = app.addresses?.data?.evmAddresses?.slice(0, count) || [];
|
|
4333
|
+
const solanaAddresses = app.addresses?.data?.solanaAddresses?.slice(0, count) || [];
|
|
4334
|
+
return {
|
|
4335
|
+
address: appIDs[i],
|
|
4336
|
+
status: app.app_status,
|
|
4337
|
+
ip: app.ip,
|
|
4338
|
+
machineType: app.machine_type,
|
|
4339
|
+
profile: app.profile,
|
|
4340
|
+
metrics: app.metrics,
|
|
4341
|
+
evmAddresses,
|
|
4342
|
+
solanaAddresses
|
|
4343
|
+
};
|
|
4344
|
+
});
|
|
4345
|
+
}
|
|
4346
|
+
/**
|
|
4347
|
+
* Get app details from UserAPI (includes releases and build/provenance info when available).
|
|
4348
|
+
*
|
|
4349
|
+
* Endpoint: GET /apps/:appAddress
|
|
4350
|
+
*/
|
|
4351
|
+
async getApp(appAddress) {
|
|
4352
|
+
const endpoint = `${this.config.userApiServerURL}/apps/${appAddress}`;
|
|
4353
|
+
const res = await this.makeAuthenticatedRequest(endpoint);
|
|
4354
|
+
const raw = await res.json();
|
|
4355
|
+
if (!isJsonObject(raw)) {
|
|
4356
|
+
throw new Error("Unexpected /apps/:id response: expected object");
|
|
4357
|
+
}
|
|
4358
|
+
const id = readString(raw, "id");
|
|
4359
|
+
if (!id) {
|
|
4360
|
+
throw new Error("Unexpected /apps/:id response: missing 'id'");
|
|
4361
|
+
}
|
|
4362
|
+
const releasesRaw = raw.releases;
|
|
4363
|
+
const releases = Array.isArray(releasesRaw) ? releasesRaw.map((r) => transformAppRelease(r)).filter((r) => !!r) : [];
|
|
4364
|
+
return {
|
|
4365
|
+
id,
|
|
4366
|
+
creator: readString(raw, "creator"),
|
|
4367
|
+
contractStatus: readString(raw, "contract_status") ?? readString(raw, "contractStatus"),
|
|
4368
|
+
releases
|
|
4369
|
+
};
|
|
4370
|
+
}
|
|
4371
|
+
/**
|
|
4372
|
+
* Get available SKUs (instance types) from UserAPI
|
|
4373
|
+
*/
|
|
4374
|
+
async getSKUs() {
|
|
4375
|
+
const endpoint = `${this.config.userApiServerURL}/skus`;
|
|
4376
|
+
const response = await this.makeAuthenticatedRequest(endpoint);
|
|
4377
|
+
const result = await response.json();
|
|
4378
|
+
return {
|
|
4379
|
+
skus: result.skus || result.SKUs || []
|
|
4380
|
+
};
|
|
4381
|
+
}
|
|
4382
|
+
/**
|
|
4383
|
+
* Get logs for an app
|
|
4384
|
+
*/
|
|
4385
|
+
async getLogs(appID) {
|
|
4386
|
+
const endpoint = `${this.config.userApiServerURL}/logs/${appID}`;
|
|
4387
|
+
const response = await this.makeAuthenticatedRequest(endpoint, CanViewAppLogsPermission);
|
|
4388
|
+
return await response.text();
|
|
4389
|
+
}
|
|
4390
|
+
/**
|
|
4391
|
+
* Get statuses for apps
|
|
4392
|
+
*/
|
|
4393
|
+
async getStatuses(appIDs) {
|
|
4394
|
+
const endpoint = `${this.config.userApiServerURL}/status`;
|
|
4395
|
+
const url = `${endpoint}?${new URLSearchParams({ apps: appIDs.join(",") })}`;
|
|
4396
|
+
const response = await this.makeAuthenticatedRequest(url);
|
|
4397
|
+
const result = await response.json();
|
|
4398
|
+
const apps = result.apps || result.Apps || [];
|
|
4399
|
+
return apps.map((app, i) => ({
|
|
4400
|
+
address: app.address || appIDs[i],
|
|
4401
|
+
status: app.status || app.Status || ""
|
|
4402
|
+
}));
|
|
4403
|
+
}
|
|
4404
|
+
/**
|
|
4405
|
+
* Upload app profile information with optional image
|
|
4406
|
+
*
|
|
4407
|
+
* @param appAddress - The app's contract address
|
|
4408
|
+
* @param name - Display name for the app
|
|
4409
|
+
* @param options - Optional fields including website, description, xURL, and image
|
|
4410
|
+
* @param options.image - Image file as Blob or File (browser: from input element, Node.js: new Blob([buffer]))
|
|
4411
|
+
* @param options.imageName - Filename for the image (required if image is provided)
|
|
4412
|
+
*/
|
|
4413
|
+
async uploadAppProfile(appAddress, name, options) {
|
|
4414
|
+
const endpoint = `${this.config.userApiServerURL}/apps/${appAddress}/profile`;
|
|
4415
|
+
const formData = new FormData();
|
|
4416
|
+
formData.append("name", name);
|
|
4417
|
+
if (options?.website) {
|
|
4418
|
+
formData.append("website", options.website);
|
|
4419
|
+
}
|
|
4420
|
+
if (options?.description) {
|
|
4421
|
+
formData.append("description", options.description);
|
|
4422
|
+
}
|
|
4423
|
+
if (options?.xURL) {
|
|
4424
|
+
formData.append("xURL", options.xURL);
|
|
4425
|
+
}
|
|
4426
|
+
if (options?.image) {
|
|
4427
|
+
const fileName = options.image instanceof File ? options.image.name : options.imageName || "image";
|
|
4428
|
+
formData.append("image", options.image, fileName);
|
|
4429
|
+
}
|
|
4430
|
+
const headers = {
|
|
4431
|
+
"x-client-id": this.clientId
|
|
4432
|
+
};
|
|
4433
|
+
const expiry = BigInt(Math.floor(Date.now() / 1e3) + 5 * 60);
|
|
4434
|
+
const authHeaders = await this.generateAuthHeaders(CanUpdateAppProfilePermission, expiry);
|
|
4435
|
+
Object.assign(headers, authHeaders);
|
|
4436
|
+
try {
|
|
4437
|
+
const response = await import_axios.default.post(endpoint, formData, {
|
|
4438
|
+
headers,
|
|
4439
|
+
maxRedirects: 0,
|
|
4440
|
+
validateStatus: () => true,
|
|
4441
|
+
// Don't throw on any status
|
|
4442
|
+
maxContentLength: Infinity,
|
|
4443
|
+
// Allow large file uploads
|
|
4444
|
+
maxBodyLength: Infinity
|
|
4445
|
+
// Allow large file uploads
|
|
4446
|
+
});
|
|
4447
|
+
const status = response.status;
|
|
4448
|
+
if (status !== 200 && status !== 201) {
|
|
4449
|
+
const body = typeof response.data === "string" ? response.data : JSON.stringify(response.data);
|
|
4450
|
+
if (status === 403 && body.includes("Cloudflare") && body.includes("challenge-platform")) {
|
|
4451
|
+
throw new Error(
|
|
4452
|
+
`Cloudflare protection is blocking the request. This is likely due to bot detection.
|
|
4453
|
+
Status: ${status}`
|
|
4454
|
+
);
|
|
4455
|
+
}
|
|
4456
|
+
throw new Error(
|
|
4457
|
+
`UserAPI request failed: ${status} ${status >= 200 && status < 300 ? "OK" : "Error"} - ${body.substring(0, 500)}${body.length > 500 ? "..." : ""}`
|
|
4458
|
+
);
|
|
4459
|
+
}
|
|
4460
|
+
return response.data;
|
|
4461
|
+
} catch (error) {
|
|
4462
|
+
if (error.message?.includes("fetch failed") || error.message?.includes("ECONNREFUSED") || error.message?.includes("ENOTFOUND") || error.cause) {
|
|
4463
|
+
const cause = error.cause?.message || error.cause || error.message;
|
|
4464
|
+
throw new Error(
|
|
4465
|
+
`Failed to connect to UserAPI at ${endpoint}: ${cause}
|
|
4466
|
+
Please check:
|
|
4467
|
+
1. Your internet connection
|
|
4468
|
+
2. The API server is accessible: ${this.config.userApiServerURL}
|
|
4469
|
+
3. Firewall/proxy settings`
|
|
4470
|
+
);
|
|
4471
|
+
}
|
|
4472
|
+
throw error;
|
|
4473
|
+
}
|
|
4474
|
+
}
|
|
4475
|
+
async makeAuthenticatedRequest(url, permission) {
|
|
4476
|
+
const headers = {
|
|
4477
|
+
"x-client-id": this.clientId
|
|
4478
|
+
};
|
|
4479
|
+
if (permission) {
|
|
4480
|
+
const expiry = BigInt(Math.floor(Date.now() / 1e3) + 5 * 60);
|
|
4481
|
+
const authHeaders = await this.generateAuthHeaders(permission, expiry);
|
|
4482
|
+
Object.assign(headers, authHeaders);
|
|
4483
|
+
}
|
|
4484
|
+
try {
|
|
4485
|
+
const response = await import_axios.default.get(url, {
|
|
4486
|
+
headers,
|
|
4487
|
+
maxRedirects: 0,
|
|
4488
|
+
validateStatus: () => true
|
|
4489
|
+
// Don't throw on any status
|
|
4490
|
+
});
|
|
4491
|
+
const status = response.status;
|
|
4492
|
+
const statusText = status >= 200 && status < 300 ? "OK" : "Error";
|
|
4493
|
+
if (status < 200 || status >= 300) {
|
|
4494
|
+
const body = typeof response.data === "string" ? response.data : JSON.stringify(response.data);
|
|
4495
|
+
throw new Error(`UserAPI request failed: ${status} ${statusText} - ${body}`);
|
|
4496
|
+
}
|
|
4497
|
+
return {
|
|
4498
|
+
json: async () => response.data,
|
|
4499
|
+
text: async () => typeof response.data === "string" ? response.data : JSON.stringify(response.data)
|
|
4500
|
+
};
|
|
4501
|
+
} catch (error) {
|
|
4502
|
+
if (error.message?.includes("fetch failed") || error.message?.includes("ECONNREFUSED") || error.message?.includes("ENOTFOUND") || error.cause) {
|
|
4503
|
+
const cause = error.cause?.message || error.cause || error.message;
|
|
4504
|
+
throw new Error(
|
|
4505
|
+
`Failed to connect to UserAPI at ${url}: ${cause}
|
|
4506
|
+
Please check:
|
|
4507
|
+
1. Your internet connection
|
|
4508
|
+
2. The API server is accessible: ${this.config.userApiServerURL}
|
|
4509
|
+
3. Firewall/proxy settings`
|
|
4510
|
+
);
|
|
4511
|
+
}
|
|
4512
|
+
throw error;
|
|
4774
4513
|
}
|
|
4775
|
-
];
|
|
4776
|
-
const hash = await walletClient.sendTransaction({
|
|
4777
|
-
account,
|
|
4778
|
-
to: account.address,
|
|
4779
|
-
// Send to self
|
|
4780
|
-
data: "0x",
|
|
4781
|
-
// Empty data
|
|
4782
|
-
value: 0n,
|
|
4783
|
-
authorizationList
|
|
4784
|
-
});
|
|
4785
|
-
logger.info(`Transaction sent: ${hash}`);
|
|
4786
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
4787
|
-
if (receipt.status === "reverted") {
|
|
4788
|
-
logger.error(`Undelegate transaction (hash: ${hash}) reverted`);
|
|
4789
|
-
throw new Error(`Undelegate transaction (hash: ${hash}) reverted`);
|
|
4790
4514
|
}
|
|
4791
|
-
|
|
4515
|
+
/**
|
|
4516
|
+
* Generate authentication headers for UserAPI requests
|
|
4517
|
+
*/
|
|
4518
|
+
async generateAuthHeaders(permission, expiry) {
|
|
4519
|
+
const { signature } = await calculatePermissionSignature({
|
|
4520
|
+
permission,
|
|
4521
|
+
expiry,
|
|
4522
|
+
appControllerAddress: this.config.appControllerAddress,
|
|
4523
|
+
publicClient: this.publicClient,
|
|
4524
|
+
walletClient: this.walletClient
|
|
4525
|
+
});
|
|
4526
|
+
return {
|
|
4527
|
+
Authorization: `Bearer ${stripHexPrefix(signature)}`,
|
|
4528
|
+
"X-eigenx-expiry": expiry.toString()
|
|
4529
|
+
};
|
|
4530
|
+
}
|
|
4531
|
+
};
|
|
4532
|
+
function transformAppReleaseBuild(raw) {
|
|
4533
|
+
if (!isJsonObject(raw)) return void 0;
|
|
4534
|
+
const depsRaw = raw.dependencies;
|
|
4535
|
+
const deps = isJsonObject(depsRaw) ? Object.fromEntries(
|
|
4536
|
+
Object.entries(depsRaw).flatMap(([digest, depRaw]) => {
|
|
4537
|
+
const parsed = transformAppReleaseBuild(depRaw);
|
|
4538
|
+
return parsed ? [[digest, parsed]] : [];
|
|
4539
|
+
})
|
|
4540
|
+
) : void 0;
|
|
4541
|
+
return {
|
|
4542
|
+
buildId: readString(raw, "build_id") ?? readString(raw, "buildId"),
|
|
4543
|
+
billingAddress: readString(raw, "billing_address") ?? readString(raw, "billingAddress"),
|
|
4544
|
+
repoUrl: readString(raw, "repo_url") ?? readString(raw, "repoUrl"),
|
|
4545
|
+
gitRef: readString(raw, "git_ref") ?? readString(raw, "gitRef"),
|
|
4546
|
+
status: readString(raw, "status"),
|
|
4547
|
+
buildType: readString(raw, "build_type") ?? readString(raw, "buildType"),
|
|
4548
|
+
imageName: readString(raw, "image_name") ?? readString(raw, "imageName"),
|
|
4549
|
+
imageDigest: readString(raw, "image_digest") ?? readString(raw, "imageDigest"),
|
|
4550
|
+
imageUrl: readString(raw, "image_url") ?? readString(raw, "imageUrl"),
|
|
4551
|
+
provenanceJson: raw.provenance_json ?? raw.provenanceJson,
|
|
4552
|
+
provenanceSignature: readString(raw, "provenance_signature") ?? readString(raw, "provenanceSignature"),
|
|
4553
|
+
createdAt: readString(raw, "created_at") ?? readString(raw, "createdAt"),
|
|
4554
|
+
updatedAt: readString(raw, "updated_at") ?? readString(raw, "updatedAt"),
|
|
4555
|
+
errorMessage: readString(raw, "error_message") ?? readString(raw, "errorMessage"),
|
|
4556
|
+
dependencies: deps
|
|
4557
|
+
};
|
|
4558
|
+
}
|
|
4559
|
+
function transformAppRelease(raw) {
|
|
4560
|
+
if (!isJsonObject(raw)) return void 0;
|
|
4561
|
+
return {
|
|
4562
|
+
appId: readString(raw, "appId") ?? readString(raw, "app_id"),
|
|
4563
|
+
rmsReleaseId: readString(raw, "rmsReleaseId") ?? readString(raw, "rms_release_id"),
|
|
4564
|
+
imageDigest: readString(raw, "imageDigest") ?? readString(raw, "image_digest"),
|
|
4565
|
+
registryUrl: readString(raw, "registryUrl") ?? readString(raw, "registry_url"),
|
|
4566
|
+
publicEnv: readString(raw, "publicEnv") ?? readString(raw, "public_env"),
|
|
4567
|
+
encryptedEnv: readString(raw, "encryptedEnv") ?? readString(raw, "encrypted_env"),
|
|
4568
|
+
upgradeByTime: readNumber(raw, "upgradeByTime") ?? readNumber(raw, "upgrade_by_time"),
|
|
4569
|
+
createdAt: readString(raw, "createdAt") ?? readString(raw, "created_at"),
|
|
4570
|
+
createdAtBlock: readString(raw, "createdAtBlock") ?? readString(raw, "created_at_block"),
|
|
4571
|
+
build: raw.build ? transformAppReleaseBuild(raw.build) : void 0
|
|
4572
|
+
};
|
|
4792
4573
|
}
|
|
4793
4574
|
|
|
4794
4575
|
// src/client/common/contract/watcher.ts
|
|
@@ -4796,8 +4577,8 @@ var WATCH_POLL_INTERVAL_SECONDS = 5;
|
|
|
4796
4577
|
var APP_STATUS_RUNNING = "Running";
|
|
4797
4578
|
var APP_STATUS_FAILED = "Failed";
|
|
4798
4579
|
async function watchUntilRunning(options, logger) {
|
|
4799
|
-
const {
|
|
4800
|
-
const userApiClient = new UserApiClient(environmentConfig,
|
|
4580
|
+
const { walletClient, publicClient, environmentConfig, appId } = options;
|
|
4581
|
+
const userApiClient = new UserApiClient(environmentConfig, walletClient, publicClient);
|
|
4801
4582
|
let initialStatus;
|
|
4802
4583
|
let initialIP;
|
|
4803
4584
|
let hasChanged = false;
|
|
@@ -4846,8 +4627,8 @@ async function watchUntilRunning(options, logger) {
|
|
|
4846
4627
|
}
|
|
4847
4628
|
var APP_STATUS_STOPPED = "Stopped";
|
|
4848
4629
|
async function watchUntilUpgradeComplete(options, logger) {
|
|
4849
|
-
const {
|
|
4850
|
-
const userApiClient = new UserApiClient(environmentConfig,
|
|
4630
|
+
const { walletClient, publicClient, environmentConfig, appId } = options;
|
|
4631
|
+
const userApiClient = new UserApiClient(environmentConfig, walletClient, publicClient);
|
|
4851
4632
|
let initialStatus;
|
|
4852
4633
|
let initialIP;
|
|
4853
4634
|
let hasChanged = false;
|
|
@@ -4910,7 +4691,7 @@ function sleep(ms) {
|
|
|
4910
4691
|
|
|
4911
4692
|
// src/client/common/utils/validation.ts
|
|
4912
4693
|
var import_fs = __toESM(require("fs"), 1);
|
|
4913
|
-
var
|
|
4694
|
+
var import_viem5 = require("viem");
|
|
4914
4695
|
function validateAppName(name) {
|
|
4915
4696
|
if (!name) {
|
|
4916
4697
|
throw new Error("App name cannot be empty");
|
|
@@ -4958,7 +4739,7 @@ function validateAppID(appID) {
|
|
|
4958
4739
|
throw new Error("App ID is required");
|
|
4959
4740
|
}
|
|
4960
4741
|
const normalized = typeof appID === "string" ? addHexPrefix(appID) : appID;
|
|
4961
|
-
if ((0,
|
|
4742
|
+
if ((0, import_viem5.isAddress)(normalized)) {
|
|
4962
4743
|
return normalized;
|
|
4963
4744
|
}
|
|
4964
4745
|
throw new Error(`Invalid app ID: '${appID}' is not a valid address`);
|
|
@@ -4993,68 +4774,142 @@ function validateResourceUsageMonitoring(resourceUsageMonitoring) {
|
|
|
4993
4774
|
}
|
|
4994
4775
|
}
|
|
4995
4776
|
|
|
4777
|
+
// src/client/common/config/environment.ts
|
|
4778
|
+
var SEPOLIA_CHAIN_ID = 11155111;
|
|
4779
|
+
var MAINNET_CHAIN_ID = 1;
|
|
4780
|
+
var CommonAddresses = {
|
|
4781
|
+
ERC7702Delegator: "0x63c0c19a282a1b52b07dd5a65b58948a07dae32b"
|
|
4782
|
+
};
|
|
4783
|
+
var ChainAddresses = {
|
|
4784
|
+
[MAINNET_CHAIN_ID]: {
|
|
4785
|
+
PermissionController: "0x25E5F8B1E7aDf44518d35D5B2271f114e081f0E5"
|
|
4786
|
+
},
|
|
4787
|
+
[SEPOLIA_CHAIN_ID]: {
|
|
4788
|
+
PermissionController: "0x44632dfBdCb6D3E21EF613B0ca8A6A0c618F5a37"
|
|
4789
|
+
}
|
|
4790
|
+
};
|
|
4791
|
+
var ENVIRONMENTS = {
|
|
4792
|
+
"sepolia-dev": {
|
|
4793
|
+
name: "sepolia",
|
|
4794
|
+
build: "dev",
|
|
4795
|
+
appControllerAddress: "0xa86DC1C47cb2518327fB4f9A1627F51966c83B92",
|
|
4796
|
+
permissionControllerAddress: ChainAddresses[SEPOLIA_CHAIN_ID].PermissionController,
|
|
4797
|
+
erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,
|
|
4798
|
+
kmsServerURL: "http://10.128.0.57:8080",
|
|
4799
|
+
userApiServerURL: "https://userapi-compute-sepolia-dev.eigencloud.xyz",
|
|
4800
|
+
defaultRPCURL: "https://ethereum-sepolia-rpc.publicnode.com"
|
|
4801
|
+
},
|
|
4802
|
+
sepolia: {
|
|
4803
|
+
name: "sepolia",
|
|
4804
|
+
build: "prod",
|
|
4805
|
+
appControllerAddress: "0x0dd810a6ffba6a9820a10d97b659f07d8d23d4E2",
|
|
4806
|
+
permissionControllerAddress: ChainAddresses[SEPOLIA_CHAIN_ID].PermissionController,
|
|
4807
|
+
erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,
|
|
4808
|
+
kmsServerURL: "http://10.128.15.203:8080",
|
|
4809
|
+
userApiServerURL: "https://userapi-compute-sepolia-prod.eigencloud.xyz",
|
|
4810
|
+
defaultRPCURL: "https://ethereum-sepolia-rpc.publicnode.com"
|
|
4811
|
+
},
|
|
4812
|
+
"mainnet-alpha": {
|
|
4813
|
+
name: "mainnet-alpha",
|
|
4814
|
+
build: "prod",
|
|
4815
|
+
appControllerAddress: "0xc38d35Fc995e75342A21CBd6D770305b142Fbe67",
|
|
4816
|
+
permissionControllerAddress: ChainAddresses[MAINNET_CHAIN_ID].PermissionController,
|
|
4817
|
+
erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,
|
|
4818
|
+
kmsServerURL: "http://10.128.0.2:8080",
|
|
4819
|
+
userApiServerURL: "https://userapi-compute.eigencloud.xyz",
|
|
4820
|
+
defaultRPCURL: "https://ethereum-rpc.publicnode.com"
|
|
4821
|
+
}
|
|
4822
|
+
};
|
|
4823
|
+
var CHAIN_ID_TO_ENVIRONMENT = {
|
|
4824
|
+
[SEPOLIA_CHAIN_ID.toString()]: "sepolia",
|
|
4825
|
+
[MAINNET_CHAIN_ID.toString()]: "mainnet-alpha"
|
|
4826
|
+
};
|
|
4827
|
+
function getEnvironmentConfig(environment, chainID) {
|
|
4828
|
+
const env = ENVIRONMENTS[environment];
|
|
4829
|
+
if (!env) {
|
|
4830
|
+
throw new Error(`Unknown environment: ${environment}`);
|
|
4831
|
+
}
|
|
4832
|
+
if (!isEnvironmentAvailable(environment)) {
|
|
4833
|
+
throw new Error(
|
|
4834
|
+
`Environment ${environment} is not available in this build type. Available environments: ${getAvailableEnvironments().join(", ")}`
|
|
4835
|
+
);
|
|
4836
|
+
}
|
|
4837
|
+
if (chainID) {
|
|
4838
|
+
const expectedEnv = CHAIN_ID_TO_ENVIRONMENT[chainID.toString()];
|
|
4839
|
+
if (expectedEnv && expectedEnv !== environment) {
|
|
4840
|
+
throw new Error(`Environment ${environment} does not match chain ID ${chainID}`);
|
|
4841
|
+
}
|
|
4842
|
+
}
|
|
4843
|
+
const resolvedChainID = chainID || (environment === "sepolia" || environment === "sepolia-dev" ? SEPOLIA_CHAIN_ID : MAINNET_CHAIN_ID);
|
|
4844
|
+
return {
|
|
4845
|
+
...env,
|
|
4846
|
+
chainID: BigInt(resolvedChainID)
|
|
4847
|
+
};
|
|
4848
|
+
}
|
|
4849
|
+
function getBuildType() {
|
|
4850
|
+
const buildTimeType = true ? "dev"?.toLowerCase() : void 0;
|
|
4851
|
+
const runtimeType = process.env.BUILD_TYPE?.toLowerCase();
|
|
4852
|
+
const buildType = buildTimeType || runtimeType;
|
|
4853
|
+
if (buildType === "dev") {
|
|
4854
|
+
return "dev";
|
|
4855
|
+
}
|
|
4856
|
+
return "prod";
|
|
4857
|
+
}
|
|
4858
|
+
function getAvailableEnvironments() {
|
|
4859
|
+
const buildType = getBuildType();
|
|
4860
|
+
if (buildType === "dev") {
|
|
4861
|
+
return ["sepolia-dev"];
|
|
4862
|
+
}
|
|
4863
|
+
return ["sepolia", "mainnet-alpha"];
|
|
4864
|
+
}
|
|
4865
|
+
function isEnvironmentAvailable(environment) {
|
|
4866
|
+
return getAvailableEnvironments().includes(environment);
|
|
4867
|
+
}
|
|
4868
|
+
|
|
4996
4869
|
// src/client/common/utils/preflight.ts
|
|
4997
|
-
var import_viem7 = require("viem");
|
|
4998
|
-
var import_accounts4 = require("viem/accounts");
|
|
4999
4870
|
async function doPreflightChecks(options, logger) {
|
|
5000
|
-
|
|
5001
|
-
const privateKey = await getPrivateKeyOrFail(options.privateKey);
|
|
4871
|
+
const { walletClient, publicClient } = options;
|
|
5002
4872
|
logger.debug("Determining environment...");
|
|
5003
4873
|
const environmentConfig = getEnvironmentConfig(options.environment || "sepolia");
|
|
5004
|
-
|
|
5005
|
-
if (!
|
|
5006
|
-
|
|
5007
|
-
}
|
|
5008
|
-
if (!rpcUrl) {
|
|
5009
|
-
throw new Error(
|
|
5010
|
-
`RPC URL is required. Provide via options.rpcUrl, RPC_URL env var, or ensure environment has default RPC URL`
|
|
5011
|
-
);
|
|
4874
|
+
const account = walletClient.account;
|
|
4875
|
+
if (!account) {
|
|
4876
|
+
throw new Error("WalletClient must have an account attached");
|
|
5012
4877
|
}
|
|
5013
|
-
logger.debug("
|
|
5014
|
-
const publicClient = (0, import_viem7.createPublicClient)({
|
|
5015
|
-
transport: (0, import_viem7.http)(rpcUrl)
|
|
5016
|
-
});
|
|
4878
|
+
logger.debug("Validating chain ID...");
|
|
5017
4879
|
try {
|
|
5018
4880
|
const chainID = await publicClient.getChainId();
|
|
5019
4881
|
if (BigInt(chainID) !== environmentConfig.chainID) {
|
|
5020
4882
|
throw new Error(`Chain ID mismatch: expected ${environmentConfig.chainID}, got ${chainID}`);
|
|
5021
4883
|
}
|
|
5022
4884
|
} catch (err) {
|
|
5023
|
-
throw new Error(
|
|
4885
|
+
throw new Error(
|
|
4886
|
+
`Cannot connect to ${environmentConfig.name} RPC at ${publicClient.transport.url}: ${err.message}`
|
|
4887
|
+
);
|
|
5024
4888
|
}
|
|
5025
|
-
const privateKeyHex = addHexPrefix(privateKey);
|
|
5026
|
-
const account = (0, import_accounts4.privateKeyToAccount)(privateKeyHex);
|
|
5027
|
-
const selfAddress = account.address;
|
|
5028
4889
|
return {
|
|
5029
|
-
|
|
5030
|
-
|
|
4890
|
+
walletClient,
|
|
4891
|
+
publicClient,
|
|
5031
4892
|
environmentConfig,
|
|
5032
|
-
account
|
|
5033
|
-
selfAddress
|
|
4893
|
+
selfAddress: account.address
|
|
5034
4894
|
};
|
|
5035
4895
|
}
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
const cleaned = stripHexPrefix(key);
|
|
5054
|
-
if (!/^[0-9a-fA-F]{64}$/.test(cleaned)) {
|
|
5055
|
-
throw new Error("Invalid private key format (must be 64 hex characters)");
|
|
5056
|
-
}
|
|
5057
|
-
}
|
|
4896
|
+
|
|
4897
|
+
// src/client/common/utils/logger.ts
|
|
4898
|
+
var defaultLogger = {
|
|
4899
|
+
info: (...args) => console.info(...args),
|
|
4900
|
+
warn: (...args) => console.warn(...args),
|
|
4901
|
+
error: (...args) => console.error(...args),
|
|
4902
|
+
debug: (...args) => console.debug(...args)
|
|
4903
|
+
};
|
|
4904
|
+
var getLogger = (verbose) => ({
|
|
4905
|
+
info: (...args) => console.info(...args),
|
|
4906
|
+
warn: (...args) => console.warn(...args),
|
|
4907
|
+
error: (...args) => console.error(...args),
|
|
4908
|
+
debug: (...args) => verbose && console.debug(...args)
|
|
4909
|
+
});
|
|
4910
|
+
|
|
4911
|
+
// src/client/common/utils/billingapi.ts
|
|
4912
|
+
var import_axios2 = __toESM(require("axios"), 1);
|
|
5058
4913
|
|
|
5059
4914
|
// src/client/common/telemetry/noop.ts
|
|
5060
4915
|
var NoopClient = class {
|
|
@@ -5262,7 +5117,9 @@ async function prepareDeployFromVerifiableBuild(options, logger = defaultLogger)
|
|
|
5262
5117
|
}
|
|
5263
5118
|
},
|
|
5264
5119
|
async () => {
|
|
5265
|
-
if (!options.
|
|
5120
|
+
if (!options.walletClient.account) {
|
|
5121
|
+
throw new Error("WalletClient must have an account attached");
|
|
5122
|
+
}
|
|
5266
5123
|
if (!options.imageRef) throw new Error("imageRef is required for deployment");
|
|
5267
5124
|
if (!options.imageDigest) throw new Error("imageDigest is required for deployment");
|
|
5268
5125
|
assertValidImageReference(options.imageRef);
|
|
@@ -5278,8 +5135,8 @@ async function prepareDeployFromVerifiableBuild(options, logger = defaultLogger)
|
|
|
5278
5135
|
logger.debug("Performing preflight checks...");
|
|
5279
5136
|
const preflightCtx = await doPreflightChecks(
|
|
5280
5137
|
{
|
|
5281
|
-
|
|
5282
|
-
|
|
5138
|
+
walletClient: options.walletClient,
|
|
5139
|
+
publicClient: options.publicClient,
|
|
5283
5140
|
environment: options.environment
|
|
5284
5141
|
},
|
|
5285
5142
|
logger
|
|
@@ -5289,12 +5146,12 @@ async function prepareDeployFromVerifiableBuild(options, logger = defaultLogger)
|
|
|
5289
5146
|
const salt = generateRandomSalt();
|
|
5290
5147
|
logger.debug(`Generated salt: ${Buffer.from(salt).toString("hex")}`);
|
|
5291
5148
|
logger.debug("Calculating app ID...");
|
|
5292
|
-
const appIDToBeDeployed = await calculateAppID(
|
|
5293
|
-
preflightCtx.
|
|
5294
|
-
|
|
5295
|
-
preflightCtx.
|
|
5149
|
+
const appIDToBeDeployed = await calculateAppID({
|
|
5150
|
+
publicClient: preflightCtx.publicClient,
|
|
5151
|
+
environmentConfig: preflightCtx.environmentConfig,
|
|
5152
|
+
ownerAddress: preflightCtx.selfAddress,
|
|
5296
5153
|
salt
|
|
5297
|
-
);
|
|
5154
|
+
});
|
|
5298
5155
|
logger.info(``);
|
|
5299
5156
|
logger.info(`App ID: ${appIDToBeDeployed}`);
|
|
5300
5157
|
logger.info(``);
|
|
@@ -5312,12 +5169,13 @@ async function prepareDeployFromVerifiableBuild(options, logger = defaultLogger)
|
|
|
5312
5169
|
logger.debug("Preparing deploy batch...");
|
|
5313
5170
|
const batch = await prepareDeployBatch(
|
|
5314
5171
|
{
|
|
5315
|
-
|
|
5316
|
-
|
|
5172
|
+
walletClient: preflightCtx.walletClient,
|
|
5173
|
+
publicClient: preflightCtx.publicClient,
|
|
5317
5174
|
environmentConfig: preflightCtx.environmentConfig,
|
|
5318
5175
|
salt,
|
|
5319
5176
|
release,
|
|
5320
|
-
publicLogs
|
|
5177
|
+
publicLogs,
|
|
5178
|
+
imageRef: options.imageRef
|
|
5321
5179
|
},
|
|
5322
5180
|
logger
|
|
5323
5181
|
);
|
|
@@ -5344,8 +5202,8 @@ async function prepareDeployFromVerifiableBuild(options, logger = defaultLogger)
|
|
|
5344
5202
|
);
|
|
5345
5203
|
}
|
|
5346
5204
|
function validateDeployOptions(options) {
|
|
5347
|
-
if (!options.
|
|
5348
|
-
throw new Error("
|
|
5205
|
+
if (!options.walletClient.account) {
|
|
5206
|
+
throw new Error("WalletClient must have an account attached");
|
|
5349
5207
|
}
|
|
5350
5208
|
if (!options.dockerfilePath && !options.imageRef) {
|
|
5351
5209
|
throw new Error("Either dockerfilePath or imageRef is required for deployment");
|
|
@@ -5384,8 +5242,8 @@ async function deploy(options, logger = defaultLogger) {
|
|
|
5384
5242
|
logger.debug("Performing preflight checks...");
|
|
5385
5243
|
const preflightCtx = await doPreflightChecks(
|
|
5386
5244
|
{
|
|
5387
|
-
|
|
5388
|
-
|
|
5245
|
+
walletClient: options.walletClient,
|
|
5246
|
+
publicClient: options.publicClient,
|
|
5389
5247
|
environment: options.environment
|
|
5390
5248
|
},
|
|
5391
5249
|
logger
|
|
@@ -5402,12 +5260,12 @@ async function deploy(options, logger = defaultLogger) {
|
|
|
5402
5260
|
const salt = generateRandomSalt();
|
|
5403
5261
|
logger.debug(`Generated salt: ${Buffer.from(salt).toString("hex")}`);
|
|
5404
5262
|
logger.debug("Calculating app ID...");
|
|
5405
|
-
const appIDToBeDeployed = await calculateAppID(
|
|
5406
|
-
preflightCtx.
|
|
5407
|
-
|
|
5408
|
-
preflightCtx.
|
|
5263
|
+
const appIDToBeDeployed = await calculateAppID({
|
|
5264
|
+
publicClient: preflightCtx.publicClient,
|
|
5265
|
+
environmentConfig: preflightCtx.environmentConfig,
|
|
5266
|
+
ownerAddress: preflightCtx.selfAddress,
|
|
5409
5267
|
salt
|
|
5410
|
-
);
|
|
5268
|
+
});
|
|
5411
5269
|
logger.info(``);
|
|
5412
5270
|
logger.info(`App ID: ${appIDToBeDeployed}`);
|
|
5413
5271
|
logger.info(``);
|
|
@@ -5428,8 +5286,8 @@ async function deploy(options, logger = defaultLogger) {
|
|
|
5428
5286
|
logger.info("Deploying on-chain...");
|
|
5429
5287
|
const deployResult = await deployApp(
|
|
5430
5288
|
{
|
|
5431
|
-
|
|
5432
|
-
|
|
5289
|
+
walletClient: preflightCtx.walletClient,
|
|
5290
|
+
publicClient: preflightCtx.publicClient,
|
|
5433
5291
|
environmentConfig: preflightCtx.environmentConfig,
|
|
5434
5292
|
salt,
|
|
5435
5293
|
release,
|
|
@@ -5442,8 +5300,8 @@ async function deploy(options, logger = defaultLogger) {
|
|
|
5442
5300
|
logger.info("Waiting for app to start...");
|
|
5443
5301
|
const ipAddress = await watchUntilRunning(
|
|
5444
5302
|
{
|
|
5445
|
-
|
|
5446
|
-
|
|
5303
|
+
walletClient: preflightCtx.walletClient,
|
|
5304
|
+
publicClient: preflightCtx.publicClient,
|
|
5447
5305
|
environmentConfig: preflightCtx.environmentConfig,
|
|
5448
5306
|
appId: deployResult.appId
|
|
5449
5307
|
},
|
|
@@ -5460,12 +5318,10 @@ async function deploy(options, logger = defaultLogger) {
|
|
|
5460
5318
|
);
|
|
5461
5319
|
}
|
|
5462
5320
|
async function checkQuotaAvailable(preflightCtx) {
|
|
5463
|
-
const
|
|
5464
|
-
const environmentConfig = preflightCtx.environmentConfig;
|
|
5465
|
-
const userAddress = preflightCtx.selfAddress;
|
|
5321
|
+
const { publicClient, environmentConfig, selfAddress: userAddress } = preflightCtx;
|
|
5466
5322
|
let maxQuota;
|
|
5467
5323
|
try {
|
|
5468
|
-
maxQuota = await getMaxActiveAppsPerUser(
|
|
5324
|
+
maxQuota = await getMaxActiveAppsPerUser(publicClient, environmentConfig, userAddress);
|
|
5469
5325
|
} catch (err) {
|
|
5470
5326
|
throw new Error(`failed to get quota limit: ${err.message}`);
|
|
5471
5327
|
}
|
|
@@ -5476,7 +5332,7 @@ async function checkQuotaAvailable(preflightCtx) {
|
|
|
5476
5332
|
}
|
|
5477
5333
|
let activeCount;
|
|
5478
5334
|
try {
|
|
5479
|
-
activeCount = await getActiveAppCount(
|
|
5335
|
+
activeCount = await getActiveAppCount(publicClient, environmentConfig, userAddress);
|
|
5480
5336
|
} catch (err) {
|
|
5481
5337
|
throw new Error(`failed to get active app count: ${err.message}`);
|
|
5482
5338
|
}
|
|
@@ -5507,8 +5363,8 @@ async function prepareDeploy(options, logger = defaultLogger) {
|
|
|
5507
5363
|
logger.debug("Performing preflight checks...");
|
|
5508
5364
|
const preflightCtx = await doPreflightChecks(
|
|
5509
5365
|
{
|
|
5510
|
-
|
|
5511
|
-
|
|
5366
|
+
walletClient: options.walletClient,
|
|
5367
|
+
publicClient: options.publicClient,
|
|
5512
5368
|
environment: options.environment
|
|
5513
5369
|
},
|
|
5514
5370
|
logger
|
|
@@ -5525,12 +5381,12 @@ async function prepareDeploy(options, logger = defaultLogger) {
|
|
|
5525
5381
|
const salt = generateRandomSalt();
|
|
5526
5382
|
logger.debug(`Generated salt: ${Buffer.from(salt).toString("hex")}`);
|
|
5527
5383
|
logger.debug("Calculating app ID...");
|
|
5528
|
-
const appIDToBeDeployed = await calculateAppID(
|
|
5529
|
-
preflightCtx.
|
|
5530
|
-
|
|
5531
|
-
preflightCtx.
|
|
5384
|
+
const appIDToBeDeployed = await calculateAppID({
|
|
5385
|
+
publicClient: preflightCtx.publicClient,
|
|
5386
|
+
environmentConfig: preflightCtx.environmentConfig,
|
|
5387
|
+
ownerAddress: preflightCtx.selfAddress,
|
|
5532
5388
|
salt
|
|
5533
|
-
);
|
|
5389
|
+
});
|
|
5534
5390
|
logger.info(``);
|
|
5535
5391
|
logger.info(`App ID: ${appIDToBeDeployed}`);
|
|
5536
5392
|
logger.info(``);
|
|
@@ -5551,12 +5407,13 @@ async function prepareDeploy(options, logger = defaultLogger) {
|
|
|
5551
5407
|
logger.debug("Preparing deploy batch...");
|
|
5552
5408
|
const batch = await prepareDeployBatch(
|
|
5553
5409
|
{
|
|
5554
|
-
|
|
5555
|
-
|
|
5410
|
+
walletClient: preflightCtx.walletClient,
|
|
5411
|
+
publicClient: preflightCtx.publicClient,
|
|
5556
5412
|
environmentConfig: preflightCtx.environmentConfig,
|
|
5557
5413
|
salt,
|
|
5558
5414
|
release,
|
|
5559
|
-
publicLogs
|
|
5415
|
+
publicLogs,
|
|
5416
|
+
imageRef: finalImageRef
|
|
5560
5417
|
},
|
|
5561
5418
|
logger
|
|
5562
5419
|
);
|
|
@@ -5601,25 +5458,23 @@ async function executeDeploy(options) {
|
|
|
5601
5458
|
}
|
|
5602
5459
|
);
|
|
5603
5460
|
}
|
|
5604
|
-
async function watchDeployment(appId,
|
|
5461
|
+
async function watchDeployment(appId, walletClient, publicClient, environmentConfig, logger = defaultLogger, skipTelemetry) {
|
|
5605
5462
|
return withSDKTelemetry(
|
|
5606
5463
|
{
|
|
5607
5464
|
functionName: "watchDeployment",
|
|
5608
5465
|
skipTelemetry,
|
|
5609
5466
|
properties: {
|
|
5610
|
-
environment
|
|
5467
|
+
environment: environmentConfig.name
|
|
5611
5468
|
}
|
|
5612
5469
|
},
|
|
5613
5470
|
async () => {
|
|
5614
|
-
const environmentConfig = getEnvironmentConfig(environment);
|
|
5615
5471
|
logger.info("Waiting for app to start...");
|
|
5616
5472
|
return watchUntilRunning(
|
|
5617
5473
|
{
|
|
5618
|
-
|
|
5619
|
-
|
|
5474
|
+
walletClient,
|
|
5475
|
+
publicClient,
|
|
5620
5476
|
environmentConfig,
|
|
5621
|
-
appId
|
|
5622
|
-
clientId
|
|
5477
|
+
appId
|
|
5623
5478
|
},
|
|
5624
5479
|
logger
|
|
5625
5480
|
);
|
|
@@ -5628,18 +5483,12 @@ async function watchDeployment(appId, privateKey, rpcUrl, environment, logger =
|
|
|
5628
5483
|
}
|
|
5629
5484
|
|
|
5630
5485
|
// src/client/common/utils/permissions.ts
|
|
5631
|
-
var import_viem8 = require("viem");
|
|
5632
5486
|
var AnyoneCanCallAddress = "0x493219d9949348178af1f58740655951a8cd110c";
|
|
5633
5487
|
var ApiPermissionsTarget = "0x57ee1fb74c1087e26446abc4fb87fd8f07c43d8d";
|
|
5634
5488
|
var CanViewAppLogsPermission2 = "0x2fd3f2fe";
|
|
5635
5489
|
async function checkAppLogPermission(preflightCtx, appAddress, logger) {
|
|
5636
|
-
const chain = getChainFromID(preflightCtx.environmentConfig.chainID);
|
|
5637
|
-
const publicClient = (0, import_viem8.createPublicClient)({
|
|
5638
|
-
chain,
|
|
5639
|
-
transport: (0, import_viem8.http)(preflightCtx.rpcUrl)
|
|
5640
|
-
});
|
|
5641
5490
|
try {
|
|
5642
|
-
const canCall = await publicClient.readContract({
|
|
5491
|
+
const canCall = await preflightCtx.publicClient.readContract({
|
|
5643
5492
|
address: preflightCtx.environmentConfig.permissionControllerAddress,
|
|
5644
5493
|
abi: PermissionController_default,
|
|
5645
5494
|
functionName: "canCall",
|
|
@@ -5666,8 +5515,8 @@ async function prepareUpgradeFromVerifiableBuild(options, logger = defaultLogger
|
|
|
5666
5515
|
logger.debug("Performing preflight checks...");
|
|
5667
5516
|
const preflightCtx = await doPreflightChecks(
|
|
5668
5517
|
{
|
|
5669
|
-
|
|
5670
|
-
|
|
5518
|
+
walletClient: options.walletClient,
|
|
5519
|
+
publicClient: options.publicClient,
|
|
5671
5520
|
environment: options.environment
|
|
5672
5521
|
},
|
|
5673
5522
|
logger
|
|
@@ -5699,13 +5548,14 @@ async function prepareUpgradeFromVerifiableBuild(options, logger = defaultLogger
|
|
|
5699
5548
|
const needsPermissionChange = currentlyPublic !== publicLogs;
|
|
5700
5549
|
logger.debug("Preparing upgrade batch...");
|
|
5701
5550
|
const batch = await prepareUpgradeBatch({
|
|
5702
|
-
|
|
5703
|
-
|
|
5551
|
+
walletClient: preflightCtx.walletClient,
|
|
5552
|
+
publicClient: preflightCtx.publicClient,
|
|
5704
5553
|
environmentConfig: preflightCtx.environmentConfig,
|
|
5705
|
-
|
|
5554
|
+
appID,
|
|
5706
5555
|
release,
|
|
5707
5556
|
publicLogs,
|
|
5708
|
-
needsPermissionChange
|
|
5557
|
+
needsPermissionChange,
|
|
5558
|
+
imageRef: options.imageRef
|
|
5709
5559
|
});
|
|
5710
5560
|
logger.debug("Estimating gas...");
|
|
5711
5561
|
const gasEstimate = await estimateBatchGas({
|
|
@@ -5729,8 +5579,8 @@ async function prepareUpgradeFromVerifiableBuild(options, logger = defaultLogger
|
|
|
5729
5579
|
);
|
|
5730
5580
|
}
|
|
5731
5581
|
function validateUpgradeOptions(options) {
|
|
5732
|
-
if (!options.
|
|
5733
|
-
throw new Error("
|
|
5582
|
+
if (!options.walletClient?.account) {
|
|
5583
|
+
throw new Error("walletClient with account is required for upgrade");
|
|
5734
5584
|
}
|
|
5735
5585
|
if (!options.appId) {
|
|
5736
5586
|
throw new Error("appId is required for upgrade");
|
|
@@ -5767,8 +5617,8 @@ async function upgrade(options, logger = defaultLogger) {
|
|
|
5767
5617
|
logger.debug("Performing preflight checks...");
|
|
5768
5618
|
const preflightCtx = await doPreflightChecks(
|
|
5769
5619
|
{
|
|
5770
|
-
|
|
5771
|
-
|
|
5620
|
+
walletClient: options.walletClient,
|
|
5621
|
+
publicClient: options.publicClient,
|
|
5772
5622
|
environment: options.environment
|
|
5773
5623
|
},
|
|
5774
5624
|
logger
|
|
@@ -5802,10 +5652,10 @@ async function upgrade(options, logger = defaultLogger) {
|
|
|
5802
5652
|
logger.info("Upgrading on-chain...");
|
|
5803
5653
|
const txHash = await upgradeApp(
|
|
5804
5654
|
{
|
|
5805
|
-
|
|
5806
|
-
|
|
5655
|
+
walletClient: preflightCtx.walletClient,
|
|
5656
|
+
publicClient: preflightCtx.publicClient,
|
|
5807
5657
|
environmentConfig: preflightCtx.environmentConfig,
|
|
5808
|
-
|
|
5658
|
+
appID,
|
|
5809
5659
|
release,
|
|
5810
5660
|
publicLogs,
|
|
5811
5661
|
needsPermissionChange,
|
|
@@ -5817,8 +5667,8 @@ async function upgrade(options, logger = defaultLogger) {
|
|
|
5817
5667
|
logger.info("Waiting for upgrade to complete...");
|
|
5818
5668
|
await watchUntilUpgradeComplete(
|
|
5819
5669
|
{
|
|
5820
|
-
|
|
5821
|
-
|
|
5670
|
+
walletClient: preflightCtx.walletClient,
|
|
5671
|
+
publicClient: preflightCtx.publicClient,
|
|
5822
5672
|
environmentConfig: preflightCtx.environmentConfig,
|
|
5823
5673
|
appId: appID
|
|
5824
5674
|
},
|
|
@@ -5845,8 +5695,8 @@ async function prepareUpgrade(options, logger = defaultLogger) {
|
|
|
5845
5695
|
logger.debug("Performing preflight checks...");
|
|
5846
5696
|
const preflightCtx = await doPreflightChecks(
|
|
5847
5697
|
{
|
|
5848
|
-
|
|
5849
|
-
|
|
5698
|
+
walletClient: options.walletClient,
|
|
5699
|
+
publicClient: options.publicClient,
|
|
5850
5700
|
environment: options.environment
|
|
5851
5701
|
},
|
|
5852
5702
|
logger
|
|
@@ -5879,13 +5729,14 @@ async function prepareUpgrade(options, logger = defaultLogger) {
|
|
|
5879
5729
|
const needsPermissionChange = currentlyPublic !== publicLogs;
|
|
5880
5730
|
logger.debug("Preparing upgrade batch...");
|
|
5881
5731
|
const batch = await prepareUpgradeBatch({
|
|
5882
|
-
|
|
5883
|
-
|
|
5732
|
+
walletClient: preflightCtx.walletClient,
|
|
5733
|
+
publicClient: preflightCtx.publicClient,
|
|
5884
5734
|
environmentConfig: preflightCtx.environmentConfig,
|
|
5885
|
-
|
|
5735
|
+
appID,
|
|
5886
5736
|
release,
|
|
5887
5737
|
publicLogs,
|
|
5888
|
-
needsPermissionChange
|
|
5738
|
+
needsPermissionChange,
|
|
5739
|
+
imageRef: finalImageRef
|
|
5889
5740
|
});
|
|
5890
5741
|
logger.debug("Estimating gas...");
|
|
5891
5742
|
const gasEstimate = await estimateBatchGas({
|
|
@@ -5926,25 +5777,23 @@ async function executeUpgrade(options) {
|
|
|
5926
5777
|
}
|
|
5927
5778
|
);
|
|
5928
5779
|
}
|
|
5929
|
-
async function watchUpgrade(appId,
|
|
5780
|
+
async function watchUpgrade(appId, walletClient, publicClient, environmentConfig, logger = defaultLogger, skipTelemetry) {
|
|
5930
5781
|
return withSDKTelemetry(
|
|
5931
5782
|
{
|
|
5932
5783
|
functionName: "watchUpgrade",
|
|
5933
5784
|
skipTelemetry,
|
|
5934
5785
|
properties: {
|
|
5935
|
-
environment
|
|
5786
|
+
environment: environmentConfig.name
|
|
5936
5787
|
}
|
|
5937
5788
|
},
|
|
5938
5789
|
async () => {
|
|
5939
|
-
const environmentConfig = getEnvironmentConfig(environment);
|
|
5940
5790
|
logger.info("Waiting for upgrade to complete...");
|
|
5941
5791
|
await watchUntilUpgradeComplete(
|
|
5942
5792
|
{
|
|
5943
|
-
|
|
5944
|
-
|
|
5793
|
+
walletClient,
|
|
5794
|
+
publicClient,
|
|
5945
5795
|
environmentConfig,
|
|
5946
|
-
appId
|
|
5947
|
-
clientId
|
|
5796
|
+
appId
|
|
5948
5797
|
},
|
|
5949
5798
|
logger
|
|
5950
5799
|
);
|
|
@@ -6508,31 +6357,24 @@ async function watchLogs(appID, userApiClient, initialLogs) {
|
|
|
6508
6357
|
}
|
|
6509
6358
|
console.log("\nStopped watching");
|
|
6510
6359
|
}
|
|
6511
|
-
async function logs(options, logger = defaultLogger, skipTelemetry = false) {
|
|
6512
|
-
const skipTelemetryFlag = skipTelemetry || options.skipTelemetry || false;
|
|
6360
|
+
async function logs(options, walletClient, publicClient, environmentConfig, logger = defaultLogger, skipTelemetry = false) {
|
|
6513
6361
|
return withSDKTelemetry(
|
|
6514
6362
|
{
|
|
6515
6363
|
functionName: "logs",
|
|
6516
|
-
skipTelemetry
|
|
6517
|
-
properties: { environment:
|
|
6364
|
+
skipTelemetry,
|
|
6365
|
+
properties: { environment: environmentConfig.name }
|
|
6518
6366
|
},
|
|
6519
6367
|
async () => {
|
|
6520
6368
|
console.log();
|
|
6521
6369
|
if (!options.appID) {
|
|
6522
6370
|
throw new Error("appID is required for viewing logs");
|
|
6523
6371
|
}
|
|
6524
|
-
const environment = options.environment || "sepolia";
|
|
6525
|
-
const environmentConfig = getEnvironmentConfig(environment);
|
|
6526
|
-
const rpcUrl = options.rpcUrl || environmentConfig.defaultRPCURL;
|
|
6527
|
-
if (!rpcUrl) {
|
|
6528
|
-
throw new Error("RPC URL is required for authenticated requests");
|
|
6529
|
-
}
|
|
6530
6372
|
const appID = validateAppID(options.appID);
|
|
6531
6373
|
const formattedApp = formatAppDisplay(environmentConfig.name, appID, "");
|
|
6532
6374
|
const userApiClient = new UserApiClient(
|
|
6533
6375
|
environmentConfig,
|
|
6534
|
-
|
|
6535
|
-
|
|
6376
|
+
walletClient,
|
|
6377
|
+
publicClient,
|
|
6536
6378
|
options.clientId
|
|
6537
6379
|
);
|
|
6538
6380
|
let logsText;
|
|
@@ -6609,35 +6451,39 @@ async function logs(options, logger = defaultLogger, skipTelemetry = false) {
|
|
|
6609
6451
|
}
|
|
6610
6452
|
|
|
6611
6453
|
// src/client/modules/compute/app/index.ts
|
|
6612
|
-
var CONTROLLER_ABI = (0,
|
|
6454
|
+
var CONTROLLER_ABI = (0, import_viem6.parseAbi)([
|
|
6613
6455
|
"function startApp(address appId)",
|
|
6614
6456
|
"function stopApp(address appId)",
|
|
6615
6457
|
"function terminateApp(address appId)"
|
|
6616
6458
|
]);
|
|
6617
6459
|
function encodeStartAppData(appId) {
|
|
6618
|
-
return (0,
|
|
6460
|
+
return (0, import_viem6.encodeFunctionData)({
|
|
6619
6461
|
abi: CONTROLLER_ABI,
|
|
6620
6462
|
functionName: "startApp",
|
|
6621
6463
|
args: [appId]
|
|
6622
6464
|
});
|
|
6623
6465
|
}
|
|
6624
6466
|
function encodeStopAppData(appId) {
|
|
6625
|
-
return (0,
|
|
6467
|
+
return (0, import_viem6.encodeFunctionData)({
|
|
6626
6468
|
abi: CONTROLLER_ABI,
|
|
6627
6469
|
functionName: "stopApp",
|
|
6628
6470
|
args: [appId]
|
|
6629
6471
|
});
|
|
6630
6472
|
}
|
|
6631
6473
|
function encodeTerminateAppData(appId) {
|
|
6632
|
-
return (0,
|
|
6474
|
+
return (0, import_viem6.encodeFunctionData)({
|
|
6633
6475
|
abi: CONTROLLER_ABI,
|
|
6634
6476
|
functionName: "terminateApp",
|
|
6635
6477
|
args: [appId]
|
|
6636
6478
|
});
|
|
6637
6479
|
}
|
|
6638
6480
|
function createAppModule(ctx) {
|
|
6639
|
-
const
|
|
6481
|
+
const { walletClient, publicClient } = ctx;
|
|
6640
6482
|
const skipTelemetry = ctx.skipTelemetry || false;
|
|
6483
|
+
if (!walletClient.account) {
|
|
6484
|
+
throw new Error("WalletClient must have an account attached");
|
|
6485
|
+
}
|
|
6486
|
+
const account = walletClient.account;
|
|
6641
6487
|
const environment = getEnvironmentConfig(ctx.environment);
|
|
6642
6488
|
const logger = getLogger(ctx.verbose);
|
|
6643
6489
|
return {
|
|
@@ -6648,8 +6494,8 @@ function createAppModule(ctx) {
|
|
|
6648
6494
|
async deploy(opts) {
|
|
6649
6495
|
const result = await deploy(
|
|
6650
6496
|
{
|
|
6651
|
-
|
|
6652
|
-
|
|
6497
|
+
walletClient,
|
|
6498
|
+
publicClient,
|
|
6653
6499
|
environment: ctx.environment,
|
|
6654
6500
|
appName: opts.name,
|
|
6655
6501
|
instanceType: opts.instanceType,
|
|
@@ -6673,8 +6519,8 @@ function createAppModule(ctx) {
|
|
|
6673
6519
|
const result = await upgrade(
|
|
6674
6520
|
{
|
|
6675
6521
|
appId,
|
|
6676
|
-
|
|
6677
|
-
|
|
6522
|
+
walletClient,
|
|
6523
|
+
publicClient,
|
|
6678
6524
|
environment: ctx.environment,
|
|
6679
6525
|
instanceType: opts.instanceType,
|
|
6680
6526
|
dockerfilePath: opts.dockerfile,
|
|
@@ -6695,8 +6541,8 @@ function createAppModule(ctx) {
|
|
|
6695
6541
|
async prepareDeploy(opts) {
|
|
6696
6542
|
return prepareDeploy(
|
|
6697
6543
|
{
|
|
6698
|
-
|
|
6699
|
-
|
|
6544
|
+
walletClient,
|
|
6545
|
+
publicClient,
|
|
6700
6546
|
environment: ctx.environment,
|
|
6701
6547
|
appName: opts.name,
|
|
6702
6548
|
instanceType: opts.instanceType,
|
|
@@ -6713,8 +6559,8 @@ function createAppModule(ctx) {
|
|
|
6713
6559
|
async prepareDeployFromVerifiableBuild(opts) {
|
|
6714
6560
|
return prepareDeployFromVerifiableBuild(
|
|
6715
6561
|
{
|
|
6716
|
-
|
|
6717
|
-
|
|
6562
|
+
walletClient,
|
|
6563
|
+
publicClient,
|
|
6718
6564
|
environment: ctx.environment,
|
|
6719
6565
|
appName: opts.name,
|
|
6720
6566
|
instanceType: opts.instanceType,
|
|
@@ -6729,17 +6575,6 @@ function createAppModule(ctx) {
|
|
|
6729
6575
|
);
|
|
6730
6576
|
},
|
|
6731
6577
|
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
6578
|
const result = await executeDeploy({
|
|
6744
6579
|
prepared,
|
|
6745
6580
|
context: {
|
|
@@ -6761,11 +6596,10 @@ function createAppModule(ctx) {
|
|
|
6761
6596
|
async watchDeployment(appId) {
|
|
6762
6597
|
return watchDeployment(
|
|
6763
6598
|
appId,
|
|
6764
|
-
|
|
6765
|
-
|
|
6766
|
-
|
|
6599
|
+
walletClient,
|
|
6600
|
+
publicClient,
|
|
6601
|
+
environment,
|
|
6767
6602
|
logger,
|
|
6768
|
-
ctx.clientId,
|
|
6769
6603
|
skipTelemetry
|
|
6770
6604
|
);
|
|
6771
6605
|
},
|
|
@@ -6774,8 +6608,8 @@ function createAppModule(ctx) {
|
|
|
6774
6608
|
return prepareUpgrade(
|
|
6775
6609
|
{
|
|
6776
6610
|
appId,
|
|
6777
|
-
|
|
6778
|
-
|
|
6611
|
+
walletClient,
|
|
6612
|
+
publicClient,
|
|
6779
6613
|
environment: ctx.environment,
|
|
6780
6614
|
instanceType: opts.instanceType,
|
|
6781
6615
|
dockerfilePath: opts.dockerfile,
|
|
@@ -6792,8 +6626,8 @@ function createAppModule(ctx) {
|
|
|
6792
6626
|
return prepareUpgradeFromVerifiableBuild(
|
|
6793
6627
|
{
|
|
6794
6628
|
appId,
|
|
6795
|
-
|
|
6796
|
-
|
|
6629
|
+
walletClient,
|
|
6630
|
+
publicClient,
|
|
6797
6631
|
environment: ctx.environment,
|
|
6798
6632
|
instanceType: opts.instanceType,
|
|
6799
6633
|
envFilePath: opts.envFile,
|
|
@@ -6807,17 +6641,6 @@ function createAppModule(ctx) {
|
|
|
6807
6641
|
);
|
|
6808
6642
|
},
|
|
6809
6643
|
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
6644
|
const result = await executeUpgrade({
|
|
6822
6645
|
prepared,
|
|
6823
6646
|
context: {
|
|
@@ -6836,15 +6659,7 @@ function createAppModule(ctx) {
|
|
|
6836
6659
|
};
|
|
6837
6660
|
},
|
|
6838
6661
|
async watchUpgrade(appId) {
|
|
6839
|
-
return watchUpgrade(
|
|
6840
|
-
appId,
|
|
6841
|
-
privateKey,
|
|
6842
|
-
ctx.rpcUrl,
|
|
6843
|
-
ctx.environment,
|
|
6844
|
-
logger,
|
|
6845
|
-
ctx.clientId,
|
|
6846
|
-
skipTelemetry
|
|
6847
|
-
);
|
|
6662
|
+
return watchUpgrade(appId, walletClient, publicClient, environment, logger, skipTelemetry);
|
|
6848
6663
|
},
|
|
6849
6664
|
// Profile management
|
|
6850
6665
|
async setProfile(appId, profile) {
|
|
@@ -6857,33 +6672,32 @@ function createAppModule(ctx) {
|
|
|
6857
6672
|
async () => {
|
|
6858
6673
|
const userApiClient = new UserApiClient(
|
|
6859
6674
|
environment,
|
|
6860
|
-
|
|
6861
|
-
|
|
6675
|
+
walletClient,
|
|
6676
|
+
publicClient,
|
|
6862
6677
|
ctx.clientId
|
|
6863
6678
|
);
|
|
6864
|
-
return userApiClient.uploadAppProfile(
|
|
6865
|
-
|
|
6866
|
-
profile.
|
|
6867
|
-
profile.
|
|
6868
|
-
profile.
|
|
6869
|
-
profile.
|
|
6870
|
-
|
|
6871
|
-
);
|
|
6679
|
+
return userApiClient.uploadAppProfile(appId, profile.name, {
|
|
6680
|
+
website: profile.website,
|
|
6681
|
+
description: profile.description,
|
|
6682
|
+
xURL: profile.xURL,
|
|
6683
|
+
image: profile.image,
|
|
6684
|
+
imageName: profile.imageName
|
|
6685
|
+
});
|
|
6872
6686
|
}
|
|
6873
6687
|
);
|
|
6874
6688
|
},
|
|
6875
6689
|
async logs(opts) {
|
|
6876
6690
|
return logs(
|
|
6877
6691
|
{
|
|
6878
|
-
privateKey,
|
|
6879
6692
|
appID: opts.appID,
|
|
6880
6693
|
watch: opts.watch,
|
|
6881
|
-
environment: ctx.environment,
|
|
6882
6694
|
clientId: ctx.clientId
|
|
6883
6695
|
},
|
|
6696
|
+
walletClient,
|
|
6697
|
+
publicClient,
|
|
6698
|
+
environment,
|
|
6884
6699
|
logger,
|
|
6885
6700
|
skipTelemetry
|
|
6886
|
-
// Skip if called from CLI
|
|
6887
6701
|
);
|
|
6888
6702
|
},
|
|
6889
6703
|
async start(appId, opts) {
|
|
@@ -6896,15 +6710,15 @@ function createAppModule(ctx) {
|
|
|
6896
6710
|
},
|
|
6897
6711
|
async () => {
|
|
6898
6712
|
const pendingMessage = `Starting app ${appId}...`;
|
|
6899
|
-
const data = (0,
|
|
6713
|
+
const data = (0, import_viem6.encodeFunctionData)({
|
|
6900
6714
|
abi: CONTROLLER_ABI,
|
|
6901
6715
|
functionName: "startApp",
|
|
6902
6716
|
args: [appId]
|
|
6903
6717
|
});
|
|
6904
6718
|
const tx = await sendAndWaitForTransaction(
|
|
6905
6719
|
{
|
|
6906
|
-
|
|
6907
|
-
|
|
6720
|
+
walletClient,
|
|
6721
|
+
publicClient,
|
|
6908
6722
|
environmentConfig: environment,
|
|
6909
6723
|
to: environment.appControllerAddress,
|
|
6910
6724
|
data,
|
|
@@ -6928,15 +6742,15 @@ function createAppModule(ctx) {
|
|
|
6928
6742
|
},
|
|
6929
6743
|
async () => {
|
|
6930
6744
|
const pendingMessage = `Stopping app ${appId}...`;
|
|
6931
|
-
const data = (0,
|
|
6745
|
+
const data = (0, import_viem6.encodeFunctionData)({
|
|
6932
6746
|
abi: CONTROLLER_ABI,
|
|
6933
6747
|
functionName: "stopApp",
|
|
6934
6748
|
args: [appId]
|
|
6935
6749
|
});
|
|
6936
6750
|
const tx = await sendAndWaitForTransaction(
|
|
6937
6751
|
{
|
|
6938
|
-
|
|
6939
|
-
|
|
6752
|
+
walletClient,
|
|
6753
|
+
publicClient,
|
|
6940
6754
|
environmentConfig: environment,
|
|
6941
6755
|
to: environment.appControllerAddress,
|
|
6942
6756
|
data,
|
|
@@ -6960,15 +6774,15 @@ function createAppModule(ctx) {
|
|
|
6960
6774
|
},
|
|
6961
6775
|
async () => {
|
|
6962
6776
|
const pendingMessage = `Terminating app ${appId}...`;
|
|
6963
|
-
const data = (0,
|
|
6777
|
+
const data = (0, import_viem6.encodeFunctionData)({
|
|
6964
6778
|
abi: CONTROLLER_ABI,
|
|
6965
6779
|
functionName: "terminateApp",
|
|
6966
6780
|
args: [appId]
|
|
6967
6781
|
});
|
|
6968
6782
|
const tx = await sendAndWaitForTransaction(
|
|
6969
6783
|
{
|
|
6970
|
-
|
|
6971
|
-
|
|
6784
|
+
walletClient,
|
|
6785
|
+
publicClient,
|
|
6972
6786
|
environmentConfig: environment,
|
|
6973
6787
|
to: environment.appControllerAddress,
|
|
6974
6788
|
data,
|
|
@@ -6984,9 +6798,9 @@ function createAppModule(ctx) {
|
|
|
6984
6798
|
},
|
|
6985
6799
|
async isDelegated() {
|
|
6986
6800
|
return isDelegated({
|
|
6987
|
-
|
|
6988
|
-
|
|
6989
|
-
|
|
6801
|
+
publicClient,
|
|
6802
|
+
environmentConfig: environment,
|
|
6803
|
+
address: account.address
|
|
6990
6804
|
});
|
|
6991
6805
|
},
|
|
6992
6806
|
async undelegate() {
|
|
@@ -7000,8 +6814,8 @@ function createAppModule(ctx) {
|
|
|
7000
6814
|
async () => {
|
|
7001
6815
|
const tx = await undelegate(
|
|
7002
6816
|
{
|
|
7003
|
-
|
|
7004
|
-
|
|
6817
|
+
walletClient,
|
|
6818
|
+
publicClient,
|
|
7005
6819
|
environmentConfig: environment
|
|
7006
6820
|
},
|
|
7007
6821
|
logger
|