Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
407787e
wip
wemeetagain Oct 11, 2023
9ecdfc3
wip
wemeetagain Oct 25, 2023
43863f8
more polish
wemeetagain Oct 26, 2023
ad72035
more polish
wemeetagain Oct 26, 2023
ca1ea73
add more endpoints
wemeetagain Oct 26, 2023
20399a1
Add createApiRequest and ApiResponse
wemeetagain Oct 28, 2023
c1ffa65
Add createApiClientMethod
wemeetagain Oct 28, 2023
4c27428
Simplify
wemeetagain Oct 28, 2023
c490944
add timeout
wemeetagain Oct 28, 2023
485f73c
Add request with timeout
wemeetagain Oct 29, 2023
e3aa732
Move api response success log
wemeetagain Oct 29, 2023
99bde49
Add optional extra response transform
wemeetagain Oct 29, 2023
918e0e7
Update new metadata header names to follow spec convention
nflaig Oct 29, 2023
020666a
More robust content-type header parsing
nflaig Oct 29, 2023
eed6ccb
Return null as error if res is ok
nflaig Oct 29, 2023
1cdcd4e
Support query params in post requests
nflaig Oct 30, 2023
83b6fd8
Rename path / query params type
nflaig Oct 30, 2023
1314878
Clean up getHealth example
nflaig Oct 30, 2023
212666f
Apply feedback
wemeetagain Oct 30, 2023
6f66e29
Add createApiClientMethods
wemeetagain Oct 30, 2023
6a40e14
Start server impl
wemeetagain Oct 30, 2023
863d536
Add status code
wemeetagain Oct 30, 2023
3536dc6
Add route creation
wemeetagain Oct 30, 2023
2a078cb
Support ssz or value application responses
wemeetagain Oct 30, 2023
4b7c051
Simplify meta toHeaders
wemeetagain Oct 30, 2023
aeabcd6
Clean up server status code
wemeetagain Oct 30, 2023
a0d5af7
Add refactored HttpClient
wemeetagain Nov 2, 2023
677660b
Consistently rename params to args
nflaig Nov 2, 2023
a9a1f2c
Update getHealth example, no nested objects
nflaig Nov 2, 2023
51b6656
Add headers to request
nflaig Nov 2, 2023
70daf28
Decouple header parsing from wire format, 415 error handling
nflaig Nov 2, 2023
92797bf
Rename supported media types const
nflaig Nov 2, 2023
4b7e26b
Update 415 error handling
nflaig Nov 2, 2023
0ddc43c
Uppercase header names in error messages
nflaig Nov 2, 2023
c47dfdc
Move functions around, delete old types and utilities
wemeetagain Nov 3, 2023
83cec8a
Remove more
wemeetagain Nov 3, 2023
f3b3f94
Refactor beacon block route definitions
wemeetagain Nov 3, 2023
00b215c
Simplify ApiResponse types
wemeetagain Nov 4, 2023
e99ed79
Add sszTest example
wemeetagain Nov 4, 2023
b47369b
Add beacon pool route definitions
wemeetagain Nov 4, 2023
f372000
Add beacon state route definitions
wemeetagain Nov 4, 2023
db81879
Add remaining beacon route definitions
wemeetagain Nov 4, 2023
0f03542
Add config route definitions
wemeetagain Nov 4, 2023
2d80b97
Add debug route definitions
wemeetagain Nov 5, 2023
5e5feda
Add events route description
wemeetagain Nov 5, 2023
3ecf5fb
Add lightclient route definitions
wemeetagain Nov 7, 2023
ec2d09b
Merge branch 'unstable' into cayman/ssz-api
nflaig Nov 9, 2023
94379d7
Flatten function params
nflaig Nov 9, 2023
44dd312
Type safety for optional params in write / parse req
nflaig Nov 9, 2023
592d396
Method args are optional if only optional props
nflaig Nov 9, 2023
de5249e
Fix genesisValidatorsRoot type issue
nflaig Nov 11, 2023
36e0017
Revert requiring all params in write / parse req
nflaig Nov 11, 2023
698e655
Update http client errors
nflaig Nov 18, 2023
4cf91b3
Add lodestar route definitions
wemeetagain Nov 8, 2023
1b556ff
Add node route definitions
wemeetagain Nov 20, 2023
e1bc382
Add proof route definitions
wemeetagain Nov 20, 2023
d0e82d0
Add builder route definitions
wemeetagain Nov 28, 2023
6c9379a
Add validator route definitions
wemeetagain Dec 1, 2023
f605775
Merge branch 'unstable' into cayman/ssz-api
nflaig Dec 4, 2023
f8713f1
Application method response can be void
nflaig Dec 5, 2023
645d5d5
Generic options can be passed to application methods
nflaig Dec 5, 2023
9f6ada9
Default endpoint request type has body property
nflaig Dec 5, 2023
6e8f24d
Improve types of transform methods
nflaig Dec 5, 2023
9ec57ad
Export server types from index (to be removed)
nflaig Dec 5, 2023
66c5fa3
Update config api impl
nflaig Dec 5, 2023
9656959
Update lightclient api impl
nflaig Dec 5, 2023
2249d80
Update events api impl
nflaig Dec 5, 2023
3a174f4
Update lodestar api impl
nflaig Dec 5, 2023
a9061ec
Update proof api impl
nflaig Dec 5, 2023
4d71245
Update node api impl
nflaig Dec 5, 2023
ca7efde
Update debug api impl
nflaig Dec 5, 2023
df42c15
Update state api impl
nflaig Dec 5, 2023
48efe33
Update pool api impl
nflaig Dec 5, 2023
8efa4b1
Update blocks api impl
nflaig Dec 5, 2023
895586a
Partially update validator api impl
nflaig Dec 5, 2023
6b39a0d
Update beacon routes export
nflaig Dec 5, 2023
e1964ee
Align submitPoolBlsToExecutionChange method args
nflaig Dec 5, 2023
b9c78b5
Filters are always a object
nflaig Dec 5, 2023
13b65fc
Update errors messages
nflaig Dec 5, 2023
25201d4
Merge branch 'unstable' into cayman/ssz-api
nflaig Dec 7, 2023
19c5b80
Add beacon client methods
wemeetagain Dec 8, 2023
bac340e
Merge branch 'unstable' into cayman/ssz-api
nflaig Jan 4, 2024
b5c16da
Add missing routeId label to stream time metric
nflaig Jan 4, 2024
34b624d
Fix json casing in codecs
nflaig Jan 7, 2024
ad9aaa3
Apply remaining changes from #6227
nflaig Jan 7, 2024
c470aa7
Produce block apis only have version meta
nflaig Jan 7, 2024
766a3b8
Add block values meta to all produce block apis
nflaig Jan 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 0 additions & 46 deletions packages/api/src/beacon/client/beacon.ts

This file was deleted.

13 changes: 0 additions & 13 deletions packages/api/src/beacon/client/config.ts

This file was deleted.

60 changes: 0 additions & 60 deletions packages/api/src/beacon/client/debug.ts

This file was deleted.

94 changes: 51 additions & 43 deletions packages/api/src/beacon/client/events.ts
Original file line number Diff line number Diff line change
@@ -1,57 +1,65 @@
import {ChainForkConfig} from "@lodestar/config";
import {Api, BeaconEvent, routesData, getEventSerdes} from "../routes/events.js";
import {stringifyQuery, urlJoin} from "../../utils/client/format.js";
import {BeaconEvent, getEventSerdes, Endpoints, definitions} from "../routes/events.js";
import {getEventSource} from "../../utils/client/eventSource.js";
import {HttpStatusCode} from "../../utils/client/httpStatusCode.js";
import {IHttpClient} from "../../utils/client/httpClient.js";
import {ApiClientMethods} from "../../utils/client/method.js";
import {compileRouteUrlFormater} from "../../utils/urlFormat.js";

/**
* REST HTTP client for events routes
*/
export function getClient(config: ChainForkConfig, baseUrl: string): Api {
export function getClient(config: ChainForkConfig, client: IHttpClient): ApiClientMethods<Endpoints> {
const eventSerdes = getEventSerdes(config);

const urlFormatter = compileRouteUrlFormater(definitions.eventstream.url);
const eventstreamDefinitionExtended = {
...definitions.eventstream,
urlFormatter,
operationId: "eventstream",
};

return {
eventstream: async (topics, signal, onEvent) => {
const query = stringifyQuery({topics});
const url = `${urlJoin(baseUrl, routesData.eventstream.url)}?${query}`;
// eslint-disable-next-line @typescript-eslint/naming-convention
const EventSource = await getEventSource();
const eventSource = new EventSource(url);

try {
await new Promise<void>((resolve, reject) => {
for (const topic of topics) {
eventSource.addEventListener(topic, ((event: MessageEvent) => {
const message = eventSerdes.fromJson(topic, JSON.parse(event.data));
onEvent({type: topic, message} as BeaconEvent);
}) as EventListener);
eventstream: async (args, init) => {
const fetch = async (input: RequestInfo | URL): Promise<Response> => {
const url = input instanceof Request ? input.url : input;
// eslint-disable-next-line @typescript-eslint/naming-convention
const EventSource = await getEventSource();
const eventSource = new EventSource(url);

const {topics, signal, onEvent, onError, onClose} = args;

const close = (): void => {
eventSource.close();
onClose?.();
signal.removeEventListener("abort", close);
};
signal.addEventListener("abort", close, {once: true});

for (const topic of topics) {
eventSource.addEventListener(topic, ((event: MessageEvent) => {
const message = eventSerdes.fromJson(topic, JSON.parse(event.data));
onEvent({type: topic, message} as BeaconEvent);
}) as EventListener);
}

// EventSource will try to reconnect always on all errors
// `eventSource.onerror` events are informative but don't indicate the EventSource closed
// The only way to abort the connection from the client is via eventSource.close()
eventSource.onerror = function onerror(err) {
const errEs = err as unknown as EventSourceError;
onError?.(errEs);
// Consider 400 and 500 status errors unrecoverable, close the eventsource
if (errEs.status === 400 || errEs.status === 500) {
close();
}
// TODO: else log the error somewhere
// console.log("eventstream client error", errEs);
};

return new Response();
};

// EventSource will try to reconnect always on all errors
// `eventSource.onerror` events are informative but don't indicate the EventSource closed
// The only way to abort the connection from the client is via eventSource.close()
eventSource.onerror = function onerror(err) {
const errEs = err as unknown as EventSourceError;
// Consider 400 and 500 status errors unrecoverable, close the eventsource
if (errEs.status === 400) {
reject(Error(`400 Invalid topics: ${errEs.message}`));
}
if (errEs.status === 500) {
reject(Error(`500 Internal Server Error: ${errEs.message}`));
}

// TODO: else log the error somewhere
// console.log("eventstream client error", errEs);
};

// And abort resolve the promise so finally {} eventSource.close()
signal.addEventListener("abort", () => resolve(), {once: true});
});
} finally {
eventSource.close();
}

return {ok: true, response: undefined, status: HttpStatusCode.OK};
return client.request(eventstreamDefinitionExtended, args, init ?? {}, fetch);
},
};
}
Expand Down
52 changes: 32 additions & 20 deletions packages/api/src/beacon/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
import {ChainForkConfig} from "@lodestar/config";
import {Api} from "../routes/index.js";
import {IHttpClient, HttpClient, HttpClientOptions, HttpClientModules} from "../../utils/client/index.js";
import {
IHttpClient,
HttpClient,
HttpClientOptions,
HttpClientModules,
createApiClientMethods,
ApiClientMethods,
} from "../../utils/client/index.js";

import * as beacon from "./beacon.js";
import * as configApi from "./config.js";
import * as debug from "./debug.js";
import {
Endpoints,
beacon,
config as configApi,
debug,
lightclient,
lodestar,
node,
proof,
validator,
} from "../routes/index.js";
import * as events from "./events.js";
import * as lightclient from "./lightclient.js";
import * as lodestar from "./lodestar.js";
import * as node from "./node.js";
import * as proof from "./proof.js";
import * as validator from "./validator.js";

type ClientModules = HttpClientModules & {
config: ChainForkConfig;
Expand All @@ -20,19 +29,22 @@ type ClientModules = HttpClientModules & {
/**
* REST HTTP client for all routes
*/
export function getClient(opts: HttpClientOptions, modules: ClientModules): Api {
export function getClient(
opts: HttpClientOptions,
modules: ClientModules
): {[K in keyof Endpoints]: ApiClientMethods<Endpoints[K]>} {
const {config} = modules;
const httpClient = modules.httpClient ?? new HttpClient(opts, modules);

return {
beacon: beacon.getClient(config, httpClient),
config: configApi.getClient(config, httpClient),
debug: debug.getClient(config, httpClient),
events: events.getClient(config, httpClient.baseUrl),
lightclient: lightclient.getClient(config, httpClient),
lodestar: lodestar.getClient(config, httpClient),
node: node.getClient(config, httpClient),
proof: proof.getClient(config, httpClient),
validator: validator.getClient(config, httpClient),
beacon: createApiClientMethods(beacon.getDefinitions(config), httpClient),
config: createApiClientMethods(configApi.definitions, httpClient),
debug: createApiClientMethods(debug.definitions, httpClient),
events: events.getClient(config, httpClient),
lightclient: createApiClientMethods(lightclient.getDefinitions(config), httpClient),
lodestar: createApiClientMethods(lodestar.definitions, httpClient),
node: createApiClientMethods(node.definitions, httpClient),
proof: createApiClientMethods(proof.definitions, httpClient),
validator: createApiClientMethods(validator.definitions, httpClient),
};
}
13 changes: 0 additions & 13 deletions packages/api/src/beacon/client/lightclient.ts

This file was deleted.

13 changes: 0 additions & 13 deletions packages/api/src/beacon/client/lodestar.ts

This file was deleted.

13 changes: 0 additions & 13 deletions packages/api/src/beacon/client/node.ts

This file was deleted.

Loading