import { MethodData } from '@shared/models/blockchain/method-data' ; import BigNumber from 'bignumber.js' ; import { compareAddresses } from 'src/app/shared/utils/utils' ; import { SymbolToken } from '@shared/models/tokens/symbol-token' ; import { ROUTER_TOKENS_NET_MODE } from '@features/instant-trade/services/instant-trade-service/providers/polygon/algebra-service/utils/quoter-controller/constants/router-tokens' ; import { ContractData } from '@shared/models/blockchain/contract-data' ; import { AlgebraRoute } from '@features/instant-trade/services/instant-trade-service/providers/polygon/algebra-service/models/algebra-instant-trade' ; import { EthLikeWeb3Public } from '@core/services/blockchain/blockchain-adapters/eth-like/web3-public/eth-like-web3-public' ; interface RecGraphVisitorOptions { routesTokens : SymbolToken [ ] ; toToken : SymbolToken ; amountAbsolute : string ; maxTransitTokens : number ; } /**
 * Works with requests, related to Uniswap v3 liquidity pools.
 */ export class AlgebraQuoterController { private routerTokens : SymbolToken [ ] ; param path return public static getEncodedPath ( path ) { const encodedPath = path . reduce ( ( accEncodedPath , token ) => accEncodedPath + token . address . slice ( 2 ) . toLowerCase ( ) , '' ) ; return `0x${ encodedPath }` ; } param path param amountAbsolute private static getQuoterMethodData ( path , amountAbsolute ) { if ( path . length === 2 ) { return { path : path , methodData : { methodName : 'quoteExactInputSingle' , methodArguments : [ path [ 0 ] . address , path [ 1 ] . address , amountAbsolute , 0 ] } } ; } return { path : path , methodData : { methodName : 'quoteExactInput' , methodArguments : [ AlgebraQuoterController . getEncodedPath ( path ) , amountAbsolute ] } } ; } constructor ( private readonly web3Public , private readonly quoterContract ) { this . routerTokens = ROUTER_TOKENS_NET_MODE . mainnet ; } public setTestingMode ( ) { this . routerTokens = ROUTER_TOKENS_NET_MODE . testnet ; } param fromToken param toToken param amountAbsolute param routeMaxTransitPools public async getAllRoutes ( fromToken , toToken , amountAbsolute , routeMaxTransitPools ) { const routesTokens = this . routerTokens . filter ( token => ! compareAddresses ( token . address , fromToken . address ) && ! compareAddresses ( token . address , toToken . address ) ) ; const options = { routesTokens , toToken , amountAbsolute } ; const quoterMethodsData = [ ... Array ( routeMaxTransitPools + 1 ) ] . map ( ( _ , maxTransitTokens ) => this . getQuoterMethodsData ( { ... options , maxTransitTokens } , [ fromToken ] ) ) . flat ( ) ; const results = await this . web3Public . multicallContractMethods < { 0 : string ; } > ( this . quoterContract . address , this . quoterContract . abi , quoterMethodsData . map ( quoterMethodData => quoterMethodData . methodData ) ) ; return results . map ( ( result , index ) => { if ( result . success ) { return { outputAbsoluteAmount : new BigNumber ( result . output [ 0 ] ) , path : quoterMethodsData [ index ] . path } ; } return null ; } ) . filter ( route => route !== null ) ; } /**
     * Returns swap methods' names and arguments, built with passed pools' addresses, to use it in Quoter contract.
     */ private getQuoterMethodsData ( options , path ) { const { routesTokens , toToken , amountAbsolute , maxTransitTokens } = options ; if ( path . length === maxTransitTokens + 1 ) { return [ AlgebraQuoterController . getQuoterMethodData ( path . concat ( toToken ) , amountAbsolute ) ] ; } return routesTokens . filter ( token => ! path . includes ( token ) ) . map ( token => this . getQuoterMethodsData ( options , path . concat ( token ) ) ) . flat ( ) ; } }