-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[iain feat] release 1.0.0-rc0 of nft-hooks
- Loading branch information
0 parents
commit db142e4
Showing
41 changed files
with
15,556 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
env_defaults: &env_defaults | ||
working_directory: ~ | ||
docker: | ||
- image: circleci/node:14.15.1 | ||
|
||
version: 2.1 | ||
jobs: | ||
prepare: | ||
<<: *env_defaults | ||
steps: | ||
- checkout | ||
|
||
# Download and cache dependencies | ||
- restore_cache: | ||
keys: | ||
- v1.0-dependencies-{{ checksum "yarn.lock" }} | ||
# fallback to using the latest cache if no exact match is found | ||
- v1.0-dependencies- | ||
|
||
- node/install-packages: | ||
pkg-manager: yarn | ||
|
||
- run: yarn install | ||
|
||
- run: yarn add jest-junit -W | ||
|
||
- save_cache: | ||
paths: | ||
- node_modules | ||
key: v1.0-dependencies-{{ checksum "yarn.lock" }} | ||
|
||
- persist_to_workspace: | ||
root: . | ||
paths: | ||
- node_modules | ||
|
||
test: | ||
<<: *env_defaults | ||
steps: | ||
- checkout | ||
- attach_workspace: | ||
at: . | ||
- run: | ||
command: yarn run jest --ci --testResultsProcessor="jest-junit" --coverage --coverageDirectory ~/coverage | ||
name: Run Tests | ||
environment: | ||
JEST_JUNIT_OUTPUT_DIR: "~/reports/nft-hooks" | ||
- store_test_results: {path: "~/reports/nft-hooks"} | ||
- store_artifacts: {path: "~/coverage"} | ||
build: | ||
<<: *env_defaults | ||
steps: | ||
- checkout | ||
- attach_workspace: | ||
at: . | ||
- run: | ||
command: yarn run build | ||
name: Build Typescript Package | ||
|
||
orbs: | ||
node: circleci/[email protected] | ||
workflows: | ||
test: | ||
jobs: | ||
- prepare: | ||
pre-steps: | ||
- run: | ||
command: echo "registry=https://registry.npmjs.org/" > ~/.npmrc && echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" >> ~/.npmrc | ||
- build: | ||
requires: | ||
- prepare | ||
- test: | ||
requires: | ||
- build | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
dist/ | ||
graph-schemas/*.graphql | ||
yarn-error.log | ||
node_modules/ | ||
.DS_Store | ||
.husky |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Changelog | ||
|
||
All notable changes to this project will be documented in this file. | ||
|
||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | ||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
|
||
|
||
## [1.0.0-rc0] - 2021-05-07 | ||
|
||
### RC0 Public Release | ||
|
||
* Initial public RC release | ||
* Added base 3 hooks to interact with individual NFTs | ||
* Supports Zora auction contracts and zNFTs for the time being | ||
* Normalizes and fetches currency information from Uniswap | ||
* Uses batching and caching for repeatable data requests | ||
* Loads NFT Metadata and Content for each record |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2021 Zora Labs, Inc | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
## @zoralabs/nft-hooks | ||
|
||
Simple React hooks to load Zora NFT data. Includes on-chain data, NFT metadata, and tools for fetching NFT content if needed. | ||
|
||
Put together, these power implementations of the zNFT protocol on any website. | ||
|
||
This library consists of a data fetch class and associated React hooks to load NFT data is an easy, efficient manner. The API both batches and caches requests, meaning you can use the hooks across a page without needing to worry about significant performance penalties. | ||
|
||
|
||
Install: | ||
``` | ||
yarn add @zoralabs/nft-hooks | ||
``` | ||
|
||
Then you can import and use the hooks in your react application: | ||
|
||
``` | ||
import {useNFT, useNFTMetadata} from "@zoralabs/nft-hooks"; | ||
function MyNFT() { | ||
const {data} = useNFT("20"); | ||
const {metadata} = useNFTMetadata(data && data.metadataURI); | ||
return ( | ||
<div> | ||
<h3>{metadata.title}</h3> | ||
<p>{metadata.description}</p> | ||
<p>Owned by: {data.owner.id}</p> | ||
</div> | ||
); | ||
} | ||
``` | ||
|
||
### All hooks: | ||
|
||
| Hook | Usage | | ||
| -- | -- | | ||
| [useNFT](docs/useNFT.md) | Fetches on-chain NFT data | | ||
| [useNFTMetadata](docs/useNFTMetadata.md) | Fetches NFT metadata from a URL | | ||
| [useNFTContent](docs/useNFTContent.md) | Fetches text content from server for rendering from content URL | | ||
|
||
|
||
### Development: | ||
|
||
1. `git clone https://github.com/ourzora/nft-hooks` | ||
2. `cd nft-hooks` | ||
3. `npm i -g yarn` if you don't have yarn installed | ||
4. `yarn` | ||
5. `yarn run test` test your code | ||
|
||
Pull requests and tickets are accepted for issues and improvements | ||
to this library. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"generates": { | ||
"./src/graph-queries/zora-types.d.ts": { | ||
"schema": "./graph-schemas/zora.graphql", | ||
"documents": "./src/graph-queries/zora.ts", | ||
"plugins": ["typescript", "typescript-operations"] | ||
}, | ||
"./src/graph-queries/uniswap-types.d.ts": { | ||
"schema": "./graph-schemas/uniswap.graphql", | ||
"documents": "./src/graph-queries/uniswap.ts", | ||
"plugins": ["typescript", "typescript-operations"] | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
This hook fetches data found on the blockchain from the given zNFT. The only argument for the hook is the NFT id. To fetch data for zNFTs on other networks, use the `NFTFetchConfiguration` wrapper component to set the correct network for loading the NFT data. | ||
The main types are within the result `data.nft` object. This object contains the on-chain NFT data itself. The pricing information can be found in `data.pricing` which corresponds to data on-chain for Zora's perpetual zNFT auctions along with the reserve auction functionality. | ||
|
||
```ts | ||
import {useNFT} from "@zoralabs/nft-hooks"; | ||
|
||
type NFTDataType = { | ||
nft: { | ||
id: string, // ID of zNFT | ||
owner: {id: string}, // Address of owner | ||
creator: {id: string}, // Address of creator | ||
metadataURI: string, // URI of metadata for zNFT | ||
metadataHash: string, // sha256 hash for metadata for zNFT | ||
contentURI: string, // URI of content described by metadata | ||
contentHash: string, // sha256 hash of content | ||
}, | ||
|
||
pricing: { | ||
perpetual: { | ||
bids: { // empty array if no bids | ||
id: string; | ||
createdAtTimestamp: string; | ||
bidder: { id: string }; | ||
pricing: PricingInfo; | ||
}[], | ||
ask?: { | ||
id: string, | ||
createdAtTimestamp: string; | ||
pricing: PricingInfo; | ||
}; | ||
}, | ||
reserve?: { | ||
auctionCurrency: CurrencyInformation; | ||
id: string; | ||
tokenId: string; | ||
status: "Pending" | "Active" | "Canceled" | "Finished"; | ||
firstBidTime: string; | ||
duration: string; | ||
expectedEndTimestamp: string; | ||
createdAtTimestamp: string; | ||
finalizedAtTimestamp: string; | ||
}, | ||
}; | ||
|
||
// Current/ongoing auction information synthesized from pricing data | ||
auction: { | ||
highestBid: { | ||
pricing: PricingInfo; | ||
placedBy: string; | ||
placedAt: string; | ||
}; | ||
current: { | ||
auctionType: "reserve" | "perpetual"; | ||
endingAt?: string; | ||
likelyHasEnded: boolean; // If an auction ended but has not been finalized this will be true. | ||
reserveMet: boolean; | ||
reservePrice?: PricingInfo; | ||
}; | ||
}; | ||
}; | ||
|
||
export type PricingInfo = { | ||
currency: CurrencyInformation; | ||
amount: string; // Amount as raw bignumber | ||
prettyAmount: string; // Amount as a normalized BigDecimal value | ||
computedValue?: PricingInfoValue; // Computed value in USD and ETH (available from Uniswap API call) | ||
}; | ||
|
||
type CurrencyInformation = { | ||
id: string, // Blockchain address of currency. If ETH currency, will be 0x0000000000000000000000000000000000000000 | ||
name: string, // Name of currency | ||
symbol: string, // Symbol of currency | ||
decimals: number, // Decimals for currency | ||
}; | ||
|
||
|
||
type useNFT = (id: string) => { | ||
loading: boolean; | ||
error?: string; // undefined if no error, string if error | ||
chainNFT?: NFTDataType; // undefined in error or loading states | ||
} | ||
|
||
// Example with usage: | ||
const {chainNFT, loading} = useNFT("2"); | ||
``` | ||
|
||
Alternatively, the same information can be fetched using the base MediaFetchAgentfor server-side or non-react use: | ||
|
||
```ts | ||
import {MediaFetchAgent, Networks} from "@zoralabs/nft-hooks"; | ||
|
||
// Be careful making multiple instances of the fetch agent | ||
// Each instance contains a different request cache. | ||
const fetchAgent = new MediaFetchAgent(Networks.MAINNET); | ||
|
||
// Get result from the server | ||
const result = await fetchAgent.loadNFTData("2"); | ||
// result type is NFTDataType | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
This hook makes a request to fetch metadata from IPFS retrieved from the zNFT `metadataURI`. | ||
|
||
Most IPFS servers allow remote JSON fetches, including all Zora NFTs. | ||
There is a chance this request could fail when the server does not allow cross-origin requests. | ||
Requests are set with a 15 second timeout to allow showing the user an error message instead of an | ||
indefinite loader. | ||
|
||
Hook result type: | ||
```ts | ||
// This is a union type meaning one or another in typescript. | ||
// Use the (media.type) to determine which type was returned from the hook. | ||
type MediaContentType = | ||
| { | ||
uri: string; // URI of content to render, used for media | ||
type: 'uri', // Shows that no content was downloaded, should only render | ||
mimeType: string // mime type string from metadata for rendering | ||
} | ||
| { | ||
text: string; // Text of result | ||
type: 'text', // Shows that text content to render was downloaded | ||
mimeType: string // mime type string from metadata for rendering | ||
}; | ||
|
||
type useNFTContentType = { | ||
loading: boolean; // If loading from the server | ||
error?: string; // Error returned from network request error or timeout | ||
content?: MediaContentType; // MediaConetentType shown above; | ||
} | ||
``` | ||
To use the hook, simply pass in the `contentURI` from the zNFT on-chain data and `mimeType` from the NFT Metadata. | ||
If you do not have access to `mimeType` from the metadata or do not wish to retrieve the metadata, the `mimeType` can be omitted with a small performance impact. | ||
Content returned from this hook is _not_ cached, each time the hook is used the content is fetched. | ||
```ts | ||
import {useNFTContent} from "@zoralabs/nft-hooks"; | ||
|
||
const MyMediaData = ({uri: string, mimeType: string}) => { | ||
const {error, loading, metadata} = useNFTContent(uri, mimeType); | ||
|
||
if (error) { | ||
return <div>Error fetching content</div>; | ||
} | ||
|
||
if (loading) { | ||
return <div>loading...</div>; | ||
} | ||
|
||
if (content.type === 'text') { | ||
return <div>{content.text}</div>; | ||
} | ||
if (content.mimeType.startsWith("audio")) { | ||
return <audio src={content.uri} />; | ||
} | ||
if (content.mimeType.startsWith("video")) { | ||
return <video src={content.uri} />; | ||
} | ||
if (content.mimeType.startsWith("image")) { | ||
return <img src={content.uri} />; | ||
} | ||
return <div>unknown: {content.mimeType}</div>; | ||
} | ||
``` | ||
|
||
|
||
Alternatively, the same information can be fetched using the base `MediaFetchAgent` for server-side or non-react use: | ||
```ts | ||
import {MediaFetchAgent} from "@zoralabs/nft-hooks"; | ||
|
||
// Get result from the server | ||
const result = await MediaFetchAgent.fetchContent("https://ipfs.io/ipfs/METADATA_HASH", "application/json"); | ||
// result type is MediaContentType | ||
``` |
Oops, something went wrong.