refactor: clean up configuration and add production infrastructure

- Add .aitbc.yaml configuration file with test values
- Simplify .gitignore by removing merge conflicts and redundant entries
- Reorganize .gitignore sections for better clarity
- Set chain_id and proposer_id to empty strings in config.py (require explicit configuration)
- Add production Helm values configuration
- Add production nginx configuration
- Update environment variable handling in chain settings
This commit is contained in:
2026-03-19 12:59:34 +01:00
committed by aitbc
parent 5f2ab48b9a
commit b4b5a57390
111 changed files with 13106 additions and 346 deletions

2
.aitbc.yaml Normal file
View File

@@ -0,0 +1,2 @@
api_key: test_value
coordinator_url: http://127.0.0.1:18000

392
.gitignore vendored
View File

@@ -1,7 +1,4 @@
<<<<<<< Updated upstream
# AITBC Monorepo ignore rules
# Updated: 2026-03-03 - Project organization workflow completed
# Development files organized into dev/ subdirectories
# ===================
# Python
@@ -26,7 +23,9 @@ htmlcov/
.mypy_cache/
.ruff_cache/
# Environment files
# ===================
# Environment Files (SECRETS - NEVER COMMIT)
# ===================
*.env
.env.*
!.env.example
@@ -34,90 +33,45 @@ htmlcov/
.env.*.local
# ===================
# Development Environment (organized)
# ===================
dev/env/.venv/
dev/env/node_modules/
dev/env/cli_env/
dev/cache/.pytest_cache/
dev/cache/.ruff_cache/
dev/cache/.vscode/
dev/cache/logs/
dev/scripts/__pycache__/
dev/scripts/*.pyc
dev/scripts/*.pyo
# ===================
# Databases
# Database & Data
# ===================
*.db
*.sqlite
*.sqlite3
*/data/*.db
*.db-wal
*.db-shm
data/
# Alembic
alembic.ini
migrations/versions/__pycache__/
apps/blockchain-node/data/
# ===================
# Node / JavaScript
# Logs & Runtime
# ===================
node_modules/
dist/
build/
.npm/
.pnpm/
yarn.lock
pnpm-lock.yaml
.next/
.nuxt/
.cache/
# ===================
# Development Tests (organized)
# ===================
dev/tests/__pycache__/
dev/tests/*.pyc
dev/tests/test_results/
dev/tests/simple_test_results.json
dev/tests/data/
dev/tests/*.db
dev/multi-chain/__pycache__/
dev/multi-chain/*.pyc
dev/multi-chain/test_results/
# ===================
# Logs & Runtime (organized)
# ===================
logs/
dev/cache/logs/
*.log
*.log.*
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pids/
logs/
*.pid
*.seed
# ===================
# Editor & IDE
# Secrets & Credentials
# ===================
*.pem
*.key
*.crt
*.p12
secrets/
credentials/
.secrets
.gitea_token.sh
keystore/
# ===================
# IDE & Editor
# ===================
.idea/
.vscode/
.idea/
*.swp
*.swo
*~
.project
.classpath
.settings/
# ===================
# Runtime / PID files
# ===================
*.pid
apps/.service_pids
# ===================
# OS Files
@@ -132,133 +86,22 @@ Desktop.ini
# ===================
# Build & Compiled
# ===================
build/
dist/
target/
*.o
*.a
*.lib
*.dll
*.dylib
target/
out/
# ===================
# Secrets & Credentials
# Node.js
# ===================
*.pem
*.key
*.crt
*.p12
secrets/
credentials/
.secrets
.gitea_token.sh
# ===================
# Backup Files (organized)
# ===================
backup/**/*.tmp
backup/**/*.temp
backup/**/.DS_Store
backup/updates/*.log
# Large backup files (exceed GitHub size limits)
backup/updates/*.tar.gz
backup/updates/*.zip
backup/updates/*.tar.bz2
# Application backup archives
backup/explorer_backup_*.tar.gz
backup/*_backup_*.tar.gz
backup/*_backup_*.zip
# Backup documentation and indexes
backup/BACKUP_INDEX.md
backup/*.md
backup/README.md
# ===================
# Temporary Files
# ===================
tmp/
temp/
=======
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# Virtual environments
venv/
env/
ENV/
.venv/
.env/
# IDEs
.vscode/
.idea/
*.swp
*.swo
*~
# OS
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# Logs
*.log
logs/
# Database
*.db
*.sqlite
*.sqlite3
*.db-wal
*.db-shm
# Configuration with secrets
.env
.env.local
.env.*.local
config.json
secrets.json
# Temporary files
*.tmp
*.temp
*.bak
*.backup
# ===================
# Environment Files
# ===================
.env
.env.local
.env.production
*.env
.env.*.local
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# ===================
# Windsurf IDE
@@ -267,165 +110,26 @@ secrets.json
.snapshots/
# ===================
# Test Results & Artifacts
# Wallet Files (contain private keys)
# ===================
*.json
home/client/client_wallet.json
home/genesis_wallet.json
home/miner/miner_wallet.json
# ===================
# Test Results
# ===================
test-results/
**/test-results/
# ===================
# Development Logs - Keep in dev/logs/
# Temporary Files
# ===================
*.log
*.out
*.err
wget-log
download.log
tmp/
temp/
*.tmp
*.temp
*.bak
*.backup
# ===================
# Wallet files (contain keys/balances)
# ===================
home/client/client_wallet.json
home/genesis_wallet.json
home/miner/miner_wallet.json
# Root-level wallet backups (contain private keys)
*.json
# ===================
# Stale source copies
# ===================
src/aitbc_chain/
# ===================
# Project Specific
# ===================
# Coordinator database
apps/coordinator-api/src/*.db
# Blockchain node data
apps/blockchain-node/data/
# Explorer build artifacts
apps/explorer-web/dist/
# Solidity build artifacts
packages/solidity/aitbc-token/typechain-types/
packages/solidity/aitbc-token/artifacts/
packages/solidity/aitbc-token/cache/
# Local test fixtures and E2E testing
tests/e2e/fixtures/home/**/.aitbc/cache/
tests/e2e/fixtures/home/**/.aitbc/logs/
tests/e2e/fixtures/home/**/.aitbc/tmp/
tests/e2e/fixtures/home/**/.aitbc/*.log
tests/e2e/fixtures/home/**/.aitbc/*.pid
tests/e2e/fixtures/home/**/.aitbc/*.sock
# Keep fixture structure but exclude generated content
!tests/e2e/fixtures/home/
!tests/e2e/fixtures/home/**/
!tests/e2e/fixtures/home/**/.aitbc/
!tests/e2e/fixtures/home/**/.aitbc/wallets/
!tests/e2e/fixtures/home/**/.aitbc/config/
# Local test data
tests/fixtures/generated/
# GPU miner local configs
scripts/gpu/*.local.py
# Deployment secrets
scripts/deploy/*.secret.*
infra/nginx/*.local.conf
# ===================
# Documentation
# ===================
# Infrastructure docs (contains sensitive network info)
docs/infrastructure.md
# Workflow files (personal, change frequently)
docs/1_project/3_currenttask.md
docs/1_project/4_currentissue.md
# ===================
# Website (local deployment details)
# ===================
website/README.md
website/aitbc-proxy.conf
# ===================
# Local Config & Secrets
# ===================
.aitbc.yaml
apps/coordinator-api/.env
# ===================
# Windsurf IDE (personal dev tooling)
# ===================
.windsurf/
# ===================
# Deploy Scripts (hardcoded local paths & IPs)
# ===================
scripts/deploy/*
!scripts/deploy/*.example
scripts/gpu/*
!scripts/gpu/*.example
scripts/service/*
# ===================
# Infra Configs (production IPs & secrets)
# ===================
infra/nginx/nginx-aitbc*.conf
infra/helm/values/prod/
infra/helm/values/prod.yaml
=======
# Node.js
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Build artifacts
build/
dist/
target/
# System files
*.pid
*.seed
*.pid.lock
# Coverage reports
htmlcov/
.coverage
.coverage.*
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# Environments
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# AITBC specific
data/
logs/
*.db
*.sqlite
wallet*.json
keystore/
certificates/
>>>>>>> Stashed changes
.gitea_token.sh

View File

@@ -18,7 +18,7 @@ class ProposerConfig(BaseModel):
class ChainSettings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", case_sensitive=False)
chain_id: str = "ait-devnet"
chain_id: str = ""
supported_chains: str = "ait-devnet" # Comma-separated list of supported chain IDs
db_path: Path = Path("./data/chain.db")
@@ -28,7 +28,7 @@ class ChainSettings(BaseSettings):
p2p_bind_host: str = "127.0.0.2"
p2p_bind_port: int = 7070
proposer_id: str = "ait-devnet-proposer"
proposer_id: str = ""
proposer_key: Optional[str] = None
mint_per_unit: int = 0 # No new minting after genesis for production

140
infra/helm/values/prod.yaml Normal file
View File

@@ -0,0 +1,140 @@
# Production environment values
global:
environment: production
coordinator:
replicaCount: 3
image:
tag: "v0.1.0"
resources:
limits:
cpu: 2000m
memory: 2Gi
requests:
cpu: 1000m
memory: 1Gi
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 20
targetCPUUtilizationPercentage: 75
targetMemoryUtilizationPercentage: 80
config:
appEnv: production
allowOrigins: "https://app.aitbc.io"
postgresql:
auth:
existingSecret: "coordinator-db-secret"
primary:
persistence:
size: 200Gi
storageClass: fast-ssd
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 1000m
memory: 2Gi
readReplicas:
replicaCount: 2
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 500m
memory: 1Gi
monitoring:
prometheus:
server:
retention: 90d
persistentVolume:
size: 500Gi
storageClass: fast-ssd
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 1000m
memory: 2Gi
grafana:
adminPassword: "prod-admin-secure-2024"
persistence:
size: 50Gi
storageClass: fast-ssd
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 500m
memory: 1Gi
ingress:
enabled: true
hosts:
- grafana.aitbc.io
# Additional services
blockchainNode:
replicaCount: 5
resources:
limits:
cpu: 2000m
memory: 2Gi
requests:
cpu: 1000m
memory: 1Gi
autoscaling:
enabled: true
minReplicas: 5
maxReplicas: 50
targetCPUUtilizationPercentage: 70
walletDaemon:
replicaCount: 3
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 500m
memory: 512Mi
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
targetCPUUtilizationPercentage: 75
# Ingress configuration
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/rate-limit-window: "1m"
hosts:
- host: api.aitbc.io
paths:
- path: /
pathType: Prefix
tls:
- secretName: prod-tls
hosts:
- api.aitbc.io
# Security
podSecurityPolicy:
enabled: true
networkPolicy:
enabled: true
# Backup configuration
backup:
enabled: true
schedule: "0 2 * * *"
retention: "30d"

View File

@@ -0,0 +1,259 @@
# Production environment Helm values
global:
environment: prod
domain: aitbc.bubuit.net
imageTag: stable
imagePullPolicy: IfNotPresent
# Coordinator API
coordinator:
enabled: true
replicas: 3
image:
repository: aitbc/coordinator-api
tag: stable
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2000m
memory: 2Gi
service:
type: ClusterIP
port: 8001
env:
LOG_LEVEL: warn
DATABASE_URL: secretRef:db-credentials
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
targetCPUUtilization: 60
targetMemoryUtilization: 70
livenessProbe:
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
initialDelaySeconds: 5
periodSeconds: 5
# Explorer Web
explorer:
enabled: true
replicas: 3
image:
repository: aitbc/explorer-web
tag: stable
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
service:
type: ClusterIP
port: 3000
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 8
# Marketplace Web
marketplace:
enabled: true
replicas: 3
image:
repository: aitbc/marketplace-web
tag: stable
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
service:
type: ClusterIP
port: 3001
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 8
# Wallet Daemon
wallet:
enabled: true
replicas: 2
image:
repository: aitbc/wallet-daemon
tag: stable
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2000m
memory: 2Gi
service:
type: ClusterIP
port: 8002
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 6
# Trade Exchange
exchange:
enabled: true
replicas: 2
image:
repository: aitbc/trade-exchange
tag: stable
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
service:
type: ClusterIP
port: 8085
# PostgreSQL (prod uses RDS Multi-AZ)
postgresql:
enabled: false
external:
host: secretRef:db-credentials:host
port: 5432
database: coordinator
sslMode: require
# Redis (prod uses ElastiCache)
redis:
enabled: false
external:
host: secretRef:redis-credentials:host
port: 6379
auth: true
# Ingress
ingress:
enabled: true
className: nginx
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/proxy-body-size: 10m
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/rate-limit-window: 1m
cert-manager.io/cluster-issuer: letsencrypt-prod
tls:
- secretName: prod-tls
hosts:
- aitbc.bubuit.net
hosts:
- host: aitbc.bubuit.net
paths:
- path: /api
service: coordinator
port: 8001
- path: /explorer
service: explorer
port: 3000
- path: /marketplace
service: marketplace
port: 3001
- path: /wallet
service: wallet
port: 8002
- path: /Exchange
service: exchange
port: 8085
# Monitoring
monitoring:
enabled: true
prometheus:
enabled: true
retention: 30d
resources:
requests:
cpu: 500m
memory: 2Gi
limits:
cpu: 2000m
memory: 4Gi
grafana:
enabled: true
persistence:
enabled: true
size: 10Gi
alertmanager:
enabled: true
config:
receivers:
- name: slack
slack_configs:
- channel: '#aitbc-alerts'
send_resolved: true
# Logging
logging:
enabled: true
level: warn
elasticsearch:
enabled: true
retention: 30d
replicas: 3
# Pod Disruption Budgets
podDisruptionBudget:
coordinator:
minAvailable: 2
explorer:
minAvailable: 2
marketplace:
minAvailable: 2
wallet:
minAvailable: 1
# Network Policies
networkPolicy:
enabled: true
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
egress:
- to:
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- port: 53
protocol: UDP
# Security
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
readOnlyRootFilesystem: true
# Affinity - spread across zones
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: coordinator
topologyKey: topology.kubernetes.io/zone
# Priority Classes
priorityClassName: high-priority

View File

@@ -0,0 +1,247 @@
# AITBC Nginx Reverse Proxy Configuration
# Domain: aitbc.keisanki.net
# This configuration replaces the need for firehol/iptables port forwarding
# HTTP to HTTPS redirect
server {
listen 80;
server_name aitbc.keisanki.net;
# Redirect all HTTP traffic to HTTPS
return 301 https://$server_name$request_uri;
}
# Main HTTPS server block
server {
listen 443 ssl http2;
server_name aitbc.keisanki.net;
# SSL Configuration (Let's Encrypt certificates)
ssl_certificate /etc/letsencrypt/live/aitbc.keisanki.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/aitbc.keisanki.net/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline' 'unsafe-eval'" always;
# Enable gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
# Blockchain Explorer (main route)
location / {
proxy_pass http://192.168.100.10:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
# WebSocket support if needed
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# Coordinator API
location /api/ {
proxy_pass http://192.168.100.10:8000/v1/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
# CORS headers for API
add_header Access-Control-Allow-Origin "*" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,X-Api-Key" always;
# Handle preflight requests
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,X-Api-Key";
add_header Access-Control-Max-Age 1728000;
add_header Content-Type "text/plain; charset=utf-8";
add_header Content-Length 0;
return 204;
}
}
# Blockchain Node 1 RPC
location /rpc/ {
proxy_pass http://192.168.100.10:8082/rpc/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
# Blockchain Node 2 RPC (alternative endpoint)
location /rpc2/ {
proxy_pass http://192.168.100.10:8081/rpc/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
# Exchange API
location /exchange/ {
proxy_pass http://192.168.100.10:9080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
# Marketplace UI (if separate from explorer)
location /marketplace/ {
proxy_pass http://192.168.100.10:3001/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
# Handle subdirectory rewrite
rewrite ^/marketplace/(.*)$ /$1 break;
}
# Admin dashboard
location /admin/ {
proxy_pass http://192.168.100.10:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
# Optional: Restrict admin access
# allow 192.168.100.0/24;
# allow 127.0.0.1;
# deny all;
}
# Health check endpoint
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# API health checks
location /api/health {
proxy_pass http://192.168.100.10:8000/v1/health;
proxy_set_header Host $host;
access_log off;
}
# Static assets caching
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
proxy_pass http://192.168.100.10:3000;
expires 1y;
add_header Cache-Control "public, immutable";
add_header X-Content-Type-Options nosniff;
# Don't log static file access
access_log off;
}
# Deny access to hidden files
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# Custom error pages
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
# Optional: Subdomain for API-only access
server {
listen 443 ssl http2;
server_name api.aitbc.keisanki.net;
# SSL Configuration (same certificates)
ssl_certificate /etc/letsencrypt/live/aitbc.keisanki.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/aitbc.keisanki.net/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# Security headers
add_header X-Frame-Options "DENY" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# API routes only
location / {
proxy_pass http://192.168.100.10:8000/v1/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
# CORS headers
add_header Access-Control-Allow-Origin "*" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,X-Api-Key" always;
# Handle preflight requests
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,X-Api-Key";
add_header Access-Control-Max-Age 1728000;
add_header Content-Type "text/plain; charset=utf-8";
add_header Content-Length 0;
return 204;
}
}
}
# Optional: Subdomain for blockchain RPC
server {
listen 443 ssl http2;
server_name rpc.aitbc.keisanki.net;
# SSL Configuration
ssl_certificate /etc/letsencrypt/live/aitbc.keisanki.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/aitbc.keisanki.net/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# Security headers
add_header X-Frame-Options "DENY" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
# RPC routes
location / {
proxy_pass http://192.168.100.10:8082/rpc/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
}

View File

@@ -0,0 +1,133 @@
# AITBC Services Nginx Configuration
# Domain: https://aitbc.bubuit.net
server {
listen 80;
server_name aitbc.bubuit.net;
# Redirect to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name aitbc.bubuit.net;
# SSL Configuration (Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/aitbc.bubuit.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/aitbc.bubuit.net/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# Security Headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
# API Routes
location /api/ {
proxy_pass http://127.0.0.1:8000/v1/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
# Blockchain RPC Routes
location /rpc/ {
proxy_pass http://127.0.0.1:9080/rpc/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
# Marketplace UI
location /Marketplace {
proxy_pass http://127.0.0.1:3001/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Handle subdirectory
rewrite ^/Marketplace/(.*)$ /$1 break;
proxy_buffering off;
}
# Trade Exchange
location /Exchange {
proxy_pass http://127.0.0.1:3002/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Handle subdirectory
rewrite ^/Exchange/(.*)$ /$1 break;
proxy_buffering off;
}
# Exchange API Routes
location /api/trades/ {
proxy_pass http://127.0.0.1:3003/api/trades/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
location /api/orders {
proxy_pass http://127.0.0.1:3003/api/orders;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
# Wallet CLI API (if needed)
location /wallet/ {
proxy_pass http://127.0.0.1:8000/wallet/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Admin routes
location /admin/ {
proxy_pass http://127.0.0.1:8000/admin/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Restrict access (optional)
# allow 127.0.0.1;
# allow 10.1.223.0/24;
# deny all;
}
# Health check
location /health {
proxy_pass http://127.0.0.1:8000/v1/health;
proxy_set_header Host $host;
}
# Default redirect to Marketplace
location / {
return 301 /Marketplace;
}
# Static file caching
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}

View File

@@ -0,0 +1,324 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type {
BaseContract,
BytesLike,
FunctionFragment,
Result,
Interface,
EventFragment,
AddressLike,
ContractRunner,
ContractMethod,
Listener,
} from "ethers";
import type {
TypedContractEvent,
TypedDeferredTopicFilter,
TypedEventLog,
TypedLogDescription,
TypedListener,
TypedContractMethod,
} from "../../../common";
export interface AccessControlInterface extends Interface {
getFunction(
nameOrSignature:
| "DEFAULT_ADMIN_ROLE"
| "getRoleAdmin"
| "grantRole"
| "hasRole"
| "renounceRole"
| "revokeRole"
| "supportsInterface"
): FunctionFragment;
getEvent(
nameOrSignatureOrTopic: "RoleAdminChanged" | "RoleGranted" | "RoleRevoked"
): EventFragment;
encodeFunctionData(
functionFragment: "DEFAULT_ADMIN_ROLE",
values?: undefined
): string;
encodeFunctionData(
functionFragment: "getRoleAdmin",
values: [BytesLike]
): string;
encodeFunctionData(
functionFragment: "grantRole",
values: [BytesLike, AddressLike]
): string;
encodeFunctionData(
functionFragment: "hasRole",
values: [BytesLike, AddressLike]
): string;
encodeFunctionData(
functionFragment: "renounceRole",
values: [BytesLike, AddressLike]
): string;
encodeFunctionData(
functionFragment: "revokeRole",
values: [BytesLike, AddressLike]
): string;
encodeFunctionData(
functionFragment: "supportsInterface",
values: [BytesLike]
): string;
decodeFunctionResult(
functionFragment: "DEFAULT_ADMIN_ROLE",
data: BytesLike
): Result;
decodeFunctionResult(
functionFragment: "getRoleAdmin",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "grantRole", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "hasRole", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "renounceRole",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "revokeRole", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "supportsInterface",
data: BytesLike
): Result;
}
export namespace RoleAdminChangedEvent {
export type InputTuple = [
role: BytesLike,
previousAdminRole: BytesLike,
newAdminRole: BytesLike
];
export type OutputTuple = [
role: string,
previousAdminRole: string,
newAdminRole: string
];
export interface OutputObject {
role: string;
previousAdminRole: string;
newAdminRole: string;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export namespace RoleGrantedEvent {
export type InputTuple = [
role: BytesLike,
account: AddressLike,
sender: AddressLike
];
export type OutputTuple = [role: string, account: string, sender: string];
export interface OutputObject {
role: string;
account: string;
sender: string;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export namespace RoleRevokedEvent {
export type InputTuple = [
role: BytesLike,
account: AddressLike,
sender: AddressLike
];
export type OutputTuple = [role: string, account: string, sender: string];
export interface OutputObject {
role: string;
account: string;
sender: string;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export interface AccessControl extends BaseContract {
connect(runner?: ContractRunner | null): AccessControl;
waitForDeployment(): Promise<this>;
interface: AccessControlInterface;
queryFilter<TCEvent extends TypedContractEvent>(
event: TCEvent,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
queryFilter<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
on<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
on<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
listeners<TCEvent extends TypedContractEvent>(
event: TCEvent
): Promise<Array<TypedListener<TCEvent>>>;
listeners(eventName?: string): Promise<Array<Listener>>;
removeAllListeners<TCEvent extends TypedContractEvent>(
event?: TCEvent
): Promise<this>;
DEFAULT_ADMIN_ROLE: TypedContractMethod<[], [string], "view">;
getRoleAdmin: TypedContractMethod<[role: BytesLike], [string], "view">;
grantRole: TypedContractMethod<
[role: BytesLike, account: AddressLike],
[void],
"nonpayable"
>;
hasRole: TypedContractMethod<
[role: BytesLike, account: AddressLike],
[boolean],
"view"
>;
renounceRole: TypedContractMethod<
[role: BytesLike, callerConfirmation: AddressLike],
[void],
"nonpayable"
>;
revokeRole: TypedContractMethod<
[role: BytesLike, account: AddressLike],
[void],
"nonpayable"
>;
supportsInterface: TypedContractMethod<
[interfaceId: BytesLike],
[boolean],
"view"
>;
getFunction<T extends ContractMethod = ContractMethod>(
key: string | FunctionFragment
): T;
getFunction(
nameOrSignature: "DEFAULT_ADMIN_ROLE"
): TypedContractMethod<[], [string], "view">;
getFunction(
nameOrSignature: "getRoleAdmin"
): TypedContractMethod<[role: BytesLike], [string], "view">;
getFunction(
nameOrSignature: "grantRole"
): TypedContractMethod<
[role: BytesLike, account: AddressLike],
[void],
"nonpayable"
>;
getFunction(
nameOrSignature: "hasRole"
): TypedContractMethod<
[role: BytesLike, account: AddressLike],
[boolean],
"view"
>;
getFunction(
nameOrSignature: "renounceRole"
): TypedContractMethod<
[role: BytesLike, callerConfirmation: AddressLike],
[void],
"nonpayable"
>;
getFunction(
nameOrSignature: "revokeRole"
): TypedContractMethod<
[role: BytesLike, account: AddressLike],
[void],
"nonpayable"
>;
getFunction(
nameOrSignature: "supportsInterface"
): TypedContractMethod<[interfaceId: BytesLike], [boolean], "view">;
getEvent(
key: "RoleAdminChanged"
): TypedContractEvent<
RoleAdminChangedEvent.InputTuple,
RoleAdminChangedEvent.OutputTuple,
RoleAdminChangedEvent.OutputObject
>;
getEvent(
key: "RoleGranted"
): TypedContractEvent<
RoleGrantedEvent.InputTuple,
RoleGrantedEvent.OutputTuple,
RoleGrantedEvent.OutputObject
>;
getEvent(
key: "RoleRevoked"
): TypedContractEvent<
RoleRevokedEvent.InputTuple,
RoleRevokedEvent.OutputTuple,
RoleRevokedEvent.OutputObject
>;
filters: {
"RoleAdminChanged(bytes32,bytes32,bytes32)": TypedContractEvent<
RoleAdminChangedEvent.InputTuple,
RoleAdminChangedEvent.OutputTuple,
RoleAdminChangedEvent.OutputObject
>;
RoleAdminChanged: TypedContractEvent<
RoleAdminChangedEvent.InputTuple,
RoleAdminChangedEvent.OutputTuple,
RoleAdminChangedEvent.OutputObject
>;
"RoleGranted(bytes32,address,address)": TypedContractEvent<
RoleGrantedEvent.InputTuple,
RoleGrantedEvent.OutputTuple,
RoleGrantedEvent.OutputObject
>;
RoleGranted: TypedContractEvent<
RoleGrantedEvent.InputTuple,
RoleGrantedEvent.OutputTuple,
RoleGrantedEvent.OutputObject
>;
"RoleRevoked(bytes32,address,address)": TypedContractEvent<
RoleRevokedEvent.InputTuple,
RoleRevokedEvent.OutputTuple,
RoleRevokedEvent.OutputObject
>;
RoleRevoked: TypedContractEvent<
RoleRevokedEvent.InputTuple,
RoleRevokedEvent.OutputTuple,
RoleRevokedEvent.OutputObject
>;
};
}

View File

@@ -0,0 +1,292 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type {
BaseContract,
BytesLike,
FunctionFragment,
Result,
Interface,
EventFragment,
AddressLike,
ContractRunner,
ContractMethod,
Listener,
} from "ethers";
import type {
TypedContractEvent,
TypedDeferredTopicFilter,
TypedEventLog,
TypedLogDescription,
TypedListener,
TypedContractMethod,
} from "../../../common";
export interface IAccessControlInterface extends Interface {
getFunction(
nameOrSignature:
| "getRoleAdmin"
| "grantRole"
| "hasRole"
| "renounceRole"
| "revokeRole"
): FunctionFragment;
getEvent(
nameOrSignatureOrTopic: "RoleAdminChanged" | "RoleGranted" | "RoleRevoked"
): EventFragment;
encodeFunctionData(
functionFragment: "getRoleAdmin",
values: [BytesLike]
): string;
encodeFunctionData(
functionFragment: "grantRole",
values: [BytesLike, AddressLike]
): string;
encodeFunctionData(
functionFragment: "hasRole",
values: [BytesLike, AddressLike]
): string;
encodeFunctionData(
functionFragment: "renounceRole",
values: [BytesLike, AddressLike]
): string;
encodeFunctionData(
functionFragment: "revokeRole",
values: [BytesLike, AddressLike]
): string;
decodeFunctionResult(
functionFragment: "getRoleAdmin",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "grantRole", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "hasRole", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "renounceRole",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "revokeRole", data: BytesLike): Result;
}
export namespace RoleAdminChangedEvent {
export type InputTuple = [
role: BytesLike,
previousAdminRole: BytesLike,
newAdminRole: BytesLike
];
export type OutputTuple = [
role: string,
previousAdminRole: string,
newAdminRole: string
];
export interface OutputObject {
role: string;
previousAdminRole: string;
newAdminRole: string;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export namespace RoleGrantedEvent {
export type InputTuple = [
role: BytesLike,
account: AddressLike,
sender: AddressLike
];
export type OutputTuple = [role: string, account: string, sender: string];
export interface OutputObject {
role: string;
account: string;
sender: string;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export namespace RoleRevokedEvent {
export type InputTuple = [
role: BytesLike,
account: AddressLike,
sender: AddressLike
];
export type OutputTuple = [role: string, account: string, sender: string];
export interface OutputObject {
role: string;
account: string;
sender: string;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export interface IAccessControl extends BaseContract {
connect(runner?: ContractRunner | null): IAccessControl;
waitForDeployment(): Promise<this>;
interface: IAccessControlInterface;
queryFilter<TCEvent extends TypedContractEvent>(
event: TCEvent,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
queryFilter<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
on<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
on<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
listeners<TCEvent extends TypedContractEvent>(
event: TCEvent
): Promise<Array<TypedListener<TCEvent>>>;
listeners(eventName?: string): Promise<Array<Listener>>;
removeAllListeners<TCEvent extends TypedContractEvent>(
event?: TCEvent
): Promise<this>;
getRoleAdmin: TypedContractMethod<[role: BytesLike], [string], "view">;
grantRole: TypedContractMethod<
[role: BytesLike, account: AddressLike],
[void],
"nonpayable"
>;
hasRole: TypedContractMethod<
[role: BytesLike, account: AddressLike],
[boolean],
"view"
>;
renounceRole: TypedContractMethod<
[role: BytesLike, callerConfirmation: AddressLike],
[void],
"nonpayable"
>;
revokeRole: TypedContractMethod<
[role: BytesLike, account: AddressLike],
[void],
"nonpayable"
>;
getFunction<T extends ContractMethod = ContractMethod>(
key: string | FunctionFragment
): T;
getFunction(
nameOrSignature: "getRoleAdmin"
): TypedContractMethod<[role: BytesLike], [string], "view">;
getFunction(
nameOrSignature: "grantRole"
): TypedContractMethod<
[role: BytesLike, account: AddressLike],
[void],
"nonpayable"
>;
getFunction(
nameOrSignature: "hasRole"
): TypedContractMethod<
[role: BytesLike, account: AddressLike],
[boolean],
"view"
>;
getFunction(
nameOrSignature: "renounceRole"
): TypedContractMethod<
[role: BytesLike, callerConfirmation: AddressLike],
[void],
"nonpayable"
>;
getFunction(
nameOrSignature: "revokeRole"
): TypedContractMethod<
[role: BytesLike, account: AddressLike],
[void],
"nonpayable"
>;
getEvent(
key: "RoleAdminChanged"
): TypedContractEvent<
RoleAdminChangedEvent.InputTuple,
RoleAdminChangedEvent.OutputTuple,
RoleAdminChangedEvent.OutputObject
>;
getEvent(
key: "RoleGranted"
): TypedContractEvent<
RoleGrantedEvent.InputTuple,
RoleGrantedEvent.OutputTuple,
RoleGrantedEvent.OutputObject
>;
getEvent(
key: "RoleRevoked"
): TypedContractEvent<
RoleRevokedEvent.InputTuple,
RoleRevokedEvent.OutputTuple,
RoleRevokedEvent.OutputObject
>;
filters: {
"RoleAdminChanged(bytes32,bytes32,bytes32)": TypedContractEvent<
RoleAdminChangedEvent.InputTuple,
RoleAdminChangedEvent.OutputTuple,
RoleAdminChangedEvent.OutputObject
>;
RoleAdminChanged: TypedContractEvent<
RoleAdminChangedEvent.InputTuple,
RoleAdminChangedEvent.OutputTuple,
RoleAdminChangedEvent.OutputObject
>;
"RoleGranted(bytes32,address,address)": TypedContractEvent<
RoleGrantedEvent.InputTuple,
RoleGrantedEvent.OutputTuple,
RoleGrantedEvent.OutputObject
>;
RoleGranted: TypedContractEvent<
RoleGrantedEvent.InputTuple,
RoleGrantedEvent.OutputTuple,
RoleGrantedEvent.OutputObject
>;
"RoleRevoked(bytes32,address,address)": TypedContractEvent<
RoleRevokedEvent.InputTuple,
RoleRevokedEvent.OutputTuple,
RoleRevokedEvent.OutputObject
>;
RoleRevoked: TypedContractEvent<
RoleRevokedEvent.InputTuple,
RoleRevokedEvent.OutputTuple,
RoleRevokedEvent.OutputObject
>;
};
}

View File

@@ -0,0 +1,5 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export type { AccessControl } from "./AccessControl";
export type { IAccessControl } from "./IAccessControl";

View File

@@ -0,0 +1,11 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type * as access from "./access";
export type { access };
import type * as interfaces from "./interfaces";
export type { interfaces };
import type * as token from "./token";
export type { token };
import type * as utils from "./utils";
export type { utils };

View File

@@ -0,0 +1,69 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type {
BaseContract,
FunctionFragment,
Interface,
ContractRunner,
ContractMethod,
Listener,
} from "ethers";
import type {
TypedContractEvent,
TypedDeferredTopicFilter,
TypedEventLog,
TypedListener,
} from "../../../../common";
export interface IERC1155ErrorsInterface extends Interface {}
export interface IERC1155Errors extends BaseContract {
connect(runner?: ContractRunner | null): IERC1155Errors;
waitForDeployment(): Promise<this>;
interface: IERC1155ErrorsInterface;
queryFilter<TCEvent extends TypedContractEvent>(
event: TCEvent,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
queryFilter<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
on<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
on<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
listeners<TCEvent extends TypedContractEvent>(
event: TCEvent
): Promise<Array<TypedListener<TCEvent>>>;
listeners(eventName?: string): Promise<Array<Listener>>;
removeAllListeners<TCEvent extends TypedContractEvent>(
event?: TCEvent
): Promise<this>;
getFunction<T extends ContractMethod = ContractMethod>(
key: string | FunctionFragment
): T;
filters: {};
}

View File

@@ -0,0 +1,69 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type {
BaseContract,
FunctionFragment,
Interface,
ContractRunner,
ContractMethod,
Listener,
} from "ethers";
import type {
TypedContractEvent,
TypedDeferredTopicFilter,
TypedEventLog,
TypedListener,
} from "../../../../common";
export interface IERC20ErrorsInterface extends Interface {}
export interface IERC20Errors extends BaseContract {
connect(runner?: ContractRunner | null): IERC20Errors;
waitForDeployment(): Promise<this>;
interface: IERC20ErrorsInterface;
queryFilter<TCEvent extends TypedContractEvent>(
event: TCEvent,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
queryFilter<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
on<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
on<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
listeners<TCEvent extends TypedContractEvent>(
event: TCEvent
): Promise<Array<TypedListener<TCEvent>>>;
listeners(eventName?: string): Promise<Array<Listener>>;
removeAllListeners<TCEvent extends TypedContractEvent>(
event?: TCEvent
): Promise<this>;
getFunction<T extends ContractMethod = ContractMethod>(
key: string | FunctionFragment
): T;
filters: {};
}

View File

@@ -0,0 +1,69 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type {
BaseContract,
FunctionFragment,
Interface,
ContractRunner,
ContractMethod,
Listener,
} from "ethers";
import type {
TypedContractEvent,
TypedDeferredTopicFilter,
TypedEventLog,
TypedListener,
} from "../../../../common";
export interface IERC721ErrorsInterface extends Interface {}
export interface IERC721Errors extends BaseContract {
connect(runner?: ContractRunner | null): IERC721Errors;
waitForDeployment(): Promise<this>;
interface: IERC721ErrorsInterface;
queryFilter<TCEvent extends TypedContractEvent>(
event: TCEvent,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
queryFilter<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
on<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
on<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
listeners<TCEvent extends TypedContractEvent>(
event: TCEvent
): Promise<Array<TypedListener<TCEvent>>>;
listeners(eventName?: string): Promise<Array<Listener>>;
removeAllListeners<TCEvent extends TypedContractEvent>(
event?: TCEvent
): Promise<this>;
getFunction<T extends ContractMethod = ContractMethod>(
key: string | FunctionFragment
): T;
filters: {};
}

View File

@@ -0,0 +1,6 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export type { IERC1155Errors } from "./IERC1155Errors";
export type { IERC20Errors } from "./IERC20Errors";
export type { IERC721Errors } from "./IERC721Errors";

View File

@@ -0,0 +1,5 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type * as draftIerc6093Sol from "./draft-IERC6093.sol";
export type { draftIerc6093Sol };

View File

@@ -0,0 +1,286 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type {
BaseContract,
BigNumberish,
BytesLike,
FunctionFragment,
Result,
Interface,
EventFragment,
AddressLike,
ContractRunner,
ContractMethod,
Listener,
} from "ethers";
import type {
TypedContractEvent,
TypedDeferredTopicFilter,
TypedEventLog,
TypedLogDescription,
TypedListener,
TypedContractMethod,
} from "../../../../common";
export interface ERC20Interface extends Interface {
getFunction(
nameOrSignature:
| "allowance"
| "approve"
| "balanceOf"
| "decimals"
| "name"
| "symbol"
| "totalSupply"
| "transfer"
| "transferFrom"
): FunctionFragment;
getEvent(nameOrSignatureOrTopic: "Approval" | "Transfer"): EventFragment;
encodeFunctionData(
functionFragment: "allowance",
values: [AddressLike, AddressLike]
): string;
encodeFunctionData(
functionFragment: "approve",
values: [AddressLike, BigNumberish]
): string;
encodeFunctionData(
functionFragment: "balanceOf",
values: [AddressLike]
): string;
encodeFunctionData(functionFragment: "decimals", values?: undefined): string;
encodeFunctionData(functionFragment: "name", values?: undefined): string;
encodeFunctionData(functionFragment: "symbol", values?: undefined): string;
encodeFunctionData(
functionFragment: "totalSupply",
values?: undefined
): string;
encodeFunctionData(
functionFragment: "transfer",
values: [AddressLike, BigNumberish]
): string;
encodeFunctionData(
functionFragment: "transferFrom",
values: [AddressLike, AddressLike, BigNumberish]
): string;
decodeFunctionResult(functionFragment: "allowance", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "approve", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "balanceOf", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "decimals", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "name", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "symbol", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "totalSupply",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "transfer", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "transferFrom",
data: BytesLike
): Result;
}
export namespace ApprovalEvent {
export type InputTuple = [
owner: AddressLike,
spender: AddressLike,
value: BigNumberish
];
export type OutputTuple = [owner: string, spender: string, value: bigint];
export interface OutputObject {
owner: string;
spender: string;
value: bigint;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export namespace TransferEvent {
export type InputTuple = [
from: AddressLike,
to: AddressLike,
value: BigNumberish
];
export type OutputTuple = [from: string, to: string, value: bigint];
export interface OutputObject {
from: string;
to: string;
value: bigint;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export interface ERC20 extends BaseContract {
connect(runner?: ContractRunner | null): ERC20;
waitForDeployment(): Promise<this>;
interface: ERC20Interface;
queryFilter<TCEvent extends TypedContractEvent>(
event: TCEvent,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
queryFilter<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
on<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
on<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
listeners<TCEvent extends TypedContractEvent>(
event: TCEvent
): Promise<Array<TypedListener<TCEvent>>>;
listeners(eventName?: string): Promise<Array<Listener>>;
removeAllListeners<TCEvent extends TypedContractEvent>(
event?: TCEvent
): Promise<this>;
allowance: TypedContractMethod<
[owner: AddressLike, spender: AddressLike],
[bigint],
"view"
>;
approve: TypedContractMethod<
[spender: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
balanceOf: TypedContractMethod<[account: AddressLike], [bigint], "view">;
decimals: TypedContractMethod<[], [bigint], "view">;
name: TypedContractMethod<[], [string], "view">;
symbol: TypedContractMethod<[], [string], "view">;
totalSupply: TypedContractMethod<[], [bigint], "view">;
transfer: TypedContractMethod<
[to: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
transferFrom: TypedContractMethod<
[from: AddressLike, to: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
getFunction<T extends ContractMethod = ContractMethod>(
key: string | FunctionFragment
): T;
getFunction(
nameOrSignature: "allowance"
): TypedContractMethod<
[owner: AddressLike, spender: AddressLike],
[bigint],
"view"
>;
getFunction(
nameOrSignature: "approve"
): TypedContractMethod<
[spender: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
getFunction(
nameOrSignature: "balanceOf"
): TypedContractMethod<[account: AddressLike], [bigint], "view">;
getFunction(
nameOrSignature: "decimals"
): TypedContractMethod<[], [bigint], "view">;
getFunction(
nameOrSignature: "name"
): TypedContractMethod<[], [string], "view">;
getFunction(
nameOrSignature: "symbol"
): TypedContractMethod<[], [string], "view">;
getFunction(
nameOrSignature: "totalSupply"
): TypedContractMethod<[], [bigint], "view">;
getFunction(
nameOrSignature: "transfer"
): TypedContractMethod<
[to: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
getFunction(
nameOrSignature: "transferFrom"
): TypedContractMethod<
[from: AddressLike, to: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
getEvent(
key: "Approval"
): TypedContractEvent<
ApprovalEvent.InputTuple,
ApprovalEvent.OutputTuple,
ApprovalEvent.OutputObject
>;
getEvent(
key: "Transfer"
): TypedContractEvent<
TransferEvent.InputTuple,
TransferEvent.OutputTuple,
TransferEvent.OutputObject
>;
filters: {
"Approval(address,address,uint256)": TypedContractEvent<
ApprovalEvent.InputTuple,
ApprovalEvent.OutputTuple,
ApprovalEvent.OutputObject
>;
Approval: TypedContractEvent<
ApprovalEvent.InputTuple,
ApprovalEvent.OutputTuple,
ApprovalEvent.OutputObject
>;
"Transfer(address,address,uint256)": TypedContractEvent<
TransferEvent.InputTuple,
TransferEvent.OutputTuple,
TransferEvent.OutputObject
>;
Transfer: TypedContractEvent<
TransferEvent.InputTuple,
TransferEvent.OutputTuple,
TransferEvent.OutputObject
>;
};
}

View File

@@ -0,0 +1,262 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type {
BaseContract,
BigNumberish,
BytesLike,
FunctionFragment,
Result,
Interface,
EventFragment,
AddressLike,
ContractRunner,
ContractMethod,
Listener,
} from "ethers";
import type {
TypedContractEvent,
TypedDeferredTopicFilter,
TypedEventLog,
TypedLogDescription,
TypedListener,
TypedContractMethod,
} from "../../../../common";
export interface IERC20Interface extends Interface {
getFunction(
nameOrSignature:
| "allowance"
| "approve"
| "balanceOf"
| "totalSupply"
| "transfer"
| "transferFrom"
): FunctionFragment;
getEvent(nameOrSignatureOrTopic: "Approval" | "Transfer"): EventFragment;
encodeFunctionData(
functionFragment: "allowance",
values: [AddressLike, AddressLike]
): string;
encodeFunctionData(
functionFragment: "approve",
values: [AddressLike, BigNumberish]
): string;
encodeFunctionData(
functionFragment: "balanceOf",
values: [AddressLike]
): string;
encodeFunctionData(
functionFragment: "totalSupply",
values?: undefined
): string;
encodeFunctionData(
functionFragment: "transfer",
values: [AddressLike, BigNumberish]
): string;
encodeFunctionData(
functionFragment: "transferFrom",
values: [AddressLike, AddressLike, BigNumberish]
): string;
decodeFunctionResult(functionFragment: "allowance", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "approve", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "balanceOf", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "totalSupply",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "transfer", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "transferFrom",
data: BytesLike
): Result;
}
export namespace ApprovalEvent {
export type InputTuple = [
owner: AddressLike,
spender: AddressLike,
value: BigNumberish
];
export type OutputTuple = [owner: string, spender: string, value: bigint];
export interface OutputObject {
owner: string;
spender: string;
value: bigint;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export namespace TransferEvent {
export type InputTuple = [
from: AddressLike,
to: AddressLike,
value: BigNumberish
];
export type OutputTuple = [from: string, to: string, value: bigint];
export interface OutputObject {
from: string;
to: string;
value: bigint;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export interface IERC20 extends BaseContract {
connect(runner?: ContractRunner | null): IERC20;
waitForDeployment(): Promise<this>;
interface: IERC20Interface;
queryFilter<TCEvent extends TypedContractEvent>(
event: TCEvent,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
queryFilter<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
on<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
on<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
listeners<TCEvent extends TypedContractEvent>(
event: TCEvent
): Promise<Array<TypedListener<TCEvent>>>;
listeners(eventName?: string): Promise<Array<Listener>>;
removeAllListeners<TCEvent extends TypedContractEvent>(
event?: TCEvent
): Promise<this>;
allowance: TypedContractMethod<
[owner: AddressLike, spender: AddressLike],
[bigint],
"view"
>;
approve: TypedContractMethod<
[spender: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
balanceOf: TypedContractMethod<[account: AddressLike], [bigint], "view">;
totalSupply: TypedContractMethod<[], [bigint], "view">;
transfer: TypedContractMethod<
[to: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
transferFrom: TypedContractMethod<
[from: AddressLike, to: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
getFunction<T extends ContractMethod = ContractMethod>(
key: string | FunctionFragment
): T;
getFunction(
nameOrSignature: "allowance"
): TypedContractMethod<
[owner: AddressLike, spender: AddressLike],
[bigint],
"view"
>;
getFunction(
nameOrSignature: "approve"
): TypedContractMethod<
[spender: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
getFunction(
nameOrSignature: "balanceOf"
): TypedContractMethod<[account: AddressLike], [bigint], "view">;
getFunction(
nameOrSignature: "totalSupply"
): TypedContractMethod<[], [bigint], "view">;
getFunction(
nameOrSignature: "transfer"
): TypedContractMethod<
[to: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
getFunction(
nameOrSignature: "transferFrom"
): TypedContractMethod<
[from: AddressLike, to: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
getEvent(
key: "Approval"
): TypedContractEvent<
ApprovalEvent.InputTuple,
ApprovalEvent.OutputTuple,
ApprovalEvent.OutputObject
>;
getEvent(
key: "Transfer"
): TypedContractEvent<
TransferEvent.InputTuple,
TransferEvent.OutputTuple,
TransferEvent.OutputObject
>;
filters: {
"Approval(address,address,uint256)": TypedContractEvent<
ApprovalEvent.InputTuple,
ApprovalEvent.OutputTuple,
ApprovalEvent.OutputObject
>;
Approval: TypedContractEvent<
ApprovalEvent.InputTuple,
ApprovalEvent.OutputTuple,
ApprovalEvent.OutputObject
>;
"Transfer(address,address,uint256)": TypedContractEvent<
TransferEvent.InputTuple,
TransferEvent.OutputTuple,
TransferEvent.OutputObject
>;
Transfer: TypedContractEvent<
TransferEvent.InputTuple,
TransferEvent.OutputTuple,
TransferEvent.OutputObject
>;
};
}

View File

@@ -0,0 +1,286 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type {
BaseContract,
BigNumberish,
BytesLike,
FunctionFragment,
Result,
Interface,
EventFragment,
AddressLike,
ContractRunner,
ContractMethod,
Listener,
} from "ethers";
import type {
TypedContractEvent,
TypedDeferredTopicFilter,
TypedEventLog,
TypedLogDescription,
TypedListener,
TypedContractMethod,
} from "../../../../../common";
export interface IERC20MetadataInterface extends Interface {
getFunction(
nameOrSignature:
| "allowance"
| "approve"
| "balanceOf"
| "decimals"
| "name"
| "symbol"
| "totalSupply"
| "transfer"
| "transferFrom"
): FunctionFragment;
getEvent(nameOrSignatureOrTopic: "Approval" | "Transfer"): EventFragment;
encodeFunctionData(
functionFragment: "allowance",
values: [AddressLike, AddressLike]
): string;
encodeFunctionData(
functionFragment: "approve",
values: [AddressLike, BigNumberish]
): string;
encodeFunctionData(
functionFragment: "balanceOf",
values: [AddressLike]
): string;
encodeFunctionData(functionFragment: "decimals", values?: undefined): string;
encodeFunctionData(functionFragment: "name", values?: undefined): string;
encodeFunctionData(functionFragment: "symbol", values?: undefined): string;
encodeFunctionData(
functionFragment: "totalSupply",
values?: undefined
): string;
encodeFunctionData(
functionFragment: "transfer",
values: [AddressLike, BigNumberish]
): string;
encodeFunctionData(
functionFragment: "transferFrom",
values: [AddressLike, AddressLike, BigNumberish]
): string;
decodeFunctionResult(functionFragment: "allowance", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "approve", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "balanceOf", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "decimals", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "name", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "symbol", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "totalSupply",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "transfer", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "transferFrom",
data: BytesLike
): Result;
}
export namespace ApprovalEvent {
export type InputTuple = [
owner: AddressLike,
spender: AddressLike,
value: BigNumberish
];
export type OutputTuple = [owner: string, spender: string, value: bigint];
export interface OutputObject {
owner: string;
spender: string;
value: bigint;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export namespace TransferEvent {
export type InputTuple = [
from: AddressLike,
to: AddressLike,
value: BigNumberish
];
export type OutputTuple = [from: string, to: string, value: bigint];
export interface OutputObject {
from: string;
to: string;
value: bigint;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export interface IERC20Metadata extends BaseContract {
connect(runner?: ContractRunner | null): IERC20Metadata;
waitForDeployment(): Promise<this>;
interface: IERC20MetadataInterface;
queryFilter<TCEvent extends TypedContractEvent>(
event: TCEvent,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
queryFilter<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
on<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
on<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
listeners<TCEvent extends TypedContractEvent>(
event: TCEvent
): Promise<Array<TypedListener<TCEvent>>>;
listeners(eventName?: string): Promise<Array<Listener>>;
removeAllListeners<TCEvent extends TypedContractEvent>(
event?: TCEvent
): Promise<this>;
allowance: TypedContractMethod<
[owner: AddressLike, spender: AddressLike],
[bigint],
"view"
>;
approve: TypedContractMethod<
[spender: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
balanceOf: TypedContractMethod<[account: AddressLike], [bigint], "view">;
decimals: TypedContractMethod<[], [bigint], "view">;
name: TypedContractMethod<[], [string], "view">;
symbol: TypedContractMethod<[], [string], "view">;
totalSupply: TypedContractMethod<[], [bigint], "view">;
transfer: TypedContractMethod<
[to: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
transferFrom: TypedContractMethod<
[from: AddressLike, to: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
getFunction<T extends ContractMethod = ContractMethod>(
key: string | FunctionFragment
): T;
getFunction(
nameOrSignature: "allowance"
): TypedContractMethod<
[owner: AddressLike, spender: AddressLike],
[bigint],
"view"
>;
getFunction(
nameOrSignature: "approve"
): TypedContractMethod<
[spender: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
getFunction(
nameOrSignature: "balanceOf"
): TypedContractMethod<[account: AddressLike], [bigint], "view">;
getFunction(
nameOrSignature: "decimals"
): TypedContractMethod<[], [bigint], "view">;
getFunction(
nameOrSignature: "name"
): TypedContractMethod<[], [string], "view">;
getFunction(
nameOrSignature: "symbol"
): TypedContractMethod<[], [string], "view">;
getFunction(
nameOrSignature: "totalSupply"
): TypedContractMethod<[], [bigint], "view">;
getFunction(
nameOrSignature: "transfer"
): TypedContractMethod<
[to: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
getFunction(
nameOrSignature: "transferFrom"
): TypedContractMethod<
[from: AddressLike, to: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
getEvent(
key: "Approval"
): TypedContractEvent<
ApprovalEvent.InputTuple,
ApprovalEvent.OutputTuple,
ApprovalEvent.OutputObject
>;
getEvent(
key: "Transfer"
): TypedContractEvent<
TransferEvent.InputTuple,
TransferEvent.OutputTuple,
TransferEvent.OutputObject
>;
filters: {
"Approval(address,address,uint256)": TypedContractEvent<
ApprovalEvent.InputTuple,
ApprovalEvent.OutputTuple,
ApprovalEvent.OutputObject
>;
Approval: TypedContractEvent<
ApprovalEvent.InputTuple,
ApprovalEvent.OutputTuple,
ApprovalEvent.OutputObject
>;
"Transfer(address,address,uint256)": TypedContractEvent<
TransferEvent.InputTuple,
TransferEvent.OutputTuple,
TransferEvent.OutputObject
>;
Transfer: TypedContractEvent<
TransferEvent.InputTuple,
TransferEvent.OutputTuple,
TransferEvent.OutputObject
>;
};
}

View File

@@ -0,0 +1,4 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export type { IERC20Metadata } from "./IERC20Metadata";

View File

@@ -0,0 +1,7 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type * as extensions from "./extensions";
export type { extensions };
export type { ERC20 } from "./ERC20";
export type { IERC20 } from "./IERC20";

View File

@@ -0,0 +1,5 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type * as erc20 from "./ERC20";
export type { erc20 };

View File

@@ -0,0 +1,69 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type {
BaseContract,
FunctionFragment,
Interface,
ContractRunner,
ContractMethod,
Listener,
} from "ethers";
import type {
TypedContractEvent,
TypedDeferredTopicFilter,
TypedEventLog,
TypedListener,
} from "../../../common";
export interface StringsInterface extends Interface {}
export interface Strings extends BaseContract {
connect(runner?: ContractRunner | null): Strings;
waitForDeployment(): Promise<this>;
interface: StringsInterface;
queryFilter<TCEvent extends TypedContractEvent>(
event: TCEvent,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
queryFilter<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
on<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
on<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
listeners<TCEvent extends TypedContractEvent>(
event: TCEvent
): Promise<Array<TypedListener<TCEvent>>>;
listeners(eventName?: string): Promise<Array<Listener>>;
removeAllListeners<TCEvent extends TypedContractEvent>(
event?: TCEvent
): Promise<this>;
getFunction<T extends ContractMethod = ContractMethod>(
key: string | FunctionFragment
): T;
filters: {};
}

View File

@@ -0,0 +1,69 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type {
BaseContract,
FunctionFragment,
Interface,
ContractRunner,
ContractMethod,
Listener,
} from "ethers";
import type {
TypedContractEvent,
TypedDeferredTopicFilter,
TypedEventLog,
TypedListener,
} from "../../../../common";
export interface ECDSAInterface extends Interface {}
export interface ECDSA extends BaseContract {
connect(runner?: ContractRunner | null): ECDSA;
waitForDeployment(): Promise<this>;
interface: ECDSAInterface;
queryFilter<TCEvent extends TypedContractEvent>(
event: TCEvent,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
queryFilter<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
on<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
on<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
listeners<TCEvent extends TypedContractEvent>(
event: TCEvent
): Promise<Array<TypedListener<TCEvent>>>;
listeners(eventName?: string): Promise<Array<Listener>>;
removeAllListeners<TCEvent extends TypedContractEvent>(
event?: TCEvent
): Promise<this>;
getFunction<T extends ContractMethod = ContractMethod>(
key: string | FunctionFragment
): T;
filters: {};
}

View File

@@ -0,0 +1,4 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export type { ECDSA } from "./ECDSA";

View File

@@ -0,0 +1,10 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type * as cryptography from "./cryptography";
export type { cryptography };
import type * as introspection from "./introspection";
export type { introspection };
import type * as math from "./math";
export type { math };
export type { Strings } from "./Strings";

View File

@@ -0,0 +1,94 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type {
BaseContract,
BytesLike,
FunctionFragment,
Result,
Interface,
ContractRunner,
ContractMethod,
Listener,
} from "ethers";
import type {
TypedContractEvent,
TypedDeferredTopicFilter,
TypedEventLog,
TypedListener,
TypedContractMethod,
} from "../../../../common";
export interface ERC165Interface extends Interface {
getFunction(nameOrSignature: "supportsInterface"): FunctionFragment;
encodeFunctionData(
functionFragment: "supportsInterface",
values: [BytesLike]
): string;
decodeFunctionResult(
functionFragment: "supportsInterface",
data: BytesLike
): Result;
}
export interface ERC165 extends BaseContract {
connect(runner?: ContractRunner | null): ERC165;
waitForDeployment(): Promise<this>;
interface: ERC165Interface;
queryFilter<TCEvent extends TypedContractEvent>(
event: TCEvent,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
queryFilter<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
on<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
on<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
listeners<TCEvent extends TypedContractEvent>(
event: TCEvent
): Promise<Array<TypedListener<TCEvent>>>;
listeners(eventName?: string): Promise<Array<Listener>>;
removeAllListeners<TCEvent extends TypedContractEvent>(
event?: TCEvent
): Promise<this>;
supportsInterface: TypedContractMethod<
[interfaceId: BytesLike],
[boolean],
"view"
>;
getFunction<T extends ContractMethod = ContractMethod>(
key: string | FunctionFragment
): T;
getFunction(
nameOrSignature: "supportsInterface"
): TypedContractMethod<[interfaceId: BytesLike], [boolean], "view">;
filters: {};
}

View File

@@ -0,0 +1,94 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type {
BaseContract,
BytesLike,
FunctionFragment,
Result,
Interface,
ContractRunner,
ContractMethod,
Listener,
} from "ethers";
import type {
TypedContractEvent,
TypedDeferredTopicFilter,
TypedEventLog,
TypedListener,
TypedContractMethod,
} from "../../../../common";
export interface IERC165Interface extends Interface {
getFunction(nameOrSignature: "supportsInterface"): FunctionFragment;
encodeFunctionData(
functionFragment: "supportsInterface",
values: [BytesLike]
): string;
decodeFunctionResult(
functionFragment: "supportsInterface",
data: BytesLike
): Result;
}
export interface IERC165 extends BaseContract {
connect(runner?: ContractRunner | null): IERC165;
waitForDeployment(): Promise<this>;
interface: IERC165Interface;
queryFilter<TCEvent extends TypedContractEvent>(
event: TCEvent,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
queryFilter<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
on<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
on<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
listeners<TCEvent extends TypedContractEvent>(
event: TCEvent
): Promise<Array<TypedListener<TCEvent>>>;
listeners(eventName?: string): Promise<Array<Listener>>;
removeAllListeners<TCEvent extends TypedContractEvent>(
event?: TCEvent
): Promise<this>;
supportsInterface: TypedContractMethod<
[interfaceId: BytesLike],
[boolean],
"view"
>;
getFunction<T extends ContractMethod = ContractMethod>(
key: string | FunctionFragment
): T;
getFunction(
nameOrSignature: "supportsInterface"
): TypedContractMethod<[interfaceId: BytesLike], [boolean], "view">;
filters: {};
}

View File

@@ -0,0 +1,5 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export type { ERC165 } from "./ERC165";
export type { IERC165 } from "./IERC165";

View File

@@ -0,0 +1,69 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type {
BaseContract,
FunctionFragment,
Interface,
ContractRunner,
ContractMethod,
Listener,
} from "ethers";
import type {
TypedContractEvent,
TypedDeferredTopicFilter,
TypedEventLog,
TypedListener,
} from "../../../../common";
export interface SafeCastInterface extends Interface {}
export interface SafeCast extends BaseContract {
connect(runner?: ContractRunner | null): SafeCast;
waitForDeployment(): Promise<this>;
interface: SafeCastInterface;
queryFilter<TCEvent extends TypedContractEvent>(
event: TCEvent,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
queryFilter<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
on<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
on<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
listeners<TCEvent extends TypedContractEvent>(
event: TCEvent
): Promise<Array<TypedListener<TCEvent>>>;
listeners(eventName?: string): Promise<Array<Listener>>;
removeAllListeners<TCEvent extends TypedContractEvent>(
event?: TCEvent
): Promise<this>;
getFunction<T extends ContractMethod = ContractMethod>(
key: string | FunctionFragment
): T;
filters: {};
}

View File

@@ -0,0 +1,4 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export type { SafeCast } from "./SafeCast";

View File

@@ -0,0 +1,5 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type * as contracts from "./contracts";
export type { contracts };

View File

@@ -0,0 +1,131 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type {
FunctionFragment,
Typed,
EventFragment,
ContractTransaction,
ContractTransactionResponse,
DeferredTopicFilter,
EventLog,
TransactionRequest,
LogDescription,
} from "ethers";
export interface TypedDeferredTopicFilter<_TCEvent extends TypedContractEvent>
extends DeferredTopicFilter {}
export interface TypedContractEvent<
InputTuple extends Array<any> = any,
OutputTuple extends Array<any> = any,
OutputObject = any
> {
(...args: Partial<InputTuple>): TypedDeferredTopicFilter<
TypedContractEvent<InputTuple, OutputTuple, OutputObject>
>;
name: string;
fragment: EventFragment;
getFragment(...args: Partial<InputTuple>): EventFragment;
}
type __TypechainAOutputTuple<T> = T extends TypedContractEvent<
infer _U,
infer W
>
? W
: never;
type __TypechainOutputObject<T> = T extends TypedContractEvent<
infer _U,
infer _W,
infer V
>
? V
: never;
export interface TypedEventLog<TCEvent extends TypedContractEvent>
extends Omit<EventLog, "args"> {
args: __TypechainAOutputTuple<TCEvent> & __TypechainOutputObject<TCEvent>;
}
export interface TypedLogDescription<TCEvent extends TypedContractEvent>
extends Omit<LogDescription, "args"> {
args: __TypechainAOutputTuple<TCEvent> & __TypechainOutputObject<TCEvent>;
}
export type TypedListener<TCEvent extends TypedContractEvent> = (
...listenerArg: [
...__TypechainAOutputTuple<TCEvent>,
TypedEventLog<TCEvent>,
...undefined[]
]
) => void;
export type MinEthersFactory<C, ARGS> = {
deploy(...a: ARGS[]): Promise<C>;
};
export type GetContractTypeFromFactory<F> = F extends MinEthersFactory<
infer C,
any
>
? C
: never;
export type GetARGsTypeFromFactory<F> = F extends MinEthersFactory<any, any>
? Parameters<F["deploy"]>
: never;
export type StateMutability = "nonpayable" | "payable" | "view";
export type BaseOverrides = Omit<TransactionRequest, "to" | "data">;
export type NonPayableOverrides = Omit<
BaseOverrides,
"value" | "blockTag" | "enableCcipRead"
>;
export type PayableOverrides = Omit<
BaseOverrides,
"blockTag" | "enableCcipRead"
>;
export type ViewOverrides = Omit<TransactionRequest, "to" | "data">;
export type Overrides<S extends StateMutability> = S extends "nonpayable"
? NonPayableOverrides
: S extends "payable"
? PayableOverrides
: ViewOverrides;
export type PostfixOverrides<A extends Array<any>, S extends StateMutability> =
| A
| [...A, Overrides<S>];
export type ContractMethodArgs<
A extends Array<any>,
S extends StateMutability
> = PostfixOverrides<{ [I in keyof A]-?: A[I] | Typed }, S>;
export type DefaultReturnType<R> = R extends Array<any> ? R[0] : R;
// export interface ContractMethod<A extends Array<any> = Array<any>, R = any, D extends R | ContractTransactionResponse = R | ContractTransactionResponse> {
export interface TypedContractMethod<
A extends Array<any> = Array<any>,
R = any,
S extends StateMutability = "payable"
> {
(...args: ContractMethodArgs<A, S>): S extends "view"
? Promise<DefaultReturnType<R>>
: Promise<ContractTransactionResponse>;
name: string;
fragment: FunctionFragment;
getFragment(...args: ContractMethodArgs<A, S>): FunctionFragment;
populateTransaction(
...args: ContractMethodArgs<A, S>
): Promise<ContractTransaction>;
staticCall(
...args: ContractMethodArgs<A, "view">
): Promise<DefaultReturnType<R>>;
send(...args: ContractMethodArgs<A, S>): Promise<ContractTransactionResponse>;
estimateGas(...args: ContractMethodArgs<A, S>): Promise<bigint>;
staticCallResult(...args: ContractMethodArgs<A, "view">): Promise<R>;
}

View File

@@ -0,0 +1,667 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type {
BaseContract,
BigNumberish,
BytesLike,
FunctionFragment,
Result,
Interface,
EventFragment,
AddressLike,
ContractRunner,
ContractMethod,
Listener,
} from "ethers";
import type {
TypedContractEvent,
TypedDeferredTopicFilter,
TypedEventLog,
TypedLogDescription,
TypedListener,
TypedContractMethod,
} from "../common";
export interface AITokenInterface extends Interface {
getFunction(
nameOrSignature:
| "ATTESTOR_ROLE"
| "COORDINATOR_ROLE"
| "DEFAULT_ADMIN_ROLE"
| "allowance"
| "approve"
| "balanceOf"
| "consumedReceipts"
| "decimals"
| "getRoleAdmin"
| "grantRole"
| "hasRole"
| "mintDigest"
| "mintWithReceipt"
| "name"
| "renounceRole"
| "revokeRole"
| "supportsInterface"
| "symbol"
| "totalSupply"
| "transfer"
| "transferFrom"
): FunctionFragment;
getEvent(
nameOrSignatureOrTopic:
| "Approval"
| "ReceiptConsumed"
| "RoleAdminChanged"
| "RoleGranted"
| "RoleRevoked"
| "Transfer"
): EventFragment;
encodeFunctionData(
functionFragment: "ATTESTOR_ROLE",
values?: undefined
): string;
encodeFunctionData(
functionFragment: "COORDINATOR_ROLE",
values?: undefined
): string;
encodeFunctionData(
functionFragment: "DEFAULT_ADMIN_ROLE",
values?: undefined
): string;
encodeFunctionData(
functionFragment: "allowance",
values: [AddressLike, AddressLike]
): string;
encodeFunctionData(
functionFragment: "approve",
values: [AddressLike, BigNumberish]
): string;
encodeFunctionData(
functionFragment: "balanceOf",
values: [AddressLike]
): string;
encodeFunctionData(
functionFragment: "consumedReceipts",
values: [BytesLike]
): string;
encodeFunctionData(functionFragment: "decimals", values?: undefined): string;
encodeFunctionData(
functionFragment: "getRoleAdmin",
values: [BytesLike]
): string;
encodeFunctionData(
functionFragment: "grantRole",
values: [BytesLike, AddressLike]
): string;
encodeFunctionData(
functionFragment: "hasRole",
values: [BytesLike, AddressLike]
): string;
encodeFunctionData(
functionFragment: "mintDigest",
values: [AddressLike, BigNumberish, BytesLike]
): string;
encodeFunctionData(
functionFragment: "mintWithReceipt",
values: [AddressLike, BigNumberish, BytesLike, BytesLike]
): string;
encodeFunctionData(functionFragment: "name", values?: undefined): string;
encodeFunctionData(
functionFragment: "renounceRole",
values: [BytesLike, AddressLike]
): string;
encodeFunctionData(
functionFragment: "revokeRole",
values: [BytesLike, AddressLike]
): string;
encodeFunctionData(
functionFragment: "supportsInterface",
values: [BytesLike]
): string;
encodeFunctionData(functionFragment: "symbol", values?: undefined): string;
encodeFunctionData(
functionFragment: "totalSupply",
values?: undefined
): string;
encodeFunctionData(
functionFragment: "transfer",
values: [AddressLike, BigNumberish]
): string;
encodeFunctionData(
functionFragment: "transferFrom",
values: [AddressLike, AddressLike, BigNumberish]
): string;
decodeFunctionResult(
functionFragment: "ATTESTOR_ROLE",
data: BytesLike
): Result;
decodeFunctionResult(
functionFragment: "COORDINATOR_ROLE",
data: BytesLike
): Result;
decodeFunctionResult(
functionFragment: "DEFAULT_ADMIN_ROLE",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "allowance", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "approve", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "balanceOf", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "consumedReceipts",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "decimals", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "getRoleAdmin",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "grantRole", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "hasRole", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "mintDigest", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "mintWithReceipt",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "name", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "renounceRole",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "revokeRole", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "supportsInterface",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "symbol", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "totalSupply",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "transfer", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "transferFrom",
data: BytesLike
): Result;
}
export namespace ApprovalEvent {
export type InputTuple = [
owner: AddressLike,
spender: AddressLike,
value: BigNumberish
];
export type OutputTuple = [owner: string, spender: string, value: bigint];
export interface OutputObject {
owner: string;
spender: string;
value: bigint;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export namespace ReceiptConsumedEvent {
export type InputTuple = [
receiptHash: BytesLike,
provider: AddressLike,
units: BigNumberish,
attestor: AddressLike
];
export type OutputTuple = [
receiptHash: string,
provider: string,
units: bigint,
attestor: string
];
export interface OutputObject {
receiptHash: string;
provider: string;
units: bigint;
attestor: string;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export namespace RoleAdminChangedEvent {
export type InputTuple = [
role: BytesLike,
previousAdminRole: BytesLike,
newAdminRole: BytesLike
];
export type OutputTuple = [
role: string,
previousAdminRole: string,
newAdminRole: string
];
export interface OutputObject {
role: string;
previousAdminRole: string;
newAdminRole: string;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export namespace RoleGrantedEvent {
export type InputTuple = [
role: BytesLike,
account: AddressLike,
sender: AddressLike
];
export type OutputTuple = [role: string, account: string, sender: string];
export interface OutputObject {
role: string;
account: string;
sender: string;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export namespace RoleRevokedEvent {
export type InputTuple = [
role: BytesLike,
account: AddressLike,
sender: AddressLike
];
export type OutputTuple = [role: string, account: string, sender: string];
export interface OutputObject {
role: string;
account: string;
sender: string;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export namespace TransferEvent {
export type InputTuple = [
from: AddressLike,
to: AddressLike,
value: BigNumberish
];
export type OutputTuple = [from: string, to: string, value: bigint];
export interface OutputObject {
from: string;
to: string;
value: bigint;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export interface AIToken extends BaseContract {
connect(runner?: ContractRunner | null): AIToken;
waitForDeployment(): Promise<this>;
interface: AITokenInterface;
queryFilter<TCEvent extends TypedContractEvent>(
event: TCEvent,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
queryFilter<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
on<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
on<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
listeners<TCEvent extends TypedContractEvent>(
event: TCEvent
): Promise<Array<TypedListener<TCEvent>>>;
listeners(eventName?: string): Promise<Array<Listener>>;
removeAllListeners<TCEvent extends TypedContractEvent>(
event?: TCEvent
): Promise<this>;
ATTESTOR_ROLE: TypedContractMethod<[], [string], "view">;
COORDINATOR_ROLE: TypedContractMethod<[], [string], "view">;
DEFAULT_ADMIN_ROLE: TypedContractMethod<[], [string], "view">;
allowance: TypedContractMethod<
[owner: AddressLike, spender: AddressLike],
[bigint],
"view"
>;
approve: TypedContractMethod<
[spender: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
balanceOf: TypedContractMethod<[account: AddressLike], [bigint], "view">;
consumedReceipts: TypedContractMethod<[arg0: BytesLike], [boolean], "view">;
decimals: TypedContractMethod<[], [bigint], "view">;
getRoleAdmin: TypedContractMethod<[role: BytesLike], [string], "view">;
grantRole: TypedContractMethod<
[role: BytesLike, account: AddressLike],
[void],
"nonpayable"
>;
hasRole: TypedContractMethod<
[role: BytesLike, account: AddressLike],
[boolean],
"view"
>;
mintDigest: TypedContractMethod<
[provider: AddressLike, units: BigNumberish, receiptHash: BytesLike],
[string],
"view"
>;
mintWithReceipt: TypedContractMethod<
[
provider: AddressLike,
units: BigNumberish,
receiptHash: BytesLike,
signature: BytesLike
],
[void],
"nonpayable"
>;
name: TypedContractMethod<[], [string], "view">;
renounceRole: TypedContractMethod<
[role: BytesLike, callerConfirmation: AddressLike],
[void],
"nonpayable"
>;
revokeRole: TypedContractMethod<
[role: BytesLike, account: AddressLike],
[void],
"nonpayable"
>;
supportsInterface: TypedContractMethod<
[interfaceId: BytesLike],
[boolean],
"view"
>;
symbol: TypedContractMethod<[], [string], "view">;
totalSupply: TypedContractMethod<[], [bigint], "view">;
transfer: TypedContractMethod<
[to: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
transferFrom: TypedContractMethod<
[from: AddressLike, to: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
getFunction<T extends ContractMethod = ContractMethod>(
key: string | FunctionFragment
): T;
getFunction(
nameOrSignature: "ATTESTOR_ROLE"
): TypedContractMethod<[], [string], "view">;
getFunction(
nameOrSignature: "COORDINATOR_ROLE"
): TypedContractMethod<[], [string], "view">;
getFunction(
nameOrSignature: "DEFAULT_ADMIN_ROLE"
): TypedContractMethod<[], [string], "view">;
getFunction(
nameOrSignature: "allowance"
): TypedContractMethod<
[owner: AddressLike, spender: AddressLike],
[bigint],
"view"
>;
getFunction(
nameOrSignature: "approve"
): TypedContractMethod<
[spender: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
getFunction(
nameOrSignature: "balanceOf"
): TypedContractMethod<[account: AddressLike], [bigint], "view">;
getFunction(
nameOrSignature: "consumedReceipts"
): TypedContractMethod<[arg0: BytesLike], [boolean], "view">;
getFunction(
nameOrSignature: "decimals"
): TypedContractMethod<[], [bigint], "view">;
getFunction(
nameOrSignature: "getRoleAdmin"
): TypedContractMethod<[role: BytesLike], [string], "view">;
getFunction(
nameOrSignature: "grantRole"
): TypedContractMethod<
[role: BytesLike, account: AddressLike],
[void],
"nonpayable"
>;
getFunction(
nameOrSignature: "hasRole"
): TypedContractMethod<
[role: BytesLike, account: AddressLike],
[boolean],
"view"
>;
getFunction(
nameOrSignature: "mintDigest"
): TypedContractMethod<
[provider: AddressLike, units: BigNumberish, receiptHash: BytesLike],
[string],
"view"
>;
getFunction(
nameOrSignature: "mintWithReceipt"
): TypedContractMethod<
[
provider: AddressLike,
units: BigNumberish,
receiptHash: BytesLike,
signature: BytesLike
],
[void],
"nonpayable"
>;
getFunction(
nameOrSignature: "name"
): TypedContractMethod<[], [string], "view">;
getFunction(
nameOrSignature: "renounceRole"
): TypedContractMethod<
[role: BytesLike, callerConfirmation: AddressLike],
[void],
"nonpayable"
>;
getFunction(
nameOrSignature: "revokeRole"
): TypedContractMethod<
[role: BytesLike, account: AddressLike],
[void],
"nonpayable"
>;
getFunction(
nameOrSignature: "supportsInterface"
): TypedContractMethod<[interfaceId: BytesLike], [boolean], "view">;
getFunction(
nameOrSignature: "symbol"
): TypedContractMethod<[], [string], "view">;
getFunction(
nameOrSignature: "totalSupply"
): TypedContractMethod<[], [bigint], "view">;
getFunction(
nameOrSignature: "transfer"
): TypedContractMethod<
[to: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
getFunction(
nameOrSignature: "transferFrom"
): TypedContractMethod<
[from: AddressLike, to: AddressLike, value: BigNumberish],
[boolean],
"nonpayable"
>;
getEvent(
key: "Approval"
): TypedContractEvent<
ApprovalEvent.InputTuple,
ApprovalEvent.OutputTuple,
ApprovalEvent.OutputObject
>;
getEvent(
key: "ReceiptConsumed"
): TypedContractEvent<
ReceiptConsumedEvent.InputTuple,
ReceiptConsumedEvent.OutputTuple,
ReceiptConsumedEvent.OutputObject
>;
getEvent(
key: "RoleAdminChanged"
): TypedContractEvent<
RoleAdminChangedEvent.InputTuple,
RoleAdminChangedEvent.OutputTuple,
RoleAdminChangedEvent.OutputObject
>;
getEvent(
key: "RoleGranted"
): TypedContractEvent<
RoleGrantedEvent.InputTuple,
RoleGrantedEvent.OutputTuple,
RoleGrantedEvent.OutputObject
>;
getEvent(
key: "RoleRevoked"
): TypedContractEvent<
RoleRevokedEvent.InputTuple,
RoleRevokedEvent.OutputTuple,
RoleRevokedEvent.OutputObject
>;
getEvent(
key: "Transfer"
): TypedContractEvent<
TransferEvent.InputTuple,
TransferEvent.OutputTuple,
TransferEvent.OutputObject
>;
filters: {
"Approval(address,address,uint256)": TypedContractEvent<
ApprovalEvent.InputTuple,
ApprovalEvent.OutputTuple,
ApprovalEvent.OutputObject
>;
Approval: TypedContractEvent<
ApprovalEvent.InputTuple,
ApprovalEvent.OutputTuple,
ApprovalEvent.OutputObject
>;
"ReceiptConsumed(bytes32,address,uint256,address)": TypedContractEvent<
ReceiptConsumedEvent.InputTuple,
ReceiptConsumedEvent.OutputTuple,
ReceiptConsumedEvent.OutputObject
>;
ReceiptConsumed: TypedContractEvent<
ReceiptConsumedEvent.InputTuple,
ReceiptConsumedEvent.OutputTuple,
ReceiptConsumedEvent.OutputObject
>;
"RoleAdminChanged(bytes32,bytes32,bytes32)": TypedContractEvent<
RoleAdminChangedEvent.InputTuple,
RoleAdminChangedEvent.OutputTuple,
RoleAdminChangedEvent.OutputObject
>;
RoleAdminChanged: TypedContractEvent<
RoleAdminChangedEvent.InputTuple,
RoleAdminChangedEvent.OutputTuple,
RoleAdminChangedEvent.OutputObject
>;
"RoleGranted(bytes32,address,address)": TypedContractEvent<
RoleGrantedEvent.InputTuple,
RoleGrantedEvent.OutputTuple,
RoleGrantedEvent.OutputObject
>;
RoleGranted: TypedContractEvent<
RoleGrantedEvent.InputTuple,
RoleGrantedEvent.OutputTuple,
RoleGrantedEvent.OutputObject
>;
"RoleRevoked(bytes32,address,address)": TypedContractEvent<
RoleRevokedEvent.InputTuple,
RoleRevokedEvent.OutputTuple,
RoleRevokedEvent.OutputObject
>;
RoleRevoked: TypedContractEvent<
RoleRevokedEvent.InputTuple,
RoleRevokedEvent.OutputTuple,
RoleRevokedEvent.OutputObject
>;
"Transfer(address,address,uint256)": TypedContractEvent<
TransferEvent.InputTuple,
TransferEvent.OutputTuple,
TransferEvent.OutputObject
>;
Transfer: TypedContractEvent<
TransferEvent.InputTuple,
TransferEvent.OutputTuple,
TransferEvent.OutputObject
>;
};
}

View File

@@ -0,0 +1,512 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type {
BaseContract,
BigNumberish,
BytesLike,
FunctionFragment,
Result,
Interface,
EventFragment,
AddressLike,
ContractRunner,
ContractMethod,
Listener,
} from "ethers";
import type {
TypedContractEvent,
TypedDeferredTopicFilter,
TypedEventLog,
TypedLogDescription,
TypedListener,
TypedContractMethod,
} from "../common";
export declare namespace AITokenRegistry {
export type ProviderInfoStruct = {
active: boolean;
collateral: BigNumberish;
};
export type ProviderInfoStructOutput = [
active: boolean,
collateral: bigint
] & { active: boolean; collateral: bigint };
}
export interface AITokenRegistryInterface extends Interface {
getFunction(
nameOrSignature:
| "COORDINATOR_ROLE"
| "DEFAULT_ADMIN_ROLE"
| "getRoleAdmin"
| "grantRole"
| "hasRole"
| "providerInfo"
| "providers"
| "registerProvider"
| "renounceRole"
| "revokeRole"
| "supportsInterface"
| "updateProvider"
): FunctionFragment;
getEvent(
nameOrSignatureOrTopic:
| "ProviderRegistered"
| "ProviderUpdated"
| "RoleAdminChanged"
| "RoleGranted"
| "RoleRevoked"
): EventFragment;
encodeFunctionData(
functionFragment: "COORDINATOR_ROLE",
values?: undefined
): string;
encodeFunctionData(
functionFragment: "DEFAULT_ADMIN_ROLE",
values?: undefined
): string;
encodeFunctionData(
functionFragment: "getRoleAdmin",
values: [BytesLike]
): string;
encodeFunctionData(
functionFragment: "grantRole",
values: [BytesLike, AddressLike]
): string;
encodeFunctionData(
functionFragment: "hasRole",
values: [BytesLike, AddressLike]
): string;
encodeFunctionData(
functionFragment: "providerInfo",
values: [AddressLike]
): string;
encodeFunctionData(
functionFragment: "providers",
values: [AddressLike]
): string;
encodeFunctionData(
functionFragment: "registerProvider",
values: [AddressLike, BigNumberish]
): string;
encodeFunctionData(
functionFragment: "renounceRole",
values: [BytesLike, AddressLike]
): string;
encodeFunctionData(
functionFragment: "revokeRole",
values: [BytesLike, AddressLike]
): string;
encodeFunctionData(
functionFragment: "supportsInterface",
values: [BytesLike]
): string;
encodeFunctionData(
functionFragment: "updateProvider",
values: [AddressLike, boolean, BigNumberish]
): string;
decodeFunctionResult(
functionFragment: "COORDINATOR_ROLE",
data: BytesLike
): Result;
decodeFunctionResult(
functionFragment: "DEFAULT_ADMIN_ROLE",
data: BytesLike
): Result;
decodeFunctionResult(
functionFragment: "getRoleAdmin",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "grantRole", data: BytesLike): Result;
decodeFunctionResult(functionFragment: "hasRole", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "providerInfo",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "providers", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "registerProvider",
data: BytesLike
): Result;
decodeFunctionResult(
functionFragment: "renounceRole",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "revokeRole", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "supportsInterface",
data: BytesLike
): Result;
decodeFunctionResult(
functionFragment: "updateProvider",
data: BytesLike
): Result;
}
export namespace ProviderRegisteredEvent {
export type InputTuple = [provider: AddressLike, collateral: BigNumberish];
export type OutputTuple = [provider: string, collateral: bigint];
export interface OutputObject {
provider: string;
collateral: bigint;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export namespace ProviderUpdatedEvent {
export type InputTuple = [
provider: AddressLike,
active: boolean,
collateral: BigNumberish
];
export type OutputTuple = [
provider: string,
active: boolean,
collateral: bigint
];
export interface OutputObject {
provider: string;
active: boolean;
collateral: bigint;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export namespace RoleAdminChangedEvent {
export type InputTuple = [
role: BytesLike,
previousAdminRole: BytesLike,
newAdminRole: BytesLike
];
export type OutputTuple = [
role: string,
previousAdminRole: string,
newAdminRole: string
];
export interface OutputObject {
role: string;
previousAdminRole: string;
newAdminRole: string;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export namespace RoleGrantedEvent {
export type InputTuple = [
role: BytesLike,
account: AddressLike,
sender: AddressLike
];
export type OutputTuple = [role: string, account: string, sender: string];
export interface OutputObject {
role: string;
account: string;
sender: string;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export namespace RoleRevokedEvent {
export type InputTuple = [
role: BytesLike,
account: AddressLike,
sender: AddressLike
];
export type OutputTuple = [role: string, account: string, sender: string];
export interface OutputObject {
role: string;
account: string;
sender: string;
}
export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
export type Filter = TypedDeferredTopicFilter<Event>;
export type Log = TypedEventLog<Event>;
export type LogDescription = TypedLogDescription<Event>;
}
export interface AITokenRegistry extends BaseContract {
connect(runner?: ContractRunner | null): AITokenRegistry;
waitForDeployment(): Promise<this>;
interface: AITokenRegistryInterface;
queryFilter<TCEvent extends TypedContractEvent>(
event: TCEvent,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
queryFilter<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TypedEventLog<TCEvent>>>;
on<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
on<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
event: TCEvent,
listener: TypedListener<TCEvent>
): Promise<this>;
once<TCEvent extends TypedContractEvent>(
filter: TypedDeferredTopicFilter<TCEvent>,
listener: TypedListener<TCEvent>
): Promise<this>;
listeners<TCEvent extends TypedContractEvent>(
event: TCEvent
): Promise<Array<TypedListener<TCEvent>>>;
listeners(eventName?: string): Promise<Array<Listener>>;
removeAllListeners<TCEvent extends TypedContractEvent>(
event?: TCEvent
): Promise<this>;
COORDINATOR_ROLE: TypedContractMethod<[], [string], "view">;
DEFAULT_ADMIN_ROLE: TypedContractMethod<[], [string], "view">;
getRoleAdmin: TypedContractMethod<[role: BytesLike], [string], "view">;
grantRole: TypedContractMethod<
[role: BytesLike, account: AddressLike],
[void],
"nonpayable"
>;
hasRole: TypedContractMethod<
[role: BytesLike, account: AddressLike],
[boolean],
"view"
>;
providerInfo: TypedContractMethod<
[provider: AddressLike],
[AITokenRegistry.ProviderInfoStructOutput],
"view"
>;
providers: TypedContractMethod<
[arg0: AddressLike],
[[boolean, bigint] & { active: boolean; collateral: bigint }],
"view"
>;
registerProvider: TypedContractMethod<
[provider: AddressLike, collateral: BigNumberish],
[void],
"nonpayable"
>;
renounceRole: TypedContractMethod<
[role: BytesLike, callerConfirmation: AddressLike],
[void],
"nonpayable"
>;
revokeRole: TypedContractMethod<
[role: BytesLike, account: AddressLike],
[void],
"nonpayable"
>;
supportsInterface: TypedContractMethod<
[interfaceId: BytesLike],
[boolean],
"view"
>;
updateProvider: TypedContractMethod<
[provider: AddressLike, active: boolean, collateral: BigNumberish],
[void],
"nonpayable"
>;
getFunction<T extends ContractMethod = ContractMethod>(
key: string | FunctionFragment
): T;
getFunction(
nameOrSignature: "COORDINATOR_ROLE"
): TypedContractMethod<[], [string], "view">;
getFunction(
nameOrSignature: "DEFAULT_ADMIN_ROLE"
): TypedContractMethod<[], [string], "view">;
getFunction(
nameOrSignature: "getRoleAdmin"
): TypedContractMethod<[role: BytesLike], [string], "view">;
getFunction(
nameOrSignature: "grantRole"
): TypedContractMethod<
[role: BytesLike, account: AddressLike],
[void],
"nonpayable"
>;
getFunction(
nameOrSignature: "hasRole"
): TypedContractMethod<
[role: BytesLike, account: AddressLike],
[boolean],
"view"
>;
getFunction(
nameOrSignature: "providerInfo"
): TypedContractMethod<
[provider: AddressLike],
[AITokenRegistry.ProviderInfoStructOutput],
"view"
>;
getFunction(
nameOrSignature: "providers"
): TypedContractMethod<
[arg0: AddressLike],
[[boolean, bigint] & { active: boolean; collateral: bigint }],
"view"
>;
getFunction(
nameOrSignature: "registerProvider"
): TypedContractMethod<
[provider: AddressLike, collateral: BigNumberish],
[void],
"nonpayable"
>;
getFunction(
nameOrSignature: "renounceRole"
): TypedContractMethod<
[role: BytesLike, callerConfirmation: AddressLike],
[void],
"nonpayable"
>;
getFunction(
nameOrSignature: "revokeRole"
): TypedContractMethod<
[role: BytesLike, account: AddressLike],
[void],
"nonpayable"
>;
getFunction(
nameOrSignature: "supportsInterface"
): TypedContractMethod<[interfaceId: BytesLike], [boolean], "view">;
getFunction(
nameOrSignature: "updateProvider"
): TypedContractMethod<
[provider: AddressLike, active: boolean, collateral: BigNumberish],
[void],
"nonpayable"
>;
getEvent(
key: "ProviderRegistered"
): TypedContractEvent<
ProviderRegisteredEvent.InputTuple,
ProviderRegisteredEvent.OutputTuple,
ProviderRegisteredEvent.OutputObject
>;
getEvent(
key: "ProviderUpdated"
): TypedContractEvent<
ProviderUpdatedEvent.InputTuple,
ProviderUpdatedEvent.OutputTuple,
ProviderUpdatedEvent.OutputObject
>;
getEvent(
key: "RoleAdminChanged"
): TypedContractEvent<
RoleAdminChangedEvent.InputTuple,
RoleAdminChangedEvent.OutputTuple,
RoleAdminChangedEvent.OutputObject
>;
getEvent(
key: "RoleGranted"
): TypedContractEvent<
RoleGrantedEvent.InputTuple,
RoleGrantedEvent.OutputTuple,
RoleGrantedEvent.OutputObject
>;
getEvent(
key: "RoleRevoked"
): TypedContractEvent<
RoleRevokedEvent.InputTuple,
RoleRevokedEvent.OutputTuple,
RoleRevokedEvent.OutputObject
>;
filters: {
"ProviderRegistered(address,uint256)": TypedContractEvent<
ProviderRegisteredEvent.InputTuple,
ProviderRegisteredEvent.OutputTuple,
ProviderRegisteredEvent.OutputObject
>;
ProviderRegistered: TypedContractEvent<
ProviderRegisteredEvent.InputTuple,
ProviderRegisteredEvent.OutputTuple,
ProviderRegisteredEvent.OutputObject
>;
"ProviderUpdated(address,bool,uint256)": TypedContractEvent<
ProviderUpdatedEvent.InputTuple,
ProviderUpdatedEvent.OutputTuple,
ProviderUpdatedEvent.OutputObject
>;
ProviderUpdated: TypedContractEvent<
ProviderUpdatedEvent.InputTuple,
ProviderUpdatedEvent.OutputTuple,
ProviderUpdatedEvent.OutputObject
>;
"RoleAdminChanged(bytes32,bytes32,bytes32)": TypedContractEvent<
RoleAdminChangedEvent.InputTuple,
RoleAdminChangedEvent.OutputTuple,
RoleAdminChangedEvent.OutputObject
>;
RoleAdminChanged: TypedContractEvent<
RoleAdminChangedEvent.InputTuple,
RoleAdminChangedEvent.OutputTuple,
RoleAdminChangedEvent.OutputObject
>;
"RoleGranted(bytes32,address,address)": TypedContractEvent<
RoleGrantedEvent.InputTuple,
RoleGrantedEvent.OutputTuple,
RoleGrantedEvent.OutputObject
>;
RoleGranted: TypedContractEvent<
RoleGrantedEvent.InputTuple,
RoleGrantedEvent.OutputTuple,
RoleGrantedEvent.OutputObject
>;
"RoleRevoked(bytes32,address,address)": TypedContractEvent<
RoleRevokedEvent.InputTuple,
RoleRevokedEvent.OutputTuple,
RoleRevokedEvent.OutputObject
>;
RoleRevoked: TypedContractEvent<
RoleRevokedEvent.InputTuple,
RoleRevokedEvent.OutputTuple,
RoleRevokedEvent.OutputObject
>;
};
}

View File

@@ -0,0 +1,5 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export type { AIToken } from "./AIToken";
export type { AITokenRegistry } from "./AITokenRegistry";

View File

@@ -0,0 +1,250 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import { Contract, Interface, type ContractRunner } from "ethers";
import type {
AccessControl,
AccessControlInterface,
} from "../../../../@openzeppelin/contracts/access/AccessControl";
const _abi = [
{
inputs: [],
name: "AccessControlBadConfirmation",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "account",
type: "address",
},
{
internalType: "bytes32",
name: "neededRole",
type: "bytes32",
},
],
name: "AccessControlUnauthorizedAccount",
type: "error",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "bytes32",
name: "role",
type: "bytes32",
},
{
indexed: true,
internalType: "bytes32",
name: "previousAdminRole",
type: "bytes32",
},
{
indexed: true,
internalType: "bytes32",
name: "newAdminRole",
type: "bytes32",
},
],
name: "RoleAdminChanged",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "bytes32",
name: "role",
type: "bytes32",
},
{
indexed: true,
internalType: "address",
name: "account",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "sender",
type: "address",
},
],
name: "RoleGranted",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "bytes32",
name: "role",
type: "bytes32",
},
{
indexed: true,
internalType: "address",
name: "account",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "sender",
type: "address",
},
],
name: "RoleRevoked",
type: "event",
},
{
inputs: [],
name: "DEFAULT_ADMIN_ROLE",
outputs: [
{
internalType: "bytes32",
name: "",
type: "bytes32",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "bytes32",
name: "role",
type: "bytes32",
},
],
name: "getRoleAdmin",
outputs: [
{
internalType: "bytes32",
name: "",
type: "bytes32",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "bytes32",
name: "role",
type: "bytes32",
},
{
internalType: "address",
name: "account",
type: "address",
},
],
name: "grantRole",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{
internalType: "bytes32",
name: "role",
type: "bytes32",
},
{
internalType: "address",
name: "account",
type: "address",
},
],
name: "hasRole",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "bytes32",
name: "role",
type: "bytes32",
},
{
internalType: "address",
name: "callerConfirmation",
type: "address",
},
],
name: "renounceRole",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{
internalType: "bytes32",
name: "role",
type: "bytes32",
},
{
internalType: "address",
name: "account",
type: "address",
},
],
name: "revokeRole",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{
internalType: "bytes4",
name: "interfaceId",
type: "bytes4",
},
],
name: "supportsInterface",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "view",
type: "function",
},
] as const;
export class AccessControl__factory {
static readonly abi = _abi;
static createInterface(): AccessControlInterface {
return new Interface(_abi) as AccessControlInterface;
}
static connect(
address: string,
runner?: ContractRunner | null
): AccessControl {
return new Contract(address, _abi, runner) as unknown as AccessControl;
}
}

View File

@@ -0,0 +1,218 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import { Contract, Interface, type ContractRunner } from "ethers";
import type {
IAccessControl,
IAccessControlInterface,
} from "../../../../@openzeppelin/contracts/access/IAccessControl";
const _abi = [
{
inputs: [],
name: "AccessControlBadConfirmation",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "account",
type: "address",
},
{
internalType: "bytes32",
name: "neededRole",
type: "bytes32",
},
],
name: "AccessControlUnauthorizedAccount",
type: "error",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "bytes32",
name: "role",
type: "bytes32",
},
{
indexed: true,
internalType: "bytes32",
name: "previousAdminRole",
type: "bytes32",
},
{
indexed: true,
internalType: "bytes32",
name: "newAdminRole",
type: "bytes32",
},
],
name: "RoleAdminChanged",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "bytes32",
name: "role",
type: "bytes32",
},
{
indexed: true,
internalType: "address",
name: "account",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "sender",
type: "address",
},
],
name: "RoleGranted",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "bytes32",
name: "role",
type: "bytes32",
},
{
indexed: true,
internalType: "address",
name: "account",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "sender",
type: "address",
},
],
name: "RoleRevoked",
type: "event",
},
{
inputs: [
{
internalType: "bytes32",
name: "role",
type: "bytes32",
},
],
name: "getRoleAdmin",
outputs: [
{
internalType: "bytes32",
name: "",
type: "bytes32",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "bytes32",
name: "role",
type: "bytes32",
},
{
internalType: "address",
name: "account",
type: "address",
},
],
name: "grantRole",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{
internalType: "bytes32",
name: "role",
type: "bytes32",
},
{
internalType: "address",
name: "account",
type: "address",
},
],
name: "hasRole",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "bytes32",
name: "role",
type: "bytes32",
},
{
internalType: "address",
name: "callerConfirmation",
type: "address",
},
],
name: "renounceRole",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{
internalType: "bytes32",
name: "role",
type: "bytes32",
},
{
internalType: "address",
name: "account",
type: "address",
},
],
name: "revokeRole",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
] as const;
export class IAccessControl__factory {
static readonly abi = _abi;
static createInterface(): IAccessControlInterface {
return new Interface(_abi) as IAccessControlInterface;
}
static connect(
address: string,
runner?: ContractRunner | null
): IAccessControl {
return new Contract(address, _abi, runner) as unknown as IAccessControl;
}
}

View File

@@ -0,0 +1,5 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export { AccessControl__factory } from "./AccessControl__factory";
export { IAccessControl__factory } from "./IAccessControl__factory";

View File

@@ -0,0 +1,7 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export * as access from "./access";
export * as interfaces from "./interfaces";
export * as token from "./token";
export * as utils from "./utils";

View File

@@ -0,0 +1,127 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import { Contract, Interface, type ContractRunner } from "ethers";
import type {
IERC1155Errors,
IERC1155ErrorsInterface,
} from "../../../../../@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC1155Errors";
const _abi = [
{
inputs: [
{
internalType: "address",
name: "sender",
type: "address",
},
{
internalType: "uint256",
name: "balance",
type: "uint256",
},
{
internalType: "uint256",
name: "needed",
type: "uint256",
},
{
internalType: "uint256",
name: "tokenId",
type: "uint256",
},
],
name: "ERC1155InsufficientBalance",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "approver",
type: "address",
},
],
name: "ERC1155InvalidApprover",
type: "error",
},
{
inputs: [
{
internalType: "uint256",
name: "idsLength",
type: "uint256",
},
{
internalType: "uint256",
name: "valuesLength",
type: "uint256",
},
],
name: "ERC1155InvalidArrayLength",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "operator",
type: "address",
},
],
name: "ERC1155InvalidOperator",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "receiver",
type: "address",
},
],
name: "ERC1155InvalidReceiver",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "sender",
type: "address",
},
],
name: "ERC1155InvalidSender",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "operator",
type: "address",
},
{
internalType: "address",
name: "owner",
type: "address",
},
],
name: "ERC1155MissingApprovalForAll",
type: "error",
},
] as const;
export class IERC1155Errors__factory {
static readonly abi = _abi;
static createInterface(): IERC1155ErrorsInterface {
return new Interface(_abi) as IERC1155ErrorsInterface;
}
static connect(
address: string,
runner?: ContractRunner | null
): IERC1155Errors {
return new Contract(address, _abi, runner) as unknown as IERC1155Errors;
}
}

View File

@@ -0,0 +1,111 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import { Contract, Interface, type ContractRunner } from "ethers";
import type {
IERC20Errors,
IERC20ErrorsInterface,
} from "../../../../../@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC20Errors";
const _abi = [
{
inputs: [
{
internalType: "address",
name: "spender",
type: "address",
},
{
internalType: "uint256",
name: "allowance",
type: "uint256",
},
{
internalType: "uint256",
name: "needed",
type: "uint256",
},
],
name: "ERC20InsufficientAllowance",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "sender",
type: "address",
},
{
internalType: "uint256",
name: "balance",
type: "uint256",
},
{
internalType: "uint256",
name: "needed",
type: "uint256",
},
],
name: "ERC20InsufficientBalance",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "approver",
type: "address",
},
],
name: "ERC20InvalidApprover",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "receiver",
type: "address",
},
],
name: "ERC20InvalidReceiver",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "sender",
type: "address",
},
],
name: "ERC20InvalidSender",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "spender",
type: "address",
},
],
name: "ERC20InvalidSpender",
type: "error",
},
] as const;
export class IERC20Errors__factory {
static readonly abi = _abi;
static createInterface(): IERC20ErrorsInterface {
return new Interface(_abi) as IERC20ErrorsInterface;
}
static connect(
address: string,
runner?: ContractRunner | null
): IERC20Errors {
return new Contract(address, _abi, runner) as unknown as IERC20Errors;
}
}

View File

@@ -0,0 +1,128 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import { Contract, Interface, type ContractRunner } from "ethers";
import type {
IERC721Errors,
IERC721ErrorsInterface,
} from "../../../../../@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC721Errors";
const _abi = [
{
inputs: [
{
internalType: "address",
name: "sender",
type: "address",
},
{
internalType: "uint256",
name: "tokenId",
type: "uint256",
},
{
internalType: "address",
name: "owner",
type: "address",
},
],
name: "ERC721IncorrectOwner",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "operator",
type: "address",
},
{
internalType: "uint256",
name: "tokenId",
type: "uint256",
},
],
name: "ERC721InsufficientApproval",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "approver",
type: "address",
},
],
name: "ERC721InvalidApprover",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "operator",
type: "address",
},
],
name: "ERC721InvalidOperator",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "owner",
type: "address",
},
],
name: "ERC721InvalidOwner",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "receiver",
type: "address",
},
],
name: "ERC721InvalidReceiver",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "sender",
type: "address",
},
],
name: "ERC721InvalidSender",
type: "error",
},
{
inputs: [
{
internalType: "uint256",
name: "tokenId",
type: "uint256",
},
],
name: "ERC721NonexistentToken",
type: "error",
},
] as const;
export class IERC721Errors__factory {
static readonly abi = _abi;
static createInterface(): IERC721ErrorsInterface {
return new Interface(_abi) as IERC721ErrorsInterface;
}
static connect(
address: string,
runner?: ContractRunner | null
): IERC721Errors {
return new Contract(address, _abi, runner) as unknown as IERC721Errors;
}
}

View File

@@ -0,0 +1,6 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export { IERC1155Errors__factory } from "./IERC1155Errors__factory";
export { IERC20Errors__factory } from "./IERC20Errors__factory";
export { IERC721Errors__factory } from "./IERC721Errors__factory";

View File

@@ -0,0 +1,4 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export * as draftIerc6093Sol from "./draft-IERC6093.sol";

View File

@@ -0,0 +1,330 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import { Contract, Interface, type ContractRunner } from "ethers";
import type {
ERC20,
ERC20Interface,
} from "../../../../../@openzeppelin/contracts/token/ERC20/ERC20";
const _abi = [
{
inputs: [
{
internalType: "address",
name: "spender",
type: "address",
},
{
internalType: "uint256",
name: "allowance",
type: "uint256",
},
{
internalType: "uint256",
name: "needed",
type: "uint256",
},
],
name: "ERC20InsufficientAllowance",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "sender",
type: "address",
},
{
internalType: "uint256",
name: "balance",
type: "uint256",
},
{
internalType: "uint256",
name: "needed",
type: "uint256",
},
],
name: "ERC20InsufficientBalance",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "approver",
type: "address",
},
],
name: "ERC20InvalidApprover",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "receiver",
type: "address",
},
],
name: "ERC20InvalidReceiver",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "sender",
type: "address",
},
],
name: "ERC20InvalidSender",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "spender",
type: "address",
},
],
name: "ERC20InvalidSpender",
type: "error",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "owner",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "spender",
type: "address",
},
{
indexed: false,
internalType: "uint256",
name: "value",
type: "uint256",
},
],
name: "Approval",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "from",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "to",
type: "address",
},
{
indexed: false,
internalType: "uint256",
name: "value",
type: "uint256",
},
],
name: "Transfer",
type: "event",
},
{
inputs: [
{
internalType: "address",
name: "owner",
type: "address",
},
{
internalType: "address",
name: "spender",
type: "address",
},
],
name: "allowance",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "address",
name: "spender",
type: "address",
},
{
internalType: "uint256",
name: "value",
type: "uint256",
},
],
name: "approve",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{
internalType: "address",
name: "account",
type: "address",
},
],
name: "balanceOf",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "decimals",
outputs: [
{
internalType: "uint8",
name: "",
type: "uint8",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "name",
outputs: [
{
internalType: "string",
name: "",
type: "string",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "symbol",
outputs: [
{
internalType: "string",
name: "",
type: "string",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "totalSupply",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "address",
name: "to",
type: "address",
},
{
internalType: "uint256",
name: "value",
type: "uint256",
},
],
name: "transfer",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{
internalType: "address",
name: "from",
type: "address",
},
{
internalType: "address",
name: "to",
type: "address",
},
{
internalType: "uint256",
name: "value",
type: "uint256",
},
],
name: "transferFrom",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "nonpayable",
type: "function",
},
] as const;
export class ERC20__factory {
static readonly abi = _abi;
static createInterface(): ERC20Interface {
return new Interface(_abi) as ERC20Interface;
}
static connect(address: string, runner?: ContractRunner | null): ERC20 {
return new Contract(address, _abi, runner) as unknown as ERC20;
}
}

View File

@@ -0,0 +1,205 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import { Contract, Interface, type ContractRunner } from "ethers";
import type {
IERC20,
IERC20Interface,
} from "../../../../../@openzeppelin/contracts/token/ERC20/IERC20";
const _abi = [
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "owner",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "spender",
type: "address",
},
{
indexed: false,
internalType: "uint256",
name: "value",
type: "uint256",
},
],
name: "Approval",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "from",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "to",
type: "address",
},
{
indexed: false,
internalType: "uint256",
name: "value",
type: "uint256",
},
],
name: "Transfer",
type: "event",
},
{
inputs: [
{
internalType: "address",
name: "owner",
type: "address",
},
{
internalType: "address",
name: "spender",
type: "address",
},
],
name: "allowance",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "address",
name: "spender",
type: "address",
},
{
internalType: "uint256",
name: "value",
type: "uint256",
},
],
name: "approve",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{
internalType: "address",
name: "account",
type: "address",
},
],
name: "balanceOf",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "totalSupply",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "address",
name: "to",
type: "address",
},
{
internalType: "uint256",
name: "value",
type: "uint256",
},
],
name: "transfer",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{
internalType: "address",
name: "from",
type: "address",
},
{
internalType: "address",
name: "to",
type: "address",
},
{
internalType: "uint256",
name: "value",
type: "uint256",
},
],
name: "transferFrom",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "nonpayable",
type: "function",
},
] as const;
export class IERC20__factory {
static readonly abi = _abi;
static createInterface(): IERC20Interface {
return new Interface(_abi) as IERC20Interface;
}
static connect(address: string, runner?: ContractRunner | null): IERC20 {
return new Contract(address, _abi, runner) as unknown as IERC20;
}
}

View File

@@ -0,0 +1,247 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import { Contract, Interface, type ContractRunner } from "ethers";
import type {
IERC20Metadata,
IERC20MetadataInterface,
} from "../../../../../../@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata";
const _abi = [
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "owner",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "spender",
type: "address",
},
{
indexed: false,
internalType: "uint256",
name: "value",
type: "uint256",
},
],
name: "Approval",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "from",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "to",
type: "address",
},
{
indexed: false,
internalType: "uint256",
name: "value",
type: "uint256",
},
],
name: "Transfer",
type: "event",
},
{
inputs: [
{
internalType: "address",
name: "owner",
type: "address",
},
{
internalType: "address",
name: "spender",
type: "address",
},
],
name: "allowance",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "address",
name: "spender",
type: "address",
},
{
internalType: "uint256",
name: "value",
type: "uint256",
},
],
name: "approve",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{
internalType: "address",
name: "account",
type: "address",
},
],
name: "balanceOf",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "decimals",
outputs: [
{
internalType: "uint8",
name: "",
type: "uint8",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "name",
outputs: [
{
internalType: "string",
name: "",
type: "string",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "symbol",
outputs: [
{
internalType: "string",
name: "",
type: "string",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "totalSupply",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "address",
name: "to",
type: "address",
},
{
internalType: "uint256",
name: "value",
type: "uint256",
},
],
name: "transfer",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{
internalType: "address",
name: "from",
type: "address",
},
{
internalType: "address",
name: "to",
type: "address",
},
{
internalType: "uint256",
name: "value",
type: "uint256",
},
],
name: "transferFrom",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "nonpayable",
type: "function",
},
] as const;
export class IERC20Metadata__factory {
static readonly abi = _abi;
static createInterface(): IERC20MetadataInterface {
return new Interface(_abi) as IERC20MetadataInterface;
}
static connect(
address: string,
runner?: ContractRunner | null
): IERC20Metadata {
return new Contract(address, _abi, runner) as unknown as IERC20Metadata;
}
}

View File

@@ -0,0 +1,4 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export { IERC20Metadata__factory } from "./IERC20Metadata__factory";

View File

@@ -0,0 +1,6 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export * as extensions from "./extensions";
export { ERC20__factory } from "./ERC20__factory";
export { IERC20__factory } from "./IERC20__factory";

View File

@@ -0,0 +1,4 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export * as erc20 from "./ERC20";

View File

@@ -0,0 +1,90 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import {
Contract,
ContractFactory,
ContractTransactionResponse,
Interface,
} from "ethers";
import type { Signer, ContractDeployTransaction, ContractRunner } from "ethers";
import type { NonPayableOverrides } from "../../../../common";
import type {
Strings,
StringsInterface,
} from "../../../../@openzeppelin/contracts/utils/Strings";
const _abi = [
{
inputs: [
{
internalType: "uint256",
name: "value",
type: "uint256",
},
{
internalType: "uint256",
name: "length",
type: "uint256",
},
],
name: "StringsInsufficientHexLength",
type: "error",
},
{
inputs: [],
name: "StringsInvalidAddressFormat",
type: "error",
},
{
inputs: [],
name: "StringsInvalidChar",
type: "error",
},
] as const;
const _bytecode =
"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d3fa6b95cf4f76e64227a9b2373ccb228efd9715fd7983e0646867999cceb9fb64736f6c63430008180033";
type StringsConstructorParams =
| [signer?: Signer]
| ConstructorParameters<typeof ContractFactory>;
const isSuperArgs = (
xs: StringsConstructorParams
): xs is ConstructorParameters<typeof ContractFactory> => xs.length > 1;
export class Strings__factory extends ContractFactory {
constructor(...args: StringsConstructorParams) {
if (isSuperArgs(args)) {
super(...args);
} else {
super(_abi, _bytecode, args[0]);
}
}
override getDeployTransaction(
overrides?: NonPayableOverrides & { from?: string }
): Promise<ContractDeployTransaction> {
return super.getDeployTransaction(overrides || {});
}
override deploy(overrides?: NonPayableOverrides & { from?: string }) {
return super.deploy(overrides || {}) as Promise<
Strings & {
deploymentTransaction(): ContractTransactionResponse;
}
>;
}
override connect(runner: ContractRunner | null): Strings__factory {
return super.connect(runner) as Strings__factory;
}
static readonly bytecode = _bytecode;
static readonly abi = _abi;
static createInterface(): StringsInterface {
return new Interface(_abi) as StringsInterface;
}
static connect(address: string, runner?: ContractRunner | null): Strings {
return new Contract(address, _abi, runner) as unknown as Strings;
}
}

View File

@@ -0,0 +1,91 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import {
Contract,
ContractFactory,
ContractTransactionResponse,
Interface,
} from "ethers";
import type { Signer, ContractDeployTransaction, ContractRunner } from "ethers";
import type { NonPayableOverrides } from "../../../../../common";
import type {
ECDSA,
ECDSAInterface,
} from "../../../../../@openzeppelin/contracts/utils/cryptography/ECDSA";
const _abi = [
{
inputs: [],
name: "ECDSAInvalidSignature",
type: "error",
},
{
inputs: [
{
internalType: "uint256",
name: "length",
type: "uint256",
},
],
name: "ECDSAInvalidSignatureLength",
type: "error",
},
{
inputs: [
{
internalType: "bytes32",
name: "s",
type: "bytes32",
},
],
name: "ECDSAInvalidSignatureS",
type: "error",
},
] as const;
const _bytecode =
"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a02ae933cd95f2ee943a9a3e5cbf4c6b7a6f7cc463d2cb58fac8fce23a0ba09464736f6c63430008180033";
type ECDSAConstructorParams =
| [signer?: Signer]
| ConstructorParameters<typeof ContractFactory>;
const isSuperArgs = (
xs: ECDSAConstructorParams
): xs is ConstructorParameters<typeof ContractFactory> => xs.length > 1;
export class ECDSA__factory extends ContractFactory {
constructor(...args: ECDSAConstructorParams) {
if (isSuperArgs(args)) {
super(...args);
} else {
super(_abi, _bytecode, args[0]);
}
}
override getDeployTransaction(
overrides?: NonPayableOverrides & { from?: string }
): Promise<ContractDeployTransaction> {
return super.getDeployTransaction(overrides || {});
}
override deploy(overrides?: NonPayableOverrides & { from?: string }) {
return super.deploy(overrides || {}) as Promise<
ECDSA & {
deploymentTransaction(): ContractTransactionResponse;
}
>;
}
override connect(runner: ContractRunner | null): ECDSA__factory {
return super.connect(runner) as ECDSA__factory;
}
static readonly bytecode = _bytecode;
static readonly abi = _abi;
static createInterface(): ECDSAInterface {
return new Interface(_abi) as ECDSAInterface;
}
static connect(address: string, runner?: ContractRunner | null): ECDSA {
return new Contract(address, _abi, runner) as unknown as ECDSA;
}
}

View File

@@ -0,0 +1,4 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export { ECDSA__factory } from "./ECDSA__factory";

View File

@@ -0,0 +1,7 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export * as cryptography from "./cryptography";
export * as introspection from "./introspection";
export * as math from "./math";
export { Strings__factory } from "./Strings__factory";

View File

@@ -0,0 +1,41 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import { Contract, Interface, type ContractRunner } from "ethers";
import type {
ERC165,
ERC165Interface,
} from "../../../../../@openzeppelin/contracts/utils/introspection/ERC165";
const _abi = [
{
inputs: [
{
internalType: "bytes4",
name: "interfaceId",
type: "bytes4",
},
],
name: "supportsInterface",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "view",
type: "function",
},
] as const;
export class ERC165__factory {
static readonly abi = _abi;
static createInterface(): ERC165Interface {
return new Interface(_abi) as ERC165Interface;
}
static connect(address: string, runner?: ContractRunner | null): ERC165 {
return new Contract(address, _abi, runner) as unknown as ERC165;
}
}

View File

@@ -0,0 +1,41 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import { Contract, Interface, type ContractRunner } from "ethers";
import type {
IERC165,
IERC165Interface,
} from "../../../../../@openzeppelin/contracts/utils/introspection/IERC165";
const _abi = [
{
inputs: [
{
internalType: "bytes4",
name: "interfaceId",
type: "bytes4",
},
],
name: "supportsInterface",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "view",
type: "function",
},
] as const;
export class IERC165__factory {
static readonly abi = _abi;
static createInterface(): IERC165Interface {
return new Interface(_abi) as IERC165Interface;
}
static connect(address: string, runner?: ContractRunner | null): IERC165 {
return new Contract(address, _abi, runner) as unknown as IERC165;
}
}

View File

@@ -0,0 +1,5 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export { ERC165__factory } from "./ERC165__factory";
export { IERC165__factory } from "./IERC165__factory";

View File

@@ -0,0 +1,118 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import {
Contract,
ContractFactory,
ContractTransactionResponse,
Interface,
} from "ethers";
import type { Signer, ContractDeployTransaction, ContractRunner } from "ethers";
import type { NonPayableOverrides } from "../../../../../common";
import type {
SafeCast,
SafeCastInterface,
} from "../../../../../@openzeppelin/contracts/utils/math/SafeCast";
const _abi = [
{
inputs: [
{
internalType: "uint8",
name: "bits",
type: "uint8",
},
{
internalType: "int256",
name: "value",
type: "int256",
},
],
name: "SafeCastOverflowedIntDowncast",
type: "error",
},
{
inputs: [
{
internalType: "int256",
name: "value",
type: "int256",
},
],
name: "SafeCastOverflowedIntToUint",
type: "error",
},
{
inputs: [
{
internalType: "uint8",
name: "bits",
type: "uint8",
},
{
internalType: "uint256",
name: "value",
type: "uint256",
},
],
name: "SafeCastOverflowedUintDowncast",
type: "error",
},
{
inputs: [
{
internalType: "uint256",
name: "value",
type: "uint256",
},
],
name: "SafeCastOverflowedUintToInt",
type: "error",
},
] as const;
const _bytecode =
"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212201c97bba8d553a67561101942b2a9afa3628667de55efed8df898d3aab783793c64736f6c63430008180033";
type SafeCastConstructorParams =
| [signer?: Signer]
| ConstructorParameters<typeof ContractFactory>;
const isSuperArgs = (
xs: SafeCastConstructorParams
): xs is ConstructorParameters<typeof ContractFactory> => xs.length > 1;
export class SafeCast__factory extends ContractFactory {
constructor(...args: SafeCastConstructorParams) {
if (isSuperArgs(args)) {
super(...args);
} else {
super(_abi, _bytecode, args[0]);
}
}
override getDeployTransaction(
overrides?: NonPayableOverrides & { from?: string }
): Promise<ContractDeployTransaction> {
return super.getDeployTransaction(overrides || {});
}
override deploy(overrides?: NonPayableOverrides & { from?: string }) {
return super.deploy(overrides || {}) as Promise<
SafeCast & {
deploymentTransaction(): ContractTransactionResponse;
}
>;
}
override connect(runner: ContractRunner | null): SafeCast__factory {
return super.connect(runner) as SafeCast__factory;
}
static readonly bytecode = _bytecode;
static readonly abi = _abi;
static createInterface(): SafeCastInterface {
return new Interface(_abi) as SafeCastInterface;
}
static connect(address: string, runner?: ContractRunner | null): SafeCast {
return new Contract(address, _abi, runner) as unknown as SafeCast;
}
}

View File

@@ -0,0 +1,4 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export { SafeCast__factory } from "./SafeCast__factory";

View File

@@ -0,0 +1,4 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export * as contracts from "./contracts";

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export { AIToken__factory } from "./AIToken__factory";
export { AITokenRegistry__factory } from "./AITokenRegistry__factory";

View File

@@ -0,0 +1,5 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export * as openzeppelin from "./@openzeppelin";
export * as contracts from "./contracts";

View File

@@ -0,0 +1,315 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import { ethers } from "ethers";
import {
DeployContractOptions,
FactoryOptions,
HardhatEthersHelpers as HardhatEthersHelpersBase,
} from "@nomicfoundation/hardhat-ethers/types";
import * as Contracts from ".";
declare module "hardhat/types/runtime" {
interface HardhatEthersHelpers extends HardhatEthersHelpersBase {
getContractFactory(
name: "AccessControl",
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<Contracts.AccessControl__factory>;
getContractFactory(
name: "IAccessControl",
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<Contracts.IAccessControl__factory>;
getContractFactory(
name: "IERC1155Errors",
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<Contracts.IERC1155Errors__factory>;
getContractFactory(
name: "IERC20Errors",
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<Contracts.IERC20Errors__factory>;
getContractFactory(
name: "IERC721Errors",
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<Contracts.IERC721Errors__factory>;
getContractFactory(
name: "ERC20",
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<Contracts.ERC20__factory>;
getContractFactory(
name: "IERC20Metadata",
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<Contracts.IERC20Metadata__factory>;
getContractFactory(
name: "IERC20",
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<Contracts.IERC20__factory>;
getContractFactory(
name: "ECDSA",
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<Contracts.ECDSA__factory>;
getContractFactory(
name: "ERC165",
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<Contracts.ERC165__factory>;
getContractFactory(
name: "IERC165",
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<Contracts.IERC165__factory>;
getContractFactory(
name: "SafeCast",
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<Contracts.SafeCast__factory>;
getContractFactory(
name: "Strings",
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<Contracts.Strings__factory>;
getContractFactory(
name: "AIToken",
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<Contracts.AIToken__factory>;
getContractFactory(
name: "AITokenRegistry",
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<Contracts.AITokenRegistry__factory>;
getContractAt(
name: "AccessControl",
address: string | ethers.Addressable,
signer?: ethers.Signer
): Promise<Contracts.AccessControl>;
getContractAt(
name: "IAccessControl",
address: string | ethers.Addressable,
signer?: ethers.Signer
): Promise<Contracts.IAccessControl>;
getContractAt(
name: "IERC1155Errors",
address: string | ethers.Addressable,
signer?: ethers.Signer
): Promise<Contracts.IERC1155Errors>;
getContractAt(
name: "IERC20Errors",
address: string | ethers.Addressable,
signer?: ethers.Signer
): Promise<Contracts.IERC20Errors>;
getContractAt(
name: "IERC721Errors",
address: string | ethers.Addressable,
signer?: ethers.Signer
): Promise<Contracts.IERC721Errors>;
getContractAt(
name: "ERC20",
address: string | ethers.Addressable,
signer?: ethers.Signer
): Promise<Contracts.ERC20>;
getContractAt(
name: "IERC20Metadata",
address: string | ethers.Addressable,
signer?: ethers.Signer
): Promise<Contracts.IERC20Metadata>;
getContractAt(
name: "IERC20",
address: string | ethers.Addressable,
signer?: ethers.Signer
): Promise<Contracts.IERC20>;
getContractAt(
name: "ECDSA",
address: string | ethers.Addressable,
signer?: ethers.Signer
): Promise<Contracts.ECDSA>;
getContractAt(
name: "ERC165",
address: string | ethers.Addressable,
signer?: ethers.Signer
): Promise<Contracts.ERC165>;
getContractAt(
name: "IERC165",
address: string | ethers.Addressable,
signer?: ethers.Signer
): Promise<Contracts.IERC165>;
getContractAt(
name: "SafeCast",
address: string | ethers.Addressable,
signer?: ethers.Signer
): Promise<Contracts.SafeCast>;
getContractAt(
name: "Strings",
address: string | ethers.Addressable,
signer?: ethers.Signer
): Promise<Contracts.Strings>;
getContractAt(
name: "AIToken",
address: string | ethers.Addressable,
signer?: ethers.Signer
): Promise<Contracts.AIToken>;
getContractAt(
name: "AITokenRegistry",
address: string | ethers.Addressable,
signer?: ethers.Signer
): Promise<Contracts.AITokenRegistry>;
deployContract(
name: "AccessControl",
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.AccessControl>;
deployContract(
name: "IAccessControl",
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.IAccessControl>;
deployContract(
name: "IERC1155Errors",
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.IERC1155Errors>;
deployContract(
name: "IERC20Errors",
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.IERC20Errors>;
deployContract(
name: "IERC721Errors",
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.IERC721Errors>;
deployContract(
name: "ERC20",
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.ERC20>;
deployContract(
name: "IERC20Metadata",
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.IERC20Metadata>;
deployContract(
name: "IERC20",
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.IERC20>;
deployContract(
name: "ECDSA",
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.ECDSA>;
deployContract(
name: "ERC165",
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.ERC165>;
deployContract(
name: "IERC165",
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.IERC165>;
deployContract(
name: "SafeCast",
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.SafeCast>;
deployContract(
name: "Strings",
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.Strings>;
deployContract(
name: "AIToken",
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.AIToken>;
deployContract(
name: "AITokenRegistry",
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.AITokenRegistry>;
deployContract(
name: "AccessControl",
args: any[],
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.AccessControl>;
deployContract(
name: "IAccessControl",
args: any[],
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.IAccessControl>;
deployContract(
name: "IERC1155Errors",
args: any[],
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.IERC1155Errors>;
deployContract(
name: "IERC20Errors",
args: any[],
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.IERC20Errors>;
deployContract(
name: "IERC721Errors",
args: any[],
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.IERC721Errors>;
deployContract(
name: "ERC20",
args: any[],
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.ERC20>;
deployContract(
name: "IERC20Metadata",
args: any[],
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.IERC20Metadata>;
deployContract(
name: "IERC20",
args: any[],
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.IERC20>;
deployContract(
name: "ECDSA",
args: any[],
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.ECDSA>;
deployContract(
name: "ERC165",
args: any[],
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.ERC165>;
deployContract(
name: "IERC165",
args: any[],
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.IERC165>;
deployContract(
name: "SafeCast",
args: any[],
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.SafeCast>;
deployContract(
name: "Strings",
args: any[],
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.Strings>;
deployContract(
name: "AIToken",
args: any[],
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.AIToken>;
deployContract(
name: "AITokenRegistry",
args: any[],
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<Contracts.AITokenRegistry>;
// default types
getContractFactory(
name: string,
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<ethers.ContractFactory>;
getContractFactory(
abi: any[],
bytecode: ethers.BytesLike,
signer?: ethers.Signer
): Promise<ethers.ContractFactory>;
getContractAt(
nameOrAbi: string | any[],
address: string | ethers.Addressable,
signer?: ethers.Signer
): Promise<ethers.Contract>;
deployContract(
name: string,
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<ethers.Contract>;
deployContract(
name: string,
args: any[],
signerOrOptions?: ethers.Signer | DeployContractOptions
): Promise<ethers.Contract>;
}
}

View File

@@ -0,0 +1,38 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type * as openzeppelin from "./@openzeppelin";
export type { openzeppelin };
import type * as contracts from "./contracts";
export type { contracts };
export * as factories from "./factories";
export type { AccessControl } from "./@openzeppelin/contracts/access/AccessControl";
export { AccessControl__factory } from "./factories/@openzeppelin/contracts/access/AccessControl__factory";
export type { IAccessControl } from "./@openzeppelin/contracts/access/IAccessControl";
export { IAccessControl__factory } from "./factories/@openzeppelin/contracts/access/IAccessControl__factory";
export type { IERC1155Errors } from "./@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC1155Errors";
export { IERC1155Errors__factory } from "./factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC1155Errors__factory";
export type { IERC20Errors } from "./@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC20Errors";
export { IERC20Errors__factory } from "./factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC20Errors__factory";
export type { IERC721Errors } from "./@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC721Errors";
export { IERC721Errors__factory } from "./factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC721Errors__factory";
export type { ERC20 } from "./@openzeppelin/contracts/token/ERC20/ERC20";
export { ERC20__factory } from "./factories/@openzeppelin/contracts/token/ERC20/ERC20__factory";
export type { IERC20Metadata } from "./@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata";
export { IERC20Metadata__factory } from "./factories/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata__factory";
export type { IERC20 } from "./@openzeppelin/contracts/token/ERC20/IERC20";
export { IERC20__factory } from "./factories/@openzeppelin/contracts/token/ERC20/IERC20__factory";
export type { ECDSA } from "./@openzeppelin/contracts/utils/cryptography/ECDSA";
export { ECDSA__factory } from "./factories/@openzeppelin/contracts/utils/cryptography/ECDSA__factory";
export type { ERC165 } from "./@openzeppelin/contracts/utils/introspection/ERC165";
export { ERC165__factory } from "./factories/@openzeppelin/contracts/utils/introspection/ERC165__factory";
export type { IERC165 } from "./@openzeppelin/contracts/utils/introspection/IERC165";
export { IERC165__factory } from "./factories/@openzeppelin/contracts/utils/introspection/IERC165__factory";
export type { SafeCast } from "./@openzeppelin/contracts/utils/math/SafeCast";
export { SafeCast__factory } from "./factories/@openzeppelin/contracts/utils/math/SafeCast__factory";
export type { Strings } from "./@openzeppelin/contracts/utils/Strings";
export { Strings__factory } from "./factories/@openzeppelin/contracts/utils/Strings__factory";
export type { AIToken } from "./contracts/AIToken";
export { AIToken__factory } from "./factories/contracts/AIToken__factory";
export type { AITokenRegistry } from "./contracts/AITokenRegistry";
export { AITokenRegistry__factory } from "./factories/contracts/AITokenRegistry__factory";

View File

@@ -0,0 +1,24 @@
#!/bin/bash
# Clean up failed deployment and prepare for redeployment
echo "🧹 Cleaning up failed deployment..."
echo "=================================="
# Stop any running services
echo "Stopping services..."
ssh ns3-root "systemctl stop blockchain-node blockchain-rpc nginx 2>/dev/null || true"
# Remove old directories
echo "Removing old directories..."
ssh ns3-root "rm -rf /opt/blockchain-node /opt/blockchain-node-src /opt/blockchain-explorer 2>/dev/null || true"
# Remove systemd services
echo "Removing systemd services..."
ssh ns3-root "systemctl disable blockchain-node blockchain-rpc blockchain-explorer 2>/dev/null || true"
ssh ns3-root "rm -f /etc/systemd/system/blockchain-node.service /etc/systemd/system/blockchain-rpc.service /etc/systemd/system/blockchain-explorer.service 2>/dev/null || true"
ssh ns3-root "systemctl daemon-reload"
echo "✅ Cleanup complete!"
echo ""
echo "You can now run: ./scripts/deploy/deploy-all-remote.sh"

View File

@@ -0,0 +1,109 @@
#!/usr/bin/env python3
"""
Deploy AITBC services to incus container
"""
import subprocess
import time
import sys
def run_command(cmd, container=None):
"""Run command locally or in container"""
if container:
cmd = f"incus exec {container} -- {cmd}"
print(f"Running: {cmd}")
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
if result.returncode != 0:
print(f"Error: {result.stderr}")
return False
return True
def deploy_to_container():
container = "aitbc"
container_ip = "10.1.223.93"
print("🚀 Deploying AITBC services to container...")
# Stop local services
print("\n📋 Stopping local services...")
subprocess.run("sudo fuser -k 8000/tcp 2>/dev/null || true", shell=True)
subprocess.run("sudo fuser -k 9080/tcp 2>/dev/null || true", shell=True)
subprocess.run("pkill -f 'marketplace-ui' 2>/dev/null || true", shell=True)
subprocess.run("pkill -f 'trade-exchange' 2>/dev/null || true", shell=True)
# Copy project to container
print("\n📁 Copying project to container...")
subprocess.run(f"incus file push -r /home/oib/windsurf/aitbc {container}/home/oib/", shell=True)
# Setup Python environment in container
print("\n🐍 Setting up Python environment...")
run_command("cd /home/oib/aitbc && python3 -m venv .venv", container)
run_command("cd /home/oib/aitbc && source .venv/bin/activate && pip install fastapi uvicorn httpx sqlmodel", container)
# Install dependencies
print("\n📦 Installing dependencies...")
run_command("cd /home/oib/aitbc/apps/coordinator-api && source ../../.venv/bin/activate && pip install -e .", container)
run_command("cd /home/oib/aitbc/apps/blockchain-node && source ../../.venv/bin/activate && pip install -e .", container)
# Create startup script
print("\n🔧 Creating startup script...")
startup_script = """#!/bin/bash
cd /home/oib/aitbc
# Start blockchain node
echo "Starting blockchain node..."
cd apps/blockchain-node
source ../../.venv/bin/activate
python -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 9080 &
NODE_PID=$!
# Start coordinator API
echo "Starting coordinator API..."
cd ../coordinator-api
source ../../.venv/bin/activate
python -m uvicorn src.app.main:app --host 0.0.0.0 --port 8000 &
COORD_PID=$!
# Start marketplace UI
echo "Starting marketplace UI..."
cd ../marketplace-ui
python server.py --port 3001 &
MARKET_PID=$!
# Start trade exchange
echo "Starting trade exchange..."
cd ../trade-exchange
python server.py --port 3002 &
EXCHANGE_PID=$!
echo "Services started!"
echo "Blockchain: http://10.1.223.93:9080"
echo "API: http://10.1.223.93:8000"
echo "Marketplace: http://10.1.223.93:3001"
echo "Exchange: http://10.1.223.93:3002"
# Wait for services
wait $NODE_PID $COORD_PID $MARKET_PID $EXCHANGE_PID
"""
# Write startup script to container
with open('/tmp/start_aitbc.sh', 'w') as f:
f.write(startup_script)
subprocess.run("incus file push /tmp/start_aitbc.sh aitbc/home/oib/", shell=True)
run_command("chmod +x /home/oib/start_aitbc.sh", container)
# Start services
print("\n🚀 Starting AITBC services...")
run_command("/home/oib/start_aitbc.sh", container)
print(f"\n✅ Services deployed to container!")
print(f"\n📋 Access URLs:")
print(f" 🌐 Container IP: {container_ip}")
print(f" 📊 Marketplace: http://{container_ip}:3001")
print(f" 💱 Trade Exchange: http://{container_ip}:3002")
print(f" 🔗 API: http://{container_ip}:8000")
print(f" ⛓️ Blockchain: http://{container_ip}:9080")
if __name__ == "__main__":
deploy_to_container()

View File

@@ -0,0 +1,56 @@
#!/bin/bash
# Deploy blockchain node and explorer by building directly on ns3
echo "🚀 AITBC Remote Deployment (Build on Server)"
echo "=========================================="
echo "This will build the blockchain node directly on ns3"
echo "to utilize the gigabit connection instead of uploading."
echo ""
# Copy deployment scripts to server
echo "Copying deployment scripts to ns3..."
scp scripts/deploy/deploy-blockchain-remote.sh ns3-root:/opt/
scp scripts/deploy/deploy-explorer-remote.sh ns3-root:/opt/
# Create directories on server first
echo "Creating directories on ns3..."
ssh ns3-root "mkdir -p /opt/blockchain-node-src /opt/blockchain-node"
# Copy blockchain source code to server (excluding data files)
echo "Copying blockchain source code to ns3..."
rsync -av --exclude='data/' --exclude='*.db' --exclude='__pycache__' --exclude='.venv' apps/blockchain-node/ ns3-root:/opt/blockchain-node-src/
# Execute blockchain deployment
echo ""
echo "Deploying blockchain node..."
ssh ns3-root "cd /opt && cp -r /opt/blockchain-node-src/* /opt/blockchain-node/ && cd /opt/blockchain-node && chmod +x ../deploy-blockchain-remote.sh && ../deploy-blockchain-remote.sh"
# Wait for blockchain to start
echo ""
echo "Waiting 10 seconds for blockchain node to start..."
sleep 10
# Execute explorer deployment on ns3
echo ""
echo "Deploying blockchain explorer..."
ssh ns3-root "cd /opt && ./deploy-explorer-remote.sh"
# Check services
echo ""
echo "Checking service status..."
ssh ns3-root "systemctl status blockchain-node blockchain-rpc nginx --no-pager | grep -E 'Active:|Main PID:'"
echo ""
echo "✅ Deployment complete!"
echo ""
echo "Services:"
echo " - Blockchain Node RPC: http://localhost:8082"
echo " - Blockchain Explorer: http://localhost:3000"
echo ""
echo "External access:"
echo " - Blockchain Node RPC: http://aitbc.keisanki.net:8082"
echo " - Blockchain Explorer: http://aitbc.keisanki.net:3000"
echo ""
echo "The blockchain node will start syncing automatically."
echo "The explorer connects to the local node and displays real-time data."

View File

@@ -0,0 +1,207 @@
#!/bin/bash
# Deploy blockchain node and explorer to incus container
set -e
echo "🚀 Deploying Blockchain Node and Explorer"
echo "========================================"
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Copy blockchain node to container
print_status "Copying blockchain node to container..."
ssh ns3-root "rm -rf /opt/blockchain-node 2>/dev/null || true"
scp -r apps/blockchain-node ns3-root:/opt/
# Setup blockchain node in container
print_status "Setting up blockchain node..."
ssh ns3-root << 'EOF'
cd /opt/blockchain-node
# Create configuration
cat > .env << EOL
CHAIN_ID=ait-devnet
DB_PATH=./data/chain.db
RPC_BIND_HOST=0.0.0.0
RPC_BIND_PORT=8082
P2P_BIND_HOST=0.0.0.0
P2P_BIND_PORT=7070
PROPOSER_KEY=proposer_key_$(date +%s)
MINT_PER_UNIT=1000
COORDINATOR_RATIO=0.05
GOSSIP_BACKEND=memory
EOL
# Create data directory
mkdir -p data/devnet
# Setup Python environment
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e .
# Generate genesis
export PYTHONPATH="${PWD}/src:${PWD}/scripts:${PYTHONPATH:-}"
python scripts/make_genesis.py --output data/devnet/genesis.json --force
EOF
# Create systemd service for blockchain node
print_status "Creating systemd service for blockchain node..."
ssh ns3-root << 'EOF'
cat > /etc/systemd/system/blockchain-node.service << EOL
[Unit]
Description=AITBC Blockchain Node
After=network.target
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m aitbc_chain.main
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
cat > /etc/systemd/system/blockchain-rpc.service << EOL
[Unit]
Description=AITBC Blockchain RPC API
After=blockchain-node.service
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8082
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
systemctl daemon-reload
systemctl enable blockchain-node blockchain-rpc
EOF
# Start blockchain node
print_status "Starting blockchain node..."
ssh ns3-root "systemctl start blockchain-node blockchain-rpc"
# Wait for node to start
print_status "Waiting for blockchain node to start..."
sleep 5
# Check status
print_status "Checking blockchain node status..."
ssh ns3-root "systemctl status blockchain-node blockchain-rpc --no-pager | grep -E 'Active:|Main PID:'"
# Copy explorer to container
print_status "Copying blockchain explorer to container..."
ssh ns3-root "rm -rf /opt/blockchain-explorer 2>/dev/null || true"
scp -r apps/blockchain-explorer ns3-root:/opt/
# Setup explorer in container
print_status "Setting up blockchain explorer..."
ssh ns3-root << 'EOF'
cd /opt/blockchain-explorer
# Create Python environment
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
EOF
# Create systemd service for explorer
print_status "Creating systemd service for blockchain explorer..."
ssh ns3-root << 'EOF'
cat > /etc/systemd/system/blockchain-explorer.service << EOL
[Unit]
Description=AITBC Blockchain Explorer
After=blockchain-rpc.service
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-explorer
Environment=PATH=/opt/blockchain-explorer/.venv/bin:/usr/local/bin:/usr/bin:/bin
ExecStart=/opt/blockchain-explorer/.venv/bin/python3 main.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
systemctl daemon-reload
systemctl enable blockchain-explorer
EOF
# Start explorer
print_status "Starting blockchain explorer..."
ssh ns3-root "systemctl start blockchain-explorer"
# Wait for explorer to start
print_status "Waiting for explorer to start..."
sleep 3
# Setup port forwarding
print_status "Setting up port forwarding..."
ssh ns3-root << 'EOF'
# Clear existing NAT rules
iptables -t nat -F PREROUTING 2>/dev/null || true
iptables -t nat -F POSTROUTING 2>/dev/null || true
# Add port forwarding for blockchain RPC
iptables -t nat -A PREROUTING -p tcp --dport 8082 -j DNAT --to-destination 192.168.100.10:8082
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 8082 -j MASQUERADE
# Add port forwarding for explorer
iptables -t nat -A PREROUTING -p tcp --dport 3000 -j DNAT --to-destination 192.168.100.10:3000
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 3000 -j MASQUERADE
# Save rules
mkdir -p /etc/iptables
iptables-save > /etc/iptables/rules.v4
# Install iptables-persistent for persistence
apt-get update
apt-get install -y iptables-persistent
EOF
# Check all services
print_status "Checking all services..."
ssh ns3-root "systemctl status blockchain-node blockchain-rpc blockchain-explorer --no-pager | grep -E 'Active:|Main PID:'"
print_success "✅ Deployment complete!"
echo ""
echo "Services deployed:"
echo " - Blockchain Node RPC: http://192.168.100.10:8082"
echo " - Blockchain Explorer: http://192.168.100.10:3000"
echo ""
echo "External access:"
echo " - Blockchain Node RPC: http://aitbc.keisanki.net:8082"
echo " - Blockchain Explorer: http://aitbc.keisanki.net:3000"
echo ""
echo "The explorer is connected to the local blockchain node and will display"
echo "real-time blockchain data including blocks and transactions."

View File

@@ -0,0 +1,94 @@
#!/bin/bash
# Deploy blockchain explorer to incus container
set -e
echo "🔍 Deploying Blockchain Explorer"
echo "================================="
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Copy explorer to container
print_status "Copying blockchain explorer to container..."
ssh ns3-root "rm -rf /opt/blockchain-explorer 2>/dev/null || true"
scp -r apps/blockchain-explorer ns3-root:/opt/
# Setup explorer in container
print_status "Setting up blockchain explorer..."
ssh ns3-root << 'EOF'
cd /opt/blockchain-explorer
# Create Python environment
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
EOF
# Create systemd service for explorer
print_status "Creating systemd service for blockchain explorer..."
ssh ns3-root << 'EOF'
cat > /etc/systemd/system/blockchain-explorer.service << EOL
[Unit]
Description=AITBC Blockchain Explorer
After=blockchain-rpc.service
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-explorer
Environment=PATH=/opt/blockchain-explorer/.venv/bin:/usr/local/bin:/usr/bin:/bin
ExecStart=/opt/blockchain-explorer/.venv/bin/python3 main.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
systemctl daemon-reload
systemctl enable blockchain-explorer
EOF
# Start explorer
print_status "Starting blockchain explorer..."
ssh ns3-root "systemctl start blockchain-explorer"
# Wait for explorer to start
print_status "Waiting for explorer to start..."
sleep 3
# Setup port forwarding for explorer
print_status "Setting up port forwarding for explorer..."
ssh ns3-root << 'EOF'
# Add port forwarding for explorer
iptables -t nat -A PREROUTING -p tcp --dport 3000 -j DNAT --to-destination 192.168.100.10:3000
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 3000 -j MASQUERADE
# Save rules
iptables-save > /etc/iptables/rules.v4
EOF
# Check status
print_status "Checking blockchain explorer status..."
ssh ns3-root "systemctl status blockchain-explorer --no-pager | grep -E 'Active:|Main PID:'"
print_success "✅ Blockchain explorer deployed!"
echo ""
echo "Explorer URL: http://192.168.100.10:3000"
echo "External URL: http://aitbc.keisanki.net:3000"
echo ""
echo "The explorer will automatically connect to the local blockchain node."
echo "You can view blocks, transactions, and chain statistics."

View File

@@ -0,0 +1,157 @@
#!/bin/bash
# Deploy blockchain node directly on ns3 server (build in place)
set -e
echo "🚀 Deploying Blockchain Node on ns3 (Build in Place)"
echo "====================================================="
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Check if we're on the right server
print_status "Checking server..."
if [ "$(hostname)" != "ns3" ] && [ "$(hostname)" != "aitbc" ]; then
print_warning "This script should be run on ns3 server"
echo "Please run: ssh ns3-root"
echo "Then: cd /opt && ./deploy-blockchain-remote.sh"
exit 1
fi
# Install dependencies if needed
print_status "Installing dependencies..."
apt-get update
apt-get install -y python3 python3-venv python3-pip git curl
# Create directory
print_status "Creating blockchain node directory..."
mkdir -p /opt/blockchain-node
cd /opt/blockchain-node
# Check if source code exists
if [ ! -d "src" ]; then
print_status "Source code not found in /opt/blockchain-node, copying from /opt/blockchain-node-src..."
if [ -d "/opt/blockchain-node-src" ]; then
cp -r /opt/blockchain-node-src/* .
else
print_warning "Source code not found. Please ensure it was copied properly."
exit 1
fi
fi
# Setup Python environment
print_status "Setting up Python environment..."
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e .
# Create configuration with auto-sync
print_status "Creating configuration..."
cat > .env << EOL
CHAIN_ID=ait-devnet
DB_PATH=./data/chain.db
RPC_BIND_HOST=0.0.0.0
RPC_BIND_PORT=8082
P2P_BIND_HOST=0.0.0.0
P2P_BIND_PORT=7070
PROPOSER_KEY=proposer_key_$(date +%s)
MINT_PER_UNIT=1000
COORDINATOR_RATIO=0.05
GOSSIP_BACKEND=memory
EOL
# Create fresh data directory
print_status "Creating fresh data directory..."
rm -rf data
mkdir -p data/devnet
# Generate fresh genesis
print_status "Generating fresh genesis block..."
export PYTHONPATH="${PWD}/src:${PWD}/scripts:${PYTHONPATH:-}"
python scripts/make_genesis.py --output data/devnet/genesis.json --force
# Create systemd service for blockchain node
print_status "Creating systemd services..."
cat > /etc/systemd/system/blockchain-node.service << EOL
[Unit]
Description=AITBC Blockchain Node
After=network.target
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m aitbc_chain.main
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
cat > /etc/systemd/system/blockchain-rpc.service << EOL
[Unit]
Description=AITBC Blockchain RPC API
After=blockchain-node.service
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8082
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
# Enable and start services
print_status "Starting blockchain node..."
systemctl daemon-reload
systemctl enable blockchain-node blockchain-rpc
systemctl start blockchain-node blockchain-rpc
# Wait for services to start
print_status "Waiting for services to start..."
sleep 5
# Check status
print_status "Checking service status..."
systemctl status blockchain-node blockchain-rpc --no-pager | head -15
# Setup port forwarding if in container
if [ "$(hostname)" = "aitbc" ]; then
print_status "Setting up port forwarding..."
iptables -t nat -A PREROUTING -p tcp --dport 8082 -j DNAT --to-destination 192.168.100.10:8082
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 8082 -j MASQUERADE
iptables-save > /etc/iptables/rules.v4
fi
print_success "✅ Blockchain node deployed!"
echo ""
if [ "$(hostname)" = "aitbc" ]; then
echo "Node RPC: http://192.168.100.10:8082"
echo "External RPC: http://aitbc.keisanki.net:8082"
else
echo "Node RPC: http://95.216.198.140:8082"
echo "External RPC: http://aitbc.keisanki.net:8082"
fi
echo ""
echo "The node will automatically sync on startup."

View File

@@ -0,0 +1,139 @@
#!/bin/bash
# Deploy blockchain node and explorer to incus container
set -e
echo "🚀 Deploying Blockchain Node and Explorer"
echo "========================================"
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Copy blockchain node to container
print_status "Copying blockchain node to container..."
ssh ns3-root "rm -rf /opt/blockchain-node 2>/dev/null || true"
scp -r apps/blockchain-node ns3-root:/opt/
# Setup blockchain node in container
print_status "Setting up blockchain node..."
ssh ns3-root << 'EOF'
cd /opt/blockchain-node
# Create configuration
cat > .env << EOL
CHAIN_ID=ait-devnet
DB_PATH=./data/chain.db
RPC_BIND_HOST=0.0.0.0
RPC_BIND_PORT=8082
P2P_BIND_HOST=0.0.0.0
P2P_BIND_PORT=7070
PROPOSER_KEY=proposer_key_$(date +%s)
MINT_PER_UNIT=1000
COORDINATOR_RATIO=0.05
GOSSIP_BACKEND=memory
EOL
# Create data directory
mkdir -p data/devnet
# Setup Python environment
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e .
# Generate genesis
export PYTHONPATH="${PWD}/src:${PWD}/scripts:${PYTHONPATH:-}"
python scripts/make_genesis.py --output data/devnet/genesis.json --force
EOF
# Create systemd service for blockchain node
print_status "Creating systemd service for blockchain node..."
ssh ns3-root << 'EOF'
cat > /etc/systemd/system/blockchain-node.service << EOL
[Unit]
Description=AITBC Blockchain Node
After=network.target
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m aitbc_chain.main
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
cat > /etc/systemd/system/blockchain-rpc.service << EOL
[Unit]
Description=AITBC Blockchain RPC API
After=blockchain-node.service
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8082
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
systemctl daemon-reload
systemctl enable blockchain-node blockchain-rpc
EOF
# Start blockchain node
print_status "Starting blockchain node..."
ssh ns3-root "systemctl start blockchain-node blockchain-rpc"
# Wait for node to start
print_status "Waiting for blockchain node to start..."
sleep 5
# Check status
print_status "Checking blockchain node status..."
ssh ns3-root "systemctl status blockchain-node blockchain-rpc --no-pager | grep -E 'Active:|Main PID:'"
# Setup port forwarding
print_status "Setting up port forwarding..."
ssh ns3-root << 'EOF'
# Clear existing rules
iptables -t nat -F PREROUTING 2>/dev/null || true
iptables -t nat -F POSTROUTING 2>/dev/null || true
# Add port forwarding for blockchain RPC
iptables -t nat -A PREROUTING -p tcp --dport 8082 -j DNAT --to-destination 192.168.100.10:8082
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 8082 -j MASQUERADE
# Save rules
mkdir -p /etc/iptables
iptables-save > /etc/iptables/rules.v4
EOF
print_success "✅ Blockchain node deployed!"
echo ""
echo "Node RPC: http://192.168.100.10:8082"
echo "External RPC: http://aitbc.keisanki.net:8082"
echo ""
echo "Next: Deploying blockchain explorer..."

316
scripts/deploy/deploy-direct.sh Executable file
View File

@@ -0,0 +1,316 @@
#!/bin/bash
# Deploy blockchain node and explorer directly on ns3
set -e
echo "🚀 AITBC Direct Deployment on ns3"
echo "================================="
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Check if we're on ns3
if [ "$(hostname)" != "ns3" ] && [ "$(hostname)" != "aitbc" ]; then
print_warning "This script must be run on ns3 server"
echo "Run: ssh ns3-root"
echo "Then: cd /opt && ./deploy-direct.sh"
exit 1
fi
# Stop existing services
print_status "Stopping existing services..."
systemctl stop blockchain-node blockchain-rpc blockchain-explorer nginx 2>/dev/null || true
# Install dependencies
print_status "Installing dependencies..."
apt-get update
apt-get install -y python3 python3-venv python3-pip git curl nginx
# Deploy blockchain node
print_status "Deploying blockchain node..."
cd /opt
rm -rf blockchain-node
cp -r blockchain-node-src blockchain-node
cd blockchain-node
# Create configuration
print_status "Creating configuration..."
cat > .env << EOL
CHAIN_ID=ait-devnet
DB_PATH=./data/chain.db
RPC_BIND_HOST=0.0.0.0
RPC_BIND_PORT=8082
P2P_BIND_HOST=0.0.0.0
P2P_BIND_PORT=7070
PROPOSER_KEY=proposer_key_$(date +%s)
MINT_PER_UNIT=1000
COORDINATOR_RATIO=0.05
GOSSIP_BACKEND=memory
EOL
# Create fresh data directory
rm -rf data
mkdir -p data/devnet
# Setup Python environment
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e .
# Generate genesis
export PYTHONPATH="${PWD}/src:${PWD}/scripts:${PYTHONPATH:-}"
python scripts/make_genesis.py --output data/devnet/genesis.json --force
# Create systemd services
print_status "Creating systemd services..."
cat > /etc/systemd/system/blockchain-node.service << EOL
[Unit]
Description=AITBC Blockchain Node
After=network.target
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m aitbc_chain.main
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
cat > /etc/systemd/system/blockchain-rpc.service << EOL
[Unit]
Description=AITBC Blockchain RPC API
After=blockchain-node.service
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8082
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
# Start blockchain services
print_status "Starting blockchain services..."
systemctl daemon-reload
systemctl enable blockchain-node blockchain-rpc
systemctl start blockchain-node blockchain-rpc
# Deploy explorer
print_status "Deploying blockchain explorer..."
cd /opt
rm -rf blockchain-explorer
mkdir -p blockchain-explorer
cd blockchain-explorer
# Create HTML explorer
cat > index.html << 'EOF'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AITBC Blockchain Explorer</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/lucide@latest"></script>
</head>
<body class="bg-gray-50">
<header class="bg-blue-600 text-white shadow-lg">
<div class="container mx-auto px-4 py-4">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-3">
<i data-lucide="cube" class="w-8 h-8"></i>
<h1 class="text-2xl font-bold">AITBC Blockchain Explorer</h1>
</div>
<button onclick="refreshData()" class="bg-blue-500 hover:bg-blue-400 px-3 py-1 rounded flex items-center space-x-1">
<i data-lucide="refresh-cw" class="w-4 h-4"></i>
<span>Refresh</span>
</button>
</div>
</div>
</header>
<main class="container mx-auto px-4 py-8">
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm">Current Height</p>
<p class="text-2xl font-bold" id="chain-height">-</p>
</div>
<i data-lucide="trending-up" class="w-10 h-10 text-green-500"></i>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm">Latest Block</p>
<p class="text-lg font-mono" id="latest-hash">-</p>
</div>
<i data-lucide="hash" class="w-10 h-10 text-blue-500"></i>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm">Node Status</p>
<p class="text-lg font-semibold" id="node-status">-</p>
</div>
<i data-lucide="activity" class="w-10 h-10 text-purple-500"></i>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b">
<h2 class="text-xl font-semibold flex items-center">
<i data-lucide="blocks" class="w-5 h-5 mr-2"></i>
Latest Blocks
</h2>
</div>
<div class="p-6">
<table class="w-full">
<thead>
<tr class="text-left text-gray-500 text-sm">
<th class="pb-3">Height</th>
<th class="pb-3">Hash</th>
<th class="pb-3">Timestamp</th>
<th class="pb-3">Transactions</th>
</tr>
</thead>
<tbody id="blocks-table">
<tr>
<td colspan="4" class="text-center py-8 text-gray-500">
Loading blocks...
</td>
</tr>
</tbody>
</table>
</div>
</div>
</main>
<script>
lucide.createIcons();
const RPC_URL = 'http://localhost:8082';
async function refreshData() {
try {
const response = await fetch(`${RPC_URL}/rpc/head`);
const head = await response.json();
document.getElementById('chain-height').textContent = head.height || '-';
document.getElementById('latest-hash').textContent = head.hash ? head.hash.substring(0, 16) + '...' : '-';
document.getElementById('node-status').innerHTML = '<span class="text-green-500">Online</span>';
// Load last 10 blocks
const tbody = document.getElementById('blocks-table');
tbody.innerHTML = '';
for (let i = 0; i < 10 && head.height - i >= 0; i++) {
const blockResponse = await fetch(`${RPC_URL}/rpc/blocks/${head.height - i}`);
const block = await blockResponse.json();
const row = tbody.insertRow();
row.innerHTML = `
<td class="py-3 font-mono">${block.height}</td>
<td class="py-3 font-mono text-sm">${block.hash ? block.hash.substring(0, 16) + '...' : '-'}</td>
<td class="py-3 text-sm">${new Date(block.timestamp * 1000).toLocaleString()}</td>
<td class="py-3">${block.transactions ? block.transactions.length : 0}</td>
`;
}
} catch (error) {
console.error('Error:', error);
document.getElementById('node-status').innerHTML = '<span class="text-red-500">Error</span>';
}
}
refreshData();
setInterval(refreshData, 30000);
</script>
</body>
</html>
EOF
# Configure nginx
print_status "Configuring nginx..."
cat > /etc/nginx/sites-available/blockchain-explorer << EOL
server {
listen 3000;
server_name _;
root /opt/blockchain-explorer;
index index.html;
location / {
try_files \$uri \$uri/ =404;
}
}
EOL
ln -sf /etc/nginx/sites-available/blockchain-explorer /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
nginx -t
systemctl reload nginx
# Setup port forwarding if in container
if [ "$(hostname)" = "aitbc" ]; then
print_status "Setting up port forwarding..."
iptables -t nat -F PREROUTING 2>/dev/null || true
iptables -t nat -F POSTROUTING 2>/dev/null || true
iptables -t nat -A PREROUTING -p tcp --dport 8082 -j DNAT --to-destination 192.168.100.10:8082
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 8082 -j MASQUERADE
iptables -t nat -A PREROUTING -p tcp --dport 3000 -j DNAT --to-destination 192.168.100.10:3000
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 3000 -j MASQUERADE
iptables-save > /etc/iptables/rules.v4
fi
# Wait for services to start
print_status "Waiting for services to start..."
sleep 5
# Check services
print_status "Checking service status..."
systemctl status blockchain-node blockchain-rpc nginx --no-pager | grep -E 'Active:|Main PID:'
print_success "✅ Deployment complete!"
echo ""
echo "Services:"
if [ "$(hostname)" = "aitbc" ]; then
echo " - Blockchain Node RPC: http://192.168.100.10:8082"
echo " - Blockchain Explorer: http://192.168.100.10:3000"
echo ""
echo "External access:"
echo " - Blockchain Node RPC: http://aitbc.keisanki.net:8082"
echo " - Blockchain Explorer: http://aitbc.keisanki.net:3000"
else
echo " - Blockchain Node RPC: http://localhost:8082"
echo " - Blockchain Explorer: http://localhost:3000"
echo ""
echo "External access:"
echo " - Blockchain Node RPC: http://aitbc.keisanki.net:8082"
echo " - Blockchain Explorer: http://aitbc.keisanki.net:3000"
fi

88
scripts/deploy/deploy-domain.sh Executable file
View File

@@ -0,0 +1,88 @@
#!/bin/bash
# Deploy AITBC services to domain https://aitbc.bubuit.net
set -e
DOMAIN="aitbc.bubuit.net"
CONTAINER="aitbc"
echo "🚀 Deploying AITBC services to https://$DOMAIN"
echo ""
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Stop local services
print_status "Stopping local services..."
sudo fuser -k 8000/tcp 2>/dev/null || true
sudo fuser -k 9080/tcp 2>/dev/null || true
sudo fuser -k 3001/tcp 2>/dev/null || true
sudo fuser -k 3002/tcp 2>/dev/null || true
# Deploy to container
print_status "Deploying to container..."
python /home/oib/windsurf/aitbc/container-deploy.py
# Copy nginx config to container
print_status "Configuring nginx for domain..."
incus file push /home/oib/windsurf/aitbc/nginx-aitbc.conf $CONTAINER/etc/nginx/sites-available/aitbc
# Enable site
incus exec $CONTAINER -- ln -sf /etc/nginx/sites-available/aitbc /etc/nginx/sites-enabled/
incus exec $CONTAINER -- rm -f /etc/nginx/sites-enabled/default
# Test nginx config
incus exec $CONTAINER -- nginx -t
# Reload nginx
incus exec $CONTAINER -- systemctl reload nginx
# Install SSL certificate (Let's Encrypt)
print_warning "SSL Certificate Setup:"
echo "1. Ensure port 80/443 are forwarded to container IP (10.1.223.93)"
echo "2. Run certbot in container:"
echo " incus exec $CONTAINER -- certbot --nginx -d $DOMAIN"
echo ""
# Update UIs to use correct API endpoints
print_status "Updating API endpoints..."
# Update marketplace API base URL
incus exec $CONTAINER -- sed -i "s|http://127.0.0.1:8000|https://$DOMAIN/api|g" /home/oib/aitbc/apps/marketplace-ui/index.html
# Update exchange API endpoints
incus exec $CONTAINER -- sed -i "s|http://127.0.0.1:8000|https://$DOMAIN/api|g" /home/oib/aitbc/apps/trade-exchange/index.html
incus exec $CONTAINER -- sed -i "s|http://127.0.0.1:9080|https://$DOMAIN/rpc|g" /home/oib/aitbc/apps/trade-exchange/index.html
# Restart services to apply changes
print_status "Restarting services..."
incus exec $CONTAINER -- pkill -f "server.py"
sleep 2
incus exec $CONTAINER -- /home/oib/start_aitbc.sh
echo ""
print_status "✅ Deployment complete!"
echo ""
echo "📋 Service URLs:"
echo " 🌐 Domain: https://$DOMAIN"
echo " 📊 Marketplace: https://$DOMAIN/Marketplace"
echo " 💱 Trade Exchange: https://$DOMAIN/Exchange"
echo " 🔗 API: https://$DOMAIN/api"
echo " ⛓️ Blockchain RPC: https://$DOMAIN/rpc"
echo ""
echo "📝 Next Steps:"
echo "1. Forward ports 80/443 to container IP (10.1.223.93)"
echo "2. Install SSL certificate:"
echo " incus exec $CONTAINER -- certbot --nginx -d $DOMAIN"
echo "3. Test services at the URLs above"

View File

@@ -0,0 +1,74 @@
#!/bin/bash
# Deploy AITBC Trade Exchange to the server
set -e
SERVER="root@10.1.223.93"
EXCHANGE_DIR="/root/aitbc/apps/trade-exchange"
echo "🚀 Deploying AITBC Trade Exchange"
echo "=================================="
echo "Server: $SERVER"
echo ""
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Test SSH connection
print_status "Testing SSH connection..."
ssh $SERVER "hostname && ip a show eth0 | grep inet"
# Copy updated files
print_status "Copying updated Exchange files..."
scp /home/oib/windsurf/aitbc/apps/trade-exchange/index.html $SERVER:$EXCHANGE_DIR/
scp /home/oib/windsurf/aitbc/apps/trade-exchange/server.py $SERVER:$EXCHANGE_DIR/
# Ensure assets are available
print_status "Ensuring assets directory exists..."
ssh $SERVER "mkdir -p /var/www/aitbc.bubuit.net/assets"
ssh $SERVER "mkdir -p /var/www/aitbc.bubuit.net/assets/css"
ssh $SERVER "mkdir -p /var/www/aitbc.bubuit.net/assets/js"
# Copy assets if they don't exist
print_status "Copying assets if needed..."
if ! ssh $SERVER "test -f /var/www/aitbc.bubuit.net/assets/css/aitbc.css"; then
scp -r /home/oib/windsurf/aitbc/assets/* $SERVER:/var/www/aitbc.bubuit.net/assets/
fi
# Restart the exchange service
print_status "Restarting Trade Exchange service..."
ssh $SERVER "systemctl restart aitbc-exchange"
# Wait for service to start
print_status "Waiting for service to start..."
sleep 5
# Check service status
print_status "Checking service status..."
ssh $SERVER "systemctl status aitbc-exchange --no-pager -l | head -10"
# Test the endpoint
print_status "Testing Exchange endpoint..."
ssh $SERVER "curl -s http://127.0.0.1:3002/ | head -c 100"
echo ""
echo ""
print_status "✅ Exchange deployment complete!"
echo ""
echo "📋 URLs:"
echo " 🌐 IP: http://10.1.223.93/Exchange"
echo " 🔒 Domain: https://aitbc.bubuit.net/Exchange"
echo ""
echo "🔍 To check logs:"
echo " ssh $SERVER 'journalctl -u aitbc-exchange -f'"

View File

@@ -0,0 +1,396 @@
#!/bin/bash
# Deploy blockchain explorer directly on ns3 server
set -e
echo "🔍 Deploying Blockchain Explorer on ns3"
echo "======================================"
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Check if we're on the right server
if [ "$(hostname)" != "ns3" ] && [ "$(hostname)" != "aitbc" ]; then
print_warning "This script should be run on ns3 server"
exit 1
fi
# Create directory
print_status "Creating blockchain explorer directory..."
mkdir -p /opt/blockchain-explorer
cd /opt/blockchain-explorer
# Create a simple HTML-based explorer (no build needed)
print_status "Creating web-based explorer..."
cat > index.html << 'EOF'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AITBC Blockchain Explorer</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/lucide@latest"></script>
<style>
.fade-in { animation: fadeIn 0.3s ease-in; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
</style>
</head>
<body class="bg-gray-50">
<header class="bg-blue-600 text-white shadow-lg">
<div class="container mx-auto px-4 py-4">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-3">
<i data-lucide="cube" class="w-8 h-8"></i>
<h1 class="text-2xl font-bold">AITBC Blockchain Explorer</h1>
</div>
<div class="flex items-center space-x-4">
<span class="text-sm">Network: <span class="font-mono bg-blue-700 px-2 py-1 rounded">ait-devnet</span></span>
<button onclick="refreshData()" class="bg-blue-500 hover:bg-blue-400 px-3 py-1 rounded flex items-center space-x-1">
<i data-lucide="refresh-cw" class="w-4 h-4"></i>
<span>Refresh</span>
</button>
</div>
</div>
</div>
</header>
<main class="container mx-auto px-4 py-8">
<!-- Chain Stats -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm">Current Height</p>
<p class="text-2xl font-bold" id="chain-height">-</p>
</div>
<i data-lucide="trending-up" class="w-10 h-10 text-green-500"></i>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm">Latest Block</p>
<p class="text-lg font-mono" id="latest-hash">-</p>
</div>
<i data-lucide="hash" class="w-10 h-10 text-blue-500"></i>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm">Node Status</p>
<p class="text-lg font-semibold" id="node-status">-</p>
</div>
<i data-lucide="activity" class="w-10 h-10 text-purple-500"></i>
</div>
</div>
</div>
<!-- Search -->
<div class="bg-white rounded-lg shadow p-6 mb-8">
<div class="flex space-x-4">
<input type="text" id="search-input" placeholder="Search by block height, hash, or transaction hash"
class="flex-1 px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
<button onclick="search()" class="bg-blue-600 text-white px-6 py-2 rounded-lg hover:bg-blue-700">
Search
</button>
</div>
</div>
<!-- Latest Blocks -->
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b">
<h2 class="text-xl font-semibold flex items-center">
<i data-lucide="blocks" class="w-5 h-5 mr-2"></i>
Latest Blocks
</h2>
</div>
<div class="p-6">
<div class="overflow-x-auto">
<table class="w-full">
<thead>
<tr class="text-left text-gray-500 text-sm">
<th class="pb-3">Height</th>
<th class="pb-3">Hash</th>
<th class="pb-3">Timestamp</th>
<th class="pb-3">Transactions</th>
<th class="pb-3">Actions</th>
</tr>
</thead>
<tbody id="blocks-table">
<tr>
<td colspan="5" class="text-center py-8 text-gray-500">
Loading blocks...
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- Block Details Modal -->
<div id="block-modal" class="fixed inset-0 bg-black bg-opacity-50 hidden z-50">
<div class="flex items-center justify-center min-h-screen p-4">
<div class="bg-white rounded-lg max-w-4xl w-full max-h-[90vh] overflow-y-auto">
<div class="p-6 border-b">
<div class="flex justify-between items-center">
<h2 class="text-2xl font-bold">Block Details</h2>
<button onclick="closeModal()" class="text-gray-500 hover:text-gray-700">
<i data-lucide="x" class="w-6 h-6"></i>
</button>
</div>
</div>
<div class="p-6" id="block-details">
<!-- Block details will be loaded here -->
</div>
</div>
</div>
</div>
</main>
<footer class="bg-gray-800 text-white mt-12">
<div class="container mx-auto px-4 py-6 text-center">
<p class="text-sm">AITBC Blockchain Explorer - Connected to node at http://localhost:8082</p>
</div>
</footer>
<script>
// Initialize lucide icons
lucide.createIcons();
// RPC URL - change based on environment
const RPC_URL = window.location.hostname === 'localhost' ?
'http://localhost:8082' :
'http://95.216.198.140:8082';
// Global state
let currentData = {};
// Load initial data
document.addEventListener('DOMContentLoaded', () => {
refreshData();
});
// Refresh all data
async function refreshData() {
try {
await Promise.all([
loadChainStats(),
loadLatestBlocks()
]);
} catch (error) {
console.error('Error refreshing data:', error);
document.getElementById('node-status').innerHTML = '<span class="text-red-500">Error</span>';
}
}
// Load chain statistics
async function loadChainStats() {
const response = await fetch(`${RPC_URL}/rpc/head`);
const data = await response.json();
document.getElementById('chain-height').textContent = data.height || '-';
document.getElementById('latest-hash').textContent = data.hash ? data.hash.substring(0, 16) + '...' : '-';
document.getElementById('node-status').innerHTML = '<span class="text-green-500">Online</span>';
currentData.head = data;
}
// Load latest blocks
async function loadLatestBlocks() {
const tbody = document.getElementById('blocks-table');
tbody.innerHTML = '<tr><td colspan="5" class="text-center py-8 text-gray-500">Loading blocks...</td></tr>';
const head = await fetch(`${RPC_URL}/rpc/head`).then(r => r.json());
const blocks = [];
// Load last 10 blocks
for (let i = 0; i < 10 && head.height - i >= 0; i++) {
const block = await fetch(`${RPC_URL}/rpc/blocks/${head.height - i}`).then(r => r.json());
blocks.push(block);
}
tbody.innerHTML = blocks.map(block => `
<tr class="border-t hover:bg-gray-50">
<td class="py-3 font-mono">${block.height}</td>
<td class="py-3 font-mono text-sm">${block.hash ? block.hash.substring(0, 16) + '...' : '-'}</td>
<td class="py-3 text-sm">${formatTimestamp(block.timestamp)}</td>
<td class="py-3">${block.transactions ? block.transactions.length : 0}</td>
<td class="py-3">
<button onclick="showBlockDetails(${block.height})" class="text-blue-600 hover:text-blue-800">
View Details
</button>
</td>
</tr>
`).join('');
}
// Show block details
async function showBlockDetails(height) {
const block = await fetch(`${RPC_URL}/rpc/blocks/${height}`).then(r => r.json());
const modal = document.getElementById('block-modal');
const details = document.getElementById('block-details');
details.innerHTML = `
<div class="space-y-6">
<div>
<h3 class="text-lg font-semibold mb-2">Block Header</h3>
<div class="bg-gray-50 rounded p-4 space-y-2">
<div class="flex justify-between">
<span class="text-gray-600">Height:</span>
<span class="font-mono">${block.height}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Hash:</span>
<span class="font-mono text-sm">${block.hash || '-'}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Parent Hash:</span>
<span class="font-mono text-sm">${block.parent_hash || '-'}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Timestamp:</span>
<span>${formatTimestamp(block.timestamp)}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Proposer:</span>
<span class="font-mono text-sm">${block.proposer || '-'}</span>
</div>
</div>
</div>
${block.transactions && block.transactions.length > 0 ? `
<div>
<h3 class="text-lg font-semibold mb-2">Transactions (${block.transactions.length})</h3>
<div class="space-y-2">
${block.transactions.map(tx => `
<div class="bg-gray-50 rounded p-4">
<div class="flex justify-between mb-2">
<span class="text-gray-600">Hash:</span>
<span class="font-mono text-sm">${tx.hash || '-'}</span>
</div>
<div class="flex justify-between mb-2">
<span class="text-gray-600">Type:</span>
<span>${tx.type || '-'}</span>
</div>
<div class="flex justify-between mb-2">
<span class="text-gray-600">From:</span>
<span class="font-mono text-sm">${tx.sender || '-'}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Fee:</span>
<span>${tx.fee || '0'}</span>
</div>
</div>
`).join('')}
</div>
</div>
` : '<p class="text-gray-500">No transactions in this block</p>'}
</div>
`;
modal.classList.remove('hidden');
}
// Close modal
function closeModal() {
document.getElementById('block-modal').classList.add('hidden');
}
// Search functionality
async function search() {
const query = document.getElementById('search-input').value.trim();
if (!query) return;
// Try block height first
if (/^\\d+$/.test(query)) {
showBlockDetails(parseInt(query));
return;
}
// TODO: Add transaction hash search
alert('Search by block height is currently supported');
}
// Format timestamp
function formatTimestamp(timestamp) {
if (!timestamp) return '-';
return new Date(timestamp * 1000).toLocaleString();
}
// Auto-refresh every 30 seconds
setInterval(refreshData, 30000);
</script>
</body>
</html>
EOF
# Install a simple web server
print_status "Installing web server..."
apt-get install -y nginx
# Configure nginx to serve the explorer
print_status "Configuring nginx..."
cat > /etc/nginx/sites-available/blockchain-explorer << EOL
server {
listen 3000;
server_name _;
root /opt/blockchain-explorer;
index index.html;
location / {
try_files \$uri \$uri/ =404;
}
# CORS headers for API access
location /rpc/ {
proxy_pass http://localhost:8082;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
}
}
EOL
# Enable the site
ln -sf /etc/nginx/sites-available/blockchain-explorer /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
# Test and reload nginx
nginx -t
systemctl reload nginx
# Setup port forwarding if in container
if [ "$(hostname)" = "aitbc" ]; then
print_status "Setting up port forwarding..."
iptables -t nat -A PREROUTING -p tcp --dport 3000 -j DNAT --to-destination 192.168.100.10:3000
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 3000 -j MASQUERADE
iptables-save > /etc/iptables/rules.v4
fi
print_status "Checking nginx status..."
systemctl status nginx --no-pager | head -10
print_success "✅ Blockchain explorer deployed!"
echo ""
echo "Explorer URL: http://localhost:3000"
if [ "$(hostname)" = "aitbc" ]; then
echo "External URL: http://aitbc.keisanki.net:3000"
else
echo "External URL: http://aitbc.keisanki.net:3000"
fi
echo ""
echo "The explorer is a static HTML site served by nginx."

View File

@@ -0,0 +1,66 @@
#!/bin/bash
# Deploy AITBC Explorer to the server
set -e
SERVER="root@10.1.223.93"
EXPLORER_DIR="/root/aitbc/apps/explorer-web"
NGINX_CONFIG="/etc/nginx/sites-available/aitbc"
echo "🚀 Deploying AITBC Explorer to Server"
echo "====================================="
echo "Server: $SERVER"
echo ""
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Build the explorer locally first
print_status "Building explorer locally..."
cd /home/oib/windsurf/aitbc/apps/explorer-web
npm run build
# Copy built files to server
print_status "Copying explorer build to server..."
scp -r dist $SERVER:$EXPLORER_DIR/
# Update nginx config to include explorer
print_status "Updating nginx configuration..."
# Backup current config
ssh $SERVER "cp $NGINX_CONFIG ${NGINX_CONFIG}.backup"
# Add explorer location to nginx config
ssh $SERVER "sed -i '/# Health endpoint/i\\
# Explorer\\
location /explorer/ {\\
alias /root/aitbc/apps/explorer-web/dist/;\\
try_files \$uri \$uri/ /explorer/index.html;\\
}\\
\\
# Explorer mock data\\
location /explorer/mock/ {\\
alias /root/aitbc/apps/explorer-web/public/mock/;\\
}\\
' $NGINX_CONFIG"
# Test and reload nginx
print_status "Testing and reloading nginx..."
ssh $SERVER "nginx -t && systemctl reload nginx"
print_status "✅ Explorer deployment complete!"
echo ""
echo "📋 Explorer URL:"
echo " 🌐 Explorer: https://aitbc.bubuit.net/explorer/"
echo ""

View File

@@ -0,0 +1,121 @@
#!/bin/bash
# Deploy the first blockchain node
set -e
echo "🚀 Deploying First Blockchain Node"
echo "================================="
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
NODE1_DIR="/opt/blockchain-node"
# Create configuration for first node
print_status "Creating configuration for first node..."
cat > $NODE1_DIR/.env << EOF
CHAIN_ID=ait-devnet
DB_PATH=./data/chain.db
RPC_BIND_HOST=127.0.0.1
RPC_BIND_PORT=8080
P2P_BIND_HOST=0.0.0.0
P2P_BIND_PORT=7070
PROPOSER_KEY=node1_proposer_key_$(date +%s)
MINT_PER_UNIT=1000
COORDINATOR_RATIO=0.05
GOSSIP_BACKEND=http
GOSSIP_BROADCAST_URL=http://127.0.0.1:7071/gossip
EOF
# Create data directory
mkdir -p $NODE1_DIR/data/devnet
# Generate genesis file
print_status "Generating genesis file..."
cd $NODE1_DIR
export PYTHONPATH="${NODE1_DIR}/src:${NODE1_DIR}/scripts:${PYTHONPATH:-}"
python3 scripts/make_genesis.py --output data/devnet/genesis.json --force
# Create systemd service
print_status "Creating systemd service..."
sudo cat > /etc/systemd/system/blockchain-node.service << EOF
[Unit]
Description=AITBC Blockchain Node 1
After=network.target
[Service]
Type=exec
User=root
WorkingDirectory=$NODE1_DIR
Environment=PATH=$NODE1_DIR/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=$NODE1_DIR/src:$NODE1_DIR/scripts
ExecStart=$NODE1_DIR/.venv/bin/python3 -m aitbc_chain.main
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
# Create RPC API service
print_status "Creating RPC API service..."
sudo cat > /etc/systemd/system/blockchain-rpc.service << EOF
[Unit]
Description=AITBC Blockchain RPC API 1
After=blockchain-node.service
[Service]
Type=exec
User=root
WorkingDirectory=$NODE1_DIR
Environment=PATH=$NODE1_DIR/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=$NODE1_DIR/src:$NODE1_DIR/scripts
ExecStart=$NODE1_DIR/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8080
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
# Setup Python environment if not exists
if [ ! -d "$NODE1_DIR/.venv" ]; then
print_status "Setting up Python environment..."
cd $NODE1_DIR
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e .
fi
# Enable and start services
print_status "Enabling and starting services..."
sudo systemctl daemon-reload
sudo systemctl enable blockchain-node blockchain-rpc
sudo systemctl start blockchain-node blockchain-rpc
# Check status
print_status "Checking service status..."
sudo systemctl status blockchain-node --no-pager -l
sudo systemctl status blockchain-rpc --no-pager -l
echo ""
print_status "✅ First blockchain node deployed!"
echo ""
echo "Node 1 RPC: http://127.0.0.1:8080"
echo "Node 2 RPC: http://127.0.0.1:8081"
echo ""
echo "To check logs:"
echo " Node 1: sudo journalctl -u blockchain-node -f"
echo " Node 2: sudo journalctl -u blockchain-node-2 -f"

View File

@@ -0,0 +1,306 @@
#!/bin/bash
# Deploy blockchain node and explorer inside the container
set -e
echo "🚀 Deploying Inside Container"
echo "============================"
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Check if we're in the container
if [ ! -f /proc/1/environ ] || ! grep -q container=lxc /proc/1/environ 2>/dev/null; then
if [ "$(hostname)" != "aitbc" ]; then
print_warning "This script must be run inside the aitbc container"
exit 1
fi
fi
# Stop existing services
print_status "Stopping existing services..."
systemctl stop blockchain-node blockchain-rpc nginx 2>/dev/null || true
# Install dependencies
print_status "Installing dependencies..."
apt-get update
apt-get install -y python3 python3-venv python3-pip git curl nginx
# Deploy blockchain node
print_status "Deploying blockchain node..."
cd /opt
rm -rf blockchain-node
# The source is already in blockchain-node-src, copy it properly
cp -r blockchain-node-src blockchain-node
cd blockchain-node
# Check if pyproject.toml exists
if [ ! -f pyproject.toml ]; then
print_warning "pyproject.toml not found, looking for it..."
find . -name "pyproject.toml" -type f
# If it's in a subdirectory, move everything up
if [ -f blockchain-node-src/pyproject.toml ]; then
print_status "Moving files from nested directory..."
mv blockchain-node-src/* .
rmdir blockchain-node-src
fi
fi
# Create configuration
print_status "Creating configuration..."
cat > .env << EOL
CHAIN_ID=ait-devnet
DB_PATH=./data/chain.db
RPC_BIND_HOST=0.0.0.0
RPC_BIND_PORT=8082
P2P_BIND_HOST=0.0.0.0
P2P_BIND_PORT=7070
PROPOSER_KEY=proposer_key_$(date +%s)
MINT_PER_UNIT=1000
COORDINATOR_RATIO=0.05
GOSSIP_BACKEND=memory
EOL
# Create fresh data directory
rm -rf data
mkdir -p data/devnet
# Setup Python environment
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e .
# Generate genesis
export PYTHONPATH="${PWD}/src:${PWD}/scripts:${PYTHONPATH:-}"
python scripts/make_genesis.py --output data/devnet/genesis.json --force
# Create systemd services
print_status "Creating systemd services..."
cat > /etc/systemd/system/blockchain-node.service << EOL
[Unit]
Description=AITBC Blockchain Node
After=network.target
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m aitbc_chain.main
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
cat > /etc/systemd/system/blockchain-rpc.service << EOL
[Unit]
Description=AITBC Blockchain RPC API
After=blockchain-node.service
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8082
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
# Start blockchain services
print_status "Starting blockchain services..."
systemctl daemon-reload
systemctl enable blockchain-node blockchain-rpc
systemctl start blockchain-node blockchain-rpc
# Deploy explorer
print_status "Deploying blockchain explorer..."
cd /opt
rm -rf blockchain-explorer
mkdir -p blockchain-explorer
cd blockchain-explorer
# Create HTML explorer
cat > index.html << 'EOF'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AITBC Blockchain Explorer</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/lucide@latest"></script>
</head>
<body class="bg-gray-50">
<header class="bg-blue-600 text-white shadow-lg">
<div class="container mx-auto px-4 py-4">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-3">
<i data-lucide="cube" class="w-8 h-8"></i>
<h1 class="text-2xl font-bold">AITBC Blockchain Explorer</h1>
</div>
<button onclick="refreshData()" class="bg-blue-500 hover:bg-blue-400 px-3 py-1 rounded flex items-center space-x-1">
<i data-lucide="refresh-cw" class="w-4 h-4"></i>
<span>Refresh</span>
</button>
</div>
</div>
</header>
<main class="container mx-auto px-4 py-8">
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm">Current Height</p>
<p class="text-2xl font-bold" id="chain-height">-</p>
</div>
<i data-lucide="trending-up" class="w-10 h-10 text-green-500"></i>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm">Latest Block</p>
<p class="text-lg font-mono" id="latest-hash">-</p>
</div>
<i data-lucide="hash" class="w-10 h-10 text-blue-500"></i>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm">Node Status</p>
<p class="text-lg font-semibold" id="node-status">-</p>
</div>
<i data-lucide="activity" class="w-10 h-10 text-purple-500"></i>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b">
<h2 class="text-xl font-semibold flex items-center">
<i data-lucide="blocks" class="w-5 h-5 mr-2"></i>
Latest Blocks
</h2>
</div>
<div class="p-6">
<table class="w-full">
<thead>
<tr class="text-left text-gray-500 text-sm">
<th class="pb-3">Height</th>
<th class="pb-3">Hash</th>
<th class="pb-3">Timestamp</th>
<th class="pb-3">Transactions</th>
</tr>
</thead>
<tbody id="blocks-table">
<tr>
<td colspan="4" class="text-center py-8 text-gray-500">
Loading blocks...
</td>
</tr>
</tbody>
</table>
</div>
</div>
</main>
<script>
lucide.createIcons();
const RPC_URL = 'http://localhost:8082';
async function refreshData() {
try {
const response = await fetch(`${RPC_URL}/rpc/head`);
const head = await response.json();
document.getElementById('chain-height').textContent = head.height || '-';
document.getElementById('latest-hash').textContent = head.hash ? head.hash.substring(0, 16) + '...' : '-';
document.getElementById('node-status').innerHTML = '<span class="text-green-500">Online</span>';
// Load last 10 blocks
const tbody = document.getElementById('blocks-table');
tbody.innerHTML = '';
for (let i = 0; i < 10 && head.height - i >= 0; i++) {
const blockResponse = await fetch(`${RPC_URL}/rpc/blocks/${head.height - i}`);
const block = await blockResponse.json();
const row = tbody.insertRow();
row.innerHTML = `
<td class="py-3 font-mono">${block.height}</td>
<td class="py-3 font-mono text-sm">${block.hash ? block.hash.substring(0, 16) + '...' : '-'}</td>
<td class="py-3 text-sm">${new Date(block.timestamp * 1000).toLocaleString()}</td>
<td class="py-3">${block.transactions ? block.transactions.length : 0}</td>
`;
}
} catch (error) {
console.error('Error:', error);
document.getElementById('node-status').innerHTML = '<span class="text-red-500">Error</span>';
}
}
refreshData();
setInterval(refreshData, 30000);
</script>
</body>
</html>
EOF
# Configure nginx
print_status "Configuring nginx..."
cat > /etc/nginx/sites-available/blockchain-explorer << EOL
server {
listen 3000;
server_name _;
root /opt/blockchain-explorer;
index index.html;
location / {
try_files \$uri \$uri/ =404;
}
}
EOL
ln -sf /etc/nginx/sites-available/blockchain-explorer /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
nginx -t
systemctl reload nginx
# Wait for services to start
print_status "Waiting for services to start..."
sleep 5
# Check services
print_status "Checking service status..."
systemctl status blockchain-node blockchain-rpc nginx --no-pager | grep -E 'Active:|Main PID:'
print_success "✅ Deployment complete in container!"
echo ""
echo "Services:"
echo " - Blockchain Node RPC: http://localhost:8082"
echo " - Blockchain Explorer: http://localhost:3000"
echo ""
echo "These are accessible from the host via port forwarding."

View File

@@ -0,0 +1,56 @@
#!/bin/bash
# Deploy Modern Blockchain Explorer
set -e
echo "🚀 Deploying Modern Blockchain Explorer"
echo "======================================"
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Stop existing services
print_status "Stopping existing services..."
systemctl stop nginx 2>/dev/null || true
# Create directory
print_status "Creating explorer directory..."
rm -rf /opt/blockchain-explorer
mkdir -p /opt/blockchain-explorer/assets
# Copy files
print_status "Copying explorer files..."
cp -r /opt/blockchain-node-src/apps/blockchain-explorer/* /opt/blockchain-explorer/
# Update nginx configuration
print_status "Updating nginx configuration..."
cp /opt/blockchain-explorer/nginx.conf /etc/nginx/sites-available/blockchain-explorer
ln -sf /etc/nginx/sites-available/blockchain-explorer /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
# Test and start nginx
print_status "Starting nginx..."
nginx -t
systemctl start nginx
print_success "✅ Modern explorer deployed!"
echo ""
echo "Access URLs:"
echo " - Explorer: http://localhost:3000/"
echo " - API: http://localhost:3000/api/v1/"
echo ""
echo "Standardized API Endpoints:"
echo " - GET /api/v1/chain/head"
echo " - GET /api/v1/chain/blocks?limit=N"
echo " - GET /api/v1/chain/blocks/{height}"

View File

@@ -0,0 +1,160 @@
#!/bin/bash
# Deploy nginx reverse proxy for AITBC services
# This replaces firehol/iptables port forwarding with nginx reverse proxy
set -e
echo "🚀 Deploying Nginx Reverse Proxy for AITBC"
echo "=========================================="
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if we're on the host server
if ! grep -q "ns3-root" ~/.ssh/config 2>/dev/null; then
print_error "ns3-root SSH configuration not found. Please add it to ~/.ssh/config"
exit 1
fi
# Install nginx on host if not already installed
print_status "Checking nginx installation on host..."
ssh ns3-root "which nginx > /dev/null || (apt-get update && apt-get install -y nginx)"
# Install certbot for SSL certificates
print_status "Checking certbot installation..."
ssh ns3-root "which certbot > /dev/null || (apt-get update && apt-get install -y certbot python3-certbot-nginx)"
# Copy nginx configuration
print_status "Copying nginx configuration..."
scp infra/nginx/nginx-aitbc-reverse-proxy.conf ns3-root:/tmp/aitbc-reverse-proxy.conf
# Backup existing nginx configuration
print_status "Backing up existing nginx configuration..."
ssh ns3-root "mkdir -p /etc/nginx/backup && cp -r /etc/nginx/sites-available/* /etc/nginx/backup/ 2>/dev/null || true"
# Install the new configuration
print_status "Installing nginx reverse proxy configuration..."
ssh ns3-root << 'EOF'
# Remove existing configurations
rm -f /etc/nginx/sites-enabled/default
rm -f /etc/nginx/sites-available/aitbc*
# Copy new configuration
cp /tmp/aitbc-reverse-proxy.conf /etc/nginx/sites-available/aitbc-reverse-proxy.conf
# Create symbolic link
ln -sf /etc/nginx/sites-available/aitbc-reverse-proxy.conf /etc/nginx/sites-enabled/
# Test nginx configuration
nginx -t
EOF
# Check if SSL certificate exists
print_status "Checking SSL certificate..."
if ! ssh ns3-root "test -f /etc/letsencrypt/live/aitbc.keisanki.net/fullchain.pem"; then
print_warning "SSL certificate not found. Obtaining Let's Encrypt certificate..."
# Obtain SSL certificate
ssh ns3-root << 'EOF'
# Stop nginx temporarily
systemctl stop nginx 2>/dev/null || true
# Obtain certificate
certbot certonly --standalone -d aitbc.keisanki.net -d api.aitbc.keisanki.net -d rpc.aitbc.keisanki.net --email admin@keisanki.net --agree-tos --non-interactive
# Start nginx
systemctl start nginx
EOF
if [ $? -ne 0 ]; then
print_error "Failed to obtain SSL certificate. Please run certbot manually:"
echo "certbot certonly --standalone -d aitbc.keisanki.net -d api.aitbc.keisanki.net -d rpc.aitbc.keisanki.net"
exit 1
fi
fi
# Restart nginx
print_status "Restarting nginx..."
ssh ns3-root "systemctl restart nginx && systemctl enable nginx"
# Remove old iptables rules (optional)
print_warning "Removing old iptables port forwarding rules (if they exist)..."
ssh ns3-root << 'EOF'
# Flush existing NAT rules for AITBC ports
iptables -t nat -D PREROUTING -p tcp --dport 8000 -j DNAT --to-destination 192.168.100.10:8000 2>/dev/null || true
iptables -t nat -D POSTROUTING -p tcp -d 192.168.100.10 --dport 8000 -j MASQUERADE 2>/dev/null || true
iptables -t nat -D PREROUTING -p tcp --dport 8081 -j DNAT --to-destination 192.168.100.10:8081 2>/dev/null || true
iptables -t nat -D POSTROUTING -p tcp -d 192.168.100.10 --dport 8081 -j MASQUERADE 2>/dev/null || true
iptables -t nat -D PREROUTING -p tcp --dport 8082 -j DNAT --to-destination 192.168.100.10:8082 2>/dev/null || true
iptables -t nat -D POSTROUTING -p tcp -d 192.168.100.10 --dport 8082 -j MASQUERADE 2>/dev/null || true
iptables -t nat -D PREROUTING -p tcp --dport 9080 -j DNAT --to-destination 192.168.100.10:9080 2>/dev/null || true
iptables -t nat -D POSTROUTING -p tcp -d 192.168.100.10 --dport 9080 -j MASQUERADE 2>/dev/null || true
iptables -t nat -D PREROUTING -p tcp --dport 3000 -j DNAT --to-destination 192.168.100.10:3000 2>/dev/null || true
iptables -t nat -D POSTROUTING -p tcp -d 192.168.100.10 --dport 3000 -j MASQUERADE 2>/dev/null || true
# Save iptables rules
iptables-save > /etc/iptables/rules.v4 2>/dev/null || true
EOF
# Wait for nginx to start
sleep 2
# Test the configuration
print_status "Testing reverse proxy configuration..."
echo ""
# Test main domain
if curl -s -o /dev/null -w "%{http_code}" https://aitbc.keisanki.net/health | grep -q "200"; then
print_status "✅ Main domain (aitbc.keisanki.net) - OK"
else
print_error "❌ Main domain (aitbc.keisanki.net) - FAILED"
fi
# Test API endpoint
if curl -s -o /dev/null -w "%{http_code}" https://aitbc.keisanki.net/api/health | grep -q "200"; then
print_status "✅ API endpoint - OK"
else
print_warning "⚠️ API endpoint - Not responding (service may not be running)"
fi
# Test RPC endpoint
if curl -s -o /dev/null -w "%{http_code}" https://aitbc.keisanki.net/rpc/head | grep -q "200"; then
print_status "✅ RPC endpoint - OK"
else
print_warning "⚠️ RPC endpoint - Not responding (blockchain node may not be running)"
fi
echo ""
print_status "🎉 Nginx reverse proxy deployment complete!"
echo ""
echo "Service URLs:"
echo " • Blockchain Explorer: https://aitbc.keisanki.net"
echo " • API: https://aitbc.keisanki.net/api/"
echo " • RPC: https://aitbc.keisanki.net/rpc/"
echo " • Exchange: https://aitbc.keisanki.net/exchange/"
echo ""
echo "Alternative URLs:"
echo " • API-only: https://api.aitbc.keisanki.net"
echo " • RPC-only: https://rpc.aitbc.keisanki.net"
echo ""
echo "Note: Make sure all services are running in the container:"
echo " • blockchain-explorer.service (port 3000)"
echo " • coordinator-api.service (port 8000)"
echo " • blockchain-rpc.service (port 8082)"
echo " • aitbc-exchange.service (port 9080)"

View File

@@ -0,0 +1,55 @@
#!/bin/bash
echo "🚀 Deploying AITBC for Production..."
# 1. Setup production assets
echo "📦 Setting up production assets..."
bash setup-production-assets.sh
# 2. Copy assets to server
echo "📋 Copying assets to server..."
scp -r assets/ aitbc:/var/www/html/
# 3. Update Nginx configuration
echo "⚙️ Updating Nginx configuration..."
ssh aitbc "cat >> /etc/nginx/sites-available/aitbc.conf << 'EOF'
# Serve production assets
location /assets/ {
alias /var/www/html/assets/;
expires 1y;
add_header Cache-Control \"public, immutable\";
add_header X-Content-Type-Options nosniff;
# Gzip compression
gzip on;
gzip_types text/css application/javascript image/svg+xml;
}
# Security headers
add_header Referrer-Policy \"strict-origin-when-cross-origin\" always;
add_header X-Frame-Options \"SAMEORIGIN\" always;
add_header X-Content-Type-Options \"nosniff\" always;
EOF"
# 4. Reload Nginx
echo "🔄 Reloading Nginx..."
ssh aitbc "nginx -t && systemctl reload nginx"
# 5. Update Exchange page to use production assets
echo "🔄 Updating Exchange page..."
scp apps/trade-exchange/index.prod.html aitbc:/root/aitbc/apps/trade-exchange/index.html
# 6. Update Marketplace page
echo "🔄 Updating Marketplace page..."
sed -i 's|https://cdn.tailwindcss.com|/assets/js/tailwind.js|g' apps/marketplace-ui/index.html
sed -i 's|https://unpkg.com/axios/dist/axios.min.js|/assets/js/axios.min.js|g' apps/marketplace-ui/index.html
sed -i 's|https://unpkg.com/lucide@latest|/assets/js/lucide.js|g' apps/marketplace-ui/index.html
scp apps/marketplace-ui/index.html aitbc:/root/aitbc/apps/marketplace-ui/
echo "✅ Production deployment complete!"
echo ""
echo "📝 Next steps:"
echo "1. Restart services: ssh aitbc 'systemctl restart aitbc-exchange aitbc-marketplace-ui'"
echo "2. Clear browser cache"
echo "3. Test all pages"

View File

@@ -0,0 +1,18 @@
#!/bin/bash
# Deploy blockchain node by building directly on ns3 server
echo "🚀 Remote Blockchain Deployment (Build on Server)"
echo "=============================================="
# Copy deployment script to server
echo "Copying deployment script to ns3..."
scp scripts/deploy/deploy-blockchain-remote.sh ns3-root:/opt/
# Execute deployment on server
echo "Executing deployment on ns3 (utilizing gigabit connection)..."
ssh ns3-root "cd /opt && chmod +x deploy-blockchain-remote.sh && ./deploy-blockchain-remote.sh"
echo ""
echo "Deployment complete!"
echo "The blockchain node was built directly on ns3 using its fast connection."

View File

@@ -0,0 +1,127 @@
#!/bin/bash
# Deploy a second blockchain node on the same server
set -e
echo "🚀 Deploying Second Blockchain Node"
echo "=================================="
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Create directory for second node
print_status "Creating directory for second node..."
NODE2_DIR="/opt/blockchain-node-2"
sudo mkdir -p $NODE2_DIR
sudo chown $USER:$USER $NODE2_DIR
# Copy blockchain node code
print_status "Copying blockchain node code..."
cp -r /opt/blockchain-node/* $NODE2_DIR/
# Create configuration for second node
print_status "Creating configuration for second node..."
cat > $NODE2_DIR/.env << EOF
CHAIN_ID=ait-devnet
DB_PATH=./data/chain2.db
RPC_BIND_HOST=127.0.0.1
RPC_BIND_PORT=8081
P2P_BIND_HOST=0.0.0.0
P2P_BIND_PORT=7071
PROPOSER_KEY=node2_proposer_key_$(date +%s)
MINT_PER_UNIT=1000
COORDINATOR_RATIO=0.05
GOSSIP_BACKEND=http
GOSSIP_BROADCAST_URL=http://127.0.0.1:7070/gossip
EOF
# Create data directory
mkdir -p $NODE2_DIR/data/devnet
# Generate genesis file (same as first node)
print_status "Generating genesis file..."
cd $NODE2_DIR
export PYTHONPATH="${NODE2_DIR}/src:${NODE2_DIR}/scripts:${PYTHONPATH:-}"
python3 scripts/make_genesis.py --output data/devnet/genesis.json --force
# Create systemd service
print_status "Creating systemd service..."
sudo cat > /etc/systemd/system/blockchain-node-2.service << EOF
[Unit]
Description=AITBC Blockchain Node 2
After=network.target
[Service]
Type=exec
User=root
WorkingDirectory=$NODE2_DIR
Environment=PATH=$NODE2_DIR/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=$NODE2_DIR/src:$NODE2_DIR/scripts
ExecStart=$NODE2_DIR/.venv/bin/python3 -m aitbc_chain.main
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
# Create RPC API service
print_status "Creating RPC API service..."
sudo cat > /etc/systemd/system/blockchain-rpc-2.service << EOF
[Unit]
Description=AITBC Blockchain RPC API 2
After=blockchain-node-2.service
[Service]
Type=exec
User=root
WorkingDirectory=$NODE2_DIR
Environment=PATH=$NODE2_DIR/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=$NODE2_DIR/src:$NODE2_DIR/scripts
ExecStart=$NODE2_DIR/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8081
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
# Setup Python environment
print_status "Setting up Python environment..."
cd $NODE2_DIR
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e .
# Enable and start services
print_status "Enabling and starting services..."
sudo systemctl daemon-reload
sudo systemctl enable blockchain-node-2 blockchain-rpc-2
sudo systemctl start blockchain-node-2 blockchain-rpc-2
# Check status
print_status "Checking service status..."
sudo systemctl status blockchain-node-2 --no-pager -l
sudo systemctl status blockchain-rpc-2 --no-pager -l
echo ""
print_status "✅ Second blockchain node deployed!"
echo ""
echo "Node 1 RPC: http://127.0.0.1:8080"
echo "Node 2 RPC: http://127.0.0.1:8081"
echo ""
echo "To check logs:"
echo " Node 1: sudo journalctl -u blockchain-node -f"
echo " Node 2: sudo journalctl -u blockchain-node-2 -f"

View File

@@ -0,0 +1,84 @@
#!/bin/bash
# Deploy blockchain node inside incus container aitbc
set -e
echo "🚀 AITBC Deployment in Incus Container"
echo "======================================"
echo "This will deploy inside the aitbc container"
echo ""
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Check if we're on ns3 host
if [ "$(hostname)" != "ns3" ]; then
print_warning "This script must be run on ns3 host"
echo "Run: ssh ns3-root"
exit 1
fi
# Check if container exists
if ! incus list | grep -q "aitbc.*RUNNING"; then
print_warning "Container aitbc is not running"
exit 1
fi
# Copy source to container
print_status "Copying source code to container..."
incus exec aitbc -- rm -rf /opt/blockchain-node-src 2>/dev/null || true
incus exec aitbc -- mkdir -p /opt/blockchain-node-src
# Use the source already on the server
incus file push -r /opt/blockchain-node-src/. aitbc/opt/blockchain-node-src/
# Fix the nested directory issue - move everything up one level
incus exec aitbc -- sh -c 'if [ -d /opt/blockchain-node-src/blockchain-node-src ]; then mv /opt/blockchain-node-src/blockchain-node-src/* /opt/blockchain-node-src/ && rmdir /opt/blockchain-node-src/blockchain-node-src; fi'
# Copy deployment script to container
print_status "Copying deployment script to container..."
incus file push /opt/deploy-in-container.sh aitbc/opt/
# Execute deployment inside container
print_status "Deploying inside container..."
incus exec aitbc -- bash /opt/deploy-in-container.sh
# Setup port forwarding on host
print_status "Setting up port forwarding on host..."
iptables -t nat -F PREROUTING 2>/dev/null || true
iptables -t nat -F POSTROUTING 2>/dev/null || true
# Forward blockchain RPC
iptables -t nat -A PREROUTING -p tcp --dport 8082 -j DNAT --to-destination 192.168.100.10:8082
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 8082 -j MASQUERADE
# Forward explorer
iptables -t nat -A PREROUTING -p tcp --dport 3000 -j DNAT --to-destination 192.168.100.10:3000
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 3000 -j MASQUERADE
# Save rules
mkdir -p /etc/iptables
iptables-save > /etc/iptables/rules.v4
# Check services
print_status "Checking services in container..."
incus exec aitbc -- systemctl status blockchain-node blockchain-rpc nginx --no-pager | grep -E 'Active:|Main PID:'
print_success "✅ Deployment complete!"
echo ""
echo "Services in container aitbc:"
echo " - Blockchain Node RPC: http://192.168.100.10:8082"
echo " - Blockchain Explorer: http://192.168.100.10:3000"
echo ""
echo "External access via ns3:"
echo " - Blockchain Node RPC: http://aitbc.keisanki.net:8082"
echo " - Blockchain Explorer: http://aitbc.keisanki.net:3000"

View File

@@ -0,0 +1,253 @@
#!/bin/bash
# AITBC Services Deployment to Incus Container
# This script deploys all AITBC services to the 'aitbc' container
set -e
CONTAINER_NAME="aitbc"
CONTAINER_IP="10.1.223.93"
PROJECT_DIR="/home/oib/windsurf/aitbc"
echo "🚀 Deploying AITBC services to container: $CONTAINER_NAME"
echo "Container IP: $CONTAINER_IP"
echo ""
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Function to print colored output
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Stop local services
print_status "Stopping local AITBC services..."
sudo fuser -k 8000/tcp 2>/dev/null || true
sudo fuser -k 9080/tcp 2>/dev/null || true
sudo fuser -k 3001/tcp 2>/dev/null || true
sudo fuser -k 3002/tcp 2>/dev/null || true
pkill -f "aitbc_chain.app" 2>/dev/null || true
pkill -f "marketplace-ui" 2>/dev/null || true
pkill -f "trade-exchange" 2>/dev/null || true
# Copy project to container
print_status "Copying AITBC project to container..."
incus file push -r $PROJECT_DIR $CONTAINER_NAME/home/oib/
# Setup container environment
print_status "Setting up container environment..."
incus exec $CONTAINER_NAME -- bash -c "
cd /home/oib/aitbc
python -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
"
# Install dependencies for each service
print_status "Installing dependencies..."
# Coordinator API
print_status "Installing Coordinator API dependencies..."
incus exec $CONTAINER_NAME -- bash -c "
cd /home/oib/aitbc/apps/coordinator-api
source ../.venv/bin/activate
pip install -e .
pip install fastapi uvicorn
"
# Blockchain Node
print_status "Installing Blockchain Node dependencies..."
incus exec $CONTAINER_NAME -- bash -c "
cd /home/oib/aitbc/apps/blockchain-node
source ../.venv/bin/activate
pip install -e .
pip install fastapi uvicorn
"
# Create systemd service files
print_status "Creating systemd services..."
# Coordinator API service
incus exec $CONTAINER_NAME -- tee /etc/systemd/system/aitbc-coordinator.service > /dev/null <<EOF
[Unit]
Description=AITBC Coordinator API
After=network.target
[Service]
Type=exec
User=oib
Group=oib
WorkingDirectory=/home/oib/aitbc/apps/coordinator-api
Environment=PATH=/home/oib/aitbc/.venv/bin
ExecStart=/home/oib/aitbc/.venv/bin/python -m uvicorn src.app.main:app --host 0.0.0.0 --port 8000
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
# Blockchain Node service
incus exec $CONTAINER_NAME -- tee /etc/systemd/system/aitbc-blockchain.service > /dev/null <<EOF
[Unit]
Description=AITBC Blockchain Node
After=network.target
[Service]
Type=exec
User=oib
Group=oib
WorkingDirectory=/home/oib/aitbc/apps/blockchain-node
Environment=PATH=/home/oib/aitbc/.venv/bin
ExecStart=/home/oib/aitbc/.venv/bin/python -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 9080
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
# Marketplace UI service
incus exec $CONTAINER_NAME -- tee /etc/systemd/system/aitbc-marketplace.service > /dev/null <<EOF
[Unit]
Description=AITBC Marketplace UI
After=network.target
[Service]
Type=exec
User=oib
Group=oib
WorkingDirectory=/home/oib/aitbc/apps/marketplace-ui
Environment=PATH=/home/oib/aitbc/.venv/bin
ExecStart=/home/oib/aitbc/.venv/bin/python server.py --port 3001
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
# Trade Exchange service
incus exec $CONTAINER_NAME -- tee /etc/systemd/system/aitbc-exchange.service > /dev/null <<EOF
[Unit]
Description=AITBC Trade Exchange
After=network.target
[Service]
Type=exec
User=oib
Group=oib
WorkingDirectory=/home/oib/aitbc/apps/trade-exchange
Environment=PATH=/home/oib/aitbc/.venv/bin
ExecStart=/home/oib/aitbc/.venv/bin/python server.py --port 3002
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
# Reload systemd and start services
print_status "Starting AITBC services..."
incus exec $CONTAINER_NAME -- systemctl daemon-reload
incus exec $CONTAINER_NAME -- systemctl enable aitbc-coordinator
incus exec $CONTAINER_NAME -- systemctl enable aitbc-blockchain
incus exec $CONTAINER_NAME -- systemctl enable aitbc-marketplace
incus exec $CONTAINER_NAME -- systemctl enable aitbc-exchange
incus exec $CONTAINER_NAME -- systemctl start aitbc-coordinator
incus exec $CONTAINER_NAME -- systemctl start aitbc-blockchain
incus exec $CONTAINER_NAME -- systemctl start aitbc-marketplace
incus exec $CONTAINER_NAME -- systemctl start aitbc-exchange
# Wait for services to start
print_status "Waiting for services to start..."
sleep 10
# Check service status
print_status "Checking service status..."
incus exec $CONTAINER_NAME -- systemctl status aitbc-coordinator --no-pager -l
incus exec $CONTAINER_NAME -- systemctl status aitbc-blockchain --no-pager -l
incus exec $CONTAINER_NAME -- systemctl status aitbc-marketplace --no-pager -l
incus exec $CONTAINER_NAME -- systemctl status aitbc-exchange --no-pager -l
# Create nginx configuration for reverse proxy
print_status "Setting up Nginx reverse proxy..."
incus exec $CONTAINER_NAME -- tee /etc/nginx/sites-available/aitbc > /dev/null <<EOF
server {
listen 80;
server_name _;
# Coordinator API
location /api/ {
proxy_pass http://127.0.0.1:8000/v1/;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
# Blockchain RPC
location /rpc/ {
proxy_pass http://127.0.0.1:9080/rpc/;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
# Marketplace UI
location /marketplace/ {
proxy_pass http://127.0.0.1:3001/;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
# Trade Exchange
location /exchange/ {
proxy_pass http://127.0.0.1:3002/;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
# Default redirect to marketplace
location / {
return 301 /marketplace/;
}
}
EOF
# Enable nginx site
incus exec $CONTAINER_NAME -- ln -sf /etc/nginx/sites-available/aitbc /etc/nginx/sites-enabled/
incus exec $CONTAINER_NAME -- rm -f /etc/nginx/sites-enabled/default
incus exec $CONTAINER_NAME -- nginx -t && incus exec $CONTAINER_NAME -- systemctl reload nginx
# Print access information
echo ""
print_status "✅ AITBC services deployed successfully!"
echo ""
echo "📋 Service URLs:"
echo " 🌐 Public IP: $CONTAINER_IP"
echo " 📊 Marketplace: http://$CONTAINER_IP/marketplace/"
echo " 💱 Trade Exchange: http://$CONTAINER_IP/exchange/"
echo " 🔗 API: http://$CONTAINER_IP/api/"
echo " ⛓️ Blockchain RPC: http://$CONTAINER_IP/rpc/"
echo ""
print_status "To check logs: incus exec $CONTAINER_NAME -- journalctl -u aitbc-coordinator -f"
print_status "To restart services: incus exec $CONTAINER_NAME -- systemctl restart aitbc-*"

View File

@@ -0,0 +1,241 @@
#!/bin/bash
# Deploy AITBC services to the aitbc server (10.1.223.93)
set -e
SERVER="root@10.1.223.93"
PROJECT_DIR="/root/aitbc"
echo "🚀 Deploying AITBC to Server"
echo "=========================="
echo "Server: $SERVER"
echo ""
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Test SSH connection
print_status "Testing SSH connection..."
ssh $SERVER "hostname && ip a show eth0 | grep inet"
# Copy project to server
print_status "Copying project to server..."
ssh $SERVER "rm -rf $PROJECT_DIR 2>/dev/null || true"
scp -r /home/oib/windsurf/aitbc $SERVER:/root/
# Setup Python environment
print_status "Setting up Python environment..."
ssh $SERVER "cd $PROJECT_DIR && python3 -m venv .venv && source .venv/bin/activate && pip install --upgrade pip"
# Install dependencies
print_status "Installing dependencies..."
ssh $SERVER "cd $PROJECT_DIR/apps/coordinator-api && source ../../.venv/bin/activate && pip install -e ."
ssh $SERVER "cd $PROJECT_DIR/apps/blockchain-node && source ../../.venv/bin/activate && pip install -e ."
# Create systemd service files
print_status "Creating systemd services..."
# Coordinator API service
ssh $SERVER 'cat > /etc/systemd/system/aitbc-coordinator.service << EOF
[Unit]
Description=AITBC Coordinator API
After=network.target
[Service]
Type=exec
User=root
WorkingDirectory=/root/aitbc/apps/coordinator-api
Environment=PATH=/root/aitbc/.venv/bin
ExecStart=/root/aitbc/.venv/bin/python -m uvicorn src.app.main:app --host 0.0.0.0 --port 8000
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF'
# Blockchain Node service
ssh $SERVER 'cat > /etc/systemd/system/aitbc-blockchain.service << EOF
[Unit]
Description=AITBC Blockchain Node
After=network.target
[Service]
Type=exec
User=root
WorkingDirectory=/root/aitbc/apps/blockchain-node
Environment=PATH=/root/aitbc/.venv/bin
ExecStart=/root/aitbc/.venv/bin/python -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 9080
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF'
# Marketplace UI service
ssh $SERVER 'cat > /etc/systemd/system/aitbc-marketplace.service << EOF
[Unit]
Description=AITBC Marketplace UI
After=network.target
[Service]
Type=exec
User=root
WorkingDirectory=/root/aitbc/apps/marketplace-ui
Environment=PATH=/root/aitbc/.venv/bin
ExecStart=/root/aitbc/.venv/bin/python server.py --port 3001
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF'
# Trade Exchange service
ssh $SERVER 'cat > /etc/systemd/system/aitbc-exchange.service << EOF
[Unit]
Description=AITBC Trade Exchange
After=network.target
[Service]
Type=exec
User=root
WorkingDirectory=/root/aitbc/apps/trade-exchange
Environment=PATH=/root/aitbc/.venv/bin
ExecStart=/root/aitbc/.venv/bin/python server.py --port 3002
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF'
# Install nginx if not installed
print_status "Installing nginx..."
ssh $SERVER "apt update && apt install -y nginx"
# Create nginx configuration
print_status "Configuring nginx..."
ssh $SERVER 'cat > /etc/nginx/sites-available/aitbc << EOF
server {
listen 80;
server_name aitbc.bubuit.net;
# API routes
location /api/ {
proxy_pass http://127.0.0.1:8000/v1/;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
# Admin routes
location /admin/ {
proxy_pass http://127.0.0.1:8000/admin/;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
# Blockchain RPC
location /rpc/ {
proxy_pass http://127.0.0.1:9080/rpc/;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
# Marketplace UI
location /Marketplace {
proxy_pass http://127.0.0.1:3001/;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
# Trade Exchange
location /Exchange {
proxy_pass http://127.0.0.1:3002/;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
# Health endpoint
location /health {
proxy_pass http://127.0.0.1:8000/v1/health;
proxy_set_header Host \$host;
}
# Default redirect
location / {
return 301 /Marketplace;
}
}
EOF'
# Enable nginx site
ssh $SERVER "ln -sf /etc/nginx/sites-available/aitbc /etc/nginx/sites-enabled/"
ssh $SERVER "rm -f /etc/nginx/sites-enabled/default"
# Test and reload nginx
ssh $SERVER "nginx -t && systemctl reload nginx"
# Start services
print_status "Starting AITBC services..."
ssh $SERVER "systemctl daemon-reload"
ssh $SERVER "systemctl enable aitbc-coordinator aitbc-blockchain aitbc-marketplace aitbc-exchange"
ssh $SERVER "systemctl start aitbc-coordinator aitbc-blockchain aitbc-marketplace aitbc-exchange"
# Wait for services to start
print_status "Waiting for services to start..."
sleep 10
# Check service status
print_status "Checking service status..."
ssh $SERVER "systemctl status aitbc-coordinator --no-pager -l | head -10"
ssh $SERVER "systemctl status aitbc-blockchain --no-pager -l | head -10"
# Test endpoints
print_status "Testing endpoints..."
ssh $SERVER "curl -s http://127.0.0.1:8000/v1/health | head -c 100"
echo ""
ssh $SERVER "curl -s http://127.0.0.1:8000/v1/admin/stats -H 'X-Api-Key: ${ADMIN_API_KEY}' | head -c 100"
echo ""
echo ""
print_status "✅ Deployment complete!"
echo ""
echo "📋 Service URLs:"
echo " 🌐 Server IP: 10.1.223.93"
echo " 📊 Marketplace: http://10.1.223.93/Marketplace"
echo " 💱 Trade Exchange: http://10.1.223.93/Exchange"
echo " 🔗 API: http://10.1.223.93/api"
echo " ⛓️ Blockchain RPC: http://10.1.223.93/rpc"
echo ""
echo "🔒 Domain URLs (with SSL):"
echo " 📊 Marketplace: https://aitbc.bubuit.net/Marketplace"
echo " 💱 Trade Exchange: https://aitbc.bubuit.net/Exchange"
echo " 🔗 API: https://aitbc.bubuit.net/api"
echo " ⛓️ Blockchain RPC: https://aitbc.bubuit.net/rpc"
echo ""
print_status "To manage services:"
echo " ssh aitbc 'systemctl status aitbc-coordinator'"
echo " ssh aitbc 'journalctl -u aitbc-coordinator -f'"

View File

@@ -0,0 +1,158 @@
#!/usr/bin/env python3
"""
Deploy AITBC services to incus container with GPU miner integration
"""
import subprocess
import time
import sys
def run_command(cmd, container=None):
"""Run command locally or in container"""
if container:
cmd = f"incus exec {container} -- {cmd}"
print(f"Running: {cmd}")
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
if result.returncode != 0:
print(f"Error: {result.stderr}")
return False
return True
def deploy_to_container():
container = "aitbc"
container_ip = "10.1.223.93"
print("🚀 Deploying AITBC services to container with GPU miner...")
# Check if container exists
result = subprocess.run("incus list -c n", shell=True, capture_output=True, text=True)
if container not in result.stdout:
print(f"\n📦 Creating container {container}...")
subprocess.run(f"incus launch images:ubuntu/22.04 {container}", shell=True)
time.sleep(10)
# Ensure container is running
subprocess.run(f"incus start {container}", shell=True)
time.sleep(5)
# Update and install packages in container
print("\n📦 Installing packages in container...")
run_command("apt-get update", container)
run_command("apt-get install -y python3 python3-pip python3-venv curl", container)
# Stop local services
print("\n📋 Stopping local services...")
subprocess.run("sudo fuser -k 8000/tcp 2>/dev/null || true", shell=True)
subprocess.run("sudo fuser -k 9080/tcp 2>/dev/null || true", shell=True)
subprocess.run("pkill -f 'marketplace-ui' 2>/dev/null || true", shell=True)
subprocess.run("pkill -f 'trade-exchange' 2>/dev/null || true", shell=True)
# Copy project to container
print("\n📁 Copying project to container...")
subprocess.run(f"incus file push -r /home/oib/windsurf/aitbc {container}/home/oib/", shell=True)
# Setup Python environment in container
print("\n🐍 Setting up Python environment...")
run_command("cd /home/oib/aitbc && python3 -m venv .venv", container)
run_command("cd /home/oib/aitbc && source .venv/bin/activate && pip install fastapi uvicorn httpx sqlmodel psutil", container)
# Install dependencies
print("\n📦 Installing dependencies...")
run_command("cd /home/oib/aitbc/apps/coordinator-api && source ../../.venv/bin/activate && pip install -e .", container)
run_command("cd /home/oib/aitbc/apps/blockchain-node && source ../../.venv/bin/activate && pip install -e .", container)
# Create startup script with GPU miner
print("\n🔧 Creating startup script with GPU miner...")
startup_script = """#!/bin/bash
cd /home/oib/aitbc
source .venv/bin/activate
# Start coordinator API
echo "Starting Coordinator API..."
cd apps/coordinator-api
source ../../.venv/bin/activate
python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 &
COORD_PID=$!
# Start blockchain node
echo "Starting Blockchain Node..."
cd ../../apps/blockchain-node
source ../../.venv/bin/activate
python -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 9080 &
BLOCK_PID=$!
# Start trade exchange
echo "Starting Trade Exchange..."
cd ../../apps/trade-exchange
source ../../.venv/bin/activate
python simple_exchange_api.py &
EXCHANGE_PID=$!
# Start GPU registry
echo "Starting GPU Registry..."
cd ../..
python gpu_registry_demo.py &
REGISTRY_PID=$!
# Start GPU miner
echo "Starting GPU Miner..."
python gpu_miner_with_wait.py &
MINER_PID=$!
echo "All services started!"
echo "Coordinator API: http://10.1.223.93:8000"
echo "Blockchain RPC: http://10.1.223.93:9080"
echo "Trade Exchange: http://10.1.223.93:3002"
echo "GPU Registry: http://10.1.223.93:8091"
# Wait for services
wait $COORD_PID $BLOCK_PID $EXCHANGE_PID $REGISTRY_PID $MINER_PID
"""
# Write startup script to container
with open('/tmp/startup.sh', 'w') as f:
f.write(startup_script)
subprocess.run(f"incus file push /tmp/startup.sh {container}/home/oib/aitbc/", shell=True)
run_command("chmod +x /home/oib/aitbc/startup.sh", container)
# Create systemd service
print("\n⚙️ Creating systemd service...")
service_content = """[Unit]
Description=AITBC Services with GPU Miner
After=network.target
[Service]
Type=simple
User=oib
WorkingDirectory=/home/oib/aitbc
ExecStart=/home/oib/aitbc/startup.sh
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
"""
with open('/tmp/aitbc.service', 'w') as f:
f.write(service_content)
subprocess.run(f"incus file push /tmp/aitbc.service {container}/tmp/", shell=True)
run_command("mv /tmp/aitbc.service /etc/systemd/system/", container)
run_command("systemctl daemon-reload", container)
run_command("systemctl enable aitbc.service", container)
run_command("systemctl start aitbc.service", container)
print("\n✅ Deployment complete!")
print(f"\n📊 Service URLs:")
print(f" - Coordinator API: http://{container_ip}:8000")
print(f" - Blockchain RPC: http://{container_ip}:9080")
print(f" - Trade Exchange: http://{container_ip}:3002")
print(f" - GPU Registry: http://{container_ip}:8091")
print(f"\n🔍 Check GPU status:")
print(f" curl http://{container_ip}:8091/miners/list")
print(f"\n📋 To manage services in container:")
print(f" incus exec {container} -- systemctl status aitbc")
print(f" incus exec {container} -- journalctl -u aitbc -f")
if __name__ == "__main__":
deploy_to_container()

View File

@@ -0,0 +1,130 @@
#!/usr/bin/env python3
"""
Deploy GPU Miner Integration to AITBC Container
"""
import subprocess
import sys
def run_in_container(cmd):
"""Run command in aitbc container"""
full_cmd = f"incus exec aitbc -- {cmd}"
print(f"Running: {full_cmd}")
result = subprocess.run(full_cmd, shell=True, capture_output=True, text=True)
if result.returncode != 0:
print(f"Error: {result.stderr}")
return False, result.stderr
return True, result.stdout
def deploy_gpu_miner_to_container():
print("🚀 Deploying GPU Miner Integration to AITBC Container...")
# Check container access
print("\n1. 🔍 Checking container access...")
success, output = run_in_container("whoami")
if success:
print(f" Container user: {output.strip()}")
else:
print(" ❌ Cannot access container")
return
# Copy GPU miner files to container
print("\n2. 📁 Copying GPU miner files...")
files_to_copy = [
"gpu_miner_with_wait.py",
"gpu_registry_demo.py"
]
for file in files_to_copy:
cmd = f"incus file push /home/oib/windsurf/aitbc/{file} aitbc/home/oib/"
print(f" Copying {file}...")
result = subprocess.run(cmd, shell=True)
if result.returncode == 0:
print(f"{file} copied")
else:
print(f" ❌ Failed to copy {file}")
# Install dependencies in container
print("\n3. 📦 Installing dependencies...")
run_in_container("pip install httpx fastapi uvicorn psutil")
# Create GPU miner service in container
print("\n4. ⚙️ Creating GPU miner service...")
service_content = """[Unit]
Description=AITBC GPU Miner Client
After=network.target
[Service]
Type=simple
User=oib
WorkingDirectory=/home/oib
ExecStart=/usr/bin/python3 gpu_miner_with_wait.py
Restart=always
RestartSec=30
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
"""
# Write service file to container
with open('/tmp/gpu-miner.service', 'w') as f:
f.write(service_content)
subprocess.run("incus file push /tmp/gpu-miner.service aitbc/tmp/", shell=True)
run_in_container("sudo mv /tmp/gpu-miner.service /etc/systemd/system/")
run_in_container("sudo systemctl daemon-reload")
run_in_container("sudo systemctl enable gpu-miner.service")
run_in_container("sudo systemctl start gpu-miner.service")
# Create GPU registry service in container
print("\n5. 🎮 Creating GPU registry service...")
registry_service = """[Unit]
Description=AITBC GPU Registry
After=network.target
[Service]
Type=simple
User=oib
WorkingDirectory=/home/oib
ExecStart=/usr/bin/python3 gpu_registry_demo.py
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
"""
with open('/tmp/gpu-registry.service', 'w') as f:
f.write(registry_service)
subprocess.run("incus file push /tmp/gpu-registry.service aitbc/tmp/", shell=True)
run_in_container("sudo mv /tmp/gpu-registry.service /etc/systemd/system/")
run_in_container("sudo systemctl daemon-reload")
run_in_container("sudo systemctl enable gpu-registry.service")
run_in_container("sudo systemctl start gpu-registry.service")
# Check services
print("\n6. 📊 Checking services...")
success, output = run_in_container("sudo systemctl status gpu-miner.service --no-pager")
print(output)
success, output = run_in_container("sudo systemctl status gpu-registry.service --no-pager")
print(output)
# Update coordinator to include miner endpoints
print("\n7. 🔗 Updating coordinator API...")
print("\n✅ GPU Miner deployed to container!")
print("\n📊 Access URLs:")
print(" - Container IP: 10.1.223.93")
print(" - GPU Registry: http://10.1.223.93:8091/miners/list")
print(" - Coordinator API: http://10.1.223.93:8000")
print("\n🔧 To manage services in container:")
print(" incus exec aitbc -- sudo systemctl status gpu-miner")
print(" incus exec aitbc -- sudo journalctl -u gpu-miner -f")
if __name__ == "__main__":
deploy_gpu_miner_to_container()

View File

@@ -0,0 +1,113 @@
#!/bin/bash
# Setup gossip relay to connect blockchain nodes
set -e
echo "🌐 Setting up Gossip Relay for Blockchain Nodes"
echo "=============================================="
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Stop existing nodes
print_status "Stopping blockchain nodes..."
sudo systemctl stop blockchain-node blockchain-node-2 blockchain-rpc blockchain-rpc-2 2>/dev/null || true
# Update node configurations to use broadcast backend
print_status "Updating Node 1 configuration..."
sudo cat > /opt/blockchain-node/.env << EOF
CHAIN_ID=ait-devnet
DB_PATH=./data/chain.db
RPC_BIND_HOST=127.0.0.1
RPC_BIND_PORT=8082
P2P_BIND_HOST=0.0.0.0
P2P_BIND_PORT=7070
PROPOSER_KEY=node1_proposer_key_$(date +%s)
MINT_PER_UNIT=1000
COORDINATOR_RATIO=0.05
GOSSIP_BACKEND=broadcast
GOSSIP_BROADCAST_URL=http://127.0.0.1:7070/gossip
EOF
print_status "Updating Node 2 configuration..."
sudo cat > /opt/blockchain-node-2/.env << EOF
CHAIN_ID=ait-devnet
DB_PATH=./data/chain2.db
RPC_BIND_HOST=127.0.0.1
RPC_BIND_PORT=8081
P2P_BIND_HOST=0.0.0.0
P2P_BIND_PORT=7071
PROPOSER_KEY=node2_proposer_key_$(date +%s)
MINT_PER_UNIT=1000
COORDINATOR_RATIO=0.05
GOSSIP_BACKEND=broadcast
GOSSIP_BROADCAST_URL=http://127.0.0.1:7070/gossip
EOF
# Create gossip relay service
print_status "Creating gossip relay service..."
sudo cat > /etc/systemd/system/blockchain-gossip-relay.service << EOF
[Unit]
Description=AITBC Blockchain Gossip Relay
After=network.target
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m aitbc_chain.gossip.relay --port 7070 --host 0.0.0.0
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
# Enable and start gossip relay
print_status "Starting gossip relay..."
sudo systemctl daemon-reload
sudo systemctl enable blockchain-gossip-relay
sudo systemctl start blockchain-gossip-relay
# Wait for relay to start
sleep 2
# Check if relay is running
print_status "Checking gossip relay status..."
sudo systemctl status blockchain-gossip-relay --no-pager | head -10
# Restart blockchain nodes
print_status "Restarting blockchain nodes with shared gossip..."
sudo systemctl start blockchain-node blockchain-node-2 blockchain-rpc blockchain-rpc-2
# Wait for nodes to start
sleep 3
# Check status
print_status "Checking node status..."
sudo systemctl status blockchain-node blockchain-node-2 --no-pager | grep -E 'Active:|Main PID:'
echo ""
print_status "✅ Gossip relay setup complete!"
echo ""
echo "Nodes are now connected via shared gossip backend."
echo "They should sync blocks and transactions."
echo ""
echo "To verify connectivity:"
echo " 1. Run: python /opt/test_blockchain_simple.py"
echo " 2. Check if heights are converging"
echo ""
echo "Gossip relay logs: sudo journalctl -u blockchain-gossip-relay -f"

View File

@@ -0,0 +1,40 @@
#!/bin/bash
# Test if blockchain node and explorer are running
echo "🔍 Testing Blockchain Deployment"
echo "==============================="
# Test blockchain RPC
echo "Testing blockchain RPC..."
if curl -s http://aitbc.keisanki.net:8082/rpc/head > /dev/null; then
echo "✅ Blockchain RPC is accessible"
curl -s http://aitbc.keisanki.net:8082/rpc/head | jq '.height'
else
echo "❌ Blockchain RPC is not accessible"
fi
# Test explorer
echo ""
echo "Testing blockchain explorer..."
if curl -s http://aitbc.keisanki.net:3000 > /dev/null; then
echo "✅ Explorer is accessible"
else
echo "❌ Explorer is not accessible"
fi
# Check services on server
echo ""
echo "Checking service status on ns3..."
ssh ns3-root "systemctl is-active blockchain-node blockchain-rpc nginx" | while read service status; do
if [ "$status" = "active" ]; then
echo "$service is running"
else
echo "$service is not running"
fi
done
# Check logs if needed
echo ""
echo "Recent blockchain logs:"
ssh ns3-root "journalctl -u blockchain-node -n 5 --no-pager"

View File

@@ -0,0 +1,89 @@
#!/bin/bash
# Deploy GPU Miner to AITBC Container - All in One
set -e
echo "🚀 Deploying GPU Miner to AITBC Container..."
# Step 1: Copy files
echo "1. Copying GPU scripts..."
scp -o StrictHostKeyChecking=no /home/oib/windsurf/aitbc/gpu_registry_demo.py aitbc:/home/oib/
scp -o StrictHostKeyChecking=no /home/oib/windsurf/aitbc/gpu_miner_with_wait.py aitbc:/home/oib/
# Step 2: Install Python and deps
echo "2. Installing Python and dependencies..."
ssh aitbc 'sudo apt-get update -qq'
ssh aitbc 'sudo apt-get install -y -qq python3 python3-venv python3-pip'
ssh aitbc 'python3 -m venv /home/oib/.venv-gpu'
ssh aitbc '/home/oib/.venv-gpu/bin/pip install -q fastapi uvicorn httpx psutil'
# Step 3: Create GPU registry service
echo "3. Creating GPU registry service..."
ssh aitbc "sudo tee /etc/systemd/system/aitbc-gpu-registry.service >/dev/null <<'EOF'
[Unit]
Description=AITBC GPU Registry
After=network.target
[Service]
Type=simple
User=oib
WorkingDirectory=/home/oib
ExecStart=/home/oib/.venv-gpu/bin/python /home/oib/gpu_registry_demo.py
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF"
# Step 4: Start GPU registry
echo "4. Starting GPU registry..."
ssh aitbc 'sudo systemctl daemon-reload'
ssh aitbc 'sudo systemctl enable --now aitbc-gpu-registry.service'
# Step 5: Create GPU miner service
echo "5. Creating GPU miner service..."
ssh aitbc "sudo tee /etc/systemd/system/aitbc-gpu-miner.service >/dev/null <<'EOF'
[Unit]
Description=AITBC GPU Miner Client
After=network.target aitbc-gpu-registry.service
Wants=aitbc-gpu-registry.service
[Service]
Type=simple
User=oib
WorkingDirectory=/home/oib
ExecStart=/home/oib/.venv-gpu/bin/python /home/oib/gpu_miner_with_wait.py
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF"
# Step 6: Start GPU miner
echo "6. Starting GPU miner..."
ssh aitbc 'sudo systemctl daemon-reload'
ssh aitbc 'sudo systemctl enable --now aitbc-gpu-miner.service'
# Step 7: Check services
echo "7. Checking services..."
echo -e "\n=== GPU Registry Service ==="
ssh aitbc 'sudo systemctl status aitbc-gpu-registry.service --no-pager'
echo -e "\n=== GPU Miner Service ==="
ssh aitbc 'sudo systemctl status aitbc-gpu-miner.service --no-pager'
# Step 8: Verify GPU registration
echo -e "\n8. Verifying GPU registration..."
sleep 3
echo " curl http://10.1.223.93:8091/miners/list"
curl -s http://10.1.223.93:8091/miners/list | python3 -c "import sys,json; data=json.load(sys.stdin); print(f'✅ Found {len(data.get(\"gpus\", []))} GPU(s)'); [print(f' - {gpu[\"capabilities\"][\"gpu\"][\"model\"]} ({gpu[\"capabilities\"][\"gpu\"][\"memory_gb\"]}GB)') for gpu in data.get('gpus', [])]"
echo -e "\n✅ Deployment complete!"
echo "GPU Registry: http://10.1.223.93:8091"
echo "GPU Miner: Running and sending heartbeats"

View File

@@ -0,0 +1,89 @@
#!/bin/bash
# Deploy GPU Miner to AITBC Container
echo "🚀 Deploying GPU Miner to AITBC Container..."
# Check if container is accessible
echo "1. Checking container access..."
sudo incus exec aitbc -- whoami
# Copy GPU miner files
echo "2. Copying GPU miner files..."
sudo incus file push /home/oib/windsurf/aitbc/gpu_miner_with_wait.py aitbc/home/oib/
sudo incus file push /home/oib/windsurf/aitbc/gpu_registry_demo.py aitbc/home/oib/
# Install dependencies
echo "3. Installing dependencies..."
sudo incus exec aitbc -- pip install httpx fastapi uvicorn psutil
# Create GPU miner service
echo "4. Creating GPU miner service..."
cat << 'EOF' | sudo tee /tmp/gpu-miner.service
[Unit]
Description=AITBC GPU Miner Client
After=network.target
[Service]
Type=simple
User=oib
WorkingDirectory=/home/oib
ExecStart=/usr/bin/python3 gpu_miner_with_wait.py
Restart=always
RestartSec=30
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
sudo incus file push /tmp/gpu-miner.service aitbc/tmp/
sudo incus exec aitbc -- sudo mv /tmp/gpu-miner.service /etc/systemd/system/
sudo incus exec aitbc -- sudo systemctl daemon-reload
sudo incus exec aitbc -- sudo systemctl enable gpu-miner.service
sudo incus exec aitbc -- sudo systemctl start gpu-miner.service
# Create GPU registry service
echo "5. Creating GPU registry service..."
cat << 'EOF' | sudo tee /tmp/gpu-registry.service
[Unit]
Description=AITBC GPU Registry
After=network.target
[Service]
Type=simple
User=oib
WorkingDirectory=/home/oib
ExecStart=/usr/bin/python3 gpu_registry_demo.py
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
sudo incus file push /tmp/gpu-registry.service aitbc/tmp/
sudo incus exec aitbc -- sudo mv /tmp/gpu-registry.service /etc/systemd/system/
sudo incus exec aitbc -- sudo systemctl daemon-reload
sudo incus exec aitbc -- sudo systemctl enable gpu-registry.service
sudo incus exec aitbc -- sudo systemctl start gpu-registry.service
# Check services
echo "6. Checking services..."
echo "GPU Miner Service:"
sudo incus exec aitbc -- sudo systemctl status gpu-miner.service --no-pager
echo -e "\nGPU Registry Service:"
sudo incus exec aitbc -- sudo systemctl status gpu-registry.service --no-pager
# Show access URLs
echo -e "\n✅ Deployment complete!"
echo "Access URLs:"
echo " - Container IP: 10.1.223.93"
echo " - GPU Registry: http://10.1.223.93:8091/miners/list"
echo " - Coordinator API: http://10.1.223.93:8000"
echo -e "\nTo check GPU status:"
echo " curl http://10.1.223.93:8091/miners/list"

View File

@@ -0,0 +1,92 @@
#!/usr/bin/env python3
"""
GPU Exchange Integration Demo
Shows how the GPU miner is integrated with the exchange
"""
import json
import httpx
import subprocess
import time
from datetime import datetime
print("🔗 AITBC GPU Exchange Integration")
print("=" * 50)
# Check GPU Registry
print("\n1. 📊 Checking GPU Registry...")
try:
response = httpx.get("http://localhost:8091/miners/list")
if response.status_code == 200:
data = response.json()
gpus = data.get("gpus", [])
print(f" Found {len(gpus)} registered GPU(s)")
for gpu in gpus:
print(f"\n 🎮 GPU Details:")
print(f" Model: {gpu['capabilities']['gpu']['model']}")
print(f" Memory: {gpu['capabilities']['gpu']['memory_gb']} GB")
print(f" CUDA: {gpu['capabilities']['gpu']['cuda_version']}")
print(f" Status: {gpu.get('status', 'Unknown')}")
print(f" Region: {gpu.get('region', 'Unknown')}")
else:
print(" ❌ GPU Registry not accessible")
except Exception as e:
print(f" ❌ Error: {e}")
# Check Exchange
print("\n2. 💰 Checking Trade Exchange...")
try:
response = httpx.get("http://localhost:3002")
if response.status_code == 200:
print(" ✅ Trade Exchange is running")
print(" 🌐 URL: http://localhost:3002")
else:
print(" ❌ Trade Exchange not responding")
except:
print(" ❌ Trade Exchange not accessible")
# Check Blockchain
print("\n3. ⛓️ Checking Blockchain Node...")
try:
response = httpx.get("http://localhost:9080/rpc/head")
if response.status_code == 200:
data = response.json()
print(f" ✅ Blockchain Node active")
print(f" Block Height: {data.get('height', 'Unknown')}")
print(f" Block Hash: {data.get('hash', 'Unknown')[:16]}...")
else:
print(" ❌ Blockchain Node not responding")
except:
print(" ❌ Blockchain Node not accessible")
# Show Integration Points
print("\n4. 🔌 Integration Points:")
print(" • GPU Registry: http://localhost:8091/miners/list")
print(" • Trade Exchange: http://localhost:3002")
print(" • Blockchain RPC: http://localhost:9080")
print(" • GPU Marketplace: Exchange > Browse GPU Marketplace")
# Show API Usage
print("\n5. 📡 API Usage Examples:")
print("\n Get registered GPUs:")
print(" curl http://localhost:8091/miners/list")
print("\n Get GPU details:")
print(" curl http://localhost:8091/miners/localhost-gpu-miner")
print("\n Get blockchain info:")
print(" curl http://localhost:9080/rpc/head")
# Show Current Status
print("\n6. 📈 Current System Status:")
print(" ✅ GPU Miner: Running (systemd)")
print(" ✅ GPU Registry: Running on port 8091")
print(" ✅ Trade Exchange: Running on port 3002")
print(" ✅ Blockchain Node: Running on port 9080")
print("\n" + "=" * 50)
print("🎯 GPU is successfully integrated with the exchange!")
print("\nNext steps:")
print("1. Open http://localhost:3002 in your browser")
print("2. Click 'Browse GPU Marketplace'")
print("3. View the registered RTX 4060 Ti GPU")
print("4. Purchase GPU compute time with AITBC tokens")

View File

@@ -0,0 +1,396 @@
#!/usr/bin/env python3
"""
Real GPU Miner Client for AITBC - runs on host with actual GPU
"""
import json
import time
import httpx
import logging
import sys
import subprocess
import os
from datetime import datetime
# Configuration
COORDINATOR_URL = "http://127.0.0.1:18000"
MINER_ID = "${MINER_API_KEY}"
AUTH_TOKEN = "${MINER_API_KEY}"
HEARTBEAT_INTERVAL = 15
MAX_RETRIES = 10
RETRY_DELAY = 30
# Setup logging with explicit configuration
LOG_PATH = "/home/oib/windsurf/aitbc/logs/host_gpu_miner.log"
os.makedirs(os.path.dirname(LOG_PATH), exist_ok=True)
class FlushHandler(logging.StreamHandler):
def emit(self, record):
super().emit(record)
self.flush()
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
FlushHandler(sys.stdout),
logging.FileHandler(LOG_PATH)
]
)
logger = logging.getLogger(__name__)
# Force stdout to be unbuffered
sys.stdout.reconfigure(line_buffering=True)
sys.stderr.reconfigure(line_buffering=True)
# GPU capabilities (RTX 4060 Ti)
GPU_CAPABILITIES = {
"gpu": {
"model": "NVIDIA GeForce RTX 4060 Ti",
"memory_gb": 16,
"cuda_version": "12.4",
"platform": "CUDA",
"supported_tasks": ["inference", "training", "stable-diffusion", "llama"],
"max_concurrent_jobs": 1
}
}
def get_gpu_info():
"""Get real GPU information"""
try:
result = subprocess.run(['nvidia-smi', '--query-gpu=name,memory.total,memory.used,utilization.gpu',
'--format=csv,noheader,nounits'],
capture_output=True, text=True, timeout=5)
if result.returncode == 0:
info = result.stdout.strip().split(', ')
return {
"name": info[0],
"memory_total": int(info[1]),
"memory_used": int(info[2]),
"utilization": int(info[3])
}
except Exception as e:
logger.error(f"Failed to get GPU info: {e}")
return None
def check_ollama():
"""Check if Ollama is running and has models"""
try:
response = httpx.get("http://localhost:11434/api/tags", timeout=5)
if response.status_code == 200:
models = response.json().get('models', [])
model_names = [m['name'] for m in models]
logger.info(f"Ollama running with models: {model_names}")
return True, model_names
else:
logger.error("Ollama not responding")
return False, []
except Exception as e:
logger.error(f"Ollama check failed: {e}")
return False, []
def wait_for_coordinator():
"""Wait for coordinator to be available"""
for i in range(MAX_RETRIES):
try:
response = httpx.get(f"{COORDINATOR_URL}/v1/health", timeout=5)
if response.status_code == 200:
logger.info("Coordinator is available!")
return True
except:
pass
logger.info(f"Waiting for coordinator... ({i+1}/{MAX_RETRIES})")
time.sleep(RETRY_DELAY)
logger.error("Coordinator not available after max retries")
return False
def register_miner():
"""Register the miner with the coordinator"""
register_data = {
"capabilities": GPU_CAPABILITIES,
"concurrency": 1,
"region": "localhost"
}
headers = {
"X-Api-Key": AUTH_TOKEN,
"Content-Type": "application/json"
}
try:
response = httpx.post(
f"{COORDINATOR_URL}/v1/miners/register?miner_id={MINER_ID}",
json=register_data,
headers=headers,
timeout=10
)
if response.status_code == 200:
data = response.json()
logger.info(f"Successfully registered miner: {data}")
return data.get("session_token", "demo-token")
else:
logger.error(f"Registration failed: {response.status_code} - {response.text}")
return None
except Exception as e:
logger.error(f"Registration error: {e}")
return None
def send_heartbeat():
"""Send heartbeat to coordinator with real GPU stats"""
gpu_info = get_gpu_info()
if gpu_info:
heartbeat_data = {
"status": "active",
"current_jobs": 0,
"last_seen": datetime.utcnow().isoformat(),
"gpu_utilization": gpu_info["utilization"],
"memory_used": gpu_info["memory_used"],
"memory_total": gpu_info["memory_total"]
}
else:
heartbeat_data = {
"status": "active",
"current_jobs": 0,
"last_seen": datetime.utcnow().isoformat(),
"gpu_utilization": 0,
"memory_used": 0,
}
headers = {
"X-Api-Key": AUTH_TOKEN,
"Content-Type": "application/json"
}
try:
response = httpx.post(
f"{COORDINATOR_URL}/v1/miners/heartbeat?miner_id={MINER_ID}",
json=heartbeat_data,
headers=headers,
timeout=5
)
if response.status_code == 200:
logger.info(f"Heartbeat sent (GPU: {gpu_info['utilization'] if gpu_info else 'N/A'}%)")
else:
logger.error(f"Heartbeat failed: {response.status_code} - {response.text}")
except Exception as e:
logger.error(f"Heartbeat error: {e}")
def execute_job(job, available_models):
"""Execute a job using real GPU resources"""
job_id = job.get('job_id')
payload = job.get('payload', {})
logger.info(f"Executing job {job_id}: {payload}")
try:
if payload.get('type') == 'inference':
# Get the prompt and model
prompt = payload.get('prompt', '')
model = payload.get('model', 'llama3.2:latest')
# Check if model is available
if model not in available_models:
# Use first available model
if available_models:
model = available_models[0]
logger.info(f"Using available model: {model}")
else:
raise Exception("No models available in Ollama")
# Call Ollama API for real GPU inference
logger.info(f"Running inference on GPU with model: {model}")
start_time = time.time()
ollama_response = httpx.post(
"http://localhost:11434/api/generate",
json={
"model": model,
"prompt": prompt,
"stream": False
},
timeout=60
)
if ollama_response.status_code == 200:
result = ollama_response.json()
output = result.get('response', '')
execution_time = time.time() - start_time
# Get GPU stats after execution
gpu_after = get_gpu_info()
# Submit result back to coordinator
submit_result(job_id, {
"result": {
"status": "completed",
"output": output,
"model": model,
"tokens_processed": result.get('eval_count', 0),
"execution_time": execution_time,
"gpu_used": True
},
"metrics": {
"gpu_utilization": gpu_after["utilization"] if gpu_after else 0,
"memory_used": gpu_after["memory_used"] if gpu_after else 0,
"memory_peak": max(gpu_after["memory_used"] if gpu_after else 0, 2048)
}
})
logger.info(f"Job {job_id} completed in {execution_time:.2f}s")
return True
else:
logger.error(f"Ollama error: {ollama_response.status_code}")
submit_result(job_id, {
"result": {
"status": "failed",
"error": f"Ollama error: {ollama_response.text}"
}
})
return False
else:
# Unsupported job type
logger.error(f"Unsupported job type: {payload.get('type')}")
submit_result(job_id, {
"result": {
"status": "failed",
"error": f"Unsupported job type: {payload.get('type')}"
}
})
return False
except Exception as e:
logger.error(f"Job execution error: {e}")
submit_result(job_id, {
"result": {
"status": "failed",
"error": str(e)
}
})
return False
def submit_result(job_id, result):
"""Submit job result to coordinator"""
headers = {
"X-Api-Key": AUTH_TOKEN,
"Content-Type": "application/json"
}
try:
response = httpx.post(
f"{COORDINATOR_URL}/v1/miners/{job_id}/result",
json=result,
headers=headers,
timeout=10
)
if response.status_code == 200:
logger.info(f"Result submitted for job {job_id}")
else:
logger.error(f"Result submission failed: {response.status_code} - {response.text}")
except Exception as e:
logger.error(f"Result submission error: {e}")
def poll_for_jobs():
"""Poll for available jobs"""
poll_data = {
"max_wait_seconds": 5
}
headers = {
"X-Api-Key": AUTH_TOKEN,
"Content-Type": "application/json"
}
try:
response = httpx.post(
f"{COORDINATOR_URL}/v1/miners/poll",
json=poll_data,
headers=headers,
timeout=10
)
if response.status_code == 200:
job = response.json()
logger.info(f"Received job: {job}")
return job
elif response.status_code == 204:
return None
else:
logger.error(f"Poll failed: {response.status_code} - {response.text}")
return None
except Exception as e:
logger.error(f"Error polling for jobs: {e}")
return None
def main():
"""Main miner loop"""
logger.info("Starting Real GPU Miner Client on Host...")
# Check GPU availability
gpu_info = get_gpu_info()
if not gpu_info:
logger.error("GPU not available, exiting")
sys.exit(1)
logger.info(f"GPU detected: {gpu_info['name']} ({gpu_info['memory_total']}MB)")
# Check Ollama
ollama_available, models = check_ollama()
if not ollama_available:
logger.error("Ollama not available - please install and start Ollama")
sys.exit(1)
logger.info(f"Ollama models available: {', '.join(models)}")
# Wait for coordinator
if not wait_for_coordinator():
sys.exit(1)
# Register with coordinator
session_token = register_miner()
if not session_token:
logger.error("Failed to register, exiting")
sys.exit(1)
logger.info("Miner registered successfully, starting main loop...")
# Main loop
last_heartbeat = 0
last_poll = 0
try:
while True:
current_time = time.time()
# Send heartbeat
if current_time - last_heartbeat >= HEARTBEAT_INTERVAL:
send_heartbeat()
last_heartbeat = current_time
# Poll for jobs
if current_time - last_poll >= 3:
job = poll_for_jobs()
if job:
# Execute the job with real GPU
execute_job(job, models)
last_poll = current_time
time.sleep(1)
except KeyboardInterrupt:
logger.info("Shutting down miner...")
except Exception as e:
logger.error(f"Error in main loop: {e}")
sys.exit(1)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,3 @@
#!/bin/bash
# Wrapper script for GPU miner to ensure proper logging
exec /home/oib/windsurf/aitbc/.venv/bin/python -u /home/oib/windsurf/aitbc/scripts/gpu/gpu_miner_host.py 2>&1

View File

@@ -0,0 +1,72 @@
#!/usr/bin/env python3
"""
Simple GPU Registry Server for demonstration
"""
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Dict, Any, Optional
import uvicorn
from datetime import datetime
app = FastAPI(title="GPU Registry Demo")
# In-memory storage
registered_gpus: Dict[str, Dict] = {}
class GPURegistration(BaseModel):
capabilities: Dict[str, Any]
concurrency: int = 1
region: Optional[str] = None
class Heartbeat(BaseModel):
inflight: int = 0
status: str = "ONLINE"
metadata: Dict[str, Any] = {}
@app.get("/")
async def root():
return {"message": "GPU Registry Demo", "registered_gpus": len(registered_gpus)}
@app.get("/health")
async def health():
return {"status": "ok"}
@app.post("/miners/register")
async def register_gpu(miner_id: str, gpu_data: GPURegistration):
"""Register a GPU miner"""
registered_gpus[miner_id] = {
"id": miner_id,
"registered_at": datetime.utcnow().isoformat(),
"last_heartbeat": datetime.utcnow().isoformat(),
**gpu_data.dict()
}
return {"status": "ok", "message": f"GPU {miner_id} registered successfully"}
@app.post("/miners/heartbeat")
async def heartbeat(miner_id: str, heartbeat_data: Heartbeat):
"""Receive heartbeat from GPU miner"""
if miner_id not in registered_gpus:
raise HTTPException(status_code=404, detail="GPU not registered")
registered_gpus[miner_id]["last_heartbeat"] = datetime.utcnow().isoformat()
registered_gpus[miner_id]["status"] = heartbeat_data.status
registered_gpus[miner_id]["metadata"] = heartbeat_data.metadata
return {"status": "ok"}
@app.get("/miners/list")
async def list_gpus():
"""List all registered GPUs"""
return {"gpus": list(registered_gpus.values())}
@app.get("/miners/{miner_id}")
async def get_gpu(miner_id: str):
"""Get details of a specific GPU"""
if miner_id not in registered_gpus:
raise HTTPException(status_code=404, detail="GPU not registered")
return registered_gpus[miner_id]
if __name__ == "__main__":
print("Starting GPU Registry Demo on http://localhost:8091")
uvicorn.run(app, host="0.0.0.0", port=8091)

View File

@@ -0,0 +1,146 @@
#!/usr/bin/env python3
"""
Integrate GPU Miner with existing Trade Exchange
"""
import httpx
import json
import subprocess
import time
from datetime import datetime
# Configuration
EXCHANGE_URL = "http://localhost:3002"
GPU_REGISTRY_URL = "http://localhost:8091"
def update_exchange_with_gpu():
"""Update the exchange frontend to show registered GPUs"""
# Read the exchange HTML
with open('/home/oib/windsurf/aitbc/apps/trade-exchange/index.html', 'r') as f:
html_content = f.read()
# Add GPU marketplace integration
gpu_integration = """
<script>
// GPU Integration
async function loadRealGPUOffers() {
try {
const response = await fetch('http://localhost:8091/miners/list');
const data = await response.json();
if (data.gpus && data.gpus.length > 0) {
displayRealGPUOffers(data.gpus);
} else {
displayDemoOffers();
}
} catch (error) {
console.log('Using demo GPU offers');
displayDemoOffers();
}
}
function displayRealGPUOffers(gpus) {
const container = document.getElementById('gpuList');
container.innerHTML = '';
gpus.forEach(gpu => {
const gpuCard = `
<div class="bg-white rounded-lg shadow-lg p-6 card-hover">
<div class="flex justify-between items-start mb-4">
<h3 class="text-lg font-semibold">${gpu.capabilities.gpu.model}</h3>
<span class="bg-green-100 text-green-800 px-2 py-1 rounded text-sm">Available</span>
</div>
<div class="space-y-2 text-sm text-gray-600 mb-4">
<p><i data-lucide="monitor" class="w-4 h-4 inline mr-1"></i>Memory: ${gpu.capabilities.gpu.memory_gb} GB</p>
<p><i data-lucide="zap" class="w-4 h-4 inline mr-1"></i>CUDA: ${gpu.capabilities.gpu.cuda_version}</p>
<p><i data-lucide="cpu" class="w-4 h-4 inline mr-1"></i>Concurrency: ${gpu.concurrency}</p>
<p><i data-lucide="map-pin" class="w-4 h-4 inline mr-1"></i>Region: ${gpu.region}</p>
</div>
<div class="flex justify-between items-center">
<span class="text-2xl font-bold text-purple-600">50 AITBC/hr</span>
<button onclick="purchaseGPU('${gpu.id}')" class="bg-purple-600 text-white px-4 py-2 rounded hover:bg-purple-700 transition">
Purchase
</button>
</div>
</div>
`;
container.innerHTML += gpuCard;
});
lucide.createIcons();
}
// Override the loadGPUOffers function
const originalLoadGPUOffers = loadGPUOffers;
loadGPUOffers = loadRealGPUOffers;
</script>
"""
# Insert before closing body tag
if '</body>' in html_content:
html_content = html_content.replace('</body>', gpu_integration + '</body>')
# Write back to file
with open('/home/oib/windsurf/aitbc/apps/trade-exchange/index.html', 'w') as f:
f.write(html_content)
print("✅ Updated exchange with GPU integration!")
else:
print("❌ Could not find </body> tag in exchange HTML")
def create_gpu_api_endpoint():
"""Create an API endpoint in the exchange to serve GPU data"""
api_code = """
@app.get("/api/gpu/offers")
async def get_gpu_offers():
\"\"\"Get available GPU offers\"\"\"
try:
# Fetch from GPU registry
response = httpx.get("http://localhost:8091/miners/list")
if response.status_code == 200:
data = response.json()
return {"offers": data.get("gpus", [])}
except:
pass
# Return demo data if registry not available
return {
"offers": [{
"id": "demo-gpu-1",
"model": "NVIDIA RTX 4060 Ti",
"memory_gb": 16,
"price_per_hour": 50,
"available": True
}]
}
"""
print("\n📝 To add GPU API endpoint to exchange, add this code to simple_exchange_api.py:")
print(api_code)
def main():
print("🔗 Integrating GPU Miner with Trade Exchange...")
# Update exchange frontend
update_exchange_with_gpu()
# Show API integration code
create_gpu_api_endpoint()
print("\n📊 Integration Summary:")
print("1. ✅ Exchange frontend updated to show real GPUs")
print("2. 📝 See above for API endpoint code")
print("3. 🌐 Access the exchange at: http://localhost:3002")
print("4. 🎯 GPU Registry available at: http://localhost:8091/miners/list")
print("\n🔄 To see the integrated GPU marketplace:")
print("1. Restart the trade exchange if needed:")
print(" cd /home/oib/windsurf/aitbc/apps/trade-exchange")
print(" python simple_exchange_api.py")
print("2. Open http://localhost:3002 in browser")
print("3. Click 'Browse GPU Marketplace'")
if __name__ == "__main__":
main()

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