Goals


  1. Allow frames to request EIP-712 typed wallet signatures from Farcaster apps.
  2. Minimize risk to users from malicious frames.

Proposal


Extend the frame TransactionTargetResponse type with a new eth_signTypedData_v4 method:


type TransactionTargetResponse =
  | {
      chainId: string;
      method: "eth_sendTransaction";
      attribution?: boolean;
      params: EthSendTransactionParams;
    }
  | {
      chainId: string;
      method: "eth_signTypedData_v4";
      params: EthSignTypedDataV4Params;
    };

Add a new params type for signatures, EthSignTypedDataV4Params:

import { TypedData } from 'abitype';
import { Hex, Address } from 'viem';

type EthSignTypedDataV4Params = {
  domain?: {
    chainId?: number;
    name?: string;
    salt?: Hex;
    verifyingContract?: Address;
    version?: string;
  },
  types: TypedData; 
  primaryType: string;
  message: Record<string, unknown>
}

For example, a frame could return the typed signature request below from a frame transaction URL to request a typed signature from the user’s wallet:

{
  "method": "eth_signTypedData_v4",
  "params": {
    "domain": {
      "name": "Ether Mail",
      "version": "1",
      "chainId": 1,
      "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
    },
    "types": {
      "Person": [
        { "name": "name", "type": "string" },
        { "name": "wallet", "type": "address" }
      ],
      "Mail": [
        { "name": "from", "type": "Person" },
        { "name": "to", "type": "Person" },
        { "name": "contents", "type": "string" }
      ]
    },
    "primaryType": "Mail",
    "message": {
      "from": {
        "name": "Cow",
        "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
      },
      "to": {
        "name": "Bob",
        "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
      },
      "contents": "Hello, Bob!"
    }
  }
}

Handling Signature requests

The client must forward this signature request to the user's wallet. If the user signs the message, the client must send a POST request to the post_url with a Signature Packet, including the signature bytes as its transaction_id and signing address in address.

Other behavior is the same as existing frame transaction buttons.

Security considerations

Apps should strongly consider using a signature simulation provider to scan signatures and protect users from malicious requests.