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

The Solana delegated client mirrors the EVM delegated client one-for-one — same auth model, same webhook decrypt helper, same revocation. Only the chain client type and the signature format differ. For the full delegation flow (how the webhook is sent, what the encrypted envelope contains, security best practices), see EVM Delegated Access. This page covers only the Solana-specific bits.

Prerequisites

  • EVM Delegated Access — read this first for the full flow
  • An RSA private key registered with Dynamic for webhook decryption (PEM-encoded PKCS#8)

Decrypting the Webhook

Identical to EVM:
import xyz.dynamic.waas.delegated.DecryptedWebhookData;
import xyz.dynamic.waas.delegated.Webhook;

DecryptedWebhookData decrypted = Webhook.decryptDelegatedWebhookData(
    rsaPrivateKeyPem,
    payload.encryptedDelegatedKeyShare(),
    payload.encryptedWalletApiKey()
);

Building the Delegated SVM Client

import xyz.dynamic.waas.core.types.Environment;
import xyz.dynamic.waas.delegated.DelegatedWalletClientOpts;
import xyz.dynamic.waas.svm.delegated.DelegatedSvmWalletClient;

DelegatedWalletClientOpts opts = DelegatedWalletClientOpts.builder()
    .apiKey("your-dashboard-api-key")
    .environment(Environment.PROD)
    .environmentId("your-environment-id")
    .build();

DelegatedSvmWalletClient svm = new DelegatedSvmWalletClient(opts);
DelegatedSvmWalletClient is AutoCloseable — wrap it in try-with-resources or close it explicitly.

Signing a Solana Message

import xyz.dynamic.waas.svm.delegated.opts.DelegatedSignMessageOpts;

String signatureB58 = svm.signMessage(DelegatedSignMessageOpts.builder()
    .walletId(walletId)
    .walletApiKey(decrypted.walletApiKey())
    .keyShare(decrypted.serverKeyShare())
    .walletProperties(walletProperties)
    .message("Hello, World!".getBytes(java.nio.charset.StandardCharsets.UTF_8))
    .build()
).join();
signatureB58 is the base58-encoded 64-byte Ed25519 signature.

Signing a Solana Transaction

signTransaction accepts the serialized message bytes (bytes(transaction.message) — not the full serialized tx) and returns the Ed25519 signature as lowercase hex (not base58 — note the format difference vs signMessage):
import xyz.dynamic.waas.svm.delegated.opts.DelegatedSignTransactionOpts;

byte[] messageBytes = /* bytes(transaction.message) */;

String signatureHex = svm.signTransaction(DelegatedSignTransactionOpts.builder()
    .walletId(walletId)
    .walletApiKey(decrypted.walletApiKey())
    .keyShare(decrypted.serverKeyShare())
    .messageBytes(messageBytes)
    .build()
).join();
Splice the hex-decoded signature into your wire envelope at the appropriate signer slot — see Sign SVM Transactions § Assembling the Wire Envelope.

Exporting a Private Key

import java.util.List;
import xyz.dynamic.waas.svm.delegated.opts.DelegatedExportOpts;

String secretSeedB58 = svm.exportPrivateKey(DelegatedExportOpts.builder()
    .walletId(walletId)
    .walletApiKey(decrypted.walletApiKey())
    .externalServerKeyShares(List.of(decrypted.serverKeyShare()))
    .build()
).join();
Exporting bypasses MPC entirely — see Export SVM Private Key for the same one-way-operation caveats.

Revoking Delegation

Same as EVM — call revokeDelegation on the base delegated client:
svm.base().revokeDelegation(walletId, decrypted.walletApiKey()).join();