{"id":13450334,"url":"https://github.com/bpierre/use-nft","last_synced_at":"2025-06-22T06:02:51.375Z","repository":{"id":40541637,"uuid":"351451233","full_name":"bpierre/use-nft","owner":"bpierre","description":"🍮 React hook to fetch metadata from any NFT.","archived":false,"fork":false,"pushed_at":"2022-12-05T14:50:00.000Z","size":5091,"stargazers_count":477,"open_issues_count":6,"forks_count":61,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-06-22T01:16:23.585Z","etag":null,"topics":["erc-721","ethereum","nft","react"],"latest_commit_sha":null,"homepage":"https://use-nft.spectre.xyz/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bpierre.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-03-25T13:44:14.000Z","updated_at":"2025-05-03T15:04:23.000Z","dependencies_parsed_at":"2023-01-23T03:30:48.413Z","dependency_job_id":null,"html_url":"https://github.com/bpierre/use-nft","commit_stats":null,"previous_names":["spectrexyz/use-nft"],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/bpierre/use-nft","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpierre%2Fuse-nft","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpierre%2Fuse-nft/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpierre%2Fuse-nft/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpierre%2Fuse-nft/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bpierre","download_url":"https://codeload.github.com/bpierre/use-nft/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpierre%2Fuse-nft/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261243971,"owners_count":23129633,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["erc-721","ethereum","nft","react"],"created_at":"2024-07-31T07:00:33.705Z","updated_at":"2025-06-22T06:02:51.311Z","avatar_url":"https://github.com/bpierre.png","language":"TypeScript","funding_links":[],"categories":["**NFT Platforms**","TypeScript"],"sub_categories":["**NFT Play-to-Earn**"],"readme":"\u003cp align=center\u003e\u003cimg src=https://user-images.githubusercontent.com/36158/112562506-52184100-8dcf-11eb-95ae-88d5dfb06f4a.png\u003e\n\n[![npm version](https://badgen.net/npm/v/use-nft)](https://www.npmjs.com/package/use-nft) [![bundle size](https://badgen.net/bundlephobia/minzip/use-nft)](https://bundlephobia.com/result?p=use-nft) [![License](https://badgen.net/github/license/spectrexyz/use-nft)](https://github.com/spectrexyz/use-nft/blob/main/LICENSE)\n\nuseNft() allows to access the metadata of any NFT ([EIP 721](https://eips.ethereum.org/EIPS/eip-721), [EIP 1155](https://eips.ethereum.org/EIPS/eip-1155) and [more](https://www.larvalabs.com/cryptopunks)) on the Ethereum blockchain.\n\n## Install\n\n```console\nnpm install --save use-nft\n```\n\n## Usage\n\nuseNft() uses a concept of “fetchers”, in order to provide different ways to retrieve data from Ethereum. If you use the [Ethers](https://github.com/ethers-io/ethers.js) in your app, using `ethersFetcher()` is recommended. Otherwise you can use `ethereumFetcher()`, which only requires a [standard Ethereum provider](https://eips.ethereum.org/EIPS/eip-1193), like the one provided by MetaMask.\n\n```jsx\nimport { getDefaultProvider } from \"ethers\"\nimport { NftProvider, useNft } from \"use-nft\"\n\n// We are using the \"ethers\" fetcher here.\nconst ethersConfig = {\n  provider: getDefaultProvider(\"homestead\"),\n}\n\n// Alternatively, you can use the \"ethereum\" fetcher. Note\n// that we are using window.ethereum here (injected by wallets\n// like MetaMask), but any standard Ethereum provider would work.\n// const fetcher = [\"ethereum\", { ethereum }]\n\n// Wrap your app with \u003cNftProvider /\u003e.\nfunction App() {\n  return (\n    \u003cNftProvider fetcher={[\"ethers\", ethersConfig]}\u003e\n      \u003cNft /\u003e\n    \u003c/NftProvider\u003e\n  )\n}\n\n// useNft() is now ready to be used in your app. Pass\n// the NFT contract and token ID to fetch the metadata.\nfunction Nft() {\n  const { loading, error, nft } = useNft(\n    \"0xd07dc4262bcdbf85190c01c996b4c06a461d2430\",\n    \"90473\"\n  )\n\n  // nft.loading is true during load.\n  if (loading) return \u003c\u003eLoading…\u003c/\u003e\n\n  // nft.error is an Error instance in case of error.\n  if (error || !nft) return \u003c\u003eError.\u003c/\u003e\n\n  // You can now display the NFT metadata.\n  return (\n    \u003csection\u003e\n      \u003ch1\u003e{nft.name}\u003c/h1\u003e\n      \u003cimg src={nft.image} alt=\"\" /\u003e\n      \u003cp\u003e{nft.description}\u003c/p\u003e\n      \u003cp\u003eOwner: {nft.owner}\u003c/p\u003e\n      \u003cp\u003eMetadata URL: {nft.metadataUrl}\u003c/p\u003e\n    \u003c/section\u003e\n  )\n}\n```\n\n## API\n\n### `useNft(contract, tokenId)`\n\nThe useNft() hook requires two arguments: the NFT `contract` address, and its token ID.\n\nThe returned value is an object containing information about the loading state:\n\n```tsx\nconst { status, loading, error, reload, nft } = useNft(\n  \"0xd07dc4262bcdbf85190c01c996b4c06a461d2430\",\n  \"90473\"\n)\n\n// one of \"error\", \"loading\" and \"done\"\nstatus\n\n// same as status === \"loading\"\nloading\n\n// undefined or Error instance when status === \"error\"\nerror\n\n// call this function to retry in case of error\nreload\n\n// nft is undefined when status !== \"done\"\nnft\n\n// name of the NFT (or empty string)\nnft.name\n\n// description of the NFT (or empty string)\nnft.description\n\n// image / media URL of the NFT (or empty string)\nnft.image\n\n// the type of media: \"image\", \"video\" or \"unknown\"\nnft.imageType\n\n// current owner of the NFT (or empty string)\nnft.owner\n\n// url of the json containing the NFT's metadata\nnft.metadataUrl\n\n// the raw NFT metadata, or null if non applicable\nnft.rawData\n```\n\nAs TypeScript type:\n\n```tsx\ntype NftResult = {\n  status: \"error\" | \"loading\" | \"done\"\n  loading: boolean\n  reload: () =\u003e void\n  error?: Error\n  nft?: {\n    description: string\n    image: string\n    imageType: \"image\" | \"video\" | \"unknown\"\n    name: string\n    owner: string\n    metadataUrl?: string\n    rawData: Record\u003cstring, unknown\u003e | null\n  }\n}\n```\n\n### `\u003cNftProvider /\u003e`\n\nNftProvider requires a prop to be passed: `fetcher`. It can take a declaration for the embedded fetchers, or you can alternatively pass a custom fetcher.\n\n#### `fetcher`\n\n##### With Ethers.js\n\nMake sure to add either `ethers` or `@ethersproject/contracts` to your app:\n\n```console\nnpm install --save ethers\n```\n\nThen:\n\n```tsx\n\u003cNftProvider fetcher={[\"ethers\", { provider }]} /\u003e\n```\n\nWhere `provider` is a [provider](https://docs.ethers.io/v5/api/providers/) from the [Ethers](https://docs.ethers.io/) library (not to be mistaken with [standard Ethereum providers](https://eips.ethereum.org/EIPS/eip-1193)).\n\n##### With an Ethereum provider\n\n```tsx\n\u003cNftProvider fetcher={[\"ethereum\", { ethereum }]} /\u003e\n```\n\nWhere `ethereum` is a [standard Ethereum provider](https://eips.ethereum.org/EIPS/eip-1193).\n\n##### Custom fetcher\n\nA fetcher is an object implementing the `Fetcher` type:\n\n```tsx\ntype Fetcher\u003cConfig\u003e = {\n  config: Config\n  fetchNft: (contractAddress: string, tokenId: string) =\u003e Promise\u003cNftMetadata\u003e\n}\ntype NftMetadata = {\n  name: string\n  description: string\n  image: string\n}\n```\n\nSee the implementation of the [Ethers](https://github.com/spectrexyz/use-nft/blob/38bd803f20e778b9bb684d682c194a812a94a05c/src/fetchers/ethers/index.tsx#L12-L42) and [Ethereum](https://github.com/spectrexyz/use-nft/blob/38bd803f20e778b9bb684d682c194a812a94a05c/src/fetchers/ethereum/index.tsx#L12-L42) fetchers for more details.\n\n#### `ipfsUrl`\n\nA function that allows to define the IPFS gateway (defaults to `https://ipfs.io/`).\n\nDefault value:\n\n```js\nfunction ipfsUrl(cid, path = \"\") {\n  return `https://ipfs.io/ipfs/${cid}${path}`\n}\n```\n\n#### `imageProxy`\n\nAllows to proxy the image URL. This is useful to optimize (compress / resize) the raw NFT images by passing the URL to a service.\n\nDefault value:\n\n```js\nfunction imageProxy(url, metadata) {\n  return url\n}\n```\n\n#### `jsonProxy`\n\nAllows to proxy the JSON URL. This is useful to get around the CORS limitations of certain NFT services.\n\nDefault value:\n\n```js\nfunction jsonProxy(url) {\n  return url\n}\n```\n\n### FetchWrapper\n\n`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.\n\n```js\nimport { FetchWrapper } from \"use-nft\"\n```\n\nPass the fetcher declaration to the `FetchWrapper` and call the `fetchNft` function to retreive the NFT data.\n\n```js\n// See the documentation for \u003cNftProvider /\u003e fetcher prop\nconst fetcher = [\"ethers\", { provider: ethers.getDefaultProvider() }]\n\nconst fetchWrapper = new FetchWrapper(fetcher)\n\n// You can also pass options to the constructor (same as the \u003cNftProvider /\u003e props):\n// const fetchWrapper = new FetchWrapper(fetcher, {\n//   ipfsUrl: (cid, path) =\u003e `…`,\n//   imageProxy: (url) =\u003e `…`,\n//   jsonProxy: (url) =\u003e `…`,\n// })\n\nconst result = await fetchWrapper.fetchNft(\n  \"0xd07dc4262bcdbf85190c01c996b4c06a461d2430\",\n  \"90473\"\n)\n```\n\nThe `fetchNft()` function returns a promise which resolves to an `NftMetadata` object.\n\n## Supported NFT formats\n\nAny standard NFT ([EIP 721](https://eips.ethereum.org/EIPS/eip-721) or [EIP 1155](https://eips.ethereum.org/EIPS/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.\n\nThis table keeps track of the NFT minting services that have been tested with useNft() and the adaptations needed.\n\n| NFT minting service                                  | Supported | Specific adaptations done by useNft()                                                  |\n| ---------------------------------------------------- | --------- | -------------------------------------------------------------------------------------- |\n| [AITO](https://www.thisisaito.xyz/)                  | Yes       |                                                                                        |\n| [Async Art](https://async.art/)                      | Yes       |                                                                                        |\n| [Clovers](https://clovers.network/)                  | Yes       |                                                                                        |\n| [CryptoKitties](https://www.cryptokitties.co/)       | Yes       | Non standard NFT, dedicated mechanism.                                                 |\n| [CryptoPunks](https://www.larvalabs.com/cryptopunks) | Yes       | Non standard NFT, dedicated mechanism.                                                 |\n| [Cryptovoxels](https://www.cryptovoxels.com/)        | Yes       |                                                                                        |\n| [Decentraland ](https://decentraland.org/)           | Yes       | Estate and parcels are fetched from The Graph. Wearables are fetched as standard NFTs. |\n| [Foundation](https://foundation.app/)                | Yes       |                                                                                        |\n| [JOYWORLD](https://www.joy.world/joys)               | Yes       |                                                                                        |\n| [KnownOrigin](https://knownorigin.io/)               | Yes       |                                                                                        |\n| [MakersPlace](https://makersplace.com/)              | Yes       | Incorrect JSON format (uses `imageUrl` instead of `image`).                            |\n| [Meebits](https://meebits.larvalabs.com/)            | Yes       | CORS restricted, requires a JSON proxy to be set (see `jsonProxy`).                    |\n| [MoonCats](https://mooncatrescue.com/)               | Yes       | Non standard NFT, dedicated mechanism.                                                 |\n| [Nifty Gateway](https://niftygateway.com/)           | Yes       | Incorrect metadata URL.                                                                |\n| [OpenSea](https://opensea.io/)                       | Yes       | Incorrect metadata URL.                                                                |\n| [Portion.io](https://app.portion.io/)                | Yes       | Non-standard JSON format.                                                              |\n| [Rarible](https://rarible.com/)                      | Yes       |                                                                                        |\n| [SuperRare](https://superrare.co/)                   | Yes       |                                                                                        |\n| [Uniswap V3](https://uniswap.org/)                   | Yes       |                                                                                        |\n| [Zora](https://zora.co/)                             | Yes       |                                                                                        |\n\n## License\n\n[MIT](LICENSE)\n\n## Special Thanks 🙏\n\nThanks to [ImageKit.io](https://imagekit.io/) for supporting the project by providing a free plan.\n\n\u003ca href=\"https://imagekit.io/\"\u003e\n  \u003cimg width=\"220\" alt=\"ImageKit\" src=\"https://user-images.githubusercontent.com/36158/128070654-9628ec2f-1006-4e9d-a36a-7051bb5a641b.png\"\u003e\n\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbpierre%2Fuse-nft","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbpierre%2Fuse-nft","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbpierre%2Fuse-nft/lists"}