11use crate :: proto:: { FidsRequest , FidsResponse } ;
22use crate :: {
33 config:: HubConfig ,
4- hub:: stream:: EventStream ,
4+ hub:: { HeaderInterceptor , stream:: EventStream } ,
55 proto:: {
66 BlocksRequest , GetInfoRequest , GetInfoResponse , ShardChunksRequest , ShardChunksResponse ,
77 hub_service_client:: HubServiceClient ,
@@ -15,9 +15,14 @@ use std::{
1515} ;
1616use tokio_stream:: Stream ;
1717use tonic:: Status ;
18+ use tonic:: service:: interceptor:: InterceptedService ;
1819use tonic:: transport:: { Channel , ClientTlsConfig } ;
1920use tracing:: { error, info, warn} ;
2021
22+ /// Hub gRPC client configured with automatic custom header injection.
23+ pub type AuthenticatedHubServiceClient =
24+ HubServiceClient < InterceptedService < Channel , HeaderInterceptor > > ;
25+
2126#[ derive( Debug , thiserror:: Error ) ]
2227pub enum Error {
2328 #[ error( "Connection error: {0}" ) ]
@@ -124,8 +129,8 @@ impl HubRetryPolicy {
124129pub struct Hub {
125130 // Use a Channel directly for building services with middleware
126131 channel : Option < Channel > ,
127- // Raw client without middleware
128- client : Option < HubServiceClient < Channel > > ,
132+ // Authenticated client with automatic header injection
133+ client : Option < AuthenticatedHubServiceClient > ,
129134 config : Arc < HubConfig > ,
130135 host : String ,
131136 // Headers wrapped in Arc for cheap cloning in retry closures
@@ -156,9 +161,11 @@ impl Hub {
156161 } )
157162 }
158163
159- /// Add custom headers to request
160- fn add_custom_headers < T > ( & self , request : tonic:: Request < T > ) -> tonic:: Request < T > {
161- crate :: hub:: add_custom_headers ( request, & self . headers )
164+ fn create_authenticated_client (
165+ channel : Channel ,
166+ headers : Arc < HashMap < String , String > > ,
167+ ) -> AuthenticatedHubServiceClient {
168+ HubServiceClient :: with_interceptor ( channel, HeaderInterceptor :: new ( headers) )
162169 }
163170
164171 /// Create an empty hub instance for testing or mock purposes
@@ -259,13 +266,13 @@ impl Hub {
259266 // Store the channel for future use
260267 self . channel = Some ( channel. clone ( ) ) ;
261268
262- // Create base client without middleware for operations that don't need retries
263- let client = HubServiceClient :: new ( channel. clone ( ) ) ;
269+ // Create base client with automatic custom header injection
270+ let client = Self :: create_authenticated_client ( channel. clone ( ) , Arc :: clone ( & self . headers ) ) ;
264271 self . client = Some ( client) ;
265272
266273 // Test connection with info request
267274 // Get hub info without middleware first time to avoid double retry
268- let info_request = self . add_custom_headers ( tonic:: Request :: new ( GetInfoRequest { } ) ) ;
275+ let info_request = tonic:: Request :: new ( GetInfoRequest { } ) ;
269276 match self . client . as_mut ( ) . unwrap ( ) . get_info ( info_request) . await {
270277 Ok ( response) => {
271278 let hub_info = response. into_inner ( ) ;
@@ -385,7 +392,7 @@ impl Hub {
385392 }
386393 }
387394
388- pub fn client ( & mut self ) -> Option < & mut HubServiceClient < Channel > > {
395+ pub fn client ( & mut self ) -> Option < & mut AuthenticatedHubServiceClient > {
389396 self . client . as_mut ( )
390397 }
391398
@@ -419,13 +426,11 @@ impl Hub {
419426 start_block_number : start_block,
420427 stop_block_number : end_block,
421428 } ) ;
422- let request_with_headers = self . add_custom_headers ( request) ;
423-
424429 // Get a mutable reference to the client
425430 let client = self . client . as_mut ( ) . ok_or ( Error :: NotConnected ) ?;
426431
427432 // Try to execute the request
428- match client. get_blocks ( request_with_headers ) . await {
433+ match client. get_blocks ( request ) . await {
429434 Ok ( response) => {
430435 // Reset error count and update success timestamp
431436 self . error_count . store ( 0 , std:: sync:: atomic:: Ordering :: SeqCst ) ;
@@ -496,14 +501,13 @@ impl Hub {
496501 let headers = Arc :: clone ( & headers) ;
497502 Box :: pin ( async move {
498503 let channel = channel. ok_or ( Error :: NotConnected ) ?;
499- let mut client = HubServiceClient :: new ( channel) ;
504+ let mut client = Self :: create_authenticated_client ( channel, Arc :: clone ( & headers ) ) ;
500505 let request = tonic:: Request :: new ( ShardChunksRequest {
501506 shard_id,
502507 start_block_number : start_block,
503508 stop_block_number : end_block,
504509 } ) ;
505- let request_with_headers = crate :: hub:: add_custom_headers ( request, & headers) ;
506- match client. get_shard_chunks ( request_with_headers) . await {
510+ match client. get_shard_chunks ( request) . await {
507511 Ok ( response) => Ok ( response. into_inner ( ) ) ,
508512 Err ( status) => Err ( Error :: StatusError ( status) ) ,
509513 }
@@ -534,10 +538,9 @@ impl Hub {
534538 let headers = Arc :: clone ( & headers) ;
535539 Box :: pin ( async move {
536540 let channel = channel. ok_or ( Error :: NotConnected ) ?;
537- let mut client = HubServiceClient :: new ( channel) ;
541+ let mut client = Self :: create_authenticated_client ( channel, Arc :: clone ( & headers ) ) ;
538542 let request = tonic:: Request :: new ( GetInfoRequest { } ) ;
539- let request_with_headers = crate :: hub:: add_custom_headers ( request, & headers) ;
540- match client. get_info ( request_with_headers) . await {
543+ match client. get_info ( request) . await {
541544 Ok ( response) => Ok ( response. into_inner ( ) ) ,
542545 Err ( status) => Err ( Error :: StatusError ( status) ) ,
543546 }
@@ -579,15 +582,14 @@ impl Hub {
579582 let headers = Arc :: clone ( & headers) ;
580583 Box :: pin ( async move {
581584 let channel = channel. ok_or ( Error :: NotConnected ) ?;
582- let mut client = HubServiceClient :: new ( channel) ;
585+ let mut client = Self :: create_authenticated_client ( channel, Arc :: clone ( & headers ) ) ;
583586 let request = tonic:: Request :: new ( FidsRequest {
584587 page_size,
585588 page_token : page_token_clone,
586589 reverse,
587590 shard_id : 0 ,
588591 } ) ;
589- let request_with_headers = crate :: hub:: add_custom_headers ( request, & headers) ;
590- match client. get_fids ( request_with_headers) . await {
592+ match client. get_fids ( request) . await {
591593 Ok ( response) => Ok ( response. into_inner ( ) ) ,
592594 Err ( status) => Err ( Error :: StatusError ( status) ) ,
593595 }
@@ -614,10 +616,8 @@ impl Hub {
614616 let headers = Arc :: clone ( & headers) ;
615617 Box :: pin ( async move {
616618 let channel = channel. ok_or ( Error :: NotConnected ) ?;
617- let mut client = HubServiceClient :: new ( channel) ;
618- let request_with_headers =
619- crate :: hub:: add_custom_headers ( tonic:: Request :: new ( request) , & headers) ;
620- match client. get_casts_by_fid ( request_with_headers) . await {
619+ let mut client = Self :: create_authenticated_client ( channel, Arc :: clone ( & headers) ) ;
620+ match client. get_casts_by_fid ( tonic:: Request :: new ( request) ) . await {
621621 Ok ( response) => Ok ( response. into_inner ( ) ) ,
622622 Err ( status) => Err ( Error :: StatusError ( status) ) ,
623623 }
@@ -644,10 +644,8 @@ impl Hub {
644644 let headers = Arc :: clone ( & headers) ;
645645 Box :: pin ( async move {
646646 let channel = channel. ok_or ( Error :: NotConnected ) ?;
647- let mut client = HubServiceClient :: new ( channel) ;
648- let request_with_headers =
649- crate :: hub:: add_custom_headers ( tonic:: Request :: new ( request) , & headers) ;
650- match client. get_reactions_by_fid ( request_with_headers) . await {
647+ let mut client = Self :: create_authenticated_client ( channel, Arc :: clone ( & headers) ) ;
648+ match client. get_reactions_by_fid ( tonic:: Request :: new ( request) ) . await {
651649 Ok ( response) => Ok ( response. into_inner ( ) ) ,
652650 Err ( status) => Err ( Error :: StatusError ( status) ) ,
653651 }
@@ -674,10 +672,8 @@ impl Hub {
674672 let headers = Arc :: clone ( & headers) ;
675673 Box :: pin ( async move {
676674 let channel = channel. ok_or ( Error :: NotConnected ) ?;
677- let mut client = HubServiceClient :: new ( channel) ;
678- let request_with_headers =
679- crate :: hub:: add_custom_headers ( tonic:: Request :: new ( request) , & headers) ;
680- match client. get_links_by_fid ( request_with_headers) . await {
675+ let mut client = Self :: create_authenticated_client ( channel, Arc :: clone ( & headers) ) ;
676+ match client. get_links_by_fid ( tonic:: Request :: new ( request) ) . await {
681677 Ok ( response) => Ok ( response. into_inner ( ) ) ,
682678 Err ( status) => Err ( Error :: StatusError ( status) ) ,
683679 }
@@ -704,10 +700,8 @@ impl Hub {
704700 let headers = Arc :: clone ( & headers) ;
705701 Box :: pin ( async move {
706702 let channel = channel. ok_or ( Error :: NotConnected ) ?;
707- let mut client = HubServiceClient :: new ( channel) ;
708- let request_with_headers =
709- crate :: hub:: add_custom_headers ( tonic:: Request :: new ( request) , & headers) ;
710- match client. get_verifications_by_fid ( request_with_headers) . await {
703+ let mut client = Self :: create_authenticated_client ( channel, Arc :: clone ( & headers) ) ;
704+ match client. get_verifications_by_fid ( tonic:: Request :: new ( request) ) . await {
711705 Ok ( response) => Ok ( response. into_inner ( ) ) ,
712706 Err ( status) => Err ( Error :: StatusError ( status) ) ,
713707 }
@@ -734,10 +728,8 @@ impl Hub {
734728 let headers = Arc :: clone ( & headers) ;
735729 Box :: pin ( async move {
736730 let channel = channel. ok_or ( Error :: NotConnected ) ?;
737- let mut client = HubServiceClient :: new ( channel) ;
738- let request_with_headers =
739- crate :: hub:: add_custom_headers ( tonic:: Request :: new ( request) , & headers) ;
740- match client. get_user_data_by_fid ( request_with_headers) . await {
731+ let mut client = Self :: create_authenticated_client ( channel, Arc :: clone ( & headers) ) ;
732+ match client. get_user_data_by_fid ( tonic:: Request :: new ( request) ) . await {
741733 Ok ( response) => Ok ( response. into_inner ( ) ) ,
742734 Err ( status) => Err ( Error :: StatusError ( status) ) ,
743735 }
@@ -764,10 +756,8 @@ impl Hub {
764756 let headers = Arc :: clone ( & headers) ;
765757 Box :: pin ( async move {
766758 let channel = channel. ok_or ( Error :: NotConnected ) ?;
767- let mut client = HubServiceClient :: new ( channel) ;
768- let request_with_headers =
769- crate :: hub:: add_custom_headers ( tonic:: Request :: new ( request) , & headers) ;
770- match client. get_all_user_data_messages_by_fid ( request_with_headers) . await {
759+ let mut client = Self :: create_authenticated_client ( channel, Arc :: clone ( & headers) ) ;
760+ match client. get_all_user_data_messages_by_fid ( tonic:: Request :: new ( request) ) . await {
771761 Ok ( response) => Ok ( response. into_inner ( ) ) ,
772762 Err ( status) => Err ( Error :: StatusError ( status) ) ,
773763 }
@@ -824,10 +814,8 @@ impl Hub {
824814 let headers = Arc :: clone ( & headers) ;
825815 Box :: pin ( async move {
826816 let channel = channel. ok_or ( Error :: NotConnected ) ?;
827- let mut client = HubServiceClient :: new ( channel) ;
828- let request_with_headers =
829- crate :: hub:: add_custom_headers ( tonic:: Request :: new ( request) , & headers) ;
830- match client. get_on_chain_events ( request_with_headers) . await {
817+ let mut client = Self :: create_authenticated_client ( channel, Arc :: clone ( & headers) ) ;
818+ match client. get_on_chain_events ( tonic:: Request :: new ( request) ) . await {
831819 Ok ( response) => Ok ( response. into_inner ( ) ) ,
832820 Err ( status) => Err ( Error :: StatusError ( status) ) ,
833821 }
@@ -970,7 +958,7 @@ mod tests {
970958
971959 // Test that custom headers are properly added to requests
972960 let request = tonic:: Request :: new ( GetInfoRequest { } ) ;
973- let request_with_headers = hub. add_custom_headers ( request) ;
961+ let request_with_headers = crate :: hub:: add_custom_headers ( request, & hub . headers ) ;
974962
975963 let metadata = request_with_headers. metadata ( ) ;
976964 assert_eq ! ( metadata. get( "x-api-key" ) . unwrap( ) . to_str( ) . unwrap( ) , "test-key" ) ;
0 commit comments