UNPKG

@agentek/tools

Version:

Blockchain tools for AI agents

136 lines 6.28 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.estimateGasCostTool = void 0; const zod_1 = require("zod"); const client_js_1 = require("../client.js"); const viem_1 = require("viem"); const tools_js_1 = require("../cryptoprices/tools.js"); exports.estimateGasCostTool = (0, client_js_1.createTool)({ name: "estimateGasCost", description: "Estimate the gas cost for a transaction in both native token and USD", parameters: zod_1.z.object({ chainId: zod_1.z.number().describe("Chain ID (e.g. 1 for Ethereum, 137 for Polygon)"), gasUnits: zod_1.z.number().describe("Estimated gas units for the transaction"), maxFeePerGas: zod_1.z.string().optional().describe("Optional max fee per gas in gwei"), maxPriorityFeePerGas: zod_1.z.string().optional().describe("Optional max priority fee per gas in gwei") }), execute: async (client, args) => { const { chainId, gasUnits, maxFeePerGas, maxPriorityFeePerGas } = args; // Get the public client for the specified chain const publicClient = client.getPublicClient(chainId); if (!publicClient) { throw new Error(`No public client available for chain ID ${chainId}`); } try { // Get latest gas prices if not provided let feeData; if (!maxFeePerGas || !maxPriorityFeePerGas) { try { feeData = await publicClient.estimateFeesPerGas(); } catch (error) { // Fallback for chains that don't support EIP-1559 const gasPrice = await publicClient.getGasPrice(); feeData = { maxFeePerGas: gasPrice, maxPriorityFeePerGas: BigInt(0) }; } } // Use provided values or defaults const finalMaxFeePerGas = maxFeePerGas ? (0, viem_1.parseUnits)(maxFeePerGas, 9) : feeData?.maxFeePerGas ?? BigInt(0); const finalMaxPriorityFeePerGas = maxPriorityFeePerGas ? (0, viem_1.parseUnits)(maxPriorityFeePerGas, 9) : feeData?.maxPriorityFeePerGas ?? BigInt(0); // Calculate total gas cost in wei, with chain-specific adjustments const totalGasCost = BigInt(gasUnits) * finalMaxFeePerGas * getGasPriceDivisor(chainId) / BigInt(1000); // Get the chain's native token symbol const nativeSymbol = getNativeTokenSymbol(chainId); // Format gas prices to gwei for readability const formattedMaxFeePerGas = (0, viem_1.formatUnits)(finalMaxFeePerGas, 9); const formattedMaxPriorityFeePerGas = (0, viem_1.formatUnits)(finalMaxPriorityFeePerGas, 9); // Format total cost to ether units const formattedTotalCost = (0, viem_1.formatUnits)(totalGasCost, 18); // Try to get USD price let usdPrice = null; let usdCost = null; try { // Try to use getCryptoPrice tool if available const priceResponse = await tools_js_1.getCryptoPriceTool.execute(client, { symbol: nativeSymbol }); if (priceResponse && priceResponse.price) { usdPrice = priceResponse.price; if (usdPrice) usdCost = parseFloat(formattedTotalCost) * usdPrice; else { throw new Error("Price data not found"); } } } catch (error) { // Silently fail if price lookup doesn't work console.error("Error fetching price:", error); } return { chainId, gasUnits, maxFeePerGas: formattedMaxFeePerGas, maxPriorityFeePerGas: formattedMaxPriorityFeePerGas, totalCost: formattedTotalCost, nativeSymbol, usdPrice: usdPrice, usdCost: usdCost !== null ? usdCost.toFixed(2) : null, timestamp: new Date().toISOString() }; } catch (error) { throw new Error(`Error estimating gas cost: ${error instanceof Error ? error.message : String(error)}`); } } }); // Helper function to get native token symbol based on chain ID function getNativeTokenSymbol(chainId) { const symbols = { 1: "ETH", // Ethereum Mainnet 10: "ETH", // Optimism 42161: "ETH", // Arbitrum 137: "MATIC", // Polygon 56: "BNB", // BNB Chain 43114: "AVAX", // Avalanche 8453: "ETH", // Base 324: "ETH", // zkSync Era 100: "XDAI", // Gnosis Chain 42220: "CELO", // Celo 250: "FTM", // Fantom 1101: "ETH", // Polygon zkEVM 5: "ETH", // Goerli testnet 11155111: "ETH" // Sepolia testnet }; return symbols[chainId] || "ETH"; // Default to ETH if chain ID not recognized } // Helper function to adjust gas price calculation for different chains // Return value is relative to 1000 (which is the base value for Ethereum mainnet) // For example, 100 means 10x cheaper than Ethereum, 10000 means 10x more expensive function getGasPriceDivisor(chainId) { const adjustments = { 1: 1000, // Ethereum Mainnet - baseline 10: 200, // Optimism - usually ~5x cheaper than mainnet 42161: 100, // Arbitrum - usually ~10x cheaper than mainnet 137: 10, // Polygon - usually ~100x cheaper than mainnet 56: 50, // BNB Chain - usually ~20x cheaper than mainnet 43114: 100, // Avalanche - usually ~10x cheaper than mainnet 8453: 200, // Base - usually ~5x cheaper than mainnet 324: 100, // zkSync Era 100: 20, // Gnosis Chain 42220: 50, // Celo 250: 20, // Fantom 1101: 50, // Polygon zkEVM 5: 1000, // Goerli testnet 11155111: 1000 // Sepolia testnet }; return BigInt(adjustments[chainId] || 1000); // Default to mainnet if chain ID not recognized } //# sourceMappingURL=tools.js.map