UNPKG

@coinbase/agentkit

Version:

Coinbase AgentKit core primitives

107 lines (106 loc) 4.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PERMIT2_ADDRESS = void 0; exports.isNativeEth = isNativeEth; exports.getTokenDetails = getTokenDetails; const viem_1 = require("viem"); // Permit2 contract address is the same across all networks exports.PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3"; /** * Checks if a token is native ETH. * * @param token - The token address to check. * @returns True if the token is native ETH, false otherwise. */ function isNativeEth(token) { return token.toLowerCase() === "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; } /** * Gets the details (decimals and name) for both fromToken and toToken * * @param walletProvider - The EVM wallet provider to read contracts * @param fromToken - The contract address of the from token * @param toToken - The contract address of the to token * @returns Promise<{fromTokenDecimals: number, toTokenDecimals: number, fromTokenName: string, toTokenName: string}> */ async function getTokenDetails(walletProvider, fromToken, toToken) { // Initialize default values for native ETH let fromTokenDecimals = 18; let fromTokenName = "ETH"; let toTokenDecimals = 18; let toTokenName = "ETH"; // Prepare multicall contracts array const contracts = []; const contractIndexMap = { fromDecimals: -1, fromName: -1, toDecimals: -1, toName: -1, }; // Add from token contracts if not native ETH if (!isNativeEth(fromToken)) { contractIndexMap.fromDecimals = contracts.length; contracts.push({ address: fromToken, abi: viem_1.erc20Abi, functionName: "decimals", }); contractIndexMap.fromName = contracts.length; contracts.push({ address: fromToken, abi: viem_1.erc20Abi, functionName: "name", }); } // Add to token contracts if not native ETH if (!isNativeEth(toToken)) { contractIndexMap.toDecimals = contracts.length; contracts.push({ address: toToken, abi: viem_1.erc20Abi, functionName: "decimals", }); contractIndexMap.toName = contracts.length; contracts.push({ address: toToken, abi: viem_1.erc20Abi, functionName: "name", }); } // Execute multicall if there are contracts to call if (contracts.length > 0) { try { const results = await walletProvider.getPublicClient().multicall({ contracts, }); // Extract from token details if (contractIndexMap.fromDecimals !== -1) { const decimalsResult = results[contractIndexMap.fromDecimals]; const nameResult = results[contractIndexMap.fromName]; if (decimalsResult.status === "success" && nameResult.status === "success") { fromTokenDecimals = decimalsResult.result; fromTokenName = nameResult.result; } else { throw new Error(`Failed to read details for fromToken ${fromToken}. This address may not be a valid ERC20 contract.`); } } // Extract to token details if (contractIndexMap.toDecimals !== -1) { const decimalsResult = results[contractIndexMap.toDecimals]; const nameResult = results[contractIndexMap.toName]; if (decimalsResult.status === "success" && nameResult.status === "success") { toTokenDecimals = decimalsResult.result; toTokenName = nameResult.result; } else { throw new Error(`Failed to read details for toToken ${toToken}. This address may not be a valid ERC20 contract.`); } } } catch (error) { throw new Error(`Failed to read token details via multicall. Error: ${error}`); } } return { fromTokenDecimals, toTokenDecimals, fromTokenName, toTokenName }; }