> ## 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.

# Sign SVM Transactions

> Sign Solana transactions with Dynamic's Java SDK

## 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`](/java/svm/send-transaction) 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

* [Created an SVM wallet](/java/svm/create-wallet)

## Build the Message

Build the unsigned Solana transaction with your Solana library of choice — [`sava-core`](https://github.com/sava-software/sava) is the canonical JVM option — then serialize **just the message portion** (everything after the signature section):

```java theme={"system"}
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

```java theme={"system"}
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:

```java theme={"system"}
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

* [Send transactions in one call](/java/svm/send-transaction)
* [Sponsor transactions](/java/svm/sponsor-transaction)
* [Sign messages](/java/svm/sign-messages)
* [Delegated access](/java/svm/delegated-access)
