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::signMessage signs raw bytes 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.
The SDK also exposes an off-chain verifier — DynamicEvmWalletClient.verifyMessageSignature(...) — for recovering the signer locally without any MPC or network I/O.
Prerequisites
Basic Message Signing
The Java SDK is stateless — every sign call requires walletProperties and externalServerKeyShares. Load both from where you persisted them at wallet creation time.
import java.util.List;
import xyz.dynamic.waas.ServerKeyShare;
import xyz.dynamic.waas.core.types.WalletProperties;
import xyz.dynamic.waas.evm.DynamicEvmWalletClient;
import xyz.dynamic.waas.opts.SignMessageOpts;
// Load the metadata + shares you persisted at creation time.
WalletProperties walletProperties = WalletProperties.fromJson(
redis.get("wallet:" + accountAddress)
);
List<ServerKeyShare> externalServerKeyShares = ServerKeyShare.fromJsonList(
vault.read("wallet:" + accountAddress + "/shares")
);
String signature = client.signMessage(SignMessageOpts.builder()
.message("Hello, World!".getBytes(java.nio.charset.StandardCharsets.UTF_8))
.walletProperties(walletProperties)
.externalServerKeyShares(externalServerKeyShares)
.build()
).join();
System.out.println("Signature: " + signature);
signature is a 0x-prefixed hex string — pass it directly to any EIP-191 verifier (web3j, ethers, viem, etc).
Verifying the signer locally
Because the signature is standard EIP-191, you can recover the signer with the SDK’s static helper — no MPC ceremony, no network I/O:
boolean ok = DynamicEvmWalletClient.verifyMessageSignature(
walletProperties.accountAddress(),
"Hello, World!".getBytes(java.nio.charset.StandardCharsets.UTF_8),
signature
);
assert ok : "signature does not match accountAddress";
verifyMessageSignature hashes the message via EIP-191, recovers the signer address from (r || s || v), and compares it case-insensitively to accountAddress. Returns false on any structural failure (bad length, bad recovery, mismatch).
Common Use Cases
Authentication
String nonce = String.valueOf(System.currentTimeMillis());
String message = "Sign this message to authenticate: " + nonce;
String signature = client.signMessage(SignMessageOpts.builder()
.message(message.getBytes(java.nio.charset.StandardCharsets.UTF_8))
.walletProperties(walletProperties)
.externalServerKeyShares(externalServerKeyShares)
.build()
).join();
Data Integrity
String payloadJson = "{\"userId\":123,\"action\":\"transfer\",\"amount\":\"100\"}";
String signature = client.signMessage(SignMessageOpts.builder()
.message(payloadJson.getBytes(java.nio.charset.StandardCharsets.UTF_8))
.walletProperties(walletProperties)
.externalServerKeyShares(externalServerKeyShares)
.build()
).join();
Next Steps