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 walks you through creating EVM wallets using Dynamic’s Python SDK. You’ll learn how to choose a threshold signature scheme, back up key shares, and handle errors.

Prerequisites

Step 1: Choose Your Security Model

Dynamic supports two threshold signature schemes:
  • Security: Highest — requires both your server and Dynamic’s infrastructure
  • Availability: Lower — both parties must be online to sign
  • Use case: Default for all server-side wallets

TWO_OF_THREE (Advanced)

  • Security: High — requires 2 of 3 shares
  • Availability: Medium — tolerates one party being offline
  • Use case: Setups that need to tolerate one share being offline

Step 2: Create Your First Wallet

create_wallet_account returns a WalletProperties object — the user-facing fields are account_address and wallet_id.
import asyncio
import os
from dynamic_wallet_sdk import DynamicEvmWalletClient, ThresholdSignatureScheme

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

        wallet = await client.create_wallet_account(
            threshold_signature_scheme=ThresholdSignatureScheme.TWO_OF_TWO,
            password="your-secure-password",
        )
        print(f"EVM wallet: {wallet.account_address} (id: {wallet.wallet_id})")

asyncio.run(main())
The password parameter encrypts your key shares and backs them up to Dynamic at keygen time. Keep this password — you’ll need it to sign and to recover shares. threshold_signature_scheme defaults to TWO_OF_TWO if omitted.

Step 3: Store Wallet Information

After creating a wallet, store the address and wallet ID for later use:
async with DynamicEvmWalletClient(os.environ["DYNAMIC_ENV_ID"]) as client:
    await client.authenticate_api_token(os.environ["DYNAMIC_API_TOKEN"])

    wallet = await client.create_wallet_account(password="your-secure-password")

    wallet_data = {
        "address": wallet.account_address,
        "wallet_id": wallet.wallet_id,
    }
    print(wallet_data)
To rehydrate a wallet in a fresh process, call load_wallet(address) and pass password= to subsequent sign calls — the SDK transparently recovers the encrypted key shares from Dynamic’s backup:
async with DynamicEvmWalletClient(os.environ["DYNAMIC_ENV_ID"]) as client:
    await client.authenticate_api_token(os.environ["DYNAMIC_API_TOKEN"])

    await client.load_wallet(wallet_data["address"])
    signature = await client.sign_message(
        message="hello",
        address=wallet_data["address"],
        password="your-secure-password",
    )

Step 4: Handle Errors

All SDK exceptions inherit from DynamicSDKError. The most relevant subclasses for wallet creation and lookup are AuthenticationError (bad or expired API token) and WalletNotFoundError (raised by load_wallet and get_wallet_from_map when the address is unknown).
from dynamic_wallet_sdk import DynamicSDKError, AuthenticationError

try:
    wallet = await client.create_wallet_account(password="your-secure-password")
    print(f"Wallet created: {wallet.account_address}")
except AuthenticationError:
    print("Authentication failed — check your API token")
except DynamicSDKError as e:
    print(f"Wallet creation failed: {e}")

Best Practices

  1. Password security — Use a strong, unique password per wallet. Consider storing it encrypted in a secrets manager.
  2. Store wallet ID — Save the wallet_id alongside the address in your database. It’s needed for delegated signing.
  3. Error handling — Always handle DynamicSDKError and its subclasses.
  4. Context manager — Use async with so the HTTP client is properly closed.

Next Steps