Source mirror · commit 369512f · 2026-10-26 · MIT · canonical repo: gitlab.com/jiapunk/upgrade-airlock
git clone https://upgrade-airlock.pages.dev/source/upgrade-airlock.git
upgrade-airlock / web / src / chaindata.ts
web/src/chaindata.ts67 lines · 2671 bytes
1// Deployment addresses the page reads.
2// - live (?mode=airlock): src/chain-data-sepolia.json, written by scripts/sync-sepolia-data.mjs from the
3// DeployEth.s.sol output (default deployments/sepolia.json). Until a deployment exists it is a placeholder
4// (pending: true) and the page says the contracts are not deployed yet.
5// - offline (?mode=offline): the deployment block inside src/recorded-run.json (scripts/record-run.mjs).
6import SEPOLIA_DATA from './chain-data-sepolia.json'
7import RECORDED from './recorded-run.json'
8import { OFFLINE } from './runtime'
9import type { ImplName } from './types'
10
11export interface ChainData {
12 pending: boolean
13 chainId: number
14 startBlock: number
15 delayBlocks: number
16 airlockAdmin: string
17 proxy: string
18 /** AirlockReceiver: guardians[0] and the clearance oracle (Chainlink CRE reports land here) */
19 receiver: string
20 /** Human emergency guardian: guardians[1] */
21 emergencyGuardian: string
22 /** Manual clearance and codehash registry (not a guardian) */
23 approver: string
24 owner: string
25 attester: string
26 forwarder: string
27 impls: Partial<Record<ImplName, string>>
28}
29
30/** A JSON-RPC log as returned by eth_getLogs / eth_subscribe */
31export interface RawLog {
32 address: string
33 topics: `0x${string}`[]
34 data: `0x${string}`
35 blockNumber: `0x${string}`
36 transactionHash: `0x${string}`
37 logIndex: `0x${string}`
38 removed?: boolean
39}
40
41/** The recorded run that offline mode plays back */
42export interface RecordedRun {
43 v: number
44 /** sepolia: recorded from Ethereum Sepolia; sepolia-fork: recorded from a local anvil fork of Sepolia; none: placeholder */
45 source: 'sepolia' | 'sepolia-fork' | 'none'
46 /** Recording date (YYYY-MM-DD) */
47 recordedOn: string
48 /** Last block of the recording */
49 head: number
50 deployment: ChainData
51 logs: RawLog[]
52 /** block number -> block timestamp (s) */
53 blocks: Record<string, number>
54 /** tx hash -> receipt numbers */
55 receipts: Record<string, { status: string; gasUsed: string; effectiveGasPrice: string; blockNumber: number }>
56 /** id -> getProposal + clearanceOf at the end of the recording */
57 proposals: Record<
58 string,
59 { kind: number; status: number; proposer: string; target: string; codehash: string; proposedBlock: number; readyBlock: number; vetoCount: number; clearanceOf: string }
60 >
61}
62
63export const RECORDING = RECORDED as unknown as RecordedRun
64export const DATA: ChainData = (OFFLINE ? RECORDING.deployment : SEPOLIA_DATA) as ChainData
65
66/** The live deployment file is still a placeholder (or offline mode has no recording yet) */
67export const PENDING = DATA.pending === true || (OFFLINE && RECORDING.source === 'none')