@layr-labs/ecloud-sdk 0.2.2-dev → 0.3.0-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 +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 +527 -147
- 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 +527 -147
- package/dist/browser.js.map +1 -1
- package/dist/{compute-BYhSs8en.d.ts → compute-CdZxISln.d.ts} +1 -1
- package/dist/{compute-Bpjb3hYD.d.cts → compute-Dstl0CA0.d.cts} +1 -1
- package/dist/compute.cjs +130 -120
- 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 +132 -120
- package/dist/compute.js.map +1 -1
- package/dist/{helpers-CEvhJz7f.d.cts → helpers-4w0Iojmm.d.ts} +245 -4
- package/dist/{helpers-CQuBwQnu.d.ts → helpers-Dk0zwgms.d.cts} +245 -4
- package/dist/{index-DeQzn_yM.d.cts → index-C0w92tCs.d.cts} +4 -0
- package/dist/{index-DeQzn_yM.d.ts → index-C0w92tCs.d.ts} +4 -0
- package/dist/index.cjs +489 -148
- 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 +491 -148
- 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, {
|
|
@@ -4560,130 +4692,8 @@ async function calculateBillingAuthSignature(options) {
|
|
|
4560
4692
|
return { signature, expiry };
|
|
4561
4693
|
}
|
|
4562
4694
|
|
|
4563
|
-
// src/client/common/auth/session.ts
|
|
4564
|
-
var SessionError = class extends Error {
|
|
4565
|
-
constructor(message, code, statusCode) {
|
|
4566
|
-
super(message);
|
|
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;
|
|
4574
|
-
}
|
|
4575
|
-
async function parseErrorResponse(response) {
|
|
4576
|
-
try {
|
|
4577
|
-
const data = await response.json();
|
|
4578
|
-
return data.error || response.statusText;
|
|
4579
|
-
} catch {
|
|
4580
|
-
return response.statusText;
|
|
4581
|
-
}
|
|
4582
|
-
}
|
|
4583
|
-
async function loginToComputeApi(config, request) {
|
|
4584
|
-
let response;
|
|
4585
|
-
try {
|
|
4586
|
-
response = await fetch(`${config.baseUrl}/auth/siwe/login`, {
|
|
4587
|
-
method: "POST",
|
|
4588
|
-
credentials: "include",
|
|
4589
|
-
// Include cookies for session management
|
|
4590
|
-
headers: {
|
|
4591
|
-
"Content-Type": "application/json"
|
|
4592
|
-
},
|
|
4593
|
-
body: JSON.stringify({
|
|
4594
|
-
message: request.message,
|
|
4595
|
-
signature: stripHexPrefix2(request.signature)
|
|
4596
|
-
})
|
|
4597
|
-
});
|
|
4598
|
-
} catch (error) {
|
|
4599
|
-
throw new SessionError(
|
|
4600
|
-
`Network error connecting to ${config.baseUrl}: ${error instanceof Error ? error.message : String(error)}`,
|
|
4601
|
-
"NETWORK_ERROR"
|
|
4602
|
-
);
|
|
4603
|
-
}
|
|
4604
|
-
if (!response.ok) {
|
|
4605
|
-
const errorMessage = await parseErrorResponse(response);
|
|
4606
|
-
const status = response.status;
|
|
4607
|
-
if (status === 400) {
|
|
4608
|
-
if (errorMessage.toLowerCase().includes("siwe")) {
|
|
4609
|
-
throw new SessionError(`Invalid SIWE message: ${errorMessage}`, "INVALID_MESSAGE", status);
|
|
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);
|
|
4615
|
-
}
|
|
4616
|
-
throw new SessionError(`Login failed: ${errorMessage}`, "UNKNOWN", status);
|
|
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
4695
|
// src/client/common/utils/userapi.ts
|
|
4696
|
+
init_session();
|
|
4687
4697
|
function isJsonObject(value) {
|
|
4688
4698
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4689
4699
|
}
|
|
@@ -4700,7 +4710,7 @@ var CanViewAppLogsPermission = "0x2fd3f2fe";
|
|
|
4700
4710
|
var CanViewSensitiveAppInfoPermission = "0x0e67b22f";
|
|
4701
4711
|
var CanUpdateAppProfilePermission = "0x036fef61";
|
|
4702
4712
|
function getDefaultClientId() {
|
|
4703
|
-
const version = true ? "0.
|
|
4713
|
+
const version = true ? "0.3.0-dev" : "0.0.0";
|
|
4704
4714
|
return `ecloud-sdk/v${version}`;
|
|
4705
4715
|
}
|
|
4706
4716
|
var UserApiClient = class {
|
|
@@ -5608,21 +5618,214 @@ function isSubscriptionActive(status) {
|
|
|
5608
5618
|
|
|
5609
5619
|
// src/client/common/utils/billingapi.ts
|
|
5610
5620
|
var import_axios2 = __toESM(require("axios"), 1);
|
|
5621
|
+
|
|
5622
|
+
// src/client/common/auth/billingSession.ts
|
|
5623
|
+
var BillingSessionError = class extends Error {
|
|
5624
|
+
constructor(message, code, statusCode) {
|
|
5625
|
+
super(message);
|
|
5626
|
+
this.code = code;
|
|
5627
|
+
this.statusCode = statusCode;
|
|
5628
|
+
this.name = "BillingSessionError";
|
|
5629
|
+
}
|
|
5630
|
+
};
|
|
5631
|
+
function stripHexPrefix3(hex) {
|
|
5632
|
+
return hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
5633
|
+
}
|
|
5634
|
+
async function parseErrorResponse2(response) {
|
|
5635
|
+
try {
|
|
5636
|
+
const data = await response.json();
|
|
5637
|
+
return data.error || response.statusText;
|
|
5638
|
+
} catch {
|
|
5639
|
+
return response.statusText;
|
|
5640
|
+
}
|
|
5641
|
+
}
|
|
5642
|
+
async function loginToBillingApi(config, request) {
|
|
5643
|
+
let response;
|
|
5644
|
+
try {
|
|
5645
|
+
response = await fetch(`${config.baseUrl}/auth/siwe/login`, {
|
|
5646
|
+
method: "POST",
|
|
5647
|
+
credentials: "include",
|
|
5648
|
+
// Include cookies for session management
|
|
5649
|
+
headers: {
|
|
5650
|
+
"Content-Type": "application/json"
|
|
5651
|
+
},
|
|
5652
|
+
body: JSON.stringify({
|
|
5653
|
+
message: request.message,
|
|
5654
|
+
signature: stripHexPrefix3(request.signature)
|
|
5655
|
+
})
|
|
5656
|
+
});
|
|
5657
|
+
} catch (error) {
|
|
5658
|
+
throw new BillingSessionError(
|
|
5659
|
+
`Network error connecting to ${config.baseUrl}: ${error instanceof Error ? error.message : String(error)}`,
|
|
5660
|
+
"NETWORK_ERROR"
|
|
5661
|
+
);
|
|
5662
|
+
}
|
|
5663
|
+
if (!response.ok) {
|
|
5664
|
+
const errorMessage = await parseErrorResponse2(response);
|
|
5665
|
+
const status = response.status;
|
|
5666
|
+
if (status === 400) {
|
|
5667
|
+
if (errorMessage.toLowerCase().includes("siwe")) {
|
|
5668
|
+
throw new BillingSessionError(`Invalid SIWE message: ${errorMessage}`, "INVALID_MESSAGE", status);
|
|
5669
|
+
}
|
|
5670
|
+
throw new BillingSessionError(`Bad request: ${errorMessage}`, "INVALID_MESSAGE", status);
|
|
5671
|
+
}
|
|
5672
|
+
if (status === 401) {
|
|
5673
|
+
throw new BillingSessionError(`Invalid signature: ${errorMessage}`, "INVALID_SIGNATURE", status);
|
|
5674
|
+
}
|
|
5675
|
+
throw new BillingSessionError(`Login failed: ${errorMessage}`, "UNKNOWN", status);
|
|
5676
|
+
}
|
|
5677
|
+
const data = await response.json();
|
|
5678
|
+
return {
|
|
5679
|
+
success: data.success,
|
|
5680
|
+
address: data.address
|
|
5681
|
+
};
|
|
5682
|
+
}
|
|
5683
|
+
async function getBillingApiSession(config) {
|
|
5684
|
+
let response;
|
|
5685
|
+
try {
|
|
5686
|
+
response = await fetch(`${config.baseUrl}/auth/session`, {
|
|
5687
|
+
method: "GET",
|
|
5688
|
+
credentials: "include",
|
|
5689
|
+
// Include cookies for session management
|
|
5690
|
+
headers: {
|
|
5691
|
+
"Content-Type": "application/json"
|
|
5692
|
+
}
|
|
5693
|
+
});
|
|
5694
|
+
} catch {
|
|
5695
|
+
return {
|
|
5696
|
+
authenticated: false
|
|
5697
|
+
};
|
|
5698
|
+
}
|
|
5699
|
+
if (response.status === 401) {
|
|
5700
|
+
return {
|
|
5701
|
+
authenticated: false
|
|
5702
|
+
};
|
|
5703
|
+
}
|
|
5704
|
+
if (!response.ok) {
|
|
5705
|
+
const errorMessage = await parseErrorResponse2(response);
|
|
5706
|
+
throw new BillingSessionError(`Failed to get session: ${errorMessage}`, "UNKNOWN", response.status);
|
|
5707
|
+
}
|
|
5708
|
+
const data = await response.json();
|
|
5709
|
+
return {
|
|
5710
|
+
authenticated: data.authenticated,
|
|
5711
|
+
address: data.address,
|
|
5712
|
+
chainId: data.chainId,
|
|
5713
|
+
authenticatedAt: data.authenticatedAt
|
|
5714
|
+
};
|
|
5715
|
+
}
|
|
5716
|
+
async function logoutFromBillingApi(config) {
|
|
5717
|
+
let response;
|
|
5718
|
+
try {
|
|
5719
|
+
response = await fetch(`${config.baseUrl}/auth/logout`, {
|
|
5720
|
+
method: "POST",
|
|
5721
|
+
credentials: "include",
|
|
5722
|
+
// Include cookies for session management
|
|
5723
|
+
headers: {
|
|
5724
|
+
"Content-Type": "application/json"
|
|
5725
|
+
}
|
|
5726
|
+
});
|
|
5727
|
+
} catch (error) {
|
|
5728
|
+
throw new BillingSessionError(
|
|
5729
|
+
`Network error connecting to ${config.baseUrl}: ${error instanceof Error ? error.message : String(error)}`,
|
|
5730
|
+
"NETWORK_ERROR"
|
|
5731
|
+
);
|
|
5732
|
+
}
|
|
5733
|
+
if (response.status === 401) {
|
|
5734
|
+
return;
|
|
5735
|
+
}
|
|
5736
|
+
if (!response.ok) {
|
|
5737
|
+
const errorMessage = await parseErrorResponse2(response);
|
|
5738
|
+
throw new BillingSessionError(`Logout failed: ${errorMessage}`, "UNKNOWN", response.status);
|
|
5739
|
+
}
|
|
5740
|
+
}
|
|
5741
|
+
|
|
5742
|
+
// src/client/common/utils/billingapi.ts
|
|
5611
5743
|
var BillingApiClient = class {
|
|
5612
|
-
constructor(config, walletClient) {
|
|
5744
|
+
constructor(config, walletClient, options = {}) {
|
|
5613
5745
|
this.config = config;
|
|
5614
5746
|
this.walletClient = walletClient;
|
|
5747
|
+
this.options = options;
|
|
5748
|
+
this.useSession = options.useSession ?? false;
|
|
5749
|
+
if (!this.useSession && !walletClient) {
|
|
5750
|
+
throw new Error("WalletClient is required when not using session authentication");
|
|
5751
|
+
}
|
|
5615
5752
|
}
|
|
5616
5753
|
/**
|
|
5617
5754
|
* Get the address of the connected wallet
|
|
5755
|
+
* Returns undefined if using session auth without a wallet client
|
|
5618
5756
|
*/
|
|
5619
5757
|
get address() {
|
|
5620
|
-
const account = this.walletClient
|
|
5758
|
+
const account = this.walletClient?.account;
|
|
5621
5759
|
if (!account) {
|
|
5622
|
-
|
|
5760
|
+
if (!this.useSession) {
|
|
5761
|
+
throw new Error("WalletClient must have an account attached");
|
|
5762
|
+
}
|
|
5763
|
+
return void 0;
|
|
5623
5764
|
}
|
|
5624
5765
|
return account.address;
|
|
5625
5766
|
}
|
|
5767
|
+
/**
|
|
5768
|
+
* Get the base URL of the billing API
|
|
5769
|
+
*/
|
|
5770
|
+
get baseUrl() {
|
|
5771
|
+
return this.config.billingApiServerURL;
|
|
5772
|
+
}
|
|
5773
|
+
// ==========================================================================
|
|
5774
|
+
// SIWE Session Methods
|
|
5775
|
+
// ==========================================================================
|
|
5776
|
+
/**
|
|
5777
|
+
* Login to the billing API using SIWE
|
|
5778
|
+
*
|
|
5779
|
+
* This establishes a session with the billing API by verifying the SIWE message
|
|
5780
|
+
* and signature. On success, a session cookie is set in the browser.
|
|
5781
|
+
*
|
|
5782
|
+
* @param request - Login request containing SIWE message and signature
|
|
5783
|
+
* @returns Login result with the authenticated address
|
|
5784
|
+
*
|
|
5785
|
+
* @example
|
|
5786
|
+
* ```typescript
|
|
5787
|
+
* const { message } = createSiweMessage({
|
|
5788
|
+
* address: userAddress,
|
|
5789
|
+
* chainId: 11155111,
|
|
5790
|
+
* domain: window.location.host,
|
|
5791
|
+
* uri: window.location.origin,
|
|
5792
|
+
* });
|
|
5793
|
+
*
|
|
5794
|
+
* const signature = await signMessageAsync({ message });
|
|
5795
|
+
* const result = await billingClient.siweLogin({ message, signature });
|
|
5796
|
+
* ```
|
|
5797
|
+
*/
|
|
5798
|
+
async siweLogin(request) {
|
|
5799
|
+
return loginToBillingApi({ baseUrl: this.baseUrl }, request);
|
|
5800
|
+
}
|
|
5801
|
+
/**
|
|
5802
|
+
* Logout from the billing API
|
|
5803
|
+
*
|
|
5804
|
+
* This destroys the current session and clears the session cookie.
|
|
5805
|
+
*/
|
|
5806
|
+
async siweLogout() {
|
|
5807
|
+
return logoutFromBillingApi({ baseUrl: this.baseUrl });
|
|
5808
|
+
}
|
|
5809
|
+
/**
|
|
5810
|
+
* Get the current session status from the billing API
|
|
5811
|
+
*
|
|
5812
|
+
* @returns Session information including authentication status and address
|
|
5813
|
+
*/
|
|
5814
|
+
async getSession() {
|
|
5815
|
+
return getBillingApiSession({ baseUrl: this.baseUrl });
|
|
5816
|
+
}
|
|
5817
|
+
/**
|
|
5818
|
+
* Check if there is a valid session
|
|
5819
|
+
*
|
|
5820
|
+
* @returns True if session is authenticated, false otherwise
|
|
5821
|
+
*/
|
|
5822
|
+
async isSessionValid() {
|
|
5823
|
+
const session = await this.getSession();
|
|
5824
|
+
return session.authenticated;
|
|
5825
|
+
}
|
|
5826
|
+
// ==========================================================================
|
|
5827
|
+
// Subscription Methods
|
|
5828
|
+
// ==========================================================================
|
|
5626
5829
|
async createSubscription(productId = "compute", options) {
|
|
5627
5830
|
const endpoint = `${this.config.billingApiServerURL}/products/${productId}/subscription`;
|
|
5628
5831
|
const body = options ? {
|
|
@@ -5641,10 +5844,72 @@ var BillingApiClient = class {
|
|
|
5641
5844
|
const endpoint = `${this.config.billingApiServerURL}/products/${productId}/subscription`;
|
|
5642
5845
|
await this.makeAuthenticatedRequest(endpoint, "DELETE", productId);
|
|
5643
5846
|
}
|
|
5847
|
+
// ==========================================================================
|
|
5848
|
+
// Internal Methods
|
|
5849
|
+
// ==========================================================================
|
|
5644
5850
|
/**
|
|
5645
5851
|
* Make an authenticated request to the billing API
|
|
5852
|
+
*
|
|
5853
|
+
* Uses session auth if useSession is true, otherwise uses EIP-712 signature auth.
|
|
5646
5854
|
*/
|
|
5647
5855
|
async makeAuthenticatedRequest(url, method, productId, body) {
|
|
5856
|
+
if (this.useSession) {
|
|
5857
|
+
return this.makeSessionAuthenticatedRequest(url, method, body);
|
|
5858
|
+
}
|
|
5859
|
+
return this.makeSignatureAuthenticatedRequest(url, method, productId, body);
|
|
5860
|
+
}
|
|
5861
|
+
/**
|
|
5862
|
+
* Make a request using session-based authentication (cookies)
|
|
5863
|
+
*/
|
|
5864
|
+
async makeSessionAuthenticatedRequest(url, method, body) {
|
|
5865
|
+
const headers = {};
|
|
5866
|
+
if (body) {
|
|
5867
|
+
headers["Content-Type"] = "application/json";
|
|
5868
|
+
}
|
|
5869
|
+
try {
|
|
5870
|
+
const response = await fetch(url, {
|
|
5871
|
+
method,
|
|
5872
|
+
credentials: "include",
|
|
5873
|
+
// Include cookies for session management
|
|
5874
|
+
headers,
|
|
5875
|
+
body: body ? JSON.stringify(body) : void 0
|
|
5876
|
+
});
|
|
5877
|
+
const status = response.status;
|
|
5878
|
+
const statusText = status >= 200 && status < 300 ? "OK" : "Error";
|
|
5879
|
+
if (status < 200 || status >= 300) {
|
|
5880
|
+
let errorBody;
|
|
5881
|
+
try {
|
|
5882
|
+
errorBody = await response.text();
|
|
5883
|
+
} catch {
|
|
5884
|
+
errorBody = statusText;
|
|
5885
|
+
}
|
|
5886
|
+
throw new Error(`BillingAPI request failed: ${status} ${statusText} - ${errorBody}`);
|
|
5887
|
+
}
|
|
5888
|
+
const responseData = await response.json();
|
|
5889
|
+
return {
|
|
5890
|
+
json: async () => responseData,
|
|
5891
|
+
text: async () => JSON.stringify(responseData)
|
|
5892
|
+
};
|
|
5893
|
+
} catch (error) {
|
|
5894
|
+
if (error.name === "TypeError" || error.message?.includes("fetch")) {
|
|
5895
|
+
throw new Error(
|
|
5896
|
+
`Failed to connect to BillingAPI at ${url}: ${error.message}
|
|
5897
|
+
Please check:
|
|
5898
|
+
1. Your internet connection
|
|
5899
|
+
2. The API server is accessible: ${this.config.billingApiServerURL}
|
|
5900
|
+
3. Firewall/proxy settings`
|
|
5901
|
+
);
|
|
5902
|
+
}
|
|
5903
|
+
throw error;
|
|
5904
|
+
}
|
|
5905
|
+
}
|
|
5906
|
+
/**
|
|
5907
|
+
* Make a request using EIP-712 signature authentication
|
|
5908
|
+
*/
|
|
5909
|
+
async makeSignatureAuthenticatedRequest(url, method, productId, body) {
|
|
5910
|
+
if (!this.walletClient) {
|
|
5911
|
+
throw new Error("WalletClient is required for signature authentication");
|
|
5912
|
+
}
|
|
5648
5913
|
const expiry = BigInt(Math.floor(Date.now() / 1e3) + 5 * 60);
|
|
5649
5914
|
const { signature } = await calculateBillingAuthSignature({
|
|
5650
5915
|
walletClient: this.walletClient,
|
|
@@ -7659,7 +7924,10 @@ function createBillingModule(config) {
|
|
|
7659
7924
|
};
|
|
7660
7925
|
}
|
|
7661
7926
|
logger.debug(`Creating subscription for ${productId}...`);
|
|
7662
|
-
const result = await billingApi.createSubscription(productId
|
|
7927
|
+
const result = await billingApi.createSubscription(productId, {
|
|
7928
|
+
successUrl: opts?.successUrl,
|
|
7929
|
+
cancelUrl: opts?.cancelUrl
|
|
7930
|
+
});
|
|
7663
7931
|
logger.debug(`Checkout URL: ${result.checkoutUrl}`);
|
|
7664
7932
|
return {
|
|
7665
7933
|
type: "checkout_created",
|
|
@@ -7751,9 +8019,22 @@ async function requestWithRetry(config) {
|
|
|
7751
8019
|
}
|
|
7752
8020
|
var BuildApiClient = class {
|
|
7753
8021
|
constructor(options) {
|
|
7754
|
-
|
|
8022
|
+
let url = options.baseUrl;
|
|
8023
|
+
while (url.endsWith("/")) {
|
|
8024
|
+
url = url.slice(0, -1);
|
|
8025
|
+
}
|
|
8026
|
+
this.baseUrl = url;
|
|
7755
8027
|
this.clientId = options.clientId;
|
|
7756
8028
|
this.walletClient = options.walletClient;
|
|
8029
|
+
this.useSession = options.useSession ?? false;
|
|
8030
|
+
this.billingSessionId = options.billingSessionId;
|
|
8031
|
+
}
|
|
8032
|
+
/**
|
|
8033
|
+
* Update the billing session ID.
|
|
8034
|
+
* Call this after logging into the billing API to enable session-based auth for builds.
|
|
8035
|
+
*/
|
|
8036
|
+
setBillingSessionId(sessionId) {
|
|
8037
|
+
this.billingSessionId = sessionId;
|
|
7757
8038
|
}
|
|
7758
8039
|
/**
|
|
7759
8040
|
* Get the address of the connected wallet
|
|
@@ -7765,8 +8046,17 @@ var BuildApiClient = class {
|
|
|
7765
8046
|
}
|
|
7766
8047
|
return account.address;
|
|
7767
8048
|
}
|
|
8049
|
+
/**
|
|
8050
|
+
* Submit a new build request.
|
|
8051
|
+
* Supports two auth modes (session auth is tried first when billingSessionId is available):
|
|
8052
|
+
* 1. Session-based auth: X-Billing-Session header (forwarded billing_session cookie)
|
|
8053
|
+
* 2. Signature-based auth: Authorization + X-Account + X-eigenx-expiry headers (requires walletClient)
|
|
8054
|
+
*/
|
|
7768
8055
|
async submitBuild(payload) {
|
|
7769
|
-
|
|
8056
|
+
if (this.useSession && this.billingSessionId) {
|
|
8057
|
+
return this.billingSessionAuthJsonRequest("/builds", "POST", payload);
|
|
8058
|
+
}
|
|
8059
|
+
return this.signatureAuthJsonRequest("/builds", "POST", payload);
|
|
7770
8060
|
}
|
|
7771
8061
|
async getBuild(buildId) {
|
|
7772
8062
|
return this.publicJsonRequest(`/builds/${encodeURIComponent(buildId)}`);
|
|
@@ -7777,8 +8067,11 @@ var BuildApiClient = class {
|
|
|
7777
8067
|
async verify(identifier) {
|
|
7778
8068
|
return this.publicJsonRequest(`/builds/verify/${encodeURIComponent(identifier)}`);
|
|
7779
8069
|
}
|
|
8070
|
+
/**
|
|
8071
|
+
* Get build logs. Supports session auth (identity verification only, no billing check).
|
|
8072
|
+
*/
|
|
7780
8073
|
async getLogs(buildId) {
|
|
7781
|
-
return this.
|
|
8074
|
+
return this.sessionOrSignatureTextRequest(`/builds/${encodeURIComponent(buildId)}/logs`);
|
|
7782
8075
|
}
|
|
7783
8076
|
async listBuilds(params) {
|
|
7784
8077
|
const res = await requestWithRetry({
|
|
@@ -7786,7 +8079,9 @@ var BuildApiClient = class {
|
|
|
7786
8079
|
method: "GET",
|
|
7787
8080
|
params,
|
|
7788
8081
|
headers: this.clientId ? { "x-client-id": this.clientId } : void 0,
|
|
7789
|
-
timeout: 6e4
|
|
8082
|
+
timeout: 6e4,
|
|
8083
|
+
validateStatus: () => true,
|
|
8084
|
+
withCredentials: this.useSession
|
|
7790
8085
|
});
|
|
7791
8086
|
if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
|
|
7792
8087
|
return res.data;
|
|
@@ -7796,12 +8091,18 @@ var BuildApiClient = class {
|
|
|
7796
8091
|
url: `${this.baseUrl}${path8}`,
|
|
7797
8092
|
method: "GET",
|
|
7798
8093
|
headers: this.clientId ? { "x-client-id": this.clientId } : void 0,
|
|
7799
|
-
timeout: 6e4
|
|
8094
|
+
timeout: 6e4,
|
|
8095
|
+
validateStatus: () => true,
|
|
8096
|
+
withCredentials: this.useSession
|
|
7800
8097
|
});
|
|
7801
8098
|
if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
|
|
7802
8099
|
return res.data;
|
|
7803
8100
|
}
|
|
7804
|
-
|
|
8101
|
+
/**
|
|
8102
|
+
* Make a request that ALWAYS requires signature auth (for billing verification).
|
|
8103
|
+
* Used for endpoints like POST /builds that need to verify subscription status.
|
|
8104
|
+
*/
|
|
8105
|
+
async signatureAuthJsonRequest(path8, method, body) {
|
|
7805
8106
|
if (!this.walletClient?.account) {
|
|
7806
8107
|
throw new Error("WalletClient with account required for authenticated requests");
|
|
7807
8108
|
}
|
|
@@ -7823,32 +8124,69 @@ var BuildApiClient = class {
|
|
|
7823
8124
|
method,
|
|
7824
8125
|
headers,
|
|
7825
8126
|
data: body,
|
|
7826
|
-
timeout: 6e4
|
|
8127
|
+
timeout: 6e4,
|
|
8128
|
+
validateStatus: () => true,
|
|
8129
|
+
withCredentials: this.useSession
|
|
7827
8130
|
});
|
|
7828
8131
|
if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
|
|
7829
8132
|
return res.data;
|
|
7830
8133
|
}
|
|
7831
|
-
|
|
7832
|
-
|
|
7833
|
-
|
|
8134
|
+
/**
|
|
8135
|
+
* Make a request using billing session auth (for billing verification without wallet signature).
|
|
8136
|
+
* Forwards the billing_session cookie value via X-Billing-Session header.
|
|
8137
|
+
* Used for endpoints that need to verify subscription status when using session-based auth.
|
|
8138
|
+
*/
|
|
8139
|
+
async billingSessionAuthJsonRequest(path8, method, body) {
|
|
8140
|
+
if (!this.billingSessionId) {
|
|
8141
|
+
throw new Error("billingSessionId required for session-based billing auth");
|
|
7834
8142
|
}
|
|
7835
|
-
const headers = {
|
|
8143
|
+
const headers = {
|
|
8144
|
+
"Content-Type": "application/json",
|
|
8145
|
+
"X-Billing-Session": this.billingSessionId
|
|
8146
|
+
};
|
|
7836
8147
|
if (this.clientId) headers["x-client-id"] = this.clientId;
|
|
7837
|
-
const
|
|
7838
|
-
|
|
7839
|
-
|
|
7840
|
-
|
|
7841
|
-
|
|
8148
|
+
const res = await requestWithRetry({
|
|
8149
|
+
url: `${this.baseUrl}${path8}`,
|
|
8150
|
+
method,
|
|
8151
|
+
headers,
|
|
8152
|
+
data: body,
|
|
8153
|
+
timeout: 6e4,
|
|
8154
|
+
validateStatus: () => true,
|
|
8155
|
+
withCredentials: this.useSession
|
|
7842
8156
|
});
|
|
7843
|
-
|
|
7844
|
-
|
|
7845
|
-
|
|
8157
|
+
if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
|
|
8158
|
+
return res.data;
|
|
8159
|
+
}
|
|
8160
|
+
/**
|
|
8161
|
+
* Make an authenticated request that can use session OR signature auth.
|
|
8162
|
+
* When useSession is true, relies on cookies for identity verification.
|
|
8163
|
+
* Used for endpoints that only need identity verification (not billing).
|
|
8164
|
+
*/
|
|
8165
|
+
async sessionOrSignatureTextRequest(path8) {
|
|
8166
|
+
const headers = {};
|
|
8167
|
+
if (this.clientId) headers["x-client-id"] = this.clientId;
|
|
8168
|
+
if (!this.useSession) {
|
|
8169
|
+
if (!this.walletClient?.account) {
|
|
8170
|
+
throw new Error("WalletClient with account required for authenticated requests");
|
|
8171
|
+
}
|
|
8172
|
+
const expiry = BigInt(Math.floor(Date.now() / 1e3) + 60);
|
|
8173
|
+
const { signature } = await calculateBillingAuthSignature({
|
|
8174
|
+
walletClient: this.walletClient,
|
|
8175
|
+
product: "compute",
|
|
8176
|
+
expiry
|
|
8177
|
+
});
|
|
8178
|
+
headers.Authorization = `Bearer ${signature}`;
|
|
8179
|
+
headers["X-eigenx-expiry"] = expiry.toString();
|
|
8180
|
+
headers["X-Account"] = this.address;
|
|
8181
|
+
}
|
|
7846
8182
|
const res = await requestWithRetry({
|
|
7847
8183
|
url: `${this.baseUrl}${path8}`,
|
|
7848
8184
|
method: "GET",
|
|
7849
8185
|
headers,
|
|
7850
8186
|
timeout: 6e4,
|
|
7851
|
-
responseType: "text"
|
|
8187
|
+
responseType: "text",
|
|
8188
|
+
validateStatus: () => true,
|
|
8189
|
+
withCredentials: this.useSession
|
|
7852
8190
|
});
|
|
7853
8191
|
if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
|
|
7854
8192
|
return typeof res.data === "string" ? res.data : JSON.stringify(res.data);
|
|
@@ -8415,6 +8753,9 @@ function isSiweMessageNotYetValid(params) {
|
|
|
8415
8753
|
return /* @__PURE__ */ new Date() < params.notBefore;
|
|
8416
8754
|
}
|
|
8417
8755
|
|
|
8756
|
+
// src/client/common/auth/index.ts
|
|
8757
|
+
init_session();
|
|
8758
|
+
|
|
8418
8759
|
// src/client/common/utils/instance.ts
|
|
8419
8760
|
async function getCurrentInstanceType(preflightCtx, appID, logger, clientId) {
|
|
8420
8761
|
try {
|