Skip to main content
ERC-1271 is a standard interface that allows smart contracts to verify signatures on behalf of an address. When a Privy embedded wallet is upgraded to a smart contract wallet — via EIP-7702 or Privy’s gas sponsorship — the wallet address has contract code. Some smart contracts and off-chain verifiers check signatures by calling the ERC-1271 isValidSignature method on the wallet address instead of using ecrecover. To ensure your signatures are verifiable by these ERC-1271 aware systems, Privy supports an erc1271 signature mode.
ERC-1271 signature mode is only needed when your wallet is an EIP-7702 delegated smart contract wallet, such as when using Privy’s gas sponsorship. Standard embedded wallets (EOAs) do not need this mode.

When to use ERC-1271 signatures

Use ERC-1271 signatures when all of the following are true:
  • Your wallet uses gas sponsorship or is otherwise delegated via EIP-7702
  • A smart contract or off-chain service verifies signatures using the ERC-1271 isValidSignature interface
Common use cases include:
  • DeFi protocols that support both EOA and smart account signers
  • Off-chain payment authorization (e.g. x402 payments with gas-sponsored wallets)
  • SIWE (Sign-In With Ethereum) with smart contract wallets
  • Any integration where the verifier calls IERC1271.isValidSignature on the signer address

Producing ERC-1271 signatures

Privy exposes ERC-1271 signing through the signatureOptions: {type: 'erc1271'} option on signing methods. Pass signatureOptions: {type: 'erc1271'} to signing methods when the wallet is gas-sponsored or EIP-7702 delegated.

Signing a message

import {PrivyClient} from '@privy-io/node';

const privy = new PrivyClient({appId, appSecret});

const {signature} = await privy
  .wallets()
  .ethereum()
  .signMessage('your-wallet-id', {
    message: 'I authorize this action',
    signatureOptions: {type: 'erc1271'}
  });

Signing typed data (EIP-712)

import {PrivyClient} from '@privy-io/node';

const privy = new PrivyClient({appId, appSecret});

const {signature} = await privy
  .wallets()
  .ethereum()
  .signTypedData('your-wallet-id', {
    params: {
      typed_data: {
        domain: {
          name: 'My App',
          version: '1',
          chainId: 1,
          verifyingContract: '<your-verifying-contract-address>'
        },
        types: {
          Order: [
            {name: 'amount', type: 'uint256'},
            {name: 'deadline', type: 'uint256'}
          ]
        },
        primary_type: 'Order',
        message: {
          amount: '1000000',
          deadline: '1893456000'
        }
      }
    },
    signatureOptions: {type: 'erc1271'}
  });

How it works

When a Privy embedded wallet is upgraded via EIP-7702 (either through gas sponsorship or a direct delegation), the wallet address has smart contract bytecode. The delegated smart contract implements isValidSignature(bytes32 hash, bytes signature), which validates that the underlying EOA’s private key produced the signature. Privy’s erc1271 signature mode produces signatures in the exact format that the delegated smart contract’s isValidSignature implementation expects. Without this mode, the raw ECDSA signature bytes may not match the format the smart contract validates, causing verification to fail.