@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/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@aspan/sdk",
3
+ "version": "0.1.4",
4
+ "description": "TypeScript SDK for Aspan Protocol - LST-backed stablecoin on BNB Chain",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "src"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup src/index.ts --format cjs,esm --dts",
21
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
22
+ "lint": "eslint src --ext .ts",
23
+ "typecheck": "tsc --noEmit",
24
+ "test": "vitest run",
25
+ "test:watch": "vitest",
26
+ "clean": "rm -rf dist",
27
+ "prepublishOnly": "npm run build",
28
+ "bot": "tsx src/bot/index.ts",
29
+ "bot:dev": "tsx watch src/bot/index.ts"
30
+ },
31
+ "keywords": [
32
+ "aspan",
33
+ "defi",
34
+ "stablecoin",
35
+ "lst",
36
+ "bnb",
37
+ "ethereum",
38
+ "web3",
39
+ "sdk"
40
+ ],
41
+ "author": "",
42
+ "license": "MIT",
43
+ "dependencies": {
44
+ "viem": "^2.21.0"
45
+ },
46
+ "devDependencies": {
47
+ "@types/node": "^20.10.0",
48
+ "tsup": "^8.0.1",
49
+ "typescript": "^5.3.0",
50
+ "vitest": "^1.0.0",
51
+ "eslint": "^8.55.0",
52
+ "@typescript-eslint/eslint-plugin": "^6.13.0",
53
+ "@typescript-eslint/parser": "^6.13.0",
54
+ "tsx": "^4.7.0",
55
+ "dotenv": "^16.3.1"
56
+ },
57
+ "peerDependencies": {
58
+ "viem": ">=2.0.0"
59
+ },
60
+ "engines": {
61
+ "node": ">=18.0.0"
62
+ }
63
+ }
@@ -0,0 +1,531 @@
1
+ /**
2
+ * Combined Diamond ABI - includes all facet functions
3
+ * This ABI is used to interact with the Aspan Diamond contract
4
+ */
5
+ export const DiamondABI = [
6
+ // ============ PoolFacet ============
7
+ {
8
+ type: "function",
9
+ name: "mintApUSD",
10
+ inputs: [
11
+ { name: "_lstToken", type: "address", internalType: "address" },
12
+ { name: "_lstAmount", type: "uint256", internalType: "uint256" }
13
+ ],
14
+ outputs: [{ name: "apUSDAmount", type: "uint256", internalType: "uint256" }],
15
+ stateMutability: "nonpayable"
16
+ },
17
+ {
18
+ type: "function",
19
+ name: "redeemApUSD",
20
+ inputs: [
21
+ { name: "_lstToken", type: "address", internalType: "address" },
22
+ { name: "_apUSDAmount", type: "uint256", internalType: "uint256" }
23
+ ],
24
+ outputs: [{ name: "lstAmount", type: "uint256", internalType: "uint256" }],
25
+ stateMutability: "nonpayable"
26
+ },
27
+ {
28
+ type: "function",
29
+ name: "mintXBNB",
30
+ inputs: [
31
+ { name: "_lstToken", type: "address", internalType: "address" },
32
+ { name: "_lstAmount", type: "uint256", internalType: "uint256" }
33
+ ],
34
+ outputs: [{ name: "xBNBAmount", type: "uint256", internalType: "uint256" }],
35
+ stateMutability: "nonpayable"
36
+ },
37
+ {
38
+ type: "function",
39
+ name: "redeemXBNB",
40
+ inputs: [
41
+ { name: "_lstToken", type: "address", internalType: "address" },
42
+ { name: "_xBNBAmount", type: "uint256", internalType: "uint256" }
43
+ ],
44
+ outputs: [{ name: "lstAmount", type: "uint256", internalType: "uint256" }],
45
+ stateMutability: "nonpayable"
46
+ },
47
+ {
48
+ type: "function",
49
+ name: "getXBNBPriceBNB",
50
+ inputs: [],
51
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
52
+ stateMutability: "view"
53
+ },
54
+ {
55
+ type: "function",
56
+ name: "getXBNBPriceUSD",
57
+ inputs: [],
58
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
59
+ stateMutability: "view"
60
+ },
61
+ {
62
+ type: "function",
63
+ name: "getTVLInBNB",
64
+ inputs: [],
65
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
66
+ stateMutability: "view"
67
+ },
68
+ {
69
+ type: "function",
70
+ name: "getTVLInUSD",
71
+ inputs: [],
72
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
73
+ stateMutability: "view"
74
+ },
75
+ {
76
+ type: "function",
77
+ name: "getCollateralRatio",
78
+ inputs: [],
79
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
80
+ stateMutability: "view"
81
+ },
82
+ {
83
+ type: "function",
84
+ name: "getCurrentFees",
85
+ inputs: [],
86
+ outputs: [
87
+ { name: "currentCR", type: "uint256", internalType: "uint256" },
88
+ { name: "tierMinCR", type: "uint256", internalType: "uint256" },
89
+ { name: "apUSDMintFee", type: "uint16", internalType: "uint16" },
90
+ { name: "apUSDRedeemFee", type: "uint16", internalType: "uint16" },
91
+ { name: "xBNBMintFee", type: "uint16", internalType: "uint16" },
92
+ { name: "xBNBRedeemFee", type: "uint16", internalType: "uint16" },
93
+ { name: "apUSDMintDisabled", type: "bool", internalType: "bool" }
94
+ ],
95
+ stateMutability: "view"
96
+ },
97
+ {
98
+ type: "function",
99
+ name: "getEffectiveLeverage",
100
+ inputs: [],
101
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
102
+ stateMutability: "view"
103
+ },
104
+ {
105
+ type: "function",
106
+ name: "getApUSDSupply",
107
+ inputs: [],
108
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
109
+ stateMutability: "view"
110
+ },
111
+ {
112
+ type: "function",
113
+ name: "getXBNBSupply",
114
+ inputs: [],
115
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
116
+ stateMutability: "view"
117
+ },
118
+ {
119
+ type: "function",
120
+ name: "getLSTCollateral",
121
+ inputs: [{ name: "_lstToken", type: "address", internalType: "address" }],
122
+ outputs: [{ name: "amount", type: "uint256", internalType: "uint256" }],
123
+ stateMutability: "view"
124
+ },
125
+
126
+ // ============ PoolFacet Events ============
127
+ {
128
+ type: "event",
129
+ name: "ApUSDMinted",
130
+ inputs: [
131
+ { name: "user", type: "address", indexed: true, internalType: "address" },
132
+ { name: "lstToken", type: "address", indexed: true, internalType: "address" },
133
+ { name: "lstAmount", type: "uint256", indexed: false, internalType: "uint256" },
134
+ { name: "apUSDAmount", type: "uint256", indexed: false, internalType: "uint256" },
135
+ { name: "feeBPS", type: "uint256", indexed: false, internalType: "uint256" }
136
+ ],
137
+ anonymous: false
138
+ },
139
+ {
140
+ type: "event",
141
+ name: "ApUSDRedeemed",
142
+ inputs: [
143
+ { name: "user", type: "address", indexed: true, internalType: "address" },
144
+ { name: "lstToken", type: "address", indexed: true, internalType: "address" },
145
+ { name: "apUSDAmount", type: "uint256", indexed: false, internalType: "uint256" },
146
+ { name: "lstAmount", type: "uint256", indexed: false, internalType: "uint256" },
147
+ { name: "feeBPS", type: "uint256", indexed: false, internalType: "uint256" }
148
+ ],
149
+ anonymous: false
150
+ },
151
+ {
152
+ type: "event",
153
+ name: "XBNBMinted",
154
+ inputs: [
155
+ { name: "user", type: "address", indexed: true, internalType: "address" },
156
+ { name: "lstToken", type: "address", indexed: true, internalType: "address" },
157
+ { name: "lstAmount", type: "uint256", indexed: false, internalType: "uint256" },
158
+ { name: "xBNBAmount", type: "uint256", indexed: false, internalType: "uint256" },
159
+ { name: "feeBPS", type: "uint256", indexed: false, internalType: "uint256" }
160
+ ],
161
+ anonymous: false
162
+ },
163
+ {
164
+ type: "event",
165
+ name: "XBNBRedeemed",
166
+ inputs: [
167
+ { name: "user", type: "address", indexed: true, internalType: "address" },
168
+ { name: "lstToken", type: "address", indexed: true, internalType: "address" },
169
+ { name: "xBNBAmount", type: "uint256", indexed: false, internalType: "uint256" },
170
+ { name: "lstAmount", type: "uint256", indexed: false, internalType: "uint256" },
171
+ { name: "feeBPS", type: "uint256", indexed: false, internalType: "uint256" }
172
+ ],
173
+ anonymous: false
174
+ },
175
+
176
+ // ============ OracleFacet ============
177
+ {
178
+ type: "function",
179
+ name: "getBNBPriceUSD",
180
+ inputs: [],
181
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
182
+ stateMutability: "view"
183
+ },
184
+ {
185
+ type: "function",
186
+ name: "getLSTPriceUSD",
187
+ inputs: [{ name: "_lstToken", type: "address", internalType: "address" }],
188
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
189
+ stateMutability: "view"
190
+ },
191
+ {
192
+ type: "function",
193
+ name: "getLSTInfo",
194
+ inputs: [{ name: "_lstToken", type: "address", internalType: "address" }],
195
+ outputs: [
196
+ { name: "isAccepted", type: "bool", internalType: "bool" },
197
+ { name: "priceFeed", type: "address", internalType: "address" },
198
+ { name: "manualPriceUSD", type: "uint256", internalType: "uint256" },
199
+ { name: "collateralAmount", type: "uint256", internalType: "uint256" },
200
+ { name: "decimals", type: "uint8", internalType: "uint8" },
201
+ { name: "exchangeRateProvider", type: "address", internalType: "address" },
202
+ { name: "useIntrinsicValue", type: "bool", internalType: "bool" }
203
+ ],
204
+ stateMutability: "view"
205
+ },
206
+ {
207
+ type: "function",
208
+ name: "getSupportedLSTs",
209
+ inputs: [],
210
+ outputs: [{ name: "", type: "address[]", internalType: "address[]" }],
211
+ stateMutability: "view"
212
+ },
213
+ {
214
+ type: "function",
215
+ name: "isLSTSupported",
216
+ inputs: [{ name: "_lstToken", type: "address", internalType: "address" }],
217
+ outputs: [{ name: "", type: "bool", internalType: "bool" }],
218
+ stateMutability: "view"
219
+ },
220
+ {
221
+ type: "function",
222
+ name: "bnbPriceFeed",
223
+ inputs: [],
224
+ outputs: [{ name: "", type: "address", internalType: "address" }],
225
+ stateMutability: "view"
226
+ },
227
+ {
228
+ type: "function",
229
+ name: "getOracleBounds",
230
+ inputs: [{ name: "_priceFeed", type: "address", internalType: "address" }],
231
+ outputs: [
232
+ { name: "minPrice", type: "uint256", internalType: "uint256" },
233
+ { name: "maxPrice", type: "uint256", internalType: "uint256" }
234
+ ],
235
+ stateMutability: "view"
236
+ },
237
+
238
+ // ============ StabilityPoolFacet ============
239
+ {
240
+ type: "function",
241
+ name: "deposit",
242
+ inputs: [{ name: "_apUSDAmount", type: "uint256", internalType: "uint256" }],
243
+ outputs: [{ name: "shares", type: "uint256", internalType: "uint256" }],
244
+ stateMutability: "nonpayable"
245
+ },
246
+ {
247
+ type: "function",
248
+ name: "withdraw",
249
+ inputs: [{ name: "_shares", type: "uint256", internalType: "uint256" }],
250
+ outputs: [{ name: "assets", type: "uint256", internalType: "uint256" }],
251
+ stateMutability: "nonpayable"
252
+ },
253
+ {
254
+ type: "function",
255
+ name: "withdrawAssets",
256
+ inputs: [{ name: "_assets", type: "uint256", internalType: "uint256" }],
257
+ outputs: [{ name: "shares", type: "uint256", internalType: "uint256" }],
258
+ stateMutability: "nonpayable"
259
+ },
260
+ {
261
+ type: "function",
262
+ name: "getShares",
263
+ inputs: [{ name: "_user", type: "address", internalType: "address" }],
264
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
265
+ stateMutability: "view"
266
+ },
267
+ {
268
+ type: "function",
269
+ name: "getBalance",
270
+ inputs: [{ name: "_user", type: "address", internalType: "address" }],
271
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
272
+ stateMutability: "view"
273
+ },
274
+ {
275
+ type: "function",
276
+ name: "getExchangeRate",
277
+ inputs: [],
278
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
279
+ stateMutability: "view"
280
+ },
281
+ {
282
+ type: "function",
283
+ name: "getTotalStaked",
284
+ inputs: [],
285
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
286
+ stateMutability: "view"
287
+ },
288
+ {
289
+ type: "function",
290
+ name: "previewDeposit",
291
+ inputs: [{ name: "_assets", type: "uint256", internalType: "uint256" }],
292
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
293
+ stateMutability: "view"
294
+ },
295
+ {
296
+ type: "function",
297
+ name: "previewRedeem",
298
+ inputs: [{ name: "_shares", type: "uint256", internalType: "uint256" }],
299
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
300
+ stateMutability: "view"
301
+ },
302
+ {
303
+ type: "function",
304
+ name: "getPendingYield",
305
+ inputs: [],
306
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
307
+ stateMutability: "view"
308
+ },
309
+ {
310
+ type: "function",
311
+ name: "harvestYield",
312
+ inputs: [],
313
+ outputs: [{ name: "yieldAmount", type: "uint256", internalType: "uint256" }],
314
+ stateMutability: "nonpayable"
315
+ },
316
+
317
+ // ============ StabilityPoolFacet Events ============
318
+ {
319
+ type: "event",
320
+ name: "Deposited",
321
+ inputs: [
322
+ { name: "user", type: "address", indexed: true, internalType: "address" },
323
+ { name: "apUSDAmount", type: "uint256", indexed: false, internalType: "uint256" },
324
+ { name: "sharesReceived", type: "uint256", indexed: false, internalType: "uint256" }
325
+ ],
326
+ anonymous: false
327
+ },
328
+ {
329
+ type: "event",
330
+ name: "Withdrawn",
331
+ inputs: [
332
+ { name: "user", type: "address", indexed: true, internalType: "address" },
333
+ { name: "sharesRedeemed", type: "uint256", indexed: false, internalType: "uint256" },
334
+ { name: "apUSDReceived", type: "uint256", indexed: false, internalType: "uint256" }
335
+ ],
336
+ anonymous: false
337
+ },
338
+ {
339
+ type: "event",
340
+ name: "YieldHarvested",
341
+ inputs: [
342
+ { name: "yieldUSD", type: "uint256", indexed: false, internalType: "uint256" }
343
+ ],
344
+ anonymous: false
345
+ },
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
+
387
+ // ============ ConfigFacet ============
388
+ {
389
+ type: "function",
390
+ name: "getTokens",
391
+ inputs: [],
392
+ outputs: [
393
+ { name: "apUSD", type: "address", internalType: "address" },
394
+ { name: "xBNB", type: "address", internalType: "address" }
395
+ ],
396
+ stateMutability: "view"
397
+ },
398
+ {
399
+ type: "function",
400
+ name: "getSApUSD",
401
+ inputs: [],
402
+ outputs: [{ name: "", type: "address", internalType: "address" }],
403
+ stateMutability: "view"
404
+ },
405
+ {
406
+ type: "function",
407
+ name: "getStabilityPool",
408
+ inputs: [],
409
+ outputs: [{ name: "", type: "address", internalType: "address" }],
410
+ stateMutability: "view"
411
+ },
412
+ {
413
+ type: "function",
414
+ name: "getTreasury",
415
+ inputs: [],
416
+ outputs: [{ name: "", type: "address", internalType: "address" }],
417
+ stateMutability: "view"
418
+ },
419
+ {
420
+ type: "function",
421
+ name: "getFeeTierCount",
422
+ inputs: [],
423
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
424
+ stateMutability: "view"
425
+ },
426
+ {
427
+ type: "function",
428
+ name: "getFeeTier",
429
+ inputs: [{ name: "_index", type: "uint256", internalType: "uint256" }],
430
+ outputs: [
431
+ { name: "minCR", type: "uint256", internalType: "uint256" },
432
+ { name: "apUSDMintFee", type: "uint16", internalType: "uint16" },
433
+ { name: "apUSDRedeemFee", type: "uint16", internalType: "uint16" },
434
+ { name: "xBNBMintFee", type: "uint16", internalType: "uint16" },
435
+ { name: "xBNBRedeemFee", type: "uint16", internalType: "uint16" },
436
+ { name: "apUSDMintDisabled", type: "bool", internalType: "bool" }
437
+ ],
438
+ stateMutability: "view"
439
+ },
440
+ {
441
+ type: "function",
442
+ name: "getCurrentFeeTier",
443
+ inputs: [],
444
+ outputs: [
445
+ { name: "minCR", type: "uint256", internalType: "uint256" },
446
+ { name: "apUSDMintFee", type: "uint16", internalType: "uint16" },
447
+ { name: "apUSDRedeemFee", type: "uint16", internalType: "uint16" },
448
+ { name: "xBNBMintFee", type: "uint16", internalType: "uint16" },
449
+ { name: "xBNBRedeemFee", type: "uint16", internalType: "uint16" },
450
+ { name: "apUSDMintDisabled", type: "bool", internalType: "bool" },
451
+ { name: "currentCR", type: "uint256", internalType: "uint256" }
452
+ ],
453
+ stateMutability: "view"
454
+ },
455
+ {
456
+ type: "function",
457
+ name: "getMaxPriceAge",
458
+ inputs: [],
459
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
460
+ stateMutability: "view"
461
+ },
462
+ {
463
+ type: "function",
464
+ name: "getMinDepositPeriod",
465
+ inputs: [],
466
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
467
+ stateMutability: "view"
468
+ },
469
+ {
470
+ type: "function",
471
+ name: "isPaused",
472
+ inputs: [],
473
+ outputs: [{ name: "", type: "bool", internalType: "bool" }],
474
+ stateMutability: "view"
475
+ },
476
+
477
+ // ============ StabilityModeFacet ============
478
+ {
479
+ type: "function",
480
+ name: "getStabilityMode",
481
+ inputs: [],
482
+ outputs: [
483
+ { name: "mode", type: "uint8", internalType: "uint8" },
484
+ { name: "currentCR", type: "uint256", internalType: "uint256" }
485
+ ],
486
+ stateMutability: "view"
487
+ },
488
+ {
489
+ type: "function",
490
+ name: "canTriggerStabilityMode2",
491
+ inputs: [],
492
+ outputs: [
493
+ { name: "canTrigger", type: "bool", internalType: "bool" },
494
+ { name: "currentCR", type: "uint256", internalType: "uint256" },
495
+ { name: "potentialConversion", type: "uint256", internalType: "uint256" }
496
+ ],
497
+ stateMutability: "view"
498
+ },
499
+ {
500
+ type: "function",
501
+ name: "triggerStabilityMode2",
502
+ inputs: [{ name: "_targetCR", type: "uint256", internalType: "uint256" }],
503
+ outputs: [
504
+ { name: "apUSDBurned", type: "uint256", internalType: "uint256" },
505
+ { name: "xBNBMinted", type: "uint256", internalType: "uint256" }
506
+ ],
507
+ stateMutability: "nonpayable"
508
+ },
509
+
510
+ // ============ StabilityModeFacet Events ============
511
+ {
512
+ type: "event",
513
+ name: "StabilityMode2Triggered",
514
+ inputs: [
515
+ { name: "currentCR", type: "uint256", indexed: false, internalType: "uint256" },
516
+ { name: "targetCR", type: "uint256", indexed: false, internalType: "uint256" },
517
+ { name: "apUSDBurned", type: "uint256", indexed: false, internalType: "uint256" },
518
+ { name: "xBNBMinted", type: "uint256", indexed: false, internalType: "uint256" }
519
+ ],
520
+ anonymous: false
521
+ },
522
+
523
+ // ============ OwnershipFacet ============
524
+ {
525
+ type: "function",
526
+ name: "owner",
527
+ inputs: [],
528
+ outputs: [{ name: "", type: "address", internalType: "address" }],
529
+ stateMutability: "view"
530
+ }
531
+ ] as const;
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Bot Configuration
3
+ * Loads environment variables and provides typed configuration
4
+ */
5
+
6
+ import type { Address } from "viem";
7
+
8
+ export interface BotConfig {
9
+ // RPC Configuration
10
+ rpcUrl: string;
11
+ rpcFallbackUrls: string[];
12
+
13
+ // Contract Address
14
+ diamondAddress: Address;
15
+
16
+ // Monitoring Intervals (milliseconds)
17
+ statsReportInterval: number;
18
+ crCheckInterval: number;
19
+
20
+ // CR Thresholds (18 decimals: 1.5e18 = 150%)
21
+ crThresholdMode1: bigint;
22
+ crThresholdMode2: bigint;
23
+
24
+ // TVL Impact Threshold (percentage)
25
+ tvlImpactThresholdPercent: number;
26
+
27
+ // Slack Configuration
28
+ slackWebhookUrl: string;
29
+ slackRateLimitMs: number;
30
+
31
+ // Retry Configuration
32
+ maxRetries: number;
33
+ retryDelayMs: number;
34
+ retryBackoffMultiplier: number;
35
+ }
36
+
37
+ export function loadConfig(): BotConfig {
38
+ const slackWebhookUrl = process.env.SLACK_WEBHOOK_URL;
39
+ if (!slackWebhookUrl) {
40
+ throw new Error("SLACK_WEBHOOK_URL environment variable is required");
41
+ }
42
+
43
+ return {
44
+ // RPC
45
+ rpcUrl: process.env.RPC_URL ?? "https://bsc-dataseed1.binance.org",
46
+ rpcFallbackUrls: (process.env.RPC_FALLBACK_URLS ?? "")
47
+ .split(",")
48
+ .map((url) => url.trim())
49
+ .filter(Boolean),
50
+
51
+ // Contract
52
+ diamondAddress: (process.env.DIAMOND_ADDRESS ??
53
+ "0x10d25Ae0690533e0BA9E64EC7ae77dbD4fE8A46f") as Address,
54
+
55
+ // Intervals
56
+ statsReportInterval: parseInt(
57
+ process.env.STATS_INTERVAL_MS ?? "300000",
58
+ 10
59
+ ), // 5 min
60
+ crCheckInterval: parseInt(process.env.CR_CHECK_INTERVAL_MS ?? "30000", 10), // 30 sec
61
+
62
+ // CR Thresholds
63
+ crThresholdMode1: BigInt(
64
+ process.env.CR_THRESHOLD_MODE1 ?? "1500000000000000000"
65
+ ), // 150%
66
+ crThresholdMode2: BigInt(
67
+ process.env.CR_THRESHOLD_MODE2 ?? "1300000000000000000"
68
+ ), // 130%
69
+
70
+ // TVL
71
+ tvlImpactThresholdPercent: parseFloat(
72
+ process.env.TVL_IMPACT_THRESHOLD ?? "5"
73
+ ),
74
+
75
+ // Slack
76
+ slackWebhookUrl,
77
+ slackRateLimitMs: parseInt(process.env.SLACK_RATE_LIMIT_MS ?? "1000", 10),
78
+
79
+ // Retry
80
+ maxRetries: parseInt(process.env.MAX_RETRIES ?? "3", 10),
81
+ retryDelayMs: parseInt(process.env.RETRY_DELAY_MS ?? "1000", 10),
82
+ retryBackoffMultiplier: parseFloat(process.env.RETRY_BACKOFF ?? "2"),
83
+ };
84
+ }