Skip to main content
Glama

approve_token_spending

Authorize a DeFi protocol or exchange to spend your ERC20 tokens. Submit private key, token and spender addresses, and amount to enable token transactions securely on EVM-compatible networks.

Instructions

Approve another address (like a DeFi protocol or exchange) to spend your ERC20 tokens. This is often required before interacting with DeFi protocols.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
amountYesThe amount of tokens to approve in token units, not wei (e.g., '1000' to approve spending 1000 tokens). Use a very large number for unlimited approval.
networkNoNetwork name (e.g., 'ethereum', 'optimism', 'arbitrum', 'base', 'polygon') or chain ID. Defaults to Ethereum mainnet.
privateKeyYesPrivate key of the token owner account in hex format (with or without 0x prefix). SECURITY: This is used only for transaction signing and is not stored.
spenderAddressYesThe contract address being approved to spend your tokens (e.g., a DEX or lending protocol)
tokenAddressYesThe contract address of the ERC20 token to approve for spending (e.g., '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' for USDC on Ethereum)

Implementation Reference

  • Registration of the 'approve_token_spending' MCP tool, including input schema (Zod) and thin handler wrapper that calls services.approveERC20
    // Approve ERC20 token spending server.tool( 'approve_token_spending', 'Approve another address (like a DeFi protocol or exchange) to spend your ERC20 tokens. This is often required before interacting with DeFi protocols.', { privateKey: z .string() .describe( 'Private key of the token owner account in hex format (with or without 0x prefix). SECURITY: This is used only for transaction signing and is not stored.' ), tokenAddress: z .string() .describe( "The contract address of the ERC20 token to approve for spending (e.g., '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' for USDC on Ethereum)" ), spenderAddress: z .string() .describe( 'The contract address being approved to spend your tokens (e.g., a DEX or lending protocol)' ), amount: z .string() .describe( "The amount of tokens to approve in token units, not wei (e.g., '1000' to approve spending 1000 tokens). Use a very large number for unlimited approval." ), network: z .string() .optional() .describe( "Network name (e.g., 'ethereum', 'optimism', 'arbitrum', 'base', 'polygon') or chain ID. Defaults to Ethereum mainnet." ) }, async ({ privateKey, tokenAddress, spenderAddress, amount, network = 'ethereum' }) => { try { // Get the formattedKey with 0x prefix const formattedKey = privateKey.startsWith('0x') ? (privateKey as `0x${string}`) : (`0x${privateKey}` as `0x${string}`); const result = await services.approveERC20( tokenAddress as Address, spenderAddress as Address, amount, formattedKey, network ); return { content: [ { type: 'text', text: JSON.stringify( { success: true, txHash: result.txHash, network, tokenAddress, spender: spenderAddress, amount: result.amount.formatted, symbol: result.token.symbol }, null, 2 ) } ] }; } catch (error) { return { content: [ { type: 'text', text: `Error approving token spending: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } );
  • Core implementation of ERC20 token approval: resolves addresses, fetches token metadata, parses amount, and executes the 'approve' contract call using viem.
    /** * Approve ERC20 token spending * @param tokenAddressOrEns Token contract address or ENS name * @param spenderAddressOrEns Spender address or ENS name * @param amount Amount to approve (in token units) * @param privateKey Owner's private key * @param network Network name or chain ID * @returns Transaction details */ export async function approveERC20( tokenAddressOrEns: string, spenderAddressOrEns: string, amount: string, privateKey: string | `0x${string}`, network: string = 'ethereum' ): Promise<{ txHash: Hash; amount: { raw: bigint; formatted: string; }; token: { symbol: string; decimals: number; }; }> { // Resolve ENS names to addresses if needed const tokenAddress = (await resolveAddress( tokenAddressOrEns, network )) as Address; const spenderAddress = (await resolveAddress( spenderAddressOrEns, network )) as Address; // Ensure the private key has 0x prefix const formattedKey = typeof privateKey === 'string' && !privateKey.startsWith('0x') ? (`0x${privateKey}` as `0x${string}`) : (privateKey as `0x${string}`); // Get token details const publicClient = getPublicClient(network); const contract = getContract({ address: tokenAddress, abi: erc20TransferAbi, client: publicClient }); // Get token decimals and symbol const decimals = await contract.read.decimals(); const symbol = await contract.read.symbol(); // Parse the amount with the correct number of decimals const rawAmount = parseUnits(amount, decimals); // Create wallet client for sending the transaction const walletClient = getWalletClient(formattedKey, network); // Send the transaction const hash = await walletClient.writeContract({ address: tokenAddress, abi: erc20TransferAbi, functionName: 'approve', args: [spenderAddress, rawAmount], account: walletClient.account!, chain: walletClient.chain }); return { txHash: hash, amount: { raw: rawAmount, formatted: amount }, token: { symbol, decimals } }; }
  • ERC20 ABI fragment used for approve, transfer, decimals, and symbol reads.
    const erc20TransferAbi = [ { inputs: [ { type: 'address', name: 'to' }, { type: 'uint256', name: 'amount' } ], name: 'transfer', outputs: [{ type: 'bool' }], stateMutability: 'nonpayable', type: 'function' }, { inputs: [ { type: 'address', name: 'spender' }, { type: 'uint256', name: 'amount' } ], name: 'approve', outputs: [{ type: 'bool' }], stateMutability: 'nonpayable', type: 'function' }, { inputs: [], name: 'decimals', outputs: [{ type: 'uint8' }], stateMutability: 'view', type: 'function' }, { inputs: [], name: 'symbol', outputs: [{ type: 'string' }], stateMutability: 'view', type: 'function' } ] as const;

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/chulanpro5/evm-mcp-server'

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