diff --git a/src/components/FeatureFlagModal/FeatureFlagModal.tsx b/src/components/FeatureFlagModal/FeatureFlagModal.tsx index 7bb8f81c8a..8e7dd9c02c 100644 --- a/src/components/FeatureFlagModal/FeatureFlagModal.tsx +++ b/src/components/FeatureFlagModal/FeatureFlagModal.tsx @@ -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" /> + , 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; + senderAddress: Scalars['String']; + nftTrades: Array | NftTradeInput; + tokenTrades?: InputMaybe | 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) { @@ -1722,4 +1732,68 @@ export function useNftBalanceLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions } export type NftBalanceQueryHookResult = ReturnType; export type NftBalanceLazyQueryHookResult = ReturnType; -export type NftBalanceQueryResult = Apollo.QueryResult; \ No newline at end of file +export type NftBalanceQueryResult = Apollo.QueryResult; +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) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(NftRouteDocument, options); + } +export function useNftRouteLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(NftRouteDocument, options); + } +export type NftRouteQueryHookResult = ReturnType; +export type NftRouteLazyQueryHookResult = ReturnType; +export type NftRouteQueryResult = Apollo.QueryResult; \ No newline at end of file diff --git a/src/graphql/data/nft/Routing.ts b/src/graphql/data/nft/Routing.ts new file mode 100644 index 0000000000..0a1c83b534 --- /dev/null +++ b/src/graphql/data/nft/Routing.ts @@ -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, + }, + }) +} diff --git a/src/nft/components/bag/Bag.tsx b/src/nft/components/bag/Bag.tsx index e69afb7346..28886a8230 100644 --- a/src/nft/components/bag/Bag.tsx +++ b/src/nft/components/bag/Bag.tsx @@ -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( diff --git a/src/test-utils.tsx b/src/test-utils.tsx index a3bac20ad9..4c805b587f 100644 --- a/src/test-utils.tsx +++ b/src/test-utils.tsx @@ -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 }) => { - - {children} - + + + {children} + +