@@ -56,6 +56,8 @@ export {
5656 getCachedGenesisConstants ,
5757 addCachedAccount ,
5858 networkConfig ,
59+ setMinaDefaultHeaders ,
60+ setArchiveDefaultHeaders ,
5961 setGraphqlEndpoint ,
6062 setGraphqlEndpoints ,
6163 setMinaGraphqlFallbackEndpoints ,
@@ -85,6 +87,10 @@ type ActionsQueryInputs = {
8587 tokenId ?: string ;
8688} ;
8789
90+ let minaDefaultHeaders : HeadersInit = { } ;
91+
92+ let archiveDefaultHeaders : HeadersInit = { } ;
93+
8894let networkConfig = {
8995 minaEndpoint : '' ,
9096 minaFallbackEndpoints : [ ] as string [ ] ,
@@ -102,6 +108,52 @@ function checkForValidUrl(url: string) {
102108 }
103109}
104110
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+
123+ /**
124+ * Sets up the default headers to be used for all Mina node GraphQL requests, example usage:
125+ * ```typescript
126+ * setMinaDefaultHeaders({ Authorization: 'Bearer example-token' });
127+ * ```
128+ *
129+ * It can be overridden by passing headers to the individual fetch functions, example usage:
130+ * ```typescript
131+ * setMinaDefaultHeaders({ Authorization: 'Bearer default-token' });
132+ * await fetchAccount({publicKey}, minaEndpoint, { headers: { Authorization: 'Bearer override-token' } });
133+ * ```
134+ * @param headers Arbitrary sized headers to be used for all Mina node GraphQL requests.
135+ */
136+ function setMinaDefaultHeaders ( headers : HeadersInit ) {
137+ minaDefaultHeaders = headers ;
138+ }
139+
140+ /**
141+ * Sets up the default headers to be used for all Archive node GraphQL requests, example usage:
142+ * ```typescript
143+ * setArchiveDefaultHeaders({ Authorization: 'Bearer example-token' });
144+ * ```
145+ *
146+ * It can be overridden by passing headers to the individual fetch functions, example usage:
147+ * ```typescript
148+ * setArchiveDefaultHeaders({ Authorization: 'Bearer default-token' });
149+ * await fetchEvents({publicKey}, archiveEndpoint, { headers: { Authorization: 'Bearer override-token' } });
150+ * ```
151+ * @param headers Arbitrary sized headers to be used for all Mina Archive node GraphQL requests.
152+ */
153+ function setArchiveDefaultHeaders ( headers : HeadersInit ) {
154+ archiveDefaultHeaders = headers ;
155+ }
156+
105157function setGraphqlEndpoints ( [
106158 graphqlEndpoint ,
107159 ...fallbackEndpoints
@@ -173,13 +225,13 @@ function setLightnetAccountManagerEndpoint(endpoint: string) {
173225 * @param accountInfo.publicKey The specified publicKey to get account information on
174226 * @param accountInfo.tokenId The specified tokenId to get account information on
175227 * @param graphqlEndpoint The graphql endpoint to fetch from
176- * @param config An object that exposes an additional timeout option
228+ * @param config An object that exposes an additional timeout and header options
177229 * @returns zkapp information on the specified account or an error is thrown
178230 */
179231async function fetchAccount (
180232 accountInfo : { publicKey : string | PublicKey ; tokenId ?: string | Field } ,
181233 graphqlEndpoint = networkConfig . minaEndpoint ,
182- { timeout = defaultTimeout } = { }
234+ { timeout = defaultTimeout , headers } : FetchConfig = { }
183235) : Promise <
184236 | { account : Types . Account ; error : undefined }
185237 | { account : undefined ; error : FetchError }
@@ -198,6 +250,7 @@ async function fetchAccount(
198250 graphqlEndpoint ,
199251 {
200252 timeout,
253+ headers,
201254 }
202255 ) ;
203256}
@@ -236,7 +289,7 @@ async function fetchAccountInternal(
236289 } ;
237290}
238291
239- type FetchConfig = { timeout ?: number } ;
292+ type FetchConfig = { timeout ?: number ; headers ?: HeadersInit } ;
240293type FetchResponse < TDataResponse = any > = { data : TDataResponse ; errors ?: any } ;
241294type FetchError = {
242295 statusCode : number ;
@@ -458,11 +511,15 @@ function accountCacheKey(
458511/**
459512 * Fetches the last block on the Mina network.
460513 */
461- async function fetchLastBlock ( graphqlEndpoint = networkConfig . minaEndpoint ) {
514+ async function fetchLastBlock (
515+ graphqlEndpoint = networkConfig . minaEndpoint ,
516+ headers ?: HeadersInit
517+ ) {
462518 let [ resp , error ] = await makeGraphqlRequest < LastBlockQueryResponse > (
463519 lastBlockQuery ,
464520 graphqlEndpoint ,
465- networkConfig . minaFallbackEndpoints
521+ networkConfig . minaFallbackEndpoints ,
522+ { headers }
466523 ) ;
467524 if ( error ) throw Error ( error . statusText ) ;
468525 let lastBlock = resp ?. data ?. bestChain ?. [ 0 ] ;
@@ -478,11 +535,21 @@ async function fetchLastBlock(graphqlEndpoint = networkConfig.minaEndpoint) {
478535 return network ;
479536}
480537
481- async function fetchCurrentSlot ( graphqlEndpoint = networkConfig . minaEndpoint ) {
538+ /**
539+ * Fetches the current slot number of the Mina network.
540+ * @param graphqlEndpoint GraphQL endpoint to fetch from
541+ * @param headers optional headers to pass to the fetch request
542+ * @returns The current slot number
543+ */
544+ async function fetchCurrentSlot (
545+ graphqlEndpoint = networkConfig . minaEndpoint ,
546+ headers ?: HeadersInit
547+ ) {
482548 let [ resp , error ] = await makeGraphqlRequest < CurrentSlotResponse > (
483549 currentSlotQuery ,
484550 graphqlEndpoint ,
485- networkConfig . minaFallbackEndpoints
551+ networkConfig . minaFallbackEndpoints ,
552+ { headers }
486553 ) ;
487554 if ( error ) throw Error ( `Error making GraphQL request: ${ error . statusText } ` ) ;
488555 let bestChain = resp ?. data ?. bestChain ;
@@ -597,12 +664,14 @@ function parseEpochData({
597664 */
598665async function fetchTransactionStatus (
599666 txId : string ,
600- graphqlEndpoint = networkConfig . minaEndpoint
667+ graphqlEndpoint = networkConfig . minaEndpoint ,
668+ headers ?: HeadersInit
601669) : Promise < TransactionStatus > {
602670 let [ resp , error ] = await makeGraphqlRequest < TransactionStatusQueryResponse > (
603671 transactionStatusQuery ( txId ) ,
604672 graphqlEndpoint ,
605- networkConfig . minaFallbackEndpoints
673+ networkConfig . minaFallbackEndpoints ,
674+ { headers }
606675 ) ;
607676 if ( error ) throw Error ( error . statusText ) ;
608677 let txStatus = resp ?. data ?. transactionStatus ;
@@ -618,14 +687,15 @@ async function fetchTransactionStatus(
618687function sendZkapp (
619688 json : string ,
620689 graphqlEndpoint = networkConfig . minaEndpoint ,
621- { timeout = defaultTimeout } = { }
690+ { timeout = defaultTimeout , headers } : FetchConfig = { }
622691) {
623692 return makeGraphqlRequest < SendZkAppResponse > (
624693 sendZkappQuery ( json ) ,
625694 graphqlEndpoint ,
626695 networkConfig . minaFallbackEndpoints ,
627696 {
628697 timeout,
698+ headers,
629699 }
630700 ) ;
631701}
@@ -637,6 +707,7 @@ function sendZkapp(
637707 * @param [accountInfo.tokenId] - The optional token ID for the account.
638708 * @param [graphqlEndpoint=networkConfig.archiveEndpoint] - The GraphQL endpoint to query. Defaults to the Archive Node GraphQL API.
639709 * @param [filterOptions={ }] - The optional filter options object.
710+ * @param headers - Optional headers to pass to the fetch request
640711 * @returns A promise that resolves to an array of objects containing event data, block information and transaction information for the account.
641712 * @throws If the GraphQL request fails or the response is invalid.
642713 * @example
@@ -649,7 +720,8 @@ function sendZkapp(
649720async function fetchEvents (
650721 accountInfo : { publicKey : string ; tokenId ?: string } ,
651722 graphqlEndpoint = networkConfig . archiveEndpoint ,
652- filterOptions : EventActionFilterOptions = { }
723+ filterOptions : EventActionFilterOptions = { } ,
724+ headers ?: HeadersInit
653725) {
654726 if ( ! graphqlEndpoint )
655727 throw Error (
@@ -663,7 +735,8 @@ async function fetchEvents(
663735 filterOptions
664736 ) ,
665737 graphqlEndpoint ,
666- networkConfig . archiveFallbackEndpoints
738+ networkConfig . archiveFallbackEndpoints ,
739+ { headers }
667740 ) ;
668741 if ( error ) throw Error ( error . statusText ) ;
669742 let fetchedEvents = response ?. data . events ;
@@ -697,6 +770,7 @@ async function fetchEvents(
697770 *
698771 * @param accountInfo - An {@link ActionsQueryInputs} containing the public key, and optional query parameters for the actions query
699772 * @param graphqlEndpoint - The GraphQL endpoint to fetch from. Defaults to the configured Mina endpoint.
773+ * @param headers - Optional headers to pass to the fetch request
700774 *
701775 * @returns A promise that resolves to an object containing the final actions hash for the account, and a list of actions
702776 * @throws Will throw an error if the GraphQL endpoint is invalid or if the fetch request fails.
@@ -710,7 +784,8 @@ async function fetchEvents(
710784 */
711785async function fetchActions (
712786 accountInfo : ActionsQueryInputs ,
713- graphqlEndpoint = networkConfig . archiveEndpoint
787+ graphqlEndpoint = networkConfig . archiveEndpoint ,
788+ headers ?: HeadersInit
714789) : Promise <
715790 | {
716791 actions : string [ ] [ ] ;
@@ -731,7 +806,8 @@ async function fetchActions(
731806 let [ response , error ] = await makeGraphqlRequest < ActionQueryResponse > (
732807 getActionsQuery ( publicKey , actionStates , tokenId ) ,
733808 graphqlEndpoint ,
734- networkConfig . archiveFallbackEndpoints
809+ networkConfig . archiveFallbackEndpoints ,
810+ { headers }
735811 ) ;
736812 // As of 2025-01-07, minascan is running a version of the node which supports `sequenceNumber` and `zkappAccountUpdateIds` fields
737813 // We could consider removing this fallback since no other nodes are widely used
@@ -746,7 +822,8 @@ async function fetchActions(
746822 /* _excludeTransactionInfo= */ true
747823 ) ,
748824 graphqlEndpoint ,
749- networkConfig . archiveFallbackEndpoints
825+ networkConfig . archiveFallbackEndpoints ,
826+ { headers } // Should we pass headers to other nodes?
750827 ) ;
751828 if ( error )
752829 throw Error (
@@ -867,12 +944,14 @@ export function createActionsList(
867944 * Fetches genesis constants.
868945 */
869946async function fetchGenesisConstants (
870- graphqlEndpoint = networkConfig . minaEndpoint
947+ graphqlEndpoint = networkConfig . minaEndpoint ,
948+ headers ?: HeadersInit
871949) : Promise < GenesisConstants > {
872950 let [ resp , error ] = await makeGraphqlRequest < GenesisConstantsResponse > (
873951 genesisConstantsQuery ,
874952 graphqlEndpoint ,
875- networkConfig . minaFallbackEndpoints
953+ networkConfig . minaFallbackEndpoints ,
954+ { headers }
876955 ) ;
877956 if ( error ) throw Error ( error . statusText ) ;
878957 const genesisConstants = resp ?. data ?. genesisConstants ;
@@ -1029,7 +1108,7 @@ async function makeGraphqlRequest<TDataResponse = any>(
10291108 query : string ,
10301109 graphqlEndpoint = networkConfig . minaEndpoint ,
10311110 fallbackEndpoints : string [ ] ,
1032- { timeout = defaultTimeout } = { } as FetchConfig
1111+ { timeout = defaultTimeout , headers } = { } as FetchConfig
10331112) {
10341113 if ( graphqlEndpoint === 'none' )
10351114 throw Error (
@@ -1049,7 +1128,11 @@ async function makeGraphqlRequest<TDataResponse = any>(
10491128 try {
10501129 let response = await fetch ( url , {
10511130 method : 'POST' ,
1052- headers : { 'Content-Type' : 'application/json' } ,
1131+ headers : {
1132+ 'Content-Type' : 'application/json' ,
1133+ ...( isArchiveUrl ( url ) ? archiveDefaultHeaders : minaDefaultHeaders ) ,
1134+ ...headers ,
1135+ } ,
10531136 body,
10541137 signal : controller . signal ,
10551138 } ) ;
0 commit comments