@@ -26,8 +26,10 @@ import { CHAIN_IDS, TEST_CHAINS } from '../../../shared/constants/network';
2626import { stripHexPrefix } from '../../../shared/modules/hexstring-utils' ;
2727import { getMethodDataAsync } from '../../../shared/lib/four-byte' ;
2828import {
29- initializeChainlistDomains ,
30- isChainlistDomain ,
29+ getSafeChainsListFromCacheOnly ,
30+ getIsMetaMaskInfuraEndpointUrl ,
31+ getIsQuicknodeEndpointUrl ,
32+ KNOWN_CUSTOM_ENDPOINT_URLS ,
3133} from '../../../shared/lib/network-utils' ;
3234
3335/**
@@ -477,12 +479,120 @@ export function getConversionRatesForNativeAsset({
477479 return conversionRateResult ;
478480}
479481
480- // Re-export chainlist domain functions for backward compatibility
481- // These were moved to shared/lib/network-utils.ts
482- export {
483- initializeChainlistDomains as initializeRpcProviderDomains ,
484- isChainlistDomain as isKnownDomain ,
485- } ;
482+ // Cache for known domains from eth-chainlist
483+ let knownDomainsSet : Set < string > | null = null ;
484+ let initPromise : Promise < void > | null = null ;
485+
486+ /**
487+ * Extracts the hostname from a URL.
488+ *
489+ * @param url - The URL to extract the hostname from.
490+ * @returns The lowercase hostname, or null if the URL is invalid.
491+ */
492+ function extractHostname ( url : string ) : string | null {
493+ try {
494+ const parsedUrl = new URL ( url ) ;
495+ return parsedUrl . hostname . toLowerCase ( ) ;
496+ } catch {
497+ return null ;
498+ }
499+ }
500+
501+ /**
502+ * Initialize the set of known domains from the eth-chainlist cache.
503+ * This should be called once at startup in the background context.
504+ *
505+ * @returns A promise that resolves when initialization is complete.
506+ */
507+ export async function initializeRpcProviderDomains ( ) : Promise < void > {
508+ if ( initPromise ) {
509+ return initPromise ;
510+ }
511+
512+ initPromise = ( async ( ) => {
513+ try {
514+ const chainsList = await getSafeChainsListFromCacheOnly ( ) ;
515+ knownDomainsSet = new Set < string > ( ) ;
516+
517+ for ( const chain of chainsList ) {
518+ if ( chain . rpc && Array . isArray ( chain . rpc ) ) {
519+ for ( const rpcUrl of chain . rpc ) {
520+ const hostname = extractHostname ( rpcUrl ) ;
521+ if ( hostname ) {
522+ knownDomainsSet . add ( hostname ) ;
523+ }
524+ }
525+ }
526+ }
527+ } catch ( error ) {
528+ console . error ( 'Error initializing known domains:' , error ) ;
529+ knownDomainsSet = new Set < string > ( ) ;
530+ }
531+ } ) ( ) ;
532+
533+ return initPromise ;
534+ }
535+
536+ /**
537+ * Check if a domain is in the known domains list (eth-chainlist).
538+ *
539+ * @param domain - The domain to check.
540+ * @returns True if the domain is found in the chainlist cache.
541+ */
542+ export function isKnownDomain ( domain : string ) : boolean {
543+ if ( ! domain ) {
544+ return false ;
545+ }
546+ return knownDomainsSet ?. has ( domain . toLowerCase ( ) ) ?? false ;
547+ }
548+
549+ /**
550+ * Check if an RPC endpoint URL's domain is defined in eth-chainlist.
551+ *
552+ * @param endpointUrl - The URL of the RPC endpoint.
553+ * @returns True if the endpoint's domain is in the chainlist.
554+ */
555+ function isChainlistEndpointUrl ( endpointUrl : string ) : boolean {
556+ const hostname = extractHostname ( endpointUrl ) ;
557+ if ( ! hostname ) {
558+ return false ;
559+ }
560+ return isKnownDomain ( hostname ) ;
561+ }
562+
563+ /**
564+ * Some URLs that users add as networks refer to private servers, and we do not
565+ * want to report these in Segment (or any other data collection service). This
566+ * function returns whether the given RPC endpoint is safe to share.
567+ *
568+ * This function is only available in the background context where the chainlist
569+ * domains are initialized. UI should call the background API method instead.
570+ *
571+ * @param endpointUrl - The URL of the endpoint.
572+ * @param infuraProjectId - Our Infura project ID.
573+ * @returns True if the endpoint URL is safe to share with external data
574+ * collection services, false otherwise.
575+ */
576+ export function isPublicEndpointUrl (
577+ endpointUrl : string ,
578+ infuraProjectId : string ,
579+ ) : boolean {
580+ const isMetaMaskInfuraEndpointUrl = getIsMetaMaskInfuraEndpointUrl (
581+ endpointUrl ,
582+ infuraProjectId ,
583+ ) ;
584+ const isQuicknodeEndpointUrl = getIsQuicknodeEndpointUrl ( endpointUrl ) ;
585+ const isKnownCustomEndpointUrl =
586+ KNOWN_CUSTOM_ENDPOINT_URLS . includes ( endpointUrl ) ;
587+ const isChainlistEndpoint = isChainlistEndpointUrl ( endpointUrl ) ;
588+
589+ return (
590+ isMetaMaskInfuraEndpointUrl ||
591+ isQuicknodeEndpointUrl ||
592+ isKnownCustomEndpointUrl ||
593+ isChainlistEndpoint
594+ ) ;
595+ }
486596
487597/**
488598 * Extracts the domain from an RPC endpoint URL with privacy considerations
@@ -518,12 +628,12 @@ export function extractRpcDomain(
518628 }
519629 }
520630
521- // Use the provided test domains if available, otherwise use isChainlistDomain
631+ // Use the provided test domains if available, otherwise use isKnownDomain
522632 if ( knownDomainsForTesting ) {
523633 if ( knownDomainsForTesting . has ( url . hostname . toLowerCase ( ) ) ) {
524634 return url . hostname . toLowerCase ( ) ;
525635 }
526- } else if ( isChainlistDomain ( url . hostname ) ) {
636+ } else if ( isKnownDomain ( url . hostname ) ) {
527637 return url . hostname . toLowerCase ( ) ;
528638 }
529639
0 commit comments