@metamask/bridge-controller 1.0.0 → 3.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 +21 -1
- package/dist/bridge-controller.cjs +85 -51
- package/dist/bridge-controller.cjs.map +1 -1
- package/dist/bridge-controller.d.cts +2 -5
- package/dist/bridge-controller.d.cts.map +1 -1
- package/dist/bridge-controller.d.mts +2 -5
- package/dist/bridge-controller.d.mts.map +1 -1
- package/dist/bridge-controller.mjs +72 -38
- package/dist/bridge-controller.mjs.map +1 -1
- package/dist/constants/bridge.cjs +15 -14
- package/dist/constants/bridge.cjs.map +1 -1
- package/dist/constants/bridge.d.cts +6 -0
- package/dist/constants/bridge.d.cts.map +1 -1
- package/dist/constants/bridge.d.mts +6 -0
- package/dist/constants/bridge.d.mts.map +1 -1
- package/dist/constants/bridge.mjs +14 -13
- package/dist/constants/bridge.mjs.map +1 -1
- package/dist/types.cjs +2 -0
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +24 -18
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +24 -18
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +2 -0
- package/dist/types.mjs.map +1 -1
- package/dist/utils/balance.cjs +10 -7
- package/dist/utils/balance.cjs.map +1 -1
- package/dist/utils/balance.d.cts +3 -2
- package/dist/utils/balance.d.cts.map +1 -1
- package/dist/utils/balance.d.mts +3 -2
- package/dist/utils/balance.d.mts.map +1 -1
- package/dist/utils/balance.mjs +8 -5
- package/dist/utils/balance.mjs.map +1 -1
- package/dist/utils/bridge.cjs +2 -2
- package/dist/utils/bridge.cjs.map +1 -1
- package/dist/utils/bridge.d.cts.map +1 -1
- package/dist/utils/bridge.d.mts.map +1 -1
- package/dist/utils/bridge.mjs +1 -1
- package/dist/utils/bridge.mjs.map +1 -1
- package/dist/utils/fetch.cjs +14 -22
- package/dist/utils/fetch.cjs.map +1 -1
- package/dist/utils/fetch.d.cts.map +1 -1
- package/dist/utils/fetch.d.mts.map +1 -1
- package/dist/utils/fetch.mjs +17 -25
- package/dist/utils/fetch.mjs.map +1 -1
- package/dist/utils/validators.cjs +92 -102
- package/dist/utils/validators.cjs.map +1 -1
- package/dist/utils/validators.d.cts +5 -28
- package/dist/utils/validators.d.cts.map +1 -1
- package/dist/utils/validators.d.mts +5 -28
- package/dist/utils/validators.d.mts.map +1 -1
- package/dist/utils/validators.mjs +90 -99
- package/dist/utils/validators.mjs.map +1 -1
- package/package.json +9 -4
package/CHANGELOG.md
CHANGED
|
@@ -7,11 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [3.0.0]
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **BREAKING:** Switch over from `ethers` at v6 to `@ethersproject` packages at v5.7.0 for mobile compatibility ([#5416](https://github.com/MetaMask/core/pull/5416))
|
|
15
|
+
- Improve `BridgeController` API response validation readability by using `@metamask/superstruct` ([#5408](https://github.com/MetaMask/core/pull/5408))
|
|
16
|
+
|
|
17
|
+
## [2.0.0]
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- Mobile feature flags ([#5359](https://github.com/MetaMask/core/pull/5359))
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- **BREAKING:** Change `BridgeController` state structure to have all fields at root of state ([#5406](https://github.com/MetaMask/core/pull/5406))
|
|
26
|
+
- **BREAKING:** Change `BridgeController` state defaults to `null` instead of `undefined` ([#5406](https://github.com/MetaMask/core/pull/5406))
|
|
27
|
+
|
|
10
28
|
## [1.0.0]
|
|
11
29
|
|
|
12
30
|
### Added
|
|
13
31
|
|
|
14
32
|
- Initial release ([#5317](https://github.com/MetaMask/core/pull/5317))
|
|
15
33
|
|
|
16
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/bridge-controller@
|
|
34
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/bridge-controller@3.0.0...HEAD
|
|
35
|
+
[3.0.0]: https://github.com/MetaMask/core/compare/@metamask/bridge-controller@2.0.0...@metamask/bridge-controller@3.0.0
|
|
36
|
+
[2.0.0]: https://github.com/MetaMask/core/compare/@metamask/bridge-controller@1.0.0...@metamask/bridge-controller@2.0.0
|
|
17
37
|
[1.0.0]: https://github.com/MetaMask/core/releases/tag/@metamask/bridge-controller@1.0.0
|
|
@@ -13,20 +13,48 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
13
13
|
var _BridgeController_instances, _BridgeController_abortController, _BridgeController_quotesFirstFetched, _BridgeController_clientId, _BridgeController_getLayer1GasFee, _BridgeController_fetchFn, _BridgeController_hasSufficientBalance, _BridgeController_fetchBridgeQuotes, _BridgeController_appendL1GasFees, _BridgeController_getSelectedAccount, _BridgeController_getSelectedNetworkClient, _BridgeController_getSelectedNetworkClientId;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.BridgeController = void 0;
|
|
16
|
+
const contracts_1 = require("@ethersproject/contracts");
|
|
17
|
+
const providers_1 = require("@ethersproject/providers");
|
|
16
18
|
const metamask_eth_abis_1 = require("@metamask/metamask-eth-abis");
|
|
17
19
|
const polling_controller_1 = require("@metamask/polling-controller");
|
|
18
20
|
const utils_1 = require("@metamask/utils");
|
|
19
|
-
const ethers_1 = require("ethers");
|
|
20
21
|
const bridge_1 = require("./constants/bridge.cjs");
|
|
21
|
-
const bridge_2 = require("./constants/bridge.cjs");
|
|
22
22
|
const chains_1 = require("./constants/chains.cjs");
|
|
23
23
|
const types_1 = require("./types.cjs");
|
|
24
24
|
const balance_1 = require("./utils/balance.cjs");
|
|
25
|
-
const
|
|
25
|
+
const bridge_2 = require("./utils/bridge.cjs");
|
|
26
26
|
const fetch_1 = require("./utils/fetch.cjs");
|
|
27
27
|
const quote_1 = require("./utils/quote.cjs");
|
|
28
28
|
const metadata = {
|
|
29
|
-
|
|
29
|
+
bridgeFeatureFlags: {
|
|
30
|
+
persist: false,
|
|
31
|
+
anonymous: false,
|
|
32
|
+
},
|
|
33
|
+
quoteRequest: {
|
|
34
|
+
persist: false,
|
|
35
|
+
anonymous: false,
|
|
36
|
+
},
|
|
37
|
+
quotes: {
|
|
38
|
+
persist: false,
|
|
39
|
+
anonymous: false,
|
|
40
|
+
},
|
|
41
|
+
quotesInitialLoadTime: {
|
|
42
|
+
persist: false,
|
|
43
|
+
anonymous: false,
|
|
44
|
+
},
|
|
45
|
+
quotesLastFetched: {
|
|
46
|
+
persist: false,
|
|
47
|
+
anonymous: false,
|
|
48
|
+
},
|
|
49
|
+
quotesLoadingStatus: {
|
|
50
|
+
persist: false,
|
|
51
|
+
anonymous: false,
|
|
52
|
+
},
|
|
53
|
+
quoteFetchError: {
|
|
54
|
+
persist: false,
|
|
55
|
+
anonymous: false,
|
|
56
|
+
},
|
|
57
|
+
quotesRefreshCount: {
|
|
30
58
|
persist: false,
|
|
31
59
|
anonymous: false,
|
|
32
60
|
},
|
|
@@ -35,14 +63,12 @@ const RESET_STATE_ABORT_MESSAGE = 'Reset controller state';
|
|
|
35
63
|
class BridgeController extends (0, polling_controller_1.StaticIntervalPollingController)() {
|
|
36
64
|
constructor({ messenger, state, clientId, getLayer1GasFee, fetchFn, }) {
|
|
37
65
|
super({
|
|
38
|
-
name:
|
|
66
|
+
name: bridge_1.BRIDGE_CONTROLLER_NAME,
|
|
39
67
|
metadata,
|
|
40
68
|
messenger,
|
|
41
69
|
state: {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
...state,
|
|
45
|
-
},
|
|
70
|
+
...(0, bridge_2.getDefaultBridgeControllerState)(),
|
|
71
|
+
...state,
|
|
46
72
|
},
|
|
47
73
|
});
|
|
48
74
|
_BridgeController_instances.add(this);
|
|
@@ -58,22 +84,21 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
58
84
|
this.stopAllPolling();
|
|
59
85
|
__classPrivateFieldGet(this, _BridgeController_abortController, "f")?.abort('Quote request updated');
|
|
60
86
|
const updatedQuoteRequest = {
|
|
61
|
-
...
|
|
87
|
+
...bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteRequest,
|
|
62
88
|
...paramsToUpdate,
|
|
63
89
|
};
|
|
64
90
|
this.update((state) => {
|
|
65
|
-
state.
|
|
66
|
-
state.
|
|
67
|
-
state.
|
|
68
|
-
|
|
69
|
-
state.
|
|
70
|
-
|
|
71
|
-
state.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
bridge_2.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesInitialLoadTime;
|
|
91
|
+
state.quoteRequest = updatedQuoteRequest;
|
|
92
|
+
state.quotes = bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotes;
|
|
93
|
+
state.quotesLastFetched =
|
|
94
|
+
bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLastFetched;
|
|
95
|
+
state.quotesLoadingStatus =
|
|
96
|
+
bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLoadingStatus;
|
|
97
|
+
state.quoteFetchError = bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;
|
|
98
|
+
state.quotesRefreshCount =
|
|
99
|
+
bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesRefreshCount;
|
|
100
|
+
state.quotesInitialLoadTime =
|
|
101
|
+
bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesInitialLoadTime;
|
|
77
102
|
});
|
|
78
103
|
if ((0, quote_1.isValidQuoteRequest)(updatedQuoteRequest)) {
|
|
79
104
|
__classPrivateFieldSet(this, _BridgeController_quotesFirstFetched, Date.now(), "f");
|
|
@@ -103,32 +128,41 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
103
128
|
this.stopAllPolling();
|
|
104
129
|
__classPrivateFieldGet(this, _BridgeController_abortController, "f")?.abort(RESET_STATE_ABORT_MESSAGE);
|
|
105
130
|
this.update((state) => {
|
|
106
|
-
state.
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
131
|
+
// Cannot do direct assignment to state, i.e. state = {... }, need to manually assign each field
|
|
132
|
+
state.quoteRequest = bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteRequest;
|
|
133
|
+
state.quotesInitialLoadTime =
|
|
134
|
+
bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesInitialLoadTime;
|
|
135
|
+
state.quotes = bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotes;
|
|
136
|
+
state.quotesLastFetched =
|
|
137
|
+
bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLastFetched;
|
|
138
|
+
state.quotesLoadingStatus =
|
|
139
|
+
bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesLoadingStatus;
|
|
140
|
+
state.quoteFetchError = bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;
|
|
141
|
+
state.quotesRefreshCount =
|
|
142
|
+
bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quotesRefreshCount;
|
|
143
|
+
// Keep feature flags
|
|
144
|
+
const originalFeatureFlags = state.bridgeFeatureFlags;
|
|
145
|
+
state.bridgeFeatureFlags = originalFeatureFlags;
|
|
111
146
|
});
|
|
112
147
|
};
|
|
113
148
|
this.setBridgeFeatureFlags = async () => {
|
|
114
149
|
const bridgeFeatureFlags = await (0, fetch_1.fetchBridgeFeatureFlags)(__classPrivateFieldGet(this, _BridgeController_clientId, "f"), __classPrivateFieldGet(this, _BridgeController_fetchFn, "f"));
|
|
115
150
|
this.update((state) => {
|
|
116
|
-
state.
|
|
151
|
+
state.bridgeFeatureFlags = bridgeFeatureFlags;
|
|
117
152
|
});
|
|
118
153
|
this.setIntervalLength(bridgeFeatureFlags[types_1.BridgeFeatureFlagsKey.EXTENSION_CONFIG].refreshRate);
|
|
119
154
|
};
|
|
120
155
|
_BridgeController_fetchBridgeQuotes.set(this, async ({ networkClientId: _networkClientId, updatedQuoteRequest, }) => {
|
|
121
|
-
const {
|
|
156
|
+
const { bridgeFeatureFlags, quotesInitialLoadTime, quotesRefreshCount } = this.state;
|
|
122
157
|
__classPrivateFieldGet(this, _BridgeController_abortController, "f")?.abort('New quote request');
|
|
123
158
|
__classPrivateFieldSet(this, _BridgeController_abortController, new AbortController(), "f");
|
|
124
159
|
if (updatedQuoteRequest.srcChainId === updatedQuoteRequest.destChainId) {
|
|
125
160
|
return;
|
|
126
161
|
}
|
|
127
162
|
this.update((state) => {
|
|
128
|
-
state.
|
|
129
|
-
state.
|
|
130
|
-
state.
|
|
131
|
-
bridge_2.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;
|
|
163
|
+
state.quotesLoadingStatus = types_1.RequestStatus.LOADING;
|
|
164
|
+
state.quoteRequest = updatedQuoteRequest;
|
|
165
|
+
state.quoteFetchError = bridge_1.DEFAULT_BRIDGE_CONTROLLER_STATE.quoteFetchError;
|
|
132
166
|
});
|
|
133
167
|
try {
|
|
134
168
|
const quotes = await (0, fetch_1.fetchBridgeQuotes)(updatedQuoteRequest,
|
|
@@ -139,8 +173,8 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
139
173
|
__classPrivateFieldGet(this, _BridgeController_abortController, "f").signal, __classPrivateFieldGet(this, _BridgeController_clientId, "f"), __classPrivateFieldGet(this, _BridgeController_fetchFn, "f"));
|
|
140
174
|
const quotesWithL1GasFees = await __classPrivateFieldGet(this, _BridgeController_appendL1GasFees, "f").call(this, quotes);
|
|
141
175
|
this.update((state) => {
|
|
142
|
-
state.
|
|
143
|
-
state.
|
|
176
|
+
state.quotes = quotesWithL1GasFees;
|
|
177
|
+
state.quotesLoadingStatus = types_1.RequestStatus.FETCHED;
|
|
144
178
|
});
|
|
145
179
|
}
|
|
146
180
|
catch (error) {
|
|
@@ -150,15 +184,15 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
150
184
|
return;
|
|
151
185
|
}
|
|
152
186
|
this.update((state) => {
|
|
153
|
-
state.
|
|
187
|
+
state.quoteFetchError =
|
|
154
188
|
error instanceof Error ? error.message : 'Unknown error';
|
|
155
|
-
state.
|
|
189
|
+
state.quotesLoadingStatus = types_1.RequestStatus.ERROR;
|
|
156
190
|
});
|
|
157
191
|
console.log('Failed to fetch bridge quotes', error);
|
|
158
192
|
}
|
|
159
193
|
finally {
|
|
160
|
-
const { maxRefreshCount } =
|
|
161
|
-
const updatedQuotesRefreshCount =
|
|
194
|
+
const { maxRefreshCount } = bridgeFeatureFlags[types_1.BridgeFeatureFlagsKey.EXTENSION_CONFIG];
|
|
195
|
+
const updatedQuotesRefreshCount = quotesRefreshCount + 1;
|
|
162
196
|
// Stop polling if the maximum number of refreshes has been reached
|
|
163
197
|
if (updatedQuoteRequest.insufficientBal ||
|
|
164
198
|
(!updatedQuoteRequest.insufficientBal &&
|
|
@@ -168,12 +202,12 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
168
202
|
// Update quote fetching stats
|
|
169
203
|
const quotesLastFetched = Date.now();
|
|
170
204
|
this.update((state) => {
|
|
171
|
-
state.
|
|
205
|
+
state.quotesInitialLoadTime =
|
|
172
206
|
updatedQuotesRefreshCount === 1 && __classPrivateFieldGet(this, _BridgeController_quotesFirstFetched, "f")
|
|
173
207
|
? quotesLastFetched - __classPrivateFieldGet(this, _BridgeController_quotesFirstFetched, "f")
|
|
174
|
-
:
|
|
175
|
-
state.
|
|
176
|
-
state.
|
|
208
|
+
: quotesInitialLoadTime;
|
|
209
|
+
state.quotesLastFetched = quotesLastFetched;
|
|
210
|
+
state.quotesRefreshCount = updatedQuotesRefreshCount;
|
|
177
211
|
});
|
|
178
212
|
}
|
|
179
213
|
});
|
|
@@ -201,7 +235,7 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
201
235
|
});
|
|
202
236
|
return {
|
|
203
237
|
...quoteResponse,
|
|
204
|
-
l1GasFeesInHexWei: (0,
|
|
238
|
+
l1GasFeesInHexWei: (0, bridge_2.sumHexes)(approvalL1GasFees, tradeL1GasFees),
|
|
205
239
|
};
|
|
206
240
|
}
|
|
207
241
|
return quoteResponse;
|
|
@@ -218,10 +252,10 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
218
252
|
if (!provider) {
|
|
219
253
|
throw new Error('No provider found');
|
|
220
254
|
}
|
|
221
|
-
const ethersProvider = new
|
|
222
|
-
const contract = new
|
|
255
|
+
const ethersProvider = new providers_1.Web3Provider(provider);
|
|
256
|
+
const contract = new contracts_1.Contract(contractAddress, metamask_eth_abis_1.abiERC20, ethersProvider);
|
|
223
257
|
const { address: walletAddress } = __classPrivateFieldGet(this, _BridgeController_instances, "m", _BridgeController_getSelectedAccount).call(this);
|
|
224
|
-
const allowance = await contract.allowance(walletAddress,
|
|
258
|
+
const allowance = await contract.allowance(walletAddress, bridge_1.METABRIDGE_CHAIN_TO_ADDRESS_MAP[chainId]);
|
|
225
259
|
return allowance.toString();
|
|
226
260
|
};
|
|
227
261
|
this.setIntervalLength(bridge_1.REFRESH_INTERVAL_MS);
|
|
@@ -230,10 +264,10 @@ class BridgeController extends (0, polling_controller_1.StaticIntervalPollingCon
|
|
|
230
264
|
__classPrivateFieldSet(this, _BridgeController_clientId, clientId, "f");
|
|
231
265
|
__classPrivateFieldSet(this, _BridgeController_fetchFn, fetchFn, "f");
|
|
232
266
|
// Register action handlers
|
|
233
|
-
this.messagingSystem.registerActionHandler(`${
|
|
234
|
-
this.messagingSystem.registerActionHandler(`${
|
|
235
|
-
this.messagingSystem.registerActionHandler(`${
|
|
236
|
-
this.messagingSystem.registerActionHandler(`${
|
|
267
|
+
this.messagingSystem.registerActionHandler(`${bridge_1.BRIDGE_CONTROLLER_NAME}:setBridgeFeatureFlags`, this.setBridgeFeatureFlags.bind(this));
|
|
268
|
+
this.messagingSystem.registerActionHandler(`${bridge_1.BRIDGE_CONTROLLER_NAME}:updateBridgeQuoteRequestParams`, this.updateBridgeQuoteRequestParams.bind(this));
|
|
269
|
+
this.messagingSystem.registerActionHandler(`${bridge_1.BRIDGE_CONTROLLER_NAME}:resetState`, this.resetState.bind(this));
|
|
270
|
+
this.messagingSystem.registerActionHandler(`${bridge_1.BRIDGE_CONTROLLER_NAME}:getBridgeERC20Allowance`, this.getBridgeERC20Allowance.bind(this));
|
|
237
271
|
}
|
|
238
272
|
}
|
|
239
273
|
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 { BigNumber } from '@ethersproject/bignumber';\nimport { Contract } from '@ethersproject/contracts';\nimport { Web3Provider } from '@ethersproject/providers';\nimport 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';\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 Web3Provider(provider);\n const contract = new Contract(contractAddress, abiERC20, ethersProvider);\n const { address: walletAddress } = this.#getSelectedAccount();\n const allowance: BigNumber = 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":"
|
|
1
|
+
{"version":3,"file":"bridge-controller.d.cts","sourceRoot":"","sources":["../src/bridge-controller.ts"],"names":[],"mappings":"AAIA,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;AAE3C,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":"
|
|
1
|
+
{"version":3,"file":"bridge-controller.d.mts","sourceRoot":"","sources":["../src/bridge-controller.ts"],"names":[],"mappings":"AAIA,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;AAE3C,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"}
|