@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.
- package/lib/beacon/client/beacon.d.ts.map +1 -0
- package/lib/beacon/client/config.d.ts.map +1 -0
- package/lib/beacon/client/debug.d.ts.map +1 -0
- package/lib/beacon/client/events.d.ts.map +1 -0
- package/lib/beacon/client/index.d.ts.map +1 -0
- package/lib/beacon/client/index.js.map +1 -1
- package/lib/beacon/client/lightclient.d.ts.map +1 -0
- package/lib/beacon/client/lodestar.d.ts.map +1 -0
- package/lib/beacon/client/node.d.ts.map +1 -0
- package/lib/beacon/client/proof.d.ts.map +1 -0
- package/lib/beacon/client/validator.d.ts.map +1 -0
- package/lib/beacon/index.d.ts +1 -1
- package/lib/beacon/index.d.ts.map +1 -0
- package/lib/beacon/index.js.map +1 -1
- package/lib/beacon/routes/beacon/block.d.ts.map +1 -0
- package/lib/beacon/routes/beacon/index.d.ts +3 -3
- package/lib/beacon/routes/beacon/index.d.ts.map +1 -0
- package/lib/beacon/routes/beacon/index.js.map +1 -1
- package/lib/beacon/routes/beacon/pool.d.ts +1 -1
- package/lib/beacon/routes/beacon/pool.d.ts.map +1 -0
- package/lib/beacon/routes/beacon/rewards.d.ts.map +1 -0
- package/lib/beacon/routes/beacon/rewards.js.map +1 -1
- package/lib/beacon/routes/beacon/state.d.ts +2 -2
- package/lib/beacon/routes/beacon/state.d.ts.map +1 -0
- package/lib/beacon/routes/config.d.ts +1 -1
- package/lib/beacon/routes/config.d.ts.map +1 -0
- package/lib/beacon/routes/debug.d.ts.map +1 -0
- package/lib/beacon/routes/events.d.ts.map +1 -0
- package/lib/beacon/routes/events.js.map +1 -1
- package/lib/beacon/routes/index.d.ts.map +1 -0
- package/lib/beacon/routes/index.js.map +1 -1
- package/lib/beacon/routes/lightclient.d.ts.map +1 -0
- package/lib/beacon/routes/lodestar.d.ts.map +1 -0
- package/lib/beacon/routes/node.d.ts.map +1 -0
- package/lib/beacon/routes/proof.d.ts.map +1 -0
- package/lib/beacon/routes/validator.d.ts +1 -1
- package/lib/beacon/routes/validator.d.ts.map +1 -0
- package/lib/beacon/server/beacon.d.ts.map +1 -0
- package/lib/beacon/server/config.d.ts.map +1 -0
- package/lib/beacon/server/debug.d.ts.map +1 -0
- package/lib/beacon/server/events.d.ts.map +1 -0
- package/lib/beacon/server/index.d.ts +1 -1
- package/lib/beacon/server/index.d.ts.map +1 -0
- package/lib/beacon/server/index.js.map +1 -1
- package/lib/beacon/server/lightclient.d.ts.map +1 -0
- package/lib/beacon/server/lodestar.d.ts.map +1 -0
- package/lib/beacon/server/node.d.ts.map +1 -0
- package/lib/beacon/server/proof.d.ts.map +1 -0
- package/lib/beacon/server/validator.d.ts.map +1 -0
- package/lib/builder/client.d.ts.map +1 -0
- package/lib/builder/index.d.ts.map +1 -0
- package/lib/builder/index.js.map +1 -1
- package/lib/builder/routes.d.ts.map +1 -0
- package/lib/builder/routes.js.map +1 -1
- package/lib/builder/server/index.d.ts +1 -1
- package/lib/builder/server/index.d.ts.map +1 -0
- package/lib/index.d.ts +6 -6
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +3 -3
- package/lib/index.js.map +1 -1
- package/lib/keymanager/client.d.ts.map +1 -0
- package/lib/keymanager/index.d.ts +2 -2
- package/lib/keymanager/index.d.ts.map +1 -0
- package/lib/keymanager/index.js +1 -2
- package/lib/keymanager/index.js.map +1 -1
- package/lib/keymanager/routes.d.ts.map +1 -0
- package/lib/keymanager/server/index.d.ts +1 -1
- package/lib/keymanager/server/index.d.ts.map +1 -0
- package/lib/server/index.d.ts.map +1 -0
- package/lib/utils/client/error.d.ts.map +1 -0
- package/lib/utils/client/error.js +2 -0
- package/lib/utils/client/error.js.map +1 -1
- package/lib/utils/client/eventSource.d.ts.map +1 -0
- package/lib/utils/client/format.d.ts.map +1 -0
- package/lib/utils/client/httpClient.d.ts +1 -2
- package/lib/utils/client/httpClient.d.ts.map +1 -0
- package/lib/utils/client/httpClient.js +13 -9
- package/lib/utils/client/httpClient.js.map +1 -1
- package/lib/utils/client/index.d.ts +1 -1
- package/lib/utils/client/index.d.ts.map +1 -0
- package/lib/utils/client/index.js +1 -1
- package/lib/utils/client/index.js.map +1 -1
- package/lib/utils/client/method.d.ts.map +1 -0
- package/lib/utils/client/metrics.d.ts.map +1 -0
- package/lib/utils/client/request.d.ts.map +1 -0
- package/lib/utils/client/response.d.ts.map +1 -0
- package/lib/utils/client/response.js +6 -0
- package/lib/utils/client/response.js.map +1 -1
- package/lib/utils/codecs.d.ts.map +1 -0
- package/lib/utils/fork.d.ts.map +1 -0
- package/lib/utils/headers.d.ts.map +1 -0
- package/lib/utils/httpStatusCode.d.ts.map +1 -0
- package/lib/utils/index.d.ts.map +1 -0
- package/lib/utils/metadata.d.ts.map +1 -0
- package/lib/utils/schema.d.ts.map +1 -0
- package/lib/utils/serdes.d.ts.map +1 -0
- package/lib/utils/server/error.d.ts.map +1 -0
- package/lib/utils/server/error.js +1 -0
- package/lib/utils/server/error.js.map +1 -1
- package/lib/utils/server/handler.d.ts.map +1 -0
- package/lib/utils/server/index.d.ts.map +1 -0
- package/lib/utils/server/method.d.ts.map +1 -0
- package/lib/utils/server/parser.d.ts.map +1 -0
- package/lib/utils/server/route.d.ts.map +1 -0
- package/lib/utils/server/route.js.map +1 -1
- package/lib/utils/types.d.ts.map +1 -0
- package/lib/utils/urlFormat.d.ts.map +1 -0
- package/lib/utils/wireFormat.d.ts.map +1 -0
- package/package.json +17 -11
- package/src/beacon/client/beacon.ts +12 -0
- package/src/beacon/client/config.ts +12 -0
- package/src/beacon/client/debug.ts +12 -0
- package/src/beacon/client/events.ts +69 -0
- package/src/beacon/client/index.ts +46 -0
- package/src/beacon/client/lightclient.ts +12 -0
- package/src/beacon/client/lodestar.ts +12 -0
- package/src/beacon/client/node.ts +12 -0
- package/src/beacon/client/proof.ts +12 -0
- package/src/beacon/client/validator.ts +12 -0
- package/src/beacon/index.ts +24 -0
- package/src/beacon/routes/beacon/block.ts +602 -0
- package/src/beacon/routes/beacon/index.ts +66 -0
- package/src/beacon/routes/beacon/pool.ts +503 -0
- package/src/beacon/routes/beacon/rewards.ts +216 -0
- package/src/beacon/routes/beacon/state.ts +588 -0
- package/src/beacon/routes/config.ts +114 -0
- package/src/beacon/routes/debug.ts +231 -0
- package/src/beacon/routes/events.ts +337 -0
- package/src/beacon/routes/index.ts +33 -0
- package/src/beacon/routes/lightclient.ts +241 -0
- package/src/beacon/routes/lodestar.ts +456 -0
- package/src/beacon/routes/node.ts +286 -0
- package/src/beacon/routes/proof.ts +79 -0
- package/src/beacon/routes/validator.ts +1014 -0
- package/src/beacon/server/beacon.ts +7 -0
- package/src/beacon/server/config.ts +7 -0
- package/src/beacon/server/debug.ts +7 -0
- package/src/beacon/server/events.ts +73 -0
- package/src/beacon/server/index.ts +55 -0
- package/src/beacon/server/lightclient.ts +7 -0
- package/src/beacon/server/lodestar.ts +7 -0
- package/src/beacon/server/node.ts +7 -0
- package/src/beacon/server/proof.ts +7 -0
- package/src/beacon/server/validator.ts +7 -0
- package/src/builder/client.ts +9 -0
- package/src/builder/index.ts +26 -0
- package/src/builder/routes.ts +227 -0
- package/src/builder/server/index.ts +19 -0
- package/src/index.ts +19 -0
- package/src/keymanager/client.ts +9 -0
- package/src/keymanager/index.ts +39 -0
- package/src/keymanager/routes.ts +699 -0
- package/src/keymanager/server/index.ts +19 -0
- package/src/server/index.ts +2 -0
- package/src/utils/client/error.ts +10 -0
- package/src/utils/client/eventSource.ts +7 -0
- package/src/utils/client/format.ts +22 -0
- package/src/utils/client/httpClient.ts +444 -0
- package/src/utils/client/index.ts +6 -0
- package/src/utils/client/method.ts +50 -0
- package/src/utils/client/metrics.ts +9 -0
- package/src/utils/client/request.ts +113 -0
- package/src/utils/client/response.ts +205 -0
- package/src/utils/codecs.ts +143 -0
- package/src/utils/fork.ts +44 -0
- package/src/utils/headers.ts +173 -0
- package/src/utils/httpStatusCode.ts +392 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/metadata.ts +170 -0
- package/src/utils/schema.ts +141 -0
- package/src/utils/serdes.ts +120 -0
- package/src/utils/server/error.ts +9 -0
- package/src/utils/server/handler.ts +149 -0
- package/src/utils/server/index.ts +5 -0
- package/src/utils/server/method.ts +38 -0
- package/src/utils/server/parser.ts +15 -0
- package/src/utils/server/route.ts +45 -0
- package/src/utils/types.ts +161 -0
- package/src/utils/urlFormat.ts +112 -0
- package/src/utils/wireFormat.ts +24 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import {ContainerType, Type, ValueOf} from "@chainsafe/ssz";
|
|
2
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
3
|
+
import {BeaconState, StringType, fulu, ssz} from "@lodestar/types";
|
|
4
|
+
import {
|
|
5
|
+
ArrayOf,
|
|
6
|
+
EmptyArgs,
|
|
7
|
+
EmptyMeta,
|
|
8
|
+
EmptyMetaCodec,
|
|
9
|
+
EmptyRequest,
|
|
10
|
+
EmptyRequestCodec,
|
|
11
|
+
WithVersion,
|
|
12
|
+
} from "../../utils/codecs.js";
|
|
13
|
+
import {
|
|
14
|
+
ExecutionOptimisticFinalizedAndVersionCodec,
|
|
15
|
+
ExecutionOptimisticFinalizedAndVersionMeta,
|
|
16
|
+
} from "../../utils/metadata.js";
|
|
17
|
+
import {Schema} from "../../utils/schema.js";
|
|
18
|
+
import {Endpoint, RouteDefinitions} from "../../utils/types.js";
|
|
19
|
+
import {WireFormat} from "../../utils/wireFormat.js";
|
|
20
|
+
import {BlockArgs} from "./beacon/block.js";
|
|
21
|
+
import {StateArgs} from "./beacon/state.js";
|
|
22
|
+
|
|
23
|
+
const stringType = new StringType();
|
|
24
|
+
const ProtoNodeType = new ContainerType(
|
|
25
|
+
{
|
|
26
|
+
executionPayloadBlockHash: stringType,
|
|
27
|
+
executionPayloadNumber: ssz.UintNum64,
|
|
28
|
+
executionStatus: stringType,
|
|
29
|
+
slot: ssz.Slot,
|
|
30
|
+
blockRoot: stringType,
|
|
31
|
+
parentRoot: stringType,
|
|
32
|
+
stateRoot: stringType,
|
|
33
|
+
targetRoot: stringType,
|
|
34
|
+
timeliness: ssz.Boolean,
|
|
35
|
+
justifiedEpoch: ssz.Epoch,
|
|
36
|
+
justifiedRoot: stringType,
|
|
37
|
+
finalizedEpoch: ssz.Epoch,
|
|
38
|
+
finalizedRoot: stringType,
|
|
39
|
+
unrealizedJustifiedEpoch: ssz.Epoch,
|
|
40
|
+
unrealizedJustifiedRoot: stringType,
|
|
41
|
+
unrealizedFinalizedEpoch: ssz.Epoch,
|
|
42
|
+
unrealizedFinalizedRoot: stringType,
|
|
43
|
+
parent: stringType,
|
|
44
|
+
weight: ssz.Uint32,
|
|
45
|
+
bestChild: stringType,
|
|
46
|
+
bestDescendant: stringType,
|
|
47
|
+
},
|
|
48
|
+
{jsonCase: "eth2"}
|
|
49
|
+
);
|
|
50
|
+
const DebugChainHeadType = new ContainerType(
|
|
51
|
+
{
|
|
52
|
+
slot: ssz.Slot,
|
|
53
|
+
root: stringType,
|
|
54
|
+
executionOptimistic: ssz.Boolean,
|
|
55
|
+
},
|
|
56
|
+
{jsonCase: "eth2"}
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
const ForkChoiceNodeType = new ContainerType(
|
|
60
|
+
{
|
|
61
|
+
slot: ssz.Slot,
|
|
62
|
+
blockRoot: stringType,
|
|
63
|
+
parentRoot: stringType,
|
|
64
|
+
justifiedEpoch: ssz.Epoch,
|
|
65
|
+
finalizedEpoch: ssz.Epoch,
|
|
66
|
+
weight: ssz.UintNum64,
|
|
67
|
+
validity: new StringType<"valid" | "invalid" | "optimistic">(),
|
|
68
|
+
executionBlockHash: stringType,
|
|
69
|
+
},
|
|
70
|
+
{jsonCase: "eth2"}
|
|
71
|
+
);
|
|
72
|
+
const ForkChoiceResponseType = new ContainerType(
|
|
73
|
+
{
|
|
74
|
+
justifiedCheckpoint: ssz.phase0.Checkpoint,
|
|
75
|
+
finalizedCheckpoint: ssz.phase0.Checkpoint,
|
|
76
|
+
forkChoiceNodes: ArrayOf(ForkChoiceNodeType),
|
|
77
|
+
},
|
|
78
|
+
{jsonCase: "eth2"}
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const ProtoNodeListType = ArrayOf(ProtoNodeType);
|
|
82
|
+
const DebugChainHeadListType = ArrayOf(DebugChainHeadType);
|
|
83
|
+
|
|
84
|
+
type ProtoNodeList = ValueOf<typeof ProtoNodeListType>;
|
|
85
|
+
type DebugChainHeadList = ValueOf<typeof DebugChainHeadListType>;
|
|
86
|
+
type ForkChoiceResponse = ValueOf<typeof ForkChoiceResponseType>;
|
|
87
|
+
|
|
88
|
+
export type Endpoints = {
|
|
89
|
+
/**
|
|
90
|
+
* Retrieves all possible chain heads (leaves of fork choice tree).
|
|
91
|
+
*/
|
|
92
|
+
getDebugChainHeadsV2: Endpoint<
|
|
93
|
+
// ⏎
|
|
94
|
+
"GET",
|
|
95
|
+
EmptyArgs,
|
|
96
|
+
EmptyRequest,
|
|
97
|
+
DebugChainHeadList,
|
|
98
|
+
EmptyMeta
|
|
99
|
+
>;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Retrieves all current fork choice context
|
|
103
|
+
*/
|
|
104
|
+
getDebugForkChoice: Endpoint<
|
|
105
|
+
// ⏎
|
|
106
|
+
"GET",
|
|
107
|
+
EmptyArgs,
|
|
108
|
+
EmptyRequest,
|
|
109
|
+
ForkChoiceResponse,
|
|
110
|
+
EmptyMeta
|
|
111
|
+
>;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Dump all ProtoArray's nodes to debug
|
|
115
|
+
*/
|
|
116
|
+
getProtoArrayNodes: Endpoint<
|
|
117
|
+
// ⏎
|
|
118
|
+
"GET",
|
|
119
|
+
EmptyArgs,
|
|
120
|
+
EmptyRequest,
|
|
121
|
+
ProtoNodeList,
|
|
122
|
+
EmptyMeta
|
|
123
|
+
>;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Get full BeaconState object
|
|
127
|
+
* Returns full BeaconState object for given stateId.
|
|
128
|
+
* Depending on `Accept` header it can be returned either as json or as bytes serialized by SSZ
|
|
129
|
+
*/
|
|
130
|
+
getStateV2: Endpoint<
|
|
131
|
+
"GET",
|
|
132
|
+
StateArgs,
|
|
133
|
+
{params: {state_id: string}},
|
|
134
|
+
BeaconState,
|
|
135
|
+
ExecutionOptimisticFinalizedAndVersionMeta
|
|
136
|
+
>;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Get data column sidecars
|
|
140
|
+
* Retrieves data column sidecars for a given block id.
|
|
141
|
+
*/
|
|
142
|
+
getDebugDataColumnSidecars: Endpoint<
|
|
143
|
+
"GET",
|
|
144
|
+
BlockArgs & {
|
|
145
|
+
/**
|
|
146
|
+
* Array of indices for data column sidecars to request for in the specified block.
|
|
147
|
+
* This endpoint will only return columns that the node is actually custodying.
|
|
148
|
+
* If not specified, returns all data column sidecars that this node is custodying in the block.
|
|
149
|
+
*/
|
|
150
|
+
indices?: number[];
|
|
151
|
+
},
|
|
152
|
+
{params: {block_id: string}; query: {indices?: number[]}},
|
|
153
|
+
fulu.DataColumnSidecars,
|
|
154
|
+
ExecutionOptimisticFinalizedAndVersionMeta
|
|
155
|
+
>;
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
export function getDefinitions(_config: ChainForkConfig): RouteDefinitions<Endpoints> {
|
|
159
|
+
return {
|
|
160
|
+
getDebugChainHeadsV2: {
|
|
161
|
+
url: "/eth/v2/debug/beacon/heads",
|
|
162
|
+
method: "GET",
|
|
163
|
+
req: EmptyRequestCodec,
|
|
164
|
+
resp: {
|
|
165
|
+
data: DebugChainHeadListType,
|
|
166
|
+
meta: EmptyMetaCodec,
|
|
167
|
+
onlySupport: WireFormat.json,
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
getDebugForkChoice: {
|
|
171
|
+
url: "/eth/v1/debug/fork_choice",
|
|
172
|
+
method: "GET",
|
|
173
|
+
req: EmptyRequestCodec,
|
|
174
|
+
resp: {
|
|
175
|
+
data: ForkChoiceResponseType,
|
|
176
|
+
meta: EmptyMetaCodec,
|
|
177
|
+
onlySupport: WireFormat.json,
|
|
178
|
+
transform: {
|
|
179
|
+
toResponse: (data) => ({
|
|
180
|
+
...(data as ForkChoiceResponse),
|
|
181
|
+
}),
|
|
182
|
+
fromResponse: (resp) => ({
|
|
183
|
+
data: resp as ForkChoiceResponse,
|
|
184
|
+
}),
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
getProtoArrayNodes: {
|
|
189
|
+
url: "/eth/v0/debug/forkchoice",
|
|
190
|
+
method: "GET",
|
|
191
|
+
req: EmptyRequestCodec,
|
|
192
|
+
resp: {
|
|
193
|
+
data: ProtoNodeListType,
|
|
194
|
+
meta: EmptyMetaCodec,
|
|
195
|
+
onlySupport: WireFormat.json,
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
getStateV2: {
|
|
199
|
+
url: "/eth/v2/debug/beacon/states/{state_id}",
|
|
200
|
+
method: "GET",
|
|
201
|
+
req: {
|
|
202
|
+
writeReq: ({stateId}) => ({params: {state_id: stateId.toString()}}),
|
|
203
|
+
parseReq: ({params}) => ({stateId: params.state_id}),
|
|
204
|
+
schema: {
|
|
205
|
+
params: {state_id: Schema.StringRequired},
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
resp: {
|
|
209
|
+
data: WithVersion((fork) => ssz[fork].BeaconState as Type<BeaconState>),
|
|
210
|
+
meta: ExecutionOptimisticFinalizedAndVersionCodec,
|
|
211
|
+
},
|
|
212
|
+
init: {
|
|
213
|
+
// Default timeout is not sufficient to download state as JSON
|
|
214
|
+
timeoutMs: 5 * 60 * 1000,
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
getDebugDataColumnSidecars: {
|
|
218
|
+
url: "/eth/v1/debug/beacon/data_column_sidecars/{block_id}",
|
|
219
|
+
method: "GET",
|
|
220
|
+
req: {
|
|
221
|
+
writeReq: ({blockId, indices}) => ({params: {block_id: blockId.toString()}, query: {indices}}),
|
|
222
|
+
parseReq: ({params, query}) => ({blockId: params.block_id, indices: query.indices}),
|
|
223
|
+
schema: {params: {block_id: Schema.StringRequired}, query: {indices: Schema.UintArray}},
|
|
224
|
+
},
|
|
225
|
+
resp: {
|
|
226
|
+
data: ssz.fulu.DataColumnSidecars,
|
|
227
|
+
meta: ExecutionOptimisticFinalizedAndVersionCodec,
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
};
|
|
231
|
+
}
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import {ContainerType, ListBasicType, ValueOf} from "@chainsafe/ssz";
|
|
2
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
3
|
+
import {ForkName, MAX_BLOB_COMMITMENTS_PER_BLOCK} from "@lodestar/params";
|
|
4
|
+
import {
|
|
5
|
+
Attestation,
|
|
6
|
+
AttesterSlashing,
|
|
7
|
+
Epoch,
|
|
8
|
+
LightClientFinalityUpdate,
|
|
9
|
+
LightClientOptimisticUpdate,
|
|
10
|
+
RootHex,
|
|
11
|
+
SSEPayloadAttributes,
|
|
12
|
+
Slot,
|
|
13
|
+
StringType,
|
|
14
|
+
UintNum64,
|
|
15
|
+
altair,
|
|
16
|
+
capella,
|
|
17
|
+
electra,
|
|
18
|
+
phase0,
|
|
19
|
+
ssz,
|
|
20
|
+
sszTypesFor,
|
|
21
|
+
} from "@lodestar/types";
|
|
22
|
+
import {EmptyMeta, EmptyResponseCodec, EmptyResponseData} from "../../utils/codecs.js";
|
|
23
|
+
import {getPostAltairForkTypes, getPostBellatrixForkTypes} from "../../utils/fork.js";
|
|
24
|
+
import {Endpoint, RouteDefinitions, Schema} from "../../utils/index.js";
|
|
25
|
+
import {VersionType} from "../../utils/metadata.js";
|
|
26
|
+
|
|
27
|
+
const stringType = new StringType();
|
|
28
|
+
export const blobSidecarSSE = new ContainerType(
|
|
29
|
+
{
|
|
30
|
+
blockRoot: stringType,
|
|
31
|
+
index: ssz.BlobIndex,
|
|
32
|
+
slot: ssz.Slot,
|
|
33
|
+
kzgCommitment: stringType,
|
|
34
|
+
versionedHash: stringType,
|
|
35
|
+
},
|
|
36
|
+
{typeName: "BlobSidecarSSE", jsonCase: "eth2"}
|
|
37
|
+
);
|
|
38
|
+
type BlobSidecarSSE = ValueOf<typeof blobSidecarSSE>;
|
|
39
|
+
|
|
40
|
+
export const dataColumnSidecarSSE = new ContainerType(
|
|
41
|
+
{
|
|
42
|
+
blockRoot: stringType,
|
|
43
|
+
index: ssz.ColumnIndex,
|
|
44
|
+
slot: ssz.Slot,
|
|
45
|
+
kzgCommitments: new ListBasicType(stringType, MAX_BLOB_COMMITMENTS_PER_BLOCK),
|
|
46
|
+
},
|
|
47
|
+
{typeName: "DataColumnSidecarSSE", jsonCase: "eth2"}
|
|
48
|
+
);
|
|
49
|
+
type DataColumnSidecarSSE = ValueOf<typeof dataColumnSidecarSSE>;
|
|
50
|
+
|
|
51
|
+
export enum EventType {
|
|
52
|
+
/**
|
|
53
|
+
* The node has finished processing, resulting in a new head. previous_duty_dependent_root is
|
|
54
|
+
* `get_block_root_at_slot(state, compute_start_slot_at_epoch(epoch - 1) - 1)` and
|
|
55
|
+
* current_duty_dependent_root is `get_block_root_at_slot(state, compute_start_slot_at_epoch(epoch) - 1)`.
|
|
56
|
+
* Both dependent roots use the genesis block root in the case of underflow.
|
|
57
|
+
*/
|
|
58
|
+
head = "head",
|
|
59
|
+
/** The node has received a block (from P2P or API) that is successfully imported on the fork-choice `on_block` handler */
|
|
60
|
+
block = "block",
|
|
61
|
+
/** The node has received a block (from P2P or API) that passes validation rules of the `beacon_block` topic */
|
|
62
|
+
blockGossip = "block_gossip",
|
|
63
|
+
/** The node has received a valid attestation (from P2P or API) */
|
|
64
|
+
attestation = "attestation",
|
|
65
|
+
/** The node has received a valid SingleAttestation (from P2P or API) */
|
|
66
|
+
singleAttestation = "single_attestation",
|
|
67
|
+
/** The node has received a valid voluntary exit (from P2P or API) */
|
|
68
|
+
voluntaryExit = "voluntary_exit",
|
|
69
|
+
/** The node has received a valid proposer slashing (from P2P or API) */
|
|
70
|
+
proposerSlashing = "proposer_slashing",
|
|
71
|
+
/** The node has received a valid attester slashing (from P2P or API) */
|
|
72
|
+
attesterSlashing = "attester_slashing",
|
|
73
|
+
/** The node has received a valid blsToExecutionChange (from P2P or API) */
|
|
74
|
+
blsToExecutionChange = "bls_to_execution_change",
|
|
75
|
+
/** Finalized checkpoint has been updated */
|
|
76
|
+
finalizedCheckpoint = "finalized_checkpoint",
|
|
77
|
+
/** The node has reorganized its chain */
|
|
78
|
+
chainReorg = "chain_reorg",
|
|
79
|
+
/** The node has received a valid sync committee SignedContributionAndProof (from P2P or API) */
|
|
80
|
+
contributionAndProof = "contribution_and_proof",
|
|
81
|
+
/** New or better optimistic header update available */
|
|
82
|
+
lightClientOptimisticUpdate = "light_client_optimistic_update",
|
|
83
|
+
/** New or better finality update available */
|
|
84
|
+
lightClientFinalityUpdate = "light_client_finality_update",
|
|
85
|
+
/** Payload attributes for block proposal */
|
|
86
|
+
payloadAttributes = "payload_attributes",
|
|
87
|
+
/** The node has received a valid BlobSidecar (from P2P or API) */
|
|
88
|
+
blobSidecar = "blob_sidecar",
|
|
89
|
+
/** The node has received a valid DataColumnSidecar (from P2P or API) */
|
|
90
|
+
dataColumnSidecar = "data_column_sidecar",
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export const eventTypes: {[K in EventType]: K} = {
|
|
94
|
+
[EventType.head]: EventType.head,
|
|
95
|
+
[EventType.block]: EventType.block,
|
|
96
|
+
[EventType.blockGossip]: EventType.blockGossip,
|
|
97
|
+
[EventType.attestation]: EventType.attestation,
|
|
98
|
+
[EventType.singleAttestation]: EventType.singleAttestation,
|
|
99
|
+
[EventType.voluntaryExit]: EventType.voluntaryExit,
|
|
100
|
+
[EventType.proposerSlashing]: EventType.proposerSlashing,
|
|
101
|
+
[EventType.attesterSlashing]: EventType.attesterSlashing,
|
|
102
|
+
[EventType.blsToExecutionChange]: EventType.blsToExecutionChange,
|
|
103
|
+
[EventType.finalizedCheckpoint]: EventType.finalizedCheckpoint,
|
|
104
|
+
[EventType.chainReorg]: EventType.chainReorg,
|
|
105
|
+
[EventType.contributionAndProof]: EventType.contributionAndProof,
|
|
106
|
+
[EventType.lightClientOptimisticUpdate]: EventType.lightClientOptimisticUpdate,
|
|
107
|
+
[EventType.lightClientFinalityUpdate]: EventType.lightClientFinalityUpdate,
|
|
108
|
+
[EventType.payloadAttributes]: EventType.payloadAttributes,
|
|
109
|
+
[EventType.blobSidecar]: EventType.blobSidecar,
|
|
110
|
+
[EventType.dataColumnSidecar]: EventType.dataColumnSidecar,
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export type EventData = {
|
|
114
|
+
[EventType.head]: {
|
|
115
|
+
slot: Slot;
|
|
116
|
+
block: RootHex;
|
|
117
|
+
state: RootHex;
|
|
118
|
+
epochTransition: boolean;
|
|
119
|
+
previousDutyDependentRoot: RootHex;
|
|
120
|
+
currentDutyDependentRoot: RootHex;
|
|
121
|
+
executionOptimistic: boolean;
|
|
122
|
+
};
|
|
123
|
+
[EventType.block]: {
|
|
124
|
+
slot: Slot;
|
|
125
|
+
block: RootHex;
|
|
126
|
+
executionOptimistic: boolean;
|
|
127
|
+
};
|
|
128
|
+
[EventType.blockGossip]: {
|
|
129
|
+
slot: Slot;
|
|
130
|
+
block: RootHex;
|
|
131
|
+
};
|
|
132
|
+
[EventType.attestation]: Attestation;
|
|
133
|
+
[EventType.singleAttestation]: electra.SingleAttestation;
|
|
134
|
+
[EventType.voluntaryExit]: phase0.SignedVoluntaryExit;
|
|
135
|
+
[EventType.proposerSlashing]: phase0.ProposerSlashing;
|
|
136
|
+
[EventType.attesterSlashing]: AttesterSlashing;
|
|
137
|
+
[EventType.blsToExecutionChange]: capella.SignedBLSToExecutionChange;
|
|
138
|
+
[EventType.finalizedCheckpoint]: {
|
|
139
|
+
block: RootHex;
|
|
140
|
+
state: RootHex;
|
|
141
|
+
epoch: Epoch;
|
|
142
|
+
executionOptimistic: boolean;
|
|
143
|
+
};
|
|
144
|
+
[EventType.chainReorg]: {
|
|
145
|
+
slot: Slot;
|
|
146
|
+
depth: UintNum64;
|
|
147
|
+
oldHeadBlock: RootHex;
|
|
148
|
+
newHeadBlock: RootHex;
|
|
149
|
+
oldHeadState: RootHex;
|
|
150
|
+
newHeadState: RootHex;
|
|
151
|
+
epoch: Epoch;
|
|
152
|
+
executionOptimistic: boolean;
|
|
153
|
+
};
|
|
154
|
+
[EventType.contributionAndProof]: altair.SignedContributionAndProof;
|
|
155
|
+
[EventType.lightClientOptimisticUpdate]: {version: ForkName; data: LightClientOptimisticUpdate};
|
|
156
|
+
[EventType.lightClientFinalityUpdate]: {version: ForkName; data: LightClientFinalityUpdate};
|
|
157
|
+
[EventType.payloadAttributes]: {version: ForkName; data: SSEPayloadAttributes};
|
|
158
|
+
[EventType.blobSidecar]: BlobSidecarSSE;
|
|
159
|
+
[EventType.dataColumnSidecar]: DataColumnSidecarSSE;
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
export type BeaconEvent = {[K in EventType]: {type: K; message: EventData[K]}}[EventType];
|
|
163
|
+
|
|
164
|
+
type EventstreamArgs = {
|
|
165
|
+
/** Event types to subscribe to */
|
|
166
|
+
topics: EventType[];
|
|
167
|
+
signal: AbortSignal;
|
|
168
|
+
onEvent: (event: BeaconEvent) => void;
|
|
169
|
+
onError?: (err: Error) => void;
|
|
170
|
+
onClose?: () => void;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
export type Endpoints = {
|
|
174
|
+
/**
|
|
175
|
+
* Subscribe to beacon node events
|
|
176
|
+
* Provides endpoint to subscribe to beacon node Server-Sent-Events stream.
|
|
177
|
+
* Consumers should use [eventsource](https://html.spec.whatwg.org/multipage/server-sent-events.html#the-eventsource-interface)
|
|
178
|
+
* implementation to listen on those events.
|
|
179
|
+
*
|
|
180
|
+
* Returns if SSE stream has been opened.
|
|
181
|
+
*/
|
|
182
|
+
eventstream: Endpoint<
|
|
183
|
+
// ⏎
|
|
184
|
+
"GET",
|
|
185
|
+
EventstreamArgs,
|
|
186
|
+
{query: {topics: EventType[]}},
|
|
187
|
+
EmptyResponseData,
|
|
188
|
+
EmptyMeta
|
|
189
|
+
>;
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
export function getDefinitions(_config: ChainForkConfig): RouteDefinitions<Endpoints> {
|
|
193
|
+
return {
|
|
194
|
+
eventstream: {
|
|
195
|
+
url: "/eth/v1/events",
|
|
196
|
+
method: "GET",
|
|
197
|
+
req: {
|
|
198
|
+
writeReq: ({topics}) => ({query: {topics}}),
|
|
199
|
+
parseReq: ({query}) => ({topics: query.topics}) as EventstreamArgs,
|
|
200
|
+
schema: {
|
|
201
|
+
query: {topics: Schema.StringArrayRequired},
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
resp: EmptyResponseCodec,
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export type TypeJson<T> = {
|
|
210
|
+
toJson: (data: T) => unknown; // server
|
|
211
|
+
fromJson: (data: unknown) => T; // client
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
export function getTypeByEvent(config: ChainForkConfig): {[K in EventType]: TypeJson<EventData[K]>} {
|
|
215
|
+
const WithVersion = <T>(getType: (fork: ForkName) => TypeJson<T>): TypeJson<{data: T; version: ForkName}> => {
|
|
216
|
+
return {
|
|
217
|
+
toJson: ({data, version}) => ({
|
|
218
|
+
data: getType(version).toJson(data),
|
|
219
|
+
version,
|
|
220
|
+
}),
|
|
221
|
+
fromJson: (val) => {
|
|
222
|
+
const {version} = VersionType.fromJson(val);
|
|
223
|
+
return {
|
|
224
|
+
data: getType(version).fromJson((val as {data: unknown}).data),
|
|
225
|
+
version,
|
|
226
|
+
};
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
return {
|
|
232
|
+
[EventType.head]: new ContainerType(
|
|
233
|
+
{
|
|
234
|
+
slot: ssz.Slot,
|
|
235
|
+
block: stringType,
|
|
236
|
+
state: stringType,
|
|
237
|
+
epochTransition: ssz.Boolean,
|
|
238
|
+
previousDutyDependentRoot: stringType,
|
|
239
|
+
currentDutyDependentRoot: stringType,
|
|
240
|
+
executionOptimistic: ssz.Boolean,
|
|
241
|
+
},
|
|
242
|
+
{jsonCase: "eth2"}
|
|
243
|
+
),
|
|
244
|
+
|
|
245
|
+
[EventType.block]: new ContainerType(
|
|
246
|
+
{
|
|
247
|
+
slot: ssz.Slot,
|
|
248
|
+
block: stringType,
|
|
249
|
+
executionOptimistic: ssz.Boolean,
|
|
250
|
+
},
|
|
251
|
+
{jsonCase: "eth2"}
|
|
252
|
+
),
|
|
253
|
+
[EventType.blockGossip]: new ContainerType(
|
|
254
|
+
{
|
|
255
|
+
slot: ssz.Slot,
|
|
256
|
+
block: stringType,
|
|
257
|
+
},
|
|
258
|
+
{jsonCase: "eth2"}
|
|
259
|
+
),
|
|
260
|
+
|
|
261
|
+
[EventType.attestation]: {
|
|
262
|
+
toJson: (attestation) => {
|
|
263
|
+
const fork = config.getForkName(attestation.data.slot);
|
|
264
|
+
return sszTypesFor(fork).Attestation.toJson(attestation);
|
|
265
|
+
},
|
|
266
|
+
fromJson: (attestation) => {
|
|
267
|
+
const fork = config.getForkName((attestation as Attestation).data.slot);
|
|
268
|
+
return sszTypesFor(fork).Attestation.fromJson(attestation);
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
[EventType.singleAttestation]: ssz.electra.SingleAttestation,
|
|
272
|
+
[EventType.voluntaryExit]: ssz.phase0.SignedVoluntaryExit,
|
|
273
|
+
[EventType.proposerSlashing]: ssz.phase0.ProposerSlashing,
|
|
274
|
+
[EventType.attesterSlashing]: {
|
|
275
|
+
toJson: (attesterSlashing) => {
|
|
276
|
+
const fork = config.getForkName(Number(attesterSlashing.attestation1.data.slot));
|
|
277
|
+
return sszTypesFor(fork).AttesterSlashing.toJson(attesterSlashing);
|
|
278
|
+
},
|
|
279
|
+
fromJson: (attesterSlashing) => {
|
|
280
|
+
const fork = config.getForkName(Number((attesterSlashing as AttesterSlashing).attestation1.data.slot));
|
|
281
|
+
return sszTypesFor(fork).AttesterSlashing.fromJson(attesterSlashing);
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
[EventType.blsToExecutionChange]: ssz.capella.SignedBLSToExecutionChange,
|
|
285
|
+
|
|
286
|
+
[EventType.finalizedCheckpoint]: new ContainerType(
|
|
287
|
+
{
|
|
288
|
+
block: stringType,
|
|
289
|
+
state: stringType,
|
|
290
|
+
epoch: ssz.Epoch,
|
|
291
|
+
executionOptimistic: ssz.Boolean,
|
|
292
|
+
},
|
|
293
|
+
{jsonCase: "eth2"}
|
|
294
|
+
),
|
|
295
|
+
|
|
296
|
+
[EventType.chainReorg]: new ContainerType(
|
|
297
|
+
{
|
|
298
|
+
slot: ssz.Slot,
|
|
299
|
+
depth: ssz.UintNum64,
|
|
300
|
+
oldHeadBlock: stringType,
|
|
301
|
+
newHeadBlock: stringType,
|
|
302
|
+
oldHeadState: stringType,
|
|
303
|
+
newHeadState: stringType,
|
|
304
|
+
epoch: ssz.Epoch,
|
|
305
|
+
executionOptimistic: ssz.Boolean,
|
|
306
|
+
},
|
|
307
|
+
{jsonCase: "eth2"}
|
|
308
|
+
),
|
|
309
|
+
|
|
310
|
+
[EventType.contributionAndProof]: ssz.altair.SignedContributionAndProof,
|
|
311
|
+
[EventType.payloadAttributes]: WithVersion((fork) => getPostBellatrixForkTypes(fork).SSEPayloadAttributes),
|
|
312
|
+
[EventType.blobSidecar]: blobSidecarSSE,
|
|
313
|
+
[EventType.dataColumnSidecar]: dataColumnSidecarSSE,
|
|
314
|
+
|
|
315
|
+
[EventType.lightClientOptimisticUpdate]: WithVersion(
|
|
316
|
+
(fork) => getPostAltairForkTypes(fork).LightClientOptimisticUpdate
|
|
317
|
+
),
|
|
318
|
+
[EventType.lightClientFinalityUpdate]: WithVersion(
|
|
319
|
+
(fork) => getPostAltairForkTypes(fork).LightClientFinalityUpdate
|
|
320
|
+
),
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
export function getEventSerdes(config: ChainForkConfig) {
|
|
325
|
+
const typeByEvent = getTypeByEvent(config);
|
|
326
|
+
|
|
327
|
+
return {
|
|
328
|
+
toJson: (event: BeaconEvent): unknown => {
|
|
329
|
+
const eventType = typeByEvent[event.type] as TypeJson<BeaconEvent["message"]>;
|
|
330
|
+
return eventType.toJson(event.message);
|
|
331
|
+
},
|
|
332
|
+
fromJson: (type: EventType, data: unknown): BeaconEvent["message"] => {
|
|
333
|
+
const eventType = typeByEvent[type] as TypeJson<BeaconEvent["message"]>;
|
|
334
|
+
return eventType.fromJson(data);
|
|
335
|
+
},
|
|
336
|
+
};
|
|
337
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// biome-ignore assist/source/organizeImports: We want to keep these groups of imports together for better readability
|
|
2
|
+
import {Endpoints as BeaconEndpoints} from "./beacon/index.js";
|
|
3
|
+
import {Endpoints as ConfigEndpoints} from "./config.js";
|
|
4
|
+
import {Endpoints as DebugEndpoints} from "./debug.js";
|
|
5
|
+
import {Endpoints as EventsEndpoints} from "./events.js";
|
|
6
|
+
import {Endpoints as LightclientEndpoints} from "./lightclient.js";
|
|
7
|
+
import {Endpoints as LodestarEndpoints} from "./lodestar.js";
|
|
8
|
+
import {Endpoints as NodeEndpoints} from "./node.js";
|
|
9
|
+
import {Endpoints as ProofEndpoints} from "./proof.js";
|
|
10
|
+
import {Endpoints as ValidatorEndpoints} from "./validator.js";
|
|
11
|
+
|
|
12
|
+
import * as beacon from "./beacon/index.js";
|
|
13
|
+
import * as config from "./config.js";
|
|
14
|
+
import * as debug from "./debug.js";
|
|
15
|
+
import * as events from "./events.js";
|
|
16
|
+
import * as lightclient from "./lightclient.js";
|
|
17
|
+
import * as lodestar from "./lodestar.js";
|
|
18
|
+
import * as node from "./node.js";
|
|
19
|
+
import * as proof from "./proof.js";
|
|
20
|
+
import * as validator from "./validator.js";
|
|
21
|
+
export {beacon, config, debug, events, lightclient, lodestar, node, proof, validator};
|
|
22
|
+
|
|
23
|
+
export type Endpoints = {
|
|
24
|
+
beacon: BeaconEndpoints;
|
|
25
|
+
config: ConfigEndpoints;
|
|
26
|
+
debug: DebugEndpoints;
|
|
27
|
+
events: EventsEndpoints;
|
|
28
|
+
lightclient: LightclientEndpoints;
|
|
29
|
+
lodestar: LodestarEndpoints;
|
|
30
|
+
node: NodeEndpoints;
|
|
31
|
+
proof: ProofEndpoints;
|
|
32
|
+
validator: ValidatorEndpoints;
|
|
33
|
+
};
|