@aspan/sdk 0.4.0 → 0.4.2

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 CHANGED
@@ -476,6 +476,30 @@ var DiamondABI = [
476
476
  outputs: [{ name: "", type: "bool", internalType: "bool" }],
477
477
  stateMutability: "view"
478
478
  },
479
+ {
480
+ type: "function",
481
+ name: "bootstrap",
482
+ inputs: [
483
+ { name: "_lstToken", type: "address", internalType: "address" },
484
+ { name: "_lstAmount", type: "uint256", internalType: "uint256" }
485
+ ],
486
+ outputs: [{ name: "xBNBAmount", type: "uint256", internalType: "uint256" }],
487
+ stateMutability: "nonpayable"
488
+ },
489
+ {
490
+ type: "function",
491
+ name: "isBootstrapped",
492
+ inputs: [],
493
+ outputs: [{ name: "", type: "bool", internalType: "bool" }],
494
+ stateMutability: "view"
495
+ },
496
+ {
497
+ type: "function",
498
+ name: "getBootstrapXBNBAmount",
499
+ inputs: [],
500
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
501
+ stateMutability: "view"
502
+ },
479
503
  // ============ StabilityModeFacet ============
480
504
  {
481
505
  type: "function",
@@ -508,6 +532,13 @@ var DiamondABI = [
508
532
  ],
509
533
  stateMutability: "nonpayable"
510
534
  },
535
+ {
536
+ type: "function",
537
+ name: "cleanXbnb",
538
+ inputs: [{ name: "_xBNBAmount", type: "uint256", internalType: "uint256" }],
539
+ outputs: [],
540
+ stateMutability: "nonpayable"
541
+ },
511
542
  // ============ StabilityModeFacet Events ============
512
543
  {
513
544
  type: "event",
@@ -527,10 +558,78 @@ var DiamondABI = [
527
558
  inputs: [],
528
559
  outputs: [{ name: "", type: "address", internalType: "address" }],
529
560
  stateMutability: "view"
561
+ },
562
+ // ============ Fee Manager ============
563
+ {
564
+ type: "function",
565
+ name: "setFeeManager",
566
+ inputs: [{ name: "_feeManager", type: "address", internalType: "address" }],
567
+ outputs: [],
568
+ stateMutability: "nonpayable"
569
+ },
570
+ {
571
+ type: "function",
572
+ name: "getFeeManager",
573
+ inputs: [],
574
+ outputs: [{ name: "", type: "address", internalType: "address" }],
575
+ stateMutability: "view"
576
+ },
577
+ {
578
+ type: "function",
579
+ name: "setFeeTiers",
580
+ inputs: [{
581
+ name: "_tiers",
582
+ type: "tuple[]",
583
+ internalType: "struct LibAppStorage.FeeTier[]",
584
+ components: [
585
+ { name: "minCR", type: "uint256", internalType: "uint256" },
586
+ { name: "apUSDMintFee", type: "uint16", internalType: "uint16" },
587
+ { name: "apUSDRedeemFee", type: "uint16", internalType: "uint16" },
588
+ { name: "xBNBMintFee", type: "uint16", internalType: "uint16" },
589
+ { name: "xBNBRedeemFee", type: "uint16", internalType: "uint16" },
590
+ { name: "apUSDMintDisabled", type: "bool", internalType: "bool" }
591
+ ]
592
+ }],
593
+ outputs: [],
594
+ stateMutability: "nonpayable"
595
+ },
596
+ {
597
+ type: "event",
598
+ name: "FeeManagerSet",
599
+ inputs: [
600
+ { name: "feeManager", type: "address", indexed: true, internalType: "address" }
601
+ ],
602
+ anonymous: false
530
603
  }
531
604
  ];
532
605
 
533
606
  // src/client.ts
607
+ var pharosTestnet = {
608
+ id: 688689,
609
+ name: "Pharos Atlantic Testnet",
610
+ nativeCurrency: { name: "PHRS", symbol: "PHRS", decimals: 18 },
611
+ rpcUrls: {
612
+ default: { http: ["https://atlantic.dplabs-internal.com"] }
613
+ },
614
+ blockExplorers: {
615
+ default: { name: "Pharos Explorer", url: "https://atlantic.pharosscan.xyz" }
616
+ }
617
+ };
618
+ var CHAIN_IDS = {
619
+ BSC: 56,
620
+ BSC_TESTNET: 97,
621
+ PHAROS: 688689
622
+ };
623
+ var CHAIN_MAP = {
624
+ [CHAIN_IDS.BSC]: bsc,
625
+ [CHAIN_IDS.BSC_TESTNET]: bscTestnet,
626
+ [CHAIN_IDS.PHAROS]: pharosTestnet
627
+ };
628
+ function getChainById(chainId) {
629
+ const chain = CHAIN_MAP[chainId];
630
+ if (!chain) throw new Error(`[Aspan SDK] Unsupported chainId: ${chainId}`);
631
+ return chain;
632
+ }
534
633
  var AspanReadClient = class _AspanReadClient {
535
634
  publicClient;
536
635
  diamondAddress;
@@ -1171,6 +1270,29 @@ var AspanReadClient = class _AspanReadClient {
1171
1270
  functionName: "isPaused"
1172
1271
  });
1173
1272
  }
1273
+ // ============ Bootstrap View Functions ============
1274
+ /**
1275
+ * Check if xBNB liquidity has been bootstrapped
1276
+ * @returns true if bootstrap has been called
1277
+ */
1278
+ async isBootstrapped() {
1279
+ return this.publicClient.readContract({
1280
+ address: this.diamondAddress,
1281
+ abi: DiamondABI,
1282
+ functionName: "isBootstrapped"
1283
+ });
1284
+ }
1285
+ /**
1286
+ * Get the amount of xBNB locked in bootstrap (burned to dead address)
1287
+ * @returns xBNB amount in wei
1288
+ */
1289
+ async getBootstrapXBNBAmount() {
1290
+ return this.publicClient.readContract({
1291
+ address: this.diamondAddress,
1292
+ abi: DiamondABI,
1293
+ functionName: "getBootstrapXBNBAmount"
1294
+ });
1295
+ }
1174
1296
  // ============ Stability Mode View Functions ============
1175
1297
  async getStabilityMode() {
1176
1298
  try {
@@ -1370,6 +1492,75 @@ var AspanClient = class extends AspanReadClient {
1370
1492
  functionName: "harvestYield"
1371
1493
  });
1372
1494
  }
1495
+ // ============ Risk Management Functions ============
1496
+ /**
1497
+ * Trigger Stability Mode 2 forced conversion
1498
+ * @description Anyone can call when CR < 130%. Burns apUSD from stability pool
1499
+ * and mints xBNB to compensate stakers.
1500
+ * @param targetCR Target CR to restore to (in BPS, e.g., 14000 = 140%)
1501
+ * @returns Transaction hash
1502
+ */
1503
+ async triggerStabilityMode2(targetCR = 14000n) {
1504
+ return this.walletClient.writeContract({
1505
+ chain: this.chain,
1506
+ account: this.walletClient.account,
1507
+ address: this.diamondAddress,
1508
+ abi: DiamondABI,
1509
+ functionName: "triggerStabilityMode2",
1510
+ args: [targetCR]
1511
+ });
1512
+ }
1513
+ /**
1514
+ * Clean underwater xBNB (burn without getting LST back)
1515
+ * @description Only works when xBNB is underwater (price = 0)
1516
+ * @param xBNBAmount Amount of xBNB to clean (burn)
1517
+ * @returns Transaction hash
1518
+ */
1519
+ async cleanXbnb(xBNBAmount) {
1520
+ return this.walletClient.writeContract({
1521
+ chain: this.chain,
1522
+ account: this.walletClient.account,
1523
+ address: this.diamondAddress,
1524
+ abi: DiamondABI,
1525
+ functionName: "cleanXbnb",
1526
+ args: [xBNBAmount]
1527
+ });
1528
+ }
1529
+ // ============ Fee Management Functions ============
1530
+ /**
1531
+ * Set fee tiers (requires feeManager or owner role)
1532
+ * @param tiers Array of fee tier configurations
1533
+ * @returns Transaction hash
1534
+ */
1535
+ async setFeeTiers(tiers) {
1536
+ return this.walletClient.writeContract({
1537
+ chain: this.chain,
1538
+ account: this.walletClient.account,
1539
+ address: this.diamondAddress,
1540
+ abi: DiamondABI,
1541
+ functionName: "setFeeTiers",
1542
+ args: [tiers]
1543
+ });
1544
+ }
1545
+ // ============ Admin Functions ============
1546
+ /**
1547
+ * Bootstrap xBNB liquidity (owner only)
1548
+ * @description Initializes xBNB supply by minting to dead address, preventing extreme initial prices.
1549
+ * Similar to Uniswap V2's MINIMUM_LIQUIDITY. Can only be called once.
1550
+ * @param lstToken LST token address to deposit
1551
+ * @param lstAmount Amount of LST to deposit for bootstrap
1552
+ * @returns Transaction hash
1553
+ */
1554
+ async bootstrap(lstToken, lstAmount) {
1555
+ return this.walletClient.writeContract({
1556
+ chain: this.chain,
1557
+ account: this.walletClient.account,
1558
+ address: this.diamondAddress,
1559
+ abi: DiamondABI,
1560
+ functionName: "bootstrap",
1561
+ args: [lstToken, lstAmount]
1562
+ });
1563
+ }
1373
1564
  // ============ Transaction Helpers ============
1374
1565
  /**
1375
1566
  * Wait for transaction confirmation
@@ -1410,6 +1601,29 @@ function createAspanTestnetClient(diamondAddress, account, rpcUrl) {
1410
1601
  rpcUrl
1411
1602
  });
1412
1603
  }
1604
+ function createAspanPharosReadClient(diamondAddress, rpcUrl) {
1605
+ return new AspanReadClient({
1606
+ diamondAddress,
1607
+ chain: pharosTestnet,
1608
+ rpcUrl
1609
+ });
1610
+ }
1611
+ function createAspanPharosClient(diamondAddress, account, rpcUrl) {
1612
+ return new AspanClient({
1613
+ diamondAddress,
1614
+ account,
1615
+ chain: pharosTestnet,
1616
+ rpcUrl
1617
+ });
1618
+ }
1619
+ function createAspanReadClientForChain(diamondAddress, chainId = CHAIN_IDS.BSC, rpcUrl) {
1620
+ const chain = getChainById(chainId);
1621
+ return new AspanReadClient({ diamondAddress, chain, rpcUrl });
1622
+ }
1623
+ function createAspanWriteClientForChain(diamondAddress, chainId = CHAIN_IDS.BSC, walletClient, rpcUrl) {
1624
+ const chain = getChainById(chainId);
1625
+ return new AspanClient({ diamondAddress, chain, walletClient, rpcUrl });
1626
+ }
1413
1627
 
1414
1628
  // src/router.ts
1415
1629
  import {
@@ -2181,6 +2395,29 @@ function createRouterTestnetClient(routerAddress, account, rpcUrl) {
2181
2395
  rpcUrl
2182
2396
  });
2183
2397
  }
2398
+ function createRouterPharosReadClient(routerAddress, rpcUrl) {
2399
+ return new AspanRouterReadClient({
2400
+ routerAddress,
2401
+ chain: pharosTestnet,
2402
+ rpcUrl
2403
+ });
2404
+ }
2405
+ function createRouterPharosClient(routerAddress, account, rpcUrl) {
2406
+ return new AspanRouterClient({
2407
+ routerAddress,
2408
+ account,
2409
+ chain: pharosTestnet,
2410
+ rpcUrl
2411
+ });
2412
+ }
2413
+ function createRouterReadClientForChain(routerAddress, chainId = CHAIN_IDS.BSC, rpcUrl) {
2414
+ const chain = getChainById(chainId);
2415
+ return new AspanRouterReadClient({ routerAddress, chain, rpcUrl });
2416
+ }
2417
+ function createRouterWriteClientForChain(routerAddress, chainId = CHAIN_IDS.BSC, walletClient, rpcUrl) {
2418
+ const chain = getChainById(chainId);
2419
+ return new AspanRouterClient({ routerAddress, chain, walletClient, rpcUrl });
2420
+ }
2184
2421
 
2185
2422
  // src/types.ts
2186
2423
  function encodeV3Path(tokens, fees) {
@@ -2200,20 +2437,29 @@ var PRECISION = 10n ** 18n;
2200
2437
  var BPS_PRECISION = 10000n;
2201
2438
  var PRICE_PRECISION = 10n ** 8n;
2202
2439
  var BSC_ADDRESSES = {
2203
- diamond: "0x10d25Ae0690533e0BA9E64EC7ae77dbD4fE8A46f",
2204
- router: "0x813d3D1A3154950E2f1d8718305426a335A974A9",
2205
- apUSD: "0x1977097E2E5697A6DD91b6732F368a14F50f6B3d",
2206
- xBNB: "0xB78eB4d5928bAb158Eb23c3154544084cD2661d5",
2207
- sApUSD: "0xE2BE739C4aA4126ee72D612d9548C38B1B0e5A1b",
2440
+ diamond: "0x6a11B30d3a70727d5477D6d8090e144443fA1c78",
2441
+ router: "0x29dd49b2e98674ee7531f17e4d40a7725918c3f6",
2442
+ apUSD: "0x4570047eeB5aDb4081c5d470494EB5134e34A287",
2443
+ xBNB: "0x0A0c9CD826e747D99F90D63e780B3727Da4D0d43",
2444
+ sApUSD: "0x73407A291c007a47CC926EcD5CaC256A1E2d00cF",
2208
2445
  // LSTs
2209
2446
  slisBNB: "0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B",
2210
2447
  asBNB: "0x77734e70b6E88b4d82fE632a168EDf6e700912b6",
2211
- wclisBNB: "0x439faaC2229559121C4Ad4fd8B3FE13Dff038046",
2448
+ wclisBNB: "0x448f7c2fa4e5135a4a5B50879602cf3CD428e108",
2212
2449
  // Stablecoins
2213
2450
  USDT: "0x55d398326f99059fF775485246999027B3197955",
2214
2451
  USDC: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",
2215
2452
  WBNB: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"
2216
2453
  };
2454
+ var PHAROS_ADDRESSES = {
2455
+ diamond: "0x67011Ce4B5E534FA78dD9922559B7005197DBcc8",
2456
+ apUSD: "0x82ac96db027772cE8a770e099370b5D7941B3ae4",
2457
+ xBNB: "0xFF43b2f50b2c6c588d14Ea4565Ee5Eb93e438576",
2458
+ sApUSD: "0xFA4B826CfD5faaAfA48E4963d8a7d6Cf9889A9A8",
2459
+ mockLST: "0xc7BB55759e8e04AfAA620De96E9E133B1FAd3e18",
2460
+ mockPriceFeed: "0xa2B41DDE7a7BB0A897DE476Ea441fB27A6978682",
2461
+ mockExchangeRate: "0xffA1938e072Ea3b144EA7e61662dd8B0818D82B9"
2462
+ };
2217
2463
  function formatAmount(amount, decimals = 4) {
2218
2464
  const divisor = 10n ** BigInt(18 - decimals);
2219
2465
  const scaled = amount / divisor;
@@ -2252,23 +2498,35 @@ export {
2252
2498
  AspanRouterReadClient,
2253
2499
  BPS_PRECISION,
2254
2500
  BSC_ADDRESSES,
2501
+ CHAIN_IDS,
2255
2502
  DiamondABI,
2503
+ PHAROS_ADDRESSES,
2256
2504
  PRECISION,
2257
2505
  PRICE_PRECISION,
2258
2506
  RouterABI,
2259
2507
  calculateAPY,
2260
2508
  createAspanClient,
2509
+ createAspanPharosClient,
2510
+ createAspanPharosReadClient,
2261
2511
  createAspanReadClient,
2512
+ createAspanReadClientForChain,
2262
2513
  createAspanTestnetClient,
2263
2514
  createAspanTestnetReadClient,
2515
+ createAspanWriteClientForChain,
2264
2516
  createRouterClient,
2517
+ createRouterPharosClient,
2518
+ createRouterPharosReadClient,
2265
2519
  createRouterReadClient,
2520
+ createRouterReadClientForChain,
2266
2521
  createRouterTestnetClient,
2267
2522
  createRouterTestnetReadClient,
2523
+ createRouterWriteClientForChain,
2268
2524
  encodeV3Path,
2269
2525
  formatAmount,
2270
2526
  formatCR,
2271
2527
  formatFeeBPS,
2272
2528
  formatPriceUSD,
2273
- parseAmount
2529
+ getChainById,
2530
+ parseAmount,
2531
+ pharosTestnet
2274
2532
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aspan/sdk",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "TypeScript SDK for Aspan Protocol - LST-backed stablecoin on BNB Chain",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -27,8 +27,8 @@ const TOKENS = {
27
27
  WBNB: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c" as Address,
28
28
  USDT: "0x55d398326f99059fF775485246999027B3197955" as Address,
29
29
  slisBNB: "0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B" as Address,
30
- apUSD: "0x1977097E2E5697A6DD91b6732F368a14F50f6B3d" as Address,
31
- xBNB: "0xB78eB4d5928bAb158Eb23c3154544084cD2661d5" as Address,
30
+ apUSD: "0x4570047eeB5aDb4081c5d470494EB5134e34A287" as Address,
31
+ xBNB: "0x0A0c9CD826e747D99F90D63e780B3727Da4D0d43" as Address,
32
32
  };
33
33
 
34
34
  const ERC20_ABI = [
@@ -477,6 +477,30 @@ export const DiamondABI = [
477
477
  outputs: [{ name: "", type: "bool", internalType: "bool" }],
478
478
  stateMutability: "view"
479
479
  },
480
+ {
481
+ type: "function",
482
+ name: "bootstrap",
483
+ inputs: [
484
+ { name: "_lstToken", type: "address", internalType: "address" },
485
+ { name: "_lstAmount", type: "uint256", internalType: "uint256" }
486
+ ],
487
+ outputs: [{ name: "xBNBAmount", type: "uint256", internalType: "uint256" }],
488
+ stateMutability: "nonpayable"
489
+ },
490
+ {
491
+ type: "function",
492
+ name: "isBootstrapped",
493
+ inputs: [],
494
+ outputs: [{ name: "", type: "bool", internalType: "bool" }],
495
+ stateMutability: "view"
496
+ },
497
+ {
498
+ type: "function",
499
+ name: "getBootstrapXBNBAmount",
500
+ inputs: [],
501
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
502
+ stateMutability: "view"
503
+ },
480
504
 
481
505
  // ============ StabilityModeFacet ============
482
506
  {
@@ -510,6 +534,13 @@ export const DiamondABI = [
510
534
  ],
511
535
  stateMutability: "nonpayable"
512
536
  },
537
+ {
538
+ type: "function",
539
+ name: "cleanXbnb",
540
+ inputs: [{ name: "_xBNBAmount", type: "uint256", internalType: "uint256" }],
541
+ outputs: [],
542
+ stateMutability: "nonpayable"
543
+ },
513
544
 
514
545
  // ============ StabilityModeFacet Events ============
515
546
  {
@@ -531,5 +562,48 @@ export const DiamondABI = [
531
562
  inputs: [],
532
563
  outputs: [{ name: "", type: "address", internalType: "address" }],
533
564
  stateMutability: "view"
565
+ },
566
+
567
+ // ============ Fee Manager ============
568
+ {
569
+ type: "function",
570
+ name: "setFeeManager",
571
+ inputs: [{ name: "_feeManager", type: "address", internalType: "address" }],
572
+ outputs: [],
573
+ stateMutability: "nonpayable"
574
+ },
575
+ {
576
+ type: "function",
577
+ name: "getFeeManager",
578
+ inputs: [],
579
+ outputs: [{ name: "", type: "address", internalType: "address" }],
580
+ stateMutability: "view"
581
+ },
582
+ {
583
+ type: "function",
584
+ name: "setFeeTiers",
585
+ inputs: [{
586
+ name: "_tiers",
587
+ type: "tuple[]",
588
+ internalType: "struct LibAppStorage.FeeTier[]",
589
+ components: [
590
+ { name: "minCR", type: "uint256", internalType: "uint256" },
591
+ { name: "apUSDMintFee", type: "uint16", internalType: "uint16" },
592
+ { name: "apUSDRedeemFee", type: "uint16", internalType: "uint16" },
593
+ { name: "xBNBMintFee", type: "uint16", internalType: "uint16" },
594
+ { name: "xBNBRedeemFee", type: "uint16", internalType: "uint16" },
595
+ { name: "apUSDMintDisabled", type: "bool", internalType: "bool" }
596
+ ]
597
+ }],
598
+ outputs: [],
599
+ stateMutability: "nonpayable"
600
+ },
601
+ {
602
+ type: "event",
603
+ name: "FeeManagerSet",
604
+ inputs: [
605
+ { name: "feeManager", type: "address", indexed: true, internalType: "address" }
606
+ ],
607
+ anonymous: false
534
608
  }
535
609
  ] as const;
@@ -0,0 +1,100 @@
1
+ /**
2
+ * SApUSD (Staked ApUSD) Vault ABI
3
+ * Multi-asset vault for staking apUSD and absorbing xBNB during stability events
4
+ */
5
+ export const SApUSDABI = [
6
+ // ============ View Functions ============
7
+ {
8
+ type: "function",
9
+ name: "totalAssets",
10
+ inputs: [],
11
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
12
+ stateMutability: "view"
13
+ },
14
+ {
15
+ type: "function",
16
+ name: "totalSupply",
17
+ inputs: [],
18
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
19
+ stateMutability: "view"
20
+ },
21
+ {
22
+ type: "function",
23
+ name: "balanceOf",
24
+ inputs: [{ name: "account", type: "address", internalType: "address" }],
25
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
26
+ stateMutability: "view"
27
+ },
28
+ {
29
+ type: "function",
30
+ name: "hasStabilityConversion",
31
+ inputs: [],
32
+ outputs: [
33
+ { name: "hasXBNB", type: "bool", internalType: "bool" },
34
+ { name: "xBNBAmount", type: "uint256", internalType: "uint256" }
35
+ ],
36
+ stateMutability: "view"
37
+ },
38
+ {
39
+ type: "function",
40
+ name: "exchangeRate",
41
+ inputs: [],
42
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
43
+ stateMutability: "view"
44
+ },
45
+ {
46
+ type: "function",
47
+ name: "previewCleanXBNB",
48
+ inputs: [
49
+ { name: "_xBNBAmount", type: "uint256", internalType: "uint256" },
50
+ { name: "_router", type: "address", internalType: "address" },
51
+ { name: "_path", type: "address[]", internalType: "address[]" }
52
+ ],
53
+ outputs: [{ name: "expectedApUSD", type: "uint256", internalType: "uint256" }],
54
+ stateMutability: "view"
55
+ },
56
+ {
57
+ type: "function",
58
+ name: "KEEPER_ROLE",
59
+ inputs: [],
60
+ outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
61
+ stateMutability: "view"
62
+ },
63
+ {
64
+ type: "function",
65
+ name: "hasRole",
66
+ inputs: [
67
+ { name: "role", type: "bytes32", internalType: "bytes32" },
68
+ { name: "account", type: "address", internalType: "address" }
69
+ ],
70
+ outputs: [{ name: "", type: "bool", internalType: "bool" }],
71
+ stateMutability: "view"
72
+ },
73
+
74
+ // ============ Keeper Functions ============
75
+ {
76
+ type: "function",
77
+ name: "cleanXBNB",
78
+ inputs: [
79
+ { name: "_xBNBAmount", type: "uint256", internalType: "uint256" },
80
+ { name: "_minApUSDOut", type: "uint256", internalType: "uint256" },
81
+ { name: "_router", type: "address", internalType: "address" },
82
+ { name: "_path", type: "address[]", internalType: "address[]" },
83
+ { name: "_deadline", type: "uint256", internalType: "uint256" }
84
+ ],
85
+ outputs: [{ name: "apUSDReceived", type: "uint256", internalType: "uint256" }],
86
+ stateMutability: "nonpayable"
87
+ },
88
+
89
+ // ============ Events ============
90
+ {
91
+ type: "event",
92
+ name: "VaultCleaned",
93
+ inputs: [
94
+ { name: "xBNBSold", type: "uint256", indexed: false, internalType: "uint256" },
95
+ { name: "apUSDReceived", type: "uint256", indexed: false, internalType: "uint256" },
96
+ { name: "keeper", type: "address", indexed: true, internalType: "address" }
97
+ ],
98
+ anonymous: false
99
+ }
100
+ ] as const;
package/src/bot/config.ts CHANGED
@@ -32,6 +32,29 @@ export interface BotConfig {
32
32
  maxRetries: number;
33
33
  retryDelayMs: number;
34
34
  retryBackoffMultiplier: number;
35
+
36
+ // Risk Keeper Configuration (optional)
37
+ riskKeeper?: {
38
+ enabled: boolean;
39
+ sApUSDAddress: Address;
40
+ routerAddress: Address;
41
+ wbnbAddress: Address;
42
+ privateKey: `0x${string}`;
43
+ sm2CooldownMs: number;
44
+ sm2MaxPoolPercent: number;
45
+ twapIntervalMs: number;
46
+ twapPercentage: number;
47
+ maxSlippageBps: number;
48
+ twapStartCR: bigint;
49
+ maxVolatilityPercent: number;
50
+ };
51
+
52
+ // Fee Manager Configuration (optional)
53
+ feeManager?: {
54
+ enabled: boolean;
55
+ privateKey: `0x${string}`;
56
+ checkIntervalMs: number;
57
+ };
35
58
  }
36
59
 
37
60
  export function loadConfig(): BotConfig {
@@ -50,7 +73,7 @@ export function loadConfig(): BotConfig {
50
73
 
51
74
  // Contract
52
75
  diamondAddress: (process.env.DIAMOND_ADDRESS ??
53
- "0x10d25Ae0690533e0BA9E64EC7ae77dbD4fE8A46f") as Address,
76
+ "0x6a11B30d3a70727d5477D6d8090e144443fA1c78") as Address,
54
77
 
55
78
  // Intervals
56
79
  statsReportInterval: parseInt(
@@ -80,5 +103,32 @@ export function loadConfig(): BotConfig {
80
103
  maxRetries: parseInt(process.env.MAX_RETRIES ?? "3", 10),
81
104
  retryDelayMs: parseInt(process.env.RETRY_DELAY_MS ?? "1000", 10),
82
105
  retryBackoffMultiplier: parseFloat(process.env.RETRY_BACKOFF ?? "2"),
106
+
107
+ // Risk Keeper (optional - only enabled if private key is provided)
108
+ riskKeeper: process.env.KEEPER_PRIVATE_KEY
109
+ ? {
110
+ enabled: process.env.RISK_KEEPER_ENABLED === "true",
111
+ sApUSDAddress: (process.env.SAPUSD_ADDRESS ?? "") as Address,
112
+ routerAddress: (process.env.ROUTER_ADDRESS ?? "0x10ED43C718714eb63d5aA57B78B54704E256024E") as Address, // PancakeSwap V2
113
+ wbnbAddress: (process.env.WBNB_ADDRESS ?? "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c") as Address,
114
+ privateKey: process.env.KEEPER_PRIVATE_KEY as `0x${string}`,
115
+ sm2CooldownMs: parseInt(process.env.SM2_COOLDOWN_MS ?? "1800000", 10), // 30 min
116
+ sm2MaxPoolPercent: parseInt(process.env.SM2_MAX_POOL_PERCENT ?? "40", 10), // 40%
117
+ twapIntervalMs: parseInt(process.env.TWAP_INTERVAL_MS ?? "600000", 10), // 10 min
118
+ twapPercentage: parseInt(process.env.TWAP_PERCENTAGE ?? "5", 10), // 5%
119
+ maxSlippageBps: parseInt(process.env.MAX_SLIPPAGE_BPS ?? "50", 10), // 0.5%
120
+ twapStartCR: BigInt(process.env.TWAP_START_CR ?? "13500"), // 135%
121
+ maxVolatilityPercent: parseInt(process.env.MAX_VOLATILITY_PERCENT ?? "5", 10), // 5%
122
+ }
123
+ : undefined,
124
+
125
+ // Fee Manager (optional - uses same or different private key)
126
+ feeManager: process.env.FEE_MANAGER_ENABLED === "true" && process.env.FEE_MANAGER_PRIVATE_KEY
127
+ ? {
128
+ enabled: true,
129
+ privateKey: process.env.FEE_MANAGER_PRIVATE_KEY as `0x${string}`,
130
+ checkIntervalMs: parseInt(process.env.FEE_CHECK_INTERVAL_MS ?? "60000", 10), // 1 min
131
+ }
132
+ : undefined,
83
133
  };
84
134
  }