npm package: @0xessential/use-metadata
Description: NFT metadata fetching 
Author: sammybauch
Latest version: 1.1.2

# use-metadata

React hook for fetching metadata for NFTs serially across multiple providers.

NFT metadata indexing services face an immense challenge in covering every edge case for every NFT on multiple blockchains.

This React hook allows developers to specify an array of indexing services, and each will be queried in order until a successful response is returned. If no indexing service returns suitable metadata, the hook will call the contract directly for `tokenURI` and then fetch that URL.

## Install

```bash
 yarn add @0xessential/use-metadata
```

## MetadataProvider

### Import

Import the `<MetadataProvider>` to wrap any components that depend on the `useMetadata` hook.

```jsx
  // _app.tsx
  import type { AppProps } from 'next/app';
  import { MetadataProvider, infura } from '@0xessential/use-metadata';
  import React from 'react';

  function MyApp({ Component, pageProps }: AppProps) {
    return (      
      <MetadataProvider>
        <Component {...pageProps} />
      </MetadataProvider>
    );
  }

  export default MyApp;
```

### Configure

Each supported indexer provides a configuration function that accepts arguments for authentication and network support. You must pass at least one indexer to the `<MetadataProvider>`.

Indexers will be queried in the order you provide them in MetadataProvider configuration.

We suggest first implementing the `rpc` indexer - this is a last resort service that fetches the `tokenURI` from the NFT contract via an RPC provider and then fetches the metadata with `fetch`.

Then add configuration for the indexing services you use.

#### rpc

The `rpc` indexer provides a fallback that fetches an NFT's `tokenURI` from the NFT contract via an RPC provider.

This should be included last in your array of indexers, but is a sensible configuration to start with.

The `rpc` configuration expects a URL for each network you support in your dapp.

```jsx
  //...
  import { MetadataProvider, rpc } from '@0xessential/use-metadata';
  //...

  function MyApp({ Component, pageProps }: AppProps) {
    return (      
      <MetadataProvider indexers={[
        rpc({
          '1': process.env.MAINNET_RPC_URL,
          '137': process.env.POLYGON_RPC_URL
        })
      ]}>
        <Component {...pageProps} />
      </MetadataProvider>
    );
  }

  return MyApp;
```

#### Alchemy

Alchemy requires an API key per network your dApp supports. Configuration is passed as an object keyed by chain ID with objects as values with `apiKey` and `network`.

```jsx
  //...
  import { MetadataProvider, alchemy } from '@0xessential/use-metadata';
  import { Network } from 'alchemy-sdk';
  //...

  function MyApp({ Component, pageProps }: AppProps) {
    return (      
      <MetadataProvider indexers={[
        alchemy({
          '1': {
            apiKey: process.env.ALCHEMY_ETH_MAINNET_API_KEY,
            network: Network.ETH_MAINNET,
          },
          '137': {
            apiKey: process.env.ALCHEMY_POLYGON_MAINNET_API_KEY,
            network: Network.MATIC_MAINNET,
          }
        })
      ]}>
        <Component {...pageProps} />
      </MetadataProvider>
    );
  }

  return MyApp;
```

### 1. Set a secret in an environment variable

The authentication token/credentials have to be made available in the CI service via environment variables. For more information, see "[Authentication for plugins](https://semantic-release.gitbook.io/semantic-release/usage/ci-configuration#authentication-for-plugins)".