Skip to main content
Glama

approve_token_spending

Authorize token spending for cross-chain trading on Paloma DEX by approving a spender contract to access your tokens on supported EVM chains.

Instructions

Approve token spending for trading (two-step approval process).

Args:
    chain_id: Chain ID (1, 10, 56, 100, 137, 8453, 42161)
    token_address: Address of token to approve
    spender_address: Address that will spend the tokens (typically Trader contract)
    amount: Amount to approve in wei (defaults to unlimited)

Returns:
    JSON string with approval transaction details.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
chain_idYes
token_addressYes
spender_addressYes
amountNo

Implementation Reference

  • The main handler function for the 'approve_token_spending' tool. It performs a safe two-step ERC-20 approval: first resets any existing allowance to 0, then approves the new amount (unlimited by default). Executes actual blockchain transactions on the specified chain using the configured Web3 client and account private key.
    async def approve_token_spending(ctx: Context, chain_id: str, token_address: str, spender_address: str, amount: Optional[str] = None) -> str:
        """Approve token spending for trading (two-step approval process).
        
        Args:
            chain_id: Chain ID (1, 10, 56, 100, 137, 8453, 42161)
            token_address: Address of token to approve
            spender_address: Address that will spend the tokens (typically Trader contract)
            amount: Amount to approve in wei (defaults to unlimited)
        
        Returns:
            JSON string with approval transaction details.
        """
        try:
            paloma_ctx = ctx.request_context.lifespan_context
            
            if chain_id not in CHAIN_CONFIGS:
                return f"Error: Unsupported chain ID {chain_id}"
            
            config = CHAIN_CONFIGS[chain_id]
            
            if chain_id not in paloma_ctx.web3_clients:
                return f"Error: Web3 client not available for {config.name}"
            
            # Validate addresses
            if not Web3.is_address(token_address):
                return f"Error: Invalid token address: {token_address}"
            
            if not Web3.is_address(spender_address):
                return f"Error: Invalid spender address: {spender_address}"
            
            web3 = paloma_ctx.web3_clients[chain_id]
            token_contract = web3.eth.contract(address=token_address, abi=ERC20_ABI)
            
            # Use unlimited approval if no amount specified
            approval_amount = int(amount) if amount else MAX_AMOUNT
            
            # Check current allowance
            current_allowance = token_contract.functions.allowance(
                paloma_ctx.address, spender_address
            ).call()
            
            transactions = []
            
            # Step 1: Reset allowance to 0 if it exists
            if current_allowance > 0:
                reset_tx_data = token_contract.functions.approve(spender_address, 0).build_transaction({
                    'from': paloma_ctx.address,
                    'gas': 100000,
                    'gasPrice': web3.to_wei(config.gas_price_gwei, 'gwei'),
                    'nonce': web3.eth.get_transaction_count(paloma_ctx.address)
                })
                
                # Sign and send reset transaction
                signed_reset = paloma_ctx.account.sign_transaction(reset_tx_data)
                reset_tx_hash = web3.eth.send_raw_transaction(signed_reset.rawTransaction)
                
                # Wait for confirmation
                reset_receipt = web3.eth.wait_for_transaction_receipt(reset_tx_hash)
                
                transactions.append({
                    "step": "reset_allowance",
                    "tx_hash": reset_tx_hash.hex(),
                    "status": "success" if reset_receipt.status == 1 else "failed"
                })
            
            # Step 2: Set new allowance
            approve_tx_data = token_contract.functions.approve(spender_address, approval_amount).build_transaction({
                'from': paloma_ctx.address,
                'gas': 100000,
                'gasPrice': web3.to_wei(config.gas_price_gwei, 'gwei'),
                'nonce': web3.eth.get_transaction_count(paloma_ctx.address)
            })
            
            # Sign and send approval transaction
            signed_approve = paloma_ctx.account.sign_transaction(approve_tx_data)
            approve_tx_hash = web3.eth.send_raw_transaction(signed_approve.rawTransaction)
            
            # Wait for confirmation
            approve_receipt = web3.eth.wait_for_transaction_receipt(approve_tx_hash)
            
            transactions.append({
                "step": "set_allowance",
                "tx_hash": approve_tx_hash.hex(),
                "status": "success" if approve_receipt.status == 1 else "failed",
                "approved_amount": str(approval_amount)
            })
            
            # Get token symbol for display
            try:
                token_symbol = token_contract.functions.symbol().call()
            except:
                token_symbol = "Unknown"
            
            result = {
                "chain": config.name,
                "chain_id": config.chain_id,
                "token_address": token_address,
                "token_symbol": token_symbol,
                "spender_address": spender_address,
                "owner_address": paloma_ctx.address,
                "approved_amount": str(approval_amount),
                "is_unlimited": approval_amount == MAX_AMOUNT,
                "transactions": transactions,
                "all_successful": all(tx["status"] == "success" for tx in transactions)
            }
            
            return json.dumps(result, indent=2)
            
        except Exception as e:
            logger.error(f"Error approving token spending: {e}")
            return f"Error approving token spending: {str(e)}"
  • Minimal ERC-20 ABI used by the approve_token_spending handler, including essential functions: balanceOf, decimals, symbol, approve, and allowance.
    ERC20_ABI = [
        {
            "constant": True,
            "inputs": [{"name": "_owner", "type": "address"}],
            "name": "balanceOf",
            "outputs": [{"name": "balance", "type": "uint256"}],
            "type": "function"
        },
        {
            "constant": True,
            "inputs": [],
            "name": "decimals",
            "outputs": [{"name": "", "type": "uint8"}],
            "type": "function"
        },
        {
            "constant": True,
            "inputs": [],
            "name": "symbol",
            "outputs": [{"name": "", "type": "string"}],
            "type": "function"
        },
        {
            "constant": False,
            "inputs": [
                {"name": "spender", "type": "address"},
                {"name": "amount", "type": "uint256"}
            ],
            "name": "approve",
            "outputs": [{"name": "", "type": "bool"}],
            "type": "function"
        },
        {
            "constant": True,
            "inputs": [
                {"name": "owner", "type": "address"},
                {"name": "spender", "type": "address"}
            ],
            "name": "allowance",
            "outputs": [{"name": "", "type": "uint256"}],
            "type": "function"
        }
  • Trading constants used in approval logic, including MAX_AMOUNT for unlimited approvals.
    MAX_AMOUNT = 2**256 - 1  # Maximum approval amount
    GAS_MULTIPLIER = 3  # Divide by this for 33% gas buffer
    MAX_SPREAD = 0.4  # 40% maximum spread limit
  • padex.py:1483-1483 (registration)
    FastMCP decorator that registers the approve_token_spending function as an MCP tool, automatically generating input schema from signature and docstring.
    async def approve_token_spending(ctx: Context, chain_id: str, token_address: str, spender_address: str, amount: Optional[str] = None) -> str:

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/VolumeFi/mcpPADEX'

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