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
DynamicEvmWalletClient::sign_message signs a UTF-8 message using EIP-191 (personal_sign) and returns a 0x-prefixed r || s || v signature (65 bytes / 130 hex chars). Message signing is commonly used for authentication, nonce verification, and data integrity checks.
Prerequisites
Basic Message Signing
The Rust SDK is stateless — every sign call requires WalletProperties and external_server_key_shares. Load both from where you persisted them at wallet creation time.
use dynamic_waas_sdk::{ServerKeyShare, WalletProperties};
use dynamic_waas_sdk_evm::DynamicEvmWalletClient;
let evm = DynamicEvmWalletClient::new(&client);
// Load the metadata + shares you persisted at creation time.
let wallet_properties: WalletProperties = serde_json::from_str(
&redis.get(format!("wallet:{}", account_address)).await?,
)?;
let external_server_key_shares: Vec<ServerKeyShare> = serde_json::from_slice(
&vault.read(format!("wallet:{}/shares", account_address)).await?,
)?;
let signature = evm
.sign_message(
&wallet_properties,
&external_server_key_shares,
"Hello, World!",
)
.await?;
println!("Signature: {signature}");
signature is a 0x-prefixed hex string — pass it directly to any EIP-191 verifier (alloy, ethers, viem, etc).
Verifying the signer locally
Because the signature is standard EIP-191, you can recover the signer with any EVM library. With alloy:
use alloy_primitives::{Address, Signature};
let prefixed = format!(
"\x19Ethereum Signed Message:\n{}{}",
"Hello, World!".len(),
"Hello, World!",
);
let digest = alloy_primitives::keccak256(prefixed.as_bytes());
let sig: Signature = signature.parse()?;
let recovered: Address = sig.recover_address_from_prehash(&digest)?;
assert_eq!(
recovered.to_checksum(None),
wallet_properties.account_address,
);
Common Use Cases
Authentication
let nonce = chrono::Utc::now().timestamp_millis().to_string();
let message = format!("Sign this message to authenticate: {nonce}");
let signature = evm
.sign_message(&wallet_properties, &external_server_key_shares, &message)
.await?;
Data Integrity
let payload = serde_json::json!({ "user_id": 123, "action": "transfer", "amount": "100" });
let message = serde_json::to_string(&payload)?;
let signature = evm
.sign_message(&wallet_properties, &external_server_key_shares, &message)
.await?;
Next Steps