Skip to content
Back to skills

Permit2 Signature Transfer

ASecurity

Uses permitWitnessTransferFrom for gasless token transfers with EIP-712 signatures. Use when implementing swap/deposit/withdraw with Permit2 signature-based authorization.

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

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 10, 2026

npx -y skills add cyotee/indexedex --skill permit2-signature-transfer --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Permit2 Signature Transfer?

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

Security grade badge for Permit2 Signature Transfer
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/cyotee-permit2-signature-transfer/badge)](https://www.skillsdirectory.com/skills/cyotee-permit2-signature-transfer)

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-signature-transfer
description: Uses permitWitnessTransferFrom for gasless token transfers with EIP-712 signatures. Use when implementing swap/deposit/withdraw with Permit2 signature-based authorization.
---

# Permit2 Signature Transfer

The recommended pattern for IndexedEx operations. Users sign **one EIP-712 message** off-chain - no pre-approval needed.

## Quick Start

```typescript
import { SignatureTransfer, PERMIT2_ADDRESS } from '@uniswap/permit2-sdk'
import { useSignTypedData, useWriteContract } from 'wagmi'
import { parseUnits, keccak256, encodePacked } from 'viem'

// Build permit (what user authorizes)
const permit: SignatureTransfer.PermitTransferFrom = {
  permitted: { token: tokenInAddress, amount: parseUnits('100', 6) },
  nonce: BigInt(Date.now()) << 8n,
  deadline: BigInt(Math.floor(Date.now() / 1000) + 1800n)
}

// Build witness (binds signature to this specific action)
const witness = {
  actionId: keccak256(encodePacked(
    ['address', 'address', 'address', 'uint256'],
    [tokenIn, tokenOut, vaultAddress, amountIn]
  )),
}

// Get EIP-712 data
const { domain, types, values } = SignatureTransfer.getPermitData(
  permit,
  PERMIT2_ADDRESS,
  chainId,
  { witness, witnessTypeName: 'Witness', witnessType: WITNESS_TYPE }
)

// User signs
const signature = await signTypedDataAsync(domain, types, values)
```

## Witness Types

### For exchangeIn (Exact In Swap)

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

### For exchangeOut (Exact Out Swap)

```typescript
// actionId includes maxAmountIn since that's variable
const witness = {
  actionId: keccak256(encodePacked(
    ['address', 'address', 'address', 'uint256', 'uint256'],
    [tokenIn, tokenOut, vaultAddress, amountOut, maxAmountIn]
  ))
}
```

## Contract Integration

See `permit2-signature-transfer-contract` skill for Solidity implementation.

Files in this skill

  • README.md1 KB
  • SKILL.md1.9 KB

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…