Commit 1bb750f1 authored by Vignesh Mohankumar's avatar Vignesh Mohankumar Committed by GitHub

feat: track quote method in Quote Received event (#6807)

* WIP

* WIP

* more work

* comment

* fix

* v2slice

* add method to data

* add names

* fellback

* rm-log

* only success
parent 53152726
...@@ -3,7 +3,7 @@ import { useWeb3React } from '@web3-react/core' ...@@ -3,7 +3,7 @@ import { useWeb3React } from '@web3-react/core'
import { WRAPPED_NATIVE_CURRENCY } from 'constants/tokens' import { WRAPPED_NATIVE_CURRENCY } from 'constants/tokens'
import { DebounceSwapQuoteVariant, useDebounceSwapQuoteFlag } from 'featureFlags/flags/debounceSwapQuote' import { DebounceSwapQuoteVariant, useDebounceSwapQuoteFlag } from 'featureFlags/flags/debounceSwapQuote'
import { useMemo } from 'react' import { useMemo } from 'react'
import { InterfaceTrade, TradeState } from 'state/routing/types' import { InterfaceTrade, QuoteMethod, TradeState } from 'state/routing/types'
import { useRoutingAPITrade } from 'state/routing/useRoutingAPITrade' import { useRoutingAPITrade } from 'state/routing/useRoutingAPITrade'
import { useRouterPreference } from 'state/user/hooks' import { useRouterPreference } from 'state/user/hooks'
...@@ -31,6 +31,7 @@ export function useBestTrade( ...@@ -31,6 +31,7 @@ export function useBestTrade(
): { ): {
state: TradeState state: TradeState
trade?: InterfaceTrade trade?: InterfaceTrade
method?: QuoteMethod
} { } {
const { chainId } = useWeb3React() const { chainId } = useWeb3React()
const autoRouterSupported = useAutoRouterSupported() const autoRouterSupported = useAutoRouterSupported()
......
import { Trade } from '@uniswap/router-sdk' import { Trade } from '@uniswap/router-sdk'
import { Currency, CurrencyAmount, Percent, Price, Token, TradeType } from '@uniswap/sdk-core' import { Currency, CurrencyAmount, Percent, Price, Token, TradeType } from '@uniswap/sdk-core'
import { NATIVE_CHAIN_ID } from 'constants/tokens' import { NATIVE_CHAIN_ID } from 'constants/tokens'
import { InterfaceTrade } from 'state/routing/types' import { InterfaceTrade, QuoteMethod } from 'state/routing/types'
import { computeRealizedPriceImpact } from 'utils/prices' import { computeRealizedPriceImpact } from 'utils/prices'
export const getDurationUntilTimestampSeconds = (futureTimestampInSecondsSinceEpoch?: number): number | undefined => { export const getDurationUntilTimestampSeconds = (futureTimestampInSecondsSinceEpoch?: number): number | undefined => {
...@@ -54,7 +54,8 @@ export const formatSwapSignedAnalyticsEventProperties = ({ ...@@ -54,7 +54,8 @@ export const formatSwapSignedAnalyticsEventProperties = ({
export const formatEventPropertiesForTrade = ( export const formatEventPropertiesForTrade = (
trade: Trade<Currency, Currency, TradeType>, trade: Trade<Currency, Currency, TradeType>,
allowedSlippage: Percent, allowedSlippage: Percent,
gasUseEstimateUSD?: string gasUseEstimateUSD?: string,
method?: QuoteMethod
) => { ) => {
return { return {
token_in_symbol: trade.inputAmount.currency.symbol, token_in_symbol: trade.inputAmount.currency.symbol,
...@@ -71,5 +72,6 @@ export const formatEventPropertiesForTrade = ( ...@@ -71,5 +72,6 @@ export const formatEventPropertiesForTrade = (
token_out_amount: formatToDecimal(trade.outputAmount, trade.outputAmount.currency.decimals), token_out_amount: formatToDecimal(trade.outputAmount, trade.outputAmount.currency.decimals),
minimum_output_after_slippage: trade.minimumAmountOut(allowedSlippage).toSignificant(6), minimum_output_after_slippage: trade.minimumAmountOut(allowedSlippage).toSignificant(6),
allowed_slippage: formatPercentNumber(allowedSlippage), allowed_slippage: formatPercentNumber(allowedSlippage),
method,
} }
} }
...@@ -265,7 +265,7 @@ export function Swap({ ...@@ -265,7 +265,7 @@ export function Swap({
}, [connectedChainId, prefilledState, previousConnectedChainId, previousPrefilledState]) }, [connectedChainId, prefilledState, previousConnectedChainId, previousPrefilledState])
const { const {
trade: { state: tradeState, trade }, trade: { state: tradeState, trade, method },
allowedSlippage, allowedSlippage,
autoSlippage, autoSlippage,
currencyBalances, currencyBalances,
...@@ -528,10 +528,10 @@ export function Swap({ ...@@ -528,10 +528,10 @@ export function Swap({
setSwapQuoteReceivedDate(new Date()) setSwapQuoteReceivedDate(new Date())
sendAnalyticsEvent(SwapEventName.SWAP_QUOTE_RECEIVED, { sendAnalyticsEvent(SwapEventName.SWAP_QUOTE_RECEIVED, {
...formatEventPropertiesForTrade(trade, allowedSlippage, trade.gasUseEstimateUSD ?? undefined), ...formatEventPropertiesForTrade(trade, allowedSlippage, trade.gasUseEstimateUSD ?? undefined, method),
...trace, ...trace,
}) })
}, [prevTrade, trade, trace, allowedSlippage]) }, [prevTrade, trade, trace, allowedSlippage, method])
const showDetailsDropdown = Boolean( const showDetailsDropdown = Boolean(
!showWrap && userHasSpecifiedInputOutput && (trade || routeIsLoading || routeIsSyncing) !showWrap && userHasSpecifiedInputOutput && (trade || routeIsLoading || routeIsSyncing)
......
...@@ -7,7 +7,7 @@ import ms from 'ms.macro' ...@@ -7,7 +7,7 @@ import ms from 'ms.macro'
import qs from 'qs' import qs from 'qs'
import { trace } from 'tracing/trace' import { trace } from 'tracing/trace'
import { QuoteData, TradeResult } from './types' import { QuoteData, QuoteMethod, TradeResult } from './types'
import { getRouter, isExactInput, shouldUseAPIRouter, transformRoutesToTrade } from './utils' import { getRouter, isExactInput, shouldUseAPIRouter, transformRoutesToTrade } from './utils'
export enum RouterPreference { export enum RouterPreference {
...@@ -84,6 +84,7 @@ export const routingApi = createApi({ ...@@ -84,6 +84,7 @@ export const routingApi = createApi({
) )
}, },
async queryFn(args, _api, _extraOptions, fetch) { async queryFn(args, _api, _extraOptions, fetch) {
const fellBack = false
if (shouldUseAPIRouter(args)) { if (shouldUseAPIRouter(args)) {
try { try {
const { tokenInAddress, tokenInChainId, tokenOutAddress, tokenOutChainId, amount, tradeType } = args const { tokenInAddress, tokenInChainId, tokenOutAddress, tokenOutChainId, amount, tradeType } = args
...@@ -113,7 +114,7 @@ export const routingApi = createApi({ ...@@ -113,7 +114,7 @@ export const routingApi = createApi({
const quoteData = response.data as QuoteData const quoteData = response.data as QuoteData
const tradeResult = transformRoutesToTrade(args, quoteData) const tradeResult = transformRoutesToTrade(args, quoteData)
return { data: tradeResult } return { data: { ...tradeResult, method: QuoteMethod.ROUTING_API } }
} catch (error: any) { } catch (error: any) {
console.warn( console.warn(
`GetQuote failed on routing API, falling back to client: ${error?.message ?? error?.detail ?? error}` `GetQuote failed on routing API, falling back to client: ${error?.message ?? error?.detail ?? error}`
...@@ -121,10 +122,11 @@ export const routingApi = createApi({ ...@@ -121,10 +122,11 @@ export const routingApi = createApi({
} }
} }
try { try {
const method = fellBack ? QuoteMethod.CLIENT_SIDE_FALLBACK : QuoteMethod.CLIENT_SIDE
const router = getRouter(args.tokenInChainId) const router = getRouter(args.tokenInChainId)
const quoteResult = await getClientSideQuote(args, router, CLIENT_PARAMS) const quoteResult = await getClientSideQuote(args, router, CLIENT_PARAMS)
if (quoteResult.state === QuoteState.SUCCESS) { if (quoteResult.state === QuoteState.SUCCESS) {
return { data: transformRoutesToTrade(args, quoteResult.data) } return { data: { ...transformRoutesToTrade(args, quoteResult.data), method } }
} else { } else {
return { data: quoteResult } return { data: quoteResult }
} }
......
...@@ -13,6 +13,12 @@ export enum TradeState { ...@@ -13,6 +13,12 @@ export enum TradeState {
VALID, VALID,
} }
export enum QuoteMethod {
ROUTING_API = 'ROUTING_API',
CLIENT_SIDE = 'CLIENT_SIDE',
CLIENT_SIDE_FALLBACK = 'CLIENT_SIDE_FALLBACK', // If client-side was used after the routing-api call failed.
}
// from https://github.com/Uniswap/routing-api/blob/main/lib/handlers/schema.ts // from https://github.com/Uniswap/routing-api/blob/main/lib/handlers/schema.ts
type TokenInRoute = Pick<Token, 'address' | 'chainId' | 'symbol' | 'decimals'> type TokenInRoute = Pick<Token, 'address' | 'chainId' | 'symbol' | 'decimals'>
...@@ -134,10 +140,12 @@ export type TradeResult = ...@@ -134,10 +140,12 @@ export type TradeResult =
| { | {
state: QuoteState.NOT_FOUND state: QuoteState.NOT_FOUND
trade?: undefined trade?: undefined
method?: QuoteMethod
} }
| { | {
state: QuoteState.SUCCESS state: QuoteState.SUCCESS
trade: InterfaceTrade trade: InterfaceTrade
method?: QuoteMethod
} }
export enum PoolType { export enum PoolType {
......
...@@ -10,7 +10,7 @@ import { useMemo } from 'react' ...@@ -10,7 +10,7 @@ import { useMemo } from 'react'
import { INTERNAL_ROUTER_PREFERENCE_PRICE, RouterPreference, useGetQuoteQuery } from 'state/routing/slice' import { INTERNAL_ROUTER_PREFERENCE_PRICE, RouterPreference, useGetQuoteQuery } from 'state/routing/slice'
import { useGetQuoteQuery as useGetQuoteQueryV2 } from 'state/routing/v2Slice' import { useGetQuoteQuery as useGetQuoteQueryV2 } from 'state/routing/v2Slice'
import { InterfaceTrade, QuoteState, TradeState } from './types' import { InterfaceTrade, QuoteMethod, QuoteState, TradeState } from './types'
const TRADE_NOT_FOUND = { state: TradeState.NO_ROUTE_FOUND, trade: undefined } as const const TRADE_NOT_FOUND = { state: TradeState.NO_ROUTE_FOUND, trade: undefined } as const
const TRADE_LOADING = { state: TradeState.LOADING, trade: undefined } as const const TRADE_LOADING = { state: TradeState.LOADING, trade: undefined } as const
...@@ -30,6 +30,7 @@ export function useRoutingAPITrade<TTradeType extends TradeType>( ...@@ -30,6 +30,7 @@ export function useRoutingAPITrade<TTradeType extends TradeType>(
): { ): {
state: TradeState state: TradeState
trade?: InterfaceTrade trade?: InterfaceTrade
method?: QuoteMethod
} { } {
const [currencyIn, currencyOut]: [Currency | undefined, Currency | undefined] = useMemo( const [currencyIn, currencyOut]: [Currency | undefined, Currency | undefined] = useMemo(
() => () =>
...@@ -92,9 +93,19 @@ export function useRoutingAPITrade<TTradeType extends TradeType>( ...@@ -92,9 +93,19 @@ export function useRoutingAPITrade<TTradeType extends TradeType>(
return { return {
state: isCurrent ? TradeState.VALID : TradeState.LOADING, state: isCurrent ? TradeState.VALID : TradeState.LOADING,
trade: tradeResult.trade, trade: tradeResult.trade,
method: tradeResult?.method,
} }
} }
}, [amountSpecified, isCurrent, isError, queryArgs, skipFetch, tradeResult?.state, tradeResult?.trade]) }, [
amountSpecified,
isCurrent,
isError,
queryArgs,
skipFetch,
tradeResult?.state,
tradeResult?.trade,
tradeResult?.method,
])
} }
// only want to enable this when app hook called // only want to enable this when app hook called
......
...@@ -5,7 +5,7 @@ import ms from 'ms.macro' ...@@ -5,7 +5,7 @@ import ms from 'ms.macro'
import { trace } from 'tracing/trace' import { trace } from 'tracing/trace'
import { GetQuoteArgs, INTERNAL_ROUTER_PREFERENCE_PRICE, RouterPreference } from './slice' import { GetQuoteArgs, INTERNAL_ROUTER_PREFERENCE_PRICE, RouterPreference } from './slice'
import { QuoteDataV2, QuoteState, TradeResult } from './types' import { QuoteDataV2, QuoteMethod, QuoteState, TradeResult } from './types'
import { getRouter, isExactInput, shouldUseAPIRouter, transformRoutesToTrade } from './utils' import { getRouter, isExactInput, shouldUseAPIRouter, transformRoutesToTrade } from './utils'
const CLIENT_PARAMS = { const CLIENT_PARAMS = {
...@@ -54,7 +54,9 @@ export const routingApiV2 = createApi({ ...@@ -54,7 +54,9 @@ export const routingApiV2 = createApi({
) )
}, },
async queryFn(args: GetQuoteArgs, _api, _extraOptions, fetch) { async queryFn(args: GetQuoteArgs, _api, _extraOptions, fetch) {
let fellBack = false
if (shouldUseAPIRouter(args)) { if (shouldUseAPIRouter(args)) {
fellBack = true
try { try {
const { tokenInAddress, tokenInChainId, tokenOutAddress, tokenOutChainId, amount, tradeType } = args const { tokenInAddress, tokenInChainId, tokenOutAddress, tokenOutChainId, amount, tradeType } = args
const type = isExactInput(tradeType) ? 'EXACT_INPUT' : 'EXACT_OUTPUT' const type = isExactInput(tradeType) ? 'EXACT_INPUT' : 'EXACT_OUTPUT'
...@@ -94,7 +96,7 @@ export const routingApiV2 = createApi({ ...@@ -94,7 +96,7 @@ export const routingApiV2 = createApi({
const quoteData = response.data as QuoteDataV2 const quoteData = response.data as QuoteDataV2
const tradeResult = transformRoutesToTrade(args, quoteData.quote) const tradeResult = transformRoutesToTrade(args, quoteData.quote)
return { data: tradeResult } return { data: { ...tradeResult, method: QuoteMethod.ROUTING_API } }
} catch (error: any) { } catch (error: any) {
console.warn( console.warn(
`GetQuote failed on API v2, falling back to client: ${error?.message ?? error?.detail ?? error}` `GetQuote failed on API v2, falling back to client: ${error?.message ?? error?.detail ?? error}`
...@@ -102,10 +104,11 @@ export const routingApiV2 = createApi({ ...@@ -102,10 +104,11 @@ export const routingApiV2 = createApi({
} }
} }
try { try {
const method = fellBack ? QuoteMethod.CLIENT_SIDE_FALLBACK : QuoteMethod.CLIENT_SIDE
const router = getRouter(args.tokenInChainId) const router = getRouter(args.tokenInChainId)
const quoteResult = await getClientSideQuote(args, router, CLIENT_PARAMS) const quoteResult = await getClientSideQuote(args, router, CLIENT_PARAMS)
if (quoteResult.state === QuoteState.SUCCESS) { if (quoteResult.state === QuoteState.SUCCESS) {
return { data: transformRoutesToTrade(args, quoteResult.data) } return { data: { ...transformRoutesToTrade(args, quoteResult.data), method } }
} else { } else {
return { data: quoteResult } return { data: quoteResult }
} }
......
...@@ -9,7 +9,7 @@ import { ParsedQs } from 'qs' ...@@ -9,7 +9,7 @@ import { ParsedQs } from 'qs'
import { ReactNode, useCallback, useEffect, useMemo } from 'react' import { ReactNode, useCallback, useEffect, useMemo } from 'react'
import { AnyAction } from 'redux' import { AnyAction } from 'redux'
import { useAppDispatch } from 'state/hooks' import { useAppDispatch } from 'state/hooks'
import { InterfaceTrade, TradeState } from 'state/routing/types' import { InterfaceTrade, QuoteMethod, TradeState } from 'state/routing/types'
import { useUserSlippageToleranceWithDefault } from 'state/user/hooks' import { useUserSlippageToleranceWithDefault } from 'state/user/hooks'
import { TOKEN_SHORTHANDS } from '../../constants/tokens' import { TOKEN_SHORTHANDS } from '../../constants/tokens'
...@@ -83,6 +83,7 @@ export function useDerivedSwapInfo( ...@@ -83,6 +83,7 @@ export function useDerivedSwapInfo(
trade: { trade: {
trade?: InterfaceTrade trade?: InterfaceTrade
state: TradeState state: TradeState
method?: QuoteMethod
} }
allowedSlippage: Percent allowedSlippage: Percent
autoSlippage: Percent autoSlippage: Percent
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment