Requires
xyz.dynamic.unitysdk.solana package and com.solana.unity_sdk for transaction building. Message signing works without these packages.Sign message
Message signing works without the Solana extension package:Copy
Ask AI
string signature = await DynamicSDK.Instance.Networks.Solana.SignMessage(
wallet.Id, "Hello World");
Send SOL (versioned transaction)
Copy
Ask AI
using Solana.Unity.Programs;
using Solana.Unity.Rpc.Models;
using Solana.Unity.Wallet;
var solana = DynamicSDK.Instance.Networks.Solana;
var rpcClient = solana.CreateConnection();
// Get recent blockhash
var blockHashResult = await rpcClient.GetLatestBlockHashAsync();
var blockHash = blockHashResult.Result.Value.Blockhash;
var fromKey = new PublicKey(wallet.Address);
var toKey = new PublicKey("RecipientAddress");
var lamports = (ulong)(0.01 * 1_000_000_000); // 0.01 SOL
// Build versioned (v0) transaction
var tx = new VersionedTransaction
{
RecentBlockHash = blockHash,
FeePayer = fromKey,
Instructions = new List<TransactionInstruction>
{
SystemProgram.Transfer(fromKey, toKey, lamports)
},
AddressTableLookups = new List<MessageAddressTableLookup>()
};
var message = tx.CompileMessage();
// Prepend 1 empty signature slot for the SDK to sign
var txBytes = new byte[1 + 64 + message.Length];
txBytes[0] = 1; // 1 signature slot (compact-u16)
// bytes 1..64 stay zero (empty signature placeholder)
Buffer.BlockCopy(message, 0, txBytes, 65, message.Length);
string txHash = await solana.SignAndSendTransaction(
wallet.Id, txBytes, SolanaTransactionType.Versioned);
Send SPL token (versioned transaction)
Copy
Ask AI
using Solana.Unity.Programs;
using Solana.Unity.Rpc.Models;
using Solana.Unity.Wallet;
var solana = DynamicSDK.Instance.Networks.Solana;
var rpcClient = solana.CreateConnection();
var blockHashResult = await rpcClient.GetLatestBlockHashAsync();
var blockHash = blockHashResult.Result.Value.Blockhash;
var ownerKey = new PublicKey(wallet.Address);
var recipientKey = new PublicKey("RecipientAddress");
var mintKey = new PublicKey("TokenMintAddress"); // e.g. USDC mint
// Derive Associated Token Accounts
var sourceAta = AssociatedTokenAccountProgram
.DeriveAssociatedTokenAccount(ownerKey, mintKey);
var destAta = AssociatedTokenAccountProgram
.DeriveAssociatedTokenAccount(recipientKey, mintKey);
int decimals = 6; // USDC has 6 decimals
var rawAmount = (ulong)(1.5 * Math.Pow(10, decimals)); // 1.5 USDC
var tx = new VersionedTransaction
{
RecentBlockHash = blockHash,
FeePayer = ownerKey,
Instructions = new List<TransactionInstruction>
{
// Create destination ATA if it doesn't exist (idempotent)
AssociatedTokenAccountProgram.CreateAssociatedTokenAccount(
ownerKey, recipientKey, mintKey),
// Transfer SPL tokens
TokenProgram.Transfer(sourceAta, destAta, rawAmount, ownerKey)
},
AddressTableLookups = new List<MessageAddressTableLookup>()
};
var message = tx.CompileMessage();
var txBytes = new byte[1 + 64 + message.Length];
txBytes[0] = 1;
Buffer.BlockCopy(message, 0, txBytes, 65, message.Length);
string txHash = await solana.SignAndSendTransaction(
wallet.Id, txBytes, SolanaTransactionType.Versioned);
Common token mint addresses
| Token | Network | Mint Address |
|---|---|---|
| USDC | Mainnet (101) | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v |
| USDC | Devnet (103) | 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU |
Complete example
Copy
Ask AI
using DynamicSDK.Core;
using Solana.Unity.Programs;
using Solana.Unity.Rpc.Models;
using Solana.Unity.Wallet;
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Linq;
public class SolanaTransactionManager : MonoBehaviour
{
private BaseWallet _solWallet;
private void Start()
{
_solWallet = DynamicSDK.Instance.Wallets.UserWallets
.FirstOrDefault(w => w.Chain.ToUpper() == "SOL");
}
public async void SendSol(string toAddress, double amount)
{
if (_solWallet == null)
{
Debug.LogError("No Solana wallet available");
return;
}
try
{
var solana = DynamicSDK.Instance.Networks.Solana;
var rpcClient = solana.CreateConnection();
var blockHashResult = await rpcClient.GetLatestBlockHashAsync();
var blockHash = blockHashResult.Result.Value.Blockhash;
var fromKey = new PublicKey(_solWallet.Address);
var toKey = new PublicKey(toAddress);
var lamports = (ulong)(amount * 1_000_000_000);
var tx = new VersionedTransaction
{
RecentBlockHash = blockHash,
FeePayer = fromKey,
Instructions = new List<TransactionInstruction>
{
SystemProgram.Transfer(fromKey, toKey, lamports)
},
AddressTableLookups = new List<MessageAddressTableLookup>()
};
var message = tx.CompileMessage();
var txBytes = new byte[1 + 64 + message.Length];
txBytes[0] = 1;
Buffer.BlockCopy(message, 0, txBytes, 65, message.Length);
string txHash = await solana.SignAndSendTransaction(
_solWallet.Id, txBytes, SolanaTransactionType.Versioned);
Debug.Log($"Transaction sent: {txHash}");
}
catch (Exception ex)
{
Debug.LogError($"Transaction failed: {ex.Message}");
}
}
public async void SignMessage(string message)
{
if (_solWallet == null)
{
Debug.LogError("No Solana wallet available");
return;
}
string signature = await DynamicSDK.Instance.Networks.Solana.SignMessage(
_solWallet.Id, message);
Debug.Log($"Signature: {signature}");
}
}
Next steps
- Message Signing - Sign messages with Solana wallets
- Token Balances - Query token balances