@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.cjs
CHANGED
|
@@ -5,6 +5,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esm = (fn, res) => function __init() {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
};
|
|
8
11
|
var __export = (target, all) => {
|
|
9
12
|
for (var name in all)
|
|
10
13
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -27,6 +30,135 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
30
|
));
|
|
28
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
32
|
|
|
33
|
+
// src/client/common/auth/session.ts
|
|
34
|
+
function stripHexPrefix2(hex) {
|
|
35
|
+
return hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
36
|
+
}
|
|
37
|
+
async function parseErrorResponse(response) {
|
|
38
|
+
try {
|
|
39
|
+
const data = await response.json();
|
|
40
|
+
return data.error || response.statusText;
|
|
41
|
+
} catch {
|
|
42
|
+
return response.statusText;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async function loginToComputeApi(config, request) {
|
|
46
|
+
let response;
|
|
47
|
+
try {
|
|
48
|
+
response = await fetch(`${config.baseUrl}/auth/siwe/login`, {
|
|
49
|
+
method: "POST",
|
|
50
|
+
credentials: "include",
|
|
51
|
+
// Include cookies for session management
|
|
52
|
+
headers: {
|
|
53
|
+
"Content-Type": "application/json"
|
|
54
|
+
},
|
|
55
|
+
body: JSON.stringify({
|
|
56
|
+
message: request.message,
|
|
57
|
+
signature: stripHexPrefix2(request.signature)
|
|
58
|
+
})
|
|
59
|
+
});
|
|
60
|
+
} catch (error) {
|
|
61
|
+
throw new SessionError(
|
|
62
|
+
`Network error connecting to ${config.baseUrl}: ${error instanceof Error ? error.message : String(error)}`,
|
|
63
|
+
"NETWORK_ERROR"
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
const errorMessage = await parseErrorResponse(response);
|
|
68
|
+
const status = response.status;
|
|
69
|
+
if (status === 400) {
|
|
70
|
+
if (errorMessage.toLowerCase().includes("siwe")) {
|
|
71
|
+
throw new SessionError(`Invalid SIWE message: ${errorMessage}`, "INVALID_MESSAGE", status);
|
|
72
|
+
}
|
|
73
|
+
throw new SessionError(`Bad request: ${errorMessage}`, "INVALID_MESSAGE", status);
|
|
74
|
+
}
|
|
75
|
+
if (status === 401) {
|
|
76
|
+
throw new SessionError(`Invalid signature: ${errorMessage}`, "INVALID_SIGNATURE", status);
|
|
77
|
+
}
|
|
78
|
+
throw new SessionError(`Login failed: ${errorMessage}`, "UNKNOWN", status);
|
|
79
|
+
}
|
|
80
|
+
const data = await response.json();
|
|
81
|
+
return {
|
|
82
|
+
success: data.success,
|
|
83
|
+
address: data.address
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
async function getComputeApiSession(config) {
|
|
87
|
+
let response;
|
|
88
|
+
try {
|
|
89
|
+
response = await fetch(`${config.baseUrl}/auth/session`, {
|
|
90
|
+
method: "GET",
|
|
91
|
+
credentials: "include",
|
|
92
|
+
// Include cookies for session management
|
|
93
|
+
headers: {
|
|
94
|
+
"Content-Type": "application/json"
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
} catch {
|
|
98
|
+
return {
|
|
99
|
+
authenticated: false
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
if (response.status === 401) {
|
|
103
|
+
return {
|
|
104
|
+
authenticated: false
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
if (!response.ok) {
|
|
108
|
+
const errorMessage = await parseErrorResponse(response);
|
|
109
|
+
throw new SessionError(`Failed to get session: ${errorMessage}`, "UNKNOWN", response.status);
|
|
110
|
+
}
|
|
111
|
+
const data = await response.json();
|
|
112
|
+
return {
|
|
113
|
+
authenticated: data.authenticated,
|
|
114
|
+
address: data.address,
|
|
115
|
+
chainId: data.chain_id
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
async function logoutFromComputeApi(config) {
|
|
119
|
+
let response;
|
|
120
|
+
try {
|
|
121
|
+
response = await fetch(`${config.baseUrl}/auth/logout`, {
|
|
122
|
+
method: "POST",
|
|
123
|
+
credentials: "include",
|
|
124
|
+
// Include cookies for session management
|
|
125
|
+
headers: {
|
|
126
|
+
"Content-Type": "application/json"
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
} catch (error) {
|
|
130
|
+
throw new SessionError(
|
|
131
|
+
`Network error connecting to ${config.baseUrl}: ${error instanceof Error ? error.message : String(error)}`,
|
|
132
|
+
"NETWORK_ERROR"
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
if (response.status === 401) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (!response.ok) {
|
|
139
|
+
const errorMessage = await parseErrorResponse(response);
|
|
140
|
+
throw new SessionError(`Logout failed: ${errorMessage}`, "UNKNOWN", response.status);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
async function isSessionValid(config) {
|
|
144
|
+
const session = await getComputeApiSession(config);
|
|
145
|
+
return session.authenticated;
|
|
146
|
+
}
|
|
147
|
+
var SessionError;
|
|
148
|
+
var init_session = __esm({
|
|
149
|
+
"src/client/common/auth/session.ts"() {
|
|
150
|
+
"use strict";
|
|
151
|
+
SessionError = class extends Error {
|
|
152
|
+
constructor(message, code, statusCode) {
|
|
153
|
+
super(message);
|
|
154
|
+
this.code = code;
|
|
155
|
+
this.statusCode = statusCode;
|
|
156
|
+
this.name = "SessionError";
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
|
|
30
162
|
// src/index.ts
|
|
31
163
|
var index_exports = {};
|
|
32
164
|
__export(index_exports, {
|
|
@@ -2314,7 +2446,7 @@ function encodeExecuteBatchData(executions) {
|
|
|
2314
2446
|
});
|
|
2315
2447
|
}
|
|
2316
2448
|
async function estimateBatchGas(options) {
|
|
2317
|
-
const { publicClient, account, executions } = options;
|
|
2449
|
+
const { publicClient, account, executions, authorizationList } = options;
|
|
2318
2450
|
const executeBatchData = encodeExecuteBatchData(executions);
|
|
2319
2451
|
const [gasTipCap, block, estimatedGas] = await Promise.all([
|
|
2320
2452
|
publicClient.estimateMaxPriorityFeePerGas(),
|
|
@@ -2322,7 +2454,8 @@ async function estimateBatchGas(options) {
|
|
|
2322
2454
|
publicClient.estimateGas({
|
|
2323
2455
|
account,
|
|
2324
2456
|
to: account,
|
|
2325
|
-
data: executeBatchData
|
|
2457
|
+
data: executeBatchData,
|
|
2458
|
+
authorizationList
|
|
2326
2459
|
})
|
|
2327
2460
|
]);
|
|
2328
2461
|
const baseFee = block.baseFeePerGas ?? 0n;
|
|
@@ -2345,8 +2478,44 @@ async function checkERC7702Delegation(publicClient, account, delegatorAddress) {
|
|
|
2345
2478
|
const expectedCode = `0xef0100${delegatorAddress.slice(2)}`;
|
|
2346
2479
|
return code.toLowerCase() === expectedCode.toLowerCase();
|
|
2347
2480
|
}
|
|
2481
|
+
async function createAuthorizationList(options) {
|
|
2482
|
+
const { walletClient, publicClient, environmentConfig } = options;
|
|
2483
|
+
const account = walletClient.account;
|
|
2484
|
+
if (!account) {
|
|
2485
|
+
throw new Error("Wallet client must have an account");
|
|
2486
|
+
}
|
|
2487
|
+
const isDelegated2 = await checkERC7702Delegation(
|
|
2488
|
+
publicClient,
|
|
2489
|
+
account.address,
|
|
2490
|
+
environmentConfig.erc7702DelegatorAddress
|
|
2491
|
+
);
|
|
2492
|
+
if (isDelegated2) {
|
|
2493
|
+
return void 0;
|
|
2494
|
+
}
|
|
2495
|
+
const transactionNonce = await publicClient.getTransactionCount({
|
|
2496
|
+
address: account.address,
|
|
2497
|
+
blockTag: "pending"
|
|
2498
|
+
});
|
|
2499
|
+
const chainId = await publicClient.getChainId();
|
|
2500
|
+
const authorizationNonce = transactionNonce + 1;
|
|
2501
|
+
const signedAuthorization = await walletClient.signAuthorization({
|
|
2502
|
+
account,
|
|
2503
|
+
contractAddress: environmentConfig.erc7702DelegatorAddress,
|
|
2504
|
+
chainId,
|
|
2505
|
+
nonce: Number(authorizationNonce)
|
|
2506
|
+
});
|
|
2507
|
+
return [signedAuthorization];
|
|
2508
|
+
}
|
|
2348
2509
|
async function executeBatch(options, logger = noopLogger) {
|
|
2349
|
-
const {
|
|
2510
|
+
const {
|
|
2511
|
+
walletClient,
|
|
2512
|
+
publicClient,
|
|
2513
|
+
environmentConfig,
|
|
2514
|
+
executions,
|
|
2515
|
+
pendingMessage,
|
|
2516
|
+
gas,
|
|
2517
|
+
authorizationList: providedAuthList
|
|
2518
|
+
} = options;
|
|
2350
2519
|
const account = walletClient.account;
|
|
2351
2520
|
if (!account) {
|
|
2352
2521
|
throw new Error("Wallet client must have an account");
|
|
@@ -2356,27 +2525,29 @@ async function executeBatch(options, logger = noopLogger) {
|
|
|
2356
2525
|
throw new Error("Wallet client must have a chain");
|
|
2357
2526
|
}
|
|
2358
2527
|
const executeBatchData = encodeExecuteBatchData(executions);
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2528
|
+
let authorizationList = providedAuthList || [];
|
|
2529
|
+
if (authorizationList.length === 0) {
|
|
2530
|
+
const isDelegated2 = await checkERC7702Delegation(
|
|
2531
|
+
publicClient,
|
|
2532
|
+
account.address,
|
|
2533
|
+
environmentConfig.erc7702DelegatorAddress
|
|
2534
|
+
);
|
|
2535
|
+
if (!isDelegated2) {
|
|
2536
|
+
const transactionNonce = await publicClient.getTransactionCount({
|
|
2537
|
+
address: account.address,
|
|
2538
|
+
blockTag: "pending"
|
|
2539
|
+
});
|
|
2540
|
+
const chainId = await publicClient.getChainId();
|
|
2541
|
+
const authorizationNonce = transactionNonce + 1;
|
|
2542
|
+
logger.debug("Using wallet client signing for EIP-7702 authorization");
|
|
2543
|
+
const signedAuthorization = await walletClient.signAuthorization({
|
|
2544
|
+
account,
|
|
2545
|
+
contractAddress: environmentConfig.erc7702DelegatorAddress,
|
|
2546
|
+
chainId,
|
|
2547
|
+
nonce: Number(authorizationNonce)
|
|
2548
|
+
});
|
|
2549
|
+
authorizationList = [signedAuthorization];
|
|
2550
|
+
}
|
|
2380
2551
|
}
|
|
2381
2552
|
if (pendingMessage) {
|
|
2382
2553
|
logger.info(pendingMessage);
|
|
@@ -2391,6 +2562,9 @@ async function executeBatch(options, logger = noopLogger) {
|
|
|
2391
2562
|
if (authorizationList.length > 0) {
|
|
2392
2563
|
txRequest.authorizationList = authorizationList;
|
|
2393
2564
|
}
|
|
2565
|
+
if (gas?.gasLimit) {
|
|
2566
|
+
txRequest.gas = gas.gasLimit;
|
|
2567
|
+
}
|
|
2394
2568
|
if (gas?.maxFeePerGas) {
|
|
2395
2569
|
txRequest.maxFeePerGas = gas.maxFeePerGas;
|
|
2396
2570
|
}
|
|
@@ -4139,7 +4313,8 @@ async function executeDeployBatch(data, context, gas, logger = noopLogger) {
|
|
|
4139
4313
|
environmentConfig: context.environmentConfig,
|
|
4140
4314
|
executions: data.executions,
|
|
4141
4315
|
pendingMessage,
|
|
4142
|
-
gas
|
|
4316
|
+
gas,
|
|
4317
|
+
authorizationList: data.authorizationList
|
|
4143
4318
|
},
|
|
4144
4319
|
logger
|
|
4145
4320
|
);
|
|
@@ -4250,7 +4425,8 @@ async function executeUpgradeBatch(data, context, gas, logger = noopLogger) {
|
|
|
4250
4425
|
environmentConfig: context.environmentConfig,
|
|
4251
4426
|
executions: data.executions,
|
|
4252
4427
|
pendingMessage,
|
|
4253
|
-
gas
|
|
4428
|
+
gas,
|
|
4429
|
+
authorizationList: data.authorizationList
|
|
4254
4430
|
},
|
|
4255
4431
|
logger
|
|
4256
4432
|
);
|
|
@@ -4560,166 +4736,44 @@ async function calculateBillingAuthSignature(options) {
|
|
|
4560
4736
|
return { signature, expiry };
|
|
4561
4737
|
}
|
|
4562
4738
|
|
|
4563
|
-
// src/client/common/
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
this.code = code;
|
|
4568
|
-
this.statusCode = statusCode;
|
|
4569
|
-
this.name = "SessionError";
|
|
4570
|
-
}
|
|
4571
|
-
};
|
|
4572
|
-
function stripHexPrefix2(hex) {
|
|
4573
|
-
return hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
4739
|
+
// src/client/common/utils/userapi.ts
|
|
4740
|
+
init_session();
|
|
4741
|
+
function isJsonObject(value) {
|
|
4742
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4574
4743
|
}
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
return data.error || response.statusText;
|
|
4579
|
-
} catch {
|
|
4580
|
-
return response.statusText;
|
|
4581
|
-
}
|
|
4744
|
+
function readString(obj, key) {
|
|
4745
|
+
const v = obj[key];
|
|
4746
|
+
return typeof v === "string" ? v : void 0;
|
|
4582
4747
|
}
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
);
|
|
4748
|
+
function readNumber(obj, key) {
|
|
4749
|
+
const v = obj[key];
|
|
4750
|
+
return typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
4751
|
+
}
|
|
4752
|
+
var MAX_ADDRESS_COUNT = 5;
|
|
4753
|
+
var CanViewAppLogsPermission = "0x2fd3f2fe";
|
|
4754
|
+
var CanViewSensitiveAppInfoPermission = "0x0e67b22f";
|
|
4755
|
+
var CanUpdateAppProfilePermission = "0x036fef61";
|
|
4756
|
+
function getDefaultClientId() {
|
|
4757
|
+
const version = true ? "0.3.0-dev.0" : "0.0.0";
|
|
4758
|
+
return `ecloud-sdk/v${version}`;
|
|
4759
|
+
}
|
|
4760
|
+
var UserApiClient = class {
|
|
4761
|
+
constructor(config, walletClient, publicClient, options) {
|
|
4762
|
+
this.config = config;
|
|
4763
|
+
this.walletClient = walletClient;
|
|
4764
|
+
this.publicClient = publicClient;
|
|
4765
|
+
this.clientId = options?.clientId || getDefaultClientId();
|
|
4766
|
+
this.useSession = options?.useSession ?? false;
|
|
4603
4767
|
}
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
throw new SessionError(`Bad request: ${errorMessage}`, "INVALID_MESSAGE", status);
|
|
4612
|
-
}
|
|
4613
|
-
if (status === 401) {
|
|
4614
|
-
throw new SessionError(`Invalid signature: ${errorMessage}`, "INVALID_SIGNATURE", status);
|
|
4768
|
+
/**
|
|
4769
|
+
* Get the address of the connected wallet
|
|
4770
|
+
*/
|
|
4771
|
+
get address() {
|
|
4772
|
+
const account = this.walletClient.account;
|
|
4773
|
+
if (!account) {
|
|
4774
|
+
throw new Error("WalletClient must have an account attached");
|
|
4615
4775
|
}
|
|
4616
|
-
|
|
4617
|
-
}
|
|
4618
|
-
const data = await response.json();
|
|
4619
|
-
return {
|
|
4620
|
-
success: data.success,
|
|
4621
|
-
address: data.address
|
|
4622
|
-
};
|
|
4623
|
-
}
|
|
4624
|
-
async function getComputeApiSession(config) {
|
|
4625
|
-
let response;
|
|
4626
|
-
try {
|
|
4627
|
-
response = await fetch(`${config.baseUrl}/auth/session`, {
|
|
4628
|
-
method: "GET",
|
|
4629
|
-
credentials: "include",
|
|
4630
|
-
// Include cookies for session management
|
|
4631
|
-
headers: {
|
|
4632
|
-
"Content-Type": "application/json"
|
|
4633
|
-
}
|
|
4634
|
-
});
|
|
4635
|
-
} catch {
|
|
4636
|
-
return {
|
|
4637
|
-
authenticated: false
|
|
4638
|
-
};
|
|
4639
|
-
}
|
|
4640
|
-
if (response.status === 401) {
|
|
4641
|
-
return {
|
|
4642
|
-
authenticated: false
|
|
4643
|
-
};
|
|
4644
|
-
}
|
|
4645
|
-
if (!response.ok) {
|
|
4646
|
-
const errorMessage = await parseErrorResponse(response);
|
|
4647
|
-
throw new SessionError(`Failed to get session: ${errorMessage}`, "UNKNOWN", response.status);
|
|
4648
|
-
}
|
|
4649
|
-
const data = await response.json();
|
|
4650
|
-
return {
|
|
4651
|
-
authenticated: data.authenticated,
|
|
4652
|
-
address: data.address,
|
|
4653
|
-
chainId: data.chain_id
|
|
4654
|
-
};
|
|
4655
|
-
}
|
|
4656
|
-
async function logoutFromComputeApi(config) {
|
|
4657
|
-
let response;
|
|
4658
|
-
try {
|
|
4659
|
-
response = await fetch(`${config.baseUrl}/auth/logout`, {
|
|
4660
|
-
method: "POST",
|
|
4661
|
-
credentials: "include",
|
|
4662
|
-
// Include cookies for session management
|
|
4663
|
-
headers: {
|
|
4664
|
-
"Content-Type": "application/json"
|
|
4665
|
-
}
|
|
4666
|
-
});
|
|
4667
|
-
} catch (error) {
|
|
4668
|
-
throw new SessionError(
|
|
4669
|
-
`Network error connecting to ${config.baseUrl}: ${error instanceof Error ? error.message : String(error)}`,
|
|
4670
|
-
"NETWORK_ERROR"
|
|
4671
|
-
);
|
|
4672
|
-
}
|
|
4673
|
-
if (response.status === 401) {
|
|
4674
|
-
return;
|
|
4675
|
-
}
|
|
4676
|
-
if (!response.ok) {
|
|
4677
|
-
const errorMessage = await parseErrorResponse(response);
|
|
4678
|
-
throw new SessionError(`Logout failed: ${errorMessage}`, "UNKNOWN", response.status);
|
|
4679
|
-
}
|
|
4680
|
-
}
|
|
4681
|
-
async function isSessionValid(config) {
|
|
4682
|
-
const session = await getComputeApiSession(config);
|
|
4683
|
-
return session.authenticated;
|
|
4684
|
-
}
|
|
4685
|
-
|
|
4686
|
-
// src/client/common/utils/userapi.ts
|
|
4687
|
-
function isJsonObject(value) {
|
|
4688
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4689
|
-
}
|
|
4690
|
-
function readString(obj, key) {
|
|
4691
|
-
const v = obj[key];
|
|
4692
|
-
return typeof v === "string" ? v : void 0;
|
|
4693
|
-
}
|
|
4694
|
-
function readNumber(obj, key) {
|
|
4695
|
-
const v = obj[key];
|
|
4696
|
-
return typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
4697
|
-
}
|
|
4698
|
-
var MAX_ADDRESS_COUNT = 5;
|
|
4699
|
-
var CanViewAppLogsPermission = "0x2fd3f2fe";
|
|
4700
|
-
var CanViewSensitiveAppInfoPermission = "0x0e67b22f";
|
|
4701
|
-
var CanUpdateAppProfilePermission = "0x036fef61";
|
|
4702
|
-
function getDefaultClientId() {
|
|
4703
|
-
const version = true ? "0.2.2-dev" : "0.0.0";
|
|
4704
|
-
return `ecloud-sdk/v${version}`;
|
|
4705
|
-
}
|
|
4706
|
-
var UserApiClient = class {
|
|
4707
|
-
constructor(config, walletClient, publicClient, options) {
|
|
4708
|
-
this.config = config;
|
|
4709
|
-
this.walletClient = walletClient;
|
|
4710
|
-
this.publicClient = publicClient;
|
|
4711
|
-
this.clientId = options?.clientId || getDefaultClientId();
|
|
4712
|
-
this.useSession = options?.useSession ?? false;
|
|
4713
|
-
}
|
|
4714
|
-
/**
|
|
4715
|
-
* Get the address of the connected wallet
|
|
4716
|
-
*/
|
|
4717
|
-
get address() {
|
|
4718
|
-
const account = this.walletClient.account;
|
|
4719
|
-
if (!account) {
|
|
4720
|
-
throw new Error("WalletClient must have an account attached");
|
|
4721
|
-
}
|
|
4722
|
-
return account.address;
|
|
4776
|
+
return account.address;
|
|
4723
4777
|
}
|
|
4724
4778
|
async getInfos(appIDs, addressCount = 1) {
|
|
4725
4779
|
const count = Math.min(addressCount, MAX_ADDRESS_COUNT);
|
|
@@ -5608,21 +5662,214 @@ function isSubscriptionActive(status) {
|
|
|
5608
5662
|
|
|
5609
5663
|
// src/client/common/utils/billingapi.ts
|
|
5610
5664
|
var import_axios2 = __toESM(require("axios"), 1);
|
|
5665
|
+
|
|
5666
|
+
// src/client/common/auth/billingSession.ts
|
|
5667
|
+
var BillingSessionError = class extends Error {
|
|
5668
|
+
constructor(message, code, statusCode) {
|
|
5669
|
+
super(message);
|
|
5670
|
+
this.code = code;
|
|
5671
|
+
this.statusCode = statusCode;
|
|
5672
|
+
this.name = "BillingSessionError";
|
|
5673
|
+
}
|
|
5674
|
+
};
|
|
5675
|
+
function stripHexPrefix3(hex) {
|
|
5676
|
+
return hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
5677
|
+
}
|
|
5678
|
+
async function parseErrorResponse2(response) {
|
|
5679
|
+
try {
|
|
5680
|
+
const data = await response.json();
|
|
5681
|
+
return data.error || response.statusText;
|
|
5682
|
+
} catch {
|
|
5683
|
+
return response.statusText;
|
|
5684
|
+
}
|
|
5685
|
+
}
|
|
5686
|
+
async function loginToBillingApi(config, request) {
|
|
5687
|
+
let response;
|
|
5688
|
+
try {
|
|
5689
|
+
response = await fetch(`${config.baseUrl}/auth/siwe/login`, {
|
|
5690
|
+
method: "POST",
|
|
5691
|
+
credentials: "include",
|
|
5692
|
+
// Include cookies for session management
|
|
5693
|
+
headers: {
|
|
5694
|
+
"Content-Type": "application/json"
|
|
5695
|
+
},
|
|
5696
|
+
body: JSON.stringify({
|
|
5697
|
+
message: request.message,
|
|
5698
|
+
signature: stripHexPrefix3(request.signature)
|
|
5699
|
+
})
|
|
5700
|
+
});
|
|
5701
|
+
} catch (error) {
|
|
5702
|
+
throw new BillingSessionError(
|
|
5703
|
+
`Network error connecting to ${config.baseUrl}: ${error instanceof Error ? error.message : String(error)}`,
|
|
5704
|
+
"NETWORK_ERROR"
|
|
5705
|
+
);
|
|
5706
|
+
}
|
|
5707
|
+
if (!response.ok) {
|
|
5708
|
+
const errorMessage = await parseErrorResponse2(response);
|
|
5709
|
+
const status = response.status;
|
|
5710
|
+
if (status === 400) {
|
|
5711
|
+
if (errorMessage.toLowerCase().includes("siwe")) {
|
|
5712
|
+
throw new BillingSessionError(`Invalid SIWE message: ${errorMessage}`, "INVALID_MESSAGE", status);
|
|
5713
|
+
}
|
|
5714
|
+
throw new BillingSessionError(`Bad request: ${errorMessage}`, "INVALID_MESSAGE", status);
|
|
5715
|
+
}
|
|
5716
|
+
if (status === 401) {
|
|
5717
|
+
throw new BillingSessionError(`Invalid signature: ${errorMessage}`, "INVALID_SIGNATURE", status);
|
|
5718
|
+
}
|
|
5719
|
+
throw new BillingSessionError(`Login failed: ${errorMessage}`, "UNKNOWN", status);
|
|
5720
|
+
}
|
|
5721
|
+
const data = await response.json();
|
|
5722
|
+
return {
|
|
5723
|
+
success: data.success,
|
|
5724
|
+
address: data.address
|
|
5725
|
+
};
|
|
5726
|
+
}
|
|
5727
|
+
async function getBillingApiSession(config) {
|
|
5728
|
+
let response;
|
|
5729
|
+
try {
|
|
5730
|
+
response = await fetch(`${config.baseUrl}/auth/session`, {
|
|
5731
|
+
method: "GET",
|
|
5732
|
+
credentials: "include",
|
|
5733
|
+
// Include cookies for session management
|
|
5734
|
+
headers: {
|
|
5735
|
+
"Content-Type": "application/json"
|
|
5736
|
+
}
|
|
5737
|
+
});
|
|
5738
|
+
} catch {
|
|
5739
|
+
return {
|
|
5740
|
+
authenticated: false
|
|
5741
|
+
};
|
|
5742
|
+
}
|
|
5743
|
+
if (response.status === 401) {
|
|
5744
|
+
return {
|
|
5745
|
+
authenticated: false
|
|
5746
|
+
};
|
|
5747
|
+
}
|
|
5748
|
+
if (!response.ok) {
|
|
5749
|
+
const errorMessage = await parseErrorResponse2(response);
|
|
5750
|
+
throw new BillingSessionError(`Failed to get session: ${errorMessage}`, "UNKNOWN", response.status);
|
|
5751
|
+
}
|
|
5752
|
+
const data = await response.json();
|
|
5753
|
+
return {
|
|
5754
|
+
authenticated: data.authenticated,
|
|
5755
|
+
address: data.address,
|
|
5756
|
+
chainId: data.chainId,
|
|
5757
|
+
authenticatedAt: data.authenticatedAt
|
|
5758
|
+
};
|
|
5759
|
+
}
|
|
5760
|
+
async function logoutFromBillingApi(config) {
|
|
5761
|
+
let response;
|
|
5762
|
+
try {
|
|
5763
|
+
response = await fetch(`${config.baseUrl}/auth/logout`, {
|
|
5764
|
+
method: "POST",
|
|
5765
|
+
credentials: "include",
|
|
5766
|
+
// Include cookies for session management
|
|
5767
|
+
headers: {
|
|
5768
|
+
"Content-Type": "application/json"
|
|
5769
|
+
}
|
|
5770
|
+
});
|
|
5771
|
+
} catch (error) {
|
|
5772
|
+
throw new BillingSessionError(
|
|
5773
|
+
`Network error connecting to ${config.baseUrl}: ${error instanceof Error ? error.message : String(error)}`,
|
|
5774
|
+
"NETWORK_ERROR"
|
|
5775
|
+
);
|
|
5776
|
+
}
|
|
5777
|
+
if (response.status === 401) {
|
|
5778
|
+
return;
|
|
5779
|
+
}
|
|
5780
|
+
if (!response.ok) {
|
|
5781
|
+
const errorMessage = await parseErrorResponse2(response);
|
|
5782
|
+
throw new BillingSessionError(`Logout failed: ${errorMessage}`, "UNKNOWN", response.status);
|
|
5783
|
+
}
|
|
5784
|
+
}
|
|
5785
|
+
|
|
5786
|
+
// src/client/common/utils/billingapi.ts
|
|
5611
5787
|
var BillingApiClient = class {
|
|
5612
|
-
constructor(config, walletClient) {
|
|
5788
|
+
constructor(config, walletClient, options = {}) {
|
|
5613
5789
|
this.config = config;
|
|
5614
5790
|
this.walletClient = walletClient;
|
|
5791
|
+
this.options = options;
|
|
5792
|
+
this.useSession = options.useSession ?? false;
|
|
5793
|
+
if (!this.useSession && !walletClient) {
|
|
5794
|
+
throw new Error("WalletClient is required when not using session authentication");
|
|
5795
|
+
}
|
|
5615
5796
|
}
|
|
5616
5797
|
/**
|
|
5617
5798
|
* Get the address of the connected wallet
|
|
5799
|
+
* Returns undefined if using session auth without a wallet client
|
|
5618
5800
|
*/
|
|
5619
5801
|
get address() {
|
|
5620
|
-
const account = this.walletClient
|
|
5802
|
+
const account = this.walletClient?.account;
|
|
5621
5803
|
if (!account) {
|
|
5622
|
-
|
|
5804
|
+
if (!this.useSession) {
|
|
5805
|
+
throw new Error("WalletClient must have an account attached");
|
|
5806
|
+
}
|
|
5807
|
+
return void 0;
|
|
5623
5808
|
}
|
|
5624
5809
|
return account.address;
|
|
5625
5810
|
}
|
|
5811
|
+
/**
|
|
5812
|
+
* Get the base URL of the billing API
|
|
5813
|
+
*/
|
|
5814
|
+
get baseUrl() {
|
|
5815
|
+
return this.config.billingApiServerURL;
|
|
5816
|
+
}
|
|
5817
|
+
// ==========================================================================
|
|
5818
|
+
// SIWE Session Methods
|
|
5819
|
+
// ==========================================================================
|
|
5820
|
+
/**
|
|
5821
|
+
* Login to the billing API using SIWE
|
|
5822
|
+
*
|
|
5823
|
+
* This establishes a session with the billing API by verifying the SIWE message
|
|
5824
|
+
* and signature. On success, a session cookie is set in the browser.
|
|
5825
|
+
*
|
|
5826
|
+
* @param request - Login request containing SIWE message and signature
|
|
5827
|
+
* @returns Login result with the authenticated address
|
|
5828
|
+
*
|
|
5829
|
+
* @example
|
|
5830
|
+
* ```typescript
|
|
5831
|
+
* const { message } = createSiweMessage({
|
|
5832
|
+
* address: userAddress,
|
|
5833
|
+
* chainId: 11155111,
|
|
5834
|
+
* domain: window.location.host,
|
|
5835
|
+
* uri: window.location.origin,
|
|
5836
|
+
* });
|
|
5837
|
+
*
|
|
5838
|
+
* const signature = await signMessageAsync({ message });
|
|
5839
|
+
* const result = await billingClient.siweLogin({ message, signature });
|
|
5840
|
+
* ```
|
|
5841
|
+
*/
|
|
5842
|
+
async siweLogin(request) {
|
|
5843
|
+
return loginToBillingApi({ baseUrl: this.baseUrl }, request);
|
|
5844
|
+
}
|
|
5845
|
+
/**
|
|
5846
|
+
* Logout from the billing API
|
|
5847
|
+
*
|
|
5848
|
+
* This destroys the current session and clears the session cookie.
|
|
5849
|
+
*/
|
|
5850
|
+
async siweLogout() {
|
|
5851
|
+
return logoutFromBillingApi({ baseUrl: this.baseUrl });
|
|
5852
|
+
}
|
|
5853
|
+
/**
|
|
5854
|
+
* Get the current session status from the billing API
|
|
5855
|
+
*
|
|
5856
|
+
* @returns Session information including authentication status and address
|
|
5857
|
+
*/
|
|
5858
|
+
async getSession() {
|
|
5859
|
+
return getBillingApiSession({ baseUrl: this.baseUrl });
|
|
5860
|
+
}
|
|
5861
|
+
/**
|
|
5862
|
+
* Check if there is a valid session
|
|
5863
|
+
*
|
|
5864
|
+
* @returns True if session is authenticated, false otherwise
|
|
5865
|
+
*/
|
|
5866
|
+
async isSessionValid() {
|
|
5867
|
+
const session = await this.getSession();
|
|
5868
|
+
return session.authenticated;
|
|
5869
|
+
}
|
|
5870
|
+
// ==========================================================================
|
|
5871
|
+
// Subscription Methods
|
|
5872
|
+
// ==========================================================================
|
|
5626
5873
|
async createSubscription(productId = "compute", options) {
|
|
5627
5874
|
const endpoint = `${this.config.billingApiServerURL}/products/${productId}/subscription`;
|
|
5628
5875
|
const body = options ? {
|
|
@@ -5641,10 +5888,72 @@ var BillingApiClient = class {
|
|
|
5641
5888
|
const endpoint = `${this.config.billingApiServerURL}/products/${productId}/subscription`;
|
|
5642
5889
|
await this.makeAuthenticatedRequest(endpoint, "DELETE", productId);
|
|
5643
5890
|
}
|
|
5891
|
+
// ==========================================================================
|
|
5892
|
+
// Internal Methods
|
|
5893
|
+
// ==========================================================================
|
|
5644
5894
|
/**
|
|
5645
5895
|
* Make an authenticated request to the billing API
|
|
5896
|
+
*
|
|
5897
|
+
* Uses session auth if useSession is true, otherwise uses EIP-712 signature auth.
|
|
5646
5898
|
*/
|
|
5647
5899
|
async makeAuthenticatedRequest(url, method, productId, body) {
|
|
5900
|
+
if (this.useSession) {
|
|
5901
|
+
return this.makeSessionAuthenticatedRequest(url, method, body);
|
|
5902
|
+
}
|
|
5903
|
+
return this.makeSignatureAuthenticatedRequest(url, method, productId, body);
|
|
5904
|
+
}
|
|
5905
|
+
/**
|
|
5906
|
+
* Make a request using session-based authentication (cookies)
|
|
5907
|
+
*/
|
|
5908
|
+
async makeSessionAuthenticatedRequest(url, method, body) {
|
|
5909
|
+
const headers = {};
|
|
5910
|
+
if (body) {
|
|
5911
|
+
headers["Content-Type"] = "application/json";
|
|
5912
|
+
}
|
|
5913
|
+
try {
|
|
5914
|
+
const response = await fetch(url, {
|
|
5915
|
+
method,
|
|
5916
|
+
credentials: "include",
|
|
5917
|
+
// Include cookies for session management
|
|
5918
|
+
headers,
|
|
5919
|
+
body: body ? JSON.stringify(body) : void 0
|
|
5920
|
+
});
|
|
5921
|
+
const status = response.status;
|
|
5922
|
+
const statusText = status >= 200 && status < 300 ? "OK" : "Error";
|
|
5923
|
+
if (status < 200 || status >= 300) {
|
|
5924
|
+
let errorBody;
|
|
5925
|
+
try {
|
|
5926
|
+
errorBody = await response.text();
|
|
5927
|
+
} catch {
|
|
5928
|
+
errorBody = statusText;
|
|
5929
|
+
}
|
|
5930
|
+
throw new Error(`BillingAPI request failed: ${status} ${statusText} - ${errorBody}`);
|
|
5931
|
+
}
|
|
5932
|
+
const responseData = await response.json();
|
|
5933
|
+
return {
|
|
5934
|
+
json: async () => responseData,
|
|
5935
|
+
text: async () => JSON.stringify(responseData)
|
|
5936
|
+
};
|
|
5937
|
+
} catch (error) {
|
|
5938
|
+
if (error.name === "TypeError" || error.message?.includes("fetch")) {
|
|
5939
|
+
throw new Error(
|
|
5940
|
+
`Failed to connect to BillingAPI at ${url}: ${error.message}
|
|
5941
|
+
Please check:
|
|
5942
|
+
1. Your internet connection
|
|
5943
|
+
2. The API server is accessible: ${this.config.billingApiServerURL}
|
|
5944
|
+
3. Firewall/proxy settings`
|
|
5945
|
+
);
|
|
5946
|
+
}
|
|
5947
|
+
throw error;
|
|
5948
|
+
}
|
|
5949
|
+
}
|
|
5950
|
+
/**
|
|
5951
|
+
* Make a request using EIP-712 signature authentication
|
|
5952
|
+
*/
|
|
5953
|
+
async makeSignatureAuthenticatedRequest(url, method, productId, body) {
|
|
5954
|
+
if (!this.walletClient) {
|
|
5955
|
+
throw new Error("WalletClient is required for signature authentication");
|
|
5956
|
+
}
|
|
5648
5957
|
const expiry = BigInt(Math.floor(Date.now() / 1e3) + 5 * 60);
|
|
5649
5958
|
const { signature } = await calculateBillingAuthSignature({
|
|
5650
5959
|
walletClient: this.walletClient,
|
|
@@ -5964,16 +6273,24 @@ async function prepareDeployFromVerifiableBuild(options, logger = defaultLogger)
|
|
|
5964
6273
|
},
|
|
5965
6274
|
logger
|
|
5966
6275
|
);
|
|
6276
|
+
logger.debug("Checking delegation status...");
|
|
6277
|
+
const authorizationList = await createAuthorizationList({
|
|
6278
|
+
walletClient: batch.walletClient,
|
|
6279
|
+
publicClient: batch.publicClient,
|
|
6280
|
+
environmentConfig: batch.environmentConfig
|
|
6281
|
+
});
|
|
5967
6282
|
logger.debug("Estimating gas...");
|
|
5968
6283
|
const gasEstimate = await estimateBatchGas({
|
|
5969
6284
|
publicClient: batch.publicClient,
|
|
5970
6285
|
account: batch.walletClient.account.address,
|
|
5971
|
-
executions: batch.executions
|
|
6286
|
+
executions: batch.executions,
|
|
6287
|
+
authorizationList
|
|
5972
6288
|
});
|
|
5973
6289
|
const data = {
|
|
5974
6290
|
appId: batch.appId,
|
|
5975
6291
|
salt: batch.salt,
|
|
5976
|
-
executions: batch.executions
|
|
6292
|
+
executions: batch.executions,
|
|
6293
|
+
authorizationList
|
|
5977
6294
|
};
|
|
5978
6295
|
return {
|
|
5979
6296
|
prepared: {
|
|
@@ -6202,16 +6519,24 @@ async function prepareDeploy(options, logger = defaultLogger) {
|
|
|
6202
6519
|
},
|
|
6203
6520
|
logger
|
|
6204
6521
|
);
|
|
6522
|
+
logger.debug("Checking delegation status...");
|
|
6523
|
+
const authorizationList = await createAuthorizationList({
|
|
6524
|
+
walletClient: batch.walletClient,
|
|
6525
|
+
publicClient: batch.publicClient,
|
|
6526
|
+
environmentConfig: batch.environmentConfig
|
|
6527
|
+
});
|
|
6205
6528
|
logger.debug("Estimating gas...");
|
|
6206
6529
|
const gasEstimate = await estimateBatchGas({
|
|
6207
6530
|
publicClient: batch.publicClient,
|
|
6208
6531
|
account: batch.walletClient.account.address,
|
|
6209
|
-
executions: batch.executions
|
|
6532
|
+
executions: batch.executions,
|
|
6533
|
+
authorizationList
|
|
6210
6534
|
});
|
|
6211
6535
|
const data = {
|
|
6212
6536
|
appId: batch.appId,
|
|
6213
6537
|
salt: batch.salt,
|
|
6214
|
-
executions: batch.executions
|
|
6538
|
+
executions: batch.executions,
|
|
6539
|
+
authorizationList
|
|
6215
6540
|
};
|
|
6216
6541
|
return {
|
|
6217
6542
|
prepared: {
|
|
@@ -6342,15 +6667,23 @@ async function prepareUpgradeFromVerifiableBuild(options, logger = defaultLogger
|
|
|
6342
6667
|
needsPermissionChange,
|
|
6343
6668
|
imageRef: options.imageRef
|
|
6344
6669
|
});
|
|
6670
|
+
logger.debug("Checking delegation status...");
|
|
6671
|
+
const authorizationList = await createAuthorizationList({
|
|
6672
|
+
walletClient: batch.walletClient,
|
|
6673
|
+
publicClient: batch.publicClient,
|
|
6674
|
+
environmentConfig: batch.environmentConfig
|
|
6675
|
+
});
|
|
6345
6676
|
logger.debug("Estimating gas...");
|
|
6346
6677
|
const gasEstimate = await estimateBatchGas({
|
|
6347
6678
|
publicClient: batch.publicClient,
|
|
6348
6679
|
account: batch.walletClient.account.address,
|
|
6349
|
-
executions: batch.executions
|
|
6680
|
+
executions: batch.executions,
|
|
6681
|
+
authorizationList
|
|
6350
6682
|
});
|
|
6351
6683
|
const data = {
|
|
6352
6684
|
appId: batch.appId,
|
|
6353
|
-
executions: batch.executions
|
|
6685
|
+
executions: batch.executions,
|
|
6686
|
+
authorizationList
|
|
6354
6687
|
};
|
|
6355
6688
|
return {
|
|
6356
6689
|
prepared: {
|
|
@@ -6523,15 +6856,23 @@ async function prepareUpgrade(options, logger = defaultLogger) {
|
|
|
6523
6856
|
needsPermissionChange,
|
|
6524
6857
|
imageRef: finalImageRef
|
|
6525
6858
|
});
|
|
6859
|
+
logger.debug("Checking delegation status...");
|
|
6860
|
+
const authorizationList = await createAuthorizationList({
|
|
6861
|
+
walletClient: batch.walletClient,
|
|
6862
|
+
publicClient: batch.publicClient,
|
|
6863
|
+
environmentConfig: batch.environmentConfig
|
|
6864
|
+
});
|
|
6526
6865
|
logger.debug("Estimating gas...");
|
|
6527
6866
|
const gasEstimate = await estimateBatchGas({
|
|
6528
6867
|
publicClient: batch.publicClient,
|
|
6529
6868
|
account: batch.walletClient.account.address,
|
|
6530
|
-
executions: batch.executions
|
|
6869
|
+
executions: batch.executions,
|
|
6870
|
+
authorizationList
|
|
6531
6871
|
});
|
|
6532
6872
|
const data = {
|
|
6533
6873
|
appId: batch.appId,
|
|
6534
|
-
executions: batch.executions
|
|
6874
|
+
executions: batch.executions,
|
|
6875
|
+
authorizationList
|
|
6535
6876
|
};
|
|
6536
6877
|
return {
|
|
6537
6878
|
prepared: {
|
|
@@ -7659,7 +8000,10 @@ function createBillingModule(config) {
|
|
|
7659
8000
|
};
|
|
7660
8001
|
}
|
|
7661
8002
|
logger.debug(`Creating subscription for ${productId}...`);
|
|
7662
|
-
const result = await billingApi.createSubscription(productId
|
|
8003
|
+
const result = await billingApi.createSubscription(productId, {
|
|
8004
|
+
successUrl: opts?.successUrl,
|
|
8005
|
+
cancelUrl: opts?.cancelUrl
|
|
8006
|
+
});
|
|
7663
8007
|
logger.debug(`Checkout URL: ${result.checkoutUrl}`);
|
|
7664
8008
|
return {
|
|
7665
8009
|
type: "checkout_created",
|
|
@@ -7751,9 +8095,22 @@ async function requestWithRetry(config) {
|
|
|
7751
8095
|
}
|
|
7752
8096
|
var BuildApiClient = class {
|
|
7753
8097
|
constructor(options) {
|
|
7754
|
-
|
|
8098
|
+
let url = options.baseUrl;
|
|
8099
|
+
while (url.endsWith("/")) {
|
|
8100
|
+
url = url.slice(0, -1);
|
|
8101
|
+
}
|
|
8102
|
+
this.baseUrl = url;
|
|
7755
8103
|
this.clientId = options.clientId;
|
|
7756
8104
|
this.walletClient = options.walletClient;
|
|
8105
|
+
this.useSession = options.useSession ?? false;
|
|
8106
|
+
this.billingSessionId = options.billingSessionId;
|
|
8107
|
+
}
|
|
8108
|
+
/**
|
|
8109
|
+
* Update the billing session ID.
|
|
8110
|
+
* Call this after logging into the billing API to enable session-based auth for builds.
|
|
8111
|
+
*/
|
|
8112
|
+
setBillingSessionId(sessionId) {
|
|
8113
|
+
this.billingSessionId = sessionId;
|
|
7757
8114
|
}
|
|
7758
8115
|
/**
|
|
7759
8116
|
* Get the address of the connected wallet
|
|
@@ -7765,8 +8122,17 @@ var BuildApiClient = class {
|
|
|
7765
8122
|
}
|
|
7766
8123
|
return account.address;
|
|
7767
8124
|
}
|
|
8125
|
+
/**
|
|
8126
|
+
* Submit a new build request.
|
|
8127
|
+
* Supports two auth modes (session auth is tried first when billingSessionId is available):
|
|
8128
|
+
* 1. Session-based auth: X-Billing-Session header (forwarded billing_session cookie)
|
|
8129
|
+
* 2. Signature-based auth: Authorization + X-Account + X-eigenx-expiry headers (requires walletClient)
|
|
8130
|
+
*/
|
|
7768
8131
|
async submitBuild(payload) {
|
|
7769
|
-
|
|
8132
|
+
if (this.useSession && this.billingSessionId) {
|
|
8133
|
+
return this.billingSessionAuthJsonRequest("/builds", "POST", payload);
|
|
8134
|
+
}
|
|
8135
|
+
return this.signatureAuthJsonRequest("/builds", "POST", payload);
|
|
7770
8136
|
}
|
|
7771
8137
|
async getBuild(buildId) {
|
|
7772
8138
|
return this.publicJsonRequest(`/builds/${encodeURIComponent(buildId)}`);
|
|
@@ -7777,8 +8143,11 @@ var BuildApiClient = class {
|
|
|
7777
8143
|
async verify(identifier) {
|
|
7778
8144
|
return this.publicJsonRequest(`/builds/verify/${encodeURIComponent(identifier)}`);
|
|
7779
8145
|
}
|
|
8146
|
+
/**
|
|
8147
|
+
* Get build logs. Supports session auth (identity verification only, no billing check).
|
|
8148
|
+
*/
|
|
7780
8149
|
async getLogs(buildId) {
|
|
7781
|
-
return this.
|
|
8150
|
+
return this.sessionOrSignatureTextRequest(`/builds/${encodeURIComponent(buildId)}/logs`);
|
|
7782
8151
|
}
|
|
7783
8152
|
async listBuilds(params) {
|
|
7784
8153
|
const res = await requestWithRetry({
|
|
@@ -7786,7 +8155,9 @@ var BuildApiClient = class {
|
|
|
7786
8155
|
method: "GET",
|
|
7787
8156
|
params,
|
|
7788
8157
|
headers: this.clientId ? { "x-client-id": this.clientId } : void 0,
|
|
7789
|
-
timeout: 6e4
|
|
8158
|
+
timeout: 6e4,
|
|
8159
|
+
validateStatus: () => true,
|
|
8160
|
+
withCredentials: this.useSession
|
|
7790
8161
|
});
|
|
7791
8162
|
if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
|
|
7792
8163
|
return res.data;
|
|
@@ -7796,12 +8167,18 @@ var BuildApiClient = class {
|
|
|
7796
8167
|
url: `${this.baseUrl}${path8}`,
|
|
7797
8168
|
method: "GET",
|
|
7798
8169
|
headers: this.clientId ? { "x-client-id": this.clientId } : void 0,
|
|
7799
|
-
timeout: 6e4
|
|
8170
|
+
timeout: 6e4,
|
|
8171
|
+
validateStatus: () => true,
|
|
8172
|
+
withCredentials: this.useSession
|
|
7800
8173
|
});
|
|
7801
8174
|
if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
|
|
7802
8175
|
return res.data;
|
|
7803
8176
|
}
|
|
7804
|
-
|
|
8177
|
+
/**
|
|
8178
|
+
* Make a request that ALWAYS requires signature auth (for billing verification).
|
|
8179
|
+
* Used for endpoints like POST /builds that need to verify subscription status.
|
|
8180
|
+
*/
|
|
8181
|
+
async signatureAuthJsonRequest(path8, method, body) {
|
|
7805
8182
|
if (!this.walletClient?.account) {
|
|
7806
8183
|
throw new Error("WalletClient with account required for authenticated requests");
|
|
7807
8184
|
}
|
|
@@ -7823,32 +8200,69 @@ var BuildApiClient = class {
|
|
|
7823
8200
|
method,
|
|
7824
8201
|
headers,
|
|
7825
8202
|
data: body,
|
|
7826
|
-
timeout: 6e4
|
|
8203
|
+
timeout: 6e4,
|
|
8204
|
+
validateStatus: () => true,
|
|
8205
|
+
withCredentials: this.useSession
|
|
7827
8206
|
});
|
|
7828
8207
|
if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
|
|
7829
8208
|
return res.data;
|
|
7830
8209
|
}
|
|
7831
|
-
|
|
7832
|
-
|
|
7833
|
-
|
|
8210
|
+
/**
|
|
8211
|
+
* Make a request using billing session auth (for billing verification without wallet signature).
|
|
8212
|
+
* Forwards the billing_session cookie value via X-Billing-Session header.
|
|
8213
|
+
* Used for endpoints that need to verify subscription status when using session-based auth.
|
|
8214
|
+
*/
|
|
8215
|
+
async billingSessionAuthJsonRequest(path8, method, body) {
|
|
8216
|
+
if (!this.billingSessionId) {
|
|
8217
|
+
throw new Error("billingSessionId required for session-based billing auth");
|
|
7834
8218
|
}
|
|
7835
|
-
const headers = {
|
|
8219
|
+
const headers = {
|
|
8220
|
+
"Content-Type": "application/json",
|
|
8221
|
+
"X-Billing-Session": this.billingSessionId
|
|
8222
|
+
};
|
|
7836
8223
|
if (this.clientId) headers["x-client-id"] = this.clientId;
|
|
7837
|
-
const
|
|
7838
|
-
|
|
7839
|
-
|
|
7840
|
-
|
|
7841
|
-
|
|
8224
|
+
const res = await requestWithRetry({
|
|
8225
|
+
url: `${this.baseUrl}${path8}`,
|
|
8226
|
+
method,
|
|
8227
|
+
headers,
|
|
8228
|
+
data: body,
|
|
8229
|
+
timeout: 6e4,
|
|
8230
|
+
validateStatus: () => true,
|
|
8231
|
+
withCredentials: this.useSession
|
|
7842
8232
|
});
|
|
7843
|
-
|
|
7844
|
-
|
|
7845
|
-
|
|
8233
|
+
if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
|
|
8234
|
+
return res.data;
|
|
8235
|
+
}
|
|
8236
|
+
/**
|
|
8237
|
+
* Make an authenticated request that can use session OR signature auth.
|
|
8238
|
+
* When useSession is true, relies on cookies for identity verification.
|
|
8239
|
+
* Used for endpoints that only need identity verification (not billing).
|
|
8240
|
+
*/
|
|
8241
|
+
async sessionOrSignatureTextRequest(path8) {
|
|
8242
|
+
const headers = {};
|
|
8243
|
+
if (this.clientId) headers["x-client-id"] = this.clientId;
|
|
8244
|
+
if (!this.useSession) {
|
|
8245
|
+
if (!this.walletClient?.account) {
|
|
8246
|
+
throw new Error("WalletClient with account required for authenticated requests");
|
|
8247
|
+
}
|
|
8248
|
+
const expiry = BigInt(Math.floor(Date.now() / 1e3) + 60);
|
|
8249
|
+
const { signature } = await calculateBillingAuthSignature({
|
|
8250
|
+
walletClient: this.walletClient,
|
|
8251
|
+
product: "compute",
|
|
8252
|
+
expiry
|
|
8253
|
+
});
|
|
8254
|
+
headers.Authorization = `Bearer ${signature}`;
|
|
8255
|
+
headers["X-eigenx-expiry"] = expiry.toString();
|
|
8256
|
+
headers["X-Account"] = this.address;
|
|
8257
|
+
}
|
|
7846
8258
|
const res = await requestWithRetry({
|
|
7847
8259
|
url: `${this.baseUrl}${path8}`,
|
|
7848
8260
|
method: "GET",
|
|
7849
8261
|
headers,
|
|
7850
8262
|
timeout: 6e4,
|
|
7851
|
-
responseType: "text"
|
|
8263
|
+
responseType: "text",
|
|
8264
|
+
validateStatus: () => true,
|
|
8265
|
+
withCredentials: this.useSession
|
|
7852
8266
|
});
|
|
7853
8267
|
if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
|
|
7854
8268
|
return typeof res.data === "string" ? res.data : JSON.stringify(res.data);
|
|
@@ -8415,6 +8829,9 @@ function isSiweMessageNotYetValid(params) {
|
|
|
8415
8829
|
return /* @__PURE__ */ new Date() < params.notBefore;
|
|
8416
8830
|
}
|
|
8417
8831
|
|
|
8832
|
+
// src/client/common/auth/index.ts
|
|
8833
|
+
init_session();
|
|
8834
|
+
|
|
8418
8835
|
// src/client/common/utils/instance.ts
|
|
8419
8836
|
async function getCurrentInstanceType(preflightCtx, appID, logger, clientId) {
|
|
8420
8837
|
try {
|