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

## Overview

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

## Prerequisites

* Dynamic SDK initialized (see [Installation Guide](/flutter/quickstart))
* Basic understanding of [EVM transactions](/flutter/wallets/evm/send-eth)
* `dynamic_sdk_web3dart` package installed

## Get Current Gas Price

Fetch the current gas price from the network:

```dart theme={"system"}
import 'package:dynamic_sdk/dynamic_sdk.dart';
import 'package:dynamic_sdk_web3dart/dynamic_sdk_web3dart.dart';
import 'package:web3dart/web3dart.dart';

final sdk = DynamicSDK.instance;

Future<BigInt?> getGasPrice(int chainId) async {
  try {
    final client = sdk.web3dart.createPublicClient(chainId: chainId);
    final gasPrice = await client.getGasPrice();
    return gasPrice.getValueInUnitBI(EtherUnit.wei);
  } catch (e) {
    print('Failed to get gas price: $e');
    return null;
  }
}
```

## Standard Gas Limits

Use these standard gas limits for common transaction types:

```dart theme={"system"}
/// Common gas limits for different transaction types
class GasLimits {
  /// Standard ETH transfer: 21,000 gas
  static const int ethTransfer = 21000;

  /// ERC-20 token transfer: 65,000 gas
  static const int erc20Transfer = 65000;

  /// ERC-20 approve: 50,000 gas
  static const int erc20Approve = 50000;

  /// Contract deployment: 500,000+ gas (varies by contract)
  static const int contractDeploy = 500000;

  /// Contract function call: 100,000 gas (estimate first)
  static const int contractCall = 100000;

  /// NFT minting: 150,000 gas (varies by contract)
  static const int nftMint = 150000;
}

// Usage
final transaction = Transaction(
  from: EthereumAddress.fromHex(wallet.address),
  to: EthereumAddress.fromHex(recipientAddress),
  value: EtherAmount.inWei(BigInt.from(amountInWei)),
  gasPrice: EtherAmount.inWei(gasPrice),
  maxGas: GasLimits.ethTransfer,
);
```

## EIP-1559 Gas Pricing

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

### Understanding EIP-1559 Parameters

```dart theme={"system"}
class EIP1559Gas {
  /// Base fee: Algorithmically determined by the network
  /// This is burned and adjusts based on network congestion
  final BigInt baseFeePerGas;

  /// Priority fee (tip): Goes to the miner/validator
  /// Higher tips get faster inclusion
  final BigInt maxPriorityFeePerGas;

  /// Max fee: Maximum you're willing to pay per gas
  /// Should be: baseFee + maxPriorityFee + buffer
  final BigInt maxFeePerGas;

  EIP1559Gas({
    required this.baseFeePerGas,
    required this.maxPriorityFeePerGas,
    required this.maxFeePerGas,
  });
}
```

### Setting Gas Prices

```dart theme={"system"}
Future<EIP1559Gas> calculateGasPrices(int chainId) async {
  final client = sdk.web3dart.createPublicClient(chainId: chainId);

  // Get current base fee
  final gasPrice = await client.getGasPrice();
  final baseFee = gasPrice.getValueInUnitBI(EtherUnit.wei);

  // Set priority fee (tip)
  final priorityFee = baseFee ~/ BigInt.from(2); // Typically 50% of base fee

  // Set max fee (with 2x buffer for volatility)
  final maxFee = baseFee * BigInt.from(2) + priorityFee;

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

// Usage
final gasPrices = await calculateGasPrices(1);

final transaction = Transaction(
  from: EthereumAddress.fromHex(wallet.address),
  to: EthereumAddress.fromHex(recipient),
  value: EtherAmount.inWei(BigInt.from(amount)),
  maxGas: 21000,
  maxFeePerGas: EtherAmount.inWei(gasPrices.maxFeePerGas),
  maxPriorityFeePerGas: EtherAmount.inWei(gasPrices.maxPriorityFeePerGas),
);
```

## Gas Optimization Strategies

### Choose Optimal Gas Prices

```dart theme={"system"}
class GasStrategy {
  /// Low priority: Base fee + minimal tip
  static EIP1559Gas slow(BigInt baseFee) {
    return EIP1559Gas(
      baseFeePerGas: baseFee,
      maxPriorityFeePerGas: BigInt.from(1000000000), // 1 Gwei
      maxFeePerGas: baseFee + BigInt.from(1000000000),
    );
  }

  /// Medium priority: Base fee + standard tip
  static EIP1559Gas standard(BigInt baseFee) {
    final priorityFee = baseFee ~/ BigInt.from(2);
    return EIP1559Gas(
      baseFeePerGas: baseFee,
      maxPriorityFeePerGas: priorityFee,
      maxFeePerGas: baseFee * BigInt.from(2) + priorityFee,
    );
  }

  /// High priority: Base fee + high tip
  static EIP1559Gas fast(BigInt baseFee) {
    final priorityFee = baseFee;
    return EIP1559Gas(
      baseFeePerGas: baseFee,
      maxPriorityFeePerGas: priorityFee,
      maxFeePerGas: baseFee * BigInt.from(3) + priorityFee,
    );
  }
}

// Usage
final client = sdk.web3dart.createPublicClient(chainId: 1);
final gasPrice = await client.getGasPrice();
final baseFee = gasPrice.getValueInUnitBI(EtherUnit.wei);

// Choose strategy based on urgency
final gas = GasStrategy.fast(baseFee);
```

## Gas Cost Calculator

Calculate the total cost of a transaction:

```dart theme={"system"}
class GasCostCalculator {
  /// Calculate transaction cost in Wei
  static BigInt calculateCost({
    required int gasLimit,
    required BigInt maxFeePerGas,
  }) {
    return BigInt.from(gasLimit) * maxFeePerGas;
  }

  /// Calculate transaction cost in ETH
  static double calculateCostInETH({
    required int gasLimit,
    required BigInt maxFeePerGas,
  }) {
    final costWei = calculateCost(
      gasLimit: gasLimit,
      maxFeePerGas: maxFeePerGas,
    );
    return costWei.toDouble() / 1e18;
  }

  /// Calculate transaction cost in USD (given ETH price)
  static double calculateCostInUSD({
    required int gasLimit,
    required BigInt maxFeePerGas,
    required double ethPriceUSD,
  }) {
    final costETH = calculateCostInETH(
      gasLimit: gasLimit,
      maxFeePerGas: maxFeePerGas,
    );
    return costETH * ethPriceUSD;
  }
}

// Usage
final gasLimit = 21000;
final maxFeePerGas = BigInt.from(50000000000); // 50 Gwei

final costETH = GasCostCalculator.calculateCostInETH(
  gasLimit: gasLimit,
  maxFeePerGas: maxFeePerGas,
);
print('Transaction cost: $costETH ETH');

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

## Gas Price Display Widget

```dart theme={"system"}
import 'package:flutter/material.dart';
import 'package:dynamic_sdk/dynamic_sdk.dart';
import 'package:dynamic_sdk_web3dart/dynamic_sdk_web3dart.dart';
import 'package:web3dart/web3dart.dart';

class GasPriceWidget extends StatefulWidget {
  final int chainId;

  const GasPriceWidget({Key? key, required this.chainId}) : super(key: key);

  @override
  State<GasPriceWidget> createState() => _GasPriceWidgetState();
}

class _GasPriceWidgetState extends State<GasPriceWidget> {
  final sdk = DynamicSDK.instance;
  BigInt? currentGasPrice;
  String? recommendation;

  @override
  void initState() {
    super.initState();
    _updateGasPrice();
  }

  Future<void> _updateGasPrice() async {
    try {
      final client = sdk.web3dart.createPublicClient(chainId: widget.chainId);
      final gasPrice = await client.getGasPrice();
      final priceWei = gasPrice.getValueInUnitBI(EtherUnit.wei);
      final priceGwei = priceWei.toDouble() / 1e9;

      setState(() {
        currentGasPrice = priceWei;

        // 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 (e) {
      print('Failed to update gas price: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    final priceGwei = currentGasPrice != null
        ? (currentGasPrice!.toDouble() / 1e9)
        : null;

    return Container(
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: Colors.grey[200],
        borderRadius: BorderRadius.circular(8),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              const Text(
                'Gas Price',
                style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
              ),
              const Spacer(),
              IconButton(
                icon: const Icon(Icons.refresh),
                onPressed: _updateGasPrice,
              ),
            ],
          ),
          const SizedBox(height: 8),
          if (priceGwei != null) ...[
            Row(
              children: [
                Text(
                  '${priceGwei.toStringAsFixed(2)} Gwei',
                  style: const TextStyle(
                    fontSize: 24,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                const SizedBox(width: 8),
                if (priceGwei < 20)
                  const Icon(Icons.check_circle, color: Colors.green)
                else if (priceGwei < 50)
                  const Icon(Icons.warning, color: Colors.orange)
                else
                  const Icon(Icons.error, color: Colors.red),
              ],
            ),
            if (recommendation != null) ...[
              const SizedBox(height: 4),
              Text(
                recommendation!,
                style: const TextStyle(fontSize: 12, color: Colors.grey),
              ),
            ],
          ] else
            const CircularProgressIndicator(),
        ],
      ),
    );
  }
}
```

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

```dart theme={"system"}
class ChainGasDefaults {
  static Map<String, int> getDefaults(int chainId) {
    switch (chainId) {
      case 1: // Ethereum
        return {'gasLimit': 21000, 'priorityFee': 2000000000}; // 2 Gwei

      case 137: // Polygon
        return {'gasLimit': 21000, 'priorityFee': 30000000000}; // 30 Gwei

      case 10: // Optimism
      case 8453: // Base
        return {'gasLimit': 21000, 'priorityFee': 1000000}; // 0.001 Gwei

      case 42161: // Arbitrum
        return {'gasLimit': 21000, 'priorityFee': 1000000}; // 0.001 Gwei

      default:
        return {'gasLimit': 21000, 'priorityFee': 1000000000}; // 1 Gwei
    }
  }
}
```

## Best Practices

### 1. Always Add a Buffer

```dart theme={"system"}
// Add 10-20% buffer to gas estimates
int addGasBuffer(int estimatedGas, {double bufferPercentage = 20}) {
  return (estimatedGas * (1 + bufferPercentage / 100)).toInt();
}

// Usage
final gasWithBuffer = addGasBuffer(21000, bufferPercentage: 20);
```

### 2. Set Reasonable Max Fees

```dart theme={"system"}
// Don't set maxFeePerGas too low, or transaction may fail
Future<BigInt> calculateSafeMaxFee(int chainId) async {
  final client = sdk.web3dart.createPublicClient(chainId: chainId);
  final gasPrice = await client.getGasPrice();
  final baseFee = gasPrice.getValueInUnitBI(EtherUnit.wei);
  return baseFee * BigInt.from(2); // At least 2x base fee
}
```

### 3. Monitor Gas Prices

```dart theme={"system"}
Future<bool> shouldWaitForBetterGas(int chainId, {double thresholdGwei = 100}) async {
  try {
    final client = sdk.web3dart.createPublicClient(chainId: chainId);
    final gasPrice = await client.getGasPrice();
    final priceGwei = gasPrice.getValueInUnitBI(EtherUnit.wei).toDouble() / 1e9;

    if (priceGwei > thresholdGwei) {
      print('Gas prices are high ($priceGwei Gwei). Consider waiting.');
      return true;
    }
    return false;
  } catch (e) {
    print('Failed to check gas price: $e');
    return false;
  }
}
```

### 4. Handle Gas Errors

```dart theme={"system"}
Future<String?> sendTransactionWithGasHandling({
  required BaseWallet wallet,
  required Transaction transaction,
}) async {
  try {
    return await DynamicSDK.instance.web3dart.sendTransaction(
      transaction: transaction,
      wallet: wallet,
    );
  } catch (e) {
    if (e.toString().contains('gas')) {
      print('Gas estimation failed - try increasing gas limit');
    }
    return null;
  }
}
```

## Next Steps

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