Overview

This guide covers sending transactions and managing network connections with the Dynamic Swift SDK.

Prerequisites

Transaction Management

Send ETH Transaction

// Transaction parameters
let amount = BigUInt(10000000000000000) // 0.01 ETH in wei
let recipient = EthereumAddress("0xd4f748199B91c22095150d2d4Cca3Fe6175B0CbA")
let chainId = SupportedEthereumNetwork.sepoliaTestnet.chainConfig.chainId

do {
    // Get network client for Sepolia
    let networkClient: BaseEthereumClient = try await ethereumWallet.getNetworkClient(for: chainId)

    // Get current gas price and set gas limit
    let gasPrice = try await networkClient.eth_gasPriceBigInt()
    let gasLimit = BigUInt(21_000) // Standard ETH transfer

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

    // Send transaction
    let txHash = try await ethereumWallet.sendTransaction(transaction)

    print("✅ Transaction sent!")
    print("🔗 Transaction Hash: \(txHash)")

    // Get network details for block explorer URL
    if let supportedNetwork = SupportedEthereumNetwork.fromChainId(chainId) {
        let networkConfig = supportedNetwork.chainConfig
        if let explorerUrl = networkConfig.blockExplorerUrls.first {
            print("🔍 View on \(networkConfig.name): \(explorerUrl)/tx/\(txHash)")
        }
    }
} catch {
    print("❌ Transaction failed: \(error)")
}

Create Transaction

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
)

Send Transaction

do {
    let txHash = try await ethereumWallet.sendTransaction(transaction)
    print("Transaction Hash: \(txHash)")
    
    // Get network details for block explorer URL
    if let supportedNetwork = SupportedEthereumNetwork.fromChainId(chainId) {
        let networkConfig = supportedNetwork.chainConfig
        if let explorerUrl = networkConfig.blockExplorerUrls.first {
            print("🔍 View on \(networkConfig.name): \(explorerUrl)/tx/\(txHash)")
        }
    }
} catch {
    print("Transaction failed: \(error)")
}

Sign Transaction

do {
    let signedTransaction = try await ethereumWallet.sign(transaction: transaction)
    print("Transaction signed successfully")
    print("Signature: \(signedTransaction)")
} catch {
    print("Failed to sign transaction: \(error)")
}

Network Management

Switch Networks

// Switch to Sepolia testnet
let sepoliaNetwork = SupportedEthereumNetwork.sepoliaTestnet.chainConfig

do {
    try await ethereumWallet.switchNetwork(to: sepoliaNetwork)
    print("🌐 Switched to Ethereum Sepolia")
} catch {
    print("❌ Failed to switch to Sepolia: \(error)")
}

Get Network Client

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)")
}

Error Handling

Common Transaction Errors

do {
    let txHash = try await ethereumWallet.sendTransaction(transaction)
} catch {
    if let nsError = error as NSError? {
        switch nsError.code {
        case 2001:
            print("Insufficient balance for transaction")
        case 2002:
            print("Invalid transaction parameters")
        case 2003:
            print("Network connection failed")
        case 2004:
            print("Gas price too low")
        default:
            print("Transaction error: \(error)")
        }
    }
}

Best Practices

1. Network Switching

Always switch to the desired network before performing operations:
// Switch to Sepolia first
let sepoliaNetwork = SupportedEthereumNetwork.sepoliaTestnet.chainConfig
try await wallet.switchNetwork(to: sepoliaNetwork)

// Then perform operations
let balance = try await wallet.getBalance(.Latest)

2. Explorer URL Generation

Generate dynamic block explorer URLs for transaction tracking:
let txHash = try await ethereumWallet.sendTransaction(transaction)
print("✅ Transaction sent!")
print("🔗 Transaction Hash: \(txHash)")

// Get network details for block explorer URL
if let supportedNetwork = SupportedEthereumNetwork.fromChainId(chainId) {
    let networkConfig = supportedNetwork.chainConfig
    if let explorerUrl = networkConfig.blockExplorerUrls.first {
        print("🔍 View on \(networkConfig.name): \(explorerUrl)/tx/\(txHash)")
    }
}

3. Gas Management

// 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)

Next Steps

After mastering transactions, you can: