@lodestar/api 1.50.0-dev.b4eaa62b30 → 1.50.0-dev.b726a05a4d

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 (44) hide show
  1. package/lib/beacon/client/events.d.ts.map +1 -1
  2. package/lib/beacon/client/events.js +2 -1
  3. package/lib/beacon/client/events.js.map +1 -1
  4. package/lib/beacon/routes/beacon/index.d.ts +28 -2
  5. package/lib/beacon/routes/beacon/index.d.ts.map +1 -1
  6. package/lib/beacon/routes/beacon/index.js +23 -1
  7. package/lib/beacon/routes/beacon/index.js.map +1 -1
  8. package/lib/beacon/routes/beacon/state.d.ts +30 -5
  9. package/lib/beacon/routes/beacon/state.d.ts.map +1 -1
  10. package/lib/beacon/routes/beacon/state.js +25 -4
  11. package/lib/beacon/routes/beacon/state.js.map +1 -1
  12. package/lib/beacon/routes/debug.d.ts +24 -10
  13. package/lib/beacon/routes/debug.d.ts.map +1 -1
  14. package/lib/beacon/routes/debug.js +19 -18
  15. package/lib/beacon/routes/debug.js.map +1 -1
  16. package/lib/beacon/routes/events.d.ts +18 -5
  17. package/lib/beacon/routes/events.d.ts.map +1 -1
  18. package/lib/beacon/routes/events.js +28 -5
  19. package/lib/beacon/routes/events.js.map +1 -1
  20. package/lib/index.d.ts +1 -1
  21. package/lib/index.d.ts.map +1 -1
  22. package/lib/index.js.map +1 -1
  23. package/lib/utils/client/error.d.ts +8 -1
  24. package/lib/utils/client/error.d.ts.map +1 -1
  25. package/lib/utils/client/error.js +4 -1
  26. package/lib/utils/client/error.js.map +1 -1
  27. package/lib/utils/client/response.d.ts +1 -1
  28. package/lib/utils/client/response.d.ts.map +1 -1
  29. package/lib/utils/client/response.js +11 -7
  30. package/lib/utils/client/response.js.map +1 -1
  31. package/lib/utils/fork.d.ts +2 -1
  32. package/lib/utils/fork.d.ts.map +1 -1
  33. package/lib/utils/fork.js +7 -1
  34. package/lib/utils/fork.js.map +1 -1
  35. package/package.json +7 -7
  36. package/src/beacon/client/events.ts +3 -0
  37. package/src/beacon/routes/beacon/index.ts +40 -1
  38. package/src/beacon/routes/beacon/state.ts +50 -8
  39. package/src/beacon/routes/debug.ts +22 -18
  40. package/src/beacon/routes/events.ts +39 -12
  41. package/src/index.ts +1 -1
  42. package/src/utils/client/error.ts +7 -1
  43. package/src/utils/client/response.ts +13 -9
  44. package/src/utils/fork.ts +10 -0
@@ -80,40 +80,52 @@ const ForkChoiceResponseType = new ContainerType(
80
80
 
81
81
  const ForkChoiceNodeV2ExtraDataType = new ContainerType(
82
82
  {
83
+ attestationScore: ssz.Gwei,
83
84
  executionOptimistic: ssz.Boolean,
85
+ gasLimit: new OptionalType(ssz.UintNum64),
84
86
  timestamp: ssz.UintNum64,
87
+ stateRoot: stringType,
85
88
  target: stringType,
86
- justifiedEpoch: ssz.Epoch,
87
- finalizedEpoch: ssz.Epoch,
88
89
  unrealizedJustifiedEpoch: ssz.Epoch,
90
+ unrealizedJustifiedRoot: stringType,
89
91
  unrealizedFinalizedEpoch: ssz.Epoch,
90
- payloadAttesterCount: new OptionalType(ssz.UintNum64),
91
- payloadAvailabilityYesCount: new OptionalType(ssz.UintNum64),
92
- payloadDataAvailabilityYesCount: new OptionalType(ssz.UintNum64),
93
- gasLimit: new OptionalType(ssz.UintNum64),
92
+ unrealizedFinalizedRoot: stringType,
94
93
  },
95
94
  {jsonCase: "eth2"}
96
95
  );
96
+ const payloadStatusType = new StringType<"pending" | "empty" | "full">();
97
97
  const ForkChoiceNodeV2Type = new ContainerType(
98
98
  {
99
- payloadStatus: new StringType<"pending" | "empty" | "full">(),
100
99
  slot: ssz.Slot,
101
100
  blockRoot: stringType,
101
+ payloadStatus: payloadStatusType,
102
102
  parentRoot: stringType,
103
+ parentPayloadStatus: new OptionalType(payloadStatusType),
104
+ justifiedCheckpoint: ssz.phase0.Checkpoint,
105
+ finalizedCheckpoint: ssz.phase0.Checkpoint,
103
106
  weight: ssz.Gwei,
104
107
  validity: new StringType<"valid" | "invalid" | "optimistic">(),
105
108
  executionBlockHash: stringType,
109
+ payloadAttesterCount: ssz.UintNum64,
110
+ payloadAvailabilityYesCount: ssz.UintNum64,
111
+ payloadDataAvailabilityYesCount: ssz.UintNum64,
106
112
  extraData: ForkChoiceNodeV2ExtraDataType,
107
113
  },
108
114
  {jsonCase: "eth2"}
109
115
  );
110
116
  const ForkChoiceExtraDataType = new ContainerType(
111
117
  {
112
- unrealizedJustifiedCheckpoint: ssz.phase0.Checkpoint,
113
- unrealizedFinalizedCheckpoint: ssz.phase0.Checkpoint,
118
+ head: new ContainerType(
119
+ {
120
+ blockRoot: stringType,
121
+ payloadStatus: payloadStatusType,
122
+ },
123
+ {jsonCase: "eth2"}
124
+ ),
114
125
  proposerBoostRoot: stringType,
115
126
  previousProposerBoostRoot: stringType,
116
- headRoot: stringType,
127
+ unrealizedJustifiedCheckpoint: ssz.phase0.Checkpoint,
128
+ unrealizedFinalizedCheckpoint: ssz.phase0.Checkpoint,
117
129
  },
118
130
  {jsonCase: "eth2"}
119
131
  );
@@ -255,14 +267,6 @@ export function getDefinitions(_config: ChainForkConfig): RouteDefinitions<Endpo
255
267
  data: ForkChoiceResponseV2Type,
256
268
  meta: EmptyMetaCodec,
257
269
  onlySupport: WireFormat.json,
258
- transform: {
259
- toResponse: (data) => ({
260
- ...(data as ForkChoiceResponseV2),
261
- }),
262
- fromResponse: (resp) => ({
263
- data: resp as ForkChoiceResponseV2,
264
- }),
265
- },
266
270
  },
267
271
  },
268
272
  getProtoArrayNodes: {
@@ -69,10 +69,31 @@ const headV2 = new ContainerType(
69
69
  },
70
70
  {typeName: "HeadV2", jsonCase: "eth2"}
71
71
  );
72
+ const phase0Block = new ContainerType(
73
+ {
74
+ slot: ssz.Slot,
75
+ block: stringType,
76
+ executionOptimistic: ssz.Boolean,
77
+ },
78
+ {typeName: "Block", jsonCase: "eth2"}
79
+ );
80
+ const gloasBlock = new ContainerType(
81
+ {
82
+ slot: ssz.Slot,
83
+ block: stringType,
84
+ blockHash: stringType,
85
+ builderIndex: ssz.BuilderIndex,
86
+ executionOptimistic: ssz.Boolean,
87
+ },
88
+ {typeName: "BlockGloas", jsonCase: "eth2"}
89
+ );
72
90
  type FuluDataColumnSidecarSSE = ValueOf<typeof fuluDataColumnSidecarSSE>;
73
91
  type GloasDataColumnSidecarSSE = ValueOf<typeof gloasDataColumnSidecarSSE>;
74
92
  type DataColumnSidecarSSE = FuluDataColumnSidecarSSE | GloasDataColumnSidecarSSE;
75
93
  type HeadV2 = ValueOf<typeof headV2>;
94
+ type Phase0BlockSSE = ValueOf<typeof phase0Block>;
95
+ type GloasBlockSSE = ValueOf<typeof gloasBlock>;
96
+ type BlockSSE = Phase0BlockSSE | GloasBlockSSE;
76
97
 
77
98
  export enum EventType {
78
99
  /**
@@ -182,11 +203,7 @@ export type EventData = {
182
203
  version: ForkName;
183
204
  data: HeadV2;
184
205
  };
185
- [EventType.block]: {
186
- slot: Slot;
187
- block: RootHex;
188
- executionOptimistic: boolean;
189
- };
206
+ [EventType.block]: BlockSSE;
190
207
  [EventType.blockGossip]: {
191
208
  slot: Slot;
192
209
  block: RootHex;
@@ -253,6 +270,8 @@ type EventstreamArgs = {
253
270
  topics: EventType[];
254
271
  signal: AbortSignal;
255
272
  onEvent: (event: BeaconEvent) => void;
273
+ /** Called every time the connection is established, including reconnects */
274
+ onOpen?: () => void;
256
275
  onError?: (err: Error) => void;
257
276
  onClose?: () => void;
258
277
  };
@@ -330,14 +349,22 @@ export function getTypeByEvent(config: ChainForkConfig): {[K in EventType]: Type
330
349
  ),
331
350
  [EventType.headV2]: WithVersion(() => headV2),
332
351
 
333
- [EventType.block]: new ContainerType(
334
- {
335
- slot: ssz.Slot,
336
- block: stringType,
337
- executionOptimistic: ssz.Boolean,
352
+ [EventType.block]: {
353
+ toJson: (data) => {
354
+ const fork = config.getForkName(data.slot);
355
+ if (isForkPostGloas(fork)) {
356
+ return gloasBlock.toJson(data as GloasBlockSSE);
357
+ }
358
+ return phase0Block.toJson(data);
338
359
  },
339
- {jsonCase: "eth2"}
340
- ),
360
+ fromJson: (data) => {
361
+ const fork = config.getForkName(Number((data as BlockSSE).slot));
362
+ if (isForkPostGloas(fork)) {
363
+ return gloasBlock.fromJson(data);
364
+ }
365
+ return phase0Block.fromJson(data);
366
+ },
367
+ },
341
368
  [EventType.blockGossip]: new ContainerType(
342
369
  {
343
370
  slot: ssz.Slot,
package/src/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  // Re-exporting beacon only for backwards compatibility
2
2
  export * from "./beacon/index.js";
3
- export {ApiError} from "./utils/client/error.js";
3
+ export {ApiError, type ApiFailure} from "./utils/client/error.js";
4
4
  export type {
5
5
  ApiClientMethods,
6
6
  HttpClientModules,
@@ -1,10 +1,16 @@
1
+ /** Failure of a single item of a batch request, `index` refers to the submitted array */
2
+ export type ApiFailure = {index: number; message: string};
3
+
1
4
  export class ApiError extends Error {
2
5
  status: number;
3
6
  operationId: string;
7
+ /** Set if the server rejected only some items of a batch request */
8
+ failures?: ApiFailure[];
4
9
 
5
- constructor(message: string, status: number, operationId: string) {
10
+ constructor(message: string, status: number, operationId: string, failures?: ApiFailure[]) {
6
11
  super(`${operationId} failed with status ${status}: ${message}`);
7
12
  this.status = status;
8
13
  this.operationId = operationId;
14
+ this.failures = failures;
9
15
  }
10
16
  }
@@ -2,7 +2,7 @@ import {HeadersExtra, HttpHeader, parseContentTypeHeader} from "../headers.js";
2
2
  import {HttpStatusCode} from "../httpStatusCode.js";
3
3
  import {Endpoint} from "../types.js";
4
4
  import {WireFormat, getWireFormat} from "../wireFormat.js";
5
- import {ApiError} from "./error.js";
5
+ import {ApiError, ApiFailure} from "./error.js";
6
6
  import {RouteDefinitionExtra} from "./request.js";
7
7
 
8
8
  export type RawBody =
@@ -162,7 +162,8 @@ export class ApiResponse<E extends Endpoint> extends Response {
162
162
  return null;
163
163
  }
164
164
 
165
- return new ApiError(this.getErrorMessage(), this.status, this.definition.operationId);
165
+ const {message, failures} = this.parseErrorBody();
166
+ return new ApiError(message, this.status, this.definition.operationId, failures);
166
167
  }
167
168
 
168
169
  async errorBody(): Promise<string> {
@@ -187,19 +188,22 @@ export class ApiResponse<E extends Endpoint> extends Response {
187
188
  return this._errorBody;
188
189
  }
189
190
 
190
- private getErrorMessage(): string {
191
+ private parseErrorBody(): {message: string; failures?: ApiFailure[]} {
191
192
  const errBody = this.resolvedErrorBody();
192
193
  try {
193
- const errJson = JSON.parse(errBody) as {message?: string; failures?: {message: string}[]};
194
+ const errJson = JSON.parse(errBody) as {message?: string; failures?: ApiFailure[]};
194
195
  if (errJson.message) {
195
- if (errJson.failures) {
196
- return `${errJson.message}\n` + errJson.failures.map((e) => e.message).join("\n");
196
+ if (Array.isArray(errJson.failures)) {
197
+ return {
198
+ message: `${errJson.message}\n` + errJson.failures.map((e) => e.message).join("\n"),
199
+ failures: errJson.failures,
200
+ };
197
201
  }
198
- return errJson.message;
202
+ return {message: errJson.message};
199
203
  }
200
- return errBody;
204
+ return {message: errBody};
201
205
  } catch (_e) {
202
- return errBody || this.statusText;
206
+ return {message: errBody || this.statusText};
203
207
  }
204
208
  }
205
209
  }
package/src/utils/fork.ts CHANGED
@@ -3,10 +3,12 @@ import {
3
3
  ForkPostAltair,
4
4
  ForkPostBellatrix,
5
5
  ForkPostDeneb,
6
+ ForkPostElectra,
6
7
  ForkPostGloas,
7
8
  isForkPostAltair,
8
9
  isForkPostBellatrix,
9
10
  isForkPostDeneb,
11
+ isForkPostElectra,
10
12
  isForkPostGloas,
11
13
  } from "@lodestar/params";
12
14
  import {SSZTypesFor, sszTypesFor} from "@lodestar/types";
@@ -45,6 +47,14 @@ export function getPostDenebForkTypes(fork: ForkName): SSZTypesFor<ForkPostDeneb
45
47
  return sszTypesFor(fork);
46
48
  }
47
49
 
50
+ export function getPostElectraForkTypes(fork: ForkName): SSZTypesFor<ForkPostElectra> {
51
+ if (!isForkPostElectra(fork)) {
52
+ throw Error(`Invalid fork=${fork} for post-electra fork types`);
53
+ }
54
+
55
+ return sszTypesFor(fork);
56
+ }
57
+
48
58
  export function getPostGloasForkTypes(fork: ForkName): SSZTypesFor<ForkPostGloas> {
49
59
  if (!isForkPostGloas(fork)) {
50
60
  throw Error(`Invalid fork=${fork} for post-gloas fork types`);