Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import sanitizeUrl, {
compareSanitizedUrl,
} from '../../../../../util/sanitizeUrl';
import onlyKeepHost from '../../../../../util/onlyKeepHost';
import { isPublicEndpointUrl } from '../../../../../core/Engine/controllers/network-controller/utils';
import { themeAppearanceLight } from '../../../../../constants/storage';
import CustomNetwork from './CustomNetworkView/CustomNetwork';
import Button, {
Expand All @@ -55,6 +56,7 @@ import { selectIsRpcFailoverEnabled } from '../../../../../selectors/featureFlag
import { regex } from '../../../../../../app/util/regex';
import { NetworksViewSelectorsIDs } from '../../../../../../e2e/selectors/Settings/NetworksView.selectors';
import { isSafeChainId, toHex } from '@metamask/controller-utils';
import { hexToNumber } from '@metamask/utils';
import { CustomDefaultNetworkIDs } from '../../../../../../e2e/selectors/Onboarding/CustomDefaultNetwork.selectors';
import { updateIncomingTransactions } from '../../../../../util/transaction-controller';
import { withMetricsAwareness } from '../../../../../components/hooks/useMetrics';
Expand Down Expand Up @@ -90,7 +92,8 @@ import Tag from '../../../../../component-library/components/Tags/Tag/Tag';
import { CellComponentSelectorsIDs } from '../../../../../../e2e/selectors/wallet/CellComponent.selectors';
import stripProtocol from '../../../../../util/stripProtocol';
import stripKeyFromInfuraUrl from '../../../../../util/stripKeyFromInfuraUrl';
import { MetaMetrics } from '../../../../../core/Analytics';
import { MetaMetrics, MetaMetricsEvents } from '../../../../../core/Analytics';
import { MetricsEventBuilder } from '../../../../../core/Analytics/MetricsEventBuilder';
import {
addItemToChainIdList,
removeItemFromChainIdList,
Expand Down Expand Up @@ -546,6 +549,7 @@ export class NetworkSettings extends PureComponent {
isCustomMainnet,
shouldNetworkSwitchPopToWallet,
navigation,
trackRpcUpdateFromBanner,
}) => {
const { NetworkController } = Engine.context;

Expand Down Expand Up @@ -583,6 +587,37 @@ export class NetworkSettings extends PureComponent {
}
: undefined,
);

// Track RPC update from network connection banner
if (trackRpcUpdateFromBanner) {
const newRpcEndpoint =
networkConfig.rpcEndpoints[networkConfig.defaultRpcEndpointIndex];
const oldRpcEndpoint =
existingNetwork.rpcEndpoints?.[
existingNetwork.defaultRpcEndpointIndex ?? 0
];

const chainIdAsDecimal = hexToNumber(chainId);

const sanitizeRpcUrl = (url) =>
isPublicEndpointUrl(url, infuraProjectId)
? onlyKeepHost(url)
: 'custom';

this.props.metrics.trackEvent(
MetricsEventBuilder.createEventBuilder(
MetaMetricsEvents.NetworkConnectionBannerRpcUpdated,
)
.addProperties({
chain_id_caip: `eip155:${chainIdAsDecimal}`,
from_rpc_domain: oldRpcEndpoint?.url
? sanitizeRpcUrl(oldRpcEndpoint.url)
: 'unknown',
to_rpc_domain: sanitizeRpcUrl(newRpcEndpoint.url),
})
.build(),
);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Undefined Endpoint Crashes Application

The newRpcEndpoint can be undefined if networkConfig.defaultRpcEndpointIndex is -1 (when RPC URL is not found in array via findIndex), causing a runtime error when accessing .url on line 616. The code accesses newRpcEndpoint.url without null-checking, while oldRpcEndpoint.url is properly guarded with optional chaining. This will crash if the RPC URL lookup fails.

Fix in Cursor Fix in Web

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

newRpcEndpoint.url is guaranteed to exist because:

  1. rpcUrl is validated at form level before submission
  2. rpcUrl is found via findIndex in rpcUrls array (line 559)
  3. defaultRpcEndpointIndex can never be -1 after form validation

} else {
await NetworkController.addNetwork({
...networkConfig,
Expand Down Expand Up @@ -628,6 +663,9 @@ export class NetworkSettings extends PureComponent {

const shouldNetworkSwitchPopToWallet =
route.params?.shouldNetworkSwitchPopToWallet ?? true;

const trackRpcUpdateFromBanner =
route.params?.trackRpcUpdateFromBanner ?? false;
// Check if CTA is disabled
const isCtaDisabled =
!enableAction || this.disabledByChainId() || this.disabledBySymbol();
Expand Down Expand Up @@ -703,6 +741,7 @@ export class NetworkSettings extends PureComponent {
networkType,
networkUrl,
showNetworkOnboarding,
trackRpcUpdateFromBanner,
});
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ describe('useNetworkConnectionBanner', () => {
network: rpcUrl,
shouldNetworkSwitchPopToWallet: false,
shouldShowPopularNetworks: false,
trackRpcUpdateFromBanner: true,
},
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ const useNetworkConnectionBanner = (): {
network: rpcUrl,
shouldNetworkSwitchPopToWallet: false,
shouldShowPopularNetworks: false,
trackRpcUpdateFromBanner: true,
});

trackEvent(
Expand Down
4 changes: 4 additions & 0 deletions app/core/Analytics/MetaMetrics.events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,7 @@ enum EVENT_NAME {
// NETWORK CONNECTION BANNER
NETWORK_CONNECTION_BANNER_SHOWN = 'Network Connection Banner Shown',
NETWORK_CONNECTION_BANNER_UPDATE_RPC_CLICKED = 'Network Connection Banner Update RPC Clicked',
NetworkConnectionBannerRpcUpdated = 'Network Connection Banner RPC Updated',

// Deep Link Modal Viewed
DEEP_LINK_PRIVATE_MODAL_VIEWED = 'Deep Link Private Modal Viewed',
Expand Down Expand Up @@ -1329,6 +1330,9 @@ const events = {
NETWORK_CONNECTION_BANNER_UPDATE_RPC_CLICKED: generateOpt(
EVENT_NAME.NETWORK_CONNECTION_BANNER_UPDATE_RPC_CLICKED,
),
NetworkConnectionBannerRpcUpdated: generateOpt(
EVENT_NAME.NetworkConnectionBannerRpcUpdated,
),

// Multi SRP
IMPORT_SECRET_RECOVERY_PHRASE_CLICKED: generateOpt(
Expand Down
Loading