Skip to content

Commit 86909dd

Browse files
authored
Merge pull request #2334 from pyth-network/cprussin/allow-passing-fetch-arguments-to-hermes-client
feat(hermes-client): allow passing fetch options
2 parents 1b335a5 + 4624180 commit 86909dd

File tree

3 files changed

+179
-483
lines changed

3 files changed

+179
-483
lines changed

apps/hermes/client/js/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pythnetwork/hermes-client",
3-
"version": "1.3.1",
3+
"version": "1.4.0",
44
"description": "Pyth Hermes Client",
55
"author": {
66
"name": "Pyth Data Association"
@@ -47,7 +47,7 @@
4747
"openapi-zod-client": "^1.18.1",
4848
"prettier": "^2.6.2",
4949
"ts-jest": "^29.0.5",
50-
"typescript": "^4.6.3",
50+
"typescript": "catalog:",
5151
"yargs": "^17.4.1"
5252
},
5353
"dependencies": {

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

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -63,23 +63,17 @@ export class HermesClient {
6363
schema: z.ZodSchema<ResponseData>,
6464
options?: RequestInit,
6565
retries = this.httpRetries,
66-
backoff = 100 + Math.floor(Math.random() * 100), // Adding randomness to the initial backoff to avoid "thundering herd" scenario where a lot of clients that get kicked off all at the same time (say some script or something) and fail to connect all retry at exactly the same time too
67-
externalAbortController?: AbortController
66+
backoff = 100 + Math.floor(Math.random() * 100) // Adding randomness to the initial backoff to avoid "thundering herd" scenario where a lot of clients that get kicked off all at the same time (say some script or something) and fail to connect all retry at exactly the same time too
6867
): Promise<ResponseData> {
69-
const controller = externalAbortController ?? new AbortController();
70-
const { signal } = controller;
71-
options = {
72-
...options,
73-
signal,
74-
headers: { ...this.headers, ...options?.headers },
75-
}; // Merge any existing options with the signal and headers
76-
77-
// Set a timeout to abort the request if it takes too long
78-
const timeout = setTimeout(() => controller.abort(), this.timeout);
79-
8068
try {
81-
const response = await fetch(url, options);
82-
clearTimeout(timeout); // Clear the timeout if the request completes in time
69+
const response = await fetch(url, {
70+
...options,
71+
signal: AbortSignal.any([
72+
...(options?.signal ? [options.signal] : []),
73+
AbortSignal.timeout(this.timeout),
74+
]),
75+
headers: { ...this.headers, ...options?.headers },
76+
});
8377
if (!response.ok) {
8478
const errorBody = await response.text();
8579
throw new Error(
@@ -91,7 +85,6 @@ export class HermesClient {
9185
const data = await response.json();
9286
return schema.parse(data);
9387
} catch (error) {
94-
clearTimeout(timeout);
9588
if (
9689
retries > 0 &&
9790
!(error instanceof Error && error.name === "AbortError")
@@ -115,17 +108,22 @@ export class HermesClient {
115108
*
116109
* @returns Array of PriceFeedMetadata objects.
117110
*/
118-
async getPriceFeeds(options?: {
111+
async getPriceFeeds({
112+
fetchOptions,
113+
...options
114+
}: {
119115
query?: string;
120116
filter?: string;
121-
}): Promise<PriceFeedMetadata[]> {
117+
fetchOptions?: RequestInit;
118+
} = {}): Promise<PriceFeedMetadata[]> {
122119
const url = this.buildURL("price_feeds");
123120
if (options) {
124121
this.appendUrlSearchParams(url, options);
125122
}
126123
return await this.httpRequest(
127124
url.toString(),
128-
schemas.PriceFeedMetadata.array()
125+
schemas.PriceFeedMetadata.array(),
126+
fetchOptions
129127
);
130128
}
131129

@@ -140,10 +138,14 @@ export class HermesClient {
140138
*
141139
* @returns PublisherCaps object containing the latest publisher stake caps.
142140
*/
143-
async getLatestPublisherCaps(options?: {
141+
async getLatestPublisherCaps({
142+
fetchOptions,
143+
...options
144+
}: {
144145
encoding?: EncodingType;
145146
parsed?: boolean;
146-
}): Promise<PublisherCaps> {
147+
fetchOptions?: RequestInit;
148+
} = {}): Promise<PublisherCaps> {
147149
const url = this.buildURL("updates/publisher_stake_caps/latest");
148150
if (options) {
149151
this.appendUrlSearchParams(url, options);
@@ -173,7 +175,8 @@ export class HermesClient {
173175
encoding?: EncodingType;
174176
parsed?: boolean;
175177
ignoreInvalidPriceIds?: boolean;
176-
}
178+
},
179+
fetchOptions?: RequestInit
177180
): Promise<PriceUpdate> {
178181
const url = this.buildURL("updates/price/latest");
179182
for (const id of ids) {
@@ -185,7 +188,7 @@ export class HermesClient {
185188
this.appendUrlSearchParams(url, transformedOptions);
186189
}
187190

188-
return this.httpRequest(url.toString(), schemas.PriceUpdate);
191+
return this.httpRequest(url.toString(), schemas.PriceUpdate, fetchOptions);
189192
}
190193

191194
/**
@@ -209,7 +212,8 @@ export class HermesClient {
209212
encoding?: EncodingType;
210213
parsed?: boolean;
211214
ignoreInvalidPriceIds?: boolean;
212-
}
215+
},
216+
fetchOptions?: RequestInit
213217
): Promise<PriceUpdate> {
214218
const url = this.buildURL(`updates/price/${publishTime}`);
215219
for (const id of ids) {
@@ -221,7 +225,7 @@ export class HermesClient {
221225
this.appendUrlSearchParams(url, transformedOptions);
222226
}
223227

224-
return this.httpRequest(url.toString(), schemas.PriceUpdate);
228+
return this.httpRequest(url.toString(), schemas.PriceUpdate, fetchOptions);
225229
}
226230

227231
/**
@@ -286,7 +290,8 @@ export class HermesClient {
286290
encoding?: EncodingType;
287291
parsed?: boolean;
288292
ignoreInvalidPriceIds?: boolean;
289-
}
293+
},
294+
fetchOptions?: RequestInit
290295
): Promise<TwapsResponse> {
291296
const url = this.buildURL(`updates/twap/${window_seconds}/latest`);
292297
for (const id of ids) {
@@ -298,7 +303,11 @@ export class HermesClient {
298303
this.appendUrlSearchParams(url, transformedOptions);
299304
}
300305

301-
return this.httpRequest(url.toString(), schemas.TwapsResponse);
306+
return this.httpRequest(
307+
url.toString(),
308+
schemas.TwapsResponse,
309+
fetchOptions
310+
);
302311
}
303312

304313
private appendUrlSearchParams(

0 commit comments

Comments
 (0)