Skip to content

Commit 7eaabfb

Browse files
authored
Switch to a given network if adding a network that is already added. (#3154)
2 parents 1e2ecce + 0ebefb5 commit 7eaabfb

File tree

2 files changed

+88
-14
lines changed

2 files changed

+88
-14
lines changed

background/services/provider-bridge/index.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,25 @@ export default class ProviderBridgeService extends BaseService<Events> {
532532

533533
this.addNetworkRequestId += 1
534534

535+
const [rawChainData, address, siteTitle, favicon] = params
536+
const validatedData = validateAddEthereumChainParameter(
537+
rawChainData as AddEthereumChainParameter
538+
)
539+
540+
const supportedNetwork =
541+
await this.internalEthereumProviderService.getTrackedNetworkByChainId(
542+
validatedData.chainId
543+
)
544+
545+
if (supportedNetwork) {
546+
// If the network is already added - just switch to it.
547+
return await this.internalEthereumProviderService.routeSafeRPCRequest(
548+
method,
549+
params,
550+
origin
551+
)
552+
}
553+
535554
const window = await showExtensionPopup(
536555
AllowedQueryParamPage.addNewChain,
537556
{ requestId: id.toString() }
@@ -543,11 +562,6 @@ export default class ProviderBridgeService extends BaseService<Events> {
543562
}
544563
})
545564

546-
const [rawChainData, address, siteTitle, favicon] = params
547-
const validatedData = validateAddEthereumChainParameter(
548-
rawChainData as AddEthereumChainParameter
549-
)
550-
551565
const userConfirmation = new Promise<void>((resolve, reject) => {
552566
this.#pendingAddNetworkRequests[id] = {
553567
resolve,

background/services/provider-bridge/tests/index.unit.test.ts

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@ import {
44
} from "@tallyho/provider-bridge-shared"
55
import sinon from "sinon"
66
import browser from "webextension-polyfill"
7+
// FIXME Pull the appropriate dependency to this package.json so we're not
8+
// FIXME relying on weird cross-package dependencies.
79
// eslint-disable-next-line import/no-extraneous-dependencies
810
import { waitFor } from "@testing-library/dom"
11+
import * as popupUtils from "../show-popup"
912
import * as featureFlags from "../../../features"
10-
import { wait } from "../../../lib/utils"
1113
import { createProviderBridgeService } from "../../../tests/factories"
1214
import { AddEthereumChainParameter } from "../../internal-ethereum-provider"
1315
import ProviderBridgeService from "../index"
1416
import { validateAddEthereumChainParameter } from "../utils"
17+
import { ETHEREUM } from "../../../constants"
1518

1619
const WINDOW = {
1720
focused: true,
@@ -133,6 +136,7 @@ describe("ProviderBridgeService", () => {
133136
const { enablingPermission } = BASE_DATA
134137

135138
jest.spyOn(featureFlags, "isEnabled").mockImplementation(() => true)
139+
const showPopupSpy = jest.spyOn(popupUtils, "default")
136140

137141
const request = providerBridgeService.routeContentScriptRPCRequest(
138142
{
@@ -143,21 +147,24 @@ describe("ProviderBridgeService", () => {
143147
enablingPermission.origin
144148
)
145149

146-
// eslint-disable-next-line @typescript-eslint/dot-notation
147-
const IEP = providerBridgeService["internalEthereumProviderService"]
150+
// @ts-expect-error private access to reference the service
151+
const IEP = providerBridgeService.internalEthereumProviderService
148152
const spy = jest.spyOn(IEP, "routeSafeRPCRequest")
149153

150-
await wait(0) // wait next tick to setup popup
154+
// wait until popup is set up
155+
await waitFor(() => expect(showPopupSpy).toHaveBeenCalled())
151156

152157
const validatedPayload = validateAddEthereumChainParameter(
153158
params[0] as AddEthereumChainParameter
154159
)
155160

156-
expect(providerBridgeService.getNewCustomRPCDetails("0")).toEqual({
157-
...validatedPayload,
158-
favicon: "favicon.png",
159-
siteTitle: "some site",
160-
})
161+
await waitFor(() =>
162+
expect(providerBridgeService.getNewCustomRPCDetails("0")).toEqual({
163+
...validatedPayload,
164+
favicon: "favicon.png",
165+
siteTitle: "some site",
166+
})
167+
)
161168

162169
expect(spy).not.toHaveBeenCalled()
163170
providerBridgeService.handleAddNetworkRequest("0", true)
@@ -172,5 +179,58 @@ describe("ProviderBridgeService", () => {
172179

173180
await expect(request).resolves.toEqual(null) // resolves without errors
174181
})
182+
183+
it("should skip user confirmation if the network already exists", async () => {
184+
const params = [
185+
{
186+
chainId: "1",
187+
chainName: "Ethereum Mainnet",
188+
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
189+
iconUrl: undefined,
190+
rpcUrls: ["booyan"],
191+
blockExplorerUrls: ["https://etherscan.io"],
192+
},
193+
"0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
194+
"some site",
195+
"favicon.png",
196+
]
197+
198+
const { enablingPermission } = BASE_DATA
199+
200+
jest.spyOn(featureFlags, "isEnabled").mockImplementation(() => true)
201+
const showPopupSpy = jest.spyOn(popupUtils, "default")
202+
203+
const internalEthereumProvider =
204+
// @ts-expect-error private access to reference the service
205+
providerBridgeService.internalEthereumProviderService
206+
jest
207+
.spyOn(internalEthereumProvider, "getTrackedNetworkByChainId")
208+
.mockImplementation(() => Promise.resolve(ETHEREUM))
209+
const internalEthereumProviderSpy = jest.spyOn(
210+
internalEthereumProvider,
211+
"routeSafeRPCRequest"
212+
)
213+
214+
const request = providerBridgeService.routeContentScriptRPCRequest(
215+
{
216+
...enablingPermission,
217+
},
218+
"wallet_addEthereumChain",
219+
params,
220+
enablingPermission.origin
221+
)
222+
223+
await waitFor(() =>
224+
expect(internalEthereumProviderSpy).toHaveBeenCalledWith(
225+
"wallet_addEthereumChain",
226+
params,
227+
BASE_DATA.origin
228+
)
229+
)
230+
231+
// expect no popup
232+
expect(showPopupSpy).not.toHaveBeenCalled()
233+
await expect(request).resolves.toEqual(null) // resolves without errors
234+
})
175235
})
176236
})

0 commit comments

Comments
 (0)