@metamask/bridge-controller 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,11 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.0.0]
11
+
12
+ ### Added
13
+
14
+ - Mobile feature flags ([#5359](https://github.com/MetaMask/core/pull/5359))
15
+
16
+ ### Changed
17
+
18
+ - **BREAKING:** Change `BridgeController` state structure to have all fields at root of state ([#5406](https://github.com/MetaMask/core/pull/5406))
19
+ - **BREAKING:** Change `BridgeController` state defaults to `null` instead of `undefined` ([#5406](https://github.com/MetaMask/core/pull/5406))
20
+
10
21
  ## [1.0.0]
11
22
 
12
23
  ### Added
13
24
 
14
25
  - Initial release ([#5317](https://github.com/MetaMask/core/pull/5317))
15
26
 
16
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/bridge-controller@1.0.0...HEAD
27
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/bridge-controller@2.0.0...HEAD
28
+ [2.0.0]: https://github.com/MetaMask/core/compare/@metamask/bridge-controller@1.0.0...@metamask/bridge-controller@2.0.0
17
29
  [1.0.0]: https://github.com/MetaMask/core/releases/tag/@metamask/bridge-controller@1.0.0
@@ -18,15 +18,42 @@ const polling_controller_1 = require("@metamask/polling-controller");
18
18
  const utils_1 = require("@metamask/utils");
19
19
  const ethers_1 = require("ethers");
20
20
  const bridge_1 = require("./constants/bridge.cjs");
21
- const bridge_2 = require("./constants/bridge.cjs");
22
21
  const chains_1 = require("./constants/chains.cjs");
23
22
  const types_1 = require("./types.cjs");
24
23
  const balance_1 = require("./utils/balance.cjs");
25
- const bridge_3 = require("./utils/bridge.cjs");
24
+ const bridge_2 = require("./utils/bridge.cjs");
26
25
  const fetch_1 = require("./utils/fetch.cjs");
27
26
  const quote_1 = require("./utils/quote.cjs");
28
27
  const metadata = {
29
- bridgeState: {
28
+ bridgeFeatureFlags: {
29
+ persist: false,
30
+ anonymous: false,
31
+ },
32
+ quoteRequest: {
33
+ persist: false,
34
+ anonymous: false,
35
+ },
36
+ quotes: {
37
+ persist: false,
38
+ anonymous: false,
39
+ },
40
+ quotesInitialLoadTime: {
41
+ persist: false,
42
+ anonymous: false,
43
+ },
44
+ quotesLastFetched: {
45
+ persist: false,
46
+ anonymous: false,
47
+ },
48
+ quotesLoadingStatus: {
49
+ persist: false,
50
+ anonymous: false,
51
+ },
52
+ quoteFetchError: {
53
+ persist: false,
54
+ anonymous: false,
55
+ },
56
+ quotesRefreshCount: {
30
57
  persist: false,
31
58
  anonymous: false,
32
59
  },
@@ -35,14 +62,12 @@ const RESET_STATE_ABORT_MESSAGE = 'Reset controller state';
35
62
  class BridgeController extends (0, polling_controller_1.StaticIntervalPollingController)() {
36
63
  constructor({ messenger, state, clientId, getLayer1GasFee, fetchFn, }) {
37
64
  super({
38
- name: bridge_2.BRIDGE_CONTROLLER_NAME,
65
+ name: bridge_1.BRIDGE_CONTROLLER_NAME,
39
66
  metadata,
40
67
  messenger,
41
68
  state: {
42
- bridgeState: {
43
- ...(0, bridge_3.getDefaultBridgeControllerState)(),
44
- ...state,
45
- },
69
+ ...(0, bridge_2.getDefaultBridgeControllerState)(),
70
+ ...state,
46
71
  },
47
72
  });
48
73
  _BridgeController_instances.add(this);
@@ -58,22 +83,21 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
58
83
  this.stopAllPolling();
59
84
  __classPrivateFieldGet(this, _BridgeController_abortController, "f")?.abort('Quote request updated');
60
85
  const updatedQuoteRequest = {
61
- ...bridge_2.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteRequest,
86
+ ...bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteRequest,
62
87
  ...paramsToUpdate,
63
88
  };
64
89
  this.update((state) => {
65
- state.bridgeState.quoteRequest = updatedQuoteRequest;
66
- state.bridgeState.quotes = bridge_2.DEFAULT_BRIDGE_CONTROLLER_STATE.quotes;
67
- state.bridgeState.quotesLastFetched =
68
- bridge_2.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLastFetched;
69
- state.bridgeState.quotesLoadingStatus =
70
- bridge_2.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLoadingStatus;
71
- state.bridgeState.quoteFetchError =
72
- bridge_2.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;
73
- state.bridgeState.quotesRefreshCount =
74
- bridge_2.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesRefreshCount;
75
- state.bridgeState.quotesInitialLoadTime =
76
- bridge_2.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesInitialLoadTime;
90
+ state.quoteRequest = updatedQuoteRequest;
91
+ state.quotes = bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotes;
92
+ state.quotesLastFetched =
93
+ bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLastFetched;
94
+ state.quotesLoadingStatus =
95
+ bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLoadingStatus;
96
+ state.quoteFetchError = bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;
97
+ state.quotesRefreshCount =
98
+ bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesRefreshCount;
99
+ state.quotesInitialLoadTime =
100
+ bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesInitialLoadTime;
77
101
  });
78
102
  if ((0, quote_1.isValidQuoteRequest)(updatedQuoteRequest)) {
79
103
  __classPrivateFieldSet(this, _BridgeController_quotesFirstFetched, Date.now(), "f");
@@ -103,32 +127,41 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
103
127
  this.stopAllPolling();
104
128
  __classPrivateFieldGet(this, _BridgeController_abortController, "f")?.abort(RESET_STATE_ABORT_MESSAGE);
105
129
  this.update((state) => {
106
- state.bridgeState = {
107
- ...bridge_2.DEFAULT_BRIDGE_CONTROLLER_STATE,
108
- quotes: [],
109
- bridgeFeatureFlags: state.bridgeState.bridgeFeatureFlags,
110
- };
130
+ // Cannot do direct assignment to state, i.e. state = {... }, need to manually assign each field
131
+ state.quoteRequest = bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteRequest;
132
+ state.quotesInitialLoadTime =
133
+ bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesInitialLoadTime;
134
+ state.quotes = bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotes;
135
+ state.quotesLastFetched =
136
+ bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLastFetched;
137
+ state.quotesLoadingStatus =
138
+ bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLoadingStatus;
139
+ state.quoteFetchError = bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;
140
+ state.quotesRefreshCount =
141
+ bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesRefreshCount;
142
+ // Keep feature flags
143
+ const originalFeatureFlags = state.bridgeFeatureFlags;
144
+ state.bridgeFeatureFlags = originalFeatureFlags;
111
145
  });
112
146
  };
113
147
  this.setBridgeFeatureFlags = async () => {
114
148
  const bridgeFeatureFlags = await (0, fetch_1.fetchBridgeFeatureFlags)(__classPrivateFieldGet(this, _BridgeController_clientId, "f"), __classPrivateFieldGet(this, _BridgeController_fetchFn, "f"));
115
149
  this.update((state) => {
116
- state.bridgeState.bridgeFeatureFlags = bridgeFeatureFlags;
150
+ state.bridgeFeatureFlags = bridgeFeatureFlags;
117
151
  });
118
152
  this.setIntervalLength(bridgeFeatureFlags[types_1.BridgeFeatureFlagsKey.EXTENSION_CONFIG].refreshRate);
119
153
  };
120
154
  _BridgeController_fetchBridgeQuotes.set(this, async ({ networkClientId: _networkClientId, updatedQuoteRequest, }) => {
121
- const { bridgeState } = this.state;
155
+ const { bridgeFeatureFlags, quotesInitialLoadTime, quotesRefreshCount } = this.state;
122
156
  __classPrivateFieldGet(this, _BridgeController_abortController, "f")?.abort('New quote request');
123
157
  __classPrivateFieldSet(this, _BridgeController_abortController, new AbortController(), "f");
124
158
  if (updatedQuoteRequest.srcChainId === updatedQuoteRequest.destChainId) {
125
159
  return;
126
160
  }
127
161
  this.update((state) => {
128
- state.bridgeState.quotesLoadingStatus = types_1.RequestStatus.LOADING;
129
- state.bridgeState.quoteRequest = updatedQuoteRequest;
130
- state.bridgeState.quoteFetchError =
131
- bridge_2.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;
162
+ state.quotesLoadingStatus = types_1.RequestStatus.LOADING;
163
+ state.quoteRequest = updatedQuoteRequest;
164
+ state.quoteFetchError = bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;
132
165
  });
133
166
  try {
134
167
  const quotes = await (0, fetch_1.fetchBridgeQuotes)(updatedQuoteRequest,
@@ -139,8 +172,8 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
139
172
  __classPrivateFieldGet(this, _BridgeController_abortController, "f").signal, __classPrivateFieldGet(this, _BridgeController_clientId, "f"), __classPrivateFieldGet(this, _BridgeController_fetchFn, "f"));
140
173
  const quotesWithL1GasFees = await __classPrivateFieldGet(this, _BridgeController_appendL1GasFees, "f").call(this, quotes);
141
174
  this.update((state) => {
142
- state.bridgeState.quotes = quotesWithL1GasFees;
143
- state.bridgeState.quotesLoadingStatus = types_1.RequestStatus.FETCHED;
175
+ state.quotes = quotesWithL1GasFees;
176
+ state.quotesLoadingStatus = types_1.RequestStatus.FETCHED;
144
177
  });
145
178
  }
146
179
  catch (error) {
@@ -150,15 +183,15 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
150
183
  return;
151
184
  }
152
185
  this.update((state) => {
153
- state.bridgeState.quoteFetchError =
186
+ state.quoteFetchError =
154
187
  error instanceof Error ? error.message : 'Unknown error';
155
- state.bridgeState.quotesLoadingStatus = types_1.RequestStatus.ERROR;
188
+ state.quotesLoadingStatus = types_1.RequestStatus.ERROR;
156
189
  });
157
190
  console.log('Failed to fetch bridge quotes', error);
158
191
  }
159
192
  finally {
160
- const { maxRefreshCount } = bridgeState.bridgeFeatureFlags[types_1.BridgeFeatureFlagsKey.EXTENSION_CONFIG];
161
- const updatedQuotesRefreshCount = bridgeState.quotesRefreshCount + 1;
193
+ const { maxRefreshCount } = bridgeFeatureFlags[types_1.BridgeFeatureFlagsKey.EXTENSION_CONFIG];
194
+ const updatedQuotesRefreshCount = quotesRefreshCount + 1;
162
195
  // Stop polling if the maximum number of refreshes has been reached
163
196
  if (updatedQuoteRequest.insufficientBal ||
164
197
  (!updatedQuoteRequest.insufficientBal &&
@@ -168,12 +201,12 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
168
201
  // Update quote fetching stats
169
202
  const quotesLastFetched = Date.now();
170
203
  this.update((state) => {
171
- state.bridgeState.quotesInitialLoadTime =
204
+ state.quotesInitialLoadTime =
172
205
  updatedQuotesRefreshCount === 1 && __classPrivateFieldGet(this, _BridgeController_quotesFirstFetched, "f")
173
206
  ? quotesLastFetched - __classPrivateFieldGet(this, _BridgeController_quotesFirstFetched, "f")
174
- : bridgeState.quotesInitialLoadTime;
175
- state.bridgeState.quotesLastFetched = quotesLastFetched;
176
- state.bridgeState.quotesRefreshCount = updatedQuotesRefreshCount;
207
+ : quotesInitialLoadTime;
208
+ state.quotesLastFetched = quotesLastFetched;
209
+ state.quotesRefreshCount = updatedQuotesRefreshCount;
177
210
  });
178
211
  }
179
212
  });
@@ -201,7 +234,7 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
201
234
  });
202
235
  return {
203
236
  ...quoteResponse,
204
- l1GasFeesInHexWei: (0, bridge_3.sumHexes)(approvalL1GasFees, tradeL1GasFees),
237
+ l1GasFeesInHexWei: (0, bridge_2.sumHexes)(approvalL1GasFees, tradeL1GasFees),
205
238
  };
206
239
  }
207
240
  return quoteResponse;
@@ -221,7 +254,7 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
221
254
  const ethersProvider = new ethers_1.BrowserProvider(provider);
222
255
  const contract = new ethers_1.Contract(contractAddress, metamask_eth_abis_1.abiERC20, ethersProvider);
223
256
  const { address: walletAddress } = __classPrivateFieldGet(this, _BridgeController_instances, "m", _BridgeController_getSelectedAccount).call(this);
224
- const allowance = await contract.allowance(walletAddress, bridge_2.METABRIDGE_CHAIN_TO_ADDRESS_MAP[chainId]);
257
+ const allowance = await contract.allowance(walletAddress, bridge_1.METABRIDGE_CHAIN_TO_ADDRESS_MAP[chainId]);
225
258
  return allowance.toString();
226
259
  };
227
260
  this.setIntervalLength(bridge_1.REFRESH_INTERVAL_MS);
@@ -230,10 +263,10 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
230
263
  __classPrivateFieldSet(this, _BridgeController_clientId, clientId, "f");
231
264
  __classPrivateFieldSet(this, _BridgeController_fetchFn, fetchFn, "f");
232
265
  // Register action handlers
233
- this.messagingSystem.registerActionHandler(`${bridge_2.BRIDGE_CONTROLLER_NAME}:setBridgeFeatureFlags`, this.setBridgeFeatureFlags.bind(this));
234
- this.messagingSystem.registerActionHandler(`${bridge_2.BRIDGE_CONTROLLER_NAME}:updateBridgeQuoteRequestParams`, this.updateBridgeQuoteRequestParams.bind(this));
235
- this.messagingSystem.registerActionHandler(`${bridge_2.BRIDGE_CONTROLLER_NAME}:resetState`, this.resetState.bind(this));
236
- this.messagingSystem.registerActionHandler(`${bridge_2.BRIDGE_CONTROLLER_NAME}:getBridgeERC20Allowance`, this.getBridgeERC20Allowance.bind(this));
266
+ this.messagingSystem.registerActionHandler(`${bridge_1.BRIDGE_CONTROLLER_NAME}:setBridgeFeatureFlags`, this.setBridgeFeatureFlags.bind(this));
267
+ this.messagingSystem.registerActionHandler(`${bridge_1.BRIDGE_CONTROLLER_NAME}:updateBridgeQuoteRequestParams`, this.updateBridgeQuoteRequestParams.bind(this));
268
+ this.messagingSystem.registerActionHandler(`${bridge_1.BRIDGE_CONTROLLER_NAME}:resetState`, this.resetState.bind(this));
269
+ this.messagingSystem.registerActionHandler(`${bridge_1.BRIDGE_CONTROLLER_NAME}:getBridgeERC20Allowance`, this.getBridgeERC20Allowance.bind(this));
237
270
  }
238
271
  }
239
272
  exports.BridgeController = BridgeController;
@@ -1 +1 @@
1
- {"version":3,"file":"bridge-controller.cjs","sourceRoot":"","sources":["../src/bridge-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type { StateMetadata } from '@metamask/base-controller';\nimport type { ChainId } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport type { NetworkClientId } from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { TransactionParams } from '@metamask/transaction-controller';\nimport { numberToHex } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport { BrowserProvider, Contract } from 'ethers';\n\nimport type { BridgeClientId } from './constants/bridge';\nimport { REFRESH_INTERVAL_MS } from './constants/bridge';\nimport {\n BRIDGE_CONTROLLER_NAME,\n DEFAULT_BRIDGE_CONTROLLER_STATE,\n METABRIDGE_CHAIN_TO_ADDRESS_MAP,\n} from './constants/bridge';\nimport { CHAIN_IDS } from './constants/chains';\nimport {\n type L1GasFees,\n type QuoteRequest,\n type QuoteResponse,\n type TxData,\n type BridgeControllerState,\n BridgeFeatureFlagsKey,\n RequestStatus,\n} from './types';\nimport type { BridgeControllerMessenger, FetchFunction } from './types';\nimport { hasSufficientBalance } from './utils/balance';\nimport { getDefaultBridgeControllerState, sumHexes } from './utils/bridge';\nimport { fetchBridgeFeatureFlags, fetchBridgeQuotes } from './utils/fetch';\nimport { isValidQuoteRequest } from './utils/quote';\n\nconst metadata: StateMetadata<{ bridgeState: BridgeControllerState }> = {\n bridgeState: {\n persist: false,\n anonymous: false,\n },\n};\n\nconst RESET_STATE_ABORT_MESSAGE = 'Reset controller state';\n\n/** The input to start polling for the {@link BridgeController} */\ntype BridgePollingInput = {\n networkClientId: NetworkClientId;\n updatedQuoteRequest: QuoteRequest;\n};\n\nexport class BridgeController extends StaticIntervalPollingController<BridgePollingInput>()<\n typeof BRIDGE_CONTROLLER_NAME,\n { bridgeState: BridgeControllerState },\n BridgeControllerMessenger\n> {\n #abortController: AbortController | undefined;\n\n #quotesFirstFetched: number | undefined;\n\n readonly #clientId: string;\n\n readonly #getLayer1GasFee: (params: {\n transactionParams: TransactionParams;\n chainId: ChainId;\n }) => Promise<string>;\n\n readonly #fetchFn: FetchFunction;\n\n constructor({\n messenger,\n state,\n clientId,\n getLayer1GasFee,\n fetchFn,\n }: {\n messenger: BridgeControllerMessenger;\n state?: Partial<BridgeControllerState>;\n clientId: BridgeClientId;\n getLayer1GasFee: (params: {\n transactionParams: TransactionParams;\n chainId: ChainId;\n }) => Promise<string>;\n fetchFn: FetchFunction;\n }) {\n super({\n name: BRIDGE_CONTROLLER_NAME,\n metadata,\n messenger,\n state: {\n bridgeState: {\n ...getDefaultBridgeControllerState(),\n ...state,\n },\n },\n });\n\n this.setIntervalLength(REFRESH_INTERVAL_MS);\n\n this.#abortController = new AbortController();\n this.#getLayer1GasFee = getLayer1GasFee;\n this.#clientId = clientId;\n this.#fetchFn = fetchFn;\n\n // Register action handlers\n this.messagingSystem.registerActionHandler(\n `${BRIDGE_CONTROLLER_NAME}:setBridgeFeatureFlags`,\n this.setBridgeFeatureFlags.bind(this),\n );\n this.messagingSystem.registerActionHandler(\n `${BRIDGE_CONTROLLER_NAME}:updateBridgeQuoteRequestParams`,\n this.updateBridgeQuoteRequestParams.bind(this),\n );\n this.messagingSystem.registerActionHandler(\n `${BRIDGE_CONTROLLER_NAME}:resetState`,\n this.resetState.bind(this),\n );\n this.messagingSystem.registerActionHandler(\n `${BRIDGE_CONTROLLER_NAME}:getBridgeERC20Allowance`,\n this.getBridgeERC20Allowance.bind(this),\n );\n }\n\n _executePoll = async (pollingInput: BridgePollingInput) => {\n await this.#fetchBridgeQuotes(pollingInput);\n };\n\n updateBridgeQuoteRequestParams = async (\n paramsToUpdate: Partial<QuoteRequest>,\n ) => {\n this.stopAllPolling();\n this.#abortController?.abort('Quote request updated');\n\n const updatedQuoteRequest = {\n ...DEFAULT_BRIDGE_CONTROLLER_STATE.quoteRequest,\n ...paramsToUpdate,\n };\n\n this.update((state) => {\n state.bridgeState.quoteRequest = updatedQuoteRequest;\n state.bridgeState.quotes = DEFAULT_BRIDGE_CONTROLLER_STATE.quotes;\n state.bridgeState.quotesLastFetched =\n DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLastFetched;\n state.bridgeState.quotesLoadingStatus =\n DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLoadingStatus;\n state.bridgeState.quoteFetchError =\n DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;\n state.bridgeState.quotesRefreshCount =\n DEFAULT_BRIDGE_CONTROLLER_STATE.quotesRefreshCount;\n state.bridgeState.quotesInitialLoadTime =\n DEFAULT_BRIDGE_CONTROLLER_STATE.quotesInitialLoadTime;\n });\n\n if (isValidQuoteRequest(updatedQuoteRequest)) {\n this.#quotesFirstFetched = Date.now();\n const walletAddress = this.#getSelectedAccount().address;\n const srcChainIdInHex = numberToHex(updatedQuoteRequest.srcChainId);\n\n const insufficientBal =\n paramsToUpdate.insufficientBal ||\n !(await this.#hasSufficientBalance(updatedQuoteRequest));\n\n const networkClientId = this.#getSelectedNetworkClientId(srcChainIdInHex);\n this.startPolling({\n networkClientId,\n updatedQuoteRequest: {\n ...updatedQuoteRequest,\n walletAddress,\n insufficientBal,\n },\n });\n }\n };\n\n readonly #hasSufficientBalance = async (quoteRequest: QuoteRequest) => {\n const walletAddress = this.#getSelectedAccount().address;\n const srcChainIdInHex = numberToHex(quoteRequest.srcChainId);\n const provider = this.#getSelectedNetworkClient()?.provider;\n\n return (\n provider &&\n (await hasSufficientBalance(\n provider,\n walletAddress,\n quoteRequest.srcTokenAddress,\n quoteRequest.srcTokenAmount,\n srcChainIdInHex,\n ))\n );\n };\n\n resetState = () => {\n this.stopAllPolling();\n this.#abortController?.abort(RESET_STATE_ABORT_MESSAGE);\n\n this.update((state) => {\n state.bridgeState = {\n ...DEFAULT_BRIDGE_CONTROLLER_STATE,\n quotes: [],\n bridgeFeatureFlags: state.bridgeState.bridgeFeatureFlags,\n };\n });\n };\n\n setBridgeFeatureFlags = async () => {\n const bridgeFeatureFlags = await fetchBridgeFeatureFlags(\n this.#clientId,\n this.#fetchFn,\n );\n this.update((state) => {\n state.bridgeState.bridgeFeatureFlags = bridgeFeatureFlags;\n });\n this.setIntervalLength(\n bridgeFeatureFlags[BridgeFeatureFlagsKey.EXTENSION_CONFIG].refreshRate,\n );\n };\n\n readonly #fetchBridgeQuotes = async ({\n networkClientId: _networkClientId,\n updatedQuoteRequest,\n }: BridgePollingInput) => {\n const { bridgeState } = this.state;\n this.#abortController?.abort('New quote request');\n this.#abortController = new AbortController();\n if (updatedQuoteRequest.srcChainId === updatedQuoteRequest.destChainId) {\n return;\n }\n this.update((state) => {\n state.bridgeState.quotesLoadingStatus = RequestStatus.LOADING;\n state.bridgeState.quoteRequest = updatedQuoteRequest;\n state.bridgeState.quoteFetchError =\n DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;\n });\n\n try {\n const quotes = await fetchBridgeQuotes(\n updatedQuoteRequest,\n // AbortController is always defined by this line, because we assign it a few lines above,\n // not sure why Jest thinks it's not\n // Linters accurately say that it's defined\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.#abortController!.signal as AbortSignal,\n this.#clientId,\n this.#fetchFn,\n );\n\n const quotesWithL1GasFees = await this.#appendL1GasFees(quotes);\n\n this.update((state) => {\n state.bridgeState.quotes = quotesWithL1GasFees;\n state.bridgeState.quotesLoadingStatus = RequestStatus.FETCHED;\n });\n } catch (error) {\n const isAbortError = (error as Error).name === 'AbortError';\n const isAbortedDueToReset = error === RESET_STATE_ABORT_MESSAGE;\n if (isAbortedDueToReset || isAbortError) {\n return;\n }\n\n this.update((state) => {\n state.bridgeState.quoteFetchError =\n error instanceof Error ? error.message : 'Unknown error';\n state.bridgeState.quotesLoadingStatus = RequestStatus.ERROR;\n });\n console.log('Failed to fetch bridge quotes', error);\n } finally {\n const { maxRefreshCount } =\n bridgeState.bridgeFeatureFlags[BridgeFeatureFlagsKey.EXTENSION_CONFIG];\n\n const updatedQuotesRefreshCount = bridgeState.quotesRefreshCount + 1;\n // Stop polling if the maximum number of refreshes has been reached\n if (\n updatedQuoteRequest.insufficientBal ||\n (!updatedQuoteRequest.insufficientBal &&\n updatedQuotesRefreshCount >= maxRefreshCount)\n ) {\n this.stopAllPolling();\n }\n\n // Update quote fetching stats\n const quotesLastFetched = Date.now();\n this.update((state) => {\n state.bridgeState.quotesInitialLoadTime =\n updatedQuotesRefreshCount === 1 && this.#quotesFirstFetched\n ? quotesLastFetched - this.#quotesFirstFetched\n : bridgeState.quotesInitialLoadTime;\n state.bridgeState.quotesLastFetched = quotesLastFetched;\n state.bridgeState.quotesRefreshCount = updatedQuotesRefreshCount;\n });\n }\n };\n\n readonly #appendL1GasFees = async (\n quotes: QuoteResponse[],\n ): Promise<(QuoteResponse & L1GasFees)[]> => {\n return await Promise.all(\n quotes.map(async (quoteResponse) => {\n const { quote, trade, approval } = quoteResponse;\n const chainId = numberToHex(quote.srcChainId) as ChainId;\n if (\n [CHAIN_IDS.OPTIMISM.toString(), CHAIN_IDS.BASE.toString()].includes(\n chainId,\n )\n ) {\n const getTxParams = (txData: TxData) => ({\n from: txData.from,\n to: txData.to,\n value: txData.value,\n data: txData.data,\n gasLimit: txData.gasLimit?.toString(),\n });\n const approvalL1GasFees = approval\n ? await this.#getLayer1GasFee({\n transactionParams: getTxParams(approval),\n chainId,\n })\n : '0';\n const tradeL1GasFees = await this.#getLayer1GasFee({\n transactionParams: getTxParams(trade),\n chainId,\n });\n return {\n ...quoteResponse,\n l1GasFeesInHexWei: sumHexes(approvalL1GasFees, tradeL1GasFees),\n };\n }\n return quoteResponse;\n }),\n );\n };\n\n #getSelectedAccount() {\n return this.messagingSystem.call('AccountsController:getSelectedAccount');\n }\n\n #getSelectedNetworkClient() {\n const { selectedNetworkClientId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const networkClient = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n return networkClient;\n }\n\n #getSelectedNetworkClientId(chainId: Hex) {\n return this.messagingSystem.call(\n 'NetworkController:findNetworkClientIdByChainId',\n chainId,\n );\n }\n\n /**\n *\n * @param contractAddress - The address of the ERC20 token contract\n * @param chainId - The hex chain ID of the bridge network\n * @returns The atomic allowance of the ERC20 token contract\n */\n getBridgeERC20Allowance = async (\n contractAddress: string,\n chainId: Hex,\n ): Promise<string> => {\n const provider = this.#getSelectedNetworkClient()?.provider;\n if (!provider) {\n throw new Error('No provider found');\n }\n\n const ethersProvider = new BrowserProvider(provider);\n const contract = new Contract(contractAddress, abiERC20, ethersProvider);\n const { address: walletAddress } = this.#getSelectedAccount();\n const allowance: bigint = await contract.allowance(\n walletAddress,\n METABRIDGE_CHAIN_TO_ADDRESS_MAP[chainId],\n );\n return allowance.toString();\n };\n}\n"]}
1
+ {"version":3,"file":"bridge-controller.cjs","sourceRoot":"","sources":["../src/bridge-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type { StateMetadata } from '@metamask/base-controller';\nimport type { ChainId } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport type { NetworkClientId } from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { TransactionParams } from '@metamask/transaction-controller';\nimport { numberToHex } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport { BrowserProvider, Contract } from 'ethers';\n\nimport type { BridgeClientId } from './constants/bridge';\nimport {\n BRIDGE_CONTROLLER_NAME,\n DEFAULT_BRIDGE_CONTROLLER_STATE,\n METABRIDGE_CHAIN_TO_ADDRESS_MAP,\n REFRESH_INTERVAL_MS,\n} from './constants/bridge';\nimport { CHAIN_IDS } from './constants/chains';\nimport {\n type L1GasFees,\n type QuoteRequest,\n type QuoteResponse,\n type TxData,\n type BridgeControllerState,\n type BridgeControllerMessenger,\n type FetchFunction,\n BridgeFeatureFlagsKey,\n RequestStatus,\n} from './types';\nimport { hasSufficientBalance } from './utils/balance';\nimport { getDefaultBridgeControllerState, sumHexes } from './utils/bridge';\nimport { fetchBridgeFeatureFlags, fetchBridgeQuotes } from './utils/fetch';\nimport { isValidQuoteRequest } from './utils/quote';\n\nconst metadata: StateMetadata<BridgeControllerState> = {\n bridgeFeatureFlags: {\n persist: false,\n anonymous: false,\n },\n quoteRequest: {\n persist: false,\n anonymous: false,\n },\n quotes: {\n persist: false,\n anonymous: false,\n },\n quotesInitialLoadTime: {\n persist: false,\n anonymous: false,\n },\n quotesLastFetched: {\n persist: false,\n anonymous: false,\n },\n quotesLoadingStatus: {\n persist: false,\n anonymous: false,\n },\n quoteFetchError: {\n persist: false,\n anonymous: false,\n },\n quotesRefreshCount: {\n persist: false,\n anonymous: false,\n },\n};\n\nconst RESET_STATE_ABORT_MESSAGE = 'Reset controller state';\n\n/** The input to start polling for the {@link BridgeController} */\ntype BridgePollingInput = {\n networkClientId: NetworkClientId;\n updatedQuoteRequest: QuoteRequest;\n};\n\nexport class BridgeController extends StaticIntervalPollingController<BridgePollingInput>()<\n typeof BRIDGE_CONTROLLER_NAME,\n BridgeControllerState,\n BridgeControllerMessenger\n> {\n #abortController: AbortController | undefined;\n\n #quotesFirstFetched: number | undefined;\n\n readonly #clientId: string;\n\n readonly #getLayer1GasFee: (params: {\n transactionParams: TransactionParams;\n chainId: ChainId;\n }) => Promise<string>;\n\n readonly #fetchFn: FetchFunction;\n\n constructor({\n messenger,\n state,\n clientId,\n getLayer1GasFee,\n fetchFn,\n }: {\n messenger: BridgeControllerMessenger;\n state?: Partial<BridgeControllerState>;\n clientId: BridgeClientId;\n getLayer1GasFee: (params: {\n transactionParams: TransactionParams;\n chainId: ChainId;\n }) => Promise<string>;\n fetchFn: FetchFunction;\n }) {\n super({\n name: BRIDGE_CONTROLLER_NAME,\n metadata,\n messenger,\n state: {\n ...getDefaultBridgeControllerState(),\n ...state,\n },\n });\n\n this.setIntervalLength(REFRESH_INTERVAL_MS);\n\n this.#abortController = new AbortController();\n this.#getLayer1GasFee = getLayer1GasFee;\n this.#clientId = clientId;\n this.#fetchFn = fetchFn;\n\n // Register action handlers\n this.messagingSystem.registerActionHandler(\n `${BRIDGE_CONTROLLER_NAME}:setBridgeFeatureFlags`,\n this.setBridgeFeatureFlags.bind(this),\n );\n this.messagingSystem.registerActionHandler(\n `${BRIDGE_CONTROLLER_NAME}:updateBridgeQuoteRequestParams`,\n this.updateBridgeQuoteRequestParams.bind(this),\n );\n this.messagingSystem.registerActionHandler(\n `${BRIDGE_CONTROLLER_NAME}:resetState`,\n this.resetState.bind(this),\n );\n this.messagingSystem.registerActionHandler(\n `${BRIDGE_CONTROLLER_NAME}:getBridgeERC20Allowance`,\n this.getBridgeERC20Allowance.bind(this),\n );\n }\n\n _executePoll = async (pollingInput: BridgePollingInput) => {\n await this.#fetchBridgeQuotes(pollingInput);\n };\n\n updateBridgeQuoteRequestParams = async (\n paramsToUpdate: Partial<QuoteRequest>,\n ) => {\n this.stopAllPolling();\n this.#abortController?.abort('Quote request updated');\n\n const updatedQuoteRequest = {\n ...DEFAULT_BRIDGE_CONTROLLER_STATE.quoteRequest,\n ...paramsToUpdate,\n };\n\n this.update((state) => {\n state.quoteRequest = updatedQuoteRequest;\n state.quotes = DEFAULT_BRIDGE_CONTROLLER_STATE.quotes;\n state.quotesLastFetched =\n DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLastFetched;\n state.quotesLoadingStatus =\n DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLoadingStatus;\n state.quoteFetchError = DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;\n state.quotesRefreshCount =\n DEFAULT_BRIDGE_CONTROLLER_STATE.quotesRefreshCount;\n state.quotesInitialLoadTime =\n DEFAULT_BRIDGE_CONTROLLER_STATE.quotesInitialLoadTime;\n });\n\n if (isValidQuoteRequest(updatedQuoteRequest)) {\n this.#quotesFirstFetched = Date.now();\n const walletAddress = this.#getSelectedAccount().address;\n const srcChainIdInHex = numberToHex(updatedQuoteRequest.srcChainId);\n\n const insufficientBal =\n paramsToUpdate.insufficientBal ||\n !(await this.#hasSufficientBalance(updatedQuoteRequest));\n\n const networkClientId = this.#getSelectedNetworkClientId(srcChainIdInHex);\n this.startPolling({\n networkClientId,\n updatedQuoteRequest: {\n ...updatedQuoteRequest,\n walletAddress,\n insufficientBal,\n },\n });\n }\n };\n\n readonly #hasSufficientBalance = async (quoteRequest: QuoteRequest) => {\n const walletAddress = this.#getSelectedAccount().address;\n const srcChainIdInHex = numberToHex(quoteRequest.srcChainId);\n const provider = this.#getSelectedNetworkClient()?.provider;\n\n return (\n provider &&\n (await hasSufficientBalance(\n provider,\n walletAddress,\n quoteRequest.srcTokenAddress,\n quoteRequest.srcTokenAmount,\n srcChainIdInHex,\n ))\n );\n };\n\n resetState = () => {\n this.stopAllPolling();\n this.#abortController?.abort(RESET_STATE_ABORT_MESSAGE);\n\n this.update((state) => {\n // Cannot do direct assignment to state, i.e. state = {... }, need to manually assign each field\n state.quoteRequest = DEFAULT_BRIDGE_CONTROLLER_STATE.quoteRequest;\n state.quotesInitialLoadTime =\n DEFAULT_BRIDGE_CONTROLLER_STATE.quotesInitialLoadTime;\n state.quotes = DEFAULT_BRIDGE_CONTROLLER_STATE.quotes;\n state.quotesLastFetched =\n DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLastFetched;\n state.quotesLoadingStatus =\n DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLoadingStatus;\n state.quoteFetchError = DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;\n state.quotesRefreshCount =\n DEFAULT_BRIDGE_CONTROLLER_STATE.quotesRefreshCount;\n\n // Keep feature flags\n const originalFeatureFlags = state.bridgeFeatureFlags;\n state.bridgeFeatureFlags = originalFeatureFlags;\n });\n };\n\n setBridgeFeatureFlags = async () => {\n const bridgeFeatureFlags = await fetchBridgeFeatureFlags(\n this.#clientId,\n this.#fetchFn,\n );\n this.update((state) => {\n state.bridgeFeatureFlags = bridgeFeatureFlags;\n });\n this.setIntervalLength(\n bridgeFeatureFlags[BridgeFeatureFlagsKey.EXTENSION_CONFIG].refreshRate,\n );\n };\n\n readonly #fetchBridgeQuotes = async ({\n networkClientId: _networkClientId,\n updatedQuoteRequest,\n }: BridgePollingInput) => {\n const { bridgeFeatureFlags, quotesInitialLoadTime, quotesRefreshCount } =\n this.state;\n this.#abortController?.abort('New quote request');\n this.#abortController = new AbortController();\n if (updatedQuoteRequest.srcChainId === updatedQuoteRequest.destChainId) {\n return;\n }\n this.update((state) => {\n state.quotesLoadingStatus = RequestStatus.LOADING;\n state.quoteRequest = updatedQuoteRequest;\n state.quoteFetchError = DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;\n });\n\n try {\n const quotes = await fetchBridgeQuotes(\n updatedQuoteRequest,\n // AbortController is always defined by this line, because we assign it a few lines above,\n // not sure why Jest thinks it's not\n // Linters accurately say that it's defined\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.#abortController!.signal as AbortSignal,\n this.#clientId,\n this.#fetchFn,\n );\n\n const quotesWithL1GasFees = await this.#appendL1GasFees(quotes);\n\n this.update((state) => {\n state.quotes = quotesWithL1GasFees;\n state.quotesLoadingStatus = RequestStatus.FETCHED;\n });\n } catch (error) {\n const isAbortError = (error as Error).name === 'AbortError';\n const isAbortedDueToReset = error === RESET_STATE_ABORT_MESSAGE;\n if (isAbortedDueToReset || isAbortError) {\n return;\n }\n\n this.update((state) => {\n state.quoteFetchError =\n error instanceof Error ? error.message : 'Unknown error';\n state.quotesLoadingStatus = RequestStatus.ERROR;\n });\n console.log('Failed to fetch bridge quotes', error);\n } finally {\n const { maxRefreshCount } =\n bridgeFeatureFlags[BridgeFeatureFlagsKey.EXTENSION_CONFIG];\n\n const updatedQuotesRefreshCount = quotesRefreshCount + 1;\n // Stop polling if the maximum number of refreshes has been reached\n if (\n updatedQuoteRequest.insufficientBal ||\n (!updatedQuoteRequest.insufficientBal &&\n updatedQuotesRefreshCount >= maxRefreshCount)\n ) {\n this.stopAllPolling();\n }\n\n // Update quote fetching stats\n const quotesLastFetched = Date.now();\n this.update((state) => {\n state.quotesInitialLoadTime =\n updatedQuotesRefreshCount === 1 && this.#quotesFirstFetched\n ? quotesLastFetched - this.#quotesFirstFetched\n : quotesInitialLoadTime;\n state.quotesLastFetched = quotesLastFetched;\n state.quotesRefreshCount = updatedQuotesRefreshCount;\n });\n }\n };\n\n readonly #appendL1GasFees = async (\n quotes: QuoteResponse[],\n ): Promise<(QuoteResponse & L1GasFees)[]> => {\n return await Promise.all(\n quotes.map(async (quoteResponse) => {\n const { quote, trade, approval } = quoteResponse;\n const chainId = numberToHex(quote.srcChainId) as ChainId;\n if (\n [CHAIN_IDS.OPTIMISM.toString(), CHAIN_IDS.BASE.toString()].includes(\n chainId,\n )\n ) {\n const getTxParams = (txData: TxData) => ({\n from: txData.from,\n to: txData.to,\n value: txData.value,\n data: txData.data,\n gasLimit: txData.gasLimit?.toString(),\n });\n const approvalL1GasFees = approval\n ? await this.#getLayer1GasFee({\n transactionParams: getTxParams(approval),\n chainId,\n })\n : '0';\n const tradeL1GasFees = await this.#getLayer1GasFee({\n transactionParams: getTxParams(trade),\n chainId,\n });\n return {\n ...quoteResponse,\n l1GasFeesInHexWei: sumHexes(approvalL1GasFees, tradeL1GasFees),\n };\n }\n return quoteResponse;\n }),\n );\n };\n\n #getSelectedAccount() {\n return this.messagingSystem.call('AccountsController:getSelectedAccount');\n }\n\n #getSelectedNetworkClient() {\n const { selectedNetworkClientId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const networkClient = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n return networkClient;\n }\n\n #getSelectedNetworkClientId(chainId: Hex) {\n return this.messagingSystem.call(\n 'NetworkController:findNetworkClientIdByChainId',\n chainId,\n );\n }\n\n /**\n *\n * @param contractAddress - The address of the ERC20 token contract\n * @param chainId - The hex chain ID of the bridge network\n * @returns The atomic allowance of the ERC20 token contract\n */\n getBridgeERC20Allowance = async (\n contractAddress: string,\n chainId: Hex,\n ): Promise<string> => {\n const provider = this.#getSelectedNetworkClient()?.provider;\n if (!provider) {\n throw new Error('No provider found');\n }\n\n const ethersProvider = new BrowserProvider(provider);\n const contract = new Contract(contractAddress, abiERC20, ethersProvider);\n const { address: walletAddress } = this.#getSelectedAccount();\n const allowance: bigint = await contract.allowance(\n walletAddress,\n METABRIDGE_CHAIN_TO_ADDRESS_MAP[chainId],\n );\n return allowance.toString();\n };\n}\n"]}
@@ -4,8 +4,7 @@ import type { TransactionParams } from "@metamask/transaction-controller";
4
4
  import type { Hex } from "@metamask/utils";
5
5
  import type { BridgeClientId } from "./constants/bridge.cjs";
6
6
  import { BRIDGE_CONTROLLER_NAME } from "./constants/bridge.cjs";
7
- import { type QuoteRequest, type BridgeControllerState } from "./types.cjs";
8
- import type { BridgeControllerMessenger, FetchFunction } from "./types.cjs";
7
+ import { type QuoteRequest, type BridgeControllerState, type BridgeControllerMessenger, type FetchFunction } from "./types.cjs";
9
8
  /** The input to start polling for the {@link BridgeController} */
10
9
  type BridgePollingInput = {
11
10
  networkClientId: NetworkClientId;
@@ -26,9 +25,7 @@ declare const BridgeController_base: (abstract new (...args: any[]) => {
26
25
  stopPollingByPollingToken(pollingToken: string): void;
27
26
  onPollingComplete(input: BridgePollingInput, callback: (input: BridgePollingInput) => void): void;
28
27
  }) & typeof import("@metamask/base-controller").BaseController;
29
- export declare class BridgeController extends BridgeController_base<typeof BRIDGE_CONTROLLER_NAME, {
30
- bridgeState: BridgeControllerState;
31
- }, BridgeControllerMessenger> {
28
+ export declare class BridgeController extends BridgeController_base<typeof BRIDGE_CONTROLLER_NAME, BridgeControllerState, BridgeControllerMessenger> {
32
29
  #private;
33
30
  constructor({ messenger, state, clientId, getLayer1GasFee, fetchFn, }: {
34
31
  messenger: BridgeControllerMessenger;
@@ -1 +1 @@
1
- {"version":3,"file":"bridge-controller.d.cts","sourceRoot":"","sources":["../src/bridge-controller.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,mCAAmC;AAE1D,OAAO,KAAK,EAAE,eAAe,EAAE,qCAAqC;AAEpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,yCAAyC;AAE1E,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAG3C,OAAO,KAAK,EAAE,cAAc,EAAE,+BAA2B;AAEzD,OAAO,EACL,sBAAsB,EAGvB,+BAA2B;AAE5B,OAAO,EAEL,KAAK,YAAY,EAGjB,KAAK,qBAAqB,EAG3B,oBAAgB;AACjB,OAAO,KAAK,EAAE,yBAAyB,EAAE,aAAa,EAAE,oBAAgB;AAexE,kEAAkE;AAClE,KAAK,kBAAkB,GAAG;IACxB,eAAe,EAAE,eAAe,CAAC;IACjC,mBAAmB,EAAE,YAAY,CAAC;CACnC,CAAC;;;;;;;;;;;;;;;;AAEF,qBAAa,gBAAiB,SAAQ,sBACpC,OAAO,sBAAsB,EAC7B;IAAE,WAAW,EAAE,qBAAqB,CAAA;CAAE,EACtC,yBAAyB,CAC1B;;gBAca,EACV,SAAS,EACT,KAAK,EACL,QAAQ,EACR,eAAe,EACf,OAAO,GACR,EAAE;QACD,SAAS,EAAE,yBAAyB,CAAC;QACrC,KAAK,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;QACvC,QAAQ,EAAE,cAAc,CAAC;QACzB,eAAe,EAAE,CAAC,MAAM,EAAE;YACxB,iBAAiB,EAAE,iBAAiB,CAAC;YACrC,OAAO,EAAE,OAAO,CAAC;SAClB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QACtB,OAAO,EAAE,aAAa,CAAC;KACxB;IAuCD,YAAY,iBAAwB,kBAAkB,mBAEpD;IAEF,8BAA8B,mBACZ,QAAQ,YAAY,CAAC,mBA4CrC;IAmBF,UAAU,aAWR;IAEF,qBAAqB,sBAWnB;IA0IF;;;;;OAKG;IACH,uBAAuB,oBACJ,MAAM,WACd,GAAG,KACX,QAAQ,MAAM,CAAC,CAchB;CACH"}
1
+ {"version":3,"file":"bridge-controller.d.cts","sourceRoot":"","sources":["../src/bridge-controller.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,mCAAmC;AAE1D,OAAO,KAAK,EAAE,eAAe,EAAE,qCAAqC;AAEpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,yCAAyC;AAE1E,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAG3C,OAAO,KAAK,EAAE,cAAc,EAAE,+BAA2B;AACzD,OAAO,EACL,sBAAsB,EAIvB,+BAA2B;AAE5B,OAAO,EAEL,KAAK,YAAY,EAGjB,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,aAAa,EAGnB,oBAAgB;AA2CjB,kEAAkE;AAClE,KAAK,kBAAkB,GAAG;IACxB,eAAe,EAAE,eAAe,CAAC;IACjC,mBAAmB,EAAE,YAAY,CAAC;CACnC,CAAC;;;;;;;;;;;;;;;;AAEF,qBAAa,gBAAiB,SAAQ,sBACpC,OAAO,sBAAsB,EAC7B,qBAAqB,EACrB,yBAAyB,CAC1B;;gBAca,EACV,SAAS,EACT,KAAK,EACL,QAAQ,EACR,eAAe,EACf,OAAO,GACR,EAAE;QACD,SAAS,EAAE,yBAAyB,CAAC;QACrC,KAAK,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;QACvC,QAAQ,EAAE,cAAc,CAAC;QACzB,eAAe,EAAE,CAAC,MAAM,EAAE;YACxB,iBAAiB,EAAE,iBAAiB,CAAC;YACrC,OAAO,EAAE,OAAO,CAAC;SAClB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QACtB,OAAO,EAAE,aAAa,CAAC;KACxB;IAqCD,YAAY,iBAAwB,kBAAkB,mBAEpD;IAEF,8BAA8B,mBACZ,QAAQ,YAAY,CAAC,mBA2CrC;IAmBF,UAAU,aAsBR;IAEF,qBAAqB,sBAWnB;IA0IF;;;;;OAKG;IACH,uBAAuB,oBACJ,MAAM,WACd,GAAG,KACX,QAAQ,MAAM,CAAC,CAchB;CACH"}
@@ -4,8 +4,7 @@ import type { TransactionParams } from "@metamask/transaction-controller";
4
4
  import type { Hex } from "@metamask/utils";
5
5
  import type { BridgeClientId } from "./constants/bridge.mjs";
6
6
  import { BRIDGE_CONTROLLER_NAME } from "./constants/bridge.mjs";
7
- import { type QuoteRequest, type BridgeControllerState } from "./types.mjs";
8
- import type { BridgeControllerMessenger, FetchFunction } from "./types.mjs";
7
+ import { type QuoteRequest, type BridgeControllerState, type BridgeControllerMessenger, type FetchFunction } from "./types.mjs";
9
8
  /** The input to start polling for the {@link BridgeController} */
10
9
  type BridgePollingInput = {
11
10
  networkClientId: NetworkClientId;
@@ -26,9 +25,7 @@ declare const BridgeController_base: (abstract new (...args: any[]) => {
26
25
  stopPollingByPollingToken(pollingToken: string): void;
27
26
  onPollingComplete(input: BridgePollingInput, callback: (input: BridgePollingInput) => void): void;
28
27
  }) & typeof import("@metamask/base-controller").BaseController;
29
- export declare class BridgeController extends BridgeController_base<typeof BRIDGE_CONTROLLER_NAME, {
30
- bridgeState: BridgeControllerState;
31
- }, BridgeControllerMessenger> {
28
+ export declare class BridgeController extends BridgeController_base<typeof BRIDGE_CONTROLLER_NAME, BridgeControllerState, BridgeControllerMessenger> {
32
29
  #private;
33
30
  constructor({ messenger, state, clientId, getLayer1GasFee, fetchFn, }: {
34
31
  messenger: BridgeControllerMessenger;
@@ -1 +1 @@
1
- {"version":3,"file":"bridge-controller.d.mts","sourceRoot":"","sources":["../src/bridge-controller.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,mCAAmC;AAE1D,OAAO,KAAK,EAAE,eAAe,EAAE,qCAAqC;AAEpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,yCAAyC;AAE1E,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAG3C,OAAO,KAAK,EAAE,cAAc,EAAE,+BAA2B;AAEzD,OAAO,EACL,sBAAsB,EAGvB,+BAA2B;AAE5B,OAAO,EAEL,KAAK,YAAY,EAGjB,KAAK,qBAAqB,EAG3B,oBAAgB;AACjB,OAAO,KAAK,EAAE,yBAAyB,EAAE,aAAa,EAAE,oBAAgB;AAexE,kEAAkE;AAClE,KAAK,kBAAkB,GAAG;IACxB,eAAe,EAAE,eAAe,CAAC;IACjC,mBAAmB,EAAE,YAAY,CAAC;CACnC,CAAC;;;;;;;;;;;;;;;;AAEF,qBAAa,gBAAiB,SAAQ,sBACpC,OAAO,sBAAsB,EAC7B;IAAE,WAAW,EAAE,qBAAqB,CAAA;CAAE,EACtC,yBAAyB,CAC1B;;gBAca,EACV,SAAS,EACT,KAAK,EACL,QAAQ,EACR,eAAe,EACf,OAAO,GACR,EAAE;QACD,SAAS,EAAE,yBAAyB,CAAC;QACrC,KAAK,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;QACvC,QAAQ,EAAE,cAAc,CAAC;QACzB,eAAe,EAAE,CAAC,MAAM,EAAE;YACxB,iBAAiB,EAAE,iBAAiB,CAAC;YACrC,OAAO,EAAE,OAAO,CAAC;SAClB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QACtB,OAAO,EAAE,aAAa,CAAC;KACxB;IAuCD,YAAY,iBAAwB,kBAAkB,mBAEpD;IAEF,8BAA8B,mBACZ,QAAQ,YAAY,CAAC,mBA4CrC;IAmBF,UAAU,aAWR;IAEF,qBAAqB,sBAWnB;IA0IF;;;;;OAKG;IACH,uBAAuB,oBACJ,MAAM,WACd,GAAG,KACX,QAAQ,MAAM,CAAC,CAchB;CACH"}
1
+ {"version":3,"file":"bridge-controller.d.mts","sourceRoot":"","sources":["../src/bridge-controller.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,mCAAmC;AAE1D,OAAO,KAAK,EAAE,eAAe,EAAE,qCAAqC;AAEpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,yCAAyC;AAE1E,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAG3C,OAAO,KAAK,EAAE,cAAc,EAAE,+BAA2B;AACzD,OAAO,EACL,sBAAsB,EAIvB,+BAA2B;AAE5B,OAAO,EAEL,KAAK,YAAY,EAGjB,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,aAAa,EAGnB,oBAAgB;AA2CjB,kEAAkE;AAClE,KAAK,kBAAkB,GAAG;IACxB,eAAe,EAAE,eAAe,CAAC;IACjC,mBAAmB,EAAE,YAAY,CAAC;CACnC,CAAC;;;;;;;;;;;;;;;;AAEF,qBAAa,gBAAiB,SAAQ,sBACpC,OAAO,sBAAsB,EAC7B,qBAAqB,EACrB,yBAAyB,CAC1B;;gBAca,EACV,SAAS,EACT,KAAK,EACL,QAAQ,EACR,eAAe,EACf,OAAO,GACR,EAAE;QACD,SAAS,EAAE,yBAAyB,CAAC;QACrC,KAAK,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;QACvC,QAAQ,EAAE,cAAc,CAAC;QACzB,eAAe,EAAE,CAAC,MAAM,EAAE;YACxB,iBAAiB,EAAE,iBAAiB,CAAC;YACrC,OAAO,EAAE,OAAO,CAAC;SAClB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QACtB,OAAO,EAAE,aAAa,CAAC;KACxB;IAqCD,YAAY,iBAAwB,kBAAkB,mBAEpD;IAEF,8BAA8B,mBACZ,QAAQ,YAAY,CAAC,mBA2CrC;IAmBF,UAAU,aAsBR;IAEF,qBAAqB,sBAWnB;IA0IF;;;;;OAKG;IACH,uBAAuB,oBACJ,MAAM,WACd,GAAG,KACX,QAAQ,MAAM,CAAC,CAchB;CACH"}
@@ -14,8 +14,7 @@ import { abiERC20 } from "@metamask/metamask-eth-abis";
14
14
  import { StaticIntervalPollingController } from "@metamask/polling-controller";
15
15
  import { numberToHex } from "@metamask/utils";
16
16
  import { BrowserProvider, Contract } from "ethers";
17
- import { REFRESH_INTERVAL_MS } from "./constants/bridge.mjs";
18
- import { BRIDGE_CONTROLLER_NAME, DEFAULT_BRIDGE_CONTROLLER_STATE, METABRIDGE_CHAIN_TO_ADDRESS_MAP } from "./constants/bridge.mjs";
17
+ import { BRIDGE_CONTROLLER_NAME, DEFAULT_BRIDGE_CONTROLLER_STATE, METABRIDGE_CHAIN_TO_ADDRESS_MAP, REFRESH_INTERVAL_MS } from "./constants/bridge.mjs";
19
18
  import { CHAIN_IDS } from "./constants/chains.mjs";
20
19
  import { BridgeFeatureFlagsKey, RequestStatus } from "./types.mjs";
21
20
  import { hasSufficientBalance } from "./utils/balance.mjs";
@@ -23,7 +22,35 @@ import { getDefaultBridgeControllerState, sumHexes } from "./utils/bridge.mjs";
23
22
  import { fetchBridgeFeatureFlags, fetchBridgeQuotes } from "./utils/fetch.mjs";
24
23
  import { isValidQuoteRequest } from "./utils/quote.mjs";
25
24
  const metadata = {
26
- bridgeState: {
25
+ bridgeFeatureFlags: {
26
+ persist: false,
27
+ anonymous: false,
28
+ },
29
+ quoteRequest: {
30
+ persist: false,
31
+ anonymous: false,
32
+ },
33
+ quotes: {
34
+ persist: false,
35
+ anonymous: false,
36
+ },
37
+ quotesInitialLoadTime: {
38
+ persist: false,
39
+ anonymous: false,
40
+ },
41
+ quotesLastFetched: {
42
+ persist: false,
43
+ anonymous: false,
44
+ },
45
+ quotesLoadingStatus: {
46
+ persist: false,
47
+ anonymous: false,
48
+ },
49
+ quoteFetchError: {
50
+ persist: false,
51
+ anonymous: false,
52
+ },
53
+ quotesRefreshCount: {
27
54
  persist: false,
28
55
  anonymous: false,
29
56
  },
@@ -36,10 +63,8 @@ export class BridgeController extends StaticIntervalPollingController() {
36
63
  metadata,
37
64
  messenger,
38
65
  state: {
39
- bridgeState: {
40
- ...getDefaultBridgeControllerState(),
41
- ...state,
42
- },
66
+ ...getDefaultBridgeControllerState(),
67
+ ...state,
43
68
  },
44
69
  });
45
70
  _BridgeController_instances.add(this);
@@ -59,17 +84,16 @@ export class BridgeController extends StaticIntervalPollingController() {
59
84
  ...paramsToUpdate,
60
85
  };
61
86
  this.update((state) => {
62
- state.bridgeState.quoteRequest = updatedQuoteRequest;
63
- state.bridgeState.quotes = DEFAULT_BRIDGE_CONTROLLER_STATE.quotes;
64
- state.bridgeState.quotesLastFetched =
87
+ state.quoteRequest = updatedQuoteRequest;
88
+ state.quotes = DEFAULT_BRIDGE_CONTROLLER_STATE.quotes;
89
+ state.quotesLastFetched =
65
90
  DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLastFetched;
66
- state.bridgeState.quotesLoadingStatus =
91
+ state.quotesLoadingStatus =
67
92
  DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLoadingStatus;
68
- state.bridgeState.quoteFetchError =
69
- DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;
70
- state.bridgeState.quotesRefreshCount =
93
+ state.quoteFetchError = DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;
94
+ state.quotesRefreshCount =
71
95
  DEFAULT_BRIDGE_CONTROLLER_STATE.quotesRefreshCount;
72
- state.bridgeState.quotesInitialLoadTime =
96
+ state.quotesInitialLoadTime =
73
97
  DEFAULT_BRIDGE_CONTROLLER_STATE.quotesInitialLoadTime;
74
98
  });
75
99
  if (isValidQuoteRequest(updatedQuoteRequest)) {
@@ -100,32 +124,41 @@ export class BridgeController extends StaticIntervalPollingController() {
100
124
  this.stopAllPolling();
101
125
  __classPrivateFieldGet(this, _BridgeController_abortController, "f")?.abort(RESET_STATE_ABORT_MESSAGE);
102
126
  this.update((state) => {
103
- state.bridgeState = {
104
- ...DEFAULT_BRIDGE_CONTROLLER_STATE,
105
- quotes: [],
106
- bridgeFeatureFlags: state.bridgeState.bridgeFeatureFlags,
107
- };
127
+ // Cannot do direct assignment to state, i.e. state = {... }, need to manually assign each field
128
+ state.quoteRequest = DEFAULT_BRIDGE_CONTROLLER_STATE.quoteRequest;
129
+ state.quotesInitialLoadTime =
130
+ DEFAULT_BRIDGE_CONTROLLER_STATE.quotesInitialLoadTime;
131
+ state.quotes = DEFAULT_BRIDGE_CONTROLLER_STATE.quotes;
132
+ state.quotesLastFetched =
133
+ DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLastFetched;
134
+ state.quotesLoadingStatus =
135
+ DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLoadingStatus;
136
+ state.quoteFetchError = DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;
137
+ state.quotesRefreshCount =
138
+ DEFAULT_BRIDGE_CONTROLLER_STATE.quotesRefreshCount;
139
+ // Keep feature flags
140
+ const originalFeatureFlags = state.bridgeFeatureFlags;
141
+ state.bridgeFeatureFlags = originalFeatureFlags;
108
142
  });
109
143
  };
110
144
  this.setBridgeFeatureFlags = async () => {
111
145
  const bridgeFeatureFlags = await fetchBridgeFeatureFlags(__classPrivateFieldGet(this, _BridgeController_clientId, "f"), __classPrivateFieldGet(this, _BridgeController_fetchFn, "f"));
112
146
  this.update((state) => {
113
- state.bridgeState.bridgeFeatureFlags = bridgeFeatureFlags;
147
+ state.bridgeFeatureFlags = bridgeFeatureFlags;
114
148
  });
115
149
  this.setIntervalLength(bridgeFeatureFlags[BridgeFeatureFlagsKey.EXTENSION_CONFIG].refreshRate);
116
150
  };
117
151
  _BridgeController_fetchBridgeQuotes.set(this, async ({ networkClientId: _networkClientId, updatedQuoteRequest, }) => {
118
- const { bridgeState } = this.state;
152
+ const { bridgeFeatureFlags, quotesInitialLoadTime, quotesRefreshCount } = this.state;
119
153
  __classPrivateFieldGet(this, _BridgeController_abortController, "f")?.abort('New quote request');
120
154
  __classPrivateFieldSet(this, _BridgeController_abortController, new AbortController(), "f");
121
155
  if (updatedQuoteRequest.srcChainId === updatedQuoteRequest.destChainId) {
122
156
  return;
123
157
  }
124
158
  this.update((state) => {
125
- state.bridgeState.quotesLoadingStatus = RequestStatus.LOADING;
126
- state.bridgeState.quoteRequest = updatedQuoteRequest;
127
- state.bridgeState.quoteFetchError =
128
- DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;
159
+ state.quotesLoadingStatus = RequestStatus.LOADING;
160
+ state.quoteRequest = updatedQuoteRequest;
161
+ state.quoteFetchError = DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;
129
162
  });
130
163
  try {
131
164
  const quotes = await fetchBridgeQuotes(updatedQuoteRequest,
@@ -136,8 +169,8 @@ export class BridgeController extends StaticIntervalPollingController() {
136
169
  __classPrivateFieldGet(this, _BridgeController_abortController, "f").signal, __classPrivateFieldGet(this, _BridgeController_clientId, "f"), __classPrivateFieldGet(this, _BridgeController_fetchFn, "f"));
137
170
  const quotesWithL1GasFees = await __classPrivateFieldGet(this, _BridgeController_appendL1GasFees, "f").call(this, quotes);
138
171
  this.update((state) => {
139
- state.bridgeState.quotes = quotesWithL1GasFees;
140
- state.bridgeState.quotesLoadingStatus = RequestStatus.FETCHED;
172
+ state.quotes = quotesWithL1GasFees;
173
+ state.quotesLoadingStatus = RequestStatus.FETCHED;
141
174
  });
142
175
  }
143
176
  catch (error) {
@@ -147,15 +180,15 @@ export class BridgeController extends StaticIntervalPollingController() {
147
180
  return;
148
181
  }
149
182
  this.update((state) => {
150
- state.bridgeState.quoteFetchError =
183
+ state.quoteFetchError =
151
184
  error instanceof Error ? error.message : 'Unknown error';
152
- state.bridgeState.quotesLoadingStatus = RequestStatus.ERROR;
185
+ state.quotesLoadingStatus = RequestStatus.ERROR;
153
186
  });
154
187
  console.log('Failed to fetch bridge quotes', error);
155
188
  }
156
189
  finally {
157
- const { maxRefreshCount } = bridgeState.bridgeFeatureFlags[BridgeFeatureFlagsKey.EXTENSION_CONFIG];
158
- const updatedQuotesRefreshCount = bridgeState.quotesRefreshCount + 1;
190
+ const { maxRefreshCount } = bridgeFeatureFlags[BridgeFeatureFlagsKey.EXTENSION_CONFIG];
191
+ const updatedQuotesRefreshCount = quotesRefreshCount + 1;
159
192
  // Stop polling if the maximum number of refreshes has been reached
160
193
  if (updatedQuoteRequest.insufficientBal ||
161
194
  (!updatedQuoteRequest.insufficientBal &&
@@ -165,12 +198,12 @@ export class BridgeController extends StaticIntervalPollingController() {
165
198
  // Update quote fetching stats
166
199
  const quotesLastFetched = Date.now();
167
200
  this.update((state) => {
168
- state.bridgeState.quotesInitialLoadTime =
201
+ state.quotesInitialLoadTime =
169
202
  updatedQuotesRefreshCount === 1 && __classPrivateFieldGet(this, _BridgeController_quotesFirstFetched, "f")
170
203
  ? quotesLastFetched - __classPrivateFieldGet(this, _BridgeController_quotesFirstFetched, "f")
171
- : bridgeState.quotesInitialLoadTime;
172
- state.bridgeState.quotesLastFetched = quotesLastFetched;
173
- state.bridgeState.quotesRefreshCount = updatedQuotesRefreshCount;
204
+ : quotesInitialLoadTime;
205
+ state.quotesLastFetched = quotesLastFetched;
206
+ state.quotesRefreshCount = updatedQuotesRefreshCount;
174
207
  });
175
208
  }
176
209
  });