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