chore: update file permissions to executable across repository

- Change file mode from 644 to 755 for all project files
- Add chain_id parameter to get_balance RPC endpoint with default "ait-devnet"
- Rename Miner.extra_meta_data to extra_metadata for consistency
This commit is contained in:
oib
2026-03-06 22:17:54 +01:00
parent bb5363bebc
commit 15427c96c0
1794 changed files with 43849 additions and 530 deletions

0
.editorconfig Normal file → Executable file
View File

0
.env.example Normal file → Executable file
View File

0
.github/dependabot.yml vendored Normal file → Executable file
View File

505
.github/workflows/ci-cd.yml vendored Normal file
View File

@@ -0,0 +1,505 @@
name: AITBC CI/CD Pipeline
on:
push:
branches: [ main, develop, feature/*, hotfix/* ]
pull_request:
branches: [ main, develop ]
release:
types: [ published ]
env:
PYTHON_VERSION: "3.13"
NODE_VERSION: "18"
jobs:
# Code Quality and Testing
lint-and-test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11", "3.12", "3.13"]
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Cache pip dependencies
uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('**/requirements*.txt') }}
restore-keys: |
${{ runner.os }}-pip-${{ matrix.python-version }}-
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
pip install -r requirements-test.txt
- name: Lint Python code
run: |
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
black --check .
isort --check-only --diff .
mypy . --ignore-missing-imports
- name: Run unit tests
run: |
pytest tests/unit/ -v --cov=aitbc_cli --cov-report=xml --cov-report=html --cov-report=term
- name: Run integration tests
run: |
pytest tests/integration/ -v --tb=short
- name: Run performance tests
run: |
pytest tests/performance/ -v --tb=short
- name: Run security tests
run: |
pytest tests/security/ -v --tb=short
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: ./coverage.xml
flags: unittests
name: codecov-umbrella
# CLI Testing
test-cli:
runs-on: ubuntu-latest
needs: lint-and-test
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.13"
- name: Install CLI
run: |
cd cli
python -m pip install -e .
- name: Test CLI commands
run: |
cd cli
python -m aitbc_cli.main --help
python -m aitbc_cli.main wallet --help
python -m aitbc_cli.main blockchain --help
python -m aitbc_cli.main multisig --help
python -m aitbc_cli.main genesis-protection --help
python -m aitbc_cli.main transfer-control --help
python -m aitbc_cli.main compliance --help
python -m aitbc_cli.main exchange --help
python -m aitbc_cli.main oracle --help
python -m aitbc_cli.main market-maker --help
- name: Test CLI functionality
run: |
cd cli
python -m aitbc_cli.main --test-mode multisig create --threshold 3 --owners "owner1,owner2,owner3"
python -m aitbc_cli.main --test-mode transfer-control set-limit --wallet test_wallet --max-daily 1000
# Multi-Chain Service Testing
test-services:
runs-on: ubuntu-latest
needs: lint-and-test
services:
redis:
image: redis:7
ports:
- 6379:6379
postgres:
image: postgres:15
env:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: aitbc_test
ports:
- 5432:5432
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.13"
- name: Install dependencies
run: |
pip install -r requirements.txt
pip install -r requirements-dev.txt
pip install -r requirements-test.txt
- name: Test blockchain service
run: |
cd apps/blockchain-node
python -m pytest tests/ -v -k "test_blockchain"
- name: Test coordinator service
run: |
cd apps/coordinator-api
python -m pytest tests/ -v -k "test_coordinator"
- name: Test consensus service
run: |
cd apps/consensus-node
python -m pytest tests/ -v -k "test_consensus"
- name: Test network service
run: |
cd apps/network-node
python -m pytest tests/ -v -k "test_network"
- name: Test explorer service
run: |
cd apps/explorer
python -m pytest tests/ -v -k "test_explorer"
# Production Services Testing
test-production-services:
runs-on: ubuntu-latest
needs: lint-and-test
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.13"
- name: Install dependencies
run: |
pip install -r requirements.txt
pip install -r requirements-dev.txt
pip install -r requirements-test.txt
- name: Test exchange service
run: |
cd apps/exchange-integration
python -m pytest tests/ -v -k "test_exchange"
- name: Test compliance service
run: |
cd apps/compliance-service
python -m pytest tests/ -v -k "test_compliance"
- name: Test trading engine
run: |
cd apps/trading-engine
python -m pytest tests/ -v -k "test_trading"
- name: Test plugin registry
run: |
cd apps/plugin-registry
python -m pytest tests/ -v -k "test_plugin_registry"
- name: Test plugin marketplace
run: |
cd apps/plugin-marketplace
python -m pytest tests/ -v -k "test_plugin_marketplace"
- name: Test global infrastructure
run: |
cd apps/global-infrastructure
python -m pytest tests/ -v -k "test_global_infrastructure"
- name: Test AI agents
run: |
cd apps/global-ai-agents
python -m pytest tests/ -v -k "test_ai_agents"
# Security Scanning
security-scan:
runs-on: ubuntu-latest
needs: lint-and-test
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
- name: Run CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
languages: python
- name: Run Bandit security linter
run: |
pip install bandit
bandit -r . -f json -o bandit-report.json
bandit -r . -f text
- name: Run Safety check
run: |
pip install safety
safety check --json --output safety-report.json
- name: Run semgrep security scan
uses: semgrep/semgrep-action@v1
with:
config: >-
p:security
p:owertools
# Build and Package
build:
runs-on: ubuntu-latest
needs: [test-cli, test-services, test-production-services]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.13"
- name: Build CLI package
run: |
cd cli
python -m build
- name: Build services packages
run: |
for service in apps/*/; do
if [ -f "$service/pyproject.toml" ]; then
cd "$service"
python -m build
cd - > /dev/null
fi
done
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: build-artifacts
path: |
cli/dist/*
apps/*/dist/*
retention-days: 30
# Deployment to Staging
deploy-staging:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/develop'
environment: staging
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: build-artifacts
- name: Deploy CLI to staging
run: |
echo "Deploying CLI to staging environment"
# Add actual deployment commands here
- name: Deploy services to staging
run: |
echo "Deploying services to staging environment"
# Add actual deployment commands here
- name: Run smoke tests on staging
run: |
echo "Running smoke tests on staging"
# Add smoke test commands here
# Deployment to Production
deploy-production:
runs-on: ubuntu-latest
needs: deploy-staging
if: github.event_name == 'release'
environment: production
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: build-artifacts
- name: Deploy CLI to production
run: |
echo "Deploying CLI to production environment"
# Add actual deployment commands here
- name: Deploy services to production
run: |
echo "Deploying services to production environment"
# Add actual deployment commands here
- name: Run health checks on production
run: |
echo "Running health checks on production"
# Add health check commands here
- name: Notify deployment success
run: |
echo "Deployment to production completed successfully"
# Performance Testing
performance-test:
runs-on: ubuntu-latest
needs: deploy-staging
if: github.event_name == 'pull_request'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.13"
- name: Install dependencies
run: |
pip install -r requirements-test.txt
pip install locust
- name: Run performance tests
run: |
cd tests/performance
python -m pytest test_performance.py::TestPerformance::test_cli_performance -v
python -m pytest test_performance.py::TestPerformance::test_concurrent_cli_operations -v
- name: Run load tests
run: |
cd tests/performance
locust -f locustfile.py --headless -u 10 -r 1 -t 30s --host http://staging.aitbc.dev
# Documentation Generation
docs:
runs-on: ubuntu-latest
needs: lint-and-test
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.13"
- name: Install documentation dependencies
run: |
pip install sphinx sphinx-rtd-theme myst-parser
- name: Generate documentation
run: |
cd docs
make html
- name: Deploy documentation
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs/_build/html
# Release Management
release:
runs-on: ubuntu-latest
needs: [build, security-scan]
if: github.event_name == 'release'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: build-artifacts
- name: Create Release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: AITBC Release ${{ github.ref }}
draft: false
prerelease: false
- name: Upload CLI Release Asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: cli/dist/*
asset_name: aitbc-cli-${{ github.ref_name }}.tar.gz
asset_content_type: application/gzip
- name: Upload Services Release Asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: apps/*/dist/*
asset_name: aitbc-services-${{ github.ref_name }}.tar.gz
asset_content_type: application/gzip
# Notification
notify:
runs-on: ubuntu-latest
needs: [lint-and-test, test-cli, test-services, test-production-services, security-scan]
if: always()
steps:
- name: Notify on success
if: needs.lint-and-test.result == 'success' && needs.test-cli.result == 'success' && needs.test-services.result == 'success' && needs.test-production-services.result == 'success' && needs.security-scan.result == 'success'
run: |
echo "✅ All tests passed successfully!"
# Add Slack/Discord notification here
- name: Notify on failure
if: needs.lint-and-test.result == 'failure' || needs.test-cli.result == 'failure' || needs.test-services.result == 'failure' || needs.test-production-services.result == 'failure' || needs.security-scan.result == 'failure'
run: |
echo "❌ Some tests failed!"
# Add Slack/Discord notification here

0
.github/workflows/cli-level1-tests.yml vendored Normal file → Executable file
View File

0
.gitignore vendored Normal file → Executable file
View File

102
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,102 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- id: check-json
- id: check-merge-conflict
- id: debug-statements
- id: check-docstring-first
- id: check-executables-have-shebangs
- id: check-toml
- id: check-xml
- id: check-case-conflict
- id: check-ast
- id: check-builddir
- id: check-shebang-scripts
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
language_version: python3
args: [--line-length=127]
- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
args: [--profile=black, --line-length=127]
- repo: https://github.com/pycqa/flake8
rev: 6.0.0
hooks:
- id: flake8
args: [--max-line-length=127, --extend-ignore=E203,W503]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.3.0
hooks:
- id: mypy
additional_dependencies: [types-requests, types-python-dateutil]
args: [--ignore-missing-imports]
- repo: https://github.com/PyCQA/bandit
rev: 1.7.5
hooks:
- id: bandit
args: [-r, ., -f, json, -o, bandit-report.json]
pass_filenames: false
- repo: https://github.com/pycqa/pydocstyle
rev: 6.3.0
hooks:
- id: pydocstyle
args: [--convention=google]
- repo: https://github.com/asottile/pyupgrade
rev: v3.3.1
hooks:
- id: pyupgrade
args: [--py311-plus]
- repo: https://github.com/Lucas-C/pre-commit-hooks-safety
rev: v1.3.2
hooks:
- id: python-safety-dependencies-check
files: requirements.*\.txt$
- repo: https://github.com/Lucas-C/pre-commit-hooks-safety
rev: v1.3.2
hooks:
- id: python-safety-check
args: [--json, --output, safety-report.json]
- repo: local
hooks:
- id: pytest-check
name: pytest-check
entry: pytest
language: system
args: [tests/unit/, --tb=short, -q]
pass_filenames: false
always_run: true
- id: security-check
name: security-check
entry: pytest
language: system
args: [tests/security/, --tb=short, -q]
pass_filenames: false
always_run: true
- id: performance-check
name: performance-check
entry: pytest
language: system
args: [tests/performance/test_performance_lightweight.py::TestPerformance::test_cli_performance, --tb=short, -q]
pass_filenames: false
always_run: true

66
Dockerfile Normal file
View File

@@ -0,0 +1,66 @@
# Multi-stage build for AITBC CLI
FROM python:3.13-slim as builder
# Set working directory
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y \
gcc \
g++ \
make \
libffi-dev \
libssl-dev \
&& rm -rf /var/lib/apt/lists/*
# Copy requirements
COPY cli/requirements.txt .
COPY cli/requirements-dev.txt .
# Install Python dependencies
RUN pip install --no-cache-dir --upgrade pip && \
pip install --no-cache-dir -r requirements.txt && \
pip install --no-cache-dir -r requirements-dev.txt
# Copy CLI source code
COPY cli/ .
# Install CLI in development mode
RUN pip install -e .
# Production stage
FROM python:3.13-slim as production
# Create non-root user
RUN useradd --create-home --shell /bin/bash aitbc
# Set working directory
WORKDIR /app
# Install runtime dependencies
RUN apt-get update && apt-get install -y \
curl \
&& rm -rf /var/lib/apt/lists/*
# Copy CLI from builder stage
COPY --from=builder /usr/local/lib/python3.13/site-packages /usr/local/lib/python3.13/site-packages
COPY --from=builder /usr/local/bin /usr/local/bin
# Create data directories
RUN mkdir -p /home/aitbc/.aitbc && \
chown -R aitbc:aitbc /home/aitbc
# Switch to non-root user
USER aitbc
# Set environment variables
ENV PATH=/home/aitbc/.local/bin:$PATH
ENV PYTHONPATH=/app
ENV AITBC_DATA_DIR=/home/aitbc/.aitbc
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD python -m aitbc_cli.main --version || exit 1
# Default command
CMD ["python", "-m", "aitbc_cli.main", "--help"]

0
LICENSE Normal file → Executable file
View File

0
README.md Normal file → Executable file
View File

0
SECURITY.md Normal file → Executable file
View File

0
apps/EXPLORER_MERGE_SUMMARY.md Normal file → Executable file
View File

0
apps/blockchain-explorer/README.md Normal file → Executable file
View File

0
apps/blockchain-explorer/assets/index.js Normal file → Executable file
View File

0
apps/blockchain-explorer/assets/style.css Normal file → Executable file
View File

0
apps/blockchain-explorer/index.html Normal file → Executable file
View File

0
apps/blockchain-explorer/main.py Normal file → Executable file
View File

0
apps/blockchain-explorer/nginx.conf Normal file → Executable file
View File

0
apps/blockchain-explorer/requirements.txt Normal file → Executable file
View File

0
apps/blockchain-node/.env.example Normal file → Executable file
View File

0
apps/blockchain-node/README.md Normal file → Executable file
View File

0
apps/blockchain-node/alembic.ini Normal file → Executable file
View File

0
apps/blockchain-node/create_genesis.py Normal file → Executable file
View File

0
apps/blockchain-node/data/devnet/genesis.json Normal file → Executable file
View File

0
apps/blockchain-node/docs/SCHEMA.md Normal file → Executable file
View File

0
apps/blockchain-node/init_genesis.py Normal file → Executable file
View File

0
apps/blockchain-node/migrations/README Normal file → Executable file
View File

0
apps/blockchain-node/migrations/env.py Normal file → Executable file
View File

0
apps/blockchain-node/migrations/script.py.mako Normal file → Executable file
View File

View File

View File

0
apps/blockchain-node/observability/README.md Normal file → Executable file
View File

0
apps/blockchain-node/observability/alerts.yml Normal file → Executable file
View File

View File

View File

0
apps/blockchain-node/observability/prometheus.yml Normal file → Executable file
View File

0
apps/blockchain-node/poetry.lock generated Normal file → Executable file
View File

0
apps/blockchain-node/pyproject.toml Normal file → Executable file
View File

0
apps/blockchain-node/requirements.txt Normal file → Executable file
View File

View File

0
apps/blockchain-node/scripts/assign_proposer.py Normal file → Executable file
View File

View File

0
apps/blockchain-node/scripts/keygen.py Normal file → Executable file
View File

0
apps/blockchain-node/scripts/load_genesis.py Normal file → Executable file
View File

0
apps/blockchain-node/scripts/make_genesis.py Normal file → Executable file
View File

0
apps/blockchain-node/scripts/mock_coordinator.py Normal file → Executable file
View File

0
apps/blockchain-node/scripts/start_mock_blockchain.sh Normal file → Executable file
View File

0
apps/blockchain-node/scripts/ws_load_test.py Normal file → Executable file
View File

0
apps/blockchain-node/src/aitbc_chain/__init__.py Normal file → Executable file
View File

0
apps/blockchain-node/src/aitbc_chain/app.py Normal file → Executable file
View File

0
apps/blockchain-node/src/aitbc_chain/config.py Normal file → Executable file
View File

View File

0
apps/blockchain-node/src/aitbc_chain/consensus/poa.py Normal file → Executable file
View File

View File

View File

View File

0
apps/blockchain-node/src/aitbc_chain/database.py Normal file → Executable file
View File

View File

0
apps/blockchain-node/src/aitbc_chain/gossip/broker.py Normal file → Executable file
View File

0
apps/blockchain-node/src/aitbc_chain/gossip/relay.py Normal file → Executable file
View File

0
apps/blockchain-node/src/aitbc_chain/logger.py Normal file → Executable file
View File

0
apps/blockchain-node/src/aitbc_chain/main.py Normal file → Executable file
View File

0
apps/blockchain-node/src/aitbc_chain/mempool.py Normal file → Executable file
View File

0
apps/blockchain-node/src/aitbc_chain/metrics.py Normal file → Executable file
View File

0
apps/blockchain-node/src/aitbc_chain/models.py Normal file → Executable file
View File

View File

View File

View File

2
apps/blockchain-node/src/aitbc_chain/rpc/router.py Normal file → Executable file
View File

@@ -300,7 +300,7 @@ async def get_receipts(limit: int = 20, offset: int = 0) -> Dict[str, Any]:
@router.get("/getBalance/{address}", summary="Get account balance") @router.get("/getBalance/{address}", summary="Get account balance")
async def get_balance(address: str) -> Dict[str, Any]: async def get_balance(address: str, chain_id: str = "ait-devnet") -> Dict[str, Any]:
metrics_registry.increment("rpc_get_balance_total") metrics_registry.increment("rpc_get_balance_total")
start = time.perf_counter() start = time.perf_counter()
with session_scope() as session: with session_scope() as session:

0
apps/blockchain-node/src/aitbc_chain/rpc/websocket.py Normal file → Executable file
View File

0
apps/blockchain-node/src/aitbc_chain/sync.py Normal file → Executable file
View File

0
apps/blockchain-node/tests/conftest.py Normal file → Executable file
View File

0
apps/blockchain-node/tests/test_gossip_broadcast.py Normal file → Executable file
View File

0
apps/blockchain-node/tests/test_mempool.py Normal file → Executable file
View File

0
apps/blockchain-node/tests/test_models.py Normal file → Executable file
View File

View File

0
apps/blockchain-node/tests/test_sync.py Normal file → Executable file
View File

0
apps/blockchain-node/tests/test_websocket.py Normal file → Executable file
View File

431
apps/compliance-service/main.py Executable file
View File

@@ -0,0 +1,431 @@
"""
Production Compliance Service for AITBC
Handles KYC/AML, regulatory compliance, and monitoring
"""
import asyncio
import json
import logging
from datetime import datetime, timedelta
from pathlib import Path
from typing import Dict, Any, List, Optional
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
app = FastAPI(
title="AITBC Compliance Service",
description="Regulatory compliance and monitoring for AITBC operations",
version="1.0.0"
)
# Data models
class KYCRequest(BaseModel):
user_id: str
name: str
email: str
document_type: str
document_number: str
address: Dict[str, str]
class ComplianceReport(BaseModel):
report_type: str
description: str
severity: str # low, medium, high, critical
details: Dict[str, Any]
class TransactionMonitoring(BaseModel):
transaction_id: str
user_id: str
amount: float
currency: str
counterparty: str
timestamp: datetime
# In-memory storage (in production, use database)
kyc_records: Dict[str, Dict] = {}
compliance_reports: Dict[str, Dict] = {}
suspicious_transactions: Dict[str, Dict] = {}
compliance_rules: Dict[str, Dict] = {}
risk_scores: Dict[str, Dict] = {}
@app.get("/")
async def root():
return {
"service": "AITBC Compliance Service",
"status": "running",
"timestamp": datetime.utcnow().isoformat(),
"version": "1.0.0"
}
@app.get("/health")
async def health_check():
return {
"status": "healthy",
"kyc_records": len(kyc_records),
"compliance_reports": len(compliance_reports),
"suspicious_transactions": len(suspicious_transactions),
"active_rules": len(compliance_rules)
}
@app.post("/api/v1/kyc/submit")
async def submit_kyc(kyc_request: KYCRequest):
"""Submit KYC verification request"""
if kyc_request.user_id in kyc_records:
raise HTTPException(status_code=400, detail="KYC already submitted for this user")
# Create KYC record
kyc_record = {
"user_id": kyc_request.user_id,
"name": kyc_request.name,
"email": kyc_request.email,
"document_type": kyc_request.document_type,
"document_number": kyc_request.document_number,
"address": kyc_request.address,
"status": "pending",
"submitted_at": datetime.utcnow().isoformat(),
"reviewed_at": None,
"approved_at": None,
"risk_score": "medium",
"notes": []
}
kyc_records[kyc_request.user_id] = kyc_record
# Simulate KYC verification process
await asyncio.sleep(2) # Simulate verification delay
# Auto-approve for demo (in production, this would involve actual verification)
kyc_record["status"] = "approved"
kyc_record["reviewed_at"] = datetime.utcnow().isoformat()
kyc_record["approved_at"] = datetime.utcnow().isoformat()
kyc_record["risk_score"] = "low"
logger.info(f"KYC approved for user: {kyc_request.user_id}")
return {
"user_id": kyc_request.user_id,
"status": kyc_record["status"],
"risk_score": kyc_record["risk_score"],
"approved_at": kyc_record["approved_at"]
}
@app.get("/api/v1/kyc/{user_id}")
async def get_kyc_status(user_id: str):
"""Get KYC status for a user"""
if user_id not in kyc_records:
raise HTTPException(status_code=404, detail="KYC record not found")
return kyc_records[user_id]
@app.get("/api/v1/kyc")
async def list_kyc_records():
"""List all KYC records"""
return {
"kyc_records": list(kyc_records.values()),
"total_records": len(kyc_records),
"approved": len([r for r in kyc_records.values() if r["status"] == "approved"]),
"pending": len([r for r in kyc_records.values() if r["status"] == "pending"]),
"rejected": len([r for r in kyc_records.values() if r["status"] == "rejected"])
}
@app.post("/api/v1/compliance/report")
async def create_compliance_report(report: ComplianceReport):
"""Create a compliance report"""
report_id = f"report_{int(datetime.utcnow().timestamp())}"
compliance_record = {
"report_id": report_id,
"report_type": report.report_type,
"description": report.description,
"severity": report.severity,
"details": report.details,
"status": "open",
"created_at": datetime.utcnow().isoformat(),
"assigned_to": None,
"resolved_at": None,
"resolution": None
}
compliance_reports[report_id] = compliance_record
logger.info(f"Compliance report created: {report_id} - {report.report_type}")
return {
"report_id": report_id,
"status": "created",
"severity": report.severity,
"created_at": compliance_record["created_at"]
}
@app.get("/api/v1/compliance/reports")
async def list_compliance_reports():
"""List all compliance reports"""
return {
"reports": list(compliance_reports.values()),
"total_reports": len(compliance_reports),
"open": len([r for r in compliance_reports.values() if r["status"] == "open"]),
"resolved": len([r for r in compliance_reports.values() if r["status"] == "resolved"])
}
@app.post("/api/v1/monitoring/transaction")
async def monitor_transaction(transaction: TransactionMonitoring):
"""Monitor transaction for compliance"""
transaction_id = transaction.transaction_id
# Create transaction monitoring record
monitoring_record = {
"transaction_id": transaction_id,
"user_id": transaction.user_id,
"amount": transaction.amount,
"currency": transaction.currency,
"counterparty": transaction.counterparty,
"timestamp": transaction.timestamp.isoformat(),
"monitored_at": datetime.utcnow().isoformat(),
"risk_score": calculate_transaction_risk(transaction),
"flags": [],
"status": "monitored"
}
suspicious_transactions[transaction_id] = monitoring_record
# Check for suspicious patterns
flags = check_suspicious_patterns(transaction)
if flags:
monitoring_record["flags"] = flags
monitoring_record["status"] = "flagged"
# Create compliance report for suspicious transaction
await create_suspicious_transaction_report(transaction, flags)
return {
"transaction_id": transaction_id,
"risk_score": monitoring_record["risk_score"],
"flags": flags,
"status": monitoring_record["status"]
}
@app.get("/api/v1/monitoring/transactions")
async def list_monitored_transactions():
"""List all monitored transactions"""
return {
"transactions": list(suspicious_transactions.values()),
"total_transactions": len(suspicious_transactions),
"flagged": len([t for t in suspicious_transactions.values() if t["status"] == "flagged"]),
"suspicious": len([t for t in suspicious_transactions.values() if t["risk_score"] == "high"])
}
@app.post("/api/v1/rules/create")
async def create_compliance_rule(rule_data: Dict[str, Any]):
"""Create a new compliance rule"""
rule_id = f"rule_{int(datetime.utcnow().timestamp())}"
rule = {
"rule_id": rule_id,
"name": rule_data.get("name"),
"description": rule_data.get("description"),
"type": rule_data.get("type"),
"conditions": rule_data.get("conditions", {}),
"actions": rule_data.get("actions", []),
"severity": rule_data.get("severity", "medium"),
"active": True,
"created_at": datetime.utcnow().isoformat(),
"trigger_count": 0
}
compliance_rules[rule_id] = rule
logger.info(f"Compliance rule created: {rule_id} - {rule['name']}")
return {
"rule_id": rule_id,
"name": rule["name"],
"status": "created",
"active": rule["active"]
}
@app.get("/api/v1/rules")
async def list_compliance_rules():
"""List all compliance rules"""
return {
"rules": list(compliance_rules.values()),
"total_rules": len(compliance_rules),
"active": len([r for r in compliance_rules.values() if r["active"]])
}
@app.get("/api/v1/dashboard")
async def compliance_dashboard():
"""Get compliance dashboard data"""
total_users = len(kyc_records)
approved_users = len([r for r in kyc_records.values() if r["status"] == "approved"])
pending_reviews = len([r for r in kyc_records.values() if r["status"] == "pending"])
total_reports = len(compliance_reports)
open_reports = len([r for r in compliance_reports.values() if r["status"] == "open"])
total_transactions = len(suspicious_transactions)
flagged_transactions = len([t for t in suspicious_transactions.values() if t["status"] == "flagged"])
return {
"summary": {
"total_users": total_users,
"approved_users": approved_users,
"pending_reviews": pending_reviews,
"approval_rate": (approved_users / total_users * 100) if total_users > 0 else 0,
"total_reports": total_reports,
"open_reports": open_reports,
"total_transactions": total_transactions,
"flagged_transactions": flagged_transactions,
"flag_rate": (flagged_transactions / total_transactions * 100) if total_transactions > 0 else 0
},
"risk_distribution": get_risk_distribution(),
"recent_activity": get_recent_activity(),
"generated_at": datetime.utcnow().isoformat()
}
# Helper functions
def calculate_transaction_risk(transaction: TransactionMonitoring) -> str:
"""Calculate risk score for a transaction"""
risk_score = 0
# Amount-based risk
if transaction.amount > 10000:
risk_score += 3
elif transaction.amount > 1000:
risk_score += 2
elif transaction.amount > 100:
risk_score += 1
# Time-based risk (transactions outside business hours)
hour = transaction.timestamp.hour
if hour < 9 or hour > 17:
risk_score += 1
# Convert to risk level
if risk_score >= 4:
return "high"
elif risk_score >= 2:
return "medium"
else:
return "low"
def check_suspicious_patterns(transaction: TransactionMonitoring) -> List[str]:
"""Check for suspicious transaction patterns"""
flags = []
# High value transaction
if transaction.amount > 50000:
flags.append("high_value_transaction")
# Rapid transactions (check if user has multiple transactions in short time)
user_transactions = [t for t in suspicious_transactions.values()
if t["user_id"] == transaction.user_id]
recent_transactions = [t for t in user_transactions
if datetime.fromisoformat(t["monitored_at"]) >
datetime.utcnow() - timedelta(hours=1)]
if len(recent_transactions) > 5:
flags.append("rapid_transactions")
# Unusual counterparty
if transaction.counterparty in ["high_risk_entity_1", "high_risk_entity_2"]:
flags.append("high_risk_counterparty")
return flags
async def create_suspicious_transaction_report(transaction: TransactionMonitoring, flags: List[str]):
"""Create compliance report for suspicious transaction"""
report_data = ComplianceReport(
report_type="suspicious_transaction",
description=f"Suspicious transaction detected: {transaction.transaction_id}",
severity="high",
details={
"transaction_id": transaction.transaction_id,
"user_id": transaction.user_id,
"amount": transaction.amount,
"flags": flags,
"timestamp": transaction.timestamp.isoformat()
}
)
await create_compliance_report(report_data)
def get_risk_distribution() -> Dict[str, int]:
"""Get distribution of risk scores"""
distribution = {"low": 0, "medium": 0, "high": 0}
for record in kyc_records.values():
distribution[record["risk_score"]] = distribution.get(record["risk_score"], 0) + 1
for transaction in suspicious_transactions.values():
distribution[transaction["risk_score"]] = distribution.get(transaction["risk_score"], 0) + 1
return distribution
def get_recent_activity() -> List[Dict]:
"""Get recent compliance activity"""
activities = []
# Recent KYC approvals
recent_kyc = [r for r in kyc_records.values()
if r.get("approved_at") and
datetime.fromisoformat(r["approved_at"]) >
datetime.utcnow() - timedelta(hours=24)]
for kyc in recent_kyc[:5]:
activities.append({
"type": "kyc_approved",
"description": f"KYC approved for {kyc['name']}",
"timestamp": kyc["approved_at"]
})
# Recent compliance reports
recent_reports = [r for r in compliance_reports.values()
if datetime.fromisoformat(r["created_at"]) >
datetime.utcnow() - timedelta(hours=24)]
for report in recent_reports[:5]:
activities.append({
"type": "compliance_report",
"description": f"Report: {report['description']}",
"timestamp": report["created_at"]
})
# Sort by timestamp
activities.sort(key=lambda x: x["timestamp"], reverse=True)
return activities[:10]
# Background task for periodic compliance checks
async def periodic_compliance_checks():
"""Background task for periodic compliance monitoring"""
while True:
await asyncio.sleep(300) # Check every 5 minutes
# Check for expired KYC records
current_time = datetime.utcnow()
for user_id, kyc_record in kyc_records.items():
if kyc_record["status"] == "approved":
approved_time = datetime.fromisoformat(kyc_record["approved_at"])
if current_time - approved_time > timedelta(days=365):
# Flag for re-verification
kyc_record["status"] = "reverification_required"
logger.info(f"KYC re-verification required for user: {user_id}")
@app.on_event("startup")
async def startup_event():
logger.info("Starting AITBC Compliance Service")
# Start background compliance checks
asyncio.create_task(periodic_compliance_checks())
@app.on_event("shutdown")
async def shutdown_event():
logger.info("Shutting down AITBC Compliance Service")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8011, log_level="info")

0
apps/coordinator-api/.env.example Normal file → Executable file
View File

0
apps/coordinator-api/= Normal file → Executable file
View File

0
apps/coordinator-api/QUICK_WINS_SUMMARY.md Normal file → Executable file
View File

0
apps/coordinator-api/README.md Normal file → Executable file
View File

0
apps/coordinator-api/aitbc/api/v1/settlement.py Normal file → Executable file
View File

0
apps/coordinator-api/aitbc/logging.py Normal file → Executable file
View File

0
apps/coordinator-api/aitbc/settlement/__init__.py Normal file → Executable file
View File

View File

0
apps/coordinator-api/aitbc/settlement/bridges/base.py Normal file → Executable file
View File

View File

0
apps/coordinator-api/aitbc/settlement/hooks.py Normal file → Executable file
View File

0
apps/coordinator-api/aitbc/settlement/manager.py Normal file → Executable file
View File

0
apps/coordinator-api/aitbc/settlement/storage.py Normal file → Executable file
View File

Some files were not shown because too many files have changed in this diff Show More