@layr-labs/ecloud-sdk 0.2.2-dev → 0.3.0-dev.0
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 +273 -4
- package/dist/billing.cjs.map +1 -1
- package/dist/billing.d.cts +1 -1
- package/dist/billing.d.ts +1 -1
- package/dist/billing.js +275 -4
- package/dist/billing.js.map +1 -1
- package/dist/browser.cjs +569 -173
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +53 -12
- package/dist/browser.d.ts +53 -12
- package/dist/browser.js +569 -173
- package/dist/browser.js.map +1 -1
- package/dist/{compute-BYhSs8en.d.ts → compute-BcJuIxc1.d.ts} +1 -1
- package/dist/{compute-Bpjb3hYD.d.cts → compute-oD9uqLtr.d.cts} +1 -1
- package/dist/compute.cjs +240 -154
- 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 +242 -154
- package/dist/compute.js.map +1 -1
- package/dist/{helpers-CQuBwQnu.d.ts → helpers-BNGcO-VX.d.cts} +249 -5
- package/dist/{helpers-CEvhJz7f.d.cts → helpers-Cp8qGRTb.d.ts} +249 -5
- package/dist/{index-DeQzn_yM.d.cts → index-5y9NG_Id.d.cts} +9 -1
- package/dist/{index-DeQzn_yM.d.ts → index-5y9NG_Id.d.ts} +9 -1
- package/dist/index.cjs +631 -214
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +633 -214
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,3 +1,137 @@
|
|
|
1
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
2
|
+
var __esm = (fn, res) => function __init() {
|
|
3
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
// src/client/common/auth/session.ts
|
|
7
|
+
function stripHexPrefix2(hex) {
|
|
8
|
+
return hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
9
|
+
}
|
|
10
|
+
async function parseErrorResponse(response) {
|
|
11
|
+
try {
|
|
12
|
+
const data = await response.json();
|
|
13
|
+
return data.error || response.statusText;
|
|
14
|
+
} catch {
|
|
15
|
+
return response.statusText;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
async function loginToComputeApi(config, request) {
|
|
19
|
+
let response;
|
|
20
|
+
try {
|
|
21
|
+
response = await fetch(`${config.baseUrl}/auth/siwe/login`, {
|
|
22
|
+
method: "POST",
|
|
23
|
+
credentials: "include",
|
|
24
|
+
// Include cookies for session management
|
|
25
|
+
headers: {
|
|
26
|
+
"Content-Type": "application/json"
|
|
27
|
+
},
|
|
28
|
+
body: JSON.stringify({
|
|
29
|
+
message: request.message,
|
|
30
|
+
signature: stripHexPrefix2(request.signature)
|
|
31
|
+
})
|
|
32
|
+
});
|
|
33
|
+
} catch (error) {
|
|
34
|
+
throw new SessionError(
|
|
35
|
+
`Network error connecting to ${config.baseUrl}: ${error instanceof Error ? error.message : String(error)}`,
|
|
36
|
+
"NETWORK_ERROR"
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
const errorMessage = await parseErrorResponse(response);
|
|
41
|
+
const status = response.status;
|
|
42
|
+
if (status === 400) {
|
|
43
|
+
if (errorMessage.toLowerCase().includes("siwe")) {
|
|
44
|
+
throw new SessionError(`Invalid SIWE message: ${errorMessage}`, "INVALID_MESSAGE", status);
|
|
45
|
+
}
|
|
46
|
+
throw new SessionError(`Bad request: ${errorMessage}`, "INVALID_MESSAGE", status);
|
|
47
|
+
}
|
|
48
|
+
if (status === 401) {
|
|
49
|
+
throw new SessionError(`Invalid signature: ${errorMessage}`, "INVALID_SIGNATURE", status);
|
|
50
|
+
}
|
|
51
|
+
throw new SessionError(`Login failed: ${errorMessage}`, "UNKNOWN", status);
|
|
52
|
+
}
|
|
53
|
+
const data = await response.json();
|
|
54
|
+
return {
|
|
55
|
+
success: data.success,
|
|
56
|
+
address: data.address
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
async function getComputeApiSession(config) {
|
|
60
|
+
let response;
|
|
61
|
+
try {
|
|
62
|
+
response = await fetch(`${config.baseUrl}/auth/session`, {
|
|
63
|
+
method: "GET",
|
|
64
|
+
credentials: "include",
|
|
65
|
+
// Include cookies for session management
|
|
66
|
+
headers: {
|
|
67
|
+
"Content-Type": "application/json"
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
} catch {
|
|
71
|
+
return {
|
|
72
|
+
authenticated: false
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (response.status === 401) {
|
|
76
|
+
return {
|
|
77
|
+
authenticated: false
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
if (!response.ok) {
|
|
81
|
+
const errorMessage = await parseErrorResponse(response);
|
|
82
|
+
throw new SessionError(`Failed to get session: ${errorMessage}`, "UNKNOWN", response.status);
|
|
83
|
+
}
|
|
84
|
+
const data = await response.json();
|
|
85
|
+
return {
|
|
86
|
+
authenticated: data.authenticated,
|
|
87
|
+
address: data.address,
|
|
88
|
+
chainId: data.chain_id
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
async function logoutFromComputeApi(config) {
|
|
92
|
+
let response;
|
|
93
|
+
try {
|
|
94
|
+
response = await fetch(`${config.baseUrl}/auth/logout`, {
|
|
95
|
+
method: "POST",
|
|
96
|
+
credentials: "include",
|
|
97
|
+
// Include cookies for session management
|
|
98
|
+
headers: {
|
|
99
|
+
"Content-Type": "application/json"
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
} catch (error) {
|
|
103
|
+
throw new SessionError(
|
|
104
|
+
`Network error connecting to ${config.baseUrl}: ${error instanceof Error ? error.message : String(error)}`,
|
|
105
|
+
"NETWORK_ERROR"
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
if (response.status === 401) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (!response.ok) {
|
|
112
|
+
const errorMessage = await parseErrorResponse(response);
|
|
113
|
+
throw new SessionError(`Logout failed: ${errorMessage}`, "UNKNOWN", response.status);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async function isSessionValid(config) {
|
|
117
|
+
const session = await getComputeApiSession(config);
|
|
118
|
+
return session.authenticated;
|
|
119
|
+
}
|
|
120
|
+
var SessionError;
|
|
121
|
+
var init_session = __esm({
|
|
122
|
+
"src/client/common/auth/session.ts"() {
|
|
123
|
+
"use strict";
|
|
124
|
+
SessionError = class extends Error {
|
|
125
|
+
constructor(message, code, statusCode) {
|
|
126
|
+
super(message);
|
|
127
|
+
this.code = code;
|
|
128
|
+
this.statusCode = statusCode;
|
|
129
|
+
this.name = "SessionError";
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
1
135
|
// src/client/modules/compute/app/index.ts
|
|
2
136
|
import { parseAbi as parseAbi2, encodeFunctionData as encodeFunctionData3 } from "viem";
|
|
3
137
|
|
|
@@ -2167,7 +2301,7 @@ function encodeExecuteBatchData(executions) {
|
|
|
2167
2301
|
});
|
|
2168
2302
|
}
|
|
2169
2303
|
async function estimateBatchGas(options) {
|
|
2170
|
-
const { publicClient, account, executions } = options;
|
|
2304
|
+
const { publicClient, account, executions, authorizationList } = options;
|
|
2171
2305
|
const executeBatchData = encodeExecuteBatchData(executions);
|
|
2172
2306
|
const [gasTipCap, block, estimatedGas] = await Promise.all([
|
|
2173
2307
|
publicClient.estimateMaxPriorityFeePerGas(),
|
|
@@ -2175,7 +2309,8 @@ async function estimateBatchGas(options) {
|
|
|
2175
2309
|
publicClient.estimateGas({
|
|
2176
2310
|
account,
|
|
2177
2311
|
to: account,
|
|
2178
|
-
data: executeBatchData
|
|
2312
|
+
data: executeBatchData,
|
|
2313
|
+
authorizationList
|
|
2179
2314
|
})
|
|
2180
2315
|
]);
|
|
2181
2316
|
const baseFee = block.baseFeePerGas ?? 0n;
|
|
@@ -2198,8 +2333,44 @@ async function checkERC7702Delegation(publicClient, account, delegatorAddress) {
|
|
|
2198
2333
|
const expectedCode = `0xef0100${delegatorAddress.slice(2)}`;
|
|
2199
2334
|
return code.toLowerCase() === expectedCode.toLowerCase();
|
|
2200
2335
|
}
|
|
2336
|
+
async function createAuthorizationList(options) {
|
|
2337
|
+
const { walletClient, publicClient, environmentConfig } = options;
|
|
2338
|
+
const account = walletClient.account;
|
|
2339
|
+
if (!account) {
|
|
2340
|
+
throw new Error("Wallet client must have an account");
|
|
2341
|
+
}
|
|
2342
|
+
const isDelegated2 = await checkERC7702Delegation(
|
|
2343
|
+
publicClient,
|
|
2344
|
+
account.address,
|
|
2345
|
+
environmentConfig.erc7702DelegatorAddress
|
|
2346
|
+
);
|
|
2347
|
+
if (isDelegated2) {
|
|
2348
|
+
return void 0;
|
|
2349
|
+
}
|
|
2350
|
+
const transactionNonce = await publicClient.getTransactionCount({
|
|
2351
|
+
address: account.address,
|
|
2352
|
+
blockTag: "pending"
|
|
2353
|
+
});
|
|
2354
|
+
const chainId = await publicClient.getChainId();
|
|
2355
|
+
const authorizationNonce = transactionNonce + 1;
|
|
2356
|
+
const signedAuthorization = await walletClient.signAuthorization({
|
|
2357
|
+
account,
|
|
2358
|
+
contractAddress: environmentConfig.erc7702DelegatorAddress,
|
|
2359
|
+
chainId,
|
|
2360
|
+
nonce: Number(authorizationNonce)
|
|
2361
|
+
});
|
|
2362
|
+
return [signedAuthorization];
|
|
2363
|
+
}
|
|
2201
2364
|
async function executeBatch(options, logger = noopLogger) {
|
|
2202
|
-
const {
|
|
2365
|
+
const {
|
|
2366
|
+
walletClient,
|
|
2367
|
+
publicClient,
|
|
2368
|
+
environmentConfig,
|
|
2369
|
+
executions,
|
|
2370
|
+
pendingMessage,
|
|
2371
|
+
gas,
|
|
2372
|
+
authorizationList: providedAuthList
|
|
2373
|
+
} = options;
|
|
2203
2374
|
const account = walletClient.account;
|
|
2204
2375
|
if (!account) {
|
|
2205
2376
|
throw new Error("Wallet client must have an account");
|
|
@@ -2209,27 +2380,29 @@ async function executeBatch(options, logger = noopLogger) {
|
|
|
2209
2380
|
throw new Error("Wallet client must have a chain");
|
|
2210
2381
|
}
|
|
2211
2382
|
const executeBatchData = encodeExecuteBatchData(executions);
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2383
|
+
let authorizationList = providedAuthList || [];
|
|
2384
|
+
if (authorizationList.length === 0) {
|
|
2385
|
+
const isDelegated2 = await checkERC7702Delegation(
|
|
2386
|
+
publicClient,
|
|
2387
|
+
account.address,
|
|
2388
|
+
environmentConfig.erc7702DelegatorAddress
|
|
2389
|
+
);
|
|
2390
|
+
if (!isDelegated2) {
|
|
2391
|
+
const transactionNonce = await publicClient.getTransactionCount({
|
|
2392
|
+
address: account.address,
|
|
2393
|
+
blockTag: "pending"
|
|
2394
|
+
});
|
|
2395
|
+
const chainId = await publicClient.getChainId();
|
|
2396
|
+
const authorizationNonce = transactionNonce + 1;
|
|
2397
|
+
logger.debug("Using wallet client signing for EIP-7702 authorization");
|
|
2398
|
+
const signedAuthorization = await walletClient.signAuthorization({
|
|
2399
|
+
account,
|
|
2400
|
+
contractAddress: environmentConfig.erc7702DelegatorAddress,
|
|
2401
|
+
chainId,
|
|
2402
|
+
nonce: Number(authorizationNonce)
|
|
2403
|
+
});
|
|
2404
|
+
authorizationList = [signedAuthorization];
|
|
2405
|
+
}
|
|
2233
2406
|
}
|
|
2234
2407
|
if (pendingMessage) {
|
|
2235
2408
|
logger.info(pendingMessage);
|
|
@@ -2244,6 +2417,9 @@ async function executeBatch(options, logger = noopLogger) {
|
|
|
2244
2417
|
if (authorizationList.length > 0) {
|
|
2245
2418
|
txRequest.authorizationList = authorizationList;
|
|
2246
2419
|
}
|
|
2420
|
+
if (gas?.gasLimit) {
|
|
2421
|
+
txRequest.gas = gas.gasLimit;
|
|
2422
|
+
}
|
|
2247
2423
|
if (gas?.maxFeePerGas) {
|
|
2248
2424
|
txRequest.maxFeePerGas = gas.maxFeePerGas;
|
|
2249
2425
|
}
|
|
@@ -3992,7 +4168,8 @@ async function executeDeployBatch(data, context, gas, logger = noopLogger) {
|
|
|
3992
4168
|
environmentConfig: context.environmentConfig,
|
|
3993
4169
|
executions: data.executions,
|
|
3994
4170
|
pendingMessage,
|
|
3995
|
-
gas
|
|
4171
|
+
gas,
|
|
4172
|
+
authorizationList: data.authorizationList
|
|
3996
4173
|
},
|
|
3997
4174
|
logger
|
|
3998
4175
|
);
|
|
@@ -4103,7 +4280,8 @@ async function executeUpgradeBatch(data, context, gas, logger = noopLogger) {
|
|
|
4103
4280
|
environmentConfig: context.environmentConfig,
|
|
4104
4281
|
executions: data.executions,
|
|
4105
4282
|
pendingMessage,
|
|
4106
|
-
gas
|
|
4283
|
+
gas,
|
|
4284
|
+
authorizationList: data.authorizationList
|
|
4107
4285
|
},
|
|
4108
4286
|
logger
|
|
4109
4287
|
);
|
|
@@ -4413,166 +4591,44 @@ async function calculateBillingAuthSignature(options) {
|
|
|
4413
4591
|
return { signature, expiry };
|
|
4414
4592
|
}
|
|
4415
4593
|
|
|
4416
|
-
// src/client/common/
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
this.code = code;
|
|
4421
|
-
this.statusCode = statusCode;
|
|
4422
|
-
this.name = "SessionError";
|
|
4423
|
-
}
|
|
4424
|
-
};
|
|
4425
|
-
function stripHexPrefix2(hex) {
|
|
4426
|
-
return hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
4594
|
+
// src/client/common/utils/userapi.ts
|
|
4595
|
+
init_session();
|
|
4596
|
+
function isJsonObject(value) {
|
|
4597
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4427
4598
|
}
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
return data.error || response.statusText;
|
|
4432
|
-
} catch {
|
|
4433
|
-
return response.statusText;
|
|
4434
|
-
}
|
|
4599
|
+
function readString(obj, key) {
|
|
4600
|
+
const v = obj[key];
|
|
4601
|
+
return typeof v === "string" ? v : void 0;
|
|
4435
4602
|
}
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
);
|
|
4603
|
+
function readNumber(obj, key) {
|
|
4604
|
+
const v = obj[key];
|
|
4605
|
+
return typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
4606
|
+
}
|
|
4607
|
+
var MAX_ADDRESS_COUNT = 5;
|
|
4608
|
+
var CanViewAppLogsPermission = "0x2fd3f2fe";
|
|
4609
|
+
var CanViewSensitiveAppInfoPermission = "0x0e67b22f";
|
|
4610
|
+
var CanUpdateAppProfilePermission = "0x036fef61";
|
|
4611
|
+
function getDefaultClientId() {
|
|
4612
|
+
const version = true ? "0.3.0-dev.0" : "0.0.0";
|
|
4613
|
+
return `ecloud-sdk/v${version}`;
|
|
4614
|
+
}
|
|
4615
|
+
var UserApiClient = class {
|
|
4616
|
+
constructor(config, walletClient, publicClient, options) {
|
|
4617
|
+
this.config = config;
|
|
4618
|
+
this.walletClient = walletClient;
|
|
4619
|
+
this.publicClient = publicClient;
|
|
4620
|
+
this.clientId = options?.clientId || getDefaultClientId();
|
|
4621
|
+
this.useSession = options?.useSession ?? false;
|
|
4456
4622
|
}
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
throw new SessionError(`Bad request: ${errorMessage}`, "INVALID_MESSAGE", status);
|
|
4465
|
-
}
|
|
4466
|
-
if (status === 401) {
|
|
4467
|
-
throw new SessionError(`Invalid signature: ${errorMessage}`, "INVALID_SIGNATURE", status);
|
|
4623
|
+
/**
|
|
4624
|
+
* Get the address of the connected wallet
|
|
4625
|
+
*/
|
|
4626
|
+
get address() {
|
|
4627
|
+
const account = this.walletClient.account;
|
|
4628
|
+
if (!account) {
|
|
4629
|
+
throw new Error("WalletClient must have an account attached");
|
|
4468
4630
|
}
|
|
4469
|
-
|
|
4470
|
-
}
|
|
4471
|
-
const data = await response.json();
|
|
4472
|
-
return {
|
|
4473
|
-
success: data.success,
|
|
4474
|
-
address: data.address
|
|
4475
|
-
};
|
|
4476
|
-
}
|
|
4477
|
-
async function getComputeApiSession(config) {
|
|
4478
|
-
let response;
|
|
4479
|
-
try {
|
|
4480
|
-
response = await fetch(`${config.baseUrl}/auth/session`, {
|
|
4481
|
-
method: "GET",
|
|
4482
|
-
credentials: "include",
|
|
4483
|
-
// Include cookies for session management
|
|
4484
|
-
headers: {
|
|
4485
|
-
"Content-Type": "application/json"
|
|
4486
|
-
}
|
|
4487
|
-
});
|
|
4488
|
-
} catch {
|
|
4489
|
-
return {
|
|
4490
|
-
authenticated: false
|
|
4491
|
-
};
|
|
4492
|
-
}
|
|
4493
|
-
if (response.status === 401) {
|
|
4494
|
-
return {
|
|
4495
|
-
authenticated: false
|
|
4496
|
-
};
|
|
4497
|
-
}
|
|
4498
|
-
if (!response.ok) {
|
|
4499
|
-
const errorMessage = await parseErrorResponse(response);
|
|
4500
|
-
throw new SessionError(`Failed to get session: ${errorMessage}`, "UNKNOWN", response.status);
|
|
4501
|
-
}
|
|
4502
|
-
const data = await response.json();
|
|
4503
|
-
return {
|
|
4504
|
-
authenticated: data.authenticated,
|
|
4505
|
-
address: data.address,
|
|
4506
|
-
chainId: data.chain_id
|
|
4507
|
-
};
|
|
4508
|
-
}
|
|
4509
|
-
async function logoutFromComputeApi(config) {
|
|
4510
|
-
let response;
|
|
4511
|
-
try {
|
|
4512
|
-
response = await fetch(`${config.baseUrl}/auth/logout`, {
|
|
4513
|
-
method: "POST",
|
|
4514
|
-
credentials: "include",
|
|
4515
|
-
// Include cookies for session management
|
|
4516
|
-
headers: {
|
|
4517
|
-
"Content-Type": "application/json"
|
|
4518
|
-
}
|
|
4519
|
-
});
|
|
4520
|
-
} catch (error) {
|
|
4521
|
-
throw new SessionError(
|
|
4522
|
-
`Network error connecting to ${config.baseUrl}: ${error instanceof Error ? error.message : String(error)}`,
|
|
4523
|
-
"NETWORK_ERROR"
|
|
4524
|
-
);
|
|
4525
|
-
}
|
|
4526
|
-
if (response.status === 401) {
|
|
4527
|
-
return;
|
|
4528
|
-
}
|
|
4529
|
-
if (!response.ok) {
|
|
4530
|
-
const errorMessage = await parseErrorResponse(response);
|
|
4531
|
-
throw new SessionError(`Logout failed: ${errorMessage}`, "UNKNOWN", response.status);
|
|
4532
|
-
}
|
|
4533
|
-
}
|
|
4534
|
-
async function isSessionValid(config) {
|
|
4535
|
-
const session = await getComputeApiSession(config);
|
|
4536
|
-
return session.authenticated;
|
|
4537
|
-
}
|
|
4538
|
-
|
|
4539
|
-
// src/client/common/utils/userapi.ts
|
|
4540
|
-
function isJsonObject(value) {
|
|
4541
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4542
|
-
}
|
|
4543
|
-
function readString(obj, key) {
|
|
4544
|
-
const v = obj[key];
|
|
4545
|
-
return typeof v === "string" ? v : void 0;
|
|
4546
|
-
}
|
|
4547
|
-
function readNumber(obj, key) {
|
|
4548
|
-
const v = obj[key];
|
|
4549
|
-
return typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
4550
|
-
}
|
|
4551
|
-
var MAX_ADDRESS_COUNT = 5;
|
|
4552
|
-
var CanViewAppLogsPermission = "0x2fd3f2fe";
|
|
4553
|
-
var CanViewSensitiveAppInfoPermission = "0x0e67b22f";
|
|
4554
|
-
var CanUpdateAppProfilePermission = "0x036fef61";
|
|
4555
|
-
function getDefaultClientId() {
|
|
4556
|
-
const version = true ? "0.2.2-dev" : "0.0.0";
|
|
4557
|
-
return `ecloud-sdk/v${version}`;
|
|
4558
|
-
}
|
|
4559
|
-
var UserApiClient = class {
|
|
4560
|
-
constructor(config, walletClient, publicClient, options) {
|
|
4561
|
-
this.config = config;
|
|
4562
|
-
this.walletClient = walletClient;
|
|
4563
|
-
this.publicClient = publicClient;
|
|
4564
|
-
this.clientId = options?.clientId || getDefaultClientId();
|
|
4565
|
-
this.useSession = options?.useSession ?? false;
|
|
4566
|
-
}
|
|
4567
|
-
/**
|
|
4568
|
-
* Get the address of the connected wallet
|
|
4569
|
-
*/
|
|
4570
|
-
get address() {
|
|
4571
|
-
const account = this.walletClient.account;
|
|
4572
|
-
if (!account) {
|
|
4573
|
-
throw new Error("WalletClient must have an account attached");
|
|
4574
|
-
}
|
|
4575
|
-
return account.address;
|
|
4631
|
+
return account.address;
|
|
4576
4632
|
}
|
|
4577
4633
|
async getInfos(appIDs, addressCount = 1) {
|
|
4578
4634
|
const count = Math.min(addressCount, MAX_ADDRESS_COUNT);
|
|
@@ -5461,21 +5517,214 @@ function isSubscriptionActive(status) {
|
|
|
5461
5517
|
|
|
5462
5518
|
// src/client/common/utils/billingapi.ts
|
|
5463
5519
|
import axios2 from "axios";
|
|
5520
|
+
|
|
5521
|
+
// src/client/common/auth/billingSession.ts
|
|
5522
|
+
var BillingSessionError = class extends Error {
|
|
5523
|
+
constructor(message, code, statusCode) {
|
|
5524
|
+
super(message);
|
|
5525
|
+
this.code = code;
|
|
5526
|
+
this.statusCode = statusCode;
|
|
5527
|
+
this.name = "BillingSessionError";
|
|
5528
|
+
}
|
|
5529
|
+
};
|
|
5530
|
+
function stripHexPrefix3(hex) {
|
|
5531
|
+
return hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
5532
|
+
}
|
|
5533
|
+
async function parseErrorResponse2(response) {
|
|
5534
|
+
try {
|
|
5535
|
+
const data = await response.json();
|
|
5536
|
+
return data.error || response.statusText;
|
|
5537
|
+
} catch {
|
|
5538
|
+
return response.statusText;
|
|
5539
|
+
}
|
|
5540
|
+
}
|
|
5541
|
+
async function loginToBillingApi(config, request) {
|
|
5542
|
+
let response;
|
|
5543
|
+
try {
|
|
5544
|
+
response = await fetch(`${config.baseUrl}/auth/siwe/login`, {
|
|
5545
|
+
method: "POST",
|
|
5546
|
+
credentials: "include",
|
|
5547
|
+
// Include cookies for session management
|
|
5548
|
+
headers: {
|
|
5549
|
+
"Content-Type": "application/json"
|
|
5550
|
+
},
|
|
5551
|
+
body: JSON.stringify({
|
|
5552
|
+
message: request.message,
|
|
5553
|
+
signature: stripHexPrefix3(request.signature)
|
|
5554
|
+
})
|
|
5555
|
+
});
|
|
5556
|
+
} catch (error) {
|
|
5557
|
+
throw new BillingSessionError(
|
|
5558
|
+
`Network error connecting to ${config.baseUrl}: ${error instanceof Error ? error.message : String(error)}`,
|
|
5559
|
+
"NETWORK_ERROR"
|
|
5560
|
+
);
|
|
5561
|
+
}
|
|
5562
|
+
if (!response.ok) {
|
|
5563
|
+
const errorMessage = await parseErrorResponse2(response);
|
|
5564
|
+
const status = response.status;
|
|
5565
|
+
if (status === 400) {
|
|
5566
|
+
if (errorMessage.toLowerCase().includes("siwe")) {
|
|
5567
|
+
throw new BillingSessionError(`Invalid SIWE message: ${errorMessage}`, "INVALID_MESSAGE", status);
|
|
5568
|
+
}
|
|
5569
|
+
throw new BillingSessionError(`Bad request: ${errorMessage}`, "INVALID_MESSAGE", status);
|
|
5570
|
+
}
|
|
5571
|
+
if (status === 401) {
|
|
5572
|
+
throw new BillingSessionError(`Invalid signature: ${errorMessage}`, "INVALID_SIGNATURE", status);
|
|
5573
|
+
}
|
|
5574
|
+
throw new BillingSessionError(`Login failed: ${errorMessage}`, "UNKNOWN", status);
|
|
5575
|
+
}
|
|
5576
|
+
const data = await response.json();
|
|
5577
|
+
return {
|
|
5578
|
+
success: data.success,
|
|
5579
|
+
address: data.address
|
|
5580
|
+
};
|
|
5581
|
+
}
|
|
5582
|
+
async function getBillingApiSession(config) {
|
|
5583
|
+
let response;
|
|
5584
|
+
try {
|
|
5585
|
+
response = await fetch(`${config.baseUrl}/auth/session`, {
|
|
5586
|
+
method: "GET",
|
|
5587
|
+
credentials: "include",
|
|
5588
|
+
// Include cookies for session management
|
|
5589
|
+
headers: {
|
|
5590
|
+
"Content-Type": "application/json"
|
|
5591
|
+
}
|
|
5592
|
+
});
|
|
5593
|
+
} catch {
|
|
5594
|
+
return {
|
|
5595
|
+
authenticated: false
|
|
5596
|
+
};
|
|
5597
|
+
}
|
|
5598
|
+
if (response.status === 401) {
|
|
5599
|
+
return {
|
|
5600
|
+
authenticated: false
|
|
5601
|
+
};
|
|
5602
|
+
}
|
|
5603
|
+
if (!response.ok) {
|
|
5604
|
+
const errorMessage = await parseErrorResponse2(response);
|
|
5605
|
+
throw new BillingSessionError(`Failed to get session: ${errorMessage}`, "UNKNOWN", response.status);
|
|
5606
|
+
}
|
|
5607
|
+
const data = await response.json();
|
|
5608
|
+
return {
|
|
5609
|
+
authenticated: data.authenticated,
|
|
5610
|
+
address: data.address,
|
|
5611
|
+
chainId: data.chainId,
|
|
5612
|
+
authenticatedAt: data.authenticatedAt
|
|
5613
|
+
};
|
|
5614
|
+
}
|
|
5615
|
+
async function logoutFromBillingApi(config) {
|
|
5616
|
+
let response;
|
|
5617
|
+
try {
|
|
5618
|
+
response = await fetch(`${config.baseUrl}/auth/logout`, {
|
|
5619
|
+
method: "POST",
|
|
5620
|
+
credentials: "include",
|
|
5621
|
+
// Include cookies for session management
|
|
5622
|
+
headers: {
|
|
5623
|
+
"Content-Type": "application/json"
|
|
5624
|
+
}
|
|
5625
|
+
});
|
|
5626
|
+
} catch (error) {
|
|
5627
|
+
throw new BillingSessionError(
|
|
5628
|
+
`Network error connecting to ${config.baseUrl}: ${error instanceof Error ? error.message : String(error)}`,
|
|
5629
|
+
"NETWORK_ERROR"
|
|
5630
|
+
);
|
|
5631
|
+
}
|
|
5632
|
+
if (response.status === 401) {
|
|
5633
|
+
return;
|
|
5634
|
+
}
|
|
5635
|
+
if (!response.ok) {
|
|
5636
|
+
const errorMessage = await parseErrorResponse2(response);
|
|
5637
|
+
throw new BillingSessionError(`Logout failed: ${errorMessage}`, "UNKNOWN", response.status);
|
|
5638
|
+
}
|
|
5639
|
+
}
|
|
5640
|
+
|
|
5641
|
+
// src/client/common/utils/billingapi.ts
|
|
5464
5642
|
var BillingApiClient = class {
|
|
5465
|
-
constructor(config, walletClient) {
|
|
5643
|
+
constructor(config, walletClient, options = {}) {
|
|
5466
5644
|
this.config = config;
|
|
5467
5645
|
this.walletClient = walletClient;
|
|
5646
|
+
this.options = options;
|
|
5647
|
+
this.useSession = options.useSession ?? false;
|
|
5648
|
+
if (!this.useSession && !walletClient) {
|
|
5649
|
+
throw new Error("WalletClient is required when not using session authentication");
|
|
5650
|
+
}
|
|
5468
5651
|
}
|
|
5469
5652
|
/**
|
|
5470
5653
|
* Get the address of the connected wallet
|
|
5654
|
+
* Returns undefined if using session auth without a wallet client
|
|
5471
5655
|
*/
|
|
5472
5656
|
get address() {
|
|
5473
|
-
const account = this.walletClient
|
|
5657
|
+
const account = this.walletClient?.account;
|
|
5474
5658
|
if (!account) {
|
|
5475
|
-
|
|
5659
|
+
if (!this.useSession) {
|
|
5660
|
+
throw new Error("WalletClient must have an account attached");
|
|
5661
|
+
}
|
|
5662
|
+
return void 0;
|
|
5476
5663
|
}
|
|
5477
5664
|
return account.address;
|
|
5478
5665
|
}
|
|
5666
|
+
/**
|
|
5667
|
+
* Get the base URL of the billing API
|
|
5668
|
+
*/
|
|
5669
|
+
get baseUrl() {
|
|
5670
|
+
return this.config.billingApiServerURL;
|
|
5671
|
+
}
|
|
5672
|
+
// ==========================================================================
|
|
5673
|
+
// SIWE Session Methods
|
|
5674
|
+
// ==========================================================================
|
|
5675
|
+
/**
|
|
5676
|
+
* Login to the billing API using SIWE
|
|
5677
|
+
*
|
|
5678
|
+
* This establishes a session with the billing API by verifying the SIWE message
|
|
5679
|
+
* and signature. On success, a session cookie is set in the browser.
|
|
5680
|
+
*
|
|
5681
|
+
* @param request - Login request containing SIWE message and signature
|
|
5682
|
+
* @returns Login result with the authenticated address
|
|
5683
|
+
*
|
|
5684
|
+
* @example
|
|
5685
|
+
* ```typescript
|
|
5686
|
+
* const { message } = createSiweMessage({
|
|
5687
|
+
* address: userAddress,
|
|
5688
|
+
* chainId: 11155111,
|
|
5689
|
+
* domain: window.location.host,
|
|
5690
|
+
* uri: window.location.origin,
|
|
5691
|
+
* });
|
|
5692
|
+
*
|
|
5693
|
+
* const signature = await signMessageAsync({ message });
|
|
5694
|
+
* const result = await billingClient.siweLogin({ message, signature });
|
|
5695
|
+
* ```
|
|
5696
|
+
*/
|
|
5697
|
+
async siweLogin(request) {
|
|
5698
|
+
return loginToBillingApi({ baseUrl: this.baseUrl }, request);
|
|
5699
|
+
}
|
|
5700
|
+
/**
|
|
5701
|
+
* Logout from the billing API
|
|
5702
|
+
*
|
|
5703
|
+
* This destroys the current session and clears the session cookie.
|
|
5704
|
+
*/
|
|
5705
|
+
async siweLogout() {
|
|
5706
|
+
return logoutFromBillingApi({ baseUrl: this.baseUrl });
|
|
5707
|
+
}
|
|
5708
|
+
/**
|
|
5709
|
+
* Get the current session status from the billing API
|
|
5710
|
+
*
|
|
5711
|
+
* @returns Session information including authentication status and address
|
|
5712
|
+
*/
|
|
5713
|
+
async getSession() {
|
|
5714
|
+
return getBillingApiSession({ baseUrl: this.baseUrl });
|
|
5715
|
+
}
|
|
5716
|
+
/**
|
|
5717
|
+
* Check if there is a valid session
|
|
5718
|
+
*
|
|
5719
|
+
* @returns True if session is authenticated, false otherwise
|
|
5720
|
+
*/
|
|
5721
|
+
async isSessionValid() {
|
|
5722
|
+
const session = await this.getSession();
|
|
5723
|
+
return session.authenticated;
|
|
5724
|
+
}
|
|
5725
|
+
// ==========================================================================
|
|
5726
|
+
// Subscription Methods
|
|
5727
|
+
// ==========================================================================
|
|
5479
5728
|
async createSubscription(productId = "compute", options) {
|
|
5480
5729
|
const endpoint = `${this.config.billingApiServerURL}/products/${productId}/subscription`;
|
|
5481
5730
|
const body = options ? {
|
|
@@ -5494,10 +5743,72 @@ var BillingApiClient = class {
|
|
|
5494
5743
|
const endpoint = `${this.config.billingApiServerURL}/products/${productId}/subscription`;
|
|
5495
5744
|
await this.makeAuthenticatedRequest(endpoint, "DELETE", productId);
|
|
5496
5745
|
}
|
|
5746
|
+
// ==========================================================================
|
|
5747
|
+
// Internal Methods
|
|
5748
|
+
// ==========================================================================
|
|
5497
5749
|
/**
|
|
5498
5750
|
* Make an authenticated request to the billing API
|
|
5751
|
+
*
|
|
5752
|
+
* Uses session auth if useSession is true, otherwise uses EIP-712 signature auth.
|
|
5499
5753
|
*/
|
|
5500
5754
|
async makeAuthenticatedRequest(url, method, productId, body) {
|
|
5755
|
+
if (this.useSession) {
|
|
5756
|
+
return this.makeSessionAuthenticatedRequest(url, method, body);
|
|
5757
|
+
}
|
|
5758
|
+
return this.makeSignatureAuthenticatedRequest(url, method, productId, body);
|
|
5759
|
+
}
|
|
5760
|
+
/**
|
|
5761
|
+
* Make a request using session-based authentication (cookies)
|
|
5762
|
+
*/
|
|
5763
|
+
async makeSessionAuthenticatedRequest(url, method, body) {
|
|
5764
|
+
const headers = {};
|
|
5765
|
+
if (body) {
|
|
5766
|
+
headers["Content-Type"] = "application/json";
|
|
5767
|
+
}
|
|
5768
|
+
try {
|
|
5769
|
+
const response = await fetch(url, {
|
|
5770
|
+
method,
|
|
5771
|
+
credentials: "include",
|
|
5772
|
+
// Include cookies for session management
|
|
5773
|
+
headers,
|
|
5774
|
+
body: body ? JSON.stringify(body) : void 0
|
|
5775
|
+
});
|
|
5776
|
+
const status = response.status;
|
|
5777
|
+
const statusText = status >= 200 && status < 300 ? "OK" : "Error";
|
|
5778
|
+
if (status < 200 || status >= 300) {
|
|
5779
|
+
let errorBody;
|
|
5780
|
+
try {
|
|
5781
|
+
errorBody = await response.text();
|
|
5782
|
+
} catch {
|
|
5783
|
+
errorBody = statusText;
|
|
5784
|
+
}
|
|
5785
|
+
throw new Error(`BillingAPI request failed: ${status} ${statusText} - ${errorBody}`);
|
|
5786
|
+
}
|
|
5787
|
+
const responseData = await response.json();
|
|
5788
|
+
return {
|
|
5789
|
+
json: async () => responseData,
|
|
5790
|
+
text: async () => JSON.stringify(responseData)
|
|
5791
|
+
};
|
|
5792
|
+
} catch (error) {
|
|
5793
|
+
if (error.name === "TypeError" || error.message?.includes("fetch")) {
|
|
5794
|
+
throw new Error(
|
|
5795
|
+
`Failed to connect to BillingAPI at ${url}: ${error.message}
|
|
5796
|
+
Please check:
|
|
5797
|
+
1. Your internet connection
|
|
5798
|
+
2. The API server is accessible: ${this.config.billingApiServerURL}
|
|
5799
|
+
3. Firewall/proxy settings`
|
|
5800
|
+
);
|
|
5801
|
+
}
|
|
5802
|
+
throw error;
|
|
5803
|
+
}
|
|
5804
|
+
}
|
|
5805
|
+
/**
|
|
5806
|
+
* Make a request using EIP-712 signature authentication
|
|
5807
|
+
*/
|
|
5808
|
+
async makeSignatureAuthenticatedRequest(url, method, productId, body) {
|
|
5809
|
+
if (!this.walletClient) {
|
|
5810
|
+
throw new Error("WalletClient is required for signature authentication");
|
|
5811
|
+
}
|
|
5501
5812
|
const expiry = BigInt(Math.floor(Date.now() / 1e3) + 5 * 60);
|
|
5502
5813
|
const { signature } = await calculateBillingAuthSignature({
|
|
5503
5814
|
walletClient: this.walletClient,
|
|
@@ -5817,16 +6128,24 @@ async function prepareDeployFromVerifiableBuild(options, logger = defaultLogger)
|
|
|
5817
6128
|
},
|
|
5818
6129
|
logger
|
|
5819
6130
|
);
|
|
6131
|
+
logger.debug("Checking delegation status...");
|
|
6132
|
+
const authorizationList = await createAuthorizationList({
|
|
6133
|
+
walletClient: batch.walletClient,
|
|
6134
|
+
publicClient: batch.publicClient,
|
|
6135
|
+
environmentConfig: batch.environmentConfig
|
|
6136
|
+
});
|
|
5820
6137
|
logger.debug("Estimating gas...");
|
|
5821
6138
|
const gasEstimate = await estimateBatchGas({
|
|
5822
6139
|
publicClient: batch.publicClient,
|
|
5823
6140
|
account: batch.walletClient.account.address,
|
|
5824
|
-
executions: batch.executions
|
|
6141
|
+
executions: batch.executions,
|
|
6142
|
+
authorizationList
|
|
5825
6143
|
});
|
|
5826
6144
|
const data = {
|
|
5827
6145
|
appId: batch.appId,
|
|
5828
6146
|
salt: batch.salt,
|
|
5829
|
-
executions: batch.executions
|
|
6147
|
+
executions: batch.executions,
|
|
6148
|
+
authorizationList
|
|
5830
6149
|
};
|
|
5831
6150
|
return {
|
|
5832
6151
|
prepared: {
|
|
@@ -6055,16 +6374,24 @@ async function prepareDeploy(options, logger = defaultLogger) {
|
|
|
6055
6374
|
},
|
|
6056
6375
|
logger
|
|
6057
6376
|
);
|
|
6377
|
+
logger.debug("Checking delegation status...");
|
|
6378
|
+
const authorizationList = await createAuthorizationList({
|
|
6379
|
+
walletClient: batch.walletClient,
|
|
6380
|
+
publicClient: batch.publicClient,
|
|
6381
|
+
environmentConfig: batch.environmentConfig
|
|
6382
|
+
});
|
|
6058
6383
|
logger.debug("Estimating gas...");
|
|
6059
6384
|
const gasEstimate = await estimateBatchGas({
|
|
6060
6385
|
publicClient: batch.publicClient,
|
|
6061
6386
|
account: batch.walletClient.account.address,
|
|
6062
|
-
executions: batch.executions
|
|
6387
|
+
executions: batch.executions,
|
|
6388
|
+
authorizationList
|
|
6063
6389
|
});
|
|
6064
6390
|
const data = {
|
|
6065
6391
|
appId: batch.appId,
|
|
6066
6392
|
salt: batch.salt,
|
|
6067
|
-
executions: batch.executions
|
|
6393
|
+
executions: batch.executions,
|
|
6394
|
+
authorizationList
|
|
6068
6395
|
};
|
|
6069
6396
|
return {
|
|
6070
6397
|
prepared: {
|
|
@@ -6195,15 +6522,23 @@ async function prepareUpgradeFromVerifiableBuild(options, logger = defaultLogger
|
|
|
6195
6522
|
needsPermissionChange,
|
|
6196
6523
|
imageRef: options.imageRef
|
|
6197
6524
|
});
|
|
6525
|
+
logger.debug("Checking delegation status...");
|
|
6526
|
+
const authorizationList = await createAuthorizationList({
|
|
6527
|
+
walletClient: batch.walletClient,
|
|
6528
|
+
publicClient: batch.publicClient,
|
|
6529
|
+
environmentConfig: batch.environmentConfig
|
|
6530
|
+
});
|
|
6198
6531
|
logger.debug("Estimating gas...");
|
|
6199
6532
|
const gasEstimate = await estimateBatchGas({
|
|
6200
6533
|
publicClient: batch.publicClient,
|
|
6201
6534
|
account: batch.walletClient.account.address,
|
|
6202
|
-
executions: batch.executions
|
|
6535
|
+
executions: batch.executions,
|
|
6536
|
+
authorizationList
|
|
6203
6537
|
});
|
|
6204
6538
|
const data = {
|
|
6205
6539
|
appId: batch.appId,
|
|
6206
|
-
executions: batch.executions
|
|
6540
|
+
executions: batch.executions,
|
|
6541
|
+
authorizationList
|
|
6207
6542
|
};
|
|
6208
6543
|
return {
|
|
6209
6544
|
prepared: {
|
|
@@ -6376,15 +6711,23 @@ async function prepareUpgrade(options, logger = defaultLogger) {
|
|
|
6376
6711
|
needsPermissionChange,
|
|
6377
6712
|
imageRef: finalImageRef
|
|
6378
6713
|
});
|
|
6714
|
+
logger.debug("Checking delegation status...");
|
|
6715
|
+
const authorizationList = await createAuthorizationList({
|
|
6716
|
+
walletClient: batch.walletClient,
|
|
6717
|
+
publicClient: batch.publicClient,
|
|
6718
|
+
environmentConfig: batch.environmentConfig
|
|
6719
|
+
});
|
|
6379
6720
|
logger.debug("Estimating gas...");
|
|
6380
6721
|
const gasEstimate = await estimateBatchGas({
|
|
6381
6722
|
publicClient: batch.publicClient,
|
|
6382
6723
|
account: batch.walletClient.account.address,
|
|
6383
|
-
executions: batch.executions
|
|
6724
|
+
executions: batch.executions,
|
|
6725
|
+
authorizationList
|
|
6384
6726
|
});
|
|
6385
6727
|
const data = {
|
|
6386
6728
|
appId: batch.appId,
|
|
6387
|
-
executions: batch.executions
|
|
6729
|
+
executions: batch.executions,
|
|
6730
|
+
authorizationList
|
|
6388
6731
|
};
|
|
6389
6732
|
return {
|
|
6390
6733
|
prepared: {
|
|
@@ -7512,7 +7855,10 @@ function createBillingModule(config) {
|
|
|
7512
7855
|
};
|
|
7513
7856
|
}
|
|
7514
7857
|
logger.debug(`Creating subscription for ${productId}...`);
|
|
7515
|
-
const result = await billingApi.createSubscription(productId
|
|
7858
|
+
const result = await billingApi.createSubscription(productId, {
|
|
7859
|
+
successUrl: opts?.successUrl,
|
|
7860
|
+
cancelUrl: opts?.cancelUrl
|
|
7861
|
+
});
|
|
7516
7862
|
logger.debug(`Checkout URL: ${result.checkoutUrl}`);
|
|
7517
7863
|
return {
|
|
7518
7864
|
type: "checkout_created",
|
|
@@ -7604,9 +7950,22 @@ async function requestWithRetry(config) {
|
|
|
7604
7950
|
}
|
|
7605
7951
|
var BuildApiClient = class {
|
|
7606
7952
|
constructor(options) {
|
|
7607
|
-
|
|
7953
|
+
let url = options.baseUrl;
|
|
7954
|
+
while (url.endsWith("/")) {
|
|
7955
|
+
url = url.slice(0, -1);
|
|
7956
|
+
}
|
|
7957
|
+
this.baseUrl = url;
|
|
7608
7958
|
this.clientId = options.clientId;
|
|
7609
7959
|
this.walletClient = options.walletClient;
|
|
7960
|
+
this.useSession = options.useSession ?? false;
|
|
7961
|
+
this.billingSessionId = options.billingSessionId;
|
|
7962
|
+
}
|
|
7963
|
+
/**
|
|
7964
|
+
* Update the billing session ID.
|
|
7965
|
+
* Call this after logging into the billing API to enable session-based auth for builds.
|
|
7966
|
+
*/
|
|
7967
|
+
setBillingSessionId(sessionId) {
|
|
7968
|
+
this.billingSessionId = sessionId;
|
|
7610
7969
|
}
|
|
7611
7970
|
/**
|
|
7612
7971
|
* Get the address of the connected wallet
|
|
@@ -7618,8 +7977,17 @@ var BuildApiClient = class {
|
|
|
7618
7977
|
}
|
|
7619
7978
|
return account.address;
|
|
7620
7979
|
}
|
|
7980
|
+
/**
|
|
7981
|
+
* Submit a new build request.
|
|
7982
|
+
* Supports two auth modes (session auth is tried first when billingSessionId is available):
|
|
7983
|
+
* 1. Session-based auth: X-Billing-Session header (forwarded billing_session cookie)
|
|
7984
|
+
* 2. Signature-based auth: Authorization + X-Account + X-eigenx-expiry headers (requires walletClient)
|
|
7985
|
+
*/
|
|
7621
7986
|
async submitBuild(payload) {
|
|
7622
|
-
|
|
7987
|
+
if (this.useSession && this.billingSessionId) {
|
|
7988
|
+
return this.billingSessionAuthJsonRequest("/builds", "POST", payload);
|
|
7989
|
+
}
|
|
7990
|
+
return this.signatureAuthJsonRequest("/builds", "POST", payload);
|
|
7623
7991
|
}
|
|
7624
7992
|
async getBuild(buildId) {
|
|
7625
7993
|
return this.publicJsonRequest(`/builds/${encodeURIComponent(buildId)}`);
|
|
@@ -7630,8 +7998,11 @@ var BuildApiClient = class {
|
|
|
7630
7998
|
async verify(identifier) {
|
|
7631
7999
|
return this.publicJsonRequest(`/builds/verify/${encodeURIComponent(identifier)}`);
|
|
7632
8000
|
}
|
|
8001
|
+
/**
|
|
8002
|
+
* Get build logs. Supports session auth (identity verification only, no billing check).
|
|
8003
|
+
*/
|
|
7633
8004
|
async getLogs(buildId) {
|
|
7634
|
-
return this.
|
|
8005
|
+
return this.sessionOrSignatureTextRequest(`/builds/${encodeURIComponent(buildId)}/logs`);
|
|
7635
8006
|
}
|
|
7636
8007
|
async listBuilds(params) {
|
|
7637
8008
|
const res = await requestWithRetry({
|
|
@@ -7639,7 +8010,9 @@ var BuildApiClient = class {
|
|
|
7639
8010
|
method: "GET",
|
|
7640
8011
|
params,
|
|
7641
8012
|
headers: this.clientId ? { "x-client-id": this.clientId } : void 0,
|
|
7642
|
-
timeout: 6e4
|
|
8013
|
+
timeout: 6e4,
|
|
8014
|
+
validateStatus: () => true,
|
|
8015
|
+
withCredentials: this.useSession
|
|
7643
8016
|
});
|
|
7644
8017
|
if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
|
|
7645
8018
|
return res.data;
|
|
@@ -7649,12 +8022,18 @@ var BuildApiClient = class {
|
|
|
7649
8022
|
url: `${this.baseUrl}${path8}`,
|
|
7650
8023
|
method: "GET",
|
|
7651
8024
|
headers: this.clientId ? { "x-client-id": this.clientId } : void 0,
|
|
7652
|
-
timeout: 6e4
|
|
8025
|
+
timeout: 6e4,
|
|
8026
|
+
validateStatus: () => true,
|
|
8027
|
+
withCredentials: this.useSession
|
|
7653
8028
|
});
|
|
7654
8029
|
if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
|
|
7655
8030
|
return res.data;
|
|
7656
8031
|
}
|
|
7657
|
-
|
|
8032
|
+
/**
|
|
8033
|
+
* Make a request that ALWAYS requires signature auth (for billing verification).
|
|
8034
|
+
* Used for endpoints like POST /builds that need to verify subscription status.
|
|
8035
|
+
*/
|
|
8036
|
+
async signatureAuthJsonRequest(path8, method, body) {
|
|
7658
8037
|
if (!this.walletClient?.account) {
|
|
7659
8038
|
throw new Error("WalletClient with account required for authenticated requests");
|
|
7660
8039
|
}
|
|
@@ -7676,32 +8055,69 @@ var BuildApiClient = class {
|
|
|
7676
8055
|
method,
|
|
7677
8056
|
headers,
|
|
7678
8057
|
data: body,
|
|
7679
|
-
timeout: 6e4
|
|
8058
|
+
timeout: 6e4,
|
|
8059
|
+
validateStatus: () => true,
|
|
8060
|
+
withCredentials: this.useSession
|
|
7680
8061
|
});
|
|
7681
8062
|
if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
|
|
7682
8063
|
return res.data;
|
|
7683
8064
|
}
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
|
|
8065
|
+
/**
|
|
8066
|
+
* Make a request using billing session auth (for billing verification without wallet signature).
|
|
8067
|
+
* Forwards the billing_session cookie value via X-Billing-Session header.
|
|
8068
|
+
* Used for endpoints that need to verify subscription status when using session-based auth.
|
|
8069
|
+
*/
|
|
8070
|
+
async billingSessionAuthJsonRequest(path8, method, body) {
|
|
8071
|
+
if (!this.billingSessionId) {
|
|
8072
|
+
throw new Error("billingSessionId required for session-based billing auth");
|
|
7687
8073
|
}
|
|
7688
|
-
const headers = {
|
|
8074
|
+
const headers = {
|
|
8075
|
+
"Content-Type": "application/json",
|
|
8076
|
+
"X-Billing-Session": this.billingSessionId
|
|
8077
|
+
};
|
|
7689
8078
|
if (this.clientId) headers["x-client-id"] = this.clientId;
|
|
7690
|
-
const
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
|
|
8079
|
+
const res = await requestWithRetry({
|
|
8080
|
+
url: `${this.baseUrl}${path8}`,
|
|
8081
|
+
method,
|
|
8082
|
+
headers,
|
|
8083
|
+
data: body,
|
|
8084
|
+
timeout: 6e4,
|
|
8085
|
+
validateStatus: () => true,
|
|
8086
|
+
withCredentials: this.useSession
|
|
7695
8087
|
});
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
|
|
8088
|
+
if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
|
|
8089
|
+
return res.data;
|
|
8090
|
+
}
|
|
8091
|
+
/**
|
|
8092
|
+
* Make an authenticated request that can use session OR signature auth.
|
|
8093
|
+
* When useSession is true, relies on cookies for identity verification.
|
|
8094
|
+
* Used for endpoints that only need identity verification (not billing).
|
|
8095
|
+
*/
|
|
8096
|
+
async sessionOrSignatureTextRequest(path8) {
|
|
8097
|
+
const headers = {};
|
|
8098
|
+
if (this.clientId) headers["x-client-id"] = this.clientId;
|
|
8099
|
+
if (!this.useSession) {
|
|
8100
|
+
if (!this.walletClient?.account) {
|
|
8101
|
+
throw new Error("WalletClient with account required for authenticated requests");
|
|
8102
|
+
}
|
|
8103
|
+
const expiry = BigInt(Math.floor(Date.now() / 1e3) + 60);
|
|
8104
|
+
const { signature } = await calculateBillingAuthSignature({
|
|
8105
|
+
walletClient: this.walletClient,
|
|
8106
|
+
product: "compute",
|
|
8107
|
+
expiry
|
|
8108
|
+
});
|
|
8109
|
+
headers.Authorization = `Bearer ${signature}`;
|
|
8110
|
+
headers["X-eigenx-expiry"] = expiry.toString();
|
|
8111
|
+
headers["X-Account"] = this.address;
|
|
8112
|
+
}
|
|
7699
8113
|
const res = await requestWithRetry({
|
|
7700
8114
|
url: `${this.baseUrl}${path8}`,
|
|
7701
8115
|
method: "GET",
|
|
7702
8116
|
headers,
|
|
7703
8117
|
timeout: 6e4,
|
|
7704
|
-
responseType: "text"
|
|
8118
|
+
responseType: "text",
|
|
8119
|
+
validateStatus: () => true,
|
|
8120
|
+
withCredentials: this.useSession
|
|
7705
8121
|
});
|
|
7706
8122
|
if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
|
|
7707
8123
|
return typeof res.data === "string" ? res.data : JSON.stringify(res.data);
|
|
@@ -8268,6 +8684,9 @@ function isSiweMessageNotYetValid(params) {
|
|
|
8268
8684
|
return /* @__PURE__ */ new Date() < params.notBefore;
|
|
8269
8685
|
}
|
|
8270
8686
|
|
|
8687
|
+
// src/client/common/auth/index.ts
|
|
8688
|
+
init_session();
|
|
8689
|
+
|
|
8271
8690
|
// src/client/common/utils/instance.ts
|
|
8272
8691
|
async function getCurrentInstanceType(preflightCtx, appID, logger, clientId) {
|
|
8273
8692
|
try {
|