@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,602 @@
1
+ import {ContainerType, ListCompositeType, ValueOf} from "@chainsafe/ssz";
2
+ import {ChainForkConfig} from "@lodestar/config";
3
+ import {
4
+ ForkName,
5
+ ForkPostDeneb,
6
+ ForkPreBellatrix,
7
+ ForkPreDeneb,
8
+ ForkPreElectra,
9
+ isForkPostBellatrix,
10
+ isForkPostDeneb,
11
+ } from "@lodestar/params";
12
+ import {
13
+ BeaconBlockBody,
14
+ RootHex,
15
+ SignedBeaconBlock,
16
+ SignedBlindedBeaconBlock,
17
+ SignedBlockContents,
18
+ Slot,
19
+ deneb,
20
+ ssz,
21
+ sszTypesFor,
22
+ } from "@lodestar/types";
23
+ import {EmptyMeta, EmptyResponseCodec, EmptyResponseData, WithVersion} from "../../../utils/codecs.js";
24
+ import {getPostBellatrixForkTypes, toForkName} from "../../../utils/fork.js";
25
+ import {fromHeaders} from "../../../utils/headers.js";
26
+ import {Endpoint, RequestCodec, RouteDefinitions, Schema} from "../../../utils/index.js";
27
+ import {
28
+ ExecutionOptimisticAndFinalizedCodec,
29
+ ExecutionOptimisticAndFinalizedMeta,
30
+ ExecutionOptimisticFinalizedAndVersionCodec,
31
+ ExecutionOptimisticFinalizedAndVersionMeta,
32
+ MetaHeader,
33
+ } from "../../../utils/metadata.js";
34
+ import {WireFormat} from "../../../utils/wireFormat.js";
35
+
36
+ export const BlockHeaderResponseType = new ContainerType({
37
+ root: ssz.Root,
38
+ canonical: ssz.Boolean,
39
+ header: ssz.phase0.SignedBeaconBlockHeader,
40
+ });
41
+ export const BlockHeadersResponseType = new ListCompositeType(BlockHeaderResponseType, 1000);
42
+ export const RootResponseType = new ContainerType({
43
+ root: ssz.Root,
44
+ });
45
+
46
+ export type BlockHeaderResponse = ValueOf<typeof BlockHeaderResponseType>;
47
+ export type BlockHeadersResponse = ValueOf<typeof BlockHeadersResponseType>;
48
+ export type RootResponse = ValueOf<typeof RootResponseType>;
49
+
50
+ export type BlockId = RootHex | Slot | "head" | "genesis" | "finalized" | "justified";
51
+
52
+ export type BlockArgs = {
53
+ /**
54
+ * Block identifier.
55
+ * Can be one of: "head" (canonical head in node's view), "genesis", "finalized", "justified", \<slot\>, \<hex encoded blockRoot with 0x prefix\>.
56
+ */
57
+ blockId: BlockId;
58
+ };
59
+
60
+ export enum BroadcastValidation {
61
+ /**
62
+ NOTE: The value `none` is not part of the spec.
63
+
64
+ In case a node is configured only with the unknownBlockSync, it needs to know the unknown parent blocks on the network
65
+ to initiate the syncing process. Such cases can be covered only if we publish blocks and make sure no gossip validation
66
+ is performed on those. But this behavior is not the default.
67
+ */
68
+ none = "none",
69
+ gossip = "gossip",
70
+ consensus = "consensus",
71
+ consensusAndEquivocation = "consensus_and_equivocation",
72
+ }
73
+
74
+ export type Endpoints = {
75
+ /**
76
+ * Get block
77
+ * Retrieves block details for given block id.
78
+ */
79
+ getBlockV2: Endpoint<
80
+ "GET",
81
+ BlockArgs,
82
+ {params: {block_id: string}},
83
+ SignedBeaconBlock,
84
+ ExecutionOptimisticFinalizedAndVersionMeta
85
+ >;
86
+
87
+ /**
88
+ * Get blinded block
89
+ * Retrieves blinded block for given block id.
90
+ */
91
+ getBlindedBlock: Endpoint<
92
+ "GET",
93
+ BlockArgs,
94
+ {params: {block_id: string}},
95
+ SignedBlindedBeaconBlock | SignedBeaconBlock<ForkPreBellatrix>,
96
+ ExecutionOptimisticFinalizedAndVersionMeta
97
+ >;
98
+
99
+ /**
100
+ * Get block attestations
101
+ * Retrieves attestation included in requested block.
102
+ */
103
+ getBlockAttestations: Endpoint<
104
+ "GET",
105
+ BlockArgs,
106
+ {params: {block_id: string}},
107
+ BeaconBlockBody<ForkPreElectra>["attestations"],
108
+ ExecutionOptimisticAndFinalizedMeta
109
+ >;
110
+
111
+ /**
112
+ * Get block attestations
113
+ * Retrieves attestation included in requested block.
114
+ */
115
+ getBlockAttestationsV2: Endpoint<
116
+ "GET",
117
+ BlockArgs,
118
+ {params: {block_id: string}},
119
+ BeaconBlockBody["attestations"],
120
+ ExecutionOptimisticFinalizedAndVersionMeta
121
+ >;
122
+
123
+ /**
124
+ * Get block header
125
+ * Retrieves block header for given block id.
126
+ */
127
+ getBlockHeader: Endpoint<
128
+ "GET",
129
+ BlockArgs,
130
+ {params: {block_id: string}},
131
+ BlockHeaderResponse,
132
+ ExecutionOptimisticAndFinalizedMeta
133
+ >;
134
+
135
+ /**
136
+ * Get block headers
137
+ * Retrieves block headers matching given query. By default it will fetch current head slot blocks.
138
+ */
139
+ getBlockHeaders: Endpoint<
140
+ "GET",
141
+ {slot?: Slot; parentRoot?: string},
142
+ {query: {slot?: number; parent_root?: string}},
143
+ BlockHeaderResponse[],
144
+ ExecutionOptimisticAndFinalizedMeta
145
+ >;
146
+
147
+ /**
148
+ * Get block root
149
+ * Retrieves hashTreeRoot of BeaconBlock/BeaconBlockHeader
150
+ */
151
+ getBlockRoot: Endpoint<
152
+ "GET",
153
+ BlockArgs,
154
+ {params: {block_id: string}},
155
+ RootResponse,
156
+ ExecutionOptimisticAndFinalizedMeta
157
+ >;
158
+
159
+ /**
160
+ * Publish a signed block.
161
+ * Instructs the beacon node to broadcast a newly signed beacon block to the beacon network,
162
+ * to be included in the beacon chain. The beacon node is not required to validate the signed
163
+ * `BeaconBlock`, and a successful response (20X) only indicates that the broadcast has been
164
+ * successful. The beacon node is expected to integrate the new block into its state, and
165
+ * therefore validate the block internally, however blocks which fail the validation are still
166
+ * broadcast but a different status code is returned (202)
167
+ *
168
+ * Returns if the block was validated successfully and has been broadcast. It has also been integrated into the beacon node's database.
169
+ */
170
+ publishBlock: Endpoint<
171
+ "POST",
172
+ {signedBlockContents: SignedBlockContents},
173
+ {body: unknown; headers: {[MetaHeader.Version]: string}},
174
+ EmptyResponseData,
175
+ EmptyMeta
176
+ >;
177
+
178
+ publishBlockV2: Endpoint<
179
+ "POST",
180
+ {
181
+ signedBlockContents: SignedBlockContents;
182
+ broadcastValidation?: BroadcastValidation;
183
+ },
184
+ {body: unknown; headers: {[MetaHeader.Version]: string}; query: {broadcast_validation?: string}},
185
+ EmptyResponseData,
186
+ EmptyMeta
187
+ >;
188
+
189
+ /**
190
+ * Publish a signed blinded block by submitting it to the mev relay and patching in the block
191
+ * transactions beacon node gets in response.
192
+ */
193
+ publishBlindedBlock: Endpoint<
194
+ "POST",
195
+ {signedBlindedBlock: SignedBlindedBeaconBlock},
196
+ {body: unknown; headers: {[MetaHeader.Version]: string}},
197
+ EmptyResponseData,
198
+ EmptyMeta
199
+ >;
200
+
201
+ publishBlindedBlockV2: Endpoint<
202
+ "POST",
203
+ {
204
+ signedBlindedBlock: SignedBlindedBeaconBlock;
205
+ broadcastValidation?: BroadcastValidation;
206
+ },
207
+ {body: unknown; headers: {[MetaHeader.Version]: string}; query: {broadcast_validation?: string}},
208
+ EmptyResponseData,
209
+ EmptyMeta
210
+ >;
211
+
212
+ /**
213
+ * Get block BlobSidecar
214
+ * Retrieves BlobSidecar included in requested block.
215
+ */
216
+ getBlobSidecars: Endpoint<
217
+ "GET",
218
+ BlockArgs & {
219
+ /**
220
+ * Array of indices for blob sidecars to request for in the specified block.
221
+ * Returns all blob sidecars in the block if not specified.
222
+ */
223
+ indices?: number[];
224
+ },
225
+ {params: {block_id: string}; query: {indices?: number[]}},
226
+ deneb.BlobSidecars,
227
+ ExecutionOptimisticFinalizedAndVersionMeta
228
+ >;
229
+
230
+ /**
231
+ * Get blobs
232
+ * Retrieves blobs for a given block id.
233
+ */
234
+ getBlobs: Endpoint<
235
+ "GET",
236
+ BlockArgs & {
237
+ /**
238
+ * Array of versioned hashes for blobs to request for in the specified block.
239
+ * Returns all blobs in the block if not specified.
240
+ */
241
+ versionedHashes?: string[];
242
+ },
243
+ {params: {block_id: string}; query: {versioned_hashes?: string[]}},
244
+ deneb.Blobs,
245
+ ExecutionOptimisticAndFinalizedMeta
246
+ >;
247
+ };
248
+
249
+ // biome-ignore lint/suspicious/noExplicitAny: Return type has to match multiple routes and we only care about request type here
250
+ const blockIdOnlyReq: RequestCodec<Endpoint<"GET", {blockId: BlockId}, {params: {block_id: string}}, any, any>> = {
251
+ writeReq: ({blockId}) => ({params: {block_id: blockId.toString()}}),
252
+ parseReq: ({params}) => ({blockId: params.block_id}),
253
+ schema: {params: {block_id: Schema.StringRequired}},
254
+ };
255
+
256
+ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoints> {
257
+ return {
258
+ getBlockV2: {
259
+ url: "/eth/v2/beacon/blocks/{block_id}",
260
+ method: "GET",
261
+ req: blockIdOnlyReq,
262
+ resp: {
263
+ data: WithVersion((fork) => ssz[fork].SignedBeaconBlock),
264
+ meta: ExecutionOptimisticFinalizedAndVersionCodec,
265
+ },
266
+ },
267
+ getBlindedBlock: {
268
+ url: "/eth/v1/beacon/blinded_blocks/{block_id}",
269
+ method: "GET",
270
+ req: blockIdOnlyReq,
271
+ resp: {
272
+ data: WithVersion((fork) =>
273
+ isForkPostBellatrix(fork) ? ssz[fork].SignedBlindedBeaconBlock : ssz[fork].SignedBeaconBlock
274
+ ),
275
+ meta: ExecutionOptimisticFinalizedAndVersionCodec,
276
+ },
277
+ },
278
+ getBlockAttestations: {
279
+ url: "/eth/v1/beacon/blocks/{block_id}/attestations",
280
+ method: "GET",
281
+ req: blockIdOnlyReq,
282
+ resp: {
283
+ data: ssz.phase0.BeaconBlockBody.fields.attestations,
284
+ meta: ExecutionOptimisticAndFinalizedCodec,
285
+ },
286
+ },
287
+ getBlockAttestationsV2: {
288
+ url: "/eth/v2/beacon/blocks/{block_id}/attestations",
289
+ method: "GET",
290
+ req: blockIdOnlyReq,
291
+ resp: {
292
+ data: WithVersion((fork) => ssz[fork].BeaconBlockBody.fields.attestations),
293
+ meta: ExecutionOptimisticFinalizedAndVersionCodec,
294
+ },
295
+ },
296
+ getBlockHeader: {
297
+ url: "/eth/v1/beacon/headers/{block_id}",
298
+ method: "GET",
299
+ req: blockIdOnlyReq,
300
+ resp: {
301
+ data: BlockHeaderResponseType,
302
+ meta: ExecutionOptimisticAndFinalizedCodec,
303
+ },
304
+ },
305
+ getBlockHeaders: {
306
+ url: "/eth/v1/beacon/headers",
307
+ method: "GET",
308
+ req: {
309
+ writeReq: ({slot, parentRoot}) => ({query: {slot, parent_root: parentRoot}}),
310
+ parseReq: ({query}) => ({slot: query.slot, parentRoot: query.parent_root}),
311
+ schema: {query: {slot: Schema.Uint, parent_root: Schema.String}},
312
+ },
313
+ resp: {
314
+ data: BlockHeadersResponseType,
315
+ meta: ExecutionOptimisticAndFinalizedCodec,
316
+ },
317
+ },
318
+ getBlockRoot: {
319
+ url: "/eth/v1/beacon/blocks/{block_id}/root",
320
+ method: "GET",
321
+ req: blockIdOnlyReq,
322
+ resp: {
323
+ data: RootResponseType,
324
+ meta: ExecutionOptimisticAndFinalizedCodec,
325
+ },
326
+ },
327
+ publishBlock: {
328
+ url: "/eth/v1/beacon/blocks",
329
+ method: "POST",
330
+ req: {
331
+ writeReqJson: ({signedBlockContents}) => {
332
+ const slot = signedBlockContents.signedBlock.message.slot;
333
+ const fork = config.getForkName(slot);
334
+
335
+ return {
336
+ body: isForkPostDeneb(fork)
337
+ ? sszTypesFor(fork).SignedBlockContents.toJson(signedBlockContents as SignedBlockContents<ForkPostDeneb>)
338
+ : sszTypesFor(fork).SignedBeaconBlock.toJson(
339
+ signedBlockContents.signedBlock as SignedBeaconBlock<ForkPreDeneb>
340
+ ),
341
+ headers: {
342
+ [MetaHeader.Version]: config.getForkName(slot),
343
+ },
344
+ };
345
+ },
346
+ parseReqJson: ({body, headers}) => {
347
+ let forkName: ForkName;
348
+ // As per spec, version header is optional for JSON requests
349
+ const versionHeader = fromHeaders(headers, MetaHeader.Version, false);
350
+ if (versionHeader !== undefined) {
351
+ forkName = toForkName(versionHeader);
352
+ } else {
353
+ // Determine fork from slot in JSON payload
354
+ forkName = config.getForkName(
355
+ (body as {signed_block: unknown}).signed_block !== undefined
356
+ ? (body as {signed_block: SignedBeaconBlock}).signed_block.message.slot
357
+ : (body as SignedBeaconBlock).message.slot
358
+ );
359
+ }
360
+ return {
361
+ signedBlockContents: isForkPostDeneb(forkName)
362
+ ? sszTypesFor(forkName).SignedBlockContents.fromJson(body)
363
+ : {signedBlock: ssz[forkName].SignedBeaconBlock.fromJson(body)},
364
+ };
365
+ },
366
+ writeReqSsz: ({signedBlockContents}) => {
367
+ const slot = signedBlockContents.signedBlock.message.slot;
368
+ const fork = config.getForkName(slot);
369
+
370
+ return {
371
+ body: isForkPostDeneb(fork)
372
+ ? sszTypesFor(fork).SignedBlockContents.serialize(
373
+ signedBlockContents as SignedBlockContents<ForkPostDeneb>
374
+ )
375
+ : sszTypesFor(fork).SignedBeaconBlock.serialize(
376
+ signedBlockContents.signedBlock as SignedBeaconBlock<ForkPreDeneb>
377
+ ),
378
+ headers: {
379
+ [MetaHeader.Version]: config.getForkName(slot),
380
+ },
381
+ };
382
+ },
383
+ parseReqSsz: ({body, headers}) => {
384
+ const forkName = toForkName(fromHeaders(headers, MetaHeader.Version));
385
+ return {
386
+ signedBlockContents: isForkPostDeneb(forkName)
387
+ ? sszTypesFor(forkName).SignedBlockContents.deserialize(body)
388
+ : {signedBlock: ssz[forkName].SignedBeaconBlock.deserialize(body)},
389
+ };
390
+ },
391
+ schema: {
392
+ body: Schema.Object,
393
+ headers: {[MetaHeader.Version]: Schema.String},
394
+ },
395
+ },
396
+ resp: EmptyResponseCodec,
397
+ init: {
398
+ requestWireFormat: WireFormat.ssz,
399
+ },
400
+ },
401
+ publishBlockV2: {
402
+ url: "/eth/v2/beacon/blocks",
403
+ method: "POST",
404
+ req: {
405
+ writeReqJson: ({signedBlockContents, broadcastValidation}) => {
406
+ const slot = signedBlockContents.signedBlock.message.slot;
407
+ const fork = config.getForkName(slot);
408
+ return {
409
+ body: isForkPostDeneb(fork)
410
+ ? sszTypesFor(fork).SignedBlockContents.toJson(signedBlockContents as SignedBlockContents<ForkPostDeneb>)
411
+ : sszTypesFor(fork).SignedBeaconBlock.toJson(
412
+ signedBlockContents.signedBlock as SignedBeaconBlock<ForkPreDeneb>
413
+ ),
414
+ headers: {
415
+ [MetaHeader.Version]: fork,
416
+ },
417
+ query: {broadcast_validation: broadcastValidation},
418
+ };
419
+ },
420
+ parseReqJson: ({body, headers, query}) => {
421
+ const forkName = toForkName(fromHeaders(headers, MetaHeader.Version));
422
+ return {
423
+ signedBlockContents: isForkPostDeneb(forkName)
424
+ ? sszTypesFor(forkName).SignedBlockContents.fromJson(body)
425
+ : {signedBlock: ssz[forkName].SignedBeaconBlock.fromJson(body)},
426
+ broadcastValidation: query.broadcast_validation as BroadcastValidation,
427
+ };
428
+ },
429
+ writeReqSsz: ({signedBlockContents, broadcastValidation}) => {
430
+ const slot = signedBlockContents.signedBlock.message.slot;
431
+ const fork = config.getForkName(slot);
432
+
433
+ return {
434
+ body: isForkPostDeneb(fork)
435
+ ? sszTypesFor(fork).SignedBlockContents.serialize(
436
+ signedBlockContents as SignedBlockContents<ForkPostDeneb>
437
+ )
438
+ : sszTypesFor(fork).SignedBeaconBlock.serialize(
439
+ signedBlockContents.signedBlock as SignedBeaconBlock<ForkPreDeneb>
440
+ ),
441
+ headers: {
442
+ [MetaHeader.Version]: fork,
443
+ },
444
+ query: {broadcast_validation: broadcastValidation},
445
+ };
446
+ },
447
+ parseReqSsz: ({body, headers, query}) => {
448
+ const forkName = toForkName(fromHeaders(headers, MetaHeader.Version));
449
+ return {
450
+ signedBlockContents: isForkPostDeneb(forkName)
451
+ ? sszTypesFor(forkName).SignedBlockContents.deserialize(body)
452
+ : {signedBlock: ssz[forkName].SignedBeaconBlock.deserialize(body)},
453
+ broadcastValidation: query.broadcast_validation as BroadcastValidation,
454
+ };
455
+ },
456
+ schema: {
457
+ body: Schema.Object,
458
+ query: {broadcast_validation: Schema.String},
459
+ headers: {[MetaHeader.Version]: Schema.String},
460
+ },
461
+ },
462
+ resp: EmptyResponseCodec,
463
+ init: {
464
+ requestWireFormat: WireFormat.ssz,
465
+ },
466
+ },
467
+ publishBlindedBlock: {
468
+ url: "/eth/v1/beacon/blinded_blocks",
469
+ method: "POST",
470
+ req: {
471
+ writeReqJson: ({signedBlindedBlock}) => {
472
+ const fork = config.getForkName(signedBlindedBlock.message.slot);
473
+ return {
474
+ body: getPostBellatrixForkTypes(fork).SignedBlindedBeaconBlock.toJson(signedBlindedBlock),
475
+ headers: {
476
+ [MetaHeader.Version]: fork,
477
+ },
478
+ };
479
+ },
480
+ parseReqJson: ({body, headers}) => {
481
+ let fork: ForkName;
482
+ // As per spec, version header is optional for JSON requests
483
+ const versionHeader = fromHeaders(headers, MetaHeader.Version, false);
484
+ if (versionHeader !== undefined) {
485
+ fork = toForkName(versionHeader);
486
+ } else {
487
+ // Determine fork from slot in JSON payload
488
+ fork = config.getForkName((body as SignedBlindedBeaconBlock).message.slot);
489
+ }
490
+
491
+ return {
492
+ signedBlindedBlock: getPostBellatrixForkTypes(fork).SignedBlindedBeaconBlock.fromJson(body),
493
+ };
494
+ },
495
+ writeReqSsz: ({signedBlindedBlock}) => {
496
+ const fork = config.getForkName(signedBlindedBlock.message.slot);
497
+ return {
498
+ body: getPostBellatrixForkTypes(fork).SignedBlindedBeaconBlock.serialize(signedBlindedBlock),
499
+ headers: {
500
+ [MetaHeader.Version]: fork,
501
+ },
502
+ };
503
+ },
504
+ parseReqSsz: ({body, headers}) => {
505
+ const fork = toForkName(fromHeaders(headers, MetaHeader.Version));
506
+ return {
507
+ signedBlindedBlock: getPostBellatrixForkTypes(fork).SignedBlindedBeaconBlock.deserialize(body),
508
+ };
509
+ },
510
+ schema: {
511
+ body: Schema.Object,
512
+ headers: {[MetaHeader.Version]: Schema.String},
513
+ },
514
+ },
515
+ resp: EmptyResponseCodec,
516
+ init: {
517
+ requestWireFormat: WireFormat.ssz,
518
+ },
519
+ },
520
+ publishBlindedBlockV2: {
521
+ url: "/eth/v2/beacon/blinded_blocks",
522
+ method: "POST",
523
+ req: {
524
+ writeReqJson: ({signedBlindedBlock, broadcastValidation}) => {
525
+ const fork = config.getForkName(signedBlindedBlock.message.slot);
526
+ return {
527
+ body: getPostBellatrixForkTypes(fork).SignedBlindedBeaconBlock.toJson(signedBlindedBlock),
528
+ headers: {
529
+ [MetaHeader.Version]: fork,
530
+ },
531
+ query: {broadcast_validation: broadcastValidation},
532
+ };
533
+ },
534
+ parseReqJson: ({body, headers, query}) => {
535
+ const fork = toForkName(fromHeaders(headers, MetaHeader.Version));
536
+ return {
537
+ signedBlindedBlock: getPostBellatrixForkTypes(fork).SignedBlindedBeaconBlock.fromJson(body),
538
+ broadcastValidation: query.broadcast_validation as BroadcastValidation,
539
+ };
540
+ },
541
+ writeReqSsz: ({signedBlindedBlock, broadcastValidation}) => {
542
+ const fork = config.getForkName(signedBlindedBlock.message.slot);
543
+ return {
544
+ body: getPostBellatrixForkTypes(fork).SignedBlindedBeaconBlock.serialize(signedBlindedBlock),
545
+ headers: {
546
+ [MetaHeader.Version]: fork,
547
+ },
548
+ query: {broadcast_validation: broadcastValidation},
549
+ };
550
+ },
551
+ parseReqSsz: ({body, headers, query}) => {
552
+ const fork = toForkName(fromHeaders(headers, MetaHeader.Version));
553
+ return {
554
+ signedBlindedBlock: getPostBellatrixForkTypes(fork).SignedBlindedBeaconBlock.deserialize(body),
555
+ broadcastValidation: query.broadcast_validation as BroadcastValidation,
556
+ };
557
+ },
558
+ schema: {
559
+ body: Schema.Object,
560
+ query: {broadcast_validation: Schema.String},
561
+ headers: {[MetaHeader.Version]: Schema.String},
562
+ },
563
+ },
564
+ resp: EmptyResponseCodec,
565
+ init: {
566
+ requestWireFormat: WireFormat.ssz,
567
+ },
568
+ },
569
+ getBlobSidecars: {
570
+ url: "/eth/v1/beacon/blob_sidecars/{block_id}",
571
+ method: "GET",
572
+ req: {
573
+ writeReq: ({blockId, indices}) => ({params: {block_id: blockId.toString()}, query: {indices}}),
574
+ parseReq: ({params, query}) => ({blockId: params.block_id, indices: query.indices}),
575
+ schema: {params: {block_id: Schema.StringRequired}, query: {indices: Schema.UintArray}},
576
+ },
577
+ resp: {
578
+ data: ssz.deneb.BlobSidecars,
579
+ meta: ExecutionOptimisticFinalizedAndVersionCodec,
580
+ },
581
+ },
582
+ getBlobs: {
583
+ url: "/eth/v1/beacon/blobs/{block_id}",
584
+ method: "GET",
585
+ req: {
586
+ writeReq: ({blockId, versionedHashes}) => ({
587
+ params: {block_id: blockId.toString()},
588
+ query: {versioned_hashes: versionedHashes},
589
+ }),
590
+ parseReq: ({params, query}) => ({
591
+ blockId: params.block_id,
592
+ versionedHashes: query.versioned_hashes?.map((hash) => hash.toLowerCase()),
593
+ }),
594
+ schema: {params: {block_id: Schema.StringRequired}, query: {versioned_hashes: Schema.StringArray}},
595
+ },
596
+ resp: {
597
+ data: ssz.deneb.Blobs,
598
+ meta: ExecutionOptimisticAndFinalizedCodec,
599
+ },
600
+ },
601
+ };
602
+ }
@@ -0,0 +1,66 @@
1
+ import {ChainForkConfig} from "@lodestar/config";
2
+ import {phase0, ssz} from "@lodestar/types";
3
+ import {EmptyArgs, EmptyMeta, EmptyMetaCodec, EmptyRequest, EmptyRequestCodec} from "../../../utils/codecs.js";
4
+ import {Endpoint, RouteDefinitions} from "../../../utils/types.js";
5
+ import * as block from "./block.js";
6
+ import * as pool from "./pool.js";
7
+ import * as rewards from "./rewards.js";
8
+ import * as state from "./state.js";
9
+
10
+ // NOTE: We choose to split the block, pool, state and rewards namespaces so the files are not too big.
11
+ // However, for a consumer all these methods are within the same service "beacon"
12
+ export {block, pool, state, rewards};
13
+
14
+ export type {BlockHeaderResponse, BlockId} from "./block.js";
15
+ export {BroadcastValidation} from "./block.js";
16
+ export type {
17
+ AttestationsRewards,
18
+ BlockRewards,
19
+ IdealAttestationsReward,
20
+ SyncCommitteeRewards,
21
+ TotalAttestationsReward,
22
+ } from "./rewards.js";
23
+ // TODO: Review if re-exporting all these types is necessary
24
+ export type {
25
+ EpochCommitteeResponse,
26
+ EpochSyncCommitteeResponse,
27
+ FinalityCheckpoints,
28
+ StateId,
29
+ ValidatorBalance,
30
+ ValidatorId,
31
+ ValidatorIdentities,
32
+ ValidatorResponse,
33
+ ValidatorStatus,
34
+ } from "./state.js";
35
+
36
+ export type Endpoints = block.Endpoints &
37
+ pool.Endpoints &
38
+ state.Endpoints &
39
+ rewards.Endpoints & {
40
+ getGenesis: Endpoint<
41
+ // ⏎
42
+ "GET",
43
+ EmptyArgs,
44
+ EmptyRequest,
45
+ phase0.Genesis,
46
+ EmptyMeta
47
+ >;
48
+ };
49
+
50
+ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoints> {
51
+ return {
52
+ getGenesis: {
53
+ url: "/eth/v1/beacon/genesis",
54
+ method: "GET",
55
+ req: EmptyRequestCodec,
56
+ resp: {
57
+ data: ssz.phase0.Genesis,
58
+ meta: EmptyMetaCodec,
59
+ },
60
+ },
61
+ ...block.getDefinitions(config),
62
+ ...pool.getDefinitions(config),
63
+ ...state.getDefinitions(config),
64
+ ...rewards.getDefinitions(config),
65
+ };
66
+ }