UNPKG

@lodestar/api

Version:

A Typescript REST client for the Ethereum Consensus API

184 lines 8.63 kB
import { ContainerType } from "@chainsafe/ssz"; import { StringType, ssz, sszTypesFor, } from "@lodestar/types"; import { EmptyResponseCodec } from "../../utils/codecs.js"; import { getPostAltairForkTypes, getPostBellatrixForkTypes } from "../../utils/fork.js"; import { Schema } from "../../utils/index.js"; import { VersionType } from "../../utils/metadata.js"; const stringType = new StringType(); export const blobSidecarSSE = new ContainerType({ blockRoot: stringType, index: ssz.BlobIndex, slot: ssz.Slot, kzgCommitment: stringType, versionedHash: stringType, }, { typeName: "BlobSidecarSSE", jsonCase: "eth2" }); export var EventType; (function (EventType) { /** * The node has finished processing, resulting in a new head. previous_duty_dependent_root is * `get_block_root_at_slot(state, compute_start_slot_at_epoch(epoch - 1) - 1)` and * current_duty_dependent_root is `get_block_root_at_slot(state, compute_start_slot_at_epoch(epoch) - 1)`. * Both dependent roots use the genesis block root in the case of underflow. */ EventType["head"] = "head"; /** The node has received a block (from P2P or API) that is successfully imported on the fork-choice `on_block` handler */ EventType["block"] = "block"; /** The node has received a block (from P2P or API) that passes validation rules of the `beacon_block` topic */ EventType["blockGossip"] = "block_gossip"; /** The node has received a valid attestation (from P2P or API) */ EventType["attestation"] = "attestation"; /** The node has received a valid SingleAttestation (from P2P or API) */ EventType["singleAttestation"] = "single_attestation"; /** The node has received a valid voluntary exit (from P2P or API) */ EventType["voluntaryExit"] = "voluntary_exit"; /** The node has received a valid proposer slashing (from P2P or API) */ EventType["proposerSlashing"] = "proposer_slashing"; /** The node has received a valid attester slashing (from P2P or API) */ EventType["attesterSlashing"] = "attester_slashing"; /** The node has received a valid blsToExecutionChange (from P2P or API) */ EventType["blsToExecutionChange"] = "bls_to_execution_change"; /** Finalized checkpoint has been updated */ EventType["finalizedCheckpoint"] = "finalized_checkpoint"; /** The node has reorganized its chain */ EventType["chainReorg"] = "chain_reorg"; /** The node has received a valid sync committee SignedContributionAndProof (from P2P or API) */ EventType["contributionAndProof"] = "contribution_and_proof"; /** New or better optimistic header update available */ EventType["lightClientOptimisticUpdate"] = "light_client_optimistic_update"; /** New or better finality update available */ EventType["lightClientFinalityUpdate"] = "light_client_finality_update"; /** Payload attributes for block proposal */ EventType["payloadAttributes"] = "payload_attributes"; /** The node has received a valid blobSidecar (from P2P or API) */ EventType["blobSidecar"] = "blob_sidecar"; })(EventType || (EventType = {})); export const eventTypes = { [EventType.head]: EventType.head, [EventType.block]: EventType.block, [EventType.blockGossip]: EventType.blockGossip, [EventType.attestation]: EventType.attestation, [EventType.singleAttestation]: EventType.singleAttestation, [EventType.voluntaryExit]: EventType.voluntaryExit, [EventType.proposerSlashing]: EventType.proposerSlashing, [EventType.attesterSlashing]: EventType.attesterSlashing, [EventType.blsToExecutionChange]: EventType.blsToExecutionChange, [EventType.finalizedCheckpoint]: EventType.finalizedCheckpoint, [EventType.chainReorg]: EventType.chainReorg, [EventType.contributionAndProof]: EventType.contributionAndProof, [EventType.lightClientOptimisticUpdate]: EventType.lightClientOptimisticUpdate, [EventType.lightClientFinalityUpdate]: EventType.lightClientFinalityUpdate, [EventType.payloadAttributes]: EventType.payloadAttributes, [EventType.blobSidecar]: EventType.blobSidecar, }; export function getDefinitions(_config) { return { eventstream: { url: "/eth/v1/events", method: "GET", req: { writeReq: ({ topics }) => ({ query: { topics } }), parseReq: ({ query }) => ({ topics: query.topics }), schema: { query: { topics: Schema.StringArrayRequired }, }, }, resp: EmptyResponseCodec, }, }; } export function getTypeByEvent(config) { const WithVersion = (getType) => { return { toJson: ({ data, version }) => ({ data: getType(version).toJson(data), version, }), fromJson: (val) => { const { version } = VersionType.fromJson(val); return { data: getType(version).fromJson(val.data), version, }; }, }; }; return { [EventType.head]: new ContainerType({ slot: ssz.Slot, block: stringType, state: stringType, epochTransition: ssz.Boolean, previousDutyDependentRoot: stringType, currentDutyDependentRoot: stringType, executionOptimistic: ssz.Boolean, }, { jsonCase: "eth2" }), [EventType.block]: new ContainerType({ slot: ssz.Slot, block: stringType, executionOptimistic: ssz.Boolean, }, { jsonCase: "eth2" }), [EventType.blockGossip]: new ContainerType({ slot: ssz.Slot, block: stringType, }, { jsonCase: "eth2" }), [EventType.attestation]: { toJson: (attestation) => { const fork = config.getForkName(attestation.data.slot); return sszTypesFor(fork).Attestation.toJson(attestation); }, fromJson: (attestation) => { const fork = config.getForkName(attestation.data.slot); return sszTypesFor(fork).Attestation.fromJson(attestation); }, }, [EventType.singleAttestation]: ssz.electra.SingleAttestation, [EventType.voluntaryExit]: ssz.phase0.SignedVoluntaryExit, [EventType.proposerSlashing]: ssz.phase0.ProposerSlashing, [EventType.attesterSlashing]: { toJson: (attesterSlashing) => { const fork = config.getForkName(Number(attesterSlashing.attestation1.data.slot)); return sszTypesFor(fork).AttesterSlashing.toJson(attesterSlashing); }, fromJson: (attesterSlashing) => { const fork = config.getForkName(Number(attesterSlashing.attestation1.data.slot)); return sszTypesFor(fork).AttesterSlashing.fromJson(attesterSlashing); }, }, [EventType.blsToExecutionChange]: ssz.capella.SignedBLSToExecutionChange, [EventType.finalizedCheckpoint]: new ContainerType({ block: stringType, state: stringType, epoch: ssz.Epoch, executionOptimistic: ssz.Boolean, }, { jsonCase: "eth2" }), [EventType.chainReorg]: new ContainerType({ slot: ssz.Slot, depth: ssz.UintNum64, oldHeadBlock: stringType, newHeadBlock: stringType, oldHeadState: stringType, newHeadState: stringType, epoch: ssz.Epoch, executionOptimistic: ssz.Boolean, }, { jsonCase: "eth2" }), [EventType.contributionAndProof]: ssz.altair.SignedContributionAndProof, [EventType.payloadAttributes]: WithVersion((fork) => getPostBellatrixForkTypes(fork).SSEPayloadAttributes), [EventType.blobSidecar]: blobSidecarSSE, [EventType.lightClientOptimisticUpdate]: WithVersion((fork) => getPostAltairForkTypes(fork).LightClientOptimisticUpdate), [EventType.lightClientFinalityUpdate]: WithVersion((fork) => getPostAltairForkTypes(fork).LightClientFinalityUpdate), }; } export function getEventSerdes(config) { const typeByEvent = getTypeByEvent(config); return { toJson: (event) => { const eventType = typeByEvent[event.type]; return eventType.toJson(event.message); }, fromJson: (type, data) => { const eventType = typeByEvent[type]; return eventType.fromJson(data); }, }; } //# sourceMappingURL=events.js.map