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

# wagmi + viem Wrapper

> Iframe wrapper using browser wallets (MetaMask) with ERC-4337 smart accounts via permissionless

This guide covers building an iframe wrapper that connects browser wallets (MetaMask, injected) and derives a Safe smart account using `permissionless` for ERC-4337 UserOperations. Single-chain (Polygon) by default.

<Info>
  For the complete one-shot LLM prompt, see [`/llms-iframe-wagmi-viem.txt`](/llms-iframe-wagmi-viem.txt).
</Info>

***

## Tech Stack

* **React** (18+) with TypeScript
* **Vite** as build tool
* **Tailwind CSS** for styling
* **wagmi** for wallet connection
* **viem** for Ethereum interactions
* **permissionless** for ERC-4337 smart accounts
* **@tanstack/react-query** (wagmi peer dependency)

***

## Smart Account Constants

These constants are part of the Pods protocol and must be used exactly as specified:

```typescript theme={null}
import { hexToBigInt, keccak256, stringToBytes } from 'viem'

// Default salt for Pods smart accounts
// Produces: 66612165172041560534486737891040272261009897627722856013316623938731930217937n
const PODS_SALT = hexToBigInt(keccak256(stringToBytes('pods.finance')))

// Safe 4337 module address
const SAFE_4337_MODULE_ADDRESS = '0xa581c4A4DB7175302464fF3C06380BC3270b4037' as const

// Default chain
const CHAIN_ID = 137
```

***

## Smart Account Derivation

Use `permissionless`'s `toSafeSmartAccount` to derive the smart account address:

* **Client:** a viem `publicClient` connected to Polygon via Alchemy RPC
* **EntryPoint:** version 0.6 (`entryPoint06Address` from `viem/account-abstraction`)
* **Owners:** the connected EOA wallet address
* **Salt:** `PODS_SALT`
* **Safe version:** `'1.4.1'`
* **Safe 4337 module:** `SAFE_4337_MODULE_ADDRESS`

The resulting `safeAccount.address` is passed to the iframe as `smartAccountAddress`.

<Note>
  The `toSafeSmartAccount` API shape may vary by `permissionless` version. The key parameters above are stable — consult the [permissionless docs](https://docs.pimlico.io/permissionless) for the exact call signature.
</Note>

***

## Wallet Connection

Configure wagmi with:

* **Chain:** Polygon (chain ID 137)
* **Connector:** `injected()` (MetaMask, browser wallets)
* **Transport:** Alchemy RPC (`https://polygon-mainnet.g.alchemy.com/v2/{ALCHEMY_RPC_ID}`)

Wrap your app in `WagmiProvider` and `QueryClientProvider`.

Use wagmi hooks:

* `useAccount()` — get connected address and status
* `useConnect()` — connect with the injected connector
* `useDisconnect()` — disconnect wallet

***

## UserOperation Flow

To process bytecodes into a signed ERC-4337 UserOperation:

1. **Get EOA** from the browser wallet (`window.ethereum`)
2. **Create a wallet client** (viem) using the browser wallet as transport
3. **Create a public client** (viem) connected to Polygon via Alchemy RPC
4. **Create a paymaster client** (viem) using the same Alchemy RPC
5. **Create the Safe smart account** using `toSafeSmartAccount` with Pods constants
6. **Create a smart account client** (permissionless) with the safe account, paymaster, and bundler transport
7. **Transform bytecodes** to calls: `{ to, data, value }` — convert `value` strings to `BigInt`
8. **Prepare the UserOperation** via the smart account client, passing the Alchemy `policyId` as paymaster context
9. **Sign the UserOperation** using the Safe smart account signing method
10. **Submit** via `sendUserOperation` on the bundler client
11. **Poll** for the transaction receipt using `getUserOperationReceipt` and `waitForUserOperationReceipt`

<Note>
  The exact methods for steps 8-10 depend on your `permissionless` version. Some versions combine prepare + sign + send into a single call. Consult the docs for your version.
</Note>

***

## Environment Variables

```env theme={null}
VITE_WEBVIEW_URL=https://iframe.pods.finance
VITE_ALCHEMY_RPC_ID=your_alchemy_api_key
VITE_ALCHEMY_POLICY_ID=your_alchemy_gas_policy_id
VITE_PODS_API_URL=https://api.pods.finance
VITE_PODS_API_KEY=your_pods_api_key
VITE_ALLOWED_ORIGINS=*
```

All variables use the `VITE_` prefix for Vite's environment variable exposure. Default chain is Polygon (137).

***

## UI Requirements

1. **Header** with Connect Wallet button (shows address + Disconnect when connected), Earn/Swap toggle
2. **Before wallet connection:** placeholder message ("Connect your wallet to begin")
3. **While deriving smart account:** loading spinner
4. **After connection + SA derived:** render the Pods iframe with correct URL params
5. **Iframe:** `allow="clipboard-write"`, fills available space, not in DOM before wallet connection

***

## Documentation References

* [Iframe Overview](/iframe/overview) — Protocol spec, query params, postMessage types
* [Privy Wrapper](/iframe/privy) — Alternative wrapper with Privy auth + multi-chain
* [wagmi docs](https://wagmi.sh)
* [viem docs](https://viem.sh)
* [permissionless docs](https://docs.pimlico.io/permissionless)
