Documentation Index
Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Connect to Solana networks to query accounts, check balances, and prepare transactions.
Prerequisites
Get Solana Wallets
import com.dynamic.sdk.android.DynamicSDK
import com.dynamic.sdk.android.Models.BaseWallet
val sdk = DynamicSDK.getInstance()
// Get all Solana wallets
val solanaWallets = sdk.wallets.userWallets.filter {
it.chain.uppercase() == "SOL"
}
// Use first Solana wallet
val wallet = solanaWallets.firstOrNull()
if (wallet != null) {
println("Solana Address: ${wallet.address}")
}
Create Solana Connection
import com.solanaweb3.Connection
import com.solanaweb3.Cluster
val connection = Connection(Cluster.DEVNET)
val mainnetConnection = Connection(Cluster.MAINNET_BETA)
val customConnection = Connection("https://api.mainnet-beta.solana.com")
Query Account Balance
import com.solanaweb3.Connection
import com.solanaweb3.Cluster
import org.sol4k.PublicKey
suspend fun getBalance(address: String): Long {
return try {
val connection = Connection(Cluster.DEVNET)
val publicKey = PublicKey(address)
connection.getBalance(publicKey)
} catch (e: Exception) {
println("Failed to get balance: ${e.message}")
0L
}
}
Get Latest Blockhash
import com.solanaweb3.Connection
import com.solanaweb3.Cluster
suspend fun getLatestBlockhash(): String {
return try {
val connection = Connection(Cluster.DEVNET)
val blockhashResult = connection.getLatestBlockhash()
blockhashResult.blockhash
} catch (e: Exception) {
println("Failed to get blockhash: ${e.message}")
throw e
}
}
// Usage
val blockhash = getLatestBlockhash()
println("Latest blockhash: $blockhash")
Lamports Conversion
fun solToLamports(sol: Double): Long = (sol * 1_000_000_000).toLong()
fun lamportsToSol(lamports: Long): Double = lamports / 1_000_000_000.0
Solana Network Configuration
import com.solanaweb3.Cluster
enum class SolanaNetwork(val cluster: Cluster, val displayName: String) {
DEVNET(Cluster.DEVNET, "Devnet"),
TESTNET(Cluster.TESTNET, "Testnet"),
MAINNET(Cluster.MAINNET_BETA, "Mainnet Beta");
fun createConnection(): Connection {
return Connection(cluster)
}
}
// Usage
val network = SolanaNetwork.DEVNET
val connection = network.createConnection()
Best Practices
- Handle network errors gracefully
- Cache connection instances to avoid repeated creation
- Validate public key format before use
- Use devnet for testing, mainnet for production
- Monitor balance changes periodically if needed
Error Handling
sealed class SolanaConnectionError {
data class NetworkError(val message: String) : SolanaConnectionError()
data class InvalidAddress(val message: String) : SolanaConnectionError()
data class RpcError(val message: String) : SolanaConnectionError()
data class Unknown(val message: String) : SolanaConnectionError()
}
fun parseSolanaError(e: Exception): SolanaConnectionError {
val errorMessage = e.message?.lowercase() ?: ""
return when {
errorMessage.contains("network") || errorMessage.contains("connection") ->
SolanaConnectionError.NetworkError("Network connection failed")
errorMessage.contains("invalid") && errorMessage.contains("address") ->
SolanaConnectionError.InvalidAddress("Invalid Solana address")
errorMessage.contains("rpc") ->
SolanaConnectionError.RpcError("RPC request failed")
else ->
SolanaConnectionError.Unknown(e.message ?: "Unknown error")
}
}
// Usage in ViewModel
try {
val balance = connection.getBalance(publicKey)
_balance.value = balance
} catch (e: Exception) {
val error = parseSolanaError(e)
_errorMessage.value = when (error) {
is SolanaConnectionError.NetworkError -> error.message
is SolanaConnectionError.InvalidAddress -> error.message
is SolanaConnectionError.RpcError -> error.message
is SolanaConnectionError.Unknown -> error.message
}
}
Troubleshooting
Connection timeout: Use reliable RPC endpoint or implement retry logic with exponential backoff
Invalid blockhash: Fetch blockhash immediately before creating transaction (valid ~60 seconds)
Rate limiting: Add delays between requests or use rate limiting wrapper
What’s Next