Skip to main content

Overview

This guide covers gas management including gas price retrieval, gas limits, and gas optimization with the Dynamic Swift SDK.

Prerequisites

Gas Management

Get Current Gas Price

let networkClient = try await ethereumWallet.getNetworkClient(for: chainId)

do {
    let gasPrice = try await networkClient.eth_gasPriceBigInt()
    print("Current gas price: \(gasPrice) wei")
} catch {
    print("Failed to get gas price: \(error)")
}

Gas Limit for ETH Transfers

// Standard gas limit for ETH transfers (used in sample app)
let gasLimit = BigUInt(21_000) // Standard ETH transfer
print("ETH Transfer Gas Limit: \(gasLimit)")

Gas Price Management

Get Network Gas Price

let dynamicClient: DynamicClient
let ethereumWallet: EthereumWallet
let chainId = SupportedEthereumNetwork.sepoliaTestnet.chainConfig.chainId

do {
    let networkClient = try await ethereumWallet.getNetworkClient(for: chainId)
    print("Connected to Sepolia network: \(chainId)")

    // Get gas price for transactions
    let gasPrice = try await networkClient.eth_gasPriceBigInt()
    print("Current gas price: \(gasPrice) wei")
} catch {
    print("Failed to get network client: \(error)")
}

Convert Gas Price to Gwei

// Convert Wei to Gwei for user-friendly display
func weiToGwei(_ wei: BigUInt) -> Double {
    let gweiValue = Double(String(wei)) ?? 0.0
    return gweiValue / pow(10.0, 9.0) // 1 Gwei = 10^9 Wei
}

// Usage
let gasPriceWei = try await networkClient.eth_gasPriceBigInt()
let gasPriceGwei = weiToGwei(gasPriceWei)
print("Gas Price: \(String(format: "%.2f", gasPriceGwei)) Gwei")

Gas Limit Management

Standard Gas Limits

// Common gas limits for different transaction types
struct GasLimits {
    static let ethTransfer = BigUInt(21_000)      // Standard ETH transfer
    static let erc20Transfer = BigUInt(65_000)    // ERC-20 token transfer
    static let contractDeploy = BigUInt(500_000)  // Contract deployment
    static let contractCall = BigUInt(100_000)    // Contract function call
}

// Usage
let gasLimit = GasLimits.ethTransfer
print("Using standard ETH transfer gas limit: \(gasLimit)")

Estimate Gas Limit

// Estimate gas for complex transactions
func estimateGasForTransaction(_ transaction: EthereumTransaction) async throws -> BigUInt {
    let networkClient = try await ethereumWallet.getNetworkClient(for: transaction.chainId)
    return try await networkClient.eth_estimateGas(transaction)
}

// Usage
let transaction = EthereumTransaction(
    from: ethereumWallet.address,
    to: recipient,
    value: amount,
    data: Data(),
    nonce: nil,
    gasPrice: gasPrice,
    gasLimit: nil, // Will be estimated
    chainId: chainId
)

do {
    let estimatedGas = try await estimateGasForTransaction(transaction)
    print("Estimated gas: \(estimatedGas)")

    // Add buffer for safety (20% buffer)
    let gasWithBuffer = estimatedGas + (estimatedGas / 5)
    print("Gas with buffer: \(gasWithBuffer)")
} catch {
    print("Failed to estimate gas: \(error)")
}

Gas Optimization

Dynamic Gas Pricing

// Get optimal gas price based on network conditions
func getOptimalGasPrice() async throws -> BigUInt {
    let networkClient = try await ethereumWallet.getNetworkClient(for: chainId)
    let currentGasPrice = try await networkClient.eth_gasPriceBigInt()

    // Add 10% buffer for faster confirmation
    let optimalGasPrice = currentGasPrice + (currentGasPrice / 10)
    return optimalGasPrice
}

// Usage
do {
    let optimalGasPrice = try await getOptimalGasPrice()
    print("Optimal gas price: \(optimalGasPrice) wei")
} catch {
    print("Failed to get optimal gas price: \(error)")
}

Gas Price Strategies

enum GasStrategy {
    case low      // Slow but cheap
    case medium   // Balanced
    case high     // Fast but expensive
}

func getGasPriceForStrategy(_ strategy: GasStrategy, basePrice: BigUInt) -> BigUInt {
    switch strategy {
    case .low:
        return basePrice - (basePrice / 10) // 10% below base
    case .medium:
        return basePrice // Use base price
    case .high:
        return basePrice + (basePrice / 5) // 20% above base
    }
}

// Usage
let baseGasPrice = try await networkClient.eth_gasPriceBigInt()
let fastGasPrice = getGasPriceForStrategy(.high, basePrice: baseGasPrice)
print("Fast gas price: \(fastGasPrice) wei")

Transaction Gas Management

Create Transaction with Gas

let fromAddress = ethereumWallet.address
let toAddress = EthereumAddress("0xRecipientAddress")
let amount = BigUInt(1000000000000000000) // 1 ETH in wei
let gasPrice = try await networkClient.eth_gasPriceBigInt()
let gasLimit = BigUInt(21_000)
let chainId = SupportedEthereumNetwork.sepoliaTestnet.chainConfig.chainId

let transaction = EthereumTransaction(
    from: fromAddress,
    to: toAddress,
    value: amount,
    data: Data(),
    nonce: nil,
    gasPrice: gasPrice,
    gasLimit: gasLimit,
    chainId: chainId
)

Calculate Transaction Cost

// Calculate total transaction cost in ETH
func calculateTransactionCost(gasPrice: BigUInt, gasLimit: BigUInt) -> Double {
    let totalWei = gasPrice * gasLimit
    let totalEth = Double(String(totalWei)) ?? 0.0
    return totalEth / pow(10.0, 18.0)
}

// Usage
let gasPrice = try await networkClient.eth_gasPriceBigInt()
let gasLimit = BigUInt(21_000)
let cost = calculateTransactionCost(gasPrice: gasPrice, gasLimit: gasLimit)
print("Transaction cost: \(String(format: "%.6f", cost)) ETH")

Best Practices

1. Always Get Current Gas Price

// Always get current gas price before sending transactions
let gasPrice = try await networkClient.eth_gasPriceBigInt()
let gasLimit = BigUInt(21_000) // Standard ETH transfer

// For complex transactions, estimate gas limit
let estimatedGas = try await networkClient.eth_estimateGas(transaction)

2. Use Appropriate Gas Limits

// Use standard limits for simple transactions
let gasLimit = GasLimits.ethTransfer

// Estimate for complex transactions
let estimatedGas = try await estimateGasForTransaction(transaction)
let gasWithBuffer = estimatedGas + (estimatedGas / 5) // 20% buffer

3. Monitor Gas Prices

// Monitor gas prices for optimal timing
func monitorGasPrices() async {
    while true {
        do {
            let gasPrice = try await networkClient.eth_gasPriceBigInt()
            let gasPriceGwei = weiToGwei(gasPrice)
            print("Current gas price: \(String(format: "%.2f", gasPriceGwei)) Gwei")

            // Wait 30 seconds before next check
            try await Task.sleep(nanoseconds: 30_000_000_000)
        } catch {
            print("Failed to get gas price: \(error)")
            break
        }
    }
}

Error Handling

do {
    let gasPrice = try await networkClient.eth_gasPriceBigInt()
} catch {
    if let nsError = error as NSError? {
        switch nsError.code {
        case 5001:
            print("Gas price too high")
        case 5002:
            print("Gas limit exceeded")
        case 5003:
            print("Insufficient gas for transaction")
        default:
            print("Gas error: \(error)")
        }
    }
}

Next Steps

After mastering gas management, you can:
I