Skip to content

Commit 05086a2

Browse files
committed
refactor fetch functions to reduce setMinaDefaultHeaders calls and fix unit tests
1 parent 3b703b1 commit 05086a2

File tree

2 files changed

+33
-40
lines changed

2 files changed

+33
-40
lines changed

src/lib/mina/fetch.ts

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ type NetworkConfig = {
7979
archiveEndpoint: string;
8080
archiveFallbackEndpoints: string[];
8181
lightnetAccountManagerEndpoint: string;
82+
minaDefaultHeaders: HeadersInit;
83+
archiveDefaultHeaders: HeadersInit;
8284
};
8385

8486
type ActionsQueryInputs = {
@@ -87,16 +89,14 @@ type ActionsQueryInputs = {
8789
tokenId?: string;
8890
};
8991

90-
let minaDefaultHeaders: HeadersInit = {};
91-
92-
let archiveDefaultHeaders: HeadersInit = {};
93-
9492
let networkConfig = {
9593
minaEndpoint: '',
9694
minaFallbackEndpoints: [] as string[],
9795
archiveEndpoint: '',
9896
archiveFallbackEndpoints: [] as string[],
9997
lightnetAccountManagerEndpoint: '',
98+
minaDefaultHeaders: {},
99+
archiveDefaultHeaders: {},
100100
} satisfies NetworkConfig;
101101

102102
function checkForValidUrl(url: string) {
@@ -108,18 +108,6 @@ function checkForValidUrl(url: string) {
108108
}
109109
}
110110

111-
/**
112-
* Internal function to classify the URL as an archive node or not.
113-
* @param url graphql endpoint
114-
* @returns boolean indicating if the URL is an archive node or not
115-
*/
116-
function isArchiveUrl(url: string): boolean {
117-
return (
118-
url === networkConfig.archiveEndpoint ||
119-
networkConfig.archiveFallbackEndpoints.includes(url)
120-
);
121-
}
122-
123111
/**
124112
* Sets up the default headers to be used for all Mina node GraphQL requests, example usage:
125113
* ```typescript
@@ -134,7 +122,7 @@ function isArchiveUrl(url: string): boolean {
134122
* @param headers Arbitrary sized headers to be used for all Mina node GraphQL requests.
135123
*/
136124
function setMinaDefaultHeaders(headers: HeadersInit) {
137-
minaDefaultHeaders = headers;
125+
networkConfig.minaDefaultHeaders = headers;
138126
}
139127

140128
/**
@@ -151,7 +139,7 @@ function setMinaDefaultHeaders(headers: HeadersInit) {
151139
* @param headers Arbitrary sized headers to be used for all Mina Archive node GraphQL requests.
152140
*/
153141
function setArchiveDefaultHeaders(headers: HeadersInit) {
154-
archiveDefaultHeaders = headers;
142+
networkConfig.archiveDefaultHeaders = headers;
155143
}
156144

157145
function setGraphqlEndpoints([
@@ -161,13 +149,17 @@ function setGraphqlEndpoints([
161149
setGraphqlEndpoint(graphqlEndpoint);
162150
setMinaGraphqlFallbackEndpoints(fallbackEndpoints);
163151
}
164-
function setGraphqlEndpoint(graphqlEndpoint: string) {
152+
function setGraphqlEndpoint(
153+
graphqlEndpoint: string,
154+
minaDefaultHeaders?: HeadersInit
155+
) {
165156
if (!checkForValidUrl(graphqlEndpoint)) {
166157
throw new Error(
167158
`Invalid GraphQL endpoint: ${graphqlEndpoint}. Please specify a valid URL.`
168159
);
169160
}
170161
networkConfig.minaEndpoint = graphqlEndpoint;
162+
if (minaDefaultHeaders) setMinaDefaultHeaders(minaDefaultHeaders);
171163
}
172164
function setMinaGraphqlFallbackEndpoints(graphqlEndpoints: string[]) {
173165
if (graphqlEndpoints.some((endpoint) => !checkForValidUrl(endpoint))) {
@@ -182,13 +174,17 @@ function setMinaGraphqlFallbackEndpoints(graphqlEndpoints: string[]) {
182174
* Sets up a GraphQL endpoint to be used for fetching information from an Archive Node.
183175
*
184176
*/
185-
function setArchiveGraphqlEndpoint(graphqlEndpoint: string) {
177+
function setArchiveGraphqlEndpoint(
178+
graphqlEndpoint: string,
179+
archiveDefaultHeaders?: HeadersInit
180+
) {
186181
if (!checkForValidUrl(graphqlEndpoint)) {
187182
throw new Error(
188183
`Invalid GraphQL endpoint: ${graphqlEndpoint}. Please specify a valid URL.`
189184
);
190185
}
191186
networkConfig.archiveEndpoint = graphqlEndpoint;
187+
if (archiveDefaultHeaders) setArchiveDefaultHeaders(archiveDefaultHeaders);
192188
}
193189
function setArchiveGraphqlFallbackEndpoints(graphqlEndpoints: string[]) {
194190
if (graphqlEndpoints.some((endpoint) => !checkForValidUrl(endpoint))) {
@@ -250,7 +246,7 @@ async function fetchAccount(
250246
graphqlEndpoint,
251247
{
252248
timeout,
253-
headers,
249+
headers: { ...networkConfig.minaDefaultHeaders, ...headers },
254250
}
255251
);
256252
}
@@ -519,7 +515,7 @@ async function fetchLastBlock(
519515
lastBlockQuery,
520516
graphqlEndpoint,
521517
networkConfig.minaFallbackEndpoints,
522-
{ headers }
518+
{ headers: { ...networkConfig.minaDefaultHeaders, ...headers } }
523519
);
524520
if (error) throw Error(error.statusText);
525521
let lastBlock = resp?.data?.bestChain?.[0];
@@ -549,7 +545,7 @@ async function fetchCurrentSlot(
549545
currentSlotQuery,
550546
graphqlEndpoint,
551547
networkConfig.minaFallbackEndpoints,
552-
{ headers }
548+
{ headers: { ...networkConfig.minaDefaultHeaders, ...headers } }
553549
);
554550
if (error) throw Error(`Error making GraphQL request: ${error.statusText}`);
555551
let bestChain = resp?.data?.bestChain;
@@ -671,7 +667,7 @@ async function fetchTransactionStatus(
671667
transactionStatusQuery(txId),
672668
graphqlEndpoint,
673669
networkConfig.minaFallbackEndpoints,
674-
{ headers }
670+
{ headers: { ...networkConfig.minaDefaultHeaders, ...headers } }
675671
);
676672
if (error) throw Error(error.statusText);
677673
let txStatus = resp?.data?.transactionStatus;
@@ -695,7 +691,7 @@ function sendZkapp(
695691
networkConfig.minaFallbackEndpoints,
696692
{
697693
timeout,
698-
headers,
694+
headers: { ...networkConfig.minaDefaultHeaders, ...headers },
699695
}
700696
);
701697
}
@@ -736,7 +732,7 @@ async function fetchEvents(
736732
),
737733
graphqlEndpoint,
738734
networkConfig.archiveFallbackEndpoints,
739-
{ headers }
735+
{ headers: { ...networkConfig.archiveDefaultHeaders, ...headers } }
740736
);
741737
if (error) throw Error(error.statusText);
742738
let fetchedEvents = response?.data.events;
@@ -807,7 +803,7 @@ async function fetchActions(
807803
getActionsQuery(publicKey, actionStates, tokenId),
808804
graphqlEndpoint,
809805
networkConfig.archiveFallbackEndpoints,
810-
{ headers }
806+
{ headers: { ...networkConfig.archiveDefaultHeaders, ...headers } }
811807
);
812808
// As of 2025-01-07, minascan is running a version of the node which supports `sequenceNumber` and `zkappAccountUpdateIds` fields
813809
// We could consider removing this fallback since no other nodes are widely used
@@ -823,7 +819,7 @@ async function fetchActions(
823819
),
824820
graphqlEndpoint,
825821
networkConfig.archiveFallbackEndpoints,
826-
{ headers } // Should we pass headers to other nodes?
822+
{ headers: { ...networkConfig.archiveDefaultHeaders, ...headers } }
827823
);
828824
if (error)
829825
throw Error(
@@ -951,7 +947,7 @@ async function fetchGenesisConstants(
951947
genesisConstantsQuery,
952948
graphqlEndpoint,
953949
networkConfig.minaFallbackEndpoints,
954-
{ headers }
950+
{ headers: { ...networkConfig.minaDefaultHeaders, ...headers } }
955951
);
956952
if (error) throw Error(error.statusText);
957953
const genesisConstants = resp?.data?.genesisConstants;
@@ -1130,7 +1126,6 @@ async function makeGraphqlRequest<TDataResponse = any>(
11301126
method: 'POST',
11311127
headers: {
11321128
'Content-Type': 'application/json',
1133-
...(isArchiveUrl(url) ? archiveDefaultHeaders : minaDefaultHeaders),
11341129
...headers,
11351130
},
11361131
body,

src/lib/mina/fetch.unit-test.ts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -238,14 +238,18 @@ describe('Fetch', () => {
238238

239239
setGraphqlEndpoint(minaEndpoint);
240240
setArchiveGraphqlEndpoint(archiveEndpoint);
241+
setMinaDefaultHeaders({ Authorization: 'Bearer mina-default-token' });
242+
setArchiveDefaultHeaders({
243+
Authorization: 'Bearer archive-default-token',
244+
});
241245
});
242246

243247
afterEach(() => {
244248
global.fetch = originalFetch;
249+
lastFetchOptions = null;
245250
});
246251

247252
test('Mina default headers with per request headers', async () => {
248-
setMinaDefaultHeaders({ Authorization: 'Bearer mina-default-token' });
249253
const perRequestHeaders = { 'X-Custom': 'custom-value' };
250254
await fetchAccount(
251255
{ publicKey: PrivateKey.random().toPublicKey().toBase58() },
@@ -263,8 +267,6 @@ describe('Fetch', () => {
263267
});
264268

265269
test('Per request headers overrides default headers', async () => {
266-
setMinaDefaultHeaders({ Authorization: 'Bearer mina-default-token' });
267-
268270
const perRequestHeaders = {
269271
Authorization: 'Bearer override-token',
270272
'X-Test': 'value',
@@ -285,10 +287,6 @@ describe('Fetch', () => {
285287
});
286288

287289
test('Archive default headers with per request headers', async () => {
288-
setArchiveDefaultHeaders({
289-
Authorization: 'Bearer archive-default-token',
290-
});
291-
292290
const perRequestHeaders = { 'X-Another': 'another-value' };
293291
await fetchEvents(
294292
{ publicKey: PrivateKey.random().toPublicKey().toBase58() },
@@ -324,11 +322,11 @@ describe('Fetch', () => {
324322

325323
test('Default and per request headers are used for fetchActions', async () => {
326324
setMinaDefaultHeaders({
327-
'X-Default': 'default-header',
325+
Authorization: 'Bearer archive-default-token',
328326
});
329327

330328
const perRequestHeaders = {
331-
Authorization: 'Bearer archive-default-token',
329+
'X-Default': 'default-header',
332330
};
333331
await fetchActions(
334332
{
@@ -344,8 +342,8 @@ describe('Fetch', () => {
344342

345343
expect(lastFetchOptions.headers).toMatchObject({
346344
'Content-Type': 'application/json',
347-
'X-Default': 'default-header',
348345
Authorization: 'Bearer archive-default-token',
346+
'X-Default': 'default-header',
349347
});
350348
});
351349

0 commit comments

Comments
 (0)