@aspan/sdk 0.1.8 → 0.2.0
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 +218 -0
- package/dist/index.d.mts +1183 -1
- package/dist/index.d.ts +1183 -1
- package/dist/index.js +1049 -0
- package/dist/index.mjs +1047 -0
- package/package.json +1 -1
- package/src/abi/router.ts +554 -0
- package/src/index.ts +35 -0
- package/src/router.ts +686 -0
- package/src/types.ts +218 -0
package/src/router.ts
ADDED
|
@@ -0,0 +1,686 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Aspan Router Client
|
|
3
|
+
* TypeScript client for interacting with the AspanRouter periphery contract
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
createPublicClient,
|
|
8
|
+
createWalletClient,
|
|
9
|
+
http,
|
|
10
|
+
zeroAddress,
|
|
11
|
+
type Address,
|
|
12
|
+
type PublicClient,
|
|
13
|
+
type WalletClient,
|
|
14
|
+
type Transport,
|
|
15
|
+
type Chain,
|
|
16
|
+
type Account,
|
|
17
|
+
type Hash,
|
|
18
|
+
} from "viem";
|
|
19
|
+
import { bsc, bscTestnet } from "viem/chains";
|
|
20
|
+
import { RouterABI } from "./abi/router";
|
|
21
|
+
import type {
|
|
22
|
+
SwapAndMintParams,
|
|
23
|
+
StakeAndMintParams,
|
|
24
|
+
SwapAndMintDefaultParams,
|
|
25
|
+
RouterMintApUSDParams,
|
|
26
|
+
RouterMintXBNBParams,
|
|
27
|
+
RouterRedeemApUSDParams,
|
|
28
|
+
RouterRedeemXBNBParams,
|
|
29
|
+
RouterRedeemAndSwapParams,
|
|
30
|
+
RouterRedeemAndUnstakeParams,
|
|
31
|
+
WithdrawalRequestInfo,
|
|
32
|
+
ExpectedOutput,
|
|
33
|
+
} from "./types";
|
|
34
|
+
|
|
35
|
+
// ============ Configuration ============
|
|
36
|
+
|
|
37
|
+
export interface AspanRouterClientConfig {
|
|
38
|
+
/** Router contract address */
|
|
39
|
+
routerAddress: Address;
|
|
40
|
+
/** Chain to connect to */
|
|
41
|
+
chain?: Chain;
|
|
42
|
+
/** RPC URL (optional, uses default if not provided) */
|
|
43
|
+
rpcUrl?: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface AspanRouterWriteClientConfig extends AspanRouterClientConfig {
|
|
47
|
+
/** Account for signing transactions (required if walletClient not provided) */
|
|
48
|
+
account?: Account;
|
|
49
|
+
/** External wallet client (for browser environments with wagmi/rainbowkit) */
|
|
50
|
+
walletClient?: WalletClient<Transport, Chain, Account>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// ============ Read-Only Client ============
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Read-only client for querying AspanRouter state
|
|
57
|
+
*/
|
|
58
|
+
export class AspanRouterReadClient {
|
|
59
|
+
protected readonly publicClient: PublicClient;
|
|
60
|
+
protected readonly routerAddress: Address;
|
|
61
|
+
protected readonly chain: Chain;
|
|
62
|
+
|
|
63
|
+
constructor(config: AspanRouterClientConfig) {
|
|
64
|
+
this.routerAddress = config.routerAddress;
|
|
65
|
+
this.chain = config.chain ?? bsc;
|
|
66
|
+
|
|
67
|
+
this.publicClient = createPublicClient({
|
|
68
|
+
chain: this.chain,
|
|
69
|
+
transport: http(config.rpcUrl),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ============ View Functions ============
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Get the default LST address
|
|
77
|
+
*/
|
|
78
|
+
async getDefaultLST(): Promise<Address> {
|
|
79
|
+
return this.publicClient.readContract({
|
|
80
|
+
address: this.routerAddress,
|
|
81
|
+
abi: RouterABI,
|
|
82
|
+
functionName: "defaultLST",
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Check if an input token is supported
|
|
88
|
+
*/
|
|
89
|
+
async isSupportedInputToken(token: Address): Promise<boolean> {
|
|
90
|
+
return this.publicClient.readContract({
|
|
91
|
+
address: this.routerAddress,
|
|
92
|
+
abi: RouterABI,
|
|
93
|
+
functionName: "supportedInputTokens",
|
|
94
|
+
args: [token],
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Check if an LST is supported
|
|
100
|
+
*/
|
|
101
|
+
async isSupportedLST(lst: Address): Promise<boolean> {
|
|
102
|
+
return this.publicClient.readContract({
|
|
103
|
+
address: this.routerAddress,
|
|
104
|
+
abi: RouterABI,
|
|
105
|
+
functionName: "supportedLSTs",
|
|
106
|
+
args: [lst],
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Get the Diamond contract address
|
|
112
|
+
*/
|
|
113
|
+
async getDiamond(): Promise<Address> {
|
|
114
|
+
return this.publicClient.readContract({
|
|
115
|
+
address: this.routerAddress,
|
|
116
|
+
abi: RouterABI,
|
|
117
|
+
functionName: "diamond",
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Get expected output from a swap and mint operation
|
|
123
|
+
*/
|
|
124
|
+
async getExpectedOutput(
|
|
125
|
+
inputToken: Address,
|
|
126
|
+
inputAmount: bigint,
|
|
127
|
+
targetLST: Address,
|
|
128
|
+
mintXBNB: boolean
|
|
129
|
+
): Promise<ExpectedOutput> {
|
|
130
|
+
const result = await this.publicClient.readContract({
|
|
131
|
+
address: this.routerAddress,
|
|
132
|
+
abi: RouterABI,
|
|
133
|
+
functionName: "getExpectedOutput",
|
|
134
|
+
args: [inputToken, inputAmount, targetLST, mintXBNB],
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
expectedLST: result[0],
|
|
139
|
+
expectedMint: result[1],
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Get user's withdrawal request indices
|
|
145
|
+
*/
|
|
146
|
+
async getUserWithdrawalIndices(user: Address): Promise<bigint[]> {
|
|
147
|
+
const result = await this.publicClient.readContract({
|
|
148
|
+
address: this.routerAddress,
|
|
149
|
+
abi: RouterABI,
|
|
150
|
+
functionName: "getUserWithdrawalIndices",
|
|
151
|
+
args: [user],
|
|
152
|
+
});
|
|
153
|
+
return [...result];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Get withdrawal request status
|
|
158
|
+
*/
|
|
159
|
+
async getWithdrawalStatus(
|
|
160
|
+
requestIndex: bigint
|
|
161
|
+
): Promise<WithdrawalRequestInfo> {
|
|
162
|
+
const result = await this.publicClient.readContract({
|
|
163
|
+
address: this.routerAddress,
|
|
164
|
+
abi: RouterABI,
|
|
165
|
+
functionName: "getWithdrawalStatus",
|
|
166
|
+
args: [requestIndex],
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
isClaimable: result[0],
|
|
171
|
+
bnbAmount: result[1],
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// ============ Token Address Getters ============
|
|
176
|
+
|
|
177
|
+
async getWBNB(): Promise<Address> {
|
|
178
|
+
return this.publicClient.readContract({
|
|
179
|
+
address: this.routerAddress,
|
|
180
|
+
abi: RouterABI,
|
|
181
|
+
functionName: "wbnb",
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async getUSDT(): Promise<Address> {
|
|
186
|
+
return this.publicClient.readContract({
|
|
187
|
+
address: this.routerAddress,
|
|
188
|
+
abi: RouterABI,
|
|
189
|
+
functionName: "usdt",
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
async getUSDC(): Promise<Address> {
|
|
194
|
+
return this.publicClient.readContract({
|
|
195
|
+
address: this.routerAddress,
|
|
196
|
+
abi: RouterABI,
|
|
197
|
+
functionName: "usdc",
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async getSlisBNB(): Promise<Address> {
|
|
202
|
+
return this.publicClient.readContract({
|
|
203
|
+
address: this.routerAddress,
|
|
204
|
+
abi: RouterABI,
|
|
205
|
+
functionName: "slisBNB",
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
async getAsBNB(): Promise<Address> {
|
|
210
|
+
return this.publicClient.readContract({
|
|
211
|
+
address: this.routerAddress,
|
|
212
|
+
abi: RouterABI,
|
|
213
|
+
functionName: "asBNB",
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
async getWclisBNB(): Promise<Address> {
|
|
218
|
+
return this.publicClient.readContract({
|
|
219
|
+
address: this.routerAddress,
|
|
220
|
+
abi: RouterABI,
|
|
221
|
+
functionName: "wclisBNB",
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
async getApUSD(): Promise<Address> {
|
|
226
|
+
return this.publicClient.readContract({
|
|
227
|
+
address: this.routerAddress,
|
|
228
|
+
abi: RouterABI,
|
|
229
|
+
functionName: "apUSD",
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
async getXBNB(): Promise<Address> {
|
|
234
|
+
return this.publicClient.readContract({
|
|
235
|
+
address: this.routerAddress,
|
|
236
|
+
abi: RouterABI,
|
|
237
|
+
functionName: "xBNB",
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// ============ Write Client ============
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Full client with write capabilities for AspanRouter
|
|
246
|
+
*/
|
|
247
|
+
export class AspanRouterClient extends AspanRouterReadClient {
|
|
248
|
+
private readonly walletClient: WalletClient;
|
|
249
|
+
|
|
250
|
+
constructor(config: AspanRouterWriteClientConfig) {
|
|
251
|
+
super(config);
|
|
252
|
+
|
|
253
|
+
if (config.walletClient) {
|
|
254
|
+
this.walletClient = config.walletClient;
|
|
255
|
+
} else if (config.account) {
|
|
256
|
+
this.walletClient = createWalletClient({
|
|
257
|
+
account: config.account,
|
|
258
|
+
chain: this.chain,
|
|
259
|
+
transport: http(config.rpcUrl),
|
|
260
|
+
});
|
|
261
|
+
} else {
|
|
262
|
+
throw new Error("Either walletClient or account must be provided");
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// ============ Core Functions ============
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Swap input token to LST and mint apUSD
|
|
270
|
+
*/
|
|
271
|
+
async swapAndMintApUSD(params: SwapAndMintParams): Promise<Hash> {
|
|
272
|
+
const value =
|
|
273
|
+
params.swapParams.inputToken === zeroAddress
|
|
274
|
+
? params.swapParams.inputAmount
|
|
275
|
+
: 0n;
|
|
276
|
+
|
|
277
|
+
return this.walletClient.writeContract({
|
|
278
|
+
chain: this.chain,
|
|
279
|
+
account: this.walletClient.account!,
|
|
280
|
+
address: this.routerAddress,
|
|
281
|
+
abi: RouterABI,
|
|
282
|
+
functionName: "swapAndMintApUSD",
|
|
283
|
+
args: [
|
|
284
|
+
{
|
|
285
|
+
inputToken: params.swapParams.inputToken,
|
|
286
|
+
inputAmount: params.swapParams.inputAmount,
|
|
287
|
+
targetLST: params.swapParams.targetLST,
|
|
288
|
+
minLSTOut: params.swapParams.minLSTOut,
|
|
289
|
+
poolFee: params.swapParams.poolFee,
|
|
290
|
+
useV2: params.swapParams.useV2,
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
mintXBNB: params.mintParams.mintXBNB,
|
|
294
|
+
minMintOut: params.mintParams.minMintOut,
|
|
295
|
+
recipient: params.mintParams.recipient,
|
|
296
|
+
deadline: params.mintParams.deadline,
|
|
297
|
+
},
|
|
298
|
+
],
|
|
299
|
+
value,
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Swap input token to LST and mint xBNB
|
|
305
|
+
*/
|
|
306
|
+
async swapAndMintXBNB(params: SwapAndMintParams): Promise<Hash> {
|
|
307
|
+
const value =
|
|
308
|
+
params.swapParams.inputToken === zeroAddress
|
|
309
|
+
? params.swapParams.inputAmount
|
|
310
|
+
: 0n;
|
|
311
|
+
|
|
312
|
+
return this.walletClient.writeContract({
|
|
313
|
+
chain: this.chain,
|
|
314
|
+
account: this.walletClient.account!,
|
|
315
|
+
address: this.routerAddress,
|
|
316
|
+
abi: RouterABI,
|
|
317
|
+
functionName: "swapAndMintXBNB",
|
|
318
|
+
args: [
|
|
319
|
+
{
|
|
320
|
+
inputToken: params.swapParams.inputToken,
|
|
321
|
+
inputAmount: params.swapParams.inputAmount,
|
|
322
|
+
targetLST: params.swapParams.targetLST,
|
|
323
|
+
minLSTOut: params.swapParams.minLSTOut,
|
|
324
|
+
poolFee: params.swapParams.poolFee,
|
|
325
|
+
useV2: params.swapParams.useV2,
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
mintXBNB: params.mintParams.mintXBNB,
|
|
329
|
+
minMintOut: params.mintParams.minMintOut,
|
|
330
|
+
recipient: params.mintParams.recipient,
|
|
331
|
+
deadline: params.mintParams.deadline,
|
|
332
|
+
},
|
|
333
|
+
],
|
|
334
|
+
value,
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Stake native BNB directly to LST and mint
|
|
340
|
+
*/
|
|
341
|
+
async stakeAndMint(params: StakeAndMintParams): Promise<Hash> {
|
|
342
|
+
return this.walletClient.writeContract({
|
|
343
|
+
chain: this.chain,
|
|
344
|
+
account: this.walletClient.account!,
|
|
345
|
+
address: this.routerAddress,
|
|
346
|
+
abi: RouterABI,
|
|
347
|
+
functionName: "stakeAndMint",
|
|
348
|
+
args: [
|
|
349
|
+
params.targetLST,
|
|
350
|
+
params.mintXBNB,
|
|
351
|
+
params.minMintOut,
|
|
352
|
+
params.deadline,
|
|
353
|
+
],
|
|
354
|
+
value: params.value,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// ============ Simplified Functions ============
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Swap input token and mint apUSD using default LST
|
|
362
|
+
*/
|
|
363
|
+
async swapAndMintApUSDDefault(params: SwapAndMintDefaultParams): Promise<Hash> {
|
|
364
|
+
const value =
|
|
365
|
+
params.inputToken === zeroAddress ? params.value ?? params.inputAmount : 0n;
|
|
366
|
+
|
|
367
|
+
return this.walletClient.writeContract({
|
|
368
|
+
chain: this.chain,
|
|
369
|
+
account: this.walletClient.account!,
|
|
370
|
+
address: this.routerAddress,
|
|
371
|
+
abi: RouterABI,
|
|
372
|
+
functionName: "swapAndMintApUSDDefault",
|
|
373
|
+
args: [
|
|
374
|
+
params.inputToken,
|
|
375
|
+
params.inputAmount,
|
|
376
|
+
params.minMintOut,
|
|
377
|
+
params.deadline,
|
|
378
|
+
],
|
|
379
|
+
value,
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Swap input token and mint xBNB using default LST
|
|
385
|
+
*/
|
|
386
|
+
async swapAndMintXBNBDefault(params: SwapAndMintDefaultParams): Promise<Hash> {
|
|
387
|
+
const value =
|
|
388
|
+
params.inputToken === zeroAddress ? params.value ?? params.inputAmount : 0n;
|
|
389
|
+
|
|
390
|
+
return this.walletClient.writeContract({
|
|
391
|
+
chain: this.chain,
|
|
392
|
+
account: this.walletClient.account!,
|
|
393
|
+
address: this.routerAddress,
|
|
394
|
+
abi: RouterABI,
|
|
395
|
+
functionName: "swapAndMintXBNBDefault",
|
|
396
|
+
args: [
|
|
397
|
+
params.inputToken,
|
|
398
|
+
params.inputAmount,
|
|
399
|
+
params.minMintOut,
|
|
400
|
+
params.deadline,
|
|
401
|
+
],
|
|
402
|
+
value,
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Stake native BNB and mint apUSD using default LST
|
|
408
|
+
*/
|
|
409
|
+
async stakeAndMintApUSD(minMintOut: bigint, value: bigint): Promise<Hash> {
|
|
410
|
+
return this.walletClient.writeContract({
|
|
411
|
+
chain: this.chain,
|
|
412
|
+
account: this.walletClient.account!,
|
|
413
|
+
address: this.routerAddress,
|
|
414
|
+
abi: RouterABI,
|
|
415
|
+
functionName: "stakeAndMintApUSD",
|
|
416
|
+
args: [minMintOut],
|
|
417
|
+
value,
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Stake native BNB and mint xBNB using default LST
|
|
423
|
+
*/
|
|
424
|
+
async stakeAndMintXBNB(minMintOut: bigint, value: bigint): Promise<Hash> {
|
|
425
|
+
return this.walletClient.writeContract({
|
|
426
|
+
chain: this.chain,
|
|
427
|
+
account: this.walletClient.account!,
|
|
428
|
+
address: this.routerAddress,
|
|
429
|
+
abi: RouterABI,
|
|
430
|
+
functionName: "stakeAndMintXBNB",
|
|
431
|
+
args: [minMintOut],
|
|
432
|
+
value,
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// ============ Direct Mint/Redeem Functions ============
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Mint apUSD by providing LST directly (no swap)
|
|
440
|
+
*/
|
|
441
|
+
async mintApUSD(params: RouterMintApUSDParams): Promise<Hash> {
|
|
442
|
+
return this.walletClient.writeContract({
|
|
443
|
+
chain: this.chain,
|
|
444
|
+
account: this.walletClient.account!,
|
|
445
|
+
address: this.routerAddress,
|
|
446
|
+
abi: RouterABI,
|
|
447
|
+
functionName: "mintApUSD",
|
|
448
|
+
args: [params.lst, params.lstAmount, params.minOut ?? 0n],
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Mint xBNB by providing LST directly (no swap)
|
|
454
|
+
*/
|
|
455
|
+
async mintXBNB(params: RouterMintXBNBParams): Promise<Hash> {
|
|
456
|
+
return this.walletClient.writeContract({
|
|
457
|
+
chain: this.chain,
|
|
458
|
+
account: this.walletClient.account!,
|
|
459
|
+
address: this.routerAddress,
|
|
460
|
+
abi: RouterABI,
|
|
461
|
+
functionName: "mintXBNB",
|
|
462
|
+
args: [params.lst, params.lstAmount, params.minOut ?? 0n],
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Redeem apUSD for LST (no swap)
|
|
468
|
+
*/
|
|
469
|
+
async redeemApUSD(params: RouterRedeemApUSDParams): Promise<Hash> {
|
|
470
|
+
return this.walletClient.writeContract({
|
|
471
|
+
chain: this.chain,
|
|
472
|
+
account: this.walletClient.account!,
|
|
473
|
+
address: this.routerAddress,
|
|
474
|
+
abi: RouterABI,
|
|
475
|
+
functionName: "redeemApUSD",
|
|
476
|
+
args: [params.lst, params.apUSDAmount, params.minOut ?? 0n],
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Redeem xBNB for LST (no swap)
|
|
482
|
+
*/
|
|
483
|
+
async redeemXBNB(params: RouterRedeemXBNBParams): Promise<Hash> {
|
|
484
|
+
return this.walletClient.writeContract({
|
|
485
|
+
chain: this.chain,
|
|
486
|
+
account: this.walletClient.account!,
|
|
487
|
+
address: this.routerAddress,
|
|
488
|
+
abi: RouterABI,
|
|
489
|
+
functionName: "redeemXBNB",
|
|
490
|
+
args: [params.lst, params.xBNBAmount, params.minOut ?? 0n],
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// ============ Redeem and Swap Functions ============
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Redeem apUSD and swap LST to output token
|
|
498
|
+
*/
|
|
499
|
+
async redeemApUSDAndSwap(params: RouterRedeemAndSwapParams): Promise<Hash> {
|
|
500
|
+
return this.walletClient.writeContract({
|
|
501
|
+
chain: this.chain,
|
|
502
|
+
account: this.walletClient.account!,
|
|
503
|
+
address: this.routerAddress,
|
|
504
|
+
abi: RouterABI,
|
|
505
|
+
functionName: "redeemApUSDAndSwap",
|
|
506
|
+
args: [
|
|
507
|
+
params.lst,
|
|
508
|
+
params.amount,
|
|
509
|
+
params.outputToken,
|
|
510
|
+
params.minOut,
|
|
511
|
+
params.deadline,
|
|
512
|
+
params.useV2,
|
|
513
|
+
params.poolFee,
|
|
514
|
+
],
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Redeem xBNB and swap LST to output token
|
|
520
|
+
*/
|
|
521
|
+
async redeemXBNBAndSwap(params: RouterRedeemAndSwapParams): Promise<Hash> {
|
|
522
|
+
return this.walletClient.writeContract({
|
|
523
|
+
chain: this.chain,
|
|
524
|
+
account: this.walletClient.account!,
|
|
525
|
+
address: this.routerAddress,
|
|
526
|
+
abi: RouterABI,
|
|
527
|
+
functionName: "redeemXBNBAndSwap",
|
|
528
|
+
args: [
|
|
529
|
+
params.lst,
|
|
530
|
+
params.amount,
|
|
531
|
+
params.outputToken,
|
|
532
|
+
params.minOut,
|
|
533
|
+
params.deadline,
|
|
534
|
+
params.useV2,
|
|
535
|
+
params.poolFee,
|
|
536
|
+
],
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/**
|
|
541
|
+
* Redeem apUSD and instantly unstake LST to native BNB via DEX
|
|
542
|
+
*/
|
|
543
|
+
async redeemApUSDAndUnstake(
|
|
544
|
+
params: RouterRedeemAndUnstakeParams
|
|
545
|
+
): Promise<Hash> {
|
|
546
|
+
return this.walletClient.writeContract({
|
|
547
|
+
chain: this.chain,
|
|
548
|
+
account: this.walletClient.account!,
|
|
549
|
+
address: this.routerAddress,
|
|
550
|
+
abi: RouterABI,
|
|
551
|
+
functionName: "redeemApUSDAndUnstake",
|
|
552
|
+
args: [params.lst, params.amount, params.minBNBOut, params.deadline],
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
* Redeem xBNB and instantly unstake LST to native BNB via DEX
|
|
558
|
+
*/
|
|
559
|
+
async redeemXBNBAndUnstake(
|
|
560
|
+
params: RouterRedeemAndUnstakeParams
|
|
561
|
+
): Promise<Hash> {
|
|
562
|
+
return this.walletClient.writeContract({
|
|
563
|
+
chain: this.chain,
|
|
564
|
+
account: this.walletClient.account!,
|
|
565
|
+
address: this.routerAddress,
|
|
566
|
+
abi: RouterABI,
|
|
567
|
+
functionName: "redeemXBNBAndUnstake",
|
|
568
|
+
args: [params.lst, params.amount, params.minBNBOut, params.deadline],
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// ============ Native Unstake Functions ============
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Redeem apUSD and request native unstake from Lista (starts unbonding period)
|
|
576
|
+
*/
|
|
577
|
+
async redeemApUSDAndRequestUnstake(apUSDAmount: bigint): Promise<Hash> {
|
|
578
|
+
return this.walletClient.writeContract({
|
|
579
|
+
chain: this.chain,
|
|
580
|
+
account: this.walletClient.account!,
|
|
581
|
+
address: this.routerAddress,
|
|
582
|
+
abi: RouterABI,
|
|
583
|
+
functionName: "redeemApUSDAndRequestUnstake",
|
|
584
|
+
args: [apUSDAmount],
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
/**
|
|
589
|
+
* Redeem xBNB and request native unstake from Lista (starts unbonding period)
|
|
590
|
+
*/
|
|
591
|
+
async redeemXBNBAndRequestUnstake(xBNBAmount: bigint): Promise<Hash> {
|
|
592
|
+
return this.walletClient.writeContract({
|
|
593
|
+
chain: this.chain,
|
|
594
|
+
account: this.walletClient.account!,
|
|
595
|
+
address: this.routerAddress,
|
|
596
|
+
abi: RouterABI,
|
|
597
|
+
functionName: "redeemXBNBAndRequestUnstake",
|
|
598
|
+
args: [xBNBAmount],
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* Claim BNB after unbonding period completes
|
|
604
|
+
*/
|
|
605
|
+
async claimUnstake(requestIndex: bigint): Promise<Hash> {
|
|
606
|
+
return this.walletClient.writeContract({
|
|
607
|
+
chain: this.chain,
|
|
608
|
+
account: this.walletClient.account!,
|
|
609
|
+
address: this.routerAddress,
|
|
610
|
+
abi: RouterABI,
|
|
611
|
+
functionName: "claimUnstake",
|
|
612
|
+
args: [requestIndex],
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
// ============ Transaction Helpers ============
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* Wait for transaction confirmation
|
|
620
|
+
*/
|
|
621
|
+
async waitForTransaction(hash: Hash) {
|
|
622
|
+
return this.publicClient.waitForTransactionReceipt({ hash });
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
// ============ Factory Functions ============
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* Create a read-only router client for BSC mainnet
|
|
630
|
+
*/
|
|
631
|
+
export function createRouterReadClient(
|
|
632
|
+
routerAddress: Address,
|
|
633
|
+
rpcUrl?: string
|
|
634
|
+
): AspanRouterReadClient {
|
|
635
|
+
return new AspanRouterReadClient({
|
|
636
|
+
routerAddress,
|
|
637
|
+
chain: bsc,
|
|
638
|
+
rpcUrl,
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Create a full router client for BSC mainnet
|
|
644
|
+
*/
|
|
645
|
+
export function createRouterClient(
|
|
646
|
+
routerAddress: Address,
|
|
647
|
+
account: Account,
|
|
648
|
+
rpcUrl?: string
|
|
649
|
+
): AspanRouterClient {
|
|
650
|
+
return new AspanRouterClient({
|
|
651
|
+
routerAddress,
|
|
652
|
+
account,
|
|
653
|
+
chain: bsc,
|
|
654
|
+
rpcUrl,
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* Create a read-only router client for BSC testnet
|
|
660
|
+
*/
|
|
661
|
+
export function createRouterTestnetReadClient(
|
|
662
|
+
routerAddress: Address,
|
|
663
|
+
rpcUrl?: string
|
|
664
|
+
): AspanRouterReadClient {
|
|
665
|
+
return new AspanRouterReadClient({
|
|
666
|
+
routerAddress,
|
|
667
|
+
chain: bscTestnet,
|
|
668
|
+
rpcUrl,
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
/**
|
|
673
|
+
* Create a full router client for BSC testnet
|
|
674
|
+
*/
|
|
675
|
+
export function createRouterTestnetClient(
|
|
676
|
+
routerAddress: Address,
|
|
677
|
+
account: Account,
|
|
678
|
+
rpcUrl?: string
|
|
679
|
+
): AspanRouterClient {
|
|
680
|
+
return new AspanRouterClient({
|
|
681
|
+
routerAddress,
|
|
682
|
+
account,
|
|
683
|
+
chain: bscTestnet,
|
|
684
|
+
rpcUrl,
|
|
685
|
+
});
|
|
686
|
+
}
|