import { BigNumberish } from '@ethersproject/bignumber' ; import { Contract } from '@ethersproject/contracts' ; import { AddressZero } from '@ethersproject/constants' ; import { SwapTypes , SwapInfo , SwapV2 } from '../types' ; import { SOR } from '../index' ; type FundManagement = { sender : string ; recipient : string ; fromInternalBalance : boolean ; toInternalBalance : boolean ; } ; export async function queryBatchSwap ( vaultContract , swapType , swaps , assets ) { const funds = { sender : AddressZero , recipient : AddressZero , fromInternalBalance : false , toInternalBalance : false , } ; return await vaultContract . queryBatchSwap ( swapType , swaps , assets , funds ) ; } async function getSorSwapInfo ( tokenIn , tokenOut , swapType , amount , sor ) { const swapInfo = await sor . getSwaps ( tokenIn . toLowerCase ( ) , tokenOut . toLowerCase ( ) , swapType , amount ) ; return swapInfo ; } function batchSwaps ( assetArray , swaps ) { const newAssetArray = [ ... new Set ( assetArray . flat ( ) ) ] ; swaps . forEach ( ( swap , i ) => { swap . forEach ( ( poolSwap ) => { poolSwap . assetInIndex = newAssetArray . indexOf ( assetArray [ i ] [ poolSwap . assetInIndex ] ) ; poolSwap . assetOutIndex = newAssetArray . indexOf ( assetArray [ i ] [ poolSwap . assetOutIndex ] ) ; } ) ; } ) ; const batchedSwaps = swaps . flat ( ) ; return { swaps : batchedSwaps , assets : newAssetArray } ; } export async function queryBatchSwapTokensIn ( sor , vaultContract , tokensIn , amountsIn , tokenOut ) { const swaps = [ ] ; const assetArray = [ ] ; for ( let i = 0 ; i < tokensIn . length ; i ++ ) { const swap = await getSorSwapInfo ( tokensIn [ i ] , tokenOut , SwapTypes . SwapExactIn , amountsIn [ i ] . toString ( ) , sor ) ; swaps . push ( swap . swaps ) ; assetArray . push ( swap . tokenAddresses ) ; } const batchedSwaps = batchSwaps ( assetArray , swaps ) ; let amountTokenOut = '0' ; try { const deltas = await queryBatchSwap ( vaultContract , SwapTypes . SwapExactIn , batchedSwaps . swaps , batchedSwaps . assets ) ; amountTokenOut = deltas [ batchedSwaps . assets . indexOf ( tokenOut . toLowerCase ( ) ) ] ?? '0' ; } catch ( err ) { console . error ( `queryBatchSwapTokensIn error: ${ err . message }` ) ; } return { amountTokenOut , swaps : batchedSwaps . swaps , assets : batchedSwaps . assets , } ; } export async function queryBatchSwapTokensOut ( sor , vaultContract , tokenIn , amountsIn , tokensOut ) { const swaps = [ ] ; const assetArray = [ ] ; for ( let i = 0 ; i < tokensOut . length ; i ++ ) { const swap = await getSorSwapInfo ( tokenIn , tokensOut [ i ] , SwapTypes . SwapExactIn , amountsIn [ i ] . toString ( ) , sor ) ; swaps . push ( swap . swaps ) ; assetArray . push ( swap . tokenAddresses ) ; } const batchedSwaps = batchSwaps ( assetArray , swaps ) ; const amountTokensOut = Array ( tokensOut . length ) . fill ( '0' ) ; try { const deltas = await queryBatchSwap ( vaultContract , SwapTypes . SwapExactIn , batchedSwaps . swaps , batchedSwaps . assets ) ; tokensOut . forEach ( ( t , i ) => { const amount = deltas [ batchedSwaps . assets . indexOf ( t . toLowerCase ( ) ) ] ; if ( amount ) amountTokensOut [ i ] = amount . toString ( ) ; } ) ; } catch ( err ) { console . error ( `queryBatchSwapTokensOut error: ${ err . message }` ) ; } return { amountTokensOut , swaps : batchedSwaps . swaps , assets : batchedSwaps . assets , } ; }