Skip to main content
Glama

agentek-eth

by NaniDAO
intents.ts3.73 kB
import { z } from "zod"; import { AgentekClient, createTool, Intent } from "../client.js"; import { Address, encodeFunctionData, erc20Abi, parseUnits, PublicClient, } from "viem"; import { erc20Chains } from "./constants.js"; const intentApproveParameters = z.object({ token: z.string().describe("The token address"), amount: z.string().describe("The amount to approve"), spender: z.string().describe("The spender address to approve"), chainId: z.number().optional().describe("Optional specific chain to use"), }); export const ETH_ADDRESS = "0x0000000000000000000000000000000000000000" as Address; const getTokenDecimals = async ( publicClient: PublicClient, token: Address, ): Promise<number> => { if (token == ETH_ADDRESS) { return 18; } else { return await publicClient.readContract({ abi: erc20Abi, functionName: "decimals", address: token, }); } }; export const intentApproveTool = createTool({ name: "intentApprove", description: "Creates an intent to approve token spending", supportedChains: erc20Chains, parameters: intentApproveParameters, execute: async ( client: AgentekClient, args: z.infer<typeof intentApproveParameters>, ): Promise<Intent> => { const { token, amount, spender, chainId } = args; const chains = client.filterSupportedChains(erc20Chains, chainId); const from = await client.getAddress(); if (token === ETH_ADDRESS) { throw new Error("Cannot approve ETH, only ERC20 tokens"); } const chainsInfo = ( await Promise.all( chains.map(async (chain) => { try { const publicClient = client.getPublicClient(chain.id); const decimals = await getTokenDecimals( publicClient, token as Address, ); const amountBigInt = parseUnits(amount, decimals); return { chain, amount: amountBigInt, decimals, }; } catch (error) { console.error(`Error processing chain ${chain.id}:`, error); return undefined; } }), ) ).filter( (chainInfo): chainInfo is NonNullable<typeof chainInfo> => chainInfo !== undefined, ); let executionChain; if (chainsInfo.length === 0) { throw new Error("No supported chains found with valid token information"); } else { executionChain = await Promise.all( chainsInfo.map(async (chainInfo) => { const publicClient = client.getPublicClient(chainInfo.chain.id); const gasPrice = await publicClient.getGasPrice(); return { ...chainInfo, gasPrice, }; }), ).then((chains) => chains.reduce((cheapest, current) => current.gasPrice < cheapest.gasPrice ? current : cheapest, ), ); } const walletClient = client.getWalletClient(executionChain.chain.id); const ops = [ { target: token as Address, value: "0", data: encodeFunctionData({ abi: erc20Abi, functionName: "approve", args: [spender as Address, executionChain.amount], }), }, ]; if (!walletClient) { return { intent: `approve ${amount.toString()} ${token} for spender ${spender}`, ops, chain: executionChain.chain.id, }; } else { const hash = await client.executeOps(ops, executionChain.chain.id); return { intent: `Approve ${amount.toString()} ${token} from ${from} for spender ${spender}`, ops, chain: executionChain.chain.id, hash: hash, }; } }, });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/NaniDAO/agentek'

If you have feedback or need assistance with the MCP directory API, please join our Discord server