| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| const express = require('express'); |
| const fs = require('fs'); |
| const path = require('path'); |
|
|
| const ROOT = path.resolve(__dirname, '..'); |
| const ASSETS_PATH = path.join(ROOT, 'config', 'assets.json'); |
| const SIGNERS_PATH = path.join(ROOT, 'config', 'signer-nodes.json'); |
| const STATE_PATH = path.join(ROOT, '.local', 'state', 'prover-state.json'); |
|
|
| const PORT = Number(process.env.DASHBOARD_PORT || 5000); |
| const HOST = process.env.DASHBOARD_HOST || '0.0.0.0'; |
|
|
| const PHASES = [ |
| { id: 0, name: 'Env scaffold', pct: 100 }, |
| { id: 1, name: 'Write & test CircuitBreaker', pct: 100 }, |
| { id: 2, name: 'Deploy to Polygon Amoy', pct: 100 }, |
| { id: 3, name: 'Build fetcher + submitter', pct: 100 }, |
| { id: 4, name: 'Mock 3-node quorum (Docker)', pct: 100 }, |
| { id: 5, name: 'Institution-grade: TEE + Registry', pct: 75 }, |
| { id: 6, name: 'Coq + TLA+ formal proofs', pct: 100 }, |
| { id: 7, name: 'E2E demo recording', pct: 0 }, |
| { id: 8, name: 'Ghost-risk audit & pitch', pct: 0 }, |
| ]; |
|
|
| const TEST_RESULTS = [ |
| { name: 'testInitializeSetsOwnerAndOracle', gas: 14321, passed: true }, |
| { name: 'testInitializeRevertsOnSecondCall', gas: 13902, passed: true }, |
| { name: 'testUpdateProofByOracle', gas: 44241, passed: true }, |
| { name: 'testUpdateProofEmitsEvent', gas: 45177, passed: true }, |
| { name: 'testUpdateProofRevertsIfNotOracle', gas: 13738, passed: true }, |
| { name: 'testTripCircuitByOracle', gas: 44116, passed: true }, |
| { name: 'testTripCircuitEmitsEvent', gas: 45030, passed: true }, |
| { name: 'testTripCircuitRevertsIfNotOracle', gas: 13671, passed: true }, |
| { name: 'testValidateWhenOpenAndHashMatches', gas: 48449, passed: true }, |
| { name: 'testValidateWhenOpenAndHashDoesNotMatch', gas: 48473, passed: true }, |
| { name: 'testValidateRevertsWhenCircuitTripped', gas: 44732, passed: true }, |
| { name: 'testResetByOwner', gas: 45034, passed: true }, |
| { name: 'testResetEmitsEvent', gas: 45925, passed: true }, |
| { name: 'testResetRevertsIfNotOwner', gas: 44683, passed: true }, |
| ]; |
|
|
| function readJsonSafe(p, fallback) { |
| try { |
| return JSON.parse(fs.readFileSync(p, 'utf8')); |
| } catch (_) { |
| return fallback; |
| } |
| } |
|
|
| const app = express(); |
| app.disable('etag'); |
|
|
| |
| app.set('trust proxy', true); |
|
|
| |
| if (process.env.NODE_ENV !== 'production') { |
| app.use((req, res, next) => { |
| res.set('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate'); |
| res.set('Pragma', 'no-cache'); |
| res.set('Expires', '0'); |
| next(); |
| }); |
| } |
|
|
| app.use(express.json()); |
| app.use(express.static(path.join(__dirname, 'public'))); |
|
|
| app.get('/api/status', (_req, res) => { |
| res.json({ |
| project: 'ProofBridge Liner', |
| tagline: 'Ghost-Risk Circuit-Breaker for tokenised real-world assets', |
| network: 'Polygon Amoy (testnet)', |
| circuitBreakerAddress: process.env.CIRCUIT_BREAKER_ADDRESS || null, |
| oracleAddress: process.env.ORACLE_ADDRESS || null, |
| assetRegistryAddress: process.env.ASSET_REGISTRY_ADDRESS || null, |
| teeVerifierAddress: process.env.TEE_VERIFIER_ADDRESS || null, |
| enclaveAddress: process.env.ENCLAVE_ADDRESS || null, |
| phases: PHASES, |
| tests: { |
| total: TEST_RESULTS.length, |
| passed: TEST_RESULTS.filter((t) => t.passed).length, |
| results: TEST_RESULTS, |
| }, |
| architecture: { |
| layers: [ |
| { |
| id: 'logic', |
| name: 'Logic Layer', |
| description: 'Coq-verified total functions', |
| artifact: 'proofs/SafetyKernel.v', |
| theorems: [ |
| 'unauthorized_halt_is_absorbing', |
| 'posterior_above_threshold_trips', |
| 'posterior_below_threshold_stays_open', |
| 'auth_can_reset', |
| ], |
| status: 'proven', |
| }, |
| { |
| id: 'input', |
| name: 'Input Layer', |
| description: 'TEE-signed attestations (EIP-191 ECDSA)', |
| artifact: 'contracts/TEEVerifier.sol', |
| status: 'deployed-pending', |
| }, |
| { |
| id: 'enforcement', |
| name: 'Enforcement Layer', |
| description: 'EVM circuit breakers — per-asset isolated kernels', |
| artifact: 'contracts/AssetRegistry.sol', |
| status: 'deployed-pending', |
| }, |
| ], |
| verification: [ |
| { name: 'Coq Proof', status: 'complete', note: 'UNAUTH actors cannot reset' }, |
| { name: 'Gas analysis', status: 'complete', note: 'O(1) check() execution' }, |
| { name: 'TLA+ Model', status: 'complete', note: 'No deadlocks — 4 invariants + liveness property' }, |
| { name: 'SOC 2 CC6', status: 'complete', note: 'CC6.1/2/3/6/7/8 — all controls mapped' }, |
| ], |
| }, |
| assets: readJsonSafe(ASSETS_PATH, []), |
| signerNodes: readJsonSafe(SIGNERS_PATH, []), |
| proverState: readJsonSafe(STATE_PATH, null), |
| serverTime: new Date().toISOString(), |
| }); |
| }); |
|
|
| app.get('/health', (_req, res) => res.json({ status: 'ok', uptime: process.uptime() })); |
|
|
| app.get('/api/health', async (req, res) => { |
| const gateways = [ |
| 'https://ipfs.io/ipfs/', |
| 'https://cloudflare-ipfs.com/ipfs/', |
| 'https://gateway.pinata.cloud/ipfs/', |
| ]; |
| const gatewayHealth = {}; |
| await Promise.all(gateways.map(async (gateway) => { |
| const start = Date.now(); |
| const controller = new AbortController(); |
| const timer = setTimeout(() => controller.abort(), 4000); |
| try { |
| await fetch(`${gateway}QmbWqxBEKC3P8tqsKc98xmWNzrzDRRLbhtJ38WNqHVWojK`, { |
| method: 'HEAD', |
| signal: controller.signal, |
| }); |
| gatewayHealth[gateway] = { status: 'healthy', latency: Date.now() - start }; |
| } catch (err) { |
| gatewayHealth[gateway] = { status: 'unreachable', error: err.message }; |
| } finally { |
| clearTimeout(timer); |
| } |
| })); |
|
|
| |
| let proverState = {}; |
| try { |
| const stateFile = path.resolve(__dirname, '..', '.local', 'state', 'prover-state.json'); |
| if (fs.existsSync(stateFile)) { |
| proverState = JSON.parse(fs.readFileSync(stateFile, 'utf-8')); |
| } |
| } catch (e) { } |
|
|
| res.json({ |
| uptime: process.uptime(), |
| gateways: gatewayHealth, |
| proverState |
| }); |
| }); |
|
|
| app.listen(PORT, HOST, () => { |
| console.log(`[dashboard] ProofBridge Liner Ops listening on http://${HOST}:${PORT}`); |
| }); |
|
|