@toruslabs/ethereum-controllers 9.2.0 → 9.4.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.
Files changed (31) hide show
  1. package/dist/lib.cjs/Currency/CurrencyController.js +9 -4
  2. package/dist/lib.cjs/Eip5792/walletGetCapabilities.js +9 -0
  3. package/dist/lib.cjs/Eip5792/walletSendCalls.js +8 -2
  4. package/dist/lib.cjs/Network/createEthereumMiddleware.js +7 -3
  5. package/dist/lib.cjs/Preferences/PreferencesController.js +34 -400
  6. package/dist/lib.cjs/Tokens/TokenRatesController.js +16 -7
  7. package/dist/lib.cjs/Transaction/TransactionController.js +1 -1
  8. package/dist/lib.cjs/index.js +2 -2
  9. package/dist/lib.cjs/types/Currency/CurrencyController.d.ts +4 -2
  10. package/dist/lib.cjs/types/Eip5792/walletGetCapabilities.d.ts +2 -1
  11. package/dist/lib.cjs/types/Eip5792/walletSendCalls.d.ts +4 -2
  12. package/dist/lib.cjs/types/Network/interfaces.d.ts +5 -1
  13. package/dist/lib.cjs/types/Preferences/IPreferencesController.d.ts +0 -6
  14. package/dist/lib.cjs/types/Preferences/PreferencesController.d.ts +5 -29
  15. package/dist/lib.cjs/types/Tokens/TokenRatesController.d.ts +5 -3
  16. package/dist/lib.cjs/types/utils/constants.d.ts +5 -0
  17. package/dist/lib.cjs/types/utils/helpers.d.ts +0 -13
  18. package/dist/lib.cjs/types/utils/interfaces.d.ts +6 -68
  19. package/dist/lib.cjs/utils/constants.js +7 -0
  20. package/dist/lib.cjs/utils/helpers.js +0 -119
  21. package/dist/lib.esm/Currency/CurrencyController.js +10 -5
  22. package/dist/lib.esm/Eip5792/walletGetCapabilities.js +9 -0
  23. package/dist/lib.esm/Eip5792/walletSendCalls.js +9 -2
  24. package/dist/lib.esm/Network/createEthereumMiddleware.js +7 -3
  25. package/dist/lib.esm/Preferences/PreferencesController.js +37 -405
  26. package/dist/lib.esm/Tokens/TokenRatesController.js +17 -8
  27. package/dist/lib.esm/index.js +2 -2
  28. package/dist/lib.esm/utils/constants.js +6 -1
  29. package/dist/lib.esm/utils/helpers.js +3 -120
  30. package/dist/lib.esm/utils/interfaces.js +0 -2
  31. package/package.json +6 -6
@@ -3,7 +3,6 @@
3
3
  var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
4
4
  var _defineProperty = require('@babel/runtime/helpers/defineProperty');
5
5
  var baseControllers = require('@toruslabs/base-controllers');
6
- var httpHelpers = require('@toruslabs/http-helpers');
7
6
  var log = require('loglevel');
8
7
 
9
8
  class CurrencyController extends baseControllers.BaseCurrencyController {
@@ -11,13 +10,15 @@ class CurrencyController extends baseControllers.BaseCurrencyController {
11
10
  config,
12
11
  state,
13
12
  idleTimeTracker,
14
- onNetworkChanged
13
+ onNetworkChanged,
14
+ getAuthHttpClient
15
15
  }) {
16
16
  super({
17
17
  config,
18
18
  state
19
19
  });
20
20
  _defineProperty(this, "pollingManager", void 0);
21
+ _defineProperty(this, "getAuthHttpClient", void 0);
21
22
  this.defaultState = _objectSpread(_objectSpread({}, this.defaultState), {}, {
22
23
  commonDenomination: "USD",
23
24
  commonDenominatorPrice: 0
@@ -30,6 +31,7 @@ class CurrencyController extends baseControllers.BaseCurrencyController {
30
31
  this.updateConversionRate();
31
32
  }
32
33
  });
34
+ this.getAuthHttpClient = getAuthHttpClient;
33
35
  this.pollingManager = new baseControllers.PollingManager(idleTimeTracker, this.config.pollInterval);
34
36
  }
35
37
  setCommonDenomination(commonDenomination) {
@@ -84,11 +86,14 @@ class CurrencyController extends baseControllers.BaseCurrencyController {
84
86
  }
85
87
  async retrieveConversionRate(fromCurrency, toCurrency, commonDenomination) {
86
88
  try {
87
- let apiUrl = `${this.config.api}/currency?fsym=${fromCurrency.toUpperCase()}&tsyms=${toCurrency.toUpperCase()}`;
89
+ const httpClient = baseControllers.resolveAuthHttpClient(this.getAuthHttpClient, this.name);
90
+ let apiUrl = `${this.config.api}/v2/currency?fsym=${fromCurrency.toUpperCase()}&tsyms=${toCurrency.toUpperCase()}`;
88
91
  if (commonDenomination && commonDenomination.toUpperCase() !== toCurrency.toUpperCase()) {
89
92
  apiUrl += `,${commonDenomination.toUpperCase()}`;
90
93
  }
91
- const parsedResponse = await httpHelpers.get(apiUrl);
94
+ const parsedResponse = await httpClient.get(apiUrl, {
95
+ authenticated: true
96
+ });
92
97
  return parsedResponse;
93
98
  } catch (error) {
94
99
  log.error(error, `CurrencyController - updateCommonDenominatorPrice: Failed to query rate for currency: ${fromCurrency}/ ${toCurrency}`);
@@ -2,6 +2,7 @@
2
2
 
3
3
  var auth = require('@web3auth/auth');
4
4
  var eip7702Utils = require('../Eip7702/eip7702Utils.js');
5
+ var constants = require('../utils/constants.js');
5
6
  var eip5792Types = require('../utils/eip5792Types.js');
6
7
 
7
8
  /**
@@ -33,6 +34,14 @@ async function walletGetCapabilities(request, getEthCode, context) {
33
34
  const cachedDelegations = ((_context$getCachedDel = context.getCachedDelegations) === null || _context$getCachedDel === void 0 ? void 0 : _context$getCachedDel.call(context)) || {};
34
35
  const capabilities = {};
35
36
  for (const chainId of supportedChains) {
37
+ if (context.getSmartAccountEipStandard() !== constants.SMART_ACCOUNT_EIP_STANDARD.EIP_7702) {
38
+ capabilities[chainId] = {
39
+ atomic: {
40
+ status: eip5792Types.Eip5792AtomicStatus.UNSUPPORTED
41
+ }
42
+ };
43
+ continue;
44
+ }
36
45
  const cacheKey = `${walletAddress.toLowerCase()}-${chainId.toLowerCase()}`;
37
46
  let delegationAddress = cachedDelegations[cacheKey];
38
47
  let atomicStatus = eip5792Types.Eip5792AtomicStatus.SUPPORTED;
@@ -4,6 +4,7 @@ var auth = require('@web3auth/auth');
4
4
  var uuid = require('uuid');
5
5
  var viem = require('viem');
6
6
  var eip7702Utils = require('../Eip7702/eip7702Utils.js');
7
+ var constants = require('../utils/constants.js');
7
8
  var eip5792Types = require('../utils/eip5792Types.js');
8
9
 
9
10
  /**
@@ -42,8 +43,9 @@ function validateCall(call, index) {
42
43
  /**
43
44
  * Validates the parameters for wallet_sendCalls (EIP-5792).
44
45
  * @param sendCallsParams - The parameters to validate.
46
+ * @param context - The context
45
47
  */
46
- function validateSendCallsParams(sendCallsParams) {
48
+ function validateSendCallsParams(sendCallsParams, context) {
47
49
  // Basic structure validation
48
50
  if (!sendCallsParams) {
49
51
  throw auth.rpcErrors.invalidParams("Missing send calls parameters");
@@ -67,6 +69,10 @@ function validateSendCallsParams(sendCallsParams) {
67
69
  if (!Array.isArray(sendCallsParams.calls) || sendCallsParams.calls.length === 0) {
68
70
  throw auth.rpcErrors.invalidParams("Invalid calls: must be a non-empty array");
69
71
  }
72
+ // Validate smart account standard for batch calls
73
+ if (sendCallsParams.calls.length > 1 && context.getSmartAccountEipStandard() !== constants.SMART_ACCOUNT_EIP_STANDARD.EIP_7702) {
74
+ throw auth.rpcErrors.methodNotSupported("wallet_sendCalls is only supported for batch calls when smart account standard is EIP-7702");
75
+ }
70
76
  // Validate each call
71
77
  sendCallsParams.calls.forEach((call, index) => {
72
78
  validateCall(call, index);
@@ -128,7 +134,7 @@ async function walletSendCalls(request, getEthCode, context) {
128
134
  return;
129
135
  }
130
136
  const sendCallsParams = Array.isArray(params) ? params[0] : params;
131
- validateSendCallsParams(sendCallsParams);
137
+ validateSendCallsParams(sendCallsParams, context);
132
138
  const {
133
139
  chainId,
134
140
  from,
@@ -482,15 +482,19 @@ function createEip5792Middleware({
482
482
  const {
483
483
  getSupportedChains,
484
484
  getCachedDelegations,
485
- updateDelegationCache
485
+ updateDelegationCache,
486
+ getSmartAccountEipStandard
486
487
  } = eip5792Config;
487
488
  const getCapabilitiesContext = {
488
489
  getSupportedChains,
489
490
  getCachedDelegations,
490
- updateDelegationCache
491
+ updateDelegationCache,
492
+ getSmartAccountEipStandard
491
493
  };
492
494
  const sendCallsContext = {
493
- processTransactionBatch
495
+ processTransaction,
496
+ processTransactionBatch,
497
+ getSmartAccountEipStandard
494
498
  };
495
499
  return auth.createScaffoldMiddlewareV2({
496
500
  [eip5792Types.EIP_5792_METHODS.WALLET_GET_CAPABILITIES]: async ({
@@ -3,75 +3,43 @@
3
3
  var _defineProperty = require('@babel/runtime/helpers/defineProperty');
4
4
  var baseControllers = require('@toruslabs/base-controllers');
5
5
  var metadataHelpers = require('@toruslabs/metadata-helpers');
6
- var asyncMutex = require('async-mutex');
7
6
  var log = require('loglevel');
8
7
  var constants = require('../utils/constants.js');
9
- var helpers = require('../utils/helpers.js');
10
8
 
11
9
  class PreferencesController extends baseControllers.BasePreferencesController {
12
10
  constructor({
13
11
  config,
14
12
  state,
15
- provider,
16
13
  signAuthMessage,
17
14
  getProviderConfig,
18
15
  setProviderConfig,
19
- validateSignMessage
16
+ validateSignMessage,
17
+ getAuthHttpClient
20
18
  }) {
21
19
  super({
22
20
  config,
23
21
  state,
24
- defaultPreferences: {
25
- formattedPastTransactions: [],
26
- fetchedPastTx: [],
27
- paymentTx: [],
28
- etherscanTransactions: []
29
- },
22
+ defaultPreferences: {},
30
23
  signAuthMessage,
31
- validateSignMessage
24
+ validateSignMessage,
25
+ getAuthHttpClient
32
26
  });
33
27
  _defineProperty(this, "chainNamespace", baseControllers.CHAIN_NAMESPACES.EIP155);
34
- _defineProperty(this, "_handle", void 0);
35
- _defineProperty(this, "_mutex", new asyncMutex.Mutex());
36
28
  _defineProperty(this, "getProviderConfig", void 0);
37
29
  _defineProperty(this, "setProviderConfig", void 0);
38
- _defineProperty(this, "provider", void 0);
39
- this.provider = provider;
40
30
  this.getProviderConfig = getProviderConfig;
41
31
  this.setProviderConfig = setProviderConfig;
42
32
  }
43
- async poll(interval) {
44
- var _this$getAddressState;
45
- const releaseLock = await this._mutex.acquire();
46
- if (interval) this.configure({
47
- pollInterval: interval
48
- });
49
- if (this._handle) window.clearTimeout(this._handle);
50
- // call here
51
- const storeSelectedAddress = this.state.selectedAddress;
52
- if (!storeSelectedAddress) return;
53
- if (!((_this$getAddressState = this.getAddressState(storeSelectedAddress)) !== null && _this$getAddressState !== void 0 && _this$getAddressState.jwtToken)) return;
54
- // This should never throw
55
- await this.sync(storeSelectedAddress);
56
- releaseLock();
57
- this._handle = window.setTimeout(() => {
58
- this.poll(this.config.pollInterval);
59
- }, this.config.pollInterval);
60
- }
61
33
  async initPreferences(params) {
62
34
  const {
63
35
  address,
64
36
  jwtToken,
65
- calledFromEmbed,
37
+ accessToken,
38
+ origin,
66
39
  userInfo,
67
- rehydrate,
68
- locale = "en",
69
40
  type,
70
41
  signatures,
71
- web3AuthClientId,
72
42
  web3AuthNetwork,
73
- loginMode,
74
- sessionPubKey,
75
43
  aaProvider,
76
44
  eoaAddress,
77
45
  mainAddress
@@ -83,6 +51,8 @@ class PreferencesController extends baseControllers.BasePreferencesController {
83
51
  address,
84
52
  userInfo,
85
53
  idToken: jwtToken,
54
+ accessToken,
55
+ origin,
86
56
  type,
87
57
  metadata: {
88
58
  email: userInfo.email,
@@ -94,180 +64,19 @@ class PreferencesController extends baseControllers.BasePreferencesController {
94
64
  main_address: mainAddress
95
65
  }
96
66
  });
97
- const {
98
- groupedAuthConnectionId,
99
- authConnectionId,
100
- userId
101
- } = userInfo || {};
102
- const userExists = await this.sync(address);
103
- if (!userExists) {
104
- const accountState = this.getAddressState(address);
105
- await this.createUser({
106
- selectedCurrency: accountState.selectedCurrency,
107
- theme: accountState.theme,
108
- groupedAuthConnectionId,
109
- authConnectionId,
110
- userId,
111
- locale,
112
- address,
113
- type,
114
- web3AuthNetwork,
115
- metadata: {
116
- aa_provider: aaProvider,
117
- chain_id: chainId,
118
- eoa_address: eoaAddress
119
- }
120
- });
121
- }
122
67
  if (eoaAddress) this.updateState({
123
68
  eoaAddress
124
69
  }, address);
125
- this.storeUserLogin({
126
- groupedAuthConnectionId,
127
- authConnectionId,
128
- userId,
129
- options: {
130
- calledFromEmbed,
131
- rehydrate
132
- },
133
- address,
134
- web3AuthClientId,
135
- web3AuthNetwork,
136
- sessionPubKey,
137
- loginMode
138
- });
139
70
  }
140
71
  getSelectedAddress() {
141
72
  return this.state.selectedAddress;
142
73
  }
143
- async sync(address) {
144
- try {
145
- const user = await this.getUser(address);
146
- if (user) {
147
- const {
148
- default_currency: defaultCurrency,
149
- contacts,
150
- theme,
151
- locale,
152
- public_address: userPublicAddress,
153
- default_public_address: defaultPublicAddress,
154
- customNetworks,
155
- customTokens,
156
- customNfts,
157
- account_type: accountType
158
- } = user || {};
159
- // update latest data in state.
160
- this.updateState({
161
- contacts,
162
- theme,
163
- selectedCurrency: defaultCurrency,
164
- locale,
165
- defaultPublicAddress: defaultPublicAddress || userPublicAddress,
166
- customTokens,
167
- customNfts,
168
- customNetworks,
169
- accountType: accountType
170
- }, address);
171
- return true;
172
- }
173
- return false;
174
- } catch (error) {
175
- if (baseControllers.isUnauthorizedError(error)) {
176
- throw error;
177
- }
178
- log.error(error);
179
- return false;
180
- } finally {
181
- this.getWalletOrders(address).then(walletTx => {
182
- // eslint-disable-next-line promise/always-return
183
- if (walletTx && walletTx.length > 0) {
184
- this.updateState({
185
- fetchedPastTx: [...walletTx]
186
- }, address);
187
- this.calculatePastTx(walletTx, address);
188
- }
189
- }).catch(error => log.error(error));
190
- }
191
- }
192
- async patchNewTx(tx, address) {
193
- var _this$getAddressState2;
194
- const formattedTx = helpers.formatPastTx({
195
- transaction: tx,
196
- blockExplorerUrl: this.getBlockExplorerUrl()
197
- });
198
- const storePastTx = ((_this$getAddressState2 = this.getAddressState(address)) === null || _this$getAddressState2 === void 0 ? void 0 : _this$getAddressState2.formattedPastTransactions) || [];
199
- const duplicateIndex = storePastTx.findIndex(x => x.transaction_hash === tx.transaction_hash && x.chainId === tx.chain_id);
200
- if (tx.status === baseControllers.TransactionStatus.submitted || tx.status === baseControllers.TransactionStatus.confirmed) {
201
- if (duplicateIndex === -1) {
202
- var _tx$to;
203
- // No duplicate found
204
- const finalTx = this.cancelTxCalculate([...storePastTx, formattedTx]);
205
- tx.is_cancel = formattedTx.is_cancel;
206
- tx.to = (_tx$to = tx.to) === null || _tx$to === void 0 ? void 0 : _tx$to.toLowerCase();
207
- tx.from = tx.from.toLowerCase();
208
- this.updateState({
209
- formattedPastTransactions: finalTx
210
- }, address);
211
- this.postPastTx(tx, address);
212
- } else {
213
- // avoid overriding is_cancel
214
- formattedTx.is_cancel = storePastTx[duplicateIndex].is_cancel;
215
- storePastTx[duplicateIndex] = formattedTx;
216
- this.updateState({
217
- formattedPastTransactions: this.cancelTxCalculate([...storePastTx])
218
- }, address);
219
- }
220
- }
221
- }
222
- recalculatePastTx(address) {
223
- // This triggers store update which calculates past Tx status for that network
224
- const selectedAddress = address || this.state.selectedAddress;
225
- const state = this.getAddressState(selectedAddress);
226
- if (!(state !== null && state !== void 0 && state.fetchedPastTx)) return;
227
- this.calculatePastTx(state.fetchedPastTx, selectedAddress);
228
- }
229
- async refetchEtherscanTx(address) {
230
- var _this$getAddressState3;
231
- const selectedAddress = address || this.state.selectedAddress;
232
- if (!selectedAddress) return [];
233
- const lowerCaseSelectedAddress = selectedAddress === null || selectedAddress === void 0 ? void 0 : selectedAddress.toLowerCase();
234
- if ((_this$getAddressState3 = this.getAddressState(selectedAddress)) !== null && _this$getAddressState3 !== void 0 && _this$getAddressState3.jwtToken) {
235
- const {
236
- chainId
237
- } = this.getProviderConfig();
238
- if (constants.MM_TOKEN_API_SUPPORTED_CHAINS.includes(chainId)) {
239
- const etherscanTxn = await this.fetchEtherscanTx({
240
- selectedAddress,
241
- chainId: this.getProviderConfig().chainId
242
- });
243
- const finalEthScanTxn = await helpers.addEtherscanTransactions({
244
- txn: etherscanTxn,
245
- lowerCaseSelectedAddress,
246
- provider: this.provider,
247
- chainId,
248
- blockExplorerUrl: this.getBlockExplorerUrl()
249
- });
250
- log.info("Formatted Etherscan Response", finalEthScanTxn);
251
- this.updateState({
252
- etherscanTransactions: finalEthScanTxn
253
- });
254
- return etherscanTxn;
255
- }
256
- }
257
- }
258
- async fetchEtherscanTx(parameters) {
259
- try {
260
- const response = await this.wsApiClient.authGet(`etherscan?chainId=${parameters.chainId}`, this.authCredentials(parameters.selectedAddress));
261
- log.info("Etherscan Response API", response);
262
- return response.success ? response.data : [];
263
- } catch (error) {
264
- log.error("unable to fetch etherscan tx", error);
265
- return [];
266
- }
267
- }
268
74
  async fetchQuote(parameters) {
269
75
  try {
270
- const response = await this.wsApiClient.authPost("quote", parameters, this.authCredentials());
76
+ const response = await this.getAuthHttpClient().post(`${this.config.api}/v2/quote`, parameters, {
77
+ authenticated: true,
78
+ headers: this.constructAuthHeaders()
79
+ });
271
80
  return response.success ? response.data : [];
272
81
  } catch (error) {
273
82
  log.error("unable to get swap quote", error);
@@ -276,32 +85,40 @@ class PreferencesController extends baseControllers.BasePreferencesController {
276
85
  }
277
86
  async getEtherScanTokens(address, chainId, skipCache) {
278
87
  const selectedAddress = address;
279
- let path = `tokens?chainId=${chainId}&address=${selectedAddress}`;
88
+ let path = `v2/tokens?chainId=${chainId}&address=${selectedAddress}`;
280
89
  if (skipCache) {
281
90
  path += `&skipCache=true`;
282
91
  }
283
- const result = await this.wsApiClient.authGet(path, this.authCredentials());
92
+ // TODO: pass selected address as headers and not as a query parameter
93
+ const result = await this.getAuthHttpClient().get(`${this.config.api}/${path}`, {
94
+ authenticated: true
95
+ });
284
96
  return result.data;
285
97
  }
286
98
  async getSimpleHashNfts(address, chainId, skipCache) {
287
99
  const selectedAddress = address;
288
- let path = `nfts?chainId=${chainId}&address=${selectedAddress}`;
100
+ let path = `v2/nfts?chainId=${chainId}&address=${selectedAddress}`;
289
101
  if (skipCache) {
290
102
  path += `&skipCache=true`;
291
103
  }
292
- const result = await this.wsApiClient.authGet(path, this.authCredentials());
104
+ // TODO: pass selected address as headers and not as a query parameter
105
+ const result = await this.getAuthHttpClient().get(`${this.config.api}/${path}`, {
106
+ authenticated: true,
107
+ headers: this.constructAuthHeaders()
108
+ });
293
109
  return result.data;
294
110
  }
295
111
  getCustomTokens(address) {
296
- var _this$getAddressState4, _this$getAddressState5;
297
- return (_this$getAddressState4 = (_this$getAddressState5 = this.getAddressState(address)) === null || _this$getAddressState5 === void 0 ? void 0 : _this$getAddressState5.customTokens) !== null && _this$getAddressState4 !== void 0 ? _this$getAddressState4 : [];
112
+ var _this$getAddressState, _this$getAddressState2;
113
+ return (_this$getAddressState = (_this$getAddressState2 = this.getAddressState(address)) === null || _this$getAddressState2 === void 0 ? void 0 : _this$getAddressState2.customTokens) !== null && _this$getAddressState !== void 0 ? _this$getAddressState : [];
298
114
  }
299
115
  getCustomNfts(address) {
300
- var _this$getAddressState6, _this$getAddressState7;
301
- return (_this$getAddressState6 = (_this$getAddressState7 = this.getAddressState(address)) === null || _this$getAddressState7 === void 0 ? void 0 : _this$getAddressState7.customNfts) !== null && _this$getAddressState6 !== void 0 ? _this$getAddressState6 : [];
116
+ var _this$getAddressState3, _this$getAddressState4;
117
+ return (_this$getAddressState3 = (_this$getAddressState4 = this.getAddressState(address)) === null || _this$getAddressState4 === void 0 ? void 0 : _this$getAddressState4.customNfts) !== null && _this$getAddressState3 !== void 0 ? _this$getAddressState3 : [];
302
118
  }
303
- isChainIdSupported(address, chainId) {
304
- const approveChainOptions = this.getChainOptions(address);
119
+ // NOTE: keep address params for now, might need to handle aa addresses later
120
+ isChainIdSupported(_address, chainId) {
121
+ const approveChainOptions = this.getChainOptions();
305
122
  const providerConfig = approveChainOptions.find(x => metadataHelpers.remove0x(x.chainId) === chainId);
306
123
  return !!providerConfig;
307
124
  }
@@ -309,19 +126,7 @@ class PreferencesController extends baseControllers.BasePreferencesController {
309
126
  const approveChainOptions = this.getChainOptions();
310
127
  const providerConfig = approveChainOptions.find(x => x.chainId === network.chainId);
311
128
  if (providerConfig) return;
312
- const newNetwork = {
313
- displayName: network.chainName,
314
- rpcTarget: network.rpcUrls[0],
315
- ticker: network.nativeCurrency.symbol,
316
- chainId: network.chainId,
317
- blockExplorerUrl: network.blockExplorerUrls[0],
318
- tickerName: network.nativeCurrency.name,
319
- logo: network.nativeCurrency.symbol
320
- };
321
- const isSuccess = await this.addCustomNetwork({
322
- network: newNetwork
323
- });
324
- if (!isSuccess) throw new Error("unable to add custom network");
129
+ throw new Error(`chainId ${network.chainId} is not supported`);
325
130
  }
326
131
  switchChain(data) {
327
132
  const chainOptions = this.getChainOptions();
@@ -332,179 +137,8 @@ class PreferencesController extends baseControllers.BasePreferencesController {
332
137
  throw new Error(`chainId ${data.chainId} is not supported`);
333
138
  }
334
139
  }
335
- // Custom Network methods
336
- async addCustomNetwork({
337
- network
338
- }) {
339
- try {
340
- const {
341
- selectedAddress
342
- } = this.state;
343
- const payload = {
344
- network_name: network.displayName,
345
- rpc_url: network.rpcTarget,
346
- chain_id: network.chainId,
347
- symbol: network.ticker,
348
- block_explorer_url: network.blockExplorerUrl || undefined,
349
- is_testnet: network.isTestnet || false,
350
- logo: network.logo,
351
- symbol_name: network.tickerName
352
- };
353
- const res = await this.wsApiClient.authPost("customnetwork", payload, this.authCredentials(selectedAddress), {
354
- useAPIKey: true
355
- });
356
- await this.sync(selectedAddress);
357
- return res.data.id;
358
- } catch {
359
- log.error("error adding custom network");
360
- return null;
361
- }
362
- }
363
- async deleteCustomNetwork(id) {
364
- try {
365
- const {
366
- selectedAddress
367
- } = this.state;
368
- await this.wsApiClient.authRemove(`customnetwork/${id}`, {}, this.authCredentials(selectedAddress), {
369
- useAPIKey: true
370
- });
371
- await this.sync(selectedAddress);
372
- return true;
373
- } catch {
374
- log.error("error deleting custom network");
375
- return false;
376
- }
377
- }
378
- async editCustomNetwork({
379
- network,
380
- id
381
- }) {
382
- try {
383
- const {
384
- selectedAddress
385
- } = this.state;
386
- const payload = {
387
- network_name: network.displayName,
388
- rpc_url: network.rpcTarget,
389
- chain_id: network.chainId,
390
- symbol: network.ticker || undefined,
391
- block_explorer_url: network.blockExplorerUrl || undefined,
392
- is_testnet: network.isTestnet || false
393
- };
394
- await this.wsApiClient.authPatch(`customnetwork/${id}`, payload, this.authCredentials(selectedAddress), {
395
- useAPIKey: true
396
- });
397
- await this.sync(selectedAddress);
398
- return true;
399
- } catch {
400
- log.error("error editing custom network");
401
- return false;
402
- }
403
- }
404
- getChainOptions(address = this.state.selectedAddress) {
405
- var _identities$address$c, _identities$address;
406
- const {
407
- identities
408
- } = this.state;
409
- const customNetworks = (_identities$address$c = (_identities$address = identities[address]) === null || _identities$address === void 0 ? void 0 : _identities$address.customNetworks) !== null && _identities$address$c !== void 0 ? _identities$address$c : [];
410
- const custom = Object.values(customNetworks).reduce((chains, network) => {
411
- const networkItem = {
412
- blockExplorerUrl: network.block_explorer_url,
413
- chainId: network.chain_id,
414
- displayName: network.network_name,
415
- logo: "eth.svg",
416
- rpcTarget: network.rpc_url,
417
- ticker: network.symbol,
418
- tickerName: network.symbol.toUpperCase(),
419
- isCustom: true,
420
- id: network.id
421
- };
422
- if (Object.keys(constants.SUPPORTED_NETWORKS).includes(networkItem.chainId)) return chains;
423
- chains.push(networkItem);
424
- return chains;
425
- }, []);
426
- const supported = Object.values(constants.SUPPORTED_NETWORKS).reduce((chains, network) => {
427
- chains.push(network);
428
- return chains;
429
- }, []);
430
- return [...supported, ...custom];
431
- }
432
- getBlockExplorerUrl() {
433
- const supportedNetworks = this.getChainOptions();
434
- const network = supportedNetworks.find(x => x.chainId === this.getProviderConfig().chainId);
435
- if (!network) return "";
436
- return `${network.blockExplorerUrl}`;
437
- }
438
- async calculatePastTx(txs, address) {
439
- const pastTx = [];
440
- const pendingTx = [];
441
- const lowerCaseSelectedAddress = address.toLowerCase();
442
- const supportedNetworks = this.getChainOptions(address);
443
- const supportedNetwork = supportedNetworks.find(x => x.chainId === this.getProviderConfig().chainId);
444
- for (const x of txs) {
445
- var _x$to;
446
- if ((supportedNetwork === null || supportedNetwork === void 0 ? void 0 : supportedNetwork.chainId) === x.chain_id && x.to && x.from && (lowerCaseSelectedAddress === x.from.toLowerCase() || lowerCaseSelectedAddress === ((_x$to = x.to) === null || _x$to === void 0 ? void 0 : _x$to.toLowerCase()))) {
447
- if (x.status !== "confirmed") {
448
- pendingTx.push(x);
449
- } else {
450
- const finalObject = helpers.formatPastTx({
451
- transaction: x,
452
- lowerCaseSelectedAddress,
453
- blockExplorerUrl: this.getBlockExplorerUrl()
454
- });
455
- pastTx.push(finalObject);
456
- }
457
- }
458
- }
459
- const pendingTxPromises = pendingTx.map(x => helpers.getEthTxStatus(x.transaction_hash, this.provider).catch(error => log.error(error)));
460
- const resolvedTxStatuses = await Promise.all(pendingTxPromises);
461
- for (const [index, element] of pendingTx.entries()) {
462
- const finalObject = helpers.formatPastTx({
463
- transaction: element,
464
- lowerCaseSelectedAddress,
465
- blockExplorerUrl: this.getBlockExplorerUrl()
466
- });
467
- finalObject.status = resolvedTxStatuses[index] || baseControllers.TransactionStatus.submitted;
468
- pastTx.push(finalObject);
469
- if (lowerCaseSelectedAddress === element.from.toLowerCase() && finalObject.status && finalObject.status !== element.status) this.patchPastTx({
470
- id: element.id,
471
- status: finalObject.status
472
- }, address);
473
- }
474
- const finalTx = this.cancelTxCalculate(pastTx);
475
- this.updateState({
476
- formattedPastTransactions: [...finalTx]
477
- }, address);
478
- }
479
- cancelTxCalculate(pastTx) {
480
- const nonceMap = {};
481
- for (const x of pastTx) {
482
- if (!nonceMap[x.nonce]) nonceMap[x.nonce] = [x];else {
483
- nonceMap[x.nonce].push(x);
484
- }
485
- }
486
- for (const [, value] of Object.entries(nonceMap)) {
487
- // has duplicate
488
- if (value.length > 1) {
489
- // get latest and mark it as is_cancel
490
- const latestTxs = value.sort((a, b) => {
491
- const aDate = new Date(a.date).getTime();
492
- const bDate = new Date(b.date).getTime();
493
- return bDate - aDate;
494
- });
495
- const latestCancelTx = latestTxs[0];
496
- latestCancelTx.is_cancel = true;
497
- latestTxs.slice(1).forEach(x => {
498
- x.hasCancel = true;
499
- x.status = latestCancelTx.status === "confirmed" ? baseControllers.TransactionStatus.cancelled : baseControllers.TransactionStatus.cancelling;
500
- x.cancelDateInitiated = `${helpers.formatTime(new Date(latestCancelTx.date).getTime())} - ${helpers.formatDate(latestCancelTx.date)}`;
501
- x.etherscanLink = latestCancelTx.etherscanLink;
502
- x.cancelGas = latestCancelTx.gas;
503
- x.cancelGasPrice = latestCancelTx.gasPrice;
504
- });
505
- }
506
- }
507
- return pastTx;
140
+ getChainOptions() {
141
+ return Object.values(constants.SUPPORTED_NETWORKS);
508
142
  }
509
143
  }
510
144