@aspan/sdk 0.4.5 → 0.4.7

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",
@@ -363,6 +356,16 @@ var DiamondABI = [
363
356
  outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
364
357
  stateMutability: "view"
365
358
  },
359
+ {
360
+ type: "function",
361
+ name: "previewRedeemMulti",
362
+ inputs: [{ name: "_shares", type: "uint256", internalType: "uint256" }],
363
+ outputs: [
364
+ { name: "assets", type: "address[]", internalType: "address[]" },
365
+ { name: "amounts", type: "uint256[]", internalType: "uint256[]" }
366
+ ],
367
+ stateMutability: "view"
368
+ },
366
369
  {
367
370
  type: "function",
368
371
  name: "getPendingYield",
@@ -729,13 +732,13 @@ var SApUSDABI = [
729
732
  },
730
733
  {
731
734
  type: "function",
732
- name: "previewRedeemMulti",
735
+ name: "previewRedeem",
733
736
  inputs: [
734
737
  { name: "shares", type: "uint256", internalType: "uint256" }
735
738
  ],
736
739
  outputs: [
737
- { name: "assets", type: "address[]", internalType: "address[]" },
738
- { name: "amounts", type: "uint256[]", internalType: "uint256[]" }
740
+ { name: "apUSDOut", type: "uint256", internalType: "uint256" },
741
+ { name: "xBNBOut", type: "uint256", internalType: "uint256" }
739
742
  ],
740
743
  stateMutability: "view"
741
744
  },
@@ -782,56 +785,69 @@ var SApUSDABI = [
782
785
  },
783
786
  {
784
787
  type: "function",
785
- name: "previewCleanXBNB",
788
+ name: "hasRole",
786
789
  inputs: [
787
- { name: "_xBNBAmount", type: "uint256", internalType: "uint256" },
788
- { name: "_router", type: "address", internalType: "address" },
789
- { name: "_path", type: "address[]", internalType: "address[]" }
790
+ { name: "role", type: "bytes32", internalType: "bytes32" },
791
+ { name: "account", type: "address", internalType: "address" }
790
792
  ],
791
- outputs: [{ name: "expectedApUSD", type: "uint256", internalType: "uint256" }],
793
+ outputs: [{ name: "", type: "bool", internalType: "bool" }],
792
794
  stateMutability: "view"
793
795
  },
796
+ // ============ Write Functions ============
794
797
  {
795
798
  type: "function",
796
- name: "KEEPER_ROLE",
797
- inputs: [],
798
- outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
799
- 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"
800
810
  },
801
811
  {
802
812
  type: "function",
803
- name: "hasRole",
813
+ name: "deposit",
804
814
  inputs: [
805
- { name: "role", type: "bytes32", internalType: "bytes32" },
806
- { name: "account", type: "address", internalType: "address" }
815
+ { name: "assets", type: "uint256", internalType: "uint256" },
816
+ { name: "receiver", type: "address", internalType: "address" }
807
817
  ],
808
- outputs: [{ name: "", type: "bool", internalType: "bool" }],
809
- stateMutability: "view"
818
+ outputs: [{ name: "shares", type: "uint256", internalType: "uint256" }],
819
+ stateMutability: "nonpayable"
810
820
  },
811
- // ============ Keeper Functions ============
821
+ // ============ Accounting Functions ============
812
822
  {
813
823
  type: "function",
814
- name: "cleanXBNB",
824
+ name: "addAccounting",
815
825
  inputs: [
816
- { name: "_xBNBAmount", type: "uint256", internalType: "uint256" },
817
- { name: "_minApUSDOut", type: "uint256", internalType: "uint256" },
818
- { name: "_router", type: "address", internalType: "address" },
819
- { name: "_path", type: "address[]", internalType: "address[]" },
820
- { name: "_deadline", type: "uint256", internalType: "uint256" }
826
+ { name: "apUSD", type: "uint256", internalType: "uint256" },
827
+ { name: "xBNB", type: "uint256", internalType: "uint256" }
821
828
  ],
822
- outputs: [{ name: "apUSDReceived", type: "uint256", internalType: "uint256" }],
829
+ outputs: [],
823
830
  stateMutability: "nonpayable"
824
831
  },
825
- // ============ Events ============
826
832
  {
827
- type: "event",
828
- name: "VaultCleaned",
833
+ type: "function",
834
+ name: "subAccounting",
829
835
  inputs: [
830
- { name: "xBNBSold", type: "uint256", indexed: false, internalType: "uint256" },
831
- { name: "apUSDReceived", type: "uint256", indexed: false, internalType: "uint256" },
832
- { name: "keeper", type: "address", indexed: true, internalType: "address" }
836
+ { name: "apUSD", type: "uint256", internalType: "uint256" },
837
+ { name: "xBNB", type: "uint256", internalType: "uint256" }
833
838
  ],
834
- 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"
835
851
  }
836
852
  ];
837
853
 
@@ -1291,45 +1307,26 @@ var AspanReadClient = class _AspanReadClient {
1291
1307
  throw error;
1292
1308
  }
1293
1309
  }
1294
- async previewRedeem(shares) {
1295
- try {
1296
- return await this.publicClient.readContract({
1297
- address: this.diamondAddress,
1298
- abi: DiamondABI,
1299
- functionName: "previewRedeem",
1300
- args: [shares]
1301
- });
1302
- } catch (error) {
1303
- if (this.isZeroSupplyError(error)) {
1304
- return shares;
1305
- }
1306
- throw error;
1307
- }
1308
- }
1309
1310
  /**
1310
1311
  * Preview withdraw with multi-asset support (apUSD + xBNB)
1312
+ * Replaces previewRedeem — works for both clean and dirty pools.
1311
1313
  * @param shares Amount of sApUSD shares to redeem
1312
1314
  * @returns Object with apUSD and xBNB amounts, plus whether vault has xBNB
1313
1315
  */
1314
1316
  async previewRedeemMulti(shares) {
1315
- const sApUSDAddress = await this.getSApUSD();
1316
- const [result, conversion] = await Promise.all([
1317
- this.publicClient.readContract({
1318
- address: sApUSDAddress,
1319
- abi: SApUSDABI,
1320
- functionName: "previewRedeemMulti",
1321
- args: [shares]
1322
- }),
1323
- this.publicClient.readContract({
1324
- address: sApUSDAddress,
1325
- abi: SApUSDABI,
1326
- functionName: "hasStabilityConversion"
1327
- })
1328
- ]);
1317
+ const [assets, amounts] = await this.publicClient.readContract({
1318
+ address: this.diamondAddress,
1319
+ abi: DiamondABI,
1320
+ functionName: "previewRedeemMulti",
1321
+ args: [shares]
1322
+ });
1323
+ const hasXBNB = amounts.length > 1 && amounts[1] > 0n;
1329
1324
  return {
1330
- apUSD: result[1][0],
1331
- xBNB: result[1][1],
1332
- hasXBNB: conversion[0]
1325
+ apUSD: amounts[0] ?? 0n,
1326
+ xBNB: amounts[1] ?? 0n,
1327
+ hasXBNB,
1328
+ assets,
1329
+ amounts
1333
1330
  };
1334
1331
  }
1335
1332
  async getPendingYield() {
@@ -1822,21 +1819,6 @@ var AspanClient = class extends AspanReadClient {
1822
1819
  args: [params.shares]
1823
1820
  });
1824
1821
  }
1825
- /**
1826
- * Withdraw from stability pool by asset amount
1827
- * @param params Withdraw parameters
1828
- * @returns Transaction hash
1829
- */
1830
- async withdrawAssets(params) {
1831
- return this.walletClient.writeContract({
1832
- chain: this.chain,
1833
- account: this.walletClient.account,
1834
- address: this.diamondAddress,
1835
- abi: DiamondABI,
1836
- functionName: "withdrawAssets",
1837
- args: [params.assets]
1838
- });
1839
- }
1840
1822
  /**
1841
1823
  * Harvest yield from LSTs
1842
1824
  * @returns Transaction hash
@@ -2166,6 +2148,20 @@ var RouterABI = [
2166
2148
  outputs: [{ type: "bool" }],
2167
2149
  stateMutability: "view"
2168
2150
  },
2151
+ {
2152
+ type: "function",
2153
+ name: "lstModes",
2154
+ inputs: [{ name: "lst", type: "address" }],
2155
+ outputs: [{ type: "uint8" }],
2156
+ stateMutability: "view"
2157
+ },
2158
+ {
2159
+ type: "function",
2160
+ name: "isLSTRoutable",
2161
+ inputs: [{ name: "lst", type: "address" }],
2162
+ outputs: [{ type: "bool" }],
2163
+ stateMutability: "view"
2164
+ },
2169
2165
  // Preview functions - unified
2170
2166
  {
2171
2167
  type: "function",
@@ -2428,6 +2424,29 @@ var AspanRouterReadClient = class {
2428
2424
  args: [lst]
2429
2425
  });
2430
2426
  }
2427
+ /**
2428
+ * Get LST mode (0 = SYNC, 1 = ASYNC_DIRECT_ONLY)
2429
+ */
2430
+ async getLSTMode(lst) {
2431
+ const mode = await this.publicClient.readContract({
2432
+ address: this.routerAddress,
2433
+ abi: RouterABI,
2434
+ functionName: "lstModes",
2435
+ args: [lst]
2436
+ });
2437
+ return Number(mode);
2438
+ }
2439
+ /**
2440
+ * Check whether an LST supports routed flows (swap/stake/redeemAndSwap)
2441
+ */
2442
+ async isLSTRoutable(lst) {
2443
+ return this.publicClient.readContract({
2444
+ address: this.routerAddress,
2445
+ abi: RouterABI,
2446
+ functionName: "isLSTRoutable",
2447
+ args: [lst]
2448
+ });
2449
+ }
2431
2450
  /**
2432
2451
  * Get the Diamond contract address
2433
2452
  */
@@ -2466,6 +2485,92 @@ var AspanRouterReadClient = class {
2466
2485
  args: [lst, redeemXBNB, amount]
2467
2486
  });
2468
2487
  }
2488
+ /**
2489
+ * SDK-only preview: input token -> estimated LST -> previewMint
2490
+ * Note: oracle-based estimation (does not include live DEX slippage/price impact)
2491
+ */
2492
+ async previewMintByInput(inputToken, inputAmount, targetLST, mintXBNB) {
2493
+ if (inputAmount === 0n) return { lstAmount: 0n, mintedAmount: 0n };
2494
+ const [diamond, wbnb, usdt, usdc] = await Promise.all([
2495
+ this.getDiamond(),
2496
+ this.getWBNB(),
2497
+ this.getUSDT(),
2498
+ this.getUSDC()
2499
+ ]);
2500
+ const [bnbPrice8, lstPrice] = await Promise.all([
2501
+ this.publicClient.readContract({
2502
+ address: diamond,
2503
+ abi: DiamondABI,
2504
+ functionName: "getBNBPriceUSD"
2505
+ }),
2506
+ this.publicClient.readContract({
2507
+ address: diamond,
2508
+ abi: DiamondABI,
2509
+ functionName: "getLSTPriceUSD",
2510
+ args: [targetLST]
2511
+ })
2512
+ ]);
2513
+ const bnbPrice18 = BigInt(bnbPrice8) * 10n ** 10n;
2514
+ const lstPrice18 = BigInt(lstPrice);
2515
+ const one = 10n ** 18n;
2516
+ let lstAmount = 0n;
2517
+ const inNorm = inputToken.toLowerCase();
2518
+ if (inNorm === targetLST.toLowerCase()) {
2519
+ lstAmount = inputAmount;
2520
+ } else if (inNorm === import_viem2.zeroAddress.toLowerCase() || inNorm === wbnb.toLowerCase()) {
2521
+ const usdValue = inputAmount * bnbPrice18 / one;
2522
+ lstAmount = lstPrice18 === 0n ? 0n : usdValue * one / lstPrice18;
2523
+ } else if (inNorm === usdt.toLowerCase() || inNorm === usdc.toLowerCase()) {
2524
+ lstAmount = lstPrice18 === 0n ? 0n : inputAmount * one / lstPrice18;
2525
+ } else {
2526
+ throw new Error("Unsupported input token for SDK preview");
2527
+ }
2528
+ const mintedAmount = await this.previewMint(targetLST, lstAmount, mintXBNB);
2529
+ return { lstAmount, mintedAmount };
2530
+ }
2531
+ /**
2532
+ * SDK-only preview: previewRedeem -> estimated output token
2533
+ * Note: oracle-based estimation (does not include live DEX slippage/price impact)
2534
+ */
2535
+ async previewRedeemToOutput(lst, redeemXBNB, amount, outputToken) {
2536
+ const lstAmount = await this.previewRedeem(lst, redeemXBNB, amount);
2537
+ if (lstAmount === 0n) return { lstAmount: 0n, outputAmount: 0n };
2538
+ const [diamond, wbnb, usdt, usdc] = await Promise.all([
2539
+ this.getDiamond(),
2540
+ this.getWBNB(),
2541
+ this.getUSDT(),
2542
+ this.getUSDC()
2543
+ ]);
2544
+ const [bnbPrice8, lstPrice] = await Promise.all([
2545
+ this.publicClient.readContract({
2546
+ address: diamond,
2547
+ abi: DiamondABI,
2548
+ functionName: "getBNBPriceUSD"
2549
+ }),
2550
+ this.publicClient.readContract({
2551
+ address: diamond,
2552
+ abi: DiamondABI,
2553
+ functionName: "getLSTPriceUSD",
2554
+ args: [lst]
2555
+ })
2556
+ ]);
2557
+ const bnbPrice18 = BigInt(bnbPrice8) * 10n ** 10n;
2558
+ const lstPrice18 = BigInt(lstPrice);
2559
+ const one = 10n ** 18n;
2560
+ const usdValue = lstAmount * lstPrice18 / one;
2561
+ let outputAmount = 0n;
2562
+ const outNorm = outputToken.toLowerCase();
2563
+ if (outNorm === lst.toLowerCase()) {
2564
+ outputAmount = lstAmount;
2565
+ } else if (outNorm === import_viem2.zeroAddress.toLowerCase() || outNorm === wbnb.toLowerCase()) {
2566
+ outputAmount = bnbPrice18 === 0n ? 0n : usdValue * one / bnbPrice18;
2567
+ } else if (outNorm === usdt.toLowerCase() || outNorm === usdc.toLowerCase()) {
2568
+ outputAmount = usdValue;
2569
+ } else {
2570
+ throw new Error("Unsupported output token for SDK preview");
2571
+ }
2572
+ return { lstAmount, outputAmount };
2573
+ }
2469
2574
  /**
2470
2575
  * Get user's withdrawal request indices
2471
2576
  */
@@ -2804,7 +2909,7 @@ var BPS_PRECISION = 10000n;
2804
2909
  var PRICE_PRECISION = 10n ** 8n;
2805
2910
  var BSC_ADDRESSES = {
2806
2911
  diamond: "0x6a11B30d3a70727d5477D6d8090e144443fA1c78",
2807
- router: "0x29dd49b2e98674ee7531f17e4d40a7725918c3f6",
2912
+ router: "0x34a64c4EbDe830773083BA8c9469456616F6723b",
2808
2913
  apUSD: "0x4570047eeB5aDb4081c5d470494EB5134e34A287",
2809
2914
  xBNB: "0x0A0c9CD826e747D99F90D63e780B3727Da4D0d43",
2810
2915
  sApUSD: "0x896770Dba7c0481539E25aaB56bE285ECF6D65eB",