Skip to content
Draft
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
11 changes: 11 additions & 0 deletions packages/network-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Add a `getInfuraAuthToken` option to `NetworkController`, which presents the token it returns as a bearer credential in the `Authorization` header on requests to the built-in Infura endpoints ([#10252](https://github.com/MetaMask/core/pull/10252))
- The token is read immediately before each request, so a refreshed token is used by the next request.
- Only the built-in Infura endpoints reached through `infuraProjectId` present the token. Custom RPC endpoints and failover endpoints never do, even when hosted by Infura, so a user supplied Infura key is never paired with it.
- Because the token identifies the user, the caller decides when to withhold it. Resolve with `undefined` rather than rejecting in the states where no token can be read, such as while the wallet is locked.
- Add a `getRequestHeaders` option to `RpcServiceOptions`, which can be supplied per endpoint through `NetworkControllerOptions.getRpcServiceOptions` ([#10252](https://github.com/MetaMask/core/pull/10252))
- The callback runs immediately before each HTTP request, including each retry attempt, so headers that change over the lifetime of a network client are read again rather than captured once.
- Its headers take precedence over those in `fetchOptions` and those passed to `request`. Because an RPC service is bound to a single endpoint, they only ever reach that endpoint.
- If the callback rejects, the request attempt fails with that error. Resolve with `undefined` to make the request without the headers instead.

### Changed

- Bump `uuid` from `^8.3.2` to `^9.0.1` ([#10117](https://github.com/MetaMask/core/pull/10117))
Expand Down
23 changes: 23 additions & 0 deletions packages/network-controller/src/NetworkController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,21 @@ export type NetworkControllerOptions = {
getBlockTrackerOptions?: (
rpcEndpointUrl: string,
) => Omit<PollingBlockTrackerOptions, 'provider'>;
/**
* Returns the token to present as a bearer credential on requests to the
* built-in Infura endpoints, or `undefined` to make them without one.
*
* Called immediately before each request, so a refreshed token is used by the
* next request. Only the built-in Infura endpoints reached through
* `infuraProjectId` present the token; custom RPC endpoints and failover
* endpoints never do, even when hosted by Infura.
*
* Because the token identifies the user, the caller is responsible for
* withholding it when the user has not consented to being identified, and for
* resolving with `undefined` rather than rejecting in the states where no
* token can be read, such as while the wallet is locked.
*/
getInfuraAuthToken?: () => Promise<string | undefined>;
/**
* Configuration for the "RPC Service Unavailable" and "RPC Service Degraded"
* analytics events the controller emits via the `AnalyticsController:trackEvent`
Expand Down Expand Up @@ -1305,6 +1320,8 @@ export class NetworkController extends BaseController<

readonly #getBlockTrackerOptions: NetworkControllerOptions['getBlockTrackerOptions'];

readonly #getInfuraAuthToken: NetworkControllerOptions['getInfuraAuthToken'];

readonly #analyticsOptions: ResolvedNetworkControllerAnalyticsOptions;

#networkConfigurationsByNetworkClientId: Map<
Expand All @@ -1328,6 +1345,7 @@ export class NetworkController extends BaseController<
log,
getRpcServiceOptions,
getBlockTrackerOptions,
getInfuraAuthToken,
analyticsOptions,
} = options;
const initialState = {
Expand Down Expand Up @@ -1372,6 +1390,7 @@ export class NetworkController extends BaseController<
this.#log = log;
this.#getRpcServiceOptions = getRpcServiceOptions;
this.#getBlockTrackerOptions = getBlockTrackerOptions;
this.#getInfuraAuthToken = getInfuraAuthToken;
this.#analyticsOptions = {
isRpcEndpointUrlPublic: (): boolean => false,
rpcServiceEventsSampleRate: 0,
Expand Down Expand Up @@ -2865,6 +2884,7 @@ export class NetworkController extends BaseController<
},
getRpcServiceOptions: this.#getRpcServiceOptions,
getBlockTrackerOptions: this.#getBlockTrackerOptions,
getInfuraAuthToken: this.#getInfuraAuthToken,
messenger: this.messenger,
rpcFailoverMode: this.#rpcFailoverMode,
logger: this.#log,
Expand All @@ -2884,6 +2904,7 @@ export class NetworkController extends BaseController<
},
getRpcServiceOptions: this.#getRpcServiceOptions,
getBlockTrackerOptions: this.#getBlockTrackerOptions,
getInfuraAuthToken: this.#getInfuraAuthToken,
messenger: this.messenger,
rpcFailoverMode: this.#rpcFailoverMode,
logger: this.#log,
Expand Down Expand Up @@ -3050,6 +3071,7 @@ export class NetworkController extends BaseController<
},
getRpcServiceOptions: this.#getRpcServiceOptions,
getBlockTrackerOptions: this.#getBlockTrackerOptions,
getInfuraAuthToken: this.#getInfuraAuthToken,
messenger: this.messenger,
rpcFailoverMode: this.#rpcFailoverMode,
logger: this.#log,
Expand All @@ -3069,6 +3091,7 @@ export class NetworkController extends BaseController<
},
getRpcServiceOptions: this.#getRpcServiceOptions,
getBlockTrackerOptions: this.#getBlockTrackerOptions,
getInfuraAuthToken: this.#getInfuraAuthToken,
messenger: this.messenger,
rpcFailoverMode: this.#rpcFailoverMode,
logger: this.#log,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ const UNINITIALIZED_TARGET = { __UNINITIALIZED__: true };
* options. See {@link NetworkControllerOptions.getRpcServiceOptions}.
* @param args.getBlockTrackerOptions - Factory for constructing block tracker
* options. See {@link NetworkControllerOptions.getBlockTrackerOptions}.
* @param args.getInfuraAuthToken - Returns the token to present as a bearer
* credential on requests to a built-in Infura endpoint.
* @param args.messenger - The network controller messenger.
* @param args.rpcFailoverMode - The RPC failover mode to apply: `disabled`,
* `enabled` (divert to the failover URLs when the primary is unavailable), or
Expand All @@ -95,6 +97,7 @@ export function createAutoManagedNetworkClient<
PollingBlockTrackerOptions,
'provider'
> => ({}),
getInfuraAuthToken,
messenger,
rpcFailoverMode: givenRpcFailoverMode,
logger,
Expand All @@ -107,6 +110,7 @@ export function createAutoManagedNetworkClient<
getBlockTrackerOptions?: (
rpcEndpointUrl: string,
) => Omit<PollingBlockTrackerOptions, 'provider'>;
getInfuraAuthToken?: () => Promise<string | undefined>;
messenger: NetworkControllerMessenger;
rpcFailoverMode: RpcFailoverMode;
logger?: Logger;
Expand All @@ -120,6 +124,7 @@ export function createAutoManagedNetworkClient<
configuration: networkClientConfiguration,
getRpcServiceOptions,
getBlockTrackerOptions,
getInfuraAuthToken,
messenger,
rpcFailoverMode,
logger,
Expand Down
Loading