Skip to content

Commit

Permalink
Merge branch 'main' of github.com:ourzora/nft-hooks into main
Browse files Browse the repository at this point in the history
  • Loading branch information
iainnash committed May 17, 2021
2 parents a85e653 + 00b24eb commit bb548ec
Show file tree
Hide file tree
Showing 15 changed files with 802 additions and 316 deletions.
3 changes: 3 additions & 0 deletions src/fetcher/FetchResultTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ export type MetadataResultType = {
metadata: any;
};

export type AuctionResultType = ReserveAuctionPartialFragment;
export type AuctionsResult = AuctionResultType[];

export type NFTMediaDataType = {
nft: Omit<NftMediaFragment, 'currentBids' | 'currentAsk'> & {
creatorBidSharePercentage: number;
Expand Down
43 changes: 38 additions & 5 deletions src/fetcher/MediaFetchAgent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -50,8 +53,6 @@ export class MediaFetchAgent {
currencyLoader: DataLoader<string, ChainCurrencyType>;
// fetches NFT ipfs metadata from url, not batched but cached
metadataLoader: DataLoader<string, any>;
// fetches auction house data for an arbitary NFT
// auctionLoader: DataLoader<{address: string, id: string}, NFTAuctionType>;
};

constructor(network: NetworkIDs) {
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/fetcher/TransformFetchResults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
49 changes: 35 additions & 14 deletions src/graph-queries/zora-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2254,19 +2254,13 @@ export type CurrentReserveBidFragment = (
) }
);

export type AskPriceFragment = (
{ __typename?: 'Ask' }
& Pick<Ask, 'id' | 'amount' | 'createdAtTimestamp'>
& { currency: (
{ __typename?: 'Currency' }
& CurrencyShortFragment
) }
);

export type ReserveAuctionPartialFragment = (
{ __typename?: 'ReserveAuction' }
& Pick<ReserveAuction, 'id' | 'tokenId' | 'status' | 'reservePrice' | 'firstBidTime' | 'createdAtTimestamp' | 'duration' | 'expectedEndTimestamp' | 'finalizedAtTimestamp'>
& { tokenOwner: (
& Pick<ReserveAuction, 'id' | 'tokenId' | 'status' | 'approved' | 'reservePrice' | 'firstBidTime' | 'createdAtTimestamp' | 'curatorFeePercentage' | 'duration' | 'expectedEndTimestamp' | 'finalizedAtTimestamp'>
& { curator: (
{ __typename?: 'User' }
& Pick<User, 'id'>
), tokenOwner: (
{ __typename?: 'User' }
& Pick<User, 'id'>
), auctionCurrency: (
Expand All @@ -2281,19 +2275,46 @@ export type ReserveAuctionPartialFragment = (
)>> }
);

export type GetAuctionsQueryVariables = Exact<{
auctionIds?: Maybe<Array<Scalars['ID']> | Scalars['ID']>;
export type GetAuctionsByCuratorQueryVariables = Exact<{
curators?: Maybe<Array<Scalars['String']> | Scalars['String']>;
approved?: Maybe<Array<Scalars['Boolean']> | Scalars['Boolean']>;
first?: Maybe<Scalars['Int']>;
skip?: Maybe<Scalars['Int']>;
}>;


export type GetAuctionsByCuratorQuery = (
{ __typename?: 'Query' }
& { reserveAuctions: Array<(
{ __typename?: 'ReserveAuction' }
& ReserveAuctionPartialFragment
)> }
);

export type GetAllAuctionsQueryVariables = Exact<{
approved?: Maybe<Array<Scalars['Boolean']> | Scalars['Boolean']>;
first?: Maybe<Scalars['Int']>;
skip?: Maybe<Scalars['Int']>;
}>;


export type GetAuctionsQuery = (
export type GetAllAuctionsQuery = (
{ __typename?: 'Query' }
& { reserveAuctions: Array<(
{ __typename?: 'ReserveAuction' }
& ReserveAuctionPartialFragment
)> }
);

export type AskPriceFragment = (
{ __typename?: 'Ask' }
& Pick<Ask, 'id' | 'amount' | 'createdAtTimestamp'>
& { currency: (
{ __typename?: 'Currency' }
& CurrencyShortFragment
) }
);

export type NftMediaFragment = (
{ __typename?: 'Media' }
& Pick<Media, 'id' | 'creatorBidShare' | 'createdAtTimestamp' | 'metadataURI' | 'metadataHash' | 'contentURI' | 'contentHash'>
Expand Down
56 changes: 41 additions & 15 deletions src/graph-queries/zora.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -64,21 +60,51 @@ 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
}
}
`;

export const GET_MEDIA_QUERY = gql`
${AUCTION_PARTIALS}
fragment AskPrice on Ask {
id
currency {
...CurrencyShort
}
amount
createdAtTimestamp
}
fragment NFTMedia on Media {
id
creatorBidShare
Expand Down
40 changes: 40 additions & 0 deletions src/hooks/useAuctions.ts
Original file line number Diff line number Diff line change
@@ -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<ReserveAuctionPartialFragment[]>();
const [error, setError] = useState<string | undefined>();

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,
};
}
5 changes: 4 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit bb548ec

Please sign in to comment.