Skip to content

Commit 07a7767

Browse files
authored
feat(apps/hermes/client): allow authorization headers (#1738)
* feat(apps/hermes/client): allow authorization headers * bump version * pass in headers to constructor instead * address comments
1 parent 3762116 commit 07a7767

File tree

3 files changed

+42
-5
lines changed

3 files changed

+42
-5
lines changed

apps/hermes/client/js/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pythnetwork/hermes-client",
3-
"version": "1.0.3",
3+
"version": "1.0.4",
44
"description": "Pyth Hermes Client",
55
"author": {
66
"name": "Pyth Data Association"

apps/hermes/client/js/src/HermesClient.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,17 @@ export type HermesClientConfig = {
2929
* it will timeout regardless of the retries at the configured `timeout` time.
3030
*/
3131
httpRetries?: number;
32+
/**
33+
* Optional headers to be included in every request.
34+
*/
35+
headers?: HeadersInit;
3236
};
3337

3438
export class HermesClient {
3539
private baseURL: string;
3640
private timeout: DurationInMs;
3741
private httpRetries: number;
42+
private headers: HeadersInit;
3843

3944
/**
4045
* Constructs a new Connection.
@@ -46,6 +51,7 @@ export class HermesClient {
4651
this.baseURL = endpoint;
4752
this.timeout = config?.timeout ?? DEFAULT_TIMEOUT;
4853
this.httpRetries = config?.httpRetries ?? DEFAULT_HTTP_RETRIES;
54+
this.headers = config?.headers ?? {};
4955
}
5056

5157
private async httpRequest<ResponseData>(
@@ -58,7 +64,11 @@ export class HermesClient {
5864
): Promise<ResponseData> {
5965
const controller = externalAbortController ?? new AbortController();
6066
const { signal } = controller;
61-
options = { ...options, signal }; // Merge any existing options with the signal
67+
options = {
68+
...options,
69+
signal,
70+
headers: { ...this.headers, ...options?.headers },
71+
}; // Merge any existing options with the signal and headers
6272

6373
// Set a timeout to abort the request if it takes too long
6474
const timeout = setTimeout(() => controller.abort(), this.timeout);
@@ -129,7 +139,7 @@ export class HermesClient {
129139
parsed?: boolean;
130140
}
131141
): Promise<PriceUpdate> {
132-
const url = new URL(`v2/updates/price/latest`, this.baseURL);
142+
const url = new URL("v2/updates/price/latest", this.baseURL);
133143
for (const id of ids) {
134144
url.searchParams.append("ids[]", id);
135145
}
@@ -208,7 +218,7 @@ export class HermesClient {
208218
this.appendUrlSearchParams(url, transformedOptions);
209219
}
210220

211-
return new EventSource(url.toString());
221+
return new EventSource(url.toString(), { headers: this.headers });
212222
}
213223

214224
private appendUrlSearchParams(

apps/hermes/client/js/src/examples/HermesClient.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,35 @@ const argv = yargs(hideBin(process.argv))
2828
})
2929
.parseSync();
3030

31+
/**
32+
* Extracts the endpoint and basic authorization headers from a given URL string.
33+
*
34+
* @param {string} urlString - The URL string containing the endpoint and optional basic auth credentials.
35+
* @returns {{ endpoint: string; headers: HeadersInit }} An object containing the endpoint URL and headers.
36+
*/
37+
function extractBasicAuthorizationHeadersFromUrl(urlString: string): {
38+
endpoint: string;
39+
headers: HeadersInit;
40+
} {
41+
const url = new URL(urlString);
42+
const headers: HeadersInit = {};
43+
44+
if (url.username && url.password) {
45+
headers["Authorization"] = `Basic ${btoa(
46+
`${url.username}:${url.password}`
47+
)}`;
48+
url.username = "";
49+
url.password = "";
50+
}
51+
52+
return { endpoint: url.toString(), headers };
53+
}
54+
3155
async function run() {
32-
const connection = new HermesClient(argv.endpoint);
56+
const { endpoint, headers } = extractBasicAuthorizationHeadersFromUrl(
57+
argv.endpoint
58+
);
59+
const connection = new HermesClient(endpoint, { headers });
3360

3461
const priceIds = argv.priceIds as string[];
3562

0 commit comments

Comments
 (0)