@layr-labs/ecloud-sdk 0.2.1-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/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, {
@@ -42,6 +174,7 @@ __export(index_exports, {
42
174
  NotFoundError: () => NotFoundError,
43
175
  PRIMARY_LANGUAGES: () => PRIMARY_LANGUAGES,
44
176
  PostHogClient: () => PostHogClient,
177
+ SessionError: () => SessionError,
45
178
  TimeoutError: () => TimeoutError,
46
179
  UserApiClient: () => UserApiClient,
47
180
  addHexPrefix: () => addHexPrefix,
@@ -58,6 +191,7 @@ __export(index_exports, {
58
191
  createComputeModule: () => createComputeModule,
59
192
  createECloudClient: () => createECloudClient,
60
193
  createMetricsContext: () => createMetricsContext,
194
+ createSiweMessage: () => createSiweMessage,
61
195
  createTelemetryClient: () => createTelemetryClient,
62
196
  createViemClients: () => createClients,
63
197
  deleteLegacyPrivateKey: () => deleteLegacyPrivateKey,
@@ -74,6 +208,7 @@ __export(index_exports, {
74
208
  fetchTemplateCatalog: () => fetchTemplateCatalog,
75
209
  formatETH: () => formatETH,
76
210
  generateNewPrivateKey: () => generateNewPrivateKey,
211
+ generateNonce: () => generateNonce,
77
212
  getAddressFromPrivateKey: () => getAddressFromPrivateKey,
78
213
  getAllAppsByDeveloper: () => getAllAppsByDeveloper,
79
214
  getAppLatestReleaseBlockNumbers: () => getAppLatestReleaseBlockNumbers,
@@ -84,6 +219,7 @@ __export(index_exports, {
84
219
  getBuildType: () => getBuildType,
85
220
  getCategoryDescriptions: () => getCategoryDescriptions,
86
221
  getChainFromID: () => getChainFromID,
222
+ getComputeApiSession: () => getComputeApiSession,
87
223
  getCurrentInstanceType: () => getCurrentInstanceType,
88
224
  getEnvironmentConfig: () => getEnvironmentConfig,
89
225
  getLegacyKeys: () => getLegacyKeys,
@@ -96,10 +232,17 @@ __export(index_exports, {
96
232
  isEnvironmentAvailable: () => isEnvironmentAvailable,
97
233
  isMainnet: () => isMainnet,
98
234
  isNoopClient: () => isNoopClient,
235
+ isSessionValid: () => isSessionValid,
236
+ isSiweMessageExpired: () => isSiweMessageExpired,
237
+ isSiweMessageNotYetValid: () => isSiweMessageNotYetValid,
99
238
  isSubscriptionActive: () => isSubscriptionActive,
100
239
  keyExists: () => keyExists,
101
240
  listStoredKeys: () => listStoredKeys,
241
+ loginToComputeApi: () => loginToComputeApi,
242
+ logoutFromComputeApi: () => logoutFromComputeApi,
102
243
  logs: () => logs,
244
+ noopLogger: () => noopLogger,
245
+ parseSiweMessage: () => parseSiweMessage,
103
246
  prepareDeploy: () => prepareDeploy,
104
247
  prepareDeployFromVerifiableBuild: () => prepareDeployFromVerifiableBuild,
105
248
  prepareUpgrade: () => prepareUpgrade,
@@ -1237,6 +1380,18 @@ function extractRegistryNameNoDocker(imageRef) {
1237
1380
  // src/client/common/contract/eip7702.ts
1238
1381
  var import_viem = require("viem");
1239
1382
 
1383
+ // src/client/common/types/index.ts
1384
+ var noopLogger = {
1385
+ debug: () => {
1386
+ },
1387
+ info: () => {
1388
+ },
1389
+ warn: () => {
1390
+ },
1391
+ error: () => {
1392
+ }
1393
+ };
1394
+
1240
1395
  // src/client/common/abis/ERC7702Delegator.json
1241
1396
  var ERC7702Delegator_default = [
1242
1397
  {
@@ -2322,7 +2477,7 @@ async function checkERC7702Delegation(publicClient, account, delegatorAddress) {
2322
2477
  const expectedCode = `0xef0100${delegatorAddress.slice(2)}`;
2323
2478
  return code.toLowerCase() === expectedCode.toLowerCase();
2324
2479
  }
2325
- async function executeBatch(options, logger) {
2480
+ async function executeBatch(options, logger = noopLogger) {
2326
2481
  const { walletClient, publicClient, environmentConfig, executions, pendingMessage, gas } = options;
2327
2482
  const account = walletClient.account;
2328
2483
  if (!account) {
@@ -4027,7 +4182,7 @@ async function calculateAppID(options) {
4027
4182
  });
4028
4183
  return appID;
4029
4184
  }
4030
- async function prepareDeployBatch(options, logger) {
4185
+ async function prepareDeployBatch(options, logger = noopLogger) {
4031
4186
  const { walletClient, publicClient, environmentConfig, salt, release, publicLogs } = options;
4032
4187
  const account = walletClient.account;
4033
4188
  if (!account) {
@@ -4107,7 +4262,7 @@ async function prepareDeployBatch(options, logger) {
4107
4262
  environmentConfig
4108
4263
  };
4109
4264
  }
4110
- async function executeDeployBatch(data, context, gas, logger) {
4265
+ async function executeDeployBatch(data, context, gas, logger = noopLogger) {
4111
4266
  const pendingMessage = "Deploying new app...";
4112
4267
  const txHash = await executeBatch(
4113
4268
  {
@@ -4122,7 +4277,7 @@ async function executeDeployBatch(data, context, gas, logger) {
4122
4277
  );
4123
4278
  return { appId: data.appId, txHash };
4124
4279
  }
4125
- async function deployApp(options, logger) {
4280
+ async function deployApp(options, logger = noopLogger) {
4126
4281
  const prepared = await prepareDeployBatch(options, logger);
4127
4282
  const data = {
4128
4283
  appId: prepared.appId,
@@ -4137,7 +4292,15 @@ async function deployApp(options, logger) {
4137
4292
  return executeDeployBatch(data, context, options.gas, logger);
4138
4293
  }
4139
4294
  async function prepareUpgradeBatch(options) {
4140
- const { walletClient, publicClient, environmentConfig, appID, release, publicLogs, needsPermissionChange } = options;
4295
+ const {
4296
+ walletClient,
4297
+ publicClient,
4298
+ environmentConfig,
4299
+ appID,
4300
+ release,
4301
+ publicLogs,
4302
+ needsPermissionChange
4303
+ } = options;
4141
4304
  const releaseForViem = {
4142
4305
  rmsRelease: {
4143
4306
  artifacts: release.rmsRelease.artifacts.map((artifact) => ({
@@ -4210,7 +4373,7 @@ async function prepareUpgradeBatch(options) {
4210
4373
  environmentConfig
4211
4374
  };
4212
4375
  }
4213
- async function executeUpgradeBatch(data, context, gas, logger) {
4376
+ async function executeUpgradeBatch(data, context, gas, logger = noopLogger) {
4214
4377
  const pendingMessage = `Upgrading app ${data.appId}...`;
4215
4378
  const txHash = await executeBatch(
4216
4379
  {
@@ -4225,7 +4388,7 @@ async function executeUpgradeBatch(data, context, gas, logger) {
4225
4388
  );
4226
4389
  return txHash;
4227
4390
  }
4228
- async function upgradeApp(options, logger) {
4391
+ async function upgradeApp(options, logger = noopLogger) {
4229
4392
  const prepared = await prepareUpgradeBatch(options);
4230
4393
  const data = {
4231
4394
  appId: prepared.appId,
@@ -4238,8 +4401,18 @@ async function upgradeApp(options, logger) {
4238
4401
  };
4239
4402
  return executeUpgradeBatch(data, context, options.gas, logger);
4240
4403
  }
4241
- async function sendAndWaitForTransaction(options, logger) {
4242
- const { walletClient, publicClient, environmentConfig, to, data, value = 0n, pendingMessage, txDescription, gas } = options;
4404
+ async function sendAndWaitForTransaction(options, logger = noopLogger) {
4405
+ const {
4406
+ walletClient,
4407
+ publicClient,
4408
+ environmentConfig,
4409
+ to,
4410
+ data,
4411
+ value = 0n,
4412
+ pendingMessage,
4413
+ txDescription,
4414
+ gas
4415
+ } = options;
4243
4416
  const account = walletClient.account;
4244
4417
  if (!account) {
4245
4418
  throw new Error("WalletClient must have an account attached");
@@ -4359,7 +4532,13 @@ async function getAllAppsByDeveloper(publicClient, env, developer, pageSize = 10
4359
4532
  const allApps = [];
4360
4533
  const allConfigs = [];
4361
4534
  while (true) {
4362
- const { apps, appConfigs } = await getAppsByDeveloper(publicClient, env, developer, offset, pageSize);
4535
+ const { apps, appConfigs } = await getAppsByDeveloper(
4536
+ publicClient,
4537
+ env,
4538
+ developer,
4539
+ offset,
4540
+ pageSize
4541
+ );
4363
4542
  if (apps.length === 0) break;
4364
4543
  allApps.push(...apps);
4365
4544
  allConfigs.push(...appConfigs);
@@ -4415,7 +4594,7 @@ async function isDelegated(options) {
4415
4594
  environmentConfig.erc7702DelegatorAddress
4416
4595
  );
4417
4596
  }
4418
- async function undelegate(options, logger) {
4597
+ async function undelegate(options, logger = noopLogger) {
4419
4598
  const { walletClient, publicClient, environmentConfig } = options;
4420
4599
  const account = walletClient.account;
4421
4600
  if (!account) {
@@ -4514,6 +4693,7 @@ async function calculateBillingAuthSignature(options) {
4514
4693
  }
4515
4694
 
4516
4695
  // src/client/common/utils/userapi.ts
4696
+ init_session();
4517
4697
  function isJsonObject(value) {
4518
4698
  return typeof value === "object" && value !== null && !Array.isArray(value);
4519
4699
  }
@@ -4530,15 +4710,16 @@ var CanViewAppLogsPermission = "0x2fd3f2fe";
4530
4710
  var CanViewSensitiveAppInfoPermission = "0x0e67b22f";
4531
4711
  var CanUpdateAppProfilePermission = "0x036fef61";
4532
4712
  function getDefaultClientId() {
4533
- const version = true ? "0.2.1-dev" : "0.0.0";
4713
+ const version = true ? "0.3.0-dev" : "0.0.0";
4534
4714
  return `ecloud-sdk/v${version}`;
4535
4715
  }
4536
4716
  var UserApiClient = class {
4537
- constructor(config, walletClient, publicClient, clientId) {
4717
+ constructor(config, walletClient, publicClient, options) {
4538
4718
  this.config = config;
4539
4719
  this.walletClient = walletClient;
4540
4720
  this.publicClient = publicClient;
4541
- this.clientId = clientId || getDefaultClientId();
4721
+ this.clientId = options?.clientId || getDefaultClientId();
4722
+ this.useSession = options?.useSession ?? false;
4542
4723
  }
4543
4724
  /**
4544
4725
  * Get the address of the connected wallet
@@ -4626,7 +4807,7 @@ var UserApiClient = class {
4626
4807
  const apps = result.apps || result.Apps || [];
4627
4808
  return apps.map((app, i) => ({
4628
4809
  address: app.address || appIDs[i],
4629
- status: app.status || app.Status || ""
4810
+ status: app.app_status || app.App_Status || ""
4630
4811
  }));
4631
4812
  }
4632
4813
  /**
@@ -4658,9 +4839,11 @@ var UserApiClient = class {
4658
4839
  const headers = {
4659
4840
  "x-client-id": this.clientId
4660
4841
  };
4661
- const expiry = BigInt(Math.floor(Date.now() / 1e3) + 5 * 60);
4662
- const authHeaders = await this.generateAuthHeaders(CanUpdateAppProfilePermission, expiry);
4663
- Object.assign(headers, authHeaders);
4842
+ if (!this.useSession) {
4843
+ const expiry = BigInt(Math.floor(Date.now() / 1e3) + 5 * 60);
4844
+ const authHeaders = await this.generateAuthHeaders(CanUpdateAppProfilePermission, expiry);
4845
+ Object.assign(headers, authHeaders);
4846
+ }
4664
4847
  try {
4665
4848
  const response = await import_axios.default.post(endpoint, formData, {
4666
4849
  headers,
@@ -4669,8 +4852,10 @@ var UserApiClient = class {
4669
4852
  // Don't throw on any status
4670
4853
  maxContentLength: Infinity,
4671
4854
  // Allow large file uploads
4672
- maxBodyLength: Infinity
4855
+ maxBodyLength: Infinity,
4673
4856
  // Allow large file uploads
4857
+ withCredentials: true
4858
+ // Include cookies for session auth
4674
4859
  });
4675
4860
  const status = response.status;
4676
4861
  if (status !== 200 && status !== 201) {
@@ -4704,7 +4889,7 @@ Please check:
4704
4889
  const headers = {
4705
4890
  "x-client-id": this.clientId
4706
4891
  };
4707
- if (permission) {
4892
+ if (permission && !this.useSession) {
4708
4893
  const expiry = BigInt(Math.floor(Date.now() / 1e3) + 5 * 60);
4709
4894
  const authHeaders = await this.generateAuthHeaders(permission, expiry);
4710
4895
  Object.assign(headers, authHeaders);
@@ -4713,8 +4898,10 @@ Please check:
4713
4898
  const response = await import_axios.default.get(url, {
4714
4899
  headers,
4715
4900
  maxRedirects: 0,
4716
- validateStatus: () => true
4901
+ validateStatus: () => true,
4717
4902
  // Don't throw on any status
4903
+ withCredentials: true
4904
+ // Include cookies for session auth
4718
4905
  });
4719
4906
  const status = response.status;
4720
4907
  const statusText = status >= 200 && status < 300 ? "OK" : "Error";
@@ -4756,6 +4943,65 @@ Please check:
4756
4943
  "X-eigenx-expiry": expiry.toString()
4757
4944
  };
4758
4945
  }
4946
+ // ==========================================================================
4947
+ // SIWE Session Management
4948
+ // ==========================================================================
4949
+ /**
4950
+ * Login to the compute API using SIWE (Sign-In with Ethereum)
4951
+ *
4952
+ * This establishes a session with the compute API by verifying the SIWE message
4953
+ * and signature. On success, a session cookie is set in the browser.
4954
+ *
4955
+ * @param request - Login request containing SIWE message and signature
4956
+ * @returns Login result with the authenticated address
4957
+ *
4958
+ * @example
4959
+ * ```typescript
4960
+ * import { createSiweMessage } from "@layr-labs/ecloud-sdk/browser";
4961
+ *
4962
+ * const { message } = createSiweMessage({
4963
+ * address: userAddress,
4964
+ * chainId: 11155111,
4965
+ * domain: window.location.host,
4966
+ * uri: window.location.origin,
4967
+ * });
4968
+ *
4969
+ * const signature = await signMessageAsync({ message });
4970
+ * const result = await client.siweLogin({ message, signature });
4971
+ * ```
4972
+ */
4973
+ async siweLogin(request) {
4974
+ return loginToComputeApi({ baseUrl: this.config.userApiServerURL }, request);
4975
+ }
4976
+ /**
4977
+ * Logout from the compute API
4978
+ *
4979
+ * This destroys the current session and clears the session cookie.
4980
+ *
4981
+ * @example
4982
+ * ```typescript
4983
+ * await client.siweLogout();
4984
+ * ```
4985
+ */
4986
+ async siweLogout() {
4987
+ return logoutFromComputeApi({ baseUrl: this.config.userApiServerURL });
4988
+ }
4989
+ /**
4990
+ * Get the current SIWE session status from the compute API
4991
+ *
4992
+ * @returns Session information including authentication status and address
4993
+ *
4994
+ * @example
4995
+ * ```typescript
4996
+ * const session = await client.getSiweSession();
4997
+ * if (session.authenticated) {
4998
+ * console.log(`Logged in as ${session.address}`);
4999
+ * }
5000
+ * ```
5001
+ */
5002
+ async getSiweSession() {
5003
+ return getComputeApiSession({ baseUrl: this.config.userApiServerURL });
5004
+ }
4759
5005
  };
4760
5006
  function transformAppReleaseBuild(raw) {
4761
5007
  if (!isJsonObject(raw)) return void 0;
@@ -5372,24 +5618,221 @@ function isSubscriptionActive(status) {
5372
5618
 
5373
5619
  // src/client/common/utils/billingapi.ts
5374
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
5375
5743
  var BillingApiClient = class {
5376
- constructor(config, walletClient) {
5744
+ constructor(config, walletClient, options = {}) {
5377
5745
  this.config = config;
5378
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
+ }
5379
5752
  }
5380
5753
  /**
5381
5754
  * Get the address of the connected wallet
5755
+ * Returns undefined if using session auth without a wallet client
5382
5756
  */
5383
5757
  get address() {
5384
- const account = this.walletClient.account;
5758
+ const account = this.walletClient?.account;
5385
5759
  if (!account) {
5386
- throw new Error("WalletClient must have an account attached");
5760
+ if (!this.useSession) {
5761
+ throw new Error("WalletClient must have an account attached");
5762
+ }
5763
+ return void 0;
5387
5764
  }
5388
5765
  return account.address;
5389
5766
  }
5390
- async createSubscription(productId = "compute") {
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
+ // ==========================================================================
5829
+ async createSubscription(productId = "compute", options) {
5391
5830
  const endpoint = `${this.config.billingApiServerURL}/products/${productId}/subscription`;
5392
- const resp = await this.makeAuthenticatedRequest(endpoint, "POST", productId);
5831
+ const body = options ? {
5832
+ success_url: options.successUrl,
5833
+ cancel_url: options.cancelUrl
5834
+ } : void 0;
5835
+ const resp = await this.makeAuthenticatedRequest(endpoint, "POST", productId, body);
5393
5836
  return resp.json();
5394
5837
  }
5395
5838
  async getSubscription(productId = "compute") {
@@ -5401,10 +5844,72 @@ var BillingApiClient = class {
5401
5844
  const endpoint = `${this.config.billingApiServerURL}/products/${productId}/subscription`;
5402
5845
  await this.makeAuthenticatedRequest(endpoint, "DELETE", productId);
5403
5846
  }
5847
+ // ==========================================================================
5848
+ // Internal Methods
5849
+ // ==========================================================================
5404
5850
  /**
5405
5851
  * Make an authenticated request to the billing API
5852
+ *
5853
+ * Uses session auth if useSession is true, otherwise uses EIP-712 signature auth.
5854
+ */
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)
5406
5863
  */
5407
- async makeAuthenticatedRequest(url, method, productId) {
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
+ }
5408
5913
  const expiry = BigInt(Math.floor(Date.now() / 1e3) + 5 * 60);
5409
5914
  const { signature } = await calculateBillingAuthSignature({
5410
5915
  walletClient: this.walletClient,
@@ -5416,11 +5921,15 @@ var BillingApiClient = class {
5416
5921
  "X-Account": this.address,
5417
5922
  "X-Expiry": expiry.toString()
5418
5923
  };
5924
+ if (body) {
5925
+ headers["Content-Type"] = "application/json";
5926
+ }
5419
5927
  try {
5420
5928
  const response = await (0, import_axios2.default)({
5421
5929
  method,
5422
5930
  url,
5423
5931
  headers,
5932
+ data: body,
5424
5933
  timeout: 3e4,
5425
5934
  maxRedirects: 0,
5426
5935
  validateStatus: () => true
@@ -5429,8 +5938,8 @@ var BillingApiClient = class {
5429
5938
  const status = response.status;
5430
5939
  const statusText = status >= 200 && status < 300 ? "OK" : "Error";
5431
5940
  if (status < 200 || status >= 300) {
5432
- const body = typeof response.data === "string" ? response.data : JSON.stringify(response.data);
5433
- throw new Error(`BillingAPI request failed: ${status} ${statusText} - ${body}`);
5941
+ const body2 = typeof response.data === "string" ? response.data : JSON.stringify(response.data);
5942
+ throw new Error(`BillingAPI request failed: ${status} ${statusText} - ${body2}`);
5434
5943
  }
5435
5944
  return {
5436
5945
  json: async () => response.data,
@@ -6916,7 +7425,7 @@ async function logs(options, walletClient, publicClient, environmentConfig, logg
6916
7425
  environmentConfig,
6917
7426
  walletClient,
6918
7427
  publicClient,
6919
- options.clientId
7428
+ options.clientId ? { clientId: options.clientId } : void 0
6920
7429
  );
6921
7430
  let logsText;
6922
7431
  let logsError = null;
@@ -7215,7 +7724,7 @@ function createAppModule(ctx) {
7215
7724
  environment,
7216
7725
  walletClient,
7217
7726
  publicClient,
7218
- ctx.clientId
7727
+ ctx.clientId ? { clientId: ctx.clientId } : void 0
7219
7728
  );
7220
7729
  return userApiClient.uploadAppProfile(appId, profile.name, {
7221
7730
  website: profile.website,
@@ -7415,7 +7924,10 @@ function createBillingModule(config) {
7415
7924
  };
7416
7925
  }
7417
7926
  logger.debug(`Creating subscription for ${productId}...`);
7418
- const result = await billingApi.createSubscription(productId);
7927
+ const result = await billingApi.createSubscription(productId, {
7928
+ successUrl: opts?.successUrl,
7929
+ cancelUrl: opts?.cancelUrl
7930
+ });
7419
7931
  logger.debug(`Checkout URL: ${result.checkoutUrl}`);
7420
7932
  return {
7421
7933
  type: "checkout_created",
@@ -7474,11 +7986,55 @@ function createBillingModule(config) {
7474
7986
 
7475
7987
  // src/client/common/utils/buildapi.ts
7476
7988
  var import_axios3 = __toESM(require("axios"), 1);
7989
+ var MAX_RETRIES = 5;
7990
+ var INITIAL_BACKOFF_MS = 1e3;
7991
+ var MAX_BACKOFF_MS = 3e4;
7992
+ async function sleep2(ms) {
7993
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
7994
+ }
7995
+ function getRetryDelay(res, attempt) {
7996
+ const retryAfter = res.headers["retry-after"];
7997
+ if (retryAfter) {
7998
+ const seconds = parseInt(retryAfter, 10);
7999
+ if (!isNaN(seconds)) {
8000
+ return Math.min(seconds * 1e3, MAX_BACKOFF_MS);
8001
+ }
8002
+ }
8003
+ return Math.min(INITIAL_BACKOFF_MS * Math.pow(2, attempt), MAX_BACKOFF_MS);
8004
+ }
8005
+ async function requestWithRetry(config) {
8006
+ let lastResponse;
8007
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
8008
+ const res = await (0, import_axios3.default)({ ...config, validateStatus: () => true });
8009
+ lastResponse = res;
8010
+ if (res.status !== 429) {
8011
+ return res;
8012
+ }
8013
+ if (attempt < MAX_RETRIES) {
8014
+ const delay = getRetryDelay(res, attempt);
8015
+ await sleep2(delay);
8016
+ }
8017
+ }
8018
+ return lastResponse;
8019
+ }
7477
8020
  var BuildApiClient = class {
7478
8021
  constructor(options) {
7479
- this.baseUrl = options.baseUrl.replace(/\/+$/, "");
8022
+ let url = options.baseUrl;
8023
+ while (url.endsWith("/")) {
8024
+ url = url.slice(0, -1);
8025
+ }
8026
+ this.baseUrl = url;
7480
8027
  this.clientId = options.clientId;
7481
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;
7482
8038
  }
7483
8039
  /**
7484
8040
  * Get the address of the connected wallet
@@ -7490,8 +8046,17 @@ var BuildApiClient = class {
7490
8046
  }
7491
8047
  return account.address;
7492
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
+ */
7493
8055
  async submitBuild(payload) {
7494
- return this.authenticatedJsonRequest("/builds", "POST", payload);
8056
+ if (this.useSession && this.billingSessionId) {
8057
+ return this.billingSessionAuthJsonRequest("/builds", "POST", payload);
8058
+ }
8059
+ return this.signatureAuthJsonRequest("/builds", "POST", payload);
7495
8060
  }
7496
8061
  async getBuild(buildId) {
7497
8062
  return this.publicJsonRequest(`/builds/${encodeURIComponent(buildId)}`);
@@ -7502,33 +8067,42 @@ var BuildApiClient = class {
7502
8067
  async verify(identifier) {
7503
8068
  return this.publicJsonRequest(`/builds/verify/${encodeURIComponent(identifier)}`);
7504
8069
  }
8070
+ /**
8071
+ * Get build logs. Supports session auth (identity verification only, no billing check).
8072
+ */
7505
8073
  async getLogs(buildId) {
7506
- return this.authenticatedTextRequest(`/builds/${encodeURIComponent(buildId)}/logs`);
8074
+ return this.sessionOrSignatureTextRequest(`/builds/${encodeURIComponent(buildId)}/logs`);
7507
8075
  }
7508
8076
  async listBuilds(params) {
7509
- const res = await (0, import_axios3.default)({
8077
+ const res = await requestWithRetry({
7510
8078
  url: `${this.baseUrl}/builds`,
7511
8079
  method: "GET",
7512
8080
  params,
7513
8081
  headers: this.clientId ? { "x-client-id": this.clientId } : void 0,
7514
8082
  timeout: 6e4,
7515
- validateStatus: () => true
8083
+ validateStatus: () => true,
8084
+ withCredentials: this.useSession
7516
8085
  });
7517
8086
  if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
7518
8087
  return res.data;
7519
8088
  }
7520
8089
  async publicJsonRequest(path8) {
7521
- const res = await (0, import_axios3.default)({
8090
+ const res = await requestWithRetry({
7522
8091
  url: `${this.baseUrl}${path8}`,
7523
8092
  method: "GET",
7524
8093
  headers: this.clientId ? { "x-client-id": this.clientId } : void 0,
7525
8094
  timeout: 6e4,
7526
- validateStatus: () => true
8095
+ validateStatus: () => true,
8096
+ withCredentials: this.useSession
7527
8097
  });
7528
8098
  if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
7529
8099
  return res.data;
7530
8100
  }
7531
- async authenticatedJsonRequest(path8, method, body) {
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) {
7532
8106
  if (!this.walletClient?.account) {
7533
8107
  throw new Error("WalletClient with account required for authenticated requests");
7534
8108
  }
@@ -7545,39 +8119,74 @@ var BuildApiClient = class {
7545
8119
  headers.Authorization = `Bearer ${signature}`;
7546
8120
  headers["X-eigenx-expiry"] = expiry.toString();
7547
8121
  headers["X-Account"] = this.address;
7548
- const res = await (0, import_axios3.default)({
8122
+ const res = await requestWithRetry({
7549
8123
  url: `${this.baseUrl}${path8}`,
7550
8124
  method,
7551
8125
  headers,
7552
8126
  data: body,
7553
8127
  timeout: 6e4,
7554
- validateStatus: () => true
8128
+ validateStatus: () => true,
8129
+ withCredentials: this.useSession
7555
8130
  });
7556
8131
  if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
7557
8132
  return res.data;
7558
8133
  }
7559
- async authenticatedTextRequest(path8) {
7560
- if (!this.walletClient?.account) {
7561
- throw new Error("WalletClient with account required for authenticated requests");
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");
7562
8142
  }
7563
- const headers = {};
8143
+ const headers = {
8144
+ "Content-Type": "application/json",
8145
+ "X-Billing-Session": this.billingSessionId
8146
+ };
7564
8147
  if (this.clientId) headers["x-client-id"] = this.clientId;
7565
- const expiry = BigInt(Math.floor(Date.now() / 1e3) + 60);
7566
- const { signature } = await calculateBillingAuthSignature({
7567
- walletClient: this.walletClient,
7568
- product: "compute",
7569
- expiry
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
7570
8156
  });
7571
- headers.Authorization = `Bearer ${signature}`;
7572
- headers["X-eigenx-expiry"] = expiry.toString();
7573
- headers["X-Account"] = this.address;
7574
- const res = await (0, import_axios3.default)({
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
+ }
8182
+ const res = await requestWithRetry({
7575
8183
  url: `${this.baseUrl}${path8}`,
7576
8184
  method: "GET",
7577
8185
  headers,
7578
8186
  timeout: 6e4,
7579
8187
  responseType: "text",
7580
- validateStatus: () => true
8188
+ validateStatus: () => true,
8189
+ withCredentials: this.useSession
7581
8190
  });
7582
8191
  if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
7583
8192
  return typeof res.data === "string" ? res.data : JSON.stringify(res.data);
@@ -7766,7 +8375,7 @@ function createBuildModule(config) {
7766
8375
  if (build.status === BUILD_STATUS.FAILED) {
7767
8376
  throw new BuildFailedError(build.errorMessage ?? "Build failed", buildId);
7768
8377
  }
7769
- await sleep2(pollIntervalMs);
8378
+ await sleep3(pollIntervalMs);
7770
8379
  }
7771
8380
  },
7772
8381
  async *streamLogs(buildId, pollIntervalMs = DEFAULT_POLL_INTERVAL) {
@@ -7788,12 +8397,12 @@ function createBuildModule(config) {
7788
8397
  lastLength = logs2.length;
7789
8398
  }
7790
8399
  if (build.status !== BUILD_STATUS.BUILDING) break;
7791
- await sleep2(pollIntervalMs);
8400
+ await sleep3(pollIntervalMs);
7792
8401
  }
7793
8402
  }
7794
8403
  };
7795
8404
  }
7796
- function sleep2(ms) {
8405
+ function sleep3(ms) {
7797
8406
  return new Promise((resolve2) => setTimeout(resolve2, ms));
7798
8407
  }
7799
8408
  function transformBuild(raw) {
@@ -8076,6 +8685,77 @@ function generateNewPrivateKey() {
8076
8685
  };
8077
8686
  }
8078
8687
 
8688
+ // src/client/common/auth/siwe.ts
8689
+ var import_siwe = require("siwe");
8690
+ var generateNonce = import_siwe.generateNonce;
8691
+ function createSiweMessage(params) {
8692
+ const now = /* @__PURE__ */ new Date();
8693
+ const nonce = params.nonce || generateNonce();
8694
+ const issuedAt = params.issuedAt || now;
8695
+ const expirationTime = params.expirationTime || new Date(now.getTime() + 24 * 60 * 60 * 1e3);
8696
+ const siweMessage = new import_siwe.SiweMessage({
8697
+ domain: params.domain,
8698
+ address: params.address,
8699
+ statement: params.statement,
8700
+ uri: params.uri,
8701
+ version: "1",
8702
+ chainId: params.chainId,
8703
+ nonce,
8704
+ issuedAt: issuedAt.toISOString(),
8705
+ expirationTime: expirationTime.toISOString(),
8706
+ notBefore: params.notBefore?.toISOString(),
8707
+ requestId: params.requestId,
8708
+ resources: params.resources
8709
+ });
8710
+ return {
8711
+ message: siweMessage.prepareMessage(),
8712
+ params: {
8713
+ address: params.address,
8714
+ chainId: params.chainId,
8715
+ domain: params.domain,
8716
+ uri: params.uri,
8717
+ nonce,
8718
+ issuedAt,
8719
+ statement: params.statement,
8720
+ expirationTime,
8721
+ notBefore: params.notBefore,
8722
+ requestId: params.requestId,
8723
+ resources: params.resources
8724
+ }
8725
+ };
8726
+ }
8727
+ function parseSiweMessage(message) {
8728
+ try {
8729
+ const siweMessage = new import_siwe.SiweMessage(message);
8730
+ return {
8731
+ address: siweMessage.address,
8732
+ chainId: siweMessage.chainId,
8733
+ domain: siweMessage.domain,
8734
+ uri: siweMessage.uri,
8735
+ nonce: siweMessage.nonce,
8736
+ statement: siweMessage.statement,
8737
+ issuedAt: siweMessage.issuedAt ? new Date(siweMessage.issuedAt) : void 0,
8738
+ expirationTime: siweMessage.expirationTime ? new Date(siweMessage.expirationTime) : void 0,
8739
+ notBefore: siweMessage.notBefore ? new Date(siweMessage.notBefore) : void 0,
8740
+ requestId: siweMessage.requestId,
8741
+ resources: siweMessage.resources
8742
+ };
8743
+ } catch {
8744
+ return null;
8745
+ }
8746
+ }
8747
+ function isSiweMessageExpired(params) {
8748
+ if (!params.expirationTime) return false;
8749
+ return /* @__PURE__ */ new Date() > params.expirationTime;
8750
+ }
8751
+ function isSiweMessageNotYetValid(params) {
8752
+ if (!params.notBefore) return false;
8753
+ return /* @__PURE__ */ new Date() < params.notBefore;
8754
+ }
8755
+
8756
+ // src/client/common/auth/index.ts
8757
+ init_session();
8758
+
8079
8759
  // src/client/common/utils/instance.ts
8080
8760
  async function getCurrentInstanceType(preflightCtx, appID, logger, clientId) {
8081
8761
  try {
@@ -8083,7 +8763,7 @@ async function getCurrentInstanceType(preflightCtx, appID, logger, clientId) {
8083
8763
  preflightCtx.environmentConfig,
8084
8764
  preflightCtx.walletClient,
8085
8765
  preflightCtx.publicClient,
8086
- clientId
8766
+ clientId ? { clientId } : void 0
8087
8767
  );
8088
8768
  const infos = await userApiClient.getInfos([appID], 1);
8089
8769
  if (infos.length === 0) {
@@ -8147,6 +8827,7 @@ function createECloudClient(cfg) {
8147
8827
  NotFoundError,
8148
8828
  PRIMARY_LANGUAGES,
8149
8829
  PostHogClient,
8830
+ SessionError,
8150
8831
  TimeoutError,
8151
8832
  UserApiClient,
8152
8833
  addHexPrefix,
@@ -8163,6 +8844,7 @@ function createECloudClient(cfg) {
8163
8844
  createComputeModule,
8164
8845
  createECloudClient,
8165
8846
  createMetricsContext,
8847
+ createSiweMessage,
8166
8848
  createTelemetryClient,
8167
8849
  createViemClients,
8168
8850
  deleteLegacyPrivateKey,
@@ -8179,6 +8861,7 @@ function createECloudClient(cfg) {
8179
8861
  fetchTemplateCatalog,
8180
8862
  formatETH,
8181
8863
  generateNewPrivateKey,
8864
+ generateNonce,
8182
8865
  getAddressFromPrivateKey,
8183
8866
  getAllAppsByDeveloper,
8184
8867
  getAppLatestReleaseBlockNumbers,
@@ -8189,6 +8872,7 @@ function createECloudClient(cfg) {
8189
8872
  getBuildType,
8190
8873
  getCategoryDescriptions,
8191
8874
  getChainFromID,
8875
+ getComputeApiSession,
8192
8876
  getCurrentInstanceType,
8193
8877
  getEnvironmentConfig,
8194
8878
  getLegacyKeys,
@@ -8201,10 +8885,17 @@ function createECloudClient(cfg) {
8201
8885
  isEnvironmentAvailable,
8202
8886
  isMainnet,
8203
8887
  isNoopClient,
8888
+ isSessionValid,
8889
+ isSiweMessageExpired,
8890
+ isSiweMessageNotYetValid,
8204
8891
  isSubscriptionActive,
8205
8892
  keyExists,
8206
8893
  listStoredKeys,
8894
+ loginToComputeApi,
8895
+ logoutFromComputeApi,
8207
8896
  logs,
8897
+ noopLogger,
8898
+ parseSiweMessage,
8208
8899
  prepareDeploy,
8209
8900
  prepareDeployFromVerifiableBuild,
8210
8901
  prepareUpgrade,