@aspan/sdk 0.4.4 → 0.4.6

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/src/client.ts CHANGED
@@ -54,6 +54,7 @@ export function getChainById(chainId: number): Chain {
54
54
  return chain;
55
55
  }
56
56
  import { DiamondABI } from "./abi/diamond";
57
+ import { SApUSDABI } from "./abi/sApUSD";
57
58
  import type {
58
59
  LSTInfo,
59
60
  LSTYieldInfo,
@@ -525,6 +526,20 @@ export class AspanReadClient {
525
526
  });
526
527
  }
527
528
 
529
+ /**
530
+ * Get user's underlying balances (apUSD + xBNB) from sApUSD vault
531
+ */
532
+ async getBalanceMulti(user: Address): Promise<{ apUSDBalance: bigint; xBNBBalance: bigint }> {
533
+ const sApUSDAddress = await this.getSApUSD();
534
+ const [apUSDBalance, xBNBBalance] = await this.publicClient.readContract({
535
+ address: sApUSDAddress,
536
+ abi: SApUSDABI,
537
+ functionName: "underlyingBalances",
538
+ args: [user],
539
+ });
540
+ return { apUSDBalance, xBNBBalance };
541
+ }
542
+
528
543
  async getUserStabilityPoolPosition(
529
544
  user: Address
530
545
  ): Promise<UserStabilityPoolPosition> {
@@ -583,20 +598,35 @@ export class AspanReadClient {
583
598
  }
584
599
  }
585
600
 
586
- async previewRedeem(shares: bigint): Promise<bigint> {
587
- try {
588
- return await this.publicClient.readContract({
589
- address: this.diamondAddress,
590
- abi: DiamondABI,
591
- functionName: "previewRedeem",
592
- args: [shares],
593
- });
594
- } catch (error) {
595
- if (this.isZeroSupplyError(error)) {
596
- return shares; // 1:1 when pool is empty
597
- }
598
- throw error;
599
- }
601
+ /**
602
+ * Preview withdraw with multi-asset support (apUSD + xBNB)
603
+ * Replaces previewRedeem — works for both clean and dirty pools.
604
+ * @param shares Amount of sApUSD shares to redeem
605
+ * @returns Object with apUSD and xBNB amounts, plus whether vault has xBNB
606
+ */
607
+ async previewRedeemMulti(shares: bigint): Promise<{
608
+ apUSD: bigint;
609
+ xBNB: bigint;
610
+ hasXBNB: boolean;
611
+ assets: Address[];
612
+ amounts: bigint[];
613
+ }> {
614
+ // Use Diamond's previewRedeemMulti (forwards to SApUSD)
615
+ const [assets, amounts] = await this.publicClient.readContract({
616
+ address: this.diamondAddress,
617
+ abi: DiamondABI,
618
+ functionName: "previewRedeemMulti",
619
+ args: [shares],
620
+ }) as [Address[], bigint[]];
621
+
622
+ const hasXBNB = amounts.length > 1 && amounts[1] > 0n;
623
+ return {
624
+ apUSD: amounts[0] ?? 0n,
625
+ xBNB: amounts[1] ?? 0n,
626
+ hasXBNB,
627
+ assets,
628
+ amounts,
629
+ };
600
630
  }
601
631
 
602
632
  async getPendingYield(): Promise<bigint> {
@@ -770,6 +800,122 @@ export class AspanReadClient {
770
800
  };
771
801
  }
772
802
 
803
+ /**
804
+ * Get all fee tiers
805
+ * @returns Array of fee tiers sorted by minCR descending
806
+ */
807
+ async getAllFeeTiers(): Promise<FeeTier[]> {
808
+ const result = await this.publicClient.readContract({
809
+ address: this.diamondAddress,
810
+ abi: DiamondABI,
811
+ functionName: "getAllFeeTiers",
812
+ }) as unknown as Array<{
813
+ minCR: bigint;
814
+ apUSDMintFee: number;
815
+ apUSDRedeemFee: number;
816
+ xBNBMintFee: number;
817
+ xBNBRedeemFee: number;
818
+ apUSDMintDisabled: boolean;
819
+ }>;
820
+ return result.map((tier) => ({
821
+ minCR: tier.minCR,
822
+ apUSDMintFee: tier.apUSDMintFee,
823
+ apUSDRedeemFee: tier.apUSDRedeemFee,
824
+ xBNBMintFee: tier.xBNBMintFee,
825
+ xBNBRedeemFee: tier.xBNBRedeemFee,
826
+ apUSDMintDisabled: tier.apUSDMintDisabled,
827
+ }));
828
+ }
829
+
830
+ /**
831
+ * Get comprehensive vault (sApUSD) info for frontend display
832
+ * @returns Vault state including TVL, exchange rate, xBNB status
833
+ */
834
+ async getVaultInfo(): Promise<{
835
+ totalSupply: bigint;
836
+ totalAssets: bigint;
837
+ exchangeRate: bigint;
838
+ hasXBNB: boolean;
839
+ xBNBAmount: bigint;
840
+ }> {
841
+ const sApUSDAddress = await this.getSApUSD();
842
+ const [totalSupply, totalAssets, exchangeRate, conversion] = await Promise.all([
843
+ this.publicClient.readContract({
844
+ address: sApUSDAddress,
845
+ abi: SApUSDABI,
846
+ functionName: "totalSupply",
847
+ }) as Promise<bigint>,
848
+ this.publicClient.readContract({
849
+ address: sApUSDAddress,
850
+ abi: SApUSDABI,
851
+ functionName: "totalAssets",
852
+ }) as Promise<bigint>,
853
+ this.publicClient.readContract({
854
+ address: sApUSDAddress,
855
+ abi: SApUSDABI,
856
+ functionName: "exchangeRate",
857
+ }) as Promise<bigint>,
858
+ this.publicClient.readContract({
859
+ address: sApUSDAddress,
860
+ abi: SApUSDABI,
861
+ functionName: "hasStabilityConversion",
862
+ }) as Promise<[boolean, bigint]>,
863
+ ]);
864
+ return {
865
+ totalSupply,
866
+ totalAssets,
867
+ exchangeRate,
868
+ hasXBNB: conversion[0],
869
+ xBNBAmount: conversion[1],
870
+ };
871
+ }
872
+
873
+ /**
874
+ * Get full protocol dashboard data in one call (for frontend overview page)
875
+ * Batches all key metrics into a single multicall
876
+ */
877
+ async getProtocolOverview(): Promise<{
878
+ collateralRatio: bigint;
879
+ tvlBNB: bigint;
880
+ tvlUSD: bigint;
881
+ apUSDSupply: bigint;
882
+ xBNBSupply: bigint;
883
+ xBNBPriceUSD: bigint;
884
+ xBNBPriceBNB: bigint;
885
+ bnbPriceUSD: bigint;
886
+ currentFees: CurrentFeeTier;
887
+ stabilityMode: StabilityModeInfo;
888
+ totalStaked: bigint;
889
+ }> {
890
+ const [cr, tvlBNB, tvlUSD, apUSD, xBNB, xPriceUSD, xPriceBNB, bnbPrice, fees, sm, staked] =
891
+ await Promise.all([
892
+ this.getCollateralRatio(),
893
+ this.getTVLInBNB(),
894
+ this.getTVLInUSD(),
895
+ this.getApUSDSupply(),
896
+ this.getXBNBSupply(),
897
+ this.getXBNBPriceUSD(),
898
+ this.getXBNBPriceBNB(),
899
+ this.getBNBPriceUSD(),
900
+ this.getCurrentFeeTier(),
901
+ this.getStabilityMode(),
902
+ this.getTotalStaked(),
903
+ ]);
904
+ return {
905
+ collateralRatio: cr,
906
+ tvlBNB,
907
+ tvlUSD,
908
+ apUSDSupply: apUSD,
909
+ xBNBSupply: xBNB,
910
+ xBNBPriceUSD: xPriceUSD,
911
+ xBNBPriceBNB: xPriceBNB,
912
+ bnbPriceUSD: bnbPrice,
913
+ currentFees: fees,
914
+ stabilityMode: sm,
915
+ totalStaked: staked,
916
+ };
917
+ }
918
+
773
919
  async getCurrentFeeTier(): Promise<CurrentFeeTier> {
774
920
  try {
775
921
  const result = await this.publicClient.readContract({