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

DynamicSvmWalletClient::signTransaction signs the serialized message of a Solana transaction (i.e. bytes(transaction.message), not the full wire envelope) and returns the Ed25519 signature as a lowercase hex string. For most apps you’ll want sendTransaction which signs and broadcasts in one call. Reach for signTransaction when you need the raw signature out-of-band — co-signing, batched broadcast, or programs that pre-assemble the wire envelope themselves.

Prerequisites

Build the Message

Build the unsigned Solana transaction with your Solana library of choice — sava-core is the canonical JVM option — then serialize just the message portion (everything after the signature section):
import software.sava.core.tx.Transaction;
// ... assemble Transaction tx ...
byte[] messageBytes = tx.serializedMessage();  // not tx.serialize() — that includes empty sig slots
If you use a different SDK, the equivalent is bytes(transaction.message) in solana-py / solana-web3.js’s tx.compileMessage().serialize().

Sign the Message

import xyz.dynamic.waas.svm.opts.SignTransactionOpts;

String signatureHex = client.signTransaction(SignTransactionOpts.builder()
    .messageBytes(messageBytes)
    .walletProperties(walletProperties)
    .externalServerKeyShares(externalServerKeyShares)
    .build()
).join();

System.out.println("Signature: " + signatureHex);
signatureHex is a lowercase 128-char hex string (64-byte Ed25519 signature). To assemble the wire envelope, prepend the signature in the slot matching the wallet’s index in the message’s accountKeys array.

Assembling the Wire Envelope

For a single-signer transaction:
import java.nio.ByteBuffer;
import software.sava.core.encoding.CompactU16Encoding;
import org.web3j.utils.Numeric;

byte[] sigBytes = Numeric.hexStringToByteArray("0x" + signatureHex);   // 64 bytes

ByteBuffer wire = ByteBuffer.allocate(
    CompactU16Encoding.encodedLength(1) + 64 + messageBytes.length
);
CompactU16Encoding.encode(wire, 1);    // signature count
wire.put(sigBytes);
wire.put(messageBytes);

byte[] signedTxWire = new byte[wire.position()];
wire.flip(); wire.get(signedTxWire);
Send signedTxWire to any Solana RPC via sendTransaction.

Next Steps