Crypto Protocol Automation
This example demonstrates how to automate crypto protocol interactions that require GUI interaction because no API is available. Many DeFi protocols and yield farming platforms only offer web interfaces that require manual interaction. CodecFlow’s cloud desktops provide the perfect solution for automating these web-based tasks that would otherwise require constant manual attention.
import { CodecFlow } from '@codecflow/sdk';
async function createCryptoProtocolBot() { // Initialize CodecFlow with secure API key const codecflow = new CodecFlow({ apiKey: process.env.CODECFLOW_API_KEY });
// Create a secure desktop with TEE for crypto operations const desktop = await codecflow.createDesktop({ os: 'linux', // Linux is sufficient for browser-based operations version: 'ubuntu-22.04', security: { teeEnabled: true, encryptedStorage: true, isolationLevel: 'high' }, resources: { memory: '8gb', cpu: 4 } });
// Connect AI agent with MCP for web automation const agent = await desktop.connectAgent({ model: 'gpt-4', protocol: 'mcp', config: { capabilities: ['browser', 'network', 'ocr', 'screenshot'], contextProviders: [ { type: 'web-elements', recognitionLevel: 'high' } ] } });
// Create browser for protocol interactions const browser = await desktop.createBrowser({ userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', viewport: { width: 1920, height: 1080 } });
// Connect wallet (using browser extension) await browser.navigate('chrome://extensions');
// Install MetaMask or other wallet extension await agent.executeAction({ type: 'browser', action: 'installExtension', params: { extensionId: 'nkbihfbeogaeaoehlefnkodbefgpgknn' // MetaMask extension ID } });
// Set up wallet with credentials stored in TEE await browser.navigate('chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/home.html');
// Import wallet using secure credentials await agent.executeAction({ type: 'browser', action: 'clickElement', params: { selector: 'button:contains("Import wallet")' } });
// Enter seed phrase securely from TEE await agent.executeAction({ type: 'browser', action: 'typeText', params: { selector: 'textarea', text: process.env.WALLET_SEED_PHRASE } });
// Enter password await agent.executeAction({ type: 'browser', action: 'typeText', params: { selector: 'input[type="password"]', text: process.env.WALLET_PASSWORD } });
// Confirm password await agent.executeAction({ type: 'browser', action: 'typeText', params: { selector: 'input[type="password"]:nth-of-type(2)', text: process.env.WALLET_PASSWORD } });
// Accept terms await agent.executeAction({ type: 'browser', action: 'clickElement', params: { selector: 'input[type="checkbox"]' } });
// Import wallet await agent.executeAction({ type: 'browser', action: 'clickElement', params: { selector: 'button:contains("Import")' } });
// Wait for wallet setup to complete await agent.executeAction({ type: 'browser', action: 'waitForNavigation', params: { timeout: 30000 } });
// Navigate to DeFi protocol await browser.navigate('https://example-defi-protocol.com');
// Connect wallet to the protocol await agent.executeAction({ type: 'browser', action: 'clickElement', params: { selector: 'button:contains("Connect Wallet")' } });
// Select MetaMask await agent.executeAction({ type: 'browser', action: 'clickElement', params: { selector: 'div:contains("MetaMask")' } });
// Handle MetaMask popup await agent.executeAction({ type: 'browser', action: 'handlePopup', params: { action: 'approve' } });
// Define protocol interaction tasks const protocolTasks = [ { name: 'Check liquidity pools', action: async () => { await browser.navigate('https://example-defi-protocol.com/pools');
// Extract APY data using OCR if needed const poolData = await agent.executeAction({ type: 'browser', action: 'extractTableData', params: { selector: 'table.pools-table' } });
return poolData; } }, { name: 'Provide liquidity', action: async (pool) => { await browser.navigate(`https://example-defi-protocol.com/pools/${pool.id}`);
// Enter amount await agent.executeAction({ type: 'browser', action: 'typeText', params: { selector: 'input[placeholder="Enter amount"]', text: pool.amount } });
// Click approve button await agent.executeAction({ type: 'browser', action: 'clickElement', params: { selector: 'button:contains("Approve")' } });
// Handle MetaMask transaction approval await agent.executeAction({ type: 'browser', action: 'handlePopup', params: { action: 'confirmTransaction', gasSettings: { useRecommended: true } } });
// Wait for approval transaction await agent.executeAction({ type: 'browser', action: 'waitForElement', params: { selector: 'button:contains("Supply")', state: 'enabled', timeout: 60000 } });
// Click supply button await agent.executeAction({ type: 'browser', action: 'clickElement', params: { selector: 'button:contains("Supply")' } });
// Handle MetaMask transaction confirmation await agent.executeAction({ type: 'browser', action: 'handlePopup', params: { action: 'confirmTransaction', gasSettings: { useRecommended: true } } });
// Wait for transaction to complete await agent.executeAction({ type: 'browser', action: 'waitForElement', params: { selector: 'div:contains("Transaction successful")', timeout: 120000 } }); } }, { name: 'Harvest rewards', action: async () => { await browser.navigate('https://example-defi-protocol.com/farm');
// Find pools with harvestable rewards const harvestableRows = await agent.executeAction({ type: 'browser', action: 'findElements', params: { selector: 'tr:has(button:contains("Harvest"))' } });
// Harvest each pool's rewards for (const row of harvestableRows) { await agent.executeAction({ type: 'browser', action: 'clickElement', params: { element: row, childSelector: 'button:contains("Harvest")' } });
// Handle MetaMask transaction confirmation await agent.executeAction({ type: 'browser', action: 'handlePopup', params: { action: 'confirmTransaction', gasSettings: { useRecommended: true } } });
// Wait for transaction to complete await agent.executeAction({ type: 'browser', action: 'waitForElement', params: { selector: 'div:contains("Transaction successful")', timeout: 120000 } }); } } }, { name: 'Compound rewards', action: async () => { await browser.navigate('https://example-defi-protocol.com/farm');
// Find pools with compound option const compoundableRows = await agent.executeAction({ type: 'browser', action: 'findElements', params: { selector: 'tr:has(button:contains("Compound"))' } });
// Compound each pool's rewards for (const row of compoundableRows) { await agent.executeAction({ type: 'browser', action: 'clickElement', params: { element: row, childSelector: 'button:contains("Compound")' } });
// Handle MetaMask transaction confirmation await agent.executeAction({ type: 'browser', action: 'handlePopup', params: { action: 'confirmTransaction', gasSettings: { useRecommended: true } } });
// Wait for transaction to complete await agent.executeAction({ type: 'browser', action: 'waitForElement', params: { selector: 'div:contains("Transaction successful")', timeout: 120000 } }); } } } ];
// Set up automated protocol interaction schedule const schedule = [ { task: 'Check liquidity pools', interval: 3600000, lastRun: 0 }, // Every hour { task: 'Harvest rewards', interval: 86400000, lastRun: 0 }, // Every day { task: 'Compound rewards', interval: 86400000, lastRun: 0 } // Every day ];
// Decision making function to determine best pools async function findBestPools(poolData) { // Sort pools by APY const sortedPools = [...poolData].sort((a, b) => parseFloat(b.apy) - parseFloat(a.apy));
// Filter out pools with too low liquidity const viablePools = sortedPools.filter(pool => parseFloat(pool.liquidity) > 100000);
// Return top 3 pools return viablePools.slice(0, 3); }
// Start the desktop await desktop.start();
// Main automation loop const automationInterval = setInterval(async () => { try { const now = Date.now();
// Check which tasks need to be run for (const item of schedule) { if (now - item.lastRun >= item.interval) { console.log(`Running task: ${item.task}`);
// Find the task const task = protocolTasks.find(t => t.name === item.task);
if (task) { if (task.name === 'Check liquidity pools') { // Get pool data const poolData = await task.action();
// Find best pools const bestPools = await findBestPools(poolData);
// Provide liquidity to best pools const provideLiquidity = protocolTasks.find(t => t.name === 'Provide liquidity'); if (provideLiquidity) { for (const pool of bestPools) { // Calculate optimal amount based on portfolio balance const amount = (parseFloat(pool.userBalance) * 0.3).toString(); await provideLiquidity.action({ id: pool.id, amount: amount }); } } } else { // Run other tasks await task.action(); }
// Update last run time item.lastRun = now; } } } } catch (error) { console.error('Automation error:', error);
// Take screenshot for debugging const screenshot = await browser.screenshot(); console.log('Error state screenshot saved');
// Try to recover by refreshing the page await browser.reload(); } }, 60000); // Check every minute
// Graceful shutdown process.on('SIGINT', async () => { clearInterval(automationInterval);
// Close browser await browser.close();
// Shutdown desktop await desktop.shutdown(); process.exit(0); });}
createCryptoProtocolBot().catch(console.error);
import osimport timeimport signalimport asynciofrom codecflow import CodecFlow
async def create_crypto_protocol_bot(): # Initialize CodecFlow with secure API key codecflow = CodecFlow( api_key=os.environ.get('CODECFLOW_API_KEY') )
# Create a secure desktop with TEE for crypto operations desktop = await codecflow.create_desktop( os='linux', # Linux is sufficient for browser-based operations version='ubuntu-22.04', security={ 'tee_enabled': True, 'encrypted_storage': True, 'isolation_level': 'high' }, resources={ 'memory': '8gb', 'cpu': 4 } )
# Connect AI agent with MCP for web automation agent = await desktop.connect_agent( model='gpt-4', protocol='mcp', config={ 'capabilities': ['browser', 'network', 'ocr', 'screenshot'], 'context_providers': [ { 'type': 'web-elements', 'recognition_level': 'high' } ] } )
# Create browser for protocol interactions browser = await desktop.create_browser( user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', viewport={'width': 1920, 'height': 1080} )
# Connect wallet (using browser extension) await browser.navigate('chrome://extensions')
# Install MetaMask or other wallet extension await agent.execute_action({ 'type': 'browser', 'action': 'install_extension', 'params': { 'extension_id': 'nkbihfbeogaeaoehlefnkodbefgpgknn' # MetaMask extension ID } })
# Set up wallet with credentials stored in TEE await browser.navigate('chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/home.html')
# Import wallet using secure credentials await agent.execute_action({ 'type': 'browser', 'action': 'click_element', 'params': { 'selector': 'button:contains("Import wallet")' } })
# Enter seed phrase securely from TEE await agent.execute_action({ 'type': 'browser', 'action': 'type_text', 'params': { 'selector': 'textarea', 'text': os.environ.get('WALLET_SEED_PHRASE') } })
# Enter password await agent.execute_action({ 'type': 'browser', 'action': 'type_text', 'params': { 'selector': 'input[type="password"]', 'text': os.environ.get('WALLET_PASSWORD') } })
# Confirm password await agent.execute_action({ 'type': 'browser', 'action': 'type_text', 'params': { 'selector': 'input[type="password"]:nth-of-type(2)', 'text': os.environ.get('WALLET_PASSWORD') } })
# Accept terms await agent.execute_action({ 'type': 'browser', 'action': 'click_element', 'params': { 'selector': 'input[type="checkbox"]' } })
# Import wallet await agent.execute_action({ 'type': 'browser', 'action': 'click_element', 'params': { 'selector': 'button:contains("Import")' } })
# Wait for wallet setup to complete await agent.execute_action({ 'type': 'browser', 'action': 'wait_for_navigation', 'params': { 'timeout': 30000 } })
# Navigate to DeFi protocol await browser.navigate('https://example-defi-protocol.com')
# Connect wallet to the protocol await agent.execute_action({ 'type': 'browser', 'action': 'click_element', 'params': { 'selector': 'button:contains("Connect Wallet")' } })
# Select MetaMask await agent.execute_action({ 'type': 'browser', 'action': 'click_element', 'params': { 'selector': 'div:contains("MetaMask")' } })
# Handle MetaMask popup await agent.execute_action({ 'type': 'browser', 'action': 'handle_popup', 'params': { 'action': 'approve' } })
# Define protocol interaction tasks async def check_liquidity_pools(): await browser.navigate('https://example-defi-protocol.com/pools')
# Extract APY data using OCR if needed pool_data = await agent.execute_action({ 'type': 'browser', 'action': 'extract_table_data', 'params': { 'selector': 'table.pools-table' } })
return pool_data
async def provide_liquidity(pool): await browser.navigate(f'https://example-defi-protocol.com/pools/{pool["id"]}')
# Enter amount await agent.execute_action({ 'type': 'browser', 'action': 'type_text', 'params': { 'selector': 'input[placeholder="Enter amount"]', 'text': pool['amount'] } })
# Click approve button await agent.execute_action({ 'type': 'browser', 'action': 'click_element', 'params': { 'selector': 'button:contains("Approve")' } })
# Handle MetaMask transaction approval await agent.execute_action({ 'type': 'browser', 'action': 'handle_popup', 'params': { 'action': 'confirm_transaction', 'gas_settings': { 'use_recommended': True } } })
# Wait for approval transaction await agent.execute_action({ 'type': 'browser', 'action': 'wait_for_element', 'params': { 'selector': 'button:contains("Supply")', 'state': 'enabled', 'timeout': 60000 } })
# Click supply button await agent.execute_action({ 'type': 'browser', 'action': 'click_element', 'params': { 'selector': 'button:contains("Supply")' } })
# Handle MetaMask transaction confirmation await agent.execute_action({ 'type': 'browser', 'action': 'handle_popup', 'params': { 'action': 'confirm_transaction', 'gas_settings': { 'use_recommended': True } } })
# Wait for transaction to complete await agent.execute_action({ 'type': 'browser', 'action': 'wait_for_element', 'params': { 'selector': 'div:contains("Transaction successful")', 'timeout': 120000 } })
async def harvest_rewards(): await browser.navigate('https://example-defi-protocol.com/farm')
# Find pools with harvestable rewards harvestable_rows = await agent.execute_action({ 'type': 'browser', 'action': 'find_elements', 'params': { 'selector': 'tr:has(button:contains("Harvest"))' } })
# Harvest each pool's rewards for row in harvestable_rows: await agent.execute_action({ 'type': 'browser', 'action': 'click_element', 'params': { 'element': row, 'child_selector': 'button:contains("Harvest")' } })
# Handle MetaMask transaction confirmation await agent.execute_action({ 'type': 'browser', 'action': 'handle_popup', 'params': { 'action': 'confirm_transaction', 'gas_settings': { 'use_recommended': True } } })
# Wait for transaction to complete await agent.execute_action({ 'type': 'browser', 'action': 'wait_for_element', 'params': { 'selector': 'div:contains("Transaction successful")', 'timeout': 120000 } })
async def compound_rewards(): await browser.navigate('https://example-defi-protocol.com/farm')
# Find pools with compound option compoundable_rows = await agent.execute_action({ 'type': 'browser', 'action': 'find_elements', 'params': { 'selector': 'tr:has(button:contains("Compound"))' } })
# Compound each pool's rewards for row in compoundable_rows: await agent.execute_action({ 'type': 'browser', 'action': 'click_element', 'params': { 'element': row, 'child_selector': 'button:contains("Compound")' } })
# Handle MetaMask transaction confirmation await agent.execute_action({ 'type': 'browser', 'action': 'handle_popup', 'params': { 'action': 'confirm_transaction', 'gas_settings': { 'use_recommended': True } } })
# Wait for transaction to complete await agent.execute_action({ 'type': 'browser', 'action': 'wait_for_element', 'params': { 'selector': 'div:contains("Transaction successful")', 'timeout': 120000 } })
# Map task names to functions protocol_tasks = { 'Check liquidity pools': check_liquidity_pools, 'Provide liquidity': provide_liquidity, 'Harvest rewards': harvest_rewards, 'Compound rewards': compound_rewards }
# Set up automated protocol interaction schedule schedule = [ {'task': 'Check liquidity pools', 'interval': 3600, 'last_run': 0}, # Every hour {'task': 'Harvest rewards', 'interval': 86400, 'last_run': 0}, # Every day {'task': 'Compound rewards', 'interval': 86400, 'last_run': 0} # Every day ]
# Decision making function to determine best pools async def find_best_pools(pool_data): # Sort pools by APY sorted_pools = sorted(pool_data, key=lambda x: float(x['apy']), reverse=True)
# Filter out pools with too low liquidity viable_pools = [p for p in sorted_pools if float(p['liquidity']) > 100000]
# Return top 3 pools return viable_pools[:3]
# Start the desktop await desktop.start()
# Main automation loop async def automation_loop(): while True: try: now = time.time()
# Check which tasks need to be run for item in schedule: if now - item['last_run'] >= item['interval']: print(f"Running task: {item['task']}")
# Find the task task_func = protocol_tasks.get(item['task'])
if task_func: if item['task'] == 'Check liquidity pools': # Get pool data pool_data = await task_func()
# Find best pools best_pools = await find_best_pools(pool_data)
# Provide liquidity to best pools provide_liquidity_func = protocol_tasks.get('Provide liquidity') if provide_liquidity_func: for pool in best_pools: # Calculate optimal amount based on portfolio balance amount = str(float(pool['user_balance']) * 0.3) await provide_liquidity_func({ 'id': pool['id'], 'amount': amount }) else: # Run other tasks await task_func()
# Update last run time item['last_run'] = now
# Wait before next check await asyncio.sleep(60) # Check every minute
except Exception as error: print(f'Automation error: {error}')
# Take screenshot for debugging screenshot = await browser.screenshot() print('Error state screenshot saved')
# Try to recover by refreshing the page await browser.reload()
# Wait before retry await asyncio.sleep(60)
# Start automation loop automation_task = asyncio.create_task(automation_loop())
# Graceful shutdown def handle_shutdown(sig, frame): # Cancel automation loop automation_task.cancel()
# Close browser await browser.close()
# Shutdown desktop await desktop.shutdown() exit(0)
signal.signal(signal.SIGINT, handle_shutdown)
# Keep the script running try: # Wait indefinitely await asyncio.Future() except asyncio.CancelledError: pass
# Run the crypto protocol botasyncio.run(create_crypto_protocol_bot())
Key Features
Section titled “Key Features”- Web Protocol Automation: Automates interactions with DeFi protocols that only offer web interfaces
- Wallet Integration: Securely manages crypto wallet connections using browser extensions
- Transaction Handling: Automatically approves and confirms blockchain transactions
- Yield Optimization: Analyzes APY rates and automatically allocates funds to the best pools
- Secure Credentials: Uses TEE to protect sensitive wallet seed phrases and passwords
- Error Recovery: Automatically detects and recovers from failed transactions or UI changes
Note: This example demonstrates how CodecFlow’s cloud desktops can automate web-based crypto protocol interactions that would typically require manual intervention. This is particularly valuable in DeFi where optimal yields often require frequent manual interactions with various protocol websites.