# React

Our React package is designed to fit with your existing tools and workflow, making it easy to adopt, evaluate, and rage-quit if it's not the right fit for your application. You shouldn't have to entirely rework how you build Ethereum applications to adopt Global Entry, and you shouldn't have to get locked in to using our SDK because of high switching costs.

Our React SDK, `@xessential/react` is based on `wagmi`. It provides hooks with the same API as hooks from `wagmi` - `usePrepareContractWrite` and `useContractWrite` can be imported from `@xessential/react`, replacing `wagmi` imports, and the only additional change you need to make is to specify the NFT a user wishes to use.

If you are not using `wagmi`, first review the [wagmi React Getting Started guide](https://wagmi.sh/react/getting-started). Once you've wrapped your app with a `<WagmiConfig>` you're ready to install and configure `@xessential/react` for NFT Global Entry.

### Installation

You can install the SDK from NPM with

```
yarn add @xessential/react
```

or

```
npm install @xessential/react
```

### EssentialProvider

Import `EssentialProvider` and add it to your app as a child of `<WagmiConfig>`.

```typescript
import { EssentialProvider } from '@xessential/react';

function App() {
  return (
    <WagmiConfig client={client}> // follow wagmi docs for client setup
      <EssentialProvider
        config={{
          forwarderAddress: "0x000000000066b3aED7Ae8263588dA67fF381FfCa", //default
          rpcUrl: YOUR_L2_RPC_URL,
        }}
      >
        <YourRoutes />
      </EssentialProvider>  
    </WagmiConfig>
  )
}

```

#### forwarderAddress

Specify the address of the `EssentialForwarder` you're using. Will default to the canonical deployment at `0x000000000066b3aED7Ae8263588dA67fF381FfCa`.

#### rpcUrl

Provide a network-specific RPC URL for the chain where you will submit Global Entry transactions. If left blank, the SDK will use a rate-limited fallback provider.

### Usage

Now you can use Global Entry enabled hooks! Every component inside the `EssentialProvider` is now set up to use the wagmi-based hooks that depend on NFT Global Entry.

By default, these hooks will use the connected wallet from wagmi's `useAccount` hook for submitting transactions.

#### usePrepareContractWrite => useContractWrite

If you're familiar with `wagmi` you'll be comfortable with this approach already. Preparing the contract write prior to the user clicking a button to submit a transaction allows us to prepare the transaction for an instant wallet popup.

In the Global Entry context, when you prepare a contract write for a standard transaction, `usePrepareContractWrite` fetches the ownership proof in preparation of submitting the transaction.

To specify the NFT to use, include the chain ID, contract address and token ID for the NFT in `overrides.customData`:

```typescript
import { usePrepareContractWrite, useContractWrite } from '@xessential/react'

const L2_CONTRACT_ADDRESS = '0x1...';
const L2_CONTRACT_ABI = {/*...*/} as const;
const NFT_CONTRACT_ADDRESS = '0x2...';

function App() {
  const { config, error } = usePrepareContractWrite({
    address: L2_CONTRACT_ADDRESS,
    abi: L2_CONTRACT_ABI,
    functionName: 'tokenGatedFunction',
    overrides: {
      customData: {
        nftChainId: 1,
        nftContract: NFT_CONTRACT_ADDRESS,
        nftTokenId: 69,
      }
    }
  });
  const { write } = useContractWrite(config)
 
  return (
    <>
      <button disabled={!write} onClick={() => write?.()}>
        Submit Global Entry TX
      </button>
      {error && (
        <div>An error occurred preparing the transaction: {error.message}</div>
      )}
    </>
  )
}
```

So far we are assuming that the connected address directly owns the NFT being used in this transaction. If the connected address does in fact own that NFT, 0xEssential's NFT Ownership Oracle will generate and attach the ownership proof to the `config` return value, and include it when the `write` function is executed, allowing the transaction to be submitted and validated.

The APIs and return value for these hooks are exactly the same as the `wagmi` hooks. However you prefer handling callbacks and validation state will continue to work.

#### With Delegation

In the `EssentialContext` portion of this guide, we mentioned that your frontend can specify the address your contract receives as the `_msgSender()`. To accomplish this with the React SDK, you can pass an `authorizer` address to `overrides.customData`:

<pre class="language-typescript"><code class="lang-typescript">import { usePrepareContractWrite, useContractWrite } from '@xessential/react'

const L2_CONTRACT_ADDRESS = '0x1...';
const L2_CONTRACT_ABI = {/*...*/} as const;
const NFT_CONTRACT_ADDRESS = '0x2...';

function App() {
  const { config, error } = usePrepareContractWrite({
    address: L2_CONTRACT_ADDRESS,
    abi: L2_CONTRACT_ABI,
    functionName: 'tokenGatedFunction',
    overrides: {
      customData: {
        nftChainId: 1,
        nftContract: NFT_CONTRACT_ADDRESS,
        nftTokenId: 69,
        <a data-footnote-ref href="#user-content-fn-1">authorizer: '0x0090720FeD7Fed66eD658118b7B3BB0189D3A495'</a>,
      }
    }
  });
  const { write } = useContractWrite(config)
 
  return (
    &#x3C;>
      &#x3C;button disabled={!write} onClick={() => write?.()}>
        Submit Global Entry TX
      &#x3C;/button>
      {error &#x26;&#x26; (
        &#x3C;div>An error occurred preparing the transaction: {error.message}&#x3C;/div>
      )}
    &#x3C;/>
  )
}
</code></pre>

Now, the Ownership Oracle will provide a proof if the authorizer **and** connected address have authority to "use" this NFT via direct ownership and [Delegate Cash](https://delegate.cash) onchain delegations. By specifying this address as the `authorizer`, your L2 contract will now receive this address as the `_msgSender()`. The purpose is to allow users to transact from hot or burner wallets, while specifying that game rewards, or raffle winnings, or just general onchain activity accrue to a less hot wallet that the user controls.

Consider this setup, where one person has 3 EOAs they use:

* Vault wallet - owns NFTs, hardware wallet
* Hot wallet - has some assets, Rainbow or Metamask
* Burner wallet - has minimal assets, just gas or for minting

This user could create a delegation chain, first using their Vault wallet to delegate NFT access to their Hot wallet, and then using the Hot wallet to delegate NFT access to their Burner wallet. This user could then submit a Global Entry transaction from their Burner wallet, specifying their Hot wallet as the authorizer for an NFT owned by their Vault wallet. The Ownership Oracle will provide the proper proof, and your contract will receive the Hot wallet address as `_msgSender()`.

If this sounds a little complicated, don't worry! We provide one more hook to make this simple to implement.

#### useDelegatedAccount

`useDelegatedAccount` is based on wagmi's `useAccount` and helps you specify valid `authorizer` addresses. Based on the connected account, `useDelegatedAccount` will build a tree graph for all of the addresses that the connected account is delegated to through chained delegations.

See our [Account Delegation guide](/0xessential/guides/account-delegation.md) or [React API docs](/0xessential/api-docs/react.md) for details on how to utilize `useDelegatedAccount` to provide a user multi-address context, to check if an address has delegated access to a specific NFT and to help users create new delegations without leaving your app.

[^1]: Specify an "authorizer" address


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.0xessential.com/0xessential/guides/nft-global-entry/react.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
