feat: remove old routing slice and flag (#6895)

feat: remove ura flag
This commit is contained in:
cartcrom 2023-07-07 09:49:42 -04:00 committed by GitHub
parent 90f72e05b9
commit dfe50b4bee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 58 additions and 220 deletions

@ -2,7 +2,6 @@ import { BaseVariant, FeatureFlag, featureFlagSettings, useUpdateFlag } from 'fe
import { DetailsV2Variant, useDetailsV2Flag } from 'featureFlags/flags/nftDetails'
import { useRoutingAPIForPriceFlag } from 'featureFlags/flags/priceRoutingApi'
import { TraceJsonRpcVariant, useTraceJsonRpcFlag } from 'featureFlags/flags/traceJsonRpc'
import { UnifiedRouterVariant, useRoutingAPIV2Flag } from 'featureFlags/flags/unifiedRouter'
import { useWalletConnectFallbackFlag } from 'featureFlags/flags/walletConnectPopover'
import { useWalletConnectV2Flag } from 'featureFlags/flags/walletConnectV2'
import { useUpdateAtom } from 'jotai/utils'
@ -211,12 +210,6 @@ export default function FeatureFlagModal() {
featureFlag={FeatureFlag.detailsV2}
label="Use the new details page for nfts"
/>
<FeatureFlagOption
variant={UnifiedRouterVariant}
value={useRoutingAPIV2Flag()}
featureFlag={FeatureFlag.uraEnabled}
label="Enable the Unified Routing API"
/>
<FeatureFlagOption
variant={BaseVariant}
value={useRoutingAPIForPriceFlag()}

@ -1,11 +0,0 @@
import { BaseVariant, FeatureFlag, useBaseFlag } from '../index'
export function useRoutingAPIV2Flag(): BaseVariant {
return useBaseFlag(FeatureFlag.uraEnabled)
}
export function useRoutingAPIV2Enabled(): boolean {
return useRoutingAPIV2Flag() === BaseVariant.Enabled
}
export { BaseVariant as UnifiedRouterVariant }

@ -10,7 +10,6 @@ export enum FeatureFlag {
permit2 = 'permit2',
fiatOnRampButtonOnSwap = 'fiat_on_ramp_button_on_swap_page',
detailsV2 = 'details_v2',
uraEnabled = 'ura_enabled',
debounceSwapQuote = 'debounce_swap_quote',
nativeUsdcArbitrum = 'web_usdc_arbitrum',
routingAPIPrice = 'routing_api_price',

@ -6,8 +6,7 @@ import { isTestEnv } from 'utils/env'
import { updateVersion } from './global/actions'
import { sentryEnhancer } from './logging'
import reducer from './reducer'
import { routingApi } from './routing/slice'
import { routingApiV2 } from './routing/v2Slice'
import { routingApiV2 } from './routing/slice'
const PERSISTED_KEYS: string[] = ['user', 'transactions', 'lists']
@ -21,10 +20,9 @@ const store = configureStore({
// meta.arg and meta.baseQueryMeta are defaults. payload.trade is a nonserializable return value, but that's ok
// because we are not adding it into any persisted store that requires serialization (e.g. localStorage)
ignoredActionPaths: ['meta.arg', 'meta.baseQueryMeta', 'payload.trade'],
ignoredPaths: [routingApi.reducerPath, routingApiV2.reducerPath],
ignoredPaths: [routingApiV2.reducerPath],
},
})
.concat(routingApi.middleware)
.concat(routingApiV2.middleware)
.concat(save({ states: PERSISTED_KEYS, debounce: 1000 })),
preloadedState: load({ states: PERSISTED_KEYS, disableWarnings: isTestEnv() }),

@ -7,8 +7,7 @@ import lists from './lists/reducer'
import logs from './logs/slice'
import mint from './mint/reducer'
import mintV3 from './mint/v3/reducer'
import { routingApi } from './routing/slice'
import { routingApiV2 } from './routing/v2Slice'
import { routingApiV2 } from './routing/slice'
import transactions from './transactions/reducer'
import user from './user/reducer'
import wallets from './wallets/reducer'
@ -25,6 +24,5 @@ export default {
multicall: multicall.reducer,
lists,
logs,
[routingApi.reducerPath]: routingApi.reducer,
[routingApiV2.reducerPath]: routingApiV2.reducer,
}

@ -4,30 +4,11 @@ import { TradeType } from '@uniswap/sdk-core'
import { ChainId } from '@uniswap/sdk-core'
import { getClientSideQuote } from 'lib/hooks/routing/clientSideSmartOrderRouter'
import ms from 'ms.macro'
import qs from 'qs'
import { trace } from 'tracing/trace'
import { QuoteData, QuoteMethod, TradeResult } from './types'
import { QuoteMethod, QuoteReponse, QuoteState, TradeResult } from './types'
import { getRouter, isExactInput, shouldUseAPIRouter, transformRoutesToTrade } from './utils'
export enum RouterPreference {
AUTO = 'auto',
API = 'api',
CLIENT = 'client',
}
// This is excluded from `RouterPreference` enum because it's only used
// internally for token -> USDC trades to get a USD value.
export const INTERNAL_ROUTER_PREFERENCE_PRICE = 'price' as const
// routing API quote params: https://github.com/Uniswap/routing-api/blob/main/lib/handlers/quote/schema/quote-schema.ts
const API_QUERY_PARAMS = {
protocols: 'v2,v3,mixed',
}
const CLIENT_PARAMS = {
protocols: [Protocol.V2, Protocol.V3, Protocol.MIXED],
}
export interface GetQuoteArgs {
tokenInAddress: string
tokenInChainId: ChainId
@ -43,21 +24,36 @@ export interface GetQuoteArgs {
isRoutingAPIPrice?: boolean
}
enum QuoteState {
SUCCESS = 'Success',
NOT_FOUND = 'Not found',
export enum RouterPreference {
AUTO = 'auto',
API = 'api',
CLIENT = 'client',
}
export const routingApi = createApi({
reducerPath: 'routingApi',
// This is excluded from `RouterPreference` enum because it's only used
// internally for token -> USDC trades to get a USD value.
export const INTERNAL_ROUTER_PREFERENCE_PRICE = 'price' as const
const CLIENT_PARAMS = {
protocols: [Protocol.V2, Protocol.V3, Protocol.MIXED],
}
// routing API quote query params: https://github.com/Uniswap/routing-api/blob/main/lib/handlers/quote/schema/quote-schema.ts
const CLASSIC_SWAP_QUERY_PARAMS = {
...CLIENT_PARAMS,
routingType: 'CLASSIC',
}
export const routingApiV2 = createApi({
reducerPath: 'routingApiV2',
baseQuery: fetchBaseQuery({
baseUrl: 'https://api.uniswap.org/v1/',
baseUrl: 'https://api.uniswap.org/v2/',
}),
endpoints: (build) => ({
getQuote: build.query<TradeResult, GetQuoteArgs>({
async onQueryStarted(args: GetQuoteArgs, { queryFulfilled }) {
trace(
'quote',
'quote-v2',
async ({ setTraceError, setTraceStatus }) => {
try {
await queryFulfilled
@ -83,28 +79,39 @@ export const routingApi = createApi({
}
)
},
async queryFn(args, _api, _extraOptions, fetch) {
const fellBack = false
async queryFn(args: GetQuoteArgs, _api, _extraOptions, fetch) {
let fellBack = false
if (shouldUseAPIRouter(args)) {
fellBack = true
try {
const { tokenInAddress, tokenInChainId, tokenOutAddress, tokenOutChainId, amount, tradeType } = args
const type = isExactInput(tradeType) ? 'exactIn' : 'exactOut'
const query = qs.stringify({
...API_QUERY_PARAMS,
tokenInAddress,
const type = isExactInput(tradeType) ? 'EXACT_INPUT' : 'EXACT_OUTPUT'
const requestBody = {
tokenInChainId,
tokenOutAddress,
tokenIn: tokenInAddress,
tokenOutChainId,
tokenOut: tokenOutAddress,
amount,
type,
configs: [CLASSIC_SWAP_QUERY_PARAMS],
}
const response = await fetch({
method: 'POST',
url: '/quote',
body: JSON.stringify(requestBody),
})
const response = await fetch(`quote?${query}`)
if (response.error) {
try {
// cast as any here because we do a runtime check on it being an object before indexing into .errorCode
const errorData = response.error.data as any
// NO_ROUTE should be treated as a valid response to prevent retries.
if (typeof errorData === 'object' && errorData?.errorCode === 'NO_ROUTE') {
if (
typeof errorData === 'object' &&
(errorData?.errorCode === 'NO_ROUTE' || errorData?.detail === 'No quotes available')
) {
return { data: { state: QuoteState.NOT_FOUND } }
}
} catch {
@ -112,12 +119,13 @@ export const routingApi = createApi({
}
}
const quoteData = response.data as QuoteData
const tradeResult = transformRoutesToTrade(args, quoteData)
const quoteData = response.data as QuoteReponse
const tradeResult = transformRoutesToTrade(args, quoteData.quote)
return { data: { ...tradeResult, method: QuoteMethod.ROUTING_API } }
} catch (error: any) {
console.warn(
`GetQuote failed on routing API, falling back to client: ${error?.message ?? error?.detail ?? error}`
`GetQuote failed on API v2, falling back to client: ${error?.message ?? error?.detail ?? error}`
)
}
}
@ -136,11 +144,8 @@ export const routingApi = createApi({
}
},
keepUnusedDataFor: ms`10s`,
extraOptions: {
maxRetries: 0,
},
}),
}),
})
export const { useGetQuoteQuery } = routingApi
export const { useGetQuoteQuery } = routingApiV2

@ -76,7 +76,7 @@ export interface QuoteData {
routeString: string
}
export type QuoteDataV2 = {
export type QuoteReponse = {
routing: RouterPreference.API
quote: QuoteData
}

@ -3,12 +3,11 @@ import { Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core'
import { IMetric, MetricLoggerUnit, setGlobalMetric } from '@uniswap/smart-order-router'
import { sendTiming } from 'components/analytics'
import { AVERAGE_L1_BLOCK_TIME } from 'constants/chainInfo'
import { useRoutingAPIV2Enabled } from 'featureFlags/flags/unifiedRouter'
import { useRoutingAPIArguments } from 'lib/hooks/routing/useRoutingAPIArguments'
import ms from 'ms.macro'
import { useMemo } from 'react'
import { INTERNAL_ROUTER_PREFERENCE_PRICE, RouterPreference, useGetQuoteQuery } from 'state/routing/slice'
import { useGetQuoteQuery as useGetQuoteQueryV2 } from 'state/routing/v2Slice'
import { INTERNAL_ROUTER_PREFERENCE_PRICE, RouterPreference } from 'state/routing/slice'
import { useGetQuoteQuery as useGetQuoteQueryV2 } from 'state/routing/slice'
import { InterfaceTrade, QuoteMethod, QuoteState, TradeState } from './types'
@ -48,34 +47,16 @@ export function useRoutingAPITrade<TTradeType extends TradeType>(
routerPreference,
})
const shouldUseRoutingApiV2 = useRoutingAPIV2Enabled()
const {
isError: isLegacyAPIError,
data: legacyAPITradeResult,
currentData: currentLegacyAPITradeResult,
} = useGetQuoteQuery(shouldUseRoutingApiV2 ? skipToken : queryArgs ?? skipToken, {
isError,
data: tradeResult,
currentData: currentTradeResult,
} = useGetQuoteQueryV2(queryArgs ?? skipToken, {
// Price-fetching is informational and costly, so it's done less frequently.
pollingInterval: routerPreference === INTERNAL_ROUTER_PREFERENCE_PRICE ? ms`1m` : AVERAGE_L1_BLOCK_TIME,
// If latest quote from cache was fetched > 2m ago, instantly repoll for another instead of waiting for next poll period
refetchOnMountOrArgChange: 2 * 60,
})
const {
isError: isV2APIError,
data: v2TradeResult,
currentData: currentV2TradeResult,
} = useGetQuoteQueryV2(!shouldUseRoutingApiV2 ? skipToken : queryArgs ?? skipToken, {
// Price-fetching is informational and costly, so it's done less frequently.
pollingInterval: routerPreference === INTERNAL_ROUTER_PREFERENCE_PRICE ? ms`1m` : AVERAGE_L1_BLOCK_TIME,
// If latest quote from cache was fetched > 2m ago, instantly repoll for another instead of waiting for next poll period
refetchOnMountOrArgChange: 2 * 60,
})
const [tradeResult, currentTradeResult, isError] = shouldUseRoutingApiV2
? [v2TradeResult, currentV2TradeResult, isV2APIError]
: [legacyAPITradeResult, currentLegacyAPITradeResult, isLegacyAPIError]
const isCurrent = currentTradeResult === tradeResult
return useMemo(() => {

@ -1,125 +0,0 @@
import { createApi, fetchBaseQuery, FetchBaseQueryError } from '@reduxjs/toolkit/query/react'
import { Protocol } from '@uniswap/router-sdk'
import { getClientSideQuote } from 'lib/hooks/routing/clientSideSmartOrderRouter'
import ms from 'ms.macro'
import { trace } from 'tracing/trace'
import { GetQuoteArgs, INTERNAL_ROUTER_PREFERENCE_PRICE, RouterPreference } from './slice'
import { QuoteDataV2, QuoteMethod, QuoteState, TradeResult } from './types'
import { getRouter, isExactInput, shouldUseAPIRouter, transformRoutesToTrade } from './utils'
const CLIENT_PARAMS = {
protocols: [Protocol.V2, Protocol.V3, Protocol.MIXED],
}
// routing API quote query params: https://github.com/Uniswap/routing-api/blob/main/lib/handlers/quote/schema/quote-schema.ts
const CLASSIC_SWAP_QUERY_PARAMS = {
...CLIENT_PARAMS,
routingType: 'CLASSIC',
}
export const routingApiV2 = createApi({
reducerPath: 'routingApiV2',
baseQuery: fetchBaseQuery({
baseUrl: 'https://api.uniswap.org/v2/',
}),
endpoints: (build) => ({
getQuote: build.query<TradeResult, GetQuoteArgs>({
async onQueryStarted(args: GetQuoteArgs, { queryFulfilled }) {
trace(
'quote-v2',
async ({ setTraceError, setTraceStatus }) => {
try {
await queryFulfilled
} catch (error: unknown) {
if (error && typeof error === 'object' && 'error' in error) {
const queryError = (error as Record<'error', FetchBaseQueryError>).error
if (typeof queryError.status === 'number') {
setTraceStatus(queryError.status)
}
setTraceError(queryError)
} else {
throw error
}
}
},
{
data: {
...args,
isPrice: args.routerPreference === INTERNAL_ROUTER_PREFERENCE_PRICE,
isAutoRouter:
args.routerPreference === RouterPreference.AUTO || args.routerPreference === RouterPreference.API,
},
}
)
},
async queryFn(args: GetQuoteArgs, _api, _extraOptions, fetch) {
let fellBack = false
if (shouldUseAPIRouter(args)) {
fellBack = true
try {
const { tokenInAddress, tokenInChainId, tokenOutAddress, tokenOutChainId, amount, tradeType } = args
const type = isExactInput(tradeType) ? 'EXACT_INPUT' : 'EXACT_OUTPUT'
const requestBody = {
tokenInChainId,
tokenIn: tokenInAddress,
tokenOutChainId,
tokenOut: tokenOutAddress,
amount,
type,
configs: [CLASSIC_SWAP_QUERY_PARAMS],
}
const response = await fetch({
method: 'POST',
url: '/quote',
body: JSON.stringify(requestBody),
})
if (response.error) {
try {
// cast as any here because we do a runtime check on it being an object before indexing into .errorCode
const errorData = response.error.data as any
// NO_ROUTE should be treated as a valid response to prevent retries.
if (
typeof errorData === 'object' &&
(errorData?.errorCode === 'NO_ROUTE' || errorData?.detail === 'No quotes available')
) {
return { data: { state: QuoteState.NOT_FOUND } }
}
} catch {
throw response.error
}
}
const quoteData = response.data as QuoteDataV2
const tradeResult = transformRoutesToTrade(args, quoteData.quote)
return { data: { ...tradeResult, method: QuoteMethod.ROUTING_API } }
} catch (error: any) {
console.warn(
`GetQuote failed on API v2, falling back to client: ${error?.message ?? error?.detail ?? error}`
)
}
}
try {
const method = fellBack ? QuoteMethod.CLIENT_SIDE_FALLBACK : QuoteMethod.CLIENT_SIDE
const router = getRouter(args.tokenInChainId)
const quoteResult = await getClientSideQuote(args, router, CLIENT_PARAMS)
if (quoteResult.state === QuoteState.SUCCESS) {
return { data: { ...transformRoutesToTrade(args, quoteResult.data), method } }
} else {
return { data: quoteResult }
}
} catch (error: any) {
console.warn(`GetQuote failed on client: ${error}`)
return { error: { status: 'CUSTOM_ERROR', error: error?.detail ?? error?.message ?? error } }
}
},
keepUnusedDataFor: ms`10s`,
}),
}),
})
export const { useGetQuoteQuery } = routingApiV2