@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,7 @@
|
|
|
1
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
+
import {ApplicationMethods, FastifyRoutes, createFastifyRoutes} from "../../utils/server/index.js";
|
|
3
|
+
import {Endpoints, getDefinitions} from "../routes/beacon/index.js";
|
|
4
|
+
|
|
5
|
+
export function getRoutes(config: ChainForkConfig, methods: ApplicationMethods<Endpoints>): FastifyRoutes<Endpoints> {
|
|
6
|
+
return createFastifyRoutes(getDefinitions(config), methods);
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
+
import {ApplicationMethods, FastifyRoutes, createFastifyRoutes} from "../../utils/server/index.js";
|
|
3
|
+
import {Endpoints, getDefinitions} from "../routes/config.js";
|
|
4
|
+
|
|
5
|
+
export function getRoutes(config: ChainForkConfig, methods: ApplicationMethods<Endpoints>): FastifyRoutes<Endpoints> {
|
|
6
|
+
return createFastifyRoutes(getDefinitions(config), methods);
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
+
import {ApplicationMethods, FastifyRoutes, createFastifyRoutes} from "../../utils/server/index.js";
|
|
3
|
+
import {Endpoints, getDefinitions} from "../routes/debug.js";
|
|
4
|
+
|
|
5
|
+
export function getRoutes(config: ChainForkConfig, methods: ApplicationMethods<Endpoints>): FastifyRoutes<Endpoints> {
|
|
6
|
+
return createFastifyRoutes(getDefinitions(config), methods);
|
|
7
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
+
import {ApiError, ApplicationMethods, FastifyRoutes, createFastifyRoutes} from "../../utils/server/index.js";
|
|
3
|
+
import {Endpoints, eventTypes, getDefinitions, getEventSerdes} from "../routes/events.js";
|
|
4
|
+
|
|
5
|
+
export function getRoutes(config: ChainForkConfig, methods: ApplicationMethods<Endpoints>): FastifyRoutes<Endpoints> {
|
|
6
|
+
const eventSerdes = getEventSerdes(config);
|
|
7
|
+
const serverRoutes = createFastifyRoutes(getDefinitions(config), methods);
|
|
8
|
+
|
|
9
|
+
return {
|
|
10
|
+
// Non-JSON route. Server Sent Events (SSE)
|
|
11
|
+
eventstream: {
|
|
12
|
+
...serverRoutes.eventstream,
|
|
13
|
+
handler: async (req, res) => {
|
|
14
|
+
const validTopics = new Set(Object.values(eventTypes));
|
|
15
|
+
for (const topic of req.query.topics) {
|
|
16
|
+
if (!validTopics.has(topic)) {
|
|
17
|
+
throw new ApiError(400, `Invalid topic: ${topic}`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const controller = new AbortController();
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
// Add injected headers from other plugins. This is required for fastify-cors for example
|
|
25
|
+
// From: https://github.com/NodeFactoryIo/fastify-sse-v2/blob/b1686a979fbf655fb9936c0560294a0c094734d4/src/plugin.ts
|
|
26
|
+
for (const [key, value] of Object.entries(res.getHeaders())) {
|
|
27
|
+
if (value !== undefined) res.raw.setHeader(key, value);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
res.raw.setHeader("Content-Type", "text/event-stream");
|
|
31
|
+
res.raw.setHeader("Cache-Control", "no-cache,no-transform");
|
|
32
|
+
res.raw.setHeader("Connection", "keep-alive");
|
|
33
|
+
// It was reported that chrome and firefox do not play well with compressed event-streams https://github.com/lolo32/fastify-sse/issues/2
|
|
34
|
+
res.raw.setHeader("x-no-compression", 1);
|
|
35
|
+
// In case this beacon node is behind a NGINX, instruct it to disable buffering which can disrupt SSE by
|
|
36
|
+
// infinitely buffering it. http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering
|
|
37
|
+
// Source: https://stackoverflow.com/questions/13672743/eventsource-server-sent-events-through-nginx
|
|
38
|
+
res.raw.setHeader("X-Accel-Buffering", "no");
|
|
39
|
+
|
|
40
|
+
await new Promise<void>((resolve, reject) => {
|
|
41
|
+
void methods.eventstream({
|
|
42
|
+
topics: req.query.topics,
|
|
43
|
+
signal: controller.signal,
|
|
44
|
+
onEvent: (event) => {
|
|
45
|
+
try {
|
|
46
|
+
const data = eventSerdes.toJson(event);
|
|
47
|
+
res.raw.write(serializeSSEEvent({event: event.type, data}));
|
|
48
|
+
} catch (e) {
|
|
49
|
+
reject(e);
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// The stream will never end by the server unless the node is stopped.
|
|
55
|
+
// In that case the BeaconNode class will call server.close() and end this connection.
|
|
56
|
+
|
|
57
|
+
// The client may disconnect and we need to clean the subscriptions.
|
|
58
|
+
req.socket.once("close", () => resolve());
|
|
59
|
+
req.socket.once("end", () => resolve());
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// api.eventstream will never stop, so no need to ever call `res.raw.end();`
|
|
63
|
+
} finally {
|
|
64
|
+
controller.abort();
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function serializeSSEEvent(chunk: {event: string; data: unknown}): string {
|
|
72
|
+
return [`event: ${chunk.event}`, `data: ${JSON.stringify(chunk.data)}`, "\n"].join("\n");
|
|
73
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type {FastifyInstance} from "fastify";
|
|
2
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
3
|
+
import {ApplicationMethods, FastifyRoute} from "../../utils/server/index.js";
|
|
4
|
+
import {Endpoints} from "../routes/index.js";
|
|
5
|
+
import * as beacon from "./beacon.js";
|
|
6
|
+
import * as configApi from "./config.js";
|
|
7
|
+
import * as debug from "./debug.js";
|
|
8
|
+
import * as events from "./events.js";
|
|
9
|
+
import * as lightclient from "./lightclient.js";
|
|
10
|
+
import * as lodestar from "./lodestar.js";
|
|
11
|
+
import * as node from "./node.js";
|
|
12
|
+
import * as proof from "./proof.js";
|
|
13
|
+
import * as validator from "./validator.js";
|
|
14
|
+
|
|
15
|
+
export type BeaconApiMethods = {[K in keyof Endpoints]: ApplicationMethods<Endpoints[K]>};
|
|
16
|
+
|
|
17
|
+
export function registerRoutes(
|
|
18
|
+
server: FastifyInstance,
|
|
19
|
+
config: ChainForkConfig,
|
|
20
|
+
methods: BeaconApiMethods,
|
|
21
|
+
enabledNamespaces: (keyof Endpoints)[]
|
|
22
|
+
): void {
|
|
23
|
+
const routesByNamespace: {
|
|
24
|
+
// Enforces that we are declaring routes for every routeId in `Endpoints`
|
|
25
|
+
[K in keyof Endpoints]: () => {
|
|
26
|
+
// The Endpoints are enforced in each getRoutes return type
|
|
27
|
+
// biome-ignore lint/suspicious/noExplicitAny: We need to use `any` type here
|
|
28
|
+
[K2 in keyof Endpoints[K]]: FastifyRoute<any>;
|
|
29
|
+
};
|
|
30
|
+
} = {
|
|
31
|
+
// Initializes route types and their definitions
|
|
32
|
+
beacon: () => beacon.getRoutes(config, methods.beacon),
|
|
33
|
+
config: () => configApi.getRoutes(config, methods.config),
|
|
34
|
+
debug: () => debug.getRoutes(config, methods.debug),
|
|
35
|
+
events: () => events.getRoutes(config, methods.events),
|
|
36
|
+
lightclient: () => lightclient.getRoutes(config, methods.lightclient),
|
|
37
|
+
lodestar: () => lodestar.getRoutes(config, methods.lodestar),
|
|
38
|
+
node: () => node.getRoutes(config, methods.node),
|
|
39
|
+
proof: () => proof.getRoutes(config, methods.proof),
|
|
40
|
+
validator: () => validator.getRoutes(config, methods.validator),
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
for (const namespace of enabledNamespaces) {
|
|
44
|
+
const routes = routesByNamespace[namespace];
|
|
45
|
+
if (routes === undefined) {
|
|
46
|
+
throw Error(`Unknown api namespace ${namespace}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
for (const route of Object.values(routes())) {
|
|
50
|
+
// Append the namespace as a tag for downstream consumption
|
|
51
|
+
route.schema.tags = [namespace];
|
|
52
|
+
server.route(route);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
+
import {ApplicationMethods, FastifyRoutes, createFastifyRoutes} from "../../utils/server/index.js";
|
|
3
|
+
import {Endpoints, getDefinitions} from "../routes/lightclient.js";
|
|
4
|
+
|
|
5
|
+
export function getRoutes(config: ChainForkConfig, methods: ApplicationMethods<Endpoints>): FastifyRoutes<Endpoints> {
|
|
6
|
+
return createFastifyRoutes(getDefinitions(config), methods);
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
+
import {ApplicationMethods, FastifyRoutes, createFastifyRoutes} from "../../utils/server/index.js";
|
|
3
|
+
import {Endpoints, getDefinitions} from "../routes/lodestar.js";
|
|
4
|
+
|
|
5
|
+
export function getRoutes(config: ChainForkConfig, methods: ApplicationMethods<Endpoints>): FastifyRoutes<Endpoints> {
|
|
6
|
+
return createFastifyRoutes(getDefinitions(config), methods);
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
+
import {ApplicationMethods, FastifyRoutes, createFastifyRoutes} from "../../utils/server/index.js";
|
|
3
|
+
import {Endpoints, getDefinitions} from "../routes/node.js";
|
|
4
|
+
|
|
5
|
+
export function getRoutes(config: ChainForkConfig, methods: ApplicationMethods<Endpoints>): FastifyRoutes<Endpoints> {
|
|
6
|
+
return createFastifyRoutes(getDefinitions(config), methods);
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
+
import {ApplicationMethods, FastifyRoutes, createFastifyRoutes} from "../../utils/server/index.js";
|
|
3
|
+
import {Endpoints, getDefinitions} from "../routes/proof.js";
|
|
4
|
+
|
|
5
|
+
export function getRoutes(config: ChainForkConfig, methods: ApplicationMethods<Endpoints>): FastifyRoutes<Endpoints> {
|
|
6
|
+
return createFastifyRoutes(getDefinitions(config), methods);
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
+
import {ApplicationMethods, FastifyRoutes, createFastifyRoutes} from "../../utils/server/index.js";
|
|
3
|
+
import {Endpoints, getDefinitions} from "../routes/validator.js";
|
|
4
|
+
|
|
5
|
+
export function getRoutes(config: ChainForkConfig, methods: ApplicationMethods<Endpoints>): FastifyRoutes<Endpoints> {
|
|
6
|
+
return createFastifyRoutes(getDefinitions(config), methods);
|
|
7
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
+
import {ApiClientMethods, IHttpClient, createApiClientMethods} from "../utils/client/index.js";
|
|
3
|
+
import {Endpoints, getDefinitions} from "./routes.js";
|
|
4
|
+
|
|
5
|
+
export type ApiClient = ApiClientMethods<Endpoints>;
|
|
6
|
+
|
|
7
|
+
export function getClient(config: ChainForkConfig, httpClient: IHttpClient): ApiClient {
|
|
8
|
+
return createApiClientMethods(getDefinitions(config), httpClient);
|
|
9
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
+
import {HttpClient, HttpClientModules, HttpClientOptions, IHttpClient} from "../utils/client/httpClient.js";
|
|
3
|
+
import type {ApiClient} from "./client.js";
|
|
4
|
+
import * as builder from "./client.js";
|
|
5
|
+
import {Endpoints} from "./routes.js";
|
|
6
|
+
|
|
7
|
+
// NOTE: Don't export server here so it's not bundled to all consumers
|
|
8
|
+
|
|
9
|
+
export type {ApiClient, Endpoints};
|
|
10
|
+
|
|
11
|
+
// Note: builder API does not have namespaces as routes are declared at the "root" namespace
|
|
12
|
+
|
|
13
|
+
type ClientModules = HttpClientModules & {
|
|
14
|
+
config: ChainForkConfig;
|
|
15
|
+
httpClient?: IHttpClient;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* REST HTTP client for builder routes
|
|
20
|
+
*/
|
|
21
|
+
export function getClient(opts: HttpClientOptions, modules: ClientModules): ApiClient {
|
|
22
|
+
const {config} = modules;
|
|
23
|
+
const httpClient = modules.httpClient ?? new HttpClient(opts, modules);
|
|
24
|
+
|
|
25
|
+
return builder.getClient(config, httpClient);
|
|
26
|
+
}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
+
import {ForkName, VALIDATOR_REGISTRY_LIMIT, isForkPostDeneb} from "@lodestar/params";
|
|
3
|
+
import {
|
|
4
|
+
BLSPubkey,
|
|
5
|
+
ExecutionPayload,
|
|
6
|
+
ExecutionPayloadAndBlobsBundle,
|
|
7
|
+
Root,
|
|
8
|
+
SignedBlindedBeaconBlock,
|
|
9
|
+
SignedBuilderBid,
|
|
10
|
+
Slot,
|
|
11
|
+
WithOptionalBytes,
|
|
12
|
+
bellatrix,
|
|
13
|
+
ssz,
|
|
14
|
+
} from "@lodestar/types";
|
|
15
|
+
import {fromHex, toPubkeyHex, toRootHex} from "@lodestar/utils";
|
|
16
|
+
import {
|
|
17
|
+
ArrayOf,
|
|
18
|
+
EmptyArgs,
|
|
19
|
+
EmptyMeta,
|
|
20
|
+
EmptyRequest,
|
|
21
|
+
EmptyRequestCodec,
|
|
22
|
+
EmptyResponseCodec,
|
|
23
|
+
EmptyResponseData,
|
|
24
|
+
WithVersion,
|
|
25
|
+
} from "../utils/codecs.js";
|
|
26
|
+
import {getPostBellatrixForkTypes, getPostDenebForkTypes, toForkName} from "../utils/fork.js";
|
|
27
|
+
import {fromHeaders} from "../utils/headers.js";
|
|
28
|
+
import {Endpoint, RouteDefinitions, Schema} from "../utils/index.js";
|
|
29
|
+
import {MetaHeader, VersionCodec, VersionMeta} from "../utils/metadata.js";
|
|
30
|
+
import {WireFormat} from "../utils/wireFormat.js";
|
|
31
|
+
|
|
32
|
+
// Mev-boost might not return any data if there are no bids from builders or min-bid threshold was not reached.
|
|
33
|
+
// In this case, we receive a success response (204) which is not handled as an error. The generic response
|
|
34
|
+
// handler already checks the status code and will not attempt to parse the body, but it will return no value.
|
|
35
|
+
// It is important that this type indicates that there might be no value to ensure it is properly handled downstream.
|
|
36
|
+
export type MaybeSignedBuilderBid = SignedBuilderBid | undefined;
|
|
37
|
+
|
|
38
|
+
const RegistrationsType = ArrayOf(ssz.bellatrix.SignedValidatorRegistrationV1, VALIDATOR_REGISTRY_LIMIT);
|
|
39
|
+
|
|
40
|
+
export type Endpoints = {
|
|
41
|
+
status: Endpoint<
|
|
42
|
+
// ⏎
|
|
43
|
+
"GET",
|
|
44
|
+
EmptyArgs,
|
|
45
|
+
EmptyRequest,
|
|
46
|
+
EmptyResponseData,
|
|
47
|
+
EmptyMeta
|
|
48
|
+
>;
|
|
49
|
+
|
|
50
|
+
registerValidator: Endpoint<
|
|
51
|
+
"POST",
|
|
52
|
+
{registrations: bellatrix.SignedValidatorRegistrationV1[]},
|
|
53
|
+
{body: unknown},
|
|
54
|
+
EmptyResponseData,
|
|
55
|
+
EmptyMeta
|
|
56
|
+
>;
|
|
57
|
+
|
|
58
|
+
getHeader: Endpoint<
|
|
59
|
+
"GET",
|
|
60
|
+
{
|
|
61
|
+
slot: Slot;
|
|
62
|
+
parentHash: Root;
|
|
63
|
+
proposerPubkey: BLSPubkey;
|
|
64
|
+
},
|
|
65
|
+
{params: {slot: Slot; parent_hash: string; pubkey: string}},
|
|
66
|
+
MaybeSignedBuilderBid,
|
|
67
|
+
VersionMeta
|
|
68
|
+
>;
|
|
69
|
+
|
|
70
|
+
submitBlindedBlock: Endpoint<
|
|
71
|
+
"POST",
|
|
72
|
+
{signedBlindedBlock: WithOptionalBytes<SignedBlindedBeaconBlock>},
|
|
73
|
+
{body: unknown; headers: {[MetaHeader.Version]: string}},
|
|
74
|
+
ExecutionPayload | ExecutionPayloadAndBlobsBundle,
|
|
75
|
+
VersionMeta
|
|
76
|
+
>;
|
|
77
|
+
|
|
78
|
+
submitBlindedBlockV2: Endpoint<
|
|
79
|
+
"POST",
|
|
80
|
+
{signedBlindedBlock: WithOptionalBytes<SignedBlindedBeaconBlock>},
|
|
81
|
+
{body: unknown; headers: {[MetaHeader.Version]: string}},
|
|
82
|
+
EmptyResponseData,
|
|
83
|
+
EmptyMeta
|
|
84
|
+
>;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoints> {
|
|
88
|
+
return {
|
|
89
|
+
status: {
|
|
90
|
+
url: "/eth/v1/builder/status",
|
|
91
|
+
method: "GET",
|
|
92
|
+
req: EmptyRequestCodec,
|
|
93
|
+
resp: EmptyResponseCodec,
|
|
94
|
+
},
|
|
95
|
+
registerValidator: {
|
|
96
|
+
url: "/eth/v1/builder/validators",
|
|
97
|
+
method: "POST",
|
|
98
|
+
req: {
|
|
99
|
+
writeReqJson: ({registrations}) => ({body: RegistrationsType.toJson(registrations)}),
|
|
100
|
+
parseReqJson: ({body}) => ({registrations: RegistrationsType.fromJson(body)}),
|
|
101
|
+
writeReqSsz: ({registrations}) => ({body: RegistrationsType.serialize(registrations)}),
|
|
102
|
+
parseReqSsz: ({body}) => ({registrations: RegistrationsType.deserialize(body)}),
|
|
103
|
+
schema: {body: Schema.ObjectArray},
|
|
104
|
+
},
|
|
105
|
+
resp: EmptyResponseCodec,
|
|
106
|
+
init: {
|
|
107
|
+
requestWireFormat: WireFormat.ssz,
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
getHeader: {
|
|
111
|
+
url: "/eth/v1/builder/header/{slot}/{parent_hash}/{pubkey}",
|
|
112
|
+
method: "GET",
|
|
113
|
+
req: {
|
|
114
|
+
writeReq: ({slot, parentHash, proposerPubkey: proposerPubKey}) => ({
|
|
115
|
+
params: {slot, parent_hash: toRootHex(parentHash), pubkey: toPubkeyHex(proposerPubKey)},
|
|
116
|
+
}),
|
|
117
|
+
parseReq: ({params}) => ({
|
|
118
|
+
slot: params.slot,
|
|
119
|
+
parentHash: fromHex(params.parent_hash),
|
|
120
|
+
proposerPubkey: fromHex(params.pubkey),
|
|
121
|
+
}),
|
|
122
|
+
schema: {
|
|
123
|
+
params: {slot: Schema.UintRequired, parent_hash: Schema.StringRequired, pubkey: Schema.StringRequired},
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
resp: {
|
|
127
|
+
data: WithVersion<MaybeSignedBuilderBid, VersionMeta>(
|
|
128
|
+
(fork: ForkName) => getPostBellatrixForkTypes(fork).SignedBuilderBid
|
|
129
|
+
),
|
|
130
|
+
meta: VersionCodec,
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
submitBlindedBlock: {
|
|
134
|
+
url: "/eth/v1/builder/blinded_blocks",
|
|
135
|
+
method: "POST",
|
|
136
|
+
req: {
|
|
137
|
+
writeReqJson: ({signedBlindedBlock}) => {
|
|
138
|
+
const fork = config.getForkName(signedBlindedBlock.data.message.slot);
|
|
139
|
+
return {
|
|
140
|
+
body: getPostBellatrixForkTypes(fork).SignedBlindedBeaconBlock.toJson(signedBlindedBlock.data),
|
|
141
|
+
headers: {
|
|
142
|
+
[MetaHeader.Version]: fork,
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
},
|
|
146
|
+
parseReqJson: ({body, headers}) => {
|
|
147
|
+
const fork = toForkName(fromHeaders(headers, MetaHeader.Version));
|
|
148
|
+
return {
|
|
149
|
+
signedBlindedBlock: {data: getPostBellatrixForkTypes(fork).SignedBlindedBeaconBlock.fromJson(body)},
|
|
150
|
+
};
|
|
151
|
+
},
|
|
152
|
+
writeReqSsz: ({signedBlindedBlock}) => {
|
|
153
|
+
const fork = config.getForkName(signedBlindedBlock.data.message.slot);
|
|
154
|
+
return {
|
|
155
|
+
body:
|
|
156
|
+
signedBlindedBlock.bytes ??
|
|
157
|
+
getPostBellatrixForkTypes(fork).SignedBlindedBeaconBlock.serialize(signedBlindedBlock.data),
|
|
158
|
+
headers: {
|
|
159
|
+
[MetaHeader.Version]: fork,
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
},
|
|
163
|
+
parseReqSsz: ({body, headers}) => {
|
|
164
|
+
const fork = toForkName(fromHeaders(headers, MetaHeader.Version));
|
|
165
|
+
return {
|
|
166
|
+
signedBlindedBlock: {data: getPostBellatrixForkTypes(fork).SignedBlindedBeaconBlock.deserialize(body)},
|
|
167
|
+
};
|
|
168
|
+
},
|
|
169
|
+
schema: {
|
|
170
|
+
body: Schema.Object,
|
|
171
|
+
headers: {[MetaHeader.Version]: Schema.String},
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
resp: {
|
|
175
|
+
data: WithVersion<ExecutionPayload | ExecutionPayloadAndBlobsBundle, VersionMeta>((fork: ForkName) => {
|
|
176
|
+
return isForkPostDeneb(fork)
|
|
177
|
+
? getPostDenebForkTypes(fork).ExecutionPayloadAndBlobsBundle
|
|
178
|
+
: getPostBellatrixForkTypes(fork).ExecutionPayload;
|
|
179
|
+
}),
|
|
180
|
+
meta: VersionCodec,
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
submitBlindedBlockV2: {
|
|
184
|
+
url: "/eth/v2/builder/blinded_blocks",
|
|
185
|
+
method: "POST",
|
|
186
|
+
req: {
|
|
187
|
+
writeReqJson: ({signedBlindedBlock}) => {
|
|
188
|
+
const fork = config.getForkName(signedBlindedBlock.data.message.slot);
|
|
189
|
+
return {
|
|
190
|
+
body: getPostBellatrixForkTypes(fork).SignedBlindedBeaconBlock.toJson(signedBlindedBlock.data),
|
|
191
|
+
headers: {
|
|
192
|
+
[MetaHeader.Version]: fork,
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
},
|
|
196
|
+
parseReqJson: ({body, headers}) => {
|
|
197
|
+
const fork = toForkName(fromHeaders(headers, MetaHeader.Version));
|
|
198
|
+
return {
|
|
199
|
+
signedBlindedBlock: {data: getPostBellatrixForkTypes(fork).SignedBlindedBeaconBlock.fromJson(body)},
|
|
200
|
+
};
|
|
201
|
+
},
|
|
202
|
+
writeReqSsz: ({signedBlindedBlock}) => {
|
|
203
|
+
const fork = config.getForkName(signedBlindedBlock.data.message.slot);
|
|
204
|
+
return {
|
|
205
|
+
body:
|
|
206
|
+
signedBlindedBlock.bytes ??
|
|
207
|
+
getPostBellatrixForkTypes(fork).SignedBlindedBeaconBlock.serialize(signedBlindedBlock.data),
|
|
208
|
+
headers: {
|
|
209
|
+
[MetaHeader.Version]: fork,
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
},
|
|
213
|
+
parseReqSsz: ({body, headers}) => {
|
|
214
|
+
const fork = toForkName(fromHeaders(headers, MetaHeader.Version));
|
|
215
|
+
return {
|
|
216
|
+
signedBlindedBlock: {data: getPostBellatrixForkTypes(fork).SignedBlindedBeaconBlock.deserialize(body)},
|
|
217
|
+
};
|
|
218
|
+
},
|
|
219
|
+
schema: {
|
|
220
|
+
body: Schema.Object,
|
|
221
|
+
headers: {[MetaHeader.Version]: Schema.String},
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
resp: EmptyResponseCodec,
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type {FastifyInstance} from "fastify";
|
|
2
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
3
|
+
import {AnyEndpoint} from "../../utils/codecs.js";
|
|
4
|
+
import {ApplicationMethods, FastifyRoute, FastifyRoutes, createFastifyRoutes} from "../../utils/server/index.js";
|
|
5
|
+
import {Endpoints, getDefinitions} from "../routes.js";
|
|
6
|
+
|
|
7
|
+
export type BuilderApiMethods = ApplicationMethods<Endpoints>;
|
|
8
|
+
|
|
9
|
+
export function getRoutes(config: ChainForkConfig, methods: BuilderApiMethods): FastifyRoutes<Endpoints> {
|
|
10
|
+
return createFastifyRoutes(getDefinitions(config), methods);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function registerRoutes(server: FastifyInstance, config: ChainForkConfig, methods: BuilderApiMethods): void {
|
|
14
|
+
const routes = getRoutes(config, methods);
|
|
15
|
+
|
|
16
|
+
for (const route of Object.values(routes)) {
|
|
17
|
+
server.route(route as FastifyRoute<AnyEndpoint>);
|
|
18
|
+
}
|
|
19
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Re-exporting beacon only for backwards compatibility
|
|
2
|
+
export * from "./beacon/index.js";
|
|
3
|
+
export {ApiError} from "./utils/client/error.js";
|
|
4
|
+
export type {
|
|
5
|
+
ApiClientMethods,
|
|
6
|
+
HttpClientModules,
|
|
7
|
+
HttpClientOptions,
|
|
8
|
+
IHttpClient,
|
|
9
|
+
Metrics,
|
|
10
|
+
} from "./utils/client/index.js";
|
|
11
|
+
export {ApiResponse, HttpClient, defaultInit} from "./utils/client/index.js";
|
|
12
|
+
export type {ApiRequestInit} from "./utils/client/request.js";
|
|
13
|
+
export {HttpHeader, MediaType} from "./utils/headers.js";
|
|
14
|
+
export type {HttpErrorCodes, HttpSuccessCodes} from "./utils/httpStatusCode.js";
|
|
15
|
+
export {HttpStatusCode} from "./utils/httpStatusCode.js";
|
|
16
|
+
export type {Endpoint} from "./utils/types.js";
|
|
17
|
+
export {WireFormat} from "./utils/wireFormat.js";
|
|
18
|
+
|
|
19
|
+
// NOTE: Don't export server here so it's not bundled to all consumers
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
+
import {ApiClientMethods, IHttpClient, createApiClientMethods} from "../utils/client/index.js";
|
|
3
|
+
import {Endpoints, getDefinitions} from "./routes.js";
|
|
4
|
+
|
|
5
|
+
export type ApiClient = ApiClientMethods<Endpoints>;
|
|
6
|
+
|
|
7
|
+
export function getClient(config: ChainForkConfig, httpClient: IHttpClient): ApiClient {
|
|
8
|
+
return createApiClientMethods(getDefinitions(config), httpClient);
|
|
9
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
+
import {HttpClient, HttpClientModules, HttpClientOptions, IHttpClient} from "../utils/client/index.js";
|
|
3
|
+
import type {ApiClient} from "./client.js";
|
|
4
|
+
import * as keymanager from "./client.js";
|
|
5
|
+
|
|
6
|
+
// NOTE: Don't export server here so it's not bundled to all consumers
|
|
7
|
+
|
|
8
|
+
export type {
|
|
9
|
+
BuilderBoostFactorData,
|
|
10
|
+
Endpoints,
|
|
11
|
+
FeeRecipientData,
|
|
12
|
+
GasLimitData,
|
|
13
|
+
GraffitiData,
|
|
14
|
+
KeystoreStr,
|
|
15
|
+
ProposerConfigResponse,
|
|
16
|
+
PubkeyHex,
|
|
17
|
+
RemoteSignerDefinition,
|
|
18
|
+
ResponseStatus,
|
|
19
|
+
SignerDefinition,
|
|
20
|
+
SlashingProtectionData,
|
|
21
|
+
} from "./routes.js";
|
|
22
|
+
export {DeleteRemoteKeyStatus, DeletionStatus, ImportRemoteKeyStatus, ImportStatus} from "./routes.js";
|
|
23
|
+
|
|
24
|
+
export type {ApiClient};
|
|
25
|
+
|
|
26
|
+
type ClientModules = HttpClientModules & {
|
|
27
|
+
config: ChainForkConfig;
|
|
28
|
+
httpClient?: IHttpClient;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* REST HTTP client for keymanager routes
|
|
33
|
+
*/
|
|
34
|
+
export function getClient(opts: HttpClientOptions, modules: ClientModules): ApiClient {
|
|
35
|
+
const {config} = modules;
|
|
36
|
+
const httpClient = modules.httpClient ?? new HttpClient(opts, modules);
|
|
37
|
+
|
|
38
|
+
return keymanager.getClient(config, httpClient);
|
|
39
|
+
}
|