@mento-protocol/mento-sdk 3.2.7 → 3.3.0-beta.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/dist/cache/routes.d.ts +13 -0
- package/dist/cache/routes.js +14588 -0
- package/dist/cache/tokens.d.ts +68 -0
- package/dist/cache/tokens.js +514 -0
- package/dist/core/abis/activePool.d.ts +2 -0
- package/dist/core/abis/activePool.js +14 -0
- package/dist/core/abis/addressesRegistry.d.ts +2 -0
- package/dist/core/abis/addressesRegistry.js +26 -0
- package/dist/core/abis/bipoolmanager.d.ts +34 -0
- package/dist/core/abis/bipoolmanager.js +72 -0
- package/dist/core/abis/borrowerOperations.d.ts +9 -0
- package/dist/core/abis/borrowerOperations.js +89 -0
- package/dist/core/abis/breakerbox.d.ts +13 -0
- package/dist/core/abis/breakerbox.js +8 -0
- package/dist/core/abis/broker.d.ts +2 -0
- package/dist/core/abis/broker.js +9 -0
- package/dist/core/abis/erc20.d.ts +9 -0
- package/dist/core/abis/erc20.js +21 -0
- package/dist/core/abis/fpmm.d.ts +270 -0
- package/dist/core/abis/fpmm.js +49 -0
- package/dist/core/abis/fpmmFactory.d.ts +85 -0
- package/dist/core/abis/fpmmFactory.js +26 -0
- package/dist/core/abis/hintHelpers.d.ts +2 -0
- package/dist/core/abis/hintHelpers.js +14 -0
- package/dist/core/abis/index.d.ts +22 -0
- package/dist/core/abis/index.js +38 -0
- package/dist/core/abis/liquidityStrategy.d.ts +132 -0
- package/dist/core/abis/liquidityStrategy.js +10 -0
- package/dist/core/abis/multiTroveGetter.d.ts +8 -0
- package/dist/core/abis/multiTroveGetter.js +15 -0
- package/dist/core/abis/priceFeed.d.ts +7 -0
- package/dist/core/abis/priceFeed.js +16 -0
- package/dist/core/abis/pricingmodule.d.ts +2 -0
- package/dist/core/abis/pricingmodule.js +6 -0
- package/dist/core/abis/reserve.d.ts +3 -0
- package/dist/core/abis/reserve.js +18 -0
- package/dist/core/abis/router.d.ts +521 -0
- package/dist/core/abis/router.js +45 -0
- package/dist/core/abis/sortedTroves.d.ts +2 -0
- package/dist/core/abis/sortedTroves.js +15 -0
- package/dist/core/abis/systemParams.d.ts +2 -0
- package/dist/core/abis/systemParams.js +14 -0
- package/dist/core/abis/troveManager.d.ts +2 -0
- package/dist/core/abis/troveManager.js +27 -0
- package/dist/core/abis/troveNFT.d.ts +2 -0
- package/dist/core/abis/troveNFT.js +9 -0
- package/dist/core/abis/virtualPool.d.ts +50 -0
- package/dist/core/abis/virtualPool.js +11 -0
- package/dist/core/abis/virtualPoolFactory.d.ts +59 -0
- package/dist/core/abis/virtualPoolFactory.js +17 -0
- package/dist/core/constants/addresses.d.ts +18 -0
- package/dist/core/constants/addresses.js +125 -0
- package/dist/core/constants/borrowConstants.d.ts +10 -0
- package/dist/core/constants/borrowConstants.js +16 -0
- package/dist/core/constants/borrowRegistries.d.ts +7 -0
- package/dist/core/constants/borrowRegistries.js +34 -0
- package/dist/core/constants/chainId.d.ts +8 -0
- package/dist/core/constants/chainId.js +12 -0
- package/dist/core/constants/contractNames.d.ts +21 -0
- package/dist/core/constants/contractNames.js +24 -0
- package/dist/core/constants/index.d.ts +6 -0
- package/dist/core/constants/index.js +22 -0
- package/dist/core/errors/base.d.ts +8 -0
- package/dist/core/errors/base.js +17 -0
- package/dist/core/errors/index.d.ts +4 -0
- package/dist/core/errors/index.js +20 -0
- package/dist/core/errors/oracle.d.ts +9 -0
- package/dist/core/errors/oracle.js +15 -0
- package/dist/core/errors/router.d.ts +14 -0
- package/dist/core/errors/router.js +24 -0
- package/dist/core/types/borrow.d.ts +87 -0
- package/dist/core/types/borrow.js +3 -0
- package/dist/core/types/contractAddresses.d.ts +42 -0
- package/dist/core/types/contractAddresses.js +3 -0
- package/dist/core/types/index.d.ts +10 -0
- package/dist/core/types/index.js +26 -0
- package/dist/core/types/liquidity.d.ts +194 -0
- package/dist/core/types/liquidity.js +3 -0
- package/dist/core/types/pool.d.ts +208 -0
- package/dist/core/types/pool.js +14 -0
- package/dist/core/types/provider.d.ts +45 -0
- package/dist/core/types/provider.js +3 -0
- package/dist/core/types/route.d.ts +62 -0
- package/dist/core/types/route.js +3 -0
- package/dist/core/types/token.d.ts +21 -0
- package/dist/core/types/token.js +3 -0
- package/dist/core/types/tradingLimits.d.ts +91 -0
- package/dist/core/types/tradingLimits.js +3 -0
- package/dist/core/types/tradingMode.d.ts +24 -0
- package/dist/core/types/tradingMode.js +31 -0
- package/dist/core/types/transaction.d.ts +45 -0
- package/dist/core/types/transaction.js +3 -0
- package/dist/esm/cache/routes.js +14583 -0
- package/dist/esm/cache/tokens.js +506 -0
- package/dist/esm/core/abis/activePool.js +10 -0
- package/dist/esm/core/abis/addressesRegistry.js +22 -0
- package/dist/esm/core/abis/bipoolmanager.js +68 -0
- package/dist/esm/core/abis/borrowerOperations.js +85 -0
- package/dist/esm/core/abis/breakerbox.js +4 -0
- package/dist/esm/core/abis/broker.js +5 -0
- package/dist/esm/core/abis/erc20.js +17 -0
- package/dist/esm/core/abis/fpmm.js +45 -0
- package/dist/esm/core/abis/fpmmFactory.js +22 -0
- package/dist/esm/core/abis/hintHelpers.js +10 -0
- package/dist/esm/core/abis/index.js +21 -0
- package/dist/esm/core/abis/liquidityStrategy.js +6 -0
- package/dist/esm/core/abis/multiTroveGetter.js +11 -0
- package/dist/esm/core/abis/priceFeed.js +12 -0
- package/dist/esm/core/abis/pricingmodule.js +2 -0
- package/dist/esm/core/abis/reserve.js +14 -0
- package/dist/esm/core/abis/router.js +41 -0
- package/dist/esm/core/abis/sortedTroves.js +11 -0
- package/dist/esm/core/abis/systemParams.js +10 -0
- package/dist/esm/core/abis/troveManager.js +23 -0
- package/dist/esm/core/abis/troveNFT.js +5 -0
- package/dist/esm/core/abis/virtualPool.js +7 -0
- package/dist/esm/core/abis/virtualPoolFactory.js +13 -0
- package/dist/esm/core/constants/addresses.js +119 -0
- package/dist/esm/core/constants/borrowConstants.js +12 -0
- package/dist/esm/core/constants/borrowRegistries.js +29 -0
- package/dist/esm/core/constants/chainId.js +8 -0
- package/dist/esm/core/constants/contractNames.js +20 -0
- package/dist/esm/core/constants/index.js +5 -0
- package/dist/esm/core/errors/base.js +12 -0
- package/dist/esm/core/errors/index.js +3 -0
- package/dist/esm/core/errors/oracle.js +10 -0
- package/dist/esm/core/errors/router.js +18 -0
- package/dist/esm/core/types/borrow.js +1 -0
- package/dist/esm/core/types/contractAddresses.js +1 -0
- package/dist/esm/core/types/index.js +9 -0
- package/dist/esm/core/types/liquidity.js +1 -0
- package/dist/esm/core/types/pool.js +10 -0
- package/dist/esm/core/types/provider.js +1 -0
- package/dist/esm/core/types/route.js +1 -0
- package/dist/esm/core/types/token.js +1 -0
- package/dist/esm/core/types/tradingLimits.js +1 -0
- package/dist/esm/core/types/tradingMode.js +26 -0
- package/dist/esm/core/types/transaction.js +1 -0
- package/dist/esm/index.js +139 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/services/borrow/BorrowService.js +455 -0
- package/dist/esm/services/borrow/borrowHelpers.js +3 -0
- package/dist/esm/services/borrow/borrowMath.js +127 -0
- package/dist/esm/services/borrow/index.js +3 -0
- package/dist/esm/services/borrow/internal/borrowApprovalService.js +48 -0
- package/dist/esm/services/borrow/internal/borrowContextStore.js +35 -0
- package/dist/esm/services/borrow/internal/borrowErc20.js +38 -0
- package/dist/esm/services/borrow/internal/borrowHints.js +27 -0
- package/dist/esm/services/borrow/internal/borrowPositionParser.js +82 -0
- package/dist/esm/services/borrow/internal/borrowReadService.js +271 -0
- package/dist/esm/services/borrow/internal/borrowRegistryReader.js +108 -0
- package/dist/esm/services/borrow/internal/borrowTransactionService.js +271 -0
- package/dist/esm/services/borrow/internal/borrowTypes.js +1 -0
- package/dist/esm/services/borrow/internal/borrowValidation.js +89 -0
- package/dist/esm/services/index.js +8 -0
- package/dist/esm/services/liquidity/LiquidityService.js +163 -0
- package/dist/esm/services/liquidity/basicLiquidity.js +162 -0
- package/dist/esm/services/liquidity/index.js +1 -0
- package/dist/esm/services/liquidity/liquidityHelpers.js +95 -0
- package/dist/esm/services/liquidity/rebalance.js +59 -0
- package/dist/esm/services/liquidity/zapHelpers.js +181 -0
- package/dist/esm/services/liquidity/zapIn.js +131 -0
- package/dist/esm/services/liquidity/zapOut.js +248 -0
- package/dist/esm/services/pools/PoolService.js +204 -0
- package/dist/esm/services/pools/index.js +1 -0
- package/dist/esm/services/pools/poolDetails.js +209 -0
- package/dist/esm/services/pools/poolDiscovery.js +112 -0
- package/dist/esm/services/pools/rebalancePreview.js +181 -0
- package/dist/esm/services/quotes/QuoteService.js +85 -0
- package/dist/esm/services/quotes/index.js +1 -0
- package/dist/esm/services/routes/RouteService.js +268 -0
- package/dist/esm/services/routes/index.js +1 -0
- package/dist/esm/services/swap/SwapService.js +247 -0
- package/dist/esm/services/swap/index.js +1 -0
- package/dist/esm/services/tokens/index.js +1 -0
- package/dist/esm/services/tokens/tokenService.js +285 -0
- package/dist/esm/services/trading/TradingLimitsService.js +154 -0
- package/dist/esm/services/trading/TradingService.js +222 -0
- package/dist/esm/services/trading/index.js +2 -0
- package/dist/esm/utils/chainConfig.js +122 -0
- package/dist/esm/utils/costUtils.js +56 -0
- package/dist/esm/utils/deadline.js +22 -0
- package/dist/esm/utils/index.js +9 -0
- package/dist/esm/utils/multicall.js +47 -0
- package/dist/esm/utils/pathEncoder.js +69 -0
- package/dist/esm/utils/rateFeed.js +23 -0
- package/dist/esm/utils/retry.js +24 -0
- package/dist/esm/utils/routeUtils.js +361 -0
- package/dist/esm/utils/routes.js +2 -0
- package/dist/esm/utils/sortUtils.js +33 -0
- package/dist/esm/utils/tokens.js +2 -0
- package/dist/esm/utils/tradingLimits.js +163 -0
- package/dist/esm/utils/validation.js +30 -0
- package/dist/index.d.ts +101 -0
- package/dist/index.js +158 -0
- package/dist/services/borrow/BorrowService.d.ts +381 -0
- package/dist/services/borrow/BorrowService.js +460 -0
- package/dist/services/borrow/borrowHelpers.d.ts +4 -0
- package/dist/services/borrow/borrowHelpers.js +13 -0
- package/dist/services/borrow/borrowMath.d.ts +21 -0
- package/dist/services/borrow/borrowMath.js +137 -0
- package/dist/services/borrow/index.d.ts +4 -0
- package/dist/services/borrow/index.js +20 -0
- package/dist/services/borrow/internal/borrowApprovalService.d.ts +14 -0
- package/dist/services/borrow/internal/borrowApprovalService.js +53 -0
- package/dist/services/borrow/internal/borrowContextStore.d.ts +11 -0
- package/dist/services/borrow/internal/borrowContextStore.js +40 -0
- package/dist/services/borrow/internal/borrowErc20.d.ts +5 -0
- package/dist/services/borrow/internal/borrowErc20.js +43 -0
- package/dist/services/borrow/internal/borrowHints.d.ts +7 -0
- package/dist/services/borrow/internal/borrowHints.js +31 -0
- package/dist/services/borrow/internal/borrowPositionParser.d.ts +4 -0
- package/dist/services/borrow/internal/borrowPositionParser.js +87 -0
- package/dist/services/borrow/internal/borrowReadService.d.ts +31 -0
- package/dist/services/borrow/internal/borrowReadService.js +276 -0
- package/dist/services/borrow/internal/borrowRegistryReader.d.ts +5 -0
- package/dist/services/borrow/internal/borrowRegistryReader.js +113 -0
- package/dist/services/borrow/internal/borrowTransactionService.d.ts +23 -0
- package/dist/services/borrow/internal/borrowTransactionService.js +276 -0
- package/dist/services/borrow/internal/borrowTypes.d.ts +15 -0
- package/dist/services/borrow/internal/borrowTypes.js +3 -0
- package/dist/services/borrow/internal/borrowValidation.d.ts +14 -0
- package/dist/services/borrow/internal/borrowValidation.js +104 -0
- package/dist/services/index.d.ts +9 -0
- package/dist/services/index.js +25 -0
- package/dist/services/liquidity/LiquidityService.d.ts +139 -0
- package/dist/services/liquidity/LiquidityService.js +168 -0
- package/dist/services/liquidity/basicLiquidity.d.ts +11 -0
- package/dist/services/liquidity/basicLiquidity.js +172 -0
- package/dist/services/liquidity/index.d.ts +2 -0
- package/dist/services/liquidity/index.js +18 -0
- package/dist/services/liquidity/liquidityHelpers.d.ts +19 -0
- package/dist/services/liquidity/liquidityHelpers.js +104 -0
- package/dist/services/liquidity/rebalance.d.ts +6 -0
- package/dist/services/liquidity/rebalance.js +64 -0
- package/dist/services/liquidity/zapHelpers.d.ts +100 -0
- package/dist/services/liquidity/zapHelpers.js +192 -0
- package/dist/services/liquidity/zapIn.d.ts +18 -0
- package/dist/services/liquidity/zapIn.js +138 -0
- package/dist/services/liquidity/zapOut.d.ts +9 -0
- package/dist/services/liquidity/zapOut.js +255 -0
- package/dist/services/pools/PoolService.d.ts +69 -0
- package/dist/services/pools/PoolService.js +209 -0
- package/dist/services/pools/index.d.ts +2 -0
- package/dist/services/pools/index.js +18 -0
- package/dist/services/pools/poolDetails.d.ts +13 -0
- package/dist/services/pools/poolDetails.js +216 -0
- package/dist/services/pools/poolDiscovery.d.ts +12 -0
- package/dist/services/pools/poolDiscovery.js +117 -0
- package/dist/services/pools/rebalancePreview.d.ts +5 -0
- package/dist/services/pools/rebalancePreview.js +186 -0
- package/dist/services/quotes/QuoteService.d.ts +51 -0
- package/dist/services/quotes/QuoteService.js +91 -0
- package/dist/services/quotes/index.d.ts +2 -0
- package/dist/services/quotes/index.js +18 -0
- package/dist/services/routes/RouteService.d.ts +117 -0
- package/dist/services/routes/RouteService.js +306 -0
- package/dist/services/routes/index.d.ts +2 -0
- package/dist/services/routes/index.js +18 -0
- package/dist/services/swap/SwapService.d.ts +198 -0
- package/dist/services/swap/SwapService.js +252 -0
- package/dist/services/swap/index.d.ts +2 -0
- package/dist/services/swap/index.js +18 -0
- package/dist/services/tokens/index.d.ts +2 -0
- package/dist/services/tokens/index.js +18 -0
- package/dist/services/tokens/tokenService.d.ts +55 -0
- package/dist/services/tokens/tokenService.js +290 -0
- package/dist/services/trading/TradingLimitsService.d.ts +38 -0
- package/dist/services/trading/TradingLimitsService.js +159 -0
- package/dist/services/trading/TradingService.d.ts +115 -0
- package/dist/services/trading/TradingService.js +227 -0
- package/dist/services/trading/index.d.ts +3 -0
- package/dist/services/trading/index.js +19 -0
- package/dist/utils/chainConfig.d.ts +16 -0
- package/dist/utils/chainConfig.js +127 -0
- package/dist/utils/costUtils.d.ts +12 -0
- package/dist/utils/costUtils.js +60 -0
- package/dist/utils/deadline.d.ts +21 -0
- package/dist/utils/deadline.js +26 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.js +26 -0
- package/dist/utils/multicall.d.ts +30 -0
- package/dist/utils/multicall.js +52 -0
- package/dist/utils/pathEncoder.d.ts +34 -0
- package/dist/utils/pathEncoder.js +73 -0
- package/dist/utils/rateFeed.d.ts +18 -0
- package/dist/utils/rateFeed.js +27 -0
- package/dist/utils/retry.d.ts +12 -0
- package/dist/utils/retry.js +28 -0
- package/dist/utils/routeUtils.d.ts +295 -0
- package/dist/utils/routeUtils.js +371 -0
- package/dist/utils/routes.d.ts +3 -0
- package/dist/utils/routes.js +8 -0
- package/dist/utils/sortUtils.d.ts +24 -0
- package/dist/utils/sortUtils.js +39 -0
- package/dist/utils/tokens.d.ts +2 -0
- package/dist/utils/tokens.js +13 -0
- package/dist/utils/tradingLimits.d.ts +41 -0
- package/dist/utils/tradingLimits.js +171 -0
- package/dist/utils/validation.d.ts +19 -0
- package/dist/utils/validation.js +34 -0
- package/package.json +1 -1
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SwapService = void 0;
|
|
4
|
+
const viem_1 = require("viem");
|
|
5
|
+
const abis_1 = require("../../core/abis");
|
|
6
|
+
const constants_1 = require("../../core/constants");
|
|
7
|
+
const pathEncoder_1 = require("../../utils/pathEncoder");
|
|
8
|
+
const validation_1 = require("../../utils/validation");
|
|
9
|
+
const utils_1 = require("../../utils");
|
|
10
|
+
const QuoteService_1 = require("../quotes/QuoteService");
|
|
11
|
+
/**
|
|
12
|
+
* Service for building token swap transactions on the Mento protocol.
|
|
13
|
+
* Returns transaction parameters that can be executed by any wallet.
|
|
14
|
+
*/
|
|
15
|
+
class SwapService {
|
|
16
|
+
constructor(publicClient, chainId, routeService, quoteService) {
|
|
17
|
+
this.publicClient = publicClient;
|
|
18
|
+
this.chainId = chainId;
|
|
19
|
+
this.routeService = routeService;
|
|
20
|
+
this.quoteService = quoteService;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Builds a complete swap transaction including approval if needed.
|
|
24
|
+
* This is the recommended method for most use cases.
|
|
25
|
+
*
|
|
26
|
+
* @param tokenIn - The address of the input token (e.g., '0x765DE816845861e75A25fCA122bb6898B8B1282a')
|
|
27
|
+
* @param tokenOut - The address of the output token (e.g., '0x471EcE3750Da237f93B8E339c536989b8978a438')
|
|
28
|
+
* @param amountIn - The amount of input tokens (in wei/smallest unit)
|
|
29
|
+
* @param recipient - The address to receive the output tokens
|
|
30
|
+
* @param owner - The address that owns the input tokens (needed to check allowance)
|
|
31
|
+
* @param options - Swap configuration options (slippage, deadline)
|
|
32
|
+
* @param route - Optional pre-fetched route for better performance
|
|
33
|
+
* @returns Combined transaction with approval (if needed) and swap params
|
|
34
|
+
* @throws {Error} 'amountIn must be greater than zero' - if amountIn <= 0
|
|
35
|
+
* @throws {Error} 'Slippage tolerance cannot be negative' - if slippageTolerance < 0
|
|
36
|
+
* @throws {Error} 'Slippage tolerance exceeds maximum' - if slippageTolerance > 20%
|
|
37
|
+
* @throws {Error} 'Deadline must be in the future' - if deadline is not a future timestamp
|
|
38
|
+
* @throws {Error} Invalid address - if any address parameter is not a valid Ethereum address
|
|
39
|
+
* @throws {RouteNotFoundError} If no trading route exists between the token pair
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const { approval, swap } = await mento.swap.buildSwapTransaction(
|
|
44
|
+
* '0x765DE816845861e75A25fCA122bb6898B8B1282a', // USDm
|
|
45
|
+
* '0x471EcE3750Da237f93B8E339c536989b8978a438', // CELO
|
|
46
|
+
* parseUnits('100', 18),
|
|
47
|
+
* '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', // recipient
|
|
48
|
+
* '0x123...', // owner
|
|
49
|
+
* { slippageTolerance: 0.5, deadline: deadlineFromMinutes(5) }
|
|
50
|
+
* )
|
|
51
|
+
*
|
|
52
|
+
* // Execute approval if needed
|
|
53
|
+
* if (approval) {
|
|
54
|
+
* await walletClient.sendTransaction(approval)
|
|
55
|
+
* }
|
|
56
|
+
*
|
|
57
|
+
* // Execute swap
|
|
58
|
+
* await walletClient.sendTransaction(swap.params)
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
async buildSwapTransaction(tokenIn, tokenOut, amountIn, recipient, owner, options, route) {
|
|
62
|
+
const prepared = await this.prepareSwap({
|
|
63
|
+
amountIn,
|
|
64
|
+
deadline: options.deadline,
|
|
65
|
+
owner,
|
|
66
|
+
recipient,
|
|
67
|
+
route,
|
|
68
|
+
slippageTolerance: options.slippageTolerance,
|
|
69
|
+
tokenIn,
|
|
70
|
+
tokenOut,
|
|
71
|
+
});
|
|
72
|
+
if (!prepared.params) {
|
|
73
|
+
throw new Error('Swap params were not prepared');
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
approval: prepared.approval ?? null,
|
|
77
|
+
swap: {
|
|
78
|
+
params: prepared.params,
|
|
79
|
+
route: prepared.route,
|
|
80
|
+
routerRoutes: prepared.routerRoutes,
|
|
81
|
+
amountIn,
|
|
82
|
+
amountOutMin: prepared.amountOutMin,
|
|
83
|
+
expectedAmountOut: prepared.expectedAmountOut,
|
|
84
|
+
deadline: options.deadline,
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Builds swap transaction parameters without executing the transaction.
|
|
90
|
+
* Does NOT check or handle token approval - use buildSwapTransaction for that.
|
|
91
|
+
*
|
|
92
|
+
* @param tokenIn - The address of the input token (e.g., '0x765DE816845861e75A25fCA122bb6898B8B1282a')
|
|
93
|
+
* @param tokenOut - The address of the output token (e.g., '0x471EcE3750Da237f93B8E339c536989b8978a438')
|
|
94
|
+
* @param amountIn - The amount of input tokens (in wei/smallest unit)
|
|
95
|
+
* @param recipient - The address to receive the output tokens
|
|
96
|
+
* @param options - Swap configuration options (slippage, deadline)
|
|
97
|
+
* @param route - Optional pre-fetched route for better performance
|
|
98
|
+
* @returns Detailed swap parameters including transaction data
|
|
99
|
+
* @throws {Error} 'amountIn must be greater than zero' - if amountIn <= 0
|
|
100
|
+
* @throws {Error} 'Slippage tolerance cannot be negative' - if slippageTolerance < 0
|
|
101
|
+
* @throws {Error} 'Slippage tolerance exceeds maximum' - if slippageTolerance > 20%
|
|
102
|
+
* @throws {Error} 'Deadline must be in the future' - if deadline is not a future timestamp
|
|
103
|
+
* @throws {Error} Invalid address - if any address parameter is not a valid Ethereum address
|
|
104
|
+
* @throws {RouteNotFoundError} If no trading route exists between the token pair
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* const swapDetails = await mento.swap.buildSwapParams(
|
|
109
|
+
* '0x765DE816845861e75A25fCA122bb6898B8B1282a', // USDm
|
|
110
|
+
* '0x471EcE3750Da237f93B8E339c536989b8978a438', // CELO
|
|
111
|
+
* parseUnits('100', 18),
|
|
112
|
+
* '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', // recipient
|
|
113
|
+
* { slippageTolerance: 0.5, deadline: deadlineFromMinutes(5) }
|
|
114
|
+
* )
|
|
115
|
+
*
|
|
116
|
+
* // Execute with any wallet (assumes approval already granted)
|
|
117
|
+
* await walletClient.sendTransaction(swapDetails.params)
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
async buildSwapParams(tokenIn, tokenOut, amountIn, recipient, options, route) {
|
|
121
|
+
const prepared = await this.prepareSwap({
|
|
122
|
+
amountIn,
|
|
123
|
+
deadline: options.deadline,
|
|
124
|
+
recipient,
|
|
125
|
+
route,
|
|
126
|
+
slippageTolerance: options.slippageTolerance,
|
|
127
|
+
tokenIn,
|
|
128
|
+
tokenOut,
|
|
129
|
+
});
|
|
130
|
+
if (!prepared.params) {
|
|
131
|
+
throw new Error('Swap params were not prepared');
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
params: prepared.params,
|
|
135
|
+
route: prepared.route,
|
|
136
|
+
routerRoutes: prepared.routerRoutes,
|
|
137
|
+
amountIn,
|
|
138
|
+
amountOutMin: prepared.amountOutMin,
|
|
139
|
+
expectedAmountOut: prepared.expectedAmountOut,
|
|
140
|
+
deadline: options.deadline,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
async prepareSwap(input) {
|
|
144
|
+
this.validateAmountIn(input.amountIn);
|
|
145
|
+
(0, validation_1.validateAddress)(input.tokenIn, 'tokenIn');
|
|
146
|
+
(0, validation_1.validateAddress)(input.tokenOut, 'tokenOut');
|
|
147
|
+
if (input.recipient) {
|
|
148
|
+
(0, validation_1.validateAddress)(input.recipient, 'recipient');
|
|
149
|
+
}
|
|
150
|
+
if (input.owner) {
|
|
151
|
+
(0, validation_1.validateAddress)(input.owner, 'owner');
|
|
152
|
+
}
|
|
153
|
+
if (input.deadline !== undefined && input.deadline <= BigInt(Date.now()) / 1000n) {
|
|
154
|
+
throw new Error('Deadline must be in the future');
|
|
155
|
+
}
|
|
156
|
+
const route = input.route ?? await this.routeService.findRoute(input.tokenIn, input.tokenOut);
|
|
157
|
+
const routerRoutes = (0, pathEncoder_1.encodeRoutePath)(route.path, input.tokenIn, input.tokenOut);
|
|
158
|
+
const expectedAmountOut = await (0, QuoteService_1.getAmountOutForRoute)(this.publicClient, this.chainId, input.tokenIn, input.tokenOut, input.amountIn, route);
|
|
159
|
+
const amountOutMin = this.calculateMinAmountOut(expectedAmountOut, input.slippageTolerance);
|
|
160
|
+
const prepared = {
|
|
161
|
+
route,
|
|
162
|
+
routerRoutes,
|
|
163
|
+
expectedAmountOut,
|
|
164
|
+
amountOutMin,
|
|
165
|
+
};
|
|
166
|
+
if (input.owner) {
|
|
167
|
+
const currentAllowance = await this.getAllowance(input.tokenIn, input.owner);
|
|
168
|
+
prepared.approval = currentAllowance < input.amountIn
|
|
169
|
+
? this.buildApprovalParams(input.tokenIn, input.amountIn)
|
|
170
|
+
: null;
|
|
171
|
+
}
|
|
172
|
+
if (input.recipient && input.deadline !== undefined) {
|
|
173
|
+
const routerAddress = (0, constants_1.getContractAddress)(this.chainId, 'Router');
|
|
174
|
+
const data = this.encodeSwapCall(input.amountIn, amountOutMin, routerRoutes, input.recipient, input.deadline);
|
|
175
|
+
prepared.params = {
|
|
176
|
+
to: routerAddress,
|
|
177
|
+
data,
|
|
178
|
+
value: '0',
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
return prepared;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Builds approval transaction params for the Router to spend tokenIn
|
|
185
|
+
* @private
|
|
186
|
+
*/
|
|
187
|
+
buildApprovalParams(tokenIn, amount) {
|
|
188
|
+
const routerAddress = (0, constants_1.getContractAddress)(this.chainId, 'Router');
|
|
189
|
+
const data = (0, viem_1.encodeFunctionData)({
|
|
190
|
+
abi: abis_1.ERC20_ABI,
|
|
191
|
+
functionName: 'approve',
|
|
192
|
+
args: [routerAddress, amount],
|
|
193
|
+
});
|
|
194
|
+
return { to: tokenIn, data, value: '0' };
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Gets current allowance for the Router contract
|
|
198
|
+
* @private
|
|
199
|
+
*/
|
|
200
|
+
async getAllowance(tokenIn, owner) {
|
|
201
|
+
const routerAddress = (0, constants_1.getContractAddress)(this.chainId, 'Router');
|
|
202
|
+
return (0, utils_1.retryOperation)(() => this.publicClient.readContract({
|
|
203
|
+
address: tokenIn,
|
|
204
|
+
abi: abis_1.ERC20_ABI,
|
|
205
|
+
functionName: 'allowance',
|
|
206
|
+
args: [owner, routerAddress],
|
|
207
|
+
}));
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Validates that the input amount is strictly positive.
|
|
211
|
+
* @private
|
|
212
|
+
*/
|
|
213
|
+
validateAmountIn(amountIn) {
|
|
214
|
+
if (amountIn <= 0n) {
|
|
215
|
+
throw new Error('amountIn must be greater than zero');
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Calculates minimum output amount after applying slippage tolerance
|
|
220
|
+
* @param amountOut - Expected output amount
|
|
221
|
+
* @param slippageTolerance - Slippage tolerance as percentage (e.g., 0.5 for 0.5%)
|
|
222
|
+
* @returns Minimum acceptable output amount
|
|
223
|
+
* @throws Error if slippage tolerance is invalid
|
|
224
|
+
* @private
|
|
225
|
+
*/
|
|
226
|
+
calculateMinAmountOut(amountOut, slippageTolerance) {
|
|
227
|
+
const MAX_SLIPPAGE_TOLERANCE = 20; // 20% max
|
|
228
|
+
if (slippageTolerance < 0) {
|
|
229
|
+
throw new Error('Slippage tolerance cannot be negative');
|
|
230
|
+
}
|
|
231
|
+
if (slippageTolerance > MAX_SLIPPAGE_TOLERANCE) {
|
|
232
|
+
throw new Error(`Slippage tolerance ${slippageTolerance}% exceeds maximum of ${MAX_SLIPPAGE_TOLERANCE}%. ` +
|
|
233
|
+
'High slippage makes transactions vulnerable to sandwich attacks.');
|
|
234
|
+
}
|
|
235
|
+
const basisPoints = BigInt(Math.floor(slippageTolerance * 100));
|
|
236
|
+
const slippageMultiplier = 10000n - basisPoints;
|
|
237
|
+
return (amountOut * slippageMultiplier) / 10000n;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Encodes the swapExactTokensForTokens function call
|
|
241
|
+
* @private
|
|
242
|
+
*/
|
|
243
|
+
encodeSwapCall(amountIn, amountOutMin, routes, recipient, deadline) {
|
|
244
|
+
return (0, viem_1.encodeFunctionData)({
|
|
245
|
+
abi: abis_1.ROUTER_ABI,
|
|
246
|
+
functionName: 'swapExactTokensForTokens',
|
|
247
|
+
args: [amountIn, amountOutMin, routes, recipient, deadline],
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
exports.SwapService = SwapService;
|
|
252
|
+
//# sourceMappingURL=SwapService.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./SwapService"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./tokenService"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { StableToken, CollateralAsset } from '../../core/types';
|
|
2
|
+
import type { PublicClient } from 'viem';
|
|
3
|
+
export declare class TokenService {
|
|
4
|
+
private publicClient;
|
|
5
|
+
private chainId;
|
|
6
|
+
private tokenMetadataCache;
|
|
7
|
+
constructor(publicClient: PublicClient, chainId: number);
|
|
8
|
+
private isReserveV2;
|
|
9
|
+
/**
|
|
10
|
+
* Get token metadata (name, symbol, decimals)
|
|
11
|
+
* @param address - Token contract address
|
|
12
|
+
* @returns Token metadata
|
|
13
|
+
*/
|
|
14
|
+
private getTokenMetadata;
|
|
15
|
+
private getTokenMetadataBatch;
|
|
16
|
+
private readTokenMetadataWithRetry;
|
|
17
|
+
/**
|
|
18
|
+
* Get total supply of a token
|
|
19
|
+
* @param address - Token contract address
|
|
20
|
+
* @returns Total supply as string
|
|
21
|
+
*/
|
|
22
|
+
private getTotalSupply;
|
|
23
|
+
private getTotalSupplyBatch;
|
|
24
|
+
private readTotalSupplyWithRetry;
|
|
25
|
+
private getCollateralStatusBatch;
|
|
26
|
+
private readCollateralStatusWithRetry;
|
|
27
|
+
/**
|
|
28
|
+
* Get stable token addresses from the Reserve contract.
|
|
29
|
+
* Uses getStableAssets() on ReserveV2, getTokens() on legacy Reserve.
|
|
30
|
+
*/
|
|
31
|
+
private getStableTokenAddresses;
|
|
32
|
+
/**
|
|
33
|
+
* Get all stable tokens from the Reserve contract.
|
|
34
|
+
* Returns the actual on-chain ERC20 totalSupply values without adjustments.
|
|
35
|
+
* @param includeSupply - Whether to fetch total supply
|
|
36
|
+
* @returns Array of stable tokens
|
|
37
|
+
*/
|
|
38
|
+
getStableTokens(includeSupply?: boolean): Promise<StableToken[]>;
|
|
39
|
+
/**
|
|
40
|
+
* Get all collateral assets.
|
|
41
|
+
* On ReserveV2 chains, queries the reserve directly.
|
|
42
|
+
* On legacy chains, discovers collateral via BiPoolManager exchanges.
|
|
43
|
+
* @returns Array of collateral assets
|
|
44
|
+
*/
|
|
45
|
+
getCollateralAssets(): Promise<CollateralAsset[]>;
|
|
46
|
+
/**
|
|
47
|
+
* Get collateral assets directly from ReserveV2.
|
|
48
|
+
*/
|
|
49
|
+
private getCollateralAssetsV2;
|
|
50
|
+
/**
|
|
51
|
+
* Get collateral assets from legacy Reserve via BiPoolManager exchanges.
|
|
52
|
+
*/
|
|
53
|
+
private getCollateralAssetsLegacy;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=tokenService.d.ts.map
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TokenService = void 0;
|
|
4
|
+
const abis_1 = require("../../core/abis");
|
|
5
|
+
const constants_1 = require("../../core/constants");
|
|
6
|
+
const utils_1 = require("../../utils");
|
|
7
|
+
const multicall_1 = require("../../utils/multicall");
|
|
8
|
+
/**
|
|
9
|
+
* Chains that use ReserveV2 (v3) instead of the legacy Reserve contract.
|
|
10
|
+
*/
|
|
11
|
+
const RESERVE_V2_CHAINS = new Set([constants_1.ChainId.MONAD_TESTNET, constants_1.ChainId.MONAD, constants_1.ChainId.POLYGON_AMOY]);
|
|
12
|
+
class TokenService {
|
|
13
|
+
constructor(publicClient, chainId) {
|
|
14
|
+
this.publicClient = publicClient;
|
|
15
|
+
this.chainId = chainId;
|
|
16
|
+
this.tokenMetadataCache = new Map();
|
|
17
|
+
}
|
|
18
|
+
isReserveV2() {
|
|
19
|
+
return RESERVE_V2_CHAINS.has(this.chainId);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get token metadata (name, symbol, decimals)
|
|
23
|
+
* @param address - Token contract address
|
|
24
|
+
* @returns Token metadata
|
|
25
|
+
*/
|
|
26
|
+
async getTokenMetadata(address) {
|
|
27
|
+
const cacheKey = address.toLowerCase();
|
|
28
|
+
const cached = this.tokenMetadataCache.get(cacheKey);
|
|
29
|
+
if (cached) {
|
|
30
|
+
return cached;
|
|
31
|
+
}
|
|
32
|
+
const [metadata] = await this.getTokenMetadataBatch([address]);
|
|
33
|
+
this.tokenMetadataCache.set(cacheKey, metadata);
|
|
34
|
+
return metadata;
|
|
35
|
+
}
|
|
36
|
+
async getTokenMetadataBatch(addresses) {
|
|
37
|
+
if (addresses.length === 0) {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
const results = new Array(addresses.length);
|
|
41
|
+
const missing = [];
|
|
42
|
+
for (const [index, address] of addresses.entries()) {
|
|
43
|
+
const cached = this.tokenMetadataCache.get(address.toLowerCase());
|
|
44
|
+
if (cached) {
|
|
45
|
+
results[index] = cached;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
missing.push({ address, index });
|
|
49
|
+
}
|
|
50
|
+
if (missing.length === 0) {
|
|
51
|
+
return results;
|
|
52
|
+
}
|
|
53
|
+
const multicallResults = await (0, multicall_1.multicall)(this.publicClient, missing.flatMap(({ address }) => ([
|
|
54
|
+
{
|
|
55
|
+
address: address,
|
|
56
|
+
abi: abis_1.ERC20_ABI,
|
|
57
|
+
functionName: 'name',
|
|
58
|
+
args: [],
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
address: address,
|
|
62
|
+
abi: abis_1.ERC20_ABI,
|
|
63
|
+
functionName: 'symbol',
|
|
64
|
+
args: [],
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
address: address,
|
|
68
|
+
abi: abis_1.ERC20_ABI,
|
|
69
|
+
functionName: 'decimals',
|
|
70
|
+
args: [],
|
|
71
|
+
},
|
|
72
|
+
])), { allowFailure: true });
|
|
73
|
+
const hydrated = await Promise.all(missing.map(async ({ address }, index) => {
|
|
74
|
+
const resultOffset = index * 3;
|
|
75
|
+
const name = multicallResults[resultOffset];
|
|
76
|
+
const symbol = multicallResults[resultOffset + 1];
|
|
77
|
+
const decimals = multicallResults[resultOffset + 2];
|
|
78
|
+
if (name?.status === 'success' &&
|
|
79
|
+
symbol?.status === 'success' &&
|
|
80
|
+
decimals?.status === 'success') {
|
|
81
|
+
return {
|
|
82
|
+
name: name.result,
|
|
83
|
+
symbol: symbol.result,
|
|
84
|
+
decimals: Number(decimals.result),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return this.readTokenMetadataWithRetry(address);
|
|
88
|
+
}));
|
|
89
|
+
for (const [index, metadata] of hydrated.entries()) {
|
|
90
|
+
const address = missing[index].address;
|
|
91
|
+
this.tokenMetadataCache.set(address.toLowerCase(), metadata);
|
|
92
|
+
results[missing[index].index] = metadata;
|
|
93
|
+
}
|
|
94
|
+
return results;
|
|
95
|
+
}
|
|
96
|
+
async readTokenMetadataWithRetry(address) {
|
|
97
|
+
const [name, symbol, decimals] = await Promise.all([
|
|
98
|
+
(0, utils_1.retryOperation)(() => this.publicClient.readContract({
|
|
99
|
+
address: address,
|
|
100
|
+
abi: abis_1.ERC20_ABI,
|
|
101
|
+
functionName: 'name',
|
|
102
|
+
args: [],
|
|
103
|
+
})),
|
|
104
|
+
(0, utils_1.retryOperation)(() => this.publicClient.readContract({
|
|
105
|
+
address: address,
|
|
106
|
+
abi: abis_1.ERC20_ABI,
|
|
107
|
+
functionName: 'symbol',
|
|
108
|
+
args: [],
|
|
109
|
+
})),
|
|
110
|
+
(0, utils_1.retryOperation)(() => this.publicClient.readContract({
|
|
111
|
+
address: address,
|
|
112
|
+
abi: abis_1.ERC20_ABI,
|
|
113
|
+
functionName: 'decimals',
|
|
114
|
+
args: [],
|
|
115
|
+
})),
|
|
116
|
+
]);
|
|
117
|
+
return {
|
|
118
|
+
name: name,
|
|
119
|
+
symbol: symbol,
|
|
120
|
+
decimals: Number(decimals),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get total supply of a token
|
|
125
|
+
* @param address - Token contract address
|
|
126
|
+
* @returns Total supply as string
|
|
127
|
+
*/
|
|
128
|
+
async getTotalSupply(address) {
|
|
129
|
+
const [totalSupply] = await this.getTotalSupplyBatch([address]);
|
|
130
|
+
return totalSupply;
|
|
131
|
+
}
|
|
132
|
+
async getTotalSupplyBatch(addresses) {
|
|
133
|
+
if (addresses.length === 0) {
|
|
134
|
+
return [];
|
|
135
|
+
}
|
|
136
|
+
const results = await (0, multicall_1.multicall)(this.publicClient, addresses.map((address) => ({
|
|
137
|
+
address: address,
|
|
138
|
+
abi: abis_1.ERC20_ABI,
|
|
139
|
+
functionName: 'totalSupply',
|
|
140
|
+
args: [],
|
|
141
|
+
})), { allowFailure: true });
|
|
142
|
+
return Promise.all(addresses.map(async (address, index) => {
|
|
143
|
+
const result = results[index];
|
|
144
|
+
if (result?.status === 'success') {
|
|
145
|
+
return result.result.toString();
|
|
146
|
+
}
|
|
147
|
+
return this.readTotalSupplyWithRetry(address);
|
|
148
|
+
}));
|
|
149
|
+
}
|
|
150
|
+
async readTotalSupplyWithRetry(address) {
|
|
151
|
+
const totalSupply = await (0, utils_1.retryOperation)(() => this.publicClient.readContract({
|
|
152
|
+
address: address,
|
|
153
|
+
abi: abis_1.ERC20_ABI,
|
|
154
|
+
functionName: 'totalSupply',
|
|
155
|
+
args: [],
|
|
156
|
+
}));
|
|
157
|
+
return totalSupply.toString();
|
|
158
|
+
}
|
|
159
|
+
async getCollateralStatusBatch(reserveAddress, addresses) {
|
|
160
|
+
if (addresses.length === 0) {
|
|
161
|
+
return [];
|
|
162
|
+
}
|
|
163
|
+
const results = await (0, multicall_1.multicall)(this.publicClient, addresses.map((address) => ({
|
|
164
|
+
address: reserveAddress,
|
|
165
|
+
abi: abis_1.RESERVE_ABI,
|
|
166
|
+
functionName: 'isCollateralAsset',
|
|
167
|
+
args: [address],
|
|
168
|
+
})), { allowFailure: true });
|
|
169
|
+
return Promise.all(addresses.map(async (address, index) => {
|
|
170
|
+
const result = results[index];
|
|
171
|
+
if (result?.status === 'success') {
|
|
172
|
+
return result.result;
|
|
173
|
+
}
|
|
174
|
+
return this.readCollateralStatusWithRetry(reserveAddress, address);
|
|
175
|
+
}));
|
|
176
|
+
}
|
|
177
|
+
async readCollateralStatusWithRetry(reserveAddress, address) {
|
|
178
|
+
return (0, utils_1.retryOperation)(() => this.publicClient.readContract({
|
|
179
|
+
address: reserveAddress,
|
|
180
|
+
abi: abis_1.RESERVE_ABI,
|
|
181
|
+
functionName: 'isCollateralAsset',
|
|
182
|
+
args: [address],
|
|
183
|
+
}));
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Get stable token addresses from the Reserve contract.
|
|
187
|
+
* Uses getStableAssets() on ReserveV2, getTokens() on legacy Reserve.
|
|
188
|
+
*/
|
|
189
|
+
async getStableTokenAddresses(reserveAddress) {
|
|
190
|
+
if (this.isReserveV2()) {
|
|
191
|
+
return (await this.publicClient.readContract({
|
|
192
|
+
address: reserveAddress,
|
|
193
|
+
abi: abis_1.RESERVE_V2_ABI,
|
|
194
|
+
functionName: 'getStableAssets',
|
|
195
|
+
args: [],
|
|
196
|
+
}));
|
|
197
|
+
}
|
|
198
|
+
return (await this.publicClient.readContract({
|
|
199
|
+
address: reserveAddress,
|
|
200
|
+
abi: abis_1.RESERVE_ABI,
|
|
201
|
+
functionName: 'getTokens',
|
|
202
|
+
args: [],
|
|
203
|
+
}));
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Get all stable tokens from the Reserve contract.
|
|
207
|
+
* Returns the actual on-chain ERC20 totalSupply values without adjustments.
|
|
208
|
+
* @param includeSupply - Whether to fetch total supply
|
|
209
|
+
* @returns Array of stable tokens
|
|
210
|
+
*/
|
|
211
|
+
async getStableTokens(includeSupply = true) {
|
|
212
|
+
const reserveAddress = (0, constants_1.getContractAddress)(this.chainId, constants_1.RESERVE);
|
|
213
|
+
const tokenAddresses = await this.getStableTokenAddresses(reserveAddress);
|
|
214
|
+
const [metadataList, totalSupplies] = await Promise.all([
|
|
215
|
+
this.getTokenMetadataBatch(tokenAddresses),
|
|
216
|
+
includeSupply ? this.getTotalSupplyBatch(tokenAddresses) : Promise.resolve(tokenAddresses.map(() => '0')),
|
|
217
|
+
]);
|
|
218
|
+
const tokens = tokenAddresses.map((address, index) => ({
|
|
219
|
+
address,
|
|
220
|
+
...metadataList[index],
|
|
221
|
+
totalSupply: totalSupplies[index],
|
|
222
|
+
}));
|
|
223
|
+
return tokens;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Get all collateral assets.
|
|
227
|
+
* On ReserveV2 chains, queries the reserve directly.
|
|
228
|
+
* On legacy chains, discovers collateral via BiPoolManager exchanges.
|
|
229
|
+
* @returns Array of collateral assets
|
|
230
|
+
*/
|
|
231
|
+
async getCollateralAssets() {
|
|
232
|
+
if (this.isReserveV2()) {
|
|
233
|
+
return this.getCollateralAssetsV2();
|
|
234
|
+
}
|
|
235
|
+
return this.getCollateralAssetsLegacy();
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Get collateral assets directly from ReserveV2.
|
|
239
|
+
*/
|
|
240
|
+
async getCollateralAssetsV2() {
|
|
241
|
+
const reserveAddress = (0, constants_1.getContractAddress)(this.chainId, constants_1.RESERVE);
|
|
242
|
+
const collateralAddresses = (await (0, utils_1.retryOperation)(() => this.publicClient.readContract({
|
|
243
|
+
address: reserveAddress,
|
|
244
|
+
abi: abis_1.RESERVE_V2_ABI,
|
|
245
|
+
functionName: 'getCollateralAssets',
|
|
246
|
+
args: [],
|
|
247
|
+
})));
|
|
248
|
+
const metadataList = await this.getTokenMetadataBatch(collateralAddresses);
|
|
249
|
+
const assets = collateralAddresses.map((address, index) => ({
|
|
250
|
+
address,
|
|
251
|
+
...metadataList[index],
|
|
252
|
+
}));
|
|
253
|
+
return assets;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Get collateral assets from legacy Reserve via BiPoolManager exchanges.
|
|
257
|
+
*/
|
|
258
|
+
async getCollateralAssetsLegacy() {
|
|
259
|
+
const biPoolManagerAddress = (0, constants_1.tryGetContractAddress)(this.chainId, constants_1.BIPOOLMANAGER);
|
|
260
|
+
if (!biPoolManagerAddress) {
|
|
261
|
+
return [];
|
|
262
|
+
}
|
|
263
|
+
const reserveAddress = (0, constants_1.getContractAddress)(this.chainId, constants_1.RESERVE);
|
|
264
|
+
// Get all exchanges to find unique token addresses
|
|
265
|
+
const exchanges = (await (0, utils_1.retryOperation)(() => this.publicClient.readContract({
|
|
266
|
+
address: biPoolManagerAddress,
|
|
267
|
+
abi: abis_1.BIPOOL_MANAGER_ABI,
|
|
268
|
+
functionName: 'getExchanges',
|
|
269
|
+
})));
|
|
270
|
+
// Extract unique token addresses from exchanges
|
|
271
|
+
const uniqueAddresses = new Set();
|
|
272
|
+
for (const exchange of exchanges) {
|
|
273
|
+
exchange.assets.forEach((address) => uniqueAddresses.add(address));
|
|
274
|
+
}
|
|
275
|
+
const addresses = Array.from(uniqueAddresses);
|
|
276
|
+
const [collateralStatuses, metadataList] = await Promise.all([
|
|
277
|
+
this.getCollateralStatusBatch(reserveAddress, addresses),
|
|
278
|
+
this.getTokenMetadataBatch(addresses),
|
|
279
|
+
]);
|
|
280
|
+
const results = addresses.map((address, index) => {
|
|
281
|
+
if (!collateralStatuses[index]) {
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
return { address, ...metadataList[index] };
|
|
285
|
+
});
|
|
286
|
+
return results.filter((asset) => asset !== null);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
exports.TokenService = TokenService;
|
|
290
|
+
//# sourceMappingURL=tokenService.js.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { PublicClient } from 'viem';
|
|
2
|
+
import type { Pool, TradingLimit } from '../../core/types';
|
|
3
|
+
/**
|
|
4
|
+
* Service for querying trading limits from the Mento protocol.
|
|
5
|
+
* Supports both FPMM pools (TradingLimitsV2) and Virtual pools (TradingLimitsV1).
|
|
6
|
+
*/
|
|
7
|
+
export declare class TradingLimitsService {
|
|
8
|
+
private publicClient;
|
|
9
|
+
private chainId;
|
|
10
|
+
constructor(publicClient: PublicClient, chainId: number);
|
|
11
|
+
/**
|
|
12
|
+
* Get trading limits for a pool.
|
|
13
|
+
* Returns an array of TradingLimit objects for each configured limit.
|
|
14
|
+
*
|
|
15
|
+
* @param pool - The pool to get trading limits for
|
|
16
|
+
* @returns Array of TradingLimit objects with maxIn/maxOut/until
|
|
17
|
+
*/
|
|
18
|
+
getPoolTradingLimits(pool: Pool): Promise<TradingLimit[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Get trading limits for an FPMM pool.
|
|
21
|
+
* FPMM pools use TradingLimitsV2 with fixed timeframes.
|
|
22
|
+
*/
|
|
23
|
+
private getFPMMTradingLimits;
|
|
24
|
+
/**
|
|
25
|
+
* Get trading limits for a specific token in an FPMM pool.
|
|
26
|
+
*/
|
|
27
|
+
private getFPMMTokenLimits;
|
|
28
|
+
/**
|
|
29
|
+
* Get trading limits for a Virtual pool.
|
|
30
|
+
* Virtual pools use TradingLimitsV1 via the Broker contract.
|
|
31
|
+
*/
|
|
32
|
+
private getVirtualPoolTradingLimits;
|
|
33
|
+
/**
|
|
34
|
+
* Get trading limits for a specific token in a Virtual pool.
|
|
35
|
+
*/
|
|
36
|
+
private getVirtualPoolTokenLimits;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=TradingLimitsService.d.ts.map
|