@lodestar/api 1.35.0-dev.f80d2d52da → 1.35.0-dev.fcf8d024ea

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/lib/beacon/client/beacon.d.ts.map +1 -0
  2. package/lib/beacon/client/config.d.ts.map +1 -0
  3. package/lib/beacon/client/debug.d.ts.map +1 -0
  4. package/lib/beacon/client/events.d.ts.map +1 -0
  5. package/lib/beacon/client/index.d.ts.map +1 -0
  6. package/lib/beacon/client/index.js.map +1 -1
  7. package/lib/beacon/client/lightclient.d.ts.map +1 -0
  8. package/lib/beacon/client/lodestar.d.ts.map +1 -0
  9. package/lib/beacon/client/node.d.ts.map +1 -0
  10. package/lib/beacon/client/proof.d.ts.map +1 -0
  11. package/lib/beacon/client/validator.d.ts.map +1 -0
  12. package/lib/beacon/index.d.ts +1 -1
  13. package/lib/beacon/index.d.ts.map +1 -0
  14. package/lib/beacon/index.js.map +1 -1
  15. package/lib/beacon/routes/beacon/block.d.ts.map +1 -0
  16. package/lib/beacon/routes/beacon/index.d.ts +3 -3
  17. package/lib/beacon/routes/beacon/index.d.ts.map +1 -0
  18. package/lib/beacon/routes/beacon/index.js.map +1 -1
  19. package/lib/beacon/routes/beacon/pool.d.ts +1 -1
  20. package/lib/beacon/routes/beacon/pool.d.ts.map +1 -0
  21. package/lib/beacon/routes/beacon/rewards.d.ts.map +1 -0
  22. package/lib/beacon/routes/beacon/rewards.js.map +1 -1
  23. package/lib/beacon/routes/beacon/state.d.ts +2 -2
  24. package/lib/beacon/routes/beacon/state.d.ts.map +1 -0
  25. package/lib/beacon/routes/config.d.ts +1 -1
  26. package/lib/beacon/routes/config.d.ts.map +1 -0
  27. package/lib/beacon/routes/debug.d.ts.map +1 -0
  28. package/lib/beacon/routes/events.d.ts.map +1 -0
  29. package/lib/beacon/routes/events.js.map +1 -1
  30. package/lib/beacon/routes/index.d.ts.map +1 -0
  31. package/lib/beacon/routes/index.js.map +1 -1
  32. package/lib/beacon/routes/lightclient.d.ts.map +1 -0
  33. package/lib/beacon/routes/lodestar.d.ts.map +1 -0
  34. package/lib/beacon/routes/node.d.ts.map +1 -0
  35. package/lib/beacon/routes/proof.d.ts.map +1 -0
  36. package/lib/beacon/routes/validator.d.ts +1 -1
  37. package/lib/beacon/routes/validator.d.ts.map +1 -0
  38. package/lib/beacon/server/beacon.d.ts.map +1 -0
  39. package/lib/beacon/server/config.d.ts.map +1 -0
  40. package/lib/beacon/server/debug.d.ts.map +1 -0
  41. package/lib/beacon/server/events.d.ts.map +1 -0
  42. package/lib/beacon/server/index.d.ts +1 -1
  43. package/lib/beacon/server/index.d.ts.map +1 -0
  44. package/lib/beacon/server/index.js.map +1 -1
  45. package/lib/beacon/server/lightclient.d.ts.map +1 -0
  46. package/lib/beacon/server/lodestar.d.ts.map +1 -0
  47. package/lib/beacon/server/node.d.ts.map +1 -0
  48. package/lib/beacon/server/proof.d.ts.map +1 -0
  49. package/lib/beacon/server/validator.d.ts.map +1 -0
  50. package/lib/builder/client.d.ts.map +1 -0
  51. package/lib/builder/index.d.ts.map +1 -0
  52. package/lib/builder/index.js.map +1 -1
  53. package/lib/builder/routes.d.ts.map +1 -0
  54. package/lib/builder/routes.js.map +1 -1
  55. package/lib/builder/server/index.d.ts +1 -1
  56. package/lib/builder/server/index.d.ts.map +1 -0
  57. package/lib/index.d.ts +6 -6
  58. package/lib/index.d.ts.map +1 -0
  59. package/lib/index.js +3 -3
  60. package/lib/index.js.map +1 -1
  61. package/lib/keymanager/client.d.ts.map +1 -0
  62. package/lib/keymanager/index.d.ts +2 -2
  63. package/lib/keymanager/index.d.ts.map +1 -0
  64. package/lib/keymanager/index.js +1 -2
  65. package/lib/keymanager/index.js.map +1 -1
  66. package/lib/keymanager/routes.d.ts.map +1 -0
  67. package/lib/keymanager/server/index.d.ts +1 -1
  68. package/lib/keymanager/server/index.d.ts.map +1 -0
  69. package/lib/server/index.d.ts.map +1 -0
  70. package/lib/utils/client/error.d.ts.map +1 -0
  71. package/lib/utils/client/error.js +2 -0
  72. package/lib/utils/client/error.js.map +1 -1
  73. package/lib/utils/client/eventSource.d.ts.map +1 -0
  74. package/lib/utils/client/format.d.ts.map +1 -0
  75. package/lib/utils/client/httpClient.d.ts +1 -2
  76. package/lib/utils/client/httpClient.d.ts.map +1 -0
  77. package/lib/utils/client/httpClient.js +13 -9
  78. package/lib/utils/client/httpClient.js.map +1 -1
  79. package/lib/utils/client/index.d.ts +1 -1
  80. package/lib/utils/client/index.d.ts.map +1 -0
  81. package/lib/utils/client/index.js +1 -1
  82. package/lib/utils/client/index.js.map +1 -1
  83. package/lib/utils/client/method.d.ts.map +1 -0
  84. package/lib/utils/client/metrics.d.ts.map +1 -0
  85. package/lib/utils/client/request.d.ts.map +1 -0
  86. package/lib/utils/client/response.d.ts.map +1 -0
  87. package/lib/utils/client/response.js +6 -0
  88. package/lib/utils/client/response.js.map +1 -1
  89. package/lib/utils/codecs.d.ts.map +1 -0
  90. package/lib/utils/fork.d.ts.map +1 -0
  91. package/lib/utils/headers.d.ts.map +1 -0
  92. package/lib/utils/httpStatusCode.d.ts.map +1 -0
  93. package/lib/utils/index.d.ts.map +1 -0
  94. package/lib/utils/metadata.d.ts.map +1 -0
  95. package/lib/utils/schema.d.ts.map +1 -0
  96. package/lib/utils/serdes.d.ts.map +1 -0
  97. package/lib/utils/server/error.d.ts.map +1 -0
  98. package/lib/utils/server/error.js +1 -0
  99. package/lib/utils/server/error.js.map +1 -1
  100. package/lib/utils/server/handler.d.ts.map +1 -0
  101. package/lib/utils/server/index.d.ts.map +1 -0
  102. package/lib/utils/server/method.d.ts.map +1 -0
  103. package/lib/utils/server/parser.d.ts.map +1 -0
  104. package/lib/utils/server/route.d.ts.map +1 -0
  105. package/lib/utils/server/route.js.map +1 -1
  106. package/lib/utils/types.d.ts.map +1 -0
  107. package/lib/utils/urlFormat.d.ts.map +1 -0
  108. package/lib/utils/wireFormat.d.ts.map +1 -0
  109. package/package.json +17 -11
  110. package/src/beacon/client/beacon.ts +12 -0
  111. package/src/beacon/client/config.ts +12 -0
  112. package/src/beacon/client/debug.ts +12 -0
  113. package/src/beacon/client/events.ts +69 -0
  114. package/src/beacon/client/index.ts +46 -0
  115. package/src/beacon/client/lightclient.ts +12 -0
  116. package/src/beacon/client/lodestar.ts +12 -0
  117. package/src/beacon/client/node.ts +12 -0
  118. package/src/beacon/client/proof.ts +12 -0
  119. package/src/beacon/client/validator.ts +12 -0
  120. package/src/beacon/index.ts +24 -0
  121. package/src/beacon/routes/beacon/block.ts +602 -0
  122. package/src/beacon/routes/beacon/index.ts +66 -0
  123. package/src/beacon/routes/beacon/pool.ts +503 -0
  124. package/src/beacon/routes/beacon/rewards.ts +216 -0
  125. package/src/beacon/routes/beacon/state.ts +588 -0
  126. package/src/beacon/routes/config.ts +114 -0
  127. package/src/beacon/routes/debug.ts +231 -0
  128. package/src/beacon/routes/events.ts +337 -0
  129. package/src/beacon/routes/index.ts +33 -0
  130. package/src/beacon/routes/lightclient.ts +241 -0
  131. package/src/beacon/routes/lodestar.ts +456 -0
  132. package/src/beacon/routes/node.ts +286 -0
  133. package/src/beacon/routes/proof.ts +79 -0
  134. package/src/beacon/routes/validator.ts +1014 -0
  135. package/src/beacon/server/beacon.ts +7 -0
  136. package/src/beacon/server/config.ts +7 -0
  137. package/src/beacon/server/debug.ts +7 -0
  138. package/src/beacon/server/events.ts +73 -0
  139. package/src/beacon/server/index.ts +55 -0
  140. package/src/beacon/server/lightclient.ts +7 -0
  141. package/src/beacon/server/lodestar.ts +7 -0
  142. package/src/beacon/server/node.ts +7 -0
  143. package/src/beacon/server/proof.ts +7 -0
  144. package/src/beacon/server/validator.ts +7 -0
  145. package/src/builder/client.ts +9 -0
  146. package/src/builder/index.ts +26 -0
  147. package/src/builder/routes.ts +227 -0
  148. package/src/builder/server/index.ts +19 -0
  149. package/src/index.ts +19 -0
  150. package/src/keymanager/client.ts +9 -0
  151. package/src/keymanager/index.ts +39 -0
  152. package/src/keymanager/routes.ts +699 -0
  153. package/src/keymanager/server/index.ts +19 -0
  154. package/src/server/index.ts +2 -0
  155. package/src/utils/client/error.ts +10 -0
  156. package/src/utils/client/eventSource.ts +7 -0
  157. package/src/utils/client/format.ts +22 -0
  158. package/src/utils/client/httpClient.ts +444 -0
  159. package/src/utils/client/index.ts +6 -0
  160. package/src/utils/client/method.ts +50 -0
  161. package/src/utils/client/metrics.ts +9 -0
  162. package/src/utils/client/request.ts +113 -0
  163. package/src/utils/client/response.ts +205 -0
  164. package/src/utils/codecs.ts +143 -0
  165. package/src/utils/fork.ts +44 -0
  166. package/src/utils/headers.ts +173 -0
  167. package/src/utils/httpStatusCode.ts +392 -0
  168. package/src/utils/index.ts +3 -0
  169. package/src/utils/metadata.ts +170 -0
  170. package/src/utils/schema.ts +141 -0
  171. package/src/utils/serdes.ts +120 -0
  172. package/src/utils/server/error.ts +9 -0
  173. package/src/utils/server/handler.ts +149 -0
  174. package/src/utils/server/index.ts +5 -0
  175. package/src/utils/server/method.ts +38 -0
  176. package/src/utils/server/parser.ts +15 -0
  177. package/src/utils/server/route.ts +45 -0
  178. package/src/utils/types.ts +161 -0
  179. package/src/utils/urlFormat.ts +112 -0
  180. package/src/utils/wireFormat.ts +24 -0
@@ -0,0 +1,1014 @@
1
+ import {ContainerType, Type, ValueOf} from "@chainsafe/ssz";
2
+ import {ChainForkConfig} from "@lodestar/config";
3
+ import {
4
+ ForkPostDeneb,
5
+ ForkPreDeneb,
6
+ VALIDATOR_REGISTRY_LIMIT,
7
+ isForkPostDeneb,
8
+ isForkPostElectra,
9
+ } from "@lodestar/params";
10
+ import {
11
+ Attestation,
12
+ BLSSignature,
13
+ BeaconBlock,
14
+ BlindedBeaconBlock,
15
+ BlockContents,
16
+ CommitteeIndex,
17
+ Epoch,
18
+ ProducedBlockSource,
19
+ Root,
20
+ Slot,
21
+ UintBn64,
22
+ ValidatorIndex,
23
+ altair,
24
+ phase0,
25
+ ssz,
26
+ sszTypesFor,
27
+ stringType,
28
+ } from "@lodestar/types";
29
+ import {fromHex, toHex, toRootHex} from "@lodestar/utils";
30
+ import {
31
+ ArrayOf,
32
+ EmptyMeta,
33
+ EmptyMetaCodec,
34
+ EmptyResponseCodec,
35
+ EmptyResponseData,
36
+ JsonOnlyReq,
37
+ WithVersion,
38
+ } from "../../utils/codecs.js";
39
+ import {getPostBellatrixForkTypes, toForkName} from "../../utils/fork.js";
40
+ import {fromHeaders} from "../../utils/headers.js";
41
+ import {Endpoint, RouteDefinitions, Schema} from "../../utils/index.js";
42
+ import {
43
+ ExecutionOptimisticAndDependentRootCodec,
44
+ ExecutionOptimisticAndDependentRootMeta,
45
+ ExecutionOptimisticCodec,
46
+ ExecutionOptimisticMeta,
47
+ MetaHeader,
48
+ VersionCodec,
49
+ VersionMeta,
50
+ VersionType,
51
+ } from "../../utils/metadata.js";
52
+ import {fromGraffitiHex, toBoolean, toGraffitiHex} from "../../utils/serdes.js";
53
+ import {WireFormat} from "../../utils/wireFormat.js";
54
+
55
+ export enum BuilderSelection {
56
+ Default = "default",
57
+ BuilderAlways = "builderalways",
58
+ ExecutionAlways = "executionalways",
59
+ MaxProfit = "maxprofit",
60
+ /** Only activate builder flow for DVT block proposal protocols */
61
+ BuilderOnly = "builderonly",
62
+ /** Only builds execution block*/
63
+ ExecutionOnly = "executiononly",
64
+ }
65
+
66
+ /** Lodestar-specific (non-standardized) options */
67
+ export type ExtraProduceBlockOpts = {
68
+ feeRecipient?: string;
69
+ builderSelection?: BuilderSelection;
70
+ strictFeeRecipientCheck?: boolean;
71
+ blindedLocal?: boolean;
72
+ };
73
+
74
+ export const ProduceBlockV3MetaType = new ContainerType(
75
+ {
76
+ ...VersionType.fields,
77
+ /** Specifies whether the response contains full or blinded block */
78
+ executionPayloadBlinded: ssz.Boolean,
79
+ /** Execution payload value in Wei */
80
+ executionPayloadValue: ssz.UintBn64,
81
+ /** Consensus rewards paid to the proposer for this block, in Wei */
82
+ consensusBlockValue: ssz.UintBn64,
83
+ },
84
+ {jsonCase: "eth2"}
85
+ );
86
+
87
+ export type ProduceBlockV3Meta = ValueOf<typeof ProduceBlockV3MetaType> & {
88
+ /** Lodestar-specific (non-standardized) value */
89
+ executionPayloadSource: ProducedBlockSource;
90
+ };
91
+
92
+ export const AttesterDutyType = new ContainerType(
93
+ {
94
+ /** The validator's public key, uniquely identifying them */
95
+ pubkey: ssz.BLSPubkey,
96
+ /** Index of validator in validator registry */
97
+ validatorIndex: ssz.ValidatorIndex,
98
+ /** Index of the committee */
99
+ committeeIndex: ssz.CommitteeIndex,
100
+ /** Number of validators in committee */
101
+ committeeLength: ssz.UintNum64,
102
+ /** Number of committees at the provided slot */
103
+ committeesAtSlot: ssz.UintNum64,
104
+ /** Index of validator in committee */
105
+ validatorCommitteeIndex: ssz.UintNum64,
106
+ /** The slot at which the validator must attest */
107
+ slot: ssz.Slot,
108
+ },
109
+ {jsonCase: "eth2"}
110
+ );
111
+
112
+ export const ProposerDutyType = new ContainerType(
113
+ {
114
+ slot: ssz.Slot,
115
+ validatorIndex: ssz.ValidatorIndex,
116
+ pubkey: ssz.BLSPubkey,
117
+ },
118
+ {jsonCase: "eth2"}
119
+ );
120
+
121
+ /**
122
+ * From https://github.com/ethereum/beacon-APIs/pull/134
123
+ */
124
+ export const SyncDutyType = new ContainerType(
125
+ {
126
+ pubkey: ssz.BLSPubkey,
127
+ /** Index of validator in validator registry. */
128
+ validatorIndex: ssz.ValidatorIndex,
129
+ /** The indices of the validator in the sync committee. */
130
+ validatorSyncCommitteeIndices: ArrayOf(ssz.CommitteeIndex),
131
+ },
132
+ {jsonCase: "eth2"}
133
+ );
134
+
135
+ export const BeaconCommitteeSubscriptionType = new ContainerType(
136
+ {
137
+ validatorIndex: ssz.ValidatorIndex,
138
+ committeeIndex: ssz.CommitteeIndex,
139
+ committeesAtSlot: ssz.Slot,
140
+ slot: ssz.Slot,
141
+ isAggregator: ssz.Boolean,
142
+ },
143
+ {jsonCase: "eth2"}
144
+ );
145
+
146
+ /**
147
+ * From https://github.com/ethereum/beacon-APIs/pull/136
148
+ */
149
+ export const SyncCommitteeSubscriptionType = new ContainerType(
150
+ {
151
+ validatorIndex: ssz.ValidatorIndex,
152
+ syncCommitteeIndices: ArrayOf(ssz.CommitteeIndex),
153
+ untilEpoch: ssz.Epoch,
154
+ },
155
+ {jsonCase: "eth2"}
156
+ );
157
+
158
+ export const ProposerPreparationDataType = new ContainerType(
159
+ {
160
+ validatorIndex: ssz.ValidatorIndex,
161
+ feeRecipient: stringType,
162
+ },
163
+ {jsonCase: "eth2"}
164
+ );
165
+
166
+ /**
167
+ * From https://github.com/ethereum/beacon-APIs/pull/224
168
+ */
169
+ export const BeaconCommitteeSelectionType = new ContainerType(
170
+ {
171
+ /** Index of the validator */
172
+ validatorIndex: ssz.ValidatorIndex,
173
+ /** The slot at which a validator is assigned to attest */
174
+ slot: ssz.Slot,
175
+ /** The `slot_signature` calculated by the validator for the upcoming attestation slot */
176
+ selectionProof: ssz.BLSSignature,
177
+ },
178
+ {jsonCase: "eth2"}
179
+ );
180
+
181
+ /**
182
+ * From https://github.com/ethereum/beacon-APIs/pull/224
183
+ */
184
+ export const SyncCommitteeSelectionType = new ContainerType(
185
+ {
186
+ /** Index of the validator */
187
+ validatorIndex: ssz.ValidatorIndex,
188
+ /** The slot at which validator is assigned to produce a sync committee contribution */
189
+ slot: ssz.Slot,
190
+ /** SubcommitteeIndex to which the validator is assigned */
191
+ subcommitteeIndex: ssz.SubcommitteeIndex,
192
+ /** The `slot_signature` calculated by the validator for the upcoming sync committee slot */
193
+ selectionProof: ssz.BLSSignature,
194
+ },
195
+ {jsonCase: "eth2"}
196
+ );
197
+
198
+ export const LivenessResponseDataType = new ContainerType(
199
+ {
200
+ index: ssz.ValidatorIndex,
201
+ isLive: ssz.Boolean,
202
+ },
203
+ {jsonCase: "eth2"}
204
+ );
205
+
206
+ export const ValidatorIndicesType = ArrayOf(ssz.ValidatorIndex);
207
+ export const AttesterDutyListType = ArrayOf(AttesterDutyType);
208
+ export const ProposerDutyListType = ArrayOf(ProposerDutyType);
209
+ export const SyncDutyListType = ArrayOf(SyncDutyType);
210
+ export const SignedAggregateAndProofListPhase0Type = ArrayOf(ssz.phase0.SignedAggregateAndProof);
211
+ export const SignedAggregateAndProofListElectraType = ArrayOf(ssz.electra.SignedAggregateAndProof);
212
+ export const SignedContributionAndProofListType = ArrayOf(ssz.altair.SignedContributionAndProof);
213
+ export const BeaconCommitteeSubscriptionListType = ArrayOf(BeaconCommitteeSubscriptionType);
214
+ export const SyncCommitteeSubscriptionListType = ArrayOf(SyncCommitteeSubscriptionType);
215
+ export const ProposerPreparationDataListType = ArrayOf(ProposerPreparationDataType);
216
+ export const BeaconCommitteeSelectionListType = ArrayOf(BeaconCommitteeSelectionType);
217
+ export const SyncCommitteeSelectionListType = ArrayOf(SyncCommitteeSelectionType);
218
+ export const LivenessResponseDataListType = ArrayOf(LivenessResponseDataType);
219
+ export const SignedValidatorRegistrationV1ListType = ArrayOf(
220
+ ssz.bellatrix.SignedValidatorRegistrationV1,
221
+ VALIDATOR_REGISTRY_LIMIT
222
+ );
223
+
224
+ export type ValidatorIndices = ValueOf<typeof ValidatorIndicesType>;
225
+ export type AttesterDuty = ValueOf<typeof AttesterDutyType>;
226
+ export type AttesterDutyList = ValueOf<typeof AttesterDutyListType>;
227
+ export type ProposerDuty = ValueOf<typeof ProposerDutyType>;
228
+ export type ProposerDutyList = ValueOf<typeof ProposerDutyListType>;
229
+ export type SyncDuty = ValueOf<typeof SyncDutyType>;
230
+ export type SyncDutyList = ValueOf<typeof SyncDutyListType>;
231
+ export type SignedAggregateAndProofListPhase0 = ValueOf<typeof SignedAggregateAndProofListPhase0Type>;
232
+ export type SignedAggregateAndProofListElectra = ValueOf<typeof SignedAggregateAndProofListElectraType>;
233
+ export type SignedAggregateAndProofList = SignedAggregateAndProofListPhase0 | SignedAggregateAndProofListElectra;
234
+ export type SignedContributionAndProofList = ValueOf<typeof SignedContributionAndProofListType>;
235
+ export type BeaconCommitteeSubscription = ValueOf<typeof BeaconCommitteeSubscriptionType>;
236
+ export type BeaconCommitteeSubscriptionList = ValueOf<typeof BeaconCommitteeSubscriptionListType>;
237
+ export type SyncCommitteeSubscription = ValueOf<typeof SyncCommitteeSubscriptionType>;
238
+ export type SyncCommitteeSubscriptionList = ValueOf<typeof SyncCommitteeSubscriptionListType>;
239
+ export type ProposerPreparationData = ValueOf<typeof ProposerPreparationDataType>;
240
+ export type ProposerPreparationDataList = ValueOf<typeof ProposerPreparationDataListType>;
241
+ export type BeaconCommitteeSelection = ValueOf<typeof BeaconCommitteeSelectionType>;
242
+ export type BeaconCommitteeSelectionList = ValueOf<typeof BeaconCommitteeSelectionListType>;
243
+ export type SyncCommitteeSelection = ValueOf<typeof SyncCommitteeSelectionType>;
244
+ export type SyncCommitteeSelectionList = ValueOf<typeof SyncCommitteeSelectionListType>;
245
+ export type LivenessResponseData = ValueOf<typeof LivenessResponseDataType>;
246
+ export type LivenessResponseDataList = ValueOf<typeof LivenessResponseDataListType>;
247
+ export type SignedValidatorRegistrationV1List = ValueOf<typeof SignedValidatorRegistrationV1ListType>;
248
+
249
+ export type Endpoints = {
250
+ /**
251
+ * Get attester duties
252
+ * Requests the beacon node to provide a set of attestation duties, which should be performed by validators, for a particular epoch.
253
+ * Duties should only need to be checked once per epoch, however a chain reorganization (of > MIN_SEED_LOOKAHEAD epochs) could occur, resulting in a change of duties. For full safety, you should monitor head events and confirm the dependent root in this response matches:
254
+ * - event.previous_duty_dependent_root when `compute_epoch_at_slot(event.slot) == epoch`
255
+ * - event.current_duty_dependent_root when `compute_epoch_at_slot(event.slot) + 1 == epoch`
256
+ * - event.block otherwise
257
+ * The dependent_root value is `get_block_root_at_slot(state, compute_start_slot_at_epoch(epoch - 1) - 1)` or the genesis block root in the case of underflow.
258
+ */
259
+ getAttesterDuties: Endpoint<
260
+ "POST",
261
+ {
262
+ /** Should only be allowed 1 epoch ahead */
263
+ epoch: Epoch;
264
+ /** An array of the validator indices for which to obtain the duties */
265
+ indices: ValidatorIndices;
266
+ },
267
+ {params: {epoch: Epoch}; body: unknown},
268
+ AttesterDutyList,
269
+ ExecutionOptimisticAndDependentRootMeta
270
+ >;
271
+
272
+ /**
273
+ * Get block proposers duties
274
+ * Request beacon node to provide all validators that are scheduled to propose a block in the given epoch.
275
+ * Duties should only need to be checked once per epoch, however a chain reorganization could occur that results in a change of duties. For full safety, you should monitor head events and confirm the dependent root in this response matches:
276
+ * - event.current_duty_dependent_root when `compute_epoch_at_slot(event.slot) == epoch`
277
+ * - event.block otherwise
278
+ * The dependent_root value is `get_block_root_at_slot(state, compute_start_slot_at_epoch(epoch) - 1)` or the genesis block root in the case of underflow.
279
+ */
280
+ getProposerDuties: Endpoint<
281
+ "GET",
282
+ {epoch: Epoch},
283
+ {params: {epoch: Epoch}},
284
+ ProposerDutyList,
285
+ ExecutionOptimisticAndDependentRootMeta
286
+ >;
287
+
288
+ getSyncCommitteeDuties: Endpoint<
289
+ "POST",
290
+ {
291
+ epoch: number;
292
+ indices: ValidatorIndices;
293
+ },
294
+ {params: {epoch: Epoch}; body: unknown},
295
+ SyncDutyList,
296
+ ExecutionOptimisticMeta
297
+ >;
298
+
299
+ /**
300
+ * Requests a beacon node to produce a valid block, which can then be signed by a validator.
301
+ * Metadata in the response indicates the type of block produced, and the supported types of block
302
+ * will be added to as forks progress.
303
+ */
304
+ produceBlockV3: Endpoint<
305
+ "GET",
306
+ {
307
+ /** The slot for which the block should be proposed */
308
+ slot: Slot;
309
+ /** The validator's randao reveal value */
310
+ randaoReveal: BLSSignature;
311
+ /** Arbitrary data validator wants to include in block */
312
+ graffiti?: string;
313
+ skipRandaoVerification?: boolean;
314
+ builderBoostFactor?: UintBn64;
315
+ } & ExtraProduceBlockOpts,
316
+ {
317
+ params: {slot: number};
318
+ query: {
319
+ randao_reveal: string;
320
+ graffiti?: string;
321
+ skip_randao_verification?: string;
322
+ fee_recipient?: string;
323
+ builder_selection?: string;
324
+ builder_boost_factor?: string;
325
+ strict_fee_recipient_check?: boolean;
326
+ blinded_local?: boolean;
327
+ };
328
+ },
329
+ BlockContents | BlindedBeaconBlock,
330
+ ProduceBlockV3Meta
331
+ >;
332
+
333
+ /**
334
+ * Produce an attestation data
335
+ * Requests that the beacon node produce an AttestationData.
336
+ */
337
+ produceAttestationData: Endpoint<
338
+ "GET",
339
+ {
340
+ /** The committee index for which an attestation data should be created */
341
+ committeeIndex?: CommitteeIndex;
342
+ /** The slot for which an attestation data should be created */
343
+ slot: Slot;
344
+ },
345
+ {query: {slot: number; committee_index?: number}},
346
+ phase0.AttestationData,
347
+ EmptyMeta
348
+ >;
349
+
350
+ produceSyncCommitteeContribution: Endpoint<
351
+ "GET",
352
+ {
353
+ slot: Slot;
354
+ subcommitteeIndex: number;
355
+ beaconBlockRoot: Root;
356
+ },
357
+ {query: {slot: number; subcommittee_index: number; beacon_block_root: string}},
358
+ altair.SyncCommitteeContribution,
359
+ EmptyMeta
360
+ >;
361
+
362
+ /**
363
+ * Get aggregated attestation
364
+ * Aggregates all attestations matching given attestation data root and slot
365
+ * Returns an aggregated `Attestation` object with same `AttestationData` root.
366
+ */
367
+ getAggregatedAttestation: Endpoint<
368
+ "GET",
369
+ {
370
+ /** HashTreeRoot of AttestationData that validator want's aggregated */
371
+ attestationDataRoot: Root;
372
+ slot: Slot;
373
+ },
374
+ {query: {attestation_data_root: string; slot: number}},
375
+ phase0.Attestation,
376
+ EmptyMeta
377
+ >;
378
+
379
+ /**
380
+ * Get aggregated attestation
381
+ * Aggregates all attestations matching given attestation data root, slot and committee index
382
+ * Returns an aggregated `Attestation` object with same `AttestationData` root.
383
+ */
384
+ getAggregatedAttestationV2: Endpoint<
385
+ "GET",
386
+ {
387
+ /** HashTreeRoot of AttestationData that validator want's aggregated */
388
+ attestationDataRoot: Root;
389
+ slot: Slot;
390
+ committeeIndex: number;
391
+ },
392
+ {query: {attestation_data_root: string; slot: number; committee_index: number}},
393
+ Attestation,
394
+ VersionMeta
395
+ >;
396
+
397
+ /**
398
+ * Publish multiple aggregate and proofs
399
+ * Verifies given aggregate and proofs and publishes them on appropriate gossipsub topic.
400
+ */
401
+ publishAggregateAndProofs: Endpoint<
402
+ "POST",
403
+ {signedAggregateAndProofs: SignedAggregateAndProofListPhase0},
404
+ {body: unknown},
405
+ EmptyResponseData,
406
+ EmptyMeta
407
+ >;
408
+
409
+ /**
410
+ * Publish multiple aggregate and proofs
411
+ * Verifies given aggregate and proofs and publishes them on appropriate gossipsub topic.
412
+ */
413
+ publishAggregateAndProofsV2: Endpoint<
414
+ "POST",
415
+ {signedAggregateAndProofs: SignedAggregateAndProofList},
416
+ {body: unknown; headers: {[MetaHeader.Version]: string}},
417
+ EmptyResponseData,
418
+ EmptyMeta
419
+ >;
420
+
421
+ publishContributionAndProofs: Endpoint<
422
+ "POST",
423
+ {contributionAndProofs: SignedContributionAndProofList},
424
+ {body: unknown},
425
+ EmptyResponseData,
426
+ EmptyMeta
427
+ >;
428
+
429
+ /**
430
+ * Signal beacon node to prepare for a committee subnet
431
+ * After beacon node receives this request,
432
+ * search using discv5 for peers related to this subnet
433
+ * and replace current peers with those ones if necessary
434
+ * If validator `is_aggregator`, beacon node must:
435
+ * - announce subnet topic subscription on gossipsub
436
+ * - aggregate attestations received on that subnet
437
+ *
438
+ * Returns if slot signature is valid and beacon node has prepared the attestation subnet.
439
+ *
440
+ * Note that we cannot be certain the Beacon node will find peers for that subnet for various reasons.
441
+ */
442
+ prepareBeaconCommitteeSubnet: Endpoint<
443
+ "POST",
444
+ {subscriptions: BeaconCommitteeSubscriptionList},
445
+ {body: unknown},
446
+ EmptyResponseData,
447
+ EmptyMeta
448
+ >;
449
+
450
+ prepareSyncCommitteeSubnets: Endpoint<
451
+ "POST",
452
+ {subscriptions: SyncCommitteeSubscriptionList},
453
+ {body: unknown},
454
+ EmptyResponseData,
455
+ EmptyMeta
456
+ >;
457
+
458
+ prepareBeaconProposer: Endpoint<
459
+ "POST",
460
+ {proposers: ProposerPreparationDataList},
461
+ {body: unknown},
462
+ EmptyResponseData,
463
+ EmptyMeta
464
+ >;
465
+
466
+ /**
467
+ * Determine if a distributed validator has been selected to aggregate attestations
468
+ *
469
+ * This endpoint is implemented by a distributed validator middleware client to exchange
470
+ * partial beacon committee selection proofs for combined/aggregated selection proofs to allow
471
+ * a validator client to correctly determine if one of its validators has been selected to
472
+ * perform an aggregation duty in this slot.
473
+ *
474
+ * Note that this endpoint is not implemented by the beacon node and will return a 501 error
475
+ *
476
+ * Returns an array of threshold aggregated beacon committee selection proofs
477
+ */
478
+ submitBeaconCommitteeSelections: Endpoint<
479
+ "POST",
480
+ {
481
+ /** An array of partial beacon committee selection proofs */
482
+ selections: BeaconCommitteeSelectionList;
483
+ },
484
+ {body: unknown},
485
+ BeaconCommitteeSelectionList,
486
+ EmptyMeta
487
+ >;
488
+
489
+ /**
490
+ * Determine if a distributed validator has been selected to make a sync committee contribution
491
+ *
492
+ * This endpoint is implemented by a distributed validator middleware client to exchange
493
+ * partial sync committee selection proofs for combined/aggregated selection proofs to allow
494
+ * a validator client to correctly determine if one of its validators has been selected to
495
+ * perform a sync committee contribution (sync aggregation) duty in this slot.
496
+ *
497
+ * Note that this endpoint is not implemented by the beacon node and will return a 501 error
498
+ *
499
+ * Returns an array of threshold aggregated sync committee selection proofs
500
+ */
501
+ submitSyncCommitteeSelections: Endpoint<
502
+ "POST",
503
+ {
504
+ /** An array of partial sync committee selection proofs */
505
+ selections: SyncCommitteeSelectionList;
506
+ },
507
+ {body: unknown},
508
+ SyncCommitteeSelectionList,
509
+ EmptyMeta
510
+ >;
511
+
512
+ /** Returns validator indices that have been observed to be active on the network */
513
+ getLiveness: Endpoint<
514
+ "POST",
515
+ {
516
+ epoch: Epoch;
517
+ indices: ValidatorIndex[];
518
+ },
519
+ {params: {epoch: Epoch}; body: unknown},
520
+ LivenessResponseDataList,
521
+ EmptyMeta
522
+ >;
523
+
524
+ registerValidator: Endpoint<
525
+ "POST",
526
+ {registrations: SignedValidatorRegistrationV1List},
527
+ {body: unknown},
528
+ EmptyResponseData,
529
+ EmptyMeta
530
+ >;
531
+ };
532
+
533
+ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoints> {
534
+ return {
535
+ getAttesterDuties: {
536
+ url: "/eth/v1/validator/duties/attester/{epoch}",
537
+ method: "POST",
538
+ req: {
539
+ writeReqJson: ({epoch, indices}) => ({params: {epoch}, body: ValidatorIndicesType.toJson(indices)}),
540
+ parseReqJson: ({params, body}) => ({epoch: params.epoch, indices: ValidatorIndicesType.fromJson(body)}),
541
+ writeReqSsz: ({epoch, indices}) => ({params: {epoch}, body: ValidatorIndicesType.serialize(indices)}),
542
+ parseReqSsz: ({params, body}) => ({epoch: params.epoch, indices: ValidatorIndicesType.deserialize(body)}),
543
+ schema: {
544
+ params: {epoch: Schema.UintRequired},
545
+ body: Schema.StringArray,
546
+ },
547
+ },
548
+ resp: {
549
+ data: AttesterDutyListType,
550
+ meta: ExecutionOptimisticAndDependentRootCodec,
551
+ },
552
+ },
553
+ getProposerDuties: {
554
+ url: "/eth/v1/validator/duties/proposer/{epoch}",
555
+ method: "GET",
556
+ req: {
557
+ writeReq: ({epoch}) => ({params: {epoch}}),
558
+ parseReq: ({params}) => ({epoch: params.epoch}),
559
+ schema: {
560
+ params: {epoch: Schema.UintRequired},
561
+ },
562
+ },
563
+ resp: {
564
+ data: ProposerDutyListType,
565
+ meta: ExecutionOptimisticAndDependentRootCodec,
566
+ },
567
+ },
568
+ getSyncCommitteeDuties: {
569
+ url: "/eth/v1/validator/duties/sync/{epoch}",
570
+ method: "POST",
571
+ req: {
572
+ writeReqJson: ({epoch, indices}) => ({params: {epoch}, body: ValidatorIndicesType.toJson(indices)}),
573
+ parseReqJson: ({params, body}) => ({epoch: params.epoch, indices: ValidatorIndicesType.fromJson(body)}),
574
+ writeReqSsz: ({epoch, indices}) => ({params: {epoch}, body: ValidatorIndicesType.serialize(indices)}),
575
+ parseReqSsz: ({params, body}) => ({epoch: params.epoch, indices: ValidatorIndicesType.deserialize(body)}),
576
+ schema: {
577
+ params: {epoch: Schema.UintRequired},
578
+ body: Schema.StringArray,
579
+ },
580
+ },
581
+ resp: {
582
+ data: SyncDutyListType,
583
+ meta: ExecutionOptimisticCodec,
584
+ },
585
+ },
586
+ produceBlockV3: {
587
+ url: "/eth/v3/validator/blocks/{slot}",
588
+ method: "GET",
589
+ req: {
590
+ writeReq: ({
591
+ slot,
592
+ randaoReveal,
593
+ graffiti,
594
+ skipRandaoVerification,
595
+ feeRecipient,
596
+ builderSelection,
597
+ builderBoostFactor,
598
+ strictFeeRecipientCheck,
599
+ blindedLocal,
600
+ }) => ({
601
+ params: {slot},
602
+ query: {
603
+ randao_reveal: toHex(randaoReveal),
604
+ graffiti: toGraffitiHex(graffiti),
605
+ skip_randao_verification: writeSkipRandaoVerification(skipRandaoVerification),
606
+ fee_recipient: feeRecipient,
607
+ builder_selection: builderSelection,
608
+ builder_boost_factor: builderBoostFactor?.toString(),
609
+ strict_fee_recipient_check: strictFeeRecipientCheck,
610
+ blinded_local: blindedLocal,
611
+ },
612
+ }),
613
+ parseReq: ({params, query}) => ({
614
+ slot: params.slot,
615
+ randaoReveal: fromHex(query.randao_reveal),
616
+ graffiti: fromGraffitiHex(query.graffiti),
617
+ skipRandaoVerification: parseSkipRandaoVerification(query.skip_randao_verification),
618
+ feeRecipient: query.fee_recipient,
619
+ builderSelection: query.builder_selection as BuilderSelection,
620
+ builderBoostFactor: parseBuilderBoostFactor(query.builder_boost_factor),
621
+ strictFeeRecipientCheck: query.strict_fee_recipient_check,
622
+ blindedLocal: query.blinded_local,
623
+ }),
624
+ schema: {
625
+ params: {slot: Schema.UintRequired},
626
+ query: {
627
+ randao_reveal: Schema.StringRequired,
628
+ graffiti: Schema.String,
629
+ skip_randao_verification: Schema.String,
630
+ fee_recipient: Schema.String,
631
+ builder_selection: Schema.String,
632
+ builder_boost_factor: Schema.String,
633
+ strict_fee_recipient_check: Schema.Boolean,
634
+ blinded_local: Schema.Boolean,
635
+ },
636
+ },
637
+ },
638
+ resp: {
639
+ // The spec defines the response as `preDeneb.BeaconBlock | postDeneb.BlockContents`
640
+ // We represent the response as `{block: preDeneb.BeaconBlock} | postDeneb.BlockContents` (aka BlockContents in our codebase)
641
+ // Due to this discripancy, we require a hand-written codec to handle the transformation.
642
+ data: {
643
+ toJson(data, {executionPayloadBlinded, version}) {
644
+ return executionPayloadBlinded
645
+ ? getPostBellatrixForkTypes(version).BlindedBeaconBlock.toJson(data as BlindedBeaconBlock)
646
+ : isForkPostDeneb(version)
647
+ ? sszTypesFor(version).BlockContents.toJson(data as BlockContents<ForkPostDeneb>)
648
+ : (ssz[version].BeaconBlock as Type<BeaconBlock<ForkPreDeneb>>).toJson(
649
+ (data as BlockContents).block as BeaconBlock<ForkPreDeneb> // <- tranformation
650
+ );
651
+ },
652
+ fromJson(data, {executionPayloadBlinded, version}) {
653
+ return executionPayloadBlinded
654
+ ? getPostBellatrixForkTypes(version).BlindedBeaconBlock.fromJson(data)
655
+ : isForkPostDeneb(version)
656
+ ? sszTypesFor(version).BlockContents.fromJson(data)
657
+ : {block: ssz[version].BeaconBlock.fromJson(data)}; // <- tranformation
658
+ },
659
+ serialize(data, {executionPayloadBlinded, version}) {
660
+ return executionPayloadBlinded
661
+ ? getPostBellatrixForkTypes(version).BlindedBeaconBlock.serialize(data as BlindedBeaconBlock)
662
+ : isForkPostDeneb(version)
663
+ ? sszTypesFor(version).BlockContents.serialize(data as BlockContents<ForkPostDeneb>)
664
+ : (ssz[version].BeaconBlock as Type<BeaconBlock<ForkPreDeneb>>).serialize(
665
+ (data as BlockContents).block as BeaconBlock<ForkPreDeneb> // <- tranformation
666
+ );
667
+ },
668
+ deserialize(data, {executionPayloadBlinded, version}) {
669
+ return executionPayloadBlinded
670
+ ? getPostBellatrixForkTypes(version).BlindedBeaconBlock.deserialize(data)
671
+ : isForkPostDeneb(version)
672
+ ? sszTypesFor(version).BlockContents.deserialize(data)
673
+ : {block: ssz[version].BeaconBlock.deserialize(data)}; // <- tranformation
674
+ },
675
+ },
676
+ meta: {
677
+ toJson: (meta) => ({
678
+ ...ProduceBlockV3MetaType.toJson(meta),
679
+ execution_payload_source: meta.executionPayloadSource,
680
+ }),
681
+ fromJson: (val) => {
682
+ const {executionPayloadBlinded, ...meta} = ProduceBlockV3MetaType.fromJson(val);
683
+
684
+ // Extract source from the data and assign defaults in the spec compliant manner if not present
685
+ const executionPayloadSource =
686
+ (val as {execution_payload_source: ProducedBlockSource}).execution_payload_source ??
687
+ (executionPayloadBlinded === true ? ProducedBlockSource.builder : ProducedBlockSource.engine);
688
+
689
+ return {...meta, executionPayloadBlinded, executionPayloadSource};
690
+ },
691
+ toHeadersObject: (meta) => ({
692
+ [MetaHeader.Version]: meta.version,
693
+ [MetaHeader.ExecutionPayloadBlinded]: meta.executionPayloadBlinded.toString(),
694
+ [MetaHeader.ExecutionPayloadSource]: meta.executionPayloadSource.toString(),
695
+ [MetaHeader.ExecutionPayloadValue]: meta.executionPayloadValue.toString(),
696
+ [MetaHeader.ConsensusBlockValue]: meta.consensusBlockValue.toString(),
697
+ }),
698
+ fromHeaders: (headers) => {
699
+ const executionPayloadBlinded = toBoolean(headers.getRequired(MetaHeader.ExecutionPayloadBlinded));
700
+
701
+ // Extract source from the headers and assign defaults in a spec compliant manner if not present
702
+ const executionPayloadSource =
703
+ (headers.get(MetaHeader.ExecutionPayloadSource) as ProducedBlockSource) ??
704
+ (executionPayloadBlinded === true ? ProducedBlockSource.builder : ProducedBlockSource.engine);
705
+
706
+ return {
707
+ version: toForkName(headers.getRequired(MetaHeader.Version)),
708
+ executionPayloadBlinded,
709
+ executionPayloadSource,
710
+ executionPayloadValue: BigInt(headers.getRequired(MetaHeader.ExecutionPayloadValue)),
711
+ consensusBlockValue: BigInt(headers.getRequired(MetaHeader.ConsensusBlockValue)),
712
+ };
713
+ },
714
+ },
715
+ },
716
+ },
717
+ produceAttestationData: {
718
+ url: "/eth/v1/validator/attestation_data",
719
+ method: "GET",
720
+ req: {
721
+ writeReq: ({committeeIndex, slot}) => ({query: {slot, committee_index: committeeIndex}}),
722
+ parseReq: ({query}) => ({committeeIndex: query.committee_index, slot: query.slot}),
723
+ schema: {
724
+ query: {slot: Schema.UintRequired, committee_index: Schema.Uint},
725
+ },
726
+ },
727
+ resp: {
728
+ data: ssz.phase0.AttestationData,
729
+ meta: EmptyMetaCodec,
730
+ },
731
+ },
732
+ produceSyncCommitteeContribution: {
733
+ url: "/eth/v1/validator/sync_committee_contribution",
734
+ method: "GET",
735
+ req: {
736
+ writeReq: ({slot, subcommitteeIndex, beaconBlockRoot}) => ({
737
+ query: {slot, subcommittee_index: subcommitteeIndex, beacon_block_root: toRootHex(beaconBlockRoot)},
738
+ }),
739
+ parseReq: ({query}) => ({
740
+ slot: query.slot,
741
+ subcommitteeIndex: query.subcommittee_index,
742
+ beaconBlockRoot: fromHex(query.beacon_block_root),
743
+ }),
744
+ schema: {
745
+ query: {
746
+ slot: Schema.UintRequired,
747
+ subcommittee_index: Schema.UintRequired,
748
+ beacon_block_root: Schema.StringRequired,
749
+ },
750
+ },
751
+ },
752
+ resp: {
753
+ data: ssz.altair.SyncCommitteeContribution,
754
+ meta: EmptyMetaCodec,
755
+ },
756
+ },
757
+ getAggregatedAttestation: {
758
+ url: "/eth/v1/validator/aggregate_attestation",
759
+ method: "GET",
760
+ req: {
761
+ writeReq: ({attestationDataRoot, slot}) => ({
762
+ query: {attestation_data_root: toRootHex(attestationDataRoot), slot},
763
+ }),
764
+ parseReq: ({query}) => ({
765
+ attestationDataRoot: fromHex(query.attestation_data_root),
766
+ slot: query.slot,
767
+ }),
768
+ schema: {
769
+ query: {
770
+ attestation_data_root: Schema.StringRequired,
771
+ slot: Schema.UintRequired,
772
+ },
773
+ },
774
+ },
775
+ resp: {
776
+ data: ssz.phase0.Attestation,
777
+ meta: EmptyMetaCodec,
778
+ },
779
+ },
780
+ getAggregatedAttestationV2: {
781
+ url: "/eth/v2/validator/aggregate_attestation",
782
+ method: "GET",
783
+ req: {
784
+ writeReq: ({attestationDataRoot, slot, committeeIndex}) => ({
785
+ query: {attestation_data_root: toHex(attestationDataRoot), slot, committee_index: committeeIndex},
786
+ }),
787
+ parseReq: ({query}) => ({
788
+ attestationDataRoot: fromHex(query.attestation_data_root),
789
+ slot: query.slot,
790
+ committeeIndex: query.committee_index,
791
+ }),
792
+ schema: {
793
+ query: {
794
+ attestation_data_root: Schema.StringRequired,
795
+ slot: Schema.UintRequired,
796
+ committee_index: Schema.UintRequired,
797
+ },
798
+ },
799
+ },
800
+ resp: {
801
+ data: WithVersion((fork) => (isForkPostElectra(fork) ? ssz.electra.Attestation : ssz.phase0.Attestation)),
802
+ meta: VersionCodec,
803
+ },
804
+ },
805
+ publishAggregateAndProofs: {
806
+ url: "/eth/v1/validator/aggregate_and_proofs",
807
+ method: "POST",
808
+ req: {
809
+ writeReqJson: ({signedAggregateAndProofs}) => ({
810
+ body: SignedAggregateAndProofListPhase0Type.toJson(signedAggregateAndProofs),
811
+ }),
812
+ parseReqJson: ({body}) => ({
813
+ signedAggregateAndProofs: SignedAggregateAndProofListPhase0Type.fromJson(body),
814
+ }),
815
+ writeReqSsz: ({signedAggregateAndProofs}) => ({
816
+ body: SignedAggregateAndProofListPhase0Type.serialize(signedAggregateAndProofs),
817
+ }),
818
+ parseReqSsz: ({body}) => ({
819
+ signedAggregateAndProofs: SignedAggregateAndProofListPhase0Type.deserialize(body),
820
+ }),
821
+ schema: {
822
+ body: Schema.ObjectArray,
823
+ },
824
+ },
825
+ resp: EmptyResponseCodec,
826
+ },
827
+ publishAggregateAndProofsV2: {
828
+ url: "/eth/v2/validator/aggregate_and_proofs",
829
+ method: "POST",
830
+ req: {
831
+ writeReqJson: ({signedAggregateAndProofs}) => {
832
+ const fork = config.getForkName(signedAggregateAndProofs[0]?.message.aggregate.data.slot ?? 0);
833
+ return {
834
+ body: isForkPostElectra(fork)
835
+ ? SignedAggregateAndProofListElectraType.toJson(
836
+ signedAggregateAndProofs as SignedAggregateAndProofListElectra
837
+ )
838
+ : SignedAggregateAndProofListPhase0Type.toJson(
839
+ signedAggregateAndProofs as SignedAggregateAndProofListPhase0
840
+ ),
841
+ headers: {[MetaHeader.Version]: fork},
842
+ };
843
+ },
844
+ parseReqJson: ({body, headers}) => {
845
+ const fork = toForkName(fromHeaders(headers, MetaHeader.Version));
846
+ return {
847
+ signedAggregateAndProofs: isForkPostElectra(fork)
848
+ ? SignedAggregateAndProofListElectraType.fromJson(body)
849
+ : SignedAggregateAndProofListPhase0Type.fromJson(body),
850
+ };
851
+ },
852
+ writeReqSsz: ({signedAggregateAndProofs}) => {
853
+ const fork = config.getForkName(signedAggregateAndProofs[0]?.message.aggregate.data.slot ?? 0);
854
+ return {
855
+ body: isForkPostElectra(fork)
856
+ ? SignedAggregateAndProofListElectraType.serialize(
857
+ signedAggregateAndProofs as SignedAggregateAndProofListElectra
858
+ )
859
+ : SignedAggregateAndProofListPhase0Type.serialize(
860
+ signedAggregateAndProofs as SignedAggregateAndProofListPhase0
861
+ ),
862
+ headers: {[MetaHeader.Version]: fork},
863
+ };
864
+ },
865
+ parseReqSsz: ({body, headers}) => {
866
+ const fork = toForkName(fromHeaders(headers, MetaHeader.Version));
867
+ return {
868
+ signedAggregateAndProofs: isForkPostElectra(fork)
869
+ ? SignedAggregateAndProofListElectraType.deserialize(body)
870
+ : SignedAggregateAndProofListPhase0Type.deserialize(body),
871
+ };
872
+ },
873
+ schema: {
874
+ body: Schema.ObjectArray,
875
+ headers: {[MetaHeader.Version]: Schema.String},
876
+ },
877
+ },
878
+ resp: EmptyResponseCodec,
879
+ },
880
+ publishContributionAndProofs: {
881
+ url: "/eth/v1/validator/contribution_and_proofs",
882
+ method: "POST",
883
+ req: {
884
+ writeReqJson: ({contributionAndProofs}) => ({
885
+ body: SignedContributionAndProofListType.toJson(contributionAndProofs),
886
+ }),
887
+ parseReqJson: ({body}) => ({contributionAndProofs: SignedContributionAndProofListType.fromJson(body)}),
888
+ writeReqSsz: ({contributionAndProofs}) => ({
889
+ body: SignedContributionAndProofListType.serialize(contributionAndProofs),
890
+ }),
891
+ parseReqSsz: ({body}) => ({contributionAndProofs: SignedContributionAndProofListType.deserialize(body)}),
892
+ schema: {
893
+ body: Schema.ObjectArray,
894
+ },
895
+ },
896
+ resp: EmptyResponseCodec,
897
+ },
898
+ prepareBeaconCommitteeSubnet: {
899
+ url: "/eth/v1/validator/beacon_committee_subscriptions",
900
+ method: "POST",
901
+ req: {
902
+ writeReqJson: ({subscriptions}) => ({body: BeaconCommitteeSubscriptionListType.toJson(subscriptions)}),
903
+ parseReqJson: ({body}) => ({subscriptions: BeaconCommitteeSubscriptionListType.fromJson(body)}),
904
+ writeReqSsz: ({subscriptions}) => ({body: BeaconCommitteeSubscriptionListType.serialize(subscriptions)}),
905
+ parseReqSsz: ({body}) => ({subscriptions: BeaconCommitteeSubscriptionListType.deserialize(body)}),
906
+ schema: {body: Schema.ObjectArray},
907
+ },
908
+ resp: EmptyResponseCodec,
909
+ },
910
+ prepareSyncCommitteeSubnets: {
911
+ url: "/eth/v1/validator/sync_committee_subscriptions",
912
+ method: "POST",
913
+ req: {
914
+ writeReqJson: ({subscriptions}) => ({body: SyncCommitteeSubscriptionListType.toJson(subscriptions)}),
915
+ parseReqJson: ({body}) => ({subscriptions: SyncCommitteeSubscriptionListType.fromJson(body)}),
916
+ writeReqSsz: ({subscriptions}) => ({body: SyncCommitteeSubscriptionListType.serialize(subscriptions)}),
917
+ parseReqSsz: ({body}) => ({subscriptions: SyncCommitteeSubscriptionListType.deserialize(body)}),
918
+ schema: {body: Schema.ObjectArray},
919
+ },
920
+ resp: EmptyResponseCodec,
921
+ },
922
+ prepareBeaconProposer: {
923
+ url: "/eth/v1/validator/prepare_beacon_proposer",
924
+ method: "POST",
925
+ req: JsonOnlyReq({
926
+ writeReqJson: ({proposers}) => ({body: ProposerPreparationDataListType.toJson(proposers)}),
927
+ parseReqJson: ({body}) => ({proposers: ProposerPreparationDataListType.fromJson(body)}),
928
+ schema: {body: Schema.ObjectArray},
929
+ }),
930
+ resp: EmptyResponseCodec,
931
+ },
932
+ submitBeaconCommitteeSelections: {
933
+ url: "/eth/v1/validator/beacon_committee_selections",
934
+ method: "POST",
935
+ req: {
936
+ writeReqJson: ({selections}) => ({body: BeaconCommitteeSelectionListType.toJson(selections)}),
937
+ parseReqJson: ({body}) => ({selections: BeaconCommitteeSelectionListType.fromJson(body)}),
938
+ writeReqSsz: ({selections}) => ({body: BeaconCommitteeSelectionListType.serialize(selections)}),
939
+ parseReqSsz: ({body}) => ({selections: BeaconCommitteeSelectionListType.deserialize(body)}),
940
+ schema: {
941
+ body: Schema.ObjectArray,
942
+ },
943
+ },
944
+ resp: {
945
+ data: BeaconCommitteeSelectionListType,
946
+ meta: EmptyMetaCodec,
947
+ },
948
+ },
949
+ submitSyncCommitteeSelections: {
950
+ url: "/eth/v1/validator/sync_committee_selections",
951
+ method: "POST",
952
+ req: {
953
+ writeReqJson: ({selections}) => ({body: SyncCommitteeSelectionListType.toJson(selections)}),
954
+ parseReqJson: ({body}) => ({selections: SyncCommitteeSelectionListType.fromJson(body)}),
955
+ writeReqSsz: ({selections}) => ({body: SyncCommitteeSelectionListType.serialize(selections)}),
956
+ parseReqSsz: ({body}) => ({selections: SyncCommitteeSelectionListType.deserialize(body)}),
957
+ schema: {
958
+ body: Schema.ObjectArray,
959
+ },
960
+ },
961
+ resp: {
962
+ data: SyncCommitteeSelectionListType,
963
+ meta: EmptyMetaCodec,
964
+ },
965
+ },
966
+ getLiveness: {
967
+ url: "/eth/v1/validator/liveness/{epoch}",
968
+ method: "POST",
969
+ req: {
970
+ writeReqJson: ({epoch, indices}) => ({params: {epoch}, body: ValidatorIndicesType.toJson(indices)}),
971
+ parseReqJson: ({params, body}) => ({epoch: params.epoch, indices: ValidatorIndicesType.fromJson(body)}),
972
+ writeReqSsz: ({epoch, indices}) => ({params: {epoch}, body: ValidatorIndicesType.serialize(indices)}),
973
+ parseReqSsz: ({params, body}) => ({epoch: params.epoch, indices: ValidatorIndicesType.deserialize(body)}),
974
+ schema: {
975
+ params: {epoch: Schema.UintRequired},
976
+ body: Schema.StringArray,
977
+ },
978
+ },
979
+ resp: {
980
+ data: LivenessResponseDataListType,
981
+ meta: EmptyMetaCodec,
982
+ },
983
+ },
984
+ registerValidator: {
985
+ url: "/eth/v1/validator/register_validator",
986
+ method: "POST",
987
+ req: {
988
+ writeReqJson: ({registrations}) => ({body: SignedValidatorRegistrationV1ListType.toJson(registrations)}),
989
+ parseReqJson: ({body}) => ({registrations: SignedValidatorRegistrationV1ListType.fromJson(body)}),
990
+ writeReqSsz: ({registrations}) => ({body: SignedValidatorRegistrationV1ListType.serialize(registrations)}),
991
+ parseReqSsz: ({body}) => ({registrations: SignedValidatorRegistrationV1ListType.deserialize(body)}),
992
+ schema: {
993
+ body: Schema.ObjectArray,
994
+ },
995
+ },
996
+ resp: EmptyResponseCodec,
997
+ init: {
998
+ requestWireFormat: WireFormat.ssz,
999
+ },
1000
+ },
1001
+ };
1002
+ }
1003
+
1004
+ function parseBuilderBoostFactor(builderBoostFactorInput?: string | number | bigint): bigint | undefined {
1005
+ return builderBoostFactorInput !== undefined ? BigInt(builderBoostFactorInput) : undefined;
1006
+ }
1007
+
1008
+ function writeSkipRandaoVerification(skipRandaoVerification?: boolean): string | undefined {
1009
+ return skipRandaoVerification === true ? "" : undefined;
1010
+ }
1011
+
1012
+ function parseSkipRandaoVerification(skipRandaoVerification?: string): boolean {
1013
+ return skipRandaoVerification !== undefined && skipRandaoVerification === "";
1014
+ }