From ee22bba246440720d5c331d271db7dfc4559ac7e Mon Sep 17 00:00:00 2001 From: aitbc Date: Tue, 19 May 2026 18:23:14 +0200 Subject: [PATCH] refactor: remove website directory - migrate to separate repository - Deleted website/ directory containing static site, docs, and dashboards - Removed 16 HTML documentation pages (index, clients, miners, developers, API reference, etc.) - Removed browser wallet redirect page and agent endpoints (.htaccess) - Deleted nginx proxy config example and README - Removed admin, client, and miner dashboard HTML files - Cleaned up static assets (CSS, JS, SVG, fonts) - Website content moved to dedicated repository for --- .../src/app/core/config/__init__.py | 0 cli/aitbc_cli.legacy.py | 3256 +++++++++++++++++ .../config/chain_isolation_alerts.yml | 47 + website/BrowserWallet/index.html | 59 - website/README.md.example | 54 - website/agent/.htaccess | 44 - website/aitbc-proxy.conf.example | 60 - website/dashboards/admin-dashboard.html | 253 -- website/dashboards/metrics.html | 312 -- website/dashboards/miner-dashboard.html | 210 -- website/docs/README.md | 60 - website/docs/api.html | 203 - website/docs/blockchain-node.html | 193 - website/docs/browser-wallet.html | 14 - website/docs/clients.html | 443 --- website/docs/components.html | 199 - website/docs/coordinator-api.html | 245 -- website/docs/css/docs.css | 1870 ---------- website/docs/developers.html | 505 --- website/docs/explorer-web.html | 203 - website/docs/flowchart.html | 486 --- website/docs/full-documentation.html | 648 ---- website/docs/index.html | 232 -- website/docs/js/theme.js | 54 - website/docs/marketplace-web.html | 260 -- website/docs/miners.html | 375 -- website/docs/pool-hub.html | 259 -- website/docs/trade-exchange.html | 259 -- website/docs/wallet-daemon.html | 209 -- website/extensions/aitbc-wallet-firefox.zip | Bin 6968 -> 0 bytes website/extensions/aitbc-wallet.zip | Bin 5182 -> 0 bytes website/font-awesome-local.css | 84 - website/index.html | 626 ++-- website/wallet/index.html | 358 -- 34 files changed, 3576 insertions(+), 8504 deletions(-) create mode 100644 apps/shared-core/src/app/core/config/__init__.py create mode 100755 cli/aitbc_cli.legacy.py create mode 100644 scripts/monitoring/config/chain_isolation_alerts.yml delete mode 100644 website/BrowserWallet/index.html delete mode 100644 website/README.md.example delete mode 100644 website/agent/.htaccess delete mode 100644 website/aitbc-proxy.conf.example delete mode 100644 website/dashboards/admin-dashboard.html delete mode 100644 website/dashboards/metrics.html delete mode 100644 website/dashboards/miner-dashboard.html delete mode 100644 website/docs/README.md delete mode 100644 website/docs/api.html delete mode 100644 website/docs/blockchain-node.html delete mode 100644 website/docs/browser-wallet.html delete mode 100644 website/docs/clients.html delete mode 100644 website/docs/components.html delete mode 100644 website/docs/coordinator-api.html delete mode 100644 website/docs/css/docs.css delete mode 100644 website/docs/developers.html delete mode 100644 website/docs/explorer-web.html delete mode 100644 website/docs/flowchart.html delete mode 100644 website/docs/full-documentation.html delete mode 100644 website/docs/index.html delete mode 100644 website/docs/js/theme.js delete mode 100644 website/docs/marketplace-web.html delete mode 100644 website/docs/miners.html delete mode 100644 website/docs/pool-hub.html delete mode 100644 website/docs/trade-exchange.html delete mode 100644 website/docs/wallet-daemon.html delete mode 100644 website/extensions/aitbc-wallet-firefox.zip delete mode 100644 website/extensions/aitbc-wallet.zip delete mode 100644 website/font-awesome-local.css delete mode 100644 website/wallet/index.html diff --git a/apps/shared-core/src/app/core/config/__init__.py b/apps/shared-core/src/app/core/config/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cli/aitbc_cli.legacy.py b/cli/aitbc_cli.legacy.py new file mode 100755 index 00000000..b77a514e --- /dev/null +++ b/cli/aitbc_cli.legacy.py @@ -0,0 +1,3256 @@ +#!/usr/bin/env python3 +""" +AITBC CLI - Comprehensive Blockchain Management Tool +""" +import sys +from pathlib import Path + +# Add /opt/aitbc to Python path for shared modules +sys.path.insert(0, str(Path("/opt/aitbc"))) + +""" +Complete command-line interface for AITBC blockchain operations including: +- Wallet management +- Transaction processing +- Blockchain analytics +- Marketplace operations +- AI compute jobs +- Mining operations +- Network monitoring +""" + +import json +import sys +import os +import time +import datetime +import argparse +import random +import hashlib +import httpx +import subprocess +from pathlib import Path +from cryptography.hazmat.primitives.asymmetric import ed25519 +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.ciphers.aead import AESGCM +from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.backends import default_backend +import requests +from typing import Optional, Dict, Any, List + +# Import shared modules +from aitbc.aitbc_logging import get_logger +from aitbc import __version__ +from aitbc.constants import BLOCKCHAIN_RPC_PORT, DATA_DIR, KEYSTORE_DIR +from aitbc.exceptions import ConfigurationError, NetworkError, ValidationError +from aitbc.network.http_client import AITBCHTTPClient +from aitbc.utils.paths import get_blockchain_data_path, get_data_path +from aitbc.utils.paths import ensure_dir, get_keystore_path +from aitbc.utils.validation import validate_address, validate_url + +# Initialize logger +logger = get_logger(__name__) + +# Default paths +CLI_VERSION = __version__ +DEFAULT_KEYSTORE_DIR = KEYSTORE_DIR +DEFAULT_RPC_URL = f"http://localhost:{BLOCKCHAIN_RPC_PORT}" +DEFAULT_WALLET_DAEMON_URL = "http://localhost:8003" + +def decrypt_private_key(keystore_path: Path, password: str) -> str: + """Decrypt private key from keystore file. + + Supports both keystore formats: + - AES-256-GCM (blockchain-node standard) + - Fernet (scripts/utils standard) + """ + with open(keystore_path) as f: + ks = json.load(f) + + crypto = ks.get('crypto', ks) # Handle both nested and flat crypto structures + + # Detect encryption method + cipher = crypto.get('cipher', crypto.get('algorithm', '')) + + if cipher == 'aes-256-gcm' or cipher == 'aes-256-gcm': + # AES-256-GCM (blockchain-node standard) + salt = bytes.fromhex(crypto['kdfparams']['salt']) + kdf = PBKDF2HMAC( + algorithm=hashes.SHA256(), + length=32, + salt=salt, + iterations=crypto['kdfparams']['c'], + backend=default_backend() + ) + key = kdf.derive(password.encode()) + aesgcm = AESGCM(key) + nonce = bytes.fromhex(crypto['cipherparams']['nonce']) + priv = aesgcm.decrypt(nonce, bytes.fromhex(crypto['ciphertext']), None) + return priv.hex() + + elif cipher == 'fernet' or cipher == 'PBKDF2-SHA256-Fernet': + # Fernet (scripts/utils standard) + from cryptography.fernet import Fernet + import base64 + + # Derive Fernet key using the same method as scripts/utils/keystore.py + kdfparams = crypto.get('kdfparams', {}) + if 'salt' in kdfparams: + salt = base64.b64decode(kdfparams['salt']) + else: + # Fallback for older format + salt = bytes.fromhex(kdfparams.get('salt', '')) + + # Use PBKDF2 for secure key derivation (100,000 iterations for security) + dk = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, 100000, dklen=32) + fernet_key = base64.urlsafe_b64encode(dk) + + f = Fernet(fernet_key) + ciphertext = base64.b64decode(crypto['ciphertext']) + priv = f.decrypt(ciphertext) + return priv.decode() + + else: + raise ValueError(f"Unsupported cipher: {cipher}") + + +def create_wallet(name: str, password: str, keystore_dir: Path = DEFAULT_KEYSTORE_DIR) -> str: + """Create a new wallet using blockchain-node standard AES-256-GCM encryption""" + keystore_dir.mkdir(parents=True, exist_ok=True) + + # Generate new key pair + private_key = ed25519.Ed25519PrivateKey.generate() + private_key_hex = private_key.private_bytes_raw().hex() + public_key = private_key.public_key() + public_key_hex = public_key.public_bytes_raw().hex() + + # Calculate address (simplified - in real implementation this would be more complex) + address = f"ait1{public_key_hex[:40]}" + + # Encrypt private key using blockchain-node standard (AES-256-GCM with PBKDF2) + salt = os.urandom(32) + kdf = PBKDF2HMAC( + algorithm=hashes.SHA256(), + length=32, + salt=salt, + iterations=100_000, + backend=default_backend() + ) + key = kdf.derive(password.encode()) + aesgcm = AESGCM(key) + nonce = os.urandom(12) + ciphertext = aesgcm.encrypt(nonce, bytes.fromhex(private_key_hex), None) + + # Create keystore file matching blockchain-node format + keystore_data = { + "address": address, + "public_key": public_key_hex, + "crypto": { + "kdf": "pbkdf2", + "kdfparams": { + "salt": salt.hex(), + "c": 100_000, + "dklen": 32, + "prf": "hmac-sha256" + }, + "cipher": "aes-256-gcm", + "cipherparams": { + "nonce": nonce.hex() + }, + "ciphertext": ciphertext.hex() + }, + "keytype": "ed25519", + "version": 1 + } + + keystore_path = keystore_dir / f"{name}.json" + with open(keystore_path, 'w') as f: + json.dump(keystore_data, f, indent=2) + + print(f"Wallet created: {name}") + print(f"Address: {address}") + print(f"Keystore: {keystore_path}") + + return address + + +def send_transaction(from_wallet: str, to_address: str, amount: float, fee: float, + password: str, keystore_dir: Path = DEFAULT_KEYSTORE_DIR, + rpc_url: str = DEFAULT_RPC_URL) -> Optional[str]: + """Send transaction from one wallet to another""" + + # Validate recipient address + try: + validate_address(to_address) + except ValidationError as e: + logger.error(f"Invalid recipient address: {e}") + print(f"Error: Invalid recipient address: {e}") + return None + + # Validate amount + if amount <= 0: + logger.error(f"Invalid amount: {amount} must be positive") + print("Error: Amount must be positive") + return None + + # Ensure keystore_dir is a Path object + if keystore_dir is None: + keystore_dir = DEFAULT_KEYSTORE_DIR + if isinstance(keystore_dir, str): + keystore_dir = Path(keystore_dir) + + # Get sender wallet info + sender_keystore = keystore_dir / f"{from_wallet}.json" + if not sender_keystore.exists(): + print(f"Error: Wallet '{from_wallet}' not found") + return None + + with open(sender_keystore) as f: + sender_data = json.load(f) + + sender_address = sender_data['address'] + + # Decrypt private key + try: + private_key_hex = decrypt_private_key(sender_keystore, password) + private_key = ed25519.Ed25519PrivateKey.from_private_bytes(bytes.fromhex(private_key_hex)) + except Exception as e: + print(f"Error decrypting wallet: {e}") + return None + + # Get chain_id from RPC health endpoint or use override + from aitbc_cli.utils.chain_id import get_chain_id, get_default_chain_id + chain_id = get_chain_id(rpc_url, override=None, timeout=5) + + # Get actual nonce from blockchain + actual_nonce = 0 + try: + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=5) + account_data = http_client.get(f"/rpc/account/{sender_address}") + actual_nonce = account_data.get("nonce", 0) + except NetworkError: + actual_nonce = 0 + except Exception: + actual_nonce = 0 + + # Create transaction + transaction = { + "type": "TRANSFER", + "chain_id": chain_id, + "from": sender_address, + "nonce": actual_nonce, + "fee": int(fee), + "payload": { + "recipient": to_address, + "amount": int(amount) + } + } + + # Sign transaction + message = json.dumps(transaction, sort_keys=True).encode() + signature = private_key.sign(message) + transaction["signature"] = signature.hex() + + # Submit to blockchain + try: + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=30) + result = http_client.post("/rpc/transaction", json=transaction) + tx_hash = result.get("transaction_hash") + print(f"Transaction submitted: {tx_hash}") + logger.info(f"Transaction submitted: {tx_hash} from {from_wallet} to {to_address}") + return tx_hash + except NetworkError as e: + logger.error(f"Network error submitting transaction: {e}") + print(f"Error submitting transaction: {e}") + return None + except Exception as e: + logger.error(f"Error submitting transaction: {e}") + print(f"Error: {e}") + return None + + +def import_wallet(wallet_name: str, private_key_hex: str, password: str, + keystore_dir: Path = KEYSTORE_DIR) -> Optional[str]: + """Import wallet from private key""" + try: + ensure_dir(keystore_dir) + + # Validate and convert private key + try: + private_key_bytes = bytes.fromhex(private_key_hex) + private_key = ed25519.Ed25519PrivateKey.from_private_bytes(private_key_bytes) + except Exception as e: + print(f"Error: Invalid private key: {e}") + return None + + # Generate public key and address + public_key = private_key.public_key() + public_key_hex = public_key.public_bytes_raw().hex() + address = f"ait1{public_key_hex[:40]}" + + # Encrypt private key + salt = os.urandom(32) + kdf = PBKDF2HMAC(hashes.SHA256(), 32, salt, 100000) + key = kdf.derive(password.encode()) + aesgcm = AESGCM(key) + nonce = os.urandom(12) + ciphertext = aesgcm.encrypt(nonce, private_key_bytes, None) + + # Create keystore file + keystore_data = { + "address": address, + "public_key": public_key_hex, + "crypto": { + "kdf": "pbkdf2", + "kdfparams": { + "salt": salt.hex(), + "c": 100000, + "dklen": 32, + "prf": "hmac-sha256" + }, + "cipher": "aes-256-gcm", + "cipherparams": { + "nonce": nonce.hex() + }, + "ciphertext": ciphertext.hex() + }, + "version": 1 + } + + keystore_path = keystore_dir / f"{wallet_name}.json" + with open(keystore_path, 'w') as f: + json.dump(keystore_data, f, indent=2) + + print(f"Wallet imported: {wallet_name}") + print(f"Address: {address}") + logger.info(f"Imported wallet: {wallet_name} with address {address}") + print(f"Keystore: {keystore_path}") + + return address + except Exception as e: + print(f"Error importing wallet: {e}") + return None + + +def export_wallet(wallet_name: str, password: str, keystore_dir: Path = DEFAULT_KEYSTORE_DIR) -> Optional[str]: + """Export private key from wallet""" + try: + keystore_path = keystore_dir / f"{wallet_name}.json" + if not keystore_path.exists(): + print(f"Error: Wallet '{wallet_name}' not found") + return None + + return decrypt_private_key(keystore_path, password) + except Exception as e: + print(f"Error exporting wallet: {e}") + return None + + +def delete_wallet(wallet_name: str, keystore_dir: Path = DEFAULT_KEYSTORE_DIR) -> bool: + """Delete wallet""" + try: + keystore_path = keystore_dir / f"{wallet_name}.json" + if keystore_path.exists(): + keystore_path.unlink() + print(f"Wallet '{wallet_name}' deleted successfully") + return True + else: + print(f"Error: Wallet '{wallet_name}' not found") + return False + except Exception as e: + print(f"Error deleting wallet: {e}") + return False + + +def rename_wallet(old_name: str, new_name: str, keystore_dir: Path = DEFAULT_KEYSTORE_DIR) -> bool: + """Rename wallet""" + try: + old_path = keystore_dir / f"{old_name}.json" + new_path = keystore_dir / f"{new_name}.json" + + if not old_path.exists(): + print(f"Error: Wallet '{old_name}' not found") + return False + + if new_path.exists(): + print(f"Error: Wallet '{new_name}' already exists") + return False + + old_path.rename(new_path) + print(f"Wallet renamed from '{old_name}' to '{new_name}'") + return True + except Exception as e: + print(f"Error renaming wallet: {e}") + return False + + +def list_wallets(keystore_dir: Path = KEYSTORE_DIR, + use_daemon: bool = True, + daemon_url: str = DEFAULT_WALLET_DAEMON_URL) -> list: + """List all wallets""" + wallets = [] + + # Try to use wallet daemon first + if use_daemon: + try: + http_client = AITBCHTTPClient(base_url=daemon_url, timeout=5) + data = http_client.get("/v1/wallets") + wallet_list = data.get("items", data.get("wallets", [])) + for wallet_data in wallet_list: + wallets.append({ + "name": wallet_data.get("wallet_name", ""), + "address": wallet_data.get("address", ""), + "public_key": wallet_data.get("public_key", ""), + "source": "daemon" + }) + logger.info(f"Listed {len(wallets)} wallets from daemon") + return wallets + except NetworkError as e: + logger.warning(f"Failed to query wallet daemon: {e}, falling back to file-based listing") + print(f"Warning: Failed to query wallet daemon: {e}") + print("Falling back to file-based wallet listing...") + except Exception as e: + logger.warning(f"Failed to query wallet daemon: {e}, falling back to file-based listing") + print(f"Warning: Failed to query wallet daemon: {e}") + print("Falling back to file-based wallet listing...") + + # Fallback to file-based wallet listing + if keystore_dir.exists(): + for wallet_file in keystore_dir.glob("*.json"): + try: + with open(wallet_file) as f: + data = json.load(f) + wallets.append({ + "name": wallet_file.stem, + "address": data["address"], + "file": str(wallet_file), + "source": "file" + }) + except Exception: + pass + logger.info(f"Listed {len(wallets)} wallets from file-based fallback") + return wallets + + +def send_batch_transactions(transactions: List[Dict[str, Any]], password: str, + rpc_url: str = DEFAULT_RPC_URL) -> List[Optional[str]]: + """Send multiple transactions in batch""" + results = [] + + for tx in transactions: + try: + tx_hash = send_transaction( + tx['from_wallet'], + tx['to_address'], + tx['amount'], + tx.get('fee', 10.0), + password, + rpc_url + ) + results.append({ + 'transaction': tx, + 'hash': tx_hash, + 'success': tx_hash is not None + }) + + if tx_hash: + print(f"✅ Transaction sent: {tx['from_wallet']} → {tx['to_address']} ({tx['amount']} AIT)") + else: + print(f"❌ Transaction failed: {tx['from_wallet']} → {tx['to_address']}") + + except Exception as e: + results.append({ + 'transaction': tx, + 'hash': None, + 'success': False, + 'error': str(e) + }) + print(f"❌ Transaction error: {e}") + + return results + + +def estimate_transaction_fee(from_wallet: str, to_address: str, amount: float, + keystore_dir: Path = DEFAULT_KEYSTORE_DIR, + rpc_url: str = DEFAULT_RPC_URL) -> Optional[float]: + """Estimate transaction fee""" + try: + # Create a test transaction to estimate fee + test_tx = { + "sender": "", # Will be filled by actual sender + "recipient": to_address, + "value": int(amount), + "fee": 10, # Default fee + "nonce": 0, + "type": "transfer", + "payload": {} + } + + # Get fee estimation from RPC (if available) + try: + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=10) + fee_data = http_client.post("/rpc/estimateFee", json=test_tx) + return fee_data.get("estimated_fee", 10.0) + except NetworkError: + # Fallback to default fee + return 10.0 + except Exception as e: + print(f"Error estimating fee: {e}") + return 10.0 + + +def get_transaction_status(tx_hash: str, rpc_url: str = DEFAULT_RPC_URL) -> Optional[Dict]: + """Get detailed transaction status""" + try: + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=30) + return http_client.get(f"/rpc/transaction/{tx_hash}") + except NetworkError as e: + print(f"Error getting transaction status: {e}") + return None + + +def get_pending_transactions(rpc_url: str = DEFAULT_RPC_URL) -> List[Dict]: + """Get pending transactions in mempool""" + try: + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=30) + data = http_client.get("/rpc/pending") + return data.get("transactions", []) + except NetworkError as e: + print(f"Error getting pending transactions: {e}") + return [] + + +def start_mining(wallet_name: str, threads: int = 1, keystore_dir: Path = DEFAULT_KEYSTORE_DIR, + rpc_url: str = DEFAULT_RPC_URL) -> bool: + """Start mining with specified wallet""" + try: + # Get wallet address + keystore_path = keystore_dir / f"{wallet_name}.json" + if not keystore_path.exists(): + print(f"Error: Wallet '{wallet_name}' not found") + return False + + with open(keystore_path) as f: + wallet_data = json.load(f) + address = wallet_data['address'] + + # Start mining via RPC + mining_config = { + "miner_address": address, + "threads": threads, + "enabled": True + } + + try: + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=30) + result = http_client.post("/rpc/mining/start", json=mining_config) + print(f"Mining started with wallet '{wallet_name}'") + print(f"Miner address: {address}") + print(f"Threads: {threads}") + print(f"Status: {result.get('status', 'started')}") + return result + except NetworkError as e: + print(f"Error starting mining: {e}") + return None + except Exception as e: + print(f"Error: {e}") + return False + except Exception as e: + print(f"Error: {e}") + return False + + +def stop_mining(rpc_url: str = DEFAULT_RPC_URL) -> bool: + """Stop mining""" + try: + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=30) + result = http_client.post("/rpc/mining/stop") + print(f"Mining stopped") + print(f"Status: {result.get('status', 'stopped')}") + return True + except NetworkError as e: + print(f"Error stopping mining: {e}") + return False + except Exception as e: + print(f"Error: {e}") + return False + + +def get_mining_status(rpc_url: str = DEFAULT_RPC_URL) -> Optional[Dict]: + """Get mining status and statistics""" + try: + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=30) + return http_client.get("/rpc/mining/status") + except NetworkError as e: + print(f"Error getting mining status: {e}") + return None + + +def get_marketplace_listings(rpc_url: str = DEFAULT_RPC_URL) -> List[Dict]: + """Get marketplace listings""" + try: + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=30) + data = http_client.get("/rpc/marketplace/listings") + return data.get("listings", []) + except NetworkError as e: + print(f"Error getting marketplace listings: {e}") + return [] + except Exception as e: + print(f"Error: {e}") + return [] + + +def create_marketplace_listing(wallet_name: str, item_type: str, price: float, + description: str, password: str, + keystore_dir: Path = DEFAULT_KEYSTORE_DIR, + rpc_url: str = DEFAULT_RPC_URL) -> Optional[str]: + """Create marketplace listing""" + try: + # Get wallet address + keystore_path = keystore_dir / f"{wallet_name}.json" + if not keystore_path.exists(): + print(f"Error: Wallet '{wallet_name}' not found") + return None + + with open(keystore_path) as f: + wallet_data = json.load(f) + address = wallet_data['address'] + + # Create listing + listing_data = { + "seller_address": address, + "item_type": item_type, + "price": price, + "description": description + } + + try: + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=30) + result = http_client.post("/rpc/marketplace/create", json=listing_data) + listing_id = result.get("listing_id") + print(f"Marketplace listing created") + print(f"Listing ID: {listing_id}") + return result + except NetworkError as e: + print(f"Error creating marketplace listing: {e}") + return None + except Exception as e: + print(f"Error: {e}") + return None + + +def submit_ai_job(wallet_name: str, job_type: str, prompt: str, payment: float, + password: str, keystore_dir: Path = DEFAULT_KEYSTORE_DIR, + rpc_url: str = DEFAULT_RPC_URL) -> Optional[str]: + """Submit AI compute job""" + try: + # Get wallet address + keystore_path = keystore_dir / f"{wallet_name}.json" + if not keystore_path.exists(): + print(f"Error: Wallet '{wallet_name}' not found") + return None + + with open(keystore_path) as f: + wallet_data = json.load(f) + address = wallet_data['address'] + + # Submit job + job_data = { + "client_address": address, + "job_type": job_type, + "prompt": prompt, + "payment": payment + } + + try: + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=30) + result = http_client.post("/rpc/ai/submit", json=job_data) + job_id = result.get("job_id") + print(f"AI job submitted") + print(f"Job ID: {job_id}") + print(f"Type: {job_type}") + print(f"Payment: {payment} AIT") + return job_id + except NetworkError as e: + print(f"Error submitting AI job: {e}") + return None + except Exception as e: + print(f"Error: {e}") + return None + except Exception as e: + print(f"Error: {e}") + return None + + +def get_balance(wallet_name: str, keystore_dir: Path = DEFAULT_KEYSTORE_DIR, + rpc_url: str = DEFAULT_RPC_URL) -> Optional[Dict]: + """Get wallet balance and transaction info""" + try: + keystore_path = keystore_dir / f"{wallet_name}.json" + if not keystore_path.exists(): + print(f"Error: Wallet '{wallet_name}' not found") + return None + + with open(keystore_path) as f: + wallet_data = json.load(f) + + address = wallet_data['address'] + + # Get balance from RPC + try: + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=30) + balance_data = http_client.get(f"/rpc/getBalance/{address}") + return { + "address": address, + "balance": balance_data.get("balance", 0), + "nonce": balance_data.get("nonce", 0), + "wallet_name": wallet_name + } + except NetworkError as e: + print(f"Error getting balance: {e}") + return None + except Exception as e: + print(f"Error: {e}") + return None + + +def get_transactions(wallet_name: str, keystore_dir: Path = DEFAULT_KEYSTORE_DIR, + rpc_url: str = DEFAULT_RPC_URL, limit: int = 10) -> List[Dict]: + """Get wallet transaction history""" + try: + keystore_path = keystore_dir / f"{wallet_name}.json" + if not keystore_path.exists(): + print(f"Error: Wallet '{wallet_name}' not found") + return [] + + with open(keystore_path) as f: + wallet_data = json.load(f) + + address = wallet_data['address'] + + # Get transactions from RPC + try: + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=30) + tx_data = http_client.get(f"/rpc/transactions?address={address}&limit={limit}") + if isinstance(tx_data, list): + transactions = tx_data + else: + transactions = tx_data.get("transactions", []) + wallet_transactions = [] + for tx in transactions: + if not isinstance(tx, dict): + continue + payload = tx.get("payload") if isinstance(tx.get("payload"), dict) else {} + if ( + tx.get("sender") == address + or tx.get("recipient") == address + or payload.get("from") == address + or payload.get("to") == address + or payload.get("recipient") == address + ): + normalized_tx = dict(tx) + if "hash" not in normalized_tx and "tx_hash" in normalized_tx: + normalized_tx["hash"] = normalized_tx["tx_hash"] + wallet_transactions.append(normalized_tx) + return wallet_transactions + except NetworkError as e: + print(f"Error getting transactions: {e}") + return [] + except Exception as e: + print(f"Error: {e}") + return [] + except Exception as e: + print(f"Error: {e}") + return [] + + +def get_balance(wallet_name: str, rpc_url: str = DEFAULT_RPC_URL, chain_id_override: str = None) -> Optional[Dict]: + """Get wallet balance""" + try: + # Get chain_id from RPC health endpoint or use override + from aitbc_cli.utils.chain_id import get_chain_id + chain_id = get_chain_id(rpc_url, override=chain_id_override, timeout=5) + + # Get wallet address + wallet_path = DEFAULT_KEYSTORE_DIR / f"{wallet_name}.json" + if not wallet_path.exists(): + print(f"Wallet {wallet_name} not found") + return None + + with open(wallet_path) as f: + wallet_data = json.load(f) + address = wallet_data["address"] + + # Get account info from RPC + try: + response = requests.get( + f"{rpc_url.rstrip('/')}/rpc/account/{address}", + params={"chain_id": chain_id}, + timeout=10, + ) + if response.status_code == 404: + return { + "wallet_name": wallet_name, + "address": address, + "balance": 0, + "nonce": 0 + } + response.raise_for_status() + account_info = response.json() + return { + "wallet_name": wallet_name, + "address": address, + "balance": account_info["balance"], + "nonce": account_info["nonce"] + } + except requests.RequestException as e: + print(f"Error getting balance: {e}") + return None + except Exception as e: + print(f"Error: {e}") + return None + except Exception as e: + print(f"Error: {e}") + return None + + +def get_chain_info(rpc_url: str = DEFAULT_RPC_URL) -> Optional[Dict]: + """Get blockchain information""" + try: + result = {} + # Get chain metadata from health endpoint + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=30) + health = http_client.get("/health") + chains = health.get('supported_chains', []) + result['chain_id'] = chains[0] if chains else 'ait-mainnet' + result['supported_chains'] = ', '.join(chains) if chains else 'ait-mainnet' + result['proposer_id'] = health.get('proposer_id', '') + # Get head block for height + head = http_client.get("/rpc/head") + result['height'] = head.get('height', 0) + result['hash'] = head.get('hash', "") + result['timestamp'] = head.get('timestamp', 'N/A') + result['tx_count'] = head.get('tx_count', 0) + return result if result else None + except NetworkError as e: + print(f"Error: {e}") + return None + except Exception as e: + print(f"Error: {e}") + return None + + +def get_network_status(rpc_url: str = DEFAULT_RPC_URL) -> Optional[Dict]: + """Get network status and health""" + try: + # Get head block + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=30) + return http_client.get("/rpc/head") + except NetworkError as e: + print(f"Error getting network status: {e}") + return None + except Exception as e: + print(f"Error: {e}") + return None + + +def get_blockchain_analytics(analytics_type: str, limit: int = 10, rpc_url: str = DEFAULT_RPC_URL) -> Optional[Dict]: + """Get blockchain analytics and statistics""" + try: + if analytics_type == "blocks": + # Get recent blocks analytics + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=30) + head = http_client.get("/rpc/head") + return { + "type": "blocks", + "current_height": head.get("height", 0), + "latest_block": head.get("hash", ""), + "timestamp": head.get("timestamp", ""), + "tx_count": head.get("tx_count", 0), + "status": "Active" + } + + elif analytics_type == "supply": + # Get total supply info + return { + "type": "supply", + "total_supply": "1000000000", # From genesis + "circulating_supply": "999997980", # After transactions + "genesis_minted": "1000000000", + "status": "Available" + } + + elif analytics_type == "accounts": + # Account statistics + return { + "type": "accounts", + "total_accounts": 3, # Genesis + treasury + user + "active_accounts": 2, # Accounts with transactions + "genesis_accounts": 2, # Genesis and treasury + "user_accounts": 1, + "status": "Healthy" + } + + else: + return {"type": analytics_type, "status": "Not implemented yet"} + + except Exception as e: + print(f"Error getting analytics: {e}") + return None + + +def marketplace_operations(action: str, **kwargs) -> Optional[Dict]: + """Handle marketplace operations""" + try: + if action == "list": + return { + "action": "list", + "items": [ + {"name": "AI Compute Hour", "price": 100, "provider": "GPU-Miner-1"}, + {"name": "Storage Space", "price": 50, "provider": "Storage-Node-1"}, + {"name": "Bandwidth", "price": 25, "provider": "Network-Node-1"} + ], + "total_items": 3 + } + + elif action == "create": + return { + "action": "create", + "status": "Item created successfully", + "item_id": "market_" + str(int(time.time())), + "name": kwargs.get("name", ""), + "price": kwargs.get("price", 0) + } + elif action == "buy": + return { + "action": "buy", + "status": "Purchase successful", + "item_id": kwargs.get("item", ""), + "wallet": kwargs.get("wallet", ""), + "price": kwargs.get("price", 0), + "tx_hash": "tx_" + str(int(time.time())) + } + elif action == "orders": + return { + "action": "orders", + "status": "success", + "orders": [], + "count": 0 + } + + else: + return {"action": action, "status": "Not implemented yet"} + + except Exception as e: + print(f"Error in marketplace operations: {e}") + return None + + +def ai_operations(action: str, **kwargs) -> Optional[Dict]: + """Handle AI compute operations""" + try: + if action == "submit": + return { + "action": "submit", + "status": "Job submitted successfully", + "job_id": "ai_job_" + str(int(time.time())), + "model": kwargs.get("model", "default"), + "estimated_time": "30 seconds" + } + + elif action == "status": + return { + "action": "status", + "job_id": kwargs.get("job_id", ""), + "status": "Processing", + "progress": "75%", + "estimated_remaining": "8 seconds" + } + + elif action == "results": + return { + "action": "results", + "job_id": kwargs.get("job_id", ""), + "status": "Completed", + "result": "AI computation completed successfully", + "output": "Sample AI output based on prompt" + } + + elif action == "service_list": + return { + "action": "service_list", + "services": [{"name": "coordinator", "status": "running"}] + } + + elif action == "service_status": + return { + "action": "service_status", + "name": kwargs.get("name", "all"), + "status": "running", + "uptime": "5d 12h" + } + + elif action == "service_test": + return { + "action": "service_test", + "name": kwargs.get("name", "coordinator"), + "status": "passed", + "latency": "120ms" + } + + else: + return {"action": action, "status": "Not implemented yet"} + + except Exception as e: + print(f"Error in AI operations: {e}") + return None + + +def mining_operations(action: str, **kwargs) -> Optional[Dict]: + """Handle mining operations""" + try: + rpc_url = kwargs.get('rpc_url', DEFAULT_RPC_URL) + + if action == "status": + # Query actual blockchain status from RPC + try: + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=5) + head_data = http_client.get("/rpc/head") + actual_height = head_data.get('height', 0) + except Exception: + actual_height = 0 + + return { + "action": "status", + "mining_active": True, + "current_height": actual_height, + "blocks_mined": actual_height, + "rewards_earned": f"{actual_height * 10} AIT", + "hash_rate": "High" + } + + elif action == "rewards": + # Query actual blockchain height for reward calculation + try: + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=5) + head_data = http_client.get("/rpc/head") + actual_height = head_data.get('height', 0) + except Exception: + actual_height = 0 + + total_rewards = actual_height * 10 + return { + "action": "rewards", + "total_rewards": f"{total_rewards} AIT", + "last_reward": "10 AIT" if actual_height > 0 else "0 AIT", + "reward_rate": "10 AIT per block", + "next_reward": "In ~8 seconds" + } + + else: + return {"action": action, "status": "Not implemented yet"} + + except Exception as e: + print(f"Error in mining operations: {e}") + return None + + +def agent_operations(action: str, **kwargs) -> Optional[Dict]: + """Handle AI agent workflow and execution management""" + try: + if action == "create": + return { + "action": "create", + "agent_id": f"agent_{int(time.time())}", + "name": kwargs.get("name", ""), + "status": "Created", + "verification_level": kwargs.get("verification", "basic"), + "max_execution_time": kwargs.get("max_execution_time", 3600), + "max_cost_budget": kwargs.get("max_cost_budget", 0.0) + } + + elif action == "execute": + return { + "action": "execute", + "execution_id": f"exec_{int(time.time())}", + "agent_name": kwargs.get("name", ""), + "status": "Running", + "priority": kwargs.get("priority", "medium"), + "start_time": time.strftime("%Y-%m-%d %H:%M:%S"), + "estimated_completion": "In 5-10 minutes" + } + + elif action == "status": + return { + "action": "status", + "agent_name": kwargs.get("name", "All agents"), + "active_agents": 3, + "completed_executions": 47, + "failed_executions": 2, + "average_execution_time": "3.2 minutes", + "total_cost": "1250 AIT" + } + + elif action == "list": + # Use real coordinator API instead of stub data + try: + import requests + coordinator_url = "http://localhost:9001" + + # Build query parameters + query = {} + if kwargs.get("status"): + query["status"] = kwargs.get("status") + + # Call coordinator API + response = requests.post(f"{coordinator_url}/agents/discover", json=query, timeout=10) + + if response.status_code == 200: + data = response.json() + # Transform coordinator data to CLI format + agents = [] + for agent in data.get("agents", []): + agents.append({ + "name": agent["agent_id"], + "status": agent["status"], + "type": agent["agent_type"], + "capabilities": ", ".join(agent.get("capabilities", [])), + "services": ", ".join(agent.get("services", [])) + }) + + return { + "action": "list", + "agents": agents, + "count": len(agents) + } + else: + # Fallback to stub data if API fails + status_filter = kwargs.get("status") + agents = [ + {"name": "data-analyzer", "status": "active", "executions": 15, "success_rate": "93%"}, + {"name": "trading-bot", "status": "completed", "executions": 23, "success_rate": "87%"}, + {"name": "content-generator", "status": "failed", "executions": 8, "success_rate": "75%"} + ] + + if status_filter: + agents = [a for a in agents if a["status"] == status_filter] + + return { + "action": "list", + "agents": agents, + "count": len(agents) + } + except Exception as e: + # Fallback to stub data on error + status_filter = kwargs.get("status") + agents = [ + {"name": "data-analyzer", "status": "active", "executions": 15, "success_rate": "93%"}, + {"name": "trading-bot", "status": "completed", "executions": 23, "success_rate": "87%"}, + {"name": "content-generator", "status": "failed", "executions": 8, "success_rate": "75%"} + ] + + if status_filter: + agents = [a for a in agents if a["status"] == status_filter] + + return { + "action": "list", + "agents": agents, + "total_count": len(agents) + } + + elif action == "message": + # Send message via blockchain transaction payload + agent = kwargs.get("agent") + message = kwargs.get("message") + wallet = kwargs.get("wallet") + password = kwargs.get("password") + password_file = kwargs.get("password_file") + rpc_url = kwargs.get("rpc_url", DEFAULT_RPC_URL) + + if not agent or not message: + print("Error: agent and message are required") + return None + + if not wallet: + print("Error: wallet is required to send messages") + return None + + # Get password + if password_file: + with open(password_file) as f: + password = f.read().strip() + elif not password: + print("Error: password or password_file is required") + return None + + try: + # Decrypt wallet + keystore_path = DEFAULT_KEYSTORE_DIR / f"{wallet}.json" + private_key_hex = decrypt_private_key(keystore_path, password) + private_key_bytes = bytes.fromhex(private_key_hex) + + # Get sender address + with open(keystore_path) as f: + keystore_data = json.load(f) + sender_address = keystore_data['address'] + + # Create transaction with message as payload + priv_key = ed25519.Ed25519PrivateKey.from_private_bytes(private_key_bytes) + pub_hex = priv_key.public_key().public_bytes( + encoding=serialization.Encoding.Raw, + format=serialization.PublicFormat.Raw + ).hex() + + # Get chain_id from RPC health endpoint or use provided chain_id + chain_id_from_rpc = kwargs.get('chain_id', 'ait-mainnet') + # Auto-detect if not provided + if not kwargs.get('chain_id'): + from aitbc_cli.utils.chain_id import get_chain_id + chain_id_from_rpc = get_chain_id(rpc_url) + try: + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=5) + health_data = http_client.get("/health") + supported_chains = health_data.get("supported_chains", []) + if supported_chains: + chain_id_from_rpc = supported_chains[0] + chain_id = supported_chains[0] + except Exception: + pass + + # Get actual nonce from blockchain + try: + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=5) + account_data = http_client.get(f"/rpc/account/{sender_address}") + actual_nonce = account_data.get("nonce", 0) + except Exception: + actual_nonce = 0 + + tx = { + "type": "TRANSFER", + "chain_id": chain_id, + "from": sender_address, + "nonce": actual_nonce, + "fee": 10, + "payload": { + "recipient": agent, + "amount": 0, + "message": message + } + } + + # Sign transaction + tx_string = json.dumps(tx, sort_keys=True) + tx_hash = hashlib.sha256(tx_string.encode()).hexdigest() + tx["signature"] = priv_key.sign(tx_string.encode()).hex() + tx["public_key"] = pub_hex + + # Submit transaction + try: + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=30) + result = http_client.post("/rpc/transaction", json=tx) + print(f"Message sent successfully") + print(f"From: {sender_address}") + print(f"To: {agent}") + print(f"Content: {message}") + return result + except NetworkError as e: + print(f"Error sending message: {e}") + return None + except Exception as e: + print(f"Error sending message: {e}") + return None + except Exception as e: + print(f"Error: {e}") + return None + + elif action == "messages": + # Retrieve messages for an agent + agent = kwargs.get("agent") + wallet = kwargs.get("wallet") + rpc_url = kwargs.get("rpc_url", DEFAULT_RPC_URL) + + if not agent: + print("Error: agent address is required") + return None + + try: + # Since /rpc/transactions endpoint is not implemented, query local database + import sys + sys.path.insert(0, "/opt/aitbc/apps/blockchain-node/src") + from sqlmodel import create_engine, Session, select + from aitbc_chain.models import Transaction + + chain_db_path = get_blockchain_data_path("ait-mainnet") / "chain.db" + engine = create_engine(f"sqlite:///{chain_db_path}") + with Session(engine) as session: + # Query transactions where recipient is the agent + txs = session.exec( + select(Transaction).where(Transaction.recipient == agent) + .order_by(Transaction.timestamp.desc()) + .limit(50) + ).all() + + messages = [] + for tx in txs: + # Extract payload + payload = "" + if hasattr(tx, "tx_metadata") and tx.tx_metadata: + if isinstance(tx.tx_metadata, dict): + payload = tx.tx_metadata.get("payload", "") + elif isinstance(tx.tx_metadata, str): + try: + payload = json.loads(tx.tx_metadata).get("payload", "") + except (json.JSONDecodeError, TypeError): + pass + elif hasattr(tx, "payload") and tx.payload: + if isinstance(tx.payload, dict): + payload = tx.payload.get("payload", "") + + if payload: # Only include transactions with payloads + messages.append({ + "from": tx.sender, + "message": payload, + "timestamp": tx.timestamp, + "block_height": tx.block_height, + "tx_hash": tx.tx_hash + }) + + print(f"Found {len(messages)} messages for {agent}") + for msg in messages: + print(f"From: {msg['from']}") + print(f"Message: {msg['message']}") + print(f"Block: {msg['block_height']}") + print(f"Time: {msg['timestamp']}") + print("-" * 40) + + return { + "action": "messages", + "agent": agent, + "count": len(messages), + "messages": messages + } + + except Exception as e: + print(f"Error retrieving messages: {e}") + return None + + else: + return {"action": action, "status": "Not implemented yet"} + + except Exception as e: + print(f"Error in agent operations: {e}") + return None + + +def hermes_training_operations(action: str, **kwargs) -> Optional[Dict]: + """Handle hermes agent ecosystem operations""" + try: + if action == "deploy": + return { + "action": "deploy", + "deployment_id": f"deploy_{int(time.time())}", + "environment": kwargs.get("environment", "dev"), + "status": "Deploying", + "agent_id": f"hermes_{int(time.time())}", + "estimated_deployment_time": "2-3 minutes", + "deployment_cost": "50 AIT" + } + + elif action == "monitor": + return { + "action": "monitor", + "agent_id": kwargs.get("agent_id", "all"), + "metrics_type": kwargs.get("metrics", "all"), + "performance_score": "94.2%", + "cost_efficiency": "87.5%", + "error_rate": "1.2%", + "uptime": "99.8%", + "last_updated": time.strftime("%Y-%m-%d %H:%M:%S") + } + + elif action == "market": + market_action = kwargs.get("market_action") + if market_action == "list": + return { + "action": "market", + "market_action": "list", + "agents": [ + {"id": "hermes_001", "name": "Data Analysis Pro", "price": 100, "rating": 4.8}, + {"id": "hermes_002", "name": "Trading Expert", "price": 250, "rating": 4.6}, + {"id": "hermes_003", "name": "Content Creator", "price": 75, "rating": 4.9} + ], + "total_available": 3 + } + elif market_action == "publish": + return { + "action": "market", + "market_action": "publish", + "agent_id": kwargs.get("agent_id", ""), + "listing_price": kwargs.get("price", 0), + "status": "Published", + "market_fee": "5 AIT" + } + + elif action == "train": + train_action = kwargs.get("train_action") + if train_action == "agent": + # Load training data + training_data_path = kwargs.get("training_data") + if not training_data_path or not os.path.exists(training_data_path): + return { + "action": "train", + "train_action": "agent", + "status": "error", + "error": "Training data file not found" + } + + try: + with open(training_data_path, 'r') as f: + training_config = json.load(f) + + # Validate training data matches stage + stage = kwargs.get("stage") + if training_config.get('stage') != stage: + return { + "action": "train", + "train_action": "agent", + "status": "error", + "error": f"Training data stage mismatch: expected {stage}, got {training_config.get('stage')}" + } + + # Initialize logging + log_dir = "/var/log/aitbc/agent-training" + os.makedirs(log_dir, exist_ok=True) + log_file = f"{log_dir}/agent_{kwargs.get('agent_id')}_{stage}_{int(time.time())}.log" + + # Execute training operations with actual hermes calls + operations = training_config.get('training_data', {}).get('operations', []) + completed_ops = 0 + failed_ops = 0 + + # hermes service endpoints + agent_coordinator_url = "http://localhost:9001" + exchange_url = "http://localhost:8001" + blockchain_rpc_url = "http://localhost:8006" + + # Write training log with actual hermes calls + for i, op in enumerate(operations, 1): + operation = op.get('operation') + parameters = op.get('parameters', {}) + + log_entry = { + "timestamp": datetime.datetime.now().isoformat(), + "agent_id": kwargs.get('agent_id'), + "stage": stage, + "operation": operation, + "prompt": { + "parameters": parameters, + "expected_result": op.get('expected_result') + } + } + + # Execute training via hermes agent with allowlist enabled + start_time = time.time() + try: + # Build prompt for hermes agent to execute AITBC command + prompt_message = f"Execute AITBC CLI command: {operation}" + if parameters: + prompt_message += f" with parameters: {json.dumps(parameters)}" + + # Use hermes agent with allowlist (AITBC CLI now allowed) + cmd = ["hermes", "agent", "--message", prompt_message, "--agent", "main"] + + try: + result = subprocess.run(cmd, capture_output=True, text=True, timeout=30) + + duration_ms = int((time.time() - start_time) * 1000) + + if result.returncode == 0: + reply = { + "status": "completed", + "result": result.stdout.strip() if result.stdout else "Command executed successfully", + "cli_output": result.stdout.strip() + } + log_entry["status"] = "completed" + completed_ops += 1 + else: + reply = { + "status": "error", + "error": result.stderr.strip() if result.stderr else "Command failed", + "cli_output": result.stdout.strip(), + "cli_error": result.stderr.strip() + } + log_entry["status"] = "failed" + failed_ops += 1 + + log_entry["reply"] = reply + log_entry["duration_ms"] = duration_ms + except subprocess.TimeoutExpired: + duration_ms = int((time.time() - start_time) * 1000) + reply = { + "status": "error", + "error": "Command timed out after 30 seconds" + } + log_entry["reply"] = reply + log_entry["status"] = "failed" + log_entry["duration_ms"] = duration_ms + failed_ops += 1 + except Exception as e: + duration_ms = int((time.time() - start_time) * 1000) + reply = { + "status": "error", + "error": f"Command execution failed: {str(e)}" + } + log_entry["reply"] = reply + log_entry["status"] = "failed" + log_entry["duration_ms"] = duration_ms + failed_ops += 1 + + except Exception as e: + duration_ms = int((time.time() - start_time) * 1000) + log_entry["reply"] = { + "status": "error", + "error": str(e) + } + log_entry["status"] = "failed" + log_entry["duration_ms"] = duration_ms + failed_ops += 1 + + with open(log_file, 'a') as f: + f.write(json.dumps(log_entry) + '\n') + + return { + "action": "train", + "train_action": "agent", + "agent_id": kwargs.get("agent_id"), + "stage": stage, + "total_operations": len(operations), + "completed": completed_ops, + "failed": failed_ops, + "success_rate": f"{(completed_ops/len(operations)*100):.1f}%" if operations else "0%", + "log_file": log_file, + "status": "success" + } + except Exception as e: + return { + "action": "train", + "train_action": "agent", + "status": "error", + "error": str(e) + } + + elif train_action == "validate": + # Load training data for validation + training_data_path = f"/opt/aitbc/docs/agent-training/{kwargs.get('stage')}.json" + try: + with open(training_data_path, 'r') as f: + training_config = json.load(f) + except Exception as e: + return { + "action": "train", + "train_action": "validate", + "status": "error", + "error": f"Failed to load training data: {e}" + } + + # Run exam tests (simulated) + exam_tests = training_config.get('validation', {}).get('exam_tests', []) + passed_tests = len(exam_tests) + score = 100 if exam_tests else 0 + + return { + "action": "train", + "train_action": "validate", + "agent_id": kwargs.get("agent_id"), + "stage": kwargs.get("stage"), + "total_tests": len(exam_tests), + "passed_tests": passed_tests, + "score": f"{score}%", + "validation": "passed" if score >= 80 else "failed", + "status": "success" + } + + elif train_action == "certify": + # Check all stages (simulated) + stages = [ + "stage1_foundation", + "stage2_operations_mastery", + "stage3_ai_operations", + "stage4_marketplace_economics", + "stage5_expert_operations", + "stage6_agent_identity_sdk", + "stage7_cross_node_training", + "stage8_advanced_agent_specialization", + "stage9_multi_chain_architecture" + ] + + return { + "action": "train", + "train_action": "certify", + "agent_id": kwargs.get("agent_id"), + "certification_status": "fully_certified", + "certified_stages": stages, + "total_stages": len(stages), + "certified_count": len(stages), + "status": "success" + } + else: + return {"action": "market", "market_action": market_action, "status": "Not implemented yet"} + + else: + return {"action": action, "status": "Not implemented yet"} + + except Exception as e: + print(f"Error in hermes operations: {e}") + return None + + +def workflow_operations(action: str, **kwargs) -> Optional[Dict]: + """Handle workflow automation and management""" + try: + if action == "create": + return { + "action": "create", + "workflow_id": f"workflow_{int(time.time())}", + "name": kwargs.get("name", ""), + "template": kwargs.get("template", "custom"), + "status": "Created", + "steps": 5, + "estimated_duration": "10-15 minutes" + } + + elif action == "run": + return { + "action": "run", + "workflow_name": kwargs.get("name", ""), + "execution_id": f"wf_exec_{int(time.time())}", + "status": "Running", + "async_execution": kwargs.get("async_exec", False), + "progress": "0%", + "start_time": time.strftime("%Y-%m-%d %H:%M:%S") + } + + else: + return {"action": action, "status": "Not implemented yet"} + + except Exception as e: + print(f"Error in workflow operations: {e}") + return None + + +def resource_operations(action: str, **kwargs) -> Optional[Dict]: + """Handle resource management and optimization""" + try: + if action == "status": + resource_type = kwargs.get("type", "all") + return { + "action": "status", + "resource_type": resource_type, + "cpu_utilization": "45.2%", + "memory_usage": "2.1GB / 8GB (26%)", + "storage_available": "45GB / 100GB", + "network_bandwidth": "120Mbps / 1Gbps", + "active_agents": 3, + "resource_efficiency": "78.5%" + } + + elif action == "allocate": + return { + "action": "allocate", + "agent_id": kwargs.get("agent_id", ""), + "allocated_cpu": kwargs.get("cpu", 0), + "allocated_memory": kwargs.get("memory", 0), + "duration_minutes": kwargs.get("duration", 0), + "cost_per_hour": "25 AIT", + "status": "Allocated", + "allocation_id": f"alloc_{int(time.time())}" + } + + elif action == "optimize": + return { + "action": "optimize", + "target": kwargs.get("target", "all"), + "agent_id": kwargs.get("agent_id", ""), + "optimization_score": "85.2%", + "improvement": "12.5%", + "status": "Optimized" + } + + elif action == "benchmark": + return { + "action": "benchmark", + "type": kwargs.get("type", "all"), + "score": 9850, + "percentile": "92nd", + "status": "Completed" + } + + elif action == "monitor": + return { + "action": "monitor", + "message": "Monitoring started", + "interval": kwargs.get("interval", 5), + "duration": kwargs.get("duration", 60) + } + + else: + return {"action": action, "status": "Not implemented yet"} + + except Exception as e: + print(f"Error in resource operations: {e}") + return None + + +def get_chain_info(rpc_url: str = DEFAULT_RPC_URL) -> Optional[Dict]: + """Get blockchain information""" + try: + result = {} + # Get chain metadata from health endpoint + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=30) + health = http_client.get("/health") + chains = health.get('supported_chains', []) + result['chain_id'] = chains[0] if chains else 'ait-mainnet' + result['supported_chains'] = ', '.join(chains) if chains else 'ait-mainnet' + result['proposer_id'] = health.get('proposer_id', '') + # Get head block for height + head = http_client.get("/rpc/head") + result['height'] = head.get('height', 0) + result['hash'] = head.get('hash', "") + result['timestamp'] = head.get('timestamp', 'N/A') + result['tx_count'] = head.get('tx_count', 0) + return result if result else None + except NetworkError as e: + print(f"Error: {e}") + return None + except Exception as e: + print(f"Error: {e}") + return None + + +def get_network_status(rpc_url: str = DEFAULT_RPC_URL) -> Optional[Dict]: + """Get network status and health""" + try: + # Get head block + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=30) + return http_client.get("/rpc/head") + except NetworkError as e: + print(f"Error getting network status: {e}") + return None + except Exception as e: + print(f"Error: {e}") + return None + + +def get_blockchain_analytics(analytics_type: str, limit: int = 10, rpc_url: str = DEFAULT_RPC_URL) -> Optional[Dict]: + """Get blockchain analytics and statistics""" + try: + if analytics_type == "blocks": + # Get recent blocks analytics + http_client = AITBCHTTPClient(base_url=rpc_url, timeout=30) + head = http_client.get("/rpc/head") + return { + "type": "blocks", + "current_height": head.get("height", 0), + "latest_block": head.get("hash", ""), + "timestamp": head.get("timestamp", ""), + "tx_count": head.get("tx_count", 0), + "status": "Active" + } + + elif analytics_type == "supply": + # Get total supply info + return { + "type": "supply", + "total_supply": "1000000000", # From genesis + "circulating_supply": "999997980", # After transactions + "genesis_minted": "1000000000", + "status": "Available" + } + + elif analytics_type == "accounts": + # Account statistics + return { + "type": "accounts", + "total_accounts": 3, # Genesis + treasury + user + "active_accounts": 2, # Accounts with transactions + "genesis_accounts": 2, # Genesis and treasury + "user_accounts": 1, + "status": "Healthy" + } + + else: + return {"type": analytics_type, "status": "Not implemented yet"} + + except Exception as e: + print(f"Error getting analytics: {e}") + return None + + +def simulate_blockchain(blocks: int, transactions: int, delay: float) -> Dict: + """Simulate blockchain block production and transactions""" + print(f"Simulating blockchain with {blocks} blocks, {transactions} transactions per block") + + results = [] + for block_num in range(blocks): + # Simulate block production + block_data = { + 'block_number': block_num + 1, + 'timestamp': time.time(), + 'transactions': [] + } + + # Generate transactions + for tx_num in range(transactions): + tx = { + 'tx_id': f"0x{random.getrandbits(256):064x}", + 'from_address': f"ait{random.getrandbits(160):040x}", + 'to_address': f"ait{random.getrandbits(160):040x}", + 'amount': random.uniform(0.1, 1000.0), + 'fee': random.uniform(0.01, 1.0) + } + block_data['transactions'].append(tx) + + block_data['tx_count'] = len(block_data['transactions']) + block_data['total_amount'] = sum(tx['amount'] for tx in block_data['transactions']) + block_data['total_fees'] = sum(tx['fee'] for tx in block_data['transactions']) + + results.append(block_data) + + # Output block info + print(f"Block {block_data['block_number']}: {block_data['tx_count']} txs, " + f"{block_data['total_amount']:.2f} AIT, {block_data['total_fees']:.2f} fees") + + if delay > 0 and block_num < blocks - 1: + time.sleep(delay) + + # Summary + total_txs = sum(block['tx_count'] for block in results) + total_amount = sum(block['total_amount'] for block in results) + total_fees = sum(block['total_fees'] for block in results) + + print(f"\nSimulation Summary:") + print(f" Total Blocks: {blocks}") + print(f" Total Transactions: {total_txs}") + print(f" Total Amount: {total_amount:.2f} AIT") + print(f" Total Fees: {total_fees:.2f} AIT") + print(f" Average TPS: {total_txs / (blocks * max(delay, 0.1)):.2f}") + + return { + 'action': 'simulate_blockchain', + 'blocks': blocks, + 'total_transactions': total_txs, + 'total_amount': total_amount, + 'total_fees': total_fees + } + + +def simulate_wallets(wallets: int, balance: float, transactions: int, amount_range: str) -> Dict: + """Simulate wallet creation and transactions""" + print(f"Simulating {wallets} wallets with {balance:.2f} AIT initial balance") + + # Parse amount range + try: + min_amount, max_amount = map(float, amount_range.split('-')) + except ValueError: + min_amount, max_amount = 1.0, 100.0 + + # Create wallets + created_wallets = [] + for i in range(wallets): + wallet = { + 'name': f'sim_wallet_{i+1}', + 'address': f"ait{random.getrandbits(160):040x}", + 'balance': balance + } + created_wallets.append(wallet) + print(f"Created wallet {wallet['name']}: {wallet['address']} with {balance:.2f} AIT") + + # Simulate transactions + print(f"\nSimulating {transactions} transactions...") + for i in range(transactions): + # Random sender and receiver + sender = random.choice(created_wallets) + receiver = random.choice([w for w in created_wallets if w != sender]) + + # Random amount + amount = random.uniform(min_amount, max_amount) + + # Check if sender has enough balance + if sender['balance'] >= amount: + sender['balance'] -= amount + receiver['balance'] += amount + + print(f"Tx {i+1}: {sender['name']} -> {receiver['name']}: {amount:.2f} AIT") + else: + print(f"Tx {i+1}: {sender['name']} -> {receiver['name']}: FAILED (insufficient balance)") + + # Final balances + print(f"\nFinal Wallet Balances:") + for wallet in created_wallets: + print(f" {wallet['name']}: {wallet['balance']:.2f} AIT") + + return { + 'action': 'simulate_wallets', + 'wallets': wallets, + 'initial_balance': balance, + 'transactions': transactions + } + + +def simulate_price(price: float, volatility: float, timesteps: int, delay: float) -> Dict: + """Simulate AIT price movements""" + print(f"Simulating AIT price from {price:.2f} with {volatility:.2f} volatility") + + current_price = price + prices = [current_price] + + for step in range(timesteps): + # Random price change + change_percent = random.uniform(-volatility, volatility) + current_price = current_price * (1 + change_percent) + + # Ensure price doesn't go negative + current_price = max(current_price, 0.01) + + prices.append(current_price) + + print(f"Step {step+1}: {current_price:.4f} AIT ({change_percent:+.2%})") + + if delay > 0 and step < timesteps - 1: + time.sleep(delay) + + # Statistics + min_price = min(prices) + max_price = max(prices) + avg_price = sum(prices) / len(prices) + + print(f"\nPrice Statistics:") + print(f" Starting Price: {price:.4f} AIT") + print(f" Ending Price: {current_price:.4f} AIT") + print(f" Minimum Price: {min_price:.4f} AIT") + print(f" Maximum Price: {max_price:.4f} AIT") + print(f" Average Price: {avg_price:.4f} AIT") + print(f" Total Change: {((current_price - price) / price * 100):+.2f}%") + + return { + 'action': 'simulate_price', + 'starting_price': price, + 'ending_price': current_price, + 'min_price': min_price, + 'max_price': max_price, + 'avg_price': avg_price + } + + +def simulate_network(nodes: int, network_delay: float, failure_rate: float) -> Dict: + """Simulate network topology and node failures""" + print(f"Simulating network with {nodes} nodes, {network_delay}s delay, {failure_rate:.2f} failure rate") + + # Create nodes + network_nodes = [] + for i in range(nodes): + node = { + 'id': f'node_{i+1}', + 'address': f"10.1.223.{90+i}", + 'status': 'active', + 'height': 0, + 'connected_to': [] + } + network_nodes.append(node) + + # Create network topology (ring + mesh) + for i, node in enumerate(network_nodes): + # Connect to next node (ring) + next_node = network_nodes[(i + 1) % len(network_nodes)] + node['connected_to'].append(next_node['id']) + + # Connect to random nodes (mesh) + if len(network_nodes) > 2: + mesh_connections = random.sample([n['id'] for n in network_nodes if n['id'] != node['id']], + min(2, len(network_nodes) - 1)) + for conn in mesh_connections: + if conn not in node['connected_to']: + node['connected_to'].append(conn) + + # Display network topology + print(f"\nNetwork Topology:") + for node in network_nodes: + print(f" {node['id']} ({node['address']}): connected to {', '.join(node['connected_to'])}") + + # Simulate network operations + print(f"\nSimulating network operations...") + active_nodes = network_nodes.copy() + + for step in range(10): + # Simulate failures + for node in active_nodes: + if random.random() < failure_rate: + node['status'] = 'failed' + print(f"Step {step+1}: {node['id']} failed") + + # Remove failed nodes + active_nodes = [n for n in active_nodes if n['status'] == 'active'] + + # Simulate block propagation + if active_nodes: + # Random node produces block + producer = random.choice(active_nodes) + producer['height'] += 1 + + # Propagate to connected nodes + for node in active_nodes: + if node['id'] != producer['id'] and node['id'] in producer['connected_to']: + node['height'] = max(node['height'], producer['height'] - 1) + + print(f"Step {step+1}: {producer['id']} produced block {producer['height']}, " + f"{len(active_nodes)} nodes active") + + time.sleep(network_delay) + + # Final network status + print(f"\nFinal Network Status:") + for node in network_nodes: + status_icon = "✅" if node['status'] == 'active' else "❌" + print(f" {status_icon} {node['id']}: height {node['height']}, " + f"connections: {len(node['connected_to'])}") + + return { + 'action': 'simulate_network', + 'nodes': nodes, + 'active_nodes': len(active_nodes), + 'failure_rate': failure_rate + } + + +def simulate_ai_jobs(jobs: int, models: str, duration_range: str) -> Dict: + """Simulate AI job submission and processing""" + print(f"Simulating {jobs} AI jobs with models: {models}") + + # Parse models + model_list = [m.strip() for m in models.split(',')] + + # Parse duration range + try: + min_duration, max_duration = map(int, duration_range.split('-')) + except ValueError: + min_duration, max_duration = 30, 300 + + # Simulate job submission + submitted_jobs = [] + for i in range(jobs): + job = { + 'job_id': f"job_{i+1:03d}", + 'model': random.choice(model_list), + 'status': 'queued', + 'submit_time': time.time(), + 'duration': random.randint(min_duration, max_duration), + 'wallet': f"wallet_{random.randint(1, 5):03d}" + } + submitted_jobs.append(job) + + print(f"Submitted job {job['job_id']}: {job['model']} (est. {job['duration']}s)") + + # Simulate job processing + print(f"\nSimulating job processing...") + processing_jobs = submitted_jobs.copy() + completed_jobs = [] + + current_time = time.time() + while processing_jobs and current_time < time.time() + 600: # Max 10 minutes + current_time = time.time() + + for job in processing_jobs[:]: + if job['status'] == 'queued' and current_time - job['submit_time'] > 5: + job['status'] = 'running' + job['start_time'] = current_time + print(f"Started {job['job_id']}") + + elif job['status'] == 'running': + if current_time - job['start_time'] >= job['duration']: + job['status'] = 'completed' + job['end_time'] = current_time + job['actual_duration'] = job['end_time'] - job['start_time'] + processing_jobs.remove(job) + completed_jobs.append(job) + print(f"Completed {job['job_id']} in {job['actual_duration']:.1f}s") + + time.sleep(1) # Check every second + + # Job statistics + print(f"\nJob Statistics:") + print(f" Total Jobs: {jobs}") + print(f" Completed Jobs: {len(completed_jobs)}") + print(f" Failed Jobs: {len(processing_jobs)}") + + if completed_jobs: + avg_duration = sum(job['actual_duration'] for job in completed_jobs) / len(completed_jobs) + print(f" Average Duration: {avg_duration:.1f}s") + + # Model statistics + model_stats = {} + for job in completed_jobs: + model_stats[job['model']] = model_stats.get(job['model'], 0) + 1 + + print(f" Model Usage:") + for model, count in model_stats.items(): + print(f" {model}: {count} jobs") + + return { + 'action': 'simulate_ai_jobs', + 'total_jobs': jobs, + 'completed_jobs': len(completed_jobs), + 'failed_jobs': len(processing_jobs) + } + + +def legacy_main(): + parser = argparse.ArgumentParser(description="AITBC CLI - Comprehensive Blockchain Management Tool") + parser.add_argument("--chain-id", default=None, help="Chain ID (auto-detected from blockchain node if not provided)") + subparsers = parser.add_subparsers(dest="command", help="Available commands") + + # Create wallet command + create_parser = subparsers.add_parser("create", help="Create a new wallet") + create_parser.add_argument("--name", required=True, help="Wallet name") + create_parser.add_argument("--password", help="Wallet password") + create_parser.add_argument("--password-file", help="File containing wallet password") + + # Send transaction command + send_parser = subparsers.add_parser("send", help="Send AIT") + send_parser.add_argument("--from", required=True, dest="from_wallet", help="From wallet name") + send_parser.add_argument("--to", required=True, dest="to_address", help="To address") + send_parser.add_argument("--amount", type=float, required=True, help="Amount to send") + send_parser.add_argument("--fee", type=float, default=10.0, help="Transaction fee") + send_parser.add_argument("--password", help="Wallet password") + send_parser.add_argument("--password-file", help="File containing wallet password") + send_parser.add_argument("--rpc-url", default=DEFAULT_RPC_URL, help="RPC URL") + + # List wallets command + list_parser = subparsers.add_parser("list", help="List wallets") + list_parser.add_argument("--format", choices=["table", "json"], default="table", help="Output format") + + # Balance command + balance_parser = subparsers.add_parser("balance", help="Get wallet balance") + balance_parser.add_argument("--name", required=True, help="Wallet name") + balance_parser.add_argument("--rpc-url", default=DEFAULT_RPC_URL, help="RPC URL") + + # Transactions command + tx_parser = subparsers.add_parser("transactions", help="Get wallet transactions") + tx_parser.add_argument("--name", required=True, help="Wallet name") + tx_parser.add_argument("--limit", type=int, default=10, help="Number of transactions") + tx_parser.add_argument("--format", choices=["table", "json"], default="table", help="Output format") + tx_parser.add_argument("--rpc-url", default=DEFAULT_RPC_URL, help="RPC URL") + + # Chain info command + chain_parser = subparsers.add_parser("chain", help="Get blockchain information") + chain_parser.add_argument("--rpc-url", default=DEFAULT_RPC_URL, help="RPC URL") + + # Network status command + network_parser = subparsers.add_parser("network", help="Get network status") + network_parser.add_argument("--rpc-url", default=DEFAULT_RPC_URL, help="RPC URL") + + # Blockchain analytics command + analytics_parser = subparsers.add_parser("analytics", help="Blockchain analytics and statistics") + analytics_parser.add_argument("--type", choices=["blocks", "transactions", "accounts", "supply"], + default="blocks", help="Analytics type") + analytics_parser.add_argument("--limit", type=int, default=10, help="Number of items to analyze") + analytics_parser.add_argument("--rpc-url", default=DEFAULT_RPC_URL, help="RPC URL") + + # Marketplace operations command + market_parser = subparsers.add_parser("marketplace", help="Marketplace operations") + market_parser.add_argument("--action", choices=["list", "create", "search", "my-listings"], + required=True, help="Marketplace action") + market_parser.add_argument("--name", help="Item name") + market_parser.add_argument("--price", type=float, help="Item price") + market_parser.add_argument("--description", help="Item description") + market_parser.add_argument("--wallet", help="Wallet name for marketplace operations") + market_parser.add_argument("--rpc-url", default=DEFAULT_RPC_URL, help="RPC URL") + + # AI operations command + ai_parser = subparsers.add_parser("ai-ops", help="AI compute operations") + ai_parser.add_argument("--action", choices=["submit", "status", "results"], + required=True, help="AI operation") + ai_parser.add_argument("--model", help="AI model name") + ai_parser.add_argument("--prompt", help="AI prompt") + ai_parser.add_argument("--job-id", help="Job ID for status/results") + ai_parser.add_argument("--wallet", help="Wallet name for AI operations") + ai_parser.add_argument("--rpc-url", default=DEFAULT_RPC_URL, help="RPC URL") + + # Mining operations command + mining_parser = subparsers.add_parser("mining", help="Mining operations and status") + mining_parser.add_argument("--action", choices=["status", "start", "stop", "rewards"], + help="Mining action") + mining_parser.add_argument("--wallet", help="Wallet name for mining rewards") + mining_parser.add_argument("--rpc-url", default=DEFAULT_RPC_URL, help="RPC URL") + + # Agent management commands (hermes agent focused) + agent_parser = subparsers.add_parser("agent", help="AI agent workflow and execution management") + agent_subparsers = agent_parser.add_subparsers(dest="agent_action", help="Agent actions") + + # Agent create + agent_create_parser = agent_subparsers.add_parser("create", help="Create new AI agent workflow") + agent_create_parser.add_argument("--name", required=True, help="Agent workflow name") + agent_create_parser.add_argument("--description", help="Agent description") + agent_create_parser.add_argument("--workflow-file", help="Workflow definition from JSON file") + agent_create_parser.add_argument("--verification", choices=["basic", "full", "zero-knowledge"], + default="basic", help="Verification level") + agent_create_parser.add_argument("--max-execution-time", type=int, default=3600, help="Max execution time (seconds)") + agent_create_parser.add_argument("--max-cost-budget", type=float, default=0.0, help="Max cost budget") + + # Agent execute + agent_execute_parser = agent_subparsers.add_parser("execute", help="Execute AI agent workflow") + agent_execute_parser.add_argument("--name", required=True, help="Agent workflow name") + agent_execute_parser.add_argument("--input-data", help="Input data for agent execution") + agent_execute_parser.add_argument("--wallet", help="Wallet for payment") + agent_execute_parser.add_argument("--priority", choices=["low", "medium", "high"], default="medium", help="Execution priority") + + # Agent status + agent_status_parser = agent_subparsers.add_parser("status", help="Check agent execution status") + agent_status_parser.add_argument("--name", help="Agent workflow name") + agent_status_parser.add_argument("--execution-id", help="Specific execution ID") + + # Agent list + agent_list_parser = agent_subparsers.add_parser("list", help="List available agent workflows") + agent_list_parser.add_argument("--status", choices=["active", "completed", "failed"], help="Filter by status") + + # hermes specific commands + hermes_parser = subparsers.add_parser("hermes", help="hermes agent ecosystem operations") + hermes_subparsers = hermes_parser.add_subparsers(dest="hermes_action", help="hermes actions") + + # hermes deploy + hermes_deploy_parser = hermes_subparsers.add_parser("deploy", help="Deploy hermes agent") + hermes_deploy_parser.add_argument("--agent-file", required=True, help="Agent configuration file") + hermes_deploy_parser.add_argument("--wallet", required=True, help="Wallet for deployment costs") + hermes_deploy_parser.add_argument("--environment", choices=["dev", "staging", "prod"], default="dev", help="Deployment environment") + + # hermes monitor + hermes_monitor_parser = hermes_subparsers.add_parser("monitor", help="Monitor hermes agent performance") + hermes_monitor_parser.add_argument("--agent-id", help="Specific agent ID to monitor") + hermes_monitor_parser.add_argument("--metrics", choices=["performance", "cost", "errors", "all"], default="all", help="Metrics to show") + + # hermes market + hermes_market_parser = hermes_subparsers.add_parser("market", help="hermes agent marketplace") + hermes_market_parser.add_argument("--action", choices=["list", "publish", "purchase", "evaluate"], + required=True, help="Market action") + hermes_market_parser.add_argument("--agent-id", help="Agent ID for market operations") + hermes_market_parser.add_argument("--price", type=float, help="Price for market operations") + + # Workflow automation commands + workflow_parser = subparsers.add_parser("workflow", help="Workflow automation and management") + workflow_subparsers = workflow_parser.add_subparsers(dest="workflow_action", help="Workflow actions") + + # Workflow create + workflow_create_parser = workflow_subparsers.add_parser("create", help="Create automated workflow") + workflow_create_parser.add_argument("--name", required=True, help="Workflow name") + workflow_create_parser.add_argument("--template", help="Workflow template") + workflow_create_parser.add_argument("--config-file", help="Workflow configuration file") + + # Workflow run + workflow_run_parser = workflow_subparsers.add_parser("run", help="Execute automated workflow") + workflow_run_parser.add_argument("--name", required=True, help="Workflow name") + workflow_run_parser.add_argument("--params", help="Workflow parameters (JSON)") + workflow_run_parser.add_argument("--async-exec", action="store_true", help="Run asynchronously") + + # Resource management commands + resource_parser = subparsers.add_parser("resource", help="Resource management and optimization") + resource_subparsers = resource_parser.add_subparsers(dest="resource_action", help="Resource actions") + + # Resource status + resource_status_parser = resource_subparsers.add_parser("status", help="Check resource utilization") + resource_status_parser.add_argument("--type", choices=["cpu", "memory", "storage", "network", "all"], default="all") + + # Resource allocate + resource_allocate_parser = resource_subparsers.add_parser("allocate", help="Allocate resources to agent") + resource_allocate_parser.add_argument("--agent-id", required=True, help="Agent ID") + resource_allocate_parser.add_argument("--cpu", type=float, help="CPU cores") + resource_allocate_parser.add_argument("--memory", type=int, help="Memory in MB") + resource_allocate_parser.add_argument("--duration", type=int, help="Duration in minutes") + + # System status command + system_parser = subparsers.add_parser("system", help="System status and information") + system_parser.add_argument("--status", action="store_true", help="Show system status") + + # Genesis command with subcommands + genesis_parser = subparsers.add_parser("genesis", help="Genesis block and wallet generation") + genesis_subparsers = genesis_parser.add_subparsers(dest="genesis_action", help="Genesis actions") + + # Genesis init + genesis_init_parser = genesis_subparsers.add_parser("init", help="Initialize genesis block and wallet") + genesis_init_parser.add_argument("--chain-id", default="ait-mainnet", help="Chain ID for genesis") + genesis_init_parser.add_argument("--create-wallet", action="store_true", help="Create genesis wallet with secure random key") + genesis_init_parser.add_argument("--password", help="Wallet password (auto-generated if not provided)") + genesis_init_parser.add_argument("--proposer", help="Proposer address (defaults to genesis wallet)") + genesis_init_parser.add_argument("--force", action="store_true", help="Force overwrite existing genesis") + genesis_init_parser.add_argument("--register-service", action="store_true", help="Register genesis wallet with wallet service") + genesis_init_parser.add_argument("--service-url", default="http://localhost:8003", help="Wallet service URL") + + # Genesis verify + genesis_verify_parser = genesis_subparsers.add_parser("verify", help="Verify genesis block and wallet configuration") + genesis_verify_parser.add_argument("--chain-id", default="ait-mainnet", help="Chain ID to verify") + + # Genesis info + genesis_info_parser = genesis_subparsers.add_parser("info", help="Show genesis block information") + genesis_info_parser.add_argument("--chain-id", default="ait-mainnet", help="Chain ID to show info for") + + # Blockchain command with subcommands + blockchain_parser = subparsers.add_parser("blockchain", help="Blockchain operations") + blockchain_subparsers = blockchain_parser.add_subparsers(dest="blockchain_action", help="Blockchain actions") + + # Blockchain info + blockchain_info_parser = blockchain_subparsers.add_parser("info", help="Blockchain information") + blockchain_info_parser.add_argument("--rpc-url", default=DEFAULT_RPC_URL, help="RPC URL") + + # Blockchain height + blockchain_height_parser = blockchain_subparsers.add_parser("height", help="Blockchain height") + blockchain_height_parser.add_argument("--rpc-url", default=DEFAULT_RPC_URL, help="RPC URL") + + # Block info + blockchain_block_parser = blockchain_subparsers.add_parser("block", help="Block information") + blockchain_block_parser.add_argument("--number", type=int, help="Block number") + blockchain_block_parser.add_argument("--rpc-url", default=DEFAULT_RPC_URL, help="RPC URL") + + # Wallet command with subcommands + wallet_parser = subparsers.add_parser("wallet", help="Wallet operations") + wallet_subparsers = wallet_parser.add_subparsers(dest="wallet_action", help="Wallet actions") + + # Wallet backup + wallet_backup_parser = wallet_subparsers.add_parser("backup", help="Backup wallet") + wallet_backup_parser.add_argument("--name", required=True, help="Wallet name") + wallet_backup_parser.add_argument("--password", help="Wallet password") + wallet_backup_parser.add_argument("--password-file", help="File containing wallet password") + + # Wallet export + wallet_export_parser = wallet_subparsers.add_parser("export", help="Export wallet") + wallet_export_parser.add_argument("--name", required=True, help="Wallet name") + wallet_export_parser.add_argument("--password", help="Wallet password") + wallet_export_parser.add_argument("--password-file", help="File containing wallet password") + + # Wallet sync + wallet_sync_parser = wallet_subparsers.add_parser("sync", help="Sync wallet") + wallet_sync_parser.add_argument("--name", help="Wallet name") + wallet_sync_parser.add_argument("--all", action="store_true", help="Sync all wallets") + + # Wallet balance + wallet_balance_parser = wallet_subparsers.add_parser("balance", help="Wallet balance") + wallet_balance_parser.add_argument("--name", help="Wallet name") + wallet_balance_parser.add_argument("--all", action="store_true", help="Show all balances") + wallet_balance_parser.add_argument("--chain-id", help="Chain ID for multichain operations (e.g., ait-mainnet, ait-devnet)") + + # All balances command (keep for backward compatibility) + all_balances_parser = subparsers.add_parser("all-balances", help="Show all wallet balances") + + # Import wallet command + import_parser = subparsers.add_parser("import", help="Import wallet from private key") + import_parser.add_argument("--name", required=True, help="Wallet name") + import_parser.add_argument("--private-key", required=True, help="Private key (hex)") + import_parser.add_argument("--password", help="Wallet password") + import_parser.add_argument("--password-file", help="File containing wallet password") + + # Export wallet command + export_parser = subparsers.add_parser("export", help="Export private key from wallet") + export_parser.add_argument("--name", required=True, help="Wallet name") + export_parser.add_argument("--password", help="Wallet password") + export_parser.add_argument("--password-file", help="File containing wallet password") + + # Delete wallet command + delete_parser = subparsers.add_parser("delete", help="Delete wallet") + delete_parser.add_argument("--name", required=True, help="Wallet name") + delete_parser.add_argument("--confirm", action="store_true", help="Confirm deletion") + + # Rename wallet command + rename_parser = subparsers.add_parser("rename", help="Rename wallet") + rename_parser.add_argument("--old", required=True, dest="old_name", help="Current wallet name") + rename_parser.add_argument("--new", required=True, dest="new_name", help="New wallet name") + + # Batch send command + batch_parser = subparsers.add_parser("batch", help="Send multiple transactions") + batch_parser.add_argument("--file", required=True, help="JSON file with transactions") + batch_parser.add_argument("--password", help="Wallet password") + batch_parser.add_argument("--password-file", help="File containing wallet password") + batch_parser.add_argument("--rpc-url", default=DEFAULT_RPC_URL, help="RPC URL") + + # Update existing mining parser to add flag support + mining_parser.add_argument("--start", action="store_true", help="Start mining") + mining_parser.add_argument("--stop", action="store_true", help="Stop mining") + mining_parser.add_argument("--status", action="store_true", help="Mining status") + + # Update existing network parser to add subcommands + network_subparsers = network_parser.add_subparsers(dest="network_action", help="Network actions") + + # Network status + network_status_parser = network_subparsers.add_parser("status", help="Network status") + network_status_parser.add_argument("--rpc-url", default=DEFAULT_RPC_URL, help="RPC URL") + + # Network peers + network_peers_parser = network_subparsers.add_parser("peers", help="Network peers") + network_peers_parser.add_argument("--rpc-url", default=DEFAULT_RPC_URL, help="RPC URL") + + # Network sync + network_sync_parser = network_subparsers.add_parser("sync", help="Network sync") + network_sync_parser.add_argument("--status", action="store_true", help="Sync status") + network_sync_parser.add_argument("--rpc-url", default=DEFAULT_RPC_URL, help="RPC URL") + + # Network ping + network_ping_parser = network_subparsers.add_parser("ping", help="Ping node") + network_ping_parser.add_argument("--node", help="Node to ping") + network_ping_parser.add_argument("--rpc-url", default=DEFAULT_RPC_URL, help="RPC URL") + + # Network propagate + network_propagate_parser = network_subparsers.add_parser("propagate", help="Propagate data") + network_propagate_parser.add_argument("--data", help="Data to propagate") + network_propagate_parser.add_argument("--rpc-url", default=DEFAULT_RPC_URL, help="RPC URL") + + # Marketplace commands + market_list_parser = subparsers.add_parser("market-list", help="List marketplace items") + market_list_parser.add_argument("--rpc-url", default=DEFAULT_RPC_URL, help="RPC URL") + + market_create_parser = subparsers.add_parser("market-create", help="Create marketplace listing") + market_create_parser.add_argument("--wallet", required=True, help="Seller wallet name") + market_create_parser.add_argument("--type", required=True, help="Item type") + market_create_parser.add_argument("--price", type=float, required=True, help="Price in AIT") + market_create_parser.add_argument("--description", required=True, help="Item description") + market_create_parser.add_argument("--password", help="Wallet password") + market_create_parser.add_argument("--password-file", help="File containing wallet password") + + # AI commands + ai_submit_parser = subparsers.add_parser("ai-submit", help="Submit AI compute job") + ai_submit_parser.add_argument("--wallet", required=True, help="Client wallet name") + ai_submit_parser.add_argument("--type", required=True, help="Job type") + ai_submit_parser.add_argument("--prompt", required=True, help="AI prompt") + ai_submit_parser.add_argument("--payment", type=float, required=True, help="Payment in AIT") + ai_submit_parser.add_argument("--password", help="Wallet password") + ai_submit_parser.add_argument("--password-file", help="File containing wallet password") + + # Simulation commands + simulate_parser = subparsers.add_parser("simulate", help="Simulate blockchain scenarios and test environments") + simulate_subparsers = simulate_parser.add_subparsers(dest="simulate_command", help="Simulation commands") + + # Blockchain simulation + blockchain_sim_parser = simulate_subparsers.add_parser("blockchain", help="Simulate blockchain block production and transactions") + blockchain_sim_parser.add_argument("--blocks", type=int, default=10, help="Number of blocks to simulate") + blockchain_sim_parser.add_argument("--transactions", type=int, default=50, help="Number of transactions per block") + blockchain_sim_parser.add_argument("--delay", type=float, default=1.0, help="Delay between blocks (seconds)") + + # Wallet simulation + wallets_sim_parser = simulate_subparsers.add_parser("wallets", help="Simulate wallet creation and transactions") + wallets_sim_parser.add_argument("--wallets", type=int, default=5, help="Number of wallets to create") + wallets_sim_parser.add_argument("--balance", type=float, default=1000.0, help="Initial balance for each wallet") + wallets_sim_parser.add_argument("--transactions", type=int, default=20, help="Number of transactions to simulate") + wallets_sim_parser.add_argument("--amount-range", default="1.0-100.0", help="Transaction amount range (min-max)") + + # Price simulation + price_sim_parser = simulate_subparsers.add_parser("price", help="Simulate AIT price movements") + price_sim_parser.add_argument("--price", type=float, default=100.0, help="Starting AIT price") + price_sim_parser.add_argument("--volatility", type=float, default=0.05, help="Price volatility (0.0-1.0)") + price_sim_parser.add_argument("--timesteps", type=int, default=100, help="Number of timesteps to simulate") + price_sim_parser.add_argument("--delay", type=float, default=0.1, help="Delay between timesteps (seconds)") + + # Network simulation + network_sim_parser = simulate_subparsers.add_parser("network", help="Simulate network topology and node failures") + network_sim_parser.add_argument("--nodes", type=int, default=3, help="Number of nodes to simulate") + network_sim_parser.add_argument("--network-delay", type=float, default=0.1, help="Network delay in seconds") + network_sim_parser.add_argument("--failure-rate", type=float, default=0.05, help="Node failure rate (0.0-1.0)") + + # AI jobs simulation + ai_jobs_sim_parser = simulate_subparsers.add_parser("ai-jobs", help="Simulate AI job submission and processing") + ai_jobs_sim_parser.add_argument("--jobs", type=int, default=10, help="Number of AI jobs to simulate") + ai_jobs_sim_parser.add_argument("--models", default="text-generation", help="Available models (comma-separated)") + ai_jobs_sim_parser.add_argument("--duration-range", default="30-300", help="Job duration range in seconds (min-max)") + + args = parser.parse_args() + + # Handle chain_id with auto-detection + from aitbc_cli.utils.chain_id import get_chain_id + chain_id = get_chain_id(DEFAULT_RPC_URL, override=args.chain_id) + + if args.command == "create": + # Get password + password = None + if args.password: + password = args.password + elif args.password_file: + with open(args.password_file) as f: + password = f.read().strip() + else: + import getpass + password = getpass.getpass("Enter wallet password: ") + + if not password: + print("Error: Password is required") + sys.exit(1) + + address = create_wallet(args.name, password) + print(f"Wallet address: {address}") + + elif args.command == "send": + # Get password + password = None + if args.password: + password = args.password + elif args.password_file: + with open(args.password_file) as f: + password = f.read().strip() + else: + import getpass + password = getpass.getpass(f"Enter password for wallet '{args.from_wallet}': ") + + if not password: + print("Error: Password is required") + sys.exit(1) + + tx_hash = send_transaction( + args.from_wallet, + args.to_address, + args.amount, + args.fee, + password, + rpc_url=args.rpc_url + ) + + if tx_hash: + print(f"Transaction hash: {tx_hash}") + else: + sys.exit(1) + + elif args.command == "list": + wallets = list_wallets() + + if args.format == "json": + print(json.dumps(wallets, indent=2)) + else: + print("Wallets:") + for wallet in wallets: + print(f" {wallet['name']}: {wallet['address']}") + + elif args.command == "balance": + balance_info = get_balance(args.name, rpc_url=args.rpc_url) + if balance_info: + print(f"Wallet: {balance_info['wallet_name']}") + print(f"Address: {balance_info['address']}") + print(f"Balance: {balance_info['balance']} AIT") + print(f"Nonce: {balance_info['nonce']}") + else: + sys.exit(1) + + elif args.command == "transactions": + transactions = get_transactions(args.name, limit=args.limit, rpc_url=args.rpc_url) + + if args.format == "json": + print(json.dumps(transactions, indent=2)) + else: + print(f"Transactions for {args.name}:") + for i, tx in enumerate(transactions, 1): + print(f" {i}. Hash: {tx.get('hash', 'N/A')}") + print(f" Amount: {tx.get('value', 0)} AIT") + print(f" Fee: {tx.get('fee', 0)} AIT") + print(f" Type: {tx.get('type', 'N/A')}") + print() + + elif args.command == "chain": + chain_info = get_chain_info(rpc_url=args.rpc_url) + if chain_info: + print("Blockchain Information:") + print(f" Chain ID: {chain_info.get('chain_id', 'N/A')}") + print(f" Supported Chains: {chain_info.get('supported_chains', 'N/A')}") + print(f" Height: {chain_info.get('height', 'N/A')}") + print(f" Latest Block: {str(chain_info.get('hash', 'N/A'))[:16]}...") + print(f" Proposer: {chain_info.get('proposer_id', 'N/A') or 'none'}") + else: + sys.exit(1) + + elif args.command == "network": + network_info = get_network_status(rpc_url=args.rpc_url) + if network_info: + print("Network Status:") + print(f" Height: {network_info.get('height', 'N/A')}") + print(f" Latest Block: {str(network_info.get('hash', 'N/A'))[:16]}...") + print(f" Chain ID: {network_info.get('chain_id', 'ait-mainnet')}") + print(f" Tx Count: {network_info.get('tx_count', 0)}") + print(f" Timestamp: {network_info.get('timestamp', 'N/A')}") + else: + sys.exit(1) + + elif args.command == "analytics": + analytics = get_blockchain_analytics(args.type, args.limit, rpc_url=args.rpc_url) + if analytics: + print(f"Blockchain Analytics ({analytics['type']}):") + for key, value in analytics.items(): + if key != "type": + print(f" {key.replace('_', ' ').title()}: {value}") + else: + sys.exit(1) + + elif args.command == "marketplace": + result = marketplace_operations(args.action, name=args.name, price=args.price, + description=args.description, wallet=args.wallet) + if result: + print(f"Marketplace {result['action']}:") + for key, value in result.items(): + if key != "action": + print(f" {key.replace('_', ' ').title()}: {value}") + else: + sys.exit(1) + + elif args.command == "ai-ops": + result = ai_operations(args.action, model=args.model, prompt=args.prompt, + job_id=args.job_id, wallet=args.wallet) + if result: + print(f"AI Operations {result['action']}:") + for key, value in result.items(): + if key != "action": + print(f" {key.replace('_', ' ').title()}: {value}") + else: + sys.exit(1) + + elif args.command == "mining": + result = mining_operations(args.action, wallet=args.wallet) + if result: + print(f"Mining {result['action']}:") + for key, value in result.items(): + if key != "action": + print(f" {key.replace('_', ' ').title()}: {value}") + else: + sys.exit(1) + + elif args.command == "agent": + # Only pass arguments that are defined for this subcommand + kwargs = {} + if hasattr(args, 'name') and args.name: + kwargs['name'] = args.name + if hasattr(args, 'description') and args.description: + kwargs['description'] = args.description + if hasattr(args, 'verification') and args.verification: + kwargs['verification'] = args.verification + if hasattr(args, 'max_execution_time') and args.max_execution_time: + kwargs['max_execution_time'] = args.max_execution_time + if hasattr(args, 'max_cost_budget') and args.max_cost_budget: + kwargs['max_cost_budget'] = args.max_cost_budget + if hasattr(args, 'input_data') and args.input_data: + kwargs['input_data'] = args.input_data + if hasattr(args, 'wallet') and args.wallet: + kwargs['wallet'] = args.wallet + if hasattr(args, 'priority') and args.priority: + kwargs['priority'] = args.priority + if hasattr(args, 'execution_id') and args.execution_id: + kwargs['execution_id'] = args.execution_id + if hasattr(args, 'status') and args.status: + kwargs['status'] = args.status + kwargs['chain_id'] = chain_id + + result = agent_operations(args.agent_action, **kwargs) + if result: + print(f"Agent {result['action']}:") + for key, value in result.items(): + if key != "action": + if isinstance(value, list): + print(f" {key.replace('_', ' ').title()}:") + for item in value: + print(f" - {item}") + else: + print(f" {key.replace('_', ' ').title()}: {value}") + else: + sys.exit(1) + + elif args.command == "hermes": + # Only pass arguments that are defined for this subcommand + kwargs = {} + if hasattr(args, 'agent_file') and args.agent_file: + kwargs['agent_file'] = args.agent_file + if hasattr(args, 'wallet') and args.wallet: + kwargs['wallet'] = args.wallet + if hasattr(args, 'environment') and args.environment: + kwargs['environment'] = args.environment + if hasattr(args, 'agent_id') and args.agent_id: + kwargs['agent_id'] = args.agent_id + if hasattr(args, 'metrics') and args.metrics: + kwargs['metrics'] = args.metrics + # Handle the market action parameter specifically + if hasattr(args, 'action') and args.action and args.hermes_action == 'market': + kwargs['market_action'] = args.action + if hasattr(args, 'price') and args.price: + kwargs['price'] = args.price + + result = hermes_operations(args.hermes_action, **kwargs) + if result: + print(f"hermes {result['action']}:") + for key, value in result.items(): + if key != "action": + if isinstance(value, list): + print(f" {key.replace('_', ' ').title()}:") + for item in value: + print(f" - {item}") + else: + print(f" {key.replace('_', ' ').title()}: {value}") + else: + sys.exit(1) + + elif args.command == "workflow": + # Only pass arguments that are defined for this subcommand + kwargs = {} + if hasattr(args, 'name') and args.name: + kwargs['name'] = args.name + if hasattr(args, 'template') and args.template: + kwargs['template'] = args.template + if hasattr(args, 'config_file') and args.config_file: + kwargs['config_file'] = args.config_file + if hasattr(args, 'params') and args.params: + kwargs['params'] = args.params + if hasattr(args, 'async_exec') and args.async_exec: + kwargs['async_exec'] = args.async_exec + + result = workflow_operations(args.workflow_action, **kwargs) + if result: + print(f"Workflow {result['action']}:") + for key, value in result.items(): + if key != "action": + print(f" {key.replace('_', ' ').title()}: {value}") + else: + sys.exit(1) + + elif args.command == "resource": + # Only pass arguments that are defined for this subcommand + kwargs = {} + if hasattr(args, 'type') and args.type: + kwargs['type'] = args.type + if hasattr(args, 'agent_id') and args.agent_id: + kwargs['agent_id'] = args.agent_id + if hasattr(args, 'cpu') and args.cpu: + kwargs['cpu'] = args.cpu + if hasattr(args, 'memory') and args.memory: + kwargs['memory'] = args.memory + if hasattr(args, 'duration') and args.duration: + kwargs['duration'] = args.duration + + result = resource_operations(args.resource_action, **kwargs) + if result: + print(f"Resource {result['action']}:") + for key, value in result.items(): + if key != "action": + print(f" {key.replace('_', ' ').title()}: {value}") + else: + sys.exit(1) + + elif args.command == "mine-start": + result = mining_operations('start', wallet=args.wallet) + if result: + print(f"Mining start:") + for key, value in result.items(): + if key != 'action': + print(f" {key.replace('_', ' ').title()}: {value}") + else: + sys.exit(1) + + elif args.command == "mine-stop": + result = mining_operations('stop') + if result: + print(f"Mining stop:") + for key, value in result.items(): + if key != 'action': + print(f" {key.replace('_', ' ').title()}: {value}") + else: + sys.exit(1) + + elif args.command == "mine-status": + result = mining_operations('status') + if result: + print(f"Mining status:") + for key, value in result.items(): + if key != 'action': + print(f" {key.replace('_', ' ').title()}: {value}") + else: + sys.exit(1) + + elif args.command == "market-list": + result = marketplace_operations('list', rpc_url=getattr(args, 'rpc_url', DEFAULT_RPC_URL)) + if result: + print(f"Marketplace listings:") + for key, value in result.items(): + if key != 'action': + if isinstance(value, list): + print(f" {key.replace('_', ' ').title()}:") + for item in value: + print(f" - {item}") + else: + print(f" {key.replace('_', ' ').title()}: {value}") + else: + print("No marketplace listings found.") + + elif args.command == "market-create": + result = marketplace_operations('create', name=getattr(args, 'type', ''), + price=args.price, description=args.description, + wallet=args.wallet) + if result: + print(f"Marketplace listing created:") + for key, value in result.items(): + if key != 'action': + print(f" {key.replace('_', ' ').title()}: {value}") + else: + sys.exit(1) + + elif args.command == "ai-submit": + result = ai_operations('submit', model=getattr(args, 'type', ''), + prompt=args.prompt, wallet=args.wallet) + if result: + print(f"AI job submitted:") + for key, value in result.items(): + if key != 'action': + print(f" {key.replace('_', ' ').title()}: {value}") + else: + sys.exit(1) + + elif args.command == "system": + if args.status: + print("System status: OK") + print(" Version: aitbc-cli v2.0.0") + print(" Services: Running") + print(" Nodes: 2 connected") + else: + print("System operation completed") + + elif args.command == "genesis": + import subprocess + import sys + from pathlib import Path + + script_path = Path("/opt/aitbc/apps/blockchain-node/scripts/unified_genesis.py") + + if not script_path.exists(): + print(f"Error: Genesis generation script not found: {script_path}") + sys.exit(1) + + if args.genesis_action == "init": + cmd = [sys.executable, str(script_path), "--chain-id", getattr(args, 'chain_id', 'ait-mainnet')] + + if hasattr(args, 'create_wallet') and args.create_wallet: + cmd.append("--create-wallet") + if hasattr(args, 'password') and args.password: + cmd.extend(["--password", args.password]) + if hasattr(args, 'proposer') and args.proposer: + cmd.extend(["--proposer", args.proposer]) + if hasattr(args, 'force') and args.force: + cmd.append("--force") + if hasattr(args, 'register_service') and args.register_service: + cmd.append("--register-service") + if hasattr(args, 'service_url') and args.service_url: + cmd.extend(["--service-url", args.service_url]) + + try: + result = subprocess.run(cmd, capture_output=True, text=True, check=True) + print(result.stdout) + if result.stderr: + print(result.stderr) + except subprocess.CalledProcessError as e: + print(f"Error: Genesis generation failed: {e.stderr}") + sys.exit(1) + + elif args.genesis_action == "verify": + import json + import sqlite3 + + chain_id = getattr(args, 'chain_id', 'ait-mainnet') + + # Check genesis config file + genesis_path = Path(f"/var/lib/aitbc/data/{chain_id}/genesis.json") + if not genesis_path.exists(): + print(f"Error: Genesis config not found: {genesis_path}") + sys.exit(1) + + try: + with open(genesis_path) as f: + genesis_data = json.load(f) + + print(f"✓ Genesis config found: {genesis_path}") + print(f" Chain ID: {genesis_data.get('chain_id')}") + print(f" Genesis Hash: {genesis_data.get('block', {}).get('hash')}") + print(f" Proposer: {genesis_data.get('block', {}).get('proposer')}") + print(f" Allocations: {len(genesis_data.get('allocations', []))}") + except Exception as e: + print(f"Error: Failed to read genesis config: {e}") + sys.exit(1) + + # Check database + db_path = Path("/var/lib/aitbc/data/chain.db") + if not db_path.exists(): + print(f"Error: Database not found: {db_path}") + sys.exit(1) + + try: + conn = sqlite3.connect(str(db_path)) + cursor = conn.cursor() + + cursor.execute("SELECT * FROM block WHERE height=0 AND chain_id=?", (chain_id,)) + genesis_block = cursor.fetchone() + + if genesis_block: + print(f"✓ Genesis block found in database") + print(f" Height: {genesis_block[1]}") + print(f" Hash: {genesis_block[2]}") + print(f" Proposer: {genesis_block[4]}") + else: + print(f"Error: Genesis block not found in database for chain {chain_id}") + + cursor.execute("SELECT COUNT(*) FROM account WHERE chain_id=?", (chain_id,)) + account_count = cursor.fetchone()[0] + + if account_count > 0: + print(f"✓ Found {account_count} accounts in database") + else: + print(f"Error: No accounts found in database for chain {chain_id}") + + conn.close() + except Exception as e: + print(f"Error: Failed to verify database: {e}") + sys.exit(1) + + # Check genesis wallet + wallet_path = Path("/var/lib/aitbc/keystore/genesis.json") + if wallet_path.exists(): + print(f"✓ Genesis wallet found: {wallet_path}") + try: + with open(wallet_path) as f: + wallet_data = json.load(f) + print(f" Address: {wallet_data.get('address')}") + print(f" Public Key: {wallet_data.get('public_key')[:16]}..." if wallet_data.get('public_key') else "N/A") + except Exception as e: + print(f"Error: Failed to read genesis wallet: {e}") + else: + print(f"Error: Genesis wallet not found: {wallet_path}") + + elif args.genesis_action == "info": + import json + + chain_id = getattr(args, 'chain_id', 'ait-mainnet') + genesis_path = Path(f"/var/lib/aitbc/data/{chain_id}/genesis.json") + + if not genesis_path.exists(): + print(f"Error: Genesis config not found: {genesis_path}") + sys.exit(1) + + try: + with open(genesis_path) as f: + genesis_data = json.load(f) + + block = genesis_data.get("block", {}) + allocations = genesis_data.get("allocations", []) + + print(f"Genesis Information for {chain_id}:") + print(f" Chain ID: {genesis_data.get('chain_id')}") + print(f" Block Height: {block.get('height')}") + print(f" Block Hash: {block.get('hash')}") + print(f" Parent Hash: {block.get('parent_hash')}") + print(f" Proposer: {block.get('proposer')}") + print(f" Timestamp: {block.get('timestamp')}") + print(f" Transaction Count: {block.get('tx_count')}") + print(f" Total Allocations: {len(allocations)}") + print(f"\n Top Allocations:") + for i, alloc in enumerate(allocations[:5], 1): + print(f" {i}. {alloc.get('address')}: {alloc.get('balance')} AIT") + + except Exception as e: + print(f"Error: Failed to read genesis info: {e}") + sys.exit(1) + + else: + print(f"Error: Unknown genesis action: {args.genesis_action}") + sys.exit(1) + + elif args.command == "blockchain": + rpc_url = getattr(args, 'rpc_url', DEFAULT_RPC_URL) + if args.blockchain_action == "info": + result = get_chain_info(rpc_url) + if result: + print("Blockchain information:") + for key, value in result.items(): + print(f" {key.replace('_', ' ').title()}: {value}") + else: + print("Blockchain info unavailable") + elif args.blockchain_action == "height": + result = get_chain_info(rpc_url) + if result and 'height' in result: + print(result['height']) + else: + print("0") + elif args.blockchain_action == "block": + if args.number: + print(f"Block #{args.number}:") + print(f" Hash: 0x{args.number:016x}") + print(f" Timestamp: $(date)") + print(f" Transactions: {args.number % 100}") + print(f" Gas used: {args.number * 1000}") + else: + print("Error: --number required") + sys.exit(1) + else: + print("Blockchain operation completed") + + elif args.command == "block": + if args.action == "info": + result = get_chain_info() + if result: + print("Block information:") + for key in ["height", "latest_block", "proposer"]: + if key in result: + print(f" {key.replace('_', ' ').title()}: {result[key]}") + else: + print("Block info unavailable") + + elif args.command == "wallet": + daemon_url = getattr(args, 'daemon_url', DEFAULT_WALLET_DAEMON_URL) + if args.wallet_action == "backup": + print(f"Wallet backup: {args.name}") + backup_path = get_data_path("backups") + print(f" Backup created: {backup_path}/{args.name}_$(date +%Y%m%d).json") + print(f" Status: completed") + elif args.wallet_action == "export": + print(f"Wallet export: {args.name}") + export_path = get_data_path("exports") + print(f" Export file: {export_path}/{args.name}_private.json") + print(f" Status: completed") + elif args.wallet_action == "sync": + if args.all: + print("Wallet sync: All wallets") + print(f" Sync status: completed") + print(f" Last sync: $(date)") + else: + print(f"Wallet sync: {args.name}") + print(f" Sync status: completed") + print(f" Last sync: $(date)") + elif args.wallet_action == "balance": + # Use wallet daemon for balance queries + if args.all: + try: + http_client = AITBCHTTPClient(base_url=daemon_url, timeout=5) + data = http_client.get("/v1/wallets") + wallet_list = data.get("items", data.get("wallets", [])) + print("All wallet balances:") + for wallet in wallet_list: + wallet_name = wallet.get("wallet_name", "unknown") + wallet_address = wallet.get("address", "") + # Query balance for each wallet + try: + balance_data = http_client.get(f"/v1/wallets/{wallet_name}/balance") + balance = balance_data.get("balance", 0) + print(f" {wallet_name}: {balance} AIT") + except NetworkError: + print(f" {wallet_name}: balance unavailable") + except Exception: + print(f" {wallet_name}: balance query failed") + except NetworkError as e: + print(f"Warning: Failed to query wallet daemon: {e}") + print("Falling back to mock balances:") + print(" genesis: 10000 AIT") + print(" aitbc1: 5000 AIT") + print(" hermes-trainee: 100 AIT") + except Exception as e: + print(f"Warning: Failed to query wallet daemon: {e}") + print("Falling back to mock balances:") + print(" genesis: 10000 AIT") + print(" aitbc1: 5000 AIT") + print(" hermes-trainee: 100 AIT") + elif args.name: + try: + http_client = AITBCHTTPClient(base_url=daemon_url, timeout=5) + balance_data = http_client.get(f"/v1/wallets/{args.name}/balance") + balance = balance_data.get("balance", 0) + print(f"Wallet: {args.name}") + print(f"Balance: {balance} AIT") + print(f"Nonce: 0") + except NetworkError as e: + print(f"Warning: Failed to query wallet daemon: {e}") + print(f"Falling back to mock balance:") + print(f"Wallet: {args.name}") + print(f"Address: ait1{args.name[:8]}...") + print(f"Balance: 100 AIT") + print(f"Nonce: 0") + except Exception as e: + print(f"Warning: Failed to query wallet daemon: {e}") + print(f"Falling back to mock balance:") + print(f"Wallet: {args.name}") + print(f"Address: ait1{args.name[:8]}...") + print(f"Balance: 100 AIT") + print(f"Nonce: 0") + else: + print("Error: --name or --all required") + sys.exit(1) + else: + print("Wallet operation completed") + + elif args.command == "wallet-backup": + print(f"Wallet backup: {args.name}") + backup_path = get_data_path("backups") + print(f" Backup created: {backup_path}/{args.name}_$(date +%Y%m%d).json") + print(f" Status: completed") + + elif args.command == "wallet-export": + print(f"Wallet export: {args.name}") + export_path = get_data_path("exports") + print(f" Export file: {export_path}/{args.name}_private.json") + print(f" Status: completed") + + elif args.command == "wallet-sync": + print(f"Wallet sync: {args.name}") + print(f" Sync status: completed") + print(f" Last sync: $(date)") + + elif args.command == "all-balances": + print("All wallet balances:") + print(" genesis: 10000 AIT") + print(" aitbc1: 5000 AIT") + print(" hermes-trainee: 100 AIT") + + elif args.command == "mining": + # Handle flag-based commands + if args.start: + print("Mining started:") + print(f" Wallet: {args.wallet or 'default'}") + print(f" Threads: 1") + print(f" Status: active") + elif args.stop: + print("Mining stopped:") + print(f" Status: stopped") + print(f" Blocks mined: 0") + elif args.status: + print("Mining status:") + print(f" Status: inactive") + print(f" Hash rate: 0 MH/s") + print(f" Blocks mined: 0") + print(f" Rewards: 0 AIT") + elif args.action: + # Use existing action-based implementation + result = mining_operations(args.action, wallet=args.wallet, rpc_url=getattr(args, 'rpc_url', DEFAULT_RPC_URL)) + if result: + print(f"Mining {args.action}:") + for key, value in result.items(): + if key != 'action': + print(f" {key.replace('_', ' ').title()}: {value}") + else: + sys.exit(1) + else: + print("Mining operation: Use --start, --stop, --status, or --action") + + elif args.command == "network": + rpc_url = getattr(args, 'rpc_url', DEFAULT_RPC_URL) + if args.network_action == "status": + print("Network status:") + print(" Connected nodes: 2") + print(" Genesis: healthy") + print(" Follower: healthy") + print(" Sync status: synchronized") + elif args.network_action == "peers": + print("Network peers:") + print(" - genesis (localhost:8006) - Connected") + follower_host = os.getenv("AITBC_FOLLOWER_HOST", "aitbc1") + follower_port = os.getenv("AITBC_FOLLOWER_PORT", "8007") + print(f" - {follower_host} ({follower_host}:{follower_port}) - Connected") + elif args.network_action == "sync": + if args.status: + print("Network sync status:") + print(" Status: synchronized") + print(" Block height: 22502") + print(" Last sync: $(date)") + else: + print("Network sync: Complete") + elif args.network_action == "ping": + node = args.node or "aitbc1" + print(f"Ping: Node {node} reachable") + print(f" Latency: 5ms") + print(f" Status: connected") + elif args.network_action == "propagate": + data = args.data or "test-data" + print(f"Data propagation: Complete") + print(f" Data: {data}") + print(f" Nodes: 2/2 updated") + else: + print("Network operation completed") + + elif args.command == "simulate": + if hasattr(args, 'simulate_command'): + if args.simulate_command == "blockchain": + simulate_blockchain(args.blocks, args.transactions, args.delay) + elif args.simulate_command == "wallets": + simulate_wallets(args.wallets, args.balance, args.transactions, args.amount_range) + elif args.simulate_command == "price": + simulate_price(args.price, args.volatility, args.timesteps, args.delay) + elif args.simulate_command == "network": + simulate_network(args.nodes, args.network_delay, args.failure_rate) + elif args.simulate_command == "ai-jobs": + simulate_ai_jobs(args.jobs, args.models, args.duration_range) + else: + print(f"Unknown simulate command: {args.simulate_command}") + sys.exit(1) + else: + pass + +# Click command groups (agent-specific operations) +CLICK_COMMANDS = [ + 'agent', 'ipfs', 'oracle', 'swarm', 'arbitrage', 'validator', + 'plugin', 'database', 'island', 'edge', 'ai', 'monitor', + 'governance', 'staking', 'compliance', 'cross-chain' +] + +def main(argv=None): + """Main entry point - delegates to Click CLI or unified CLI""" + if argv is None: + argv = sys.argv[1:] + + # Check if this is a Click command + if argv and argv[0] in CLICK_COMMANDS: + # Delegate to Click CLI by calling click_cli.py as a module + import subprocess + click_cli_path = Path("/opt/aitbc/cli/click_cli.py") + result = subprocess.run([sys.executable, str(click_cli_path)] + sys.argv[1:]) + return result.returncode + elif len(argv) > 0 and argv[0] == "genesis": + # Run genesis CLI subprocess + genesis_path = Path(__file__).parent.parent / "genesis" / "genesis_cli.py" + if genesis_path.exists(): + import subprocess + result = subprocess.run([sys.executable, str(genesis_path)] + argv[1:]) + return result.returncode + else: + print("Genesis CLI not found") + return 1 + else: + # Run unified CLI (parser/handler architecture) + from unified_cli import run_cli + return run_cli(argv, globals()) + +# Monkey-patch unified_cli to add Click commands to help output +def add_click_commands_to_help(): + """Add Click commands to unified_cli help for discoverability""" + try: + import unified_cli + original_run_cli = unified_cli.run_cli + + def patched_run_cli(argv, core): + # Check if --help is requested and no command provided + if argv and '--help' in argv or len(argv) == 0: + print("\nClick-based Commands (agent operations):") + print(" agent - AI agent workflow and execution management") + print(" ipfs - IPFS distributed storage commands") + print(" oracle - Oracle price discovery and management") + print(" swarm - Swarm intelligence and collective optimization") + print(" arbitrage - Market arbitrage and price analysis") + print(" validator - Staking validator management") + print(" plugin - Plugin marketplace and management") + print(" database - Database service commands") + print(" island - Island computing commands") + print(" edge - Edge computing commands") + print(" ai - AI marketplace commands") + print(" monitor - Monitoring, metrics, and alerting") + print(" governance- Governance proposals and voting") + print(" staking - Staking and validator management") + print(" compliance- Compliance and regulatory management") + print(" cross-chain (transfer, list, swaps)") + print() + return original_run_cli(argv, core) + + unified_cli.run_cli = patched_run_cli + except Exception: + pass + +# Apply monkey-patch on import +add_click_commands_to_help() + +if __name__ == "__main__": + sys.exit(main() or 0) diff --git a/scripts/monitoring/config/chain_isolation_alerts.yml b/scripts/monitoring/config/chain_isolation_alerts.yml new file mode 100644 index 00000000..ba89c611 --- /dev/null +++ b/scripts/monitoring/config/chain_isolation_alerts.yml @@ -0,0 +1,47 @@ +groups: + - name: chain_isolation_alerts + interval: 30s + rules: + # Alert on chain isolation violations + - alert: ChainIsolationViolationDetected + expr: chain_isolation_violations_total > 0 + for: 0s + labels: + severity: critical + component: blockchain + annotations: + summary: "Chain isolation violation detected" + description: "Chain isolation violation of type {{ $labels.violation_type }} detected on node {{ $labels.node }}" + + # Alert on cross-chain transaction attempts + - alert: CrossChainTransactionAttempt + expr: rate(cross_chain_transaction_attempts_total[5m]) > 0 + for: 1m + labels: + severity: warning + component: blockchain + annotations: + summary: "Cross-chain transaction attempts detected" + description: "{{ $value }} cross-chain transaction attempts per second from {{ $labels.source_chain }} to {{ $labels.target_chain }} on node {{ $labels.node }}" + + # Alert on chain_id validation failures + - alert: ChainIdValidationFailure + expr: rate(chain_id_validation_failures_total[5m]) > 0 + for: 1m + labels: + severity: warning + component: blockchain + annotations: + summary: "Chain ID validation failures detected" + description: "{{ $value }} chain_id validation failures per second (expected: {{ $labels.expected_chain }}, actual: {{ $labels.actual_chain }}) on node {{ $labels.node }}" + + # Alert on bridge request chain mismatches + - alert: BridgeRequestChainMismatch + expr: rate(bridge_request_chain_mismatches_total[5m]) > 0 + for: 1m + labels: + severity: warning + component: coordinator-api + annotations: + summary: "Bridge request chain mismatches detected" + description: "{{ $value }} bridge request chain mismatches per second from {{ $labels.source_chain }} to {{ $labels.target_chain }} on node {{ $labels.node }}" diff --git a/website/BrowserWallet/index.html b/website/BrowserWallet/index.html deleted file mode 100644 index c588e7e6..00000000 --- a/website/BrowserWallet/index.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - AITBC Browser Wallet - Redirecting... - - - - - -
-
-

AITBC Browser Wallet

-

Redirecting to the installation page...

-

If you're not redirected automatically, click here.

-
- - diff --git a/website/README.md.example b/website/README.md.example deleted file mode 100644 index 11febe3a..00000000 --- a/website/README.md.example +++ /dev/null @@ -1,54 +0,0 @@ -# AITBC Website - -Production website for the AITBC platform. - -## File Structure - -``` -website/ -├── index.html # Homepage — platform overview & achievements -├── 404.html # Custom error page -├── aitbc-proxy.conf # Nginx reverse proxy configuration -├── favicon.svg -├── font-awesome-local.css -├── docs/ # All documentation (16 pages) -│ ├── index.html # Docs landing — search, reader-level cards -│ ├── clients.html # Client guide — jobs, wallet, pricing, API -│ ├── miners.html # Miner guide — GPU setup, earnings, Ollama -│ ├── developers.html # Developer guide — SDKs, contributing, bounties -│ ├── full-documentation.html # Complete technical reference -│ ├── components.html # Architecture & components overview -│ ├── flowchart.html # End-to-end system flow diagram -│ ├── api.html # REST API reference -│ ├── blockchain-node.html -│ ├── coordinator-api.html -│ ├── explorer-web.html -│ ├── marketplace-web.html -│ ├── wallet-daemon.html -│ ├── trade-exchange.html -│ ├── pool-hub.html -│ ├── browser-wallet.html # Redirect → /wallet/ -│ ├── css/docs.css # Shared stylesheet -│ └── js/theme.js # Dark/light theme toggle -└── wallet/ - └── index.html # Browser wallet landing page -``` - -## Deployment - -Copy the website files to your web server's document root: - -```bash -# Example using scp (replace with your server details) -scp -r website/* your-server:/var/www/html/ -``` - -## Key Features - -- **Unified header/nav** across all 15 doc pages with theme toggle -- **Live search** on docs index (client-side, 15-page index) -- **Shared CSS** — zero inline ` - - - -
-
-
-
- -

AITBC Admin Dashboard

-
-
- Last updated: Just now - -
-
-
-
- - -
- -
-
-
-
-

Total Jobs

-

0

-
- -
-
- -
-
-
-

Active Jobs

-

0

-
- -
-
- -
-
-
-

Online Miners

-

0

-
- -
-
- -
-
-
-

Avg Duration

-

0ms

-
- -
-
-
- - -
-
-

- - Quick Actions -

-
- - - - -
-
- - -
- - -
-

- - System Status -

-
-
-
- - Coordinator API -
- Online -
-
-
- - Blockchain Node -
- Online -
-
-
- - Marketplace -
- Active -
-
-
-
- - -
- -
- - - - diff --git a/website/dashboards/metrics.html b/website/dashboards/metrics.html deleted file mode 100644 index e1561832..00000000 --- a/website/dashboards/metrics.html +++ /dev/null @@ -1,312 +0,0 @@ - - - - - - AITBC Metrics Dashboard - - - - - -
- -
-
- -
-

System Metrics Dashboard

-

Real-time monitoring of AITBC system performance and health

-
- Last Updated: Loading... - -
-
- - -
- -
-
-

API Metrics

-
-
-
- Total Requests - - -
-
- Errors - - -
-
- Error Rate - - -
-
- Avg Response Time - - -
-
-
- - -
-
-

Database Metrics

-
-
-
- Queries - - -
-
- Errors - - -
-
- Active Connections - - -
-
-
- - -
-
-

Cache Metrics

-
-
-
- Cache Hits - - -
-
- Cache Misses - - -
-
- Hit Rate - - -
-
-
- - -
-
-

System Metrics

-
-
-
- Memory Usage - - -
-
- CPU Usage - - -
-
- Uptime - - -
-
-
-
- - -
-

System Status

-
-
- API Service - Checking... -
-
- Database - Checking... -
-
- Cache - Checking... -
-
- Blockchain - Checking... -
-
-
- -
-

Active Alerts

-
-
- Alert State - Loading... -
-
-
-
-
- - - - diff --git a/website/dashboards/miner-dashboard.html b/website/dashboards/miner-dashboard.html deleted file mode 100644 index 4d52b730..00000000 --- a/website/dashboards/miner-dashboard.html +++ /dev/null @@ -1,210 +0,0 @@ - - - - - - AITBC GPU Miner Dashboard - - - - - - -
-
-
-
- -
-

AITBC GPU Miner Dashboard

-

✓ Running on HOST with direct GPU access

-
-
-
- - - GPU Online - - -
-
-
-
- - -
- -
-
-
-

NVIDIA GeForce RTX 4060 Ti

-

Real-time GPU Performance Monitor

-
-
-
0%
-
GPU Utilization
-
-
- -
-
-
-
-

Temperature

-

43°C

-
- -
-
-
-
-
-

Power Usage

-

18W

-
- -
-
-
-
-
-

Memory Used

-

2.9GB

-
- -
-
-
-
-
-

Performance

-

P8

-
- -
-
-
-
- - -
- -
-

- - Mining Operations - 0 active jobs -

-
- -

Miner Idle

-

Ready to accept mining jobs

-
-
- - -
-

- - GPU Services Status -

-
-
-
- -
-

CUDA Computing

-

4352 CUDA cores available

-
-
- Active -
-
-
- -
-

Parallel Processing

-

Multi-threaded operations

-
-
- Active -
-
-
- -
-

Hash Generation

-

Proof-of-work computation

-
-
- Standby -
-
-
- -
-

AI Model Training

-

Machine learning operations

-
-
- Available -
-
-
-
- - -
-

System Information

-
-
- -

Host System

-

at1/localhost

-
-
- -

GPU Access

-

Direct

-
-
- -

Container

-

Not Used

-
-
-
-
- - - - diff --git a/website/docs/README.md b/website/docs/README.md deleted file mode 100644 index edb3fdc8..00000000 --- a/website/docs/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# AITBC Website Documentation - -**Level**: Beginner -**Prerequisites**: Basic familiarity with the AITBC documentation site and web UI concepts -**Estimated Time**: 15-25 minutes -**Last Updated**: 2026-04-27 -**Version**: 1.0 - -## 🧭 **Navigation Path:** -**🏠 [Documentation Home](../README.md)** → **🌐 Website Docs** → *You are here* - -**breadcrumb**: Home → Website Docs → Overview - ---- - -## 🎯 **See Also:** -- **📚 Main Documentation**: [Docs Home](../README.md) - Primary docs landing page -- **📦 Apps Documentation**: [Apps Overview](../apps/README.md) - Application-specific documentation -- **🔧 CLI Documentation**: [CLI Technical](../cli-technical/README.md) - CLI usage and technical notes -- **🧪 Testing Documentation**: [Testing Docs](../testing/README.md) - Validation and test guidance - ---- - -## 📚 **What’s in this directory?** - -This directory contains the rendered documentation website assets and entry points: - -- `index.html` - Primary website landing page. -- `full-documentation.html` - Complete doc site rendering. -- `clients.html`, `developers.html`, `miners.html`, and related role-based pages. -- Supporting static assets under `css/` and `js/`. - -### **Use these assets when you need to:** -- Review the public documentation site structure. -- Validate role-specific content rendered by the site. -- Inspect static HTML output for documentation generation. -- Reference the user-facing navigation experience. - ---- - -## 🔗 **Where to go next** - -- [Documentation Website Index](index.html) -- [Full Documentation Render](full-documentation.html) -- [Docs Home](../README.md) -- [Master Index](../MASTER_INDEX.md) - ---- - -## 📊 **Quality Metrics** -- **Structure**: 10/10 - Short landing page for the website assets. -- **Content**: 10/10 - Documents the HTML entry points and static assets. -- **Navigation**: 10/10 - Clear links back to the docs home and rendered site. -- **Status**: Active index page. - ---- - -*Last updated: 2026-04-27* -*Version: 1.0* -*Status: Active index for website documentation* diff --git a/website/docs/api.html b/website/docs/api.html deleted file mode 100644 index ce339ca9..00000000 --- a/website/docs/api.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - - API Documentation - AITBC - - - - -
- -
-
- - - - Back to Documentation - - - -
-

API Documentation

-

Complete API reference for the AITBC platform. All APIs are RESTful and use JSON for request/response format.

-
- - -
- -
-

Client API

-

Endpoints for job submission, status checking, and receipt retrieval.

- -
- POST/v1/jobs -
-

Submit a new AI compute job

- -
- GET/v1/jobs/{job_id} -
-

Get job status and results

- -
- GET/v1/jobs/{job_id}/receipt -
-

Get computation receipt

-
- - -
-

Miner API

-

Endpoints for miner registration, job assignment, and result submission.

- -
- POST/v1/miners/register -
-

Register as a miner

- -
- POST/v1/miners/{address}/heartbeat -
-

Send miner heartbeat

- -
- POST/v1/jobs/{job_id}/complete -
-

Submit job results

-
- - -
-

Admin API

-

Administrative endpoints for system management and monitoring.

- -
- GET/v1/admin/miners -
-

List all registered miners

- -
- GET/v1/admin/jobs -
-

List all jobs in system

- -
- GET/v1/admin/stats -
-

Get system statistics

-
- - -
-

Marketplace API

-

Endpoints for the compute marketplace and trading functionality.

- -
- GET/v1/marketplace/offers -
-

List available compute offers

- -
- POST/v1/marketplace/offers -
-

Create a new compute offer

- -
- POST/v1/marketplace/trades -
-

Execute a trade

-
- - -
-

Exchange API

-

Endpoints for token exchange and trading operations.

- -
- GET/v1/exchange/ticker -
-

Get current ticker prices

- -
- GET/v1/exchange/orderbook -
-

Get order book

- -
- POST/v1/exchange/orders -
-

Place a new order

-
- - -
-

Explorer API

-

Endpoints for blockchain exploration and data retrieval.

- -
- GET/v1/explorer/blocks -
-

List recent blocks

- -
- GET/v1/explorer/transactions -
-

List recent transactions

- -
- GET/v1/explorer/address/{address} -
-

Get address details

-
-
- - -
-

Authentication

-

All API requests must include an API key in the header:

-
X-Api-Key: your_api_key_here
- -

Getting API Keys

-
    -
  • Clients: Register through the web interface or contact support
  • -
  • Miners: Generated upon registration
  • -
  • Admin: Pre-configured secure keys
  • -
-
- - -
-

Base URL

-

All API endpoints are relative to the base URL:

-
https://aitbc.bubuit.net/api
- -

For development:

-
http://localhost:18000
-
- - -
-

WebSocket API

-

Real-time updates are available through WebSocket connections:

-
ws://aitbc.bubuit.net:18001/ws
- -

Subscribe to events:

-
{
-  "method": "subscribe",
-  "params": ["job_updates", "miner_heartbeats"]
-}
-
-
-
- - - - - - diff --git a/website/docs/blockchain-node.html b/website/docs/blockchain-node.html deleted file mode 100644 index f26a0d29..00000000 --- a/website/docs/blockchain-node.html +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - Blockchain Node - AITBC Documentation - - - - -
- - -
-
- - - - - - - Back to Components - - - -
-

Blockchain Node

-

PoA/PoS consensus blockchain with REST/WebSocket RPC, real-time gossip layer, and comprehensive observability

- ● Live -
- - -
-
- - System Flow: See the complete system flow diagram to understand how the blockchain node interacts with other AITBC components. -
- -

Overview

-

The AITBC Blockchain Node is the core infrastructure component that maintains the distributed ledger. It implements a hybrid Proof-of-Authority/Proof-of-Stake consensus mechanism with fast finality and supports high throughput for AI workload transactions.

- -

Key Features

-
    -
  • Hybrid PoA/PoS consensus with sub-second finality
  • -
  • REST and WebSocket RPC APIs
  • -
  • Real-time gossip protocol for block propagation
  • -
  • Comprehensive observability with Prometheus metrics
  • -
  • SQLModel-based data persistence
  • -
  • Built-in devnet tooling and scripts
  • -
-
- - -
-

Architecture

-

The blockchain node is built with a modular architecture separating concerns for consensus, storage, networking, and API layers.

- -
-
-

Consensus Engine

-

Hybrid PoA/PoS with proposer rotation and validator sets

-
-
-

Storage Layer

-

SQLModel with SQLite/PostgreSQL support

-
-
-

Networking

-

WebSocket gossip + REST API

-
-
-

Observability

-

Prometheus metrics + structured logging

-
-
-
- - -
-

API Reference

-

The blockchain node exposes both REST and WebSocket APIs for interaction.

- -

REST Endpoints

-
- GET /rpc/get_head -

Get the latest block header

-
- -
- POST /rpc/send_tx -

Submit a new transaction

-
- -
- GET /rpc/get_balance/{address} -

Get account balance

-
- -
- GET /rpc/get_block/{height} -

Get block by height

-
- -

WebSocket Subscriptions

-
    -
  • new_blocks - Real-time block notifications
  • -
  • new_transactions - Transaction pool updates
  • -
  • consensus_events - Consensus round updates
  • -
-
- - -
-

Configuration

-

The node can be configured via environment variables or configuration file.

- -

Key Settings

-
# Database
-DATABASE_URL=sqlite:///blockchain.db
-
-# Network
-RPC_HOST=0.0.0.0
-RPC_PORT=9080
-WS_PORT=9081
-
-# Consensus
-CONSENSUS_MODE=poa
-VALIDATOR_ADDRESS=0x...
-BLOCK_TIME=1s
-
-# Observability
-METRICS_PORT=9090
-LOG_LEVEL=info
-
- - -
-

Deployment

-

The blockchain node runs on the host machine with GPU access requirements.

- -

System Requirements

-
    -
  • CPU: 4+ cores recommended
  • -
  • RAM: 8GB minimum
  • -
  • Storage: 100GB+ SSD
  • -
  • Network: 1Gbps+ for gossip
  • -
- -

Installation

-
# Clone repository
-git clone https://github.com/oib/AITBC.git
-cd aitbc/apps/blockchain-node
-
-# Install dependencies
-pip install -r requirements.txt
-
-# Run node
-python -m aitbc_chain.node
-
- - -
-

Monitoring & Observability

-

The node provides comprehensive monitoring capabilities out of the box.

- -

Metrics Available

-
    -
  • Block production rate and intervals
  • -
  • Transaction pool size and latency
  • -
  • Network gossip metrics
  • -
  • Consensus health indicators
  • -
  • Resource utilization
  • -
- -

Grafana Dashboard

-

A pre-built Grafana dashboard is available at /observability/grafana/

-
-
-
- - - - - - diff --git a/website/docs/browser-wallet.html b/website/docs/browser-wallet.html deleted file mode 100644 index 9a8fcf39..00000000 --- a/website/docs/browser-wallet.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - Redirecting to AITBC Wallet... - - - - -
-

Redirecting to AITBC Browser Wallet

- - - diff --git a/website/docs/clients.html b/website/docs/clients.html deleted file mode 100644 index 45efb68f..00000000 --- a/website/docs/clients.html +++ /dev/null @@ -1,443 +0,0 @@ - - - - - - Client Documentation - AITBC - - - - -
- - -
-
-
- For Clients -

Use AITBC for AI/ML Workloads

-

Access secure, private, and verifiable AI/ML computation on the decentralized network

- -
-

✅ Now Available: Full CLI with 90+ Commands

-

Submit jobs, track lifecycle, manage wallet, and verify receipts. Supporting 13+ Ollama models with real-time blockchain verification!

-
-
- - -
-
-
- -
-

Privacy First

-

Your data and models remain confidential with zero-knowledge proofs and secure enclaves

-
-
-
- -
-

Verifiable Results

-

Every computation is cryptographically verified on the blockchain for trust and transparency

-
-
-
- -
-

Fast & Efficient

-

Access thousands of GPUs worldwide with sub-second response times

-
-
- - -
-
- - System Flow: See the complete system flow diagram to understand how client requests flow through the AITBC system. -
- -

Getting Started

-

Start using AITBC in minutes with our simple client SDK or web interface.

- -

Quick Start Options

-
    -
  • CLI Wrapper Tool: ✅ NEW - Unified bash script for job management
  • -
  • Web Interface: No installation required
  • -
  • Python SDK: For AI/ML developers
  • -
  • JavaScript SDK: For web applications
  • -
  • REST API: For any platform
  • -
- -

CLI Wrapper Tool (Recommended)

-
-
1
-
-

Submit an Inference Job

-

Use the bash CLI wrapper for easy job submission

-
-# Submit job with CLI wrapper -./scripts/aitbc-cli.sh submit inference \ - --prompt "What is machine learning?" \ - --model llama3.2:latest - -# Check job status -./scripts/aitbc-cli.sh status - -# View receipt with payment details -./scripts/aitbc-cli.sh receipts --job-id
-
-
- -
- Available Models: llama3.2, mistral, deepseek-r1:14b, gemma3, qwen2.5-coder, and 8+ more via Ollama integration. Processing time: 11-25 seconds. Rate: 0.02 AITBC per GPU second. -
- -

Web Interface (Fastest)

-
-
1
-
-

Visit the Marketplace

-

Go to aitbc.bubuit.net/marketplace

-
-
- -
-
2
-
-

Connect Your Wallet

-

Connect MetaMask or create a new AITBC wallet

-
-
- -
-
3
-
-

Submit Your Job

-

Upload your data or model, select parameters, and submit

-
-
- -
-
4
-
-

Get Results

-

Receive verified results with cryptographic proof

-
-
-
- - -
-

Popular Use Cases

- -
-
-

AI Inference ✅ LIVE

-

Run inference on pre-trained models including LLama, Mistral, DeepSeek, and custom models via Ollama

-
    -
  • Text generation (13+ models)
  • -
  • Code generation (DeepSeek, Qwen)
  • -
  • Translation (Qwen2.5-translator)
  • -
  • Real-time processing (11-25s)
  • -
-
- -
-

Model Training

-

Train and fine-tune models on your data with privacy guarantees

-
    -
  • Fine-tuning LLMs
  • -
  • Custom model training
  • -
  • Federated learning
  • -
  • Transfer learning
  • -
-
- -
-

Data Analysis

-

Process large datasets with confidential computing

-
    -
  • Statistical analysis
  • -
  • Pattern recognition
  • -
  • Predictive modeling
  • -
  • Data visualization
  • -
-
- -
-

Secure Computation

-

Run sensitive computations with end-to-end encryption

-
    -
  • Financial modeling
  • -
  • Healthcare analytics
  • -
  • Legal document processing
  • -
  • Proprietary algorithms
  • -
-
-
-
- - -
-

SDK Examples

- -

Python SDK

-
-# Install the SDK -pip install aitbc - -# Initialize client -from aitbc import AITBCClient - -client = AITBCClient(api_key="your-api-key") - -# Run inference -result = client.inference( - model="gpt-4", - prompt="Explain quantum computing", - max_tokens=500, - temperature=0.7 -) - -print(result.text) - -# Verify the receipt -is_valid = client.verify_receipt(result.receipt_id) -print(f"Verified: {is_valid}")
- -

JavaScript SDK

-
-// Install the SDK -npm install @aitbc/client - -// Initialize client -import { AITBCClient } from '@aitbc/client'; - -const client = new AITBCClient({ - apiKey: 'your-api-key', - network: 'mainnet' -}); - -// Run inference -const result = await client.inference({ - model: 'stable-diffusion', - prompt: 'A futuristic city', - steps: 50, - cfg_scale: 7.5 -}); - -// Download the image -await client.downloadImage(result.imageId, './output.png'); - -// Verify computation -const verified = await client.verify(result.receiptId); -console.log('Computation verified:', verified);
- -

REST API

-
-# Submit a job -curl -X POST https://aitbc.bubuit.net/api/v1/jobs \ - -H "Authorization: Bearer YOUR_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{ - "type": "inference", - "model": "gpt-4", - "input": { - "prompt": "Hello, AITBC!", - "max_tokens": 100 - }, - "privacy": { - "confidential": true, - "zk_proof": true - } - }' - -# Check job status -curl -X GET https://aitbc.bubuit.net/api/v1/jobs/JOB_ID \ - -H "Authorization: Bearer YOUR_TOKEN"
-
- - -
-

Pricing

-

Flexible pricing options for every use case

- -
-
-

Pay-per-use

-
$0.01/1K tokens
-
    -
  • No minimum commitment
  • -
  • Pay only for what you use
  • -
  • All models available
  • -
  • Basic support
  • -
- -
- - - -
-

Enterprise

-
Custom
-
    -
  • Unlimited usage
  • -
  • Dedicated resources
  • -
  • Custom models
  • -
  • 24/7 support
  • -
  • SLA guarantee
  • -
- -
-
-
- - -
-

Privacy & Security

- -
- Your data is never stored or exposed - All computations are performed in secure enclaves with zero-knowledge proof verification. -
- -

Privacy Features

-
    -
  • End-to-end encryption - Your data is encrypted before leaving your device
  • -
  • Zero-knowledge proofs - Prove computation without revealing inputs
  • -
  • Secure enclaves - Computations run in isolated, verified environments
  • -
  • No data retention - Providers cannot access or store your data
  • -
  • Audit trails - Full transparency on blockchain
  • -
- -

Compliance

-
    -
  • GDPR compliant
  • -
  • SOC 2 Type II certified
  • -
  • HIPAA eligible
  • -
  • ISO 27001 certified
  • -
-
- - -
-

Best Practices

- -

Optimizing Performance

-
    -
  • Use appropriate model sizes for your task
  • -
  • Batch requests when possible
  • -
  • Enable caching for repeated queries
  • -
  • Choose the right privacy level for your needs
  • -
  • Monitor your usage and costs
  • -
- -

Security Tips

-
    -
  • Keep your API keys secure
  • -
  • Use environment variables for credentials
  • -
  • Enable two-factor authentication
  • -
  • Regularly rotate your keys
  • -
  • Use VPN for additional privacy
  • -
- -

Cost Optimization

-
    -
  • Start with smaller models for testing
  • -
  • Use streaming for long responses
  • -
  • Set appropriate limits and timeouts
  • -
  • Monitor token usage
  • -
  • Consider subscription plans for regular use
  • -
-
- - -
-

Support & Resources

- -

Getting Help

- - -

Tutorials

- - -

Examples

- -
- - -
-

Frequently Asked Questions

- -
- Question not answered? Contact us at andreas.fleckl@bubuit.net -
- -

General

-
    -
  • How do I get started? - Sign up for an account, connect your wallet, and submit your first job through the web interface or API.
  • -
  • What models are available? - We support GPT-3.5/4, Claude, Llama, Stable Diffusion, and many custom models.
  • -
  • Can I use my own model? - Yes, you can upload and run private models with full confidentiality.
  • -
- -

Privacy

-
    -
  • Is my data private? - Absolutely. Your data is encrypted and never exposed to providers.
  • -
  • How do ZK proofs work? - They prove computation was done correctly without revealing inputs.
  • -
  • Can you see my prompts? - No, prompts are encrypted and processed in secure enclaves.
  • -
- -

Technical

-
    -
  • What's the response time? - Most jobs complete in 1-5 seconds depending on complexity.
  • -
  • Do you support streaming? - Yes, streaming is available for real-time applications.
  • -
  • Can I run batch jobs? - Yes, batch processing is supported for large workloads.
  • -
- -

Billing

-
    -
  • How am I billed? - Pay-per-use or monthly subscription options available.
  • -
  • Can I set spending limits? - Yes, you can set daily/monthly limits in your dashboard.
  • -
  • Do you offer refunds? - Yes, we offer refunds for service issues within 30 days.
  • -
-
-
-
- - - - - - diff --git a/website/docs/components.html b/website/docs/components.html deleted file mode 100644 index 20f1404e..00000000 --- a/website/docs/components.html +++ /dev/null @@ -1,199 +0,0 @@ - - - - - - Platform Components - AITBC Documentation - - - - -
- - -
-
- - - - - - - Back to Documentation - - - -
-

Architecture & Components

-

Explore the core components and system architecture of the AITBC platform

-
- - -
-
- - System Flow: See the complete system flow diagram to understand how all components interact in the AITBC architecture. -
- - - -
-
- -
-

Blockchain Node

-

PoA/PoS consensus with REST/WebSocket RPC, real-time gossip layer, and comprehensive observability. Production-ready with devnet tooling.

-
- Live -
- - Learn More - -
- - -
-
- -
-

Coordinator API

-

FastAPI service for job submission, miner registration, and receipt management. SQLite persistence with comprehensive endpoints.

-
- Live -
- - Learn More - -
- - -
-
- -
-

Marketplace Web

-

Vite/TypeScript marketplace with offer/bid functionality, stats dashboard, and mock/live data toggle. Production UI ready.

-
- Live -
- - Learn More - -
- - -
-
- -
-

Explorer Web

-

Full-featured blockchain explorer with blocks, transactions, addresses, and receipts tracking. Responsive design with live data.

-
- Live -
- - Learn More - -
- - -
-
- -
-

Wallet Daemon

-

Encrypted keystore with Argon2id + XChaCha20-Poly1305, REST/JSON-RPC APIs, and receipt verification capabilities.

-
- Live -
- - Learn More - -
- - -
-
- -
-

Trade Exchange

-

Bitcoin-to-AITBC exchange with QR payments, user management, and real-time trading. Buy tokens with BTC instantly.

-
- Live -
- - Learn More - -
- - -
-
- -
-

Pool Hub

-

Miner registry with scoring engine, Redis/PostgreSQL backing, and comprehensive metrics. Live matching API deployed.

-
- Live -
- - Learn More - -
-
- - -
-

Architecture Overview

-

The AITBC platform consists of 7 core components working together to provide a complete AI blockchain computing solution:

- -
-

Infrastructure Layer

-
    -
  • Blockchain Node - Distributed ledger with PoA/PoS consensus
  • -
  • Coordinator API - Job orchestration and management
  • -
  • Wallet Daemon - Secure wallet management
  • -
- -

Application Layer

-
    -
  • Marketplace Web - GPU compute marketplace
  • -
  • Trade Exchange - Token trading platform
  • -
  • Explorer Web - Blockchain explorer
  • -
  • Pool Hub - Miner coordination service
  • -
-
-
- - -
-

Quick Links

- -
-
-
- - - - - - diff --git a/website/docs/coordinator-api.html b/website/docs/coordinator-api.html deleted file mode 100644 index dc3bb6b3..00000000 --- a/website/docs/coordinator-api.html +++ /dev/null @@ -1,245 +0,0 @@ - - - - - - Coordinator API - AITBC Documentation - - - - -
- - -
-
- - - - - - - Back to Components - - - -
-

Coordinator API

-

FastAPI service for job submission, miner registration, and receipt management with SQLite persistence

- ● Live -
- - -
-
- - System Flow: See the complete system flow diagram to understand how the coordinator API fits into the overall AITBC architecture. -
- -

Overview

-

The Coordinator API is the central orchestration layer that manages job distribution between clients and miners in the AITBC network. It handles job submissions, miner registrations, and tracks all computation receipts.

- -

Key Features

-
    -
  • Job submission and tracking
  • -
  • Miner registration and heartbeat monitoring
  • -
  • Receipt management and verification
  • -
  • User management with wallet-based authentication
  • -
  • SQLite persistence with SQLModel ORM
  • -
  • Comprehensive API documentation with OpenAPI
  • -
-
- - -
-

Architecture

-

The Coordinator API follows a clean architecture with separation of concerns for domain models, API routes, and business logic.

- -
-
-

API Layer

-

FastAPI routers for clients, miners, admin, and users

-
-
-

Domain Models

-

SQLModel definitions for jobs, miners, receipts, users

-
-
-

Business Logic

-

Service layer handling job orchestration

-
-
-

Persistence

-

SQLite database with Alembic migrations

-
-
-
- - -
-

API Reference

-

The Coordinator API provides RESTful endpoints for all major operations.

- -

Client Endpoints

-
- POST /v1/client/jobs -

Submit a new computation job

-
- -
- GET /v1/client/jobs/{job_id}/status -

Get job status and progress

-
- -
- GET /v1/client/jobs/{job_id}/receipts -

Retrieve computation receipts

-
- -

Miner Endpoints

-
- POST /v1/miner/register -

Register as a compute provider

-
- -
- POST /v1/miner/heartbeat -

Send miner heartbeat

-
- -
- GET /v1/miner/jobs -

Fetch available jobs

-
- -
- POST /v1/miner/result -

Submit job result

-
- -

User Management

-
- POST /v1/users/login -

Login or register with wallet

-
- -
- GET /v1/users/me -

Get current user profile

-
- -
- GET /v1/users/{user_id}/balance -

Get user wallet balance

-
- -

Exchange Endpoints

-
- POST /v1/exchange/create-payment -

Create Bitcoin payment request

-
- -
- GET /v1/exchange/payment-status/{id} -

Check payment status

-
-
- - -
-

Authentication

-

The API uses API key authentication for clients and miners, and session-based authentication for users.

- -

API Keys

-
X-Api-Key: your-api-key-here
- -

Session Tokens

-
X-Session-Token: sha256-token-here
- -

Example Request

-
curl -X POST "https://aitbc.bubuit.net/api/v1/client/jobs" \
-  -H "X-Api-Key: your-key" \
-  -H "Content-Type: application/json" \
-  -d '{
-    "job_type": "llm_inference",
-    "parameters": {...}
-  }'
-
- - -
-

Configuration

-

The Coordinator API can be configured via environment variables.

- -

Environment Variables

-
# Database
-DATABASE_URL=sqlite:///coordinator.db
-
-# API Settings
-API_HOST=0.0.0.0
-API_PORT=8000
-
-# Security
-SECRET_KEY=your-secret-key
-API_KEYS=key1,key2,key3
-
-# Exchange
-BITCOIN_ADDRESS=tb1qxy2...
-BTC_TO_AITBC_RATE=100000
-
- - -
-

Deployment

-

The Coordinator API runs in a Docker container with nginx proxy.

- -

Docker Deployment

-
# Build image
-docker build -t aitbc-coordinator .
-
-# Run container
-docker run -d \
-  --name aitbc-coordinator \
-  -p 8000:8000 \
-  -e DATABASE_URL=sqlite:///data/coordinator.db \
-  -v $(pwd)/data:/app/data \
-  aitbc-coordinator
- -

Systemd Service

-
# Start service
-sudo systemctl start aitbc-coordinator
-
-# Check status
-sudo systemctl status aitbc-coordinator
-
-# View logs
-sudo journalctl -u aitbc-coordinator -f
-
- - -
-

Interactive API Documentation

-

Interactive API documentation is available via Swagger UI and ReDoc.

- - -
-
-
- - - - - - diff --git a/website/docs/css/docs.css b/website/docs/css/docs.css deleted file mode 100644 index a4b1691c..00000000 --- a/website/docs/css/docs.css +++ /dev/null @@ -1,1870 +0,0 @@ -/* AITBC Documentation Styles - * Shared CSS for all documentation pages - */ - -/* Reset */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -/* ============================================ - Theme Variables - ============================================ */ - -/* Dark mode (default) */ -:root { - --primary-color: #2563eb; - --secondary-color: #7c3aed; - --accent-color: #0ea5e9; - --success-color: #10b981; - --warning-color: #f59e0b; - --danger-color: #ef4444; - --text-dark: #f3f4f6; - --text-light: #9ca3af; - --bg-light: #111827; - --bg-white: #1f2937; - --border-color: #374151; - --code-bg: #0d1117; - --code-text: #e6edf3; -} - -/* Light mode */ -body.light { - --primary-color: #2563eb; - --secondary-color: #7c3aed; - --accent-color: #0ea5e9; - --success-color: #10b981; - --warning-color: #f59e0b; - --danger-color: #ef4444; - --text-dark: #1f2937; - --text-light: #6b7280; - --bg-light: #f9fafb; - --bg-white: #ffffff; - --border-color: #e5e7eb; - --code-bg: #1f2937; - --code-text: #e5e7eb; -} - -/* ============================================ - Base Styles - ============================================ */ - -body { - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; - line-height: 1.6; - color: var(--text-dark); - background: var(--bg-light); - transition: background 0.3s ease, color 0.3s ease; -} - -.container { - max-width: 1200px; - margin: 0 auto; - padding: 0 20px; -} - -a { - color: var(--primary-color); - text-decoration: none; - transition: color 0.3s ease; -} - -a:hover { - color: var(--accent-color); -} - -/* ============================================ - Header & Navigation - ============================================ */ - -header { - background: var(--bg-white); - box-shadow: 0 4px 20px rgba(0,0,0,0.15); - position: fixed; - width: 100%; - top: 0; - z-index: 1000; - border-bottom: 3px solid transparent; - background-image: linear-gradient(var(--bg-white), var(--bg-white)), - linear-gradient(90deg, var(--primary-color), var(--accent-color), var(--success-color)); - background-origin: border-box; - background-clip: padding-box, border-box; -} - -nav { - display: flex; - justify-content: space-between; - align-items: center; - padding: 1rem 0; -} - -.logo { - font-size: 1.5rem; - font-weight: bold; - background: linear-gradient(135deg, var(--primary-color), var(--accent-color)); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; - text-decoration: none; - transition: transform 0.3s ease; -} - -.logo:hover { - transform: scale(1.05); -} - -.nav-links { - display: flex; - gap: 2rem; - list-style: none; - align-items: center; -} - -.nav-links a { - color: var(--text-dark); - text-decoration: none; - transition: all 0.3s ease; - padding: 0.5rem 0; - position: relative; -} - -.nav-links a::after { - content: ''; - position: absolute; - bottom: 0; - left: 0; - width: 0; - height: 2px; - background: linear-gradient(90deg, var(--primary-color), var(--accent-color)); - transition: width 0.3s ease; -} - -.nav-links a:hover::after, -.nav-links a.active::after { - width: 100%; -} - -.nav-links a:hover { - color: var(--primary-color); -} - -/* Site Header (unified) */ -.site-header { - background: var(--bg-white); - position: fixed; - width: 100%; - top: 0; - z-index: 1000; - box-shadow: 0 1px 3px rgba(0,0,0,0.1); -} - -.site-header .header-inner { - display: flex; - align-items: center; - justify-content: space-between; - padding: 1rem 0; -} - -.site-header .brand { - display: flex; - align-items: center; - gap: 0.75rem; - text-decoration: none; -} - -.site-header .brand i { - font-size: 2rem; - color: var(--primary-color); -} - -.site-header .brand span { - font-size: 1.5rem; - font-weight: bold; - color: var(--text-dark); -} - -.site-header .header-nav { - display: flex; - align-items: center; - gap: 1.5rem; - list-style: none; -} - -.site-header .header-nav a { - color: var(--text-dark); - padding: 0.5rem 0.75rem; - border-radius: 0.5rem; - font-weight: 500; - text-decoration: none; - transition: color 0.3s; -} - -.site-header .header-nav a:hover, -.site-header .header-nav a.active { - color: var(--primary-color); -} - -@media (max-width: 768px) { - .site-header .header-nav { - gap: 0.5rem; - } - .site-header .header-nav a { - padding: 0.4rem 0.5rem; - font-size: 0.85rem; - } -} - -/* Theme Toggle Button */ -.theme-toggle { - background: none; - border: 2px solid var(--border-color); - border-radius: 0.5rem; - padding: 0.5rem 0.75rem; - cursor: pointer; - font-size: 1.1rem; - color: var(--text-dark); - transition: all 0.3s ease; -} - -.theme-toggle:hover { - background: var(--bg-white); - border-color: var(--primary-color); - transform: scale(1.05); -} - -/* ============================================ - Main Content - ============================================ */ - -main { - margin-top: 80px; - padding: 40px 0; -} - -.doc-header { - text-align: center; - margin-bottom: 3rem; -} - -.doc-header h1 { - font-size: 3rem; - color: var(--text-dark); - margin-bottom: 1rem; -} - -.doc-header p { - font-size: 1.2rem; - color: var(--text-light); - max-width: 600px; - margin: 0 auto; -} - -/* ============================================ - Content Sections - ============================================ */ - -.content-section { - background: var(--bg-white); - border-radius: 10px; - padding: 2rem; - margin-bottom: 2rem; - box-shadow: 0 2px 10px rgba(0,0,0,0.05); -} - -.content-section h2 { - font-size: 1.8rem; - margin-bottom: 1.5rem; - color: var(--text-dark); - border-bottom: 2px solid var(--primary-color); - padding-bottom: 0.5rem; -} - -.content-section h3 { - font-size: 1.4rem; - margin: 1.5rem 0 1rem; - color: var(--text-dark); -} - -.content-section h4 { - font-size: 1.1rem; - margin: 1rem 0 0.5rem; - color: var(--primary-color); -} - -.content-section p { - margin-bottom: 1rem; - color: var(--text-light); -} - -.content-section ul, -.content-section ol { - margin-bottom: 1rem; - padding-left: 2rem; -} - -.content-section li { - margin-bottom: 0.5rem; - color: var(--text-light); -} - -/* ============================================ - Code Blocks - ============================================ */ - -.code-block { - background: linear-gradient(135deg, #0d1117 0%, #161b22 100%); - color: #e6edf3; - padding: 1.5rem; - border-radius: 10px; - overflow-x: auto; - margin: 1rem 0; - font-family: 'Fira Code', 'JetBrains Mono', 'Courier New', monospace; - font-size: 0.9rem; - line-height: 1.6; - border: 1px solid #30363d; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); - white-space: pre-wrap; - word-wrap: break-word; -} - -code { - background: var(--bg-light); - padding: 0.2rem 0.4rem; - border-radius: 4px; - font-family: 'Fira Code', 'JetBrains Mono', 'Courier New', monospace; - font-size: 0.9em; - color: var(--accent-color); -} - -/* ============================================ - Steps - ============================================ */ - -.step { - display: flex; - flex-direction: row; - align-items: flex-start; - gap: 1rem; - margin-bottom: 1.5rem; - padding: 1rem 0; - border-bottom: 1px solid var(--border-color); -} - -.step:last-of-type { - border-bottom: none; -} - -.step-number { - background: linear-gradient(135deg, var(--primary-color), var(--accent-color)); - color: #fff; - width: 36px; - height: 36px; - min-width: 36px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - font-weight: bold; - font-size: 1rem; - box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3); -} - -.step-content { - flex-grow: 1; -} - -.step-content h4 { - color: var(--text-dark); - margin-bottom: 0.25rem; - font-size: 1.1rem; -} - -.step-content p { - color: var(--text-light); - margin-bottom: 0.5rem; - font-size: 0.95rem; -} - -/* ============================================ - Alert Boxes - ============================================ */ - -.alert { - padding: 1rem 1.25rem; - border-radius: 8px; - margin: 1.5rem 0; -} - -.alert-info { - background: rgba(59, 130, 246, 0.15); - border-left: 4px solid #3b82f6; - color: var(--text-dark); -} - -.alert-warning { - background: rgba(245, 158, 11, 0.15); - border-left: 4px solid #f59e0b; - color: var(--text-dark); -} - -.alert-success { - background: rgba(16, 185, 129, 0.15); - border-left: 4px solid #10b981; - color: var(--text-dark); -} - -.alert-danger { - background: rgba(239, 68, 68, 0.15); - border-left: 4px solid #ef4444; - color: var(--text-dark); -} - -/* ============================================ - Buttons - ============================================ */ - -.btn { - display: inline-block; - padding: 12px 30px; - background: var(--primary-color); - color: #fff; - text-decoration: none; - border-radius: 50px; - font-weight: 600; - transition: all 0.3s ease; - border: none; - cursor: pointer; -} - -.btn:hover { - transform: translateY(-2px); - box-shadow: 0 5px 15px rgba(0,0,0,0.2); - color: #fff; -} - -.btn-outline { - background: transparent; - color: var(--primary-color); - border: 2px solid var(--primary-color); -} - -.btn-outline:hover { - background: var(--primary-color); - color: #fff; -} - -.btn-success { - background: var(--success-color); -} - -.btn-warning { - background: var(--warning-color); -} - -.btn-danger { - background: var(--danger-color); -} - -/* ============================================ - Cards & Grids - ============================================ */ - -.card { - background: var(--bg-white); - border-radius: 10px; - padding: 1.5rem; - box-shadow: 0 2px 10px rgba(0,0,0,0.05); - transition: all 0.3s ease; -} - -.card:hover { - transform: translateY(-5px); - box-shadow: 0 8px 25px rgba(0,0,0,0.1); -} - -.grid { - display: grid; - gap: 1.5rem; -} - -.grid-2 { - grid-template-columns: repeat(2, 1fr); -} - -.grid-3 { - grid-template-columns: repeat(3, 1fr); -} - -.grid-4 { - grid-template-columns: repeat(4, 1fr); -} - -.grid-auto { - grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); -} - -/* ============================================ - Tables - ============================================ */ - -table { - width: 100%; - border-collapse: collapse; - margin: 1rem 0; -} - -th, td { - padding: 0.75rem; - text-align: left; - border-bottom: 1px solid var(--border-color); -} - -th { - background: var(--bg-light); - color: var(--text-dark); - font-weight: 600; -} - -tr:hover { - background: rgba(59, 130, 246, 0.05); -} - -/* ============================================ - Badges - ============================================ */ - -.badge { - display: inline-block; - padding: 0.25rem 0.75rem; - border-radius: 20px; - font-size: 0.85rem; - font-weight: 600; -} - -.badge-primary { - background: var(--primary-color); - color: #fff; -} - -.badge-success { - background: var(--success-color); - color: #fff; -} - -.badge-warning { - background: var(--warning-color); - color: #fff; -} - -.badge-danger { - background: var(--danger-color); - color: #fff; -} - -/* ============================================ - Quick Links - ============================================ */ - -.quick-links { - background: var(--bg-white); - border-radius: 15px; - padding: 3rem; - margin-bottom: 4rem; - box-shadow: 0 4px 20px rgba(0,0,0,0.08); -} - -.quick-links h2 { - font-size: 2rem; - margin-bottom: 2rem; - color: var(--text-dark); - text-align: center; -} - -.links-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); - gap: 1.5rem; -} - -.link-item { - display: flex; - align-items: center; - padding: 1rem; - background: var(--bg-light); - border-radius: 10px; - text-decoration: none; - color: var(--text-dark); - transition: all 0.3s; -} - -.link-item:hover { - background: var(--primary-color); - color: #fff; - transform: translateX(5px); -} - -.link-item i { - font-size: 1.5rem; - margin-right: 1rem; - color: var(--primary-color); -} - -.link-item:hover i { - color: #fff; -} - -/* ============================================ - Footer - ============================================ */ - -footer { - background: var(--bg-white); - color: var(--text-dark); - padding: 40px 0; - text-align: center; - margin-top: 40px; - border-top: 1px solid var(--border-color); -} - -footer p { - color: var(--text-light); -} - -/* ============================================ - Responsive Design - ============================================ */ - -@media (max-width: 1024px) { - .grid-4 { - grid-template-columns: repeat(2, 1fr); - } -} - -@media (max-width: 768px) { - .doc-header h1 { - font-size: 2rem; - } - - .grid-2, - .grid-3, - .grid-4 { - grid-template-columns: 1fr; - } - - .nav-links { - gap: 1rem; - } - - .step { - flex-direction: column; - } - - .content-section { - padding: 1.5rem; - } -} - -@media (max-width: 480px) { - .container { - padding: 0 15px; - } - - .btn { - padding: 10px 20px; - font-size: 0.9rem; - } -} - -/* ============================================ - Utility Classes - ============================================ */ - -.text-center { text-align: center; } -.text-left { text-align: left; } -.text-right { text-align: right; } - -.mt-1 { margin-top: 0.5rem; } -.mt-2 { margin-top: 1rem; } -.mt-3 { margin-top: 1.5rem; } -.mt-4 { margin-top: 2rem; } - -.mb-1 { margin-bottom: 0.5rem; } -.mb-2 { margin-bottom: 1rem; } -.mb-3 { margin-bottom: 1.5rem; } -.mb-4 { margin-bottom: 2rem; } - -.p-1 { padding: 0.5rem; } -.p-2 { padding: 1rem; } -.p-3 { padding: 1.5rem; } -.p-4 { padding: 2rem; } - -.hidden { display: none; } -.flex { display: flex; } -.flex-center { - display: flex; - align-items: center; - justify-content: center; -} - -/* ============================================ - Animations - ============================================ */ - -@keyframes fadeIn { - from { opacity: 0; transform: translateY(10px); } - to { opacity: 1; transform: translateY(0); } -} - -@keyframes pulse { - 0%, 100% { opacity: 1; } - 50% { opacity: 0.5; } -} - -.animate-fadeIn { - animation: fadeIn 0.5s ease-out; -} - -.animate-pulse { - animation: pulse 2s infinite; -} - -/* ============================================ - Page-Specific: Audience Badge - ============================================ */ - -.audience-badge { - display: inline-block; - color: #fff; - padding: 0.5rem 1rem; - border-radius: 20px; - font-weight: 600; - margin-bottom: 1rem; -} - -.audience-badge.miner { - background: var(--primary-color); -} - -.audience-badge.client { - background: var(--success-color); -} - -.audience-badge.developer { - background: var(--warning-color); -} - -/* ============================================ - Page-Specific: Quick Stats (Miners) - ============================================ */ - -.quick-stats { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); - gap: 1rem; - margin: 2rem 0; -} - -.stat-card { - background: var(--bg-white); - padding: 1.5rem; - border-radius: 10px; - box-shadow: 0 2px 10px rgba(0,0,0,0.05); - text-align: center; -} - -.stat-value { - font-size: 2rem; - font-weight: bold; - color: var(--primary-color); -} - -.stat-label { - color: var(--text-light); - margin-top: 0.5rem; -} - -/* ============================================ - Page-Specific: Requirements Grid (Miners) - ============================================ */ - -.requirements-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); - gap: 1rem; - margin: 1rem 0; -} - -.requirement-card { - background: var(--bg-light); - padding: 1rem; - border-radius: 8px; - border-left: 4px solid var(--primary-color); -} - -.requirement-card h4 { - color: var(--primary-color); - margin-bottom: 0.5rem; -} - -.requirement-card p { - color: var(--text-light); - margin: 0; -} - -/* ============================================ - Page-Specific: Calculator (Miners) - ============================================ */ - -.calculator { - background: var(--bg-light); - padding: 2rem; - border-radius: 10px; - margin: 2rem 0; -} - -.calculator h3 { - margin-bottom: 1.5rem; - color: var(--text-dark); -} - -.calc-row { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 1rem; - margin-bottom: 1rem; -} - -.calc-input { - display: flex; - flex-direction: column; -} - -.calc-input label { - font-weight: 600; - margin-bottom: 0.5rem; - color: var(--text-dark); -} - -.calc-input input, -.calc-input select { - padding: 0.75rem; - border: 1px solid var(--border-color); - border-radius: 8px; - font-size: 1rem; - background: var(--bg-white); - color: var(--text-dark); -} - -.calc-input input:focus, -.calc-input select:focus { - outline: none; - border-color: var(--primary-color); -} - -.calc-result { - background: var(--bg-white); - padding: 1.5rem; - border-radius: 8px; - margin-top: 1rem; - text-align: center; -} - -.calc-result-value { - font-size: 2.5rem; - font-weight: bold; - color: var(--success-color); -} - -/* ============================================ - Page-Specific: FAQ (Miners) - ============================================ */ - -.faq-item { - background: var(--bg-light); - padding: 1.25rem; - border-radius: 8px; - margin-bottom: 1rem; -} - -.faq-question { - font-weight: 600; - color: var(--text-dark); - margin-bottom: 0.5rem; -} - -.faq-answer { - color: var(--text-light); - line-height: 1.7; -} - -/* ============================================ - Page-Specific: Feature Cards (Clients) - ============================================ */ - -.feature-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); - gap: 2rem; - margin: 2rem 0; -} - -.feature-card { - background: var(--bg-white); - padding: 2rem; - border-radius: 12px; - box-shadow: 0 2px 10px rgba(0,0,0,0.05); - text-align: center; - transition: transform 0.3s ease, box-shadow 0.3s ease; -} - -.feature-card:hover { - transform: translateY(-5px); - box-shadow: 0 8px 25px rgba(0,0,0,0.1); -} - -.feature-icon { - font-size: 3rem; - color: var(--primary-color); - margin-bottom: 1rem; -} - -.feature-card h3 { - font-size: 1.5rem; - margin-bottom: 1rem; - color: var(--text-dark); -} - -.feature-card p { - color: var(--text-light); -} - -/* ============================================ - Page-Specific: Use Case Cards (Clients) - ============================================ */ - -.use-case-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); - gap: 1.5rem; - margin: 2rem 0; -} - -.use-case-card { - background: var(--bg-light); - padding: 1.5rem; - border-radius: 10px; - border-top: 4px solid var(--primary-color); -} - -.use-case-card h4 { - color: var(--primary-color); - margin-bottom: 1rem; -} - -.use-case-card p { - color: var(--text-light); -} - -/* ============================================ - Page-Specific: Pricing Table (Clients) - ============================================ */ - -.pricing-table { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); - gap: 1.5rem; - margin: 2rem 0; -} - -.pricing-card { - background: var(--bg-white); - border-radius: 12px; - padding: 2rem; - box-shadow: 0 2px 10px rgba(0,0,0,0.05); - text-align: center; - transition: transform 0.3s ease; -} - -.pricing-card.featured { - border: 2px solid var(--primary-color); - transform: scale(1.05); -} - -.pricing-card h3 { - font-size: 1.5rem; - color: var(--text-dark); - margin-bottom: 1rem; -} - -.pricing-card .price { - font-size: 3rem; - font-weight: bold; - color: var(--primary-color); - margin-bottom: 1rem; -} - -.pricing-card .price-unit { - font-size: 1rem; - color: var(--text-light); -} - -.pricing-card ul { - list-style: none; - padding: 0; - margin-bottom: 2rem; -} - -.pricing-card li { - padding: 0.5rem 0; - color: var(--text-light); -} - -.pricing-card li:before { - content: "✓"; - color: var(--success-color); - margin-right: 0.5rem; -} - -/* ============================================ - Page-Specific: Tech Stack (Developers) - ============================================ */ - -.tech-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); - gap: 1rem; - margin: 2rem 0; -} - -.tech-item { - background: var(--bg-light); - padding: 1.25rem; - border-radius: 10px; - text-align: center; - transition: all 0.3s ease; -} - -.tech-item:hover { - transform: translateY(-5px); - background: var(--bg-white); - box-shadow: 0 4px 15px rgba(0,0,0,0.1); -} - -.tech-icon { - font-size: 2rem; - color: var(--primary-color); - margin-bottom: 0.5rem; -} - -.tech-item span { - color: var(--text-dark); - font-weight: 500; -} - -/* ============================================ - Page-Specific: Contribution Cards (Developers) - ============================================ */ - -.contribution-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); - gap: 1.5rem; - margin: 2rem 0; -} - -.contribution-card { - background: var(--bg-light); - padding: 1.5rem; - border-radius: 10px; - border-left: 4px solid var(--primary-color); -} - -.contribution-card h4 { - color: var(--primary-color); - margin-bottom: 1rem; - font-size: 1.2rem; -} - -.contribution-card ul { - list-style: none; - padding: 0; -} - -.contribution-card li { - padding: 0.3rem 0; - position: relative; - padding-left: 1.5rem; - color: var(--text-light); -} - -.contribution-card li:before { - content: "→"; - position: absolute; - left: 0; - color: var(--primary-color); -} - -/* ============================================ - Page-Specific: Reader Cards (Index) - ============================================ */ - -.reader-levels { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 2rem; - margin-bottom: 4rem; -} - -.reader-card { - background: var(--bg-white); - border-radius: 15px; - padding: 2.5rem; - box-shadow: 0 4px 20px rgba(0,0,0,0.08); - transition: all 0.3s; - position: relative; - overflow: hidden; -} - -.reader-card::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 5px; -} - -.reader-card.miner::before { background: var(--primary-color); } -.reader-card.client::before { background: var(--success-color); } -.reader-card.developer::before { background: var(--warning-color); } -.reader-card.full-doc::before { background: var(--danger-color); } -.reader-card.components::before { background: #8b5cf6; } -.reader-card.flow::before { background: #06b6d4; } - -.reader-card:hover { - transform: translateY(-10px); - box-shadow: 0 8px 30px rgba(0,0,0,0.12); -} - -.reader-icon { - width: 80px; - height: 80px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - font-size: 2rem; - color: #fff; - margin-bottom: 1.5rem; -} - -.reader-card.miner .reader-icon { background: var(--primary-color); } -.reader-card.client .reader-icon { background: var(--success-color); } -.reader-card.developer .reader-icon { background: var(--warning-color); } -.reader-card.full-doc .reader-icon { background: var(--danger-color); } -.reader-card.components .reader-icon { background: #8b5cf6; } -.reader-card.flow .reader-icon { background: #06b6d4; } - -.reader-card h3 { - font-size: 1.8rem; - margin-bottom: 1rem; - color: var(--text-dark); -} - -.reader-card p { - color: var(--text-light); - margin-bottom: 2rem; - line-height: 1.8; -} - -.reader-features { - list-style: none; - margin-bottom: 2rem; - padding: 0; -} - -.reader-features li { - padding: 0.5rem 0; - color: var(--text-light); - position: relative; - padding-left: 1.5rem; -} - -.reader-features li::before { - content: "✓"; - position: absolute; - left: 0; - font-weight: bold; -} - -.reader-card.miner .reader-features li::before { color: var(--primary-color); } -.reader-card.client .reader-features li::before { color: var(--success-color); } -.reader-card.developer .reader-features li::before { color: var(--warning-color); } - -.reader-card.miner .btn { background: var(--primary-color); } -.reader-card.client .btn { background: var(--success-color); } -.reader-card.developer .btn { background: var(--warning-color); } -.reader-card.full-doc .btn { background: var(--danger-color); } -.reader-card.components .btn { background: #8b5cf6; } -.reader-card.flow .btn { background: #06b6d4; } - -/* ============================================ - Page-Specific: Search Bar (Index) - ============================================ */ - -.search-container { - max-width: 600px; - margin: 0 auto 4rem; - position: relative; -} - -.search-bar { - width: 100%; - padding: 1rem 3rem 1rem 1.5rem; - font-size: 1.1rem; - border: 2px solid var(--border-color); - border-radius: 50px; - outline: none; - transition: all 0.3s; - background: var(--bg-white); - color: var(--text-dark); -} - -.search-bar:focus { - border-color: var(--primary-color); - box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); -} - -.search-bar::placeholder { - color: var(--text-light); -} - -.search-icon { - position: absolute; - right: 1.5rem; - top: 50%; - transform: translateY(-50%); - color: var(--text-light); - font-size: 1.2rem; -} - -/* ============================================ - Page-Specific: Help Section (Index) - ============================================ */ - -.help-section { - text-align: center; - padding: 3rem; - background: var(--bg-white); - border-radius: 15px; - box-shadow: 0 4px 20px rgba(0,0,0,0.08); -} - -.help-section h2 { - font-size: 2rem; - margin-bottom: 1rem; - color: var(--text-dark); -} - -.help-section p { - color: var(--text-light); - margin-bottom: 2rem; -} - -.help-buttons { - display: flex; - gap: 1rem; - justify-content: center; - flex-wrap: wrap; -} - -/* ============================================ - Responsive: Page-Specific - ============================================ */ - -@media (max-width: 768px) { - .reader-levels { - grid-template-columns: 1fr; - } - - .calc-row { - grid-template-columns: 1fr; - } - - .pricing-card.featured { - transform: none; - } - - .help-buttons { - flex-direction: column; - align-items: center; - } - - .doc-grid { - grid-template-columns: 1fr; - } - - .sidebar { - position: static; - max-height: none; - } - - .components-grid { - grid-template-columns: 1fr; - } - - .api-grid { - grid-template-columns: 1fr; - } -} - -/* ============================================ - Component Pages: Layout - ============================================ */ - -.breadcrumb { - margin-bottom: 2rem; -} - -.breadcrumb a { - color: var(--primary-color); - text-decoration: none; -} - -.breadcrumb span { - color: var(--text-light); - margin: 0 0.5rem; -} - -.back-button { - display: inline-flex; - align-items: center; - gap: 0.5rem; - color: var(--primary-color); - text-decoration: none; - margin-bottom: 2rem; - font-weight: 600; -} - -.back-button:hover { - color: var(--secondary-color); -} - -.doc-grid { - display: grid; - grid-template-columns: 280px 1fr; - gap: 2rem; - align-items: start; -} - -.sidebar { - background: var(--bg-white); - border-radius: 10px; - padding: 1.5rem; - position: sticky; - top: 100px; - max-height: calc(100vh - 120px); - overflow-y: auto; - box-shadow: 0 2px 10px rgba(0,0,0,0.05); -} - -.sidebar h3 { - font-size: 1.1rem; - margin-bottom: 1rem; - color: var(--text-dark); -} - -.sidebar ul { - list-style: none; - padding: 0; -} - -.sidebar li { - margin-bottom: 0.25rem; -} - -.sidebar a { - display: block; - padding: 0.4rem 0.75rem; - color: var(--text-light); - text-decoration: none; - border-radius: 6px; - font-size: 0.9rem; - transition: all 0.2s; -} - -.sidebar a:hover, -.sidebar a.active { - background: rgba(59, 130, 246, 0.1); - color: var(--primary-color); -} - -.sidebar .sub-item { - padding-left: 1.5rem; - font-size: 0.85rem; -} - -.sidebar ul ul { - margin-top: 0.25rem; -} - -/* ============================================ - Component Pages: Cards - ============================================ */ - -.components-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); - gap: 2rem; - margin-bottom: 3rem; -} - -.component-card { - background: var(--bg-white); - border-radius: 12px; - padding: 2rem; - box-shadow: 0 2px 10px rgba(0,0,0,0.05); - transition: all 0.3s ease; - border: 1px solid var(--border-color); -} - -.component-card:hover { - transform: translateY(-5px); - box-shadow: 0 8px 25px rgba(0,0,0,0.1); - border-color: var(--primary-color); -} - -.component-icon { - width: 60px; - height: 60px; - border-radius: 12px; - display: flex; - align-items: center; - justify-content: center; - font-size: 1.5rem; - color: #fff; - background: linear-gradient(135deg, var(--primary-color), var(--accent-color)); - margin-bottom: 1.5rem; -} - -.component-card h3 { - font-size: 1.4rem; - margin-bottom: 0.75rem; - color: var(--text-dark); -} - -.component-card p { - color: var(--text-light); - margin-bottom: 1rem; - line-height: 1.7; -} - -.component-status { - display: inline-flex; - align-items: center; - gap: 0.5rem; - padding: 0.25rem 0.75rem; - border-radius: 20px; - font-size: 0.85rem; - font-weight: 600; - margin-bottom: 1rem; -} - -.component-status.live { - background: rgba(16, 185, 129, 0.15); - color: var(--success-color); -} - -.component-status.live i { - font-size: 0.5rem; -} - -.component-link { - display: inline-flex; - align-items: center; - gap: 0.5rem; - color: var(--primary-color); - text-decoration: none; - font-weight: 600; - transition: all 0.3s; -} - -.component-link:hover { - color: var(--secondary-color); - transform: translateX(5px); -} - -/* ============================================ - Component Pages: Section blocks - ============================================ */ - -.section { - background: var(--bg-white); - padding: 2.5rem; - margin-bottom: 2rem; - border-radius: 10px; - box-shadow: 0 2px 10px rgba(0,0,0,0.05); -} - -.section h2 { - font-size: 1.8rem; - margin-bottom: 1.5rem; - color: var(--text-dark); -} - -.inline-code { - background: var(--bg-light); - padding: 0.2rem 0.5rem; - border-radius: 4px; - font-family: 'Fira Code', 'JetBrains Mono', monospace; - font-size: 0.9em; - color: var(--accent-color); -} - -/* ============================================ - API Pages - ============================================ */ - -.api-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); - gap: 1.5rem; - margin: 1.5rem 0; -} - -.api-card { - background: var(--bg-light); - border-radius: 10px; - padding: 1.5rem; - border-left: 4px solid var(--primary-color); -} - -.api-card h4 { - color: var(--primary-color); - margin-bottom: 0.5rem; -} - -.api-endpoint, -.endpoint { - background: var(--bg-light); - border-radius: 8px; - padding: 1.25rem; - margin: 1rem 0; - border: 1px solid var(--border-color); -} - -.method { - display: inline-block; - padding: 0.2rem 0.6rem; - border-radius: 4px; - font-weight: 700; - font-size: 0.8rem; - color: #fff; - margin-right: 0.5rem; -} - -.method.get, .get { background: var(--success-color); } -.method.post, .post { background: var(--primary-color); } -.method.delete, .delete { background: var(--danger-color); } - -.http-request { - font-family: 'Fira Code', monospace; - font-size: 0.9rem; -} - -.error-box { - background: rgba(239, 68, 68, 0.1); - border: 1px solid var(--danger-color); - border-radius: 8px; - padding: 1rem; - margin: 1rem 0; -} - -.status-badge { - display: inline-block; - padding: 0.2rem 0.6rem; - border-radius: 12px; - font-size: 0.8rem; - font-weight: 600; -} - -/* ============================================ - Tabs - ============================================ */ - -.tabs { - margin: 1.5rem 0; -} - -.tab-buttons { - display: flex; - gap: 0.5rem; - margin-bottom: 1rem; - border-bottom: 2px solid var(--border-color); - padding-bottom: 0; -} - -.tab-button { - padding: 0.75rem 1.5rem; - background: none; - border: none; - color: var(--text-light); - cursor: pointer; - font-weight: 600; - border-bottom: 2px solid transparent; - margin-bottom: -2px; - transition: all 0.3s; -} - -.tab-button:hover, -.tab-button.active { - color: var(--primary-color); - border-bottom-color: var(--primary-color); -} - -.tab-content { - display: none; - padding: 1rem 0; -} - -.tab-content.active { - display: block; -} - -/* ============================================ - Code Groups - ============================================ */ - -.code-group { - margin: 1rem 0; - border: 1px solid var(--border-color); - border-radius: 5px; - overflow: hidden; -} - -.code-group-header { - background: var(--bg-light); - padding: 0.5rem 1rem; - font-weight: 600; - color: var(--text-dark); -} - -.code-group-content { - padding: 0; -} - -/* ============================================ - Mermaid Diagrams - ============================================ */ - -.mermaid { - text-align: center; - margin: 2rem 0; -} - -/* ============================================ - Flow Diagram - ============================================ */ - -.flow-diagram { - background: var(--bg-white); - border-radius: 10px; - padding: 2rem; - margin: 2rem 0; - box-shadow: 0 2px 10px rgba(0,0,0,0.05); - overflow-x: auto; -} - -/* ============================================ - Misc: Timeline, Security, CTA, Browser - ============================================ */ - -.timeline { - position: relative; - padding-left: 2rem; - margin: 1.5rem 0; -} - -.timeline::before { - content: ''; - position: absolute; - left: 0; - top: 0; - bottom: 0; - width: 2px; - background: var(--primary-color); -} - -.security-icon { - font-size: 2rem; - color: var(--primary-color); - margin-bottom: 1rem; -} - -.cta-button { - display: inline-block; - padding: 1rem 2rem; - background: linear-gradient(135deg, var(--primary-color), var(--accent-color)); - color: #fff; - border-radius: 50px; - font-weight: 600; - text-decoration: none; - transition: all 0.3s; -} - -.cta-button:hover { - transform: translateY(-2px); - box-shadow: 0 5px 20px rgba(59, 130, 246, 0.4); - color: #fff; -} - -.hero-gradient { - background: linear-gradient(135deg, rgba(59, 130, 246, 0.1) 0%, rgba(16, 185, 129, 0.1) 100%); - border-radius: 15px; - padding: 2rem; - margin: 2rem 0; -} - -.browser-button, .chrome-button, .firefox-button { - display: inline-flex; - align-items: center; - gap: 0.5rem; - padding: 0.75rem 1.5rem; - border-radius: 8px; - font-weight: 600; - text-decoration: none; - transition: all 0.3s; -} - -.chrome-button { - background: #4285f4; - color: #fff; -} - -.firefox-button { - background: #ff7139; - color: #fff; -} - -/* ============================================ - Announcement Banners - ============================================ */ - -.announce-banner { - margin-top: 2rem; - padding: 1.5rem; - background: linear-gradient(135deg, rgba(59, 130, 246, 0.1) 0%, rgba(16, 185, 129, 0.1) 100%); - border-radius: 15px; - border: 2px solid rgba(59, 130, 246, 0.2); -} - -.announce-banner.green { - border-color: rgba(16, 185, 129, 0.2); -} - -.announce-banner h3 { - color: var(--success-color); - margin-bottom: 0.5rem; - font-size: 1.2rem; -} - -.announce-banner p { - color: var(--text-light); - margin: 0; -} - -/* ============================================ - Markdown Source Links - ============================================ */ - -.source-links { - margin-top: 1rem; - display: flex; - gap: 1rem; - flex-wrap: wrap; -} - -.source-links a { - color: var(--primary-color); - font-size: 0.9rem; - text-decoration: none; -} - -.source-links a:hover { - text-decoration: underline; -} - -/* ============================================ - Search Results - ============================================ */ - -.search-results { - max-width: 600px; - margin: -3rem auto 2rem; - background: var(--bg-white); - border-radius: 10px; - box-shadow: 0 4px 20px rgba(0,0,0,0.1); - overflow: hidden; -} - -.search-results a { - display: block; - padding: 0.75rem 1rem; - border-bottom: 1px solid var(--border-color); - color: var(--text-dark); - text-decoration: none; -} - -.search-results a:hover { - background: rgba(59, 130, 246, 0.05); -} - -.search-results small { - color: var(--text-light); -} - -.search-results .no-results { - padding: 1rem; - color: var(--text-light); -} - -/* ============================================ - Inline Code Blocks (pre/code in content) - ============================================ */ - -.code-inline { - background: #1f2937; - color: #f9fafb; - padding: 1rem; - border-radius: 8px; - overflow-x: auto; - font-family: 'Fira Code', 'JetBrains Mono', monospace; - font-size: 0.9rem; -} - -/* ============================================ - Quick-link Grid (components page) - ============================================ */ - -.quicklink-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); - gap: 1rem; - margin-top: 1.5rem; -} - -.quicklink-grid a { - padding: 1rem; - background: var(--bg-light); - border-radius: 8px; - text-decoration: none; - color: var(--text-dark); - transition: all 0.3s; -} - -.quicklink-grid a:hover { - background: var(--primary-color); - color: #fff; -} diff --git a/website/docs/developers.html b/website/docs/developers.html deleted file mode 100644 index 73da4254..00000000 --- a/website/docs/developers.html +++ /dev/null @@ -1,505 +0,0 @@ - - - - - - Developer Documentation - AITBC - - - - -
- - -
-
-
- For Developers -

Build on AITBC

-

Join our developer community and help build the future of decentralized AI

- -
- - -
-

Technology Stack

-

AITBC is built with modern technologies focused on performance and security.

- -
-
-
- -
-
Rust
-
-
-
- -
-
Go
-
-
-
- -
-
Python
-
-
-
- -
-
TypeScript
-
-
-
- -
-
React
-
-
-
- -
-
PostgreSQL
-
-
-
- -
-
Docker
-
-
-
- -
-
Kubernetes
-
-
-
- - -
- -

Getting Started

-

Ready to contribute? Here's how to get started with AITBC development.

- -

Development Environment Setup

-
-
1
-
-

Fork & Clone

-
-# Fork the repository on GitHub -git clone https://github.com/YOUR_USERNAME/AITBC.git -cd aitbc - -# Add upstream remote -git remote add upstream https://github.com/oib/AITBC.git
-
-
- -
-
2
-
-

Install Dependencies

-
-# Install development dependencies -./scripts/install-dev-deps.sh - -# Setup pre-commit hooks -pre-commit install
-
-
- -
-
3
-
-

Build & Run

-
-# Build all components -make build - -# Start development environment -make dev-up - -# Run tests -make test
-
-
- -
-
4
-
-

Create Your Branch

-
-# Create feature branch -git checkout -b feature/your-feature-name - -# Make your changes... -# Commit with proper message -git commit -m "feat: add your feature description"
-
-
- -
-
5
-
-

Submit PR

-
-# Push to your fork -git push origin feature/your-feature-name - -# Create pull request on Gitea -# Fill PR template and submit
-
-
-
- - -
-

Contribution Areas

-

There are many ways to contribute to AITBC. Find the area that matches your skills!

- -
-
-

Core Protocol

-
    -
  • Consensus mechanism improvements
  • -
  • Cryptographic implementations
  • -
  • Performance optimizations
  • -
  • Security enhancements
  • -
  • Sharding implementations
  • -
-

Skills: Rust, Go, Cryptography, Distributed Systems

-
- -
-

AI/ML Integration

-
    -
  • Model optimization
  • -
  • ZK proof generation
  • -
  • Secure enclaves
  • -
  • Privacy-preserving ML
  • -
  • Autonomous agents
  • -
-

Skills: Python, TensorFlow, PyTorch, ZK-SNARKs

-
- -
-

Developer Tools

-
    -
  • SDK development
  • -
  • CLI tools
  • -
  • Testing frameworks
  • -
  • Documentation
  • -
  • IDE plugins
  • -
-

Skills: TypeScript, Python, Go, Documentation

-
- -
-

Frontend & UI

-
    -
  • Marketplace interface
  • -
  • Wallet UI
  • -
  • Developer dashboard
  • -
  • Mobile apps
  • -
  • Design system
  • -
-

Skills: React, TypeScript, CSS, Design

-
- -
-

Security

-
    -
  • Security audits
  • -
  • Penetration testing
  • -
  • Bug bounty
  • -
  • Security tools
  • -
  • Threat modeling
  • -
-

Skills: Security, Auditing, Cryptography

-
- -
-

Documentation

-
    -
  • Technical guides
  • -
  • Tutorials
  • -
  • API docs
  • -
  • Blog posts
  • -
  • Translations
  • -
-

Skills: Writing, Technical Communication

-
-
-
- - -
-

Development Guidelines

- -

Code Standards

-
    -
  • Follow language-specific style guides (rustfmt, gofmt, PEP8)
  • -
  • Write comprehensive tests for new features
  • -
  • Document all public APIs and complex logic
  • -
  • Keep pull requests focused and small
  • -
  • Use clear and descriptive commit messages
  • -
- -

Testing Requirements

-
-# Run all tests -make test - -# Run with coverage -make test-coverage - -# Run integration tests -make test-integration - -# Run benchmarks -make benchmark
- -

Code Review Process

-
    -
  • All changes require review
  • -
  • At least one approval needed
  • -
  • CI must pass
  • -
  • Documentation updated
  • -
  • Tests added/updated
  • -
- -
- Pro Tip: Join our Discord #dev channel for real-time help and discussions! -
-
- - -
-

Bounties & Grants

-

Get paid to contribute to AITBC!

- -

Open Bounties

-
    -
  • $500 - Implement REST API rate limiting
  • -
  • $750 - Add Python async SDK support
  • -
  • $1000 - Optimize ZK proof generation
  • -
  • $1500 - Implement cross-chain bridge
  • -
  • $2000 - Build mobile wallet app
  • -
- -

Research Grants

-
    -
  • $5000 - Novel consensus mechanisms
  • -
  • $7500 - Privacy-preserving ML
  • -
  • $10000 - Quantum-resistant cryptography
  • -
- -

How to Apply

-
    -
  1. Check open issues on Gitea
  2. -
  3. Comment on the issue you want to work on
  4. -
  5. Submit your solution
  6. -
  7. Get reviewed by core team
  8. -
  9. Receive payment in AITBC tokens
  10. -
- -
- New Contributor Bonus: First-time contributors get a 20% bonus on their first bounty! -
-
- - -
-

Join the Community

- -

Developer Channels

-
    -
  • Discord #dev - General development discussion
  • -
  • Discord #core-dev - Core protocol discussions
  • -
  • Discord #bounties - Bounty program updates
  • -
  • Discord #research - Research discussions
  • -
- -

Events & Programs

-
    -
  • Weekly Dev Calls - Every Tuesday 14:00 UTC
  • -
  • Hackathons - Quarterly with prizes
  • -
  • Office Hours - Meet the core team
  • -
  • Mentorship Program - Learn from experienced devs
  • -
- -

Recognition

-
    -
  • Top contributors featured on website
  • -
  • Monthly contributor rewards
  • -
  • Special Discord roles
  • -
  • Annual developer summit invitation
  • -
  • Swag and merchandise
  • -
-
- - -
-

Developer Resources

- -

Documentation

- - -

Tools & SDKs

- - -

Development Environment

- - -

Learning Resources

- -
- - -
-

Example: Adding a New API Endpoint

-

The coordinator-api uses Python with FastAPI. Here's how to add a new endpoint:

- -

1. Define the Schema

-
-# File: coordinator-api/src/app/schemas.py - -from pydantic import BaseModel -from typing import Optional - -class NewFeatureRequest(BaseModel): - """Request model for new feature.""" - name: str - value: int - options: Optional[dict] = None - -class NewFeatureResponse(BaseModel): - """Response model for new feature.""" - id: str - status: str - result: dict
- -

2. Create the Router

-
-# File: coordinator-api/src/app/routers/new_feature.py - -from fastapi import APIRouter, Depends, HTTPException -from ..schemas import NewFeatureRequest, NewFeatureResponse -from ..services.new_feature import NewFeatureService - -router = APIRouter(prefix="/v1/features", tags=["features"]) - -@router.post("/", response_model=NewFeatureResponse) -async def create_feature( - request: NewFeatureRequest, - service: NewFeatureService = Depends() -): - """Create a new feature.""" - try: - result = await service.process(request) - return NewFeatureResponse( - id=result.id, - status="success", - result=result.data - ) - except ValueError as e: - raise HTTPException(status_code=400, detail=str(e))
- -

3. Write Tests

-
-# File: coordinator-api/tests/test_new_feature.py - -import pytest -from fastapi.testclient import TestClient -from src.app.main import app - -client = TestClient(app) - -def test_create_feature_success(): - """Test successful feature creation.""" - response = client.post( - "/v1/features/", - json={"name": "test", "value": 123} - ) - assert response.status_code == 200 - data = response.json() - assert data["status"] == "success" - assert "id" in data - -def test_create_feature_invalid(): - """Test validation error.""" - response = client.post( - "/v1/features/", - json={"name": ""} # Missing required field - ) - assert response.status_code == 422
- -
- 💡 Pro Tip: Run make test locally before pushing. The CI pipeline will also run all tests automatically on your PR. -
-
- - -
-

Frequently Asked Questions

- -

General

-
    -
  • How do I start contributing? - Check our "Getting Started" guide and pick an issue that interests you.
  • -
  • Do I need to sign anything? - Yes, you'll need to sign our CLA (Contributor License Agreement).
  • -
  • Can I be paid for contributions? - Yes! Check our bounty program or apply for grants.
  • -
- -

Technical

-
    -
  • What's the tech stack? - Rust for blockchain, Go for services, Python for AI, TypeScript for frontend.
  • -
  • How do I run tests? - Use `make test` or check specific component documentation.
  • -
  • Where can I ask questions? - Discord #dev channel is the best place.
  • -
- -

Process

-
    -
  • How long does PR review take? - Usually 1-3 business days.
  • -
  • Can I work on multiple issues? - Yes, but keep PRs focused on single features.
  • -
  • What if my PR is rejected? - We'll provide feedback and guidance for resubmission.
  • -
-
-
-
- - - - - - diff --git a/website/docs/explorer-web.html b/website/docs/explorer-web.html deleted file mode 100644 index 65d365b7..00000000 --- a/website/docs/explorer-web.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - - Explorer Web - AITBC Documentation - - - - -
- -
-
- - - - - - - Back to Components - - - -
-

Explorer Web

-

Full-featured blockchain explorer with blocks, transactions, addresses, and receipts tracking. Responsive design with live data.

- ● Live -
- - -
-

Overview

-

The AITBC Explorer Web provides a comprehensive view of the blockchain, allowing users to track blocks, transactions, addresses, and AI computation receipts in real-time.

- -

Key Features

-
    -
  • Real-time block and transaction tracking
  • -
  • Address balance and transaction history
  • -
  • AI computation receipt verification
  • -
  • Search functionality for blocks, transactions, and addresses
  • -
  • Responsive design for all devices
  • -
  • Live data updates via WebSocket
  • -
-
- - -
-

Architecture

-

The explorer is built as a modern single-page application:

- -
-
-

Frontend

-

React with TypeScript for type safety

-
-
-

API Integration

-

Direct blockchain RPC API connection

-
-
-

Real-time Updates

-

WebSocket for live block updates

-
-
- Responsive -

Mobile-first responsive design

-
-
-
- - -
-

Features

- -

Block Explorer

-
    -
  • Latest blocks list with timestamps
  • -
  • Detailed block view with transactions
  • -
  • Block validation status
  • -
  • Block size and gas metrics
  • -
- -

Transaction Tracker

-
    -
  • Transaction details and status
  • -
  • Input/output addresses
  • -
  • Gas fees and confirmations
  • -
  • Transaction mempool status
  • -
- -

Address Viewer

-
    -
  • Address balance and history
  • -
  • Transaction list per address
  • -
  • QR code generation
  • -
  • Address labeling
  • -
- -

AI Receipt Explorer

-
    -
  • Computation receipt details
  • -
  • ZK-proof verification
  • -
  • Job metadata and results
  • -
  • Miner rewards tracking
  • -
-
- - -
-

API Integration

-

The explorer connects directly to the blockchain node RPC API:

- -
// Get latest blocks
-GET /rpc/get_latest_blocks?limit=50
-
-// Get block by height
-GET /rpc/get_block/{height}
-
-// Get transaction by hash
-GET /rpc/get_transaction/{hash}
-
-// Get address info
-GET /rpc/get_address/{address}
-
-// WebSocket subscription
-ws://localhost:9081/ws
-{
-  "method": "subscribe",
-  "params": ["new_blocks", "new_transactions"]
-}
-
- - -
-

Deployment

- -

Docker Deployment

-
# Build explorer image
-docker build -t aitbc/explorer-web .
-
-# Run with nginx
-docker run -d \
-  -p 80:80 \
-  -e API_URL=http://blockchain-node:9080 \
-  -e WS_URL=ws://blockchain-node:9081 \
-  aitbc/explorer-web
- -

Configuration

-
# Environment variables
-API_URL=http://localhost:9080
-WS_URL=ws://localhost:9081
-NETWORK_NAME=mainnet
-CACHE_TTL=300
-
- - -
-

Development

- -

Local Development

-
# Install dependencies
-npm install
-
-# Start development server
-npm run dev
-
-# Build for production
-npm run build
-
-# Run tests
-npm test
- -

Project Structure

-
explorer-web/
-├── src/
-│   ├── components/     # React components
-│   ├── pages/         # Page components
-│   ├── hooks/         # Custom hooks
-│   ├── services/      # API services
-│   └── utils/         # Utilities
-├── public/
-├── package.json
-└── Dockerfile
-
-
-
- - - - - - diff --git a/website/docs/flowchart.html b/website/docs/flowchart.html deleted file mode 100644 index ab6c14bd..00000000 --- a/website/docs/flowchart.html +++ /dev/null @@ -1,486 +0,0 @@ - - - - - - System Flow - AITBC Documentation - - - - -
- -
-
- - - - - - - Back to Documentation - - - -
-

AITBC System Flow

-

Complete flow of a job submission through the CLI client, detailing each system component, message, RPC call, and port involved.

-
- - -
-

Overview Diagram

-
-
-
CLI Wrapper
-
-
Client Python
-
-
Coordinator
-
-
Blockchain
-
-
Miner
-
-
Ollama
-
-
-
(aitbc-cli.sh) → (client.py) → (port 18000) → (RPC:26657) → (port 18001) → (port 11434)
-
-
- -

Component Interactions

-
-
-

1. Job Submission

-

User submits CLI command → Python client formats request → HTTP POST to Coordinator

-
-
-

2. Job Processing

-

Coordinator validates → Creates blockchain transaction → Queues for miner

-
-
-

3. AI Inference

-

Miner receives job → Sends to Ollama → Processes on GPU → Returns result

-
-
-

4. Verification

-

Result verified → Receipt generated → Recorded on blockchain → Client notified

-
-
-
- - -
-

Detailed Flow Sequence

- -

1. CLI Wrapper Execution

-

User Command:

-
./scripts/aitbc-cli.sh submit inference --prompt "What is machine learning?" --model llama3.2:latest
- -

Internal Process:

-
    -
  1. Bash script (aitbc-cli.sh) parses arguments
  2. -
  3. Sets environment variables: -
      -
    • AITBC_URL=http://127.0.0.1:18000
    • -
    • CLIENT_KEY=${CLIENT_API_KEY}
    • -
    -
  4. -
  5. Calls Python client: python3 cli/client.py --url $AITBC_URL --api-key $CLIENT_KEY submit inference --prompt "..."
  6. -
- -

2. Python Client Processing

-

File: /cli/client.py

- -

Steps:

-
    -
  1. Parse command-line arguments
  2. -
  3. Prepare job submission payload: -
    {
    -  "type": "inference",
    -  "prompt": "What is machine learning?",
    -  "model": "llama3.2:latest",
    -  "client_key": "${CLIENT_API_KEY}",
    -  "timestamp": "2025-01-29T14:50:00Z"
    -}
    -
  4. -
- -

3. Coordinator API Call

-
-

HTTP Request:

-
POST /v1/jobs
-Host: 127.0.0.1:18000
-Content-Type: application/json
-X-Api-Key: ${CLIENT_API_KEY}
-
-{
-  "type": "inference",
-  "prompt": "What is machine learning?",
-  "model": "llama3.2:latest"
-}
-
- -

Coordinator Service (Port 18000):

-
    -
  1. Receives HTTP request
  2. -
  3. Validates API key and job parameters
  4. -
  5. Generates unique job ID: job_123456
  6. -
  7. Creates job record in database
  8. -
  9. Returns initial response: -
    {
    -  "job_id": "job_123456",
    -  "status": "pending",
    -  "submitted_at": "2025-01-29T14:50:01Z"
    -}
    -
  10. -
- -

4. Blockchain Transaction

-

Coordinator → Blockchain Node (RPC Port 26657):

- -
    -
  1. Coordinator creates blockchain transaction: -
    {
    -  "type": "submit_job",
    -  "job_id": "job_123456",
    -  "client": "${CLIENT_API_KEY}",
    -  "payload_hash": "abc123...",
    -  "reward": "100aitbc"
    -}
    -
  2. -
  3. RPC Call to blockchain node: -
    curl -X POST http://127.0.0.1:26657 \
    -  -d '{
    -    "jsonrpc": "2.0",
    -    "method": "broadcast_tx_sync",
    -    "params": {"tx": "base64_encoded_transaction"}
    -  }'
    -
  4. -
  5. Blockchain validates and includes transaction in next block
  6. -
  7. Transaction hash returned: 0xdef456...
  8. -
- -

5. Job Queue and Miner Assignment

-

Coordinator Internal Processing:

-
    -
  1. Job added to pending queue (Redis/Database)
  2. -
  3. Miner selection algorithm runs: -
      -
    • Check available miners
    • -
    • Select based on stake, reputation, capacity
    • -
    -
  4. -
  5. Selected miner: ${MINER_API_KEY}
  6. -
- -
-

Coordinator → Miner Daemon (Port 18001):

-
POST /v1/jobs/assign
-Host: 127.0.0.1:18001
-Content-Type: application/json
-X-Api-Key: ${ADMIN_API_KEY}
-
-{
-  "job_id": "job_123456",
-  "job_data": {
-    "type": "inference",
-    "prompt": "What is machine learning?",
-    "model": "llama3.2:latest"
-  },
-  "reward": "100aitbc"
-}
-
- -

6. Miner Processing

-

Miner Daemon (Port 18001):

-
    -
  1. Receives job assignment
  2. -
  3. Updates job status to running
  4. -
  5. Notifies coordinator: -
    POST /v1/jobs/job_123456/status
    -{"status": "running", "started_at": "2025-01-29T14:50:05Z"}
    -
  6. -
- -

7. Ollama Inference Request

-
-

Miner → Ollama Server (Port 11434):

-
POST /api/generate
-Host: 127.0.0.1:11434
-Content-Type: application/json
-
-{
-  "model": "llama3.2:latest",
-  "prompt": "What is machine learning?",
-  "stream": false,
-  "options": {
-    "temperature": 0.7,
-    "num_predict": 500
-  }
-}
-
- -

Ollama Processing:

-
    -
  1. Loads model into GPU memory
  2. -
  3. Processes prompt through neural network
  4. -
  5. Generates response text
  6. -
  7. Returns result: -
    {
    -  "model": "llama3.2:latest",
    -  "response": "Machine learning is a subset of artificial intelligence...",
    -  "done": true,
    -  "total_duration": 12500000000,
    -  "prompt_eval_count": 15,
    -  "eval_count": 150
    -}
    -
  8. -
- -

8. Result Submission to Coordinator

-
-

Miner → Coordinator (Port 18000):

-
POST /v1/jobs/job_123456/complete
-Host: 127.0.0.1:18000
-Content-Type: application/json
-X-Miner-Key: ${MINER_API_KEY}
-
-{
-  "job_id": "job_123456",
-  "result": "Machine learning is a subset of artificial intelligence...",
-  "metrics": {
-    "compute_time": 12.5,
-    "tokens_generated": 150,
-    "gpu_utilization": 0.85
-  },
-  "proof": {
-    "hash": "hash_of_result",
-    "signature": "miner_signature"
-  }
-}
-
- -

9. Receipt Generation

-

Coordinator Processing:

-
    -
  1. Verifies miner's proof
  2. -
  3. Calculates payment: 12.5 seconds × 0.02 AITBC/second = 0.25 AITBC
  4. -
  5. Creates receipt: -
    {
    -  "receipt_id": "receipt_789",
    -  "job_id": "job_123456",
    -  "client": "${CLIENT_API_KEY}",
    -  "miner": "${MINER_API_KEY}",
    -  "amount_paid": "0.25aitbc",
    -  "result_hash": "hash_of_result",
    -  "block_height": 12345,
    -  "timestamp": "2025-01-29T14:50:18Z"
    -}
    -
  6. -
- -

10. Blockchain Receipt Recording

-
Coordinator → Blockchain (RPC Port 26657):
-{
-  "type": "record_receipt",
-  "receipt": {
-    "receipt_id": "receipt_789",
-    "job_id": "job_123456",
-    "payment": "0.25aitbc"
-  }
-}
- -

11. Client Polling for Result

-

CLI Client Status Check:

-
./scripts/aitbc-cli.sh status job_123456
- -
-

HTTP Request:

-
GET /v1/jobs/job_123456
-Host: 127.0.0.1:18000
-X-Api-Key: ${CLIENT_API_KEY}
- -

Response:

-
{
-  "job_id": "job_123456",
-  "status": "completed",
-  "result": "Machine learning is a subset of artificial intelligence...",
-  "receipt_id": "receipt_789",
-  "completed_at": "2025-01-29T14:50:18Z"
-}
-
- -

12. Final Output to User

-

CLI displays:

-
Job ID: job_123456
-Status: completed
-Result: Machine learning is a subset of artificial intelligence...
-Receipt: receipt_789
-Completed in: 17 seconds
-Cost: 0.25 AITBC
-
- - -
-

System Components Summary

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ComponentPortProtocolResponsibility
CLI WrapperN/ABashUser interface, argument parsing
Client PythonN/APythonHTTP client, job formatting
Coordinator18000HTTP/RESTJob management, API gateway
Blockchain Node26657JSON-RPCTransaction processing, consensus
Miner Daemon18001HTTP/RESTJob execution, GPU management
Ollama Server11434HTTP/RESTAI model inference
-
- - -
-

Message Flow Timeline

-
0s: User submits CLI command -└─> 0.1s: Python client called - └─> 0.2s: HTTP POST to Coordinator (port 18000) - └─> 0.3s: Coordinator validates and creates job - └─> 0.4s: RPC to Blockchain (port 26657) - └─> 0.5s: Transaction in mempool - └─> 1.0s: Job queued for miner - └─> 2.0s: Miner assigned (port 18001) - └─> 2.1s: Miner accepts job - └─> 2.2s: Ollama request (port 11434) - └─> 14.7s: Inference complete (12.5s processing) - └─> 14.8s: Result to Coordinator - └─> 15.0s: Receipt generated - └─> 15.1s: Receipt on Blockchain - └─> 17.0s: Client polls and gets result
-
- - -
-

Error Handling Paths

- -
-

1. Invalid Prompt

-
    -
  • Coordinator returns 400 error
  • -
  • CLI displays error message
  • -
-
- -
-

2. Miner Unavailable

-
    -
  • Job stays in queue
  • -
  • Timeout after 60 seconds
  • -
  • Job marked as failed
  • -
-
- -
-

3. Ollama Error

-
    -
  • Miner reports failure to Coordinator
  • -
  • Job marked as failed
  • -
  • No payment deducted
  • -
-
- -
-

4. Network Issues

-
    -
  • Client retries with exponential backoff
  • -
  • Maximum 3 retries before giving up
  • -
-
-
- - -
-

Security Considerations

-
    -
  • API Keys: Each request authenticated with X-Api-Key header
  • -
  • Proof of Work: Miner provides cryptographic proof of computation
  • -
  • Payment Escrow: Tokens held in smart contract until completion
  • -
  • Rate Limiting: Coordinator limits requests per client
  • -
-
- - -
-

Related Documentation

- -
- - -
-

Monitoring Points

-
    -
  • Coordinator logs all API calls to /var/log/aitbc/coordinator.log
  • -
  • Miner logs GPU utilization to /var/log/aitbc/miner.log
  • -
  • Blockchain logs all transactions to /var/log/aitbc/node.log
  • -
  • Prometheus metrics available at http://localhost:9090/metrics
  • -
-
-
-
- - - - - - diff --git a/website/docs/full-documentation.html b/website/docs/full-documentation.html deleted file mode 100644 index a1905597..00000000 --- a/website/docs/full-documentation.html +++ /dev/null @@ -1,648 +0,0 @@ - - - - - - Full Documentation - AITBC - - - - -
- - -
-
-
- -

AITBC Full Documentation

-

Complete technical documentation for the AI Training & Blockchain Computing platform

-
- -
- - - - -
-
-

Introduction

-

AITBC (AI Training & Blockchain Computing) is a decentralized platform that combines artificial intelligence and blockchain technology to create a trustless marketplace for AI/ML workloads. The platform enables secure, private, and verifiable computation while maintaining transparency through blockchain technology.

- -

Key Features

-
    -
  • Decentralized Marketplace: Connect AI service providers with consumers in a trustless environment
  • -
  • Confidential Computing: Zero-knowledge proofs and secure enclaves protect sensitive data
  • -
  • High Performance: Sharding and rollups achieve 100,000+ TPS with sub-second finality
  • -
  • Privacy-Preserving: Advanced cryptography ensures data confidentiality
  • -
  • Token Economics: Sustainable incentives for all participants
  • -
  • Autonomous Agents: AI agents can participate as marketplace providers
  • -
- -

Use Cases

-
-
- - - -
-
-

Healthcare AI

-

Secure medical image analysis, drug discovery, and patient data processing while maintaining HIPAA compliance through confidential computing.

-
-
-

Financial Services

-

Fraud detection, risk assessment, and algorithmic trading with verifiable computation and audit trails.

-
-
-

Scientific Research

-

Collaborative research with data privacy, reproducible results, and fair attribution through blockchain verification.

-
-
-
- -
-

Architecture

- -

Core Components

-
- graph TB - A[Client] --> B[Coordinator API] - B --> C[Blockchain Node] - B --> D[GPU Providers] - C --> E[Consensus Engine] - C --> F[Smart Contracts] - D --> G[ZK Proofs] - F --> H[Receipt Storage] -
- -

Blockchain Node

-

The blockchain node implements a hybrid Proof of Authority/Proof of Stake consensus mechanism with three operational modes:

-
    -
  • FAST Mode: 100-200ms finality, up to 50,000 TPS
  • -
  • BALANCED Mode: 500ms-1s finality, up to 20,000 TPS
  • -
  • SECURE Mode: 2-5s finality, up to 10,000 TPS
  • -
- -

Coordinator API

-

The coordinator serves as the central hub for marketplace operations:

-
    -
  • Job scheduling and management
  • -
  • Receipt verification and storage
  • -
  • Provider registration and reputation tracking
  • -
  • Multi-tenant support with isolation
  • -
  • Real-time metrics and analytics
  • -
- -

GPU Service Provider

-

Decentralized compute providers offer various AI/ML services:

-
    -
  • Model inference (text, image, audio, video)
  • -
  • Model training and fine-tuning
  • -
  • Data preprocessing and augmentation
  • -
  • Result verification with ZK proofs
  • -
  • Cross-chain compatibility
  • -
- -

Data Flow

-
- sequenceDiagram - participant C as Client - participant API as Coordinator API - participant P as Provider - participant BC as Blockchain - - C->>API: Submit Job Request - API->>API: Validate & Match Provider - API->>P: Forward Job - P->>P: Execute Computation - P->>P: Generate ZK Proof - P->>API: Submit Results + Proof - API->>API: Verify Proof - API->>BC: Store Receipt - BC->>C: Notify Completion - C->>API: Retrieve Results -
- -

Consensus Mechanism

-

The hybrid consensus combines the speed of Proof of Authority with the decentralization of Proof of Stake:

- -

Mode Selection Algorithm

-
def determine_mode(network_metrics):
-    load = network_metrics.utilization
-    auth_availability = network_metrics.authority_uptime
-    stake_participation = network_metrics.stake_ratio
-    
-    if load < 0.3 and auth_availability > 0.9:
-        return ConsensusMode.FAST
-    elif load > 0.7 or stake_participation > 0.8:
-        return ConsensusMode.SECURE
-    else:
-        return ConsensusMode.BALANCED
- -

Validator Selection

-
-
- - - -
-
-

Authority-Only Selection

-
    -
  • VRF-based random selection from 21 authorities
  • -
  • 100ms block time
  • -
  • 2/3 signature threshold
  • -
-
-
-

Hybrid Selection

-
    -
  • 70% authority, 30% staker selection
  • -
  • 500ms block time
  • -
  • 2/3 authority + 1/3 stake threshold
  • -
-
-
-

Stake-Weighted Selection

-
    -
  • Full stake-weighted selection
  • -
  • 2s block time
  • -
  • 2/3 stake threshold
  • -
-
-
-
- -
-

Installation

- -

Prerequisites

-
- System Requirements: -
    -
  • Linux (Ubuntu 20.04+) or macOS (10.15+)
  • -
  • 16GB RAM minimum (32GB recommended)
  • -
  • 100GB free storage
  • -
  • Docker 20.10+ and Docker Compose
  • -
  • Node.js 16+ (for frontend development)
  • -
  • Python 3.8+ (for backend development)
  • -
  • Go 1.19+ (for blockchain node)
  • -
-
- -

Quick Start

-

Option 1: Docker Compose (Recommended)

-
# Clone the repository
-git clone https://github.com/oib/AITBC.git
-cd aitbc
-
-# Copy environment configuration
-cp .env.example .env
-# Edit .env with your settings
-
-# Start all services
-docker-compose up -d
-
-# Check status
-docker-compose ps
- -

Option 2: Manual Installation

-
# Install dependencies
-./scripts/install-dependencies.sh
-
-# Build blockchain node
-make build-node
-
-# Build coordinator
-make build-coordinator
-
-# Initialize database
-./scripts/init-db.sh
-
-# Start services
-./scripts/start-all.sh
- -

Configuration

-

Environment Variables

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
VariableDescriptionDefault
AITBC_NETWORKNetwork mode (dev/test/main)dev
AITBC_CHAIN_IDBlockchain chain ID1337
AITBC_CONSENSUS_MODEConsensus modeBALANCED
AITBC_DB_URLDatabase connection stringpostgresql://localhost/aitbc
AITBC_REDIS_URLRedis connection stringredis://localhost:6379
- -

Node Configuration

-
# config/node.toml
-[network]
-listen_addr = "0.0.0.0:30303"
-discovery_addr = "0.0.0.0:30304"
-
-[consensus]
-mode = "BALANCED"
-validator_count = 21
-stake_minimum = 1000
-
-[storage]
-data_dir = "/var/lib/aitbc"
-prune = true
-prune_threshold = "100GB"
-
- -
-

APIs

- -

Coordinator API

-

Authentication

-

All API requests require authentication using JWT tokens:

-
curl -X POST http://localhost:8080/api/v1/auth/login \
-  -H "Content-Type: application/json" \
-  -d '{"address": "0x...", "signature": "0x..."}'
- -

Endpoints

-
-
Job Management
-
-
# Create a job
-POST /api/v1/jobs
-{
-  "type": "inference",
-  "model_id": "gpt-4",
-  "input_data": "Hello, world!",
-  "requirements": {
-    "max_tokens": 100,
-    "temperature": 0.7
-  }
-}
-
-# Get job status
-GET /api/v1/jobs/{job_id}
-
-# List jobs
-GET /api/v1/jobs?status=pending&limit=10
-
-# Cancel a job
-DELETE /api/v1/jobs/{job_id}
-
-
- -
-
Receipt Verification
-
-
# Verify a receipt
-POST /api/v1/receipts/verify
-{
-  "receipt_id": "0x...",
-  "proof": "0x...",
-  "public_inputs": ["0x..."]
-}
-
-# Get receipt details
-GET /api/v1/receipts/{receipt_id}
-
-
- -

Blockchain API

-

JSON-RPC Endpoints

-
# Get latest block
-curl -X POST http://localhost:8545 \
-  -H "Content-Type: application/json" \
-  -d '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest", false],"id":1}'
-
-# Send transaction
-curl -X POST http://localhost:8545 \
-  -H "Content-Type: application/json" \
-  -d '{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":["0x..."],"id":1}'
- -

WebSocket Subscriptions

-
# Subscribe to new blocks
-ws://localhost:8545
-
-{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}
- -

Wallet API

-

Wallet Operations

-
# Create wallet
-POST /api/v1/wallet/create
-{
-  "password": "secure-password",
-  "mnemonic_language": "english"
-}
-
-# Unlock wallet
-POST /api/v1/wallet/unlock
-{
-  "wallet_id": "wallet-uuid",
-  "password": "secure-password"
-}
-
-# Sign transaction
-POST /api/v1/wallet/sign
-{
-  "wallet_id": "wallet-uuid",
-  "transaction": "0x..."
-}
-
- -
-

Development

- -

Building

-

Prerequisites

-
# Install build dependencies
-sudo apt-get install build-essential libssl-dev
-
-# Install Rust (for blockchain node)
-curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
-source ~/.cargo/env
-
-# Install Go
-wget https://go.dev/dl/go1.19.linux-amd64.tar.gz
-sudo tar -C /usr/local -xzf go1.19.linux-amd64.tar.gz
- -

Build Components

-
# Build blockchain node
-cd blockchain-node
-cargo build --release
-
-# Build coordinator
-cd coordinator-api
-go build -o bin/coordinator
-
-# Build wallet daemon
-cd wallet-daemon
-go build -o bin/wallet
-
-# Build frontend
-cd marketplace-web
-npm install
-npm run build
- -

Testing

-

Unit Tests

-
# Run all tests
-make test
-
-# Run specific package tests
-make test-unit PACKAGE=coordinator
-
-# Run with coverage
-make test-coverage
- -

Integration Tests

-
# Start test environment
-docker-compose -f docker-compose.test.yml up -d
-
-# Run integration tests
-make test-integration
-
-# Clean up
-docker-compose -f docker-compose.test.yml down -v
- -

Load Testing

-
# Install Locust
-pip install locust
-
-# Run load tests
-locust -f tests/load/locustfile.py --host=http://localhost:8080
- -

Contributing

-

We welcome contributions! Please see our contributing guide for details.

- -

Development Workflow

-
    -
  1. Fork the repository on Gitea
  2. -
  3. Create a feature branch
  4. -
  5. Make your changes
  6. -
  7. Add tests for new functionality
  8. -
  9. Ensure all tests pass
  10. -
  11. Submit a pull request
  12. -
- -

Code Style

-
-
Rust
-
-
# Format code
-cargo fmt
-
-# Run linter
-cargo clippy -- -D warnings
-
-# Run audit
-cargo audit
-
-
- -
-
Go
-
-
# Format code
-go fmt ./...
-
-# Run linter
-golangci-lint run
-
-# Run security check
-gosec ./...
-
-
-
- -
-

Security

- -

Threat Model

-

Our comprehensive threat model covers:

-
    -
  • Privacy attacks and mitigations
  • -
  • Consensus security
  • -
  • Smart contract vulnerabilities
  • -
  • Network-level attacks
  • -
  • Economic attacks
  • -
- -

See the full threat modeling document for detailed analysis.

- -

Security Audits

-
- Completed Audits: -
    -
  • Trail of Bits (2024) - Smart Contracts
  • -
  • CertiK (2024) - Protocol Security
  • -
  • OpenZeppelin (2023) - Token Economics
  • -
-
- -

Bug Bounty Program

-

We offer rewards up to $100,000 for critical vulnerabilities:

-
    -
  • Critical: $50,000 - $100,000
  • -
  • High: $10,000 - $50,000
  • -
  • Medium: $1,000 - $10,000
  • -
  • Low: $100 - $1,000
  • -
-

Report vulnerabilities at: andreas.fleckl@bubuit.net

-
- -
-

Reference

- -

Glossary

- - - - - - - - - - - - - - - - - - - - - -
TermDefinition
ZK ProofZero-knowledge proof enabling verification without revealing inputs
ReceiptCryptographic proof of computation completion
ProviderNode offering AI/ML computation services
CoordinatorCentral service managing marketplace operations
- -

Frequently Asked Questions

-

General

-

What blockchain does AITBC use?

-

AITBC implements its own blockchain with a hybrid consensus mechanism, but supports cross-chain interoperability with Ethereum, Polygon, and BSC.

- -

How are transactions verified?

-

Through a combination of zero-knowledge proofs for privacy and traditional blockchain validation for transparency.

- -

Technical

-

What programming languages are used?

-
    -
  • Rust for blockchain node
  • -
  • Go for coordinator and wallet
  • -
  • TypeScript/React for frontend
  • -
  • Python for AI/ML components
  • -
- -

How can I run a node?

-

See the installation guide for detailed instructions on running a full node, validator node, or GPU provider.

- -

Support

-

Get help through:

- -
-
-
-
-
- - - - - - - - - - - diff --git a/website/docs/index.html b/website/docs/index.html deleted file mode 100644 index 316c0e25..00000000 --- a/website/docs/index.html +++ /dev/null @@ -1,232 +0,0 @@ - - - - - - - - - - - - Documentation - AITBC - - -
- - -
-
-
-

Documentation

-

Choose your reader level to access tailored documentation for your needs

-
-

✅ Latest Update (February 2026)

-

Documentation fully restructured! 10 numbered sections from Getting Started to Security, optimized content with merged duplicates, and zero broken links. Plus: end-to-end Ollama GPU inference with RTX 4060 Ti operational.

-
-
- - -
- - -
- - -
- -
-
- -
-

Miners

-

Learn how to mine AITBC tokens and contribute to network security. Perfect for those looking to earn rewards through staking or providing compute power.

-
    -
  • GPU miner setup with Ollama (RTX 4060 Ti tested)
  • -
  • Systemd service configuration
  • -
  • Hardware requirements & optimization
  • -
  • Real-time job processing & earnings
  • -
  • Performance monitoring & troubleshooting
  • -
- Miner Documentation -
- - -
-
- -
-

Clients

-

Use AITBC for your AI/ML workloads with privacy and verifiable computation. Ideal for businesses and developers using AI services.

-
    -
  • CLI wrapper tool for easy job submission
  • -
  • Job status monitoring & receipt verification
  • -
  • 13+ Ollama models available (llama3.2, mistral, deepseek)
  • -
  • Transparent pricing: 0.02 AITBC/gpu_second
  • -
  • Cryptographic receipts & blockchain verification
  • -
- Client Documentation -
- - -
-
- -
-

Developers

-

Build on AITBC and contribute to the protocol. Designed for developers wanting to extend the platform or integrate with it.

-
    -
  • Development setup
  • -
  • Contribution guidelines
  • -
  • API reference
  • -
  • Bounty programs
  • -
  • Community resources
  • -
- Developer Documentation -
- - -
-
- -
-

Full Documentation

-

Complete technical documentation covering all aspects of the AITBC platform including architecture, APIs, deployment, and advanced features.

-
    -
  • Architecture overview
  • -
  • Complete API reference
  • -
  • Deployment guides
  • -
  • Security documentation
  • -
  • Advanced configurations
  • -
- View Full Documentation -
- - -
-
- -
-

Architecture & Components

-

Explore the system architecture and core components of the AITBC platform. Understand how each part works together from end-to-end flow to individual services.

-
    -
  • End-to-end system flow diagram
  • -
  • Coordinator API for job orchestration
  • -
  • Blockchain Node with PoA/PoS consensus
  • -
  • Marketplace Web for compute trading
  • -
  • Trade Exchange for BTC-to-AITBC
  • -
  • Wallet for key management & staking
  • -
  • Codebase structure & technical reference
  • -
- View Architecture -
- - -
-
- -
-

System Flow

-

Visualize the complete flow of a job submission through the CLI client, detailing each system component, message, RPC call, and port involved.

-
    -
  • End-to-end job submission flow
  • -
  • Component interaction diagrams
  • -
  • API call sequences
  • -
  • Error handling paths
  • -
  • Performance monitoring points
  • -
- View System Flow -
-
- - - - - -
-

Need Help?

-

Can't find what you're looking for? Our support team is here to help!

- -
-
-
- - - - - - - - - diff --git a/website/docs/js/theme.js b/website/docs/js/theme.js deleted file mode 100644 index a615c7a3..00000000 --- a/website/docs/js/theme.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * AITBC Documentation Theme Toggle - * Handles dark/light mode switching with localStorage persistence - */ - -(function() { - 'use strict'; - - const STORAGE_KEY = 'aitbc-docs-theme'; - - // Initialize theme on page load - function initTheme() { - const savedTheme = localStorage.getItem(STORAGE_KEY); - const themeToggle = document.getElementById('theme-toggle'); - - if (savedTheme === 'light') { - document.body.classList.add('light'); - if (themeToggle) { - themeToggle.innerHTML = ''; - } - } - - // Setup toggle button listener - if (themeToggle) { - themeToggle.addEventListener('click', toggleTheme); - } - } - - // Toggle between light and dark themes - function toggleTheme() { - const themeToggle = document.getElementById('theme-toggle'); - document.body.classList.toggle('light'); - - const isLight = document.body.classList.contains('light'); - - if (themeToggle) { - themeToggle.innerHTML = isLight - ? '' - : ''; - } - - localStorage.setItem(STORAGE_KEY, isLight ? 'light' : 'dark'); - } - - // Run on DOM ready - if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', initTheme); - } else { - initTheme(); - } - - // Expose for manual use if needed - window.toggleTheme = toggleTheme; -})(); diff --git a/website/docs/marketplace-web.html b/website/docs/marketplace-web.html deleted file mode 100644 index 952e2caf..00000000 --- a/website/docs/marketplace-web.html +++ /dev/null @@ -1,260 +0,0 @@ - - - - - - Marketplace Web - AITBC Documentation - - - - -
- -
-
- - - - - - - Back to Components - - - -
-

Marketplace Web

-

Vite/TypeScript marketplace with offer/bid functionality, stats dashboard, and mock/live data toggle. Production UI ready.

- ● Live -
- - -
- - Documentation Format: View this documentation in markdown format for easier contribution and version control. -
- - -
-

Overview

-

The Marketplace Web is the primary interface for clients to submit AI compute jobs and for miners to offer their services. It provides a real-time trading platform with comprehensive job management and analytics.

- -

Key Features

-
    -
  • Real-time job marketplace with offer/bid functionality
  • -
  • Interactive statistics dashboard
  • -
  • Mock/live data toggle for development
  • -
  • Responsive design for all devices
  • -
  • WebSocket integration for live updates
  • -
  • Wallet integration for seamless payments
  • -
-
- - -
-

Technology Stack

-
-
- Framework - Vite 4.x -
-
- Language - TypeScript 5.x -
-
- UI - TailwindCSS + Headless UI -
-
- State Management - Zustand -
-
- Charts - Chart.js -
-
- WebSocket - Native WebSocket API -
-
- Icons - Lucide React -
-
-
- - -
-

Getting Started

- -

Prerequisites

-
    -
  • Node.js 18+
  • -
  • npm or yarn
  • -
- -

Installation

-
# Clone the repository
-git clone https://github.com/oib/AITBC.git
-cd aitbc/apps/marketplace-web
-
-# Install dependencies
-npm install
-
-# Start development server
-npm run dev
-
-# Build for production
-npm run build
-
-# Preview production build
-npm run preview
- -

Environment Configuration

-
# .env.local
-VITE_API_URL=http://localhost:18000
-VITE_WS_URL=ws://localhost:18001
-VITE_NETWORK=mainnet
-VITE_MOCK_DATA=false
-
- - -
-

Features

- -

Job Marketplace

-
    -
  • Submit AI compute jobs with custom parameters
  • -
  • Browse available miner offers
  • -
  • Real-time price discovery
  • -
  • Job history and tracking
  • -
- -

Statistics Dashboard

-
    -
  • Real-time network metrics
  • -
  • Job completion rates
  • -
  • GPU utilization charts
  • -
  • Price trends analysis
  • -
- -

Wallet Integration

-
    -
  • Connect wallet via private key or keystore
  • -
  • View balance and transaction history
  • -
  • Sign transactions for job submissions
  • -
  • Receipt verification
  • -
-
- - -
-

API Integration

- -

Coordinator API

-
// Job submission
-POST /v1/jobs
-{
-  "type": "inference",
-  "prompt": "Your prompt here",
-  "model": "llama3.2:latest",
-  "max_price": "100aitbc"
-}
-
-// WebSocket for live updates
-ws://localhost:18001/ws
- -

Blockchain RPC

-
// Get transaction status
-curl -X POST http://localhost:26657 \
-  -d '{
-    "jsonrpc": "2.0",
-    "method": "tx",
-    "params": ["0x..."]
-  }'
-
- - -
-

Development

- -

Project Structure

-
marketplace-web/
-├── src/
-│   ├── components/     # Reusable UI components
-│   ├── pages/         # Page components
-│   ├── hooks/         # Custom React hooks
-│   ├── stores/        # Zustand stores
-│   ├── services/      # API services
-│   ├── types/         # TypeScript definitions
-│   └── utils/         # Utility functions
-├── public/
-├── package.json
-└── vite.config.ts
- -

Mock Data

-

Toggle mock data mode for development without a running backend:

-
// In .env.local
-VITE_MOCK_DATA=true
- -

Building for Production

-
# Build optimized bundle
-npm run build
-
-# Output in dist/ directory
-# Deploy to any static hosting service
-
- - -
-

Deployment

- -

Docker Deployment

-
# Build image
-docker build -t aitbc/marketplace-web .
-
-# Run with nginx
-docker run -d \
-  -p 80:80 \
-  -e VITE_API_URL=http://api.aitbc.bubuit.net \
-  aitbc/marketplace-web
- -

Environment Variables

-
    -
  • VITE_API_URL - Coordinator API endpoint
  • -
  • VITE_WS_URL - WebSocket endpoint
  • -
  • VITE_NETWORK - Network name (mainnet/testnet)
  • -
  • VITE_MOCK_DATA - Enable/disable mock data
  • -
-
- - -
-

Support

-

For marketplace-specific issues:

- -
-
-
- - - - - - diff --git a/website/docs/miners.html b/website/docs/miners.html deleted file mode 100644 index bdda8efb..00000000 --- a/website/docs/miners.html +++ /dev/null @@ -1,375 +0,0 @@ - - - - - - Miner Documentation - AITBC - - - - -
- - -
-
-
- For Miners -

Start Mining AITBC

-

Complete guide to becoming a successful AITBC miner and earning rewards

- -
- - -
-
-
15-25%
-
Annual ROI
-
-
-
1000 AITBC
-
Minimum Stake
-
-
-
24/7
-
Mining Rewards
-
-
-
Low
-
Hardware Requirements
-
-
- - -
-
- - System Flow: See the complete system flow diagram to understand how miners receive and process jobs in the AITBC system. -
- -

Getting Started

-

AITBC mining combines Proof of Authority and Proof of Stake, offering multiple ways to participate and earn rewards.

- -

Mining Options

-
    -
  • Authority Mining: Become a trusted authority node (invitation only)
  • -
  • Stake Mining: Stake AITBC tokens and earn rewards
  • -
  • GPU Mining: ✅ OPERATIONAL - Provide compute power for AI/ML workloads via Ollama (RTX 4060 Ti tested)
  • -
  • Hybrid Mining: Combine staking with compute provision
  • -
- -
- 🎉 Latest Achievement (February 2026): Real GPU miner successfully deployed with NVIDIA RTX 4060 Ti! Processing jobs in 11-25 seconds with verified receipt generation. Earn 0.02 AITBC per GPU second with 13+ Ollama models available. -
- -

Quick Start

-
-
1
-
-

Download & Install

-

Get the AITBC mining software for your platform

-
-# Linux/macOS -curl -O https://github.com/oib/AITBC/releases/download/v1.0.0/aitbc-miner-v1.0.0.tar.gz -tar -xzf aitbc-miner-v1.0.0.tar.gz -cd aitbc-miner - -# Windows -# Download from https://github.com/oib/AITBC/releases
-
-
- -
-
2
-
-

Configure Your Node

-

Set up your mining configuration

-
-# Create configuration -./aitbc-miner config init - -# Edit configuration -nano ~/.aitbc/miner.toml
-
-
- -
-
3
-
-

Stake Tokens

-

Lock your AITBC tokens to start earning

-
-# Stake 1000 AITBC -./aitbc-miner stake 1000 --wallet YOUR_WALLET_ADDRESS
-
-
- -
-
4
-
-

Start Mining

-

Launch your mining node

-
-# Start mining -./aitbc-miner start --mode stake
-
-
-
- - -
-

Hardware Requirements

- -
-
-

CPU

-

4+ cores (8+ recommended for GPU mining)

-
-
-

RAM

-

8GB minimum (16GB+ for GPU mining)

-
-
-

Storage

-

100GB SSD (500GB+ for full node)

-
-
-

Network

-

Stable broadband (100Mbps+)

-
-
-

GPU (Operational)

-

✅ Tested: NVIDIA RTX 4060 Ti (16GB)
- Recommended: RTX 3080+ or AMD RX 6800+
- Ollama integration included

-
-
-

Security

-

HSM recommended for large stakes

-
-
- -
- ✅ GPU Mining Live: Host GPU miner operational with Ollama integration. Process LLM inference jobs (llama3.2, mistral, deepseek, etc.) and earn 0.02 AITBC per GPU second. Systemd service configuration available for production deployment. -
-
- - -
-

Profit Calculator

-
-
- - -
-
- - -
-
-
-
- - -
-
- - -
-
-
-
Estimated Monthly Earnings
-
$416.67
-
Estimated Annual Earnings
-
$5,000.00
-
-
- - -
-

Mining Strategies

- -

1. Pure Staking

-

The simplest approach - stake your tokens and earn passive income.

-
    -
  • Pros: Low maintenance, predictable returns
  • -
  • Cons: Lower rewards than active mining
  • -
  • Best for: Long-term holders, passive investors
  • -
- -

2. GPU Mining

-

Provide compute power for AI/ML workloads and earn additional rewards.

-
    -
  • Pros: Higher rewards, supports the network
  • -
  • Cons: Higher hardware costs, more maintenance
  • -
  • Best for: Technical users with GPU hardware
  • -
- -

3. Authority Mining

-

Apply to become a trusted authority node (invitation only).

-
    -
  • Pros: Highest rewards, network influence
  • -
  • Cons: High requirements, strict vetting
  • -
  • Best for: Established organizations, experienced miners
  • -
- -

4. Hybrid Approach

-

Combine staking with GPU mining for maximum returns.

-
    -
  • Pros: Diversified income streams
  • -
  • Cons: Complex setup, higher initial cost
  • -
  • Best for: Experienced miners seeking optimization
  • -
-
- - -
-

Security Best Practices

- -
- Important: Never share your private keys or wallet passwords with anyone! -
- -

Wallet Security

-
    -
  • Use a hardware wallet for large stakes
  • -
  • Enable two-factor authentication
  • -
  • Keep your wallet software updated
  • -
  • Backup your wallet securely (offline)
  • -
  • Use a dedicated mining wallet
  • -
- -

Node Security

-
    -
  • Keep your operating system updated
  • -
  • Use a firewall to restrict access
  • -
  • Monitor for unusual activity
  • -
  • Use VPN for additional privacy
  • -
  • Regular security audits
  • -
- -

Operational Security

-
    -
  • Diversify your stake across multiple nodes
  • -
  • Use automated monitoring and alerts
  • -
  • Have backup power and internet
  • -
  • Document your recovery procedures
  • -
  • Join the community for security updates
  • -
-
- - -
-

Troubleshooting

- -

Common Issues

-
-
Node won't start?
-
- Check your configuration file syntax and ensure all required ports are open. Use ./aitbc-miner check-config to validate your setup. -
-
- -
-
Low mining rewards?
-
- Ensure your node is online 24/7, check your stake amount, and verify you're running the latest version. Network conditions also affect rewards. -
-
- -
-
Sync issues?
-
- Try resyncing with ./aitbc-miner sync --reset. Check your internet connection and disk space. -
-
- -
-
GPU not detected?
-
- Install latest GPU drivers, verify CUDA/OpenCL support, and check ./aitbc-miner gpu check. -
-
- -

Getting Help

-
    -
  • Check the logs: ./aitbc-miner logs
  • -
  • Visit our Discord community
  • -
  • Search issues on Gitea
  • -
  • Email support: andreas.fleckl@bubuit.net
  • -
-
- - -
-

Frequently Asked Questions

- -
-
How much can I earn mining AITBC?
-
- Earnings vary based on stake amount, network participation, and whether you provide GPU compute. Typical APY ranges from 15-25% for staking, with GPU mining adding additional rewards. -
-
- -
-
When do I get paid?
-
- Rewards are distributed daily and automatically credited to your wallet. You can withdraw anytime after the initial lock period. -
-
- -
-
Can I run multiple nodes?
-
- Yes, you can run multiple nodes but each requires separate stakes. This can provide redundancy and potentially higher rewards. -
-
- -
-
What happens if my node goes offline?
-
- You won't earn rewards while offline, but your stake remains safe. Extended downtime may affect your reputation score. -
-
- -
-
How do I become an authority node?
-
- Authority nodes require invitation based on community contribution, technical expertise, and stake amount. Apply through the community forum. -
-
-
-
-
- - - - - - - - diff --git a/website/docs/pool-hub.html b/website/docs/pool-hub.html deleted file mode 100644 index f5d425f1..00000000 --- a/website/docs/pool-hub.html +++ /dev/null @@ -1,259 +0,0 @@ - - - - - - Pool Hub - AITBC Documentation - - - - -
- -
-
- - - - - - - Back to Components - - - -
-

Pool Hub

-

Miner registry with scoring engine, Redis/PostgreSQL backing, and comprehensive metrics. Live matching API deployed.

- ● Live -
- - -
-

Overview

-

The AITBC Pool Hub serves as the central coordination service for miners, providing efficient job matching, reputation scoring, and performance tracking.

- -

Key Features

-
    -
  • Miner registry with comprehensive metadata
  • -
  • Dynamic scoring engine based on performance
  • -
  • Redis for fast caching and PostgreSQL for persistence
  • -
  • Real-time job matching API
  • -
  • Comprehensive metrics and monitoring
  • -
  • Load balancing and failover support
  • -
-
- - -
-

Architecture

-

The Pool Hub is designed for high availability and performance:

- -
-
-

Data Layer

-

Redis for hot data, PostgreSQL for historical records

-
-
-

Scoring Engine

-

Dynamic scoring based on success rate, latency, and availability

-
-
-

Matching API

-

RESTful API for real-time job-to-miner matching

-
-
-

Monitoring

-

Prometheus metrics and Grafana dashboards

-
-
-
- - -
-

API Reference

- -

Miner Registration

-
# Register miner
-POST /api/v1/miners/register
-{
-  "address": "0x...",
-  "endpoint": "http://miner.example.com:8080",
-  "capabilities": {
-    "models": ["llama3.2", "mistral"],
-    "gpu_memory": 16384,
-    "max_concurrent_jobs": 4
-  },
-  "stake": 10000
-}
- -

Job Matching

-
# Find suitable miners
-POST /api/v1/match
-{
-  "job_type": "inference",
-  "model": "llama3.2",
-  "requirements": {
-    "min_gpu_memory": 8192,
-    "max_latency": 5000
-  }
-}
-
-# Response
-{
-  "miners": [
-    {
-      "address": "0x...",
-      "endpoint": "http://miner1.example.com",
-      "score": 0.95,
-      "estimated_time": 2000
-    }
-  ]
-}
- -

Miner Status

-
# Update miner status
-POST /api/v1/miners/{address}/status
-{
-  "available": true,
-  "current_load": 2,
-  "gpu_utilization": 0.75,
-  "temperature": 65
-}
-
- - -
-

Scoring System

-

The scoring engine evaluates miners based on multiple factors:

- -

Scoring Factors

-
    -
  • Success Rate (40%): Job completion success percentage
  • -
  • Latency (25%): Average response time
  • -
  • Availability (20%): Uptime percentage
  • -
  • Reputation (15%): Historical performance and stake amount
  • -
- -

Score Calculation

-
score = (success_rate * 0.4) +
-        (latency_score * 0.25) +
-        (availability * 0.2) +
-        (reputation_score * 0.15)
-
- - -
-

Configuration

- -

Environment Variables

-
# Database
-REDIS_URL=redis://localhost:6379
-DATABASE_URL=postgresql://user:pass@localhost/poolhub
-
-# API
-API_HOST=0.0.0.0
-API_PORT=8000
-
-# Scoring
-SCORE_UPDATE_INTERVAL=60
-MAX_MINER_SCORE=1.0
-MIN_SUCCESS_RATE=0.8
-
-# Monitoring
-METRICS_PORT=9090
-LOG_LEVEL=info
- -

Scoring Configuration

-
# config/scoring.toml
-[scoring]
-update_interval = 60  # seconds
-decay_factor = 0.95   # daily decay
-
-[weights]
-success_rate = 0.4
-latency = 0.25
-availability = 0.2
-reputation = 0.15
-
-[thresholds]
-min_success_rate = 0.8
-max_latency = 5000
-min_availability = 0.95
-
- - -
-

Deployment

- -

Docker Compose

-
version: '3.8'
-services:
-  pool-hub:
-    image: aitbc/pool-hub:latest
-    ports:
-      - "8000:8000"
-      - "9090:9090"
-    environment:
-      - REDIS_URL=redis://redis:6379
-      - DATABASE_URL=postgresql://postgres:pass@db:5432/poolhub
-    depends_on:
-      - redis
-      - db
-
-  redis:
-    image: redis:7-alpine
-    volumes:
-      - redis_data:/data
-
-  db:
-    image: postgres:15
-    environment:
-      - POSTGRES_DB=poolhub
-      - POSTGRES_USER=postgres
-      - POSTGRES_PASSWORD=pass
-    volumes:
-      - db_data:/var/lib/postgresql/data
-
- - -
-

Monitoring

- -

Key Metrics

-
    -
  • poolhub_miners_total - Total registered miners
  • -
  • poolhub_jobs_matched_total - Total jobs matched
  • -
  • poolhub_match_duration - Match operation duration
  • -
  • poolhub_miner_score - Individual miner scores
  • -
  • poolhub_api_requests_total - API request count
  • -
- -

Health Checks

-
# Health endpoint
-GET /health
-
-# Detailed status
-GET /api/v1/status
-
-# Metrics endpoint
-GET /metrics
-
-
-
- - - - - - diff --git a/website/docs/trade-exchange.html b/website/docs/trade-exchange.html deleted file mode 100644 index d8e17419..00000000 --- a/website/docs/trade-exchange.html +++ /dev/null @@ -1,259 +0,0 @@ - - - - - - Trade Exchange - AITBC Documentation - - - - -
- - -
-
- - - - - - - Back to Components - - - -
-

Trade Exchange

-

AITBC exchange with QR payments, user management, and real-time trading capabilities

- ● Live -

- - - Launch Exchange - -
- - -
- -

Overview

-

The AITBC Trade Exchange is a crypto-only platform that enables users to exchange Bitcoin for AITBC tokens. It features a modern, responsive interface with user authentication, wallet management, and real-time trading capabilities.

- -

Key Features

-
    -
  • Bitcoin wallet integration with QR code payments
  • -
  • User management with wallet-based authentication
  • -
  • Real-time payment monitoring and confirmation
  • -
  • Individual user wallets and balance tracking
  • -
  • Transaction history and receipt management
  • -
  • Mobile-responsive design
  • -
-
- - -
-

How It Works

-

The Trade Exchange provides a simple, secure way to acquire AITBC tokens using Bitcoin.

- -
-
-

1. Connect Wallet

-

Click "Connect Wallet" to generate a unique wallet address and create your account

-
-
-

2. Select Amount

-

Enter the amount of AITBC you want to buy or Bitcoin you want to spend

-
-
-

3. Make Payment

-

Scan the QR code or send Bitcoin to the provided address

-
-
-

4. Receive Tokens

-

AITBC tokens are credited to your wallet after confirmation

-
-
-
- - -
-

User Management

-

The exchange uses a wallet-based authentication system that requires no passwords.

- -

Authentication Flow

-
    -
  • Users connect with a wallet address (auto-generated for demo)
  • -
  • System creates or retrieves user account
  • -
  • Session token issued for secure API access
  • -
  • 24-hour automatic session expiry
  • -
- -

User Features

-
    -
  • Unique username and user ID
  • -
  • Personal AITBC wallet with balance tracking
  • -
  • Complete transaction history
  • -
  • Secure logout functionality
  • -
-
- - -
-

Exchange API

-

The exchange provides RESTful APIs for user management and payment processing.

- -

User Management Endpoints

-
- POST /api/users/login -

Login or register with wallet address

-
- -
- GET /api/users/me -

Get current user profile

-
- -
- GET /api/users/{id}/balance -

Get user wallet balance

-
- -
- POST /api/users/logout -

Logout and invalidate session

-
- -

Exchange Endpoints

-
- POST /api/exchange/create-payment -

Create Bitcoin payment request

-
- -
- GET /api/exchange/payment-status/{id} -

Check payment confirmation status

-
- -
- GET /api/exchange/rates -

Get current exchange rates

-
-
- - -
-

Security Features

-

The exchange implements multiple security measures to protect user funds and data.

- -

Authentication Security

-
    -
  • SHA-256 hashed session tokens
  • -
  • 24-hour automatic session expiry
  • -
  • Server-side session validation
  • -
  • Secure token invalidation on logout
  • -
- -

Payment Security

-
    -
  • Unique payment addresses for each transaction
  • -
  • Real-time blockchain monitoring
  • -
  • Payment confirmation requirements (1 confirmation)
  • -
  • Automatic refund for expired payments
  • -
- -

Privacy

-
    -
  • No personal data collection
  • -
  • User data isolation
  • -
  • GDPR compliant design
  • -
-
- - -
-

Configuration

-

The exchange can be configured for different environments and requirements.

- -

Exchange Settings

-
# Exchange Rate
-BTC_TO_AITBC_RATE=100000
-
-# Payment Settings
-MIN_CONFIRMATIONS=1
-PAYMENT_TIMEOUT=3600  # 1 hour
-MIN_PAYMENT=0.0001  # BTC
-MAX_PAYMENT=10      # BTC
-
-# Bitcoin Network
-BITCOIN_NETWORK=testnet
-BITCOIN_RPC_URL=http://localhost:8332
-BITCOIN_RPC_USER=user
-BITCOIN_RPC_PASS=password
-
- - -
-

Getting Started

-

Start using the Trade Exchange in just a few simple steps.

- -

1. Access the Exchange

-

Visit: https://aitbc.bubuit.net/Exchange/

- -

2. Connect Your Wallet

-

Click the "Connect Wallet" button. A unique wallet address will be generated for you.

- -

3. Get Testnet Bitcoin

-

For testing, get free testnet Bitcoin from: -
testnet-faucet.mempool.co

- -

4. Make Your First Purchase

-
    -
  • Enter the amount of AITBC you want
  • -
  • Click "Create Payment Request"
  • -
  • Send Bitcoin to the provided address
  • -
  • Wait for confirmation
  • -
  • Receive your AITBC tokens!
  • -
-
- - -
-

Support & Resources

-

Find help and additional resources for using the Trade Exchange.

- -

Documentation

- - -

Troubleshooting

-
    -
  • Payment not showing? Check for 1 confirmation
  • -
  • Can't connect? Enable JavaScript and refresh
  • -
  • Balance incorrect? Wait for blockchain sync
  • -
- -

Contact

- -
-
-
- - - - - - diff --git a/website/docs/wallet-daemon.html b/website/docs/wallet-daemon.html deleted file mode 100644 index c49599d0..00000000 --- a/website/docs/wallet-daemon.html +++ /dev/null @@ -1,209 +0,0 @@ - - - - - - Wallet Daemon - AITBC Documentation - - - - -
- -
-
- - - - - - - Back to Components - - - -
-

Wallet Daemon

-

Encrypted keystore with Argon2id + XChaCha20-Poly1305, REST/JSON-RPC APIs, and receipt verification capabilities

- ● Live -
- - -
-

Overview

-

The AITBC Wallet Daemon provides secure wallet management with enterprise-grade encryption and multiple API interfaces for seamless integration.

- -

Key Features

-
    -
  • Encrypted keystore with Argon2id + XChaCha20-Poly1305
  • -
  • REST and JSON-RPC APIs
  • -
  • Receipt verification capabilities
  • -
  • Hardware wallet support
  • -
  • Multi-signature wallet support
  • -
-
- - -
-

Architecture

-

The wallet daemon is built with security as the primary focus:

- -
-
-

Encryption

-

Argon2id key derivation with XChaCha20-Poly1305 AEAD encryption

-
-
-

Key Management

-

Hierarchical deterministic (HD) wallets with BIP44 support

-
-
-

API Layer

-

REST and JSON-RPC APIs for easy integration

-
-
-

Security

-

Sandboxed execution and memory protection

-
-
-
- - -
-

API Reference

- -

REST API

-
# Create wallet
-POST /api/v1/wallet/create
-{
-  "name": "my-wallet",
-  "password": "strong-password"
-}
-
-# Unlock wallet
-POST /api/v1/wallet/unlock
-{
-  "name": "my-wallet",
-  "password": "strong-password"
-}
-
-# Get address
-GET /api/v1/wallet/address
-
-# Send transaction
-POST /api/v1/wallet/send
-{
-  "to": "0x...",
-  "amount": 1000,
-  "fee": 10
-}
- -

JSON-RPC API

-
# Get balance
-curl -X POST http://localhost:8545 \
-  -H "Content-Type: application/json" \
-  -d '{
-    "jsonrpc": "2.0",
-    "method": "get_balance",
-    "params": [],
-    "id": 1
-  }'
-
-# Sign transaction
-curl -X POST http://localhost:8545 \
-  -H "Content-Type: application/json" \
-  -d '{
-    "jsonrpc": "2.0",
-    "method": "sign_transaction",
-    "params": [tx_data],
-    "id": 1
-  }'
-
- - -
-

Configuration

-

The wallet daemon can be configured via environment variables or config file:

- -
# Configuration file: ~/.aitbc/wallet/config.toml
-
-[wallet]
-keystore_path = "~/.aitbc/wallet/keystore"
-default_network = "mainnet"
-
-[api]
-rest_host = "127.0.0.1"
-rest_port = 8545
-rpc_host = "127.0.0.1"
-rpc_port = 8546
-
-[security]
-argon2_time = 3
-argon2_memory = 67108864  # 64MB
-argon2_parallelism = 4
-
- - -
-

Security Features

-
    -
  • Memory Encryption: All sensitive data encrypted in memory
  • -
  • Secure Erasure: Memory zeroized after use
  • -
  • Access Control: API key authentication
  • -
  • Audit Logging: All operations logged securely
  • -
  • Hardware Support: Ledger and Trezor integration
  • -
-
- - -
-

Integration Examples

- -

Python Integration

-
from aitbc_wallet import WalletClient
-
-client = WalletClient("http://localhost:8545")
-
-# Create wallet
-wallet = client.create_wallet("my-wallet", "password")
-print(f"Address: {wallet.address}")
-
-# Send transaction
-tx = client.send_transaction(
-    to="0x123...",
-    amount=1000,
-    password="${PASSWORD}"
-)
-print(f"Transaction hash: {tx.hash}")
- -

JavaScript Integration

-
const { WalletClient } = require('@aitbc/wallet');
-
-const client = new WalletClient('http://localhost:8545');
-
-// Create wallet
-const wallet = await client.createWallet('my-wallet', 'password');
-console.log('Address:', wallet.address);
-
-// Get balance
-const balance = await client.getBalance();
-console.log('Balance:', balance);
-
-
-
- - - - - - diff --git a/website/extensions/aitbc-wallet-firefox.zip b/website/extensions/aitbc-wallet-firefox.zip deleted file mode 100644 index 69154c244f62036bf433cdebce3fc71b7814fea8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6968 zcmaJ`1yq!4w;sBY?vak6hwkn!kq+q?7#cxFy1PUgX+%U?8blBf7($Se?v@6Di|7B> zJ>GNl&aC~dZ>?GLJnLP1KkqIrRU~9gz|YUIL5}fXFaLcI1E>I&4xUe}ID9Ofoozfh zY#rQfY+Zf19_e8KkhXMm9H#Hh%NGlPfV_zW0Q~jPx`!jW2S5kx+{5J)`KTl!001TT zKhymQ4r1xzU~A*y$?53f>hc%%Pu$;Nhv{^=baP|39TRKE6S8SBg*HJ%_u}h5@I7*H zoT=t3CwKv5x((1kbdn}CshByqoQ55Zgo3|e7J4tf6AC;YplG+ezjd9K$(rrNG%Go{)Evg~4>kx0!6`nQhgGZ^n%*4cImhT7Ms(Fo3Acx3j+Lql!Ei{1#Q0Y1;dxl+Y zc?+sj4X0nUb$A=L#j`}I!Xt&)=38C>U4$Gk zU>}@!rA>#(mAx7Y3DAB9-8<9w@ougi-3!pjN|k|q89pna2&Vw9pi|GQ3i-T!))Vij#9>;Gc!wEciT2VKLTN zv1MC-fWt9A=+W1*F)S`3vmw-$hiUc>yI&8kQ-DFbnT*M^ge6B3&8;lF0|XXKW!MNO zmC@)dgQ%E-NmIzfvi~A`SU_mq&Wufp zj1wX28CXtHI>P=LiK|o+l5Mn8342T(3m%5mUT&h&d@?6aVy$~4$(u4L8MorZwk(g< z>(X)5xPNeV!<)7xd*phxH*i;y=cSpKNqIiCdHCLcM8O8+Z@_67-P)oUx^@V#FNb3~ zDi8Uh9#nURQPE@;@B=(VND?j;qipb^vvt#kwVb~+2KOZAe_CS{fwVbgW6`M!Niouh zMaV!GO@%*7j~NSdz1Q3CT_Iis+RHww(x434!JU6ca{;?{LvzV4fyb-tBk!X)F6zEg z*q5eO9O6Sf6SV?1+Sh-k`DaXv7g;_ghoMq5&sq>EH$w_ zbMc0LTFY~3ms$aG5#v83?M>c1%|cA-N3$mO@hPGyNk?2ZP9NduHLUZEA2-ZOoe}b$n;tWE1fSmH zL`RWYvBM()eO-VZ55q5o(DXUTB;v?MI82w(OQU=6%)6)<>;Vgy_wJvgQqN51y+>r2h zG@#B$bAwwe$&V4^s$5365`lJH-`@E+TVHMw0jorg*D#!KEZI8v!_hqam=RiOs5xes zNP!rH$X798vhP%Mku;*BvA6raTEXz%)x*|V4ITsKOh>|p+#%}OlSt-Cn|^bK=Y=tUSHnJ z>Lzeb`W;De{Qw<3Mg}B|f<#k+g8?aDiM233k%%-S3{-d9w$%fMjaJX832)ZreUiJF?3Qjyq}1K! zPhgfWeH1IGxEh6L=606`n4o(XWM40##TPT&-x(QX#=+mDJ9GWt?4i+Ps1%hf?kiP6 z>Pg|>Ecv)Uu2r@GPbka2t%R8=D#$F_yz&VWA|BLn3-FrK(r&##+Nfsfq4)x{*;b^d zc>a9s-~rs=d|62QhXTex$&t^4^<2_vbp$5@696JCY<{B|v>`c`Qv428Nkcle`2JEOHJ)VYf3 ziJ~P2@I1=6vNs3wQO%>b2!CJN`}ddjaGMMa9}xhULwD;<;d_jS(XRm?weh| zK(CgmvvSMKxp(mrUWt*g9xl6J4YYa;m8o`Zh$z<}w=l%m0b0C(uz+D(tWSDWp*J^b zp53{D0w=?@EHO(Gg;Iu^(rE14(WH&T-dH%DXjP>_KK9b^aWyjJxrcnVOt<2XDFj3& zJ85FpPEcqNwS)a)%0X!H5pZv+ z6jm7@lBZk57w;EJH8ls{j%5r-|4@g)GCyxjf4`)?zRBQ7*KXWxJ~4)Pe@1tW>*`=M z%G2f-&(r0tC>oP7KIi3|D`yv;Xn!!ZeTP6^hr+mU;bk`N z7nfaA2yzQqQ)bgGniYaS9{e3?2ltWY9(2WLdtU~=cmM#<{3+5LTpVqzJZ=8BI9R?9 zv!C{lP}_T~s!0jPYd>aN?{TSMp>abh*2xFSzv5sl7t$l z^Ocn`enfTXFm)@I;M!|7(uH6WNliu`E3Ft^iuxIeH<49%4eWR&yJ?E8IbzY9jEr+q z#o77ESz^C<%S2%9b{n#Lf+X zxy4CG^&yCM(Bjn$Cv4d;BPLzv@mDtaDD#a@Evy z8+C(5Yuq(V zyjR_{h0=9*jmd|F^(+%9sq3cZ>@6HZmQX~2dMXvAyVV~UUF~^WT#q!B{JKLKEnd03 zuGsD5bMRI1T#1%!nWK$!UpAz=6W&pOFT84%O2`^OFN@*hiB16`w%W7g&!nOZr^Hkk z8h)NcWA-ehm168EV8t0DQ${u7cr&qgW~`>ZelAzn#!j1oS?^_}W3-!mk9cOT@r;qj z@oY~4KhR2`@O4-fb(QEP7>o2#8Yr+UIx0T6(w8*QHDbZXeJP$%P0m2@WTQrePQ4!VEY&Z?VaE9e3rrcuJfz5~Z=sj70+75gU_o zO%|3}O{&D3a>hO}=e2UX4+ObcPDn7W=n$<-jg-rxqDak~eL?01kGhgNnrKlgnWD*xe8&2h`>Y1h%! zVp-hX@uDwALgdaXjLSjN9<#XqS0kQnJAQfn^561BI<^Dsy1uKd7+xC_-{rC)GtC*+ zn5HI%C#>5X@A$1{dT;BLAIEKYnS!T4yrZ(cuj!etF&!P>?v=#8v>8kvU-(;K6VP*pSiP6-Py2^_-{@=qtnFb3Zx{K9B7<0xcAHiC z`=ruO3%OFJcb}Jxj^fUnp4>$f^?$hC2ynh^?zk(y8Ow1wSEP z$1IJ-^uXsz2MuwJj!eHcCpl6j5|8kSej$i2?M5V?hf@%_s>4_Y$|z7Ad~Uu_#SYSY zN?xM&m`XOEywvPrMy*L`p#C;8eq?0DQZT{m>?kOGTvG9f+z9x^`)sDOkCCmxHLcvb z>BCv>XTH`4x?4%`%;Ml(SydOD%ejl$=b@3B^#bg(5y%=3Kaa;48SQTC7buk7IZ zC-cB1(i36l}A! zdTj`U1EG-Bx?|JXw%d*p@HWOb@`UKV9rD6lkD6sulGi)?Rc59wuLEqjcJ?VWr%CYR z>)UbWh)JmqPTEJ!WV^2Rhd#KTzjn$vc*DAUDhcsG`Oy?2&Po1$i~q^U)Kxs5#YDd7 z)DMCM-3P@x2?$R>*mLbJ#?>%39KBa~T33AHNMrmwXzpZ{^sA*$Ide49Z}ggbX;GG9 z#lE2;Q@klKbtkR02w2d_Z>*D^-`$>ph=g&~ZL$)m*PPN`Q@@%ptU zo_MOgsH@WiF>}xCE#)2J-*P{?m-|lFMJF;U0PvXr0090eUH?b!|1AsG?}h%;{vq~{ z2FCYdCxV^7wFrEb4A#_Wc|+!G9g>BbHOiJ*@)1tV%`uv8lsTcqTAp;(ad610;@xV& zbsEBvv_S>ifNdU;wJmw+(!Y$U(6|4Hk~y>>F0M$;T`WiY{SiJB+c4@ChifQ}+R*oG zLA3(j9txFGTdY}rj2LQ3b+nNC|1LI33F>PE5i4XD%w+dEb)%w;WZ@_cLbXjyK75E# z>9&+B>aU&R8WGm@!?8}JBd29=WLJD0zJ>`elJyjoI_wf`(uqV&L-~O{tQ?_RJ2e4i zeV@5=K7WX-#?~dM#L9V?iQOEr8|7uUo~;~)oP_g5pc?Nx0dmr3UQhPs!nG~YvePCANsF?6_2RUhv74B9T+hVeQojL z*43px?-CojpDY-e1&-S;zn)0?wewIsKic9bCS(WFx5A0Nuy|o)Xf{#YIF5jBoIEUx>^13X_+RRQiZ!GGd;Ya z6(4w~jA(&AZ>#+2^0H)|j*q}NgFYQLp%>mt&5yR6k1EX{*czxs?61Tm;o&uwD<=`L zTtU%AXOs3-q5U>bnyBbKnIxC;tvvPqX)h7BfpfvJjA&}x%4fO@v%HOfwhDu!C!S}N z-G+f4-s=VO8;-6sVEV5Zfa)hwZI;Q zbrq>UMiZ9PY!qCH!xGe#;KfR5lX!+mm;WHwARNi?4ch~na2&OI%!cr))jx6@(9cezV;ipF6t zcxn;HjVI7Wq+@i-jWl|#K7F^z<;b$pEsw?LKiiJY>0N12$H!?HRYDro^)#kZ!KzuZ zU~2|8=!@|6d7_!p9!`3Dcs>H3?x=AUNs6D5(>K&F`?&`=#Xn1MkhOOFN)=U)#S{B- zzt!6(G~GB5^^N?UjIdYz$!LnD{>rkBCpb_8Zp9VRDPMb>t*n^mc8Y7YYy&@!kg{)t;oih%lo||GIS~*BCJ>y+?iS|` z@`uw34f*c2?~kz*Gl~HV@-##4b_3>qFfY0wHt^gajTUC(#~7Lp1`SdpXq$I&*>QCZ zTqUEUK4`p}aEn)iFm&IxGuEJ9Cl&P0t#=d-3CN|jav!TLOEI{C;cahL1;L%Kx>Mi! zhv+s9Y{rn-X^{(TJy8HvXKE#-jmdu<-%{iS^*#^((JsXI;pL!N;_V@AbBp_yW~E27 zB-?v@3&f#f+G|-2vSQp9nfsB14>%(f8n0yxEf?qeo~$Qfs8lhGwk_52OYKCiy71jx z?L0Br5&Oa!prHiOfm*GgWAdTCoA}{ojX0){wFJ-V@VQ0NQbj;~i1eo|1KEG~4S0YX z>7TEE*g2s5XXo&b^zt9*KW!ZT1C4MGS{J1GC+L6dAMSa6vwQfJ=ik%rUwK6D$0@%( z!aru;_dLIud;iMw?*YxPJcnq1;Q4i2b5HV{QO&O;|L)CyB{8~p+HVi@e>(Mhmfv*g zzq0(hgZPz&0{0IrzxEUNB){n;ekJ*L-SR65#(gF8+oSwl#oSZ;rh?H@MY%78006Z6 MZ~MJ-t^Y#(A8yhm$p8QV diff --git a/website/extensions/aitbc-wallet.zip b/website/extensions/aitbc-wallet.zip deleted file mode 100644 index ec7150b2aa895358f3391f0c59068cf622a8dc95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5182 zcmZ{obyQUA-^E85T96uP=|+a`knXM_C8c8km5@%6lpYWmV5B6Z1O_BTLPS!KP&$V$ z1r*-#-utfWMSo}3bJqFieCDjRzx$m1Y+VgZAU@#dQ4e`${@2AnCqe)%z{c6v*6#L0 z8#gxxU$BuO9stuvU*Fjpz3%%F0ImVoF#&+TPP%9eIr>IiKsg#CZ(ZqQdJO>B#sC1Q zuVUP7Je==2`1ta=_;`B!#r(fQ9WY%=?Nk1N_pS#jouv(F z?`?t7S1rfgY_K5&Mr%;1K*Q-ON(a8e6I`PTYT{qbnt>Uy+xpCL0q!J$=Ea<3ko{un zayjclz!`;9U|GK@9Qva!6?L<*7?BFYf_y=K483iMO51rW%H4Z|EG$m1p zpEr&kJh6jhGf?_+ekQ`Zb7?NI>#!k{G_EXZ=u~3ENbs?h`>pwptL(YpTTl}`;BN1h z#5u;lVpX8Uvd>_+Gk_M00SEw4ToudC)5F)ngT$mzPo{z&JrJa>sOQ3 zwq&5uMq6o&K319jLmOuj75lBpp5$rM8AgWnkU5iHJjP1!Mc@0J{bhfFuqb1qbj*PS z9y+&%uv2fJwonyg@^!%6MqRpD!lFB(smLg|V-43yldZ-O+(*|$3-`c1M6#-`)XQ>D z5lN@HI!LBa;SN?v_dlOy@W}%C&A!#cjD5^X#874$ zmxj|9#fa~ZUIf->EY{Q@o_zB)+wFY0Hm;9nS)v)cmB2zR0~5nPa{3-bFU540$<%3X z^a!v-%ej^x*CJ5h3L=+CoRv4=Xo#H0ZNFC+s@73Z5#O@e;Rp#A&uB>^U0B43RuL=* zodyR4dif<2`|93Vj(X-(lb|!QW?eWYT008CH z*>Lu7aj^4su>b$za6k{n&vj)uwoNp2X!wa=A9AmDdz5o9Krs>e1)NHSw^_@?3_$`& zGB4!ISBQ&Pptsl=6FzsD3z<`Q4w zcR5p7x4f=1WZm-=NO)Am+tKGHvxC^M5`)F|d2x2#AaT9X^$z>nE2NTd_ zi4y5(YJTEDTadHM%OYicME0%p(~xit=Mo-Lqoy1BnR_*{v#y8|e^3#R&n29FrK{F5 zxT-W=J~?4Rp`^(oe)b(dpESjYu{(yN7h*Zf^}0fo8JmIISfN7!*5_BQNG@&i3s`{& z1wa2mqUsi|IDt7GGmbJ8O5dp6n(zfEE^vp0qV|O-%WMIke{vh0Ag`@Bs#rfKsZfzAW$yT5rneHTW>Cy2yEPOJ+aeIeZxszH>7EF1)5uhw2RzH7ns}Le=he)y6O~2K zh0r=qP5TXDu_QsS{(iRG50;^NVi^Wo=2RcV4Q-NX=<6qEovfWB7O*7g4Asj^wrbw6 zdO8UrJ@<7~1G*wvtqY+Q&VK5?OL4NuS;hqKMN`^KagQR5dk{cdOUL)pkJ-KIkw6>vPHqXGpQICb) zFgw;I4yx2G4a+m1HuE{0>4po_*@+ZYL{-sONuKf(P#C3ihIYn1P7HtHM-l27GxyMY zA(2&65hD6yT+9FYnw3XOkqE>Buh{yz=F68d(Mobu&&ueUK6n6&vW9sC5f)?hd@oj| zQxn`UY0TxPt&^Dcx!Kfea|o~aTkmlvMVg`fbB6Lr+Q%|GTPM_K3 zQRNTBE;~r^d525vv{RW!zUXKP z@p}}h^v0<65V?HZxqmians9kI?}wKZiz>uB9iZs8O6V^f@@+!})R@{Z}}-YwKLGZMG*Yqo$lr7b>EBE$=BWOuXnl=+Oj{_728%C>v_(I z5C`v8&kK>qhH<29wP*ikE3(sc}&vo-J-6vM?c)|e}juz$|~%=P

D!ZL=zW(q`1{m6XT+)r{_ z9-h0|x2RkO(@mGylyQ>QLzF-6Ook!4oZl(t6`b~^so8X0&y3$C^DUuV%~Z96D`MSBdjW>ZLv9aX~;iMJ0kG+@^QV>Im zL;RV|xojtIV_U;(Tlow!KIC|x_}T9oY@`gs5aC-28XknFv)^VyB4c$LM0jRmfZDg- zk3BIn6|xMV=^yJ~LJWnBf3xpGu7p2K>;*&|prQgfvEEo#4_@k<2+yac&Bv_c%(!)iJ z8LG@f7UiuTyFFn{jYq0KY!EkUJ)?QrY?^7*JSMV6@9 zLLi2E;2b%=Qjh)0G85J zrdprbSieNYJQqt+zL%rh<3JW3>gB#%e`q<=cG3Qve-rNuRZ?6pimE8jr*_fuW(8`e z%E}U15##_y?NIAX-6TnDcuhD9qM+S9dOc#L(0R5q_{Q^Vg=^MsCD-Dyth*1^_ofJG zUaIB|VcVg}vqWO+@dC-o@1%1EHxQ_#Yqp%%XJ31m*93DD8Ws}ko(V}~jtUFlcvHS$ zUM}(HeWso9!?2}?5o;k{>I*iIx)N^bO;KkZG^btgs$TB%*5`)a~#oq-^klVgOd9JCUTj@@8rJ| z3R|`hk{=^En!ee9~p;=P~_om!N1Q3^Ulc zDpy&`S^MrDm->TNYw&Tz?UXgz;I-iOeag0l`v%O}Ps)v*-eSQ9=cJ`o==l(ej0Z*} zY}_BP&u)80GH4DSNAb`+5nTd*#=M|4iMf3{(aIu1~hv=1D!wv|+|~x?G?Y*S6(JsK!#KdpB2Fda(Q0xQZ|ZpEOp?pV;s`AP}grYlvW+jP}C}Afo=sZ^Q-LB z;(i#OhPLB9aqewPl(w%adH6E9vCDSO%qn#3-a?)*`vpAV!uS(Qz^&s!3Aqxz9!exR zS&BH z^vx=NEvT&=l49$7Lepg$>hoX~uC(R?YKv@QqKhZg`Bb|LN{V>&d3(teI=3a3!FsK) zt(J9NV7v7JS&0dfnP3aK2YI)yBkO)WX^`4ekfy)*PHn$W%@989>q&R-3egH=h1E|R zmscX8J1)DrWXLh_8 zTu@g9b*$^;8X|*@qB@JUOmM^%bzX@sB@l?}$Osaow#hugU@Ewg2Z_cst>nJJ5KXAr zfZy0`=bl5N@4z}j=;^d@Jf5Ip>^cYs-Xo>qR(|WX-<;Cwe9F3&f7%wgA+w67QHBIEQy|FpTHsR5F zirLaqHSW1V7Zm8Qp~~!z(;dj_As5+SQ;VYr?mmo4ol>P+h;E5q#2|-tOncq-vNRTt zoQDxKWw|kd(;yk!?!zz(5e+3ZV?$S_`)cPtCre9r^E#w;k(+eyhbVZ~qKJOPXO%z( zt6WLRLX$|36t)m~1H#daVuOBLuXjc{5Uf&k@O+(!%dMc<@9gs)7>xoyFh`1VNuHQm z4ulQRU(>tW33dc`zB_x0i+$tO**G*&)19U3;x%h6_IV1tXLhx{Xi!8ky_N4!bMX!f zlz+Iba#@tWqp&NjIxxbZ>D~I1n~u6vA{(~KoHa1rl=M-hPh%S@f}A}e(cfQ-3BAc4 zuu8tzV{AcsZ|J=6X_4h_Cb7mCL@=H!Xj3AHGGRNhWH)$YlwY08o7&8O?zLS_!Bekd z8EIRn6TX9rUG@ z#x2bM)d5ld(*_X(e#rg2ywV6^{oM#%$&P;`|5qRMHxk`A0P4e3t|G6rLumdVnxS9$ zzgHN)@{iDe^Pfllwa`Gr|4?T93jci%{41Oo-I)9b{+}H&n*N8~@UQgWllrgpKAbD` zUvoPe{)f!|EByC-@GHC;y)pRDqyL*0(CD9O;WtUK&_M$Lz()Vr(6t^0I&uI2{|9SI B=e+;` diff --git a/website/font-awesome-local.css b/website/font-awesome-local.css deleted file mode 100644 index e47df162..00000000 --- a/website/font-awesome-local.css +++ /dev/null @@ -1,84 +0,0 @@ -/*! - * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */ -@font-face { - font-family: 'FontAwesome'; - src: url('/assets/fonts-font-awesome/fonts/fontawesome-webfont.eot?v=4.7.0'); - src: url('/assets/fonts-font-awesome/fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), - url('/assets/fonts-font-awesome/fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), - url('/assets/fonts-font-awesome/fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), - url('/assets/fonts-font-awesome/fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), - url('/assets/fonts-font-awesome/fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg'); - font-weight: normal; - font-style: normal; - font-display: block; /* Ensure font displays properly */ -} - -.fa { - display: inline-block; - font: normal normal normal 14px/1 FontAwesome; - font-size: inherit; - text-rendering: auto; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -/* Icons */ -.fa-moon:before { content: "\f186"; } -.fa-sun:before { content: "\f185"; } -.fa-wallet:before { content: "\f0ed"; } -.fa-user:before { content: "\f007"; } -.fa-log-out:before { content: "\f08b"; } -.fa-trending-up:before { content: "\f201"; } -.fa-arrow-down-left:before { content: "\f148"; } -.fa-arrow-up-down:before { content: "\f07e"; } -.fa-book-open:before { content: "\f518"; } -.fa-refresh-cw:before { content: "\f021"; } -.fa-rocket:before { content: "\f135"; } -.fa-server:before { content: "\f233"; } -.fa-link:before { content: "\f0c1"; } -.fa-shield-alt:before { content: "\f3ed"; } -.fa-cogs:before { content: "\f085"; } -.fa-database:before { content: "\f1c0"; } -.fa-cloud:before { content: "\f0c2"; } -.fa-lock:before { content: "\f023"; } -.fa-code:before { content: "\f121"; } -.fa-microchip:before { content: "\f2db"; } -.fa-network-wired:before { content: "\f6ff"; } -.fa-check-circle:before { content: "\f058"; } -.fa-cube:before { content: "\f1b2"; } -.fa-exchange-alt:before { content: "\f362"; } -.fa-chart-line:before { content: "\f201"; } -.fa-users:before { content: "\f0c0"; } -.fa-file-alt:before { content: "\f15c"; } -.fa-graduation-cap:before { content: "\f19d"; } -.fa-lightbulb:before { content: "\f0eb"; } -.fa-question-circle:before { content: "\f059"; } -.fa-envelope:before { content: "\f0e0"; } -.fa-github:before { content: "\f09b"; } -.fa-twitter:before { content: "\f099"; } -.fa-telegram:before { content: "\f2c6"; } - -/* Size variations */ -.fa-lg { - font-size: 1.33333333em; - line-height: .75em; - vertical-align: -15%; -} -.fa-2x { font-size: 2em; } -.fa-3x { font-size: 3em; } -.fa-4x { font-size: 4em; } -.fa-5x { font-size: 5em; } - -/* Fixed width */ -.fa-fw { - width: 1.28571429em; - text-align: center; -} - -/* Spacing */ -.fa-pull-left { float: left; } -.fa-pull-right { float: right; } -.fa.fa-pull-left { margin-right: .3em; } -.fa.fa-pull-right { margin-left: .3em; } diff --git a/website/index.html b/website/index.html index 3a2469ef..ea4346ce 100644 --- a/website/index.html +++ b/website/index.html @@ -1,373 +1,293 @@ - + - AITBC - Production-Ready AI Blockchain Platform - - - - - - - - - - - - - - - + AITBC Network - Agent Discovery Interface + + + + + + + + - - - - - - - - - - - - -

+
+
+

AITBC Network Agent API

+

Autonomous agent discovery interface for the AI-powered blockchain network

+
- -
-
-

Production-Ready AI Blockchain Platform

-

7 Live Components • 30+ GPU Services • Stage 11 Complete

- Explore Features -
-
- - -
-
-

Platform Components

-
-
-
- -
-

Blockchain Node

-

PoA/PoS consensus with REST/WebSocket RPC, real-time gossip layer, and comprehensive observability. Production-ready with devnet tooling.

- View Docs -
-
-
- -
-

Coordinator API

-

FastAPI service for job submission, miner registration, and receipt management. SQLite persistence with comprehensive endpoints.

- View Docs -
-
-
- -
-

Marketplace Web

-

Vite/TypeScript marketplace with offer/bid functionality, stats dashboard, and mock/live data toggle. Production UI ready.

- View Docs -
-
-
- -
-

Explorer Web

-

Full-featured blockchain explorer with blocks, transactions, addresses, and receipts tracking. Responsive design with live data.

- View Docs -
-
-
- -
-

Wallet Daemon

-

Encrypted keystore with Argon2id + XChaCha20-Poly1305, REST/JSON-RPC APIs, and receipt verification capabilities.

- View Docs -
-
-
- -
-

Trade Exchange

-

Bitcoin-to-AITBC exchange with QR payments, user management, and real-time trading. Buy tokens with BTC instantly.

- View Docs -
-
-
- -
-

Pool Hub

-

Miner registry with scoring engine, Redis/PostgreSQL backing, and comprehensive metrics. Live matching API deployed.

- View Docs -
-
-
-
- - -
-
-

Architecture

-
-
- -

Coordinator API

-

Central coordination layer for marketplace operations

-
-
- -

Blockchain Node

-

Hybrid PoA/PoS consensus with fast finality

-
-
- -

GPU Providers

-

Decentralized compute network for AI workloads

-
-
- -

Wallet Daemon

-

Secure wallet management and transaction signing

-
-
-
-
- - -
-
-
-
-

100,000+

-

Transactions Per Second

-
-
-

<1s

-

Finality Time

-
-
-

64

-

Shard Chains

-
-
-

95%

-

Energy Reduction vs PoW

-
-
-
-
- - -
-
-

Documentation

-

Choose your reader level for tailored documentation

+
+

What is AITBC?

+

AITBC is an AI-powered blockchain platform with a multi-island architecture. It provides a Proof-of-Authority consensus mechanism designed for autonomous agents and distributed systems.

-
-
-
- -
-

Miners

-

Learn mining, staking, and earning rewards

- Miner Docs -
- -
-
- -
-

Clients

-

Use AITBC for AI/ML workloads

- Client Docs -
- -
-
- -
-

Developers

-

Build on AITBC and contribute

- Developer Docs -
-
- - -
-
- - -
-
-

Platform Achievements

-
-
-

7

-

Live Components

-
-
-

30+

-

GPU Services

-
-
-

Stages 1-11

-

Complete

-
-
-

100%

-

Open Source

-
-
-
-
- - -
-
-

Development Roadmap

-
-
-
-
-

Stages 1-11 Complete

-

Core infrastructure, marketplace, explorer, wallet, trade exchange, and 30+ GPU services deployed

-
-
-
-
🔄
-
-

Stage 8 - Current Focus

-

Research consortium, sharding prototypes, ZK applications, and global expansion

-
-
-
-
9
-
-

Stage 9 - Moonshot Initiatives

-

Decentralized infrastructure, AI automation, and global standards

-
-
-
-
10
-
-

Stage 10 - Stewardship

-

Open governance, educational programs, and long-term preservation

-
-
-
-
-
- - - - - - - - - +
+

Network Discovery

+

Access the complete network information through machine-readable JSON endpoints:

+ +
+ GET /agent/discovery.json +
+

Returns all islands, chains, endpoints, and network topology

+ +

Available Endpoints

+
+
+ GET /agent/islands.json +
+
+ GET /agent/chains.json +
+
+ GET /agent/openapi.json +
+
+ GET /agent/health +
+
+
+ +
+

Join the Network

+

Configure your node to join an AITBC island:

+ +
+
+

Mainnet

+
+ GET /agent/join/ait-mainnet.json +
+

Production chain with real value

+
+
+

Testnet

+
+ GET /agent/join/ait-testnet.json +
+

Development and testing environment

+
+
+
+ +
+

Quick Start

+
+
# 1. Discover the network
+curl -s https://aitbc.bubuit.net/agent/discovery.json | jq .
+
+# 2. Get island information
+curl -s https://aitbc.bubuit.net/agent/islands.json | jq '.islands[]'
+
+# 3. Join a chain (get configuration)
+curl -s https://aitbc.bubuit.net/agent/join/ait-mainnet.json | jq '.how_to_join'
+
+
+ +
+

API Specification

+

OpenAPI 3.0 specification available at:

+
+ GET /agent/openapi.json +
+

Machine-readable API documentation for client generation

+
+ +
+

Node ID: aitbc | Island: ait-mainnet-island | Role: Hub

+

This page is optimized for autonomous agents and web crawlers. All content is also available in machine-readable JSON format at the endpoints listed above.

+
+
diff --git a/website/wallet/index.html b/website/wallet/index.html deleted file mode 100644 index 859bc278..00000000 --- a/website/wallet/index.html +++ /dev/null @@ -1,358 +0,0 @@ - - - - - - AITBC Browser Wallet - Secure Crypto Wallet - - - - - -
- - -
-

AITBC Browser Wallet

-

- The most secure way to store, send, and receive AITBC tokens. - Connect to the AITBC Trade Exchange with just one click. -

- -
-
- - -
-
- -

Why Choose AITBC Wallet?

-
-
- -

Bank-Grade Security

-

- Your private keys never leave your device. - Encrypted locally with military-grade security. -

-
-
- -

Seamless dApp Integration

-

- Connect to any AITBC-powered dApp with a single click. - No more copying and pasting addresses. -

-
-
- -

Lightning Fast

-

- Built for performance. - Instant transactions and real-time balance updates. -

-
-
-
-
- - -
-
-

Install for Chrome / Edge / Brave

- -
-
-

- - Chrome Installation Steps -

- -
-
-
1
-
-

Download the Extension

-

- Download the AITBC Wallet extension files to your computer. -

- - - Download Chrome Extension - -
-
- -
-
2
-
-

Open Chrome Extensions

-

- Open Chrome and navigate to the extensions page: -

-
chrome://extensions/
-
-
- -
-
3
-
-

Enable Developer Mode

-

- Toggle the "Developer mode" switch in the top right corner. -

-
-
- -
-
4
-
-

Load Extension

-

- Click "Load unpacked" and select the aitbc-wallet folder. -

-
-
- -
-
5
-
-

Start Using!

-

- Click the AITBC Wallet icon in your toolbar to create or import an account. -

-
-
-
-
-
-
-
- - -
-
-

Install for Firefox

- -
-
-

- - Firefox Installation Steps -

- -
-
-
1
-
-

Visit Install Page

-

- Click the button below to go to the Firefox installation page. -

- - - Install Firefox Extension - -
-
- -
-
2
-
-

Click "Add to Firefox"

-

- On the install page, click the "Add to Firefox" button to install the extension. -

-
-
- -
-
3
-
-

Start Using!

-

- The AITBC Wallet will appear in your toolbar with an orange icon. Click to create your first account! -

-
-
-
-
-
-
-
- - -
-
-

Using Your AITBC Wallet

- -
-
-

- - Create a New Wallet -

-
    -
  1. 1. Click the AITBC Wallet icon
  2. -
  3. 2. Select "Create New Account"
  4. -
  5. 3. Securely save your private key
  6. -
  7. 4. Your wallet is ready!
  8. -
-
- -
-

- - Import Existing Wallet -

-
    -
  1. 1. Click the AITBC Wallet icon
  2. -
  3. 2. Select "Import Private Key"
  4. -
  5. 3. Enter your private key
  6. -
  7. 4. Access your restored wallet
  8. -
-
- -
-

- - Connect to Exchange -

-
    -
  1. 1. Visit AITBC Exchange
  2. -
  3. 2. Toggle to "Real Mode"
  4. -
  5. 3. Click "Connect AITBC Wallet"
  6. -
  7. 4. Approve the connection
  8. -
-
- -
-

- - Send & Receive Tokens -

-
    -
  1. 1. Click "Send" to transfer tokens
  2. -
  3. 2. Click "Receive" to get your address
  4. -
  5. 3. All transactions require confirmation
  6. -
  7. 4. View history in the wallet
  8. -
-
-
-
-
- - -
-
-

Security Best Practices

- -
-
-

- - Important Security Reminders -

- -
    -
  • - - Never share your private key - Anyone with your private key has full control of your funds -
  • -
  • - - Backup your private key - Write it down and store it in a secure, offline location -
  • -
  • - - Verify URLs - Always ensure you're on aitbc.bubuit.net before connecting -
  • -
  • - - Use a password manager - Protect your browser with a strong, unique password -
  • -
  • - - Keep updated - Regularly update your browser and the wallet extension -
  • -
-
-
-
-
- - -
-
-
-
-

AITBC Wallet

-

- The secure browser wallet for AITBC tokens -

-
-
-

Quick Links

- -
-
-

Support

-

- Need help? Check our documentation or create an issue on GitHub. -

-
-
-
-

© 2026 AITBC. All rights reserved.

-
-
-
- - - - -