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
Send ETH by creating transactions, estimating gas, and handling responses.
Prerequisites
Send ETH Transaction
import com.dynamic.sdk.android.DynamicSDK
import com.dynamic.sdk.android.Models.BaseWallet
import com.dynamic.sdk.android.Chains.EVM.EthereumTransaction
import com.dynamic.sdk.android.Chains.EVM.convertEthToWei
import kotlinx.coroutines.launch
import java.math.BigInteger
val sdk = DynamicSDK.getInstance()
suspend fun sendTransaction(wallet: BaseWallet, to: String, amountInEth: String) {
try {
val chainId = 1
val client = sdk.evm.createPublicClient(chainId)
val gasPrice = client.getGasPrice()
val maxFeePerGas = gasPrice * BigInteger.valueOf(2)
val maxPriorityFeePerGas = gasPrice
val weiAmount = convertEthToWei(amountInEth)
val transaction = EthereumTransaction(
from = wallet.address,
to = to,
value = weiAmount,
gas = BigInteger.valueOf(21000),
maxFeePerGas = maxFeePerGas,
maxPriorityFeePerGas = maxPriorityFeePerGas
)
val txHash = sdk.evm.sendTransaction(transaction, wallet)
println("Transaction sent!")
println("Hash: $txHash")
} catch (e: Exception) {
println("Transaction failed: ${e.message}")
}
}
Sign Transaction (Without Sending)
import com.dynamic.sdk.android.Chains.EVM.signEthereumTransaction
suspend fun signTransactionOnly(wallet: BaseWallet) {
try {
val signedTx = sdk.wallets.signEthereumTransaction(
wallet = wallet,
to = "0x742d35Cc6634C0532925a3b844Bc9e7595f0bDd7",
value = "0.001",
gasLimit = "21000",
maxPriorityFeePerGas = "2",
maxFeePerGas = "50"
)
println("Signed transaction: $signedTx")
} catch (e: Exception) {
println("Failed to sign: ${e.message}")
}
}
Best Practices
- Always get current gas price before sending
- Add buffer for price fluctuations (2x multiplier)
- Handle common errors: insufficient funds, gas too low, invalid address
- Validate address format before sending
- Show transaction confirmations to users
- Display transaction status with explorer links
Handle Transaction Errors
try {
val txHash = sdk.evm.sendTransaction(transaction, wallet)
} catch (e: Exception) {
when {
e.message?.contains("insufficient", ignoreCase = true) == true -> {
showError("Insufficient funds for transaction")
}
e.message?.contains("gas", ignoreCase = true) == true -> {
showError("Gas estimation failed. Try increasing gas limit.")
}
else -> {
showError("Transaction failed: ${e.message}")
}
}
}
Show Transaction Status
@Composable
fun TransactionStatusView(txHash: String, chainId: Int) {
val explorerUrl = when (chainId) {
1 -> "https://etherscan.io/tx/$txHash"
11155111 -> "https://sepolia.etherscan.io/tx/$txHash"
84532 -> "https://sepolia.basescan.org/tx/$txHash"
137 -> "https://polygonscan.com/tx/$txHash"
else -> null
}
Column {
Text("Transaction Submitted", style = MaterialTheme.typography.headlineSmall)
Text(
text = txHash,
style = MaterialTheme.typography.bodySmall,
maxLines = 1
)
explorerUrl?.let { url ->
Button(onClick = { /* Open URL */ }) {
Text("View on Explorer")
}
}
}
}
fun isValidEthereumAddress(address: String): Boolean {
return address.matches(Regex("^0x[a-fA-F0-9]{40}$"))
}
Error Handling
Common Transaction Errors
sealed class TransactionError {
data class InsufficientFunds(val message: String) : TransactionError()
data class GasEstimationFailed(val message: String) : TransactionError()
data class UserRejected(val message: String) : TransactionError()
data class NetworkError(val message: String) : TransactionError()
data class InvalidAddress(val message: String) : TransactionError()
data class Unknown(val message: String) : TransactionError()
}
fun parseTransactionError(e: Exception): TransactionError {
val errorMessage = e.message?.lowercase() ?: ""
return when {
errorMessage.contains("insufficient") ->
TransactionError.InsufficientFunds("Insufficient balance for this transaction")
errorMessage.contains("gas") ->
TransactionError.GasEstimationFailed("Gas estimation failed. Try increasing gas limit.")
errorMessage.contains("rejected") || errorMessage.contains("denied") ->
TransactionError.UserRejected("Transaction was rejected")
errorMessage.contains("network") ->
TransactionError.NetworkError("Network error. Please check your connection.")
errorMessage.contains("invalid") && errorMessage.contains("address") ->
TransactionError.InvalidAddress("Invalid recipient address")
else ->
TransactionError.Unknown("Transaction failed. Please try again.")
}
}
// Usage in ViewModel
try {
val txHash = sdk.evm.sendTransaction(transaction, wallet)
_transactionHash.value = txHash
} catch (e: Exception) {
val error = parseTransactionError(e)
_errorMessage.value = when (error) {
is TransactionError.InsufficientFunds -> error.message
is TransactionError.GasEstimationFailed -> error.message
is TransactionError.UserRejected -> error.message
is TransactionError.NetworkError -> error.message
is TransactionError.InvalidAddress -> error.message
is TransactionError.Unknown -> error.message
}
}
Troubleshooting
Transaction not confirming: Increase gas price multiplier to 3x
Insufficient funds: Check balance includes gas fees before sending
Nonce issues: SDK handles nonces automatically, manually specify only if needed
What’s Next