Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add getNetworkClientById #1562

Merged
merged 6 commits into from
Jul 31, 2023
Merged
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
61 changes: 59 additions & 2 deletions packages/network-controller/src/NetworkController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ export class NetworkController extends BaseControllerV2<
*
* @returns The list of known network clients.
*/
getNetworkClientsById(): AutoManagedBuiltInNetworkClientRegistry &
getNetworkClientRegistry(): AutoManagedBuiltInNetworkClientRegistry &
AutoManagedCustomNetworkClientRegistry {
const autoManagedNetworkClientRegistry =
this.#ensureAutoManagedNetworkClientRegistryPopulated();
Expand All @@ -641,6 +641,63 @@ export class NetworkController extends BaseControllerV2<
);
}

/**
* Returns the Infura network client with the given ID.
*
* @param infuraNetworkClientId - An Infura network client ID.
* @returns The Infura network client.
* @throws If an Infura network client does not exist with the given ID.
*/
getNetworkClientById(
infuraNetworkClientId: BuiltInNetworkClientId,
): AutoManagedNetworkClient<InfuraNetworkClientConfiguration>;

/**
* Returns the custom network client with the given ID.
*
* @param customNetworkClientId - A custom network client ID.
* @returns The custom network client.
* @throws If a custom network client does not exist with the given ID.
*/
getNetworkClientById(
customNetworkClientId: CustomNetworkClientId,
): AutoManagedNetworkClient<CustomNetworkClientConfiguration>;

getNetworkClientById(
networkClientId: NetworkClientId,
): AutoManagedNetworkClient<NetworkClientConfiguration> {
if (!networkClientId) {
throw new Error('No network client ID was provided.');
}

const autoManagedNetworkClientRegistry =
this.#ensureAutoManagedNetworkClientRegistryPopulated();

if (isInfuraProviderType(networkClientId)) {
const infuraNetworkClient =
autoManagedNetworkClientRegistry[NetworkClientType.Infura][
networkClientId
];
if (!infuraNetworkClient) {
throw new Error(
`No Infura network client was found with the ID "${networkClientId}".`,
);
}
return infuraNetworkClient;
}

const customNetworkClient =
autoManagedNetworkClientRegistry[NetworkClientType.Custom][
networkClientId
];
if (!customNetworkClient) {
throw new Error(
`No custom network client was found with the ID "${networkClientId}".`,
);
}
return customNetworkClient;
}

/**
* Executes a series of steps to apply the changes to the provider config:
*
Expand Down Expand Up @@ -1177,7 +1234,7 @@ export class NetworkController extends BaseControllerV2<
/**
* Before accessing or switching the network, the registry of network clients
* needs to be populated. Otherwise, `#applyNetworkSelection` and
* `getNetworkClients` will throw an error. This method checks to see if the
* `getNetworkClientRegistry` will throw an error. This method checks to see if the
* population step has happened yet, and if not, makes it happen.
*
* @returns The populated network client registry.
Expand Down
165 changes: 124 additions & 41 deletions packages/network-controller/tests/NetworkController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1101,7 +1101,96 @@ describe('NetworkController', () => {
});
});

describe('getNetworkClientsById', () => {
describe('getNetworkClientById', () => {
describe('If passed an existing networkClientId', () => {
it('returns a valid built-in Infura NetworkClient', async () => {
await withController(
{ infuraProjectId: 'some-infura-project-id' },
async ({ controller }) => {
const fakeNetworkClient = buildFakeClient();
mockCreateNetworkClient().mockReturnValue(fakeNetworkClient);

const networkClientRegistry = controller.getNetworkClientRegistry();
const networkClient = controller.getNetworkClientById(
NetworkType.mainnet,
);

expect(networkClient).toBe(
networkClientRegistry[NetworkType.mainnet],
);
},
);
});

it('returns a valid custom NetworkClient', async () => {
await withController(
{
state: {
networkConfigurations: {
testNetworkConfigurationId: {
rpcUrl: 'https://mock-rpc-url',
chainId: '0x1337',
ticker: 'ABC',
id: 'testNetworkConfigurationId',
},
},
},
infuraProjectId: 'some-infura-project-id',
},
async ({ controller }) => {
const fakeNetworkClient = buildFakeClient();
mockCreateNetworkClient().mockReturnValue(fakeNetworkClient);

const networkClientRegistry = controller.getNetworkClientRegistry();
const networkClient = controller.getNetworkClientById(
'testNetworkConfigurationId',
);

expect(networkClient).toBe(
networkClientRegistry.testNetworkConfigurationId,
);
},
);
});
});

describe('If passed a networkClientId that does not match a NetworkClient in the registry', () => {
it('throws an error', async () => {
await withController(
{ infuraProjectId: 'some-infura-project-id' },
async ({ controller }) => {
const fakeNetworkClient = buildFakeClient();
mockCreateNetworkClient().mockReturnValue(fakeNetworkClient);

expect(() =>
controller.getNetworkClientById('non-existent-network-id'),
).toThrow(
'No custom network client was found with the ID "non-existent-network-id',
);
},
);
});
});

describe('If not passed a networkClientId', () => {
it('throws an error', async () => {
await withController(
{ infuraProjectId: 'some-infura-project-id' },
async ({ controller }) => {
const fakeNetworkClient = buildFakeClient();
mockCreateNetworkClient().mockReturnValue(fakeNetworkClient);

expect(() =>
// @ts-expect-error Intentionally passing invalid type
controller.getNetworkClientById(),
).toThrow('No network client ID was provided.');
},
);
});
});
});

describe('getNetworkClientRegistry', () => {
describe('if neither a provider config nor network configurations are present in state', () => {
it('returns the built-in Infura networks by default', async () => {
await withController(
Expand All @@ -1110,8 +1199,8 @@ describe('NetworkController', () => {
const fakeNetworkClient = buildFakeClient();
mockCreateNetworkClient().mockReturnValue(fakeNetworkClient);

const networkClientsById = controller.getNetworkClientsById();
const simplifiedNetworkClients = Object.entries(networkClientsById)
const networkClients = controller.getNetworkClientRegistry();
const simplifiedNetworkClients = Object.entries(networkClients)
.map(
([networkClientId, networkClient]) =>
[networkClientId, networkClient.configuration] as const,
Expand Down Expand Up @@ -1198,8 +1287,8 @@ describe('NetworkController', () => {
const fakeNetworkClient = buildFakeClient();
mockCreateNetworkClient().mockReturnValue(fakeNetworkClient);

const networkClientsById = controller.getNetworkClientsById();
const simplifiedNetworkClients = Object.entries(networkClientsById)
const networkClients = controller.getNetworkClientRegistry();
const simplifiedNetworkClients = Object.entries(networkClients)
.map(
([networkClientId, networkClient]) =>
[networkClientId, networkClient.configuration] as const,
Expand Down Expand Up @@ -1271,7 +1360,7 @@ describe('NetworkController', () => {
},
],
]);
for (const networkClient of Object.values(networkClientsById)) {
for (const networkClient of Object.values(networkClients)) {
expect(networkClient.provider).toHaveProperty('sendAsync');
expect(networkClient.blockTracker).toHaveProperty(
'checkForLatestBlock',
Expand Down Expand Up @@ -1299,8 +1388,8 @@ describe('NetworkController', () => {
const fakeNetworkClient = buildFakeClient();
mockCreateNetworkClient().mockReturnValue(fakeNetworkClient);

const networkClientsById = controller.getNetworkClientsById();
const simplifiedNetworkClients = Object.entries(networkClientsById)
const networkClients = controller.getNetworkClientRegistry();
const simplifiedNetworkClients = Object.entries(networkClients)
.map(
([networkClientId, networkClient]) =>
[networkClientId, networkClient.configuration] as const,
Expand Down Expand Up @@ -1389,10 +1478,8 @@ describe('NetworkController', () => {
const fakeNetworkClient = buildFakeClient();
mockCreateNetworkClient().mockReturnValue(fakeNetworkClient);

const networkClientsById = controller.getNetworkClientsById();
const simplifiedNetworkClients = Object.entries(
networkClientsById,
)
const networkClients = controller.getNetworkClientRegistry();
const simplifiedNetworkClients = Object.entries(networkClients)
.map(
([networkClientId, networkClient]) =>
[networkClientId, networkClient.configuration] as const,
Expand Down Expand Up @@ -1495,10 +1582,8 @@ describe('NetworkController', () => {
const fakeNetworkClient = buildFakeClient();
mockCreateNetworkClient().mockReturnValue(fakeNetworkClient);

const networkClientsById = controller.getNetworkClientsById();
const simplifiedNetworkClients = Object.entries(
networkClientsById,
)
const networkClients = controller.getNetworkClientRegistry();
const simplifiedNetworkClients = Object.entries(networkClients)
.map(
([networkClientId, networkClient]) =>
[networkClientId, networkClient.configuration] as const,
Expand Down Expand Up @@ -1593,10 +1678,8 @@ describe('NetworkController', () => {
const fakeNetworkClient = buildFakeClient();
mockCreateNetworkClient().mockReturnValue(fakeNetworkClient);

const networkClientsById = controller.getNetworkClientsById();
const simplifiedNetworkClients = Object.entries(
networkClientsById,
)
const networkClients = controller.getNetworkClientRegistry();
const simplifiedNetworkClients = Object.entries(networkClients)
.map(
([networkClientId, networkClient]) =>
[networkClientId, networkClient.configuration] as const,
Expand Down Expand Up @@ -1693,10 +1776,8 @@ describe('NetworkController', () => {
const fakeNetworkClient = buildFakeClient();
mockCreateNetworkClient().mockReturnValue(fakeNetworkClient);

const networkClientsById = controller.getNetworkClientsById();
const simplifiedNetworkClients = Object.entries(
networkClientsById,
)
const networkClients = controller.getNetworkClientRegistry();
const simplifiedNetworkClients = Object.entries(networkClients)
.map(
([networkClientId, networkClient]) =>
[networkClientId, networkClient.configuration] as const,
Expand Down Expand Up @@ -4501,9 +4582,9 @@ describe('NetworkController', () => {
},
);

const networkClientsById = controller.getNetworkClientsById();
expect(Object.keys(networkClientsById)).toHaveLength(6);
expect(networkClientsById).toMatchObject({
const networkClients = controller.getNetworkClientRegistry();
expect(Object.keys(networkClients)).toHaveLength(6);
expect(networkClients).toMatchObject({
'AAAA-AAAA-AAAA-AAAA': expect.objectContaining({
configuration: {
chainId: toHex(111),
Expand Down Expand Up @@ -5008,7 +5089,7 @@ describe('NetworkController', () => {
})
.mockReturnValue(newCustomNetworkClient);
const networkClientToDestroy = Object.values(
controller.getNetworkClientsById(),
controller.getNetworkClientRegistry(),
).find(({ configuration }) => {
return (
configuration.type === NetworkClientType.Custom &&
Expand All @@ -5031,10 +5112,10 @@ describe('NetworkController', () => {
},
);

const networkClientsById = controller.getNetworkClientsById();
const networkClients = controller.getNetworkClientRegistry();
expect(networkClientToDestroy.destroy).toHaveBeenCalled();
expect(Object.keys(networkClientsById)).toHaveLength(6);
expect(networkClientsById).not.toMatchObject({
expect(Object.keys(networkClients)).toHaveLength(6);
expect(networkClients).not.toMatchObject({
[oldRpcUrl]: expect.objectContaining({
configuration: {
chainId: toHex(111),
Expand Down Expand Up @@ -5086,9 +5167,9 @@ describe('NetworkController', () => {
},
);

const networkClientsById = controller.getNetworkClientsById();
expect(Object.keys(networkClientsById)).toHaveLength(6);
expect(networkClientsById).toMatchObject({
const networkClients = controller.getNetworkClientRegistry();
expect(Object.keys(networkClients)).toHaveLength(6);
expect(networkClients).toMatchObject({
'AAAA-AAAA-AAAA-AAAA': expect.objectContaining({
configuration: {
chainId: toHex(999),
Expand Down Expand Up @@ -5129,7 +5210,8 @@ describe('NetworkController', () => {
type: NetworkClientType.Custom,
})
.mockReturnValue(newCustomNetworkClient);
const networkClientsBefore = controller.getNetworkClientsById();
const networkClientsBefore =
controller.getNetworkClientRegistry();

await controller.upsertNetworkConfiguration(
{
Expand All @@ -5143,7 +5225,8 @@ describe('NetworkController', () => {
},
);

const networkClientsAfter = controller.getNetworkClientsById();
const networkClientsAfter =
controller.getNetworkClientRegistry();
expect(networkClientsBefore).toStrictEqual(networkClientsAfter);
},
);
Expand Down Expand Up @@ -5477,7 +5560,7 @@ describe('NetworkController', () => {
})
.mockReturnValue(buildFakeClient());
const networkClientToDestroy = Object.values(
controller.getNetworkClientsById(),
controller.getNetworkClientRegistry(),
).find(({ configuration }) => {
return (
configuration.type === NetworkClientType.Custom &&
Expand All @@ -5491,7 +5574,7 @@ describe('NetworkController', () => {
controller.removeNetworkConfiguration('AAAA-AAAA-AAAA-AAAA');

expect(networkClientToDestroy.destroy).toHaveBeenCalled();
expect(controller.getNetworkClientsById()).not.toMatchObject({
expect(controller.getNetworkClientRegistry()).not.toMatchObject({
'https://test.network': expect.objectContaining({
configuration: {
chainId: toHex(111),
Expand Down Expand Up @@ -5519,16 +5602,16 @@ describe('NetworkController', () => {
it('does not update the network client registry', async () => {
await withController(async ({ controller }) => {
mockCreateNetworkClientWithDefaultsForBuiltInNetworkClients();
const networkClientsById = controller.getNetworkClientsById();
const networkClients = controller.getNetworkClientRegistry();

try {
controller.removeNetworkConfiguration('NONEXISTENT');
} catch {
// ignore error (it is tested elsewhere)
}

expect(controller.getNetworkClientsById()).toStrictEqual(
networkClientsById,
expect(controller.getNetworkClientRegistry()).toStrictEqual(
networkClients,
);
});
});
Expand Down