UNPKG

@lodestar/api

Version:

A Typescript REST client for the Ethereum Consensus API

154 lines • 7.45 kB
import { ListCompositeType } from "@chainsafe/ssz"; import { createBeaconConfig } from "@lodestar/config"; import { genesisData } from "@lodestar/config/networks"; import { ZERO_HASH } from "@lodestar/params"; import { ssz, } from "@lodestar/types"; import { fromHex } from "@lodestar/utils"; import { EmptyMetaCodec, EmptyRequestCodec, WithVersion, } from "../../utils/codecs.js"; import { getPostAltairForkTypes, toForkName } from "../../utils/fork.js"; import { Schema } from "../../utils/index.js"; import { MetaHeader, VersionCodec } from "../../utils/metadata.js"; export const HashListType = new ListCompositeType(ssz.Root, 10000); export function getDefinitions(config) { // Cache config so fork digests don't need to be recomputed let beaconConfig; const cachedBeaconConfig = () => { if (beaconConfig === undefined) { const genesisValidatorsRoot = genesisData[config.CONFIG_NAME]?.genesisValidatorsRoot; beaconConfig = createBeaconConfig(config, genesisValidatorsRoot ? fromHex(genesisValidatorsRoot) : ZERO_HASH); } return beaconConfig; }; return { getLightClientUpdatesByRange: { url: "/eth/v1/beacon/light_client/updates", method: "GET", req: { writeReq: ({ startPeriod, count }) => ({ query: { start_period: startPeriod, count } }), parseReq: ({ query }) => ({ startPeriod: query.start_period, count: query.count }), schema: { query: { start_period: Schema.UintRequired, count: Schema.UintRequired } }, }, resp: { data: { toJson: (data, meta) => { const json = []; for (const [i, update] of data.entries()) { json.push(getPostAltairForkTypes(meta.versions[i]).LightClientUpdate.toJson(update)); } return json; }, fromJson: (data, meta) => { const updates = data; const value = []; for (let i = 0; i < updates.length; i++) { const version = meta.versions[i]; value.push(getPostAltairForkTypes(version).LightClientUpdate.fromJson(updates[i])); } return value; }, serialize: (data, meta) => { const chunks = []; for (const [i, update] of data.entries()) { const version = meta.versions[i]; const forkDigest = cachedBeaconConfig().forkName2ForkDigest(version); const serialized = getPostAltairForkTypes(version).LightClientUpdate.serialize(update); const length = ssz.UintNum64.serialize(4 + serialized.length); chunks.push(length, forkDigest, serialized); } return Buffer.concat(chunks); }, deserialize: (data) => { let offset = 0; const updates = []; while (offset < data.length) { const length = ssz.UintNum64.deserialize(data.subarray(offset, offset + 8)); const forkDigest = ssz.ForkDigest.deserialize(data.subarray(offset + 8, offset + 12)); const version = cachedBeaconConfig().forkDigest2ForkName(forkDigest); updates.push(getPostAltairForkTypes(version).LightClientUpdate.deserialize(data.subarray(offset + 12, offset + 8 + length))); offset += 8 + length; } return updates; }, }, meta: { toJson: (meta) => meta, fromJson: (val) => val, toHeadersObject: (meta) => ({ [MetaHeader.Version]: meta.versions.join(","), }), fromHeaders: (headers) => { const versions = headers.getOrDefault(MetaHeader.Version, ""); return { versions: versions === "" ? [] : versions.split(",") }; }, }, transform: { toResponse: (data, meta) => { const updates = data; const resp = []; for (let i = 0; i < updates.length; i++) { resp.push({ data: updates[i], version: meta.versions[i] }); } return resp; }, fromResponse: (resp) => { if (!Array.isArray(resp)) { throw Error("JSON is not an array"); } const updates = []; const meta = { versions: [] }; for (const { data, version } of resp) { updates.push(data); meta.versions.push(toForkName(version)); } return { data: updates, meta }; }, }, }, }, getLightClientOptimisticUpdate: { url: "/eth/v1/beacon/light_client/optimistic_update", method: "GET", req: EmptyRequestCodec, resp: { data: WithVersion((fork) => getPostAltairForkTypes(fork).LightClientOptimisticUpdate), meta: VersionCodec, }, }, getLightClientFinalityUpdate: { url: "/eth/v1/beacon/light_client/finality_update", method: "GET", req: EmptyRequestCodec, resp: { data: WithVersion((fork) => getPostAltairForkTypes(fork).LightClientFinalityUpdate), meta: VersionCodec, }, }, getLightClientBootstrap: { url: "/eth/v1/beacon/light_client/bootstrap/{block_root}", method: "GET", req: { writeReq: ({ blockRoot }) => ({ params: { block_root: blockRoot } }), parseReq: ({ params }) => ({ blockRoot: params.block_root }), schema: { params: { block_root: Schema.StringRequired } }, }, resp: { data: WithVersion((fork) => getPostAltairForkTypes(fork).LightClientBootstrap), meta: VersionCodec, }, }, getLightClientCommitteeRoot: { url: "/eth/v0/beacon/light_client/committee_root", method: "GET", req: { writeReq: ({ startPeriod, count }) => ({ query: { start_period: startPeriod, count } }), parseReq: ({ query }) => ({ startPeriod: query.start_period, count: query.count }), schema: { query: { start_period: Schema.UintRequired, count: Schema.UintRequired } }, }, resp: { data: HashListType, meta: EmptyMetaCodec, }, }, }; } //# sourceMappingURL=lightclient.js.map