@layr-labs/ecloud-sdk 0.4.0-dev.1 → 0.4.0-dev.2

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.
Files changed (41) hide show
  1. package/VERSION +2 -0
  2. package/dist/attest.cjs +185 -0
  3. package/dist/attest.cjs.map +1 -0
  4. package/dist/attest.d.cts +28 -0
  5. package/dist/attest.d.ts +28 -0
  6. package/dist/attest.js +147 -0
  7. package/dist/attest.js.map +1 -0
  8. package/dist/billing.cjs +1380 -4
  9. package/dist/billing.cjs.map +1 -1
  10. package/dist/billing.d.cts +25 -3
  11. package/dist/billing.d.ts +25 -3
  12. package/dist/billing.js +1380 -4
  13. package/dist/billing.js.map +1 -1
  14. package/dist/browser.cjs +3 -2
  15. package/dist/browser.cjs.map +1 -1
  16. package/dist/browser.d.cts +4 -4
  17. package/dist/browser.d.ts +4 -4
  18. package/dist/browser.js +3 -2
  19. package/dist/browser.js.map +1 -1
  20. package/dist/{compute-DccJLbtV.d.cts → compute-BRDk7QM4.d.cts} +1 -1
  21. package/dist/{compute-DlilmZYC.d.ts → compute-CC55YQ_a.d.ts} +1 -1
  22. package/dist/compute.cjs +8 -3
  23. package/dist/compute.cjs.map +1 -1
  24. package/dist/compute.d.cts +2 -2
  25. package/dist/compute.d.ts +2 -2
  26. package/dist/compute.js +8 -3
  27. package/dist/compute.js.map +1 -1
  28. package/dist/{helpers-D_AbDeP4.d.ts → helpers-BcoV07Me.d.ts} +1 -1
  29. package/dist/{helpers-BNeMZYcY.d.cts → helpers-DdtPaQr9.d.cts} +1 -1
  30. package/dist/{index-DD7ZLbqD.d.cts → index-BEbhrwWl.d.cts} +1 -0
  31. package/dist/{index-DD7ZLbqD.d.ts → index-BEbhrwWl.d.ts} +1 -0
  32. package/dist/index.cjs +330 -95
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.d.cts +7 -6
  35. package/dist/index.d.ts +7 -6
  36. package/dist/index.js +328 -95
  37. package/dist/index.js.map +1 -1
  38. package/package.json +16 -10
  39. package/tools/kms-client-linux-amd64 +0 -0
  40. package/tools/tls-keygen-linux-amd64 +0 -0
  41. package/LICENSE +0 -7
@@ -1,4 +1,4 @@
1
- import { a8 as EnvironmentConfig, ai as SubscriptionStatus, a7 as BillingEnvironmentConfig, ag as ProductID, ak as CreateSubscriptionOptions, am as CreateSubscriptionResponse, al as GetSubscriptionOptions, au as ProductSubscriptionResponse, G as GasEstimate, ad as Logger } from './index-DD7ZLbqD.js';
1
+ import { a8 as EnvironmentConfig, ai as SubscriptionStatus, a7 as BillingEnvironmentConfig, ag as ProductID, ak as CreateSubscriptionOptions, am as CreateSubscriptionResponse, al as GetSubscriptionOptions, au as ProductSubscriptionResponse, G as GasEstimate, ad as Logger } from './index-BEbhrwWl.js';
2
2
  import { Address, Hex, WalletClient, PublicClient, SignAuthorizationReturnType, Chain } from 'viem';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { a8 as EnvironmentConfig, ai as SubscriptionStatus, a7 as BillingEnvironmentConfig, ag as ProductID, ak as CreateSubscriptionOptions, am as CreateSubscriptionResponse, al as GetSubscriptionOptions, au as ProductSubscriptionResponse, G as GasEstimate, ad as Logger } from './index-DD7ZLbqD.cjs';
1
+ import { a8 as EnvironmentConfig, ai as SubscriptionStatus, a7 as BillingEnvironmentConfig, ag as ProductID, ak as CreateSubscriptionOptions, am as CreateSubscriptionResponse, al as GetSubscriptionOptions, au as ProductSubscriptionResponse, G as GasEstimate, ad as Logger } from './index-BEbhrwWl.cjs';
2
2
  import { Address, Hex, WalletClient, PublicClient, SignAuthorizationReturnType, Chain } from 'viem';
3
3
 
4
4
  /**
@@ -612,6 +612,7 @@ interface EnvironmentConfig {
612
612
  kmsServerURL: string;
613
613
  userApiServerURL: string;
614
614
  defaultRPCURL: string;
615
+ billingRPCURL?: string;
615
616
  usdcCreditsAddress?: Address;
616
617
  }
617
618
  interface Release {
@@ -612,6 +612,7 @@ interface EnvironmentConfig {
612
612
  kmsServerURL: string;
613
613
  userApiServerURL: string;
614
614
  defaultRPCURL: string;
615
+ billingRPCURL?: string;
615
616
  usdcCreditsAddress?: Address;
616
617
  }
617
618
  interface Release {
package/dist/index.cjs CHANGED
@@ -162,6 +162,7 @@ var init_session = __esm({
162
162
  // src/index.ts
163
163
  var index_exports = {};
164
164
  __export(index_exports, {
165
+ AttestClient: () => AttestClient,
165
166
  AuthRequiredError: () => AuthRequiredError,
166
167
  BUILD_STATUS: () => BUILD_STATUS,
167
168
  BadRequestError: () => BadRequestError,
@@ -171,6 +172,7 @@ __export(index_exports, {
171
172
  ConflictError: () => ConflictError,
172
173
  ERC20ABI: () => ERC20_default,
173
174
  ForbiddenError: () => ForbiddenError,
175
+ JwtProvider: () => JwtProvider,
174
176
  NoopClient: () => NoopClient,
175
177
  NotFoundError: () => NotFoundError,
176
178
  PRIMARY_LANGUAGES: () => PRIMARY_LANGUAGES,
@@ -691,6 +693,10 @@ setup_tls() {
691
693
  # Run TLS setup
692
694
  setup_tls
693
695
 
696
+ # Export KMS variables for attestation-based JWT auth
697
+ export KMS_SERVER_URL="{{kmsServerURL}}"
698
+ export KMS_PUBLIC_KEY="$(cat /usr/local/bin/kms-signing-public-key.pem)"
699
+
694
700
  echo "compute-source-env.sh: Environment sourced."
695
701
 
696
702
  # Drop privileges to original user for the application command
@@ -4954,7 +4960,7 @@ var CanViewAppLogsPermission = "0x2fd3f2fe";
4954
4960
  var CanViewSensitiveAppInfoPermission = "0x0e67b22f";
4955
4961
  var CanUpdateAppProfilePermission = "0x036fef61";
4956
4962
  function getDefaultClientId() {
4957
- const version = true ? "0.4.0-dev.1" : "0.0.0";
4963
+ const version = true ? "0.4.0-dev.2" : "0.0.0";
4958
4964
  return `ecloud-sdk/v${version}`;
4959
4965
  }
4960
4966
  var UserApiClient = class {
@@ -5745,7 +5751,8 @@ var ENVIRONMENTS = {
5745
5751
  erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,
5746
5752
  kmsServerURL: "http://10.128.15.203:8080",
5747
5753
  userApiServerURL: "https://userapi-compute-sepolia-prod.eigencloud.xyz",
5748
- defaultRPCURL: "https://ethereum-sepolia-rpc.publicnode.com"
5754
+ defaultRPCURL: "https://ethereum-sepolia-rpc.publicnode.com",
5755
+ billingRPCURL: "https://ethereum-rpc.publicnode.com"
5749
5756
  },
5750
5757
  "mainnet-alpha": {
5751
5758
  name: "mainnet-alpha",
@@ -6285,7 +6292,7 @@ function getPostHogAPIKey() {
6285
6292
  if (process.env.ECLOUD_POSTHOG_KEY) {
6286
6293
  return process.env.ECLOUD_POSTHOG_KEY;
6287
6294
  }
6288
- return typeof POSTHOG_API_KEY_BUILD_TIME !== "undefined" ? POSTHOG_API_KEY_BUILD_TIME : void 0;
6295
+ return true ? "phc_BiKfywNft5iBI8N7MxmuVCkb4GGZj4mDFXYPmOPUAI8" : void 0;
6289
6296
  }
6290
6297
  function getPostHogEndpoint() {
6291
6298
  return process.env.ECLOUD_POSTHOG_ENDPOINT || "https://us.i.posthog.com";
@@ -8194,9 +8201,101 @@ function createComputeModule(config) {
8194
8201
  };
8195
8202
  }
8196
8203
 
8204
+ // src/client/modules/billing/index.ts
8205
+ var import_viem7 = require("viem");
8206
+
8207
+ // src/client/common/abis/USDCCredits.json
8208
+ var USDCCredits_default = [
8209
+ {
8210
+ type: "function",
8211
+ name: "purchaseCreditsFor",
8212
+ stateMutability: "nonpayable",
8213
+ inputs: [
8214
+ { name: "amount", type: "uint256" },
8215
+ { name: "account", type: "address" }
8216
+ ],
8217
+ outputs: []
8218
+ },
8219
+ {
8220
+ type: "function",
8221
+ name: "purchaseCredits",
8222
+ stateMutability: "nonpayable",
8223
+ inputs: [
8224
+ { name: "amount", type: "uint256" }
8225
+ ],
8226
+ outputs: []
8227
+ },
8228
+ {
8229
+ type: "function",
8230
+ name: "usdc",
8231
+ stateMutability: "view",
8232
+ inputs: [],
8233
+ outputs: [
8234
+ { name: "", type: "address" }
8235
+ ]
8236
+ },
8237
+ {
8238
+ type: "function",
8239
+ name: "minimumPurchase",
8240
+ stateMutability: "view",
8241
+ inputs: [],
8242
+ outputs: [
8243
+ { name: "", type: "uint256" }
8244
+ ]
8245
+ },
8246
+ {
8247
+ type: "event",
8248
+ name: "CreditsPurchased",
8249
+ inputs: [
8250
+ { name: "purchaser", type: "address", indexed: true },
8251
+ { name: "account", type: "address", indexed: true },
8252
+ { name: "amount", type: "uint256", indexed: false }
8253
+ ]
8254
+ }
8255
+ ];
8256
+
8257
+ // src/client/common/abis/ERC20.json
8258
+ var ERC20_default = [
8259
+ {
8260
+ type: "function",
8261
+ name: "approve",
8262
+ stateMutability: "nonpayable",
8263
+ inputs: [
8264
+ { name: "spender", type: "address" },
8265
+ { name: "amount", type: "uint256" }
8266
+ ],
8267
+ outputs: [
8268
+ { name: "", type: "bool" }
8269
+ ]
8270
+ },
8271
+ {
8272
+ type: "function",
8273
+ name: "balanceOf",
8274
+ stateMutability: "view",
8275
+ inputs: [
8276
+ { name: "account", type: "address" }
8277
+ ],
8278
+ outputs: [
8279
+ { name: "", type: "uint256" }
8280
+ ]
8281
+ },
8282
+ {
8283
+ type: "function",
8284
+ name: "allowance",
8285
+ stateMutability: "view",
8286
+ inputs: [
8287
+ { name: "owner", type: "address" },
8288
+ { name: "spender", type: "address" }
8289
+ ],
8290
+ outputs: [
8291
+ { name: "", type: "uint256" }
8292
+ ]
8293
+ }
8294
+ ];
8295
+
8197
8296
  // src/client/modules/billing/index.ts
8198
8297
  function createBillingModule(config) {
8199
- const { verbose = false, skipTelemetry = false, walletClient } = config;
8298
+ const { verbose = false, skipTelemetry = false, walletClient, publicClient, environment } = config;
8200
8299
  if (!walletClient.account) {
8201
8300
  throw new Error("WalletClient must have an account attached");
8202
8301
  }
@@ -8204,8 +8303,85 @@ function createBillingModule(config) {
8204
8303
  const logger = getLogger(verbose);
8205
8304
  const billingEnvConfig = getBillingEnvironmentConfig(getBuildType());
8206
8305
  const billingApi = new BillingApiClient(billingEnvConfig, walletClient);
8207
- return {
8306
+ const environmentConfig = getEnvironmentConfig(environment);
8307
+ const usdcCreditsAddress = environmentConfig.usdcCreditsAddress;
8308
+ if (!usdcCreditsAddress) {
8309
+ throw new Error(`USDCCredits contract address not configured for environment "${environment}"`);
8310
+ }
8311
+ const module2 = {
8208
8312
  address,
8313
+ async getTopUpInfo() {
8314
+ const usdcAddress = await publicClient.readContract({
8315
+ address: usdcCreditsAddress,
8316
+ abi: USDCCredits_default,
8317
+ functionName: "usdc"
8318
+ });
8319
+ const [minimumPurchase, usdcBalance, currentAllowance] = await Promise.all([
8320
+ publicClient.readContract({
8321
+ address: usdcCreditsAddress,
8322
+ abi: USDCCredits_default,
8323
+ functionName: "minimumPurchase"
8324
+ }),
8325
+ publicClient.readContract({
8326
+ address: usdcAddress,
8327
+ abi: ERC20_default,
8328
+ functionName: "balanceOf",
8329
+ args: [address]
8330
+ }),
8331
+ publicClient.readContract({
8332
+ address: usdcAddress,
8333
+ abi: ERC20_default,
8334
+ functionName: "allowance",
8335
+ args: [address, usdcCreditsAddress]
8336
+ })
8337
+ ]);
8338
+ return { usdcAddress, minimumPurchase, usdcBalance, currentAllowance };
8339
+ },
8340
+ async topUp(opts) {
8341
+ return withSDKTelemetry(
8342
+ {
8343
+ functionName: "topUp",
8344
+ skipTelemetry,
8345
+ properties: { amount: opts.amount.toString() }
8346
+ },
8347
+ async () => {
8348
+ const targetAccount = opts.account ?? address;
8349
+ const { usdcAddress, currentAllowance } = await module2.getTopUpInfo();
8350
+ const executions = [];
8351
+ if (currentAllowance < opts.amount) {
8352
+ executions.push({
8353
+ target: usdcAddress,
8354
+ value: 0n,
8355
+ callData: (0, import_viem7.encodeFunctionData)({
8356
+ abi: ERC20_default,
8357
+ functionName: "approve",
8358
+ args: [usdcCreditsAddress, opts.amount]
8359
+ })
8360
+ });
8361
+ }
8362
+ executions.push({
8363
+ target: usdcCreditsAddress,
8364
+ value: 0n,
8365
+ callData: (0, import_viem7.encodeFunctionData)({
8366
+ abi: USDCCredits_default,
8367
+ functionName: "purchaseCreditsFor",
8368
+ args: [opts.amount, targetAccount]
8369
+ })
8370
+ });
8371
+ const txHash = await executeBatch(
8372
+ {
8373
+ walletClient,
8374
+ publicClient,
8375
+ environmentConfig,
8376
+ executions,
8377
+ pendingMessage: "Submitting credit purchase..."
8378
+ },
8379
+ logger
8380
+ );
8381
+ return { txHash, walletAddress: address };
8382
+ }
8383
+ );
8384
+ },
8209
8385
  async subscribe(opts) {
8210
8386
  return withSDKTelemetry(
8211
8387
  {
@@ -8292,6 +8468,7 @@ function createBillingModule(config) {
8292
8468
  );
8293
8469
  }
8294
8470
  };
8471
+ return module2;
8295
8472
  }
8296
8473
 
8297
8474
  // src/client/common/utils/buildapi.ts
@@ -9054,95 +9231,6 @@ async function getCurrentInstanceType(preflightCtx, appID, logger, clientId) {
9054
9231
  }
9055
9232
  }
9056
9233
 
9057
- // src/client/common/abis/USDCCredits.json
9058
- var USDCCredits_default = [
9059
- {
9060
- type: "function",
9061
- name: "purchaseCreditsFor",
9062
- stateMutability: "nonpayable",
9063
- inputs: [
9064
- { name: "amount", type: "uint256" },
9065
- { name: "account", type: "address" }
9066
- ],
9067
- outputs: []
9068
- },
9069
- {
9070
- type: "function",
9071
- name: "purchaseCredits",
9072
- stateMutability: "nonpayable",
9073
- inputs: [
9074
- { name: "amount", type: "uint256" }
9075
- ],
9076
- outputs: []
9077
- },
9078
- {
9079
- type: "function",
9080
- name: "usdc",
9081
- stateMutability: "view",
9082
- inputs: [],
9083
- outputs: [
9084
- { name: "", type: "address" }
9085
- ]
9086
- },
9087
- {
9088
- type: "function",
9089
- name: "minimumPurchase",
9090
- stateMutability: "view",
9091
- inputs: [],
9092
- outputs: [
9093
- { name: "", type: "uint256" }
9094
- ]
9095
- },
9096
- {
9097
- type: "event",
9098
- name: "CreditsPurchased",
9099
- inputs: [
9100
- { name: "purchaser", type: "address", indexed: true },
9101
- { name: "account", type: "address", indexed: true },
9102
- { name: "amount", type: "uint256", indexed: false }
9103
- ]
9104
- }
9105
- ];
9106
-
9107
- // src/client/common/abis/ERC20.json
9108
- var ERC20_default = [
9109
- {
9110
- type: "function",
9111
- name: "approve",
9112
- stateMutability: "nonpayable",
9113
- inputs: [
9114
- { name: "spender", type: "address" },
9115
- { name: "amount", type: "uint256" }
9116
- ],
9117
- outputs: [
9118
- { name: "", type: "bool" }
9119
- ]
9120
- },
9121
- {
9122
- type: "function",
9123
- name: "balanceOf",
9124
- stateMutability: "view",
9125
- inputs: [
9126
- { name: "account", type: "address" }
9127
- ],
9128
- outputs: [
9129
- { name: "", type: "uint256" }
9130
- ]
9131
- },
9132
- {
9133
- type: "function",
9134
- name: "allowance",
9135
- stateMutability: "view",
9136
- inputs: [
9137
- { name: "owner", type: "address" },
9138
- { name: "spender", type: "address" }
9139
- ],
9140
- outputs: [
9141
- { name: "", type: "uint256" }
9142
- ]
9143
- }
9144
- ];
9145
-
9146
9234
  // src/client/index.ts
9147
9235
  function createECloudClient(cfg) {
9148
9236
  cfg.privateKey = addHexPrefix(cfg.privateKey);
@@ -9176,12 +9264,158 @@ function createECloudClient(cfg) {
9176
9264
  }),
9177
9265
  billing: createBillingModule({
9178
9266
  verbose: cfg.verbose,
9179
- walletClient
9267
+ walletClient,
9268
+ publicClient,
9269
+ environment: cfg.environment
9180
9270
  })
9181
9271
  };
9182
9272
  }
9273
+
9274
+ // src/client/modules/attest/attest-client.ts
9275
+ var import_node_crypto = require("crypto");
9276
+ var import_node_http = __toESM(require("http"), 1);
9277
+ var import_jose2 = require("jose");
9278
+ var DEFAULT_SOCKET_PATH = "/run/container_launcher/teeserver.sock";
9279
+ var CHALLENGE_PREFIX = "COMPUTE_APP_JWT_REQUEST_RSA_KEY_V1";
9280
+ var SIGNATURE_PREFIX = "COMPUTE_APP_KMS_SIGNATURE_V1";
9281
+ var NULL_BYTE = Buffer.from([0]);
9282
+ var AttestClient = class {
9283
+ constructor(config) {
9284
+ this.config = config;
9285
+ }
9286
+ async attest() {
9287
+ const { publicKey, privateKey } = (0, import_node_crypto.generateKeyPairSync)("rsa", {
9288
+ modulusLength: 4096,
9289
+ publicKeyEncoding: { type: "spki", format: "pem" },
9290
+ privateKeyEncoding: { type: "pkcs8", format: "pem" }
9291
+ });
9292
+ const challengeHash = (0, import_node_crypto.createHash)("sha256").update(CHALLENGE_PREFIX).update(NULL_BYTE).update(publicKey).digest();
9293
+ const socketPath = this.config.socketPath ?? DEFAULT_SOCKET_PATH;
9294
+ const attestationBytes = await this.getAttestation(socketPath, challengeHash);
9295
+ const attestResponse = await this.postAttest(attestationBytes, publicKey);
9296
+ this.verifySignature(JSON.stringify(attestResponse.data), attestResponse.signature);
9297
+ const rsaPrivateKey = await crypto.subtle.importKey(
9298
+ "pkcs8",
9299
+ pemToBuffer(privateKey),
9300
+ { name: "RSA-OAEP", hash: "SHA-256" },
9301
+ false,
9302
+ ["decrypt"]
9303
+ );
9304
+ const { plaintext } = await (0, import_jose2.compactDecrypt)(
9305
+ attestResponse.data.encryptedToken,
9306
+ rsaPrivateKey
9307
+ );
9308
+ const decrypted = JSON.parse(new TextDecoder().decode(plaintext));
9309
+ return decrypted.token;
9310
+ }
9311
+ verifySignature(dataJson, signature) {
9312
+ const message = Buffer.concat([
9313
+ Buffer.from(SIGNATURE_PREFIX),
9314
+ NULL_BYTE,
9315
+ Buffer.from(dataJson)
9316
+ ]);
9317
+ const valid = (0, import_node_crypto.verify)(
9318
+ "sha256",
9319
+ message,
9320
+ this.config.kmsPublicKey,
9321
+ Buffer.from(signature, "base64")
9322
+ );
9323
+ if (!valid) {
9324
+ throw new Error("KMS response signature verification failed");
9325
+ }
9326
+ }
9327
+ getAttestation(socketPath, challenge) {
9328
+ return new Promise((resolve2, reject) => {
9329
+ const body = JSON.stringify({ challenge: challenge.toString("base64") });
9330
+ const req = import_node_http.default.request(
9331
+ {
9332
+ socketPath,
9333
+ path: "/v1/bound_evidence",
9334
+ method: "POST",
9335
+ headers: {
9336
+ "Content-Type": "application/json",
9337
+ "Content-Length": Buffer.byteLength(body)
9338
+ }
9339
+ },
9340
+ (res) => {
9341
+ const chunks = [];
9342
+ res.on("data", (chunk) => chunks.push(chunk));
9343
+ res.on("end", () => {
9344
+ if (res.statusCode !== 200) {
9345
+ reject(new Error(`TEE attestation failed (${res.statusCode}): ${Buffer.concat(chunks).toString()}`));
9346
+ return;
9347
+ }
9348
+ resolve2(Buffer.concat(chunks));
9349
+ });
9350
+ }
9351
+ );
9352
+ req.on("error", (err) => reject(new Error(`TEE attestation request failed: ${err.message}`)));
9353
+ req.write(body);
9354
+ req.end();
9355
+ });
9356
+ }
9357
+ async postAttest(attestationBytes, rsaPublicKey) {
9358
+ const url = `${this.config.kmsServerURL}/auth/attest`;
9359
+ const body = JSON.stringify({
9360
+ version: 3,
9361
+ attestation: attestationBytes.toString("base64"),
9362
+ rsaKey: rsaPublicKey,
9363
+ audience: this.config.audience
9364
+ });
9365
+ const response = await fetch(url, {
9366
+ method: "POST",
9367
+ headers: { "Content-Type": "application/json" },
9368
+ body
9369
+ });
9370
+ if (!response.ok) {
9371
+ const text = await response.text();
9372
+ throw new Error(`KMS attest failed (${response.status}): ${text}`);
9373
+ }
9374
+ return response.json();
9375
+ }
9376
+ };
9377
+ function pemToBuffer(pem) {
9378
+ const b64 = pem.replace(/-----[A-Z ]+-----/g, "").replace(/\s/g, "");
9379
+ const buf = Buffer.from(b64, "base64");
9380
+ return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
9381
+ }
9382
+
9383
+ // src/client/modules/attest/jwt-provider.ts
9384
+ var JwtProvider = class {
9385
+ constructor(attestClient, bufferSeconds = 30) {
9386
+ this.attestClient = attestClient;
9387
+ this.bufferSeconds = bufferSeconds;
9388
+ }
9389
+ async getToken() {
9390
+ if (this.cachedToken && !this.isExpiringSoon()) {
9391
+ return this.cachedToken;
9392
+ }
9393
+ if (this.pending) {
9394
+ return this.pending;
9395
+ }
9396
+ this.pending = this.attestClient.attest().then((token) => {
9397
+ this.cachedToken = token;
9398
+ this.expiresAt = this.decodeJwtExp(token);
9399
+ return token;
9400
+ }).finally(() => {
9401
+ this.pending = void 0;
9402
+ });
9403
+ return this.pending;
9404
+ }
9405
+ isExpiringSoon() {
9406
+ if (!this.expiresAt) return true;
9407
+ return Date.now() / 1e3 >= this.expiresAt - this.bufferSeconds;
9408
+ }
9409
+ decodeJwtExp(jwt) {
9410
+ const payload = jwt.split(".")[1];
9411
+ if (!payload) return void 0;
9412
+ const decoded = JSON.parse(Buffer.from(payload, "base64url").toString());
9413
+ return decoded.exp;
9414
+ }
9415
+ };
9183
9416
  // Annotate the CommonJS export names for ESM import in node:
9184
9417
  0 && (module.exports = {
9418
+ AttestClient,
9185
9419
  AuthRequiredError,
9186
9420
  BUILD_STATUS,
9187
9421
  BadRequestError,
@@ -9191,6 +9425,7 @@ function createECloudClient(cfg) {
9191
9425
  ConflictError,
9192
9426
  ERC20ABI,
9193
9427
  ForbiddenError,
9428
+ JwtProvider,
9194
9429
  NoopClient,
9195
9430
  NotFoundError,
9196
9431
  PRIMARY_LANGUAGES,