Sign typed data

This guide will teach you how to sign EIP-712 typed data with your Smart Wallet. Typed data signing provides a more structured and secure way to sign complex data compared to plain text messages.

Prerequisites

  • API key from your dashboard
  • A Smart Wallet with an associated signer

What is typed data signing?

EIP-712 typed data signing allows users to:

  • Sign structured data with clear type definitions
  • Improve user experience with readable signature requests
  • Enhance security through type safety and domain separation

Typed data follows the EIP-712 standard, which provides a way to encode structured data for signing.

Implementation

Required SDK version: ^v4.59.1

Use the useSignTypedData hook to sign typed data with your Smart Wallet.

signTypedData.tsx
1import { useSignTypedData, useSmartAccountClient } from "@account-kit/react";
2
3export default function SignTypedData() {
4 const { client } = useSmartAccountClient({});
5 const { signTypedDataAsync } = useSignTypedData({
6 client,
7 });
8
9 const handleSignTypedData = async () => {
10 const typedData = {
11 domain: {
12 name: "MyDApp",
13 version: "1",
14 chainId: 1,
15 verifyingContract: "0x...",
16 },
17 types: {
18 Auth: [
19 { name: "user", type: "address" },
20 { name: "nonce", type: "uint256" },
21 { name: "timestamp", type: "uint256" },
22 ],
23 },
24 primaryType: "Auth",
25 message: {
26 user: "0x...", // wallet address
27 nonce: 12345,
28 timestamp: Date.now(),
29 },
30 } as const;
31
32 const signature = await signTypedDataAsync({ typedData });
33 console.log("Typed data signature:", signature);
34 };
35
36 return (
37 <div>
38 <button onClick={handleSignTypedData}>Sign Typed Data</button>
39 </div>
40 );
41}

Typed data structure

EIP-712 typed data consists of four main components:

Domain

The domain provides context and prevents signature reuse across different dApps:

1const domain = {
2 name: "Example DApp",
3 version: "1",
4 chainId: 1,
5 verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
6};

Types

Define the structure of your data:

1const types = {
2 Person: [
3 { name: "name", type: "string" },
4 { name: "wallet", type: "address" },
5 ],
6 Mail: [
7 { name: "from", type: "Person" },
8 { name: "to", type: "Person" },
9 { name: "contents", type: "string" },
10 ],
11};

Primary type

Specify which type is the main type being signed:

1const primaryType = "Mail";

Message

The actual data to sign:

1const message = {
2 from: {
3 name: "Alice",
4 wallet: "0xAaAaAaAaAaAaAaAaAaAAAAAAAAaaaAaAaAaaAaAa",
5 },
6 to: {
7 name: "Bob",
8 wallet: "0xBbBbBbBbBbBbBbBbBbBBBBBBBBbbBbBbBbbBbBb",
9 },
10 contents: "Hello, Bob!",
11};

Next steps

Build more:

Troubleshooting: