> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rhinestone.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Setting up approvals

> Handle token approvals and ETH wrapping before signing an intent.

Before signing, check whether the quote response includes a `tokenRequirements` field. This is only relevant for EOA users — smart accounts handle approvals automatically via preclaim ops.

## Smart accounts

No action required. The Orchestrator handles token approvals internally using preclaim ops on the smart account.

## EOAs

If `tokenRequirements` is present in the quote response, the user must complete these steps before signing. There are two types:

* **`approval`**: approve the specified token to the Permit2 contract on the specified chain.
* **`wrap`**: wrap native ETH into WETH on the specified chain (required when ETH is the source token).

```json theme={null}
{
  "8453": {
    "0x0000000000000000000000000000000000000000": {
      "type": "wrap",
      "amount": "102656447694688542"
    },
    "0x4200000000000000000000000000000000000006": {
      "type": "approval",
      "amount": "102656447694688542",
      "spender": "0x000000000022d473030f116ddee9f6b43ac78ba3"
    }
  }
}
```

In this example, the user must first wrap ETH on Base, then approve WETH to Permit2.

## ETH wrapping

```ts theme={null}
import { switchChain, writeContract } from "@wagmi/core";

await switchChain(wagmiConfig, { chainId: Number(chainId) });

await writeContract(wagmiConfig, {
  address: "0x4200000000000000000000000000000000000006", // WETH on the chain
  abi: [
    {
      name: "deposit",
      type: "function",
      stateMutability: "payable",
      inputs: [],
      outputs: [],
    },
  ],
  functionName: "deposit",
  value: BigInt(requirement.amount),
});
```

## ERC-20 approvals

Approve to the Permit2 contract. We recommend using `maxUint256` to avoid repeated approval prompts on future intents:

```ts theme={null}
import { switchChain, writeContract } from "@wagmi/core";
import { maxUint256, erc20Abi } from "viem";

await switchChain(wagmiConfig, { chainId: Number(chainId) });

await writeContract(wagmiConfig, {
  address: tokenAddress,
  abi: erc20Abi,
  functionName: "approve",
  args: [requirement.spender, maxUint256],
});
```

<Info>
  Approvals are always to [Permit2](https://github.com/Uniswap/permit2) — one of the most widely deployed and audited contracts in the ecosystem. Setting max approval here does not grant Rhinestone any direct access to your funds.
</Info>

If you prefer exact approvals, inspect the `tokensSpent` field in the quote response. This shows the exact amount that will be used, so approving that amount will be sufficient:

```ts theme={null}
// Use tokensSpent amount instead of maxUint256 for exact approvals
const chainSpend = intentCost.tokensSpent[chainId];
const tokenAmount = chainSpend[tokenAddress]?.unlocked;

await writeContract(wagmiConfig, {
  address: tokenAddress,
  abi: erc20Abi,
  functionName: "approve",
  args: [requirement.spender, BigInt(tokenAmount)],
});
```

## Next steps

<Card title="Signing the intent" icon="signature" href="./signing">
  Sign each element of the intent with EIP-712.
</Card>
