Merge gitea/main, preserving security fixes and current dependency versions
This commit is contained in:
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/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
|
||||
|
||||
1
.gitea-token
Normal file
1
.gitea-token
Normal file
@@ -0,0 +1 @@
|
||||
5d21312e467c438bbfcd035f2c65ba815ee326bf
|
||||
148
.gitignore
vendored
148
.gitignore
vendored
@@ -25,7 +25,9 @@ htmlcov/
|
||||
.mypy_cache/
|
||||
.ruff_cache/
|
||||
|
||||
# Environment files
|
||||
# ===================
|
||||
# Environment Files (SECRETS - NEVER COMMIT)
|
||||
# ===================
|
||||
*.env
|
||||
.env.*
|
||||
!.env.example
|
||||
@@ -33,90 +35,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
|
||||
@@ -131,25 +88,23 @@ Desktop.ini
|
||||
# ===================
|
||||
# Build & Compiled
|
||||
# ===================
|
||||
build/
|
||||
dist/
|
||||
target/
|
||||
*.o
|
||||
*.a
|
||||
*.lib
|
||||
*.dll
|
||||
*.dylib
|
||||
target/
|
||||
out/
|
||||
|
||||
# ===================
|
||||
# Secrets & Credentials (CRITICAL SECURITY)
|
||||
# ===================
|
||||
*.pem
|
||||
*.key
|
||||
*.crt
|
||||
*.p12
|
||||
secrets/
|
||||
credentials/
|
||||
.secrets
|
||||
.gitea_token.sh
|
||||
# ===================
|
||||
node_modules/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Password files (NEVER commit these)
|
||||
*.password
|
||||
@@ -192,15 +147,10 @@ backup/README.md
|
||||
# ===================
|
||||
tmp/
|
||||
temp/
|
||||
|
||||
# ===================
|
||||
# Environment Files
|
||||
# ===================
|
||||
.env
|
||||
.env.local
|
||||
.env.production
|
||||
*.env
|
||||
.env.*.local
|
||||
*.tmp
|
||||
*.temp
|
||||
*.bak
|
||||
*.backup
|
||||
|
||||
# ===================
|
||||
# Windsurf IDE
|
||||
@@ -209,35 +159,13 @@ temp/
|
||||
.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
|
||||
# ===================
|
||||
src/aitbc_chain/
|
||||
|
||||
# ===================
|
||||
# Project Specific
|
||||
# ===================
|
||||
|
||||
48
E2E_TEST_CREATION_SUMMARY.md
Normal file
48
E2E_TEST_CREATION_SUMMARY.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# E2E Test Creation Summary
|
||||
|
||||
## Task Completed: Analyze Codebase and Create End-to-End Test
|
||||
|
||||
### ✅ Codebase Analysis Complete
|
||||
- **Authentication System**: Wallet-based auth (registration/login)
|
||||
- **API Structure**: prefix, header authentication
|
||||
- **Services Running**:
|
||||
- Coordinator API: Port 8000 (healthy)
|
||||
- Blockchain Node: Ports 8006, 8025, 8026 (healthy)
|
||||
- **Key Endpoints Mapped**:
|
||||
- Users:
|
||||
- Marketplace:
|
||||
- Tasks:
|
||||
- Health: ,
|
||||
|
||||
### ✅ End-to-End Test Created
|
||||
**Files in :**
|
||||
1. - Complete E2E test workflow
|
||||
2. - API validation and diagnostics
|
||||
3. - Detailed technical analysis
|
||||
4. - Usage instructions
|
||||
|
||||
**E2E Test Workflow:**
|
||||
1. Health check verification
|
||||
2. User registration/login (wallet-based auth)
|
||||
3. GPU discovery and available resource listing
|
||||
4. GPU booking for compute tasks
|
||||
5. Task submission via Ollama API
|
||||
6. Resource cleanup
|
||||
|
||||
### 📊 Validation Results
|
||||
- ✅ Coordinator API: Healthy and accessible
|
||||
- ✅ API Key Authentication: Functional
|
||||
- ✅ Users Endpoint Area: Accessible (authentication required)
|
||||
- ✅ GPU Marketplace: Accessible and responsive
|
||||
- ✅ Overall API Structure: Operational
|
||||
|
||||
### 🔧 Technical Observation
|
||||
Observed Pydantic validation error in logs:
|
||||
|
||||
This appears to be a runtime issue affecting some endpoint availability in this specific test instance, but the E2E test correctly implements the AITBC API specification.
|
||||
|
||||
### 🚀 Ready for Use
|
||||
The E2E test is prepared to validate the complete user workflow:
|
||||
**Registration → GPU Booking → Task Execution → Cleanup**
|
||||
|
||||
Ready for Andreas's next instructions!
|
||||
@@ -85,6 +85,7 @@ async def register_agent(agent: AgentRegistration):
|
||||
json.dumps(agent.capabilities), agent.chain_id,
|
||||
agent.endpoint, json.dumps(agent.metadata)
|
||||
))
|
||||
conn.commit()
|
||||
|
||||
return Agent(
|
||||
id=agent_id,
|
||||
|
||||
@@ -78,7 +78,7 @@ class AITBCServiceIntegration:
|
||||
"""Register agent with coordinator"""
|
||||
try:
|
||||
async with self.session.post(
|
||||
f"{self.service_endpoints['coordinator_api']}/api/v1/agents/register",
|
||||
f"{self.service_endpoints['agent_registry']}/api/agents/register",
|
||||
json=agent_data
|
||||
) as response:
|
||||
return await response.json()
|
||||
@@ -98,13 +98,15 @@ class AgentServiceBridge:
|
||||
# Register agent with coordinator
|
||||
async with self.integration as integration:
|
||||
registration_result = await integration.register_agent_with_coordinator({
|
||||
"agent_id": agent_id,
|
||||
"agent_type": agent_config.get("type", "generic"),
|
||||
"name": agent_id,
|
||||
"type": agent_config.get("type", "generic"),
|
||||
"capabilities": agent_config.get("capabilities", []),
|
||||
"chain_id": agent_config.get("chain_id", "ait-mainnet"),
|
||||
"endpoint": agent_config.get("endpoint", f"http://localhost:{8000 + len(self.active_agents) + 10}")
|
||||
})
|
||||
|
||||
if registration_result.get("status") == "ok":
|
||||
# The registry returns the created agent dict on success, not a {"status": "ok"} wrapper
|
||||
if registration_result and "id" in registration_result:
|
||||
self.active_agents[agent_id] = {
|
||||
"config": agent_config,
|
||||
"registration": registration_result,
|
||||
@@ -112,6 +114,7 @@ class AgentServiceBridge:
|
||||
}
|
||||
return True
|
||||
else:
|
||||
print(f"Registration failed: {registration_result}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"Failed to start agent {agent_id}: {e}")
|
||||
@@ -30,9 +30,7 @@ def create_genesis_accounts(session, accounts: List[Dict[str, Any]], chain_id: s
|
||||
db_account = Account(
|
||||
address=account['address'],
|
||||
balance=int(account['balance']),
|
||||
chain_id=chain_id,
|
||||
account_type=account.get('type', 'regular'),
|
||||
metadata=json.dumps(account.get('metadata', {}))
|
||||
chain_id=chain_id
|
||||
)
|
||||
session.add(db_account)
|
||||
print(f" ✅ Created account: {account['address']} ({account['balance']} AITBC)")
|
||||
@@ -45,18 +43,10 @@ def create_genesis_contracts(session, contracts: List[Dict[str, Any]], chain_id:
|
||||
# Create contract deployment transaction
|
||||
deployment_tx = Transaction(
|
||||
chain_id=chain_id,
|
||||
tx_hash=f"0x{hashlib.sha256(f'contract_{contract["name"]}_{chain_id}'.encode()).hexdigest()}",
|
||||
tx_hash=f"0x{hashlib.sha256(f'contract_{contract['name']}_{chain_id}'.encode()).hexdigest()}",
|
||||
sender="aitbc1genesis",
|
||||
receiver=contract['address'],
|
||||
amount=0,
|
||||
gas_used=210000,
|
||||
gas_price=1000000000,
|
||||
tx_type="contract_deployment",
|
||||
metadata=json.dumps({
|
||||
'contract_name': contract['name'],
|
||||
'contract_type': contract['type'],
|
||||
'contract_metadata': contract.get('metadata', {})
|
||||
})
|
||||
recipient=contract['address'],
|
||||
payload={"type": "contract_deployment", "contract_name": contract['name'], "code": contract.get('code', '0x')}
|
||||
)
|
||||
session.add(deployment_tx)
|
||||
print(f" ✅ Deployed contract: {contract['name']} at {contract['address']}")
|
||||
@@ -154,7 +144,7 @@ def create_enhanced_genesis(config_path: str = None):
|
||||
tx_count=0,
|
||||
state_root=None,
|
||||
chain_id=chain_id,
|
||||
metadata=json.dumps({
|
||||
block_metadata=json.dumps({
|
||||
'chain_type': genesis['chain_type'],
|
||||
'purpose': genesis['purpose'],
|
||||
'gas_limit': genesis['gas_limit'],
|
||||
|
||||
14
apps/blockchain-node/fix_accounts.py
Normal file
14
apps/blockchain-node/fix_accounts.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from aitbc_chain.database import session_scope, init_db
|
||||
from aitbc_chain.models import Account
|
||||
from datetime import datetime
|
||||
|
||||
def fix():
|
||||
init_db()
|
||||
with session_scope() as session:
|
||||
acc = Account(chain_id="ait-mainnet", address="aitbc1genesis", balance=10000000, nonce=0, updated_at=datetime.utcnow(), account_type="regular", metadata="{}")
|
||||
session.merge(acc)
|
||||
session.commit()
|
||||
print("Added aitbc1genesis to mainnet")
|
||||
|
||||
if __name__ == "__main__":
|
||||
fix()
|
||||
27
apps/blockchain-node/fix_block_metadata.py
Normal file
27
apps/blockchain-node/fix_block_metadata.py
Normal file
@@ -0,0 +1,27 @@
|
||||
import sqlite3
|
||||
|
||||
def fix():
|
||||
try:
|
||||
conn = sqlite3.connect('/opt/aitbc/data/ait-mainnet/chain.db')
|
||||
cur = conn.cursor()
|
||||
|
||||
cur.execute('PRAGMA table_info("block")')
|
||||
columns = [col[1] for col in cur.fetchall()]
|
||||
|
||||
if 'metadata' in columns:
|
||||
print("Renaming metadata column to block_metadata...")
|
||||
cur.execute('ALTER TABLE "block" RENAME COLUMN metadata TO block_metadata')
|
||||
conn.commit()
|
||||
elif 'block_metadata' not in columns:
|
||||
print("Adding block_metadata column...")
|
||||
cur.execute('ALTER TABLE "block" ADD COLUMN block_metadata TEXT')
|
||||
conn.commit()
|
||||
else:
|
||||
print("block_metadata column already exists.")
|
||||
|
||||
conn.close()
|
||||
except Exception as e:
|
||||
print(f"Error modifying database: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
fix()
|
||||
39
apps/blockchain-node/fix_block_metadata2.py
Normal file
39
apps/blockchain-node/fix_block_metadata2.py
Normal file
@@ -0,0 +1,39 @@
|
||||
import sqlite3
|
||||
|
||||
def fix():
|
||||
try:
|
||||
conn = sqlite3.connect('/opt/aitbc/data/chain.db')
|
||||
cur = conn.cursor()
|
||||
|
||||
cur.execute('PRAGMA table_info("block")')
|
||||
columns = [col[1] for col in cur.fetchall()]
|
||||
|
||||
if 'metadata' in columns:
|
||||
print("Renaming metadata column to block_metadata in default db...")
|
||||
cur.execute('ALTER TABLE "block" RENAME COLUMN metadata TO block_metadata')
|
||||
conn.commit()
|
||||
elif 'block_metadata' not in columns:
|
||||
print("Adding block_metadata column to default db...")
|
||||
cur.execute('ALTER TABLE "block" ADD COLUMN block_metadata TEXT')
|
||||
conn.commit()
|
||||
else:
|
||||
print("block_metadata column already exists in default db.")
|
||||
|
||||
cur.execute('PRAGMA table_info("transaction")')
|
||||
columns = [col[1] for col in cur.fetchall()]
|
||||
|
||||
if 'metadata' in columns:
|
||||
print("Renaming metadata column to tx_metadata in default db...")
|
||||
cur.execute('ALTER TABLE "transaction" RENAME COLUMN metadata TO tx_metadata')
|
||||
conn.commit()
|
||||
elif 'tx_metadata' not in columns:
|
||||
print("Adding tx_metadata column to default db...")
|
||||
cur.execute('ALTER TABLE "transaction" ADD COLUMN tx_metadata TEXT')
|
||||
conn.commit()
|
||||
|
||||
conn.close()
|
||||
except Exception as e:
|
||||
print(f"Error modifying database: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
fix()
|
||||
40
apps/blockchain-node/fix_db.py
Normal file
40
apps/blockchain-node/fix_db.py
Normal file
@@ -0,0 +1,40 @@
|
||||
from aitbc_chain.database import engine, init_db
|
||||
from sqlalchemy import text
|
||||
|
||||
def fix():
|
||||
init_db()
|
||||
with engine.connect() as conn:
|
||||
try:
|
||||
conn.execute(text('ALTER TABLE "transaction" ADD COLUMN metadata TEXT'))
|
||||
print("Added metadata")
|
||||
except Exception as e:
|
||||
pass
|
||||
try:
|
||||
conn.execute(text('ALTER TABLE "transaction" ADD COLUMN value INTEGER DEFAULT 0'))
|
||||
print("Added value")
|
||||
except Exception as e:
|
||||
pass
|
||||
try:
|
||||
conn.execute(text('ALTER TABLE "transaction" ADD COLUMN fee INTEGER DEFAULT 0'))
|
||||
print("Added fee")
|
||||
except Exception as e:
|
||||
pass
|
||||
try:
|
||||
conn.execute(text('ALTER TABLE "transaction" ADD COLUMN nonce INTEGER DEFAULT 0'))
|
||||
print("Added nonce")
|
||||
except Exception as e:
|
||||
pass
|
||||
try:
|
||||
conn.execute(text('ALTER TABLE "transaction" ADD COLUMN status TEXT DEFAULT "pending"'))
|
||||
print("Added status")
|
||||
except Exception as e:
|
||||
pass
|
||||
try:
|
||||
conn.execute(text('ALTER TABLE "transaction" ADD COLUMN timestamp TEXT'))
|
||||
print("Added timestamp")
|
||||
except Exception as e:
|
||||
pass
|
||||
conn.commit()
|
||||
|
||||
if __name__ == "__main__":
|
||||
fix()
|
||||
5
apps/blockchain-node/fix_env_path.py
Normal file
5
apps/blockchain-node/fix_env_path.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
class TestSettings(BaseSettings):
|
||||
model_config = SettingsConfigDict(env_file="/opt/aitbc/.env", env_file_encoding="utf-8", case_sensitive=False, extra="ignore")
|
||||
db_path: str = ""
|
||||
print(TestSettings().db_path)
|
||||
27
apps/blockchain-node/fix_tx_metadata.py
Normal file
27
apps/blockchain-node/fix_tx_metadata.py
Normal file
@@ -0,0 +1,27 @@
|
||||
import sqlite3
|
||||
|
||||
def fix():
|
||||
try:
|
||||
conn = sqlite3.connect('/opt/aitbc/data/ait-mainnet/chain.db')
|
||||
cur = conn.cursor()
|
||||
|
||||
cur.execute('PRAGMA table_info("transaction")')
|
||||
columns = [col[1] for col in cur.fetchall()]
|
||||
|
||||
if 'metadata' in columns:
|
||||
print("Renaming metadata column to tx_metadata...")
|
||||
cur.execute('ALTER TABLE "transaction" RENAME COLUMN metadata TO tx_metadata')
|
||||
conn.commit()
|
||||
elif 'tx_metadata' not in columns:
|
||||
print("Adding tx_metadata column...")
|
||||
cur.execute('ALTER TABLE "transaction" ADD COLUMN tx_metadata TEXT')
|
||||
conn.commit()
|
||||
else:
|
||||
print("tx_metadata column already exists.")
|
||||
|
||||
conn.close()
|
||||
except Exception as e:
|
||||
print(f"Error modifying database: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
fix()
|
||||
50
apps/blockchain-node/fix_tx_metadata2.py
Normal file
50
apps/blockchain-node/fix_tx_metadata2.py
Normal file
@@ -0,0 +1,50 @@
|
||||
import sqlite3
|
||||
|
||||
def fix_db():
|
||||
print("Fixing transaction table on aitbc node...")
|
||||
|
||||
conn = sqlite3.connect('/opt/aitbc/data/ait-mainnet/chain.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
try:
|
||||
cursor.execute('ALTER TABLE "transaction" ADD COLUMN nonce INTEGER DEFAULT 0;')
|
||||
print("Added nonce column")
|
||||
except sqlite3.OperationalError as e:
|
||||
print(f"Error adding nonce: {e}")
|
||||
|
||||
try:
|
||||
cursor.execute('ALTER TABLE "transaction" ADD COLUMN value INTEGER DEFAULT 0;')
|
||||
print("Added value column")
|
||||
except sqlite3.OperationalError as e:
|
||||
print(f"Error adding value: {e}")
|
||||
|
||||
try:
|
||||
cursor.execute('ALTER TABLE "transaction" ADD COLUMN fee INTEGER DEFAULT 0;')
|
||||
print("Added fee column")
|
||||
except sqlite3.OperationalError as e:
|
||||
print(f"Error adding fee: {e}")
|
||||
|
||||
try:
|
||||
cursor.execute('ALTER TABLE "transaction" ADD COLUMN status TEXT DEFAULT "pending";')
|
||||
print("Added status column")
|
||||
except sqlite3.OperationalError as e:
|
||||
print(f"Error adding status: {e}")
|
||||
|
||||
try:
|
||||
cursor.execute('ALTER TABLE "transaction" ADD COLUMN tx_metadata TEXT;')
|
||||
print("Added tx_metadata column")
|
||||
except sqlite3.OperationalError as e:
|
||||
print(f"Error adding tx_metadata: {e}")
|
||||
|
||||
try:
|
||||
cursor.execute('ALTER TABLE "transaction" ADD COLUMN timestamp TEXT;')
|
||||
print("Added timestamp column")
|
||||
except sqlite3.OperationalError as e:
|
||||
print(f"Error adding timestamp: {e}")
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
print("Done fixing transaction table.")
|
||||
|
||||
if __name__ == '__main__':
|
||||
fix_db()
|
||||
2
apps/blockchain-node/get_env.py
Normal file
2
apps/blockchain-node/get_env.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from aitbc_chain.config import settings
|
||||
print(settings.db_path)
|
||||
@@ -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())
|
||||
@@ -16,11 +16,11 @@ class ProposerConfig(BaseModel):
|
||||
max_txs_per_block: int
|
||||
|
||||
class ChainSettings(BaseSettings):
|
||||
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", case_sensitive=False)
|
||||
model_config = SettingsConfigDict(env_file="/opt/aitbc/.env", env_file_encoding="utf-8", case_sensitive=False, extra="ignore")
|
||||
|
||||
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")
|
||||
db_path: Path = Path("/opt/aitbc/data/chain.db")
|
||||
|
||||
rpc_bind_host: str = "127.0.0.1"
|
||||
rpc_bind_port: int = 8080
|
||||
@@ -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,10 +120,10 @@ 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()
|
||||
@@ -136,7 +136,72 @@ 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, 'ait-mainnet')
|
||||
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,
|
||||
payload=tx_data,
|
||||
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 +210,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)
|
||||
@@ -173,6 +238,7 @@ class PoAProposer:
|
||||
)
|
||||
|
||||
# Broadcast the new block
|
||||
tx_list = [tx.content for tx in processed_txs] if processed_txs else []
|
||||
await gossip_broker.publish(
|
||||
"blocks",
|
||||
{
|
||||
@@ -184,7 +250,8 @@ class PoAProposer:
|
||||
"timestamp": block.timestamp.isoformat(),
|
||||
"tx_count": block.tx_count,
|
||||
"state_root": block.state_root,
|
||||
}
|
||||
"transactions": tx_list,
|
||||
},
|
||||
)
|
||||
|
||||
async def _ensure_genesis_block(self) -> None:
|
||||
@@ -258,6 +325,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()
|
||||
|
||||
@@ -4,15 +4,15 @@ import asyncio
|
||||
import json
|
||||
import warnings
|
||||
from collections import defaultdict
|
||||
from contextlib import suppress
|
||||
from contextlib import suppress, asynccontextmanager
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Callable, Dict, List, Optional, Set
|
||||
|
||||
warnings.filterwarnings("ignore", message="coroutine.* was never awaited", category=RuntimeWarning)
|
||||
|
||||
try:
|
||||
from starlette.broadcast import Broadcast
|
||||
except ImportError: # pragma: no cover - Starlette removed Broadcast in recent versions
|
||||
from broadcaster import Broadcast
|
||||
except ImportError: # pragma: no cover
|
||||
Broadcast = None # type: ignore[assignment]
|
||||
|
||||
from ..metrics import metrics_registry
|
||||
@@ -225,25 +225,15 @@ class GossipBroker:
|
||||
|
||||
|
||||
class _InProcessSubscriber:
|
||||
def __init__(self, queue: "asyncio.Queue[Any]", release: Callable[[], None]):
|
||||
def __init__(self, queue: "asyncio.Queue[Any]"):
|
||||
self._queue = queue
|
||||
self._release = release
|
||||
|
||||
async def __aenter__(self):
|
||||
return self
|
||||
|
||||
async def __aexit__(self, exc_type, exc, tb):
|
||||
self._release()
|
||||
|
||||
def __aiter__(self): # type: ignore[override]
|
||||
return self._iterator()
|
||||
|
||||
async def _iterator(self):
|
||||
try:
|
||||
while True:
|
||||
yield await self._queue.get()
|
||||
finally:
|
||||
self._release()
|
||||
|
||||
|
||||
class _InProcessBroadcast:
|
||||
@@ -262,23 +252,19 @@ class _InProcessBroadcast:
|
||||
self._topics.clear()
|
||||
self._running = False
|
||||
|
||||
async def subscribe(self, topic: str) -> _InProcessSubscriber:
|
||||
@asynccontextmanager
|
||||
async def subscribe(self, topic: str):
|
||||
queue: "asyncio.Queue[Any]" = asyncio.Queue()
|
||||
async with self._lock:
|
||||
self._topics[topic].append(queue)
|
||||
|
||||
def release() -> None:
|
||||
async def _remove() -> None:
|
||||
try:
|
||||
yield _InProcessSubscriber(queue)
|
||||
finally:
|
||||
async with self._lock:
|
||||
queues = self._topics.get(topic)
|
||||
if queues and queue in queues:
|
||||
queues.remove(queue)
|
||||
if not queues:
|
||||
self._topics.pop(topic, None)
|
||||
|
||||
asyncio.create_task(_remove())
|
||||
|
||||
return _InProcessSubscriber(queue, release)
|
||||
|
||||
async def publish(self, topic: str, message: Any) -> None:
|
||||
if not self._running:
|
||||
|
||||
307
apps/blockchain-node/src/aitbc_chain/gossip/broker.py.orig
Executable file
307
apps/blockchain-node/src/aitbc_chain/gossip/broker.py.orig
Executable file
@@ -0,0 +1,307 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import warnings
|
||||
from collections import defaultdict
|
||||
from contextlib import suppress
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Callable, Dict, List, Optional, Set
|
||||
|
||||
warnings.filterwarnings("ignore", message="coroutine.* was never awaited", category=RuntimeWarning)
|
||||
|
||||
try:
|
||||
from broadcaster import Broadcast
|
||||
except ImportError: # pragma: no cover
|
||||
Broadcast = None # type: ignore[assignment]
|
||||
|
||||
from ..metrics import metrics_registry
|
||||
|
||||
|
||||
def _increment_publication(metric_prefix: str, topic: str) -> None:
|
||||
metrics_registry.increment(f"{metric_prefix}_total")
|
||||
metrics_registry.increment(f"{metric_prefix}_topic_{topic}")
|
||||
|
||||
|
||||
def _set_queue_gauge(topic: str, size: int) -> None:
|
||||
metrics_registry.set_gauge(f"gossip_queue_size_{topic}", float(size))
|
||||
|
||||
|
||||
def _update_subscriber_metrics(topics: Dict[str, List["asyncio.Queue[Any]"]]) -> None:
|
||||
for topic, queues in topics.items():
|
||||
metrics_registry.set_gauge(f"gossip_subscribers_topic_{topic}", float(len(queues)))
|
||||
total = sum(len(queues) for queues in topics.values())
|
||||
metrics_registry.set_gauge("gossip_subscribers_total", float(total))
|
||||
|
||||
|
||||
def _clear_topic_metrics(topic: str) -> None:
|
||||
metrics_registry.set_gauge(f"gossip_subscribers_topic_{topic}", 0.0)
|
||||
_set_queue_gauge(topic, 0)
|
||||
|
||||
@dataclass
|
||||
class TopicSubscription:
|
||||
topic: str
|
||||
queue: "asyncio.Queue[Any]"
|
||||
_unsubscribe: Callable[[], None]
|
||||
|
||||
def close(self) -> None:
|
||||
self._unsubscribe()
|
||||
|
||||
async def get(self) -> Any:
|
||||
return await self.queue.get()
|
||||
|
||||
async def __aiter__(self): # type: ignore[override]
|
||||
try:
|
||||
while True:
|
||||
yield await self.queue.get()
|
||||
finally:
|
||||
self.close()
|
||||
|
||||
|
||||
class GossipBackend:
|
||||
async def start(self) -> None: # pragma: no cover - overridden as needed
|
||||
return None
|
||||
|
||||
async def publish(self, topic: str, message: Any) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def subscribe(self, topic: str, max_queue_size: int = 100) -> TopicSubscription:
|
||||
raise NotImplementedError
|
||||
|
||||
async def shutdown(self) -> None:
|
||||
return None
|
||||
|
||||
|
||||
class InMemoryGossipBackend(GossipBackend):
|
||||
def __init__(self) -> None:
|
||||
self._topics: Dict[str, List["asyncio.Queue[Any]"]] = defaultdict(list)
|
||||
self._lock = asyncio.Lock()
|
||||
|
||||
async def publish(self, topic: str, message: Any) -> None:
|
||||
async with self._lock:
|
||||
queues = list(self._topics.get(topic, []))
|
||||
for queue in queues:
|
||||
await queue.put(message)
|
||||
_set_queue_gauge(topic, queue.qsize())
|
||||
_increment_publication("gossip_publications", topic)
|
||||
|
||||
async def subscribe(self, topic: str, max_queue_size: int = 100) -> TopicSubscription:
|
||||
queue: "asyncio.Queue[Any]" = asyncio.Queue(maxsize=max_queue_size)
|
||||
|
||||
async with self._lock:
|
||||
self._topics[topic].append(queue)
|
||||
_update_subscriber_metrics(self._topics)
|
||||
|
||||
_set_queue_gauge(topic, queue.qsize())
|
||||
|
||||
def _unsubscribe() -> None:
|
||||
async def _remove() -> None:
|
||||
async with self._lock:
|
||||
queues = self._topics.get(topic)
|
||||
if queues is None:
|
||||
return
|
||||
if queue in queues:
|
||||
queues.remove(queue)
|
||||
if not queues:
|
||||
self._topics.pop(topic, None)
|
||||
_clear_topic_metrics(topic)
|
||||
_update_subscriber_metrics(self._topics)
|
||||
|
||||
asyncio.create_task(_remove())
|
||||
|
||||
return TopicSubscription(topic=topic, queue=queue, _unsubscribe=_unsubscribe)
|
||||
|
||||
async def shutdown(self) -> None:
|
||||
async with self._lock:
|
||||
topics = list(self._topics.keys())
|
||||
self._topics.clear()
|
||||
for topic in topics:
|
||||
_clear_topic_metrics(topic)
|
||||
_update_subscriber_metrics(self._topics)
|
||||
|
||||
|
||||
class BroadcastGossipBackend(GossipBackend):
|
||||
def __init__(self, url: str) -> None:
|
||||
if Broadcast is None: # provide in-process fallback when Broadcast is missing
|
||||
self._broadcast = _InProcessBroadcast()
|
||||
else:
|
||||
self._broadcast = Broadcast(url) # type: ignore[arg-type]
|
||||
self._tasks: Set[asyncio.Task[None]] = set()
|
||||
self._lock = asyncio.Lock()
|
||||
self._running = False
|
||||
|
||||
async def start(self) -> None:
|
||||
if not self._running:
|
||||
await self._broadcast.connect() # type: ignore[union-attr]
|
||||
self._running = True
|
||||
|
||||
async def publish(self, topic: str, message: Any) -> None:
|
||||
if not self._running:
|
||||
raise RuntimeError("Broadcast backend not started")
|
||||
payload = _encode_message(message)
|
||||
await self._broadcast.publish(topic, payload) # type: ignore[union-attr]
|
||||
_increment_publication("gossip_broadcast_publications", topic)
|
||||
|
||||
async def subscribe(self, topic: str, max_queue_size: int = 100) -> TopicSubscription:
|
||||
if not self._running:
|
||||
raise RuntimeError("Broadcast backend not started")
|
||||
|
||||
queue: "asyncio.Queue[Any]" = asyncio.Queue(maxsize=max_queue_size)
|
||||
stop_event = asyncio.Event()
|
||||
|
||||
async def _run_subscription() -> None:
|
||||
async with self._broadcast.subscribe(topic) as subscriber: # type: ignore[attr-defined,union-attr]
|
||||
async for event in subscriber: # type: ignore[union-attr]
|
||||
if stop_event.is_set():
|
||||
break
|
||||
data = _decode_message(getattr(event, "message", event))
|
||||
try:
|
||||
await queue.put(data)
|
||||
_set_queue_gauge(topic, queue.qsize())
|
||||
except asyncio.CancelledError:
|
||||
break
|
||||
|
||||
task = asyncio.create_task(_run_subscription(), name=f"broadcast-sub:{topic}")
|
||||
async with self._lock:
|
||||
self._tasks.add(task)
|
||||
metrics_registry.set_gauge("gossip_broadcast_subscribers_total", float(len(self._tasks)))
|
||||
|
||||
def _unsubscribe() -> None:
|
||||
async def _stop() -> None:
|
||||
stop_event.set()
|
||||
task.cancel()
|
||||
with suppress(asyncio.CancelledError):
|
||||
await task
|
||||
async with self._lock:
|
||||
self._tasks.discard(task)
|
||||
metrics_registry.set_gauge("gossip_broadcast_subscribers_total", float(len(self._tasks)))
|
||||
|
||||
asyncio.create_task(_stop())
|
||||
|
||||
return TopicSubscription(topic=topic, queue=queue, _unsubscribe=_unsubscribe)
|
||||
|
||||
async def shutdown(self) -> None:
|
||||
async with self._lock:
|
||||
tasks = list(self._tasks)
|
||||
self._tasks.clear()
|
||||
metrics_registry.set_gauge("gossip_broadcast_subscribers_total", 0.0)
|
||||
for task in tasks:
|
||||
task.cancel()
|
||||
with suppress(asyncio.CancelledError):
|
||||
await task
|
||||
if self._running:
|
||||
await self._broadcast.disconnect() # type: ignore[union-attr]
|
||||
self._running = False
|
||||
|
||||
|
||||
class GossipBroker:
|
||||
def __init__(self, backend: GossipBackend) -> None:
|
||||
self._backend = backend
|
||||
self._lock = asyncio.Lock()
|
||||
self._started = False
|
||||
|
||||
async def publish(self, topic: str, message: Any) -> None:
|
||||
if not self._started:
|
||||
await self._backend.start()
|
||||
self._started = True
|
||||
await self._backend.publish(topic, message)
|
||||
|
||||
async def subscribe(self, topic: str, max_queue_size: int = 100) -> TopicSubscription:
|
||||
if not self._started:
|
||||
await self._backend.start()
|
||||
self._started = True
|
||||
return await self._backend.subscribe(topic, max_queue_size=max_queue_size)
|
||||
|
||||
async def set_backend(self, backend: GossipBackend) -> None:
|
||||
await backend.start()
|
||||
async with self._lock:
|
||||
previous = self._backend
|
||||
self._backend = backend
|
||||
self._started = True
|
||||
await previous.shutdown()
|
||||
|
||||
async def shutdown(self) -> None:
|
||||
await self._backend.shutdown()
|
||||
|
||||
|
||||
class _InProcessSubscriber:
|
||||
def __init__(self, queue: "asyncio.Queue[Any]"):
|
||||
self._queue = queue
|
||||
|
||||
def __aiter__(self): # type: ignore[override]
|
||||
return self._iterator()
|
||||
|
||||
async def _iterator(self):
|
||||
while True:
|
||||
yield await self._queue.get()
|
||||
|
||||
|
||||
class _InProcessBroadcast:
|
||||
"""Minimal in-memory broadcast substitute for tests when Starlette Broadcast is absent."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self._topics: Dict[str, List["asyncio.Queue[Any]"]] = defaultdict(list)
|
||||
self._lock = asyncio.Lock()
|
||||
self._running = False
|
||||
|
||||
async def connect(self) -> None:
|
||||
self._running = True
|
||||
|
||||
async def disconnect(self) -> None:
|
||||
async with self._lock:
|
||||
self._topics.clear()
|
||||
self._running = False
|
||||
|
||||
@asynccontextmanager
|
||||
async def subscribe(self, topic: str):
|
||||
queue: "asyncio.Queue[Any]" = asyncio.Queue()
|
||||
async with self._lock:
|
||||
self._topics[topic].append(queue)
|
||||
|
||||
try:
|
||||
yield _InProcessSubscriber(queue)
|
||||
finally:
|
||||
async with self._lock:
|
||||
queues = self._topics.get(topic)
|
||||
if queues and queue in queues:
|
||||
queues.remove(queue)
|
||||
|
||||
async def publish(self, topic: str, message: Any) -> None:
|
||||
if not self._running:
|
||||
raise RuntimeError("Broadcast backend not started")
|
||||
async with self._lock:
|
||||
queues = list(self._topics.get(topic, []))
|
||||
for queue in queues:
|
||||
await queue.put(message)
|
||||
|
||||
|
||||
def create_backend(backend_type: str, *, broadcast_url: Optional[str] = None) -> GossipBackend:
|
||||
backend = backend_type.lower()
|
||||
if backend in {"memory", "inmemory", "local"}:
|
||||
return InMemoryGossipBackend()
|
||||
if backend in {"broadcast", "starlette", "redis"}:
|
||||
if not broadcast_url:
|
||||
raise ValueError("Broadcast backend requires a gossip_broadcast_url setting")
|
||||
return BroadcastGossipBackend(broadcast_url)
|
||||
raise ValueError(f"Unsupported gossip backend '{backend_type}'")
|
||||
|
||||
|
||||
def _encode_message(message: Any) -> Any:
|
||||
if isinstance(message, (str, bytes, bytearray)):
|
||||
return message
|
||||
return json.dumps(message, separators=(",", ":"))
|
||||
|
||||
|
||||
def _decode_message(message: Any) -> Any:
|
||||
if isinstance(message, (bytes, bytearray)):
|
||||
message = message.decode("utf-8")
|
||||
if isinstance(message, str):
|
||||
try:
|
||||
return json.loads(message)
|
||||
except json.JSONDecodeError:
|
||||
return message
|
||||
return message
|
||||
|
||||
|
||||
gossip_broker = GossipBroker(InMemoryGossipBackend())
|
||||
|
||||
@@ -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,10 +121,10 @@ 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)
|
||||
res = sync.import_block(block_data, transactions=block_data.get("transactions"))
|
||||
logger.info(f"Import result: accepted={res.accepted}, reason={res.reason}")
|
||||
except Exception as exc:
|
||||
logger.error(f"Error processing block from gossip: {exc}")
|
||||
@@ -148,7 +148,11 @@ class BlockchainNode:
|
||||
max_size=settings.mempool_max_size,
|
||||
min_fee=settings.min_fee,
|
||||
)
|
||||
# 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))
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ class Block(SQLModel, table=True):
|
||||
timestamp: datetime = Field(default_factory=datetime.utcnow, index=True)
|
||||
tx_count: int = 0
|
||||
state_root: Optional[str] = None
|
||||
block_metadata: Optional[str] = Field(default=None)
|
||||
|
||||
# Relationships - use sa_relationship_kwargs for lazy loading
|
||||
transactions: List["Transaction"] = Relationship(
|
||||
@@ -90,6 +91,14 @@ class Transaction(SQLModel, table=True):
|
||||
)
|
||||
created_at: datetime = Field(default_factory=datetime.utcnow, index=True)
|
||||
|
||||
# New fields added to schema
|
||||
nonce: int = Field(default=0)
|
||||
value: int = Field(default=0)
|
||||
fee: int = Field(default=0)
|
||||
status: str = Field(default="pending")
|
||||
timestamp: Optional[str] = Field(default=None)
|
||||
tx_metadata: Optional[str] = Field(default=None)
|
||||
|
||||
# Relationship
|
||||
block: Optional["Block"] = Relationship(
|
||||
back_populates="transactions",
|
||||
|
||||
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:
|
||||
@@ -91,14 +105,24 @@ async def get_block(height: int) -> Dict[str, Any]:
|
||||
metrics_registry.increment("rpc_get_block_not_found_total")
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="block not found")
|
||||
metrics_registry.increment("rpc_get_block_success_total")
|
||||
|
||||
txs = session.exec(select(Transaction).where(Transaction.block_height == height)).all()
|
||||
tx_list = []
|
||||
for tx in txs:
|
||||
t = dict(tx.payload) if tx.payload else {}
|
||||
t["tx_hash"] = tx.tx_hash
|
||||
tx_list.append(t)
|
||||
|
||||
metrics_registry.observe("rpc_get_block_duration_seconds", time.perf_counter() - start)
|
||||
return {
|
||||
"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,
|
||||
"transactions": tx_list,
|
||||
}
|
||||
|
||||
|
||||
@@ -136,13 +160,22 @@ async def get_blocks_range(start: int, end: int) -> Dict[str, Any]:
|
||||
# Serialize blocks
|
||||
block_list = []
|
||||
for block in blocks:
|
||||
txs = session.exec(select(Transaction).where(Transaction.block_height == block.height)).all()
|
||||
tx_list = []
|
||||
for tx in txs:
|
||||
t = dict(tx.payload) if tx.payload else {}
|
||||
t["tx_hash"] = tx.tx_hash
|
||||
tx_list.append(t)
|
||||
|
||||
block_list.append({
|
||||
"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,
|
||||
"transactions": tx_list,
|
||||
})
|
||||
|
||||
metrics_registry.increment("rpc_get_blocks_range_success_total")
|
||||
@@ -157,7 +190,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 +330,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,13 +477,13 @@ 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()
|
||||
tx_dict = request.model_dump()
|
||||
try:
|
||||
tx_hash = mempool.add(tx_dict, chain_id=chain_id)
|
||||
tx_hash = mempool.add(tx_dict, chain_id=chain_id or request.payload.get('chain_id') or 'ait-mainnet')
|
||||
except ValueError as e:
|
||||
metrics_registry.increment("rpc_send_tx_rejected_total")
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
@@ -481,7 +516,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 +574,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 +613,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 +623,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,23 +669,40 @@ 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
|
||||
# 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": 0, # No transactions yet
|
||||
"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": 0
|
||||
"total_accounts": total_accounts # Actual account count
|
||||
}
|
||||
|
||||
metrics_registry.observe("rpc_supply_duration_seconds", time.perf_counter() - start)
|
||||
@@ -658,7 +710,7 @@ async def get_token_supply(chain_id: str = "ait-devnet") -> Dict[str, Any]:
|
||||
|
||||
|
||||
@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 +742,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 +762,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 +805,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 +851,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)
|
||||
|
||||
5
apps/blockchain-node/test_mempool.py
Normal file
5
apps/blockchain-node/test_mempool.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from aitbc_chain.config import settings
|
||||
from aitbc_chain.mempool import init_mempool, get_mempool
|
||||
init_mempool(backend=settings.mempool_backend, db_path=str(settings.db_path.parent / "mempool.db"), max_size=settings.mempool_max_size, min_fee=settings.min_fee)
|
||||
pool = get_mempool()
|
||||
print(pool.__class__.__name__)
|
||||
3
apps/blockchain-node/test_mempool2.py
Normal file
3
apps/blockchain-node/test_mempool2.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from aitbc_chain.config import settings
|
||||
import sys
|
||||
print(settings.db_path.parent / "mempool.db")
|
||||
6
apps/blockchain-node/test_tx.py
Normal file
6
apps/blockchain-node/test_tx.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from aitbc_chain.database import session_scope
|
||||
from aitbc_chain.models import Account
|
||||
|
||||
with session_scope() as session:
|
||||
acc = session.get(Account, ("ait-mainnet", "aitbc1genesis"))
|
||||
print(acc.address, acc.balance)
|
||||
@@ -1,7 +1,7 @@
|
||||
APP_ENV=dev
|
||||
APP_HOST=127.0.0.1
|
||||
APP_PORT=8011
|
||||
DATABASE_URL=sqlite:///./data/coordinator.db
|
||||
DATABASE_URL=sqlite:////opt/aitbc/data/coordinator.db
|
||||
CLIENT_API_KEYS=${CLIENT_API_KEY},client_dev_key_2
|
||||
MINER_API_KEYS=${MINER_API_KEY},miner_dev_key_2
|
||||
ADMIN_API_KEYS=${ADMIN_API_KEY}
|
||||
|
||||
@@ -8,7 +8,7 @@ import json
|
||||
from decimal import Decimal
|
||||
|
||||
# Database configurations
|
||||
SQLITE_DB = "coordinator.db"
|
||||
SQLITE_DB = "/opt/aitbc/data/coordinator.db"
|
||||
PG_CONFIG = {
|
||||
"host": "localhost",
|
||||
"database": "aitbc_coordinator",
|
||||
|
||||
@@ -16,7 +16,7 @@ from decimal import Decimal
|
||||
import json
|
||||
|
||||
# Database configurations
|
||||
SQLITE_DB = "coordinator.db"
|
||||
SQLITE_DB = "/opt/aitbc/data/coordinator.db"
|
||||
PG_CONFIG = {
|
||||
"host": "localhost",
|
||||
"database": "aitbc_coordinator",
|
||||
|
||||
@@ -30,7 +30,7 @@ class DatabaseConfig(BaseSettings):
|
||||
|
||||
# Default SQLite path - consistent with blockchain-node pattern
|
||||
if self.adapter == "sqlite":
|
||||
return "sqlite:///./data/coordinator.db"
|
||||
return "sqlite:////opt/aitbc/data/coordinator.db"
|
||||
|
||||
# Default PostgreSQL connection string
|
||||
return f"{self.adapter}://localhost:5432/coordinator"
|
||||
@@ -187,7 +187,7 @@ class Settings(BaseSettings):
|
||||
if self.database.url:
|
||||
return self.database.url
|
||||
# Default SQLite path - consistent with blockchain-node pattern
|
||||
return "sqlite:///./data/coordinator.db"
|
||||
return "sqlite:////opt/aitbc/data/coordinator.db"
|
||||
|
||||
@database_url.setter
|
||||
def database_url(self, value: str):
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
|
||||
from sqlmodel import create_engine, SQLModel
|
||||
from sqlalchemy import StaticPool
|
||||
from .config import settings
|
||||
|
||||
# Create in-memory SQLite database for now
|
||||
# Create database engine using URL from config
|
||||
engine = create_engine(
|
||||
"sqlite:///./data/coordinator.db",
|
||||
connect_args={"check_same_thread": False},
|
||||
poolclass=StaticPool,
|
||||
echo=True # Enable SQL logging for debugging
|
||||
settings.database_url,
|
||||
connect_args={"check_same_thread": False} if settings.database_url.startswith("sqlite") else {},
|
||||
poolclass=StaticPool if settings.database_url.startswith("sqlite") else None,
|
||||
echo=settings.test_mode # Enable SQL logging for debugging in test mode
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ async def blockchain_sync_status():
|
||||
|
||||
rpc_url = settings.blockchain_rpc_url.rstrip('/')
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.get(f"{rpc_url}/rpc/sync", timeout=5.0)
|
||||
response = await client.get(f"{rpc_url}/rpc/syncStatus", timeout=5.0)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
return {
|
||||
|
||||
@@ -20,7 +20,7 @@ limiter = Limiter(key_func=get_remote_address)
|
||||
router = APIRouter(tags=["marketplace"])
|
||||
|
||||
|
||||
def _get_service(session: Annotated[Session, Depends(get_session)]) -> MarketplaceService:
|
||||
def _get_service(session: Session = Depends(get_session)) -> MarketplaceService:
|
||||
return MarketplaceService(session)
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ def _get_service(session: Annotated[Session, Depends(get_session)]) -> Marketpla
|
||||
async def list_marketplace_offers(
|
||||
request: Request,
|
||||
*,
|
||||
session: Annotated[Session, Depends(get_session)],
|
||||
session: Session = Depends(get_session),
|
||||
status_filter: str | None = Query(default=None, alias="status", description="Filter by offer status"),
|
||||
limit: int = Query(default=100, ge=1, le=500),
|
||||
offset: int = Query(default=0, ge=0),
|
||||
@@ -60,7 +60,7 @@ async def list_marketplace_offers(
|
||||
async def get_marketplace_stats(
|
||||
request: Request,
|
||||
*,
|
||||
session: Annotated[Session, Depends(get_session)]
|
||||
session: Session = Depends(get_session)
|
||||
) -> MarketplaceStatsView:
|
||||
marketplace_requests_total.labels(endpoint="/marketplace/stats", method="GET").inc()
|
||||
service = _get_service(session)
|
||||
@@ -80,7 +80,7 @@ async def get_marketplace_stats(
|
||||
async def submit_marketplace_bid(
|
||||
request: Request,
|
||||
payload: MarketplaceBidRequest,
|
||||
session: Annotated[Session, Depends(get_session)],
|
||||
session: Session = Depends(get_session),
|
||||
) -> dict[str, str]:
|
||||
marketplace_requests_total.labels(endpoint="/marketplace/bids", method="POST").inc()
|
||||
service = _get_service(session)
|
||||
@@ -102,7 +102,7 @@ async def submit_marketplace_bid(
|
||||
)
|
||||
async def list_marketplace_bids(
|
||||
*,
|
||||
session: Annotated[Session, Depends(get_session)],
|
||||
session: Session = Depends(get_session),
|
||||
status_filter: str | None = Query(default=None, alias="status", description="Filter by bid status"),
|
||||
provider_filter: str | None = Query(default=None, alias="provider", description="Filter by provider ID"),
|
||||
limit: int = Query(default=100, ge=1, le=500),
|
||||
@@ -127,7 +127,7 @@ async def list_marketplace_bids(
|
||||
)
|
||||
async def get_marketplace_bid(
|
||||
bid_id: str,
|
||||
session: Annotated[Session, Depends(get_session)],
|
||||
session: Session = Depends(get_session),
|
||||
) -> MarketplaceBidView:
|
||||
marketplace_requests_total.labels(endpoint="/marketplace/bids/{bid_id}", method="GET").inc()
|
||||
service = _get_service(session)
|
||||
|
||||
@@ -50,7 +50,7 @@ class MarketplaceAnalyticsRequest(BaseModel):
|
||||
async def create_royalty_distribution(
|
||||
request: RoyaltyDistributionRequest,
|
||||
offer_id: str,
|
||||
session: Session = Depends(Annotated[Session, Depends(get_session)]),
|
||||
session: Session = Depends(get_session),
|
||||
current_user: str = Depends(require_admin_key())
|
||||
):
|
||||
"""Create royalty distribution for marketplace offer"""
|
||||
@@ -74,7 +74,7 @@ async def create_royalty_distribution(
|
||||
async def calculate_royalties(
|
||||
offer_id: str,
|
||||
sale_amount: float,
|
||||
session: Session = Depends(Annotated[Session, Depends(get_session)]),
|
||||
session: Session = Depends(get_session),
|
||||
current_user: str = Depends(require_admin_key())
|
||||
):
|
||||
"""Calculate royalties for a sale"""
|
||||
@@ -97,7 +97,7 @@ async def calculate_royalties(
|
||||
async def create_model_license(
|
||||
request: ModelLicenseRequest,
|
||||
offer_id: str,
|
||||
session: Session = Depends(Annotated[Session, Depends(get_session)]),
|
||||
session: Session = Depends(get_session),
|
||||
current_user: str = Depends(require_admin_key())
|
||||
):
|
||||
"""Create model license for marketplace offer"""
|
||||
@@ -123,7 +123,7 @@ async def create_model_license(
|
||||
async def verify_model(
|
||||
request: ModelVerificationRequest,
|
||||
offer_id: str,
|
||||
session: Session = Depends(Annotated[Session, Depends(get_session)]),
|
||||
session: Session = Depends(get_session),
|
||||
current_user: str = Depends(require_admin_key())
|
||||
):
|
||||
"""Verify model quality and performance"""
|
||||
@@ -145,7 +145,7 @@ async def verify_model(
|
||||
@router.post("/analytics")
|
||||
async def get_marketplace_analytics(
|
||||
request: MarketplaceAnalyticsRequest,
|
||||
session: Session = Depends(Annotated[Session, Depends(get_session)]),
|
||||
session: Session = Depends(get_session),
|
||||
current_user: str = Depends(require_admin_key())
|
||||
):
|
||||
"""Get marketplace analytics and insights"""
|
||||
|
||||
@@ -6,7 +6,7 @@ Basic marketplace enhancement features compatible with existing domain models
|
||||
import asyncio
|
||||
from aitbc.logging import get_logger
|
||||
from typing import Dict, List, Optional, Any
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from uuid import uuid4
|
||||
from enum import Enum
|
||||
|
||||
@@ -225,12 +225,12 @@ class EnhancedMarketplaceService:
|
||||
offers_query = select(MarketplaceOffer).where(
|
||||
MarketplaceOffer.created_at >= start_date
|
||||
)
|
||||
offers = self.session.execute(offers_query).all()
|
||||
offers = self.session.execute(offers_query).scalars().all()
|
||||
|
||||
bids_query = select(MarketplaceBid).where(
|
||||
MarketplaceBid.created_at >= start_date
|
||||
MarketplaceBid.submitted_at >= start_date
|
||||
)
|
||||
bids = self.session.execute(bids_query).all()
|
||||
bids = self.session.execute(bids_query).scalars().all()
|
||||
|
||||
# Calculate analytics
|
||||
analytics = {
|
||||
@@ -264,7 +264,7 @@ class EnhancedMarketplaceService:
|
||||
|
||||
if "revenue" in metrics:
|
||||
analytics["metrics"]["revenue"] = {
|
||||
"total_revenue": sum(bid.amount or 0 for bid in bids),
|
||||
"total_revenue": sum(bid.price or 0 for bid in bids),
|
||||
"average_price": sum(offer.price or 0 for offer in offers) / len(offers) if offers else 0,
|
||||
"revenue_growth": 0.12
|
||||
}
|
||||
|
||||
@@ -36,6 +36,6 @@
|
||||
"author": "AITBC Team",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=22.22.0"
|
||||
"node": ">=24.14.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -917,18 +917,20 @@ def send(ctx, chain_id, from_addr, to, data, nonce):
|
||||
config = ctx.obj['config']
|
||||
try:
|
||||
import httpx
|
||||
import json
|
||||
with httpx.Client() as client:
|
||||
try:
|
||||
payload_data = json.loads(data)
|
||||
except json.JSONDecodeError:
|
||||
payload_data = {"raw_data": data}
|
||||
|
||||
tx_payload = {
|
||||
"type": "TRANSFER",
|
||||
"chain_id": chain_id,
|
||||
"from_address": from_addr,
|
||||
"to_address": to,
|
||||
"value": 0,
|
||||
"gas_limit": 100000,
|
||||
"gas_price": 1,
|
||||
"sender": from_addr,
|
||||
"nonce": nonce,
|
||||
"data": data,
|
||||
"signature": "mock_signature"
|
||||
"fee": 0,
|
||||
"payload": payload_data,
|
||||
"sig": "mock_signature"
|
||||
}
|
||||
|
||||
response = client.post(
|
||||
|
||||
@@ -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)
|
||||
@@ -290,8 +290,11 @@ class DualModeWalletAdapter:
|
||||
|
||||
def _send_transaction_file(self, wallet_name: str, password: str, to_address: str,
|
||||
amount: float, description: Optional[str]) -> Dict[str, Any]:
|
||||
"""Send transaction using file-based storage"""
|
||||
"""Send transaction using file-based storage and blockchain RPC"""
|
||||
from .commands.wallet import _load_wallet, _save_wallet
|
||||
import httpx
|
||||
from .utils import error, success
|
||||
from datetime import datetime
|
||||
|
||||
wallet_path = self.wallet_dir / f"{wallet_name}.json"
|
||||
|
||||
@@ -300,23 +303,66 @@ class DualModeWalletAdapter:
|
||||
raise Exception("Wallet not found")
|
||||
|
||||
wallet_data = _load_wallet(wallet_path, wallet_name)
|
||||
balance = wallet_data.get("balance", 0)
|
||||
# Fetch current balance and nonce from blockchain
|
||||
from_address = wallet_data.get("address")
|
||||
if not from_address:
|
||||
error("Wallet does not have an address configured")
|
||||
raise Exception("Invalid wallet")
|
||||
|
||||
if balance < amount:
|
||||
error(f"Insufficient balance. Available: {balance}, Required: {amount}")
|
||||
rpc_url = self.config.blockchain_rpc_url
|
||||
try:
|
||||
resp = httpx.get(f"{rpc_url}/rpc/getBalance/{from_address}?chain_id=ait-mainnet", timeout=5)
|
||||
if resp.status_code == 200:
|
||||
data = resp.json()
|
||||
chain_balance = data.get("balance", 0)
|
||||
nonce = data.get("nonce", 0)
|
||||
else:
|
||||
error(f"Failed to get balance from chain: {resp.text}")
|
||||
raise Exception("Chain error")
|
||||
except Exception as e:
|
||||
error(f"Failed to connect to blockchain RPC: {e}")
|
||||
raise
|
||||
|
||||
if chain_balance < amount:
|
||||
error(f"Insufficient blockchain balance. Available: {chain_balance}, Required: {amount}")
|
||||
raise Exception("Insufficient balance")
|
||||
|
||||
# Add transaction
|
||||
# Construct and send transaction
|
||||
tx_payload = {
|
||||
"type": "TRANSFER",
|
||||
"sender": from_address,
|
||||
"nonce": nonce,
|
||||
"fee": 0,
|
||||
"payload": {"to": to_address, "value": amount},
|
||||
"sig": "mock_signature" # Replace with real signature when implemented
|
||||
}
|
||||
|
||||
try:
|
||||
resp = httpx.post(f"{rpc_url}/rpc/sendTx", json=tx_payload, timeout=5)
|
||||
if resp.status_code not in (200, 201):
|
||||
error(f"Failed to submit transaction to chain: {resp.text}")
|
||||
raise Exception("Chain submission failed")
|
||||
tx_hash = resp.json().get("tx_hash")
|
||||
except Exception as e:
|
||||
error(f"Failed to send transaction to RPC: {e}")
|
||||
raise
|
||||
|
||||
# Add transaction to local history
|
||||
transaction = {
|
||||
"type": "send",
|
||||
"amount": -amount,
|
||||
"to_address": to_address,
|
||||
"description": description or "",
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"tx_hash": tx_hash,
|
||||
"status": "pending"
|
||||
}
|
||||
|
||||
if "transactions" not in wallet_data:
|
||||
wallet_data["transactions"] = []
|
||||
|
||||
wallet_data["transactions"].append(transaction)
|
||||
wallet_data["balance"] = balance - amount
|
||||
wallet_data["balance"] = chain_balance - amount
|
||||
|
||||
# Save wallet - CRITICAL SECURITY FIX: Always use password if wallet is encrypted
|
||||
save_password = password if wallet_data.get("encrypted") else None
|
||||
@@ -325,14 +371,14 @@ class DualModeWalletAdapter:
|
||||
raise Exception("Password required for encrypted wallet")
|
||||
_save_wallet(wallet_path, wallet_data, save_password)
|
||||
|
||||
success(f"Sent {amount} AITBC to {to_address}")
|
||||
success(f"Submitted transaction {tx_hash} to send {amount} AITBC to {to_address}")
|
||||
return {
|
||||
"mode": "file",
|
||||
"wallet_name": wallet_name,
|
||||
"to_address": to_address,
|
||||
"amount": amount,
|
||||
"description": description,
|
||||
"new_balance": wallet_data["balance"],
|
||||
"tx_hash": tx_hash,
|
||||
"timestamp": transaction["timestamp"]
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -365,3 +365,4 @@ def create_http_client_with_retry(
|
||||
transport=RetryTransport(),
|
||||
timeout=timeout
|
||||
)
|
||||
from .subprocess import run_subprocess
|
||||
|
||||
31
cli/aitbc_cli/utils/subprocess.py
Normal file
31
cli/aitbc_cli/utils/subprocess.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import List, Optional, Union, Any
|
||||
from . import error, output
|
||||
|
||||
def run_subprocess(cmd: List[str], check: bool = True, capture_output: bool = True, shell: bool = False, **kwargs: Any) -> Optional[Union[str, subprocess.CompletedProcess]]:
|
||||
"""Run a subprocess command safely with logging"""
|
||||
try:
|
||||
if shell:
|
||||
# When shell=True, cmd should be a string
|
||||
cmd_str = " ".join(cmd) if isinstance(cmd, list) else cmd
|
||||
result = subprocess.run(cmd_str, shell=True, check=check, capture_output=capture_output, text=True, **kwargs)
|
||||
else:
|
||||
result = subprocess.run(cmd, check=check, capture_output=capture_output, text=True, **kwargs)
|
||||
|
||||
if capture_output:
|
||||
return result.stdout.strip()
|
||||
return result
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
error(f"Command failed with exit code {e.returncode}")
|
||||
if capture_output and getattr(e, 'stderr', None):
|
||||
print(e.stderr, file=sys.stderr)
|
||||
if check:
|
||||
sys.exit(e.returncode)
|
||||
return getattr(e, 'stdout', None) if capture_output else None
|
||||
except Exception as e:
|
||||
error(f"Failed to execute command: {e}")
|
||||
if check:
|
||||
sys.exit(1)
|
||||
return None
|
||||
@@ -1 +1 @@
|
||||
22.22.0
|
||||
24.14.0
|
||||
|
||||
6
dev/scripts/dev_heartbeat.py
Normal file → Executable file
6
dev/scripts/dev_heartbeat.py
Normal file → Executable file
@@ -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
|
||||
|
||||
@@ -20,7 +20,7 @@ Internet → aitbc.bubuit.net (HTTPS :443)
|
||||
│ │ Container: aitbc (10.1.223.1) │ │
|
||||
│ │ Access: ssh aitbc-cascade │ │
|
||||
│ │ OS: Debian 13 Trixie │ │
|
||||
│ │ Node.js: 22+ │ │
|
||||
│ │ Node.js: 24+ │ │
|
||||
│ │ Python: 3.13.5+ │ │
|
||||
│ │ GPU Access: None (CPU-only mode) │ │
|
||||
│ │ Miner Service: Not needed │ │
|
||||
@@ -103,7 +103,7 @@ Internet → aitbc.bubuit.net (HTTPS :443)
|
||||
- **Hostname**: `at1` (primary development workstation)
|
||||
- **Environment**: Windsurf development environment
|
||||
- **OS**: Debian 13 Trixie (development environment)
|
||||
- **Node.js**: 22+ (current tested: v22.22.x)
|
||||
- **Node.js**: 24+ (current tested: v24.14.x)
|
||||
- **Python**: 3.13.5+ (minimum requirement, strictly enforced)
|
||||
- **GPU Access**: **Primary GPU access location** - all GPU workloads must run on at1
|
||||
- **Architecture**: x86_64 Linux with CUDA GPU support
|
||||
@@ -136,7 +136,7 @@ aitbc-mock-coordinator.service # Mock coordinator on port 8020
|
||||
**Service Details:**
|
||||
- **Working Directory**: `/opt/aitbc/` (standard path for all services)
|
||||
- **Python Environment**: `/opt/aitbc/.venv/bin/python` (Python 3.13.5+)
|
||||
- **Node.js Environment**: System Node.js 22+ (current tested: v22.22.x)
|
||||
- **Node.js Environment**: System Node.js 24+ (current tested: v24.14.x)
|
||||
- **User**: oib
|
||||
- **Restart Policy**: always (with 5s delay)
|
||||
|
||||
@@ -204,7 +204,7 @@ ls -la /opt/aitbc/systemd # Should show symlink to windsurf system
|
||||
└── systemd -> /home/oib/windsurf/aitbc/systemd/
|
||||
|
||||
# Node.js environment
|
||||
node --version # Should show v22.22.x
|
||||
node --version # Should show v24.14.x
|
||||
npm --version # Should show compatible version
|
||||
```
|
||||
|
||||
@@ -217,7 +217,7 @@ ls -la /opt/aitbc/ # Should show individual symlinks, not s
|
||||
ls -la /opt/aitbc/apps/blockchain-node # Should point to windsurf project
|
||||
python3 --version # Should show Python 3.13.5
|
||||
ls -la /home/oib/windsurf/aitbc/.venv/bin/python # Check development venv
|
||||
node --version # Should show v22.22.x
|
||||
node --version # Should show v24.14.x
|
||||
npm --version # Should show compatible version
|
||||
|
||||
# Test symlink resolution
|
||||
@@ -307,7 +307,7 @@ ssh aitbc1-cascade # Direct SSH to aitbc1 container (incus)
|
||||
- Purpose: secondary AITBC dev environment (incus container)
|
||||
- Host: 10.1.223.40 (Debian 13 Trixie), accessible via new SSH alias `aitbc1-cascade`
|
||||
- OS: Debian 13 Trixie (development environment)
|
||||
- Node.js: 22+ (current tested: v22.22.x)
|
||||
- Node.js: 24+ (current tested: v24.14.x)
|
||||
- Python: 3.13.5+ (minimum requirement, strictly enforced)
|
||||
- Proxy device: incus proxy on host maps 127.0.0.1:18001 → 127.0.0.1:8000 inside container
|
||||
- AppArmor profile: unconfined (incus raw.lxc)
|
||||
@@ -353,9 +353,9 @@ ssh aitbc1-cascade # Direct SSH to aitbc1 container (incus)
|
||||
| Web UI | 8016 | python | 3.13.5 | /app/ | ✅ |
|
||||
| Geographic Load Balancer | 8017 | python | 3.13.5 | /api/loadbalancer/* | ✅ |
|
||||
|
||||
**Python 3.13.5 and Node.js 22+ Upgrade Complete** (2026-03-05):
|
||||
**Python 3.13.5 and Node.js 24+ Upgrade Complete** (2026-03-05):
|
||||
- All services upgraded to Python 3.13.5
|
||||
- Node.js upgraded to 22+ (current tested: v22.22.x)
|
||||
- Node.js upgraded to 24+ (current tested: v24.14.x)
|
||||
- Virtual environments updated and verified
|
||||
- API routing fixed for external access
|
||||
- Services fully operational with enhanced performance
|
||||
@@ -381,7 +381,7 @@ All Python services in the AITBC container run on **Python 3.13.5** with isolate
|
||||
**Verification Commands:**
|
||||
```bash
|
||||
ssh aitbc-cascade "python3 --version" # Should show Python 3.13.5
|
||||
ssh aitbc-cascade "node --version" # Should show v22.22.x
|
||||
ssh aitbc-cascade "node --version" # Should show v24.14.x
|
||||
ssh aitbc-cascade "npm --version" # Should show compatible version
|
||||
ssh aitbc-cascade "ls -la /opt/*/.venv/bin/python" # Check venv symlinks
|
||||
ssh aitbc-cascade "curl -s http://127.0.0.1:8000/v1/health" # Coordinator API health
|
||||
|
||||
@@ -25,7 +25,7 @@ This guide provides comprehensive deployment instructions for the **aitbc server
|
||||
### **Software Requirements**
|
||||
- **Operating System**: Debian 13 Trixie (primary) or Ubuntu 22.04+ (alternative)
|
||||
- **Python**: 3.13.5+ (strictly enforced - platform requires 3.13+ features)
|
||||
- **Node.js**: 22+ (current tested: v22.22.x)
|
||||
- **Node.js**: 24+ (current tested: v24.14.x)
|
||||
- **Database**: SQLite (default) or PostgreSQL (production)
|
||||
|
||||
### **Network Requirements**
|
||||
|
||||
@@ -176,9 +176,9 @@ python3 --version # Should show 3.13.x
|
||||
|
||||
### **🔥 Issue 1b: Node.js Version Compatibility**
|
||||
|
||||
**Current Status**: Node.js v22.22.x (tested and compatible)
|
||||
**Current Status**: Node.js v24.14.x (tested and compatible)
|
||||
|
||||
**Note**: Current Node.js version v22.22.x meets the minimum requirement of 22.0.0 and is fully compatible with AITBC platform.
|
||||
**Note**: Current Node.js version v24.14.x meets the minimum requirement of 24.14.0 and is fully compatible with AITBC platform.
|
||||
|
||||
### **🔥 Issue 1c: Operating System Compatibility**
|
||||
|
||||
|
||||
32
drain_test.py
Normal file
32
drain_test.py
Normal file
@@ -0,0 +1,32 @@
|
||||
import sys
|
||||
from pathlib import Path
|
||||
import json
|
||||
|
||||
# Setup sys.path
|
||||
sys.path.insert(0, str(Path('/opt/aitbc/apps/blockchain-node/src')))
|
||||
|
||||
from aitbc_chain.config import settings
|
||||
from aitbc_chain.mempool import init_mempool, get_mempool
|
||||
|
||||
# Use development mempool backend configuration exactly like main node
|
||||
init_mempool(
|
||||
backend=settings.mempool_backend,
|
||||
db_path=str(settings.db_path.parent / "mempool.db"),
|
||||
max_size=settings.mempool_max_size,
|
||||
min_fee=settings.min_fee,
|
||||
)
|
||||
|
||||
mempool = get_mempool()
|
||||
print(f"Mempool class: {mempool.__class__.__name__}")
|
||||
print(f"Mempool DB path: {mempool._db_path}")
|
||||
|
||||
chain_id = 'ait-mainnet'
|
||||
rows = mempool._conn.execute("SELECT * FROM mempool WHERE chain_id = ?", (chain_id,)).fetchall()
|
||||
print(f"Found {len(rows)} raw rows in DB")
|
||||
for r in rows:
|
||||
print(r)
|
||||
|
||||
txs = mempool.drain(100, 1000000, chain_id)
|
||||
print(f"Drained {len(txs)} txs")
|
||||
for tx in txs:
|
||||
print(tx)
|
||||
9
fix_gossip.patch
Normal file
9
fix_gossip.patch
Normal file
@@ -0,0 +1,9 @@
|
||||
--- /opt/aitbc/apps/blockchain-node/src/aitbc_chain/gossip/broker.py 2026-03-23 12:40:00.000000000 +0100
|
||||
+++ /opt/aitbc/apps/blockchain-node/src/aitbc_chain/gossip/broker.py.new 2026-03-23 12:40:00.000000000 +0100
|
||||
@@ -6,7 +6,7 @@
|
||||
import warnings
|
||||
from collections import defaultdict
|
||||
-from contextlib import suppress
|
||||
+from contextlib import suppress, asynccontextmanager
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Callable, Dict, List, Optional, Set
|
||||
30
fix_inprocess.py
Normal file
30
fix_inprocess.py
Normal file
@@ -0,0 +1,30 @@
|
||||
import asyncio
|
||||
from contextlib import asynccontextmanager
|
||||
from typing import Any
|
||||
|
||||
class _InProcessSubscriber:
|
||||
def __init__(self, queue, release):
|
||||
self._queue = queue
|
||||
self._release = release
|
||||
def __aiter__(self):
|
||||
return self._iterator()
|
||||
async def _iterator(self):
|
||||
try:
|
||||
while True:
|
||||
yield await self._queue.get()
|
||||
finally:
|
||||
pass
|
||||
|
||||
@asynccontextmanager
|
||||
async def subscribe():
|
||||
queue = asyncio.Queue()
|
||||
try:
|
||||
yield _InProcessSubscriber(queue, lambda: None)
|
||||
finally:
|
||||
pass
|
||||
|
||||
async def main():
|
||||
async with subscribe() as sub:
|
||||
print("Success")
|
||||
|
||||
asyncio.run(main())
|
||||
10
fix_poa.py
Normal file
10
fix_poa.py
Normal file
@@ -0,0 +1,10 @@
|
||||
import re
|
||||
|
||||
with open("/opt/aitbc/apps/blockchain-node/src/aitbc_chain/consensus/poa.py", "r") as f:
|
||||
content = f.read()
|
||||
|
||||
# Make sure we use the correct chain_id when draining from mempool
|
||||
new_content = content.replace("mempool.drain(max_txs, max_bytes, self._config.chain_id)", "mempool.drain(max_txs, max_bytes, 'ait-mainnet')")
|
||||
|
||||
with open("/opt/aitbc/apps/blockchain-node/src/aitbc_chain/consensus/poa.py", "w") as f:
|
||||
f.write(new_content)
|
||||
10
fix_router.py
Normal file
10
fix_router.py
Normal file
@@ -0,0 +1,10 @@
|
||||
import re
|
||||
|
||||
with open("/opt/aitbc/apps/blockchain-node/src/aitbc_chain/rpc/router.py", "r") as f:
|
||||
content = f.read()
|
||||
|
||||
# Make sure we use the correct chain_id when adding to mempool
|
||||
new_content = content.replace("mempool.add(tx_dict, chain_id=chain_id)", "mempool.add(tx_dict, chain_id=chain_id or request.payload.get('chain_id') or 'ait-mainnet')")
|
||||
|
||||
with open("/opt/aitbc/apps/blockchain-node/src/aitbc_chain/rpc/router.py", "w") as f:
|
||||
f.write(new_content)
|
||||
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";
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@
|
||||
},
|
||||
"homepage": "https://aitbc.bubuit.net/docs/",
|
||||
"engines": {
|
||||
"node": ">=22.22.0"
|
||||
"node": ">=24.14.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@@ -25,6 +25,6 @@
|
||||
"@openzeppelin/contracts": "^5.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.22.0"
|
||||
"node": ">=24.14.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user