Skip to main content
Glama

execute_token_swap

Swap tokens across EVM chains using the Paloma DEX Trader contract. Specify chain, token addresses, and amount to execute cross-chain trades.

Instructions

Execute a token swap using the Trader contract.

Args:
    chain_id: Chain ID (1, 10, 56, 100, 137, 8453, 42161)
    from_token_address: Address of token to swap from
    to_token_address: Address of token to swap to
    amount_wei: Amount to swap in wei format

Returns:
    JSON string with swap transaction details.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
chain_idYes
from_token_addressYes
to_token_addressYes
amount_weiYes

Implementation Reference

  • The handler function for the 'execute_token_swap' tool. It performs the actual token swap by calling the Trader contract's purchase function on the specified EVM chain, handles approvals implicitly via prior tools, signs and sends the transaction using the configured private key, and returns transaction details.
    async def execute_token_swap(ctx: Context, chain_id: str, from_token_address: str, to_token_address: str, amount_wei: str) -> str:
        """Execute a token swap using the Trader contract.
        
        Args:
            chain_id: Chain ID (1, 10, 56, 100, 137, 8453, 42161)
            from_token_address: Address of token to swap from
            to_token_address: Address of token to swap to
            amount_wei: Amount to swap in wei format
        
        Returns:
            JSON string with swap 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}"
            
            trader_address = TRADER_ADDRESSES.get(chain_id)
            if not trader_address:
                return f"Error: Trader contract not configured for {config.name}"
            
            # Validate addresses
            if not Web3.is_address(from_token_address):
                return f"Error: Invalid from token address: {from_token_address}"
            
            if not Web3.is_address(to_token_address):
                return f"Error: Invalid to token address: {to_token_address}"
            
            try:
                amount_int = int(amount_wei)
                if amount_int <= 0:
                    raise ValueError("Amount must be positive")
            except ValueError:
                return f"Error: Invalid amount: {amount_wei}"
            
            web3 = paloma_ctx.web3_clients[chain_id]
            trader_contract = web3.eth.contract(address=trader_address, abi=TRADER_ABI)
            
            # Get gas fee from contract
            try:
                gas_fee = trader_contract.functions.gas_fee().call()
            except Exception as e:
                logger.warning(f"Failed to get gas fee from contract: {e}, using 0")
                gas_fee = 0
            
            # Build transaction
            swap_tx_data = trader_contract.functions.purchase(
                from_token_address,
                to_token_address, 
                amount_int
            ).build_transaction({
                'from': paloma_ctx.address,
                'value': gas_fee,
                'gasPrice': web3.to_wei(config.gas_price_gwei, 'gwei'),
                'nonce': web3.eth.get_transaction_count(paloma_ctx.address)
            })
            
            # Estimate gas with buffer
            try:
                estimated_gas = web3.eth.estimate_gas(swap_tx_data)
                buffered_gas = estimated_gas + (estimated_gas // GAS_MULTIPLIER)  # Add 33% buffer
                swap_tx_data['gas'] = buffered_gas
            except Exception as e:
                logger.warning(f"Gas estimation failed: {e}, using default")
                swap_tx_data['gas'] = 300000
            
            # Sign and send transaction
            signed_tx = paloma_ctx.account.sign_transaction(swap_tx_data)
            tx_hash = web3.eth.send_raw_transaction(signed_tx.rawTransaction)
            
            # Wait for confirmation
            receipt = web3.eth.wait_for_transaction_receipt(tx_hash)
            
            # Get token symbols for display
            try:
                from_contract = web3.eth.contract(address=from_token_address, abi=ERC20_ABI)
                to_contract = web3.eth.contract(address=to_token_address, abi=ERC20_ABI)
                from_symbol = from_contract.functions.symbol().call()
                to_symbol = to_contract.functions.symbol().call()
                from_decimals = from_contract.functions.decimals().call()
            except:
                from_symbol = "Unknown"
                to_symbol = "Unknown"
                from_decimals = 18
            
            amount_display = float(amount_int) / (10 ** from_decimals)
            
            result = {
                "chain": config.name,
                "chain_id": config.chain_id,
                "trader_contract": trader_address,
                "from_token": {
                    "address": from_token_address,
                    "symbol": from_symbol,
                    "amount_wei": amount_wei,
                    "amount_display": str(amount_display)
                },
                "to_token": {
                    "address": to_token_address,
                    "symbol": to_symbol
                },
                "transaction": {
                    "hash": tx_hash.hex(),
                    "status": "success" if receipt.status == 1 else "failed",
                    "gas_used": receipt.gasUsed,
                    "gas_fee_paid": str(gas_fee),
                    "block_number": receipt.blockNumber
                },
                "explorer_url": f"{config.explorer_url}/tx/{tx_hash.hex()}"
            }
            
            return json.dumps(result, indent=2)
            
        except Exception as e:
            logger.error(f"Error executing token swap: {e}")
            return f"Error executing token swap: {str(e)}"
  • ABI definition for the Trader contract, which includes the 'purchase' function called by execute_token_swap to perform the swap.
    TRADER_ABI = [
        {
            "name": "purchase",
            "type": "function",
            "inputs": [
                {"name": "from_token", "type": "address"},
                {"name": "to_token", "type": "address"},
                {"name": "amount", "type": "uint256"}
            ],
            "outputs": [],
            "stateMutability": "payable"
        },
        {
            "name": "add_liquidity",
            "type": "function",
            "inputs": [
                {"name": "token0", "type": "address"},
                {"name": "token1", "type": "address"},
                {"name": "amount0", "type": "uint256"},
                {"name": "amount1", "type": "uint256"}
            ],
            "outputs": [],
            "stateMutability": "payable"
        },
        {
            "name": "remove_liquidity",
            "type": "function",
            "inputs": [
                {"name": "token0", "type": "address"},
                {"name": "token1", "type": "address"},
                {"name": "amount", "type": "uint256"}
            ],
            "outputs": [],
            "stateMutability": "payable"
        },
        {
            "name": "gas_fee",
            "type": "function",
            "inputs": [],
            "outputs": [{"name": "", "type": "uint256"}],
            "stateMutability": "view"
        }
    ]
  • Mapping of chain IDs to Trader contract addresses used in execute_token_swap.
    TRADER_ADDRESSES = {
        ChainID.ETHEREUM_MAIN: "0x7230EC05eD8c38D5be6f58Ae41e30D1ED6cfDAf1",
        ChainID.ARBITRUM_MAIN: "0x36B8763b3b71685F21512511bB433f4A0f50213E", 
        ChainID.BASE_MAIN: "0xd58Dfd5b39fCe87dD9C434e95428DdB289934179",
        ChainID.BSC_MAIN: "0x8ee509a97279029071AB66Cb0391e8Dc67a137f9",
        ChainID.GNOSIS_MAIN: "0xd58Dfd5b39fCe87dD9C434e95428DdB289934179",
        ChainID.OPTIMISM_MAIN: "0xB6d4AAFfBbceB5e363352179E294326C91d6c127",
        ChainID.POLYGON_MAIN: "0xB6d4AAFfBbceB5e363352179E294326C91d6c127"
    }

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