chore: setting up feature flags and boilerplate gql for routing gql endpoint (#5935)

* feat: routing gql endpoint

* adding feature flags

* adding to modal

* adding mocked provider to test

* adding apollo client to mocked providers

* comment
This commit is contained in:
Jack Short 2023-02-07 16:33:41 -07:00 committed by GitHub
parent 4d82f9fb3a
commit f0b4b92b88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 147 additions and 4 deletions

@ -1,5 +1,6 @@
import { BaseVariant, FeatureFlag, featureFlagSettings, useUpdateFlag } from 'featureFlags'
import { useFiatOnrampFlag } from 'featureFlags/flags/fiatOnramp'
import { GqlRoutingVariant, useGqlRoutingFlag } from 'featureFlags/flags/gqlRouting'
import { NftListV2Variant, useNftListV2Flag } from 'featureFlags/flags/nftListV2'
import { PayWithAnyTokenVariant, usePayWithAnyTokenFlag } from 'featureFlags/flags/payWithAnyToken'
import { Permit2Variant, usePermit2Flag } from 'featureFlags/flags/permit2'
@ -236,6 +237,12 @@ export default function FeatureFlagModal() {
featureFlag={FeatureFlag.swapWidget}
label="Swap Widget"
/>
<FeatureFlagOption
variant={GqlRoutingVariant}
value={useGqlRoutingFlag()}
featureFlag={FeatureFlag.gqlRouting}
label="GraphQL NFT Routing"
/>
<FeatureFlagGroup name="Debug">
<FeatureFlagOption
variant={TraceJsonRpcVariant}

@ -5,4 +5,5 @@ export enum FeatureFlag {
nftListV2 = 'nftListV2',
payWithAnyToken = 'payWithAnyToken',
swapWidget = 'swapWidget',
gqlRouting = 'gqlRouting',
}

@ -0,0 +1,7 @@
import { BaseVariant, FeatureFlag, useBaseFlag } from '../index'
export function useGqlRoutingFlag(): BaseVariant {
return useBaseFlag(FeatureFlag.gqlRouting)
}
export { BaseVariant as GqlRoutingVariant }

@ -1006,6 +1006,16 @@ export type NftBalanceQueryVariables = Exact<{
export type NftBalanceQuery = { __typename?: 'Query', nftBalances?: { __typename?: 'NftBalanceConnection', edges: Array<{ __typename?: 'NftBalanceEdge', node: { __typename?: 'NftBalance', listedMarketplaces?: Array<NftMarketplace>, ownedAsset?: { __typename?: 'NftAsset', id: string, animationUrl?: string, description?: string, flaggedBy?: string, name?: string, ownerAddress?: string, suspiciousFlag?: boolean, tokenId: string, collection?: { __typename?: 'NftCollection', isVerified?: boolean, name?: string, twitterName?: string, image?: { __typename?: 'Image', url: string }, nftContracts?: Array<{ __typename?: 'NftContract', address: string, chain: Chain, name?: string, standard?: NftStandard, symbol?: string, totalSupply?: number }>, markets?: Array<{ __typename?: 'NftCollectionMarket', floorPrice?: { __typename?: 'TimestampedAmount', value: number } }> }, image?: { __typename?: 'Image', url: string }, originalImage?: { __typename?: 'Image', url: string }, smallImage?: { __typename?: 'Image', url: string }, thumbnail?: { __typename?: 'Image', url: string }, listings?: { __typename?: 'NftOrderConnection', edges: Array<{ __typename?: 'NftOrderEdge', node: { __typename?: 'NftOrder', createdAt: number, marketplace: NftMarketplace, endAt?: number, price: { __typename?: 'Amount', value: number, currency?: Currency } } }> } }, listingFees?: Array<{ __typename?: 'NftFee', payoutAddress: string, basisPoints: number }>, lastPrice?: { __typename?: 'TimestampedAmount', currency?: Currency, timestamp: number, value: number } } }>, pageInfo: { __typename?: 'PageInfo', endCursor?: string, hasNextPage?: boolean, hasPreviousPage?: boolean, startCursor?: string } } };
export type NftRouteQueryVariables = Exact<{
chain?: InputMaybe<Chain>;
senderAddress: Scalars['String'];
nftTrades: Array<NftTradeInput> | NftTradeInput;
tokenTrades?: InputMaybe<Array<TokenTradeInput> | TokenTradeInput>;
}>;
export type NftRouteQuery = { __typename?: 'Query', nftRoute?: { __typename?: 'NftRouteResponse', calldata: string, toAddress: string, route?: Array<{ __typename?: 'NftTrade', amount: number, contractAddress: string, id: string, marketplace: NftMarketplace, tokenId: string, tokenType: NftStandard, price: { __typename?: 'TokenAmount', currency: Currency, value: string }, quotePrice?: { __typename?: 'TokenAmount', currency: Currency, value: string } }>, sendAmount: { __typename?: 'TokenAmount', currency: Currency, value: string } } };
export const TokenDocument = gql`
query Token($chain: Chain!, $address: String) {
@ -1723,3 +1733,67 @@ export function useNftBalanceLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions
export type NftBalanceQueryHookResult = ReturnType<typeof useNftBalanceQuery>;
export type NftBalanceLazyQueryHookResult = ReturnType<typeof useNftBalanceLazyQuery>;
export type NftBalanceQueryResult = Apollo.QueryResult<NftBalanceQuery, NftBalanceQueryVariables>;
export const NftRouteDocument = gql`
query NftRoute($chain: Chain = ETHEREUM, $senderAddress: String!, $nftTrades: [NftTradeInput!]!, $tokenTrades: [TokenTradeInput!]) {
nftRoute(
chain: $chain
senderAddress: $senderAddress
nftTrades: $nftTrades
tokenTrades: $tokenTrades
) {
calldata
route {
amount
contractAddress
id
marketplace
price {
currency
value
}
quotePrice {
currency
value
}
tokenId
tokenType
}
sendAmount {
currency
value
}
toAddress
}
}
`;
/**
* __useNftRouteQuery__
*
* To run a query within a React component, call `useNftRouteQuery` and pass it any options that fit your needs.
* When your component renders, `useNftRouteQuery` returns an object from Apollo Client that contains loading, error, and data properties
* you can use to render your UI.
*
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useNftRouteQuery({
* variables: {
* chain: // value for 'chain'
* senderAddress: // value for 'senderAddress'
* nftTrades: // value for 'nftTrades'
* tokenTrades: // value for 'tokenTrades'
* },
* });
*/
export function useNftRouteQuery(baseOptions: Apollo.QueryHookOptions<NftRouteQuery, NftRouteQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<NftRouteQuery, NftRouteQueryVariables>(NftRouteDocument, options);
}
export function useNftRouteLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<NftRouteQuery, NftRouteQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<NftRouteQuery, NftRouteQueryVariables>(NftRouteDocument, options);
}
export type NftRouteQueryHookResult = ReturnType<typeof useNftRouteQuery>;
export type NftRouteLazyQueryHookResult = ReturnType<typeof useNftRouteLazyQuery>;
export type NftRouteQueryResult = Apollo.QueryResult<NftRouteQuery, NftRouteQueryVariables>;

@ -0,0 +1,47 @@
import gql from 'graphql-tag'
import { NftTradeInput, TokenTradeInput, useNftRouteQuery } from '../__generated__/types-and-hooks'
gql`
query NftRoute(
$chain: Chain = ETHEREUM
$senderAddress: String!
$nftTrades: [NftTradeInput!]!
$tokenTrades: [TokenTradeInput!]
) {
nftRoute(chain: $chain, senderAddress: $senderAddress, nftTrades: $nftTrades, tokenTrades: $tokenTrades) {
calldata
route {
amount
contractAddress
id
marketplace
price {
currency
value
}
quotePrice {
currency
value
}
tokenId
tokenType
}
sendAmount {
currency
value
}
toAddress
}
}
`
export function useNftRoute(senderAddress: string, nftTrades: NftTradeInput[], tokenTrades?: TokenTradeInput[]) {
return useNftRouteQuery({
variables: {
senderAddress,
nftTrades,
tokenTrades,
},
})
}

@ -2,7 +2,9 @@ import { BigNumber } from '@ethersproject/bignumber'
import { sendAnalyticsEvent } from '@uniswap/analytics'
import { NFTEventName } from '@uniswap/analytics-events'
import { useWeb3React } from '@web3-react/core'
import { GqlRoutingVariant, useGqlRoutingFlag } from 'featureFlags/flags/gqlRouting'
import { NftListV2Variant, useNftListV2Flag } from 'featureFlags/flags/nftListV2'
import { useNftRoute } from 'graphql/data/nft/Routing'
import { useIsNftDetailsPage, useIsNftPage, useIsNftProfilePage } from 'hooks/useIsNftPage'
import { BagFooter } from 'nft/components/bag/BagFooter'
import ListingModal from 'nft/components/bag/profile/ListingModal'
@ -134,6 +136,7 @@ const Bag = () => {
const isNFTPage = useIsNftPage()
const isMobile = useIsMobile()
const isNftListV2 = useNftListV2Flag() === NftListV2Variant.Enabled
const usingGqlRouting = useGqlRoutingFlag() === GqlRoutingVariant.Enabled
const sendTransaction = useSendTransaction((state) => state.sendTransaction)
const transactionState = useSendTransaction((state) => state.state)
@ -194,6 +197,7 @@ const Bag = () => {
setBagExpanded({ bagExpanded: false, manualClose: true })
}, [setBagExpanded])
useNftRoute(usingGqlRouting ? account ?? '' : '', [])
const fetchAssets = async () => {
const itemsToBuy = itemsInBag.filter((item) => item.status !== BagItemStatus.UNAVAILABLE).map((item) => item.asset)
const ethSellObject = buildSellObject(

@ -1,3 +1,4 @@
import { MockedProvider } from '@apollo/client/testing'
import { i18n } from '@lingui/core'
import { I18nProvider } from '@lingui/react'
import { render, renderHook } from '@testing-library/react'
@ -32,9 +33,11 @@ const WithProviders = ({ children }: { children?: ReactNode }) => {
<QueryClientProvider client={queryClient}>
<HashRouter>
<Web3Provider>
<BlockNumberProvider>
<ThemeProvider>{children}</ThemeProvider>
</BlockNumberProvider>
<MockedProvider>
<BlockNumberProvider>
<ThemeProvider>{children}</ThemeProvider>
</BlockNumberProvider>
</MockedProvider>
</Web3Provider>
</HashRouter>
</QueryClientProvider>