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::sendTransaction signs the serialized message of a Solana transaction with the MPC ceremony and broadcasts it via Solana JSON-RPC in one call. Returns the transaction signature (base58) — the standard Solana tx ID. sendTransaction is the recommended path for most apps. Reach for signTransaction only if you need to assemble the wire envelope yourself.

Prerequisites

Sign + Broadcast in One Call

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

byte[] messageBytes = /* bytes(transaction.message) — see Sign SVM Transactions */;

String txSig = client.sendTransaction(SendTransactionOpts.builder()
    .messageBytes(messageBytes)
    .walletProperties(walletProperties)
    .externalServerKeyShares(externalServerKeyShares)
    .rpcUrl("https://api.devnet.solana.com")
    .sponsor(false)        // true to take the sponsorship path
    .build()
).join();

System.out.println("Submitted tx: " + txSig);
System.out.println("Explorer: https://explorer.solana.com/tx/" + txSig + "?cluster=devnet");
A fresh JSON-RPC client is constructed per call. For high-throughput scenarios, compose signTransaction with your own pooled RPC client.

Gas Sponsorship

Setting .sponsor(true) routes the broadcast through Dynamic’s sponsor path — Dynamic pays the SOL transaction fee and you don’t need to fund the wallet’s lamports balance. Gas sponsorship must be enabled for your environment in the Dynamic dashboard.
String sponsoredTxSig = client.sendTransaction(SendTransactionOpts.builder()
    .messageBytes(messageBytes)
    .walletProperties(walletProperties)
    .externalServerKeyShares(externalServerKeyShares)
    .rpcUrl("https://api.mainnet-beta.solana.com")
    .sponsor(true)
    .build()
).join();
See Sponsor Transactions for the lower-level building block (sponsorTransaction returns the sponsor-signed wire envelope without broadcasting).

Building the Message

Use sava-core (or any other JVM Solana SDK) to assemble the unsigned transaction, fetch the latest blockhash, and serialize just the message portion:
import software.sava.core.tx.Transaction;
import software.sava.rpc.json.http.client.SolanaRpcClient;

SolanaRpcClient rpc = SolanaRpcClient.createClient(java.net.URI.create("https://api.devnet.solana.com"));
String blockhash    = rpc.getLatestBlockhash().join().blockhash();

Transaction tx = Transaction.createTx(
    walletPubkey,
    List.of(/* SystemProgram.transfer(...), etc. */),
    blockhash
);
byte[] messageBytes = tx.serializedMessage();

Error Handling

import java.util.concurrent.CompletionException;
import xyz.dynamic.waas.core.exceptions.DynamicSdkException;

try {
    String txSig = client.sendTransaction(opts).join();
    log.info("Submitted: {}", txSig);
} catch (CompletionException ce) {
    if (ce.getCause() instanceof DynamicSdkException dse) {
        log.error("Send failed: {}", dse.getMessage(), dse);
    } else {
        throw ce;
    }
}
If the broadcast itself fails (blockhash not found, sponsor pool exhausted, etc.), the error message surfaces verbatim — refresh the blockhash and retry.

Next Steps