Skip to main content

Documentation Index

Fetch the complete documentation index at: https://www.dynamic.xyz/docs/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Use the Python SDK to sign EIP-712 typed data with your server wallet. Typed data signing is used for permits, order signing, and other structured data that produces a recoverable signature.

Prerequisites

Sign Typed Data

Pass the wallet address and a typed data dict in EIP-712 format:
import asyncio
import os
from dynamic_wallet_sdk import DynamicEvmWalletClient

async def main():
    async with DynamicEvmWalletClient(os.environ["DYNAMIC_ENV_ID"]) as client:
        await client.authenticate_api_token(os.environ["DYNAMIC_API_TOKEN"])

        typed_data = {
            "types": {
                "EIP712Domain": [
                    {"name": "name", "type": "string"},
                    {"name": "version", "type": "string"},
                    {"name": "chainId", "type": "uint256"},
                ],
                "Message": [
                    {"name": "content", "type": "string"},
                    {"name": "from", "type": "address"},
                ],
            },
            "primaryType": "Message",
            "domain": {"name": "My App", "version": "1", "chainId": 1},
            "message": {"content": "Hello!", "from": "0xYourWalletAddress"},
        }

        signature = await client.sign_typed_data(
            address="0xYourWalletAddress",
            typed_data=typed_data,
        )
        print(f"Signature: {signature}")

asyncio.run(main())
The method returns the serialized ECDSA signature as a hex string (0x...).

With a Password-Protected Wallet

signature = await client.sign_typed_data(
    address="0xYourWalletAddress",
    typed_data=typed_data,
    password="your-wallet-password",
)

ERC-2612 Permit Example

A common use case is signing ERC-2612 token permits, allowing gasless approvals:
typed_data = {
    "types": {
        "EIP712Domain": [
            {"name": "name", "type": "string"},
            {"name": "version", "type": "string"},
            {"name": "chainId", "type": "uint256"},
            {"name": "verifyingContract", "type": "address"},
        ],
        "Permit": [
            {"name": "owner", "type": "address"},
            {"name": "spender", "type": "address"},
            {"name": "value", "type": "uint256"},
            {"name": "nonce", "type": "uint256"},
            {"name": "deadline", "type": "uint256"},
        ],
    },
    "primaryType": "Permit",
    "domain": {
        "name": "USD Coin",
        "version": "2",
        "chainId": 1,
        "verifyingContract": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    },
    "message": {
        "owner": "0xYourWalletAddress",
        "spender": "0xSpenderAddress",
        "value": 1000000,   # 1 USDC (6 decimals)
        "nonce": 0,
        "deadline": 1735689600,
    },
}

signature = await client.sign_typed_data(
    address="0xYourWalletAddress",
    typed_data=typed_data,
)

Next Steps