Skip to main content
Glama

ONEDeFi MCP Server

by JMadhan1
routes.py•14.5 kB
import os import json import logging from flask import render_template, request, jsonify, session from app import app, db from models import User, Wallet, Transaction, Portfolio, ProtocolPosition from utils.validation import validate_api_key, validate_address from defi_tools.dex_operations import DexOperations from defi_tools.lending import LendingOperations from defi_tools.yield_farming import YieldFarmingOperations from defi_tools.portfolio import PortfolioManager logger = logging.getLogger(__name__) # Initialize DeFi tools dex_ops = DexOperations() lending_ops = LendingOperations() yield_ops = YieldFarmingOperations() portfolio_mgr = PortfolioManager() @app.route('/') def index(): """Main landing page""" return render_template('index.html') @app.route('/dashboard') def dashboard(): """Dashboard for monitoring DeFi operations""" return render_template('dashboard.html') @app.route('/api/docs') def api_docs(): """API documentation page""" return render_template('api_docs.html') # API Routes with authentication def require_api_key(f): def decorated_function(*args, **kwargs): api_key = request.headers.get('X-API-Key') if not api_key: return jsonify({"error": "API key required"}), 401 user = User.query.filter_by(api_key=api_key, is_active=True).first() if not user: return jsonify({"error": "Invalid API key"}), 401 request.current_user = user return f(*args, **kwargs) decorated_function.__name__ = f.__name__ return decorated_function @app.route('/api/v1/swap', methods=['POST']) @require_api_key def api_swap(): """Execute DEX swap operation""" try: data = request.get_json() # Validate required fields required_fields = ['wallet_address', 'blockchain', 'token_in', 'token_out', 'amount_in'] for field in required_fields: if field not in data: return jsonify({"error": f"Missing required field: {field}"}), 400 # Validate wallet ownership wallet = Wallet.query.filter_by( address=data['wallet_address'], user_id=request.current_user.id, blockchain=data['blockchain'] ).first() if not wallet: return jsonify({"error": "Wallet not found or not owned by user"}), 404 # Execute swap result = dex_ops.execute_swap( blockchain=data['blockchain'], wallet_address=data['wallet_address'], token_in=data['token_in'], token_out=data['token_out'], amount_in=data['amount_in'], slippage=data.get('slippage', 0.5), protocol=data.get('protocol', 'uniswap') ) if result['success']: # Save transaction to database tx = Transaction( user_id=request.current_user.id, wallet_id=wallet.id, tx_hash=result['tx_hash'], blockchain=data['blockchain'], operation_type='swap', protocol=data.get('protocol', 'uniswap'), amount=data['amount_in'], token_in=data['token_in'], token_out=data['token_out'], gas_used=result.get('gas_used'), status='pending', metadata=result.get('metadata', {}) ) db.session.add(tx) db.session.commit() return jsonify(result) except Exception as e: logger.error(f"Swap operation failed: {str(e)}") return jsonify({"error": "Internal server error", "details": str(e)}), 500 @app.route('/api/v1/lend', methods=['POST']) @require_api_key def api_lend(): """Execute lending operation""" try: data = request.get_json() # Validate required fields required_fields = ['wallet_address', 'blockchain', 'protocol', 'token', 'amount'] for field in required_fields: if field not in data: return jsonify({"error": f"Missing required field: {field}"}), 400 # Validate wallet ownership wallet = Wallet.query.filter_by( address=data['wallet_address'], user_id=request.current_user.id, blockchain=data['blockchain'] ).first() if not wallet: return jsonify({"error": "Wallet not found or not owned by user"}), 404 # Execute lending operation result = lending_ops.lend_asset( blockchain=data['blockchain'], protocol=data['protocol'], wallet_address=data['wallet_address'], token=data['token'], amount=data['amount'] ) if result['success']: # Save transaction and position tx = Transaction( user_id=request.current_user.id, wallet_id=wallet.id, tx_hash=result['tx_hash'], blockchain=data['blockchain'], operation_type='lend', protocol=data['protocol'], amount=data['amount'], token_in=data['token'], gas_used=result.get('gas_used'), status='pending', metadata=result.get('metadata', {}) ) db.session.add(tx) # Create or update position position = ProtocolPosition.query.filter_by( user_id=request.current_user.id, wallet_id=wallet.id, protocol=data['protocol'], position_type='lending', token_address=data['token'] ).first() if position: # Update existing position current_amount = float(position.amount) new_amount = current_amount + float(data['amount']) position.amount = str(new_amount) else: # Create new position position = ProtocolPosition( user_id=request.current_user.id, wallet_id=wallet.id, protocol=data['protocol'], position_type='lending', token_address=data['token'], token_symbol=result.get('token_symbol', ''), amount=data['amount'], blockchain=data['blockchain'], metadata=result.get('metadata', {}) ) db.session.add(position) db.session.commit() return jsonify(result) except Exception as e: logger.error(f"Lending operation failed: {str(e)}") return jsonify({"error": "Internal server error", "details": str(e)}), 500 @app.route('/api/v1/farm', methods=['POST']) @require_api_key def api_farm(): """Execute yield farming operation""" try: data = request.get_json() # Validate required fields required_fields = ['wallet_address', 'blockchain', 'protocol', 'pool_id', 'token_a', 'token_b', 'amount_a', 'amount_b'] for field in required_fields: if field not in data: return jsonify({"error": f"Missing required field: {field}"}), 400 # Validate wallet ownership wallet = Wallet.query.filter_by( address=data['wallet_address'], user_id=request.current_user.id, blockchain=data['blockchain'] ).first() if not wallet: return jsonify({"error": "Wallet not found or not owned by user"}), 404 # Execute yield farming operation result = yield_ops.add_liquidity( blockchain=data['blockchain'], protocol=data['protocol'], wallet_address=data['wallet_address'], pool_id=data['pool_id'], token_a=data['token_a'], token_b=data['token_b'], amount_a=data['amount_a'], amount_b=data['amount_b'] ) if result['success']: # Save transaction and position tx = Transaction( user_id=request.current_user.id, wallet_id=wallet.id, tx_hash=result['tx_hash'], blockchain=data['blockchain'], operation_type='farm', protocol=data['protocol'], amount=f"{data['amount_a']},{data['amount_b']}", token_in=f"{data['token_a']},{data['token_b']}", gas_used=result.get('gas_used'), status='pending', metadata=result.get('metadata', {}) ) db.session.add(tx) # Create farming position position = ProtocolPosition( user_id=request.current_user.id, wallet_id=wallet.id, protocol=data['protocol'], position_type='farming', token_address=data['pool_id'], token_symbol=f"{result.get('token_a_symbol', '')}-{result.get('token_b_symbol', '')}", amount=result.get('lp_tokens', '0'), blockchain=data['blockchain'], metadata={ 'pool_id': data['pool_id'], 'token_a': data['token_a'], 'token_b': data['token_b'], 'amount_a': data['amount_a'], 'amount_b': data['amount_b'] } ) db.session.add(position) db.session.commit() return jsonify(result) except Exception as e: logger.error(f"Yield farming operation failed: {str(e)}") return jsonify({"error": "Internal server error", "details": str(e)}), 500 @app.route('/api/v1/portfolio/<wallet_address>') @require_api_key def api_portfolio(wallet_address): """Get portfolio information for a wallet""" try: # Validate wallet ownership wallet = Wallet.query.filter_by( address=wallet_address, user_id=request.current_user.id ).first() if not wallet: return jsonify({"error": "Wallet not found or not owned by user"}), 404 # Get portfolio data portfolio_data = portfolio_mgr.get_portfolio(wallet_address, wallet.blockchain) return jsonify(portfolio_data) except Exception as e: logger.error(f"Portfolio fetch failed: {str(e)}") return jsonify({"error": "Internal server error", "details": str(e)}), 500 @app.route('/api/v1/positions/<wallet_address>') @require_api_key def api_positions(wallet_address): """Get DeFi positions for a wallet""" try: # Validate wallet ownership wallet = Wallet.query.filter_by( address=wallet_address, user_id=request.current_user.id ).first() if not wallet: return jsonify({"error": "Wallet not found or not owned by user"}), 404 # Get positions from database positions = ProtocolPosition.query.filter_by(wallet_id=wallet.id).all() positions_data = [] for pos in positions: positions_data.append({ 'id': pos.id, 'protocol': pos.protocol, 'position_type': pos.position_type, 'token_symbol': pos.token_symbol, 'amount': pos.amount, 'apy': pos.apy, 'rewards_earned': pos.rewards_earned, 'blockchain': pos.blockchain, 'created_at': pos.created_at.isoformat(), 'metadata': pos.metadata }) return jsonify({ "wallet_address": wallet_address, "positions": positions_data, "total_positions": len(positions_data) }) except Exception as e: logger.error(f"Positions fetch failed: {str(e)}") return jsonify({"error": "Internal server error", "details": str(e)}), 500 @app.route('/api/v1/transactions/<wallet_address>') @require_api_key def api_transactions(wallet_address): """Get transaction history for a wallet""" try: # Validate wallet ownership wallet = Wallet.query.filter_by( address=wallet_address, user_id=request.current_user.id ).first() if not wallet: return jsonify({"error": "Wallet not found or not owned by user"}), 404 # Get transactions page = request.args.get('page', 1, type=int) per_page = request.args.get('per_page', 50, type=int) transactions = Transaction.query.filter_by(wallet_id=wallet.id)\ .order_by(Transaction.created_at.desc())\ .paginate(page=page, per_page=per_page, error_out=False) tx_data = [] for tx in transactions.items: tx_data.append({ 'id': tx.id, 'tx_hash': tx.tx_hash, 'blockchain': tx.blockchain, 'operation_type': tx.operation_type, 'protocol': tx.protocol, 'amount': tx.amount, 'token_in': tx.token_in, 'token_out': tx.token_out, 'gas_used': tx.gas_used, 'status': tx.status, 'created_at': tx.created_at.isoformat(), 'confirmed_at': tx.confirmed_at.isoformat() if tx.confirmed_at else None, 'metadata': tx.metadata }) return jsonify({ "wallet_address": wallet_address, "transactions": tx_data, "pagination": { "page": page, "per_page": per_page, "total": transactions.total, "pages": transactions.pages } }) except Exception as e: logger.error(f"Transactions fetch failed: {str(e)}") return jsonify({"error": "Internal server error", "details": str(e)}), 500 @app.errorhandler(404) def not_found(error): return jsonify({"error": "Endpoint not found"}), 404 @app.errorhandler(500) def internal_error(error): return jsonify({"error": "Internal server error"}), 500

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/JMadhan1/OneDefi-MCP'

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