Skip to content

Blockchain Tools

Learn how to use Hybrid's built-in blockchain tools for crypto operations, DeFi interactions, and multi-chain support.

Installing and Importing

Installation

Blockchain tools are included with the core Hybrid framework:

npm install @hybrd/core

Importing Blockchain Tools

// Import from core (recommended)
import { blockchainTools } from "@hybrd/core/tools"
 
// Import specific tools
import { 
  getBalance, 
  sendTransaction, 
  getTransaction,
  getBlock,
  getGasPrice,
  estimateGas 
} from "@hybrd/core/tools"
 
// Add to agent
import { Agent } from "@hybrd/core"
 
const agent = new Agent({
  model: yourModel,
  instructions: "Your agent instructions...",
  tools: [
    blockchainTools(), // Adds all blockchain tools
  ]
})

Core Blockchain Tools

getBalance - Get Native Token Balance

Check native token balances for any address across supported chains.

Basic Usage

// Agent can use this tool automatically
const balance = await agent.call("getBalance", {
  address: "0x1234567890abcdef1234567890abcdef12345678"
})
 
console.log(`ETH Balance: ${balance.formatted} ETH`)

Multi-Chain Balance Checking

// Check balance on specific chain
const polygonBalance = await agent.call("getBalance", {
  address: "0x1234567890abcdef1234567890abcdef12345678",
  chain: "polygon"
})
 
// Check balances across multiple chains
const chains = ["ethereum", "polygon", "arbitrum", "optimism", "base"]
const balances = await Promise.all(
  chains.map(chain => 
    agent.call("getBalance", { address: userAddress, chain })
  )
)
 
const totalValue = balances.reduce((sum, balance) => 
  sum + (balance.usdValue || 0), 0
)

Balance Monitoring

// Monitor balance changes
class BalanceMonitor {
  private lastBalances = new Map<string, number>()
  
  async checkBalanceChanges(address: string) {
    const currentBalance = await agent.call("getBalance", { address })
    const lastBalance = this.lastBalances.get(address) || 0
    
    if (currentBalance.value !== lastBalance) {
      const change = currentBalance.value - lastBalance
      const changeFormatted = change > 0 ? `+${change}` : `${change}`
      
      await agent.call("sendMessage", {
        to: address,
        content: `💰 Balance Update: ${changeFormatted} ETH\nNew Balance: ${currentBalance.formatted} ETH`
      })
      
      this.lastBalances.set(address, currentBalance.value)
    }
  }
}

sendTransaction - Send Native Tokens

Send native tokens (ETH, MATIC, etc.) to other addresses.

Basic Transaction

// Send ETH to another address
const txResult = await agent.call("sendTransaction", {
  to: "0x1234567890abcdef1234567890abcdef12345678",
  amount: "0.1", // 0.1 ETH
  chain: "ethereum"
})
 
console.log(`Transaction sent: ${txResult.hash}`)

Transaction with Gas Configuration

// Send with custom gas settings
const txResult = await agent.call("sendTransaction", {
  to: recipientAddress,
  amount: "0.05",
  chain: "ethereum",
  gasLimit: 21000,
  gasPrice: "20000000000", // 20 gwei
  priority: "fast" // or "standard", "slow"
})

Batch Transactions

// Send to multiple recipients
const recipients = [
  { address: "0x1111...", amount: "0.1" },
  { address: "0x2222...", amount: "0.2" },
  { address: "0x3333...", amount: "0.15" }
]
 
const transactions = await Promise.all(
  recipients.map(({ address, amount }) =>
    agent.call("sendTransaction", {
      to: address,
      amount,
      chain: "ethereum"
    })
  )
)
 
console.log(`Sent ${transactions.length} transactions`)

getTransaction - Get Transaction Details

Retrieve detailed information about transactions by hash.

Basic Transaction Lookup

// Get transaction details
const txDetails = await agent.call("getTransaction", {
  hash: "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
  chain: "ethereum"
})
 
console.log(`Status: ${txDetails.status}`)
console.log(`Gas Used: ${txDetails.gasUsed}`)
console.log(`Block: ${txDetails.blockNumber}`)

Transaction Analysis

// Analyze transaction for insights
async function analyzeTransaction(txHash: string) {
  const tx = await agent.call("getTransaction", { hash: txHash })
  
  const analysis = {
    efficiency: calculateGasEfficiency(tx),
    timing: analyzeTransactionTiming(tx),
    cost: calculateTransactionCost(tx),
    success: tx.status === "success"
  }
  
  return {
    transaction: tx,
    analysis,
    recommendations: generateRecommendations(analysis)
  }
}
 
function calculateGasEfficiency(tx: any) {
  const efficiency = tx.gasUsed / tx.gasLimit
  return {
    ratio: efficiency,
    rating: efficiency < 0.7 ? "efficient" : efficiency < 0.9 ? "moderate" : "inefficient"
  }
}

getBlock - Get Blockchain Block Information

Retrieve information about specific blocks.

Block Information

// Get latest block
const latestBlock = await agent.call("getBlock", {
  blockNumber: "latest",
  chain: "ethereum"
})
 
// Get specific block
const block = await agent.call("getBlock", {
  blockNumber: 18500000,
  chain: "ethereum"
})
 
console.log(`Block ${block.number} has ${block.transactions.length} transactions`)

Block Analysis

// Analyze block for network insights
async function analyzeNetworkActivity() {
  const latestBlock = await agent.call("getBlock", { 
    blockNumber: "latest",
    chain: "ethereum" 
  })
  
  const previousBlock = await agent.call("getBlock", { 
    blockNumber: latestBlock.number - 1,
    chain: "ethereum" 
  })
  
  const blockTime = latestBlock.timestamp - previousBlock.timestamp
  const gasUtilization = latestBlock.gasUsed / latestBlock.gasLimit
  
  return {
    blockTime,
    gasUtilization,
    transactionCount: latestBlock.transactions.length,
    networkCongestion: gasUtilization > 0.9 ? "high" : gasUtilization > 0.7 ? "medium" : "low"
  }
}

getGasPrice - Get Current Gas Prices

Get current gas prices for optimal transaction timing.

Current Gas Prices

// Get current gas prices
const gasPrices = await agent.call("getGasPrice", {
  chain: "ethereum"
})
 
console.log(`Standard: ${gasPrices.standard} gwei`)
console.log(`Fast: ${gasPrices.fast} gwei`)
console.log(`Instant: ${gasPrices.instant} gwei`)

Gas Price Recommendations

// Get gas recommendations based on urgency
async function getGasRecommendation(urgency: "low" | "medium" | "high") {
  const gasPrices = await agent.call("getGasPrice", { chain: "ethereum" })
  
  switch (urgency) {
    case "low":
      return {
        gasPrice: gasPrices.slow,
        estimatedTime: "10-30 minutes",
        cost: "lowest"
      }
    case "medium":
      return {
        gasPrice: gasPrices.standard,
        estimatedTime: "3-5 minutes",
        cost: "moderate"
      }
    case "high":
      return {
        gasPrice: gasPrices.fast,
        estimatedTime: "< 2 minutes",
        cost: "higher"
      }
  }
}

estimateGas - Estimate Gas Costs

Estimate gas costs for transactions before execution.

Basic Gas Estimation

// Estimate gas for a transaction
const gasEstimate = await agent.call("estimateGas", {
  to: "0x1234567890abcdef1234567890abcdef12345678",
  amount: "0.1",
  chain: "ethereum"
})
 
console.log(`Estimated gas: ${gasEstimate.gasLimit}`)
console.log(`Estimated cost: ${gasEstimate.estimatedCost} ETH`)

Smart Contract Interaction Estimation

// Estimate gas for smart contract calls
const contractEstimate = await agent.call("estimateGas", {
  to: "0xA0b86a33E6441e6e80A7181a02d6b8c4c7e3c0d1", // Contract address
  data: "0xa9059cbb000000000000000000000000...", // Encoded function call
  chain: "ethereum"
})

Tool Configuration and Runtime Context

Basic Configuration

// Configure blockchain tools
const agent = new Agent({
  tools: [
    blockchainTools({
      // Default chain
      defaultChain: "ethereum",
      
      // Supported chains
      chains: ["ethereum", "polygon", "arbitrum", "optimism", "base"],
      
      // Gas settings
      gas: {
        maxGasPrice: "50000000000", // 50 gwei max
        gasMultiplier: 1.1, // 10% buffer
        priorityFee: "2000000000" // 2 gwei priority fee
      },
      
      // RPC endpoints (optional - uses defaults)
      rpcUrls: {
        ethereum: process.env.ETHEREUM_RPC_URL,
        polygon: process.env.POLYGON_RPC_URL
      }
    })
  ]
})

Advanced Configuration

// Advanced blockchain tool configuration
const blockchainConfig = {
  // Network settings
  networks: {
    ethereum: {
      chainId: 1,
      rpcUrl: process.env.ETHEREUM_RPC_URL,
      gasSettings: {
        maxGasPrice: "100000000000", // 100 gwei
        priorityFee: "2000000000" // 2 gwei
      }
    },
    polygon: {
      chainId: 137,
      rpcUrl: process.env.POLYGON_RPC_URL,
      gasSettings: {
        maxGasPrice: "500000000000", // 500 gwei (MATIC)
        priorityFee: "30000000000" // 30 gwei
      }
    }
  },
  
  // Security settings
  security: {
    maxTransactionValue: "10", // 10 ETH max per transaction
    requireConfirmation: true,
    allowedContracts: [
      "0xA0b86a33E6441e6e80A7181a02d6b8c4c7e3c0d1" // Uniswap V3
    ]
  },
  
  // Monitoring
  monitoring: {
    trackTransactions: true,
    alertOnFailure: true,
    logGasUsage: true
  }
}
 
const agent = new Agent({
  tools: [blockchainTools(blockchainConfig)]
})

Runtime Context Integration

// Use runtime context for dynamic configuration
class ContextAwareBlockchainTools {
  static create(baseConfig: any) {
    return blockchainTools({
      ...baseConfig,
      
      // Dynamic gas pricing based on context
      getGasSettings: (context: any) => {
        const urgency = context.urgency || "medium"
        const userTier = context.user?.tier || "standard"
        
        const gasMultipliers = {
          low: 1.0,
          medium: 1.1,
          high: 1.3,
          urgent: 1.5
        }
        
        const maxGasPrices = {
          standard: "50000000000", // 50 gwei
          premium: "100000000000", // 100 gwei
          enterprise: "200000000000" // 200 gwei
        }
        
        return {
          gasMultiplier: gasMultipliers[urgency],
          maxGasPrice: maxGasPrices[userTier]
        }
      },
      
      // Dynamic chain selection
      selectChain: (context: any) => {
        const preferredChain = context.user?.preferredChain
        const transactionSize = context.transaction?.value || 0
        
        // Use L2 for small transactions
        if (transactionSize < 0.01) {
          return preferredChain || "polygon"
        }
        
        // Use mainnet for large transactions
        return "ethereum"
      }
    })
  }
}

Supported Chains

Hybrid supports multiple blockchain networks for maximum flexibility.

Ethereum Mainnet

// Ethereum configuration
const ethereumConfig = {
  chain: "ethereum",
  chainId: 1,
  nativeCurrency: "ETH",
  blockExplorer: "https://etherscan.io",
  features: [
    "full-defi-ecosystem",
    "highest-liquidity",
    "most-secure",
    "highest-gas-costs"
  ]
}
 
// Ethereum-specific operations
const ethBalance = await agent.call("getBalance", {
  address: userAddress,
  chain: "ethereum"
})

Polygon

// Polygon configuration
const polygonConfig = {
  chain: "polygon",
  chainId: 137,
  nativeCurrency: "MATIC",
  blockExplorer: "https://polygonscan.com",
  features: [
    "low-gas-costs",
    "fast-transactions",
    "ethereum-compatible",
    "growing-ecosystem"
  ]
}
 
// Polygon operations
const maticBalance = await agent.call("getBalance", {
  address: userAddress,
  chain: "polygon"
})

Arbitrum

// Arbitrum configuration
const arbitrumConfig = {
  chain: "arbitrum",
  chainId: 42161,
  nativeCurrency: "ETH",
  blockExplorer: "https://arbiscan.io",
  features: [
    "ethereum-l2",
    "low-gas-costs",
    "fast-finality",
    "optimistic-rollup"
  ]
}

Optimism

// Optimism configuration
const optimismConfig = {
  chain: "optimism",
  chainId: 10,
  nativeCurrency: "ETH",
  blockExplorer: "https://optimistic.etherscan.io",
  features: [
    "ethereum-l2",
    "low-gas-costs",
    "fast-transactions",
    "optimistic-rollup"
  ]
}

Base

// Base configuration
const baseConfig = {
  chain: "base",
  chainId: 8453,
  nativeCurrency: "ETH",
  blockExplorer: "https://basescan.org",
  features: [
    "coinbase-l2",
    "low-gas-costs",
    "fast-transactions",
    "growing-ecosystem"
  ]
}

Sepolia Testnet

// Sepolia testnet for development
const sepoliaConfig = {
  chain: "sepolia",
  chainId: 11155111,
  nativeCurrency: "ETH",
  blockExplorer: "https://sepolia.etherscan.io",
  features: [
    "ethereum-testnet",
    "free-test-eth",
    "development-friendly",
    "latest-ethereum-features"
  ]
}
 
// Use for testing
const testBalance = await agent.call("getBalance", {
  address: testAddress,
  chain: "sepolia"
})

Multi-Chain Operations

// Cross-chain balance aggregation
async function getMultiChainBalance(address: string) {
  const chains = ["ethereum", "polygon", "arbitrum", "optimism", "base"]
  
  const balances = await Promise.all(
    chains.map(async (chain) => {
      try {
        const balance = await agent.call("getBalance", { address, chain })
        return { chain, ...balance }
      } catch (error) {
        console.warn(`Failed to get balance on ${chain}:`, error)
        return { chain, value: 0, formatted: "0", error: error.message }
      }
    })
  )
  
  const totalValue = balances
    .filter(b => !b.error)
    .reduce((sum, balance) => sum + (balance.usdValue || 0), 0)
  
  return {
    balances,
    totalValue,
    summary: `Total portfolio value: ${totalValue.toLocaleString()}`
  }
}
 
// Cross-chain transaction routing
async function findOptimalChain(operation: string, amount: number) {
  const gasPrices = await Promise.all([
    agent.call("getGasPrice", { chain: "ethereum" }),
    agent.call("getGasPrice", { chain: "polygon" }),
    agent.call("getGasPrice", { chain: "arbitrum" })
  ])
  
  // Calculate costs for each chain
  const costs = gasPrices.map((gas, index) => {
    const chains = ["ethereum", "polygon", "arbitrum"]
    const gasLimit = operation === "transfer" ? 21000 : 100000
    
    return {
      chain: chains[index],
      gasCost: gas.standard * gasLimit,
      totalCost: (gas.standard * gasLimit) + amount
    }
  })
  
  // Return cheapest option
  return costs.reduce((min, current) => 
    current.totalCost < min.totalCost ? current : min
  )
}

Error Handling and Best Practices

Transaction Error Handling

// Robust transaction handling
async function sendTransactionSafely(params: any) {
  try {
    // Pre-flight checks
    await validateTransaction(params)
    
    // Estimate gas first
    const gasEstimate = await agent.call("estimateGas", params)
    
    // Check if user has sufficient balance
    const balance = await agent.call("getBalance", {
      address: params.from,
      chain: params.chain
    })
    
    const totalCost = parseFloat(params.amount) + gasEstimate.estimatedCost
    if (balance.value < totalCost) {
      throw new Error(`Insufficient balance. Need ${totalCost}, have ${balance.value}`)
    }
    
    // Send transaction
    const result = await agent.call("sendTransaction", {
      ...params,
      gasLimit: gasEstimate.gasLimit,
      gasPrice: gasEstimate.gasPrice
    })
    
    // Monitor transaction
    await monitorTransaction(result.hash, params.chain)
    
    return result
  } catch (error) {
    console.error("Transaction failed:", error)
    await handleTransactionError(error, params)
    throw error
  }
}
 
async function validateTransaction(params: any) {
  // Validate address format
  if (!/^0x[a-fA-F0-9]{40}$/.test(params.to)) {
    throw new Error("Invalid recipient address")
  }
  
  // Validate amount
  if (parseFloat(params.amount) <= 0) {
    throw new Error("Amount must be positive")
  }
  
  // Check for common mistakes
  if (params.to.toLowerCase() === params.from?.toLowerCase()) {
    throw new Error("Cannot send to same address")
  }
}
 
async function monitorTransaction(hash: string, chain: string) {
  const maxWaitTime = 300000 // 5 minutes
  const startTime = Date.now()
  
  while (Date.now() - startTime < maxWaitTime) {
    try {
      const tx = await agent.call("getTransaction", { hash, chain })
      
      if (tx.status === "success") {
        console.log(`Transaction ${hash} confirmed`)
        return tx
      } else if (tx.status === "failed") {
        throw new Error(`Transaction ${hash} failed`)
      }
      
      // Wait before checking again
      await new Promise(resolve => setTimeout(resolve, 10000)) // 10 seconds
    } catch (error) {
      // Transaction might not be mined yet
      await new Promise(resolve => setTimeout(resolve, 5000)) // 5 seconds
    }
  }
  
  throw new Error(`Transaction ${hash} not confirmed within timeout`)
}

Gas Optimization

// Gas optimization strategies
class GasOptimizer {
  static async optimizeTransaction(params: any) {
    // Get current gas prices
    const gasPrices = await agent.call("getGasPrice", { chain: params.chain })
    
    // Estimate gas for transaction
    const gasEstimate = await agent.call("estimateGas", params)
    
    // Choose optimal gas price based on urgency
    const urgency = params.urgency || "medium"
    const gasPrice = this.selectGasPrice(gasPrices, urgency)
    
    // Add buffer to gas limit
    const gasLimit = Math.ceil(gasEstimate.gasLimit * 1.1)
    
    return {
      ...params,
      gasPrice,
      gasLimit,
      estimatedCost: (gasPrice * gasLimit) / 1e18 // Convert to ETH
    }
  }
  
  static selectGasPrice(gasPrices: any, urgency: string) {
    switch (urgency) {
      case "low":
        return gasPrices.slow || gasPrices.standard
      case "medium":
        return gasPrices.standard
      case "high":
        return gasPrices.fast
      case "urgent":
        return gasPrices.instant || gasPrices.fast
      default:
        return gasPrices.standard
    }
  }
  
  static async batchOptimize(transactions: any[]) {
    // Optimize multiple transactions together
    const optimized = await Promise.all(
      transactions.map(tx => this.optimizeTransaction(tx))
    )
    
    // Calculate total cost
    const totalCost = optimized.reduce(
      (sum, tx) => sum + tx.estimatedCost, 0
    )
    
    return {
      transactions: optimized,
      totalCost,
      savings: this.calculateSavings(transactions, optimized)
    }
  }
}

Next Steps