From 00b24eb5b73fdd05794b411fb12946aa8c02b25a Mon Sep 17 00:00:00 2001 From: Iain Nash Date: Mon, 17 May 2021 16:12:26 -0400 Subject: [PATCH] Fetching curated auctions branch (#20) * v0.1.4 * adding curated auctions fetching hook * adding export * adding hook and tests * rm 1 2 * update graphql types * fix types * fix types and exports * fix ids --- package.json | 2 +- src/fetcher/FetchResultTypes.ts | 3 + src/fetcher/MediaFetchAgent.ts | 43 ++- src/fetcher/TransformFetchResults.ts | 2 +- src/graph-queries/zora-types.ts | 49 ++- src/graph-queries/zora.ts | 56 ++- src/hooks/useAuctions.ts | 40 ++ src/index.ts | 5 +- tests/__snapshots__/useAuctions.test.ts.snap | 239 ++++++++++++ tests/__snapshots__/useNFT.test.ts.snap | 381 +++++++++++-------- tests/setupFetchMock.ts | 14 +- tests/setupZoraGQLMock.ts | 35 +- tests/useAuctions.test.ts | 85 +++++ tests/useNFT.test.ts | 102 +++-- tests/useNFTContent.test.ts | 37 +- yarn.lock | 27 +- 16 files changed, 803 insertions(+), 317 deletions(-) create mode 100644 src/hooks/useAuctions.ts create mode 100644 tests/__snapshots__/useAuctions.test.ts.snap create mode 100644 tests/useAuctions.test.ts diff --git a/package.json b/package.json index e011cf5..b49a1e1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@zoralabs/nft-hooks", - "version": "0.1.3", + "version": "0.1.4", "description": "Generic Rendering Component for zNFTs", "repository": "https://github.com/our-zora/nft-hooks", "homepage": "https://github.com/our-zora/nft-hooks#README", diff --git a/src/fetcher/FetchResultTypes.ts b/src/fetcher/FetchResultTypes.ts index 6483657..19740fe 100644 --- a/src/fetcher/FetchResultTypes.ts +++ b/src/fetcher/FetchResultTypes.ts @@ -23,6 +23,9 @@ export type MetadataResultType = { metadata: any; }; +export type AuctionResultType = ReserveAuctionPartialFragment; +export type AuctionsResult = AuctionResultType[]; + export type NFTMediaDataType = { nft: Omit & { creatorBidSharePercentage: number; diff --git a/src/fetcher/MediaFetchAgent.ts b/src/fetcher/MediaFetchAgent.ts index b35780f..827344b 100644 --- a/src/fetcher/MediaFetchAgent.ts +++ b/src/fetcher/MediaFetchAgent.ts @@ -7,8 +7,11 @@ import { THEGRAPH_UNISWAP_URL_BY_NETWORK, } from '../constants/urls'; import type { NetworkIDs } from '../constants/networks'; -import { GET_MEDIA_QUERY } from '../graph-queries/zora'; -import type { GetMediaAndAuctionsQuery } from '../graph-queries/zora-types'; +import { GET_ALL_AUCTIONS, GET_AUCTION_BY_CURATOR, GET_MEDIA_QUERY } from '../graph-queries/zora'; +import type { + GetMediaAndAuctionsQuery, + GetAllAuctionsQuery, +} from '../graph-queries/zora-types'; import { GET_TOKEN_VALUES_QUERY } from '../graph-queries/uniswap'; import type { GetTokenPricesQuery } from '../graph-queries/uniswap-types'; import { TimeoutsLookupType, DEFAULT_NETWORK_TIMEOUTS_MS } from '../constants/timeouts'; @@ -50,8 +53,6 @@ export class MediaFetchAgent { currencyLoader: DataLoader; // fetches NFT ipfs metadata from url, not batched but cached metadataLoader: DataLoader; - // fetches auction house data for an arbitary NFT - // auctionLoader: DataLoader<{address: string, id: string}, NFTAuctionType>; }; constructor(network: NetworkIDs) { @@ -166,7 +167,39 @@ export class MediaFetchAgent { } /** - * Internal fetch function to retrieve Graph data for Zora NFT IDs + * Fetch function to retrieve Graph data for matching curated auctions + * This function is not cached + * + * @function fetchReserveAuctions + * @private + * @param curatorIds list of Zora NFT IDs to fetch from the graph datastore + * @returns mapped transformed list of curated auction results + */ + public async fetchReserveAuctions( + curatorIds: readonly string[], + isApproved: boolean | null = null, + first: number = 1000, + skip: number = 0 + ) { + const fetchWithTimeout = new FetchWithTimeout(this.timeouts.Graph); + const client = new GraphQLClient(this.graphEndpoint, { + fetch: fetchWithTimeout.fetch, + }); + let query = GET_ALL_AUCTIONS; + if (curatorIds.length) { + query = GET_AUCTION_BY_CURATOR; + } + const response = (await client.request(query, { + curators: curatorIds.length ? curatorIds : undefined, + first: first, + skip: skip, + approved: isApproved === null ? [true, false] : [isApproved], + })) as GetAllAuctionsQuery; + return response.reserveAuctions; + } + + /** + * Internal fetch current auctions by curator * * @function fetchMediaGraph * @private diff --git a/src/fetcher/TransformFetchResults.ts b/src/fetcher/TransformFetchResults.ts index b006722..ce7799f 100644 --- a/src/fetcher/TransformFetchResults.ts +++ b/src/fetcher/TransformFetchResults.ts @@ -298,7 +298,7 @@ export function addAuctionInformation( reservePrice: getReservePrice(), likelyHasEnded, reserveMet: hasActiveReserveAuction - ? !!chainNFT.pricing.reserve?.firstBidTime + ? !!chainNFT.pricing.reserve?.firstBidTime && chainNFT.pricing.reserve?.firstBidTime !== "0" : false, endingAt: hasActiveReserveAuction ? chainNFT.pricing.reserve?.expectedEndTimestamp diff --git a/src/graph-queries/zora-types.ts b/src/graph-queries/zora-types.ts index 935ab59..066ccc1 100644 --- a/src/graph-queries/zora-types.ts +++ b/src/graph-queries/zora-types.ts @@ -2254,19 +2254,13 @@ export type CurrentReserveBidFragment = ( ) } ); -export type AskPriceFragment = ( - { __typename?: 'Ask' } - & Pick - & { currency: ( - { __typename?: 'Currency' } - & CurrencyShortFragment - ) } -); - export type ReserveAuctionPartialFragment = ( { __typename?: 'ReserveAuction' } - & Pick - & { tokenOwner: ( + & Pick + & { curator: ( + { __typename?: 'User' } + & Pick + ), tokenOwner: ( { __typename?: 'User' } & Pick ), auctionCurrency: ( @@ -2281,12 +2275,30 @@ export type ReserveAuctionPartialFragment = ( )>> } ); -export type GetAuctionsQueryVariables = Exact<{ - auctionIds?: Maybe | Scalars['ID']>; +export type GetAuctionsByCuratorQueryVariables = Exact<{ + curators?: Maybe | Scalars['String']>; + approved?: Maybe | Scalars['Boolean']>; + first?: Maybe; + skip?: Maybe; +}>; + + +export type GetAuctionsByCuratorQuery = ( + { __typename?: 'Query' } + & { reserveAuctions: Array<( + { __typename?: 'ReserveAuction' } + & ReserveAuctionPartialFragment + )> } +); + +export type GetAllAuctionsQueryVariables = Exact<{ + approved?: Maybe | Scalars['Boolean']>; + first?: Maybe; + skip?: Maybe; }>; -export type GetAuctionsQuery = ( +export type GetAllAuctionsQuery = ( { __typename?: 'Query' } & { reserveAuctions: Array<( { __typename?: 'ReserveAuction' } @@ -2294,6 +2306,15 @@ export type GetAuctionsQuery = ( )> } ); +export type AskPriceFragment = ( + { __typename?: 'Ask' } + & Pick + & { currency: ( + { __typename?: 'Currency' } + & CurrencyShortFragment + ) } +); + export type NftMediaFragment = ( { __typename?: 'Media' } & Pick diff --git a/src/graph-queries/zora.ts b/src/graph-queries/zora.ts index 91fbff5..72d77cc 100644 --- a/src/graph-queries/zora.ts +++ b/src/graph-queries/zora.ts @@ -29,22 +29,18 @@ fragment CurrentReserveBid on ReserveAuctionBid { } } -fragment AskPrice on Ask { - id - currency { - ...CurrencyShort - } - amount - createdAtTimestamp -} - fragment ReserveAuctionPartial on ReserveAuction { id tokenId status + approved reservePrice firstBidTime createdAtTimestamp + curator { + id + } + curatorFeePercentage tokenOwner { id } @@ -64,13 +60,34 @@ fragment ReserveAuctionPartial on ReserveAuction { ` -export const GET_AUCTION_QUERY = gql` +export const GET_AUCTION_BY_CURATOR = gql` ${AUCTION_PARTIALS} - query getAuctions($auctionIds: [ID!]) { - reserveAuctions(where:{ - id_in: $auctionIds - }) { + query getAuctionsByCurator($curators: [String!], $approved: [Boolean!], $first: Int, $skip: Int) { + reserveAuctions(where: + { + curator_in: $curators, + approved_in: $approved + } + first: $first + skip: $skip + ) { + ...ReserveAuctionPartial + } + } +`; + +export const GET_ALL_AUCTIONS = gql` + ${AUCTION_PARTIALS} + + query getAllAuctions($approved: [Boolean!], $first: Int, $skip: Int) { + reserveAuctions( + where: { + approved_in: $approved + } + first: $first + skip: $skip + ) { ...ReserveAuctionPartial } } @@ -78,7 +95,16 @@ export const GET_AUCTION_QUERY = gql` export const GET_MEDIA_QUERY = gql` ${AUCTION_PARTIALS} - + + fragment AskPrice on Ask { + id + currency { + ...CurrencyShort + } + amount + createdAtTimestamp + } + fragment NFTMedia on Media { id creatorBidShare diff --git a/src/hooks/useAuctions.ts b/src/hooks/useAuctions.ts new file mode 100644 index 0000000..47432aa --- /dev/null +++ b/src/hooks/useAuctions.ts @@ -0,0 +1,40 @@ +import { useState } from 'react'; +import { ReserveAuctionPartialFragment } from 'src/graph-queries/zora-types'; + +import { useCallbackFetch } from './useCallbackFetch'; + +export type useAuctionHouseType = { + loading: boolean; + error?: string; + auctions?: ReserveAuctionPartialFragment[]; +}; + +/** + * Fetches on-chain NFT auction data for the given curator + * + * @param id id of zNFT to fetch blockchain information for + * @param curator + * @returns useNFTType hook results include loading, error, and chainNFT data. + */ +export function useAuctions( + curators: readonly string[] = [], + approved: boolean | null = null +): useAuctionHouseType { + const [auctions, setAuctions] = useState(); + const [error, setError] = useState(); + + useCallbackFetch(curators, async (fetchAgent, curators) => { + try { + let data = await fetchAgent.fetchReserveAuctions(curators, approved); + setAuctions(data); + } catch (err) { + setError(err.toString()); + } + }); + + return { + loading: !error && !auctions, + error, + auctions, + }; +} diff --git a/src/index.ts b/src/index.ts index 5c46d60..637db75 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,19 +4,22 @@ import { useNFTContent } from './hooks/useNFTContent'; import { useNFTMetadata } from './hooks/useNFTMetadata'; import { NFTFetchConfiguration } from './context/NFTFetchContext'; import { MediaFetchAgent } from './fetcher/MediaFetchAgent'; -import { NFTDataType, ChainCurrencyType } from './fetcher/FetchResultTypes'; +import { NFTDataType, ChainCurrencyType, AuctionResultType } from './fetcher/FetchResultTypes'; import * as ExtractResultData from './fetcher/TransformFetchResults'; +import { useAuctions } from './hooks/useAuctions'; export { // Hooks useNFT, useNFTContent, useNFTMetadata, + useAuctions, // Configuration NFTFetchConfiguration, // Fetch Agent underlying helper MediaFetchAgent, // Types + AuctionResultType, NFTDataType, ChainCurrencyType, // Constants diff --git a/tests/__snapshots__/useAuctions.test.ts.snap b/tests/__snapshots__/useAuctions.test.ts.snap new file mode 100644 index 0000000..e3f6c5d --- /dev/null +++ b/tests/__snapshots__/useAuctions.test.ts.snap @@ -0,0 +1,239 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`useNFT loads all auctions 1`] = ` +Array [ + Object { + "approved": true, + "auctionCurrency": Object { + "decimals": 18, + "id": "0xFACE", + "name": "Wrapped Ether", + "symbol": "WETH", + }, + "createdAtTimestamp": "12974", + "curator": Object { + "id": "10", + }, + "curatorFeePercentage": 10000, + "currentBid": Object { + "amount": "12974", + "bidType": "Final", + "bidder": Object { + "id": "10", + }, + "createdAtTimestamp": "12974", + }, + "duration": "12974", + "expectedEndTimestamp": "12974", + "finalizedAtTimestamp": "12974", + "firstBidTime": "12974", + "id": "0", + "previousBids": Array [ + Object { + "amount": "12974", + "bidInactivatedAtBlockNumber": "12974", + "bidInactivatedAtTimestamp": "12974", + "bidType": "Final", + "bidder": Object { + "id": "10", + }, + "createdAtTimestamp": "12974", + "id": "3", + }, + Object { + "amount": "12974", + "bidInactivatedAtBlockNumber": "12974", + "bidInactivatedAtTimestamp": "12974", + "bidType": "Final", + "bidder": Object { + "id": "10", + }, + "createdAtTimestamp": "12974", + "id": "4", + }, + ], + "reservePrice": "12974", + "status": "Active", + "tokenId": 0, + "tokenOwner": Object { + "id": "10", + }, + }, + Object { + "approved": true, + "auctionCurrency": Object { + "decimals": 18, + "id": "0xFACE", + "name": "Wrapped Ether", + "symbol": "WETH", + }, + "createdAtTimestamp": "12974", + "curator": Object { + "id": "10", + }, + "curatorFeePercentage": 10000, + "currentBid": Object { + "amount": "12974", + "bidType": "Final", + "bidder": Object { + "id": "10", + }, + "createdAtTimestamp": "12974", + }, + "duration": "12974", + "expectedEndTimestamp": "12974", + "finalizedAtTimestamp": "12974", + "firstBidTime": "12974", + "id": "1", + "previousBids": Array [ + Object { + "amount": "12974", + "bidInactivatedAtBlockNumber": "12974", + "bidInactivatedAtTimestamp": "12974", + "bidType": "Final", + "bidder": Object { + "id": "10", + }, + "createdAtTimestamp": "12974", + "id": "6", + }, + Object { + "amount": "12974", + "bidInactivatedAtBlockNumber": "12974", + "bidInactivatedAtTimestamp": "12974", + "bidType": "Final", + "bidder": Object { + "id": "10", + }, + "createdAtTimestamp": "12974", + "id": "7", + }, + ], + "reservePrice": "12974", + "status": "Active", + "tokenId": 1, + "tokenOwner": Object { + "id": "10", + }, + }, +] +`; + +exports[`useNFT loads specific auctions for a given curator 1`] = ` +Array [ + Object { + "approved": true, + "auctionCurrency": Object { + "decimals": 18, + "id": "0xFACE", + "name": "Wrapped Ether", + "symbol": "WETH", + }, + "createdAtTimestamp": "12974", + "curator": Object { + "id": "10", + }, + "curatorFeePercentage": 10000, + "currentBid": Object { + "amount": "12974", + "bidType": "Final", + "bidder": Object { + "id": "10", + }, + "createdAtTimestamp": "12974", + }, + "duration": "12974", + "expectedEndTimestamp": "12974", + "finalizedAtTimestamp": "12974", + "firstBidTime": "12974", + "id": "8", + "previousBids": Array [ + Object { + "amount": "12974", + "bidInactivatedAtBlockNumber": "12974", + "bidInactivatedAtTimestamp": "12974", + "bidType": "Final", + "bidder": Object { + "id": "10", + }, + "createdAtTimestamp": "12974", + "id": "11", + }, + Object { + "amount": "12974", + "bidInactivatedAtBlockNumber": "12974", + "bidInactivatedAtTimestamp": "12974", + "bidType": "Final", + "bidder": Object { + "id": "10", + }, + "createdAtTimestamp": "12974", + "id": "12", + }, + ], + "reservePrice": "12974", + "status": "Active", + "tokenId": 2, + "tokenOwner": Object { + "id": "10", + }, + }, + Object { + "approved": true, + "auctionCurrency": Object { + "decimals": 18, + "id": "0xFACE", + "name": "Wrapped Ether", + "symbol": "WETH", + }, + "createdAtTimestamp": "12974", + "curator": Object { + "id": "10", + }, + "curatorFeePercentage": 10000, + "currentBid": Object { + "amount": "12974", + "bidType": "Final", + "bidder": Object { + "id": "10", + }, + "createdAtTimestamp": "12974", + }, + "duration": "12974", + "expectedEndTimestamp": "12974", + "finalizedAtTimestamp": "12974", + "firstBidTime": "12974", + "id": "9", + "previousBids": Array [ + Object { + "amount": "12974", + "bidInactivatedAtBlockNumber": "12974", + "bidInactivatedAtTimestamp": "12974", + "bidType": "Final", + "bidder": Object { + "id": "10", + }, + "createdAtTimestamp": "12974", + "id": "14", + }, + Object { + "amount": "12974", + "bidInactivatedAtBlockNumber": "12974", + "bidInactivatedAtTimestamp": "12974", + "bidType": "Final", + "bidder": Object { + "id": "10", + }, + "createdAtTimestamp": "12974", + "id": "15", + }, + ], + "reservePrice": "12974", + "status": "Active", + "tokenId": 3, + "tokenOwner": Object { + "id": "10", + }, + }, +] +`; diff --git a/tests/__snapshots__/useNFT.test.ts.snap b/tests/__snapshots__/useNFT.test.ts.snap index 5bb0890..350634b 100644 --- a/tests/__snapshots__/useNFT.test.ts.snap +++ b/tests/__snapshots__/useNFT.test.ts.snap @@ -22,7 +22,7 @@ Object { }, "highestBid": Object { "placedAt": "12974", - "placedBy": "143", + "placedBy": "10", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -41,7 +41,7 @@ Object { "contentURI": "Hello World", "createdAtTimestamp": "12974", "creator": Object { - "id": "133", + "id": "10", }, "creatorBidShare": "12974", "creatorBidSharePercentage": 1.2974e-14, @@ -49,14 +49,14 @@ Object { "metadataHash": "ByTeSStrInG", "metadataURI": "Hello World", "owner": Object { - "id": "132", + "id": "10", }, }, "pricing": Object { "perpetual": Object { "ask": Object { "createdAtTimestamp": "12974", - "id": "134", + "id": "72", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -72,10 +72,10 @@ Object { "bids": Array [ Object { "bidder": Object { - "id": "137", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "135", + "id": "73", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -90,10 +90,10 @@ Object { }, Object { "bidder": Object { - "id": "138", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "136", + "id": "74", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -109,6 +109,7 @@ Object { ], }, "reserve": Object { + "approved": true, "auctionCurrency": Object { "decimals": 18, "id": "0xFACE", @@ -116,10 +117,14 @@ Object { "symbol": "WETH", }, "createdAtTimestamp": "12974", + "curator": Object { + "id": "10", + }, + "curatorFeePercentage": 77, "currentBid": Object { "bidType": "Final", "bidder": Object { - "id": "143", + "id": "10", }, "createdAtTimestamp": "12974", "pricing": Object { @@ -138,17 +143,17 @@ Object { "expectedEndTimestamp": "12974", "finalizedAtTimestamp": "12974", "firstBidTime": "12974", - "id": "139", + "id": "75", "previousBids": Array [ Object { "bidInactivatedAtBlockNumber": "12974", "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "146", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "144", + "id": "79", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -166,10 +171,10 @@ Object { "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "147", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "145", + "id": "80", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -187,7 +192,7 @@ Object { "status": "Active", "tokenId": "12974", "tokenOwner": Object { - "id": "141", + "id": "10", }, }, }, @@ -216,7 +221,7 @@ Object { }, "highestBid": Object { "placedAt": "12974", - "placedBy": "166", + "placedBy": "10", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -235,7 +240,7 @@ Object { "contentURI": "Hello World", "createdAtTimestamp": "12974", "creator": Object { - "id": "156", + "id": "10", }, "creatorBidShare": "12974", "creatorBidSharePercentage": 1.2974e-14, @@ -243,14 +248,14 @@ Object { "metadataHash": "ByTeSStrInG", "metadataURI": "Hello World", "owner": Object { - "id": "155", + "id": "10", }, }, "pricing": Object { "perpetual": Object { "ask": Object { "createdAtTimestamp": "12974", - "id": "157", + "id": "85", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -266,10 +271,10 @@ Object { "bids": Array [ Object { "bidder": Object { - "id": "160", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "158", + "id": "86", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -284,10 +289,10 @@ Object { }, Object { "bidder": Object { - "id": "161", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "159", + "id": "87", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -303,6 +308,7 @@ Object { ], }, "reserve": Object { + "approved": true, "auctionCurrency": Object { "decimals": 18, "id": "0xFACE", @@ -310,10 +316,14 @@ Object { "symbol": "WETH", }, "createdAtTimestamp": "12974", + "curator": Object { + "id": "10", + }, + "curatorFeePercentage": 90, "currentBid": Object { "bidType": "Final", "bidder": Object { - "id": "166", + "id": "10", }, "createdAtTimestamp": "12974", "pricing": Object { @@ -332,17 +342,17 @@ Object { "expectedEndTimestamp": "12974", "finalizedAtTimestamp": "12974", "firstBidTime": "12974", - "id": "162", + "id": "88", "previousBids": Array [ Object { "bidInactivatedAtBlockNumber": "12974", "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "169", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "167", + "id": "92", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -360,10 +370,10 @@ Object { "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "170", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "168", + "id": "93", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -381,7 +391,7 @@ Object { "status": "Active", "tokenId": "12974", "tokenOwner": Object { - "id": "164", + "id": "10", }, }, }, @@ -410,7 +420,7 @@ Object { }, "highestBid": Object { "placedAt": "12974", - "placedBy": "143", + "placedBy": "10", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -429,7 +439,7 @@ Object { "contentURI": "Hello World", "createdAtTimestamp": "12974", "creator": Object { - "id": "133", + "id": "10", }, "creatorBidShare": "12974", "creatorBidSharePercentage": 1.2974e-14, @@ -437,14 +447,14 @@ Object { "metadataHash": "ByTeSStrInG", "metadataURI": "Hello World", "owner": Object { - "id": "132", + "id": "10", }, }, "pricing": Object { "perpetual": Object { "ask": Object { "createdAtTimestamp": "12974", - "id": "134", + "id": "72", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -460,10 +470,10 @@ Object { "bids": Array [ Object { "bidder": Object { - "id": "137", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "135", + "id": "73", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -478,10 +488,10 @@ Object { }, Object { "bidder": Object { - "id": "138", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "136", + "id": "74", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -497,6 +507,7 @@ Object { ], }, "reserve": Object { + "approved": true, "auctionCurrency": Object { "decimals": 18, "id": "0xFACE", @@ -504,10 +515,14 @@ Object { "symbol": "WETH", }, "createdAtTimestamp": "12974", + "curator": Object { + "id": "10", + }, + "curatorFeePercentage": 77, "currentBid": Object { "bidType": "Final", "bidder": Object { - "id": "143", + "id": "10", }, "createdAtTimestamp": "12974", "pricing": Object { @@ -526,17 +541,17 @@ Object { "expectedEndTimestamp": "12974", "finalizedAtTimestamp": "12974", "firstBidTime": "12974", - "id": "139", + "id": "75", "previousBids": Array [ Object { "bidInactivatedAtBlockNumber": "12974", "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "146", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "144", + "id": "79", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -554,10 +569,10 @@ Object { "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "147", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "145", + "id": "80", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -575,7 +590,7 @@ Object { "status": "Active", "tokenId": "12974", "tokenOwner": Object { - "id": "141", + "id": "10", }, }, }, @@ -604,7 +619,7 @@ Object { }, "highestBid": Object { "placedAt": "12974", - "placedBy": "166", + "placedBy": "10", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -623,7 +638,7 @@ Object { "contentURI": "Hello World", "createdAtTimestamp": "12974", "creator": Object { - "id": "156", + "id": "10", }, "creatorBidShare": "12974", "creatorBidSharePercentage": 1.2974e-14, @@ -631,14 +646,14 @@ Object { "metadataHash": "ByTeSStrInG", "metadataURI": "Hello World", "owner": Object { - "id": "155", + "id": "10", }, }, "pricing": Object { "perpetual": Object { "ask": Object { "createdAtTimestamp": "12974", - "id": "157", + "id": "85", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -654,10 +669,10 @@ Object { "bids": Array [ Object { "bidder": Object { - "id": "160", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "158", + "id": "86", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -672,10 +687,10 @@ Object { }, Object { "bidder": Object { - "id": "161", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "159", + "id": "87", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -691,6 +706,7 @@ Object { ], }, "reserve": Object { + "approved": true, "auctionCurrency": Object { "decimals": 18, "id": "0xFACE", @@ -698,10 +714,14 @@ Object { "symbol": "WETH", }, "createdAtTimestamp": "12974", + "curator": Object { + "id": "10", + }, + "curatorFeePercentage": 90, "currentBid": Object { "bidType": "Final", "bidder": Object { - "id": "166", + "id": "10", }, "createdAtTimestamp": "12974", "pricing": Object { @@ -720,17 +740,17 @@ Object { "expectedEndTimestamp": "12974", "finalizedAtTimestamp": "12974", "firstBidTime": "12974", - "id": "162", + "id": "88", "previousBids": Array [ Object { "bidInactivatedAtBlockNumber": "12974", "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "169", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "167", + "id": "92", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -748,10 +768,10 @@ Object { "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "170", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "168", + "id": "93", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -769,7 +789,7 @@ Object { "status": "Active", "tokenId": "12974", "tokenOwner": Object { - "id": "164", + "id": "10", }, }, }, @@ -785,10 +805,10 @@ Object { "likelyHasEnded": true, "reserveMet": true, "reservePrice": Object { - "amount": "1000000", + "amount": "12974", "computedValue": Object { - "inETH": "1.38742323e-8", - "inUSD": "0.00019249432191436329", + "inETH": "1.800042898602e-10", + "inUSD": "0.00000249742133251694932446", }, "currency": Object { "decimals": 18, @@ -796,12 +816,12 @@ Object { "name": "Wrapped Ether", "symbol": "WETH", }, - "prettyAmount": "1e-12", + "prettyAmount": "1.2974e-14", }, }, "highestBid": Object { "placedAt": "12974", - "placedBy": "32", + "placedBy": "10", "pricing": Object { "amount": "12974", "computedValue": Object { @@ -823,7 +843,7 @@ Object { "contentURI": "https://zora.co/content", "createdAtTimestamp": "12974", "creator": Object { - "id": "25", + "id": "10", }, "creatorBidShare": "12974", "creatorBidSharePercentage": 1.2974e-14, @@ -831,14 +851,14 @@ Object { "metadataHash": "ByTeSStrInG", "metadataURI": "https://zora.co/content", "owner": Object { - "id": "24", + "id": "10", }, }, "pricing": Object { "perpetual": Object { "ask": Object { "createdAtTimestamp": "12974", - "id": "26", + "id": "14", "pricing": Object { "amount": "12974", "computedValue": Object { @@ -860,7 +880,7 @@ Object { "id": "10", }, "createdAtTimestamp": "12974", - "id": "27", + "id": "15", "pricing": Object { "amount": "10000", "computedValue": Object { @@ -879,6 +899,7 @@ Object { ], }, "reserve": Object { + "approved": true, "auctionCurrency": Object { "decimals": 18, "id": "0xFACE", @@ -886,10 +907,14 @@ Object { "symbol": "WETH", }, "createdAtTimestamp": "12974", + "curator": Object { + "id": "10", + }, + "curatorFeePercentage": 100, "currentBid": Object { "bidType": "Final", "bidder": Object { - "id": "32", + "id": "10", }, "createdAtTimestamp": "12974", "pricing": Object { @@ -911,17 +936,17 @@ Object { "expectedEndTimestamp": "12974", "finalizedAtTimestamp": "12974", "firstBidTime": "12974", - "id": "28", + "id": "16", "previousBids": Array [ Object { "bidInactivatedAtBlockNumber": "12974", "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "35", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "33", + "id": "19", "pricing": Object { "amount": "12974", "computedValue": Object { @@ -942,10 +967,10 @@ Object { "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "36", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "34", + "id": "20", "pricing": Object { "amount": "12974", "computedValue": Object { @@ -962,11 +987,11 @@ Object { }, }, ], - "reservePrice": "1000000", + "reservePrice": "12974", "status": "Active", - "tokenId": "2974", + "tokenId": 2974, "tokenOwner": Object { - "id": "30", + "id": "10", }, }, }, @@ -982,10 +1007,10 @@ Object { "likelyHasEnded": true, "reserveMet": true, "reservePrice": Object { - "amount": "1000000", + "amount": "12974", "computedValue": Object { - "inETH": "1.38742323e-8", - "inUSD": "0.00019249432191436329", + "inETH": "1.800042898602e-10", + "inUSD": "0.00000249742133251694932446", }, "currency": Object { "decimals": 18, @@ -993,12 +1018,12 @@ Object { "name": "Wrapped Ether", "symbol": "WETH", }, - "prettyAmount": "1e-12", + "prettyAmount": "1.2974e-14", }, }, "highestBid": Object { "placedAt": "12974", - "placedBy": "32", + "placedBy": "10", "pricing": Object { "amount": "12974", "computedValue": Object { @@ -1020,7 +1045,7 @@ Object { "contentURI": "https://zora.co/content", "createdAtTimestamp": "12974", "creator": Object { - "id": "25", + "id": "10", }, "creatorBidShare": "12974", "creatorBidSharePercentage": 1.2974e-14, @@ -1028,14 +1053,14 @@ Object { "metadataHash": "ByTeSStrInG", "metadataURI": "https://zora.co/content", "owner": Object { - "id": "24", + "id": "10", }, }, "pricing": Object { "perpetual": Object { "ask": Object { "createdAtTimestamp": "12974", - "id": "26", + "id": "14", "pricing": Object { "amount": "12974", "computedValue": Object { @@ -1057,7 +1082,7 @@ Object { "id": "10", }, "createdAtTimestamp": "12974", - "id": "27", + "id": "15", "pricing": Object { "amount": "10000", "computedValue": Object { @@ -1076,6 +1101,7 @@ Object { ], }, "reserve": Object { + "approved": true, "auctionCurrency": Object { "decimals": 18, "id": "0xFACE", @@ -1083,10 +1109,14 @@ Object { "symbol": "WETH", }, "createdAtTimestamp": "12974", + "curator": Object { + "id": "10", + }, + "curatorFeePercentage": 100, "currentBid": Object { "bidType": "Final", "bidder": Object { - "id": "32", + "id": "10", }, "createdAtTimestamp": "12974", "pricing": Object { @@ -1108,17 +1138,17 @@ Object { "expectedEndTimestamp": "12974", "finalizedAtTimestamp": "12974", "firstBidTime": "12974", - "id": "28", + "id": "16", "previousBids": Array [ Object { "bidInactivatedAtBlockNumber": "12974", "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "35", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "33", + "id": "19", "pricing": Object { "amount": "12974", "computedValue": Object { @@ -1139,10 +1169,10 @@ Object { "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "36", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "34", + "id": "20", "pricing": Object { "amount": "12974", "computedValue": Object { @@ -1159,11 +1189,11 @@ Object { }, }, ], - "reservePrice": "1000000", + "reservePrice": "12974", "status": "Active", - "tokenId": "2974", + "tokenId": 2974, "tokenOwner": Object { - "id": "30", + "id": "10", }, }, }, @@ -1192,7 +1222,7 @@ Object { }, "highestBid": Object { "placedAt": "12974", - "placedBy": "97", + "placedBy": "10", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1211,7 +1241,7 @@ Object { "contentURI": "Hello World", "createdAtTimestamp": "12974", "creator": Object { - "id": "87", + "id": "10", }, "creatorBidShare": "12974", "creatorBidSharePercentage": 1.2974e-14, @@ -1219,14 +1249,14 @@ Object { "metadataHash": "ByTeSStrInG", "metadataURI": "Hello World", "owner": Object { - "id": "86", + "id": "10", }, }, "pricing": Object { "perpetual": Object { "ask": Object { "createdAtTimestamp": "12974", - "id": "88", + "id": "46", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1242,10 +1272,10 @@ Object { "bids": Array [ Object { "bidder": Object { - "id": "91", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "89", + "id": "47", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1260,10 +1290,10 @@ Object { }, Object { "bidder": Object { - "id": "92", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "90", + "id": "48", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1279,6 +1309,7 @@ Object { ], }, "reserve": Object { + "approved": true, "auctionCurrency": Object { "decimals": 18, "id": "0xFACE", @@ -1286,10 +1317,14 @@ Object { "symbol": "WETH", }, "createdAtTimestamp": "12974", + "curator": Object { + "id": "10", + }, + "curatorFeePercentage": 51, "currentBid": Object { "bidType": "Final", "bidder": Object { - "id": "97", + "id": "10", }, "createdAtTimestamp": "12974", "pricing": Object { @@ -1308,17 +1343,17 @@ Object { "expectedEndTimestamp": "12974", "finalizedAtTimestamp": "12974", "firstBidTime": "12974", - "id": "93", + "id": "49", "previousBids": Array [ Object { "bidInactivatedAtBlockNumber": "12974", "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "100", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "98", + "id": "53", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1336,10 +1371,10 @@ Object { "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "101", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "99", + "id": "54", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1357,7 +1392,7 @@ Object { "status": "Active", "tokenId": "12974", "tokenOwner": Object { - "id": "95", + "id": "10", }, }, }, @@ -1386,7 +1421,7 @@ Object { }, "highestBid": Object { "placedAt": "12974", - "placedBy": "120", + "placedBy": "10", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1405,7 +1440,7 @@ Object { "contentURI": "Hello World", "createdAtTimestamp": "12974", "creator": Object { - "id": "110", + "id": "10", }, "creatorBidShare": "12974", "creatorBidSharePercentage": 1.2974e-14, @@ -1413,14 +1448,14 @@ Object { "metadataHash": "ByTeSStrInG", "metadataURI": "Hello World", "owner": Object { - "id": "109", + "id": "10", }, }, "pricing": Object { "perpetual": Object { "ask": Object { "createdAtTimestamp": "12974", - "id": "111", + "id": "59", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1436,10 +1471,10 @@ Object { "bids": Array [ Object { "bidder": Object { - "id": "114", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "112", + "id": "60", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1454,10 +1489,10 @@ Object { }, Object { "bidder": Object { - "id": "115", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "113", + "id": "61", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1473,6 +1508,7 @@ Object { ], }, "reserve": Object { + "approved": true, "auctionCurrency": Object { "decimals": 18, "id": "0xFACE", @@ -1480,10 +1516,14 @@ Object { "symbol": "WETH", }, "createdAtTimestamp": "12974", + "curator": Object { + "id": "10", + }, + "curatorFeePercentage": 64, "currentBid": Object { "bidType": "Final", "bidder": Object { - "id": "120", + "id": "10", }, "createdAtTimestamp": "12974", "pricing": Object { @@ -1502,17 +1542,17 @@ Object { "expectedEndTimestamp": "12974", "finalizedAtTimestamp": "12974", "firstBidTime": "12974", - "id": "116", + "id": "62", "previousBids": Array [ Object { "bidInactivatedAtBlockNumber": "12974", "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "123", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "121", + "id": "66", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1530,10 +1570,10 @@ Object { "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "124", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "122", + "id": "67", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1551,7 +1591,7 @@ Object { "status": "Active", "tokenId": "12974", "tokenOwner": Object { - "id": "118", + "id": "10", }, }, }, @@ -1580,7 +1620,7 @@ Object { }, "highestBid": Object { "placedAt": "12974", - "placedBy": "55", + "placedBy": "10", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1599,7 +1639,7 @@ Object { "contentURI": "https://zora.co/content", "createdAtTimestamp": "12974", "creator": Object { - "id": "48", + "id": "10", }, "creatorBidShare": "12974", "creatorBidSharePercentage": 1.2974e-14, @@ -1607,14 +1647,14 @@ Object { "metadataHash": "ByTeSStrInG", "metadataURI": "https://zora.co/content", "owner": Object { - "id": "47", + "id": "10", }, }, "pricing": Object { "perpetual": Object { "ask": Object { "createdAtTimestamp": "12974", - "id": "49", + "id": "27", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1633,7 +1673,7 @@ Object { "id": "10", }, "createdAtTimestamp": "12974", - "id": "50", + "id": "28", "pricing": Object { "amount": "10000", "computedValue": undefined, @@ -1649,6 +1689,7 @@ Object { ], }, "reserve": Object { + "approved": true, "auctionCurrency": Object { "decimals": 18, "id": "0xFACE", @@ -1656,10 +1697,14 @@ Object { "symbol": "WETH", }, "createdAtTimestamp": "12974", + "curator": Object { + "id": "10", + }, + "curatorFeePercentage": 100, "currentBid": Object { "bidType": "Final", "bidder": Object { - "id": "55", + "id": "10", }, "createdAtTimestamp": "12974", "pricing": Object { @@ -1678,17 +1723,17 @@ Object { "expectedEndTimestamp": "12974", "finalizedAtTimestamp": "12974", "firstBidTime": "12974", - "id": "51", + "id": "29", "previousBids": Array [ Object { "bidInactivatedAtBlockNumber": "12974", "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "58", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "56", + "id": "32", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1706,10 +1751,10 @@ Object { "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "59", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "57", + "id": "33", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1727,7 +1772,7 @@ Object { "status": "Active", "tokenId": "-1", "tokenOwner": Object { - "id": "53", + "id": "10", }, }, }, @@ -1756,7 +1801,7 @@ Object { }, "highestBid": Object { "placedAt": "12974", - "placedBy": "74", + "placedBy": "10", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1775,7 +1820,7 @@ Object { "contentURI": "https://zora.co/content", "createdAtTimestamp": "12974", "creator": Object { - "id": "68", + "id": "10", }, "creatorBidShare": "12974", "creatorBidSharePercentage": 1.2974e-14, @@ -1783,14 +1828,14 @@ Object { "metadataHash": "ByTeSStrInG", "metadataURI": "https://zora.co/content", "owner": Object { - "id": "67", + "id": "10", }, }, "pricing": Object { "perpetual": Object { "ask": Object { "createdAtTimestamp": "12974", - "id": "69", + "id": "37", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1806,6 +1851,7 @@ Object { "bids": Array [], }, "reserve": Object { + "approved": true, "auctionCurrency": Object { "decimals": 18, "id": "0xFACE", @@ -1813,10 +1859,14 @@ Object { "symbol": "WETH", }, "createdAtTimestamp": "12974", + "curator": Object { + "id": "10", + }, + "curatorFeePercentage": 100, "currentBid": Object { "bidType": "Final", "bidder": Object { - "id": "74", + "id": "10", }, "createdAtTimestamp": "12974", "pricing": Object { @@ -1835,17 +1885,17 @@ Object { "expectedEndTimestamp": "12974", "finalizedAtTimestamp": "12974", "firstBidTime": "12974", - "id": "70", + "id": "38", "previousBids": Array [ Object { "bidInactivatedAtBlockNumber": "12974", "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "77", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "75", + "id": "41", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1863,10 +1913,10 @@ Object { "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "78", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "76", + "id": "42", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1884,7 +1934,7 @@ Object { "status": "Active", "tokenId": "-1", "tokenOwner": Object { - "id": "72", + "id": "10", }, }, }, @@ -1900,7 +1950,7 @@ Object { "likelyHasEnded": true, "reserveMet": true, "reservePrice": Object { - "amount": "1000000", + "amount": "12974", "computedValue": undefined, "currency": Object { "decimals": 18, @@ -1908,7 +1958,7 @@ Object { "name": "Wrapped Ether", "symbol": "WETH", }, - "prettyAmount": "1e-12", + "prettyAmount": "1.2974e-14", }, }, "highestBid": Object { @@ -1932,7 +1982,7 @@ Object { "contentURI": "https://zora.co/content", "createdAtTimestamp": "12974", "creator": Object { - "id": "3", + "id": "10", }, "creatorBidShare": "12974", "creatorBidSharePercentage": 1.2974e-14, @@ -1940,14 +1990,14 @@ Object { "metadataHash": "ByTeSStrInG", "metadataURI": "https://zora.co/content", "owner": Object { - "id": "2", + "id": "10", }, }, "pricing": Object { "perpetual": Object { "ask": Object { "createdAtTimestamp": "12974", - "id": "4", + "id": "2", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -1966,7 +2016,7 @@ Object { "id": "10", }, "createdAtTimestamp": "12974", - "id": "5", + "id": "3", "pricing": Object { "amount": "10000", "computedValue": undefined, @@ -1982,6 +2032,7 @@ Object { ], }, "reserve": Object { + "approved": true, "auctionCurrency": Object { "decimals": 18, "id": "0xFACE", @@ -1989,6 +2040,10 @@ Object { "symbol": "WETH", }, "createdAtTimestamp": "12974", + "curator": Object { + "id": "10", + }, + "curatorFeePercentage": 100, "currentBid": Object { "bidType": "Final", "bidder": Object { @@ -2011,17 +2066,17 @@ Object { "expectedEndTimestamp": "12974", "finalizedAtTimestamp": "12974", "firstBidTime": "12974", - "id": "6", + "id": "4", "previousBids": Array [ Object { "bidInactivatedAtBlockNumber": "12974", "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "13", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "11", + "id": "7", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -2039,10 +2094,10 @@ Object { "bidInactivatedAtTimestamp": "12974", "bidType": "Final", "bidder": Object { - "id": "14", + "id": "10", }, "createdAtTimestamp": "12974", - "id": "12", + "id": "8", "pricing": Object { "amount": "12974", "computedValue": undefined, @@ -2056,11 +2111,11 @@ Object { }, }, ], - "reservePrice": "1000000", + "reservePrice": "12974", "status": "Active", - "tokenId": "2974", + "tokenId": 2974, "tokenOwner": Object { - "id": "8", + "id": "10", }, }, }, diff --git a/tests/setupFetchMock.ts b/tests/setupFetchMock.ts index bd0d10f..f5e1741 100644 --- a/tests/setupFetchMock.ts +++ b/tests/setupFetchMock.ts @@ -1,8 +1,14 @@ -import {FetchMockSandbox} from 'fetch-mock'; -import crossFetch from "cross-fetch"; +import { FetchMockSandbox } from 'fetch-mock'; +import crossFetch from 'cross-fetch'; -jest.mock("cross-fetch", () => require("fetch-mock-jest").sandbox()); +jest.mock('cross-fetch', () => require('fetch-mock-jest').sandbox()); const fetchMock = crossFetch as FetchMockSandbox; -export default fetchMock; \ No newline at end of file +export function getLastGraphQuery(url: string) { + // @ts-ignore + const requestBody = fetchMock.lastCall(url)[1].body as string; + return JSON.parse(requestBody); +} + +export default fetchMock; diff --git a/tests/setupZoraGQLMock.ts b/tests/setupZoraGQLMock.ts index 9b332a5..33fde68 100644 --- a/tests/setupZoraGQLMock.ts +++ b/tests/setupZoraGQLMock.ts @@ -1,17 +1,17 @@ -import { makeExecutableSchema } from "@graphql-tools/schema"; -import { addMocksToSchema } from "@graphql-tools/mock"; -import { graphql } from "graphql"; +import { makeExecutableSchema } from '@graphql-tools/schema'; +import { addMocksToSchema } from '@graphql-tools/mock'; +import { graphql } from 'graphql'; // @ts-ignore -import zoraSchema from "../graph-schemas/zora.graphql"; +import zoraSchema from '../graph-schemas/zora.graphql'; // @ts-ignore -import uniswapSchema from "../graph-schemas/uniswap.graphql"; +import uniswapSchema from '../graph-schemas/uniswap.graphql'; -import fetchMock from "./setupFetchMock"; +import fetchMock from './setupFetchMock'; let currentID = 0; -export type SchemaName = "Zora" | "Uniswap"; +export type SchemaName = 'Zora' | 'Uniswap'; const Schemas: Record = { Zora: zoraSchema, @@ -22,22 +22,25 @@ async function makeQuery( mockOverrides: any, requestBody: string, resolverOverrides: any, - schema: SchemaName = "Zora" + schema: SchemaName = 'Zora' ) { const mocks = { - BigInt: () => "12974", - BigDecimal: () => "13874.2323", - Bytes: () => "ByTeSStrInG", + BigInt: () => '12974', + BigDecimal: () => '13874.2323', + Bytes: () => 'ByTeSStrInG', // Randomly chosen by mock // breaks consistent testing - ReserveAuctionBidType: () => "Final", - ReserveAuctionStatus: () => "Active", + Boolean: () => true, + Int: () => currentID++, + ReserveAuctionBidType: () => 'Final', + ReserveAuctionStatus: () => 'Active', ID: () => (currentID++).toString(), + User: () => ({ id: '10' }), Currency: () => ({ - name: "Wrapped Ether", - symbol: "WETH", + name: 'Wrapped Ether', + symbol: 'WETH', decimals: 18, - id: "0xFACE", + id: '0xFACE', }), ...mockOverrides, }; diff --git a/tests/useAuctions.test.ts b/tests/useAuctions.test.ts new file mode 100644 index 0000000..bf522ce --- /dev/null +++ b/tests/useAuctions.test.ts @@ -0,0 +1,85 @@ +import { renderHook } from '@testing-library/react-hooks'; + +import { mockGraphQLQuery } from './setupZoraGQLMock'; + +import fetchMock, { getLastGraphQuery } from './setupFetchMock'; + +import { defaultFetchAgent } from '../src/context/NFTFetchContext'; +import { useAuctions } from '../src/hooks/useAuctions'; + +let id = 0; +const getId = () => id++; + +describe('useNFT', () => { + beforeEach(() => { + fetchMock.reset(); + defaultFetchAgent.clearCache(); + }); + const RESERVE_AUCTION_MOCK = { + tokenId: getId, + status: 'Active', + approved: true, + curatorFeePercentage: 10000, + }; + + it('loads all auctions', async () => { + const mockOverrides = { + ReserveAuction: () => ({ + ...RESERVE_AUCTION_MOCK, + }), + }; + + mockGraphQLQuery( + 'https://api.thegraph.com/subgraphs/name/ourzora/zora-v1', + mockOverrides + ); + + const { waitFor, result } = renderHook(() => useAuctions()); + + await waitFor(() => result.current.loading === false); + + expect( + getLastGraphQuery('https://api.thegraph.com/subgraphs/name/ourzora/zora-v1') + .variables + ).toEqual({ + first: 1000, + skip: 0, + approved: [true, false], + }); + + expect(result.current.error).toBeUndefined(); + expect(result.current.loading).toBeFalsy(); + expect(result.current.auctions).toMatchSnapshot(); + }); + + it('loads specific auctions for a given curator', async () => { + const mockOverrides = { + ReserveAuction: () => ({ + ...RESERVE_AUCTION_MOCK, + }), + }; + + mockGraphQLQuery( + 'https://api.thegraph.com/subgraphs/name/ourzora/zora-v1', + mockOverrides + ); + + const { waitFor, result } = renderHook(() => useAuctions(['0xtestingcurator'], true)); + + await waitFor(() => result.current.loading === false); + + expect( + getLastGraphQuery('https://api.thegraph.com/subgraphs/name/ourzora/zora-v1') + .variables + ).toEqual({ + first: 1000, + skip: 0, + approved: [true], + curators: ['0xtestingcurator'], + }); + + expect(result.current.error).toBeUndefined(); + expect(result.current.loading).toBeFalsy(); + expect(result.current.auctions).toMatchSnapshot(); + }); +}); diff --git a/tests/useNFT.test.ts b/tests/useNFT.test.ts index 7b6e80b..8722dab 100644 --- a/tests/useNFT.test.ts +++ b/tests/useNFT.test.ts @@ -1,46 +1,48 @@ -import { renderHook } from "@testing-library/react-hooks"; -import { IMockStore } from "@graphql-tools/mock"; +import { renderHook } from '@testing-library/react-hooks'; +import { IMockStore } from '@graphql-tools/mock'; -import { mockGraphQLQuery } from "./setupZoraGQLMock"; +import { mockGraphQLQuery } from './setupZoraGQLMock'; -import fetchMock from "./setupFetchMock"; +import fetchMock from './setupFetchMock'; -import { defaultFetchAgent } from "../src/context/NFTFetchContext"; -import { useNFT } from "../src"; +import { defaultFetchAgent } from '../src/context/NFTFetchContext'; +import { useNFT } from '../src'; -describe("useNFT", () => { +describe('useNFT', () => { beforeEach(() => { fetchMock.reset(); defaultFetchAgent.clearCache(); }); const MEDIA_MOCK = { - id: "2974", - contentURI: "https://zora.co/content", - metadataURI: "https://zora.co/content", + id: '2974', + contentURI: 'https://zora.co/content', + metadataURI: 'https://zora.co/content', currentBids: [ { - amount: "10000", + amount: '10000', bidder: { id: 10 }, }, ], }; + const RESERVE_AUCTION_MOCK = { + tokenId: 2974, + status: 'Active', + curatorFeePercentage: 100, + approved: true, + }; - it("loads an nft currently in an auction", async () => { + it('loads an nft currently in an auction', async () => { const mockOverrides = { Media: () => MEDIA_MOCK, - ReserveAuction: () => ({ - tokenId: "2974", - status: "Active", - reservePrice: "1000000", - }), + ReserveAuction: () => RESERVE_AUCTION_MOCK, }; mockGraphQLQuery( - "https://api.thegraph.com/subgraphs/name/ourzora/zora-v1", + 'https://api.thegraph.com/subgraphs/name/ourzora/zora-v1', mockOverrides ); - const { waitFor, result } = renderHook(() => useNFT("2974")); + const { waitFor, result } = renderHook(() => useNFT('2974')); await waitFor(() => result.current.loading === false); @@ -49,37 +51,33 @@ describe("useNFT", () => { expect(result.current.data).toMatchSnapshot(); }); - it("correctly loads auction information from uniswap", async () => { + it('correctly loads auction information from uniswap', async () => { const mockZoraOverrides = { Media: () => MEDIA_MOCK, - ReserveAuction: () => ({ - tokenId: "2974", - status: "Active", - reservePrice: "1000000", - }), + ReserveAuction: () => RESERVE_AUCTION_MOCK, }; const mockUniswapOverrides = { Token: () => ({ - id: "0xFACE", + id: '0xFACE', decimals: 18, }), }; mockGraphQLQuery( - "https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v2", + 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v2', mockUniswapOverrides, {}, - "Uniswap" + 'Uniswap' ); mockGraphQLQuery( - "https://api.thegraph.com/subgraphs/name/ourzora/zora-v1", + 'https://api.thegraph.com/subgraphs/name/ourzora/zora-v1', mockZoraOverrides, {}, - "Zora" + 'Zora' ); - const { waitFor, result } = renderHook(() => useNFT("2974", true)); + const { waitFor, result } = renderHook(() => useNFT('2974', true)); await waitFor(() => result.current.loading === false); @@ -93,19 +91,19 @@ describe("useNFT", () => { expect(result.current.data).toMatchSnapshot(); }); - it("loads an NFT not in an auction with bids", async () => { + it('loads an NFT not in an auction with bids', async () => { const mockOverrides = { Media: () => MEDIA_MOCK, // make an invalid reserve auction record to not be picked up by the fetch API - ReserveAuction: () => ({ tokenId: "-1" }), + ReserveAuction: () => ({ ...RESERVE_AUCTION_MOCK, tokenId: '-1' }), }; mockGraphQLQuery( - "https://api.thegraph.com/subgraphs/name/ourzora/zora-v1", + 'https://api.thegraph.com/subgraphs/name/ourzora/zora-v1', mockOverrides ); - const { waitFor, result } = renderHook(() => useNFT("2974")); + const { waitFor, result } = renderHook(() => useNFT('2974')); await waitFor(() => result.current.loading === false); @@ -114,36 +112,36 @@ describe("useNFT", () => { expect(result.current.data).toMatchSnapshot(); }); - it("shows an error when an NFT cannot be loaded", async () => { + it('shows an error when an NFT cannot be loaded', async () => { fetchMock.post( - "https://api.thegraph.com/subgraphs/name/ourzora/zora-v1", - "server failure", + 'https://api.thegraph.com/subgraphs/name/ourzora/zora-v1', + 'server failure', { response: { status: 500 } } ); - const { waitFor, result } = renderHook(() => useNFT("2974")); + const { waitFor, result } = renderHook(() => useNFT('2974')); await waitFor(() => result.current.loading === false); expect(result.current.data).toBeUndefined(); - expect(result.current.error).toEqual("RequestError: Request Status = 500"); + expect(result.current.error).toEqual('RequestError: Request Status = 500'); expect(result.current.loading).toBeFalsy(); }); - it("loads an NFT with no bids and no auction", async () => { + it('loads an NFT with no bids and no auction', async () => { const mediaWithNoBids = { ...MEDIA_MOCK, currentBids: [] }; const mockOverrides = { Media: () => mediaWithNoBids, // make an invalid reserve auction record to not be picked up by the fetch API - ReserveAuction: () => ({ tokenId: "-1" }), + ReserveAuction: () => ({ ...RESERVE_AUCTION_MOCK, tokenId: '-1' }), }; mockGraphQLQuery( - "https://api.thegraph.com/subgraphs/name/ourzora/zora-v1", + 'https://api.thegraph.com/subgraphs/name/ourzora/zora-v1', mockOverrides ); - const { waitFor, result } = renderHook(() => useNFT("2974")); + const { waitFor, result } = renderHook(() => useNFT('2974')); await waitFor(() => result.current.loading === false); @@ -152,20 +150,20 @@ describe("useNFT", () => { expect(result.current.data).toMatchSnapshot(); }); - it("correctly loads multiple perpetual bid NFTs", async () => { + it('correctly loads multiple perpetual bid NFTs', async () => { function useMultipleNFTHooks() { - return [useNFT("1"), useNFT("2")]; + return [useNFT('1'), useNFT('2')]; } mockGraphQLQuery( - "https://api.thegraph.com/subgraphs/name/ourzora/zora-v1", + 'https://api.thegraph.com/subgraphs/name/ourzora/zora-v1', {}, (store: IMockStore) => { return { Query: { medias: () => { // Fix returning ID for each record with multiple records. - return [store.get("Media", "1"), store.get("Media", "2")]; + return [store.get('Media', '1'), store.get('Media', '2')]; }, }, }; @@ -184,20 +182,20 @@ describe("useNFT", () => { expect(result.current[1].loading).toBeFalsy(); expect(result.current[1].data).toMatchSnapshot(); }); - it("caches multiple NFTs being loaded", async () => { + it('caches multiple NFTs being loaded', async () => { function useMultipleNFTHooks() { - return [useNFT("1"), useNFT("2")]; + return [useNFT('1'), useNFT('2')]; } mockGraphQLQuery( - "https://api.thegraph.com/subgraphs/name/ourzora/zora-v1", + 'https://api.thegraph.com/subgraphs/name/ourzora/zora-v1', {}, (store: IMockStore) => { return { Query: { medias: () => { // Fix returning ID for each record with multiple records. - return [store.get("Media", "1"), store.get("Media", "2")]; + return [store.get('Media', '1'), store.get('Media', '2')]; }, }, }; diff --git a/tests/useNFTContent.test.ts b/tests/useNFTContent.test.ts index 05a5dac..fabd39e 100644 --- a/tests/useNFTContent.test.ts +++ b/tests/useNFTContent.test.ts @@ -1,22 +1,19 @@ -import { renderHook } from "@testing-library/react-hooks"; +import { renderHook } from '@testing-library/react-hooks'; -import fetchMock from "./setupFetchMock"; +import fetchMock from './setupFetchMock'; -import { useNFTContent } from "../src"; +import { useNFTContent } from '../src'; -describe("useNFTContent", () => { +describe('useNFTContent', () => { afterEach(() => { fetchMock.reset(); }); - it("loads text content for NFT from server", async () => { - fetchMock.get( - "https://ipfs.io/ipfs/IPFS_SHA_EXAMPLE", - "this is plain text" - ); + it('loads text content for NFT from server', async () => { + fetchMock.get('https://ipfs.io/ipfs/IPFS_SHA_EXAMPLE', 'this is plain text'); const { waitFor, result } = renderHook(() => - useNFTContent("https://ipfs.io/ipfs/IPFS_SHA_EXAMPLE", "text/plain") + useNFTContent('https://ipfs.io/ipfs/IPFS_SHA_EXAMPLE', 'text/plain') ); await waitFor(() => result.current.loading === false); @@ -24,20 +21,20 @@ describe("useNFTContent", () => { expect(result.current.error).toBeUndefined(); expect(result.current.loading).toBeFalsy(); expect(result.current.content).toEqual({ - type: "text", - mimeType: "text/plain", - text: "this is plain text", + type: 'text', + mimeType: 'text/plain', + text: 'this is plain text', }); }); - it("has error fetching content", async () => { - fetchMock.get("https://ipfs.io/ipfs/IPFS_SHA_EXAMPLE", "Not Found", { + it('has error fetching content', async () => { + fetchMock.get('https://ipfs.io/ipfs/IPFS_SHA_EXAMPLE', 'Not Found', { response: { status: 404, }, }); const { waitFor, result } = renderHook(() => - useNFTContent("https://ipfs.io/ipfs/IPFS_SHA_EXAMPLE", "text/plain") + useNFTContent('https://ipfs.io/ipfs/IPFS_SHA_EXAMPLE', 'text/plain') ); await waitFor(() => result.current.loading === false); @@ -46,9 +43,9 @@ describe("useNFTContent", () => { expect(result.current.loading).toBeFalsy(); expect(result.current.content).toEqual(undefined); }); - it("returns reference URI to user", async () => { + it('returns reference URI to user', async () => { const { waitFor, result } = renderHook(() => - useNFTContent("https://ipfs.io/ipfs/IPFS_SHA_EXAMPLE", "image/gif") + useNFTContent('https://ipfs.io/ipfs/IPFS_SHA_EXAMPLE', 'image/gif') ); await waitFor(() => result.current.loading === false); @@ -56,9 +53,9 @@ describe("useNFTContent", () => { expect(result.current.error).toBeUndefined(); expect(result.current.loading).toBeFalsy(); expect(result.current.content).toEqual({ - mimeType: "image/gif", + mimeType: 'image/gif', type: 'uri', - uri: "https://ipfs.io/ipfs/IPFS_SHA_EXAMPLE", + uri: 'https://ipfs.io/ipfs/IPFS_SHA_EXAMPLE', }); }); }); diff --git a/yarn.lock b/yarn.lock index 8373719..8e219f3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1466,13 +1466,6 @@ resolved "https://registry.yarnpkg.com/@types/json-stable-stringify/-/json-stable-stringify-1.0.32.tgz#121f6917c4389db3923640b2e68de5fa64dda88e" integrity sha512-q9Q6+eUEGwQkv4Sbst3J4PNgDOvpuVuKj79Hl/qnmBMEIPzB5QoFRUtjcgcg2xNUZyYUGXBk5wYIBKHt0A+Mxw== -"@types/jsonschema@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@types/jsonschema/-/jsonschema-1.1.1.tgz#08703dfe074010e8e829123111594af731f57b1a" - integrity sha1-CHA9/gdAEOjoKRIxEVlK9zH1exo= - dependencies: - jsonschema "*" - "@types/jsonwebtoken@^8.5.0": version "8.5.1" resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#56958cb2d80f6d74352bd2e501a018e2506a8a84" @@ -1595,17 +1588,6 @@ dependencies: tslib "^2.1.0" -"@zoralabs/media-metadata-schemas@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@zoralabs/media-metadata-schemas/-/media-metadata-schemas-0.1.3.tgz#082091b70ad1bd5e3b235afed391eefb0de83770" - integrity sha512-nyB/igVrifY2/AQgeq5eg081Q17VTFh7YP5Axda5v6CpNbSYSjAfgSFGSPG7Ho8t+T24wWBane8ainJGPP25mA== - dependencies: - "@types/jsonschema" "^1.1.1" - jsonschema "^1.4.0" - ts-node "^9.1.1" - tslib "^2.0.3" - typescript "^4.1.3" - abab@^2.0.0, abab@^2.0.3, abab@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" @@ -5077,11 +5059,6 @@ jsonify@~0.0.0: resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= -jsonschema@*, jsonschema@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.0.tgz#1afa34c4bc22190d8e42271ec17ac8b3404f87b2" - integrity sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw== - jsonwebtoken@^8.5.1: version "8.5.1" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" @@ -7226,7 +7203,7 @@ ts-log@^2.2.3: resolved "https://registry.yarnpkg.com/ts-log/-/ts-log-2.2.3.tgz#4da5640fe25a9fb52642cd32391c886721318efb" integrity sha512-XvB+OdKSJ708Dmf9ore4Uf/q62AYDTzFcAdxc8KNML1mmAWywRFVt/dn1KYJH8Agt5UJNujfM3znU5PxgAzA2w== -ts-node@^9, ts-node@^9.1.1: +ts-node@^9: version "9.1.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" integrity sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg== @@ -7309,7 +7286,7 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@^4.1.3, typescript@^4.2.4: +typescript@^4.2.4: version "4.2.4" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==