Skip to main content
Glama
index.ts2.6 kB
import { ActionProvider, CreateAction, EvmWalletProvider, type Network, } from '@coinbase/agentkit'; import { encodeFunctionData, isAddress, type Abi, type AbiFunction, } from 'viem'; import { base, baseSepolia } from 'viem/chains'; import type { z } from 'zod'; import { chainIdToChain } from '../../chains.js'; import { constructBaseScanUrl } from '../utils/index.js'; import { CallContractSchema } from './schemas.js'; export class BaseMcpContractActionProvider extends ActionProvider<EvmWalletProvider> { constructor() { super('baseMcpContract', []); } @CreateAction({ name: 'call_contract', description: 'Call a contract function', schema: CallContractSchema, }) async callContract( walletProvider: EvmWalletProvider, args: z.infer<typeof CallContractSchema>, ) { let abi: string | Abi = args.abi; try { abi = JSON.parse(abi) as Abi; } catch (error) { throw new Error(`Invalid ABI: ${error}`); } if (!isAddress(args.contractAddress, { strict: false })) { throw new Error(`Invalid contract address: ${args.contractAddress}`); } let functionAbi: AbiFunction | undefined; try { functionAbi = abi.find( (item) => 'name' in item && item.name === args.functionName, ) as AbiFunction; } catch (error) { throw new Error(`Invalid function name: ${args.functionName}. ${error}`); } const chain = chainIdToChain(Number(walletProvider.getNetwork().chainId)); if (!chain) { throw new Error( `Unsupported chainId: ${walletProvider.getNetwork().chainId}`, ); } if ( functionAbi.stateMutability === 'view' || functionAbi.stateMutability === 'pure' ) { const tx = await walletProvider.readContract({ address: args.contractAddress, abi, functionName: args.functionName, args: args.functionArgs, }); return String(tx); } const tx = await walletProvider.sendTransaction({ to: args.contractAddress, data: encodeFunctionData({ abi, functionName: args.functionName, args: args.functionArgs, }), value: BigInt(args.value ?? 0), }); const link = constructBaseScanUrl(chain, tx); return JSON.stringify({ hash: tx, url: link, }); } supportsNetwork(network: Network): boolean { return ( network.chainId === String(base.id) || network.chainId === String(baseSepolia.id) ); } } export const baseMcpContractActionProvider = () => new BaseMcpContractActionProvider();

Latest Blog Posts

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/bioanywhere/mcp-base-mcp2'

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