> ## 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.

# Gas Management

> Learn how to estimate and optimize gas costs for EVM transactions with the Dynamic Swift SDK.

## Overview

This guide covers gas price estimation, gas limit calculation, and optimization strategies for EVM transactions.

## Prerequisites

* Dynamic SDK initialized (see [Installation Guide](/swift/quickstart))
* Basic understanding of [EVM transactions](/swift/wallets/evm/send-eth)

## Get Current Gas Price

Fetch the current gas price from the network:

```swift theme={"system"}
import DynamicSDKSwift

let sdk = DynamicSDK.instance()

func getGasPrice(chainId: Int) async -> Int? {
    do {
        let client = sdk.evm.createPublicClient(chainId: chainId)
        let gasPrice = try await client.getGasPrice()
        return Int(gasPrice)
    } catch {
        print("Failed to get gas price: \(error)")
        return nil
    }
}
```

## Standard Gas Limits

Use these standard gas limits for common transaction types:

```swift theme={"system"}
import SwiftBigInt

/// Common gas limits for different transaction types
struct GasLimits {
    /// Standard ETH transfer: 21,000 gas
    static let ethTransfer = 21_000

    /// ERC-20 token transfer: 65,000 gas
    static let erc20Transfer = 65_000

    /// ERC-20 approve: 50,000 gas
    static let erc20Approve = 50_000

    /// Contract deployment: 500,000+ gas (varies by contract)
    static let contractDeploy = 500_000

    /// Contract function call: 100,000 gas (estimate first)
    static let contractCall = 100_000

    /// NFT minting: 150,000 gas (varies by contract)
    static let nftMint = 150_000
}

// Usage
let transaction = EthereumTransaction(
    from: wallet.address,
    to: recipientAddress,
    value: BigUInt(amountInWei),
    gas: BigUInt(GasLimits.ethTransfer),
    maxFeePerGas: gasPrice,
    maxPriorityFeePerGas: priorityFee
)
```

## Estimate Gas for Transactions

For complex contract interactions, estimate gas dynamically:

```swift theme={"system"}
import DynamicSDKSwift

let sdk = DynamicSDK.instance()

/// Estimate gas for a transaction
func estimateGas(
    for transaction: EthereumTransaction,
    chainId: Int
) async throws -> Int {
    let client = sdk.evm.createPublicClient(chainId: chainId)
    let estimate = try await client.estimateGas(transaction)
    return Int(estimate.value)
}

/// Estimate gas with safety buffer
func estimateGasWithBuffer(
    for transaction: EthereumTransaction,
    chainId: Int,
    bufferPercentage: Double = 20.0
) async throws -> Int {
    let baseEstimate = try await estimateGas(for: transaction, chainId: chainId)
    let buffer = 1.0 + (bufferPercentage / 100.0)
    return Int(Double(baseEstimate) * buffer)
}

// Usage
let transaction = EthereumTransaction(
    to: contractAddress,
    data: calldata,
    value: 0
)

let gasLimit = try await estimateGasWithBuffer(
    for: transaction,
    chainId: 1,
    bufferPercentage: 20
)
```

## EIP-1559 Gas Pricing

EIP-1559 introduced a new gas pricing mechanism with two components:

### Understanding EIP-1559 Parameters

```swift theme={"system"}
struct EIP1559Gas {
    /// Base fee: Algorithmically determined by the network
    /// This is burned and adjusts based on network congestion
    let baseFeePerGas: Int

    /// Priority fee (tip): Goes to the miner/validator
    /// Higher tips get faster inclusion
    let maxPriorityFeePerGas: Int

    /// Max fee: Maximum you're willing to pay per gas
    /// Should be: baseFee + maxPriorityFee + buffer
    let maxFeePerGas: Int
}
```

### Setting Gas Prices

```swift theme={"system"}
func calculateGasPrices(chainId: Int) async throws -> EIP1559Gas {
    let client = sdk.evm.createPublicClient(chainId: chainId)

    // Get current base fee
    let gasPrice = try await client.getGasPrice()
    let baseFee = Int(gasPrice.value)

    // Set priority fee (tip)
    let priorityFee = baseFee / 2  // Typically 50% of base fee

    // Set max fee (with 2x buffer for volatility)
    let maxFee = baseFee * 2 + priorityFee

    return EIP1559Gas(
        baseFeePerGas: baseFee,
        maxPriorityFeePerGas: priorityFee,
        maxFeePerGas: maxFee
    )
}

// Usage
let gasPrices = try await calculateGasPrices(chainId: 1)

let transaction = EthereumTransaction(
    from: wallet.address,
    to: recipient,
    value: BigUInt(amount),
    gas: BigUInt(21000),
    maxFeePerGas: BigUInt(gasPrices.maxFeePerGas),
    maxPriorityFeePerGas: BigUInt(gasPrices.maxPriorityFeePerGas)
)
```

## Gas Optimization Strategies

### 1. Batch Transactions

Instead of sending multiple transactions, batch them when possible:

```swift theme={"system"}
/// Example: Batch multiple token approvals
func batchApprovals(
    wallet: BaseWallet,
    tokenAddress: String,
    spenders: [(address: String, amount: String)]
) async throws {
    // Use a multicall contract to batch approvals
    // This saves gas compared to individual transactions
}
```

### 2. Choose Optimal Gas Prices

```swift theme={"system"}
struct GasStrategy {
    /// Low priority: Base fee + minimal tip
    static func slow(baseFee: Int) -> EIP1559Gas {
        EIP1559Gas(
            baseFeePerGas: baseFee,
            maxPriorityFeePerGas: 1_000_000_000, // 1 Gwei
            maxFeePerGas: baseFee + 1_000_000_000
        )
    }

    /// Medium priority: Base fee + standard tip
    static func standard(baseFee: Int) -> EIP1559Gas {
        let priorityFee = baseFee / 2
        EIP1559Gas(
            baseFeePerGas: baseFee,
            maxPriorityFeePerGas: priorityFee,
            maxFeePerGas: baseFee * 2 + priorityFee
        )
    }

    /// High priority: Base fee + high tip
    static func fast(baseFee: Int) -> EIP1559Gas {
        let priorityFee = baseFee
        EIP1559Gas(
            baseFeePerGas: baseFee,
            maxPriorityFeePerGas: priorityFee,
            maxFeePerGas: baseFee * 3 + priorityFee
        )
    }
}

// Usage
let client = sdk.evm.createPublicClient(chainId: 1)
let gasPrice = try await client.getGasPrice()
let baseFee = Int(gasPrice.value)

// Choose strategy based on urgency
let gas = GasStrategy.fast(baseFee: baseFee)
```

### 3. Monitor and Adjust Gas

```swift theme={"system"}
@MainActor
class GasMonitor: ObservableObject {
    @Published var currentGasPrice: Int?
    @Published var recommendation: String?

    private let sdk = DynamicSDK.instance()
    private let chainId: Int

    init(chainId: Int) {
        self.chainId = chainId
    }

    func updateGasPrice() async {
        do {
            let client = sdk.evm.createPublicClient(chainId: chainId)
            let gasPrice = try await client.getGasPrice()
            let priceGwei = Double(gasPrice.value) / 1_000_000_000

            currentGasPrice = Int(gasPrice.value)

            // Provide recommendations
            if priceGwei < 20 {
                recommendation = "Low gas prices - good time to transact"
            } else if priceGwei < 50 {
                recommendation = "Moderate gas prices"
            } else {
                recommendation = "High gas prices - consider waiting"
            }
        } catch {
            print("Failed to update gas price: \(error)")
        }
    }
}
```

## Gas Cost Calculator

Calculate the total cost of a transaction:

```swift theme={"system"}
struct GasCostCalculator {
    /// Calculate transaction cost in Wei
    static func calculateCost(
        gasLimit: Int,
        maxFeePerGas: Int
    ) -> Int {
        return gasLimit * maxFeePerGas
    }

    /// Calculate transaction cost in ETH
    static func calculateCostInETH(
        gasLimit: Int,
        maxFeePerGas: Int
    ) -> Double {
        let costWei = calculateCost(
            gasLimit: gasLimit,
            maxFeePerGas: maxFeePerGas
        )
        return Double(costWei) / 1_000_000_000_000_000_000
    }

    /// Calculate transaction cost in USD (given ETH price)
    static func calculateCostInUSD(
        gasLimit: Int,
        maxFeePerGas: Int,
        ethPriceUSD: Double
    ) -> Double {
        let costETH = calculateCostInETH(
            gasLimit: gasLimit,
            maxFeePerGas: maxFeePerGas
        )
        return costETH * ethPriceUSD
    }
}

// Usage
let gasLimit = 21_000
let maxFeePerGas = 50_000_000_000 // 50 Gwei

let costETH = GasCostCalculator.calculateCostInETH(
    gasLimit: gasLimit,
    maxFeePerGas: maxFeePerGas
)
print("Transaction cost: \(costETH) ETH")

let costUSD = GasCostCalculator.calculateCostInUSD(
    gasLimit: gasLimit,
    maxFeePerGas: maxFeePerGas,
    ethPriceUSD: 2000
)
print("Transaction cost: $\(costUSD) USD")
```

## Gas Price Display Component

```swift theme={"system"}
import SwiftUI

struct GasPriceView: View {
    @StateObject private var monitor: GasMonitor

    init(chainId: Int) {
        _monitor = StateObject(wrappedValue: GasMonitor(chainId: chainId))
    }

    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            HStack {
                Text("Gas Price")
                    .font(.headline)

                Spacer()

                Button {
                    Task { await monitor.updateGasPrice() }
                } label: {
                    Image(systemName: "arrow.clockwise")
                }
            }

            if let gasPrice = monitor.currentGasPrice {
                let priceGwei = Double(gasPrice) / 1_000_000_000

                HStack {
                    Text("\(String(format: "%.2f", priceGwei)) Gwei")
                        .font(.title2)
                        .fontWeight(.bold)

                    if priceGwei < 20 {
                        Image(systemName: "checkmark.circle.fill")
                            .foregroundColor(.green)
                    } else if priceGwei < 50 {
                        Image(systemName: "exclamationmark.circle.fill")
                            .foregroundColor(.orange)
                    } else {
                        Image(systemName: "xmark.circle.fill")
                            .foregroundColor(.red)
                    }
                }

                if let recommendation = monitor.recommendation {
                    Text(recommendation)
                        .font(.caption)
                        .foregroundColor(.secondary)
                }
            } else {
                ProgressView()
            }
        }
        .padding()
        .background(Color(.systemGray6))
        .cornerRadius(8)
        .onAppear {
            Task { await monitor.updateGasPrice() }
        }
    }
}
```

## Chain-Specific Gas Considerations

### Ethereum Mainnet

* **Base fee**: Highly variable (10-100+ Gwei)
* **Priority fee**: 1-5 Gwei typically
* **Peak times**: Weekdays during US/EU business hours

### Layer 2 Solutions

* **Optimism/Arbitrum**: \~0.001-0.01 Gwei
* **Polygon**: \~30-100 Gwei
* **Base**: \~0.001-0.01 Gwei

```swift theme={"system"}
struct ChainGasDefaults {
    static func getDefaults(for chainId: Int) -> (gasLimit: Int, priorityFee: Int) {
        switch chainId {
        case 1: // Ethereum
            return (21_000, 2_000_000_000) // 2 Gwei priority

        case 137: // Polygon
            return (21_000, 30_000_000_000) // 30 Gwei priority

        case 10, 8453: // Optimism, Base
            return (21_000, 1_000_000) // 0.001 Gwei priority

        case 42161: // Arbitrum
            return (21_000, 1_000_000) // 0.001 Gwei priority

        default:
            return (21_000, 1_000_000_000) // 1 Gwei default
        }
    }
}
```

## Best Practices

### 1. Always Add a Buffer

```swift theme={"system"}
// Add 10-20% buffer to gas estimates
let estimatedGas = try await estimateGas(for: transaction, chainId: chainId)
let gasWithBuffer = Int(Double(estimatedGas) * 1.2)
```

### 2. Set Reasonable Max Fees

```swift theme={"system"}
// Don't set maxFeePerGas too low, or transaction may fail
let baseFee = try await client.getGasPrice()
let maxFee = Int(baseFee.value) * 2 // At least 2x base fee
```

### 3. Monitor Gas Prices

```swift theme={"system"}
// Check gas prices before important transactions
let gasPrice = try await client.getGasPrice()
let priceGwei = Double(gasPrice.value) / 1_000_000_000

if priceGwei > 100 {
    showAlert("Gas prices are high. Consider waiting.")
}
```

### 4. Handle Gas Errors

```swift theme={"system"}
do {
    let txHash = try await sdk.evm.sendTransaction(
        transaction: transaction,
        wallet: wallet
    )
} catch {
    if error.localizedDescription.contains("gas") {
        // Gas estimation failed - try increasing gas limit
        print("Consider increasing gas limit")
    }
}
```

## Next Steps

* [Send ETH Transactions](/swift/wallets/evm/send-eth) - Apply gas management to ETH transfers
* [ERC-20 Token Transfers](/swift/wallets/evm/erc20-transfers) - Optimize token transfer costs
* [Smart Contract Interactions](/swift/wallets/evm/smart-contracts) - Estimate gas for contract calls
* [Networks](/swift/wallets/general/network-management) - Understand different network gas costs
