@aspan/sdk 0.1.4

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.mjs ADDED
@@ -0,0 +1,1413 @@
1
+ // src/client.ts
2
+ import {
3
+ createPublicClient,
4
+ createWalletClient,
5
+ http
6
+ } from "viem";
7
+ import { bsc, bscTestnet } from "viem/chains";
8
+
9
+ // src/abi/diamond.ts
10
+ var DiamondABI = [
11
+ // ============ PoolFacet ============
12
+ {
13
+ type: "function",
14
+ name: "mintApUSD",
15
+ inputs: [
16
+ { name: "_lstToken", type: "address", internalType: "address" },
17
+ { name: "_lstAmount", type: "uint256", internalType: "uint256" }
18
+ ],
19
+ outputs: [{ name: "apUSDAmount", type: "uint256", internalType: "uint256" }],
20
+ stateMutability: "nonpayable"
21
+ },
22
+ {
23
+ type: "function",
24
+ name: "redeemApUSD",
25
+ inputs: [
26
+ { name: "_lstToken", type: "address", internalType: "address" },
27
+ { name: "_apUSDAmount", type: "uint256", internalType: "uint256" }
28
+ ],
29
+ outputs: [{ name: "lstAmount", type: "uint256", internalType: "uint256" }],
30
+ stateMutability: "nonpayable"
31
+ },
32
+ {
33
+ type: "function",
34
+ name: "mintXBNB",
35
+ inputs: [
36
+ { name: "_lstToken", type: "address", internalType: "address" },
37
+ { name: "_lstAmount", type: "uint256", internalType: "uint256" }
38
+ ],
39
+ outputs: [{ name: "xBNBAmount", type: "uint256", internalType: "uint256" }],
40
+ stateMutability: "nonpayable"
41
+ },
42
+ {
43
+ type: "function",
44
+ name: "redeemXBNB",
45
+ inputs: [
46
+ { name: "_lstToken", type: "address", internalType: "address" },
47
+ { name: "_xBNBAmount", type: "uint256", internalType: "uint256" }
48
+ ],
49
+ outputs: [{ name: "lstAmount", type: "uint256", internalType: "uint256" }],
50
+ stateMutability: "nonpayable"
51
+ },
52
+ {
53
+ type: "function",
54
+ name: "getXBNBPriceBNB",
55
+ inputs: [],
56
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
57
+ stateMutability: "view"
58
+ },
59
+ {
60
+ type: "function",
61
+ name: "getXBNBPriceUSD",
62
+ inputs: [],
63
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
64
+ stateMutability: "view"
65
+ },
66
+ {
67
+ type: "function",
68
+ name: "getTVLInBNB",
69
+ inputs: [],
70
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
71
+ stateMutability: "view"
72
+ },
73
+ {
74
+ type: "function",
75
+ name: "getTVLInUSD",
76
+ inputs: [],
77
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
78
+ stateMutability: "view"
79
+ },
80
+ {
81
+ type: "function",
82
+ name: "getCollateralRatio",
83
+ inputs: [],
84
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
85
+ stateMutability: "view"
86
+ },
87
+ {
88
+ type: "function",
89
+ name: "getCurrentFees",
90
+ inputs: [],
91
+ outputs: [
92
+ { name: "currentCR", type: "uint256", internalType: "uint256" },
93
+ { name: "tierMinCR", type: "uint256", internalType: "uint256" },
94
+ { name: "apUSDMintFee", type: "uint16", internalType: "uint16" },
95
+ { name: "apUSDRedeemFee", type: "uint16", internalType: "uint16" },
96
+ { name: "xBNBMintFee", type: "uint16", internalType: "uint16" },
97
+ { name: "xBNBRedeemFee", type: "uint16", internalType: "uint16" },
98
+ { name: "apUSDMintDisabled", type: "bool", internalType: "bool" }
99
+ ],
100
+ stateMutability: "view"
101
+ },
102
+ {
103
+ type: "function",
104
+ name: "getEffectiveLeverage",
105
+ inputs: [],
106
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
107
+ stateMutability: "view"
108
+ },
109
+ {
110
+ type: "function",
111
+ name: "getApUSDSupply",
112
+ inputs: [],
113
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
114
+ stateMutability: "view"
115
+ },
116
+ {
117
+ type: "function",
118
+ name: "getXBNBSupply",
119
+ inputs: [],
120
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
121
+ stateMutability: "view"
122
+ },
123
+ {
124
+ type: "function",
125
+ name: "getLSTCollateral",
126
+ inputs: [{ name: "_lstToken", type: "address", internalType: "address" }],
127
+ outputs: [{ name: "amount", type: "uint256", internalType: "uint256" }],
128
+ stateMutability: "view"
129
+ },
130
+ // ============ PoolFacet Events ============
131
+ {
132
+ type: "event",
133
+ name: "ApUSDMinted",
134
+ inputs: [
135
+ { name: "user", type: "address", indexed: true, internalType: "address" },
136
+ { name: "lstToken", type: "address", indexed: true, internalType: "address" },
137
+ { name: "lstAmount", type: "uint256", indexed: false, internalType: "uint256" },
138
+ { name: "apUSDAmount", type: "uint256", indexed: false, internalType: "uint256" },
139
+ { name: "feeBPS", type: "uint256", indexed: false, internalType: "uint256" }
140
+ ],
141
+ anonymous: false
142
+ },
143
+ {
144
+ type: "event",
145
+ name: "ApUSDRedeemed",
146
+ inputs: [
147
+ { name: "user", type: "address", indexed: true, internalType: "address" },
148
+ { name: "lstToken", type: "address", indexed: true, internalType: "address" },
149
+ { name: "apUSDAmount", type: "uint256", indexed: false, internalType: "uint256" },
150
+ { name: "lstAmount", type: "uint256", indexed: false, internalType: "uint256" },
151
+ { name: "feeBPS", type: "uint256", indexed: false, internalType: "uint256" }
152
+ ],
153
+ anonymous: false
154
+ },
155
+ {
156
+ type: "event",
157
+ name: "XBNBMinted",
158
+ inputs: [
159
+ { name: "user", type: "address", indexed: true, internalType: "address" },
160
+ { name: "lstToken", type: "address", indexed: true, internalType: "address" },
161
+ { name: "lstAmount", type: "uint256", indexed: false, internalType: "uint256" },
162
+ { name: "xBNBAmount", type: "uint256", indexed: false, internalType: "uint256" },
163
+ { name: "feeBPS", type: "uint256", indexed: false, internalType: "uint256" }
164
+ ],
165
+ anonymous: false
166
+ },
167
+ {
168
+ type: "event",
169
+ name: "XBNBRedeemed",
170
+ inputs: [
171
+ { name: "user", type: "address", indexed: true, internalType: "address" },
172
+ { name: "lstToken", type: "address", indexed: true, internalType: "address" },
173
+ { name: "xBNBAmount", type: "uint256", indexed: false, internalType: "uint256" },
174
+ { name: "lstAmount", type: "uint256", indexed: false, internalType: "uint256" },
175
+ { name: "feeBPS", type: "uint256", indexed: false, internalType: "uint256" }
176
+ ],
177
+ anonymous: false
178
+ },
179
+ // ============ OracleFacet ============
180
+ {
181
+ type: "function",
182
+ name: "getBNBPriceUSD",
183
+ inputs: [],
184
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
185
+ stateMutability: "view"
186
+ },
187
+ {
188
+ type: "function",
189
+ name: "getLSTPriceUSD",
190
+ inputs: [{ name: "_lstToken", type: "address", internalType: "address" }],
191
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
192
+ stateMutability: "view"
193
+ },
194
+ {
195
+ type: "function",
196
+ name: "getLSTInfo",
197
+ inputs: [{ name: "_lstToken", type: "address", internalType: "address" }],
198
+ outputs: [
199
+ { name: "isAccepted", type: "bool", internalType: "bool" },
200
+ { name: "priceFeed", type: "address", internalType: "address" },
201
+ { name: "manualPriceUSD", type: "uint256", internalType: "uint256" },
202
+ { name: "collateralAmount", type: "uint256", internalType: "uint256" },
203
+ { name: "decimals", type: "uint8", internalType: "uint8" },
204
+ { name: "exchangeRateProvider", type: "address", internalType: "address" },
205
+ { name: "useIntrinsicValue", type: "bool", internalType: "bool" }
206
+ ],
207
+ stateMutability: "view"
208
+ },
209
+ {
210
+ type: "function",
211
+ name: "getSupportedLSTs",
212
+ inputs: [],
213
+ outputs: [{ name: "", type: "address[]", internalType: "address[]" }],
214
+ stateMutability: "view"
215
+ },
216
+ {
217
+ type: "function",
218
+ name: "isLSTSupported",
219
+ inputs: [{ name: "_lstToken", type: "address", internalType: "address" }],
220
+ outputs: [{ name: "", type: "bool", internalType: "bool" }],
221
+ stateMutability: "view"
222
+ },
223
+ {
224
+ type: "function",
225
+ name: "bnbPriceFeed",
226
+ inputs: [],
227
+ outputs: [{ name: "", type: "address", internalType: "address" }],
228
+ stateMutability: "view"
229
+ },
230
+ {
231
+ type: "function",
232
+ name: "getOracleBounds",
233
+ inputs: [{ name: "_priceFeed", type: "address", internalType: "address" }],
234
+ outputs: [
235
+ { name: "minPrice", type: "uint256", internalType: "uint256" },
236
+ { name: "maxPrice", type: "uint256", internalType: "uint256" }
237
+ ],
238
+ stateMutability: "view"
239
+ },
240
+ // ============ StabilityPoolFacet ============
241
+ {
242
+ type: "function",
243
+ name: "deposit",
244
+ inputs: [{ name: "_apUSDAmount", type: "uint256", internalType: "uint256" }],
245
+ outputs: [{ name: "shares", type: "uint256", internalType: "uint256" }],
246
+ stateMutability: "nonpayable"
247
+ },
248
+ {
249
+ type: "function",
250
+ name: "withdraw",
251
+ inputs: [{ name: "_shares", type: "uint256", internalType: "uint256" }],
252
+ outputs: [{ name: "assets", type: "uint256", internalType: "uint256" }],
253
+ stateMutability: "nonpayable"
254
+ },
255
+ {
256
+ type: "function",
257
+ name: "withdrawAssets",
258
+ inputs: [{ name: "_assets", type: "uint256", internalType: "uint256" }],
259
+ outputs: [{ name: "shares", type: "uint256", internalType: "uint256" }],
260
+ stateMutability: "nonpayable"
261
+ },
262
+ {
263
+ type: "function",
264
+ name: "getShares",
265
+ inputs: [{ name: "_user", type: "address", internalType: "address" }],
266
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
267
+ stateMutability: "view"
268
+ },
269
+ {
270
+ type: "function",
271
+ name: "getBalance",
272
+ inputs: [{ name: "_user", type: "address", internalType: "address" }],
273
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
274
+ stateMutability: "view"
275
+ },
276
+ {
277
+ type: "function",
278
+ name: "getExchangeRate",
279
+ inputs: [],
280
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
281
+ stateMutability: "view"
282
+ },
283
+ {
284
+ type: "function",
285
+ name: "getTotalStaked",
286
+ inputs: [],
287
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
288
+ stateMutability: "view"
289
+ },
290
+ {
291
+ type: "function",
292
+ name: "previewDeposit",
293
+ inputs: [{ name: "_assets", type: "uint256", internalType: "uint256" }],
294
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
295
+ stateMutability: "view"
296
+ },
297
+ {
298
+ type: "function",
299
+ name: "previewRedeem",
300
+ inputs: [{ name: "_shares", type: "uint256", internalType: "uint256" }],
301
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
302
+ stateMutability: "view"
303
+ },
304
+ {
305
+ type: "function",
306
+ name: "getPendingYield",
307
+ inputs: [],
308
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
309
+ stateMutability: "view"
310
+ },
311
+ {
312
+ type: "function",
313
+ name: "harvestYield",
314
+ inputs: [],
315
+ outputs: [{ name: "yieldAmount", type: "uint256", internalType: "uint256" }],
316
+ stateMutability: "nonpayable"
317
+ },
318
+ // ============ StabilityPoolFacet Events ============
319
+ {
320
+ type: "event",
321
+ name: "Deposited",
322
+ inputs: [
323
+ { name: "user", type: "address", indexed: true, internalType: "address" },
324
+ { name: "apUSDAmount", type: "uint256", indexed: false, internalType: "uint256" },
325
+ { name: "sharesReceived", type: "uint256", indexed: false, internalType: "uint256" }
326
+ ],
327
+ anonymous: false
328
+ },
329
+ {
330
+ type: "event",
331
+ name: "Withdrawn",
332
+ inputs: [
333
+ { name: "user", type: "address", indexed: true, internalType: "address" },
334
+ { name: "sharesRedeemed", type: "uint256", indexed: false, internalType: "uint256" },
335
+ { name: "apUSDReceived", type: "uint256", indexed: false, internalType: "uint256" }
336
+ ],
337
+ anonymous: false
338
+ },
339
+ {
340
+ type: "event",
341
+ name: "YieldHarvested",
342
+ inputs: [
343
+ { name: "yieldUSD", type: "uint256", indexed: false, internalType: "uint256" }
344
+ ],
345
+ anonymous: false
346
+ },
347
+ // ============ YieldFacet ============
348
+ {
349
+ type: "function",
350
+ name: "getTotalYieldGenerated",
351
+ inputs: [],
352
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
353
+ stateMutability: "view"
354
+ },
355
+ {
356
+ type: "function",
357
+ name: "getLSTYieldInfo",
358
+ inputs: [{ name: "_lstToken", type: "address", internalType: "address" }],
359
+ outputs: [
360
+ { name: "lastExchangeRate", type: "uint256", internalType: "uint256" },
361
+ { name: "lastUpdateTimestamp", type: "uint256", internalType: "uint256" }
362
+ ],
363
+ stateMutability: "view"
364
+ },
365
+ {
366
+ type: "function",
367
+ name: "getMinHarvestInterval",
368
+ inputs: [],
369
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
370
+ stateMutability: "view"
371
+ },
372
+ {
373
+ type: "function",
374
+ name: "getLastHarvestTimestamp",
375
+ inputs: [],
376
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
377
+ stateMutability: "view"
378
+ },
379
+ {
380
+ type: "function",
381
+ name: "previewHarvest",
382
+ inputs: [],
383
+ outputs: [{ name: "totalYieldUSD", type: "uint256", internalType: "uint256" }],
384
+ stateMutability: "view"
385
+ },
386
+ // ============ ConfigFacet ============
387
+ {
388
+ type: "function",
389
+ name: "getTokens",
390
+ inputs: [],
391
+ outputs: [
392
+ { name: "apUSD", type: "address", internalType: "address" },
393
+ { name: "xBNB", type: "address", internalType: "address" }
394
+ ],
395
+ stateMutability: "view"
396
+ },
397
+ {
398
+ type: "function",
399
+ name: "getSApUSD",
400
+ inputs: [],
401
+ outputs: [{ name: "", type: "address", internalType: "address" }],
402
+ stateMutability: "view"
403
+ },
404
+ {
405
+ type: "function",
406
+ name: "getStabilityPool",
407
+ inputs: [],
408
+ outputs: [{ name: "", type: "address", internalType: "address" }],
409
+ stateMutability: "view"
410
+ },
411
+ {
412
+ type: "function",
413
+ name: "getTreasury",
414
+ inputs: [],
415
+ outputs: [{ name: "", type: "address", internalType: "address" }],
416
+ stateMutability: "view"
417
+ },
418
+ {
419
+ type: "function",
420
+ name: "getFeeTierCount",
421
+ inputs: [],
422
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
423
+ stateMutability: "view"
424
+ },
425
+ {
426
+ type: "function",
427
+ name: "getFeeTier",
428
+ inputs: [{ name: "_index", type: "uint256", internalType: "uint256" }],
429
+ outputs: [
430
+ { name: "minCR", type: "uint256", internalType: "uint256" },
431
+ { name: "apUSDMintFee", type: "uint16", internalType: "uint16" },
432
+ { name: "apUSDRedeemFee", type: "uint16", internalType: "uint16" },
433
+ { name: "xBNBMintFee", type: "uint16", internalType: "uint16" },
434
+ { name: "xBNBRedeemFee", type: "uint16", internalType: "uint16" },
435
+ { name: "apUSDMintDisabled", type: "bool", internalType: "bool" }
436
+ ],
437
+ stateMutability: "view"
438
+ },
439
+ {
440
+ type: "function",
441
+ name: "getCurrentFeeTier",
442
+ inputs: [],
443
+ outputs: [
444
+ { name: "minCR", type: "uint256", internalType: "uint256" },
445
+ { name: "apUSDMintFee", type: "uint16", internalType: "uint16" },
446
+ { name: "apUSDRedeemFee", type: "uint16", internalType: "uint16" },
447
+ { name: "xBNBMintFee", type: "uint16", internalType: "uint16" },
448
+ { name: "xBNBRedeemFee", type: "uint16", internalType: "uint16" },
449
+ { name: "apUSDMintDisabled", type: "bool", internalType: "bool" },
450
+ { name: "currentCR", type: "uint256", internalType: "uint256" }
451
+ ],
452
+ stateMutability: "view"
453
+ },
454
+ {
455
+ type: "function",
456
+ name: "getMaxPriceAge",
457
+ inputs: [],
458
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
459
+ stateMutability: "view"
460
+ },
461
+ {
462
+ type: "function",
463
+ name: "getMinDepositPeriod",
464
+ inputs: [],
465
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
466
+ stateMutability: "view"
467
+ },
468
+ {
469
+ type: "function",
470
+ name: "isPaused",
471
+ inputs: [],
472
+ outputs: [{ name: "", type: "bool", internalType: "bool" }],
473
+ stateMutability: "view"
474
+ },
475
+ // ============ StabilityModeFacet ============
476
+ {
477
+ type: "function",
478
+ name: "getStabilityMode",
479
+ inputs: [],
480
+ outputs: [
481
+ { name: "mode", type: "uint8", internalType: "uint8" },
482
+ { name: "currentCR", type: "uint256", internalType: "uint256" }
483
+ ],
484
+ stateMutability: "view"
485
+ },
486
+ {
487
+ type: "function",
488
+ name: "canTriggerStabilityMode2",
489
+ inputs: [],
490
+ outputs: [
491
+ { name: "canTrigger", type: "bool", internalType: "bool" },
492
+ { name: "currentCR", type: "uint256", internalType: "uint256" },
493
+ { name: "potentialConversion", type: "uint256", internalType: "uint256" }
494
+ ],
495
+ stateMutability: "view"
496
+ },
497
+ {
498
+ type: "function",
499
+ name: "triggerStabilityMode2",
500
+ inputs: [{ name: "_targetCR", type: "uint256", internalType: "uint256" }],
501
+ outputs: [
502
+ { name: "apUSDBurned", type: "uint256", internalType: "uint256" },
503
+ { name: "xBNBMinted", type: "uint256", internalType: "uint256" }
504
+ ],
505
+ stateMutability: "nonpayable"
506
+ },
507
+ // ============ StabilityModeFacet Events ============
508
+ {
509
+ type: "event",
510
+ name: "StabilityMode2Triggered",
511
+ inputs: [
512
+ { name: "currentCR", type: "uint256", indexed: false, internalType: "uint256" },
513
+ { name: "targetCR", type: "uint256", indexed: false, internalType: "uint256" },
514
+ { name: "apUSDBurned", type: "uint256", indexed: false, internalType: "uint256" },
515
+ { name: "xBNBMinted", type: "uint256", indexed: false, internalType: "uint256" }
516
+ ],
517
+ anonymous: false
518
+ },
519
+ // ============ OwnershipFacet ============
520
+ {
521
+ type: "function",
522
+ name: "owner",
523
+ inputs: [],
524
+ outputs: [{ name: "", type: "address", internalType: "address" }],
525
+ stateMutability: "view"
526
+ }
527
+ ];
528
+
529
+ // src/client.ts
530
+ var AspanReadClient = class _AspanReadClient {
531
+ publicClient;
532
+ diamondAddress;
533
+ chain;
534
+ // Known error signatures for zero supply states
535
+ static ZERO_SUPPLY_ERROR_SIGNATURES = [
536
+ "0x403e7fa6"
537
+ // Custom error when xBNB supply is zero
538
+ ];
539
+ constructor(config) {
540
+ this.diamondAddress = config.diamondAddress;
541
+ this.chain = config.chain ?? bsc;
542
+ this.publicClient = createPublicClient({
543
+ chain: this.chain,
544
+ transport: http(config.rpcUrl)
545
+ });
546
+ }
547
+ /**
548
+ * Check if error is a known zero supply error from the contract
549
+ */
550
+ isZeroSupplyError(error) {
551
+ if (error && typeof error === "object" && "message" in error) {
552
+ const message = error.message;
553
+ return _AspanReadClient.ZERO_SUPPLY_ERROR_SIGNATURES.some(
554
+ (sig) => message.includes(sig)
555
+ );
556
+ }
557
+ return false;
558
+ }
559
+ // ============ Protocol Stats ============
560
+ /**
561
+ * Get comprehensive protocol statistics
562
+ */
563
+ async getProtocolStats() {
564
+ const [
565
+ tvlInBNB,
566
+ tvlInUSD,
567
+ collateralRatio,
568
+ apUSDSupply,
569
+ xBNBSupply,
570
+ xBNBPriceBNB,
571
+ xBNBPriceUSD,
572
+ effectiveLeverage
573
+ ] = await Promise.all([
574
+ this.getTVLInBNB(),
575
+ this.getTVLInUSD(),
576
+ this.getCollateralRatio(),
577
+ this.getApUSDSupply(),
578
+ this.getXBNBSupply(),
579
+ this.getXBNBPriceBNB(),
580
+ this.getXBNBPriceUSD(),
581
+ this.getEffectiveLeverage()
582
+ ]);
583
+ return {
584
+ tvlInBNB,
585
+ tvlInUSD,
586
+ collateralRatio,
587
+ apUSDSupply,
588
+ xBNBSupply,
589
+ xBNBPriceBNB,
590
+ xBNBPriceUSD,
591
+ effectiveLeverage
592
+ };
593
+ }
594
+ /**
595
+ * Get stability pool statistics
596
+ */
597
+ async getStabilityPoolStats() {
598
+ const [totalStaked, exchangeRate, pendingYield] = await Promise.all([
599
+ this.getTotalStaked(),
600
+ this.getExchangeRate(),
601
+ this.getPendingYield()
602
+ ]);
603
+ return {
604
+ totalStaked,
605
+ exchangeRate,
606
+ pendingYield
607
+ };
608
+ }
609
+ /**
610
+ * Get yield statistics
611
+ */
612
+ async getYieldStats() {
613
+ const [
614
+ totalYieldGenerated,
615
+ pendingYield,
616
+ lastHarvestTimestamp,
617
+ minHarvestInterval,
618
+ previewedHarvest
619
+ ] = await Promise.all([
620
+ this.getTotalYieldGenerated(),
621
+ this.getPendingYield(),
622
+ this.getLastHarvestTimestamp(),
623
+ this.getMinHarvestInterval(),
624
+ this.previewHarvest()
625
+ ]);
626
+ return {
627
+ totalYieldGenerated,
628
+ pendingYield,
629
+ lastHarvestTimestamp,
630
+ minHarvestInterval,
631
+ previewedHarvest
632
+ };
633
+ }
634
+ // ============ Pool View Functions ============
635
+ async getTVLInBNB() {
636
+ try {
637
+ return await this.publicClient.readContract({
638
+ address: this.diamondAddress,
639
+ abi: DiamondABI,
640
+ functionName: "getTVLInBNB"
641
+ });
642
+ } catch (error) {
643
+ if (this.isZeroSupplyError(error)) {
644
+ return 0n;
645
+ }
646
+ throw error;
647
+ }
648
+ }
649
+ async getTVLInUSD() {
650
+ try {
651
+ return await this.publicClient.readContract({
652
+ address: this.diamondAddress,
653
+ abi: DiamondABI,
654
+ functionName: "getTVLInUSD"
655
+ });
656
+ } catch (error) {
657
+ if (this.isZeroSupplyError(error)) {
658
+ return 0n;
659
+ }
660
+ throw error;
661
+ }
662
+ }
663
+ async getCollateralRatio() {
664
+ try {
665
+ const cr = await this.publicClient.readContract({
666
+ address: this.diamondAddress,
667
+ abi: DiamondABI,
668
+ functionName: "getCollateralRatio"
669
+ });
670
+ if (cr > 10000n * 10n ** 18n) {
671
+ return 0n;
672
+ }
673
+ return cr;
674
+ } catch (error) {
675
+ if (this.isZeroSupplyError(error)) {
676
+ return 0n;
677
+ }
678
+ throw error;
679
+ }
680
+ }
681
+ async getXBNBPriceBNB() {
682
+ try {
683
+ return await this.publicClient.readContract({
684
+ address: this.diamondAddress,
685
+ abi: DiamondABI,
686
+ functionName: "getXBNBPriceBNB"
687
+ });
688
+ } catch (error) {
689
+ if (this.isZeroSupplyError(error)) {
690
+ return 0n;
691
+ }
692
+ throw error;
693
+ }
694
+ }
695
+ async getXBNBPriceUSD() {
696
+ try {
697
+ return await this.publicClient.readContract({
698
+ address: this.diamondAddress,
699
+ abi: DiamondABI,
700
+ functionName: "getXBNBPriceUSD"
701
+ });
702
+ } catch (error) {
703
+ if (this.isZeroSupplyError(error)) {
704
+ return 0n;
705
+ }
706
+ throw error;
707
+ }
708
+ }
709
+ async getEffectiveLeverage() {
710
+ try {
711
+ return await this.publicClient.readContract({
712
+ address: this.diamondAddress,
713
+ abi: DiamondABI,
714
+ functionName: "getEffectiveLeverage"
715
+ });
716
+ } catch (error) {
717
+ if (this.isZeroSupplyError(error)) {
718
+ return 0n;
719
+ }
720
+ throw error;
721
+ }
722
+ }
723
+ async getApUSDSupply() {
724
+ try {
725
+ return await this.publicClient.readContract({
726
+ address: this.diamondAddress,
727
+ abi: DiamondABI,
728
+ functionName: "getApUSDSupply"
729
+ });
730
+ } catch (error) {
731
+ if (this.isZeroSupplyError(error)) {
732
+ return 0n;
733
+ }
734
+ throw error;
735
+ }
736
+ }
737
+ async getXBNBSupply() {
738
+ try {
739
+ return await this.publicClient.readContract({
740
+ address: this.diamondAddress,
741
+ abi: DiamondABI,
742
+ functionName: "getXBNBSupply"
743
+ });
744
+ } catch (error) {
745
+ if (this.isZeroSupplyError(error)) {
746
+ return 0n;
747
+ }
748
+ throw error;
749
+ }
750
+ }
751
+ async getLSTCollateral(lstToken) {
752
+ try {
753
+ return await this.publicClient.readContract({
754
+ address: this.diamondAddress,
755
+ abi: DiamondABI,
756
+ functionName: "getLSTCollateral",
757
+ args: [lstToken]
758
+ });
759
+ } catch (error) {
760
+ if (this.isZeroSupplyError(error)) {
761
+ return 0n;
762
+ }
763
+ throw error;
764
+ }
765
+ }
766
+ async getCurrentFees() {
767
+ try {
768
+ const result = await this.publicClient.readContract({
769
+ address: this.diamondAddress,
770
+ abi: DiamondABI,
771
+ functionName: "getCurrentFees"
772
+ });
773
+ return {
774
+ currentCR: result[0],
775
+ tierMinCR: result[1],
776
+ apUSDMintFee: result[2],
777
+ apUSDRedeemFee: result[3],
778
+ xBNBMintFee: result[4],
779
+ xBNBRedeemFee: result[5],
780
+ apUSDMintDisabled: result[6]
781
+ };
782
+ } catch (error) {
783
+ if (this.isZeroSupplyError(error)) {
784
+ return {
785
+ currentCR: 0n,
786
+ tierMinCR: 0n,
787
+ apUSDMintFee: 0,
788
+ apUSDRedeemFee: 0,
789
+ xBNBMintFee: 0,
790
+ xBNBRedeemFee: 0,
791
+ apUSDMintDisabled: false
792
+ };
793
+ }
794
+ throw error;
795
+ }
796
+ }
797
+ // ============ Oracle View Functions ============
798
+ async getBNBPriceUSD() {
799
+ return this.publicClient.readContract({
800
+ address: this.diamondAddress,
801
+ abi: DiamondABI,
802
+ functionName: "getBNBPriceUSD"
803
+ });
804
+ }
805
+ async getLSTPriceUSD(lstToken) {
806
+ return this.publicClient.readContract({
807
+ address: this.diamondAddress,
808
+ abi: DiamondABI,
809
+ functionName: "getLSTPriceUSD",
810
+ args: [lstToken]
811
+ });
812
+ }
813
+ async getLSTInfo(lstToken) {
814
+ const result = await this.publicClient.readContract({
815
+ address: this.diamondAddress,
816
+ abi: DiamondABI,
817
+ functionName: "getLSTInfo",
818
+ args: [lstToken]
819
+ });
820
+ return {
821
+ isAccepted: result[0],
822
+ priceFeed: result[1],
823
+ manualPriceUSD: result[2],
824
+ collateralAmount: result[3],
825
+ decimals: result[4],
826
+ exchangeRateProvider: result[5],
827
+ useIntrinsicValue: result[6]
828
+ };
829
+ }
830
+ async getSupportedLSTs() {
831
+ return this.publicClient.readContract({
832
+ address: this.diamondAddress,
833
+ abi: DiamondABI,
834
+ functionName: "getSupportedLSTs"
835
+ });
836
+ }
837
+ async isLSTSupported(lstToken) {
838
+ return this.publicClient.readContract({
839
+ address: this.diamondAddress,
840
+ abi: DiamondABI,
841
+ functionName: "isLSTSupported",
842
+ args: [lstToken]
843
+ });
844
+ }
845
+ async getBNBPriceFeed() {
846
+ return this.publicClient.readContract({
847
+ address: this.diamondAddress,
848
+ abi: DiamondABI,
849
+ functionName: "bnbPriceFeed"
850
+ });
851
+ }
852
+ async getOracleBounds(priceFeed) {
853
+ const result = await this.publicClient.readContract({
854
+ address: this.diamondAddress,
855
+ abi: DiamondABI,
856
+ functionName: "getOracleBounds",
857
+ args: [priceFeed]
858
+ });
859
+ return {
860
+ minPrice: result[0],
861
+ maxPrice: result[1]
862
+ };
863
+ }
864
+ // ============ Stability Pool View Functions ============
865
+ async getShares(user) {
866
+ return this.publicClient.readContract({
867
+ address: this.diamondAddress,
868
+ abi: DiamondABI,
869
+ functionName: "getShares",
870
+ args: [user]
871
+ });
872
+ }
873
+ async getBalance(user) {
874
+ return this.publicClient.readContract({
875
+ address: this.diamondAddress,
876
+ abi: DiamondABI,
877
+ functionName: "getBalance",
878
+ args: [user]
879
+ });
880
+ }
881
+ async getUserStabilityPoolPosition(user) {
882
+ const [shares, balance] = await Promise.all([
883
+ this.getShares(user),
884
+ this.getBalance(user)
885
+ ]);
886
+ return { shares, balance };
887
+ }
888
+ async getExchangeRate() {
889
+ try {
890
+ return await this.publicClient.readContract({
891
+ address: this.diamondAddress,
892
+ abi: DiamondABI,
893
+ functionName: "getExchangeRate"
894
+ });
895
+ } catch (error) {
896
+ if (this.isZeroSupplyError(error)) {
897
+ return 10n ** 18n;
898
+ }
899
+ throw error;
900
+ }
901
+ }
902
+ async getTotalStaked() {
903
+ try {
904
+ return await this.publicClient.readContract({
905
+ address: this.diamondAddress,
906
+ abi: DiamondABI,
907
+ functionName: "getTotalStaked"
908
+ });
909
+ } catch (error) {
910
+ if (this.isZeroSupplyError(error)) {
911
+ return 0n;
912
+ }
913
+ throw error;
914
+ }
915
+ }
916
+ async previewDeposit(assets) {
917
+ try {
918
+ return await this.publicClient.readContract({
919
+ address: this.diamondAddress,
920
+ abi: DiamondABI,
921
+ functionName: "previewDeposit",
922
+ args: [assets]
923
+ });
924
+ } catch (error) {
925
+ if (this.isZeroSupplyError(error)) {
926
+ return assets;
927
+ }
928
+ throw error;
929
+ }
930
+ }
931
+ async previewRedeem(shares) {
932
+ try {
933
+ return await this.publicClient.readContract({
934
+ address: this.diamondAddress,
935
+ abi: DiamondABI,
936
+ functionName: "previewRedeem",
937
+ args: [shares]
938
+ });
939
+ } catch (error) {
940
+ if (this.isZeroSupplyError(error)) {
941
+ return shares;
942
+ }
943
+ throw error;
944
+ }
945
+ }
946
+ async getPendingYield() {
947
+ try {
948
+ return await this.publicClient.readContract({
949
+ address: this.diamondAddress,
950
+ abi: DiamondABI,
951
+ functionName: "getPendingYield"
952
+ });
953
+ } catch (error) {
954
+ if (this.isZeroSupplyError(error)) {
955
+ return 0n;
956
+ }
957
+ throw error;
958
+ }
959
+ }
960
+ // ============ Yield View Functions ============
961
+ async getTotalYieldGenerated() {
962
+ try {
963
+ return await this.publicClient.readContract({
964
+ address: this.diamondAddress,
965
+ abi: DiamondABI,
966
+ functionName: "getTotalYieldGenerated"
967
+ });
968
+ } catch (error) {
969
+ if (this.isZeroSupplyError(error)) {
970
+ return 0n;
971
+ }
972
+ throw error;
973
+ }
974
+ }
975
+ async getLSTYieldInfo(lstToken) {
976
+ try {
977
+ const result = await this.publicClient.readContract({
978
+ address: this.diamondAddress,
979
+ abi: DiamondABI,
980
+ functionName: "getLSTYieldInfo",
981
+ args: [lstToken]
982
+ });
983
+ return {
984
+ lastExchangeRate: result[0],
985
+ lastUpdateTimestamp: result[1]
986
+ };
987
+ } catch (error) {
988
+ if (this.isZeroSupplyError(error)) {
989
+ return {
990
+ lastExchangeRate: 0n,
991
+ lastUpdateTimestamp: 0n
992
+ };
993
+ }
994
+ throw error;
995
+ }
996
+ }
997
+ async getMinHarvestInterval() {
998
+ try {
999
+ return await this.publicClient.readContract({
1000
+ address: this.diamondAddress,
1001
+ abi: DiamondABI,
1002
+ functionName: "getMinHarvestInterval"
1003
+ });
1004
+ } catch (error) {
1005
+ if (this.isZeroSupplyError(error)) {
1006
+ return 0n;
1007
+ }
1008
+ throw error;
1009
+ }
1010
+ }
1011
+ async getLastHarvestTimestamp() {
1012
+ try {
1013
+ return await this.publicClient.readContract({
1014
+ address: this.diamondAddress,
1015
+ abi: DiamondABI,
1016
+ functionName: "getLastHarvestTimestamp"
1017
+ });
1018
+ } catch (error) {
1019
+ if (this.isZeroSupplyError(error)) {
1020
+ return 0n;
1021
+ }
1022
+ throw error;
1023
+ }
1024
+ }
1025
+ async previewHarvest() {
1026
+ try {
1027
+ return await this.publicClient.readContract({
1028
+ address: this.diamondAddress,
1029
+ abi: DiamondABI,
1030
+ functionName: "previewHarvest"
1031
+ });
1032
+ } catch (error) {
1033
+ if (this.isZeroSupplyError(error)) {
1034
+ return 0n;
1035
+ }
1036
+ throw error;
1037
+ }
1038
+ }
1039
+ // ============ Config View Functions ============
1040
+ async getTokens() {
1041
+ const [tokens, sApUSD] = await Promise.all([
1042
+ this.publicClient.readContract({
1043
+ address: this.diamondAddress,
1044
+ abi: DiamondABI,
1045
+ functionName: "getTokens"
1046
+ }),
1047
+ this.getSApUSD()
1048
+ ]);
1049
+ return {
1050
+ apUSD: tokens[0],
1051
+ xBNB: tokens[1],
1052
+ sApUSD
1053
+ };
1054
+ }
1055
+ async getSApUSD() {
1056
+ return this.publicClient.readContract({
1057
+ address: this.diamondAddress,
1058
+ abi: DiamondABI,
1059
+ functionName: "getSApUSD"
1060
+ });
1061
+ }
1062
+ async getStabilityPool() {
1063
+ return this.publicClient.readContract({
1064
+ address: this.diamondAddress,
1065
+ abi: DiamondABI,
1066
+ functionName: "getStabilityPool"
1067
+ });
1068
+ }
1069
+ async getTreasury() {
1070
+ return this.publicClient.readContract({
1071
+ address: this.diamondAddress,
1072
+ abi: DiamondABI,
1073
+ functionName: "getTreasury"
1074
+ });
1075
+ }
1076
+ async getFeeTierCount() {
1077
+ return this.publicClient.readContract({
1078
+ address: this.diamondAddress,
1079
+ abi: DiamondABI,
1080
+ functionName: "getFeeTierCount"
1081
+ });
1082
+ }
1083
+ async getFeeTier(index) {
1084
+ const result = await this.publicClient.readContract({
1085
+ address: this.diamondAddress,
1086
+ abi: DiamondABI,
1087
+ functionName: "getFeeTier",
1088
+ args: [index]
1089
+ });
1090
+ return {
1091
+ minCR: result[0],
1092
+ apUSDMintFee: result[1],
1093
+ apUSDRedeemFee: result[2],
1094
+ xBNBMintFee: result[3],
1095
+ xBNBRedeemFee: result[4],
1096
+ apUSDMintDisabled: result[5]
1097
+ };
1098
+ }
1099
+ async getCurrentFeeTier() {
1100
+ try {
1101
+ const result = await this.publicClient.readContract({
1102
+ address: this.diamondAddress,
1103
+ abi: DiamondABI,
1104
+ functionName: "getCurrentFeeTier"
1105
+ });
1106
+ return {
1107
+ minCR: result[0],
1108
+ apUSDMintFee: result[1],
1109
+ apUSDRedeemFee: result[2],
1110
+ xBNBMintFee: result[3],
1111
+ xBNBRedeemFee: result[4],
1112
+ apUSDMintDisabled: result[5],
1113
+ currentCR: result[6]
1114
+ };
1115
+ } catch (error) {
1116
+ if (this.isZeroSupplyError(error)) {
1117
+ return {
1118
+ minCR: 0n,
1119
+ apUSDMintFee: 0,
1120
+ apUSDRedeemFee: 0,
1121
+ xBNBMintFee: 0,
1122
+ xBNBRedeemFee: 0,
1123
+ apUSDMintDisabled: false,
1124
+ currentCR: 0n
1125
+ };
1126
+ }
1127
+ throw error;
1128
+ }
1129
+ }
1130
+ async getMaxPriceAge() {
1131
+ return this.publicClient.readContract({
1132
+ address: this.diamondAddress,
1133
+ abi: DiamondABI,
1134
+ functionName: "getMaxPriceAge"
1135
+ });
1136
+ }
1137
+ async getMinDepositPeriod() {
1138
+ return this.publicClient.readContract({
1139
+ address: this.diamondAddress,
1140
+ abi: DiamondABI,
1141
+ functionName: "getMinDepositPeriod"
1142
+ });
1143
+ }
1144
+ async isPaused() {
1145
+ return this.publicClient.readContract({
1146
+ address: this.diamondAddress,
1147
+ abi: DiamondABI,
1148
+ functionName: "isPaused"
1149
+ });
1150
+ }
1151
+ // ============ Stability Mode View Functions ============
1152
+ async getStabilityMode() {
1153
+ try {
1154
+ const result = await this.publicClient.readContract({
1155
+ address: this.diamondAddress,
1156
+ abi: DiamondABI,
1157
+ functionName: "getStabilityMode"
1158
+ });
1159
+ return {
1160
+ mode: result[0],
1161
+ currentCR: result[1]
1162
+ };
1163
+ } catch (error) {
1164
+ if (this.isZeroSupplyError(error)) {
1165
+ return {
1166
+ mode: 0,
1167
+ // Normal mode
1168
+ currentCR: 0n
1169
+ };
1170
+ }
1171
+ throw error;
1172
+ }
1173
+ }
1174
+ async canTriggerStabilityMode2() {
1175
+ try {
1176
+ const result = await this.publicClient.readContract({
1177
+ address: this.diamondAddress,
1178
+ abi: DiamondABI,
1179
+ functionName: "canTriggerStabilityMode2"
1180
+ });
1181
+ return {
1182
+ canTrigger: result[0],
1183
+ currentCR: result[1],
1184
+ potentialConversion: result[2]
1185
+ };
1186
+ } catch (error) {
1187
+ if (this.isZeroSupplyError(error)) {
1188
+ return {
1189
+ canTrigger: false,
1190
+ currentCR: 0n,
1191
+ potentialConversion: 0n
1192
+ };
1193
+ }
1194
+ throw error;
1195
+ }
1196
+ }
1197
+ // ============ Ownership View Functions ============
1198
+ async getOwner() {
1199
+ return this.publicClient.readContract({
1200
+ address: this.diamondAddress,
1201
+ abi: DiamondABI,
1202
+ functionName: "owner"
1203
+ });
1204
+ }
1205
+ };
1206
+ var AspanClient = class extends AspanReadClient {
1207
+ walletClient;
1208
+ constructor(config) {
1209
+ super(config);
1210
+ this.walletClient = createWalletClient({
1211
+ account: config.account,
1212
+ chain: this.chain,
1213
+ transport: http(config.rpcUrl)
1214
+ });
1215
+ }
1216
+ // ============ Pool Write Functions ============
1217
+ /**
1218
+ * Mint apUSD by depositing LST
1219
+ * @param params Mint parameters
1220
+ * @returns Transaction hash
1221
+ */
1222
+ async mintApUSD(params) {
1223
+ return this.walletClient.writeContract({
1224
+ address: this.diamondAddress,
1225
+ abi: DiamondABI,
1226
+ functionName: "mintApUSD",
1227
+ args: [params.lstToken, params.lstAmount]
1228
+ });
1229
+ }
1230
+ /**
1231
+ * Redeem apUSD for LST
1232
+ * @param params Redeem parameters
1233
+ * @returns Transaction hash
1234
+ */
1235
+ async redeemApUSD(params) {
1236
+ return this.walletClient.writeContract({
1237
+ address: this.diamondAddress,
1238
+ abi: DiamondABI,
1239
+ functionName: "redeemApUSD",
1240
+ args: [params.lstToken, params.apUSDAmount]
1241
+ });
1242
+ }
1243
+ /**
1244
+ * Mint xBNB by depositing LST
1245
+ * @param params Mint parameters
1246
+ * @returns Transaction hash
1247
+ */
1248
+ async mintXBNB(params) {
1249
+ return this.walletClient.writeContract({
1250
+ address: this.diamondAddress,
1251
+ abi: DiamondABI,
1252
+ functionName: "mintXBNB",
1253
+ args: [params.lstToken, params.lstAmount]
1254
+ });
1255
+ }
1256
+ /**
1257
+ * Redeem xBNB for LST
1258
+ * @param params Redeem parameters
1259
+ * @returns Transaction hash
1260
+ */
1261
+ async redeemXBNB(params) {
1262
+ return this.walletClient.writeContract({
1263
+ address: this.diamondAddress,
1264
+ abi: DiamondABI,
1265
+ functionName: "redeemXBNB",
1266
+ args: [params.lstToken, params.xBNBAmount]
1267
+ });
1268
+ }
1269
+ // ============ Stability Pool Write Functions ============
1270
+ /**
1271
+ * Deposit apUSD to stability pool to earn yield
1272
+ * @param params Deposit parameters
1273
+ * @returns Transaction hash
1274
+ */
1275
+ async deposit(params) {
1276
+ return this.walletClient.writeContract({
1277
+ address: this.diamondAddress,
1278
+ abi: DiamondABI,
1279
+ functionName: "deposit",
1280
+ args: [params.apUSDAmount]
1281
+ });
1282
+ }
1283
+ /**
1284
+ * Withdraw from stability pool by shares
1285
+ * @param params Withdraw parameters
1286
+ * @returns Transaction hash
1287
+ */
1288
+ async withdraw(params) {
1289
+ return this.walletClient.writeContract({
1290
+ address: this.diamondAddress,
1291
+ abi: DiamondABI,
1292
+ functionName: "withdraw",
1293
+ args: [params.shares]
1294
+ });
1295
+ }
1296
+ /**
1297
+ * Withdraw from stability pool by asset amount
1298
+ * @param params Withdraw parameters
1299
+ * @returns Transaction hash
1300
+ */
1301
+ async withdrawAssets(params) {
1302
+ return this.walletClient.writeContract({
1303
+ address: this.diamondAddress,
1304
+ abi: DiamondABI,
1305
+ functionName: "withdrawAssets",
1306
+ args: [params.assets]
1307
+ });
1308
+ }
1309
+ /**
1310
+ * Harvest yield from LSTs
1311
+ * @returns Transaction hash
1312
+ */
1313
+ async harvestYield() {
1314
+ return this.walletClient.writeContract({
1315
+ address: this.diamondAddress,
1316
+ abi: DiamondABI,
1317
+ functionName: "harvestYield"
1318
+ });
1319
+ }
1320
+ // ============ Transaction Helpers ============
1321
+ /**
1322
+ * Wait for transaction confirmation
1323
+ * @param hash Transaction hash
1324
+ * @returns Transaction receipt
1325
+ */
1326
+ async waitForTransaction(hash) {
1327
+ return this.publicClient.waitForTransactionReceipt({ hash });
1328
+ }
1329
+ };
1330
+ function createAspanReadClient(diamondAddress, rpcUrl) {
1331
+ return new AspanReadClient({
1332
+ diamondAddress,
1333
+ chain: bsc,
1334
+ rpcUrl
1335
+ });
1336
+ }
1337
+ function createAspanClient(diamondAddress, account, rpcUrl) {
1338
+ return new AspanClient({
1339
+ diamondAddress,
1340
+ account,
1341
+ chain: bsc,
1342
+ rpcUrl
1343
+ });
1344
+ }
1345
+ function createAspanTestnetReadClient(diamondAddress, rpcUrl) {
1346
+ return new AspanReadClient({
1347
+ diamondAddress,
1348
+ chain: bscTestnet,
1349
+ rpcUrl
1350
+ });
1351
+ }
1352
+ function createAspanTestnetClient(diamondAddress, account, rpcUrl) {
1353
+ return new AspanClient({
1354
+ diamondAddress,
1355
+ account,
1356
+ chain: bscTestnet,
1357
+ rpcUrl
1358
+ });
1359
+ }
1360
+
1361
+ // src/index.ts
1362
+ var PRECISION = 10n ** 18n;
1363
+ var BPS_PRECISION = 10000n;
1364
+ var PRICE_PRECISION = 10n ** 8n;
1365
+ function formatAmount(amount, decimals = 4) {
1366
+ const divisor = 10n ** BigInt(18 - decimals);
1367
+ const scaled = amount / divisor;
1368
+ const intPart = scaled / 10n ** BigInt(decimals);
1369
+ const fracPart = scaled % 10n ** BigInt(decimals);
1370
+ return `${intPart}.${fracPart.toString().padStart(decimals, "0")}`;
1371
+ }
1372
+ function parseAmount(amount) {
1373
+ const [intPart, fracPart = ""] = amount.split(".");
1374
+ const paddedFrac = fracPart.padEnd(18, "0").slice(0, 18);
1375
+ return BigInt(intPart) * PRECISION + BigInt(paddedFrac);
1376
+ }
1377
+ function formatFeeBPS(bps) {
1378
+ return `${(bps / 100).toFixed(2)}%`;
1379
+ }
1380
+ function formatCR(cr) {
1381
+ const percentage = cr * 100n / PRECISION;
1382
+ return `${percentage}%`;
1383
+ }
1384
+ function formatPriceUSD(price) {
1385
+ const dollars = price / PRICE_PRECISION;
1386
+ const cents = price % PRICE_PRECISION / 10n ** 6n;
1387
+ return `$${dollars}.${cents.toString().padStart(2, "0")}`;
1388
+ }
1389
+ function calculateAPY(previousRate, currentRate, periodDays) {
1390
+ if (previousRate === 0n || periodDays === 0) return 0;
1391
+ const rateChange = Number((currentRate - previousRate) * 10000n) / Number(previousRate);
1392
+ const dailyRate = rateChange / periodDays;
1393
+ const annualizedRate = dailyRate * 365;
1394
+ return annualizedRate / 100;
1395
+ }
1396
+ export {
1397
+ AspanClient,
1398
+ AspanReadClient,
1399
+ BPS_PRECISION,
1400
+ DiamondABI,
1401
+ PRECISION,
1402
+ PRICE_PRECISION,
1403
+ calculateAPY,
1404
+ createAspanClient,
1405
+ createAspanReadClient,
1406
+ createAspanTestnetClient,
1407
+ createAspanTestnetReadClient,
1408
+ formatAmount,
1409
+ formatCR,
1410
+ formatFeeBPS,
1411
+ formatPriceUSD,
1412
+ parseAmount
1413
+ };