Compare commits
23 Commits
ea3597319d
...
e1184bcc13
| Author | SHA1 | Date | |
|---|---|---|---|
| e1184bcc13 | |||
| d024f6e6f3 | |||
| 7cdd8f1fd0 | |||
| fb3ac34ed3 | |||
| 096ce30728 | |||
| 74ab1657f7 | |||
| eef496b70a | |||
| 845c648313 | |||
| 0c85f89776 | |||
| 0218cd1422 | |||
| f2849ee4a9 | |||
| b4b5a57390 | |||
| 5f2ab48b9a | |||
| e791aa13da | |||
| 978d4d22f6 | |||
| 1205a7c681 | |||
| 97d989bc04 | |||
| 6020ad04c4 | |||
| d99bb73a9b | |||
| 4b78f3707b | |||
| 4c2062289c | |||
| ffbf0b8966 | |||
| 92f3d84815 |
2
.aitbc.yaml
Normal file
2
.aitbc.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
api_key: test_value
|
||||
coordinator_url: http://127.0.0.1:18000
|
||||
53
.env.example
53
.env.example
@@ -3,57 +3,56 @@
|
||||
# Run: python config/security/environment-audit.py --format text
|
||||
|
||||
# =========================
|
||||
# Blockchain core (example values)
|
||||
# Blockchain core
|
||||
# =========================
|
||||
chain_id=ait-devnet
|
||||
supported_chains=ait-devnet
|
||||
rpc_bind_host=127.0.0.1
|
||||
chain_id=ait-mainnet
|
||||
supported_chains=ait-mainnet
|
||||
rpc_bind_host=0.0.0.0
|
||||
rpc_bind_port=8006
|
||||
p2p_bind_host=127.0.0.2
|
||||
p2p_bind_host=0.0.0.0
|
||||
p2p_bind_port=8005
|
||||
proposer_id=ait-devnet-proposer
|
||||
proposer_key=
|
||||
keystore_path=./keystore
|
||||
keystore_password_file=./keystore/.password
|
||||
gossip_backend=memory
|
||||
gossip_broadcast_url=
|
||||
db_path=./data/chain.db
|
||||
proposer_id=aitbc1genesis
|
||||
proposer_key=changeme_hex_private_key
|
||||
keystore_path=/opt/aitbc/keystore
|
||||
keystore_password_file=/opt/aitbc/keystore/.password
|
||||
gossip_backend=broadcast
|
||||
gossip_broadcast_url=redis://127.0.0.1:6379
|
||||
db_path=/opt/aitbc/apps/blockchain-node/data/ait-mainnet/chain.db
|
||||
mint_per_unit=0
|
||||
coordinator_ratio=0.05
|
||||
block_time_seconds=2
|
||||
enable_block_production=false
|
||||
block_time_seconds=60
|
||||
enable_block_production=true
|
||||
|
||||
# =========================
|
||||
# Coordinator API (example values)
|
||||
# Coordinator API
|
||||
# =========================
|
||||
APP_ENV=development
|
||||
APP_ENV=production
|
||||
APP_HOST=127.0.0.1
|
||||
APP_PORT=8011
|
||||
DATABASE__URL=sqlite:////opt/aitbc/data/coordinator/coordinator.db
|
||||
BLOCKCHAIN_RPC_URL=http://127.0.0.1:8006
|
||||
ALLOW_ORIGINS=["http://localhost:8011","http://localhost:8000"]
|
||||
DATABASE__URL=sqlite:///./data/coordinator.db
|
||||
BLOCKCHAIN_RPC_URL=http://127.0.0.1:8026
|
||||
ALLOW_ORIGINS=["http://localhost:8011","http://localhost:8000","http://8026"]
|
||||
JOB_TTL_SECONDS=900
|
||||
HEARTBEAT_INTERVAL_SECONDS=10
|
||||
HEARTBEAT_TIMEOUT_SECONDS=30
|
||||
RATE_LIMIT_REQUESTS=60
|
||||
RATE_LIMIT_WINDOW_SECONDS=60
|
||||
CLIENT_API_KEYS=["client_dev_key"]
|
||||
MINER_API_KEYS=["miner_dev_key"]
|
||||
ADMIN_API_KEYS=["admin_dev_key"]
|
||||
CLIENT_API_KEYS=["client_prod_key_use_real_value"]
|
||||
MINER_API_KEYS=["miner_prod_key_use_real_value"]
|
||||
ADMIN_API_KEYS=["admin_prod_key_use_real_value"]
|
||||
HMAC_SECRET=change_this_to_a_32_byte_random_secret
|
||||
JWT_SECRET=change_this_to_another_32_byte_random_secret
|
||||
|
||||
# =========================
|
||||
# Marketplace Web (example values)
|
||||
# Marketplace Web
|
||||
# =========================
|
||||
VITE_MARKETPLACE_DATA_MODE=mock
|
||||
VITE_MARKETPLACE_DATA_MODE=live
|
||||
VITE_MARKETPLACE_API=/api
|
||||
VITE_MARKETPLACE_ENABLE_BIDS=false
|
||||
VITE_MARKETPLACE_ENABLE_BIDS=true
|
||||
VITE_MARKETPLACE_REQUIRE_AUTH=false
|
||||
|
||||
# =========================
|
||||
# Notes
|
||||
# =========================
|
||||
# For production: copy this to .env and replace with real values/secrets
|
||||
# Move secrets to a secrets manager and reference via secretRef
|
||||
# For production: move secrets to a secrets manager and reference via secretRef
|
||||
# Validate config: python config/security/environment-audit.py --format text
|
||||
|
||||
347
.gitignore
vendored
347
.gitignore
vendored
@@ -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,25 +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
|
||||
node_modules/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# ===================
|
||||
# Backup Files (organized)
|
||||
@@ -180,86 +131,11 @@ backup/README.md
|
||||
# ===================
|
||||
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
|
||||
|
||||
# ===================
|
||||
# Windsurf IDE
|
||||
# ===================
|
||||
@@ -267,165 +143,16 @@ secrets.json
|
||||
.snapshots/
|
||||
|
||||
# ===================
|
||||
# Test Results & Artifacts
|
||||
# ===================
|
||||
test-results/
|
||||
**/test-results/
|
||||
|
||||
# ===================
|
||||
# Development Logs - Keep in dev/logs/
|
||||
# ===================
|
||||
*.log
|
||||
*.out
|
||||
*.err
|
||||
wget-log
|
||||
download.log
|
||||
|
||||
# ===================
|
||||
# Wallet files (contain keys/balances)
|
||||
# Wallet Files (contain private keys)
|
||||
# ===================
|
||||
*.json
|
||||
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
|
||||
# Test Results
|
||||
# ===================
|
||||
src/aitbc_chain/
|
||||
test-results/
|
||||
**/test-results/
|
||||
|
||||
# ===================
|
||||
# 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
|
||||
|
||||
@@ -32,6 +32,9 @@ class RateLimitMiddleware(BaseHTTPMiddleware):
|
||||
|
||||
async def dispatch(self, request: Request, call_next):
|
||||
client_ip = request.client.host if request.client else "unknown"
|
||||
# Bypass rate limiting for localhost (sync/health internal traffic)
|
||||
if client_ip in {"127.0.0.1", "::1"}:
|
||||
return await call_next(request)
|
||||
now = time.time()
|
||||
# Clean old entries
|
||||
self._requests[client_ip] = [
|
||||
@@ -109,7 +112,8 @@ def create_app() -> FastAPI:
|
||||
|
||||
# Middleware (applied in reverse order)
|
||||
app.add_middleware(RequestLoggingMiddleware)
|
||||
app.add_middleware(RateLimitMiddleware, max_requests=200, window_seconds=60)
|
||||
# Allow higher RPC throughput (sync + node traffic)
|
||||
app.add_middleware(RateLimitMiddleware, max_requests=5000, window_seconds=60)
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=[
|
||||
|
||||
272
apps/blockchain-node/src/aitbc_chain/chain_sync.py
Normal file
272
apps/blockchain-node/src/aitbc_chain/chain_sync.py
Normal file
@@ -0,0 +1,272 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Chain Synchronization Service
|
||||
Keeps blockchain nodes synchronized by sharing blocks via P2P and Redis gossip
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
from typing import Dict, Any, Optional, List
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class ChainSyncService:
|
||||
def __init__(self, redis_url: str, node_id: str, rpc_port: int = 8006, leader_host: str = None,
|
||||
source_host: str = "127.0.0.1", source_port: int = None,
|
||||
import_host: str = "127.0.0.1", import_port: int = None):
|
||||
self.redis_url = redis_url
|
||||
self.node_id = node_id
|
||||
self.rpc_port = rpc_port # kept for backward compat (local poll if source_port None)
|
||||
self.leader_host = leader_host # Host of the leader node (legacy)
|
||||
self.source_host = source_host
|
||||
self.source_port = source_port or rpc_port
|
||||
self.import_host = import_host
|
||||
self.import_port = import_port or rpc_port
|
||||
self._stop_event = asyncio.Event()
|
||||
self._redis = None
|
||||
self._receiver_ready = asyncio.Event()
|
||||
|
||||
async def start(self):
|
||||
"""Start chain synchronization service"""
|
||||
logger.info(f"Starting chain sync service for node {self.node_id}")
|
||||
|
||||
try:
|
||||
import redis.asyncio as redis
|
||||
self._redis = redis.from_url(self.redis_url)
|
||||
await self._redis.ping()
|
||||
logger.info("Connected to Redis for chain sync")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to connect to Redis: {e}")
|
||||
return
|
||||
|
||||
# Start block broadcasting task
|
||||
# Start block receiving task
|
||||
receive_task = asyncio.create_task(self._receive_blocks())
|
||||
# Wait until receiver subscribed so we don't drop the initial burst
|
||||
await self._receiver_ready.wait()
|
||||
broadcast_task = asyncio.create_task(self._broadcast_blocks())
|
||||
|
||||
try:
|
||||
await self._stop_event.wait()
|
||||
finally:
|
||||
broadcast_task.cancel()
|
||||
receive_task.cancel()
|
||||
await asyncio.gather(broadcast_task, receive_task, return_exceptions=True)
|
||||
|
||||
if self._redis:
|
||||
await self._redis.close()
|
||||
|
||||
async def stop(self):
|
||||
"""Stop chain synchronization service"""
|
||||
logger.info("Stopping chain sync service")
|
||||
self._stop_event.set()
|
||||
|
||||
async def _broadcast_blocks(self):
|
||||
"""Broadcast local blocks to other nodes"""
|
||||
import aiohttp
|
||||
|
||||
last_broadcast_height = 0
|
||||
retry_count = 0
|
||||
max_retries = 5
|
||||
base_delay = 2
|
||||
|
||||
while not self._stop_event.is_set():
|
||||
try:
|
||||
# Get current head from local RPC
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(f"http://{self.source_host}:{self.source_port}/rpc/head") as resp:
|
||||
if resp.status == 200:
|
||||
head_data = await resp.json()
|
||||
current_height = head_data.get('height', 0)
|
||||
|
||||
# Reset retry count on successful connection
|
||||
retry_count = 0
|
||||
|
||||
# Broadcast new blocks
|
||||
if current_height > last_broadcast_height:
|
||||
for height in range(last_broadcast_height + 1, current_height + 1):
|
||||
block_data = await self._get_block_by_height(height, session)
|
||||
if block_data:
|
||||
await self._broadcast_block(block_data)
|
||||
|
||||
last_broadcast_height = current_height
|
||||
logger.info(f"Broadcasted blocks up to height {current_height}")
|
||||
elif resp.status == 429:
|
||||
raise Exception("rate_limit")
|
||||
else:
|
||||
raise Exception(f"RPC returned status {resp.status}")
|
||||
|
||||
except Exception as e:
|
||||
retry_count += 1
|
||||
# If rate-limited, wait longer before retrying
|
||||
if str(e) == "rate_limit":
|
||||
delay = base_delay * 30
|
||||
logger.warning(f"RPC rate limited, retrying in {delay}s")
|
||||
await asyncio.sleep(delay)
|
||||
continue
|
||||
if retry_count <= max_retries:
|
||||
delay = base_delay * (2 ** (retry_count - 1)) # Exponential backoff
|
||||
logger.warning(f"RPC connection failed (attempt {retry_count}/{max_retries}), retrying in {delay}s: {e}")
|
||||
await asyncio.sleep(delay)
|
||||
continue
|
||||
else:
|
||||
logger.error(f"RPC connection failed after {max_retries} attempts, waiting {base_delay * 10}s: {e}")
|
||||
await asyncio.sleep(base_delay * 10)
|
||||
retry_count = 0 # Reset retry count after long wait
|
||||
|
||||
await asyncio.sleep(base_delay) # Check every 2 seconds when connected
|
||||
|
||||
async def _receive_blocks(self):
|
||||
"""Receive blocks from other nodes via Redis"""
|
||||
if not self._redis:
|
||||
return
|
||||
|
||||
pubsub = self._redis.pubsub()
|
||||
await pubsub.subscribe("blocks")
|
||||
self._receiver_ready.set()
|
||||
|
||||
logger.info("Subscribed to block broadcasts")
|
||||
|
||||
async for message in pubsub.listen():
|
||||
if self._stop_event.is_set():
|
||||
break
|
||||
|
||||
if message['type'] == 'message':
|
||||
try:
|
||||
block_data = json.loads(message['data'])
|
||||
await self._import_block(block_data)
|
||||
except Exception as e:
|
||||
logger.error(f"Error processing received block: {e}")
|
||||
|
||||
async def _get_block_by_height(self, height: int, session) -> Optional[Dict[str, Any]]:
|
||||
"""Get block data by height from local RPC"""
|
||||
try:
|
||||
async with session.get(f"http://{self.source_host}:{self.source_port}/rpc/blocks-range?start={height}&end={height}") as resp:
|
||||
if resp.status == 200:
|
||||
blocks_data = await resp.json()
|
||||
blocks = blocks_data.get('blocks', [])
|
||||
block = blocks[0] if blocks else None
|
||||
return block
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting block {height}: {e}")
|
||||
return None
|
||||
|
||||
async def _broadcast_block(self, block_data: Dict[str, Any]):
|
||||
"""Broadcast block to other nodes via Redis"""
|
||||
if not self._redis:
|
||||
return
|
||||
|
||||
try:
|
||||
await self._redis.publish("blocks", json.dumps(block_data))
|
||||
logger.debug(f"Broadcasted block {block_data.get('height')}")
|
||||
except Exception as e:
|
||||
logger.error(f"Error broadcasting block: {e}")
|
||||
|
||||
async def _import_block(self, block_data: Dict[str, Any]):
|
||||
"""Import block from another node"""
|
||||
import aiohttp
|
||||
|
||||
try:
|
||||
# Don't import our own blocks
|
||||
if block_data.get('proposer') == self.node_id:
|
||||
return
|
||||
|
||||
# Determine target host - if we're a follower, import to leader, else import locally
|
||||
target_host = self.import_host
|
||||
target_port = self.import_port
|
||||
|
||||
# Retry logic for import
|
||||
max_retries = 3
|
||||
base_delay = 1
|
||||
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.post(
|
||||
f"http://{target_host}:{target_port}/rpc/importBlock",
|
||||
json=block_data
|
||||
) as resp:
|
||||
if resp.status == 200:
|
||||
result = await resp.json()
|
||||
if result.get('accepted'):
|
||||
logger.info(f"Imported block {block_data.get('height')} from {block_data.get('proposer')}")
|
||||
else:
|
||||
logger.debug(f"Rejected block {block_data.get('height')}: {result.get('reason')}")
|
||||
return
|
||||
else:
|
||||
try:
|
||||
body = await resp.text()
|
||||
except Exception:
|
||||
body = "<no body>"
|
||||
raise Exception(f"HTTP {resp.status}: {body}")
|
||||
|
||||
except Exception as e:
|
||||
if attempt < max_retries - 1:
|
||||
delay = base_delay * (2 ** attempt)
|
||||
logger.warning(f"Import failed (attempt {attempt + 1}/{max_retries}), retrying in {delay}s: {e}")
|
||||
await asyncio.sleep(delay)
|
||||
else:
|
||||
logger.error(f"Failed to import block {block_data.get('height')} after {max_retries} attempts: {e}")
|
||||
return
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error importing block: {e}")
|
||||
|
||||
async def run_chain_sync(
|
||||
redis_url: str,
|
||||
node_id: str,
|
||||
rpc_port: int = 8006,
|
||||
leader_host: str = None,
|
||||
source_host: str = "127.0.0.1",
|
||||
source_port: int = None,
|
||||
import_host: str = "127.0.0.1",
|
||||
import_port: int = None,
|
||||
):
|
||||
"""Run chain synchronization service"""
|
||||
service = ChainSyncService(
|
||||
redis_url=redis_url,
|
||||
node_id=node_id,
|
||||
rpc_port=rpc_port,
|
||||
leader_host=leader_host,
|
||||
source_host=source_host,
|
||||
source_port=source_port,
|
||||
import_host=import_host,
|
||||
import_port=import_port,
|
||||
)
|
||||
await service.start()
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="AITBC Chain Synchronization Service")
|
||||
parser.add_argument("--redis", default="redis://localhost:6379", help="Redis URL")
|
||||
parser.add_argument("--node-id", required=True, help="Node identifier")
|
||||
parser.add_argument("--rpc-port", type=int, default=8006, help="RPC port")
|
||||
parser.add_argument("--leader-host", help="Leader node host (for followers)")
|
||||
parser.add_argument("--source-host", default="127.0.0.1", help="Host to poll for head/blocks")
|
||||
parser.add_argument("--source-port", type=int, help="Port to poll for head/blocks")
|
||||
parser.add_argument("--import-host", default="127.0.0.1", help="Host to import blocks into")
|
||||
parser.add_argument("--import-port", type=int, help="Port to import blocks into")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
try:
|
||||
asyncio.run(run_chain_sync(
|
||||
args.redis,
|
||||
args.node_id,
|
||||
args.rpc_port,
|
||||
args.leader_host,
|
||||
args.source_host,
|
||||
args.source_port,
|
||||
args.import_host,
|
||||
args.import_port,
|
||||
))
|
||||
except KeyboardInterrupt:
|
||||
logger.info("Chain sync service stopped by user")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
94
apps/blockchain-node/src/aitbc_chain/combined_main.py
Normal file
94
apps/blockchain-node/src/aitbc_chain/combined_main.py
Normal file
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Combined blockchain node and P2P service launcher
|
||||
Runs both the main blockchain node and P2P placeholder service
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
import signal
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Add src to path
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
from aitbc_chain.main import BlockchainNode, _run as run_node
|
||||
from aitbc_chain.config import settings
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class CombinedService:
|
||||
def __init__(self):
|
||||
self._stop_event = asyncio.Event()
|
||||
self._tasks = []
|
||||
self._loop = None
|
||||
|
||||
def set_stop_event(self):
|
||||
"""Set the stop event to trigger shutdown"""
|
||||
if self._stop_event and not self._stop_event.is_set():
|
||||
self._stop_event.set()
|
||||
|
||||
async def start(self):
|
||||
"""Start both blockchain node and P2P server"""
|
||||
self._loop = asyncio.get_running_loop()
|
||||
logger.info("Starting combined blockchain service")
|
||||
|
||||
# Start blockchain node in background
|
||||
node_task = asyncio.create_task(run_node())
|
||||
self._tasks.append(node_task)
|
||||
|
||||
logger.info(f"Combined service started - Node on mainnet")
|
||||
|
||||
try:
|
||||
await self._stop_event.wait()
|
||||
finally:
|
||||
await self.stop()
|
||||
|
||||
async def stop(self):
|
||||
"""Stop all services"""
|
||||
logger.info("Stopping combined blockchain service")
|
||||
|
||||
# Cancel all tasks
|
||||
for task in self._tasks:
|
||||
task.cancel()
|
||||
|
||||
# Wait for tasks to complete
|
||||
if self._tasks:
|
||||
await asyncio.gather(*self._tasks, return_exceptions=True)
|
||||
|
||||
self._tasks.clear()
|
||||
logger.info("Combined service stopped")
|
||||
|
||||
# Global service instance for signal handler
|
||||
_service_instance = None
|
||||
|
||||
def signal_handler(signum, frame):
|
||||
"""Handle shutdown signals"""
|
||||
logger.info(f"Received signal {signum}, initiating shutdown")
|
||||
global _service_instance
|
||||
if _service_instance:
|
||||
_service_instance.set_stop_event()
|
||||
|
||||
async def main():
|
||||
"""Main entry point"""
|
||||
global _service_instance
|
||||
service = CombinedService()
|
||||
_service_instance = service
|
||||
|
||||
# Set up signal handlers
|
||||
signal.signal(signal.SIGTERM, signal_handler)
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
|
||||
try:
|
||||
await service.start()
|
||||
except KeyboardInterrupt:
|
||||
logger.info("Received keyboard interrupt")
|
||||
finally:
|
||||
await service.stop()
|
||||
_service_instance = None
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -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
|
||||
@@ -36,6 +36,9 @@ class ChainSettings(BaseSettings):
|
||||
|
||||
block_time_seconds: int = 2
|
||||
|
||||
# Block production toggle (set false on followers)
|
||||
enable_block_production: bool = True
|
||||
|
||||
# Block production limits
|
||||
max_block_size_bytes: int = 1_000_000 # 1 MB
|
||||
max_txs_per_block: int = 500
|
||||
|
||||
@@ -120,11 +120,11 @@ class PoAProposer:
|
||||
return
|
||||
|
||||
async def _propose_block(self) -> None:
|
||||
# Check internal mempool
|
||||
# Check internal mempool and include transactions
|
||||
from ..mempool import get_mempool
|
||||
if get_mempool().size(self._config.chain_id) == 0:
|
||||
return
|
||||
|
||||
from ..models import Transaction, Account
|
||||
mempool = get_mempool()
|
||||
|
||||
with self._session_factory() as session:
|
||||
head = session.exec(select(Block).where(Block.chain_id == self._config.chain_id).order_by(Block.height.desc()).limit(1)).first()
|
||||
next_height = 0
|
||||
@@ -136,7 +136,71 @@ class PoAProposer:
|
||||
interval_seconds = (datetime.utcnow() - head.timestamp).total_seconds()
|
||||
|
||||
timestamp = datetime.utcnow()
|
||||
block_hash = self._compute_block_hash(next_height, parent_hash, timestamp)
|
||||
|
||||
# Pull transactions from mempool
|
||||
max_txs = self._config.max_txs_per_block
|
||||
max_bytes = self._config.max_block_size_bytes
|
||||
pending_txs = mempool.drain(max_txs, max_bytes, self._config.chain_id)
|
||||
self._logger.info(f"[PROPOSE] drained {len(pending_txs)} txs from mempool, chain={self._config.chain_id}")
|
||||
|
||||
# Process transactions and update balances
|
||||
processed_txs = []
|
||||
for tx in pending_txs:
|
||||
try:
|
||||
# Parse transaction data
|
||||
tx_data = tx.content
|
||||
sender = tx_data.get("sender")
|
||||
recipient = tx_data.get("payload", {}).get("to")
|
||||
value = tx_data.get("payload", {}).get("value", 0)
|
||||
fee = tx_data.get("fee", 0)
|
||||
|
||||
if not sender or not recipient:
|
||||
continue
|
||||
|
||||
# Get sender account
|
||||
sender_account = session.get(Account, (self._config.chain_id, sender))
|
||||
if not sender_account:
|
||||
continue
|
||||
|
||||
# Check sufficient balance
|
||||
total_cost = value + fee
|
||||
if sender_account.balance < total_cost:
|
||||
continue
|
||||
|
||||
# Get or create recipient account
|
||||
recipient_account = session.get(Account, (self._config.chain_id, recipient))
|
||||
if not recipient_account:
|
||||
recipient_account = Account(chain_id=self._config.chain_id, address=recipient, balance=0, nonce=0)
|
||||
session.add(recipient_account)
|
||||
session.flush()
|
||||
|
||||
# Update balances
|
||||
sender_account.balance -= total_cost
|
||||
sender_account.nonce += 1
|
||||
recipient_account.balance += value
|
||||
|
||||
# Create transaction record
|
||||
transaction = Transaction(
|
||||
chain_id=self._config.chain_id,
|
||||
tx_hash=tx.tx_hash,
|
||||
sender=sender,
|
||||
recipient=recipient,
|
||||
value=value,
|
||||
fee=fee,
|
||||
nonce=sender_account.nonce - 1,
|
||||
timestamp=timestamp,
|
||||
block_height=next_height,
|
||||
status="confirmed"
|
||||
)
|
||||
session.add(transaction)
|
||||
processed_txs.append(tx)
|
||||
|
||||
except Exception as e:
|
||||
self._logger.warning(f"Failed to process transaction {tx.tx_hash}: {e}")
|
||||
continue
|
||||
|
||||
# Compute block hash with transaction data
|
||||
block_hash = self._compute_block_hash(next_height, parent_hash, timestamp, processed_txs)
|
||||
|
||||
block = Block(
|
||||
chain_id=self._config.chain_id,
|
||||
@@ -145,7 +209,7 @@ class PoAProposer:
|
||||
parent_hash=parent_hash,
|
||||
proposer=self._config.proposer_id,
|
||||
timestamp=timestamp,
|
||||
tx_count=0,
|
||||
tx_count=len(processed_txs),
|
||||
state_root=None,
|
||||
)
|
||||
session.add(block)
|
||||
@@ -258,6 +322,11 @@ class PoAProposer:
|
||||
with self._session_factory() as session:
|
||||
return session.exec(select(Block).order_by(Block.height.desc()).limit(1)).first()
|
||||
|
||||
def _compute_block_hash(self, height: int, parent_hash: str, timestamp: datetime) -> str:
|
||||
payload = f"{self._config.chain_id}|{height}|{parent_hash}|{timestamp.isoformat()}".encode()
|
||||
def _compute_block_hash(self, height: int, parent_hash: str, timestamp: datetime, transactions: list = None) -> str:
|
||||
# Include transaction hashes in block hash computation
|
||||
tx_hashes = []
|
||||
if transactions:
|
||||
tx_hashes = [tx.tx_hash for tx in transactions]
|
||||
|
||||
payload = f"{self._config.chain_id}|{height}|{parent_hash}|{timestamp.isoformat()}|{'|'.join(sorted(tx_hashes))}".encode()
|
||||
return "0x" + hashlib.sha256(payload).hexdigest()
|
||||
|
||||
@@ -103,7 +103,7 @@ class BlockchainNode:
|
||||
if isinstance(tx_data, str):
|
||||
import json
|
||||
tx_data = json.loads(tx_data)
|
||||
chain_id = tx_data.get("chain_id", "ait-devnet")
|
||||
chain_id = tx_data.get("chain_id", settings.chain_id)
|
||||
mempool.add(tx_data, chain_id=chain_id)
|
||||
except Exception as exc:
|
||||
logger.error(f"Error processing transaction from gossip: {exc}")
|
||||
@@ -121,7 +121,7 @@ class BlockchainNode:
|
||||
if isinstance(block_data, str):
|
||||
import json
|
||||
block_data = json.loads(block_data)
|
||||
chain_id = block_data.get("chain_id", "ait-devnet")
|
||||
chain_id = block_data.get("chain_id", settings.chain_id)
|
||||
logger.info(f"Importing block for chain {chain_id}: {block_data.get('height')}")
|
||||
sync = ChainSync(session_factory=session_scope, chain_id=chain_id)
|
||||
res = sync.import_block(block_data)
|
||||
@@ -148,7 +148,11 @@ class BlockchainNode:
|
||||
max_size=settings.mempool_max_size,
|
||||
min_fee=settings.min_fee,
|
||||
)
|
||||
self._start_proposers()
|
||||
# Start proposers only if enabled (followers set enable_block_production=False)
|
||||
if getattr(settings, "enable_block_production", True):
|
||||
self._start_proposers()
|
||||
else:
|
||||
logger.info("Block production disabled on this node", extra={"proposer_id": settings.proposer_id})
|
||||
await self._setup_gossip_subscribers()
|
||||
try:
|
||||
await self._stop_event.wait()
|
||||
|
||||
@@ -38,7 +38,10 @@ class InMemoryMempool:
|
||||
self._max_size = max_size
|
||||
self._min_fee = min_fee
|
||||
|
||||
def add(self, tx: Dict[str, Any], chain_id: str = "ait-devnet") -> str:
|
||||
def add(self, tx: Dict[str, Any], chain_id: str = None) -> str:
|
||||
from .config import settings
|
||||
if chain_id is None:
|
||||
chain_id = settings.chain_id
|
||||
fee = tx.get("fee", 0)
|
||||
if fee < self._min_fee:
|
||||
raise ValueError(f"Fee {fee} below minimum {self._min_fee}")
|
||||
@@ -59,11 +62,17 @@ class InMemoryMempool:
|
||||
metrics_registry.increment(f"mempool_tx_added_total_{chain_id}")
|
||||
return tx_hash
|
||||
|
||||
def list_transactions(self, chain_id: str = "ait-devnet") -> List[PendingTransaction]:
|
||||
def list_transactions(self, chain_id: str = None) -> List[PendingTransaction]:
|
||||
from .config import settings
|
||||
if chain_id is None:
|
||||
chain_id = settings.chain_id
|
||||
with self._lock:
|
||||
return list(self._transactions.values())
|
||||
|
||||
def drain(self, max_count: int, max_bytes: int, chain_id: str = "ait-devnet") -> List[PendingTransaction]:
|
||||
def drain(self, max_count: int, max_bytes: int, chain_id: str = None) -> List[PendingTransaction]:
|
||||
from .config import settings
|
||||
if chain_id is None:
|
||||
chain_id = settings.chain_id
|
||||
"""Drain transactions for block inclusion, prioritized by fee (highest first)."""
|
||||
with self._lock:
|
||||
sorted_txs = sorted(
|
||||
@@ -87,14 +96,20 @@ class InMemoryMempool:
|
||||
metrics_registry.increment(f"mempool_tx_drained_total_{chain_id}", float(len(result)))
|
||||
return result
|
||||
|
||||
def remove(self, tx_hash: str, chain_id: str = "ait-devnet") -> bool:
|
||||
def remove(self, tx_hash: str, chain_id: str = None) -> bool:
|
||||
from .config import settings
|
||||
if chain_id is None:
|
||||
chain_id = settings.chain_id
|
||||
with self._lock:
|
||||
removed = self._transactions.pop(tx_hash, None) is not None
|
||||
if removed:
|
||||
metrics_registry.set_gauge("mempool_size", float(len(self._transactions)))
|
||||
return removed
|
||||
|
||||
def size(self, chain_id: str = "ait-devnet") -> int:
|
||||
def size(self, chain_id: str = None) -> int:
|
||||
from .config import settings
|
||||
if chain_id is None:
|
||||
chain_id = settings.chain_id
|
||||
with self._lock:
|
||||
return len(self._transactions)
|
||||
|
||||
@@ -135,7 +150,10 @@ class DatabaseMempool:
|
||||
self._conn.execute("CREATE INDEX IF NOT EXISTS idx_mempool_fee ON mempool(fee DESC)")
|
||||
self._conn.commit()
|
||||
|
||||
def add(self, tx: Dict[str, Any], chain_id: str = "ait-devnet") -> str:
|
||||
def add(self, tx: Dict[str, Any], chain_id: str = None) -> str:
|
||||
from .config import settings
|
||||
if chain_id is None:
|
||||
chain_id = settings.chain_id
|
||||
fee = tx.get("fee", 0)
|
||||
if fee < self._min_fee:
|
||||
raise ValueError(f"Fee {fee} below minimum {self._min_fee}")
|
||||
@@ -169,7 +187,10 @@ class DatabaseMempool:
|
||||
self._update_gauge(chain_id)
|
||||
return tx_hash
|
||||
|
||||
def list_transactions(self, chain_id: str = "ait-devnet") -> List[PendingTransaction]:
|
||||
def list_transactions(self, chain_id: str = None) -> List[PendingTransaction]:
|
||||
from .config import settings
|
||||
if chain_id is None:
|
||||
chain_id = settings.chain_id
|
||||
with self._lock:
|
||||
rows = self._conn.execute(
|
||||
"SELECT tx_hash, content, fee, size_bytes, received_at FROM mempool WHERE chain_id = ? ORDER BY fee DESC, received_at ASC",
|
||||
@@ -182,7 +203,10 @@ class DatabaseMempool:
|
||||
) for r in rows
|
||||
]
|
||||
|
||||
def drain(self, max_count: int, max_bytes: int, chain_id: str = "ait-devnet") -> List[PendingTransaction]:
|
||||
def drain(self, max_count: int, max_bytes: int, chain_id: str = None) -> List[PendingTransaction]:
|
||||
from .config import settings
|
||||
if chain_id is None:
|
||||
chain_id = settings.chain_id
|
||||
with self._lock:
|
||||
rows = self._conn.execute(
|
||||
"SELECT tx_hash, content, fee, size_bytes, received_at FROM mempool WHERE chain_id = ? ORDER BY fee DESC, received_at ASC",
|
||||
@@ -214,7 +238,10 @@ class DatabaseMempool:
|
||||
self._update_gauge(chain_id)
|
||||
return result
|
||||
|
||||
def remove(self, tx_hash: str, chain_id: str = "ait-devnet") -> bool:
|
||||
def remove(self, tx_hash: str, chain_id: str = None) -> bool:
|
||||
from .config import settings
|
||||
if chain_id is None:
|
||||
chain_id = settings.chain_id
|
||||
with self._lock:
|
||||
cursor = self._conn.execute("DELETE FROM mempool WHERE chain_id = ? AND tx_hash = ?", (chain_id, tx_hash))
|
||||
self._conn.commit()
|
||||
@@ -223,11 +250,17 @@ class DatabaseMempool:
|
||||
self._update_gauge(chain_id)
|
||||
return removed
|
||||
|
||||
def size(self, chain_id: str = "ait-devnet") -> int:
|
||||
def size(self, chain_id: str = None) -> int:
|
||||
from .config import settings
|
||||
if chain_id is None:
|
||||
chain_id = settings.chain_id
|
||||
with self._lock:
|
||||
return self._conn.execute("SELECT COUNT(*) FROM mempool WHERE chain_id = ?", (chain_id,)).fetchone()[0]
|
||||
|
||||
def _update_gauge(self, chain_id: str = "ait-devnet") -> None:
|
||||
def _update_gauge(self, chain_id: str = None) -> None:
|
||||
from .config import settings
|
||||
if chain_id is None:
|
||||
chain_id = settings.chain_id
|
||||
count = self._conn.execute("SELECT COUNT(*) FROM mempool WHERE chain_id = ?", (chain_id,)).fetchone()[0]
|
||||
metrics_registry.set_gauge(f"mempool_size_{chain_id}", float(count))
|
||||
|
||||
|
||||
106
apps/blockchain-node/src/aitbc_chain/p2p_network.py
Normal file
106
apps/blockchain-node/src/aitbc_chain/p2p_network.py
Normal file
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
P2P Network Service using Redis Gossip
|
||||
Handles peer-to-peer communication between blockchain nodes
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import socket
|
||||
from typing import Dict, Any, Optional
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class P2PNetworkService:
|
||||
def __init__(self, host: str, port: int, redis_url: str, node_id: str):
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.redis_url = redis_url
|
||||
self.node_id = node_id
|
||||
self._server = None
|
||||
self._stop_event = asyncio.Event()
|
||||
|
||||
async def start(self):
|
||||
"""Start P2P network service"""
|
||||
logger.info(f"Starting P2P network service on {self.host}:{self.port}")
|
||||
|
||||
# Create TCP server for P2P connections
|
||||
self._server = await asyncio.start_server(
|
||||
self._handle_connection,
|
||||
self.host,
|
||||
self.port
|
||||
)
|
||||
|
||||
logger.info(f"P2P service listening on {self.host}:{self.port}")
|
||||
|
||||
try:
|
||||
await self._stop_event.wait()
|
||||
finally:
|
||||
await self.stop()
|
||||
|
||||
async def stop(self):
|
||||
"""Stop P2P network service"""
|
||||
logger.info("Stopping P2P network service")
|
||||
if self._server:
|
||||
self._server.close()
|
||||
await self._server.wait_closed()
|
||||
|
||||
async def _handle_connection(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
|
||||
"""Handle incoming P2P connections"""
|
||||
addr = writer.get_extra_info('peername')
|
||||
logger.info(f"P2P connection from {addr}")
|
||||
|
||||
try:
|
||||
while True:
|
||||
data = await reader.read(1024)
|
||||
if not data:
|
||||
break
|
||||
|
||||
try:
|
||||
message = json.loads(data.decode())
|
||||
logger.info(f"P2P received: {message}")
|
||||
|
||||
# Handle different message types
|
||||
if message.get('type') == 'ping':
|
||||
response = {'type': 'pong', 'node_id': self.node_id}
|
||||
writer.write(json.dumps(response).encode() + b'\n')
|
||||
await writer.drain()
|
||||
|
||||
except json.JSONDecodeError:
|
||||
logger.warning(f"Invalid JSON from {addr}")
|
||||
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
except Exception as e:
|
||||
logger.error(f"P2P connection error: {e}")
|
||||
finally:
|
||||
writer.close()
|
||||
await writer.wait_closed()
|
||||
logger.info(f"P2P connection closed from {addr}")
|
||||
|
||||
async def run_p2p_service(host: str, port: int, redis_url: str, node_id: str):
|
||||
"""Run P2P service"""
|
||||
service = P2PNetworkService(host, port, redis_url, node_id)
|
||||
await service.start()
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="AITBC P2P Network Service")
|
||||
parser.add_argument("--host", default="0.0.0.0", help="Bind host")
|
||||
parser.add_argument("--port", type=int, default=8005, help="Bind port")
|
||||
parser.add_argument("--redis", default="redis://localhost:6379", help="Redis URL")
|
||||
parser.add_argument("--node-id", help="Node identifier")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
try:
|
||||
asyncio.run(run_p2p_service(args.host, args.port, args.redis, args.node_id))
|
||||
except KeyboardInterrupt:
|
||||
logger.info("P2P service stopped by user")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -18,6 +18,13 @@ from ..models import Account, Block, Receipt, Transaction
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
def get_chain_id(chain_id: str = None) -> str:
|
||||
"""Get chain_id from parameter or use default from settings"""
|
||||
if chain_id is None:
|
||||
from ..config import settings
|
||||
return settings.chain_id
|
||||
return chain_id
|
||||
|
||||
|
||||
def _serialize_receipt(receipt: Receipt) -> Dict[str, Any]:
|
||||
return {
|
||||
@@ -63,7 +70,14 @@ class EstimateFeeRequest(BaseModel):
|
||||
|
||||
|
||||
@router.get("/head", summary="Get current chain head")
|
||||
async def get_head(chain_id: str = "ait-devnet") -> Dict[str, Any]:
|
||||
async def get_head(chain_id: str = None) -> Dict[str, Any]:
|
||||
"""Get current chain head"""
|
||||
from ..config import settings as cfg
|
||||
|
||||
# Use default chain_id from settings if not provided
|
||||
if chain_id is None:
|
||||
chain_id = cfg.chain_id
|
||||
|
||||
metrics_registry.increment("rpc_get_head_total")
|
||||
start = time.perf_counter()
|
||||
with session_scope() as session:
|
||||
@@ -96,6 +110,7 @@ async def get_block(height: int) -> Dict[str, Any]:
|
||||
"height": block.height,
|
||||
"hash": block.hash,
|
||||
"parent_hash": block.parent_hash,
|
||||
"proposer": block.proposer,
|
||||
"timestamp": block.timestamp.isoformat(),
|
||||
"tx_count": block.tx_count,
|
||||
"state_root": block.state_root,
|
||||
@@ -140,6 +155,7 @@ async def get_blocks_range(start: int, end: int) -> Dict[str, Any]:
|
||||
"height": block.height,
|
||||
"hash": block.hash,
|
||||
"parent_hash": block.parent_hash,
|
||||
"proposer": block.proposer,
|
||||
"timestamp": block.timestamp.isoformat(),
|
||||
"tx_count": block.tx_count,
|
||||
"state_root": block.state_root,
|
||||
@@ -157,7 +173,8 @@ async def get_blocks_range(start: int, end: int) -> Dict[str, Any]:
|
||||
|
||||
|
||||
@router.get("/tx/{tx_hash}", summary="Get transaction by hash")
|
||||
async def get_transaction(tx_hash: str, chain_id: str = "ait-devnet") -> Dict[str, Any]:
|
||||
async def get_transaction(tx_hash: str, chain_id: str = None) -> Dict[str, Any]:
|
||||
chain_id = get_chain_id(chain_id)
|
||||
metrics_registry.increment("rpc_get_transaction_total")
|
||||
start = time.perf_counter()
|
||||
with session_scope() as session:
|
||||
@@ -296,7 +313,8 @@ async def get_receipts(limit: int = 20, offset: int = 0) -> Dict[str, Any]:
|
||||
|
||||
|
||||
@router.get("/getBalance/{address}", summary="Get account balance")
|
||||
async def get_balance(address: str, chain_id: str = "ait-devnet") -> Dict[str, Any]:
|
||||
async def get_balance(address: str, chain_id: str = None) -> Dict[str, Any]:
|
||||
chain_id = get_chain_id(chain_id)
|
||||
metrics_registry.increment("rpc_get_balance_total")
|
||||
start = time.perf_counter()
|
||||
with session_scope() as session:
|
||||
@@ -442,7 +460,7 @@ async def get_addresses(limit: int = 20, offset: int = 0, min_balance: int = 0)
|
||||
|
||||
|
||||
@router.post("/sendTx", summary="Submit a new transaction")
|
||||
async def send_transaction(request: TransactionRequest, chain_id: str = "ait-devnet") -> Dict[str, Any]:
|
||||
async def send_transaction(request: TransactionRequest, chain_id: str = None) -> Dict[str, Any]:
|
||||
metrics_registry.increment("rpc_send_tx_total")
|
||||
start = time.perf_counter()
|
||||
mempool = get_mempool()
|
||||
@@ -481,7 +499,7 @@ async def send_transaction(request: TransactionRequest, chain_id: str = "ait-dev
|
||||
|
||||
|
||||
@router.post("/submitReceipt", summary="Submit receipt claim transaction")
|
||||
async def submit_receipt(request: ReceiptSubmissionRequest, chain_id: str = "ait-devnet") -> Dict[str, Any]:
|
||||
async def submit_receipt(request: ReceiptSubmissionRequest, chain_id: str = None) -> Dict[str, Any]:
|
||||
metrics_registry.increment("rpc_submit_receipt_total")
|
||||
start = time.perf_counter()
|
||||
tx_payload = {
|
||||
@@ -539,7 +557,7 @@ class ImportBlockRequest(BaseModel):
|
||||
|
||||
|
||||
@router.post("/importBlock", summary="Import a block from a remote peer")
|
||||
async def import_block(request: ImportBlockRequest, chain_id: str = "ait-devnet") -> Dict[str, Any]:
|
||||
async def import_block(request: ImportBlockRequest, chain_id: str = None) -> Dict[str, Any]:
|
||||
from ..sync import ChainSync, ProposerSignatureValidator
|
||||
from ..config import settings as cfg
|
||||
|
||||
@@ -578,7 +596,7 @@ async def import_block(request: ImportBlockRequest, chain_id: str = "ait-devnet"
|
||||
|
||||
|
||||
@router.get("/syncStatus", summary="Get chain sync status")
|
||||
async def sync_status(chain_id: str = "ait-devnet") -> Dict[str, Any]:
|
||||
async def sync_status(chain_id: str = None) -> Dict[str, Any]:
|
||||
from ..sync import ChainSync
|
||||
from ..config import settings as cfg
|
||||
|
||||
@@ -588,7 +606,7 @@ async def sync_status(chain_id: str = "ait-devnet") -> Dict[str, Any]:
|
||||
|
||||
|
||||
@router.get("/info", summary="Get blockchain information")
|
||||
async def get_blockchain_info(chain_id: str = "ait-devnet") -> Dict[str, Any]:
|
||||
async def get_blockchain_info(chain_id: str = None) -> Dict[str, Any]:
|
||||
"""Get comprehensive blockchain information"""
|
||||
from ..config import settings as cfg
|
||||
|
||||
@@ -634,31 +652,48 @@ async def get_blockchain_info(chain_id: str = "ait-devnet") -> Dict[str, Any]:
|
||||
|
||||
|
||||
@router.get("/supply", summary="Get token supply information")
|
||||
async def get_token_supply(chain_id: str = "ait-devnet") -> Dict[str, Any]:
|
||||
async def get_token_supply(chain_id: str = None) -> Dict[str, Any]:
|
||||
"""Get token supply information"""
|
||||
from ..config import settings as cfg
|
||||
from ..models import Account
|
||||
|
||||
chain_id = get_chain_id(chain_id)
|
||||
metrics_registry.increment("rpc_supply_total")
|
||||
start = time.perf_counter()
|
||||
|
||||
with session_scope() as session:
|
||||
# Simple implementation for now
|
||||
response = {
|
||||
"chain_id": chain_id,
|
||||
"total_supply": 1000000000, # 1 billion from genesis
|
||||
"circulating_supply": 0, # No transactions yet
|
||||
"faucet_balance": 1000000000, # All tokens in faucet
|
||||
"faucet_address": "ait1faucet000000000000000000000000000000000",
|
||||
"mint_per_unit": cfg.mint_per_unit,
|
||||
"total_accounts": 0
|
||||
}
|
||||
# Calculate actual values from database
|
||||
accounts = session.exec(select(Account).where(Account.chain_id == chain_id)).all()
|
||||
total_balance = sum(account.balance for account in accounts)
|
||||
total_accounts = len(accounts)
|
||||
|
||||
# Production implementation - calculate real circulating supply
|
||||
if chain_id == "ait-mainnet":
|
||||
response = {
|
||||
"chain_id": chain_id,
|
||||
"total_supply": 1000000000, # 1 billion from genesis
|
||||
"circulating_supply": total_balance, # Actual tokens in circulation
|
||||
"mint_per_unit": cfg.mint_per_unit,
|
||||
"total_accounts": total_accounts # Actual account count
|
||||
}
|
||||
else:
|
||||
# Devnet with faucet - use actual calculations
|
||||
response = {
|
||||
"chain_id": chain_id,
|
||||
"total_supply": 1000000000, # 1 billion from genesis
|
||||
"circulating_supply": total_balance, # Actual tokens in circulation
|
||||
"faucet_balance": 1000000000, # All tokens in faucet
|
||||
"faucet_address": "ait1faucet000000000000000000000000000000000",
|
||||
"mint_per_unit": cfg.mint_per_unit,
|
||||
"total_accounts": total_accounts # Actual account count
|
||||
}
|
||||
|
||||
metrics_registry.observe("rpc_supply_duration_seconds", time.perf_counter() - start)
|
||||
return response
|
||||
|
||||
|
||||
@router.get("/validators", summary="List blockchain validators")
|
||||
async def get_validators(chain_id: str = "ait-devnet") -> Dict[str, Any]:
|
||||
async def get_validators(chain_id: str = None) -> Dict[str, Any]:
|
||||
"""List blockchain validators (authorities)"""
|
||||
from ..config import settings as cfg
|
||||
|
||||
@@ -690,7 +725,7 @@ async def get_validators(chain_id: str = "ait-devnet") -> Dict[str, Any]:
|
||||
|
||||
|
||||
@router.get("/state", summary="Get blockchain state information")
|
||||
async def get_chain_state(chain_id: str = "ait-devnet"):
|
||||
async def get_chain_state(chain_id: str = None):
|
||||
"""Get blockchain state information for a chain"""
|
||||
start = time.perf_counter()
|
||||
|
||||
@@ -710,7 +745,7 @@ async def get_chain_state(chain_id: str = "ait-devnet"):
|
||||
|
||||
|
||||
@router.get("/rpc/getBalance/{address}", summary="Get account balance")
|
||||
async def get_balance(address: str, chain_id: str = "ait-devnet"):
|
||||
async def get_balance(address: str, chain_id: str = None):
|
||||
"""Get account balance for a specific address"""
|
||||
start = time.perf_counter()
|
||||
|
||||
@@ -753,7 +788,7 @@ async def get_balance(address: str, chain_id: str = "ait-devnet"):
|
||||
|
||||
|
||||
@router.get("/rpc/head", summary="Get current chain head")
|
||||
async def get_head(chain_id: str = "ait-devnet"):
|
||||
async def get_head(chain_id: str = None):
|
||||
"""Get current chain head block"""
|
||||
start = time.perf_counter()
|
||||
|
||||
@@ -799,7 +834,7 @@ async def get_head(chain_id: str = "ait-devnet"):
|
||||
|
||||
|
||||
@router.get("/rpc/transactions", summary="Get latest transactions")
|
||||
async def get_transactions(chain_id: str = "ait-devnet", limit: int = 20, offset: int = 0):
|
||||
async def get_transactions(chain_id: str = None, limit: int = 20, offset: int = 0):
|
||||
"""Get latest transactions"""
|
||||
start = time.perf_counter()
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ from sqlmodel import Session, select
|
||||
from .config import settings
|
||||
from .logger import get_logger
|
||||
from .metrics import metrics_registry
|
||||
from .models import Block, Transaction
|
||||
from .models import Block, Transaction, Account
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
@@ -284,15 +284,45 @@ class ChainSync:
|
||||
)
|
||||
session.add(block)
|
||||
|
||||
# Import transactions if provided
|
||||
# Import transactions if provided and apply state changes
|
||||
if transactions:
|
||||
for tx_data in transactions:
|
||||
sender_addr = tx_data.get("sender", "")
|
||||
payload = tx_data.get("payload", {}) or {}
|
||||
recipient_addr = payload.get("to") or tx_data.get("recipient", "")
|
||||
value = int(payload.get("value", 0) or 0)
|
||||
fee = int(tx_data.get("fee", 0) or 0)
|
||||
tx_hash = tx_data.get("tx_hash", "")
|
||||
|
||||
# Upsert sender/recipient accounts
|
||||
sender_acct = session.get(Account, (self._chain_id, sender_addr))
|
||||
if sender_acct is None:
|
||||
sender_acct = Account(chain_id=self._chain_id, address=sender_addr, balance=0, nonce=0)
|
||||
session.add(sender_acct)
|
||||
session.flush()
|
||||
|
||||
recipient_acct = session.get(Account, (self._chain_id, recipient_addr))
|
||||
if recipient_acct is None:
|
||||
recipient_acct = Account(chain_id=self._chain_id, address=recipient_addr, balance=0, nonce=0)
|
||||
session.add(recipient_acct)
|
||||
session.flush()
|
||||
|
||||
# Apply balances/nonce; assume block validity already verified on producer
|
||||
total_cost = value + fee
|
||||
sender_acct.balance -= total_cost
|
||||
tx_nonce = tx_data.get("nonce")
|
||||
if tx_nonce is not None:
|
||||
sender_acct.nonce = max(sender_acct.nonce, int(tx_nonce) + 1)
|
||||
else:
|
||||
sender_acct.nonce += 1
|
||||
recipient_acct.balance += value
|
||||
|
||||
tx = Transaction(
|
||||
chain_id=self._chain_id,
|
||||
tx_hash=tx_data.get("tx_hash", ""),
|
||||
tx_hash=tx_hash,
|
||||
block_height=block_data["height"],
|
||||
sender=tx_data.get("sender", ""),
|
||||
recipient=tx_data.get("recipient", ""),
|
||||
sender=sender_addr,
|
||||
recipient=recipient_addr,
|
||||
payload=tx_data,
|
||||
)
|
||||
session.add(tx)
|
||||
|
||||
@@ -9,12 +9,57 @@ from ..core.genesis_generator import GenesisGenerator, GenesisValidationError
|
||||
from ..core.config import MultiChainConfig, load_multichain_config
|
||||
from ..models.chain import GenesisConfig
|
||||
from ..utils import output, error, success
|
||||
from .keystore import create_keystore_via_script
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
@click.group()
|
||||
def genesis():
|
||||
"""Genesis block generation and management commands"""
|
||||
pass
|
||||
|
||||
|
||||
@genesis.command()
|
||||
@click.option('--address', required=True, help='Wallet address (id) to create')
|
||||
@click.option('--password-file', default='/opt/aitbc/data/keystore/.password', show_default=True, type=click.Path(exists=True, dir_okay=False), help='Path to password file')
|
||||
@click.option('--output-dir', default='/opt/aitbc/data/keystore', show_default=True, help='Directory to write keystore file')
|
||||
@click.option('--force', is_flag=True, help='Overwrite existing keystore file if present')
|
||||
@click.pass_context
|
||||
def create_keystore(ctx, address, password_file, output_dir, force):
|
||||
"""Create an encrypted keystore for a genesis/treasury address."""
|
||||
try:
|
||||
create_keystore_via_script(address=address, password_file=password_file, output_dir=output_dir, force=force)
|
||||
success(f"Created keystore for {address} at {output_dir}")
|
||||
except Exception as e:
|
||||
error(f"Error creating keystore: {e}")
|
||||
raise click.Abort()
|
||||
|
||||
|
||||
@genesis.command(name="init-production")
|
||||
@click.option('--chain-id', default='ait-mainnet', show_default=True, help='Chain ID to initialize')
|
||||
@click.option('--genesis-file', default='data/genesis_prod.yaml', show_default=True, help='Path to genesis YAML (copy to /opt/aitbc/genesis_prod.yaml if needed)')
|
||||
@click.option('--db', default='/opt/aitbc/data/ait-mainnet/chain.db', show_default=True, help='SQLite DB path')
|
||||
@click.option('--force', is_flag=True, help='Overwrite existing DB (removes file if present)')
|
||||
@click.pass_context
|
||||
def init_production(ctx, chain_id, genesis_file, db, force):
|
||||
"""Initialize production chain DB using genesis allocations."""
|
||||
db_path = Path(db)
|
||||
if db_path.exists() and force:
|
||||
db_path.unlink()
|
||||
python_bin = Path(__file__).resolve().parents[3] / 'apps' / 'blockchain-node' / '.venv' / 'bin' / 'python3'
|
||||
cmd = [
|
||||
str(python_bin),
|
||||
str(Path(__file__).resolve().parents[3] / 'scripts' / 'init_production_genesis.py'),
|
||||
'--chain-id', chain_id,
|
||||
'--db', db,
|
||||
]
|
||||
try:
|
||||
subprocess.run(cmd, check=True)
|
||||
success(f"Initialized production genesis for {chain_id} at {db}")
|
||||
except subprocess.CalledProcessError as e:
|
||||
error(f"Genesis init failed: {e}")
|
||||
raise click.Abort()
|
||||
|
||||
@genesis.command()
|
||||
@click.argument('config_file', type=click.Path(exists=True))
|
||||
@click.option('--output', '-o', 'output_file', help='Output file path')
|
||||
|
||||
67
cli/aitbc_cli/commands/keystore.py
Normal file
67
cli/aitbc_cli/commands/keystore.py
Normal file
@@ -0,0 +1,67 @@
|
||||
import click
|
||||
import importlib.util
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def _load_keystore_script():
|
||||
"""Dynamically load the top-level scripts/keystore.py module."""
|
||||
root = Path(__file__).resolve().parents[3] # /opt/aitbc
|
||||
ks_path = root / "scripts" / "keystore.py"
|
||||
spec = importlib.util.spec_from_file_location("aitbc_scripts_keystore", ks_path)
|
||||
if spec is None or spec.loader is None:
|
||||
raise ImportError(f"Unable to load keystore script from {ks_path}")
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
return module
|
||||
|
||||
@click.group()
|
||||
def keystore():
|
||||
"""Keystore operations (create wallets/keystores)."""
|
||||
pass
|
||||
|
||||
@keystore.command()
|
||||
@click.option("--address", required=True, help="Wallet address (id) to create")
|
||||
@click.option(
|
||||
"--password-file",
|
||||
default="/opt/aitbc/data/keystore/.password",
|
||||
show_default=True,
|
||||
type=click.Path(exists=True, dir_okay=False),
|
||||
help="Path to password file",
|
||||
)
|
||||
@click.option(
|
||||
"--output",
|
||||
default="/opt/aitbc/data/keystore",
|
||||
show_default=True,
|
||||
help="Directory to write keystore files",
|
||||
)
|
||||
@click.option(
|
||||
"--force",
|
||||
is_flag=True,
|
||||
help="Overwrite existing keystore file if present",
|
||||
)
|
||||
@click.pass_context
|
||||
def create(ctx, address: str, password_file: str, output: str, force: bool):
|
||||
"""Create an encrypted keystore for the given address.
|
||||
|
||||
Examples:
|
||||
aitbc keystore create --address aitbc1genesis
|
||||
aitbc keystore create --address aitbc1treasury --password-file keystore/.password --output keystore
|
||||
"""
|
||||
pwd_path = Path(password_file)
|
||||
with open(pwd_path, "r", encoding="utf-8") as f:
|
||||
password = f.read().strip()
|
||||
out_dir = Path(output) if output else Path("/opt/aitbc/data/keystore")
|
||||
out_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
ks_module = _load_keystore_script()
|
||||
ks_module.create_keystore(address=address, password=password, keystore_dir=out_dir, force=force)
|
||||
click.echo(f"Created keystore for {address} at {out_dir}")
|
||||
|
||||
|
||||
# Helper so other commands (genesis) can reuse the same logic
|
||||
def create_keystore_via_script(address: str, password_file: str = "/opt/aitbc/data/keystore/.password", output_dir: str = "/opt/aitbc/data/keystore", force: bool = False):
|
||||
pwd = Path(password_file).read_text(encoding="utf-8").strip()
|
||||
out_dir = Path(output_dir)
|
||||
out_dir.mkdir(parents=True, exist_ok=True)
|
||||
ks_module = _load_keystore_script()
|
||||
ks_module.create_keystore(address=address, password=pwd, keystore_dir=out_dir, force=force)
|
||||
@@ -46,6 +46,7 @@ from .commands.marketplace_advanced import advanced # Re-enabled after fixing r
|
||||
from .commands.swarm import swarm
|
||||
from .commands.chain import chain
|
||||
from .commands.genesis import genesis
|
||||
from .commands.keystore import keystore
|
||||
from .commands.test_cli import test
|
||||
from .commands.node import node
|
||||
from .commands.analytics import analytics
|
||||
@@ -257,6 +258,7 @@ cli.add_command(ai_group)
|
||||
cli.add_command(swarm)
|
||||
cli.add_command(chain)
|
||||
cli.add_command(genesis)
|
||||
cli.add_command(keystore)
|
||||
cli.add_command(test)
|
||||
cli.add_command(node)
|
||||
cli.add_command(analytics)
|
||||
|
||||
@@ -38,10 +38,10 @@ def check_build_tests():
|
||||
rc, out = sh("poetry check")
|
||||
checks.append(("poetry check", rc == 0, out))
|
||||
# 2) Fast syntax check of CLI package
|
||||
rc, out = sh("python -m py_compile cli/aitbc_cli/__main__.py")
|
||||
rc, out = sh("python3 -m py_compile cli/aitbc_cli/main.py")
|
||||
checks.append(("cli syntax", rc == 0, out if rc != 0 else "OK"))
|
||||
# 3) Minimal test run (dry-run or 1 quick test)
|
||||
rc, out = sh("python -m pytest tests/ -v --collect-only 2>&1 | head -20")
|
||||
rc, out = sh("python3 -m pytest tests/ -v --collect-only 2>&1 | head -20")
|
||||
tests_ok = rc == 0
|
||||
checks.append(("test discovery", tests_ok, out if not tests_ok else f"Collected {out.count('test') if 'test' in out else '?'} tests"))
|
||||
all_ok = all(ok for _, ok, _ in checks)
|
||||
@@ -86,7 +86,7 @@ def check_vulnerabilities():
|
||||
"""Run security audits for Python and Node dependencies."""
|
||||
issues = []
|
||||
# Python: pip-audit (if available)
|
||||
rc, out = sh("pip-audit --requirement <(poetry export --without-hashes) 2>&1", shell=True)
|
||||
rc, out = sh("pip-audit --requirement <(poetry export --without-hashes) 2>&1")
|
||||
if rc == 0:
|
||||
# No vulnerabilities
|
||||
pass
|
||||
|
||||
140
infra/helm/values/prod.yaml
Normal file
140
infra/helm/values/prod.yaml
Normal 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"
|
||||
259
infra/helm/values/prod/values.yaml
Normal file
259
infra/helm/values/prod/values.yaml
Normal 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
|
||||
247
infra/nginx/nginx-aitbc-reverse-proxy.conf
Normal file
247
infra/nginx/nginx-aitbc-reverse-proxy.conf
Normal 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;
|
||||
}
|
||||
}
|
||||
133
infra/nginx/nginx-aitbc.conf
Normal file
133
infra/nginx/nginx-aitbc.conf
Normal 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";
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
>;
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
>;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/* Autogenerated file. Do not edit manually. */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export type { AccessControl } from "./AccessControl";
|
||||
export type { IAccessControl } from "./IAccessControl";
|
||||
@@ -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 };
|
||||
@@ -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: {};
|
||||
}
|
||||
@@ -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: {};
|
||||
}
|
||||
@@ -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: {};
|
||||
}
|
||||
@@ -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";
|
||||
@@ -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 };
|
||||
@@ -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
|
||||
>;
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
>;
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
>;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/* Autogenerated file. Do not edit manually. */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export type { IERC20Metadata } from "./IERC20Metadata";
|
||||
@@ -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";
|
||||
@@ -0,0 +1,5 @@
|
||||
/* Autogenerated file. Do not edit manually. */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type * as erc20 from "./ERC20";
|
||||
export type { erc20 };
|
||||
@@ -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: {};
|
||||
}
|
||||
@@ -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: {};
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/* Autogenerated file. Do not edit manually. */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export type { ECDSA } from "./ECDSA";
|
||||
@@ -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";
|
||||
@@ -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: {};
|
||||
}
|
||||
@@ -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: {};
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/* Autogenerated file. Do not edit manually. */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export type { ERC165 } from "./ERC165";
|
||||
export type { IERC165 } from "./IERC165";
|
||||
@@ -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: {};
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/* Autogenerated file. Do not edit manually. */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export type { SafeCast } from "./SafeCast";
|
||||
@@ -0,0 +1,5 @@
|
||||
/* Autogenerated file. Do not edit manually. */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type * as contracts from "./contracts";
|
||||
export type { contracts };
|
||||
131
packages/solidity/aitbc-token/typechain-types/common.ts
Normal file
131
packages/solidity/aitbc-token/typechain-types/common.ts
Normal 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>;
|
||||
}
|
||||
@@ -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
|
||||
>;
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
>;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/* Autogenerated file. Do not edit manually. */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export type { AIToken } from "./AIToken";
|
||||
export type { AITokenRegistry } from "./AITokenRegistry";
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
@@ -0,0 +1,4 @@
|
||||
/* Autogenerated file. Do not edit manually. */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export * as draftIerc6093Sol from "./draft-IERC6093.sol";
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/* Autogenerated file. Do not edit manually. */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export { IERC20Metadata__factory } from "./IERC20Metadata__factory";
|
||||
@@ -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";
|
||||
@@ -0,0 +1,4 @@
|
||||
/* Autogenerated file. Do not edit manually. */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export * as erc20 from "./ERC20";
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/* Autogenerated file. Do not edit manually. */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export { ECDSA__factory } from "./ECDSA__factory";
|
||||
@@ -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";
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/* Autogenerated file. Do not edit manually. */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export { SafeCast__factory } from "./SafeCast__factory";
|
||||
@@ -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
@@ -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";
|
||||
@@ -0,0 +1,5 @@
|
||||
/* Autogenerated file. Do not edit manually. */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export * as openzeppelin from "./@openzeppelin";
|
||||
export * as contracts from "./contracts";
|
||||
315
packages/solidity/aitbc-token/typechain-types/hardhat.d.ts
vendored
Normal file
315
packages/solidity/aitbc-token/typechain-types/hardhat.d.ts
vendored
Normal 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>;
|
||||
}
|
||||
}
|
||||
38
packages/solidity/aitbc-token/typechain-types/index.ts
Normal file
38
packages/solidity/aitbc-token/typechain-types/index.ts
Normal 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";
|
||||
1866
poetry.lock
generated
1866
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -147,7 +147,7 @@ dev = [
|
||||
"black==24.3.0",
|
||||
"isort==8.0.1",
|
||||
"ruff==0.15.5",
|
||||
"mypy==1.8.0",
|
||||
"mypy>=1.19.1,<2.0.0",
|
||||
"bandit==1.7.5",
|
||||
"types-requests==2.31.0",
|
||||
"types-setuptools==69.0.0",
|
||||
|
||||
24
scripts/deploy/cleanup-deployment.sh
Executable file
24
scripts/deploy/cleanup-deployment.sh
Executable 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"
|
||||
109
scripts/deploy/container-deploy.py
Normal file
109
scripts/deploy/container-deploy.py
Normal 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()
|
||||
56
scripts/deploy/deploy-all-remote.sh
Executable file
56
scripts/deploy/deploy-all-remote.sh
Executable 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."
|
||||
207
scripts/deploy/deploy-blockchain-and-explorer.sh
Executable file
207
scripts/deploy/deploy-blockchain-and-explorer.sh
Executable 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."
|
||||
94
scripts/deploy/deploy-blockchain-explorer.sh
Executable file
94
scripts/deploy/deploy-blockchain-explorer.sh
Executable 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."
|
||||
157
scripts/deploy/deploy-blockchain-remote.sh
Normal file
157
scripts/deploy/deploy-blockchain-remote.sh
Normal 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."
|
||||
139
scripts/deploy/deploy-blockchain.sh
Executable file
139
scripts/deploy/deploy-blockchain.sh
Executable 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
316
scripts/deploy/deploy-direct.sh
Executable 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
88
scripts/deploy/deploy-domain.sh
Executable 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"
|
||||
74
scripts/deploy/deploy-exchange.sh
Executable file
74
scripts/deploy/deploy-exchange.sh
Executable 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'"
|
||||
396
scripts/deploy/deploy-explorer-remote.sh
Normal file
396
scripts/deploy/deploy-explorer-remote.sh
Normal 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."
|
||||
66
scripts/deploy/deploy-explorer.sh
Executable file
66
scripts/deploy/deploy-explorer.sh
Executable 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 ""
|
||||
121
scripts/deploy/deploy-first-node.sh
Executable file
121
scripts/deploy/deploy-first-node.sh
Executable 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"
|
||||
306
scripts/deploy/deploy-in-container.sh
Executable file
306
scripts/deploy/deploy-in-container.sh
Executable 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."
|
||||
56
scripts/deploy/deploy-modern-explorer.sh
Normal file
56
scripts/deploy/deploy-modern-explorer.sh
Normal 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}"
|
||||
160
scripts/deploy/deploy-nginx-reverse-proxy.sh
Executable file
160
scripts/deploy/deploy-nginx-reverse-proxy.sh
Executable 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)"
|
||||
55
scripts/deploy/deploy-production.sh
Normal file
55
scripts/deploy/deploy-production.sh
Normal 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"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user