@layr-labs/ecloud-sdk 1.0.0-devep7 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/VERSION CHANGED
@@ -1,2 +1,2 @@
1
- version=1.0.0-devep7
2
- commit=77f99bf086444d26b080c7e076c1dfcc470f36f7
1
+ version=1.0.0
2
+ commit=3f8023569b781e80105d1f06cbba82a8fb7dd3e0
package/dist/billing.cjs CHANGED
@@ -332,6 +332,63 @@ var BillingApiClient = class {
332
332
  return resp.json();
333
333
  }
334
334
  // ==========================================================================
335
+ // Admin - Coupon Methods
336
+ // ==========================================================================
337
+ async createCoupon(amountCents) {
338
+ const endpoint = `${this.config.billingApiServerURL}/admin/coupons`;
339
+ const resp = await this.makeAuthenticatedRequest(endpoint, "POST", "compute", { amountCents });
340
+ return resp.json();
341
+ }
342
+ async listCoupons(opts) {
343
+ const params = new URLSearchParams();
344
+ if (opts?.offset !== void 0) params.set("offset", opts.offset.toString());
345
+ if (opts?.limit !== void 0) params.set("limit", opts.limit.toString());
346
+ if (opts?.active !== void 0) params.set("active", opts.active.toString());
347
+ if (opts?.redeemed !== void 0) params.set("redeemed", opts.redeemed.toString());
348
+ const qs = params.toString();
349
+ const endpoint = `${this.config.billingApiServerURL}/admin/coupons${qs ? `?${qs}` : ""}`;
350
+ const resp = await this.makeAuthenticatedRequest(endpoint, "GET", "compute");
351
+ return resp.json();
352
+ }
353
+ async getCoupon(id) {
354
+ const endpoint = `${this.config.billingApiServerURL}/admin/coupons/${id}`;
355
+ const resp = await this.makeAuthenticatedRequest(endpoint, "GET", "compute");
356
+ return resp.json();
357
+ }
358
+ async deactivateCoupon(id) {
359
+ const endpoint = `${this.config.billingApiServerURL}/admin/coupons/${id}/deactivate`;
360
+ await this.makeAuthenticatedRequest(endpoint, "POST", "compute");
361
+ }
362
+ async redeemCouponForUser(id, address) {
363
+ const endpoint = `${this.config.billingApiServerURL}/admin/coupons/${id}/redeem`;
364
+ await this.makeAuthenticatedRequest(endpoint, "POST", "compute", { address });
365
+ }
366
+ // ==========================================================================
367
+ // Admin - Admin Management Methods
368
+ // ==========================================================================
369
+ async addAdmin(address) {
370
+ const endpoint = `${this.config.billingApiServerURL}/admin/admins`;
371
+ const resp = await this.makeAuthenticatedRequest(endpoint, "POST", "compute", { address });
372
+ return resp.json();
373
+ }
374
+ async removeAdmin(address) {
375
+ const endpoint = `${this.config.billingApiServerURL}/admin/admins/${address}`;
376
+ await this.makeAuthenticatedRequest(endpoint, "DELETE", "compute");
377
+ }
378
+ async listAdmins() {
379
+ const endpoint = `${this.config.billingApiServerURL}/admin/admins`;
380
+ const resp = await this.makeAuthenticatedRequest(endpoint, "GET", "compute");
381
+ return resp.json();
382
+ }
383
+ // ==========================================================================
384
+ // User - Coupon Redemption
385
+ // ==========================================================================
386
+ async redeemCoupon(code) {
387
+ const endpoint = `${this.config.billingApiServerURL}/v1/coupons/redeem`;
388
+ const resp = await this.makeAuthenticatedRequest(endpoint, "POST", "compute", { code });
389
+ return resp.json();
390
+ }
391
+ // ==========================================================================
335
392
  // Internal Methods
336
393
  // ==========================================================================
337
394
  /**
@@ -463,6 +520,7 @@ Please check:
463
520
  // src/client/common/config/environment.ts
464
521
  var SEPOLIA_CHAIN_ID = 11155111;
465
522
  var MAINNET_CHAIN_ID = 1;
523
+ var BASE_SEPOLIA_CHAIN_ID = 84532;
466
524
  var CommonAddresses = {
467
525
  ERC7702Delegator: "0x63c0c19a282a1b52b07dd5a65b58948a07dae32b"
468
526
  };
@@ -482,27 +540,28 @@ var BILLING_ENVIRONMENTS = {
482
540
  billingApiServerURL: "https://billingapi.eigencloud.xyz"
483
541
  }
484
542
  };
485
- var PLATFORM_ENV_TESTNET_SEPOLIA = "testnet-sepolia";
486
- var PLATFORM_ENV_MAINNET_ETHEREUM = "mainnet-ethereum";
487
- var DEFAULT_APP_BASE_DOMAIN = "eigencloud.xyz";
488
543
  var ENVIRONMENTS = {
489
544
  "sepolia-dev": {
490
545
  name: "sepolia",
491
546
  build: "dev",
492
547
  appControllerAddress: "0xa86DC1C47cb2518327fB4f9A1627F51966c83B92",
548
+ releaseAbiVersion: "v1.5",
549
+ // AppController upgraded to v1.5.x (containerPolicy)
493
550
  permissionControllerAddress: ChainAddresses[SEPOLIA_CHAIN_ID].PermissionController,
494
551
  erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,
495
552
  kmsServerURL: "http://10.128.0.57:8080",
496
553
  userApiServerURL: "https://userapi-compute-sepolia-dev.eigencloud.xyz",
497
554
  defaultRPCURL: "https://ethereum-sepolia-rpc.publicnode.com",
498
555
  usdcCreditsAddress: "0xbdA3897c3A428763B59015C64AB766c288C97376",
499
- platformEnv: PLATFORM_ENV_TESTNET_SEPOLIA,
500
- appBaseDomain: DEFAULT_APP_BASE_DOMAIN
556
+ baseUsdcCreditsAddress: "0x7673a47463F80c6a3553Db9E54c8cDcd5313d0ac",
557
+ baseRPCURL: "https://base-sepolia-rpc.publicnode.com"
501
558
  },
502
559
  sepolia: {
503
560
  name: "sepolia",
504
561
  build: "prod",
505
562
  appControllerAddress: "0x0dd810a6ffba6a9820a10d97b659f07d8d23d4E2",
563
+ releaseAbiVersion: "v1.4",
564
+ // prod still on AppController v1.4.0 (3-field Release)
506
565
  permissionControllerAddress: ChainAddresses[SEPOLIA_CHAIN_ID].PermissionController,
507
566
  erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,
508
567
  kmsServerURL: "http://10.128.15.203:8080",
@@ -510,21 +569,21 @@ var ENVIRONMENTS = {
510
569
  defaultRPCURL: "https://ethereum-sepolia-rpc.publicnode.com",
511
570
  billingRPCURL: "https://ethereum-rpc.publicnode.com",
512
571
  usdcCreditsAddress: "0xed9c88640ca9149Bd9f7ee6620074af10F2E145d",
513
- platformEnv: PLATFORM_ENV_TESTNET_SEPOLIA,
514
- appBaseDomain: DEFAULT_APP_BASE_DOMAIN
572
+ baseUsdcCreditsAddress: "0x7673a47463F80c6a3553Db9E54c8cDcd5313d0ac",
573
+ baseRPCURL: "https://base-sepolia-rpc.publicnode.com"
515
574
  },
516
575
  "mainnet-alpha": {
517
576
  name: "mainnet-alpha",
518
577
  build: "prod",
519
578
  appControllerAddress: "0xc38d35Fc995e75342A21CBd6D770305b142Fbe67",
579
+ releaseAbiVersion: "v1.4",
580
+ // prod still on AppController v1.4.0 (3-field Release)
520
581
  permissionControllerAddress: ChainAddresses[MAINNET_CHAIN_ID].PermissionController,
521
582
  erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,
522
583
  kmsServerURL: "http://10.128.0.2:8080",
523
584
  userApiServerURL: "https://userapi-compute.eigencloud.xyz",
524
585
  defaultRPCURL: "https://ethereum-rpc.publicnode.com",
525
- usdcCreditsAddress: "0xed9c88640ca9149Bd9f7ee6620074af10F2E145d",
526
- platformEnv: PLATFORM_ENV_MAINNET_ETHEREUM,
527
- appBaseDomain: DEFAULT_APP_BASE_DOMAIN
586
+ usdcCreditsAddress: "0xed9c88640ca9149Bd9f7ee6620074af10F2E145d"
528
587
  }
529
588
  };
530
589
  var CHAIN_ID_TO_ENVIRONMENT = {
@@ -584,7 +643,7 @@ function getBillingEnvironmentConfig(build) {
584
643
  };
585
644
  }
586
645
  function getBuildType() {
587
- const buildTimeType = true ? "dev"?.toLowerCase() : void 0;
646
+ const buildTimeType = true ? "prod"?.toLowerCase() : void 0;
588
647
  const runtimeType = process.env.BUILD_TYPE?.toLowerCase();
589
648
  const buildType = buildTimeType || runtimeType;
590
649
  if (buildType === "dev") {
@@ -603,6 +662,41 @@ function isEnvironmentAvailable(environment) {
603
662
  return getAvailableEnvironments().includes(environment);
604
663
  }
605
664
 
665
+ // src/client/common/utils/helpers.ts
666
+ var import_viem2 = require("viem");
667
+ var import_chains2 = require("viem/chains");
668
+ var import_accounts = require("viem/accounts");
669
+
670
+ // src/client/common/constants.ts
671
+ var import_chains = require("viem/chains");
672
+ var SUPPORTED_CHAINS = [import_chains.mainnet, import_chains.sepolia, import_chains.baseSepolia];
673
+
674
+ // src/client/common/utils/helpers.ts
675
+ function getChainFromID(chainID, fallback2 = import_chains2.sepolia) {
676
+ const id = Number(chainID);
677
+ return (0, import_viem2.extractChain)({ chains: SUPPORTED_CHAINS, id }) || fallback2;
678
+ }
679
+ function createClients(options) {
680
+ const { privateKey, rpcUrl, chainId } = options;
681
+ const privateKeyHex = addHexPrefix(privateKey);
682
+ const account = (0, import_accounts.privateKeyToAccount)(privateKeyHex);
683
+ const chain = getChainFromID(chainId);
684
+ const transport = typeof rpcUrl === "string" ? (0, import_viem2.http)(rpcUrl) : (0, import_viem2.fallback)(rpcUrl.map((url) => (0, import_viem2.http)(url)));
685
+ const publicClient = (0, import_viem2.createPublicClient)({
686
+ chain,
687
+ transport
688
+ });
689
+ const walletClient = (0, import_viem2.createWalletClient)({
690
+ account,
691
+ chain,
692
+ transport
693
+ });
694
+ return { walletClient, publicClient };
695
+ }
696
+ function addHexPrefix(value) {
697
+ return value.startsWith("0x") ? value : `0x${value}`;
698
+ }
699
+
606
700
  // src/client/common/utils/logger.ts
607
701
  var getLogger = (verbose) => ({
608
702
  info: (...args) => console.info(...args),
@@ -614,14 +708,6 @@ var getLogger = (verbose) => ({
614
708
  // src/client/common/utils/userapi.ts
615
709
  var import_axios3 = __toESM(require("axios"), 1);
616
710
 
617
- // src/client/common/utils/helpers.ts
618
- var import_viem2 = require("viem");
619
- var import_chains2 = require("viem/chains");
620
- var import_accounts = require("viem/accounts");
621
-
622
- // src/client/common/constants.ts
623
- var import_chains = require("viem/chains");
624
-
625
711
  // src/client/common/utils/retry.ts
626
712
  var import_axios2 = __toESM(require("axios"), 1);
627
713
 
@@ -2117,7 +2203,7 @@ var ERC20_default = [
2117
2203
 
2118
2204
  // src/client/modules/billing/index.ts
2119
2205
  function createBillingModule(config) {
2120
- const { verbose = false, skipTelemetry = false, walletClient, publicClient, environment } = config;
2206
+ const { verbose = false, skipTelemetry = false, walletClient, publicClient, environment, privateKey } = config;
2121
2207
  if (!walletClient.account) {
2122
2208
  throw new Error("WalletClient must have an account attached");
2123
2209
  }
@@ -2126,35 +2212,69 @@ function createBillingModule(config) {
2126
2212
  const billingEnvConfig = getBillingEnvironmentConfig(getBuildType());
2127
2213
  const billingApi = new BillingApiClient(billingEnvConfig, walletClient, { verbose });
2128
2214
  const environmentConfig = getEnvironmentConfig(environment);
2129
- const usdcCreditsAddress = environmentConfig.usdcCreditsAddress;
2130
- if (!usdcCreditsAddress) {
2215
+ if (!environmentConfig.usdcCreditsAddress) {
2131
2216
  throw new Error(`USDCCredits contract address not configured for environment "${environment}"`);
2132
2217
  }
2218
+ const usdcCreditsAddress = environmentConfig.usdcCreditsAddress;
2219
+ const baseUsdcCreditsAddress = environmentConfig.baseUsdcCreditsAddress;
2220
+ const baseRPCURL = environmentConfig.baseRPCURL;
2221
+ function resolveChainConfig(chain) {
2222
+ if (chain === "base") {
2223
+ if (!baseUsdcCreditsAddress || !baseRPCURL) {
2224
+ throw new Error(`Base chain not configured for environment "${environment}"`);
2225
+ }
2226
+ if (!privateKey) {
2227
+ throw new Error("Private key required for Base chain transactions");
2228
+ }
2229
+ const baseClients = createClients({
2230
+ privateKey,
2231
+ rpcUrl: baseRPCURL,
2232
+ chainId: BigInt(BASE_SEPOLIA_CHAIN_ID)
2233
+ });
2234
+ return {
2235
+ pub: baseClients.publicClient,
2236
+ wallet: baseClients.walletClient,
2237
+ creditsAddress: baseUsdcCreditsAddress,
2238
+ envConfig: {
2239
+ ...environmentConfig,
2240
+ chainID: BigInt(BASE_SEPOLIA_CHAIN_ID),
2241
+ defaultRPCURL: baseRPCURL
2242
+ }
2243
+ };
2244
+ }
2245
+ return {
2246
+ pub: publicClient,
2247
+ wallet: walletClient,
2248
+ creditsAddress: usdcCreditsAddress,
2249
+ envConfig: environmentConfig
2250
+ };
2251
+ }
2133
2252
  const module2 = {
2134
2253
  address,
2135
- async getTopUpInfo() {
2136
- const usdcAddress = await publicClient.readContract({
2137
- address: usdcCreditsAddress,
2254
+ async getTopUpInfo(opts) {
2255
+ const { pub, creditsAddress } = resolveChainConfig(opts?.chain);
2256
+ const usdcAddress = await pub.readContract({
2257
+ address: creditsAddress,
2138
2258
  abi: USDCCredits_default,
2139
2259
  functionName: "usdc"
2140
2260
  });
2141
2261
  const [minimumPurchase, usdcBalance, currentAllowance] = await Promise.all([
2142
- publicClient.readContract({
2143
- address: usdcCreditsAddress,
2262
+ pub.readContract({
2263
+ address: creditsAddress,
2144
2264
  abi: USDCCredits_default,
2145
2265
  functionName: "minimumPurchase"
2146
2266
  }),
2147
- publicClient.readContract({
2267
+ pub.readContract({
2148
2268
  address: usdcAddress,
2149
2269
  abi: ERC20_default,
2150
2270
  functionName: "balanceOf",
2151
2271
  args: [address]
2152
2272
  }),
2153
- publicClient.readContract({
2273
+ pub.readContract({
2154
2274
  address: usdcAddress,
2155
2275
  abi: ERC20_default,
2156
2276
  functionName: "allowance",
2157
- args: [address, usdcCreditsAddress]
2277
+ args: [address, creditsAddress]
2158
2278
  })
2159
2279
  ]);
2160
2280
  return { usdcAddress, minimumPurchase, usdcBalance, currentAllowance };
@@ -2164,11 +2284,12 @@ function createBillingModule(config) {
2164
2284
  {
2165
2285
  functionName: "topUp",
2166
2286
  skipTelemetry,
2167
- properties: { amount: opts.amount.toString() }
2287
+ properties: { amount: opts.amount.toString(), chain: opts.chain || "ethereum" }
2168
2288
  },
2169
2289
  async () => {
2170
2290
  const targetAccount = opts.account ?? address;
2171
- const { usdcAddress, currentAllowance } = await module2.getTopUpInfo();
2291
+ const { pub, wallet, creditsAddress, envConfig } = resolveChainConfig(opts.chain);
2292
+ const { usdcAddress, currentAllowance } = await module2.getTopUpInfo({ chain: opts.chain });
2172
2293
  const executions = [];
2173
2294
  if (currentAllowance < opts.amount) {
2174
2295
  executions.push({
@@ -2177,12 +2298,12 @@ function createBillingModule(config) {
2177
2298
  callData: (0, import_viem5.encodeFunctionData)({
2178
2299
  abi: ERC20_default,
2179
2300
  functionName: "approve",
2180
- args: [usdcCreditsAddress, opts.amount]
2301
+ args: [creditsAddress, opts.amount]
2181
2302
  })
2182
2303
  });
2183
2304
  }
2184
2305
  executions.push({
2185
- target: usdcCreditsAddress,
2306
+ target: creditsAddress,
2186
2307
  value: 0n,
2187
2308
  callData: (0, import_viem5.encodeFunctionData)({
2188
2309
  abi: USDCCredits_default,
@@ -2192,9 +2313,9 @@ function createBillingModule(config) {
2192
2313
  });
2193
2314
  const txHash = await executeBatch(
2194
2315
  {
2195
- walletClient,
2196
- publicClient,
2197
- environmentConfig,
2316
+ walletClient: wallet,
2317
+ publicClient: pub,
2318
+ environmentConfig: envConfig,
2198
2319
  executions,
2199
2320
  pendingMessage: "Submitting credit purchase..."
2200
2321
  },
@@ -2294,6 +2415,12 @@ function createBillingModule(config) {
2294
2415
  },
2295
2416
  async purchaseCredits(amountCents, paymentMethodId) {
2296
2417
  return billingApi.purchaseCredits(amountCents, paymentMethodId);
2418
+ },
2419
+ hasBaseSupport() {
2420
+ return !!baseUsdcCreditsAddress && !!baseRPCURL;
2421
+ },
2422
+ async redeemCoupon(code) {
2423
+ return billingApi.redeemCoupon(code);
2297
2424
  }
2298
2425
  };
2299
2426
  return module2;