@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/README.md CHANGED
@@ -347,6 +347,13 @@ const hash = await client.deposit({ apUSDAmount: parseAmount("1000") });
347
347
  const position = await client.getUserStabilityPoolPosition(account.address);
348
348
  console.log("sApUSD Balance:", formatAmount(position.balance));
349
349
  console.log("Earned:", formatAmount(position.balance - position.deposited));
350
+
351
+ // Preview withdrawal (supports dirty pools with apUSD + xBNB)
352
+ const preview = await client.previewRedeemMulti(position.shares);
353
+ console.log("Will receive apUSD:", formatAmount(preview.apUSD));
354
+ if (preview.hasXBNB) {
355
+ console.log("Will also receive xBNB:", formatAmount(preview.xBNB));
356
+ }
350
357
  ```
351
358
 
352
359
  ### 5. Quick Exit: apUSD/xBNB → USDT
@@ -539,6 +546,7 @@ console.log("Leverage:", formatAmount(stats.effectiveLeverage), "x");
539
546
  | `redeemXBNB(params)` | Redeem xBNB for LST |
540
547
  | `deposit(params)` | Deposit apUSD to stability pool |
541
548
  | `withdraw(params)` | Withdraw from stability pool |
549
+ | `previewRedeemMulti(shares)` | Preview multi-asset withdrawal (apUSD + xBNB) |
542
550
  | `harvestYield()` | Trigger yield distribution |
543
551
 
544
552
  ---
package/dist/index.d.mts CHANGED
@@ -457,11 +457,30 @@ declare class AspanReadClient {
457
457
  getOracleBounds(priceFeed: Address): Promise<OracleBounds>;
458
458
  getShares(user: Address): Promise<bigint>;
459
459
  getBalance(user: Address): Promise<bigint>;
460
+ /**
461
+ * Get user's underlying balances (apUSD + xBNB) from sApUSD vault
462
+ */
463
+ getBalanceMulti(user: Address): Promise<{
464
+ apUSDBalance: bigint;
465
+ xBNBBalance: bigint;
466
+ }>;
460
467
  getUserStabilityPoolPosition(user: Address): Promise<UserStabilityPoolPosition>;
461
468
  getExchangeRate(): Promise<bigint>;
462
469
  getTotalStaked(): Promise<bigint>;
463
470
  previewDeposit(assets: bigint): Promise<bigint>;
464
- previewRedeem(shares: bigint): Promise<bigint>;
471
+ /**
472
+ * Preview withdraw with multi-asset support (apUSD + xBNB)
473
+ * Replaces previewRedeem — works for both clean and dirty pools.
474
+ * @param shares Amount of sApUSD shares to redeem
475
+ * @returns Object with apUSD and xBNB amounts, plus whether vault has xBNB
476
+ */
477
+ previewRedeemMulti(shares: bigint): Promise<{
478
+ apUSD: bigint;
479
+ xBNB: bigint;
480
+ hasXBNB: boolean;
481
+ assets: Address[];
482
+ amounts: bigint[];
483
+ }>;
465
484
  getPendingYield(): Promise<bigint>;
466
485
  getTotalYieldGenerated(): Promise<bigint>;
467
486
  getLSTYieldInfo(lstToken: Address): Promise<LSTYieldInfo>;
@@ -474,6 +493,39 @@ declare class AspanReadClient {
474
493
  getTreasury(): Promise<Address>;
475
494
  getFeeTierCount(): Promise<bigint>;
476
495
  getFeeTier(index: bigint): Promise<FeeTier>;
496
+ /**
497
+ * Get all fee tiers
498
+ * @returns Array of fee tiers sorted by minCR descending
499
+ */
500
+ getAllFeeTiers(): Promise<FeeTier[]>;
501
+ /**
502
+ * Get comprehensive vault (sApUSD) info for frontend display
503
+ * @returns Vault state including TVL, exchange rate, xBNB status
504
+ */
505
+ getVaultInfo(): Promise<{
506
+ totalSupply: bigint;
507
+ totalAssets: bigint;
508
+ exchangeRate: bigint;
509
+ hasXBNB: boolean;
510
+ xBNBAmount: bigint;
511
+ }>;
512
+ /**
513
+ * Get full protocol dashboard data in one call (for frontend overview page)
514
+ * Batches all key metrics into a single multicall
515
+ */
516
+ getProtocolOverview(): Promise<{
517
+ collateralRatio: bigint;
518
+ tvlBNB: bigint;
519
+ tvlUSD: bigint;
520
+ apUSDSupply: bigint;
521
+ xBNBSupply: bigint;
522
+ xBNBPriceUSD: bigint;
523
+ xBNBPriceBNB: bigint;
524
+ bnbPriceUSD: bigint;
525
+ currentFees: CurrentFeeTier;
526
+ stabilityMode: StabilityModeInfo;
527
+ totalStaked: bigint;
528
+ }>;
477
529
  getCurrentFeeTier(): Promise<CurrentFeeTier>;
478
530
  getMaxPriceAge(): Promise<bigint>;
479
531
  getMinDepositPeriod(): Promise<bigint>;
@@ -1377,6 +1429,24 @@ declare const DiamondABI: readonly [{
1377
1429
  readonly internalType: "uint256";
1378
1430
  }];
1379
1431
  readonly stateMutability: "view";
1432
+ }, {
1433
+ readonly type: "function";
1434
+ readonly name: "previewRedeemMulti";
1435
+ readonly inputs: readonly [{
1436
+ readonly name: "_shares";
1437
+ readonly type: "uint256";
1438
+ readonly internalType: "uint256";
1439
+ }];
1440
+ readonly outputs: readonly [{
1441
+ readonly name: "assets";
1442
+ readonly type: "address[]";
1443
+ readonly internalType: "address[]";
1444
+ }, {
1445
+ readonly name: "amounts";
1446
+ readonly type: "uint256[]";
1447
+ readonly internalType: "uint256[]";
1448
+ }];
1449
+ readonly stateMutability: "view";
1380
1450
  }, {
1381
1451
  readonly type: "function";
1382
1452
  readonly name: "getPendingYield";
@@ -1529,6 +1599,16 @@ declare const DiamondABI: readonly [{
1529
1599
  readonly internalType: "address";
1530
1600
  }];
1531
1601
  readonly stateMutability: "view";
1602
+ }, {
1603
+ readonly type: "function";
1604
+ readonly name: "setSApUSD";
1605
+ readonly inputs: readonly [{
1606
+ readonly name: "_sApUSD";
1607
+ readonly type: "address";
1608
+ readonly internalType: "address";
1609
+ }];
1610
+ readonly outputs: readonly [];
1611
+ readonly stateMutability: "nonpayable";
1532
1612
  }, {
1533
1613
  readonly type: "function";
1534
1614
  readonly name: "getStabilityPool";
@@ -1559,6 +1639,41 @@ declare const DiamondABI: readonly [{
1559
1639
  readonly internalType: "uint256";
1560
1640
  }];
1561
1641
  readonly stateMutability: "view";
1642
+ }, {
1643
+ readonly type: "function";
1644
+ readonly name: "getAllFeeTiers";
1645
+ readonly inputs: readonly [];
1646
+ readonly outputs: readonly [{
1647
+ readonly name: "";
1648
+ readonly type: "tuple[]";
1649
+ readonly internalType: "struct LibAppStorage.FeeTier[]";
1650
+ readonly components: readonly [{
1651
+ readonly name: "minCR";
1652
+ readonly type: "uint256";
1653
+ readonly internalType: "uint256";
1654
+ }, {
1655
+ readonly name: "apUSDMintFee";
1656
+ readonly type: "uint16";
1657
+ readonly internalType: "uint16";
1658
+ }, {
1659
+ readonly name: "apUSDRedeemFee";
1660
+ readonly type: "uint16";
1661
+ readonly internalType: "uint16";
1662
+ }, {
1663
+ readonly name: "xBNBMintFee";
1664
+ readonly type: "uint16";
1665
+ readonly internalType: "uint16";
1666
+ }, {
1667
+ readonly name: "xBNBRedeemFee";
1668
+ readonly type: "uint16";
1669
+ readonly internalType: "uint16";
1670
+ }, {
1671
+ readonly name: "apUSDMintDisabled";
1672
+ readonly type: "bool";
1673
+ readonly internalType: "bool";
1674
+ }];
1675
+ }];
1676
+ readonly stateMutability: "view";
1562
1677
  }, {
1563
1678
  readonly type: "function";
1564
1679
  readonly name: "getFeeTier";
package/dist/index.d.ts CHANGED
@@ -457,11 +457,30 @@ declare class AspanReadClient {
457
457
  getOracleBounds(priceFeed: Address): Promise<OracleBounds>;
458
458
  getShares(user: Address): Promise<bigint>;
459
459
  getBalance(user: Address): Promise<bigint>;
460
+ /**
461
+ * Get user's underlying balances (apUSD + xBNB) from sApUSD vault
462
+ */
463
+ getBalanceMulti(user: Address): Promise<{
464
+ apUSDBalance: bigint;
465
+ xBNBBalance: bigint;
466
+ }>;
460
467
  getUserStabilityPoolPosition(user: Address): Promise<UserStabilityPoolPosition>;
461
468
  getExchangeRate(): Promise<bigint>;
462
469
  getTotalStaked(): Promise<bigint>;
463
470
  previewDeposit(assets: bigint): Promise<bigint>;
464
- previewRedeem(shares: bigint): Promise<bigint>;
471
+ /**
472
+ * Preview withdraw with multi-asset support (apUSD + xBNB)
473
+ * Replaces previewRedeem — works for both clean and dirty pools.
474
+ * @param shares Amount of sApUSD shares to redeem
475
+ * @returns Object with apUSD and xBNB amounts, plus whether vault has xBNB
476
+ */
477
+ previewRedeemMulti(shares: bigint): Promise<{
478
+ apUSD: bigint;
479
+ xBNB: bigint;
480
+ hasXBNB: boolean;
481
+ assets: Address[];
482
+ amounts: bigint[];
483
+ }>;
465
484
  getPendingYield(): Promise<bigint>;
466
485
  getTotalYieldGenerated(): Promise<bigint>;
467
486
  getLSTYieldInfo(lstToken: Address): Promise<LSTYieldInfo>;
@@ -474,6 +493,39 @@ declare class AspanReadClient {
474
493
  getTreasury(): Promise<Address>;
475
494
  getFeeTierCount(): Promise<bigint>;
476
495
  getFeeTier(index: bigint): Promise<FeeTier>;
496
+ /**
497
+ * Get all fee tiers
498
+ * @returns Array of fee tiers sorted by minCR descending
499
+ */
500
+ getAllFeeTiers(): Promise<FeeTier[]>;
501
+ /**
502
+ * Get comprehensive vault (sApUSD) info for frontend display
503
+ * @returns Vault state including TVL, exchange rate, xBNB status
504
+ */
505
+ getVaultInfo(): Promise<{
506
+ totalSupply: bigint;
507
+ totalAssets: bigint;
508
+ exchangeRate: bigint;
509
+ hasXBNB: boolean;
510
+ xBNBAmount: bigint;
511
+ }>;
512
+ /**
513
+ * Get full protocol dashboard data in one call (for frontend overview page)
514
+ * Batches all key metrics into a single multicall
515
+ */
516
+ getProtocolOverview(): Promise<{
517
+ collateralRatio: bigint;
518
+ tvlBNB: bigint;
519
+ tvlUSD: bigint;
520
+ apUSDSupply: bigint;
521
+ xBNBSupply: bigint;
522
+ xBNBPriceUSD: bigint;
523
+ xBNBPriceBNB: bigint;
524
+ bnbPriceUSD: bigint;
525
+ currentFees: CurrentFeeTier;
526
+ stabilityMode: StabilityModeInfo;
527
+ totalStaked: bigint;
528
+ }>;
477
529
  getCurrentFeeTier(): Promise<CurrentFeeTier>;
478
530
  getMaxPriceAge(): Promise<bigint>;
479
531
  getMinDepositPeriod(): Promise<bigint>;
@@ -1377,6 +1429,24 @@ declare const DiamondABI: readonly [{
1377
1429
  readonly internalType: "uint256";
1378
1430
  }];
1379
1431
  readonly stateMutability: "view";
1432
+ }, {
1433
+ readonly type: "function";
1434
+ readonly name: "previewRedeemMulti";
1435
+ readonly inputs: readonly [{
1436
+ readonly name: "_shares";
1437
+ readonly type: "uint256";
1438
+ readonly internalType: "uint256";
1439
+ }];
1440
+ readonly outputs: readonly [{
1441
+ readonly name: "assets";
1442
+ readonly type: "address[]";
1443
+ readonly internalType: "address[]";
1444
+ }, {
1445
+ readonly name: "amounts";
1446
+ readonly type: "uint256[]";
1447
+ readonly internalType: "uint256[]";
1448
+ }];
1449
+ readonly stateMutability: "view";
1380
1450
  }, {
1381
1451
  readonly type: "function";
1382
1452
  readonly name: "getPendingYield";
@@ -1529,6 +1599,16 @@ declare const DiamondABI: readonly [{
1529
1599
  readonly internalType: "address";
1530
1600
  }];
1531
1601
  readonly stateMutability: "view";
1602
+ }, {
1603
+ readonly type: "function";
1604
+ readonly name: "setSApUSD";
1605
+ readonly inputs: readonly [{
1606
+ readonly name: "_sApUSD";
1607
+ readonly type: "address";
1608
+ readonly internalType: "address";
1609
+ }];
1610
+ readonly outputs: readonly [];
1611
+ readonly stateMutability: "nonpayable";
1532
1612
  }, {
1533
1613
  readonly type: "function";
1534
1614
  readonly name: "getStabilityPool";
@@ -1559,6 +1639,41 @@ declare const DiamondABI: readonly [{
1559
1639
  readonly internalType: "uint256";
1560
1640
  }];
1561
1641
  readonly stateMutability: "view";
1642
+ }, {
1643
+ readonly type: "function";
1644
+ readonly name: "getAllFeeTiers";
1645
+ readonly inputs: readonly [];
1646
+ readonly outputs: readonly [{
1647
+ readonly name: "";
1648
+ readonly type: "tuple[]";
1649
+ readonly internalType: "struct LibAppStorage.FeeTier[]";
1650
+ readonly components: readonly [{
1651
+ readonly name: "minCR";
1652
+ readonly type: "uint256";
1653
+ readonly internalType: "uint256";
1654
+ }, {
1655
+ readonly name: "apUSDMintFee";
1656
+ readonly type: "uint16";
1657
+ readonly internalType: "uint16";
1658
+ }, {
1659
+ readonly name: "apUSDRedeemFee";
1660
+ readonly type: "uint16";
1661
+ readonly internalType: "uint16";
1662
+ }, {
1663
+ readonly name: "xBNBMintFee";
1664
+ readonly type: "uint16";
1665
+ readonly internalType: "uint16";
1666
+ }, {
1667
+ readonly name: "xBNBRedeemFee";
1668
+ readonly type: "uint16";
1669
+ readonly internalType: "uint16";
1670
+ }, {
1671
+ readonly name: "apUSDMintDisabled";
1672
+ readonly type: "bool";
1673
+ readonly internalType: "bool";
1674
+ }];
1675
+ }];
1676
+ readonly stateMutability: "view";
1562
1677
  }, {
1563
1678
  readonly type: "function";
1564
1679
  readonly name: "getFeeTier";
package/dist/index.js CHANGED
@@ -363,6 +363,16 @@ var DiamondABI = [
363
363
  outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
364
364
  stateMutability: "view"
365
365
  },
366
+ {
367
+ type: "function",
368
+ name: "previewRedeemMulti",
369
+ inputs: [{ name: "_shares", type: "uint256", internalType: "uint256" }],
370
+ outputs: [
371
+ { name: "assets", type: "address[]", internalType: "address[]" },
372
+ { name: "amounts", type: "uint256[]", internalType: "uint256[]" }
373
+ ],
374
+ stateMutability: "view"
375
+ },
366
376
  {
367
377
  type: "function",
368
378
  name: "getPendingYield",
@@ -463,6 +473,13 @@ var DiamondABI = [
463
473
  outputs: [{ name: "", type: "address", internalType: "address" }],
464
474
  stateMutability: "view"
465
475
  },
476
+ {
477
+ type: "function",
478
+ name: "setSApUSD",
479
+ inputs: [{ name: "_sApUSD", type: "address", internalType: "address" }],
480
+ outputs: [],
481
+ stateMutability: "nonpayable"
482
+ },
466
483
  {
467
484
  type: "function",
468
485
  name: "getStabilityPool",
@@ -484,6 +501,25 @@ var DiamondABI = [
484
501
  outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
485
502
  stateMutability: "view"
486
503
  },
504
+ {
505
+ type: "function",
506
+ name: "getAllFeeTiers",
507
+ inputs: [],
508
+ outputs: [{
509
+ name: "",
510
+ type: "tuple[]",
511
+ internalType: "struct LibAppStorage.FeeTier[]",
512
+ components: [
513
+ { name: "minCR", type: "uint256", internalType: "uint256" },
514
+ { name: "apUSDMintFee", type: "uint16", internalType: "uint16" },
515
+ { name: "apUSDRedeemFee", type: "uint16", internalType: "uint16" },
516
+ { name: "xBNBMintFee", type: "uint16", internalType: "uint16" },
517
+ { name: "xBNBRedeemFee", type: "uint16", internalType: "uint16" },
518
+ { name: "apUSDMintDisabled", type: "bool", internalType: "bool" }
519
+ ]
520
+ }],
521
+ stateMutability: "view"
522
+ },
487
523
  {
488
524
  type: "function",
489
525
  name: "getFeeTier",
@@ -677,6 +713,138 @@ var DiamondABI = [
677
713
  }
678
714
  ];
679
715
 
716
+ // src/abi/sApUSD.ts
717
+ var SApUSDABI = [
718
+ // ============ View Functions ============
719
+ {
720
+ type: "function",
721
+ name: "totalAssets",
722
+ inputs: [],
723
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
724
+ stateMutability: "view"
725
+ },
726
+ {
727
+ type: "function",
728
+ name: "totalSupply",
729
+ inputs: [],
730
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
731
+ stateMutability: "view"
732
+ },
733
+ {
734
+ type: "function",
735
+ name: "balanceOf",
736
+ inputs: [{ name: "account", type: "address", internalType: "address" }],
737
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
738
+ stateMutability: "view"
739
+ },
740
+ {
741
+ type: "function",
742
+ name: "previewRedeemMulti",
743
+ inputs: [
744
+ { name: "shares", type: "uint256", internalType: "uint256" }
745
+ ],
746
+ outputs: [
747
+ { name: "assets", type: "address[]", internalType: "address[]" },
748
+ { name: "amounts", type: "uint256[]", internalType: "uint256[]" }
749
+ ],
750
+ stateMutability: "view"
751
+ },
752
+ {
753
+ type: "function",
754
+ name: "hasStabilityConversion",
755
+ inputs: [],
756
+ outputs: [
757
+ { name: "hasXBNB", type: "bool", internalType: "bool" },
758
+ { name: "xBNBAmount", type: "uint256", internalType: "uint256" }
759
+ ],
760
+ stateMutability: "view"
761
+ },
762
+ {
763
+ type: "function",
764
+ name: "totalValue",
765
+ inputs: [],
766
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
767
+ stateMutability: "view"
768
+ },
769
+ {
770
+ type: "function",
771
+ name: "underlyingBalances",
772
+ inputs: [{ name: "_user", type: "address", internalType: "address" }],
773
+ outputs: [
774
+ { name: "apUSDBalance", type: "uint256", internalType: "uint256" },
775
+ { name: "xBNBBalance", type: "uint256", internalType: "uint256" }
776
+ ],
777
+ stateMutability: "view"
778
+ },
779
+ {
780
+ type: "function",
781
+ name: "xBNBToApUSDRate",
782
+ inputs: [],
783
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
784
+ stateMutability: "view"
785
+ },
786
+ {
787
+ type: "function",
788
+ name: "exchangeRate",
789
+ inputs: [],
790
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
791
+ stateMutability: "view"
792
+ },
793
+ {
794
+ type: "function",
795
+ name: "previewCleanXBNB",
796
+ inputs: [
797
+ { name: "_xBNBAmount", type: "uint256", internalType: "uint256" },
798
+ { name: "_router", type: "address", internalType: "address" },
799
+ { name: "_path", type: "address[]", internalType: "address[]" }
800
+ ],
801
+ outputs: [{ name: "expectedApUSD", type: "uint256", internalType: "uint256" }],
802
+ stateMutability: "view"
803
+ },
804
+ {
805
+ type: "function",
806
+ name: "KEEPER_ROLE",
807
+ inputs: [],
808
+ outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
809
+ stateMutability: "view"
810
+ },
811
+ {
812
+ type: "function",
813
+ name: "hasRole",
814
+ inputs: [
815
+ { name: "role", type: "bytes32", internalType: "bytes32" },
816
+ { name: "account", type: "address", internalType: "address" }
817
+ ],
818
+ outputs: [{ name: "", type: "bool", internalType: "bool" }],
819
+ stateMutability: "view"
820
+ },
821
+ // ============ Keeper Functions ============
822
+ {
823
+ type: "function",
824
+ name: "cleanXBNB",
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" }
831
+ ],
832
+ outputs: [{ name: "apUSDReceived", type: "uint256", internalType: "uint256" }],
833
+ stateMutability: "nonpayable"
834
+ },
835
+ // ============ Events ============
836
+ {
837
+ type: "event",
838
+ name: "VaultCleaned",
839
+ 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" }
843
+ ],
844
+ anonymous: false
845
+ }
846
+ ];
847
+
680
848
  // src/client.ts
681
849
  var pharosTestnet = {
682
850
  id: 688689,
@@ -1070,6 +1238,19 @@ var AspanReadClient = class _AspanReadClient {
1070
1238
  args: [user]
1071
1239
  });
1072
1240
  }
1241
+ /**
1242
+ * Get user's underlying balances (apUSD + xBNB) from sApUSD vault
1243
+ */
1244
+ async getBalanceMulti(user) {
1245
+ const sApUSDAddress = await this.getSApUSD();
1246
+ const [apUSDBalance, xBNBBalance] = await this.publicClient.readContract({
1247
+ address: sApUSDAddress,
1248
+ abi: SApUSDABI,
1249
+ functionName: "underlyingBalances",
1250
+ args: [user]
1251
+ });
1252
+ return { apUSDBalance, xBNBBalance };
1253
+ }
1073
1254
  async getUserStabilityPoolPosition(user) {
1074
1255
  const [shares, balance] = await Promise.all([
1075
1256
  this.getShares(user),
@@ -1120,20 +1301,27 @@ var AspanReadClient = class _AspanReadClient {
1120
1301
  throw error;
1121
1302
  }
1122
1303
  }
1123
- async previewRedeem(shares) {
1124
- try {
1125
- return await this.publicClient.readContract({
1126
- address: this.diamondAddress,
1127
- abi: DiamondABI,
1128
- functionName: "previewRedeem",
1129
- args: [shares]
1130
- });
1131
- } catch (error) {
1132
- if (this.isZeroSupplyError(error)) {
1133
- return shares;
1134
- }
1135
- throw error;
1136
- }
1304
+ /**
1305
+ * Preview withdraw with multi-asset support (apUSD + xBNB)
1306
+ * Replaces previewRedeem — works for both clean and dirty pools.
1307
+ * @param shares Amount of sApUSD shares to redeem
1308
+ * @returns Object with apUSD and xBNB amounts, plus whether vault has xBNB
1309
+ */
1310
+ async previewRedeemMulti(shares) {
1311
+ const [assets, amounts] = await this.publicClient.readContract({
1312
+ address: this.diamondAddress,
1313
+ abi: DiamondABI,
1314
+ functionName: "previewRedeemMulti",
1315
+ args: [shares]
1316
+ });
1317
+ const hasXBNB = amounts.length > 1 && amounts[1] > 0n;
1318
+ return {
1319
+ apUSD: amounts[0] ?? 0n,
1320
+ xBNB: amounts[1] ?? 0n,
1321
+ hasXBNB,
1322
+ assets,
1323
+ amounts
1324
+ };
1137
1325
  }
1138
1326
  async getPendingYield() {
1139
1327
  try {
@@ -1288,6 +1476,93 @@ var AspanReadClient = class _AspanReadClient {
1288
1476
  apUSDMintDisabled: result[5]
1289
1477
  };
1290
1478
  }
1479
+ /**
1480
+ * Get all fee tiers
1481
+ * @returns Array of fee tiers sorted by minCR descending
1482
+ */
1483
+ async getAllFeeTiers() {
1484
+ const result = await this.publicClient.readContract({
1485
+ address: this.diamondAddress,
1486
+ abi: DiamondABI,
1487
+ functionName: "getAllFeeTiers"
1488
+ });
1489
+ return result.map((tier) => ({
1490
+ minCR: tier.minCR,
1491
+ apUSDMintFee: tier.apUSDMintFee,
1492
+ apUSDRedeemFee: tier.apUSDRedeemFee,
1493
+ xBNBMintFee: tier.xBNBMintFee,
1494
+ xBNBRedeemFee: tier.xBNBRedeemFee,
1495
+ apUSDMintDisabled: tier.apUSDMintDisabled
1496
+ }));
1497
+ }
1498
+ /**
1499
+ * Get comprehensive vault (sApUSD) info for frontend display
1500
+ * @returns Vault state including TVL, exchange rate, xBNB status
1501
+ */
1502
+ async getVaultInfo() {
1503
+ const sApUSDAddress = await this.getSApUSD();
1504
+ const [totalSupply, totalAssets, exchangeRate, conversion] = await Promise.all([
1505
+ this.publicClient.readContract({
1506
+ address: sApUSDAddress,
1507
+ abi: SApUSDABI,
1508
+ functionName: "totalSupply"
1509
+ }),
1510
+ this.publicClient.readContract({
1511
+ address: sApUSDAddress,
1512
+ abi: SApUSDABI,
1513
+ functionName: "totalAssets"
1514
+ }),
1515
+ this.publicClient.readContract({
1516
+ address: sApUSDAddress,
1517
+ abi: SApUSDABI,
1518
+ functionName: "exchangeRate"
1519
+ }),
1520
+ this.publicClient.readContract({
1521
+ address: sApUSDAddress,
1522
+ abi: SApUSDABI,
1523
+ functionName: "hasStabilityConversion"
1524
+ })
1525
+ ]);
1526
+ return {
1527
+ totalSupply,
1528
+ totalAssets,
1529
+ exchangeRate,
1530
+ hasXBNB: conversion[0],
1531
+ xBNBAmount: conversion[1]
1532
+ };
1533
+ }
1534
+ /**
1535
+ * Get full protocol dashboard data in one call (for frontend overview page)
1536
+ * Batches all key metrics into a single multicall
1537
+ */
1538
+ async getProtocolOverview() {
1539
+ const [cr, tvlBNB, tvlUSD, apUSD, xBNB, xPriceUSD, xPriceBNB, bnbPrice, fees, sm, staked] = await Promise.all([
1540
+ this.getCollateralRatio(),
1541
+ this.getTVLInBNB(),
1542
+ this.getTVLInUSD(),
1543
+ this.getApUSDSupply(),
1544
+ this.getXBNBSupply(),
1545
+ this.getXBNBPriceUSD(),
1546
+ this.getXBNBPriceBNB(),
1547
+ this.getBNBPriceUSD(),
1548
+ this.getCurrentFeeTier(),
1549
+ this.getStabilityMode(),
1550
+ this.getTotalStaked()
1551
+ ]);
1552
+ return {
1553
+ collateralRatio: cr,
1554
+ tvlBNB,
1555
+ tvlUSD,
1556
+ apUSDSupply: apUSD,
1557
+ xBNBSupply: xBNB,
1558
+ xBNBPriceUSD: xPriceUSD,
1559
+ xBNBPriceBNB: xPriceBNB,
1560
+ bnbPriceUSD: bnbPrice,
1561
+ currentFees: fees,
1562
+ stabilityMode: sm,
1563
+ totalStaked: staked
1564
+ };
1565
+ }
1291
1566
  async getCurrentFeeTier() {
1292
1567
  try {
1293
1568
  const result = await this.publicClient.readContract({