Problem Statement / Feature Objective
Voluntary exits require an unsigned exit message (containing validator index, epoch, and signature domain) to be signed by the withdrawal key – often held in cold storage or an air-gapped machine. Operators need a guided workflow that: constructs the unsigned exit message, presents it as a QR-encoded hex blob for air-gapped signing, accepts the signed result back, and broadcasts it to the beacon chain. The workflow must prevent accidental exits via a mandatory 3-step confirmation with cooldown timers.
Technical Invariants & Bounds
- Unsigned exit message format:
SSZ(VoluntaryExit{epoch, validator_index}) signed with domain DOMAIN_VOLUNTARY_EXIT
- QR encoding must use binary QR (not alphanumeric) to minimize scan failures – max payload size 2,953 bytes (Version 40 QR with medium error correction)
- Cooldown timer: after initiating exit for a validator, a 60-second "confirm cooldown" must elapse before broadcast is enabled
- 3-step confirmation: (1) Initiate → (2) Sign (accept signed blob) → (3) Broadcast
- Rate limiting: max 4 validator exits per epoch per operator account
- All unsigned messages must be logged with SHA-256 hash to a signed audit trail in IndexedDB
- Abort: user can cancel within the cooldown window; after broadcast, exit is irreversible (clear warning displayed)
Codebase Navigation Guide
src/hooks/useVoluntaryExit.ts – main workflow hook
src/components/validators/ExitWorkflowWizard.tsx – multi-step wizard UI
src/utils/sszSerialization.ts – SSZ encoding utilities for consensus types
src/utils/qrEncoder.ts – binary QR generation using qrcode library
src/services/beaconChainService.ts – extend with postVoluntaryExit method
src/store/exitSlice.ts – exit workflow state management
Implementation Blueprint
- Create
src/utils/exitMessageBuilder.ts – builds the SSZ-encoded VoluntaryExit message from validator index + current epoch (fetched from /eth/v1/beacon/genesis)
- Implement
src/utils/qrEncoder.ts – wraps qrcode binary mode to encode the unsigned exit hex as a QR canvas; validates payload fits Version 40 limits
- Build
src/hooks/useVoluntaryExit.ts – manages workflow steps, 60s cooldown timer, abort logic, 4-per-epoch rate limiter, and audit log
- Create
src/components/validators/ExitWorkflowWizard.tsx – 3-step wizard:
- Step 1: Validator selection + unsigned message display (QR + hex text) + cooldown timer start
- Step 2: Signed blob input (QR scanner via
react-qr-reader or paste hex) + signature validation
- Step 3: Broadcast confirmation with final warning + rate limit check
- Implement IndexedDB audit log in
src/services/exitAuditStore.ts – stores unsinged_msg_hash, timestamp, validator_index, broadcast_status
- Mount in
ValidatorDetail.tsx accessible via "Voluntary Exit" button in the validator actions toolbar
Problem Statement / Feature Objective
Voluntary exits require an unsigned exit message (containing validator index, epoch, and signature domain) to be signed by the withdrawal key – often held in cold storage or an air-gapped machine. Operators need a guided workflow that: constructs the unsigned exit message, presents it as a QR-encoded hex blob for air-gapped signing, accepts the signed result back, and broadcasts it to the beacon chain. The workflow must prevent accidental exits via a mandatory 3-step confirmation with cooldown timers.
Technical Invariants & Bounds
SSZ(VoluntaryExit{epoch, validator_index})signed with domainDOMAIN_VOLUNTARY_EXITCodebase Navigation Guide
src/hooks/useVoluntaryExit.ts– main workflow hooksrc/components/validators/ExitWorkflowWizard.tsx– multi-step wizard UIsrc/utils/sszSerialization.ts– SSZ encoding utilities for consensus typessrc/utils/qrEncoder.ts– binary QR generation usingqrcodelibrarysrc/services/beaconChainService.ts– extend withpostVoluntaryExitmethodsrc/store/exitSlice.ts– exit workflow state managementImplementation Blueprint
src/utils/exitMessageBuilder.ts– builds the SSZ-encodedVoluntaryExitmessage from validator index + current epoch (fetched from/eth/v1/beacon/genesis)src/utils/qrEncoder.ts– wrapsqrcodebinary mode to encode the unsigned exit hex as a QR canvas; validates payload fits Version 40 limitssrc/hooks/useVoluntaryExit.ts– manages workflow steps, 60s cooldown timer, abort logic, 4-per-epoch rate limiter, and audit logsrc/components/validators/ExitWorkflowWizard.tsx– 3-step wizard:react-qr-readeror paste hex) + signature validationsrc/services/exitAuditStore.ts– stores unsinged_msg_hash, timestamp, validator_index, broadcast_statusValidatorDetail.tsxaccessible via "Voluntary Exit" button in the validator actions toolbar