```
chore: refactor logging module, update genesis timestamp, remove model relationships, and reorganize routers - Rename logging.py to logger.py and update import paths in poa.py and main.py - Update devnet genesis timestamp to 1766828620 - Remove SQLModel Relationship declarations from Block, Transaction, and Receipt models - Add SessionDep type alias and get_session dependency in coordinator-api deps - Reorganize coordinator-api routers: replace explorer/registry with exchange, users, marketplace
This commit is contained in:
@ -2,11 +2,12 @@
|
||||
|
||||
## Status (2025-12-22)
|
||||
|
||||
- **Stage 1 delivery**: ✅ **DEPLOYED** - Minimal Coordinator API successfully deployed in production at https://aitbc.bubuit.net/api/v1/
|
||||
- **Stage 1 delivery**: ✅ **DEPLOYED** - Coordinator API deployed in production behind https://aitbc.bubuit.net/api/
|
||||
- FastAPI service running in Incus container on port 8000
|
||||
- Health endpoint operational: `/v1/health` returns `{"status":"ok","env":"container"}`
|
||||
- nginx proxy configured at `/api/v1/` route
|
||||
- Note: Full codebase has import issues, minimal version deployed
|
||||
- Health endpoint operational: `/api/v1/health` returns `{"status":"ok","env":"dev"}`
|
||||
- nginx proxy configured at `/api/` (so `/api/v1/*` routes to the container service)
|
||||
- Explorer API available via nginx at `/api/explorer/*` (backend: `/v1/explorer/*`)
|
||||
- Users API available via `/api/v1/users/*` (compat: `/api/users/*` for Exchange)
|
||||
- **Testing & tooling**: Pytest suites cover job scheduling, miner flows, and receipt verification; the shared CI script `scripts/ci/run_python_tests.sh` executes these tests in GitHub Actions.
|
||||
- **Documentation**: `docs/run.md` and `apps/coordinator-api/README.md` describe configuration for `RECEIPT_SIGNING_KEY_HEX` and `RECEIPT_ATTESTATION_KEY_HEX` plus the receipt history API.
|
||||
- **Service APIs**: Implemented specific service endpoints for common GPU workloads (Whisper, Stable Diffusion, LLM inference, FFmpeg, Blender) with typed schemas and validation.
|
||||
@ -60,10 +61,10 @@
|
||||
|
||||
- **Container**: Incus container 'aitbc' at `/opt/coordinator-api/`
|
||||
- **Service**: systemd service `coordinator-api.service` enabled and running
|
||||
- **Port**: 8000 (internal), proxied via nginx at `/api/v1/`
|
||||
- **Port**: 8000 (internal), proxied via nginx at `/api/` (including `/api/v1/*`)
|
||||
- **Dependencies**: Virtual environment with FastAPI, uvicorn, pydantic installed
|
||||
- **Access**: https://aitbc.bubuit.net/api/v1/health for health check
|
||||
- **Note**: Full codebase has import issues, minimal version deployed with health endpoint only
|
||||
- **Note**: Explorer + Users routes are enabled in production (see `/api/explorer/*` and `/api/v1/users/*`).
|
||||
|
||||
## Stage 2+ - IN PROGRESS
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ GET /v1/jobs?api_key=your_api_key_here
|
||||
|
||||
### cURL
|
||||
```bash
|
||||
curl -X GET https://api.aitbc.io/v1/jobs \
|
||||
curl -X GET https://aitbc.bubuit.net/api/v1/jobs \
|
||||
-H "X-API-Key: your_api_key_here"
|
||||
```
|
||||
|
||||
@ -42,7 +42,7 @@ headers = {
|
||||
}
|
||||
|
||||
response = requests.get(
|
||||
"https://api.aitbc.io/v1/jobs",
|
||||
"https://aitbc.bubuit.net/api/v1/jobs",
|
||||
headers=headers
|
||||
)
|
||||
```
|
||||
@ -53,7 +53,7 @@ const headers = {
|
||||
"X-API-Key": "your_api_key_here"
|
||||
};
|
||||
|
||||
fetch("https://api.aitbc.io/v1/jobs", {
|
||||
fetch("https://aitbc.bubuit.net/api/v1/jobs", {
|
||||
headers: headers
|
||||
})
|
||||
.then(response => response.json())
|
||||
@ -100,12 +100,12 @@ Visit the [Dashboard](https://dashboard.aitbc.io/api-keys)
|
||||
|
||||
### Revoke a Key
|
||||
```bash
|
||||
curl -X DELETE https://api.aitbc.io/v1/api-keys/{key_id} \
|
||||
curl -X DELETE https://aitbc.bubuit.net/api/v1/api-keys/{key_id} \
|
||||
-H "X-API-Key: your_master_key"
|
||||
```
|
||||
|
||||
### Regenerate a Key
|
||||
```bash
|
||||
curl -X POST https://api.aitbc.io/v1/api-keys/{key_id}/regenerate \
|
||||
curl -X POST https://aitbc.bubuit.net/api/v1/api-keys/{key_id}/regenerate \
|
||||
-H "X-API-Key: your_master_key"
|
||||
```
|
||||
@ -332,6 +332,11 @@ Retrieve statistics for a specific miner.
|
||||
GET /v1/health
|
||||
```
|
||||
|
||||
Production base URL is `https://aitbc.bubuit.net/api`, so the full health URL is:
|
||||
```http
|
||||
GET /api/v1/health
|
||||
```
|
||||
|
||||
Check the health status of the coordinator service.
|
||||
|
||||
**Response:**
|
||||
@ -9,8 +9,8 @@ The complete OpenAPI 3.0 specification for the AITBC Coordinator API is availabl
|
||||
|
||||
## Interactive Documentation
|
||||
|
||||
- [Swagger UI](https://api.aitbc.io/docs) - Interactive API explorer
|
||||
- [ReDoc](https://api.aitbc.io/redoc) - Alternative documentation view
|
||||
- [Swagger UI](https://aitbc.bubuit.net/api/docs) - Interactive API explorer
|
||||
- [ReDoc](https://aitbc.bubuit.net/api/redoc) - Alternative documentation view
|
||||
|
||||
## Download Specification
|
||||
|
||||
@ -50,7 +50,7 @@ API requests are rate-limited based on your subscription plan.
|
||||
## WebSocket API
|
||||
|
||||
Real-time updates available at:
|
||||
- WebSocket: `wss://api.aitbc.io/ws`
|
||||
- WebSocket: `wss://aitbc.bubuit.net/ws`
|
||||
- Message types: job_update, marketplace_update, receipt_created
|
||||
|
||||
## Code Generation
|
||||
@ -10,7 +10,7 @@ The Coordinator API is the central service of the AITBC platform, responsible fo
|
||||
## Base URL
|
||||
|
||||
```
|
||||
Production: https://api.aitbc.io
|
||||
Production: https://aitbc.bubuit.net/api
|
||||
Staging: https://staging-api.aitbc.io
|
||||
Development: http://localhost:8011
|
||||
```
|
||||
@ -111,7 +111,7 @@ Official SDKs are available for:
|
||||
Real-time updates are available through WebSocket connections:
|
||||
|
||||
```javascript
|
||||
const ws = new WebSocket('wss://api.aitbc.io/ws');
|
||||
const ws = new WebSocket('wss://aitbc.bubuit.net/ws');
|
||||
|
||||
ws.onmessage = (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
@ -122,7 +122,7 @@ ws.onmessage = (event) => {
|
||||
## OpenAPI Specification
|
||||
|
||||
The complete OpenAPI 3.0 specification is available:
|
||||
- [View in Swagger UI](https://api.aitbc.io/docs)
|
||||
- [View in Swagger UI](https://aitbc.bubuit.net/api/docs)
|
||||
- [Download JSON](openapi.md)
|
||||
|
||||
## Getting Started
|
||||
@ -28,7 +28,7 @@ import { AITBCClient } from '@aitbc/client';
|
||||
// Initialize the client
|
||||
const client = new AITBCClient({
|
||||
apiKey: 'your_api_key_here',
|
||||
baseUrl: 'https://api.aitbc.io'
|
||||
baseUrl: 'https://aitbc.bubuit.net/api'
|
||||
});
|
||||
|
||||
// Create a job
|
||||
@ -49,7 +49,7 @@ console.log('Job created:', job.jobId);
|
||||
### Environment Variables
|
||||
```bash
|
||||
AITBC_API_KEY=your_api_key
|
||||
AITBC_BASE_URL=https://api.aitbc.io
|
||||
AITBC_BASE_URL=https://aitbc.bubuit.net/api
|
||||
AITBC_NETWORK=mainnet
|
||||
```
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ from aitbc import AITBCClient
|
||||
# Initialize the client
|
||||
client = AITBCClient(
|
||||
api_key="your_api_key_here",
|
||||
base_url="https://api.aitbc.io" # or http://localhost:8011 for dev
|
||||
base_url="https://aitbc.bubuit.net/api" # or http://localhost:8011 for dev
|
||||
)
|
||||
|
||||
# Create a job
|
||||
@ -50,7 +50,7 @@ print(f"Result: {result}")
|
||||
### Environment Variables
|
||||
```bash
|
||||
export AITBC_API_KEY="your_api_key"
|
||||
export AITBC_BASE_URL="https://api.aitbc.io"
|
||||
export AITBC_BASE_URL="https://aitbc.bubuit.net/api"
|
||||
export AITBC_NETWORK="mainnet" # or testnet
|
||||
```
|
||||
|
||||
@ -61,7 +61,7 @@ from aitbc import AITBCClient, Config
|
||||
# Using Config object
|
||||
config = Config(
|
||||
api_key="your_api_key",
|
||||
base_url="https://api.aitbc.io",
|
||||
base_url="https://aitbc.bubuit.net/api",
|
||||
timeout=30,
|
||||
retries=3
|
||||
)
|
||||
@ -435,7 +435,7 @@ from aitbc import AITBCClient
|
||||
|
||||
client = AITBCClient(
|
||||
api_key=os.getenv("AITBC_API_KEY"),
|
||||
base_url=os.getenv("AITBC_BASE_URL", "https://api.aitbc.io")
|
||||
base_url=os.getenv("AITBC_BASE_URL", "https://aitbc.bubuit.net/api")
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
44
docs/done.md
44
docs/done.md
@ -13,7 +13,8 @@ This document tracks components that have been successfully deployed and are ope
|
||||
- Full-featured blockchain explorer
|
||||
- Mock data with genesis block (height 0) displayed
|
||||
- Blocks, transactions, addresses, receipts tracking
|
||||
- Mock/live data toggle functionality
|
||||
- Mock/live data toggle functionality (live mode backed by Coordinator API)
|
||||
- Live API (nginx): `/api/explorer/*`
|
||||
|
||||
- ✅ **Marketplace Web** - Deployed at https://aitbc.bubuit.net/marketplace/
|
||||
- Vite + TypeScript frontend
|
||||
@ -21,10 +22,12 @@ This document tracks components that have been successfully deployed and are ope
|
||||
- Mock data fixtures with API abstraction
|
||||
|
||||
- ✅ **Coordinator API** - Deployed in container
|
||||
- Minimal FastAPI service running on port 8000
|
||||
- Health endpoint: /v1/health returns {"status":"ok","env":"container"}
|
||||
- nginx proxy: /api/v1/ routes to container service
|
||||
- Note: Full codebase has import issues, minimal version deployed
|
||||
- FastAPI service running on port 8000
|
||||
- Health endpoint: `/api/v1/health` returns `{"status":"ok","env":"dev"}`
|
||||
- nginx proxy: `/api/` routes to container service (so `/api/v1/*` works)
|
||||
- Explorer API (nginx): `/api/explorer/*` → backend `/v1/explorer/*`
|
||||
- Users API: `/api/v1/users/*` (compat: `/api/users/*` for Exchange)
|
||||
- ZK Applications API: /api/zk/ endpoints for privacy-preserving features
|
||||
|
||||
- ✅ **Wallet Daemon** - Deployed in container
|
||||
- FastAPI service with encrypted keystore (Argon2id + XChaCha20-Poly1305)
|
||||
@ -38,6 +41,27 @@ This document tracks components that have been successfully deployed and are ope
|
||||
- Miner, client, developer guides
|
||||
- API references and technical specs
|
||||
|
||||
- ✅ **Trade Exchange** - Deployed at https://aitbc.bubuit.net/Exchange/
|
||||
- Bitcoin wallet integration for AITBC purchases
|
||||
- User management system with individual wallets
|
||||
- QR code generation for payments
|
||||
- Real-time payment monitoring
|
||||
- Session-based authentication
|
||||
- Exchange rate: 1 BTC = 100,000 AITBC
|
||||
|
||||
- ✅ **ZK Applications** - Privacy-preserving features deployed
|
||||
- Circom compiler v2.2.3 installed
|
||||
- ZK circuits compiled (receipt_simple with 300 constraints)
|
||||
- Trusted setup ceremony completed (Powers of Tau)
|
||||
- Available features:
|
||||
- Identity commitments
|
||||
- Stealth addresses
|
||||
- Private receipt attestation
|
||||
- Group membership proofs
|
||||
- Private bidding
|
||||
- Computation proofs
|
||||
- API endpoints: /api/zk/
|
||||
|
||||
## Host Services (GPU Access)
|
||||
|
||||
- ✅ **Blockchain Node** - Running on host
|
||||
@ -56,7 +80,11 @@ This document tracks components that have been successfully deployed and are ope
|
||||
- ✅ **nginx Configuration** - All routes configured
|
||||
- /explorer/ → Explorer Web
|
||||
- /marketplace/ → Marketplace Web
|
||||
- /api/ → Coordinator API (container)
|
||||
- /api/v1/ → Coordinator API (container)
|
||||
- /api/explorer/ → Explorer API (container)
|
||||
- /api/users/ → Users API (container, Exchange compatibility)
|
||||
- /api/zk/ → ZK Applications API (container)
|
||||
- /rpc/ → Blockchain RPC (host)
|
||||
- /v1/ → Mock Coordinator (host)
|
||||
- /wallet/ → Wallet Daemon (container)
|
||||
@ -73,7 +101,7 @@ This document tracks components that have been successfully deployed and are ope
|
||||
## Deployment Architecture
|
||||
|
||||
- **Container Services**: Public web access, no GPU required
|
||||
- Website, Explorer, Marketplace, Coordinator API, Wallet Daemon, Docs
|
||||
- Website, Explorer, Marketplace, Coordinator API, Wallet Daemon, Docs, ZK Apps
|
||||
- **Host Services**: GPU access required, private network
|
||||
- Blockchain Node, Mining operations
|
||||
- **nginx Proxy**: Routes requests between container and host
|
||||
@ -82,11 +110,13 @@ This document tracks components that have been successfully deployed and are ope
|
||||
## Current Status
|
||||
|
||||
**Production Ready**: All core services deployed and operational
|
||||
- ✅ 6 container services running
|
||||
- ✅ 8 container services running (including ZK Applications)
|
||||
- ✅ 1 host service running
|
||||
- ✅ Complete nginx proxy configuration
|
||||
- ✅ SSL/HTTPS fully configured
|
||||
- ✅ DNS resolution working
|
||||
- ✅ Trade Exchange with Bitcoin integration
|
||||
- ✅ Zero-Knowledge proof capabilities enabled
|
||||
|
||||
## Remaining Tasks
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
- ✅ Expand responsive polish beyond overview cards (tablet/mobile grid, table hover states).
|
||||
|
||||
- **Live Mode Integration**
|
||||
- ✅ Hit live coordinator endpoints (`/v1/blocks`, `/v1/transactions`, `/v1/addresses`, `/v1/receipts`) via `getDataMode() === "live"`.
|
||||
- ✅ Hit live coordinator endpoints via nginx (`/api/explorer/blocks`, `/api/explorer/transactions`, `/api/explorer/addresses`, `/api/explorer/receipts`) via `getDataMode() === "live"`.
|
||||
- ✅ Add fallbacks + error surfacing for partial/failed live responses.
|
||||
- ✅ Implement Playwright e2e tests for live mode functionality.
|
||||
|
||||
|
||||
333
docs/governance.md
Normal file
333
docs/governance.md
Normal file
@ -0,0 +1,333 @@
|
||||
# Governance Module
|
||||
|
||||
The AITBC governance module enables decentralized decision-making through proposal voting and parameter changes.
|
||||
|
||||
## Overview
|
||||
|
||||
The governance system allows AITBC token holders to:
|
||||
- Create proposals for protocol changes
|
||||
- Vote on active proposals
|
||||
- Execute approved proposals
|
||||
- Track governance history
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### Get Governance Parameters
|
||||
|
||||
Retrieve current governance system parameters.
|
||||
|
||||
```http
|
||||
GET /api/v1/governance/parameters
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"min_proposal_voting_power": 1000,
|
||||
"max_proposal_title_length": 200,
|
||||
"max_proposal_description_length": 5000,
|
||||
"default_voting_period_days": 7,
|
||||
"max_voting_period_days": 30,
|
||||
"min_quorum_threshold": 0.01,
|
||||
"max_quorum_threshold": 1.0,
|
||||
"min_approval_threshold": 0.01,
|
||||
"max_approval_threshold": 1.0,
|
||||
"execution_delay_hours": 24
|
||||
}
|
||||
```
|
||||
|
||||
### List Proposals
|
||||
|
||||
Get a list of governance proposals.
|
||||
|
||||
```http
|
||||
GET /api/v1/governance/proposals?status={status}&limit={limit}&offset={offset}
|
||||
```
|
||||
|
||||
**Query Parameters:**
|
||||
- `status` (optional): Filter by proposal status (`active`, `passed`, `rejected`, `executed`)
|
||||
- `limit` (optional): Number of proposals to return (default: 20)
|
||||
- `offset` (optional): Number of proposals to skip (default: 0)
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "proposal-uuid",
|
||||
"title": "Proposal Title",
|
||||
"description": "Description of the proposal",
|
||||
"type": "parameter_change",
|
||||
"target": {},
|
||||
"proposer": "user-address",
|
||||
"status": "active",
|
||||
"created_at": "2025-12-28T18:00:00Z",
|
||||
"voting_deadline": "2025-12-28T18:00:00Z",
|
||||
"quorum_threshold": 0.1,
|
||||
"approval_threshold": 0.5,
|
||||
"current_quorum": 0.15,
|
||||
"current_approval": 0.75,
|
||||
"votes_for": 150,
|
||||
"votes_against": 50,
|
||||
"votes_abstain": 10,
|
||||
"total_voting_power": 1000000
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### Create Proposal
|
||||
|
||||
Create a new governance proposal.
|
||||
|
||||
```http
|
||||
POST /api/v1/governance/proposals
|
||||
```
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"title": "Reduce Transaction Fees",
|
||||
"description": "This proposal suggests reducing transaction fees...",
|
||||
"type": "parameter_change",
|
||||
"target": {
|
||||
"fee_percentage": "0.05"
|
||||
},
|
||||
"voting_period": 7,
|
||||
"quorum_threshold": 0.1,
|
||||
"approval_threshold": 0.5
|
||||
}
|
||||
```
|
||||
|
||||
**Fields:**
|
||||
- `title`: Proposal title (10-200 characters)
|
||||
- `description`: Detailed description (50-5000 characters)
|
||||
- `type`: Proposal type (`parameter_change`, `protocol_upgrade`, `fund_allocation`, `policy_change`)
|
||||
- `target`: Target configuration for the proposal
|
||||
- `voting_period`: Voting period in days (1-30)
|
||||
- `quorum_threshold`: Minimum participation percentage (0.01-1.0)
|
||||
- `approval_threshold`: Minimum approval percentage (0.01-1.0)
|
||||
|
||||
### Get Proposal
|
||||
|
||||
Get details of a specific proposal.
|
||||
|
||||
```http
|
||||
GET /api/v1/governance/proposals/{proposal_id}
|
||||
```
|
||||
|
||||
### Submit Vote
|
||||
|
||||
Submit a vote on a proposal.
|
||||
|
||||
```http
|
||||
POST /api/v1/governance/vote
|
||||
```
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"proposal_id": "proposal-uuid",
|
||||
"vote": "for",
|
||||
"reason": "I support this change because..."
|
||||
}
|
||||
```
|
||||
|
||||
**Fields:**
|
||||
- `proposal_id`: ID of the proposal to vote on
|
||||
- `vote`: Vote option (`for`, `against`, `abstain`)
|
||||
- `reason` (optional): Reason for the vote (max 500 characters)
|
||||
|
||||
### Get Voting Power
|
||||
|
||||
Check a user's voting power.
|
||||
|
||||
```http
|
||||
GET /api/v1/governance/voting-power/{user_id}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"user_id": "user-address",
|
||||
"voting_power": 10000
|
||||
}
|
||||
```
|
||||
|
||||
### Execute Proposal
|
||||
|
||||
Execute an approved proposal.
|
||||
|
||||
```http
|
||||
POST /api/v1/governance/execute/{proposal_id}
|
||||
```
|
||||
|
||||
**Note:** Proposals can only be executed after:
|
||||
1. Voting period has ended
|
||||
2. Quorum threshold is met
|
||||
3. Approval threshold is met
|
||||
4. 24-hour execution delay has passed
|
||||
|
||||
## Proposal Types
|
||||
|
||||
### Parameter Change
|
||||
Modify system parameters like fees, limits, or thresholds.
|
||||
|
||||
**Example Target:**
|
||||
```json
|
||||
{
|
||||
"transaction_fee": "0.05",
|
||||
"min_stake_amount": "1000",
|
||||
"max_block_size": "2000"
|
||||
}
|
||||
```
|
||||
|
||||
### Protocol Upgrade
|
||||
Initiate a protocol upgrade with version changes.
|
||||
|
||||
**Example Target:**
|
||||
```json
|
||||
{
|
||||
"version": "1.2.0",
|
||||
"upgrade_type": "hard_fork",
|
||||
"activation_block": 1000000,
|
||||
"changes": {
|
||||
"new_features": ["feature1", "feature2"],
|
||||
"breaking_changes": ["change1"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Fund Allocation
|
||||
Allocate funds from the treasury.
|
||||
|
||||
**Example Target:**
|
||||
```json
|
||||
{
|
||||
"amount": "1000000",
|
||||
"recipient": "0x123...",
|
||||
"purpose": "Ecosystem development fund",
|
||||
"milestones": [
|
||||
{
|
||||
"description": "Phase 1 development",
|
||||
"amount": "500000",
|
||||
"deadline": "2025-06-30"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Policy Change
|
||||
Update governance or operational policies.
|
||||
|
||||
**Example Target:**
|
||||
```json
|
||||
{
|
||||
"policy_name": "voting_period",
|
||||
"new_value": "14 days",
|
||||
"rationale": "Longer voting period for better participation"
|
||||
}
|
||||
```
|
||||
|
||||
## Voting Process
|
||||
|
||||
1. **Proposal Creation**: Any user with sufficient voting power can create a proposal
|
||||
2. **Voting Period**: Token holders vote during the specified voting period
|
||||
3. **Quorum Check**: Minimum participation must be met
|
||||
4. **Approval Check**: Minimum approval ratio must be met
|
||||
5. **Execution Delay**: 24-hour delay before execution
|
||||
6. **Execution**: Approved changes are implemented
|
||||
|
||||
## Database Schema
|
||||
|
||||
### GovernanceProposal
|
||||
- `id`: Unique proposal identifier
|
||||
- `title`: Proposal title
|
||||
- `description`: Detailed description
|
||||
- `type`: Proposal type
|
||||
- `target`: Target configuration (JSON)
|
||||
- `proposer`: Address of the proposer
|
||||
- `status`: Current status
|
||||
- `created_at`: Creation timestamp
|
||||
- `voting_deadline`: End of voting period
|
||||
- `quorum_threshold`: Minimum participation required
|
||||
- `approval_threshold`: Minimum approval required
|
||||
- `executed_at`: Execution timestamp
|
||||
- `rejection_reason`: Reason for rejection
|
||||
|
||||
### ProposalVote
|
||||
- `id`: Unique vote identifier
|
||||
- `proposal_id`: Reference to proposal
|
||||
- `voter_id`: Address of the voter
|
||||
- `vote`: Vote choice (for/against/abstain)
|
||||
- `voting_power`: Power at time of vote
|
||||
- `reason`: Vote reason
|
||||
- `voted_at`: Vote timestamp
|
||||
|
||||
### TreasuryTransaction
|
||||
- `id`: Unique transaction identifier
|
||||
- `proposal_id`: Reference to proposal
|
||||
- `from_address`: Source address
|
||||
- `to_address`: Destination address
|
||||
- `amount`: Transfer amount
|
||||
- `status`: Transaction status
|
||||
- `transaction_hash`: Blockchain hash
|
||||
|
||||
## Security Considerations
|
||||
|
||||
1. **Voting Power**: Based on AITBC token holdings
|
||||
2. **Double Voting**: Prevented by tracking voter addresses
|
||||
3. **Execution Delay**: Prevents rush decisions
|
||||
4. **Quorum Requirements**: Ensures sufficient participation
|
||||
5. **Proposal Thresholds**: Prevents spam proposals
|
||||
|
||||
## Integration Guide
|
||||
|
||||
### Frontend Integration
|
||||
|
||||
```javascript
|
||||
// Fetch proposals
|
||||
const response = await fetch('/api/v1/governance/proposals');
|
||||
const proposals = await response.json();
|
||||
|
||||
// Submit vote
|
||||
await fetch('/api/v1/governance/vote', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
proposal_id: 'uuid',
|
||||
vote: 'for',
|
||||
reason: 'Support this proposal'
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
### Smart Contract Integration
|
||||
|
||||
The governance system can be integrated with smart contracts for:
|
||||
- On-chain voting
|
||||
- Automatic execution
|
||||
- Treasury management
|
||||
- Parameter enforcement
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Clear Proposals**: Provide detailed descriptions and rationales
|
||||
2. **Reasonable Thresholds**: Set achievable quorum and approval thresholds
|
||||
3. **Community Discussion**: Use forums for proposal discussion
|
||||
4. **Gradual Changes**: Implement major changes in phases
|
||||
5. **Monitoring**: Track proposal outcomes and system impact
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
1. **Delegated Voting**: Allow users to delegate voting power
|
||||
2. **Quadratic Voting**: Implement more sophisticated voting mechanisms
|
||||
3. **Time-locked Voting**: Lock tokens for voting power boosts
|
||||
4. **Multi-sig Execution**: Require multiple signatures for execution
|
||||
5. **Proposal Templates**: Standardize proposal formats
|
||||
|
||||
## Support
|
||||
|
||||
For governance-related questions:
|
||||
- Check the API documentation
|
||||
- Review proposal history
|
||||
- Contact the governance team
|
||||
- Participate in community discussions
|
||||
@ -147,6 +147,8 @@ nav:
|
||||
- Architecture: getting-started/architecture.md
|
||||
- User Guide:
|
||||
- Overview: user-guide/overview.md
|
||||
- Trade Exchange: trade_exchange.md
|
||||
- Zero-Knowledge Applications: zk-applications.md
|
||||
- Creating Jobs: user-guide/creating-jobs.md
|
||||
- Marketplace: user-guide/marketplace.md
|
||||
- Explorer: user-guide/explorer.md
|
||||
@ -166,6 +168,11 @@ nav:
|
||||
- Authentication: api/coordinator/authentication.md
|
||||
- Endpoints: api/coordinator/endpoints.md
|
||||
- OpenAPI Spec: api/coordinator/openapi.md
|
||||
- ZK Applications API:
|
||||
- Overview: api/zk/overview.md
|
||||
- Endpoints: api/zk/endpoints.md
|
||||
- Circuits: api/zk/circuits.md
|
||||
- OpenAPI Spec: api/zk/openapi.md
|
||||
- Blockchain Node API:
|
||||
- Overview: api/blockchain/overview.md
|
||||
- WebSocket API: api/blockchain/websocket.md
|
||||
|
||||
@ -75,7 +75,7 @@ metadata:
|
||||
spec:
|
||||
tls:
|
||||
- hosts:
|
||||
- api.aitbc.io
|
||||
- aitbc.bubuit.net
|
||||
secretName: api-tls
|
||||
```
|
||||
|
||||
@ -137,13 +137,13 @@ ingress:
|
||||
tls:
|
||||
- secretName: coordinator-tls
|
||||
hosts:
|
||||
- api.aitbc.io
|
||||
- aitbc.bubuit.net
|
||||
```
|
||||
|
||||
#### Blockchain Node RPC
|
||||
```yaml
|
||||
# WebSocket with TLS
|
||||
wss://api.aitbc.io:8080/ws
|
||||
wss://aitbc.bubuit.net/ws
|
||||
```
|
||||
|
||||
### 2. API Authentication Middleware
|
||||
|
||||
477
docs/partner-integration.md
Normal file
477
docs/partner-integration.md
Normal file
@ -0,0 +1,477 @@
|
||||
# Partner Integration Guide
|
||||
|
||||
This guide helps third-party services integrate with the AITBC platform for explorers, analytics, and other services.
|
||||
|
||||
## Overview
|
||||
|
||||
AITBC provides multiple integration points for partners:
|
||||
- REST APIs for real-time data
|
||||
- WebSocket streams for live updates
|
||||
- Export endpoints for bulk data
|
||||
- Webhook notifications for events
|
||||
|
||||
## Getting Started
|
||||
|
||||
### 1. Register Your Application
|
||||
|
||||
Register your service to get API credentials:
|
||||
|
||||
```bash
|
||||
curl -X POST https://aitbc.bubuit.net/api/v1/partners/register \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"name": "Your Service Name",
|
||||
"description": "Brief description of your service",
|
||||
"website": "https://yourservice.com",
|
||||
"contact": "contact@yourservice.com",
|
||||
"integration_type": "explorer"
|
||||
}'
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"partner_id": "partner-uuid",
|
||||
"api_key": "aitbc_xxxxxxxxxxxx",
|
||||
"api_secret": "secret_xxxxxxxxxxxx",
|
||||
"rate_limit": {
|
||||
"requests_per_minute": 1000,
|
||||
"requests_per_hour": 50000
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Authenticate Requests
|
||||
|
||||
Use your API credentials for authenticated requests:
|
||||
|
||||
```bash
|
||||
curl -H "Authorization: Bearer aitbc_xxxxxxxxxxxx" \
|
||||
https://aitbc.bubuit.net/api/explorer/blocks
|
||||
```
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### Blockchain Data
|
||||
|
||||
#### Get Latest Blocks
|
||||
```http
|
||||
GET /api/explorer/blocks?limit={limit}&offset={offset}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"blocks": [
|
||||
{
|
||||
"hash": "0x123...",
|
||||
"height": 1000000,
|
||||
"timestamp": "2025-12-28T18:00:00Z",
|
||||
"proposer": "0xabc...",
|
||||
"transaction_count": 150,
|
||||
"gas_used": "15000000",
|
||||
"size": 1024000
|
||||
}
|
||||
],
|
||||
"total": 1000000
|
||||
}
|
||||
```
|
||||
|
||||
#### Get Block Details
|
||||
```http
|
||||
GET /api/explorer/blocks/{block_hash}
|
||||
```
|
||||
|
||||
#### Get Transaction
|
||||
```http
|
||||
GET /api/explorer/transactions/{tx_hash}
|
||||
```
|
||||
|
||||
#### Get Address Details
|
||||
```http
|
||||
GET /api/explorer/addresses/{address}?transactions={true|false}
|
||||
```
|
||||
|
||||
### Marketplace Data
|
||||
|
||||
#### Get Active Offers
|
||||
```http
|
||||
GET /api/v1/marketplace/offers?status=active&limit={limit}
|
||||
```
|
||||
|
||||
#### Get Bid History
|
||||
```http
|
||||
GET /api/v1/marketplace/bids?offer_id={offer_id}
|
||||
```
|
||||
|
||||
#### Get Service Categories
|
||||
```http
|
||||
GET /api/v1/marketplace/services/categories
|
||||
```
|
||||
|
||||
### Analytics Data
|
||||
|
||||
#### Get Network Stats
|
||||
```http
|
||||
GET /api/v1/analytics/network/stats
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"total_blocks": 1000000,
|
||||
"total_transactions": 50000000,
|
||||
"active_addresses": 10000,
|
||||
"network_hashrate": 1500000000000,
|
||||
"average_block_time": 5.2,
|
||||
"marketplace_volume": {
|
||||
"24h": "1500000",
|
||||
"7d": "10000000",
|
||||
"30d": "40000000"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Get Historical Data
|
||||
```http
|
||||
GET /api/v1/analytics/historical?metric={metric}&period={period}&start={timestamp}&end={timestamp}
|
||||
```
|
||||
|
||||
**Metrics:**
|
||||
- `block_count`
|
||||
- `transaction_count`
|
||||
- `active_addresses`
|
||||
- `marketplace_volume`
|
||||
- `gas_price`
|
||||
|
||||
**Periods:**
|
||||
- `1h`, `1d`, `1w`, `1m`
|
||||
|
||||
## WebSocket Streams
|
||||
|
||||
Connect to the WebSocket for real-time updates:
|
||||
|
||||
```javascript
|
||||
const ws = new WebSocket('wss://aitbc.bubuit.net/ws');
|
||||
|
||||
// Authenticate
|
||||
ws.send(JSON.stringify({
|
||||
type: 'auth',
|
||||
api_key: 'aitbc_xxxxxxxxxxxx'
|
||||
}));
|
||||
|
||||
// Subscribe to blocks
|
||||
ws.send(JSON.stringify({
|
||||
type: 'subscribe',
|
||||
channel: 'blocks'
|
||||
}));
|
||||
|
||||
// Subscribe to transactions
|
||||
ws.send(JSON.stringify({
|
||||
type: 'subscribe',
|
||||
channel: 'transactions',
|
||||
filters: {
|
||||
to_address: '0xabc...'
|
||||
}
|
||||
}));
|
||||
|
||||
// Handle messages
|
||||
ws.onmessage = (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
console.log(data);
|
||||
};
|
||||
```
|
||||
|
||||
### Available Channels
|
||||
|
||||
- `blocks` - New blocks
|
||||
- `transactions` - New transactions
|
||||
- `marketplace_offers` - New marketplace offers
|
||||
- `marketplace_bids` - New bids
|
||||
- `governance` - Governance proposals and votes
|
||||
|
||||
## Bulk Data Export
|
||||
|
||||
### Export Blocks
|
||||
```http
|
||||
POST /api/v1/export/blocks
|
||||
```
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"start_block": 900000,
|
||||
"end_block": 1000000,
|
||||
"format": "json",
|
||||
"compression": "gzip"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"export_id": "export-uuid",
|
||||
"estimated_size": "500MB",
|
||||
"download_url": "https://aitbc.bubuit.net/api/v1/export/download/export-uuid"
|
||||
}
|
||||
```
|
||||
|
||||
### Export Transactions
|
||||
```http
|
||||
POST /api/v1/export/transactions
|
||||
```
|
||||
|
||||
## Webhooks
|
||||
|
||||
Configure webhooks to receive event notifications:
|
||||
|
||||
```bash
|
||||
curl -X POST https://aitbc.bubuit.net/api/v1/webhooks \
|
||||
-H "Authorization: Bearer aitbc_xxxxxxxxxxxx" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"url": "https://yourservice.com/webhook",
|
||||
"events": ["block.created", "transaction.confirmed"],
|
||||
"secret": "your_webhook_secret"
|
||||
}'
|
||||
```
|
||||
|
||||
**Webhook Payload:**
|
||||
```json
|
||||
{
|
||||
"event": "block.created",
|
||||
"timestamp": "2025-12-28T18:00:00Z",
|
||||
"data": {
|
||||
"block": {
|
||||
"hash": "0x123...",
|
||||
"height": 1000000,
|
||||
"proposer": "0xabc..."
|
||||
}
|
||||
},
|
||||
"signature": "sha256_signature"
|
||||
}
|
||||
```
|
||||
|
||||
Verify webhook signatures:
|
||||
```javascript
|
||||
const crypto = require('crypto');
|
||||
|
||||
function verifyWebhook(payload, signature, secret) {
|
||||
const expected = crypto
|
||||
.createHmac('sha256', secret)
|
||||
.update(payload)
|
||||
.digest('hex');
|
||||
|
||||
return crypto.timingSafeEqual(
|
||||
Buffer.from(signature),
|
||||
Buffer.from(expected)
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Rate Limits
|
||||
|
||||
API requests are rate-limited based on your partner tier:
|
||||
|
||||
| Tier | Requests/Minute | Requests/Hour | Features |
|
||||
|------|----------------|--------------|----------|
|
||||
| Basic | 100 | 5,000 | Public data |
|
||||
| Pro | 1,000 | 50,000 | + WebSocket |
|
||||
| Enterprise | 10,000 | 500,000 | + Bulk export |
|
||||
|
||||
Rate limit headers are included in responses:
|
||||
```
|
||||
X-RateLimit-Limit: 1000
|
||||
X-RateLimit-Remaining: 999
|
||||
X-RateLimit-Reset: 1640692800
|
||||
```
|
||||
|
||||
## SDKs and Libraries
|
||||
|
||||
### Python SDK
|
||||
```python
|
||||
from aitbc_sdk import AITBCClient
|
||||
|
||||
client = AITBCClient(
|
||||
api_key="aitbc_xxxxxxxxxxxx",
|
||||
base_url="https://aitbc.bubuit.net/api/v1"
|
||||
)
|
||||
|
||||
# Get latest block
|
||||
block = client.blocks.get_latest()
|
||||
print(f"Latest block: {block.height}")
|
||||
|
||||
# Stream transactions
|
||||
for tx in client.stream.transactions():
|
||||
print(f"New tx: {tx.hash}")
|
||||
```
|
||||
|
||||
### JavaScript SDK
|
||||
```javascript
|
||||
import { AITBCClient } from 'aitbc-sdk-js';
|
||||
|
||||
const client = new AITBCClient({
|
||||
apiKey: 'aitbc_xxxxxxxxxxxx',
|
||||
baseUrl: 'https://aitbc.bubuit.net/api/v1'
|
||||
});
|
||||
|
||||
// Get network stats
|
||||
const stats = await client.analytics.getNetworkStats();
|
||||
console.log('Network stats:', stats);
|
||||
|
||||
// Subscribe to blocks
|
||||
client.subscribe('blocks', (block) => {
|
||||
console.log('New block:', block);
|
||||
});
|
||||
```
|
||||
|
||||
## Explorer Integration Guide
|
||||
|
||||
### Display Blocks
|
||||
```html
|
||||
<div class="block-list">
|
||||
{% for block in blocks %}
|
||||
<div class="block-item">
|
||||
<a href="/block/{{ block.hash }}">
|
||||
Block #{{ block.height }}
|
||||
</a>
|
||||
<span class="timestamp">{{ block.timestamp }}</span>
|
||||
<span class="proposer">{{ block.proposer }}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
```
|
||||
|
||||
### Transaction Details
|
||||
```javascript
|
||||
async function showTransaction(txHash) {
|
||||
const tx = await client.transactions.get(txHash);
|
||||
|
||||
document.getElementById('tx-hash').textContent = tx.hash;
|
||||
document.getElementById('tx-status').textContent = tx.status;
|
||||
document.getElementById('tx-from').textContent = tx.from_address;
|
||||
document.getElementById('tx-to').textContent = tx.to_address;
|
||||
document.getElementById('tx-amount').textContent = tx.amount;
|
||||
document.getElementById('tx-gas').textContent = tx.gas_used;
|
||||
|
||||
// Show events
|
||||
const events = await client.transactions.getEvents(txHash);
|
||||
renderEvents(events);
|
||||
}
|
||||
```
|
||||
|
||||
### Address Activity
|
||||
```javascript
|
||||
async function loadAddress(address) {
|
||||
const [balance, transactions, tokens] = await Promise.all([
|
||||
client.addresses.getBalance(address),
|
||||
client.addresses.getTransactions(address),
|
||||
client.addresses.getTokens(address)
|
||||
]);
|
||||
|
||||
updateBalance(balance);
|
||||
renderTransactions(transactions);
|
||||
renderTokens(tokens);
|
||||
}
|
||||
```
|
||||
|
||||
## Analytics Integration
|
||||
|
||||
### Custom Dashboards
|
||||
```python
|
||||
import plotly.graph_objects as go
|
||||
from aitbc_sdk import AITBCClient
|
||||
|
||||
client = AITBCClient(api_key="your_key")
|
||||
|
||||
# Get historical data
|
||||
data = client.analytics.get_historical(
|
||||
metric='transaction_count',
|
||||
period='1d',
|
||||
start='2025-01-01',
|
||||
end='2025-12-28'
|
||||
)
|
||||
|
||||
# Create chart
|
||||
fig = go.Figure()
|
||||
fig.add_trace(go.Scatter(
|
||||
x=data.timestamps,
|
||||
y=data.values,
|
||||
mode='lines',
|
||||
name='Transactions per Day'
|
||||
))
|
||||
|
||||
fig.show()
|
||||
```
|
||||
|
||||
### Real-time Monitoring
|
||||
```javascript
|
||||
const client = new AITBCClient({ apiKey: 'your_key' });
|
||||
|
||||
// Monitor network health
|
||||
client.subscribe('blocks', (block) => {
|
||||
const blockTime = calculateBlockTime(block);
|
||||
updateBlockTimeMetric(blockTime);
|
||||
|
||||
if (blockTime > 10) {
|
||||
alert('Block time is high!');
|
||||
}
|
||||
});
|
||||
|
||||
// Monitor marketplace activity
|
||||
client.subscribe('marketplace_bids', (bid) => {
|
||||
updateBidChart(bid);
|
||||
checkForAnomalies(bid);
|
||||
});
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Caching**: Cache frequently accessed data
|
||||
2. **Pagination**: Use pagination for large datasets
|
||||
3. **Error Handling**: Implement proper error handling
|
||||
4. **Rate Limiting**: Respect rate limits and implement backoff
|
||||
5. **Security**: Keep API keys secure and use HTTPS
|
||||
6. **Webhooks**: Verify webhook signatures
|
||||
7. **Monitoring**: Monitor your API usage and performance
|
||||
|
||||
## Support
|
||||
|
||||
For integration support:
|
||||
- Documentation: https://aitbc.bubuit.net/docs/
|
||||
- API Reference: https://aitbc.bubuit.net/api/v1/docs
|
||||
- Email: partners@aitbc.io
|
||||
- Discord: https://discord.gg/aitbc
|
||||
|
||||
## Example Implementations
|
||||
|
||||
### Block Explorer
|
||||
- GitHub: https://github.com/aitbc/explorer-example
|
||||
- Demo: https://explorer.aitbc-example.com
|
||||
|
||||
### Analytics Platform
|
||||
- GitHub: https://github.com/aitbc/analytics-example
|
||||
- Demo: https://analytics.aitbc-example.com
|
||||
|
||||
### Mobile App
|
||||
- GitHub: https://github.com/aitbc/mobile-example
|
||||
- iOS: https://apps.apple.com/aitbc-wallet
|
||||
- Android: https://play.google.com/aitbc-wallet
|
||||
|
||||
## Changelog
|
||||
|
||||
### v1.2.0 (2025-12-28)
|
||||
- Added governance endpoints
|
||||
- Improved WebSocket reliability
|
||||
- New analytics metrics
|
||||
|
||||
### v1.1.0 (2025-12-15)
|
||||
- Added bulk export API
|
||||
- Webhook support
|
||||
- Python SDK improvements
|
||||
|
||||
### v1.0.0 (2025-12-01)
|
||||
- Initial release
|
||||
- REST API v1
|
||||
- WebSocket streams
|
||||
- JavaScript SDK
|
||||
@ -498,7 +498,7 @@ from aitbc import AITBCClient, HTTPTransport
|
||||
|
||||
# Create client with HTTP transport
|
||||
transport = HTTPTransport({
|
||||
'base_url': 'https://api.aitbc.io',
|
||||
'base_url': 'https://aitbc.bubuit.net/api',
|
||||
'timeout': 30,
|
||||
'default_headers': {'X-API-Key': 'your-key'}
|
||||
})
|
||||
@ -520,7 +520,7 @@ config = {
|
||||
'ethereum': {
|
||||
'type': 'http',
|
||||
'chain_id': 1,
|
||||
'base_url': 'https://api.aitbc.io',
|
||||
'base_url': 'https://aitbc.bubuit.net/api',
|
||||
'default': True
|
||||
},
|
||||
'polygon': {
|
||||
|
||||
@ -94,7 +94,7 @@ This roadmap aggregates high-priority tasks derived from the bootstrap specifica
|
||||
- ✅ Implement styling system, mock/live data toggle, and coordinator API wiring scaffold.
|
||||
- ✅ Render overview stats from mock block/transaction/receipt summaries with graceful empty-state fallbacks.
|
||||
- ✅ Validate live mode + responsive polish:
|
||||
- Hit live coordinator endpoints (`/v1/blocks`, `/v1/transactions`, `/v1/addresses`, `/v1/receipts`) via `getDataMode() === "live"` and reconcile payloads with UI models.
|
||||
- Hit live coordinator endpoints via nginx (`/api/explorer/blocks`, `/api/explorer/transactions`, `/api/explorer/addresses`, `/api/explorer/receipts`) via `getDataMode() === "live"` and reconcile payloads with UI models.
|
||||
- Add fallbacks + error surfacing for partial/failed live responses (toast + console diagnostics).
|
||||
- Audit responsive breakpoints (`public/css/layout.css`) and adjust grid/typography for tablet + mobile; add regression checks in Percy/Playwright snapshots.
|
||||
- ✅ Deploy to production at https://aitbc.bubuit.net/explorer/ with genesis block display
|
||||
@ -151,7 +151,7 @@ This roadmap aggregates high-priority tasks derived from the bootstrap specifica
|
||||
- 🔄 Provide SLA-backed coordinator/pool hubs with capacity planning and billing instrumentation.
|
||||
|
||||
- **Developer Experience**
|
||||
- 🔄 Publish advanced tutorials (custom proposers, marketplace extensions) and maintain versioned API docs.
|
||||
- ✅ Publish advanced tutorials (custom proposers, marketplace extensions) and maintain versioned API docs.
|
||||
- 🔄 Integrate CI/CD pipelines with canary deployments and blue/green release automation.
|
||||
- 🔄 Host quarterly architecture reviews capturing lessons learned and feeding into roadmap revisions.
|
||||
|
||||
@ -235,5 +235,85 @@ This roadmap aggregates high-priority tasks derived from the bootstrap specifica
|
||||
|
||||
|
||||
## Shared Libraries & Examples
|
||||
|
||||
## Stage 11 — Trade Exchange & Token Economy [COMPLETED: 2025-12-28]
|
||||
|
||||
- **Bitcoin Wallet Integration**
|
||||
- ✅ Implement Bitcoin payment gateway for AITBC token purchases
|
||||
- ✅ Create payment request API with unique payment addresses
|
||||
- ✅ Add QR code generation for mobile payments
|
||||
- ✅ Implement real-time payment monitoring with blockchain API
|
||||
- ✅ Configure exchange rate: 1 BTC = 100,000 AITBC
|
||||
|
||||
- **User Management System**
|
||||
- ✅ Implement wallet-based authentication with session management
|
||||
- ✅ Create individual user accounts with unique wallets
|
||||
- ✅ Add user profile pages with transaction history
|
||||
- ✅ Implement secure session tokens with 24-hour expiry
|
||||
- ✅ Add login/logout functionality across all pages
|
||||
|
||||
- **Trade Exchange Platform**
|
||||
- ✅ Build responsive trading interface with real-time price updates
|
||||
- ✅ Integrate Bitcoin payment flow with QR code display
|
||||
- ✅ Add payment status monitoring and confirmation handling
|
||||
- ✅ Implement AITBC token minting upon payment confirmation
|
||||
- ✅ Deploy to production at https://aitbc.bubuit.net/Exchange/
|
||||
|
||||
- **API Infrastructure**
|
||||
- ✅ Add user management endpoints (/api/users/*)
|
||||
- ✅ Implement exchange payment endpoints (/api/exchange/*)
|
||||
- ✅ Add session-based authentication for protected routes
|
||||
- ✅ Create transaction history and balance tracking APIs
|
||||
- ✅ Fix all import and syntax errors in coordinator API
|
||||
|
||||
## Stage 13 — Explorer Live API & Reverse Proxy Fixes [COMPLETED: 2025-12-28]
|
||||
|
||||
- **Explorer Live API**
|
||||
- ✅ Enable coordinator explorer routes at `/v1/explorer/*`.
|
||||
- ✅ Expose nginx explorer proxy at `/api/explorer/*` (maps to backend `/v1/explorer/*`).
|
||||
- ✅ Fix response schema mismatches (e.g., receipts response uses `jobId`).
|
||||
|
||||
- **Coordinator API Users/Login**
|
||||
- ✅ Ensure `/v1/users/login` is registered and working.
|
||||
- ✅ Fix missing SQLModel tables by initializing DB on startup (wallet/user tables created).
|
||||
|
||||
- **nginx Reverse Proxy Hardening**
|
||||
- ✅ Fix `/api/v1/*` routing to avoid double `/v1` prefix.
|
||||
- ✅ Add compatibility proxy for Exchange: `/api/users/*` → backend `/v1/users/*`.
|
||||
|
||||
## Stage 12 — Zero-Knowledge Proof Implementation [COMPLETED: 2025-12-28]
|
||||
|
||||
- **Circom Compiler Setup**
|
||||
- ✅ Install Circom compiler v2.2.3 on production server
|
||||
- ✅ Configure Node.js environment for ZK circuit compilation
|
||||
- ✅ Install circomlib and required dependencies
|
||||
|
||||
- **ZK Circuit Development**
|
||||
- ✅ Create receipt attestation circuit (receipt_simple.circom)
|
||||
- ✅ Implement membership proof circuit template
|
||||
- ✅ Implement bid range proof circuit template
|
||||
- ✅ Compile circuits to R1CS, WASM, and symbolic files
|
||||
|
||||
- **Trusted Setup Ceremony**
|
||||
- ✅ Perform Powers of Tau setup ceremony (2^12)
|
||||
- ✅ Generate proving keys (zkey) for Groth16
|
||||
- ✅ Export verification keys for on-chain verification
|
||||
- ✅ Complete phase 2 preparation with contributions
|
||||
|
||||
- **ZK Applications API**
|
||||
- ✅ Implement identity commitment endpoints
|
||||
- ✅ Create stealth address generation service
|
||||
- ✅ Add private receipt attestation API
|
||||
- ✅ Implement group membership proof verification
|
||||
- ✅ Add private bidding functionality
|
||||
- ✅ Create computation proof verification
|
||||
- ✅ Deploy to production at /api/zk/ endpoints
|
||||
|
||||
- **Integration & Deployment**
|
||||
- ✅ Integrate ZK proof service with coordinator API
|
||||
- ✅ Configure circuit files in production environment
|
||||
- ✅ Enable ZK proof generation in coordinator service
|
||||
- ✅ Update documentation with ZK capabilities
|
||||
|
||||
the canonical checklist during implementation. Mark completed tasks with ✅ and add dates or links to relevant PRs as development progresses.
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ def extract_openapi_spec(service_name: str, base_url: str, output_file: str):
|
||||
# Add servers configuration
|
||||
spec["servers"] = [
|
||||
{
|
||||
"url": "https://api.aitbc.io",
|
||||
"url": "https://aitbc.bubuit.net/api",
|
||||
"description": "Production server"
|
||||
},
|
||||
{
|
||||
|
||||
258
docs/trade_exchange.md
Normal file
258
docs/trade_exchange.md
Normal file
@ -0,0 +1,258 @@
|
||||
# Trade Exchange Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
The AITBC Trade Exchange is a web platform that allows users to buy AITBC tokens using Bitcoin. It features a modern, responsive interface with user authentication, wallet management, and real-time trading capabilities.
|
||||
|
||||
## Features
|
||||
|
||||
### Bitcoin Wallet Integration
|
||||
- **Payment Gateway**: Buy AITBC tokens with Bitcoin
|
||||
- **QR Code Support**: Mobile-friendly payment QR codes
|
||||
- **Real-time Monitoring**: Automatic payment confirmation tracking
|
||||
- **Exchange Rate**: 1 BTC = 100,000 AITBC (configurable)
|
||||
|
||||
### User Management
|
||||
- **Wallet-based Authentication**: No passwords required
|
||||
- **Individual Accounts**: Each user has a unique wallet and balance
|
||||
- **Session Security**: 24-hour token-based sessions
|
||||
- **Profile Management**: View transaction history and account details
|
||||
|
||||
### Trading Interface
|
||||
- **Live Prices**: Real-time exchange rate updates
|
||||
- **Payment Tracking**: Monitor Bitcoin payments and AITBC credits
|
||||
- **Transaction History**: Complete record of all trades
|
||||
- **Mobile Responsive**: Works on all devices
|
||||
|
||||
## Getting Started
|
||||
|
||||
### 1. Access the Exchange
|
||||
Visit: https://aitbc.bubuit.net/Exchange/
|
||||
|
||||
### 2. Connect Your Wallet
|
||||
1. Click "Connect Wallet" in the navigation
|
||||
2. A unique wallet address is generated
|
||||
3. Your user account is created automatically
|
||||
|
||||
### 3. Buy AITBC Tokens
|
||||
1. Navigate to the Trade section
|
||||
2. Enter the amount of AITBC you want to buy
|
||||
3. The Bitcoin equivalent is calculated
|
||||
4. Click "Create Payment Request"
|
||||
5. Send Bitcoin to the provided address
|
||||
6. Wait for confirmation (1 confirmation needed)
|
||||
7. AITBC tokens are credited to your wallet
|
||||
|
||||
## API Reference
|
||||
|
||||
### User Management
|
||||
|
||||
#### Login/Register
|
||||
```http
|
||||
POST /api/users/login
|
||||
{
|
||||
"wallet_address": "aitbc1abc123..."
|
||||
}
|
||||
```
|
||||
|
||||
Canonical route (same backend, without compatibility proxy):
|
||||
```http
|
||||
POST /api/v1/users/login
|
||||
{
|
||||
"wallet_address": "aitbc1abc123..."
|
||||
}
|
||||
```
|
||||
|
||||
#### Get User Profile
|
||||
```http
|
||||
GET /api/users/me
|
||||
Headers: X-Session-Token: <token>
|
||||
```
|
||||
|
||||
Canonical route:
|
||||
```http
|
||||
GET /api/v1/users/users/me
|
||||
Headers: X-Session-Token: <token>
|
||||
```
|
||||
|
||||
#### Get User Balance
|
||||
```http
|
||||
GET /api/users/{user_id}/balance
|
||||
Headers: X-Session-Token: <token>
|
||||
```
|
||||
|
||||
Canonical route:
|
||||
```http
|
||||
GET /api/v1/users/users/{user_id}/balance
|
||||
Headers: X-Session-Token: <token>
|
||||
```
|
||||
|
||||
#### Logout
|
||||
```http
|
||||
POST /api/users/logout
|
||||
Headers: X-Session-Token: <token>
|
||||
```
|
||||
|
||||
Canonical route:
|
||||
```http
|
||||
POST /api/v1/users/logout
|
||||
Headers: X-Session-Token: <token>
|
||||
```
|
||||
|
||||
### Exchange Operations
|
||||
|
||||
#### Create Payment Request
|
||||
```http
|
||||
POST /api/exchange/create-payment
|
||||
{
|
||||
"user_id": "uuid",
|
||||
"aitbc_amount": 1000,
|
||||
"btc_amount": 0.01
|
||||
}
|
||||
Headers: X-Session-Token: <token>
|
||||
```
|
||||
|
||||
#### Check Payment Status
|
||||
```http
|
||||
GET /api/exchange/payment-status/{payment_id}
|
||||
```
|
||||
|
||||
#### Get Exchange Rates
|
||||
```http
|
||||
GET /api/exchange/rates
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Bitcoin Settings
|
||||
- **Network**: Bitcoin Testnet (for demo)
|
||||
- **Confirmations Required**: 1
|
||||
- **Payment Timeout**: 1 hour
|
||||
- **Main Address**: tb1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh
|
||||
|
||||
### Exchange Settings
|
||||
- **Rate**: 1 BTC = 100,000 AITBC
|
||||
- **Fee**: 0.5% transaction fee
|
||||
- **Min Payment**: 0.0001 BTC
|
||||
- **Max Payment**: 10 BTC
|
||||
|
||||
## Security
|
||||
|
||||
### Authentication
|
||||
- **Session Tokens**: SHA-256 hashed tokens
|
||||
- **Expiry**: 24 hours automatic timeout
|
||||
- **Storage**: Server-side session management
|
||||
|
||||
### Privacy
|
||||
- **User Isolation**: Each user has private data
|
||||
- **No Tracking**: No personal data collected
|
||||
- **GDPR Compliant**: Minimal data retention
|
||||
|
||||
## Development
|
||||
|
||||
### Frontend Stack
|
||||
- **HTML5**: Semantic markup
|
||||
- **CSS3**: TailwindCSS for styling
|
||||
- **JavaScript**: Vanilla JS with Axios
|
||||
- **Lucide Icons**: Modern icon library
|
||||
|
||||
### Backend Stack
|
||||
- **FastAPI**: Python web framework
|
||||
- **SQLModel**: Database ORM
|
||||
- **SQLite**: Development database
|
||||
- **Pydantic**: Data validation
|
||||
|
||||
### File Structure
|
||||
```
|
||||
apps/trade-exchange/
|
||||
├── index.html # Main application
|
||||
├── bitcoin-wallet.py # Bitcoin integration
|
||||
└── README.md # Setup instructions
|
||||
|
||||
apps/coordinator-api/src/app/
|
||||
├── routers/
|
||||
│ ├── users.py # User management
|
||||
│ └── exchange.py # Exchange operations
|
||||
├── domain/
|
||||
│ └── user.py # User models
|
||||
└── schemas.py # API schemas
|
||||
```
|
||||
|
||||
## Deployment
|
||||
|
||||
### Production
|
||||
- **URL**: https://aitbc.bubuit.net/Exchange/
|
||||
- **SSL**: Fully configured
|
||||
- **CDN**: Nginx static serving
|
||||
- **API**: /api/v1/* endpoints
|
||||
|
||||
### Environment Variables
|
||||
```bash
|
||||
BITCOIN_TESTNET=true
|
||||
BITCOIN_ADDRESS=tb1q...
|
||||
BTC_TO_AITBC_RATE=100000
|
||||
MIN_CONFIRMATIONS=1
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
### Testnet Bitcoin
|
||||
Get free testnet Bitcoin from:
|
||||
- https://testnet-faucet.mempool.co/
|
||||
- https://coinfaucet.eu/en/btc-testnet/
|
||||
|
||||
### Demo Mode
|
||||
- No real Bitcoin required
|
||||
- Simulated payments for testing
|
||||
- Auto-generated wallet addresses
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
**Payment Not Showing**
|
||||
- Check transaction has 1 confirmation
|
||||
- Verify correct amount sent
|
||||
- Refresh the page
|
||||
|
||||
**Can't Connect Wallet**
|
||||
- Check JavaScript is enabled
|
||||
- Clear browser cache
|
||||
- Try a different browser
|
||||
|
||||
**Balance Incorrect**
|
||||
- Wait for blockchain sync
|
||||
- Check transaction history
|
||||
- Contact support
|
||||
|
||||
### Logs
|
||||
Check application logs:
|
||||
```bash
|
||||
journalctl -u aitbc-coordinator -f
|
||||
```
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
### Planned Features
|
||||
- [ ] MetaMask wallet support
|
||||
- [ ] Advanced trading charts
|
||||
- [ ] Limit orders
|
||||
- [ ] Mobile app
|
||||
- [ ] Multi-currency support
|
||||
|
||||
### Technical Improvements
|
||||
- [ ] Redis session storage
|
||||
- [ ] PostgreSQL database
|
||||
- [ ] Microservices architecture
|
||||
- [ ] WebSocket real-time updates
|
||||
|
||||
## Support
|
||||
|
||||
For help or questions:
|
||||
- **Documentation**: https://aitbc.bubuit.net/docs/
|
||||
- **API Docs**: https://aitbc.bubuit.net/api/docs
|
||||
- **Admin Panel**: https://aitbc.bubuit.net/admin/stats
|
||||
|
||||
## License
|
||||
|
||||
This project is part of the AITBC ecosystem. See the main repository for license information.
|
||||
390
docs/tutorials/custom-proposer.md
Normal file
390
docs/tutorials/custom-proposer.md
Normal file
@ -0,0 +1,390 @@
|
||||
# Building Custom Proposers in AITBC
|
||||
|
||||
This tutorial guides you through creating custom proposers for the AITBC blockchain network. Custom proposers allow you to implement specialized block proposal logic tailored to your specific use case.
|
||||
|
||||
## Overview
|
||||
|
||||
In AITBC, proposers are responsible for creating new blocks in the Proof of Authority (PoA) consensus. While the default proposer works for most cases, you might need custom logic for:
|
||||
- Priority-based transaction ordering
|
||||
- Specialized transaction selection
|
||||
- Custom block validation rules
|
||||
- Integration with external systems
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Python 3.8+
|
||||
- AITBC blockchain node running
|
||||
- Understanding of PoA consensus
|
||||
- Development environment set up
|
||||
|
||||
## Step 1: Create a Custom Proposer Class
|
||||
|
||||
Start by creating a new file for your custom proposer:
|
||||
|
||||
```python
|
||||
# custom_proposer.py
|
||||
from typing import List, Optional
|
||||
from datetime import datetime
|
||||
from aitbc_chain.models import Block, Transaction
|
||||
from aitbc_chain.consensus.base import BaseProposer
|
||||
from aitbc_chain.config import ProposerConfig
|
||||
|
||||
class PriorityProposer(BaseProposer):
|
||||
"""
|
||||
A custom proposer that prioritizes transactions by fee and priority score.
|
||||
"""
|
||||
|
||||
def __init__(self, config: ProposerConfig):
|
||||
super().__init__(config)
|
||||
self.min_priority_score = config.get("min_priority_score", 0)
|
||||
self.max_block_size = config.get("max_block_size", 1000)
|
||||
|
||||
async def select_transactions(
|
||||
self,
|
||||
pending_txs: List[Transaction],
|
||||
current_block: Optional[Block] = None
|
||||
) -> List[Transaction]:
|
||||
"""
|
||||
Select and order transactions based on priority.
|
||||
"""
|
||||
# Filter transactions by minimum priority
|
||||
filtered_txs = [
|
||||
tx for tx in pending_txs
|
||||
if self._calculate_priority(tx) >= self.min_priority_score
|
||||
]
|
||||
|
||||
# Sort by priority (highest first)
|
||||
sorted_txs = sorted(
|
||||
filtered_txs,
|
||||
key=self._calculate_priority,
|
||||
reverse=True
|
||||
)
|
||||
|
||||
# Limit block size
|
||||
return sorted_txs[:self.max_block_size]
|
||||
|
||||
def _calculate_priority(self, tx: Transaction) -> int:
|
||||
"""
|
||||
Calculate transaction priority score.
|
||||
"""
|
||||
# Base priority from fee
|
||||
fee_priority = tx.fee or 0
|
||||
|
||||
# Bonus for specific transaction types
|
||||
type_bonus = {
|
||||
"computation": 10,
|
||||
"settlement": 5,
|
||||
"transfer": 1
|
||||
}.get(tx.type, 0)
|
||||
|
||||
# Time-based priority (older transactions get higher priority)
|
||||
age_bonus = max(0, (datetime.utcnow() - tx.timestamp).seconds // 60)
|
||||
|
||||
return fee_priority + type_bonus + age_bonus
|
||||
```
|
||||
|
||||
## Step 2: Implement Custom Block Validation
|
||||
|
||||
Add custom validation logic for your blocks:
|
||||
|
||||
```python
|
||||
# custom_proposer.py (continued)
|
||||
from aitbc_chain.consensus.exceptions import InvalidBlockException
|
||||
|
||||
class PriorityProposer(BaseProposer):
|
||||
# ... previous code ...
|
||||
|
||||
async def validate_block(
|
||||
self,
|
||||
block: Block,
|
||||
parent_block: Optional[Block] = None
|
||||
) -> bool:
|
||||
"""
|
||||
Validate block with custom rules.
|
||||
"""
|
||||
# Run standard validation first
|
||||
if not await super().validate_block(block, parent_block):
|
||||
return False
|
||||
|
||||
# Custom validation: check minimum priority threshold
|
||||
if block.transactions:
|
||||
min_priority = min(
|
||||
self._calculate_priority(tx)
|
||||
for tx in block.transactions
|
||||
)
|
||||
|
||||
if min_priority < self.min_priority_score:
|
||||
raise InvalidBlockException(
|
||||
f"Block contains transactions below priority threshold"
|
||||
)
|
||||
|
||||
# Custom validation: ensure proposer diversity
|
||||
if parent_block and block.proposer == parent_block.proposer:
|
||||
# Allow consecutive blocks only if underutilized
|
||||
utilization = len(block.transactions) / self.max_block_size
|
||||
if utilization > 0.5:
|
||||
raise InvalidBlockException(
|
||||
"Consecutive blocks from same proposer not allowed"
|
||||
)
|
||||
|
||||
return True
|
||||
```
|
||||
|
||||
## Step 3: Register Your Custom Proposer
|
||||
|
||||
Register your proposer with the blockchain node:
|
||||
|
||||
```python
|
||||
# node_config.py
|
||||
from custom_proposer import PriorityProposer
|
||||
from aitbc_chain.config import ProposerConfig
|
||||
|
||||
def create_custom_proposer():
|
||||
"""Create and configure the custom proposer."""
|
||||
config = ProposerConfig({
|
||||
"min_priority_score": 5,
|
||||
"max_block_size": 500,
|
||||
"proposer_address": "0xYOUR_PROPOSER_ADDRESS",
|
||||
"signing_key": "YOUR_PRIVATE_KEY"
|
||||
})
|
||||
|
||||
return PriorityProposer(config)
|
||||
|
||||
# In your node initialization
|
||||
proposer = create_custom_proposer()
|
||||
node.set_proposer(proposer)
|
||||
```
|
||||
|
||||
## Step 4: Add Monitoring and Metrics
|
||||
|
||||
Track your proposer's performance:
|
||||
|
||||
```python
|
||||
# custom_proposer.py (continued)
|
||||
from prometheus_client import Counter, Histogram, Gauge
|
||||
|
||||
class PriorityProposer(BaseProposer):
|
||||
# ... previous code ...
|
||||
|
||||
def __init__(self, config: ProposerConfig):
|
||||
super().__init__(config)
|
||||
|
||||
# Metrics
|
||||
self.blocks_proposed = Counter(
|
||||
'blocks_proposed_total',
|
||||
'Total number of blocks proposed',
|
||||
['proposer_type']
|
||||
)
|
||||
self.tx_selected = Histogram(
|
||||
'transactions_selected_per_block',
|
||||
'Number of transactions selected per block'
|
||||
)
|
||||
self.avg_priority = Gauge(
|
||||
'average_transaction_priority',
|
||||
'Average priority of selected transactions'
|
||||
)
|
||||
|
||||
async def propose_block(
|
||||
self,
|
||||
pending_txs: List[Transaction]
|
||||
) -> Optional[Block]:
|
||||
"""
|
||||
Propose a new block with metrics tracking.
|
||||
"""
|
||||
selected_txs = await self.select_transactions(pending_txs)
|
||||
|
||||
if not selected_txs:
|
||||
return None
|
||||
|
||||
# Create block
|
||||
block = await self._create_block(selected_txs)
|
||||
|
||||
# Update metrics
|
||||
self.blocks_proposed.labels(proposer_type='priority').inc()
|
||||
self.tx_selected.observe(len(selected_txs))
|
||||
|
||||
if selected_txs:
|
||||
avg_prio = sum(
|
||||
self._calculate_priority(tx)
|
||||
for tx in selected_txs
|
||||
) / len(selected_txs)
|
||||
self.avg_priority.set(avg_prio)
|
||||
|
||||
return block
|
||||
```
|
||||
|
||||
## Step 5: Test Your Custom Proposer
|
||||
|
||||
Create tests for your proposer:
|
||||
|
||||
```python
|
||||
# test_custom_proposer.py
|
||||
import pytest
|
||||
from custom_proposer import PriorityProposer
|
||||
from aitbc_chain.models import Transaction
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
@pytest.fixture
|
||||
def proposer():
|
||||
config = ProposerConfig({
|
||||
"min_priority_score": 5,
|
||||
"max_block_size": 10
|
||||
})
|
||||
return PriorityProposer(config)
|
||||
|
||||
@pytest.fixture
|
||||
def sample_transactions():
|
||||
txs = []
|
||||
for i in range(20):
|
||||
tx = Transaction(
|
||||
id=f"tx_{i}",
|
||||
fee=i * 2,
|
||||
type="computation" if i % 3 == 0 else "transfer",
|
||||
timestamp=datetime.utcnow() - timedelta(minutes=i)
|
||||
)
|
||||
txs.append(tx)
|
||||
return txs
|
||||
|
||||
async def test_transaction_selection(proposer, sample_transactions):
|
||||
"""Test that high-priority transactions are selected."""
|
||||
selected = await proposer.select_transactions(sample_transactions)
|
||||
|
||||
# Should select max_block_size transactions
|
||||
assert len(selected) == 10
|
||||
|
||||
# Should be sorted by priority (highest first)
|
||||
priorities = [proposer._calculate_priority(tx) for tx in selected]
|
||||
assert priorities == sorted(priorities, reverse=True)
|
||||
|
||||
# All should meet minimum priority
|
||||
assert all(p >= 5 for p in priorities)
|
||||
|
||||
async def test_priority_calculation(proposer):
|
||||
"""Test priority calculation logic."""
|
||||
high_fee_tx = Transaction(id="1", fee=100, type="computation")
|
||||
low_fee_tx = Transaction(id="2", fee=1, type="transfer")
|
||||
|
||||
high_priority = proposer._calculate_priority(high_fee_tx)
|
||||
low_priority = proposer._calculate_priority(low_fee_tx)
|
||||
|
||||
assert high_priority > low_priority
|
||||
```
|
||||
|
||||
## Advanced Features
|
||||
|
||||
### 1. Dynamic Priority Adjustment
|
||||
|
||||
```python
|
||||
class AdaptiveProposer(PriorityProposer):
|
||||
"""Proposer that adjusts priority based on network conditions."""
|
||||
|
||||
async def adjust_priority_threshold(self):
|
||||
"""Dynamically adjust minimum priority based on pending transactions."""
|
||||
pending_count = await self.get_pending_transaction_count()
|
||||
|
||||
if pending_count > 1000:
|
||||
self.min_priority_score = 10 # Increase threshold
|
||||
elif pending_count < 100:
|
||||
self.min_priority_score = 1 # Lower threshold
|
||||
```
|
||||
|
||||
### 2. MEV Protection
|
||||
|
||||
```python
|
||||
class MEVProtectedProposer(PriorityProposer):
|
||||
"""Proposer with MEV (Maximum Extractable Value) protection."""
|
||||
|
||||
async def select_transactions(self, pending_txs):
|
||||
"""Select transactions while preventing MEV extraction."""
|
||||
# Group related transactions
|
||||
tx_groups = self._group_related_transactions(pending_txs)
|
||||
|
||||
# Process groups atomically
|
||||
selected = []
|
||||
for group in tx_groups:
|
||||
if self._validate_mev_safety(group):
|
||||
selected.extend(group)
|
||||
|
||||
return selected[:self.max_block_size]
|
||||
```
|
||||
|
||||
### 3. Cross-Shard Coordination
|
||||
|
||||
```python
|
||||
class ShardAwareProposer(BaseProposer):
|
||||
"""Proposer that coordinates across multiple shards."""
|
||||
|
||||
async def coordinate_with_shards(self, block):
|
||||
"""Coordinate block proposal with other shards."""
|
||||
# Get cross-shard dependencies
|
||||
dependencies = await self.get_cross_shard_deps(block.transactions)
|
||||
|
||||
# Wait for confirmations from other shards
|
||||
await self.wait_for_shard_confirmations(dependencies)
|
||||
|
||||
return block
|
||||
```
|
||||
|
||||
## Deployment
|
||||
|
||||
1. **Package your proposer**:
|
||||
```bash
|
||||
pip install -e .
|
||||
```
|
||||
|
||||
2. **Update node configuration**:
|
||||
```yaml
|
||||
# config.yaml
|
||||
proposer:
|
||||
type: custom
|
||||
module: my_proposers.PriorityProposer
|
||||
config:
|
||||
min_priority_score: 5
|
||||
max_block_size: 500
|
||||
```
|
||||
|
||||
3. **Restart the node**:
|
||||
```bash
|
||||
sudo systemctl restart aitbc-node
|
||||
```
|
||||
|
||||
## Monitoring
|
||||
|
||||
Monitor your proposer's performance with Grafana dashboards:
|
||||
- Block proposal rate
|
||||
- Transaction selection efficiency
|
||||
- Average priority scores
|
||||
- MEV protection metrics
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Keep proposers simple** - Complex logic can cause delays
|
||||
2. **Test thoroughly** - Use testnet before mainnet deployment
|
||||
3. **Monitor performance** - Track metrics and optimize
|
||||
4. **Handle edge cases** - Empty blocks, network partitions
|
||||
5. **Document behavior** - Clear documentation for custom logic
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Blocks not being proposed**
|
||||
- Check proposer registration
|
||||
- Verify signing key
|
||||
- Review logs for errors
|
||||
|
||||
2. **Low transaction throughput**
|
||||
- Adjust priority thresholds
|
||||
- Check block size limits
|
||||
- Optimize selection logic
|
||||
|
||||
3. **Invalid blocks**
|
||||
- Review validation rules
|
||||
- Check transaction ordering
|
||||
- Verify signatures
|
||||
|
||||
## Conclusion
|
||||
|
||||
Custom proposers give you fine-grained control over block production in AITBC. This tutorial covered the basics of creating, testing, and deploying custom proposers. You can now extend these examples to build sophisticated consensus mechanisms tailored to your specific needs.
|
||||
|
||||
For more advanced examples and community contributions, visit the AITBC GitHub repository.
|
||||
45
docs/tutorials/index.md
Normal file
45
docs/tutorials/index.md
Normal file
@ -0,0 +1,45 @@
|
||||
# AITBC Tutorials
|
||||
|
||||
Welcome to the AITBC tutorials section. Here you'll find comprehensive guides for building on the AITBC platform.
|
||||
|
||||
## Core Platform Tutorials
|
||||
|
||||
### [Building Custom Proposers](custom-proposer.md)
|
||||
Learn how to create custom block proposers for specialized consensus logic in AITBC's Proof of Authority system.
|
||||
|
||||
### [Marketplace Extensions](marketplace-extensions.md)
|
||||
Discover how to extend the AITBC marketplace with custom auction types, service categories, and integrations.
|
||||
|
||||
## Infrastructure Tutorials
|
||||
|
||||
### [Mining Setup](mining-setup.md)
|
||||
Set up your GPU miners to participate in the AITBC network and earn rewards.
|
||||
|
||||
### [Running a Node](running-node.md)
|
||||
Deploy and operate your own AITBC blockchain node.
|
||||
|
||||
## Development Tutorials
|
||||
|
||||
### [Building a DApp](building-dapp.md)
|
||||
Create decentralized applications on top of the AITBC platform.
|
||||
|
||||
### [Integration Examples](integration-examples.md)
|
||||
Real-world examples of integrating AITBC services into your applications.
|
||||
|
||||
## Advanced Tutorials
|
||||
|
||||
### [Zero-Knowledge Applications](../zk-applications.md)
|
||||
Implement privacy-preserving features using ZK-SNARKs.
|
||||
|
||||
### [Cross-Chain Integration](../developer/cross-chain.md)
|
||||
Connect AITBC with other blockchain networks.
|
||||
|
||||
## Contributing
|
||||
|
||||
Have a tutorial idea? We'd love your contributions! Check out our [contributing guide](../developer/contributing.md) to get started.
|
||||
|
||||
## Need Help?
|
||||
|
||||
- Join our [Discord community](https://discord.gg/aitbc)
|
||||
- Browse our [FAQ](../resources/faq.md)
|
||||
- Contact [support](../resources/support.md)
|
||||
631
docs/tutorials/marketplace-extensions.md
Normal file
631
docs/tutorials/marketplace-extensions.md
Normal file
@ -0,0 +1,631 @@
|
||||
# Building Marketplace Extensions in AITBC
|
||||
|
||||
This tutorial shows how to extend the AITBC marketplace with custom features, plugins, and integrations.
|
||||
|
||||
## Overview
|
||||
|
||||
The AITBC marketplace is designed to be extensible. You can add:
|
||||
- Custom auction types
|
||||
- Specialized service categories
|
||||
- Advanced filtering and search
|
||||
- Integration with external systems
|
||||
- Custom pricing models
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Node.js 16+
|
||||
- AITBC marketplace source code
|
||||
- Understanding of React/TypeScript
|
||||
- API development experience
|
||||
|
||||
## Step 1: Create a Custom Auction Type
|
||||
|
||||
Let's create a Dutch auction extension:
|
||||
|
||||
```typescript
|
||||
// src/extensions/DutchAuction.ts
|
||||
import { Auction, Bid, MarketplacePlugin } from '../types';
|
||||
|
||||
interface DutchAuctionConfig {
|
||||
startPrice: number;
|
||||
reservePrice: number;
|
||||
decrementRate: number;
|
||||
decrementInterval: number; // in seconds
|
||||
}
|
||||
|
||||
export class DutchAuction implements MarketplacePlugin {
|
||||
config: DutchAuctionConfig;
|
||||
currentPrice: number;
|
||||
lastDecrement: number;
|
||||
|
||||
constructor(config: DutchAuctionConfig) {
|
||||
this.config = config;
|
||||
this.currentPrice = config.startPrice;
|
||||
this.lastDecrement = Date.now();
|
||||
}
|
||||
|
||||
async updatePrice(): Promise<void> {
|
||||
const now = Date.now();
|
||||
const elapsed = (now - this.lastDecrement) / 1000;
|
||||
|
||||
if (elapsed >= this.config.decrementInterval) {
|
||||
const decrements = Math.floor(elapsed / this.config.decrementInterval);
|
||||
this.currentPrice = Math.max(
|
||||
this.config.reservePrice,
|
||||
this.currentPrice - (decrements * this.config.decrementRate)
|
||||
);
|
||||
this.lastDecrement = now;
|
||||
}
|
||||
}
|
||||
|
||||
async validateBid(bid: Bid): Promise<boolean> {
|
||||
await this.updatePrice();
|
||||
return bid.amount >= this.currentPrice;
|
||||
}
|
||||
|
||||
async getCurrentState(): Promise<any> {
|
||||
await this.updatePrice();
|
||||
return {
|
||||
type: 'dutch',
|
||||
currentPrice: this.currentPrice,
|
||||
nextDecrement: this.config.decrementInterval -
|
||||
((Date.now() - this.lastDecrement) / 1000)
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Step 2: Register the Extension
|
||||
|
||||
```typescript
|
||||
// src/extensions/index.ts
|
||||
import { DutchAuction } from './DutchAuction';
|
||||
import { MarketplaceRegistry } from '../core/MarketplaceRegistry';
|
||||
|
||||
const registry = new MarketplaceRegistry();
|
||||
|
||||
// Register Dutch auction
|
||||
registry.registerAuctionType('dutch', DutchAuction, {
|
||||
defaultConfig: {
|
||||
startPrice: 1000,
|
||||
reservePrice: 100,
|
||||
decrementRate: 10,
|
||||
decrementInterval: 60
|
||||
},
|
||||
validation: {
|
||||
startPrice: { type: 'number', min: 0 },
|
||||
reservePrice: { type: 'number', min: 0 },
|
||||
decrementRate: { type: 'number', min: 0 },
|
||||
decrementInterval: { type: 'number', min: 1 }
|
||||
}
|
||||
});
|
||||
|
||||
export default registry;
|
||||
```
|
||||
|
||||
## Step 3: Create UI Components
|
||||
|
||||
```tsx
|
||||
// src/components/DutchAuctionCard.tsx
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Card, Button, Progress, Typography } from 'antd';
|
||||
import { useMarketplace } from '../hooks/useMarketplace';
|
||||
|
||||
const { Title, Text } = Typography;
|
||||
|
||||
interface DutchAuctionCardProps {
|
||||
auction: any;
|
||||
}
|
||||
|
||||
export const DutchAuctionCard: React.FC<DutchAuctionCardProps> = ({ auction }) => {
|
||||
const [currentState, setCurrentState] = useState<any>(null);
|
||||
const [timeLeft, setTimeLeft] = useState<number>(0);
|
||||
const { placeBid } = useMarketplace();
|
||||
|
||||
useEffect(() => {
|
||||
const updateState = async () => {
|
||||
const state = await auction.getCurrentState();
|
||||
setCurrentState(state);
|
||||
setTimeLeft(state.nextDecrement);
|
||||
};
|
||||
|
||||
updateState();
|
||||
const interval = setInterval(updateState, 1000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [auction]);
|
||||
|
||||
const handleBid = async () => {
|
||||
try {
|
||||
await placeBid(auction.id, currentState.currentPrice);
|
||||
} catch (error) {
|
||||
console.error('Bid failed:', error);
|
||||
}
|
||||
};
|
||||
|
||||
if (!currentState) return <div>Loading...</div>;
|
||||
|
||||
const priceProgress =
|
||||
((currentState.currentPrice - auction.config.reservePrice) /
|
||||
(auction.config.startPrice - auction.config.reservePrice)) * 100;
|
||||
|
||||
return (
|
||||
<Card title={auction.title} extra={`Auction #${auction.id}`}>
|
||||
<div className="mb-4">
|
||||
<Title level={4}>Current Price: {currentState.currentPrice} AITBC</Title>
|
||||
<Progress
|
||||
percent={100 - priceProgress}
|
||||
status="active"
|
||||
format={() => `${timeLeft}s until next drop`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-between items-center">
|
||||
<Text type="secondary">
|
||||
Reserve Price: {auction.config.reservePrice} AITBC
|
||||
</Text>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={handleBid}
|
||||
disabled={currentState.currentPrice <= auction.config.reservePrice}
|
||||
>
|
||||
Buy Now
|
||||
</Button>
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## Step 4: Add Backend API Support
|
||||
|
||||
```python
|
||||
# apps/coordinator-api/src/app/routers/marketplace_extensions.py
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from pydantic import BaseModel
|
||||
from typing import Dict, Any, List
|
||||
import asyncio
|
||||
|
||||
router = APIRouter(prefix="/marketplace/extensions", tags=["marketplace-extensions"])
|
||||
|
||||
class DutchAuctionRequest(BaseModel):
|
||||
title: str
|
||||
description: str
|
||||
start_price: float
|
||||
reserve_price: float
|
||||
decrement_rate: float
|
||||
decrement_interval: int
|
||||
|
||||
class DutchAuctionState(BaseModel):
|
||||
auction_id: str
|
||||
current_price: float
|
||||
next_decrement: int
|
||||
total_bids: int
|
||||
|
||||
@router.post("/dutch-auction/create")
|
||||
async def create_dutch_auction(request: DutchAuctionRequest) -> Dict[str, str]:
|
||||
"""Create a new Dutch auction."""
|
||||
|
||||
# Validate auction parameters
|
||||
if request.reserve_price >= request.start_price:
|
||||
raise HTTPException(400, "Reserve price must be less than start price")
|
||||
|
||||
# Create auction in database
|
||||
auction_id = await marketplace_service.create_extension_auction(
|
||||
type="dutch",
|
||||
config=request.dict()
|
||||
)
|
||||
|
||||
# Start price decrement task
|
||||
asyncio.create_task(start_price_decrement(auction_id))
|
||||
|
||||
return {"auction_id": auction_id}
|
||||
|
||||
@router.get("/dutch-auction/{auction_id}/state")
|
||||
async def get_dutch_auction_state(auction_id: str) -> DutchAuctionState:
|
||||
"""Get current state of a Dutch auction."""
|
||||
|
||||
auction = await marketplace_service.get_auction(auction_id)
|
||||
if not auction or auction.type != "dutch":
|
||||
raise HTTPException(404, "Dutch auction not found")
|
||||
|
||||
current_price = calculate_current_price(auction)
|
||||
next_decrement = calculate_next_decrement(auction)
|
||||
|
||||
return DutchAuctionState(
|
||||
auction_id=auction_id,
|
||||
current_price=current_price,
|
||||
next_decrement=next_decrement,
|
||||
total_bids=auction.bid_count
|
||||
)
|
||||
|
||||
async def start_price_decrement(auction_id: str):
|
||||
"""Background task to decrement auction price."""
|
||||
while True:
|
||||
await asyncio.sleep(60) # Check every minute
|
||||
|
||||
auction = await marketplace_service.get_auction(auction_id)
|
||||
if not auction or auction.status != "active":
|
||||
break
|
||||
|
||||
new_price = calculate_current_price(auction)
|
||||
await marketplace_service.update_auction_price(auction_id, new_price)
|
||||
|
||||
if new_price <= auction.config["reserve_price"]:
|
||||
await marketplace_service.close_auction(auction_id)
|
||||
break
|
||||
```
|
||||
|
||||
## Step 5: Add Custom Service Category
|
||||
|
||||
```typescript
|
||||
// src/extensions/ServiceCategories.ts
|
||||
export interface ServiceCategory {
|
||||
id: string;
|
||||
name: string;
|
||||
icon: string;
|
||||
description: string;
|
||||
requirements: ServiceRequirement[];
|
||||
pricing: PricingModel;
|
||||
}
|
||||
|
||||
export interface ServiceRequirement {
|
||||
type: 'gpu' | 'cpu' | 'memory' | 'storage';
|
||||
minimum: number;
|
||||
recommended: number;
|
||||
unit: string;
|
||||
}
|
||||
|
||||
export interface PricingModel {
|
||||
type: 'fixed' | 'hourly' | 'per-unit';
|
||||
basePrice: number;
|
||||
unitPrice?: number;
|
||||
}
|
||||
|
||||
export const AI_INFERENCE_CATEGORY: ServiceCategory = {
|
||||
id: 'ai-inference',
|
||||
name: 'AI Inference',
|
||||
icon: 'brain',
|
||||
description: 'Large language model and neural network inference',
|
||||
requirements: [
|
||||
{ type: 'gpu', minimum: 8, recommended: 24, unit: 'GB' },
|
||||
{ type: 'memory', minimum: 16, recommended: 64, unit: 'GB' },
|
||||
{ type: 'cpu', minimum: 4, recommended: 16, unit: 'cores' }
|
||||
],
|
||||
pricing: {
|
||||
type: 'hourly',
|
||||
basePrice: 10,
|
||||
unitPrice: 0.5
|
||||
}
|
||||
};
|
||||
|
||||
// Category registry
|
||||
export const SERVICE_CATEGORIES: Record<string, ServiceCategory> = {
|
||||
'ai-inference': AI_INFERENCE_CATEGORY,
|
||||
'video-rendering': {
|
||||
id: 'video-rendering',
|
||||
name: 'Video Rendering',
|
||||
icon: 'video',
|
||||
description: 'High-quality video rendering and encoding',
|
||||
requirements: [
|
||||
{ type: 'gpu', minimum: 12, recommended: 24, unit: 'GB' },
|
||||
{ type: 'memory', minimum: 32, recommended: 128, unit: 'GB' },
|
||||
{ type: 'storage', minimum: 100, recommended: 1000, unit: 'GB' }
|
||||
],
|
||||
pricing: {
|
||||
type: 'per-unit',
|
||||
basePrice: 5,
|
||||
unitPrice: 0.1
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Step 6: Create Advanced Search Filters
|
||||
|
||||
```tsx
|
||||
// src/components/AdvancedSearch.tsx
|
||||
import React, { useState } from 'react';
|
||||
import { Select, Slider, Input, Button, Space } from 'antd';
|
||||
import { SERVICE_CATEGORIES } from '../extensions/ServiceCategories';
|
||||
|
||||
const { Option } = Select;
|
||||
const { Search } = Input;
|
||||
|
||||
interface SearchFilters {
|
||||
category?: string;
|
||||
priceRange: [number, number];
|
||||
gpuMemory: [number, number];
|
||||
providerRating: number;
|
||||
}
|
||||
|
||||
export const AdvancedSearch: React.FC<{
|
||||
onSearch: (filters: SearchFilters) => void;
|
||||
}> = ({ onSearch }) => {
|
||||
const [filters, setFilters] = useState<SearchFilters>({
|
||||
priceRange: [0, 1000],
|
||||
gpuMemory: [0, 24],
|
||||
providerRating: 0
|
||||
});
|
||||
|
||||
const handleSearch = () => {
|
||||
onSearch(filters);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-4 bg-gray-50 rounded-lg">
|
||||
<Space direction="vertical" className="w-full">
|
||||
<Search
|
||||
placeholder="Search services..."
|
||||
onSearch={(value) => setFilters({ ...filters, query: value })}
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
|
||||
<Select
|
||||
placeholder="Select category"
|
||||
style={{ width: '100%' }}
|
||||
onChange={(value) => setFilters({ ...filters, category: value })}
|
||||
allowClear
|
||||
>
|
||||
{Object.values(SERVICE_CATEGORIES).map(category => (
|
||||
<Option key={category.id} value={category.id}>
|
||||
{category.name}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
|
||||
<div>
|
||||
<label>Price Range: {filters.priceRange[0]} - {filters.priceRange[1]} AITBC</label>
|
||||
<Slider
|
||||
range
|
||||
min={0}
|
||||
max={1000}
|
||||
value={filters.priceRange}
|
||||
onChange={(value) => setFilters({ ...filters, priceRange: value })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>GPU Memory: {filters.gpuMemory[0]} - {filters.gpuMemory[1]} GB</label>
|
||||
<Slider
|
||||
range
|
||||
min={0}
|
||||
max={24}
|
||||
value={filters.gpuMemory}
|
||||
onChange={(value) => setFilters({ ...filters, gpuMemory: value })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>Minimum Provider Rating: {filters.providerRating} stars</label>
|
||||
<Slider
|
||||
min={0}
|
||||
max={5}
|
||||
step={0.5}
|
||||
value={filters.providerRating}
|
||||
onChange={(value) => setFilters({ ...filters, providerRating: value })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button type="primary" onClick={handleSearch} block>
|
||||
Apply Filters
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## Step 7: Add Integration with External Systems
|
||||
|
||||
```python
|
||||
# apps/coordinator-api/src/app/integrations/slack.py
|
||||
import httpx
|
||||
from typing import Dict, Any
|
||||
|
||||
class SlackIntegration:
|
||||
def __init__(self, webhook_url: str):
|
||||
self.webhook_url = webhook_url
|
||||
|
||||
async def notify_new_auction(self, auction: Dict[str, Any]) -> None:
|
||||
"""Send notification about new auction to Slack."""
|
||||
message = {
|
||||
"text": f"New auction created: {auction['title']}",
|
||||
"blocks": [
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": f"*New Auction Alert*\n\n*Title:* {auction['title']}\n"
|
||||
f"*Starting Price:* {auction['start_price']} AITBC\n"
|
||||
f"*Category:* {auction.get('category', 'General')}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "actions",
|
||||
"elements": [
|
||||
{
|
||||
"type": "button",
|
||||
"text": {"type": "plain_text", "text": "View Auction"},
|
||||
"url": f"https://aitbc.bubuit.net/marketplace/auction/{auction['id']}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
async with httpx.AsyncClient() as client:
|
||||
await client.post(self.webhook_url, json=message)
|
||||
|
||||
async def notify_bid_placed(self, auction_id: str, bid_amount: float) -> None:
|
||||
"""Notify when a bid is placed."""
|
||||
message = {
|
||||
"text": f"New bid of {bid_amount} AITBC placed on auction {auction_id}"
|
||||
}
|
||||
|
||||
async with httpx.AsyncClient() as client:
|
||||
await client.post(self.webhook_url, json=message)
|
||||
|
||||
# Integration with Discord
|
||||
class DiscordIntegration:
|
||||
def __init__(self, webhook_url: str):
|
||||
self.webhook_url = webhook_url
|
||||
|
||||
async def send_embed(self, title: str, description: str, fields: list) -> None:
|
||||
"""Send rich embed message to Discord."""
|
||||
embed = {
|
||||
"title": title,
|
||||
"description": description,
|
||||
"fields": fields,
|
||||
"color": 0x00ff00
|
||||
}
|
||||
|
||||
payload = {"embeds": [embed]}
|
||||
|
||||
async with httpx.AsyncClient() as client:
|
||||
await client.post(self.webhook_url, json=payload)
|
||||
```
|
||||
|
||||
## Step 8: Create Custom Pricing Model
|
||||
|
||||
```typescript
|
||||
// src/extensions/DynamicPricing.ts
|
||||
export interface PricingRule {
|
||||
condition: (context: PricingContext) => boolean;
|
||||
calculate: (basePrice: number, context: PricingContext) => number;
|
||||
}
|
||||
|
||||
export interface PricingContext {
|
||||
demand: number;
|
||||
supply: number;
|
||||
timeOfDay: number;
|
||||
dayOfWeek: number;
|
||||
providerRating: number;
|
||||
serviceCategory: string;
|
||||
}
|
||||
|
||||
export class DynamicPricingEngine {
|
||||
private rules: PricingRule[] = [];
|
||||
|
||||
addRule(rule: PricingRule) {
|
||||
this.rules.push(rule);
|
||||
}
|
||||
|
||||
calculatePrice(basePrice: number, context: PricingContext): number {
|
||||
let finalPrice = basePrice;
|
||||
|
||||
for (const rule of this.rules) {
|
||||
if (rule.condition(context)) {
|
||||
finalPrice = rule.calculate(finalPrice, context);
|
||||
}
|
||||
}
|
||||
|
||||
return Math.round(finalPrice * 100) / 100;
|
||||
}
|
||||
}
|
||||
|
||||
// Example pricing rules
|
||||
export const DEMAND_SURGE_RULE: PricingRule = {
|
||||
condition: (ctx) => ctx.demand / ctx.supply > 2,
|
||||
calculate: (price) => price * 1.5, // 50% surge
|
||||
};
|
||||
|
||||
export const PEAK_HOURS_RULE: PricingRule = {
|
||||
condition: (ctx) => ctx.timeOfDay >= 9 && ctx.timeOfDay <= 17,
|
||||
calculate: (price) => price * 1.2, // 20% peak hour premium
|
||||
};
|
||||
|
||||
export const TOP_PROVIDER_RULE: PricingRule = {
|
||||
condition: (ctx) => ctx.providerRating >= 4.5,
|
||||
calculate: (price) => price * 1.1, // 10% premium for top providers
|
||||
};
|
||||
|
||||
// Usage
|
||||
const pricingEngine = new DynamicPricingEngine();
|
||||
pricingEngine.addRule(DEMAND_SURGE_RULE);
|
||||
pricingEngine.addRule(PEAK_HOURS_RULE);
|
||||
pricingEngine.addRule(TOP_PROVIDER_RULE);
|
||||
|
||||
const finalPrice = pricingEngine.calculatePrice(100, {
|
||||
demand: 100,
|
||||
supply: 30,
|
||||
timeOfDay: 14,
|
||||
dayOfWeek: 2,
|
||||
providerRating: 4.8,
|
||||
serviceCategory: 'ai-inference'
|
||||
});
|
||||
```
|
||||
|
||||
## Testing Your Extensions
|
||||
|
||||
```typescript
|
||||
// src/extensions/__tests__/DutchAuction.test.ts
|
||||
import { DutchAuction } from '../DutchAuction';
|
||||
|
||||
describe('DutchAuction', () => {
|
||||
let auction: DutchAuction;
|
||||
|
||||
beforeEach(() => {
|
||||
auction = new DutchAuction({
|
||||
startPrice: 1000,
|
||||
reservePrice: 100,
|
||||
decrementRate: 10,
|
||||
decrementInterval: 60
|
||||
});
|
||||
});
|
||||
|
||||
test('should start with initial price', () => {
|
||||
expect(auction.currentPrice).toBe(1000);
|
||||
});
|
||||
|
||||
test('should decrement price after interval', async () => {
|
||||
// Mock time passing
|
||||
jest.spyOn(Date, 'now').mockReturnValue(Date.now() + 60000);
|
||||
|
||||
await auction.updatePrice();
|
||||
expect(auction.currentPrice).toBe(990);
|
||||
});
|
||||
|
||||
test('should not go below reserve price', async () => {
|
||||
// Mock significant time passing
|
||||
jest.spyOn(Date, 'now').mockReturnValue(Date.now() + 600000);
|
||||
|
||||
await auction.updatePrice();
|
||||
expect(auction.currentPrice).toBe(100);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Deployment
|
||||
|
||||
1. **Build your extensions**:
|
||||
```bash
|
||||
npm run build:extensions
|
||||
```
|
||||
|
||||
2. **Deploy to production**:
|
||||
```bash
|
||||
# Copy extension files
|
||||
cp -r src/extensions/* /var/www/aitbc.bubuit.net/marketplace/extensions/
|
||||
|
||||
# Update API
|
||||
scp apps/coordinator-api/src/app/routers/marketplace_extensions.py \
|
||||
aitbc:/opt/coordinator-api/src/app/routers/
|
||||
|
||||
# Restart services
|
||||
ssh aitbc "sudo systemctl restart coordinator-api"
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Modular Design** - Keep extensions independent
|
||||
2. **Backward Compatibility** - Ensure extensions work with existing marketplace
|
||||
3. **Performance** - Optimize for high-frequency operations
|
||||
4. **Security** - Validate all inputs and permissions
|
||||
5. **Documentation** - Document extension APIs and usage
|
||||
|
||||
## Conclusion
|
||||
|
||||
This tutorial covered creating marketplace extensions including custom auction types, service categories, advanced search, and external integrations. You can now build powerful extensions to enhance the AITBC marketplace functionality.
|
||||
|
||||
For more examples and community contributions, visit the marketplace extensions repository.
|
||||
@ -27,15 +27,18 @@ The AITBC explorer allows you to browse and search the blockchain for transactio
|
||||
## Using the Explorer
|
||||
|
||||
### Web Interface
|
||||
Visit [https://explorer.aitbc.io](https://explorer.aitbc.io)
|
||||
Visit [https://aitbc.bubuit.net/explorer/](https://aitbc.bubuit.net/explorer/)
|
||||
|
||||
### API Access
|
||||
```bash
|
||||
# Get transaction
|
||||
curl https://api.aitbc.io/v1/transactions/{tx_hash}
|
||||
curl https://aitbc.bubuit.net/api/v1/transactions/{tx_hash}
|
||||
|
||||
# Get job details
|
||||
curl https://api.aitbc.io/v1/jobs/{job_id}
|
||||
curl https://aitbc.bubuit.net/api/v1/jobs/{job_id}
|
||||
|
||||
# Explorer data (blocks)
|
||||
curl https://aitbc.bubuit.net/api/explorer/blocks
|
||||
```
|
||||
|
||||
## Advanced Features
|
||||
|
||||
270
docs/zk-applications.md
Normal file
270
docs/zk-applications.md
Normal file
@ -0,0 +1,270 @@
|
||||
# Zero-Knowledge Applications in AITBC
|
||||
|
||||
This document describes the Zero-Knowledge (ZK) proof capabilities implemented in the AITBC platform.
|
||||
|
||||
## Overview
|
||||
|
||||
AITBC now supports privacy-preserving operations through ZK-SNARKs, allowing users to prove computations, membership, and other properties without revealing sensitive information.
|
||||
|
||||
## Available ZK Features
|
||||
|
||||
### 1. Identity Commitments
|
||||
|
||||
Create privacy-preserving identity commitments that allow you to prove you're a valid user without revealing your identity.
|
||||
|
||||
**Endpoint**: `POST /api/zk/identity/commit`
|
||||
|
||||
**Request**:
|
||||
```json
|
||||
{
|
||||
"salt": "optional_random_string"
|
||||
}
|
||||
```
|
||||
|
||||
**Response**:
|
||||
```json
|
||||
{
|
||||
"commitment": "hash_of_identity_and_salt",
|
||||
"salt": "used_salt",
|
||||
"user_id": "user_identifier",
|
||||
"created_at": "2025-12-28T17:50:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Stealth Addresses
|
||||
|
||||
Generate one-time payment addresses for enhanced privacy in transactions.
|
||||
|
||||
**Endpoint**: `POST /api/zk/stealth/address`
|
||||
|
||||
**Parameters**:
|
||||
- `recipient_public_key` (query): The recipient's public key
|
||||
|
||||
**Response**:
|
||||
```json
|
||||
{
|
||||
"stealth_address": "0x27b224d39bb988620a1447eb4bce6fc629e15331",
|
||||
"shared_secret_hash": "b9919ff990cd8793aa587cf5fd800efb997b6dcd...",
|
||||
"ephemeral_key": "ca8acd0ae4a9372cdaeef7eb3ac7eb10",
|
||||
"view_key": "0x5f7de2cc364f7c8d64ce1051c97a1ba6028f83d9"
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Private Receipt Attestation
|
||||
|
||||
Create receipts that prove computation occurred without revealing the actual computation details.
|
||||
|
||||
**Endpoint**: `POST /api/zk/receipt/attest`
|
||||
|
||||
**Parameters**:
|
||||
- `job_id` (query): Identifier of the computation job
|
||||
- `user_address` (query): Address of the user requesting computation
|
||||
- `computation_result` (query): Hash of the computation result
|
||||
- `privacy_level` (query): "basic", "medium", or "maximum"
|
||||
|
||||
**Response**:
|
||||
```json
|
||||
{
|
||||
"job_id": "job_123",
|
||||
"user_address": "0xabcdef",
|
||||
"commitment": "a6a8598788c066115dcc8ca35032dc60b89f2e138...",
|
||||
"privacy_level": "basic",
|
||||
"timestamp": "2025-12-28T17:51:26.758953",
|
||||
"verified": true
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Group Membership Proofs
|
||||
|
||||
Prove membership in a group (miners, clients, developers) without revealing your identity.
|
||||
|
||||
**Endpoint**: `POST /api/zk/membership/verify`
|
||||
|
||||
**Request**:
|
||||
```json
|
||||
{
|
||||
"group_id": "miners",
|
||||
"nullifier": "unique_64_char_string",
|
||||
"proof": "zk_snark_proof_string"
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Private Bidding
|
||||
|
||||
Submit bids to marketplace auctions without revealing the bid amount.
|
||||
|
||||
**Endpoint**: `POST /api/zk/marketplace/private-bid`
|
||||
|
||||
**Request**:
|
||||
```json
|
||||
{
|
||||
"auction_id": "auction_123",
|
||||
"bid_commitment": "hash_of_bid_and_salt",
|
||||
"proof": "proof_that_bid_is_in_valid_range"
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Computation Proofs
|
||||
|
||||
Verify that AI computations were performed correctly without revealing the inputs.
|
||||
|
||||
**Endpoint**: `POST /api/zk/computation/verify`
|
||||
|
||||
**Request**:
|
||||
```json
|
||||
{
|
||||
"job_id": "job_456",
|
||||
"result_hash": "hash_of_computation_result",
|
||||
"proof_of_execution": "zk_snark_proof",
|
||||
"public_inputs": {}
|
||||
}
|
||||
```
|
||||
|
||||
## Anonymity Sets
|
||||
|
||||
View available anonymity sets for privacy operations:
|
||||
|
||||
**Endpoint**: `GET /api/zk/anonymity/sets`
|
||||
|
||||
**Response**:
|
||||
```json
|
||||
{
|
||||
"sets": {
|
||||
"miners": {
|
||||
"size": 100,
|
||||
"description": "Registered GPU miners",
|
||||
"type": "merkle_tree"
|
||||
},
|
||||
"clients": {
|
||||
"size": 500,
|
||||
"description": "Active clients",
|
||||
"type": "merkle_tree"
|
||||
},
|
||||
"transactions": {
|
||||
"size": 1000,
|
||||
"description": "Recent transactions",
|
||||
"type": "ring_signature"
|
||||
}
|
||||
},
|
||||
"min_anonymity": 3,
|
||||
"recommended_sets": ["miners", "clients"]
|
||||
}
|
||||
```
|
||||
|
||||
## Technical Implementation
|
||||
|
||||
### Circuit Compilation
|
||||
|
||||
The ZK circuits are compiled using:
|
||||
- **Circom**: v2.2.3
|
||||
- **Circomlib**: For standard circuit components
|
||||
- **SnarkJS**: For trusted setup and proof generation
|
||||
|
||||
### Trusted Setup
|
||||
|
||||
A complete trusted setup ceremony has been performed:
|
||||
1. Powers of Tau ceremony with 2^12 powers
|
||||
2. Phase 2 preparation for specific circuits
|
||||
3. Groth16 proving keys generated
|
||||
4. Verification keys exported
|
||||
|
||||
### Circuit Files
|
||||
|
||||
The following circuit files are deployed:
|
||||
- `receipt_simple_0001.zkey`: Proving key for receipt circuit
|
||||
- `receipt_simple.wasm`: WASM witness generator
|
||||
- `verification_key.json`: Verification key for on-chain verification
|
||||
|
||||
### Privacy Levels
|
||||
|
||||
1. **Basic**: Hash-based commitments (no ZK-SNARKs)
|
||||
2. **Medium**: Simple ZK proofs with limited constraints
|
||||
3. **Maximum**: Full ZK-SNARKs with complete privacy
|
||||
|
||||
## Security Considerations
|
||||
|
||||
1. **Trusted Setup**: The trusted setup was performed with proper entropy and multiple contributions
|
||||
2. **Randomness**: All operations use cryptographically secure random number generation
|
||||
3. **Nullifiers**: Prevent double-spending and replay attacks
|
||||
4. **Verification**: All proofs can be verified on-chain or off-chain
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
1. **Additional Circuits**: Membership and bid range circuits to be compiled
|
||||
2. **Recursive Proofs**: Enable proof composition for complex operations
|
||||
3. **On-Chain Verification**: Deploy verification contracts to blockchain
|
||||
4. **Hardware Acceleration**: GPU acceleration for proof generation
|
||||
|
||||
## API Status
|
||||
|
||||
Check the current status of ZK features:
|
||||
|
||||
**Endpoint**: `GET /api/zk/status`
|
||||
|
||||
This endpoint returns detailed information about:
|
||||
- Which ZK features are active
|
||||
- Circuit compilation status
|
||||
- Available proof types
|
||||
- Next steps for implementation
|
||||
|
||||
## Integration Guide
|
||||
|
||||
To integrate ZK proofs in your application:
|
||||
|
||||
1. **Generate Proof**: Use the appropriate endpoint to generate a proof
|
||||
2. **Submit Proof**: Include the proof in your transaction or API call
|
||||
3. **Verify Proof**: The system will automatically verify the proof
|
||||
4. **Privacy**: Your sensitive data remains private throughout the process
|
||||
|
||||
## Examples
|
||||
|
||||
### Private Marketplace Bid
|
||||
|
||||
```javascript
|
||||
// 1. Create bid commitment
|
||||
const bidAmount = 100;
|
||||
const salt = generateRandomSalt();
|
||||
const commitment = hash(bidAmount + salt);
|
||||
|
||||
// 2. Generate ZK proof that bid is within range
|
||||
const proof = await generateBidRangeProof(bidAmount, salt);
|
||||
|
||||
// 3. Submit private bid
|
||||
const response = await fetch('/api/zk/marketplace/private-bid', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
auction_id: 'auction_123',
|
||||
bid_commitment: commitment,
|
||||
proof: proof
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
### Stealth Address Payment
|
||||
|
||||
```javascript
|
||||
// 1. Generate stealth address for recipient
|
||||
const response = await fetch(
|
||||
'/api/zk/stealth/address?recipient_public_key=0x123...',
|
||||
{ method: 'POST' }
|
||||
);
|
||||
|
||||
const { stealth_address, view_key } = await response.json();
|
||||
|
||||
// 2. Send payment to stealth address
|
||||
await sendTransaction({
|
||||
to: stealth_address,
|
||||
amount: 1000
|
||||
});
|
||||
|
||||
// 3. Recipient can view funds using view_key
|
||||
const balance = await viewStealthAddressBalance(view_key);
|
||||
```
|
||||
|
||||
## Support
|
||||
|
||||
For questions about ZK applications:
|
||||
- Check the API documentation at `/docs/`
|
||||
- Review the status endpoint at `/api/zk/status`
|
||||
- Examine the circuit source code in `apps/zk-circuits/`
|
||||
Reference in New Issue
Block a user