diff --git a/app/components/Views/Settings/NetworksSettings/NetworkSettings/index.js b/app/components/Views/Settings/NetworksSettings/NetworkSettings/index.js
index 5f70f739948..3f8c7089b8f 100644
--- a/app/components/Views/Settings/NetworksSettings/NetworkSettings/index.js
+++ b/app/components/Views/Settings/NetworksSettings/NetworkSettings/index.js
@@ -447,6 +447,7 @@ export class NetworkSettings extends PureComponent {
blockExplorerUrls: [],
selectedRpcEndpointIndex: 0,
blockExplorerUrl: undefined,
+ blockExplorerUrlForm: undefined,
nickname: undefined,
chainId: undefined,
ticker: undefined,
@@ -1288,10 +1289,21 @@ export class NetworkSettings extends PureComponent {
};
onBlockExplorerItemAdd = async (url) => {
+ // If URL is empty or undefined, return early
if (!url) {
return;
}
+ // Check if the URL already exists in blockExplorerUrls
+ const { blockExplorerUrls } = this.state;
+ const urlExists = blockExplorerUrls.includes(url);
+
+ if (urlExists) {
+ // If the URL already exists, return early
+ return;
+ }
+
+ // If the URL doesn't exist, proceed with adding it
await this.setState((prevState) => ({
blockExplorerUrls: [...prevState.blockExplorerUrls, url],
}));
@@ -1351,6 +1363,7 @@ export class NetworkSettings extends PureComponent {
onBlockExplorerUrlChange = async (url) => {
const { addMode } = this.state;
await this.setState({
+ blockExplorerUrlForm: url,
blockExplorerUrl: url,
});
@@ -1486,7 +1499,10 @@ export class NetworkSettings extends PureComponent {
};
closeAddBlockExplorerRpcForm = () => {
- this.setState({ showAddBlockExplorerForm: { isVisible: false } });
+ this.setState({
+ showAddBlockExplorerForm: { isVisible: false },
+ blockExplorerUrlForm: undefined,
+ });
};
closeRpcModal = () => {
@@ -1603,6 +1619,7 @@ export class NetworkSettings extends PureComponent {
rpcUrlForm,
rpcNameForm,
rpcName,
+ blockExplorerUrlForm,
} = this.state;
const { route, networkConfigurations } = this.props;
const isCustomMainnet = route.params?.isCustomMainnet;
@@ -2204,6 +2221,7 @@ export class NetworkSettings extends PureComponent {
ref={this.inputBlockExplorerURL}
style={inputStyle}
autoCapitalize={'none'}
+ value={blockExplorerUrlForm}
autoCorrect={false}
onChangeText={this.onBlockExplorerUrlChange}
placeholder={strings(
@@ -2214,23 +2232,30 @@ export class NetworkSettings extends PureComponent {
onSubmitEditing={this.toggleNetworkDetailsModal}
keyboardAppearance={themeAppearance}
/>
- {blockExplorerUrl && !isUrl(blockExplorerUrl) && (
-
-
- {strings('app_settings.invalid_block_explorer_url')}
-
-
- )}
+ {blockExplorerUrl &&
+ (!isUrl(blockExplorerUrl) ||
+ blockExplorerUrls.includes(blockExplorerUrlForm)) && (
+
+
+ {strings('app_settings.invalid_block_explorer_url')}
+
+
+ )}
+
{
- this.onBlockExplorerItemAdd(blockExplorerUrl);
+ this.onBlockExplorerItemAdd(blockExplorerUrlForm);
}}
width={ButtonWidthTypes.Full}
labelTextVariant={TextVariant.DisplayMD}
- isDisabled={!blockExplorerUrl || !isUrl(blockExplorerUrl)}
+ isDisabled={
+ !blockExplorerUrl ||
+ !blockExplorerUrlForm ||
+ !isUrl(blockExplorerUrl)
+ }
/>
diff --git a/app/components/Views/Settings/NetworksSettings/NetworkSettings/index.test.tsx b/app/components/Views/Settings/NetworksSettings/NetworkSettings/index.test.tsx
index 1ecffde7034..c9f2e148817 100644
--- a/app/components/Views/Settings/NetworksSettings/NetworkSettings/index.test.tsx
+++ b/app/components/Views/Settings/NetworksSettings/NetworkSettings/index.test.tsx
@@ -781,6 +781,47 @@ describe('NetworkSettings', () => {
);
});
+ it('should not add an empty Block Explorer URL and should return early', async () => {
+ const instance = wrapper.instance();
+
+ // Initially, blockExplorerUrls should be empty
+ expect(wrapper.state('blockExplorerUrls').length).toBe(0);
+
+ // Open Block Explorer form modal and attempt to add an empty URL
+ instance.openAddBlockExplorerForm();
+ await instance.onBlockExplorerItemAdd('');
+
+ // Ensure the state is not updated with the empty URL
+ expect(wrapper.state('blockExplorerUrls').length).toBe(0);
+ expect(wrapper.state('blockExplorerUrl')).toBeUndefined();
+ });
+
+ it('should not add an existing Block Explorer URL and should return early', async () => {
+ const instance = wrapper.instance();
+
+ // Set initial state with an existing block explorer URL
+ await instance.setState({
+ blockExplorerUrls: ['https://existing-blockexplorer.com'],
+ });
+
+ // Ensure the initial state contains the existing URL
+ expect(wrapper.state('blockExplorerUrls').length).toBe(1);
+ expect(wrapper.state('blockExplorerUrls')[0]).toBe(
+ 'https://existing-blockexplorer.com',
+ );
+
+ // Attempt to add the same URL again
+ await instance.onBlockExplorerItemAdd(
+ 'https://existing-blockexplorer.com',
+ );
+
+ // Ensure the state remains unchanged and no duplicate is added
+ expect(wrapper.state('blockExplorerUrls').length).toBe(1);
+ expect(wrapper.state('blockExplorerUrls')[0]).toBe(
+ 'https://existing-blockexplorer.com',
+ );
+ });
+
it('should call validateRpcAndChainId when chainId and rpcUrl are set', async () => {
const instance = wrapper.instance();
const validateRpcAndChainIdSpy = jest.spyOn(