Skip to content
Back to skills

Permit2 Wagmi Integration

ASecurity

Integration patterns for Permit2 with wagmi hooks. Use when building UI components that interact with Permit2.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 10, 2026
developmenttypescript

Works with

  • cli

Security analysis

A100/100

Scanned September 10, 2026

npx -y skills add cyotee/indexedex --skill permit2-wagmi-integration --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Permit2 Wagmi Integration?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Permit2 Wagmi Integration
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/cyotee-permit2-wagmi-integration/badge)](https://www.skillsdirectory.com/skills/cyotee-permit2-wagmi-integration)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: permit2-wagmi-integration
description: Integration patterns for Permit2 with wagmi hooks. Use when building UI components that interact with Permit2.
---

# Permit2 Wagmi Integration

Complete patterns for integrating Permit2 with wagmi/viem.

## Setup

```typescript
import { useWriteContract, useReadContract, useAccount, useChainId } from 'wagmi'
import { usePublicClient, useWalletClient } from 'wagmi'
import { erc20Abi } from 'viem'
import { SignatureTransfer, PERMIT2_ADDRESS } from '@uniswap/permit2-sdk'
```

## Reading Allowances

```typescript
function useTokenAllowance(token: string, owner: string) {
  const { data } = useReadContract({
    address: token,
    abi: erc20Abi,
    functionName: 'allowance',
    args: [owner, PERMIT2_ADDRESS],
    query: { staleTime: 0 }
  })
  return data ?? 0n
}

function usePermit2Allowance(token: string, owner: string, spender: string) {
  const { data } = useReadContract({
    address: PERMIT2_ADDRESS,
    abi: [{
      inputs: [
        { name: 'owner', type: 'address' },
        { name: 'token', type: 'address' },
        { name: 'spender', type: 'address' }
      ],
      name: 'allowance',
      outputs: [
        { name: 'amount', type: 'uint160' },
        { name: 'expiration', type: 'uint48' },
        { name: 'nonce', type: 'uint48' }
      ],
      stateMutability: 'view',
      type: 'function'
    }],
    functionName: 'allowance',
    args: [owner, token, spender],
    query: { staleTime: 0 }
  })
  return data
}
```

## Signing with useSignTypedData

```typescript
import { useSignTypedData } from 'wagmi'
import { keccak256, encodePacked } from 'viem'

const WITNESS_TYPE: Record<string, TypedDataField[]> = {
  Witness: [{ name: 'actionId', type: 'bytes32' }]
}

function usePermitSignature() {
  const { signTypedDataAsync } = useSignTypedData()
  const chainId = useChainId()

  const signPermit = async (
    token: string,
    amount: bigint,
    spender: string,
    nonce: bigint,
    witness?: { actionId: `0x${string}` }
  ) => {
    const permit: SignatureTransfer.PermitTransferFrom = {
      permitted: { token, amount },
      nonce,
      deadline: BigInt(Math.floor(Date.now() / 1000)) + 1800n
    }

    const witnessData = witness
      ? { witness: witness.actionId, witnessTypeName: 'Witness', witnessType: WITNESS_TYPE }
      : undefined

    const { domain, types, values } = SignatureTransfer.getPermitData(
      permit,
      PERMIT2_ADDRESS,
      chainId,
      witnessData
    )

    return signTypedDataAsync(domain, types, values)
  }

  return { signPermit }
}
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…