refactor: replace sweep query with gql call (#5143)

replace sweep query with gql call
This commit is contained in:
Charles Bachmeier 2022-11-09 16:05:57 -05:00 committed by GitHub
parent 9f8355ed7b
commit 2abae0ee4c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 134 additions and 112 deletions

@ -2,12 +2,19 @@ import graphql from 'babel-plugin-relay/macro'
import { parseEther } from 'ethers/lib/utils'
import useInterval from 'lib/hooks/useInterval'
import ms from 'ms.macro'
import { GenieAsset } from 'nft/types'
import { GenieAsset, Trait } from 'nft/types'
import { useCallback, useMemo, useState } from 'react'
import { fetchQuery, useLazyLoadQuery, usePaginationFragment, useRelayEnvironment } from 'react-relay'
import { AssetPaginationQuery } from './__generated__/AssetPaginationQuery.graphql'
import { AssetQuery, NftAssetsFilterInput, NftAssetSortableField } from './__generated__/AssetQuery.graphql'
import {
AssetQuery,
AssetQuery$variables,
NftAssetsFilterInput,
NftAssetSortableField,
NftAssetTraitInput,
NftMarketplace,
} from './__generated__/AssetQuery.graphql'
import { AssetQuery_nftAssets$data } from './__generated__/AssetQuery_nftAssets.graphql'
const assetPaginationQuery = graphql`
@ -116,6 +123,61 @@ type NftAssetsQueryAsset = NonNullable<
NonNullable<NonNullable<AssetQuery_nftAssets$data['nftAssets']>['edges']>[number]
>
function formatAssetQueryData(queryAsset: NftAssetsQueryAsset, totalCount?: number) {
const asset = queryAsset.node
const ethPrice = parseEther(
asset.listings?.edges[0]?.node.price.value?.toLocaleString('fullwide', { useGrouping: false }) ?? '0'
).toString()
return {
id: asset.id,
address: asset?.collection?.nftContracts?.[0]?.address,
notForSale: asset.listings?.edges?.length === 0,
collectionName: asset.collection?.name,
collectionSymbol: asset.collection?.image?.url,
imageUrl: asset.image?.url,
animationUrl: asset.animationUrl,
marketplace: asset.listings?.edges[0]?.node?.marketplace?.toLowerCase(),
name: asset.name,
priceInfo: asset.listings
? {
ETHPrice: ethPrice,
baseAsset: 'ETH',
baseDecimals: '18',
basePrice: ethPrice,
}
: undefined,
susFlag: asset.suspiciousFlag,
sellorders: asset.listings?.edges.map((listingNode) => {
return {
...listingNode.node,
protocolParameters: listingNode.node?.protocolParameters
? JSON.parse(listingNode.node?.protocolParameters.toString())
: undefined,
}
}),
smallImageUrl: asset.smallImage?.url,
tokenId: asset.tokenId,
tokenType: asset.collection?.nftContracts?.[0]?.standard,
totalCount,
collectionIsVerified: asset.collection?.isVerified,
rarity: {
primaryProvider: 'Rarity Sniper', // TODO update when backend adds more providers
providers: asset.rarities?.map((rarity) => {
return {
...rarity,
provider: 'Rarity Sniper',
}
}),
},
owner: asset.ownerAddress,
creator: {
profile_img_url: asset.collection?.creator?.profileImage?.url,
address: asset.collection?.creator?.address,
},
metadataUrl: asset.metadataUrl,
}
}
export function useAssetsQuery(
address: string,
orderBy: NftAssetSortableField,
@ -159,61 +221,61 @@ export function useAssetsQuery(
const assets: GenieAsset[] = useMemo(
() =>
data.nftAssets?.edges?.map((queryAsset: NftAssetsQueryAsset) => {
const asset = queryAsset.node
const ethPrice = parseEther(
asset.listings?.edges[0]?.node.price.value?.toLocaleString('fullwide', { useGrouping: false }) ?? '0'
).toString()
return {
id: asset.id,
address: asset?.collection?.nftContracts?.[0]?.address,
notForSale: asset.listings?.edges?.length === 0,
collectionName: asset.collection?.name,
collectionSymbol: asset.collection?.image?.url,
imageUrl: asset.image?.url,
animationUrl: asset.animationUrl,
marketplace: asset.listings?.edges[0]?.node?.marketplace?.toLowerCase(),
name: asset.name,
priceInfo: asset.listings
? {
ETHPrice: ethPrice,
baseAsset: 'ETH',
baseDecimals: '18',
basePrice: ethPrice,
}
: undefined,
susFlag: asset.suspiciousFlag,
sellorders: asset.listings?.edges.map((listingNode) => {
return {
...listingNode.node,
protocolParameters: listingNode.node?.protocolParameters
? JSON.parse(listingNode.node?.protocolParameters.toString())
: undefined,
}
}),
smallImageUrl: asset.smallImage?.url,
tokenId: asset.tokenId,
tokenType: asset.collection?.nftContracts?.[0]?.standard,
totalCount: data.nftAssets?.totalCount,
collectionIsVerified: asset.collection?.isVerified,
rarity: {
primaryProvider: 'Rarity Sniper', // TODO update when backend adds more providers
providers: asset.rarities?.map((rarity) => {
return {
...rarity,
provider: 'Rarity Sniper',
}
}),
},
owner: asset.ownerAddress,
creator: {
profile_img_url: asset.collection?.creator?.profileImage?.url,
address: asset.collection?.creator?.address,
},
metadataUrl: asset.metadataUrl,
}
return formatAssetQueryData(queryAsset, data.nftAssets?.totalCount)
}),
[data.nftAssets?.edges, data.nftAssets?.totalCount]
)
return { assets, hasNext, isLoadingNext, loadNext }
}
const DEFAULT_SWEEP_AMOUNT = 50
export function useSweepAssetsQuery({
contractAddress,
markets,
price,
traits,
}: {
contractAddress: string
markets?: string[]
price?: { high?: number | string; low?: number | string; symbol: string }
traits?: Trait[]
}): GenieAsset[] {
const filter: NftAssetsFilterInput = useMemo(() => {
return {
listed: true,
maxPrice: price?.high?.toString(),
minPrice: price?.low?.toString(),
traits:
traits && traits.length > 0
? traits?.map((trait) => {
return { name: trait.trait_type, values: [trait.trait_value] } as unknown as NftAssetTraitInput
})
: undefined,
marketplaces:
markets && markets.length > 0 ? markets?.map((market) => market.toUpperCase() as NftMarketplace) : undefined,
}
}, [price, traits, markets])
const vars: AssetQuery$variables = useMemo(() => {
return {
address: contractAddress,
orderBy: 'PRICE',
asc: true,
first: DEFAULT_SWEEP_AMOUNT,
filter,
}
}, [contractAddress, filter])
const queryData = useLazyLoadQuery<AssetQuery>(assetQuery, vars)
const { data } = usePaginationFragment<AssetPaginationQuery, any>(assetPaginationQuery, queryData)
const assets: GenieAsset[] = useMemo(
() =>
data.nftAssets?.edges?.map((queryAsset: NftAssetsQueryAsset) => {
return formatAssetQueryData(queryAsset, data.nftAssets?.totalCount)
}),
[data.nftAssets?.edges, data.nftAssets?.totalCount]
)
return assets
}

@ -534,7 +534,6 @@ export const CollectionNfts = ({ contractAddress, collectionStats, rarityVerifie
</ActionsContainer>
<Sweep
contractAddress={contractAddress}
collectionStats={collectionStats}
minPrice={debouncedMinPrice}
maxPrice={debouncedMaxPrice}
showSweep={sweepIsOpen && buyNow && !hasErc1155s}

@ -2,13 +2,12 @@ import 'rc-slider/assets/index.css'
import { BigNumber } from '@ethersproject/bignumber'
import { formatEther, parseEther } from '@ethersproject/units'
import { useSweepAssetsQuery } from 'graphql/data/nft/Asset'
import { useBag, useCollectionFilters } from 'nft/hooks'
import { fetchSweep } from 'nft/queries'
import { GenieAsset, GenieCollection, Markets } from 'nft/types'
import { GenieAsset, Markets } from 'nft/types'
import { calcPoolPrice, formatWeiToDecimal } from 'nft/utils'
import { default as Slider } from 'rc-slider'
import { useEffect, useMemo, useReducer, useState } from 'react'
import { useQuery } from 'react-query'
import styled, { useTheme } from 'styled-components/macro'
import { ThemedText } from 'theme'
@ -151,13 +150,12 @@ export const NftDisplay = ({ nfts }: NftDisplayProps) => {
interface SweepProps {
contractAddress: string
collectionStats: GenieCollection
minPrice: string
maxPrice: string
showSweep: boolean
}
export const Sweep = ({ contractAddress, collectionStats, minPrice, maxPrice, showSweep }: SweepProps) => {
export const Sweep = ({ contractAddress, minPrice, maxPrice, showSweep }: SweepProps) => {
const theme = useTheme()
const [isItemsToggled, toggleSweep] = useReducer((state) => !state, true)
@ -211,52 +209,12 @@ export const Sweep = ({ contractAddress, collectionStats, minPrice, maxPrice, sh
}
}
const { data: collectionAssets, isFetched: isCollectionAssetsFetched } = useQuery(
['sweepAssets', getSweepFetcherParams('others')],
() => fetchSweep(getSweepFetcherParams('others')),
{
refetchOnWindowFocus: false,
refetchOnMount: false,
refetchOnReconnect: false,
}
)
const { data: nftxCollectionAssets, isFetched: isNftxCollectionAssetsFetched } = useQuery(
['nftxSweepAssets', collectionStats, getSweepFetcherParams(Markets.NFTX)],
() =>
collectionStats.marketplaceCount?.some(
(marketStat) => marketStat.marketplace === Markets.NFTX && marketStat.count > 0
)
? fetchSweep(getSweepFetcherParams(Markets.NFTX))
: [],
{
refetchOnWindowFocus: false,
refetchOnMount: false,
refetchOnReconnect: false,
}
)
const { data: nft20CollectionAssets, isFetched: isNft20CollectionAssetsFetched } = useQuery(
['nft20SweepAssets', getSweepFetcherParams(Markets.NFT20)],
() =>
collectionStats.marketplaceCount?.some(
(marketStat) => marketStat.marketplace === Markets.NFT20 && marketStat.count > 0
)
? fetchSweep(getSweepFetcherParams(Markets.NFT20))
: [],
{
refetchOnWindowFocus: false,
refetchOnMount: false,
refetchOnReconnect: false,
}
)
const allAssetsFetched = isCollectionAssetsFetched && isNftxCollectionAssetsFetched && isNft20CollectionAssetsFetched
const collectionAssets = useSweepAssetsQuery(getSweepFetcherParams('others'))
const nftxCollectionAssets = useSweepAssetsQuery(getSweepFetcherParams(Markets.NFTX))
const nft20CollectionAssets = useSweepAssetsQuery(getSweepFetcherParams(Markets.NFT20))
const { sortedAssets, sortedAssetsTotalEth } = useMemo(() => {
if (!allAssetsFetched || !collectionAssets || !nftxCollectionAssets || !nft20CollectionAssets)
if (!collectionAssets || !nftxCollectionAssets || !nft20CollectionAssets)
return { sortedAssets: undefined, sortedAssetsTotalEth: BigNumber.from(0) }
let counterNFTX = 0
@ -267,8 +225,11 @@ export const Sweep = ({ contractAddress, collectionStats, minPrice, maxPrice, sh
jointCollections.forEach((asset) => {
if (!asset.susFlag) {
const isNFTX = asset.marketplace === Markets.NFTX
asset.priceInfo.ETHPrice = calcPoolPrice(asset, isNFTX ? counterNFTX : counterNFT20)
BigNumber.from(asset.priceInfo.ETHPrice).gte(0) && (isNFTX ? counterNFTX++ : counterNFT20++)
const poolPrice = calcPoolPrice(asset, isNFTX ? counterNFTX : counterNFT20)
if (BigNumber.from(poolPrice).gt(0)) {
isNFTX ? counterNFTX++ : counterNFT20++
asset.priceInfo.ETHPrice = poolPrice
}
}
})
@ -294,7 +255,7 @@ export const Sweep = ({ contractAddress, collectionStats, minPrice, maxPrice, sh
BigNumber.from(0)
),
}
}, [collectionAssets, nftxCollectionAssets, nft20CollectionAssets, allAssetsFetched])
}, [collectionAssets, nftxCollectionAssets, nft20CollectionAssets])
const { sweepItemsInBag, sweepEthPrice } = useMemo(() => {
const sweepItemsInBag = itemsInBag

@ -21,7 +21,7 @@ export const calcPoolPrice = (asset: GenieAsset, position = 0) => {
: (asset.sellorders[0] as Deprecated_SellOrder)
const decimals = BigNumber.from(1).mul(10).pow(18)
const ammFee = nft.ammFeePercent ? (100 + (nft.ammFeePercent as number)) * 100 : 110 * 100
const ammFee = nft?.ammFeePercent ? (100 + (nft.ammFeePercent as number)) * 100 : 110 * 100
if (asset.marketplace === Markets.NFTX) {
const sixteenmul = BigNumber.from(1).mul(10).pow(16)
@ -43,7 +43,7 @@ export const calcPoolPrice = (asset: GenieAsset, position = 0) => {
const ethReserves = BigNumber.from(
(
(nft.ethReserves as number) ??
(nft?.ethReserves as number) ??
(
nft as Record<
string,
@ -51,12 +51,12 @@ export const calcPoolPrice = (asset: GenieAsset, position = 0) => {
ethReserves: number
}
>
).poolMetadata.ethReserves
)?.poolMetadata?.ethReserves
)?.toLocaleString('fullwide', { useGrouping: false }) ?? 1
)
const tokenReserves = BigNumber.from(
(
(nft.tokenReserves as number) ??
(nft?.tokenReserves as number) ??
(
nft as Record<
string,
@ -64,7 +64,7 @@ export const calcPoolPrice = (asset: GenieAsset, position = 0) => {
tokenReserves: number
}
>
).poolMetadata.tokenReserves
)?.poolMetadata?.tokenReserves
)?.toLocaleString('fullwide', { useGrouping: false }) ?? 1
)
const numerator = ethReserves.mul(amountToBuy).mul(1000)