UNPKG

@lodestar/api

Version:

A Typescript REST client for the Ethereum Consensus API

609 lines • 30.4 kB
import { ContainerType } from "@chainsafe/ssz"; import { isForkPostDeneb, isForkPostElectra } from "@lodestar/params"; import { ProducedBlockSource, ssz, sszTypesFor, stringType, } from "@lodestar/types"; import { fromHex, toHex, toRootHex } from "@lodestar/utils"; import { ArrayOf, EmptyMetaCodec, EmptyResponseCodec, JsonOnlyReq, WithMeta, WithVersion, } from "../../utils/codecs.js"; import { getPostBellatrixForkTypes, toForkName } from "../../utils/fork.js"; import { fromHeaders } from "../../utils/headers.js"; import { Schema } from "../../utils/index.js"; import { ExecutionOptimisticAndDependentRootCodec, ExecutionOptimisticCodec, MetaHeader, VersionCodec, VersionType, } from "../../utils/metadata.js"; import { fromGraffitiHex, toBoolean, toGraffitiHex } from "../../utils/serdes.js"; export var BuilderSelection; (function (BuilderSelection) { BuilderSelection["Default"] = "default"; BuilderSelection["BuilderAlways"] = "builderalways"; BuilderSelection["ExecutionAlways"] = "executionalways"; BuilderSelection["MaxProfit"] = "maxprofit"; /** Only activate builder flow for DVT block proposal protocols */ BuilderSelection["BuilderOnly"] = "builderonly"; /** Only builds execution block*/ BuilderSelection["ExecutionOnly"] = "executiononly"; })(BuilderSelection || (BuilderSelection = {})); export const ProduceBlockV3MetaType = new ContainerType({ ...VersionType.fields, /** Specifies whether the response contains full or blinded block */ executionPayloadBlinded: ssz.Boolean, /** Execution payload value in Wei */ executionPayloadValue: ssz.UintBn64, /** Consensus rewards paid to the proposer for this block, in Wei */ consensusBlockValue: ssz.UintBn64, }, { jsonCase: "eth2" }); export const AttesterDutyType = new ContainerType({ /** The validator's public key, uniquely identifying them */ pubkey: ssz.BLSPubkey, /** Index of validator in validator registry */ validatorIndex: ssz.ValidatorIndex, /** Index of the committee */ committeeIndex: ssz.CommitteeIndex, /** Number of validators in committee */ committeeLength: ssz.UintNum64, /** Number of committees at the provided slot */ committeesAtSlot: ssz.UintNum64, /** Index of validator in committee */ validatorCommitteeIndex: ssz.UintNum64, /** The slot at which the validator must attest */ slot: ssz.Slot, }, { jsonCase: "eth2" }); export const ProposerDutyType = new ContainerType({ slot: ssz.Slot, validatorIndex: ssz.ValidatorIndex, pubkey: ssz.BLSPubkey, }, { jsonCase: "eth2" }); /** * From https://github.com/ethereum/beacon-APIs/pull/134 */ export const SyncDutyType = new ContainerType({ pubkey: ssz.BLSPubkey, /** Index of validator in validator registry. */ validatorIndex: ssz.ValidatorIndex, /** The indices of the validator in the sync committee. */ validatorSyncCommitteeIndices: ArrayOf(ssz.CommitteeIndex), }, { jsonCase: "eth2" }); export const BeaconCommitteeSubscriptionType = new ContainerType({ validatorIndex: ssz.ValidatorIndex, committeeIndex: ssz.CommitteeIndex, committeesAtSlot: ssz.Slot, slot: ssz.Slot, isAggregator: ssz.Boolean, }, { jsonCase: "eth2" }); /** * From https://github.com/ethereum/beacon-APIs/pull/136 */ export const SyncCommitteeSubscriptionType = new ContainerType({ validatorIndex: ssz.ValidatorIndex, syncCommitteeIndices: ArrayOf(ssz.CommitteeIndex), untilEpoch: ssz.Epoch, }, { jsonCase: "eth2" }); export const ProposerPreparationDataType = new ContainerType({ validatorIndex: ssz.ValidatorIndex, feeRecipient: stringType, }, { jsonCase: "eth2" }); /** * From https://github.com/ethereum/beacon-APIs/pull/224 */ export const BeaconCommitteeSelectionType = new ContainerType({ /** Index of the validator */ validatorIndex: ssz.ValidatorIndex, /** The slot at which a validator is assigned to attest */ slot: ssz.Slot, /** The `slot_signature` calculated by the validator for the upcoming attestation slot */ selectionProof: ssz.BLSSignature, }, { jsonCase: "eth2" }); /** * From https://github.com/ethereum/beacon-APIs/pull/224 */ export const SyncCommitteeSelectionType = new ContainerType({ /** Index of the validator */ validatorIndex: ssz.ValidatorIndex, /** The slot at which validator is assigned to produce a sync committee contribution */ slot: ssz.Slot, /** SubcommitteeIndex to which the validator is assigned */ subcommitteeIndex: ssz.SubcommitteeIndex, /** The `slot_signature` calculated by the validator for the upcoming sync committee slot */ selectionProof: ssz.BLSSignature, }, { jsonCase: "eth2" }); export const LivenessResponseDataType = new ContainerType({ index: ssz.ValidatorIndex, isLive: ssz.Boolean, }, { jsonCase: "eth2" }); export const ValidatorIndicesType = ArrayOf(ssz.ValidatorIndex); export const AttesterDutyListType = ArrayOf(AttesterDutyType); export const ProposerDutyListType = ArrayOf(ProposerDutyType); export const SyncDutyListType = ArrayOf(SyncDutyType); export const SignedAggregateAndProofListPhase0Type = ArrayOf(ssz.phase0.SignedAggregateAndProof); export const SignedAggregateAndProofListElectraType = ArrayOf(ssz.electra.SignedAggregateAndProof); export const SignedContributionAndProofListType = ArrayOf(ssz.altair.SignedContributionAndProof); export const BeaconCommitteeSubscriptionListType = ArrayOf(BeaconCommitteeSubscriptionType); export const SyncCommitteeSubscriptionListType = ArrayOf(SyncCommitteeSubscriptionType); export const ProposerPreparationDataListType = ArrayOf(ProposerPreparationDataType); export const BeaconCommitteeSelectionListType = ArrayOf(BeaconCommitteeSelectionType); export const SyncCommitteeSelectionListType = ArrayOf(SyncCommitteeSelectionType); export const LivenessResponseDataListType = ArrayOf(LivenessResponseDataType); export const SignedValidatorRegistrationV1ListType = ArrayOf(ssz.bellatrix.SignedValidatorRegistrationV1); export function getDefinitions(config) { return { getAttesterDuties: { url: "/eth/v1/validator/duties/attester/{epoch}", method: "POST", req: { writeReqJson: ({ epoch, indices }) => ({ params: { epoch }, body: ValidatorIndicesType.toJson(indices) }), parseReqJson: ({ params, body }) => ({ epoch: params.epoch, indices: ValidatorIndicesType.fromJson(body) }), writeReqSsz: ({ epoch, indices }) => ({ params: { epoch }, body: ValidatorIndicesType.serialize(indices) }), parseReqSsz: ({ params, body }) => ({ epoch: params.epoch, indices: ValidatorIndicesType.deserialize(body) }), schema: { params: { epoch: Schema.UintRequired }, body: Schema.StringArray, }, }, resp: { data: AttesterDutyListType, meta: ExecutionOptimisticAndDependentRootCodec, }, }, getProposerDuties: { url: "/eth/v1/validator/duties/proposer/{epoch}", method: "GET", req: { writeReq: ({ epoch }) => ({ params: { epoch } }), parseReq: ({ params }) => ({ epoch: params.epoch }), schema: { params: { epoch: Schema.UintRequired }, }, }, resp: { data: ProposerDutyListType, meta: ExecutionOptimisticAndDependentRootCodec, }, }, getSyncCommitteeDuties: { url: "/eth/v1/validator/duties/sync/{epoch}", method: "POST", req: { writeReqJson: ({ epoch, indices }) => ({ params: { epoch }, body: ValidatorIndicesType.toJson(indices) }), parseReqJson: ({ params, body }) => ({ epoch: params.epoch, indices: ValidatorIndicesType.fromJson(body) }), writeReqSsz: ({ epoch, indices }) => ({ params: { epoch }, body: ValidatorIndicesType.serialize(indices) }), parseReqSsz: ({ params, body }) => ({ epoch: params.epoch, indices: ValidatorIndicesType.deserialize(body) }), schema: { params: { epoch: Schema.UintRequired }, body: Schema.StringArray, }, }, resp: { data: SyncDutyListType, meta: ExecutionOptimisticCodec, }, }, produceBlockV2: { url: "/eth/v2/validator/blocks/{slot}", method: "GET", req: { writeReq: ({ slot, randaoReveal, graffiti, feeRecipient, builderSelection, strictFeeRecipientCheck }) => ({ params: { slot }, query: { randao_reveal: toHex(randaoReveal), graffiti: toGraffitiHex(graffiti), fee_recipient: feeRecipient, builder_selection: builderSelection, strict_fee_recipient_check: strictFeeRecipientCheck, }, }), parseReq: ({ params, query }) => ({ slot: params.slot, randaoReveal: fromHex(query.randao_reveal), graffiti: fromGraffitiHex(query.graffiti), feeRecipient: query.fee_recipient, builderSelection: query.builder_selection, strictFeeRecipientCheck: query.strict_fee_recipient_check, }), schema: { params: { slot: Schema.UintRequired }, query: { randao_reveal: Schema.StringRequired, graffiti: Schema.String, fee_recipient: Schema.String, builder_selection: Schema.String, strict_fee_recipient_check: Schema.Boolean, }, }, }, resp: { data: WithVersion((fork) => (isForkPostDeneb(fork) ? sszTypesFor(fork).BlockContents : ssz[fork].BeaconBlock)), meta: VersionCodec, }, }, produceBlockV3: { url: "/eth/v3/validator/blocks/{slot}", method: "GET", req: { writeReq: ({ slot, randaoReveal, graffiti, skipRandaoVerification, feeRecipient, builderSelection, builderBoostFactor, strictFeeRecipientCheck, blindedLocal, }) => ({ params: { slot }, query: { randao_reveal: toHex(randaoReveal), graffiti: toGraffitiHex(graffiti), skip_randao_verification: writeSkipRandaoVerification(skipRandaoVerification), fee_recipient: feeRecipient, builder_selection: builderSelection, builder_boost_factor: builderBoostFactor?.toString(), strict_fee_recipient_check: strictFeeRecipientCheck, blinded_local: blindedLocal, }, }), parseReq: ({ params, query }) => ({ slot: params.slot, randaoReveal: fromHex(query.randao_reveal), graffiti: fromGraffitiHex(query.graffiti), skipRandaoVerification: parseSkipRandaoVerification(query.skip_randao_verification), feeRecipient: query.fee_recipient, builderSelection: query.builder_selection, builderBoostFactor: parseBuilderBoostFactor(query.builder_boost_factor), strictFeeRecipientCheck: query.strict_fee_recipient_check, blindedLocal: query.blinded_local, }), schema: { params: { slot: Schema.UintRequired }, query: { randao_reveal: Schema.StringRequired, graffiti: Schema.String, skip_randao_verification: Schema.String, fee_recipient: Schema.String, builder_selection: Schema.String, builder_boost_factor: Schema.String, strict_fee_recipient_check: Schema.Boolean, blinded_local: Schema.Boolean, }, }, }, resp: { data: WithMeta(({ version, executionPayloadBlinded }) => (executionPayloadBlinded ? getPostBellatrixForkTypes(version).BlindedBeaconBlock : isForkPostDeneb(version) ? sszTypesFor(version).BlockContents : ssz[version].BeaconBlock)), meta: { toJson: (meta) => ({ ...ProduceBlockV3MetaType.toJson(meta), execution_payload_source: meta.executionPayloadSource, }), fromJson: (val) => { const { executionPayloadBlinded, ...meta } = ProduceBlockV3MetaType.fromJson(val); // Extract source from the data and assign defaults in the spec compliant manner if not present const executionPayloadSource = val.execution_payload_source ?? (executionPayloadBlinded === true ? ProducedBlockSource.builder : ProducedBlockSource.engine); return { ...meta, executionPayloadBlinded, executionPayloadSource }; }, toHeadersObject: (meta) => ({ [MetaHeader.Version]: meta.version, [MetaHeader.ExecutionPayloadBlinded]: meta.executionPayloadBlinded.toString(), [MetaHeader.ExecutionPayloadSource]: meta.executionPayloadSource.toString(), [MetaHeader.ExecutionPayloadValue]: meta.executionPayloadValue.toString(), [MetaHeader.ConsensusBlockValue]: meta.consensusBlockValue.toString(), }), fromHeaders: (headers) => { const executionPayloadBlinded = toBoolean(headers.getRequired(MetaHeader.ExecutionPayloadBlinded)); // Extract source from the headers and assign defaults in a spec compliant manner if not present const executionPayloadSource = headers.get(MetaHeader.ExecutionPayloadSource) ?? (executionPayloadBlinded === true ? ProducedBlockSource.builder : ProducedBlockSource.engine); return { version: toForkName(headers.getRequired(MetaHeader.Version)), executionPayloadBlinded, executionPayloadSource, executionPayloadValue: BigInt(headers.getRequired(MetaHeader.ExecutionPayloadValue)), consensusBlockValue: BigInt(headers.getRequired(MetaHeader.ConsensusBlockValue)), }; }, }, }, }, produceBlindedBlock: { url: "/eth/v1/validator/blinded_blocks/{slot}", method: "GET", req: { writeReq: ({ slot, randaoReveal, graffiti }) => ({ params: { slot }, query: { randao_reveal: toHex(randaoReveal), graffiti: toGraffitiHex(graffiti) }, }), parseReq: ({ params, query }) => ({ slot: params.slot, randaoReveal: fromHex(query.randao_reveal), graffiti: fromGraffitiHex(query.graffiti), }), schema: { params: { slot: Schema.UintRequired }, query: { randao_reveal: Schema.StringRequired, graffiti: Schema.String, }, }, }, resp: { data: WithVersion((fork) => getPostBellatrixForkTypes(fork).BlindedBeaconBlock), meta: VersionCodec, }, }, produceAttestationData: { url: "/eth/v1/validator/attestation_data", method: "GET", req: { writeReq: ({ committeeIndex, slot }) => ({ query: { slot, committee_index: committeeIndex } }), parseReq: ({ query }) => ({ committeeIndex: query.committee_index, slot: query.slot }), schema: { query: { slot: Schema.UintRequired, committee_index: Schema.UintRequired }, }, }, resp: { data: ssz.phase0.AttestationData, meta: EmptyMetaCodec, }, }, produceSyncCommitteeContribution: { url: "/eth/v1/validator/sync_committee_contribution", method: "GET", req: { writeReq: ({ slot, subcommitteeIndex, beaconBlockRoot }) => ({ query: { slot, subcommittee_index: subcommitteeIndex, beacon_block_root: toRootHex(beaconBlockRoot) }, }), parseReq: ({ query }) => ({ slot: query.slot, subcommitteeIndex: query.subcommittee_index, beaconBlockRoot: fromHex(query.beacon_block_root), }), schema: { query: { slot: Schema.UintRequired, subcommittee_index: Schema.UintRequired, beacon_block_root: Schema.StringRequired, }, }, }, resp: { data: ssz.altair.SyncCommitteeContribution, meta: EmptyMetaCodec, }, }, getAggregatedAttestation: { url: "/eth/v1/validator/aggregate_attestation", method: "GET", req: { writeReq: ({ attestationDataRoot, slot }) => ({ query: { attestation_data_root: toRootHex(attestationDataRoot), slot }, }), parseReq: ({ query }) => ({ attestationDataRoot: fromHex(query.attestation_data_root), slot: query.slot, }), schema: { query: { attestation_data_root: Schema.StringRequired, slot: Schema.UintRequired, }, }, }, resp: { data: ssz.phase0.Attestation, meta: EmptyMetaCodec, }, }, getAggregatedAttestationV2: { url: "/eth/v2/validator/aggregate_attestation", method: "GET", req: { writeReq: ({ attestationDataRoot, slot, committeeIndex }) => ({ query: { attestation_data_root: toHex(attestationDataRoot), slot, committee_index: committeeIndex }, }), parseReq: ({ query }) => ({ attestationDataRoot: fromHex(query.attestation_data_root), slot: query.slot, committeeIndex: query.committee_index, }), schema: { query: { attestation_data_root: Schema.StringRequired, slot: Schema.UintRequired, committee_index: Schema.UintRequired, }, }, }, resp: { data: WithVersion((fork) => (isForkPostElectra(fork) ? ssz.electra.Attestation : ssz.phase0.Attestation)), meta: VersionCodec, }, }, publishAggregateAndProofs: { url: "/eth/v1/validator/aggregate_and_proofs", method: "POST", req: { writeReqJson: ({ signedAggregateAndProofs }) => ({ body: SignedAggregateAndProofListPhase0Type.toJson(signedAggregateAndProofs), }), parseReqJson: ({ body }) => ({ signedAggregateAndProofs: SignedAggregateAndProofListPhase0Type.fromJson(body), }), writeReqSsz: ({ signedAggregateAndProofs }) => ({ body: SignedAggregateAndProofListPhase0Type.serialize(signedAggregateAndProofs), }), parseReqSsz: ({ body }) => ({ signedAggregateAndProofs: SignedAggregateAndProofListPhase0Type.deserialize(body), }), schema: { body: Schema.ObjectArray, }, }, resp: EmptyResponseCodec, }, publishAggregateAndProofsV2: { url: "/eth/v2/validator/aggregate_and_proofs", method: "POST", req: { writeReqJson: ({ signedAggregateAndProofs }) => { const fork = config.getForkName(signedAggregateAndProofs[0]?.message.aggregate.data.slot ?? 0); return { body: isForkPostElectra(fork) ? SignedAggregateAndProofListElectraType.toJson(signedAggregateAndProofs) : SignedAggregateAndProofListPhase0Type.toJson(signedAggregateAndProofs), headers: { [MetaHeader.Version]: fork }, }; }, parseReqJson: ({ body, headers }) => { const fork = toForkName(fromHeaders(headers, MetaHeader.Version)); return { signedAggregateAndProofs: isForkPostElectra(fork) ? SignedAggregateAndProofListElectraType.fromJson(body) : SignedAggregateAndProofListPhase0Type.fromJson(body), }; }, writeReqSsz: ({ signedAggregateAndProofs }) => { const fork = config.getForkName(signedAggregateAndProofs[0]?.message.aggregate.data.slot ?? 0); return { body: isForkPostElectra(fork) ? SignedAggregateAndProofListElectraType.serialize(signedAggregateAndProofs) : SignedAggregateAndProofListPhase0Type.serialize(signedAggregateAndProofs), headers: { [MetaHeader.Version]: fork }, }; }, parseReqSsz: ({ body, headers }) => { const fork = toForkName(fromHeaders(headers, MetaHeader.Version)); return { signedAggregateAndProofs: isForkPostElectra(fork) ? SignedAggregateAndProofListElectraType.deserialize(body) : SignedAggregateAndProofListPhase0Type.deserialize(body), }; }, schema: { body: Schema.ObjectArray, headers: { [MetaHeader.Version]: Schema.String }, }, }, resp: EmptyResponseCodec, }, publishContributionAndProofs: { url: "/eth/v1/validator/contribution_and_proofs", method: "POST", req: { writeReqJson: ({ contributionAndProofs }) => ({ body: SignedContributionAndProofListType.toJson(contributionAndProofs), }), parseReqJson: ({ body }) => ({ contributionAndProofs: SignedContributionAndProofListType.fromJson(body) }), writeReqSsz: ({ contributionAndProofs }) => ({ body: SignedContributionAndProofListType.serialize(contributionAndProofs), }), parseReqSsz: ({ body }) => ({ contributionAndProofs: SignedContributionAndProofListType.deserialize(body) }), schema: { body: Schema.ObjectArray, }, }, resp: EmptyResponseCodec, }, prepareBeaconCommitteeSubnet: { url: "/eth/v1/validator/beacon_committee_subscriptions", method: "POST", req: { writeReqJson: ({ subscriptions }) => ({ body: BeaconCommitteeSubscriptionListType.toJson(subscriptions) }), parseReqJson: ({ body }) => ({ subscriptions: BeaconCommitteeSubscriptionListType.fromJson(body) }), writeReqSsz: ({ subscriptions }) => ({ body: BeaconCommitteeSubscriptionListType.serialize(subscriptions) }), parseReqSsz: ({ body }) => ({ subscriptions: BeaconCommitteeSubscriptionListType.deserialize(body) }), schema: { body: Schema.ObjectArray }, }, resp: EmptyResponseCodec, }, prepareSyncCommitteeSubnets: { url: "/eth/v1/validator/sync_committee_subscriptions", method: "POST", req: { writeReqJson: ({ subscriptions }) => ({ body: SyncCommitteeSubscriptionListType.toJson(subscriptions) }), parseReqJson: ({ body }) => ({ subscriptions: SyncCommitteeSubscriptionListType.fromJson(body) }), writeReqSsz: ({ subscriptions }) => ({ body: SyncCommitteeSubscriptionListType.serialize(subscriptions) }), parseReqSsz: ({ body }) => ({ subscriptions: SyncCommitteeSubscriptionListType.deserialize(body) }), schema: { body: Schema.ObjectArray }, }, resp: EmptyResponseCodec, }, prepareBeaconProposer: { url: "/eth/v1/validator/prepare_beacon_proposer", method: "POST", req: JsonOnlyReq({ writeReqJson: ({ proposers }) => ({ body: ProposerPreparationDataListType.toJson(proposers) }), parseReqJson: ({ body }) => ({ proposers: ProposerPreparationDataListType.fromJson(body) }), schema: { body: Schema.ObjectArray }, }), resp: EmptyResponseCodec, }, submitBeaconCommitteeSelections: { url: "/eth/v1/validator/beacon_committee_selections", method: "POST", req: { writeReqJson: ({ selections }) => ({ body: BeaconCommitteeSelectionListType.toJson(selections) }), parseReqJson: ({ body }) => ({ selections: BeaconCommitteeSelectionListType.fromJson(body) }), writeReqSsz: ({ selections }) => ({ body: BeaconCommitteeSelectionListType.serialize(selections) }), parseReqSsz: ({ body }) => ({ selections: BeaconCommitteeSelectionListType.deserialize(body) }), schema: { body: Schema.ObjectArray, }, }, resp: { data: BeaconCommitteeSelectionListType, meta: EmptyMetaCodec, }, }, submitSyncCommitteeSelections: { url: "/eth/v1/validator/sync_committee_selections", method: "POST", req: { writeReqJson: ({ selections }) => ({ body: SyncCommitteeSelectionListType.toJson(selections) }), parseReqJson: ({ body }) => ({ selections: SyncCommitteeSelectionListType.fromJson(body) }), writeReqSsz: ({ selections }) => ({ body: SyncCommitteeSelectionListType.serialize(selections) }), parseReqSsz: ({ body }) => ({ selections: SyncCommitteeSelectionListType.deserialize(body) }), schema: { body: Schema.ObjectArray, }, }, resp: { data: SyncCommitteeSelectionListType, meta: EmptyMetaCodec, }, }, getLiveness: { url: "/eth/v1/validator/liveness/{epoch}", method: "POST", req: { writeReqJson: ({ epoch, indices }) => ({ params: { epoch }, body: ValidatorIndicesType.toJson(indices) }), parseReqJson: ({ params, body }) => ({ epoch: params.epoch, indices: ValidatorIndicesType.fromJson(body) }), writeReqSsz: ({ epoch, indices }) => ({ params: { epoch }, body: ValidatorIndicesType.serialize(indices) }), parseReqSsz: ({ params, body }) => ({ epoch: params.epoch, indices: ValidatorIndicesType.deserialize(body) }), schema: { params: { epoch: Schema.UintRequired }, body: Schema.StringArray, }, }, resp: { data: LivenessResponseDataListType, meta: EmptyMetaCodec, }, }, registerValidator: { url: "/eth/v1/validator/register_validator", method: "POST", req: { writeReqJson: ({ registrations }) => ({ body: SignedValidatorRegistrationV1ListType.toJson(registrations) }), parseReqJson: ({ body }) => ({ registrations: SignedValidatorRegistrationV1ListType.fromJson(body) }), writeReqSsz: ({ registrations }) => ({ body: SignedValidatorRegistrationV1ListType.serialize(registrations) }), parseReqSsz: ({ body }) => ({ registrations: SignedValidatorRegistrationV1ListType.deserialize(body) }), schema: { body: Schema.ObjectArray, }, }, resp: EmptyResponseCodec, }, }; } function parseBuilderBoostFactor(builderBoostFactorInput) { return builderBoostFactorInput !== undefined ? BigInt(builderBoostFactorInput) : undefined; } function writeSkipRandaoVerification(skipRandaoVerification) { return skipRandaoVerification === true ? "" : undefined; } function parseSkipRandaoVerification(skipRandaoVerification) { return skipRandaoVerification !== undefined && skipRandaoVerification === ""; } //# sourceMappingURL=validator.js.map