@aspan/sdk 0.4.6 → 0.4.8

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.js CHANGED
@@ -314,13 +314,6 @@ var DiamondABI = [
314
314
  outputs: [{ name: "assets", type: "uint256", internalType: "uint256" }],
315
315
  stateMutability: "nonpayable"
316
316
  },
317
- {
318
- type: "function",
319
- name: "withdrawAssets",
320
- inputs: [{ name: "_assets", type: "uint256", internalType: "uint256" }],
321
- outputs: [{ name: "shares", type: "uint256", internalType: "uint256" }],
322
- stateMutability: "nonpayable"
323
- },
324
317
  {
325
318
  type: "function",
326
319
  name: "getShares",
@@ -739,13 +732,13 @@ var SApUSDABI = [
739
732
  },
740
733
  {
741
734
  type: "function",
742
- name: "previewRedeemMulti",
735
+ name: "previewRedeem",
743
736
  inputs: [
744
737
  { name: "shares", type: "uint256", internalType: "uint256" }
745
738
  ],
746
739
  outputs: [
747
- { name: "assets", type: "address[]", internalType: "address[]" },
748
- { name: "amounts", type: "uint256[]", internalType: "uint256[]" }
740
+ { name: "apUSDOut", type: "uint256", internalType: "uint256" },
741
+ { name: "xBNBOut", type: "uint256", internalType: "uint256" }
749
742
  ],
750
743
  stateMutability: "view"
751
744
  },
@@ -792,56 +785,69 @@ var SApUSDABI = [
792
785
  },
793
786
  {
794
787
  type: "function",
795
- name: "previewCleanXBNB",
788
+ name: "hasRole",
796
789
  inputs: [
797
- { name: "_xBNBAmount", type: "uint256", internalType: "uint256" },
798
- { name: "_router", type: "address", internalType: "address" },
799
- { name: "_path", type: "address[]", internalType: "address[]" }
790
+ { name: "role", type: "bytes32", internalType: "bytes32" },
791
+ { name: "account", type: "address", internalType: "address" }
800
792
  ],
801
- outputs: [{ name: "expectedApUSD", type: "uint256", internalType: "uint256" }],
793
+ outputs: [{ name: "", type: "bool", internalType: "bool" }],
802
794
  stateMutability: "view"
803
795
  },
796
+ // ============ Write Functions ============
804
797
  {
805
798
  type: "function",
806
- name: "KEEPER_ROLE",
807
- inputs: [],
808
- outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
809
- stateMutability: "view"
799
+ name: "redeem",
800
+ inputs: [
801
+ { name: "shares", type: "uint256", internalType: "uint256" },
802
+ { name: "receiver", type: "address", internalType: "address" },
803
+ { name: "owner", type: "address", internalType: "address" }
804
+ ],
805
+ outputs: [
806
+ { name: "apUSDOut", type: "uint256", internalType: "uint256" },
807
+ { name: "xBNBOut", type: "uint256", internalType: "uint256" }
808
+ ],
809
+ stateMutability: "nonpayable"
810
810
  },
811
811
  {
812
812
  type: "function",
813
- name: "hasRole",
813
+ name: "deposit",
814
814
  inputs: [
815
- { name: "role", type: "bytes32", internalType: "bytes32" },
816
- { name: "account", type: "address", internalType: "address" }
815
+ { name: "assets", type: "uint256", internalType: "uint256" },
816
+ { name: "receiver", type: "address", internalType: "address" }
817
817
  ],
818
- outputs: [{ name: "", type: "bool", internalType: "bool" }],
819
- stateMutability: "view"
818
+ outputs: [{ name: "shares", type: "uint256", internalType: "uint256" }],
819
+ stateMutability: "nonpayable"
820
820
  },
821
- // ============ Keeper Functions ============
821
+ // ============ Accounting Functions ============
822
822
  {
823
823
  type: "function",
824
- name: "cleanXBNB",
824
+ name: "addAccounting",
825
825
  inputs: [
826
- { name: "_xBNBAmount", type: "uint256", internalType: "uint256" },
827
- { name: "_minApUSDOut", type: "uint256", internalType: "uint256" },
828
- { name: "_router", type: "address", internalType: "address" },
829
- { name: "_path", type: "address[]", internalType: "address[]" },
830
- { name: "_deadline", type: "uint256", internalType: "uint256" }
826
+ { name: "apUSD", type: "uint256", internalType: "uint256" },
827
+ { name: "xBNB", type: "uint256", internalType: "uint256" }
831
828
  ],
832
- outputs: [{ name: "apUSDReceived", type: "uint256", internalType: "uint256" }],
829
+ outputs: [],
833
830
  stateMutability: "nonpayable"
834
831
  },
835
- // ============ Events ============
836
832
  {
837
- type: "event",
838
- name: "VaultCleaned",
833
+ type: "function",
834
+ name: "subAccounting",
839
835
  inputs: [
840
- { name: "xBNBSold", type: "uint256", indexed: false, internalType: "uint256" },
841
- { name: "apUSDReceived", type: "uint256", indexed: false, internalType: "uint256" },
842
- { name: "keeper", type: "address", indexed: true, internalType: "address" }
836
+ { name: "apUSD", type: "uint256", internalType: "uint256" },
837
+ { name: "xBNB", type: "uint256", internalType: "uint256" }
843
838
  ],
844
- anonymous: false
839
+ outputs: [],
840
+ stateMutability: "nonpayable"
841
+ },
842
+ // ============ Admin Functions ============
843
+ {
844
+ type: "function",
845
+ name: "sweepExcess",
846
+ inputs: [
847
+ { name: "recipient", type: "address", internalType: "address" }
848
+ ],
849
+ outputs: [],
850
+ stateMutability: "nonpayable"
845
851
  }
846
852
  ];
847
853
 
@@ -886,7 +892,8 @@ var AspanReadClient = class _AspanReadClient {
886
892
  this.chain = config.chain ?? import_chains.bsc;
887
893
  this.publicClient = (0, import_viem.createPublicClient)({
888
894
  chain: this.chain,
889
- transport: (0, import_viem.http)(config.rpcUrl)
895
+ transport: (0, import_viem.http)(config.rpcUrl),
896
+ batch: { multicall: true }
890
897
  });
891
898
  }
892
899
  /**
@@ -1813,21 +1820,6 @@ var AspanClient = class extends AspanReadClient {
1813
1820
  args: [params.shares]
1814
1821
  });
1815
1822
  }
1816
- /**
1817
- * Withdraw from stability pool by asset amount
1818
- * @param params Withdraw parameters
1819
- * @returns Transaction hash
1820
- */
1821
- async withdrawAssets(params) {
1822
- return this.walletClient.writeContract({
1823
- chain: this.chain,
1824
- account: this.walletClient.account,
1825
- address: this.diamondAddress,
1826
- abi: DiamondABI,
1827
- functionName: "withdrawAssets",
1828
- args: [params.assets]
1829
- });
1830
- }
1831
1823
  /**
1832
1824
  * Harvest yield from LSTs
1833
1825
  * @returns Transaction hash
@@ -2157,6 +2149,20 @@ var RouterABI = [
2157
2149
  outputs: [{ type: "bool" }],
2158
2150
  stateMutability: "view"
2159
2151
  },
2152
+ {
2153
+ type: "function",
2154
+ name: "lstModes",
2155
+ inputs: [{ name: "lst", type: "address" }],
2156
+ outputs: [{ type: "uint8" }],
2157
+ stateMutability: "view"
2158
+ },
2159
+ {
2160
+ type: "function",
2161
+ name: "isLSTRoutable",
2162
+ inputs: [{ name: "lst", type: "address" }],
2163
+ outputs: [{ type: "bool" }],
2164
+ stateMutability: "view"
2165
+ },
2160
2166
  // Preview functions - unified
2161
2167
  {
2162
2168
  type: "function",
@@ -2378,14 +2384,23 @@ var AspanRouterReadClient = class {
2378
2384
  publicClient;
2379
2385
  routerAddress;
2380
2386
  chain;
2387
+ _addressCache = /* @__PURE__ */ new Map();
2381
2388
  constructor(config) {
2382
2389
  this.routerAddress = config.routerAddress;
2383
2390
  this.chain = config.chain ?? import_chains2.bsc;
2384
2391
  this.publicClient = (0, import_viem2.createPublicClient)({
2385
2392
  chain: this.chain,
2386
- transport: (0, import_viem2.http)(config.rpcUrl)
2393
+ transport: (0, import_viem2.http)(config.rpcUrl),
2394
+ batch: { multicall: true }
2387
2395
  });
2388
2396
  }
2397
+ async _getCachedAddress(key, fetcher) {
2398
+ const cached = this._addressCache.get(key);
2399
+ if (cached) return cached;
2400
+ const addr = await fetcher();
2401
+ this._addressCache.set(key, addr);
2402
+ return addr;
2403
+ }
2389
2404
  // ============ View Functions ============
2390
2405
  /**
2391
2406
  * Get the default LST address
@@ -2420,15 +2435,41 @@ var AspanRouterReadClient = class {
2420
2435
  });
2421
2436
  }
2422
2437
  /**
2423
- * Get the Diamond contract address
2438
+ * Get LST mode (0 = SYNC, 1 = ASYNC_DIRECT_ONLY)
2424
2439
  */
2425
- async getDiamond() {
2440
+ async getLSTMode(lst) {
2441
+ const mode = await this.publicClient.readContract({
2442
+ address: this.routerAddress,
2443
+ abi: RouterABI,
2444
+ functionName: "lstModes",
2445
+ args: [lst]
2446
+ });
2447
+ return Number(mode);
2448
+ }
2449
+ /**
2450
+ * Check whether an LST supports routed flows (swap/stake/redeemAndSwap)
2451
+ */
2452
+ async isLSTRoutable(lst) {
2426
2453
  return this.publicClient.readContract({
2427
2454
  address: this.routerAddress,
2428
2455
  abi: RouterABI,
2429
- functionName: "diamond"
2456
+ functionName: "isLSTRoutable",
2457
+ args: [lst]
2430
2458
  });
2431
2459
  }
2460
+ /**
2461
+ * Get the Diamond contract address
2462
+ */
2463
+ async getDiamond() {
2464
+ return this._getCachedAddress(
2465
+ "diamond",
2466
+ async () => this.publicClient.readContract({
2467
+ address: this.routerAddress,
2468
+ abi: RouterABI,
2469
+ functionName: "diamond"
2470
+ })
2471
+ );
2472
+ }
2432
2473
  /**
2433
2474
  * Preview mint output for a given LST amount
2434
2475
  * @param lst LST token address
@@ -2457,6 +2498,96 @@ var AspanRouterReadClient = class {
2457
2498
  args: [lst, redeemXBNB, amount]
2458
2499
  });
2459
2500
  }
2501
+ /**
2502
+ * SDK-only preview: input token -> estimated LST -> previewMint
2503
+ * Note: oracle-based estimation (does not include live DEX slippage/price impact)
2504
+ */
2505
+ async previewMintByInput(inputToken, inputAmount, targetLST, mintXBNB) {
2506
+ if (inputAmount === 0n) return { lstAmount: 0n, mintedAmount: 0n };
2507
+ let lstAmount = 0n;
2508
+ const inNorm = inputToken.toLowerCase();
2509
+ if (inNorm === targetLST.toLowerCase()) {
2510
+ lstAmount = inputAmount;
2511
+ } else {
2512
+ const [diamond, wbnb, usdt, usdc] = await Promise.all([
2513
+ this.getDiamond(),
2514
+ this.getWBNB(),
2515
+ this.getUSDT(),
2516
+ this.getUSDC()
2517
+ ]);
2518
+ const [bnbPrice8, lstPrice] = await Promise.all([
2519
+ this.publicClient.readContract({
2520
+ address: diamond,
2521
+ abi: DiamondABI,
2522
+ functionName: "getBNBPriceUSD"
2523
+ }),
2524
+ this.publicClient.readContract({
2525
+ address: diamond,
2526
+ abi: DiamondABI,
2527
+ functionName: "getLSTPriceUSD",
2528
+ args: [targetLST]
2529
+ })
2530
+ ]);
2531
+ const bnbPrice18 = BigInt(bnbPrice8) * 10n ** 10n;
2532
+ const lstPrice18 = BigInt(lstPrice);
2533
+ const one = 10n ** 18n;
2534
+ if (inNorm === import_viem2.zeroAddress.toLowerCase() || inNorm === wbnb.toLowerCase()) {
2535
+ const usdValue = inputAmount * bnbPrice18 / one;
2536
+ lstAmount = lstPrice18 === 0n ? 0n : usdValue * one / lstPrice18;
2537
+ } else if (inNorm === usdt.toLowerCase() || inNorm === usdc.toLowerCase()) {
2538
+ lstAmount = lstPrice18 === 0n ? 0n : inputAmount * one / lstPrice18;
2539
+ } else {
2540
+ throw new Error("Unsupported input token for SDK preview");
2541
+ }
2542
+ }
2543
+ const mintedAmount = await this.previewMint(targetLST, lstAmount, mintXBNB);
2544
+ return { lstAmount, mintedAmount };
2545
+ }
2546
+ /**
2547
+ * SDK-only preview: previewRedeem -> estimated output token
2548
+ * Note: oracle-based estimation (does not include live DEX slippage/price impact)
2549
+ */
2550
+ async previewRedeemToOutput(lst, redeemXBNB, amount, outputToken) {
2551
+ const lstAmount = await this.previewRedeem(lst, redeemXBNB, amount);
2552
+ if (lstAmount === 0n) return { lstAmount: 0n, outputAmount: 0n };
2553
+ let outputAmount = 0n;
2554
+ const outNorm = outputToken.toLowerCase();
2555
+ if (outNorm === lst.toLowerCase()) {
2556
+ outputAmount = lstAmount;
2557
+ } else {
2558
+ const [diamond, wbnb, usdt, usdc] = await Promise.all([
2559
+ this.getDiamond(),
2560
+ this.getWBNB(),
2561
+ this.getUSDT(),
2562
+ this.getUSDC()
2563
+ ]);
2564
+ const [bnbPrice8, lstPrice] = await Promise.all([
2565
+ this.publicClient.readContract({
2566
+ address: diamond,
2567
+ abi: DiamondABI,
2568
+ functionName: "getBNBPriceUSD"
2569
+ }),
2570
+ this.publicClient.readContract({
2571
+ address: diamond,
2572
+ abi: DiamondABI,
2573
+ functionName: "getLSTPriceUSD",
2574
+ args: [lst]
2575
+ })
2576
+ ]);
2577
+ const bnbPrice18 = BigInt(bnbPrice8) * 10n ** 10n;
2578
+ const lstPrice18 = BigInt(lstPrice);
2579
+ const one = 10n ** 18n;
2580
+ const usdValue = lstAmount * lstPrice18 / one;
2581
+ if (outNorm === import_viem2.zeroAddress.toLowerCase() || outNorm === wbnb.toLowerCase()) {
2582
+ outputAmount = bnbPrice18 === 0n ? 0n : usdValue * one / bnbPrice18;
2583
+ } else if (outNorm === usdt.toLowerCase() || outNorm === usdc.toLowerCase()) {
2584
+ outputAmount = usdValue;
2585
+ } else {
2586
+ throw new Error("Unsupported output token for SDK preview");
2587
+ }
2588
+ }
2589
+ return { lstAmount, outputAmount };
2590
+ }
2460
2591
  /**
2461
2592
  * Get user's withdrawal request indices
2462
2593
  */
@@ -2486,60 +2617,84 @@ var AspanRouterReadClient = class {
2486
2617
  }
2487
2618
  // ============ Token Address Getters ============
2488
2619
  async getWBNB() {
2489
- return this.publicClient.readContract({
2490
- address: this.routerAddress,
2491
- abi: RouterABI,
2492
- functionName: "wbnb"
2493
- });
2620
+ return this._getCachedAddress(
2621
+ "wbnb",
2622
+ async () => this.publicClient.readContract({
2623
+ address: this.routerAddress,
2624
+ abi: RouterABI,
2625
+ functionName: "wbnb"
2626
+ })
2627
+ );
2494
2628
  }
2495
2629
  async getUSDT() {
2496
- return this.publicClient.readContract({
2497
- address: this.routerAddress,
2498
- abi: RouterABI,
2499
- functionName: "usdt"
2500
- });
2630
+ return this._getCachedAddress(
2631
+ "usdt",
2632
+ async () => this.publicClient.readContract({
2633
+ address: this.routerAddress,
2634
+ abi: RouterABI,
2635
+ functionName: "usdt"
2636
+ })
2637
+ );
2501
2638
  }
2502
2639
  async getUSDC() {
2503
- return this.publicClient.readContract({
2504
- address: this.routerAddress,
2505
- abi: RouterABI,
2506
- functionName: "usdc"
2507
- });
2640
+ return this._getCachedAddress(
2641
+ "usdc",
2642
+ async () => this.publicClient.readContract({
2643
+ address: this.routerAddress,
2644
+ abi: RouterABI,
2645
+ functionName: "usdc"
2646
+ })
2647
+ );
2508
2648
  }
2509
2649
  async getSlisBNB() {
2510
- return this.publicClient.readContract({
2511
- address: this.routerAddress,
2512
- abi: RouterABI,
2513
- functionName: "slisBNB"
2514
- });
2650
+ return this._getCachedAddress(
2651
+ "slisBNB",
2652
+ async () => this.publicClient.readContract({
2653
+ address: this.routerAddress,
2654
+ abi: RouterABI,
2655
+ functionName: "slisBNB"
2656
+ })
2657
+ );
2515
2658
  }
2516
2659
  async getAsBNB() {
2517
- return this.publicClient.readContract({
2518
- address: this.routerAddress,
2519
- abi: RouterABI,
2520
- functionName: "asBNB"
2521
- });
2660
+ return this._getCachedAddress(
2661
+ "asBNB",
2662
+ async () => this.publicClient.readContract({
2663
+ address: this.routerAddress,
2664
+ abi: RouterABI,
2665
+ functionName: "asBNB"
2666
+ })
2667
+ );
2522
2668
  }
2523
2669
  async getWclisBNB() {
2524
- return this.publicClient.readContract({
2525
- address: this.routerAddress,
2526
- abi: RouterABI,
2527
- functionName: "wclisBNB"
2528
- });
2670
+ return this._getCachedAddress(
2671
+ "wclisBNB",
2672
+ async () => this.publicClient.readContract({
2673
+ address: this.routerAddress,
2674
+ abi: RouterABI,
2675
+ functionName: "wclisBNB"
2676
+ })
2677
+ );
2529
2678
  }
2530
2679
  async getApUSD() {
2531
- return this.publicClient.readContract({
2532
- address: this.routerAddress,
2533
- abi: RouterABI,
2534
- functionName: "apUSD"
2535
- });
2680
+ return this._getCachedAddress(
2681
+ "apUSD",
2682
+ async () => this.publicClient.readContract({
2683
+ address: this.routerAddress,
2684
+ abi: RouterABI,
2685
+ functionName: "apUSD"
2686
+ })
2687
+ );
2536
2688
  }
2537
2689
  async getXBNB() {
2538
- return this.publicClient.readContract({
2539
- address: this.routerAddress,
2540
- abi: RouterABI,
2541
- functionName: "xBNB"
2542
- });
2690
+ return this._getCachedAddress(
2691
+ "xBNB",
2692
+ async () => this.publicClient.readContract({
2693
+ address: this.routerAddress,
2694
+ abi: RouterABI,
2695
+ functionName: "xBNB"
2696
+ })
2697
+ );
2543
2698
  }
2544
2699
  };
2545
2700
  var AspanRouterClient = class extends AspanRouterReadClient {
@@ -2795,7 +2950,7 @@ var BPS_PRECISION = 10000n;
2795
2950
  var PRICE_PRECISION = 10n ** 8n;
2796
2951
  var BSC_ADDRESSES = {
2797
2952
  diamond: "0x6a11B30d3a70727d5477D6d8090e144443fA1c78",
2798
- router: "0x29dd49b2e98674ee7531f17e4d40a7725918c3f6",
2953
+ router: "0x34a64c4EbDe830773083BA8c9469456616F6723b",
2799
2954
  apUSD: "0x4570047eeB5aDb4081c5d470494EB5134e34A287",
2800
2955
  xBNB: "0x0A0c9CD826e747D99F90D63e780B3727Da4D0d43",
2801
2956
  sApUSD: "0x896770Dba7c0481539E25aaB56bE285ECF6D65eB",