@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.
- package/dist/lib.cjs/Currency/CurrencyController.js +9 -4
- package/dist/lib.cjs/Eip5792/walletGetCapabilities.js +9 -0
- package/dist/lib.cjs/Eip5792/walletSendCalls.js +8 -2
- package/dist/lib.cjs/Network/createEthereumMiddleware.js +7 -3
- package/dist/lib.cjs/Preferences/PreferencesController.js +34 -400
- package/dist/lib.cjs/Tokens/TokenRatesController.js +16 -7
- package/dist/lib.cjs/Transaction/TransactionController.js +1 -1
- package/dist/lib.cjs/index.js +2 -2
- package/dist/lib.cjs/types/Currency/CurrencyController.d.ts +4 -2
- package/dist/lib.cjs/types/Eip5792/walletGetCapabilities.d.ts +2 -1
- package/dist/lib.cjs/types/Eip5792/walletSendCalls.d.ts +4 -2
- package/dist/lib.cjs/types/Network/interfaces.d.ts +5 -1
- package/dist/lib.cjs/types/Preferences/IPreferencesController.d.ts +0 -6
- package/dist/lib.cjs/types/Preferences/PreferencesController.d.ts +5 -29
- package/dist/lib.cjs/types/Tokens/TokenRatesController.d.ts +5 -3
- package/dist/lib.cjs/types/utils/constants.d.ts +5 -0
- package/dist/lib.cjs/types/utils/helpers.d.ts +0 -13
- package/dist/lib.cjs/types/utils/interfaces.d.ts +6 -68
- package/dist/lib.cjs/utils/constants.js +7 -0
- package/dist/lib.cjs/utils/helpers.js +0 -119
- package/dist/lib.esm/Currency/CurrencyController.js +10 -5
- package/dist/lib.esm/Eip5792/walletGetCapabilities.js +9 -0
- package/dist/lib.esm/Eip5792/walletSendCalls.js +9 -2
- package/dist/lib.esm/Network/createEthereumMiddleware.js +7 -3
- package/dist/lib.esm/Preferences/PreferencesController.js +37 -405
- package/dist/lib.esm/Tokens/TokenRatesController.js +17 -8
- package/dist/lib.esm/index.js +2 -2
- package/dist/lib.esm/utils/constants.js +6 -1
- package/dist/lib.esm/utils/helpers.js +3 -120
- package/dist/lib.esm/utils/interfaces.js +0 -2
- 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
|
-
|
|
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
|
-
|
|
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
|
|
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 {
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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$
|
|
297
|
-
return (_this$
|
|
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$
|
|
301
|
-
return (_this$
|
|
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
|
-
|
|
304
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|