@layr-labs/ecloud-sdk 1.0.0-dev.2 → 1.0.0-dev.4

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 CHANGED
@@ -1,2 +1,2 @@
1
- version=1.0.0-dev.2
2
- commit=44b22091b826ce951383ff8a7fb2136c010abb56
1
+ version=1.0.0-dev.4
2
+ commit=c09e81b17f3f5e8ea24aa8df3681741dad15a710
package/dist/billing.cjs CHANGED
@@ -317,6 +317,20 @@ var BillingApiClient = class {
317
317
  const endpoint = `${this.config.billingApiServerURL}/products/${productId}/subscription`;
318
318
  await this.makeAuthenticatedRequest(endpoint, "DELETE", productId);
319
319
  }
320
+ async getPaymentMethods() {
321
+ const endpoint = `${this.config.billingApiServerURL}/v1/payment-methods`;
322
+ const resp = await this.makeAuthenticatedRequest(endpoint, "GET", "compute");
323
+ return resp.json();
324
+ }
325
+ async purchaseCredits(amountCents, paymentMethodId) {
326
+ const endpoint = `${this.config.billingApiServerURL}/v1/credits/purchase`;
327
+ const body = { amountCents };
328
+ if (paymentMethodId) {
329
+ body.paymentMethodId = paymentMethodId;
330
+ }
331
+ const resp = await this.makeAuthenticatedRequest(endpoint, "POST", "compute", body);
332
+ return resp.json();
333
+ }
320
334
  // ==========================================================================
321
335
  // Internal Methods
322
336
  // ==========================================================================
@@ -326,10 +340,22 @@ var BillingApiClient = class {
326
340
  * Uses session auth if useSession is true, otherwise uses EIP-712 signature auth.
327
341
  */
328
342
  async makeAuthenticatedRequest(url, method, productId, body) {
329
- if (this.useSession) {
330
- return this.makeSessionAuthenticatedRequest(url, method, body);
343
+ if (this.options.verbose) {
344
+ console.debug(`[BillingAPI] ${method} ${url}`);
345
+ if (body) {
346
+ console.debug(`[BillingAPI] Payload:`, JSON.stringify(body, null, 2));
347
+ }
348
+ }
349
+ const resp = this.useSession ? await this.makeSessionAuthenticatedRequest(url, method, body) : await this.makeSignatureAuthenticatedRequest(url, method, productId, body);
350
+ if (this.options.verbose) {
351
+ const data = await resp.json();
352
+ console.debug(`[BillingAPI] Response:`, JSON.stringify(data, null, 2));
353
+ return {
354
+ json: async () => data,
355
+ text: async () => JSON.stringify(data)
356
+ };
331
357
  }
332
- return this.makeSignatureAuthenticatedRequest(url, method, productId, body);
358
+ return resp;
333
359
  }
334
360
  /**
335
361
  * Make a request using session-based authentication (cookies)
@@ -437,6 +463,7 @@ Please check:
437
463
  // src/client/common/config/environment.ts
438
464
  var SEPOLIA_CHAIN_ID = 11155111;
439
465
  var MAINNET_CHAIN_ID = 1;
466
+ var BASE_SEPOLIA_CHAIN_ID = 84532;
440
467
  var CommonAddresses = {
441
468
  ERC7702Delegator: "0x63c0c19a282a1b52b07dd5a65b58948a07dae32b"
442
469
  };
@@ -466,7 +493,9 @@ var ENVIRONMENTS = {
466
493
  kmsServerURL: "http://10.128.0.57:8080",
467
494
  userApiServerURL: "https://userapi-compute-sepolia-dev.eigencloud.xyz",
468
495
  defaultRPCURL: "https://ethereum-sepolia-rpc.publicnode.com",
469
- usdcCreditsAddress: "0xbdA3897c3A428763B59015C64AB766c288C97376"
496
+ usdcCreditsAddress: "0xbdA3897c3A428763B59015C64AB766c288C97376",
497
+ baseUsdcCreditsAddress: "0x7673a47463F80c6a3553Db9E54c8cDcd5313d0ac",
498
+ baseRPCURL: "https://base-sepolia-rpc.publicnode.com"
470
499
  },
471
500
  sepolia: {
472
501
  name: "sepolia",
@@ -478,7 +507,9 @@ var ENVIRONMENTS = {
478
507
  userApiServerURL: "https://userapi-compute-sepolia-prod.eigencloud.xyz",
479
508
  defaultRPCURL: "https://ethereum-sepolia-rpc.publicnode.com",
480
509
  billingRPCURL: "https://ethereum-rpc.publicnode.com",
481
- usdcCreditsAddress: "0xed9c88640ca9149Bd9f7ee6620074af10F2E145d"
510
+ usdcCreditsAddress: "0xed9c88640ca9149Bd9f7ee6620074af10F2E145d",
511
+ baseUsdcCreditsAddress: "0x7673a47463F80c6a3553Db9E54c8cDcd5313d0ac",
512
+ baseRPCURL: "https://base-sepolia-rpc.publicnode.com"
482
513
  },
483
514
  "mainnet-alpha": {
484
515
  name: "mainnet-alpha",
@@ -523,7 +554,13 @@ function getEnvironmentConfig(environment, chainID) {
523
554
  return {
524
555
  ...env,
525
556
  chainID: BigInt(resolvedChainID),
526
- ...apiUrlOverride ? { userApiServerURL: apiUrlOverride } : {}
557
+ ...apiUrlOverride ? { userApiServerURL: apiUrlOverride } : {},
558
+ ...process.env.ECLOUD_USER_API_URL && {
559
+ userApiServerURL: process.env.ECLOUD_USER_API_URL
560
+ },
561
+ ...process.env.ECLOUD_RPC_URL && {
562
+ defaultRPCURL: process.env.ECLOUD_RPC_URL
563
+ }
527
564
  };
528
565
  }
529
566
  function getBillingEnvironmentConfig(build) {
@@ -535,7 +572,12 @@ function getBillingEnvironmentConfig(build) {
535
572
  if (apiUrlOverride) {
536
573
  return { billingApiServerURL: apiUrlOverride };
537
574
  }
538
- return config;
575
+ return {
576
+ ...config,
577
+ ...process.env.ECLOUD_BILLING_API_URL && {
578
+ billingApiServerURL: process.env.ECLOUD_BILLING_API_URL
579
+ }
580
+ };
539
581
  }
540
582
  function getBuildType() {
541
583
  const buildTimeType = true ? "dev"?.toLowerCase() : void 0;
@@ -557,6 +599,41 @@ function isEnvironmentAvailable(environment) {
557
599
  return getAvailableEnvironments().includes(environment);
558
600
  }
559
601
 
602
+ // src/client/common/utils/helpers.ts
603
+ var import_viem2 = require("viem");
604
+ var import_chains2 = require("viem/chains");
605
+ var import_accounts = require("viem/accounts");
606
+
607
+ // src/client/common/constants.ts
608
+ var import_chains = require("viem/chains");
609
+ var SUPPORTED_CHAINS = [import_chains.mainnet, import_chains.sepolia, import_chains.baseSepolia];
610
+
611
+ // src/client/common/utils/helpers.ts
612
+ function getChainFromID(chainID, fallback2 = import_chains2.sepolia) {
613
+ const id = Number(chainID);
614
+ return (0, import_viem2.extractChain)({ chains: SUPPORTED_CHAINS, id }) || fallback2;
615
+ }
616
+ function createClients(options) {
617
+ const { privateKey, rpcUrl, chainId } = options;
618
+ const privateKeyHex = addHexPrefix(privateKey);
619
+ const account = (0, import_accounts.privateKeyToAccount)(privateKeyHex);
620
+ const chain = getChainFromID(chainId);
621
+ const transport = typeof rpcUrl === "string" ? (0, import_viem2.http)(rpcUrl) : (0, import_viem2.fallback)(rpcUrl.map((url) => (0, import_viem2.http)(url)));
622
+ const publicClient = (0, import_viem2.createPublicClient)({
623
+ chain,
624
+ transport
625
+ });
626
+ const walletClient = (0, import_viem2.createWalletClient)({
627
+ account,
628
+ chain,
629
+ transport
630
+ });
631
+ return { walletClient, publicClient };
632
+ }
633
+ function addHexPrefix(value) {
634
+ return value.startsWith("0x") ? value : `0x${value}`;
635
+ }
636
+
560
637
  // src/client/common/utils/logger.ts
561
638
  var getLogger = (verbose) => ({
562
639
  info: (...args) => console.info(...args),
@@ -568,14 +645,6 @@ var getLogger = (verbose) => ({
568
645
  // src/client/common/utils/userapi.ts
569
646
  var import_axios3 = __toESM(require("axios"), 1);
570
647
 
571
- // src/client/common/utils/helpers.ts
572
- var import_viem2 = require("viem");
573
- var import_chains2 = require("viem/chains");
574
- var import_accounts = require("viem/accounts");
575
-
576
- // src/client/common/constants.ts
577
- var import_chains = require("viem/chains");
578
-
579
648
  // src/client/common/utils/retry.ts
580
649
  var import_axios2 = __toESM(require("axios"), 1);
581
650
 
@@ -2071,44 +2140,78 @@ var ERC20_default = [
2071
2140
 
2072
2141
  // src/client/modules/billing/index.ts
2073
2142
  function createBillingModule(config) {
2074
- const { verbose = false, skipTelemetry = false, walletClient, publicClient, environment } = config;
2143
+ const { verbose = false, skipTelemetry = false, walletClient, publicClient, environment, privateKey } = config;
2075
2144
  if (!walletClient.account) {
2076
2145
  throw new Error("WalletClient must have an account attached");
2077
2146
  }
2078
2147
  const address = walletClient.account.address;
2079
2148
  const logger = getLogger(verbose);
2080
2149
  const billingEnvConfig = getBillingEnvironmentConfig(getBuildType());
2081
- const billingApi = new BillingApiClient(billingEnvConfig, walletClient);
2150
+ const billingApi = new BillingApiClient(billingEnvConfig, walletClient, { verbose });
2082
2151
  const environmentConfig = getEnvironmentConfig(environment);
2083
- const usdcCreditsAddress = environmentConfig.usdcCreditsAddress;
2084
- if (!usdcCreditsAddress) {
2152
+ if (!environmentConfig.usdcCreditsAddress) {
2085
2153
  throw new Error(`USDCCredits contract address not configured for environment "${environment}"`);
2086
2154
  }
2155
+ const usdcCreditsAddress = environmentConfig.usdcCreditsAddress;
2156
+ const baseUsdcCreditsAddress = environmentConfig.baseUsdcCreditsAddress;
2157
+ const baseRPCURL = environmentConfig.baseRPCURL;
2158
+ function resolveChainConfig(chain) {
2159
+ if (chain === "base") {
2160
+ if (!baseUsdcCreditsAddress || !baseRPCURL) {
2161
+ throw new Error(`Base chain not configured for environment "${environment}"`);
2162
+ }
2163
+ if (!privateKey) {
2164
+ throw new Error("Private key required for Base chain transactions");
2165
+ }
2166
+ const baseClients = createClients({
2167
+ privateKey,
2168
+ rpcUrl: baseRPCURL,
2169
+ chainId: BigInt(BASE_SEPOLIA_CHAIN_ID)
2170
+ });
2171
+ return {
2172
+ pub: baseClients.publicClient,
2173
+ wallet: baseClients.walletClient,
2174
+ creditsAddress: baseUsdcCreditsAddress,
2175
+ envConfig: {
2176
+ ...environmentConfig,
2177
+ chainID: BigInt(BASE_SEPOLIA_CHAIN_ID),
2178
+ defaultRPCURL: baseRPCURL
2179
+ }
2180
+ };
2181
+ }
2182
+ return {
2183
+ pub: publicClient,
2184
+ wallet: walletClient,
2185
+ creditsAddress: usdcCreditsAddress,
2186
+ envConfig: environmentConfig
2187
+ };
2188
+ }
2087
2189
  const module2 = {
2088
2190
  address,
2089
- async getTopUpInfo() {
2090
- const usdcAddress = await publicClient.readContract({
2091
- address: usdcCreditsAddress,
2191
+ async getTopUpInfo(opts) {
2192
+ const { pub, creditsAddress } = resolveChainConfig(opts?.chain);
2193
+ const usdcAddress = await pub.readContract({
2194
+ address: creditsAddress,
2092
2195
  abi: USDCCredits_default,
2093
2196
  functionName: "usdc"
2094
2197
  });
2095
2198
  const [minimumPurchase, usdcBalance, currentAllowance] = await Promise.all([
2096
- publicClient.readContract({
2097
- address: usdcCreditsAddress,
2199
+ pub.readContract({
2200
+ address: creditsAddress,
2098
2201
  abi: USDCCredits_default,
2099
2202
  functionName: "minimumPurchase"
2100
2203
  }),
2101
- publicClient.readContract({
2204
+ pub.readContract({
2102
2205
  address: usdcAddress,
2103
2206
  abi: ERC20_default,
2104
2207
  functionName: "balanceOf",
2105
2208
  args: [address]
2106
2209
  }),
2107
- publicClient.readContract({
2210
+ pub.readContract({
2108
2211
  address: usdcAddress,
2109
2212
  abi: ERC20_default,
2110
2213
  functionName: "allowance",
2111
- args: [address, usdcCreditsAddress]
2214
+ args: [address, creditsAddress]
2112
2215
  })
2113
2216
  ]);
2114
2217
  return { usdcAddress, minimumPurchase, usdcBalance, currentAllowance };
@@ -2118,11 +2221,12 @@ function createBillingModule(config) {
2118
2221
  {
2119
2222
  functionName: "topUp",
2120
2223
  skipTelemetry,
2121
- properties: { amount: opts.amount.toString() }
2224
+ properties: { amount: opts.amount.toString(), chain: opts.chain || "ethereum" }
2122
2225
  },
2123
2226
  async () => {
2124
2227
  const targetAccount = opts.account ?? address;
2125
- const { usdcAddress, currentAllowance } = await module2.getTopUpInfo();
2228
+ const { pub, wallet, creditsAddress, envConfig } = resolveChainConfig(opts.chain);
2229
+ const { usdcAddress, currentAllowance } = await module2.getTopUpInfo({ chain: opts.chain });
2126
2230
  const executions = [];
2127
2231
  if (currentAllowance < opts.amount) {
2128
2232
  executions.push({
@@ -2131,12 +2235,12 @@ function createBillingModule(config) {
2131
2235
  callData: (0, import_viem5.encodeFunctionData)({
2132
2236
  abi: ERC20_default,
2133
2237
  functionName: "approve",
2134
- args: [usdcCreditsAddress, opts.amount]
2238
+ args: [creditsAddress, opts.amount]
2135
2239
  })
2136
2240
  });
2137
2241
  }
2138
2242
  executions.push({
2139
- target: usdcCreditsAddress,
2243
+ target: creditsAddress,
2140
2244
  value: 0n,
2141
2245
  callData: (0, import_viem5.encodeFunctionData)({
2142
2246
  abi: USDCCredits_default,
@@ -2146,9 +2250,9 @@ function createBillingModule(config) {
2146
2250
  });
2147
2251
  const txHash = await executeBatch(
2148
2252
  {
2149
- walletClient,
2150
- publicClient,
2151
- environmentConfig,
2253
+ walletClient: wallet,
2254
+ publicClient: pub,
2255
+ environmentConfig: envConfig,
2152
2256
  executions,
2153
2257
  pendingMessage: "Submitting credit purchase..."
2154
2258
  },
@@ -2242,6 +2346,15 @@ function createBillingModule(config) {
2242
2346
  };
2243
2347
  }
2244
2348
  );
2349
+ },
2350
+ async getPaymentMethods() {
2351
+ return billingApi.getPaymentMethods();
2352
+ },
2353
+ async purchaseCredits(amountCents, paymentMethodId) {
2354
+ return billingApi.purchaseCredits(amountCents, paymentMethodId);
2355
+ },
2356
+ hasBaseSupport() {
2357
+ return !!baseUsdcCreditsAddress && !!baseRPCURL;
2245
2358
  }
2246
2359
  };
2247
2360
  return module2;