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

This guide shows you how to sign messages with your EVM wallet. Message signing is commonly used for authentication, proof of ownership, and off-chain data verification. The Python SDK signs messages using EIP-191 personal sign format.

Prerequisites

Basic Message Signing

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"])

        signature = await client.sign_message(
            message="Hello, Dynamic!",
            address="0xYourWalletAddress",
        )
        print(f"Signature: {signature}")

asyncio.run(main())
The returned signature is a hex string (0x...), 132 characters long (65 bytes: r + s + v).

Signing with a Password-Protected Wallet

If you created your wallet with a password, pass it when signing:
signature = await client.sign_message(
    message="Hello, Dynamic!",
    address="0xYourWalletAddress",
    password="your-wallet-password",
)
Password handling:
  • If your wallet was created without a password, omit the password parameter.
  • If your wallet was created with a password, you must provide it for all signing operations.
The same password= kwarg also enables auto-recovery in fresh processes — the SDK transparently rehydrates key shares from Dynamic’s encrypted backup before signing. See Step 3 of Create an EVM Wallet for details.

Verifying a Signature

You can verify the signature off-chain using eth-account:
from eth_account import Account
from eth_account.messages import encode_defunct

message = "Hello, Dynamic!"
signature = await client.sign_message(message=message, address=address)

msg = encode_defunct(text=message)
recovered = Account.recover_message(msg, signature=signature)

assert recovered.lower() == address.lower(), "Signature mismatch!"
print("Signature verified")

Common Use Cases

Authentication Nonce

import time

nonce = str(int(time.time()))
message = f"Sign this message to authenticate: {nonce}"

signature = await client.sign_message(message=message, address=address)

Proof of Ownership

message = f"I own wallet {address}"
signature = await client.sign_message(message=message, address=address)

Next Steps