diff --git a/apps/blockchain-node/data/chain.db-journal b/apps/blockchain-node/data/chain.db-journal new file mode 100644 index 00000000..70fbcfce Binary files /dev/null and b/apps/blockchain-node/data/chain.db-journal differ diff --git a/apps/blockchain-node/data/devnet/genesis.json b/apps/blockchain-node/data/devnet/genesis.json index 239dbe9d..0ab64e7e 100644 --- a/apps/blockchain-node/data/devnet/genesis.json +++ b/apps/blockchain-node/data/devnet/genesis.json @@ -19,5 +19,5 @@ "fee_per_byte": 1, "mint_per_unit": 1000 }, - "timestamp": 1766828620 + "timestamp": 1767000206 } diff --git a/apps/coordinator-api/src/app/routers/exchange.py b/apps/coordinator-api/src/app/routers/exchange.py index 4d4ca148..86946211 100644 --- a/apps/coordinator-api/src/app/routers/exchange.py +++ b/apps/coordinator-api/src/app/routers/exchange.py @@ -4,15 +4,13 @@ Bitcoin Exchange Router for AITBC from typing import Dict, Any from fastapi import APIRouter, HTTPException, BackgroundTasks -from sqlmodel import Session import uuid import time import json import os -from ..deps import SessionDep -from ..domain import Wallet from ..schemas import ExchangePaymentRequest, ExchangePaymentResponse +from ..services.bitcoin_wallet import get_wallet_balance, get_wallet_info router = APIRouter(tags=["exchange"]) @@ -31,7 +29,6 @@ BITCOIN_CONFIG = { @router.post("/exchange/create-payment", response_model=ExchangePaymentResponse) async def create_payment( request: ExchangePaymentRequest, - session: SessionDep, background_tasks: BackgroundTasks ) -> Dict[str, Any]: """Create a new Bitcoin payment request""" @@ -88,8 +85,7 @@ async def get_payment_status(payment_id: str) -> Dict[str, Any]: @router.post("/exchange/confirm-payment/{payment_id}") async def confirm_payment( payment_id: str, - tx_hash: str, - session: SessionDep + tx_hash: str ) -> Dict[str, Any]: """Confirm payment (webhook from payment processor)""" @@ -132,6 +128,48 @@ async def get_exchange_rates() -> Dict[str, float]: 'fee_percent': 0.5 } +@router.get("/exchange/market-stats") +async def get_market_stats() -> Dict[str, Any]: + """Get market statistics""" + + # Calculate 24h volume from payments + current_time = int(time.time()) + yesterday_time = current_time - 24 * 60 * 60 # 24 hours ago + + daily_volume = 0 + for payment in payments.values(): + if payment['status'] == 'confirmed' and payment.get('confirmed_at', 0) > yesterday_time: + daily_volume += payment['aitbc_amount'] + + # Calculate price change (simulated) + base_price = 1.0 / BITCOIN_CONFIG['exchange_rate'] + price_change_percent = 5.2 # Simulated +5.2% + + return { + 'price': base_price, + 'price_change_24h': price_change_percent, + 'daily_volume': daily_volume, + 'daily_volume_btc': daily_volume / BITCOIN_CONFIG['exchange_rate'], + 'total_payments': len([p for p in payments.values() if p['status'] == 'confirmed']), + 'pending_payments': len([p for p in payments.values() if p['status'] == 'pending']) + } + +@router.get("/exchange/wallet/balance") +async def get_wallet_balance_api() -> Dict[str, Any]: + """Get Bitcoin wallet balance""" + try: + return get_wallet_balance() + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + +@router.get("/exchange/wallet/info") +async def get_wallet_info_api() -> Dict[str, Any]: + """Get comprehensive wallet information""" + try: + return get_wallet_info() + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + async def monitor_payment(payment_id: str): """Monitor payment for confirmation (background task)""" diff --git a/apps/coordinator-api/src/app/services/bitcoin_wallet.py b/apps/coordinator-api/src/app/services/bitcoin_wallet.py new file mode 100644 index 00000000..d582aff1 --- /dev/null +++ b/apps/coordinator-api/src/app/services/bitcoin_wallet.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python3 +""" +Bitcoin Wallet Integration for AITBC Exchange +Uses RPC to connect to Bitcoin Core (or alternative like Block.io) +""" + +import os +import json +import requests +from typing import Dict, Optional + +# Bitcoin wallet configuration +WALLET_CONFIG = { + # For development, we'll use testnet + 'testnet': True, + 'rpc_url': 'http://127.0.0.1:18332', # Testnet RPC port + 'rpc_user': 'aitbc_rpc', + 'rpc_password': 'REDACTED_RPC_PASSWORD', + 'wallet_name': 'aitbc_exchange', + 'fallback_address': 'tb1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh' # Testnet address +} + +class BitcoinWallet: + def __init__(self): + self.config = WALLET_CONFIG + self.session = requests.Session() + self.session.auth = (self.config['rpc_user'], self.config['rpc_password']) + + def get_balance(self) -> float: + """Get the current Bitcoin balance""" + try: + result = self._rpc_call('getbalance', ["*", 0, False]) + if result.get('error') is not None: + print(f"Bitcoin RPC error: {result['error']}") + return 0.0 + return result.get('result', 0.0) + except Exception as e: + print(f"Failed to get balance: {e}") + return 0.0 + + def get_new_address(self) -> str: + """Generate a new Bitcoin address for deposits""" + try: + result = self._rpc_call('getnewaddress', ["", "bech32"]) + if result.get('error') is not None: + print(f"Bitcoin RPC error: {result['error']}") + return self.config['fallback_address'] + return result.get('result', self.config['fallback_address']) + except Exception as e: + print(f"Failed to get new address: {e}") + return self.config['fallback_address'] + + def list_transactions(self, count: int = 10) -> list: + """List recent transactions""" + try: + result = self._rpc_call('listtransactions', ["*", count, 0, True]) + if result.get('error') is not None: + print(f"Bitcoin RPC error: {result['error']}") + return [] + return result.get('result', []) + except Exception as e: + print(f"Failed to list transactions: {e}") + return [] + + def _rpc_call(self, method: str, params: list = None) -> Dict: + """Make an RPC call to Bitcoin Core""" + if params is None: + params = [] + + payload = { + "jsonrpc": "2.0", + "id": 1, + "method": method, + "params": params + } + + try: + response = self.session.post( + self.config['rpc_url'], + json=payload, + timeout=30 + ) + response.raise_for_status() + return response.json() + except Exception as e: + print(f"RPC call failed: {e}") + return {"error": str(e)} + +# Create a wallet instance +wallet = BitcoinWallet() + +# API endpoints for wallet integration +def get_wallet_balance() -> Dict[str, any]: + """Get wallet balance for API""" + balance = wallet.get_balance() + return { + "balance": balance, + "address": wallet.get_new_address(), + "testnet": wallet.config['testnet'] + } + +def get_wallet_info() -> Dict[str, any]: + """Get comprehensive wallet information""" + try: + wallet = BitcoinWallet() + # Test connection to Bitcoin Core + blockchain_info = wallet._rpc_call('getblockchaininfo') + is_connected = blockchain_info.get('error') is None and blockchain_info.get('result') is not None + + return { + "balance": wallet.get_balance(), + "address": wallet.get_new_address(), + "transactions": wallet.list_transactions(10), + "testnet": wallet.config['testnet'], + "wallet_type": "Bitcoin Core (Real)" if is_connected else "Bitcoin Core (Disconnected)", + "connected": is_connected, + "blocks": blockchain_info.get('result', {}).get('blocks', 0) if is_connected else 0 + } + except Exception as e: + print(f"Error getting wallet info: {e}") + return { + "balance": 0.0, + "address": "tb1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh", + "transactions": [], + "testnet": True, + "wallet_type": "Bitcoin Core (Error)", + "connected": False, + "blocks": 0 + } + +if __name__ == "__main__": + # Test the wallet integration + info = get_wallet_info() + print(json.dumps(info, indent=2)) diff --git a/apps/trade-exchange/admin.html b/apps/trade-exchange/admin.html new file mode 100644 index 00000000..18fcc98e --- /dev/null +++ b/apps/trade-exchange/admin.html @@ -0,0 +1,316 @@ + + +
+ + +The secure wallet for AITBC tokens
+ + + Download XPI File + + +about:debugging in the address bar+ After installation, click the AITBC icon in your toolbar to create or import a wallet. +
+