@aspan/sdk 0.4.9 → 0.5.1

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
@@ -22,11 +22,11 @@ import { BSC_ADDRESSES } from "@aspan/sdk";
22
22
  | Contract | Address |
23
23
  |----------|---------|
24
24
  | **Diamond (Main Entry)** | `0x6a11B30d3a70727d5477D6d8090e144443fA1c78` |
25
- | **Router** | `0x1Ca976d2043dfb785c7F3A17535B3A38c50113f3` |
25
+ | **Router** | `0xb8a90CD2811d6DDbB4B7969d30B036574842cb6E` |
26
26
  | **ApUSD** | `0x4570047eeB5aDb4081c5d470494EB5134e34A287` |
27
27
  | **XBNB** | `0x0A0c9CD826e747D99F90D63e780B3727Da4D0d43` |
28
28
  | **SApUSD** | `0xE2BE739C4aA4126ee72D612d9548C38B1B0e5A1b` |
29
- | **wclisBNB** | `0x448f7c2fa4e5135a4a5B50879602cf3CD428e108` |
29
+ | **wclisBNB** | `0xb2A0631bF0aC326fEefc201E7337E13C63Bbed07` |
30
30
 
31
31
  ## Quick Start
32
32
 
package/dist/index.d.mts CHANGED
@@ -97,14 +97,11 @@ interface RedeemXBNBParams {
97
97
  }
98
98
  /** Parameters for depositing to stability pool */
99
99
  interface DepositParams {
100
- assets: bigint;
101
- receiver: Address;
100
+ apUSDAmount: bigint;
102
101
  }
103
- /** Parameters for redeeming from stability pool */
104
- interface RedeemParams {
102
+ /** Parameters for withdrawing from stability pool */
103
+ interface WithdrawParams {
105
104
  shares: bigint;
106
- receiver: Address;
107
- owner: Address;
108
105
  }
109
106
  /** Overall protocol statistics */
110
107
  interface ProtocolStats {
@@ -206,7 +203,7 @@ interface RouterSwapParams {
206
203
  targetLST: Address;
207
204
  /** Minimum LST to receive from swap (slippage protection) */
208
205
  minLSTOut: bigint;
209
- /** PancakeSwap V3 pool fee tier (500, 2500, 10000) */
206
+ /** PancakeSwap V3 pool fee tier (100, 500, 2500, 10000) */
210
207
  poolFee: number;
211
208
  }
212
209
  /** Router mint parameters */
@@ -580,11 +577,11 @@ declare class AspanClient extends AspanReadClient {
580
577
  */
581
578
  deposit(params: DepositParams): Promise<Hash>;
582
579
  /**
583
- * Redeem from stability pool by shares
584
- * @param params Redeem parameters
580
+ * Withdraw from stability pool by shares
581
+ * @param params Withdraw parameters
585
582
  * @returns Transaction hash
586
583
  */
587
- redeem(params: RedeemParams): Promise<Hash>;
584
+ withdraw(params: WithdrawParams): Promise<Hash>;
588
585
  /**
589
586
  * Harvest yield from LSTs
590
587
  * @returns Transaction hash
@@ -773,6 +770,11 @@ declare class AspanRouterReadClient {
773
770
  getWBNB(): Promise<Address>;
774
771
  getUSDT(): Promise<Address>;
775
772
  getUSDC(): Promise<Address>;
773
+ /**
774
+ * Get stablecoin price in USD (18 decimals) from Chainlink.
775
+ * Returns 1e18 if feed unavailable (graceful fallback).
776
+ */
777
+ getStablecoinPrice(token: Address): Promise<bigint>;
776
778
  getSlisBNB(): Promise<Address>;
777
779
  getAsBNB(): Promise<Address>;
778
780
  getWclisBNB(): Promise<Address>;
@@ -1334,13 +1336,9 @@ declare const DiamondABI: readonly [{
1334
1336
  readonly type: "function";
1335
1337
  readonly name: "deposit";
1336
1338
  readonly inputs: readonly [{
1337
- readonly name: "assets";
1339
+ readonly name: "_amount";
1338
1340
  readonly type: "uint256";
1339
1341
  readonly internalType: "uint256";
1340
- }, {
1341
- readonly name: "receiver";
1342
- readonly type: "address";
1343
- readonly internalType: "address";
1344
1342
  }];
1345
1343
  readonly outputs: readonly [{
1346
1344
  readonly name: "shares";
@@ -1350,26 +1348,14 @@ declare const DiamondABI: readonly [{
1350
1348
  readonly stateMutability: "nonpayable";
1351
1349
  }, {
1352
1350
  readonly type: "function";
1353
- readonly name: "redeem";
1351
+ readonly name: "withdraw";
1354
1352
  readonly inputs: readonly [{
1355
- readonly name: "shares";
1353
+ readonly name: "_shares";
1356
1354
  readonly type: "uint256";
1357
1355
  readonly internalType: "uint256";
1358
- }, {
1359
- readonly name: "receiver";
1360
- readonly type: "address";
1361
- readonly internalType: "address";
1362
- }, {
1363
- readonly name: "owner";
1364
- readonly type: "address";
1365
- readonly internalType: "address";
1366
1356
  }];
1367
1357
  readonly outputs: readonly [{
1368
- readonly name: "apUSDOut";
1369
- readonly type: "uint256";
1370
- readonly internalType: "uint256";
1371
- }, {
1372
- readonly name: "xBNBOut";
1358
+ readonly name: "assets";
1373
1359
  readonly type: "uint256";
1374
1360
  readonly internalType: "uint256";
1375
1361
  }];
@@ -2828,15 +2814,18 @@ declare const BPS_PRECISION = 10000n;
2828
2814
  declare const PRICE_PRECISION: bigint;
2829
2815
  declare const BSC_ADDRESSES: {
2830
2816
  readonly diamond: "0x6a11B30d3a70727d5477D6d8090e144443fA1c78";
2831
- readonly router: "0x1Ca976d2043dfb785c7F3A17535B3A38c50113f3";
2817
+ readonly router: "0xb8a90CD2811d6DDbB4B7969d30B036574842cb6E";
2832
2818
  readonly apUSD: "0x4570047eeB5aDb4081c5d470494EB5134e34A287";
2833
2819
  readonly xBNB: "0x0A0c9CD826e747D99F90D63e780B3727Da4D0d43";
2834
2820
  readonly sApUSD: "0x896770Dba7c0481539E25aaB56bE285ECF6D65eB";
2835
2821
  readonly slisBNB: "0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B";
2836
2822
  readonly asBNB: "0x77734e70b6E88b4d82fE632a168EDf6e700912b6";
2837
- readonly wclisBNB: "0x448f7c2fa4e5135a4a5B50879602cf3CD428e108";
2823
+ readonly wclisBNB: "0xb2A0631bF0aC326fEefc201E7337E13C63Bbed07";
2838
2824
  readonly USDT: "0x55d398326f99059fF775485246999027B3197955";
2839
2825
  readonly USDC: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d";
2826
+ /** Chainlink price feeds (BSC Mainnet) */
2827
+ readonly USDT_USD_FEED: "0xB97Ad0E74fa7d920791E90258A6E2085088b4320";
2828
+ readonly USDC_USD_FEED: "0x51597f405303C4377E36123cBc172b13269EA163";
2840
2829
  readonly WBNB: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c";
2841
2830
  };
2842
2831
  declare const PHAROS_ADDRESSES: {
@@ -2888,4 +2877,4 @@ declare function formatPriceUSD(price: bigint): string;
2888
2877
  */
2889
2878
  declare function calculateAPY(previousRate: bigint, currentRate: bigint, periodDays: number): number;
2890
2879
 
2891
- export { type ApUSDMintedEvent, type ApUSDRedeemedEvent, AspanClient, type AspanClientConfig, AspanReadClient, AspanRouterClient, type AspanRouterClientConfig, AspanRouterReadClient, type AspanRouterWriteClientConfig, type AspanWriteClientConfig, BPS_PRECISION, BSC_ADDRESSES, type BigIntString, CHAIN_IDS, type CurrentFeeTier, type CurrentFees, type DepositParams, type DepositedEvent, DiamondABI, type ExpectedOutput, type FeeTier, type LSTInfo, type LSTYieldInfo, type MintApUSDParams, type MintXBNBParams, type OracleBounds, PHAROS_ADDRESSES, PRECISION, PRICE_PRECISION, type ProtocolStats, type RedeemAndSwapEvent, type RedeemApUSDParams, type RedeemParams, type RedeemXBNBParams, RouterABI, type RouterMintEvent, type RouterMintParams, type RouterMintParams2, type RouterRedeemAndSwapParams, type RouterRedeemAndUnstakeParams, type RouterRedeemEvent, type RouterRedeemParams, type RouterSwapParams, type StabilityMode2Info, type StabilityModeInfo, type StabilityPoolStats, type StakeAndMintEvent, type StakeAndMintParams, type SwapAndMintDefaultParams, type SwapAndMintEvent, type SwapAndMintParams, type TokenAddresses, type TransactionReceipt, type TransactionResult, type UnstakeClaimedEvent, type UnstakeRequestedEvent, type UserStabilityPoolPosition, type WithdrawalRequestInfo, type WithdrawnEvent, type XBNBMintedEvent, type XBNBRedeemedEvent, type YieldHarvestedEvent, type YieldStats, calculateAPY, createAspanClient, createAspanPharosClient, createAspanPharosReadClient, createAspanReadClient, createAspanReadClientForChain, createAspanTestnetClient, createAspanTestnetReadClient, createAspanWriteClientForChain, createRouterClient, createRouterPharosClient, createRouterPharosReadClient, createRouterReadClient, createRouterReadClientForChain, createRouterTestnetClient, createRouterTestnetReadClient, createRouterWriteClientForChain, encodeV3Path, formatAmount, formatCR, formatFeeBPS, formatPriceUSD, getChainById, parseAmount, pharosTestnet };
2880
+ export { type ApUSDMintedEvent, type ApUSDRedeemedEvent, AspanClient, type AspanClientConfig, AspanReadClient, AspanRouterClient, type AspanRouterClientConfig, AspanRouterReadClient, type AspanRouterWriteClientConfig, type AspanWriteClientConfig, BPS_PRECISION, BSC_ADDRESSES, type BigIntString, CHAIN_IDS, type CurrentFeeTier, type CurrentFees, type DepositParams, type DepositedEvent, DiamondABI, type ExpectedOutput, type FeeTier, type LSTInfo, type LSTYieldInfo, type MintApUSDParams, type MintXBNBParams, type OracleBounds, PHAROS_ADDRESSES, PRECISION, PRICE_PRECISION, type ProtocolStats, type RedeemAndSwapEvent, type RedeemApUSDParams, type RedeemXBNBParams, RouterABI, type RouterMintEvent, type RouterMintParams, type RouterMintParams2, type RouterRedeemAndSwapParams, type RouterRedeemAndUnstakeParams, type RouterRedeemEvent, type RouterRedeemParams, type RouterSwapParams, type StabilityMode2Info, type StabilityModeInfo, type StabilityPoolStats, type StakeAndMintEvent, type StakeAndMintParams, type SwapAndMintDefaultParams, type SwapAndMintEvent, type SwapAndMintParams, type TokenAddresses, type TransactionReceipt, type TransactionResult, type UnstakeClaimedEvent, type UnstakeRequestedEvent, type UserStabilityPoolPosition, type WithdrawParams, type WithdrawalRequestInfo, type WithdrawnEvent, type XBNBMintedEvent, type XBNBRedeemedEvent, type YieldHarvestedEvent, type YieldStats, calculateAPY, createAspanClient, createAspanPharosClient, createAspanPharosReadClient, createAspanReadClient, createAspanReadClientForChain, createAspanTestnetClient, createAspanTestnetReadClient, createAspanWriteClientForChain, createRouterClient, createRouterPharosClient, createRouterPharosReadClient, createRouterReadClient, createRouterReadClientForChain, createRouterTestnetClient, createRouterTestnetReadClient, createRouterWriteClientForChain, encodeV3Path, formatAmount, formatCR, formatFeeBPS, formatPriceUSD, getChainById, parseAmount, pharosTestnet };
package/dist/index.d.ts CHANGED
@@ -97,14 +97,11 @@ interface RedeemXBNBParams {
97
97
  }
98
98
  /** Parameters for depositing to stability pool */
99
99
  interface DepositParams {
100
- assets: bigint;
101
- receiver: Address;
100
+ apUSDAmount: bigint;
102
101
  }
103
- /** Parameters for redeeming from stability pool */
104
- interface RedeemParams {
102
+ /** Parameters for withdrawing from stability pool */
103
+ interface WithdrawParams {
105
104
  shares: bigint;
106
- receiver: Address;
107
- owner: Address;
108
105
  }
109
106
  /** Overall protocol statistics */
110
107
  interface ProtocolStats {
@@ -206,7 +203,7 @@ interface RouterSwapParams {
206
203
  targetLST: Address;
207
204
  /** Minimum LST to receive from swap (slippage protection) */
208
205
  minLSTOut: bigint;
209
- /** PancakeSwap V3 pool fee tier (500, 2500, 10000) */
206
+ /** PancakeSwap V3 pool fee tier (100, 500, 2500, 10000) */
210
207
  poolFee: number;
211
208
  }
212
209
  /** Router mint parameters */
@@ -580,11 +577,11 @@ declare class AspanClient extends AspanReadClient {
580
577
  */
581
578
  deposit(params: DepositParams): Promise<Hash>;
582
579
  /**
583
- * Redeem from stability pool by shares
584
- * @param params Redeem parameters
580
+ * Withdraw from stability pool by shares
581
+ * @param params Withdraw parameters
585
582
  * @returns Transaction hash
586
583
  */
587
- redeem(params: RedeemParams): Promise<Hash>;
584
+ withdraw(params: WithdrawParams): Promise<Hash>;
588
585
  /**
589
586
  * Harvest yield from LSTs
590
587
  * @returns Transaction hash
@@ -773,6 +770,11 @@ declare class AspanRouterReadClient {
773
770
  getWBNB(): Promise<Address>;
774
771
  getUSDT(): Promise<Address>;
775
772
  getUSDC(): Promise<Address>;
773
+ /**
774
+ * Get stablecoin price in USD (18 decimals) from Chainlink.
775
+ * Returns 1e18 if feed unavailable (graceful fallback).
776
+ */
777
+ getStablecoinPrice(token: Address): Promise<bigint>;
776
778
  getSlisBNB(): Promise<Address>;
777
779
  getAsBNB(): Promise<Address>;
778
780
  getWclisBNB(): Promise<Address>;
@@ -1334,13 +1336,9 @@ declare const DiamondABI: readonly [{
1334
1336
  readonly type: "function";
1335
1337
  readonly name: "deposit";
1336
1338
  readonly inputs: readonly [{
1337
- readonly name: "assets";
1339
+ readonly name: "_amount";
1338
1340
  readonly type: "uint256";
1339
1341
  readonly internalType: "uint256";
1340
- }, {
1341
- readonly name: "receiver";
1342
- readonly type: "address";
1343
- readonly internalType: "address";
1344
1342
  }];
1345
1343
  readonly outputs: readonly [{
1346
1344
  readonly name: "shares";
@@ -1350,26 +1348,14 @@ declare const DiamondABI: readonly [{
1350
1348
  readonly stateMutability: "nonpayable";
1351
1349
  }, {
1352
1350
  readonly type: "function";
1353
- readonly name: "redeem";
1351
+ readonly name: "withdraw";
1354
1352
  readonly inputs: readonly [{
1355
- readonly name: "shares";
1353
+ readonly name: "_shares";
1356
1354
  readonly type: "uint256";
1357
1355
  readonly internalType: "uint256";
1358
- }, {
1359
- readonly name: "receiver";
1360
- readonly type: "address";
1361
- readonly internalType: "address";
1362
- }, {
1363
- readonly name: "owner";
1364
- readonly type: "address";
1365
- readonly internalType: "address";
1366
1356
  }];
1367
1357
  readonly outputs: readonly [{
1368
- readonly name: "apUSDOut";
1369
- readonly type: "uint256";
1370
- readonly internalType: "uint256";
1371
- }, {
1372
- readonly name: "xBNBOut";
1358
+ readonly name: "assets";
1373
1359
  readonly type: "uint256";
1374
1360
  readonly internalType: "uint256";
1375
1361
  }];
@@ -2828,15 +2814,18 @@ declare const BPS_PRECISION = 10000n;
2828
2814
  declare const PRICE_PRECISION: bigint;
2829
2815
  declare const BSC_ADDRESSES: {
2830
2816
  readonly diamond: "0x6a11B30d3a70727d5477D6d8090e144443fA1c78";
2831
- readonly router: "0x1Ca976d2043dfb785c7F3A17535B3A38c50113f3";
2817
+ readonly router: "0xb8a90CD2811d6DDbB4B7969d30B036574842cb6E";
2832
2818
  readonly apUSD: "0x4570047eeB5aDb4081c5d470494EB5134e34A287";
2833
2819
  readonly xBNB: "0x0A0c9CD826e747D99F90D63e780B3727Da4D0d43";
2834
2820
  readonly sApUSD: "0x896770Dba7c0481539E25aaB56bE285ECF6D65eB";
2835
2821
  readonly slisBNB: "0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B";
2836
2822
  readonly asBNB: "0x77734e70b6E88b4d82fE632a168EDf6e700912b6";
2837
- readonly wclisBNB: "0x448f7c2fa4e5135a4a5B50879602cf3CD428e108";
2823
+ readonly wclisBNB: "0xb2A0631bF0aC326fEefc201E7337E13C63Bbed07";
2838
2824
  readonly USDT: "0x55d398326f99059fF775485246999027B3197955";
2839
2825
  readonly USDC: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d";
2826
+ /** Chainlink price feeds (BSC Mainnet) */
2827
+ readonly USDT_USD_FEED: "0xB97Ad0E74fa7d920791E90258A6E2085088b4320";
2828
+ readonly USDC_USD_FEED: "0x51597f405303C4377E36123cBc172b13269EA163";
2840
2829
  readonly WBNB: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c";
2841
2830
  };
2842
2831
  declare const PHAROS_ADDRESSES: {
@@ -2888,4 +2877,4 @@ declare function formatPriceUSD(price: bigint): string;
2888
2877
  */
2889
2878
  declare function calculateAPY(previousRate: bigint, currentRate: bigint, periodDays: number): number;
2890
2879
 
2891
- export { type ApUSDMintedEvent, type ApUSDRedeemedEvent, AspanClient, type AspanClientConfig, AspanReadClient, AspanRouterClient, type AspanRouterClientConfig, AspanRouterReadClient, type AspanRouterWriteClientConfig, type AspanWriteClientConfig, BPS_PRECISION, BSC_ADDRESSES, type BigIntString, CHAIN_IDS, type CurrentFeeTier, type CurrentFees, type DepositParams, type DepositedEvent, DiamondABI, type ExpectedOutput, type FeeTier, type LSTInfo, type LSTYieldInfo, type MintApUSDParams, type MintXBNBParams, type OracleBounds, PHAROS_ADDRESSES, PRECISION, PRICE_PRECISION, type ProtocolStats, type RedeemAndSwapEvent, type RedeemApUSDParams, type RedeemParams, type RedeemXBNBParams, RouterABI, type RouterMintEvent, type RouterMintParams, type RouterMintParams2, type RouterRedeemAndSwapParams, type RouterRedeemAndUnstakeParams, type RouterRedeemEvent, type RouterRedeemParams, type RouterSwapParams, type StabilityMode2Info, type StabilityModeInfo, type StabilityPoolStats, type StakeAndMintEvent, type StakeAndMintParams, type SwapAndMintDefaultParams, type SwapAndMintEvent, type SwapAndMintParams, type TokenAddresses, type TransactionReceipt, type TransactionResult, type UnstakeClaimedEvent, type UnstakeRequestedEvent, type UserStabilityPoolPosition, type WithdrawalRequestInfo, type WithdrawnEvent, type XBNBMintedEvent, type XBNBRedeemedEvent, type YieldHarvestedEvent, type YieldStats, calculateAPY, createAspanClient, createAspanPharosClient, createAspanPharosReadClient, createAspanReadClient, createAspanReadClientForChain, createAspanTestnetClient, createAspanTestnetReadClient, createAspanWriteClientForChain, createRouterClient, createRouterPharosClient, createRouterPharosReadClient, createRouterReadClient, createRouterReadClientForChain, createRouterTestnetClient, createRouterTestnetReadClient, createRouterWriteClientForChain, encodeV3Path, formatAmount, formatCR, formatFeeBPS, formatPriceUSD, getChainById, parseAmount, pharosTestnet };
2880
+ export { type ApUSDMintedEvent, type ApUSDRedeemedEvent, AspanClient, type AspanClientConfig, AspanReadClient, AspanRouterClient, type AspanRouterClientConfig, AspanRouterReadClient, type AspanRouterWriteClientConfig, type AspanWriteClientConfig, BPS_PRECISION, BSC_ADDRESSES, type BigIntString, CHAIN_IDS, type CurrentFeeTier, type CurrentFees, type DepositParams, type DepositedEvent, DiamondABI, type ExpectedOutput, type FeeTier, type LSTInfo, type LSTYieldInfo, type MintApUSDParams, type MintXBNBParams, type OracleBounds, PHAROS_ADDRESSES, PRECISION, PRICE_PRECISION, type ProtocolStats, type RedeemAndSwapEvent, type RedeemApUSDParams, type RedeemXBNBParams, RouterABI, type RouterMintEvent, type RouterMintParams, type RouterMintParams2, type RouterRedeemAndSwapParams, type RouterRedeemAndUnstakeParams, type RouterRedeemEvent, type RouterRedeemParams, type RouterSwapParams, type StabilityMode2Info, type StabilityModeInfo, type StabilityPoolStats, type StakeAndMintEvent, type StakeAndMintParams, type SwapAndMintDefaultParams, type SwapAndMintEvent, type SwapAndMintParams, type TokenAddresses, type TransactionReceipt, type TransactionResult, type UnstakeClaimedEvent, type UnstakeRequestedEvent, type UserStabilityPoolPosition, type WithdrawParams, type WithdrawalRequestInfo, type WithdrawnEvent, type XBNBMintedEvent, type XBNBRedeemedEvent, type YieldHarvestedEvent, type YieldStats, calculateAPY, createAspanClient, createAspanPharosClient, createAspanPharosReadClient, createAspanReadClient, createAspanReadClientForChain, createAspanTestnetClient, createAspanTestnetReadClient, createAspanWriteClientForChain, createRouterClient, createRouterPharosClient, createRouterPharosReadClient, createRouterReadClient, createRouterReadClientForChain, createRouterTestnetClient, createRouterTestnetReadClient, createRouterWriteClientForChain, encodeV3Path, formatAmount, formatCR, formatFeeBPS, formatPriceUSD, getChainById, parseAmount, pharosTestnet };
package/dist/index.js CHANGED
@@ -303,24 +303,18 @@ var DiamondABI = [
303
303
  {
304
304
  type: "function",
305
305
  name: "deposit",
306
- inputs: [
307
- { name: "assets", type: "uint256", internalType: "uint256" },
308
- { name: "receiver", type: "address", internalType: "address" }
309
- ],
306
+ inputs: [{ name: "_amount", type: "uint256", internalType: "uint256" }],
310
307
  outputs: [{ name: "shares", type: "uint256", internalType: "uint256" }],
311
308
  stateMutability: "nonpayable"
312
309
  },
313
310
  {
314
311
  type: "function",
315
- name: "redeem",
312
+ name: "withdraw",
316
313
  inputs: [
317
- { name: "shares", type: "uint256", internalType: "uint256" },
318
- { name: "receiver", type: "address", internalType: "address" },
319
- { name: "owner", type: "address", internalType: "address" }
314
+ { name: "_shares", type: "uint256", internalType: "uint256" }
320
315
  ],
321
316
  outputs: [
322
- { name: "apUSDOut", type: "uint256", internalType: "uint256" },
323
- { name: "xBNBOut", type: "uint256", internalType: "uint256" }
317
+ { name: "assets", type: "uint256", internalType: "uint256" }
324
318
  ],
325
319
  stateMutability: "nonpayable"
326
320
  },
@@ -1812,22 +1806,22 @@ var AspanClient = class extends AspanReadClient {
1812
1806
  address: this.diamondAddress,
1813
1807
  abi: DiamondABI,
1814
1808
  functionName: "deposit",
1815
- args: [params.assets, params.receiver]
1809
+ args: [params.apUSDAmount]
1816
1810
  });
1817
1811
  }
1818
1812
  /**
1819
- * Redeem from stability pool by shares
1820
- * @param params Redeem parameters
1813
+ * Withdraw from stability pool by shares
1814
+ * @param params Withdraw parameters
1821
1815
  * @returns Transaction hash
1822
1816
  */
1823
- async redeem(params) {
1817
+ async withdraw(params) {
1824
1818
  return this.walletClient.writeContract({
1825
1819
  chain: this.chain,
1826
1820
  account: this.walletClient.account,
1827
1821
  address: this.diamondAddress,
1828
1822
  abi: DiamondABI,
1829
- functionName: "redeem",
1830
- args: [params.shares, params.receiver, params.owner]
1823
+ functionName: "withdraw",
1824
+ args: [params.shares]
1831
1825
  });
1832
1826
  }
1833
1827
  /**
@@ -2390,6 +2384,21 @@ var RouterABI = [
2390
2384
  ];
2391
2385
 
2392
2386
  // src/router.ts
2387
+ var ChainlinkABI = [
2388
+ {
2389
+ type: "function",
2390
+ name: "latestRoundData",
2391
+ inputs: [],
2392
+ outputs: [
2393
+ { name: "roundId", type: "uint80" },
2394
+ { name: "answer", type: "int256" },
2395
+ { name: "startedAt", type: "uint256" },
2396
+ { name: "updatedAt", type: "uint256" },
2397
+ { name: "answeredInRound", type: "uint80" }
2398
+ ],
2399
+ stateMutability: "view"
2400
+ }
2401
+ ];
2393
2402
  var AspanRouterReadClient = class {
2394
2403
  publicClient;
2395
2404
  routerAddress;
@@ -2545,7 +2554,9 @@ var AspanRouterReadClient = class {
2545
2554
  const usdValue = inputAmount * bnbPrice18 / one;
2546
2555
  lstAmount = lstPrice18 === 0n ? 0n : usdValue * one / lstPrice18;
2547
2556
  } else if (inNorm === usdt.toLowerCase() || inNorm === usdc.toLowerCase()) {
2548
- lstAmount = lstPrice18 === 0n ? 0n : inputAmount * one / lstPrice18;
2557
+ const stablePrice18 = await this.getStablecoinPrice(inputToken);
2558
+ const usdValue = inputAmount * stablePrice18 / one;
2559
+ lstAmount = lstPrice18 === 0n ? 0n : usdValue * one / lstPrice18;
2549
2560
  } else {
2550
2561
  throw new Error("Unsupported input token for SDK preview");
2551
2562
  }
@@ -2591,7 +2602,8 @@ var AspanRouterReadClient = class {
2591
2602
  if (outNorm === import_viem2.zeroAddress.toLowerCase() || outNorm === wbnb.toLowerCase()) {
2592
2603
  outputAmount = bnbPrice18 === 0n ? 0n : usdValue * one / bnbPrice18;
2593
2604
  } else if (outNorm === usdt.toLowerCase() || outNorm === usdc.toLowerCase()) {
2594
- outputAmount = usdValue;
2605
+ const stablePrice18 = await this.getStablecoinPrice(outputToken);
2606
+ outputAmount = stablePrice18 === 0n ? 0n : usdValue * one / stablePrice18;
2595
2607
  } else {
2596
2608
  throw new Error("Unsupported output token for SDK preview");
2597
2609
  }
@@ -2656,6 +2668,32 @@ var AspanRouterReadClient = class {
2656
2668
  })
2657
2669
  );
2658
2670
  }
2671
+ /**
2672
+ * Get stablecoin price in USD (18 decimals) from Chainlink.
2673
+ * Returns 1e18 if feed unavailable (graceful fallback).
2674
+ */
2675
+ async getStablecoinPrice(token) {
2676
+ const usdt = await this.getUSDT();
2677
+ const usdc = await this.getUSDC();
2678
+ const norm = token.toLowerCase();
2679
+ let feed = null;
2680
+ if (norm === usdt.toLowerCase()) {
2681
+ feed = BSC_ADDRESSES.USDT_USD_FEED;
2682
+ } else if (norm === usdc.toLowerCase()) {
2683
+ feed = BSC_ADDRESSES.USDC_USD_FEED;
2684
+ }
2685
+ if (!feed) return 10n ** 18n;
2686
+ try {
2687
+ const [, answer] = await this.publicClient.readContract({
2688
+ address: feed,
2689
+ abi: ChainlinkABI,
2690
+ functionName: "latestRoundData"
2691
+ });
2692
+ return BigInt(answer) * 10n ** 10n;
2693
+ } catch {
2694
+ return 10n ** 18n;
2695
+ }
2696
+ }
2659
2697
  async getSlisBNB() {
2660
2698
  return this._getCachedAddress(
2661
2699
  "slisBNB",
@@ -2960,17 +2998,20 @@ var BPS_PRECISION = 10000n;
2960
2998
  var PRICE_PRECISION = 10n ** 8n;
2961
2999
  var BSC_ADDRESSES = {
2962
3000
  diamond: "0x6a11B30d3a70727d5477D6d8090e144443fA1c78",
2963
- router: "0x1Ca976d2043dfb785c7F3A17535B3A38c50113f3",
3001
+ router: "0xb8a90CD2811d6DDbB4B7969d30B036574842cb6E",
2964
3002
  apUSD: "0x4570047eeB5aDb4081c5d470494EB5134e34A287",
2965
3003
  xBNB: "0x0A0c9CD826e747D99F90D63e780B3727Da4D0d43",
2966
3004
  sApUSD: "0x896770Dba7c0481539E25aaB56bE285ECF6D65eB",
2967
3005
  // LSTs
2968
3006
  slisBNB: "0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B",
2969
3007
  asBNB: "0x77734e70b6E88b4d82fE632a168EDf6e700912b6",
2970
- wclisBNB: "0x448f7c2fa4e5135a4a5B50879602cf3CD428e108",
3008
+ wclisBNB: "0xb2A0631bF0aC326fEefc201E7337E13C63Bbed07",
2971
3009
  // Stablecoins
2972
3010
  USDT: "0x55d398326f99059fF775485246999027B3197955",
2973
3011
  USDC: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",
3012
+ /** Chainlink price feeds (BSC Mainnet) */
3013
+ USDT_USD_FEED: "0xB97Ad0E74fa7d920791E90258A6E2085088b4320",
3014
+ USDC_USD_FEED: "0x51597f405303C4377E36123cBc172b13269EA163",
2974
3015
  WBNB: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"
2975
3016
  };
2976
3017
  var PHAROS_ADDRESSES = {
package/dist/index.mjs CHANGED
@@ -245,24 +245,18 @@ var DiamondABI = [
245
245
  {
246
246
  type: "function",
247
247
  name: "deposit",
248
- inputs: [
249
- { name: "assets", type: "uint256", internalType: "uint256" },
250
- { name: "receiver", type: "address", internalType: "address" }
251
- ],
248
+ inputs: [{ name: "_amount", type: "uint256", internalType: "uint256" }],
252
249
  outputs: [{ name: "shares", type: "uint256", internalType: "uint256" }],
253
250
  stateMutability: "nonpayable"
254
251
  },
255
252
  {
256
253
  type: "function",
257
- name: "redeem",
254
+ name: "withdraw",
258
255
  inputs: [
259
- { name: "shares", type: "uint256", internalType: "uint256" },
260
- { name: "receiver", type: "address", internalType: "address" },
261
- { name: "owner", type: "address", internalType: "address" }
256
+ { name: "_shares", type: "uint256", internalType: "uint256" }
262
257
  ],
263
258
  outputs: [
264
- { name: "apUSDOut", type: "uint256", internalType: "uint256" },
265
- { name: "xBNBOut", type: "uint256", internalType: "uint256" }
259
+ { name: "assets", type: "uint256", internalType: "uint256" }
266
260
  ],
267
261
  stateMutability: "nonpayable"
268
262
  },
@@ -1754,22 +1748,22 @@ var AspanClient = class extends AspanReadClient {
1754
1748
  address: this.diamondAddress,
1755
1749
  abi: DiamondABI,
1756
1750
  functionName: "deposit",
1757
- args: [params.assets, params.receiver]
1751
+ args: [params.apUSDAmount]
1758
1752
  });
1759
1753
  }
1760
1754
  /**
1761
- * Redeem from stability pool by shares
1762
- * @param params Redeem parameters
1755
+ * Withdraw from stability pool by shares
1756
+ * @param params Withdraw parameters
1763
1757
  * @returns Transaction hash
1764
1758
  */
1765
- async redeem(params) {
1759
+ async withdraw(params) {
1766
1760
  return this.walletClient.writeContract({
1767
1761
  chain: this.chain,
1768
1762
  account: this.walletClient.account,
1769
1763
  address: this.diamondAddress,
1770
1764
  abi: DiamondABI,
1771
- functionName: "redeem",
1772
- args: [params.shares, params.receiver, params.owner]
1765
+ functionName: "withdraw",
1766
+ args: [params.shares]
1773
1767
  });
1774
1768
  }
1775
1769
  /**
@@ -2337,6 +2331,21 @@ var RouterABI = [
2337
2331
  ];
2338
2332
 
2339
2333
  // src/router.ts
2334
+ var ChainlinkABI = [
2335
+ {
2336
+ type: "function",
2337
+ name: "latestRoundData",
2338
+ inputs: [],
2339
+ outputs: [
2340
+ { name: "roundId", type: "uint80" },
2341
+ { name: "answer", type: "int256" },
2342
+ { name: "startedAt", type: "uint256" },
2343
+ { name: "updatedAt", type: "uint256" },
2344
+ { name: "answeredInRound", type: "uint80" }
2345
+ ],
2346
+ stateMutability: "view"
2347
+ }
2348
+ ];
2340
2349
  var AspanRouterReadClient = class {
2341
2350
  publicClient;
2342
2351
  routerAddress;
@@ -2492,7 +2501,9 @@ var AspanRouterReadClient = class {
2492
2501
  const usdValue = inputAmount * bnbPrice18 / one;
2493
2502
  lstAmount = lstPrice18 === 0n ? 0n : usdValue * one / lstPrice18;
2494
2503
  } else if (inNorm === usdt.toLowerCase() || inNorm === usdc.toLowerCase()) {
2495
- lstAmount = lstPrice18 === 0n ? 0n : inputAmount * one / lstPrice18;
2504
+ const stablePrice18 = await this.getStablecoinPrice(inputToken);
2505
+ const usdValue = inputAmount * stablePrice18 / one;
2506
+ lstAmount = lstPrice18 === 0n ? 0n : usdValue * one / lstPrice18;
2496
2507
  } else {
2497
2508
  throw new Error("Unsupported input token for SDK preview");
2498
2509
  }
@@ -2538,7 +2549,8 @@ var AspanRouterReadClient = class {
2538
2549
  if (outNorm === zeroAddress.toLowerCase() || outNorm === wbnb.toLowerCase()) {
2539
2550
  outputAmount = bnbPrice18 === 0n ? 0n : usdValue * one / bnbPrice18;
2540
2551
  } else if (outNorm === usdt.toLowerCase() || outNorm === usdc.toLowerCase()) {
2541
- outputAmount = usdValue;
2552
+ const stablePrice18 = await this.getStablecoinPrice(outputToken);
2553
+ outputAmount = stablePrice18 === 0n ? 0n : usdValue * one / stablePrice18;
2542
2554
  } else {
2543
2555
  throw new Error("Unsupported output token for SDK preview");
2544
2556
  }
@@ -2603,6 +2615,32 @@ var AspanRouterReadClient = class {
2603
2615
  })
2604
2616
  );
2605
2617
  }
2618
+ /**
2619
+ * Get stablecoin price in USD (18 decimals) from Chainlink.
2620
+ * Returns 1e18 if feed unavailable (graceful fallback).
2621
+ */
2622
+ async getStablecoinPrice(token) {
2623
+ const usdt = await this.getUSDT();
2624
+ const usdc = await this.getUSDC();
2625
+ const norm = token.toLowerCase();
2626
+ let feed = null;
2627
+ if (norm === usdt.toLowerCase()) {
2628
+ feed = BSC_ADDRESSES.USDT_USD_FEED;
2629
+ } else if (norm === usdc.toLowerCase()) {
2630
+ feed = BSC_ADDRESSES.USDC_USD_FEED;
2631
+ }
2632
+ if (!feed) return 10n ** 18n;
2633
+ try {
2634
+ const [, answer] = await this.publicClient.readContract({
2635
+ address: feed,
2636
+ abi: ChainlinkABI,
2637
+ functionName: "latestRoundData"
2638
+ });
2639
+ return BigInt(answer) * 10n ** 10n;
2640
+ } catch {
2641
+ return 10n ** 18n;
2642
+ }
2643
+ }
2606
2644
  async getSlisBNB() {
2607
2645
  return this._getCachedAddress(
2608
2646
  "slisBNB",
@@ -2907,17 +2945,20 @@ var BPS_PRECISION = 10000n;
2907
2945
  var PRICE_PRECISION = 10n ** 8n;
2908
2946
  var BSC_ADDRESSES = {
2909
2947
  diamond: "0x6a11B30d3a70727d5477D6d8090e144443fA1c78",
2910
- router: "0x1Ca976d2043dfb785c7F3A17535B3A38c50113f3",
2948
+ router: "0xb8a90CD2811d6DDbB4B7969d30B036574842cb6E",
2911
2949
  apUSD: "0x4570047eeB5aDb4081c5d470494EB5134e34A287",
2912
2950
  xBNB: "0x0A0c9CD826e747D99F90D63e780B3727Da4D0d43",
2913
2951
  sApUSD: "0x896770Dba7c0481539E25aaB56bE285ECF6D65eB",
2914
2952
  // LSTs
2915
2953
  slisBNB: "0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B",
2916
2954
  asBNB: "0x77734e70b6E88b4d82fE632a168EDf6e700912b6",
2917
- wclisBNB: "0x448f7c2fa4e5135a4a5B50879602cf3CD428e108",
2955
+ wclisBNB: "0xb2A0631bF0aC326fEefc201E7337E13C63Bbed07",
2918
2956
  // Stablecoins
2919
2957
  USDT: "0x55d398326f99059fF775485246999027B3197955",
2920
2958
  USDC: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",
2959
+ /** Chainlink price feeds (BSC Mainnet) */
2960
+ USDT_USD_FEED: "0xB97Ad0E74fa7d920791E90258A6E2085088b4320",
2961
+ USDC_USD_FEED: "0x51597f405303C4377E36123cBc172b13269EA163",
2921
2962
  WBNB: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"
2922
2963
  };
2923
2964
  var PHAROS_ADDRESSES = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aspan/sdk",
3
- "version": "0.4.9",
3
+ "version": "0.5.1",
4
4
  "description": "TypeScript SDK for Aspan Protocol - LST-backed stablecoin on BNB Chain",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -45,18 +45,18 @@
45
45
  "author": "",
46
46
  "license": "MIT",
47
47
  "dependencies": {
48
- "viem": "^2.21.0"
48
+ "viem": ">=2.0.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/node": "^20.10.0",
52
- "tsup": "^8.0.1",
53
- "typescript": "^5.3.0",
54
- "vitest": "^1.0.0",
55
- "eslint": "^8.55.0",
56
52
  "@typescript-eslint/eslint-plugin": "^6.13.0",
57
53
  "@typescript-eslint/parser": "^6.13.0",
54
+ "dotenv": "^16.3.1",
55
+ "eslint": "^8.55.0",
56
+ "tsup": "^8.0.1",
58
57
  "tsx": "^4.7.0",
59
- "dotenv": "^16.3.1"
58
+ "typescript": "^5.3.0",
59
+ "vitest": "^1.6.1"
60
60
  },
61
61
  "peerDependencies": {
62
62
  "viem": ">=2.0.0"
@@ -61,7 +61,7 @@ const BSC_RPC_URL = process.env.BSC_RPC_URL || "https://bsc-dataseed.binance.org
61
61
  const ANVIL_DEFAULT_KEY = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
62
62
 
63
63
  const DIAMOND = "0x6a11B30d3a70727d5477D6d8090e144443fA1c78" as Address;
64
- const ROUTER = "0x1Ca976d2043dfb785c7F3A17535B3A38c50113f3" as Address;
64
+ const ROUTER = "0xb8a90CD2811d6DDbB4B7969d30B036574842cb6E" as Address;
65
65
 
66
66
  const TOKENS = {
67
67
  WBNB: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c" as Address,
@@ -69,7 +69,7 @@ const TOKENS = {
69
69
  USDC: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d" as Address,
70
70
  slisBNB: "0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B" as Address,
71
71
  asBNB: "0x77734e70b6E88b4d82fE632a168EDf6e700912b6" as Address,
72
- wclisBNB: "0x448f7c2fa4e5135a4a5B50879602cf3CD428e108" as Address,
72
+ wclisBNB: "0xb2A0631bF0aC326fEefc201E7337E13C63Bbed07" as Address,
73
73
  apUSD: "0x4570047eeB5aDb4081c5d470494EB5134e34A287" as Address,
74
74
  xBNB: "0x0A0c9CD826e747D99F90D63e780B3727Da4D0d43" as Address,
75
75
  sApUSD: "0xE2BE739C4aA4126ee72D612d9548C38B1B0e5A1b" as Address,
@@ -1224,7 +1224,7 @@ describe.skipIf(!IS_FORK && !IS_LIVE)("Risk Control Tests", () => {
1224
1224
 
1225
1225
  await approve(TOKENS.apUSD, DIAMOND, depositedApUSD);
1226
1226
  try {
1227
- await waitTx(await diamondWrite.deposit({ assets: depositedApUSD, receiver: account.address }));
1227
+ await waitTx(await diamondWrite.deposit({ apUSDAmount: depositedApUSD }));
1228
1228
  } catch (err: any) {
1229
1229
  console.log(` ⚠️ Deposit failed (AccessControl or not configured): ${err.shortMessage || err.message?.slice(0, 100)}`);
1230
1230
  console.log(` Skipping remaining FC-02 tests`);
@@ -1351,7 +1351,7 @@ describe.skipIf(!IS_FORK && !IS_LIVE)("Risk Control Tests", () => {
1351
1351
 
1352
1352
  console.log(` Withdrawing ${formatAmount(currentShares)} shares...`);
1353
1353
  try {
1354
- await waitTx(await diamondWrite.redeem({ shares: currentShares, receiver: account.address, owner: account.address }));
1354
+ await waitTx(await diamondWrite.withdraw({ shares: currentShares }));
1355
1355
  } catch (err: any) {
1356
1356
  console.log(` ⚠️ Withdraw failed: ${err.shortMessage || err.message?.slice(0, 100)}`);
1357
1357
  return;
@@ -43,9 +43,9 @@ const TOKENS = {
43
43
  };
44
44
 
45
45
  // Minimal amounts — just enough to verify path connectivity
46
- const BNB_AMOUNT = parseEther("0.001");
46
+ const BNB_AMOUNT = parseEther("0.002");
47
47
  const USDT_AMOUNT = parseAmount("1");
48
- const WBNB_AMOUNT = parseEther("0.001");
48
+ const WBNB_AMOUNT = parseEther("0.002");
49
49
  const USDC_AMOUNT = parseAmount("1");
50
50
 
51
51
  const ERC20_ABI = [
@@ -589,17 +589,26 @@ describe("AspanRouter SDK", () => {
589
589
 
590
590
  const indicesBefore = await readClient.getUserWithdrawalIndices(account.address);
591
591
 
592
- const unstakeHash = await writeClient.redeemAndRequestUnstake({
593
- redeemXBNB: true,
594
- amount: freshMinted,
595
- });
596
- const unstakeReceipt = await publicClient.waitForTransactionReceipt({ hash: unstakeHash });
597
- await sleep(2000);
598
- expect(unstakeReceipt.status).toBe("success");
599
-
600
- const indicesAfter = await readClient.getUserWithdrawalIndices(account.address);
601
- expect(indicesAfter.length).toBeGreaterThan(indicesBefore.length);
602
- console.log(` Unstake requested ✓ (new indices: ${indicesAfter.length - indicesBefore.length})`);
592
+ try {
593
+ const unstakeHash = await writeClient.redeemAndRequestUnstake({
594
+ redeemXBNB: true,
595
+ amount: freshMinted,
596
+ });
597
+ const unstakeReceipt = await publicClient.waitForTransactionReceipt({ hash: unstakeHash });
598
+ await sleep(2000);
599
+ expect(unstakeReceipt.status).toBe("success");
600
+
601
+ const indicesAfter = await readClient.getUserWithdrawalIndices(account.address);
602
+ expect(indicesAfter.length).toBeGreaterThan(indicesBefore.length);
603
+ console.log(` Unstake requested ✓ (new indices: ${indicesAfter.length - indicesBefore.length})`);
604
+ } catch (err: any) {
605
+ const msg = err.shortMessage || err.message || "";
606
+ if (msg.includes("too small")) {
607
+ console.log(` ⚠️ Amount too small for Lista unstake (min ~0.001 BNB equivalent), skipped`);
608
+ } else {
609
+ throw err;
610
+ }
611
+ }
603
612
  }, 180000);
604
613
 
605
614
  // Test 9: stakeAndMint xBNB
@@ -854,7 +863,8 @@ describe("AspanRouter SDK", () => {
854
863
  return;
855
864
  }
856
865
 
857
- const unstakeAmount = apUSDBalance > parseAmount("0.5") ? parseAmount("0.5") : apUSDBalance;
866
+ // Lista requires minimum ~0.001 BNB equivalent; at ~$670/BNB, that's ~$0.67 apUSD min
867
+ const unstakeAmount = apUSDBalance > parseAmount("1.0") ? parseAmount("1.0") : apUSDBalance;
858
868
  console.log(` Requesting unstake for ${formatAmount(unstakeAmount)} apUSD (of ${formatAmount(apUSDBalance)} total)...`);
859
869
  await approve(TOKENS.apUSD, unstakeAmount);
860
870
 
@@ -243,24 +243,18 @@ export const DiamondABI = [
243
243
  {
244
244
  type: "function",
245
245
  name: "deposit",
246
- inputs: [
247
- { name: "assets", type: "uint256", internalType: "uint256" },
248
- { name: "receiver", type: "address", internalType: "address" }
249
- ],
246
+ inputs: [{ name: "_amount", type: "uint256", internalType: "uint256" }],
250
247
  outputs: [{ name: "shares", type: "uint256", internalType: "uint256" }],
251
248
  stateMutability: "nonpayable"
252
249
  },
253
250
  {
254
251
  type: "function",
255
- name: "redeem",
252
+ name: "withdraw",
256
253
  inputs: [
257
- { name: "shares", type: "uint256", internalType: "uint256" },
258
- { name: "receiver", type: "address", internalType: "address" },
259
- { name: "owner", type: "address", internalType: "address" }
254
+ { name: "_shares", type: "uint256", internalType: "uint256" }
260
255
  ],
261
256
  outputs: [
262
- { name: "apUSDOut", type: "uint256", internalType: "uint256" },
263
- { name: "xBNBOut", type: "uint256", internalType: "uint256" }
257
+ { name: "assets", type: "uint256", internalType: "uint256" }
264
258
  ],
265
259
  stateMutability: "nonpayable"
266
260
  },
package/src/client.ts CHANGED
@@ -74,7 +74,7 @@ import type {
74
74
  MintXBNBParams,
75
75
  RedeemXBNBParams,
76
76
  DepositParams,
77
- RedeemParams,
77
+ WithdrawParams,
78
78
  } from "./types";
79
79
 
80
80
  // ============ Configuration ============
@@ -1190,23 +1190,23 @@ export class AspanClient extends AspanReadClient {
1190
1190
  address: this.diamondAddress,
1191
1191
  abi: DiamondABI,
1192
1192
  functionName: "deposit",
1193
- args: [params.assets, params.receiver],
1193
+ args: [params.apUSDAmount],
1194
1194
  });
1195
1195
  }
1196
1196
 
1197
1197
  /**
1198
- * Redeem from stability pool by shares
1199
- * @param params Redeem parameters
1198
+ * Withdraw from stability pool by shares
1199
+ * @param params Withdraw parameters
1200
1200
  * @returns Transaction hash
1201
1201
  */
1202
- async redeem(params: RedeemParams): Promise<Hash> {
1202
+ async withdraw(params: WithdrawParams): Promise<Hash> {
1203
1203
  return this.walletClient.writeContract({
1204
1204
  chain: this.chain,
1205
1205
  account: this.walletClient.account!,
1206
1206
  address: this.diamondAddress,
1207
1207
  abi: DiamondABI,
1208
- functionName: "redeem",
1209
- args: [params.shares, params.receiver, params.owner],
1208
+ functionName: "withdraw",
1209
+ args: [params.shares],
1210
1210
  });
1211
1211
  }
1212
1212
 
package/src/index.ts CHANGED
@@ -67,7 +67,7 @@ export type {
67
67
  MintXBNBParams,
68
68
  RedeemXBNBParams,
69
69
  DepositParams,
70
- RedeemParams,
70
+ WithdrawParams,
71
71
  // Events
72
72
  ApUSDMintedEvent,
73
73
  ApUSDRedeemedEvent,
@@ -116,17 +116,20 @@ export const PRICE_PRECISION = 10n ** 8n; // Chainlink price precision
116
116
  // ============ Contract Addresses (BSC Mainnet) ============
117
117
  export const BSC_ADDRESSES = {
118
118
  diamond: "0x6a11B30d3a70727d5477D6d8090e144443fA1c78" as const,
119
- router: "0x1Ca976d2043dfb785c7F3A17535B3A38c50113f3" as const,
119
+ router: "0xb8a90CD2811d6DDbB4B7969d30B036574842cb6E" as const,
120
120
  apUSD: "0x4570047eeB5aDb4081c5d470494EB5134e34A287" as const,
121
121
  xBNB: "0x0A0c9CD826e747D99F90D63e780B3727Da4D0d43" as const,
122
122
  sApUSD: "0x896770Dba7c0481539E25aaB56bE285ECF6D65eB" as const,
123
123
  // LSTs
124
124
  slisBNB: "0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B" as const,
125
125
  asBNB: "0x77734e70b6E88b4d82fE632a168EDf6e700912b6" as const,
126
- wclisBNB: "0x448f7c2fa4e5135a4a5B50879602cf3CD428e108" as const,
126
+ wclisBNB: "0xb2A0631bF0aC326fEefc201E7337E13C63Bbed07" as const,
127
127
  // Stablecoins
128
128
  USDT: "0x55d398326f99059fF775485246999027B3197955" as const,
129
129
  USDC: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d" as const,
130
+ /** Chainlink price feeds (BSC Mainnet) */
131
+ USDT_USD_FEED: "0xB97Ad0E74fa7d920791E90258A6E2085088b4320" as const,
132
+ USDC_USD_FEED: "0x51597f405303C4377E36123cBc172b13269EA163" as const,
130
133
  WBNB: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c" as const,
131
134
  } as const;
132
135
 
package/src/router.ts CHANGED
@@ -19,8 +19,26 @@ import {
19
19
  } from "viem";
20
20
  import { bsc, bscTestnet } from "viem/chains";
21
21
  import { pharosTestnet, CHAIN_IDS, getChainById } from "./client";
22
+ import { BSC_ADDRESSES } from "./index";
22
23
  import { RouterABI } from "./abi/router";
23
24
  import { DiamondABI } from "./abi/diamond";
25
+
26
+ /** Chainlink AggregatorV3 — only latestRoundData needed */
27
+ const ChainlinkABI = [
28
+ {
29
+ type: "function",
30
+ name: "latestRoundData",
31
+ inputs: [],
32
+ outputs: [
33
+ { name: "roundId", type: "uint80" },
34
+ { name: "answer", type: "int256" },
35
+ { name: "startedAt", type: "uint256" },
36
+ { name: "updatedAt", type: "uint256" },
37
+ { name: "answeredInRound", type: "uint80" },
38
+ ],
39
+ stateMutability: "view",
40
+ },
41
+ ] as const;
24
42
  import type {
25
43
  SwapAndMintParams,
26
44
  StakeAndMintParams,
@@ -233,8 +251,10 @@ export class AspanRouterReadClient {
233
251
  const usdValue = (inputAmount * bnbPrice18) / one;
234
252
  lstAmount = lstPrice18 === 0n ? 0n : (usdValue * one) / lstPrice18;
235
253
  } else if (inNorm === usdt.toLowerCase() || inNorm === usdc.toLowerCase()) {
236
- // stablecoin (18-decimal normalized in this SDK path) -> LST
237
- lstAmount = lstPrice18 === 0n ? 0n : (inputAmount * one) / lstPrice18;
254
+ // stablecoin -> USD (via Chainlink) -> LST
255
+ const stablePrice18 = await this.getStablecoinPrice(inputToken);
256
+ const usdValue = (inputAmount * stablePrice18) / one;
257
+ lstAmount = lstPrice18 === 0n ? 0n : (usdValue * one) / lstPrice18;
238
258
  } else {
239
259
  throw new Error("Unsupported input token for SDK preview");
240
260
  }
@@ -292,7 +312,9 @@ export class AspanRouterReadClient {
292
312
  if (outNorm === zeroAddress.toLowerCase() || outNorm === wbnb.toLowerCase()) {
293
313
  outputAmount = bnbPrice18 === 0n ? 0n : (usdValue * one) / bnbPrice18;
294
314
  } else if (outNorm === usdt.toLowerCase() || outNorm === usdc.toLowerCase()) {
295
- outputAmount = usdValue;
315
+ // USD value -> stablecoin amount (via Chainlink price)
316
+ const stablePrice18 = await this.getStablecoinPrice(outputToken);
317
+ outputAmount = stablePrice18 === 0n ? 0n : (usdValue * one) / stablePrice18;
296
318
  } else {
297
319
  throw new Error("Unsupported output token for SDK preview");
298
320
  }
@@ -365,6 +387,34 @@ export class AspanRouterReadClient {
365
387
  );
366
388
  }
367
389
 
390
+ /**
391
+ * Get stablecoin price in USD (18 decimals) from Chainlink.
392
+ * Returns 1e18 if feed unavailable (graceful fallback).
393
+ */
394
+ async getStablecoinPrice(token: Address): Promise<bigint> {
395
+ const usdt = await this.getUSDT();
396
+ const usdc = await this.getUSDC();
397
+ const norm = token.toLowerCase();
398
+ let feed: Address | null = null;
399
+ if (norm === usdt.toLowerCase()) {
400
+ feed = BSC_ADDRESSES.USDT_USD_FEED as Address;
401
+ } else if (norm === usdc.toLowerCase()) {
402
+ feed = BSC_ADDRESSES.USDC_USD_FEED as Address;
403
+ }
404
+ if (!feed) return 10n ** 18n; // not a stablecoin, assume 1:1
405
+ try {
406
+ const [, answer] = await this.publicClient.readContract({
407
+ address: feed,
408
+ abi: ChainlinkABI,
409
+ functionName: "latestRoundData",
410
+ });
411
+ // Chainlink returns 8 decimals, normalize to 18
412
+ return BigInt(answer) * 10n ** 10n;
413
+ } catch {
414
+ return 10n ** 18n; // fallback: 1 USD
415
+ }
416
+ }
417
+
368
418
  async getSlisBNB(): Promise<Address> {
369
419
  return this._getCachedAddress("slisBNB", async () =>
370
420
  this.publicClient.readContract({
package/src/types.ts CHANGED
@@ -120,15 +120,12 @@ export interface RedeemXBNBParams {
120
120
 
121
121
  /** Parameters for depositing to stability pool */
122
122
  export interface DepositParams {
123
- assets: bigint;
124
- receiver: Address;
123
+ apUSDAmount: bigint;
125
124
  }
126
125
 
127
- /** Parameters for redeeming from stability pool */
128
- export interface RedeemParams {
126
+ /** Parameters for withdrawing from stability pool */
127
+ export interface WithdrawParams {
129
128
  shares: bigint;
130
- receiver: Address;
131
- owner: Address;
132
129
  }
133
130
 
134
131
  // ============ Protocol Stats ============
@@ -254,7 +251,7 @@ export interface RouterSwapParams {
254
251
  targetLST: Address;
255
252
  /** Minimum LST to receive from swap (slippage protection) */
256
253
  minLSTOut: bigint;
257
- /** PancakeSwap V3 pool fee tier (500, 2500, 10000) */
254
+ /** PancakeSwap V3 pool fee tier (100, 500, 2500, 10000) */
258
255
  poolFee: number;
259
256
  }
260
257