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
DynamicSvmWalletClient::signMessage signs raw bytes with Ed25519 and returns a base58-encoded 64-byte signature. The signature is over the raw message bytes — no Solana-specific message envelope is applied.
Prerequisites
Basic Message Signing
import java.nio.charset.StandardCharsets;
import java.util.List;
import xyz.dynamic.waas.ServerKeyShare;
import xyz.dynamic.waas.core.types.WalletProperties;
import xyz.dynamic.waas.opts.SignMessageOpts;
import xyz.dynamic.waas.svm.DynamicSvmWalletClient;
// 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 signatureB58 = client.signMessage(SignMessageOpts.builder()
.message("Hello, World!".getBytes(StandardCharsets.UTF_8))
.walletProperties(walletProperties)
.externalServerKeyShares(externalServerKeyShares)
.build()
).join();
System.out.println("Signature: " + signatureB58);
Verifying the signer locally
Verify the signature against the account address (a base58-encoded Ed25519 public key) with the JDK’s built-in Signature API plus any base58 codec — here using sava-core:
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
import software.sava.core.encoding.Base58;
byte[] pubkeyBytes = Base58.decode(walletProperties.accountAddress()); // 32 bytes
byte[] sigBytes = Base58.decode(signatureB58); // 64 bytes
// SubjectPublicKeyInfo prefix for Ed25519 raw 32-byte pubkey:
byte[] prefix = new byte[] {
0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x03, 0x21, 0x00
};
byte[] spki = new byte[prefix.length + pubkeyBytes.length];
System.arraycopy(prefix, 0, spki, 0, prefix.length);
System.arraycopy(pubkeyBytes, 0, spki, prefix.length, pubkeyBytes.length);
PublicKey publicKey = KeyFactory.getInstance("Ed25519")
.generatePublic(new X509EncodedKeySpec(spki));
Signature verifier = Signature.getInstance("Ed25519");
verifier.initVerify(publicKey);
verifier.update("Hello, World!".getBytes(StandardCharsets.UTF_8));
assert verifier.verify(sigBytes) : "signature does not verify";
Use case: off-chain auth
Common pattern for nonce-based wallet auth:
String nonce = java.util.UUID.randomUUID().toString();
String message = "Sign this nonce to authenticate: " + nonce;
String signatureB58 = client.signMessage(SignMessageOpts.builder()
.message(message.getBytes(StandardCharsets.UTF_8))
.walletProperties(walletProperties)
.externalServerKeyShares(externalServerKeyShares)
.build()
).join();
Next Steps