useNft() allows to access the metadata of any NFT (EIP 721, EIP 1155 and more) on the Ethereum blockchain.
Install
yarn add use-nft
Usage
useNft() uses a concept of “fetchers”, in order to provide different ways to retrieve data from Ethereum. If you use the Ethers in your app, using ethersFetcher()
is recommended. Otherwise you can use ethereumFetcher()
, which only requires a standard Ethereum provider, like the one provided by MetaMask.
import ethers from "ethers"
import { NftProvider, useNft } from "use-nft"
// We are using the "ethers" fetcher here.
const fetcher = ["ethers", { ethers, provider: ethers.getDefaultProvider() }]
// Alternatively, you can use the "ethereum" fetcher. Note
// that we are using window.ethereum here (injected by wallets
// like MetaMask), but any standard Ethereum provider would work.
// const fetcher = ["ethereum", { ethereum }]
// Wrap your app with <NftProvider />.
function App() {
return (
<NftProvider fetcher={fetcher}>
<Nft />
</NftProvider>
)
}
// useNft() is now ready to be used in your app. Pass
// the NFT contract and token ID to fetch the metadata.
function Nft() {
const { loading, error, nft } = useNft(
"0xd07dc4262bcdbf85190c01c996b4c06a461d2430",
"90473"
)
// nft.loading is true during load.
if (loading) return "Loading…"
// nft.error is an Error instance in case of error.
if (error) return "Error."
// You can now display the NFT metadata.
return (
<section>
<h1>{nft.name}</h1>
<img src={nft.image} alt="" />
<p>{nft.description}</p>
<p>Owner: {nft.owner}</p>
<p>Metadata URL: {nft.metadataUrl}</p>
</section>
)
}
Supported NFT formats
Any standard NFT (EIP 721 or EIP 1155) is, in theory supported by useNft(). In practice, some adjustments are needed to support some NFT formats, either because their implementation doesn’t follow the specification or because some parts of the specifications can be interpreted in different ways.
This table keeps track of the NFT minting services that have been tested with useNft() and the adaptations needed.
NFT minting service | Supported | Specific adaptations done by useNft() |
---|---|---|
AITO | Yes | |
Async Art | Yes | |
Clovers | Yes | |
CryptoKitties | Yes | Non standard NFT, dedicated mechanism. |
CryptoPunks | Yes | Non standard NFT, dedicated mechanism. |
Cryptovoxels | Yes | |
Decentraland | Yes | Estate and parcels are fetched from The Graph. Wearables are fetched as standard NFTs. |
Foundation | Yes | |
KnownOrigin | Yes | |
MakersPlace | Yes | Incorrect JSON format (uses imageUrl instead of image ). |
MoonCats | Yes | Non standard NFT, dedicated mechanism. |
Nifty Gateway | Yes | Incorrect metadata URL. |
OpenSea | Yes | Incorrect metadata URL. |
Portion.io | Yes | Non-standard JSON format. |
Rarible | Yes | |
SuperRare | Yes | |
Uniswap V3 | Yes | |
Zora | Yes |
API
useNft(contract: string, tokenId: string): NftResult
The useNft() hook requires two arguments: the NFT contract
address, and its token ID.
The returned value is an object containing information about the loading state:
const result = useNft("0xd07dc4262bcdbf85190c01c996b4c06a461d2430", "90473")
// one of "error", "loading" and "done"
result.status
// same as status === "loading"
result.loading
// undefined or Error instance when status === "error"
result.error
// call this function to retry in case of error
result.reload
// nft is undefined when status !== "done"
result.nft
// name of the NFT (or empty string)
result.nft.name
// description of the NFT (or empty string)
result.nft.description
// image / media URL of the NFT (or empty string)
result.nft.image
// current owner of the NFT (or empty string)
result.nft.owner
// url of the json containing the NFT's metadata
result.nft.metadataUrl
As TypeScript type:
type NftResult = {
status: "error" | "loading" | "done"
loading: boolean
reload: () => void
error?: Error
nft?: {
description: string
image: string
name: string
owner: string
metadataUrl?: string
}
}
<NftProvider />
NftProvider requires one prop to be passed: fetcher
. It can take a declaration for the embedded fetchers, or you can alternatively pass a custom fetcher.
With Ethers
<NftProvider fetcher={["ethers", { ethers, provider }]} />
ethers
is the default import of the Ethers library (note that only{ Contract }
is needed, so you can pass this instead).provider
is a provider from the Ethers library (not to be mistaken with standard Ethereum providers).
With an Ethereum provider
<NftProvider fetcher={["ethereum", { ethereum }]} />
ethereum
is a standard Ethereum providers.
Custom fetcher
A fetcher is an object implementing the Fetcher
type:
type Fetcher<Config> = {
config: Config
fetchNft: (contractAddress: string, tokenId: string) => Promise<NftMetadata>
}
type NftMetadata = {
name: string
description: string
image: string
}
See the implementation of the Ethers and Ethereum fetchers for more details.
FetchWrapper
FetchWrapper
is a class that allows to use the library with other frontend libraries than React, or with NodeJS. Unlike the useNft()
hook, FetchWrapper#fetchNft()
does not retry, cache, or do anything else than attempting to fetch the NFT data once.
import { FetchWrapper } from "use-nft"
Pass the fetcher declaration to the FetchWrapper
and call the fetchNft
function to retreive the NFT data.
const fetcher = ["ethers", { ethers, provider: ethers.getDefaultProvider() }]
const fetchWrapper = new FetchWrapper(fetcher)
const result = await fetchWrapper.fetchNft(
"0xd07dc4262bcdbf85190c01c996b4c06a461d2430",
"90473"
)
The fetchNft()
function returns a promise which resolves to an NftMetadata
object.