@lodestar/api
Version:
A Typescript REST client for the Ethereum Consensus API
154 lines • 7.45 kB
JavaScript
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