@aspan/sdk 0.4.6 → 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.
@@ -254,13 +254,6 @@ export const DiamondABI = [
254
254
  outputs: [{ name: "assets", type: "uint256", internalType: "uint256" }],
255
255
  stateMutability: "nonpayable"
256
256
  },
257
- {
258
- type: "function",
259
- name: "withdrawAssets",
260
- inputs: [{ name: "_assets", type: "uint256", internalType: "uint256" }],
261
- outputs: [{ name: "shares", type: "uint256", internalType: "uint256" }],
262
- stateMutability: "nonpayable"
263
- },
264
257
  {
265
258
  type: "function",
266
259
  name: "getShares",
package/src/abi/router.ts CHANGED
@@ -185,6 +185,20 @@ export const RouterABI = [
185
185
  outputs: [{ type: "bool" }],
186
186
  stateMutability: "view",
187
187
  },
188
+ {
189
+ type: "function",
190
+ name: "lstModes",
191
+ inputs: [{ name: "lst", type: "address" }],
192
+ outputs: [{ type: "uint8" }],
193
+ stateMutability: "view",
194
+ },
195
+ {
196
+ type: "function",
197
+ name: "isLSTRoutable",
198
+ inputs: [{ name: "lst", type: "address" }],
199
+ outputs: [{ type: "bool" }],
200
+ stateMutability: "view",
201
+ },
188
202
 
189
203
  // Preview functions - unified
190
204
  {
package/src/abi/sApUSD.ts CHANGED
@@ -27,13 +27,13 @@ export const SApUSDABI = [
27
27
  },
28
28
  {
29
29
  type: "function",
30
- name: "previewRedeemMulti",
30
+ name: "previewRedeem",
31
31
  inputs: [
32
32
  { name: "shares", type: "uint256", internalType: "uint256" }
33
33
  ],
34
34
  outputs: [
35
- { name: "assets", type: "address[]", internalType: "address[]" },
36
- { name: "amounts", type: "uint256[]", internalType: "uint256[]" }
35
+ { name: "apUSDOut", type: "uint256", internalType: "uint256" },
36
+ { name: "xBNBOut", type: "uint256", internalType: "uint256" }
37
37
  ],
38
38
  stateMutability: "view"
39
39
  },
@@ -80,57 +80,71 @@ export const SApUSDABI = [
80
80
  },
81
81
  {
82
82
  type: "function",
83
- name: "previewCleanXBNB",
83
+ name: "hasRole",
84
84
  inputs: [
85
- { name: "_xBNBAmount", type: "uint256", internalType: "uint256" },
86
- { name: "_router", type: "address", internalType: "address" },
87
- { name: "_path", type: "address[]", internalType: "address[]" }
85
+ { name: "role", type: "bytes32", internalType: "bytes32" },
86
+ { name: "account", type: "address", internalType: "address" }
88
87
  ],
89
- outputs: [{ name: "expectedApUSD", type: "uint256", internalType: "uint256" }],
88
+ outputs: [{ name: "", type: "bool", internalType: "bool" }],
90
89
  stateMutability: "view"
91
90
  },
91
+
92
+ // ============ Write Functions ============
92
93
  {
93
94
  type: "function",
94
- name: "KEEPER_ROLE",
95
- inputs: [],
96
- outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
97
- stateMutability: "view"
95
+ name: "redeem",
96
+ inputs: [
97
+ { name: "shares", type: "uint256", internalType: "uint256" },
98
+ { name: "receiver", type: "address", internalType: "address" },
99
+ { name: "owner", type: "address", internalType: "address" }
100
+ ],
101
+ outputs: [
102
+ { name: "apUSDOut", type: "uint256", internalType: "uint256" },
103
+ { name: "xBNBOut", type: "uint256", internalType: "uint256" }
104
+ ],
105
+ stateMutability: "nonpayable"
98
106
  },
99
107
  {
100
108
  type: "function",
101
- name: "hasRole",
109
+ name: "deposit",
102
110
  inputs: [
103
- { name: "role", type: "bytes32", internalType: "bytes32" },
104
- { name: "account", type: "address", internalType: "address" }
111
+ { name: "assets", type: "uint256", internalType: "uint256" },
112
+ { name: "receiver", type: "address", internalType: "address" }
105
113
  ],
106
- outputs: [{ name: "", type: "bool", internalType: "bool" }],
107
- stateMutability: "view"
114
+ outputs: [{ name: "shares", type: "uint256", internalType: "uint256" }],
115
+ stateMutability: "nonpayable"
108
116
  },
109
117
 
110
- // ============ Keeper Functions ============
118
+ // ============ Accounting Functions ============
111
119
  {
112
120
  type: "function",
113
- name: "cleanXBNB",
121
+ name: "addAccounting",
114
122
  inputs: [
115
- { name: "_xBNBAmount", type: "uint256", internalType: "uint256" },
116
- { name: "_minApUSDOut", type: "uint256", internalType: "uint256" },
117
- { name: "_router", type: "address", internalType: "address" },
118
- { name: "_path", type: "address[]", internalType: "address[]" },
119
- { name: "_deadline", type: "uint256", internalType: "uint256" }
123
+ { name: "apUSD", type: "uint256", internalType: "uint256" },
124
+ { name: "xBNB", type: "uint256", internalType: "uint256" }
120
125
  ],
121
- outputs: [{ name: "apUSDReceived", type: "uint256", internalType: "uint256" }],
126
+ outputs: [],
127
+ stateMutability: "nonpayable"
128
+ },
129
+ {
130
+ type: "function",
131
+ name: "subAccounting",
132
+ inputs: [
133
+ { name: "apUSD", type: "uint256", internalType: "uint256" },
134
+ { name: "xBNB", type: "uint256", internalType: "uint256" }
135
+ ],
136
+ outputs: [],
122
137
  stateMutability: "nonpayable"
123
138
  },
124
139
 
125
- // ============ Events ============
140
+ // ============ Admin Functions ============
126
141
  {
127
- type: "event",
128
- name: "VaultCleaned",
142
+ type: "function",
143
+ name: "sweepExcess",
129
144
  inputs: [
130
- { name: "xBNBSold", type: "uint256", indexed: false, internalType: "uint256" },
131
- { name: "apUSDReceived", type: "uint256", indexed: false, internalType: "uint256" },
132
- { name: "keeper", type: "address", indexed: true, internalType: "address" }
145
+ { name: "recipient", type: "address", internalType: "address" }
133
146
  ],
134
- anonymous: false
135
- }
147
+ outputs: [],
148
+ stateMutability: "nonpayable"
149
+ },
136
150
  ] as const;
package/src/client.ts CHANGED
@@ -75,7 +75,6 @@ import type {
75
75
  RedeemXBNBParams,
76
76
  DepositParams,
77
77
  WithdrawParams,
78
- WithdrawAssetsParams,
79
78
  } from "./types";
80
79
 
81
80
  // ============ Configuration ============
@@ -1210,22 +1209,6 @@ export class AspanClient extends AspanReadClient {
1210
1209
  });
1211
1210
  }
1212
1211
 
1213
- /**
1214
- * Withdraw from stability pool by asset amount
1215
- * @param params Withdraw parameters
1216
- * @returns Transaction hash
1217
- */
1218
- async withdrawAssets(params: WithdrawAssetsParams): Promise<Hash> {
1219
- return this.walletClient.writeContract({
1220
- chain: this.chain,
1221
- account: this.walletClient.account!,
1222
- address: this.diamondAddress,
1223
- abi: DiamondABI,
1224
- functionName: "withdrawAssets",
1225
- args: [params.assets],
1226
- });
1227
- }
1228
-
1229
1212
  /**
1230
1213
  * Harvest yield from LSTs
1231
1214
  * @returns Transaction hash
package/src/index.ts CHANGED
@@ -68,7 +68,6 @@ export type {
68
68
  RedeemXBNBParams,
69
69
  DepositParams,
70
70
  WithdrawParams,
71
- WithdrawAssetsParams,
72
71
  // Events
73
72
  ApUSDMintedEvent,
74
73
  ApUSDRedeemedEvent,
@@ -117,7 +116,7 @@ export const PRICE_PRECISION = 10n ** 8n; // Chainlink price precision
117
116
  // ============ Contract Addresses (BSC Mainnet) ============
118
117
  export const BSC_ADDRESSES = {
119
118
  diamond: "0x6a11B30d3a70727d5477D6d8090e144443fA1c78" as const,
120
- router: "0x29dd49b2e98674ee7531f17e4d40a7725918c3f6" as const,
119
+ router: "0x34a64c4EbDe830773083BA8c9469456616F6723b" as const,
121
120
  apUSD: "0x4570047eeB5aDb4081c5d470494EB5134e34A287" as const,
122
121
  xBNB: "0x0A0c9CD826e747D99F90D63e780B3727Da4D0d43" as const,
123
122
  sApUSD: "0x896770Dba7c0481539E25aaB56bE285ECF6D65eB" as const,
package/src/router.ts CHANGED
@@ -20,6 +20,7 @@ import {
20
20
  import { bsc, bscTestnet } from "viem/chains";
21
21
  import { pharosTestnet, CHAIN_IDS, getChainById } from "./client";
22
22
  import { RouterABI } from "./abi/router";
23
+ import { DiamondABI } from "./abi/diamond";
23
24
  import type {
24
25
  SwapAndMintParams,
25
26
  StakeAndMintParams,
@@ -106,6 +107,31 @@ export class AspanRouterReadClient {
106
107
  });
107
108
  }
108
109
 
110
+ /**
111
+ * Get LST mode (0 = SYNC, 1 = ASYNC_DIRECT_ONLY)
112
+ */
113
+ async getLSTMode(lst: Address): Promise<number> {
114
+ const mode = await this.publicClient.readContract({
115
+ address: this.routerAddress,
116
+ abi: RouterABI,
117
+ functionName: "lstModes",
118
+ args: [lst],
119
+ });
120
+ return Number(mode);
121
+ }
122
+
123
+ /**
124
+ * Check whether an LST supports routed flows (swap/stake/redeemAndSwap)
125
+ */
126
+ async isLSTRoutable(lst: Address): Promise<boolean> {
127
+ return this.publicClient.readContract({
128
+ address: this.routerAddress,
129
+ abi: RouterABI,
130
+ functionName: "isLSTRoutable",
131
+ args: [lst],
132
+ });
133
+ }
134
+
109
135
  /**
110
136
  * Get the Diamond contract address
111
137
  */
@@ -147,6 +173,116 @@ export class AspanRouterReadClient {
147
173
  });
148
174
  }
149
175
 
176
+ /**
177
+ * SDK-only preview: input token -> estimated LST -> previewMint
178
+ * Note: oracle-based estimation (does not include live DEX slippage/price impact)
179
+ */
180
+ async previewMintByInput(
181
+ inputToken: Address,
182
+ inputAmount: bigint,
183
+ targetLST: Address,
184
+ mintXBNB: boolean
185
+ ): Promise<{ lstAmount: bigint; mintedAmount: bigint }> {
186
+ if (inputAmount === 0n) return { lstAmount: 0n, mintedAmount: 0n };
187
+
188
+ const [diamond, wbnb, usdt, usdc] = await Promise.all([
189
+ this.getDiamond(),
190
+ this.getWBNB(),
191
+ this.getUSDT(),
192
+ this.getUSDC(),
193
+ ]);
194
+
195
+ const [bnbPrice8, lstPrice] = await Promise.all([
196
+ this.publicClient.readContract({
197
+ address: diamond,
198
+ abi: DiamondABI,
199
+ functionName: "getBNBPriceUSD",
200
+ }),
201
+ this.publicClient.readContract({
202
+ address: diamond,
203
+ abi: DiamondABI,
204
+ functionName: "getLSTPriceUSD",
205
+ args: [targetLST],
206
+ }),
207
+ ]);
208
+
209
+ const bnbPrice18 = BigInt(bnbPrice8) * 10n ** 10n;
210
+ const lstPrice18 = BigInt(lstPrice);
211
+ const one = 10n ** 18n;
212
+
213
+ let lstAmount = 0n;
214
+ const inNorm = inputToken.toLowerCase();
215
+ if (inNorm === targetLST.toLowerCase()) {
216
+ lstAmount = inputAmount;
217
+ } else if (inNorm === zeroAddress.toLowerCase() || inNorm === wbnb.toLowerCase()) {
218
+ // BNB/WBNB -> USD -> LST
219
+ const usdValue = (inputAmount * bnbPrice18) / one;
220
+ lstAmount = lstPrice18 === 0n ? 0n : (usdValue * one) / lstPrice18;
221
+ } else if (inNorm === usdt.toLowerCase() || inNorm === usdc.toLowerCase()) {
222
+ // stablecoin (18-decimal normalized in this SDK path) -> LST
223
+ lstAmount = lstPrice18 === 0n ? 0n : (inputAmount * one) / lstPrice18;
224
+ } else {
225
+ throw new Error("Unsupported input token for SDK preview");
226
+ }
227
+
228
+ const mintedAmount = await this.previewMint(targetLST, lstAmount, mintXBNB);
229
+ return { lstAmount, mintedAmount };
230
+ }
231
+
232
+ /**
233
+ * SDK-only preview: previewRedeem -> estimated output token
234
+ * Note: oracle-based estimation (does not include live DEX slippage/price impact)
235
+ */
236
+ async previewRedeemToOutput(
237
+ lst: Address,
238
+ redeemXBNB: boolean,
239
+ amount: bigint,
240
+ outputToken: Address
241
+ ): Promise<{ lstAmount: bigint; outputAmount: bigint }> {
242
+ const lstAmount = await this.previewRedeem(lst, redeemXBNB, amount);
243
+ if (lstAmount === 0n) return { lstAmount: 0n, outputAmount: 0n };
244
+
245
+ const [diamond, wbnb, usdt, usdc] = await Promise.all([
246
+ this.getDiamond(),
247
+ this.getWBNB(),
248
+ this.getUSDT(),
249
+ this.getUSDC(),
250
+ ]);
251
+
252
+ const [bnbPrice8, lstPrice] = await Promise.all([
253
+ this.publicClient.readContract({
254
+ address: diamond,
255
+ abi: DiamondABI,
256
+ functionName: "getBNBPriceUSD",
257
+ }),
258
+ this.publicClient.readContract({
259
+ address: diamond,
260
+ abi: DiamondABI,
261
+ functionName: "getLSTPriceUSD",
262
+ args: [lst],
263
+ }),
264
+ ]);
265
+
266
+ const bnbPrice18 = BigInt(bnbPrice8) * 10n ** 10n;
267
+ const lstPrice18 = BigInt(lstPrice);
268
+ const one = 10n ** 18n;
269
+ const usdValue = (lstAmount * lstPrice18) / one;
270
+
271
+ let outputAmount = 0n;
272
+ const outNorm = outputToken.toLowerCase();
273
+ if (outNorm === lst.toLowerCase()) {
274
+ outputAmount = lstAmount;
275
+ } else if (outNorm === zeroAddress.toLowerCase() || outNorm === wbnb.toLowerCase()) {
276
+ outputAmount = bnbPrice18 === 0n ? 0n : (usdValue * one) / bnbPrice18;
277
+ } else if (outNorm === usdt.toLowerCase() || outNorm === usdc.toLowerCase()) {
278
+ outputAmount = usdValue;
279
+ } else {
280
+ throw new Error("Unsupported output token for SDK preview");
281
+ }
282
+
283
+ return { lstAmount, outputAmount };
284
+ }
285
+
150
286
  /**
151
287
  * Get user's withdrawal request indices
152
288
  */
package/src/types.ts CHANGED
@@ -128,11 +128,6 @@ export interface WithdrawParams {
128
128
  shares: bigint;
129
129
  }
130
130
 
131
- /** Parameters for withdrawing assets from stability pool */
132
- export interface WithdrawAssetsParams {
133
- assets: bigint;
134
- }
135
-
136
131
  // ============ Protocol Stats ============
137
132
 
138
133
  /** Overall protocol statistics */