import { BigNumber , SignedNativeOrder , V4RFQIndicativeQuote } from '@0x/asset-swapper' ; import { ONE_SECOND_MS } from '../constants' ; /**
 * Selects the best quote from an array of quotes.
 */ export function getBestQuote < T extends V4RFQIndicativeQuote | SignedNativeOrder > ( quotes , isSelling , takerToken , makerToken , assetFillAmount , validityWindowMs ) { const now = new BigNumber ( Date . now ( ) ) ; const expirationCutoff = now . plus ( validityWindowMs ) . div ( ONE_SECOND_MS ) ; const sortedQuotes = quotes . filter ( ( q ) => getTakerToken ( q ) === takerToken && getMakerToken ( q ) === makerToken ) . filter ( ( q ) => { const requestedAmount = isSelling ? getTakerAmount ( q ) : getMakerAmount ( q ) ; return requestedAmount . gte ( assetFillAmount ) ; } ) . filter ( ( q ) => getExpiry ( q ) . gte ( expirationCutoff ) ) . sort ( ( a , b ) => { const aPrice = getMakerAmount ( a ) . div ( getTakerAmount ( a ) ) ; const bPrice = getMakerAmount ( b ) . div ( getTakerAmount ( b ) ) ; return bPrice . minus ( aPrice ) . toNumber ( ) ; } ) ; if ( sortedQuotes . length === 0 ) { return null ; } return sortedQuotes [ 0 ] ; } const getTakerToken = ( quote ) : string => { if ( isSignedNativeOrder ( quote ) ) { return quote . order . takerToken ; } return quote . takerToken ; } ; const getMakerToken = ( quote ) : string => { if ( isSignedNativeOrder ( quote ) ) { return quote . order . makerToken ; } return quote . makerToken ; } ; const getTakerAmount = ( quote ) : BigNumber => { if ( isSignedNativeOrder ( quote ) ) { return quote . order . takerAmount ; } return quote . takerAmount ; } ; const getMakerAmount = ( quote ) : BigNumber => { if ( isSignedNativeOrder ( quote ) ) { return quote . order . makerAmount ; } return quote . makerAmount ; } ; const getExpiry = ( quote ) : BigNumber => { if ( isSignedNativeOrder ( quote ) ) { return quote . order . expiry ; } return quote . expiry ; } ; const isSignedNativeOrder = ( quote ) : quote is SignedNativeOrder => { return ( quote as SignedNativeOrder ) . order !== undefined ; } ;