
Features implemented: - User authentication with JWT tokens and role-based access (developer/buyer) - Blockchain wallet linking and management with Ethereum integration - Carbon project creation and management for developers - Marketplace for browsing and purchasing carbon offsets - Transaction tracking with blockchain integration - Database models for users, projects, offsets, and transactions - Comprehensive API with authentication, wallet, project, and trading endpoints - Health check endpoint and platform information - SQLite database with Alembic migrations - Full API documentation with OpenAPI/Swagger Technical stack: - FastAPI with Python - SQLAlchemy ORM with SQLite - Web3.py for blockchain integration - JWT authentication with bcrypt - CORS enabled for frontend integration - Comprehensive error handling and validation Environment variables required: - SECRET_KEY (JWT secret) - BLOCKCHAIN_RPC_URL (optional, defaults to localhost)
130 lines
4.1 KiB
Python
130 lines
4.1 KiB
Python
from sqlalchemy.orm import Session
|
|
from app.models.user import User
|
|
from app.services.blockchain import blockchain_service
|
|
from typing import Optional, Dict, Any
|
|
|
|
class WalletService:
|
|
|
|
def link_wallet(self, db: Session, user_id: int, wallet_address: str) -> Dict[str, Any]:
|
|
"""Link a wallet address to a user account"""
|
|
|
|
# Validate wallet address format
|
|
if not blockchain_service.validate_wallet_address(wallet_address):
|
|
return {
|
|
"success": False,
|
|
"message": "Invalid wallet address format"
|
|
}
|
|
|
|
# Check if wallet is already linked to another user
|
|
existing_user = db.query(User).filter(
|
|
User.wallet_address == wallet_address,
|
|
User.id != user_id
|
|
).first()
|
|
|
|
if existing_user:
|
|
return {
|
|
"success": False,
|
|
"message": "Wallet address is already linked to another account"
|
|
}
|
|
|
|
# Get user
|
|
user = db.query(User).filter(User.id == user_id).first()
|
|
if not user:
|
|
return {
|
|
"success": False,
|
|
"message": "User not found"
|
|
}
|
|
|
|
# Update user wallet information
|
|
user.wallet_address = wallet_address
|
|
user.wallet_public_key = wallet_address # In Ethereum, address is derived from public key
|
|
|
|
try:
|
|
db.commit()
|
|
return {
|
|
"success": True,
|
|
"message": "Wallet linked successfully",
|
|
"wallet_address": wallet_address
|
|
}
|
|
except Exception as e:
|
|
db.rollback()
|
|
return {
|
|
"success": False,
|
|
"message": f"Database error: {str(e)}"
|
|
}
|
|
|
|
def unlink_wallet(self, db: Session, user_id: int) -> Dict[str, Any]:
|
|
"""Unlink wallet from user account"""
|
|
|
|
user = db.query(User).filter(User.id == user_id).first()
|
|
if not user:
|
|
return {
|
|
"success": False,
|
|
"message": "User not found"
|
|
}
|
|
|
|
if not user.wallet_address:
|
|
return {
|
|
"success": False,
|
|
"message": "No wallet linked to this account"
|
|
}
|
|
|
|
# Clear wallet information
|
|
user.wallet_address = None
|
|
user.wallet_public_key = None
|
|
|
|
try:
|
|
db.commit()
|
|
return {
|
|
"success": True,
|
|
"message": "Wallet unlinked successfully"
|
|
}
|
|
except Exception as e:
|
|
db.rollback()
|
|
return {
|
|
"success": False,
|
|
"message": f"Database error: {str(e)}"
|
|
}
|
|
|
|
def get_wallet_info(self, db: Session, user_id: int) -> Dict[str, Any]:
|
|
"""Get wallet information for a user"""
|
|
|
|
user = db.query(User).filter(User.id == user_id).first()
|
|
if not user:
|
|
return {
|
|
"success": False,
|
|
"message": "User not found"
|
|
}
|
|
|
|
if not user.wallet_address:
|
|
return {
|
|
"success": True,
|
|
"wallet_linked": False,
|
|
"wallet_address": None,
|
|
"balance": None
|
|
}
|
|
|
|
# Get wallet balance from blockchain
|
|
balance = blockchain_service.get_wallet_balance(user.wallet_address)
|
|
|
|
return {
|
|
"success": True,
|
|
"wallet_linked": True,
|
|
"wallet_address": user.wallet_address,
|
|
"balance": balance
|
|
}
|
|
|
|
def generate_test_wallet(self) -> Dict[str, Any]:
|
|
"""Generate a test wallet for development purposes"""
|
|
|
|
wallet_data = blockchain_service.generate_wallet()
|
|
|
|
return {
|
|
"success": True,
|
|
"message": "Test wallet generated successfully",
|
|
"wallet_data": wallet_data,
|
|
"warning": "This is for testing only. Keep private key secure!"
|
|
}
|
|
|
|
# Global instance
|
|
wallet_service = WalletService() |