@toruslabs/ethereum-controllers 6.3.2 → 7.0.0-alpha.1
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/757.ethereumControllers.cjs.js +226 -0
- package/dist/ethereumControllers.cjs.js +19077 -2288
- package/dist/ethereumControllers.esm.js +1808 -1614
- package/dist/ethereumControllers.umd.min.js +1 -1
- package/dist/lib.cjs/AccountAbstraction/AccountAbstractionController.js +217 -0
- package/dist/lib.cjs/AccountAbstraction/smartAccounts/BiconomySmartAccount.js +29 -0
- package/dist/lib.cjs/AccountAbstraction/smartAccounts/KernelSmartAccount.js +24 -0
- package/dist/lib.cjs/AccountAbstraction/smartAccounts/NexusSmartAccount.js +30 -0
- package/dist/lib.cjs/AccountAbstraction/smartAccounts/SafeSmartAccount.js +32 -0
- package/dist/lib.cjs/AccountAbstraction/smartAccounts/TrustSmartAccount.js +31 -0
- package/dist/lib.cjs/Block/PollingBlockTracker.js +1 -2
- package/dist/lib.cjs/Currency/CurrencyController.js +1 -2
- package/dist/lib.cjs/Gas/GasFeeController.js +1 -2
- package/dist/lib.cjs/Message/AddChainController.js +6 -9
- package/dist/lib.cjs/Message/MessageController.js +7 -10
- package/dist/lib.cjs/Message/PersonalMessageController.js +7 -10
- package/dist/lib.cjs/Message/SwitchChainController.js +6 -9
- package/dist/lib.cjs/Message/TypedMessageController.js +8 -8
- package/dist/lib.cjs/Nfts/NftsController.js +1 -2
- package/dist/lib.cjs/Preferences/PreferencesController.js +19 -3
- package/dist/lib.cjs/Tokens/TokenRatesController.js +1 -2
- package/dist/lib.cjs/Tokens/TokensController.js +1 -1
- package/dist/lib.cjs/Transaction/PendingTransactionTracker.js +2 -1
- package/dist/lib.cjs/index.js +15 -5
- package/dist/lib.cjs/utils/constants.js +10 -12
- package/dist/lib.cjs/utils/helpers.js +0 -25
- package/dist/lib.esm/AccountAbstraction/AccountAbstractionController.js +213 -0
- package/dist/lib.esm/AccountAbstraction/smartAccounts/BiconomySmartAccount.js +27 -0
- package/dist/lib.esm/AccountAbstraction/smartAccounts/KernelSmartAccount.js +22 -0
- package/dist/lib.esm/AccountAbstraction/smartAccounts/NexusSmartAccount.js +28 -0
- package/dist/lib.esm/AccountAbstraction/smartAccounts/SafeSmartAccount.js +30 -0
- package/dist/lib.esm/AccountAbstraction/smartAccounts/TrustSmartAccount.js +29 -0
- package/dist/lib.esm/Block/PollingBlockTracker.js +1 -2
- package/dist/lib.esm/Currency/CurrencyController.js +1 -2
- package/dist/lib.esm/Gas/GasFeeController.js +1 -2
- package/dist/lib.esm/Message/AddChainController.js +3 -6
- package/dist/lib.esm/Message/MessageController.js +4 -7
- package/dist/lib.esm/Message/PersonalMessageController.js +4 -7
- package/dist/lib.esm/Message/SwitchChainController.js +3 -6
- package/dist/lib.esm/Message/TypedMessageController.js +5 -5
- package/dist/lib.esm/Nfts/NftsController.js +1 -2
- package/dist/lib.esm/Preferences/PreferencesController.js +19 -3
- package/dist/lib.esm/Tokens/TokenRatesController.js +1 -2
- package/dist/lib.esm/Tokens/TokensController.js +2 -2
- package/dist/lib.esm/Transaction/PendingTransactionTracker.js +2 -1
- package/dist/lib.esm/index.js +8 -3
- package/dist/lib.esm/utils/constants.js +10 -11
- package/dist/lib.esm/utils/helpers.js +1 -25
- package/dist/types/AccountAbstraction/AccountAbstractionController.d.ts +52 -0
- package/dist/types/AccountAbstraction/smartAccounts/BiconomySmartAccount.d.ts +15 -0
- package/dist/types/AccountAbstraction/smartAccounts/KernelSmartAccount.d.ts +16 -0
- package/dist/types/AccountAbstraction/smartAccounts/LightSmartAccount.d.ts +15 -0
- package/dist/types/AccountAbstraction/smartAccounts/NexusSmartAccount.d.ts +15 -0
- package/dist/types/AccountAbstraction/smartAccounts/SafeSmartAccount.d.ts +16 -0
- package/dist/types/AccountAbstraction/smartAccounts/SimpleSmartAccount.d.ts +16 -0
- package/dist/types/AccountAbstraction/smartAccounts/TrustSmartAccount.d.ts +16 -0
- package/dist/types/AccountAbstraction/smartAccounts/index.d.ts +5 -0
- package/dist/types/Block/PollingBlockTracker.d.ts +2 -2
- package/dist/types/Currency/CurrencyController.d.ts +2 -2
- package/dist/types/Message/AddChainController.d.ts +3 -6
- package/dist/types/Message/MessageController.d.ts +5 -8
- package/dist/types/Message/PersonalMessageController.d.ts +5 -8
- package/dist/types/Message/SwitchChainController.d.ts +3 -6
- package/dist/types/Message/TypedMessageController.d.ts +3 -3
- package/dist/types/Message/types.d.ts +2 -0
- package/dist/types/Message/utils.d.ts +2 -1
- package/dist/types/Network/createEthereumMiddleware.d.ts +2 -2
- package/dist/types/Nfts/NftsController.d.ts +2 -2
- package/dist/types/Preferences/PreferencesController.d.ts +4 -1
- package/dist/types/Tokens/ITokensController.d.ts +4 -6
- package/dist/types/Tokens/TokenRatesController.d.ts +6 -14
- package/dist/types/Tokens/TokensController.d.ts +7 -7
- package/dist/types/Transaction/TransactionController.d.ts +2 -2
- package/dist/types/index.d.ts +2 -6
- package/dist/types/utils/constants.d.ts +8 -10
- package/dist/types/utils/helpers.d.ts +0 -3
- package/dist/types/utils/interfaces.d.ts +31 -2
- package/package.json +6 -4
- package/dist/lib.cjs/Message/AbstractMessageController.js +0 -107
- package/dist/lib.esm/Message/AbstractMessageController.js +0 -105
- package/dist/types/Message/AbstractMessageController.d.ts +0 -35
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import _objectSpread from '@babel/runtime/helpers/objectSpread2';
|
|
2
2
|
import _defineProperty from '@babel/runtime/helpers/defineProperty';
|
|
3
|
-
import { CHAIN_NAMESPACES, BaseController,
|
|
3
|
+
import { CHAIN_NAMESPACES, BaseController, TransactionStatus, BaseBlockTracker, idleTimeTracker, timeout, BaseCurrencyController, cloneDeep, BaseKeyringController, concatSig, AbstractMessageController, MessageStatus, randomId, MESSAGE_EVENTS, PROVIDER_JRPC_METHODS, createFetchMiddleware, createInflightCacheMiddleware, createSwappableProxy, createEventEmitterProxy, TRANSACTION_TYPES, formatSmallNumbers, addressSlicer, ACTIVITY_ACTION_RECEIVE, ACTIVITY_ACTION_SEND, significantDigits, BasePreferencesController, isUnauthorizedError, TX_EVENTS, BaseTransactionStateManager, omitBy, transactionMatchesNetwork as transactionMatchesNetwork$1, pickBy } from '@toruslabs/base-controllers';
|
|
4
4
|
import { Mutex } from 'async-mutex';
|
|
5
|
-
import { BrowserProvider, toQuantity, Contract,
|
|
5
|
+
import { BrowserProvider, toQuantity, Contract, isHexString, SigningKey, hashMessage, TypedDataEncoder, JsonRpcProvider, Interface, Transaction, keccak256 } from 'ethers';
|
|
6
6
|
import log from 'loglevel';
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
7
|
+
import { JRPCEngine, providerFromEngine, createAsyncMiddleware, mergeMiddleware, createScaffoldMiddleware, providerFromMiddleware, rpcErrors, SafeEventEmitter, providerErrors } from '@web3auth/auth';
|
|
8
|
+
import { defineChain, createPublicClient, http, createWalletClient } from 'viem';
|
|
9
|
+
import { createPaymasterClient, createBundlerClient, entryPoint06Address, entryPoint07Address } from 'viem/account-abstraction';
|
|
10
10
|
import { get } from '@toruslabs/http-helpers';
|
|
11
|
+
import { stripHexPrefix, isHexString as isHexString$1, addHexPrefix, bytesToHex, privateToPublic, toChecksumAddress, privateToAddress, ecsign, bigIntToBytes, isValidAddress } from '@ethereumjs/util';
|
|
12
|
+
import BigNumber from 'bignumber.js';
|
|
11
13
|
import _objectDestructuringEmpty from '@babel/runtime/helpers/objectDestructuringEmpty';
|
|
12
14
|
import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
|
|
13
15
|
import BN, { BN as BN$1 } from 'bn.js';
|
|
14
16
|
import stringify from 'fast-safe-stringify';
|
|
15
17
|
import deepmerge from 'deepmerge';
|
|
16
18
|
import jsonDiffer from 'fast-json-patch';
|
|
19
|
+
import { toBiconomySmartAccount, toEcdsaKernelSmartAccount, toNexusSmartAccount, toSafeSmartAccount, toTrustSmartAccount } from 'permissionless/accounts';
|
|
17
20
|
|
|
18
21
|
const erc20Abi = [{
|
|
19
22
|
constant: true,
|
|
@@ -827,16 +830,15 @@ const COINGECKO_PLATFORMS_CHAIN_CODE_MAP = {
|
|
|
827
830
|
currency: "eth"
|
|
828
831
|
}
|
|
829
832
|
};
|
|
830
|
-
const
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
UNAPPROVED_MESSAGE: "unapprovedMessage"
|
|
833
|
+
const SMART_ACCOUNT = {
|
|
834
|
+
BICONOMY: "biconomy",
|
|
835
|
+
KERNEL: "kernel",
|
|
836
|
+
SAFE: "safe",
|
|
837
|
+
TRUST: "trust",
|
|
838
|
+
// TODO: disabled because of pimlico issues
|
|
839
|
+
LIGHT: "light",
|
|
840
|
+
SIMPLE: "simple",
|
|
841
|
+
NEXUS: "nexus"
|
|
840
842
|
};
|
|
841
843
|
|
|
842
844
|
const SINGLE_CALL_BALANCES_ADDRESSES = {
|
|
@@ -998,837 +1000,607 @@ class AccountTrackerController extends BaseController {
|
|
|
998
1000
|
}
|
|
999
1001
|
}
|
|
1000
1002
|
|
|
1001
|
-
const
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
to: (to, LowerCase = true) => LowerCase ? addHexPrefix(to).toLowerCase() : addHexPrefix(to),
|
|
1010
|
-
nonce: nonce => addHexPrefix(nonce),
|
|
1011
|
-
customNonceValue: nonce => addHexPrefix(nonce),
|
|
1012
|
-
value: value => addHexPrefix(value),
|
|
1013
|
-
data: data => addHexPrefix(data),
|
|
1014
|
-
gas: gas => addHexPrefix(gas),
|
|
1015
|
-
gasPrice: gasPrice => addHexPrefix(gasPrice),
|
|
1016
|
-
type: addHexPrefix,
|
|
1017
|
-
maxFeePerGas: addHexPrefix,
|
|
1018
|
-
maxPriorityFeePerGas: addHexPrefix
|
|
1003
|
+
const eoaInterceptorMiddleware = eoaAddress => (req, res, next, end) => {
|
|
1004
|
+
req.isAAProviderRequest = true;
|
|
1005
|
+
if (req.method === "eth_accounts" || req.method === "eth_requestAccounts") {
|
|
1006
|
+
res.result = [eoaAddress];
|
|
1007
|
+
end();
|
|
1008
|
+
return;
|
|
1009
|
+
}
|
|
1010
|
+
next();
|
|
1019
1011
|
};
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1012
|
+
function eoaProviderAsMiddleware(provider) {
|
|
1013
|
+
return async (req, res, _next, end) => {
|
|
1014
|
+
// send request to provider
|
|
1015
|
+
try {
|
|
1016
|
+
const providerRes = await provider.request(req);
|
|
1017
|
+
res.result = providerRes;
|
|
1018
|
+
return end();
|
|
1019
|
+
} catch (error) {
|
|
1020
|
+
return end(error);
|
|
1021
|
+
}
|
|
1029
1022
|
};
|
|
1030
|
-
for (const key in normalizers) {
|
|
1031
|
-
const currentKey = key;
|
|
1032
|
-
if (txParameters[currentKey])
|
|
1033
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1034
|
-
normalizedTxParameters[currentKey] = normalizers[currentKey](txParameters[currentKey], lowerCase);
|
|
1035
|
-
}
|
|
1036
|
-
return normalizedTxParameters;
|
|
1037
1023
|
}
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1024
|
+
class AccountAbstractionController extends BaseController {
|
|
1025
|
+
constructor({
|
|
1026
|
+
config,
|
|
1027
|
+
state,
|
|
1028
|
+
getProviderConfig,
|
|
1029
|
+
onNetworkStateChange
|
|
1030
|
+
}) {
|
|
1031
|
+
super({
|
|
1032
|
+
state,
|
|
1033
|
+
config
|
|
1034
|
+
});
|
|
1035
|
+
_defineProperty(this, "_smartAccount", void 0);
|
|
1036
|
+
_defineProperty(this, "_publicClient", void 0);
|
|
1037
|
+
_defineProperty(this, "_walletClient", void 0);
|
|
1038
|
+
_defineProperty(this, "_bundlerClient", void 0);
|
|
1039
|
+
_defineProperty(this, "_paymasterClient", void 0);
|
|
1040
|
+
_defineProperty(this, "getProviderConfig", void 0);
|
|
1041
|
+
this.initialize();
|
|
1042
|
+
this.getProviderConfig = getProviderConfig;
|
|
1043
|
+
// TODO: handle network change in torus controller & call setupProvider
|
|
1044
|
+
onNetworkStateChange(networkState => {
|
|
1045
|
+
if (networkState.chainId !== this.config.chainId) {
|
|
1046
|
+
this.configure({
|
|
1047
|
+
chainId: networkState.chainId
|
|
1048
|
+
});
|
|
1049
|
+
}
|
|
1050
|
+
});
|
|
1051
|
+
}
|
|
1052
|
+
get smartAccount() {
|
|
1053
|
+
return this._smartAccount;
|
|
1054
|
+
}
|
|
1055
|
+
get bundlerClient() {
|
|
1056
|
+
return this._bundlerClient;
|
|
1057
|
+
}
|
|
1058
|
+
get walletClient() {
|
|
1059
|
+
return this._walletClient;
|
|
1060
|
+
}
|
|
1061
|
+
async setupProvider(eoaProvider, eoaAddress) {
|
|
1062
|
+
var _this$config$bundlerC;
|
|
1063
|
+
const providerConfig = this.getProviderConfig();
|
|
1064
|
+
const chain = defineChain({
|
|
1065
|
+
id: Number.parseInt(providerConfig.chainId, 16),
|
|
1066
|
+
// id in number form
|
|
1067
|
+
name: providerConfig.displayName,
|
|
1068
|
+
rpcUrls: {
|
|
1069
|
+
default: {
|
|
1070
|
+
http: [providerConfig.rpcTarget],
|
|
1071
|
+
webSocket: [providerConfig.wsTarget]
|
|
1072
|
+
}
|
|
1073
|
+
},
|
|
1074
|
+
blockExplorers: providerConfig.blockExplorerUrl ? {
|
|
1075
|
+
default: {
|
|
1076
|
+
name: "explorer",
|
|
1077
|
+
// TODO: correct name if chain config has it
|
|
1078
|
+
url: providerConfig.blockExplorerUrl
|
|
1079
|
+
}
|
|
1080
|
+
} : undefined,
|
|
1081
|
+
nativeCurrency: {
|
|
1082
|
+
name: providerConfig.tickerName,
|
|
1083
|
+
symbol: providerConfig.ticker,
|
|
1084
|
+
decimals: providerConfig.decimals || 18
|
|
1085
|
+
}
|
|
1086
|
+
});
|
|
1087
|
+
this._publicClient = createPublicClient({
|
|
1088
|
+
chain,
|
|
1089
|
+
transport: http(providerConfig.rpcTarget)
|
|
1090
|
+
});
|
|
1091
|
+
const aaEngine = new JRPCEngine();
|
|
1092
|
+
aaEngine.push(eoaInterceptorMiddleware(eoaAddress));
|
|
1093
|
+
aaEngine.push(eoaProviderAsMiddleware(eoaProvider));
|
|
1094
|
+
const provider = providerFromEngine(aaEngine);
|
|
1095
|
+
this._smartAccount = await this.config.smartAccountInit.getSmartAccount({
|
|
1096
|
+
owner: provider,
|
|
1097
|
+
client: this._publicClient
|
|
1098
|
+
});
|
|
1099
|
+
if (this.config.paymasterConfig) {
|
|
1100
|
+
var _this$config$paymaste;
|
|
1101
|
+
this._paymasterClient = createPaymasterClient(_objectSpread(_objectSpread({}, this.config.paymasterConfig), {}, {
|
|
1102
|
+
transport: (_this$config$paymaste = this.config.paymasterConfig.transport) !== null && _this$config$paymaste !== void 0 ? _this$config$paymaste : http(this.config.paymasterConfig.url)
|
|
1103
|
+
}));
|
|
1104
|
+
}
|
|
1105
|
+
this._bundlerClient = createBundlerClient(_objectSpread(_objectSpread({}, this.config.bundlerConfig), {}, {
|
|
1106
|
+
account: this.smartAccount,
|
|
1107
|
+
client: this._publicClient,
|
|
1108
|
+
transport: (_this$config$bundlerC = this.config.bundlerConfig.transport) !== null && _this$config$bundlerC !== void 0 ? _this$config$bundlerC : http(this.config.bundlerConfig.url),
|
|
1109
|
+
paymaster: this._paymasterClient
|
|
1110
|
+
}));
|
|
1111
|
+
this._walletClient = createWalletClient({
|
|
1112
|
+
account: this.smartAccount,
|
|
1113
|
+
chain,
|
|
1114
|
+
transport: http()
|
|
1115
|
+
});
|
|
1116
|
+
log.info("check: this._smartAccount", this.smartAccount.address);
|
|
1117
|
+
this.update({
|
|
1118
|
+
smartAccountAddress: this.smartAccount.address
|
|
1119
|
+
});
|
|
1120
|
+
}
|
|
1121
|
+
async sendTransaction(id, tx, address) {
|
|
1122
|
+
var _txParams$chainId;
|
|
1123
|
+
if (address.toLowerCase() !== this.smartAccount.address.toLowerCase()) {
|
|
1124
|
+
throw new Error("Invalid address");
|
|
1125
|
+
}
|
|
1126
|
+
const txParams = tx;
|
|
1127
|
+
const userOperationParams = {
|
|
1128
|
+
account: this.smartAccount,
|
|
1129
|
+
calls: [{
|
|
1130
|
+
to: txParams.to,
|
|
1131
|
+
// Explicit conversation required to avoid value being passed as hex
|
|
1132
|
+
value: BigInt(txParams.value),
|
|
1133
|
+
data: txParams.data
|
|
1134
|
+
}]
|
|
1135
|
+
// should not use maxFeePerGas/maxPriorityFeePerGas from transaction params since that's fee for transaction not user operation and let bundler handle it instead
|
|
1136
|
+
};
|
|
1137
|
+
const userOpMeta = {
|
|
1138
|
+
transactionParams: txParams,
|
|
1139
|
+
chainId: (_txParams$chainId = txParams.chainId) !== null && _txParams$chainId !== void 0 ? _txParams$chainId : this.getProviderConfig().chainId,
|
|
1140
|
+
createdAt: new Date(),
|
|
1141
|
+
status: TransactionStatus.approved
|
|
1142
|
+
};
|
|
1143
|
+
this.updateUserOpMeta(id, userOpMeta);
|
|
1144
|
+
// @ts-expect-error viem types are too deep
|
|
1145
|
+
const userOpHash = await this.bundlerClient.sendUserOperation(userOperationParams);
|
|
1146
|
+
this.updateUserOpMeta(id, {
|
|
1147
|
+
userOpHash,
|
|
1148
|
+
status: TransactionStatus.submitted
|
|
1149
|
+
});
|
|
1150
|
+
const txReceipt = await this.bundlerClient.waitForUserOperationReceipt({
|
|
1151
|
+
hash: userOpHash
|
|
1152
|
+
});
|
|
1153
|
+
this.updateUserOpMeta(id, {
|
|
1154
|
+
receipt: txReceipt,
|
|
1155
|
+
status: txReceipt.success ? TransactionStatus.confirmed : TransactionStatus.failed
|
|
1156
|
+
});
|
|
1157
|
+
return txReceipt.receipt.transactionHash;
|
|
1158
|
+
}
|
|
1159
|
+
async signMessage(message, address) {
|
|
1160
|
+
if (address.toLowerCase() !== this.smartAccount.address.toLowerCase()) {
|
|
1161
|
+
throw new Error("Invalid address");
|
|
1162
|
+
}
|
|
1163
|
+
return this.smartAccount.sign({
|
|
1164
|
+
hash: message
|
|
1165
|
+
});
|
|
1166
|
+
}
|
|
1167
|
+
async signPersonalMessage(message, address) {
|
|
1168
|
+
var _this$walletClient;
|
|
1169
|
+
if (address.toLowerCase() !== this.smartAccount.address.toLowerCase()) {
|
|
1170
|
+
throw new Error("Invalid address");
|
|
1171
|
+
}
|
|
1172
|
+
return (_this$walletClient = this.walletClient) === null || _this$walletClient === void 0 ? void 0 : _this$walletClient.signMessage({
|
|
1173
|
+
account: this.smartAccount,
|
|
1174
|
+
message: isHexString(message) ? {
|
|
1175
|
+
raw: message
|
|
1176
|
+
} : message
|
|
1177
|
+
});
|
|
1178
|
+
}
|
|
1179
|
+
async signTypedData(data, address) {
|
|
1180
|
+
var _this$walletClient2;
|
|
1181
|
+
if (address.toLowerCase() !== this.smartAccount.address.toLowerCase()) {
|
|
1182
|
+
throw new Error("Invalid address");
|
|
1183
|
+
}
|
|
1184
|
+
return (_this$walletClient2 = this.walletClient) === null || _this$walletClient2 === void 0 ? void 0 : _this$walletClient2.signTypedData({
|
|
1185
|
+
account: this.smartAccount,
|
|
1186
|
+
domain: _objectSpread(_objectSpread({}, data.domain), {}, {
|
|
1187
|
+
verifyingContract: data.domain.verifyingContract,
|
|
1188
|
+
salt: data.domain.salt,
|
|
1189
|
+
chainId: Number(data.domain.chainId)
|
|
1190
|
+
}),
|
|
1191
|
+
primaryType: data.primaryType,
|
|
1192
|
+
types: data.types,
|
|
1193
|
+
message: data.message
|
|
1194
|
+
});
|
|
1195
|
+
}
|
|
1196
|
+
updateUserOpMeta(id, data) {
|
|
1197
|
+
const userOp = this.state.userOperations[id];
|
|
1198
|
+
this.update({
|
|
1199
|
+
userOperations: _objectSpread(_objectSpread({}, this.state.userOperations), {}, {
|
|
1200
|
+
[id]: _objectSpread(_objectSpread({}, userOp), data)
|
|
1201
|
+
})
|
|
1202
|
+
});
|
|
1041
1203
|
}
|
|
1042
|
-
return false;
|
|
1043
1204
|
}
|
|
1044
1205
|
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1206
|
+
class BiconomySmartAccount {
|
|
1207
|
+
constructor(options) {
|
|
1208
|
+
_defineProperty(this, "name", SMART_ACCOUNT.BICONOMY);
|
|
1209
|
+
_defineProperty(this, "options", void 0);
|
|
1210
|
+
this.options = options;
|
|
1211
|
+
}
|
|
1212
|
+
async getSmartAccount(params) {
|
|
1213
|
+
var _this$options, _this$options2;
|
|
1214
|
+
return toBiconomySmartAccount(_objectSpread(_objectSpread(_objectSpread({}, this.options || {}), {}, {
|
|
1215
|
+
entryPoint: {
|
|
1216
|
+
address: ((_this$options = this.options) === null || _this$options === void 0 || (_this$options = _this$options.entryPoint) === null || _this$options === void 0 ? void 0 : _this$options.address) || entryPoint06Address,
|
|
1217
|
+
version: ((_this$options2 = this.options) === null || _this$options2 === void 0 || (_this$options2 = _this$options2.entryPoint) === null || _this$options2 === void 0 ? void 0 : _this$options2.version) || "0.6"
|
|
1218
|
+
}
|
|
1219
|
+
}, params), {}, {
|
|
1220
|
+
owners: [params.owner],
|
|
1221
|
+
client: params.client
|
|
1222
|
+
}));
|
|
1223
|
+
}
|
|
1054
1224
|
}
|
|
1055
1225
|
|
|
1056
|
-
|
|
1057
|
-
* Determine if the maxFeePerGas and maxPriorityFeePerGas fields are not
|
|
1058
|
-
* supplied and that the gasPrice field is valid if it is provided. This will
|
|
1059
|
-
* return false if gasPrice is a non hex string.
|
|
1060
|
-
* transaction -
|
|
1061
|
-
* the transaction to check
|
|
1062
|
-
* @returns true if transaction uses valid Legacy fields OR lacks
|
|
1063
|
-
* EIP1559 fields
|
|
1064
|
-
*/
|
|
1065
|
-
function isLegacyTransaction(transaction) {
|
|
1066
|
-
return typeof transaction.transaction.maxFeePerGas === "undefined" && typeof transaction.transaction.maxPriorityFeePerGas === "undefined" && (typeof transaction.transaction.gasPrice === "undefined" || isHexString(addHexPrefix(transaction.transaction.gasPrice)));
|
|
1067
|
-
}
|
|
1226
|
+
// use type of function so we don't need to pass in generic to parameter type
|
|
1068
1227
|
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1228
|
+
class KernelSmartAccount {
|
|
1229
|
+
constructor(options) {
|
|
1230
|
+
_defineProperty(this, "name", SMART_ACCOUNT.KERNEL);
|
|
1231
|
+
_defineProperty(this, "options", void 0);
|
|
1232
|
+
this.options = options;
|
|
1233
|
+
}
|
|
1234
|
+
async getSmartAccount(params) {
|
|
1235
|
+
return toEcdsaKernelSmartAccount(_objectSpread(_objectSpread(_objectSpread({}, this.options || {}), params), {}, {
|
|
1236
|
+
owners: [params.owner],
|
|
1237
|
+
client: params.client
|
|
1238
|
+
}));
|
|
1076
1239
|
}
|
|
1077
1240
|
}
|
|
1078
1241
|
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1242
|
+
class NexusSmartAccount {
|
|
1243
|
+
constructor(options) {
|
|
1244
|
+
_defineProperty(this, "name", SMART_ACCOUNT.NEXUS);
|
|
1245
|
+
_defineProperty(this, "options", void 0);
|
|
1246
|
+
this.options = options;
|
|
1247
|
+
}
|
|
1248
|
+
async getSmartAccount(params) {
|
|
1249
|
+
var _this$options, _this$options2, _this$options3;
|
|
1250
|
+
return toNexusSmartAccount(_objectSpread(_objectSpread(_objectSpread({}, this.options || {}), {}, {
|
|
1251
|
+
entryPoint: {
|
|
1252
|
+
address: ((_this$options = this.options) === null || _this$options === void 0 || (_this$options = _this$options.entryPoint) === null || _this$options === void 0 ? void 0 : _this$options.address) || entryPoint07Address,
|
|
1253
|
+
version: ((_this$options2 = this.options) === null || _this$options2 === void 0 || (_this$options2 = _this$options2.entryPoint) === null || _this$options2 === void 0 ? void 0 : _this$options2.version) || "0.7"
|
|
1254
|
+
},
|
|
1255
|
+
version: ((_this$options3 = this.options) === null || _this$options3 === void 0 ? void 0 : _this$options3.version) || "1.0.0"
|
|
1256
|
+
}, params), {}, {
|
|
1257
|
+
owners: [params.owner],
|
|
1258
|
+
client: params.client
|
|
1259
|
+
}));
|
|
1086
1260
|
}
|
|
1087
1261
|
}
|
|
1088
1262
|
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1263
|
+
// use type of function so we don't need to pass in generic to parameter type
|
|
1264
|
+
|
|
1265
|
+
class SafeSmartAccount {
|
|
1266
|
+
constructor(options) {
|
|
1267
|
+
_defineProperty(this, "name", SMART_ACCOUNT.SAFE);
|
|
1268
|
+
_defineProperty(this, "options", void 0);
|
|
1269
|
+
this.options = options;
|
|
1270
|
+
}
|
|
1271
|
+
async getSmartAccount(params) {
|
|
1272
|
+
var _this$options, _this$options2, _this$options3;
|
|
1273
|
+
return toSafeSmartAccount(_objectSpread(_objectSpread(_objectSpread({}, this.options || {}), {}, {
|
|
1274
|
+
entryPoint: {
|
|
1275
|
+
address: ((_this$options = this.options) === null || _this$options === void 0 || (_this$options = _this$options.entryPoint) === null || _this$options === void 0 ? void 0 : _this$options.address) || entryPoint07Address,
|
|
1276
|
+
version: ((_this$options2 = this.options) === null || _this$options2 === void 0 || (_this$options2 = _this$options2.entryPoint) === null || _this$options2 === void 0 ? void 0 : _this$options2.version) || "0.7"
|
|
1277
|
+
},
|
|
1278
|
+
version: ((_this$options3 = this.options) === null || _this$options3 === void 0 ? void 0 : _this$options3.version) || "1.4.1"
|
|
1279
|
+
}, params), {}, {
|
|
1280
|
+
owners: [params.owner],
|
|
1281
|
+
client: params.client
|
|
1282
|
+
}));
|
|
1107
1283
|
}
|
|
1108
1284
|
}
|
|
1109
1285
|
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1286
|
+
// use type of function so we don't need to pass in generic to parameter type
|
|
1287
|
+
|
|
1288
|
+
class TrustSmartAccount {
|
|
1289
|
+
constructor(options) {
|
|
1290
|
+
_defineProperty(this, "name", SMART_ACCOUNT.TRUST);
|
|
1291
|
+
_defineProperty(this, "options", void 0);
|
|
1292
|
+
this.options = options;
|
|
1293
|
+
}
|
|
1294
|
+
async getSmartAccount(params) {
|
|
1295
|
+
var _this$options, _this$options2;
|
|
1296
|
+
return toTrustSmartAccount(_objectSpread(_objectSpread(_objectSpread({}, this.options || {}), {}, {
|
|
1297
|
+
entryPoint: {
|
|
1298
|
+
address: ((_this$options = this.options) === null || _this$options === void 0 || (_this$options = _this$options.entryPoint) === null || _this$options === void 0 ? void 0 : _this$options.address) || entryPoint06Address,
|
|
1299
|
+
version: ((_this$options2 = this.options) === null || _this$options2 === void 0 || (_this$options2 = _this$options2.entryPoint) === null || _this$options2 === void 0 ? void 0 : _this$options2.version) || "0.6"
|
|
1300
|
+
}
|
|
1301
|
+
}, params), {}, {
|
|
1302
|
+
owner: params.owner,
|
|
1303
|
+
client: params.client
|
|
1304
|
+
}));
|
|
1119
1305
|
}
|
|
1120
1306
|
}
|
|
1121
1307
|
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1308
|
+
const DEFAULT_POLLING_INTERVAL = 20;
|
|
1309
|
+
const DEFAULT_RETRY_TIMEOUT = 2;
|
|
1310
|
+
const SEC = 1000;
|
|
1311
|
+
class PollingBlockTracker extends BaseBlockTracker {
|
|
1312
|
+
constructor({
|
|
1313
|
+
config,
|
|
1314
|
+
state = {}
|
|
1315
|
+
}) {
|
|
1316
|
+
if (!config.provider) {
|
|
1317
|
+
throw new Error("PollingBlockTracker - no provider specified.");
|
|
1131
1318
|
}
|
|
1132
|
-
|
|
1133
|
-
|
|
1319
|
+
super({
|
|
1320
|
+
config,
|
|
1321
|
+
state
|
|
1322
|
+
});
|
|
1323
|
+
const pollingInterval = config.pollingInterval || DEFAULT_POLLING_INTERVAL;
|
|
1324
|
+
const retryTimeout = config.retryTimeout || DEFAULT_RETRY_TIMEOUT;
|
|
1325
|
+
|
|
1326
|
+
// merge default + provided config.
|
|
1327
|
+
this.defaultConfig = {
|
|
1328
|
+
provider: config.provider,
|
|
1329
|
+
pollingInterval: pollingInterval * SEC,
|
|
1330
|
+
retryTimeout: retryTimeout * SEC,
|
|
1331
|
+
setSkipCacheFlag: config.setSkipCacheFlag || false
|
|
1332
|
+
};
|
|
1333
|
+
this.initialize();
|
|
1334
|
+
}
|
|
1335
|
+
async checkForLatestBlock() {
|
|
1336
|
+
await this._updateLatestBlock();
|
|
1337
|
+
return this.getLatestBlock();
|
|
1134
1338
|
}
|
|
1135
|
-
return txParameters;
|
|
1136
|
-
}
|
|
1137
1339
|
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
*/
|
|
1142
|
-
function validateTxParameters(txParams, eip1559Compatibility = true) {
|
|
1143
|
-
if (!txParams || typeof txParams !== "object" || Array.isArray(txParams)) {
|
|
1144
|
-
throw rpcErrors.invalidParams("Invalid transaction params: must be an object.");
|
|
1340
|
+
// overrides the BaseBlockTracker._start method.
|
|
1341
|
+
_start() {
|
|
1342
|
+
this._synchronize().catch(err => this.emit("error", err));
|
|
1145
1343
|
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1344
|
+
async _synchronize() {
|
|
1345
|
+
while (this.state._isRunning) {
|
|
1346
|
+
if (idleTimeTracker.checkIfIdle()) return;
|
|
1347
|
+
try {
|
|
1348
|
+
await this._updateLatestBlock();
|
|
1349
|
+
await timeout(this.config.pollingInterval);
|
|
1350
|
+
} catch (err) {
|
|
1351
|
+
const newErr = new Error(`PollingBlockTracker - encountered an error while attempting to update latest block:\n${err.stack}`);
|
|
1352
|
+
try {
|
|
1353
|
+
this.emit("error", newErr);
|
|
1354
|
+
} catch (emitErr) {
|
|
1355
|
+
log.error(newErr);
|
|
1356
|
+
}
|
|
1357
|
+
await timeout(this.config.retryTimeout);
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1148
1360
|
}
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1361
|
+
async _updateLatestBlock() {
|
|
1362
|
+
// fetch + set latest block
|
|
1363
|
+
const latestBlock = await this._fetchLatestBlock();
|
|
1364
|
+
this._newPotentialLatest(latestBlock);
|
|
1153
1365
|
}
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
ensureProperTransactionEnvelopeTypeProvided(txParams, "maxFeePerGas");
|
|
1171
|
-
ensureMutuallyExclusiveFieldsNotProvided(txParams, "maxFeePerGas", "gasPrice");
|
|
1172
|
-
ensureFieldIsString(txParams, "maxFeePerGas");
|
|
1173
|
-
break;
|
|
1174
|
-
case "maxPriorityFeePerGas":
|
|
1175
|
-
ensureProperTransactionEnvelopeTypeProvided(txParams, "maxPriorityFeePerGas");
|
|
1176
|
-
ensureMutuallyExclusiveFieldsNotProvided(txParams, "maxPriorityFeePerGas", "gasPrice");
|
|
1177
|
-
ensureFieldIsString(txParams, "maxPriorityFeePerGas");
|
|
1178
|
-
break;
|
|
1179
|
-
case "value":
|
|
1180
|
-
ensureFieldIsString(txParams, "value");
|
|
1181
|
-
if (value.toString().includes("-")) {
|
|
1182
|
-
throw rpcErrors.invalidParams(`Invalid transaction value "${value}": not a positive number.`);
|
|
1183
|
-
}
|
|
1184
|
-
if (value.toString().includes(".")) {
|
|
1185
|
-
throw rpcErrors.invalidParams(`Invalid transaction value of "${value}": number must be in wei.`);
|
|
1186
|
-
}
|
|
1187
|
-
break;
|
|
1188
|
-
case "chainId":
|
|
1189
|
-
if (typeof value !== "number" && typeof value !== "string") {
|
|
1190
|
-
throw rpcErrors.invalidParams(`Invalid transaction params: ${key} is not a Number or hex string. got: (${value})`);
|
|
1191
|
-
}
|
|
1192
|
-
break;
|
|
1193
|
-
default:
|
|
1194
|
-
ensureFieldIsString(txParams, key);
|
|
1366
|
+
async _fetchLatestBlock() {
|
|
1367
|
+
try {
|
|
1368
|
+
const block = await this.config.provider.request({
|
|
1369
|
+
method: "eth_getBlockByNumber",
|
|
1370
|
+
params: ["latest", false]
|
|
1371
|
+
});
|
|
1372
|
+
return {
|
|
1373
|
+
blockHash: block.hash,
|
|
1374
|
+
idempotencyKey: block.number,
|
|
1375
|
+
timestamp: block.timestamp,
|
|
1376
|
+
baseFeePerGas: block.baseFeePerGas,
|
|
1377
|
+
gasLimit: block.gasLimit
|
|
1378
|
+
};
|
|
1379
|
+
} catch (error) {
|
|
1380
|
+
log.error("Polling Block Tracker: ", error);
|
|
1381
|
+
throw new Error(`PollingBlockTracker - encountered error fetching block:\n${error.message}`);
|
|
1195
1382
|
}
|
|
1196
|
-
}
|
|
1197
|
-
}
|
|
1198
|
-
function normalizeAndValidateTxParams(txParams, lowerCase = true) {
|
|
1199
|
-
const normalizedTxParams = normalizeTxParameters(txParams, lowerCase);
|
|
1200
|
-
validateTxParameters(normalizedTxParams);
|
|
1201
|
-
return normalizedTxParams;
|
|
1383
|
+
}
|
|
1202
1384
|
}
|
|
1203
1385
|
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
// the tx failed for some reason, included on tx data.
|
|
1214
|
-
TransactionStatus.dropped // the tx nonce was already used
|
|
1215
|
-
];
|
|
1216
|
-
}
|
|
1217
|
-
function parseStandardTokenTransactionData(data) {
|
|
1218
|
-
try {
|
|
1219
|
-
const txDesc = erc20Interface.parseTransaction({
|
|
1220
|
-
data
|
|
1386
|
+
class CurrencyController extends BaseCurrencyController {
|
|
1387
|
+
constructor({
|
|
1388
|
+
config,
|
|
1389
|
+
state,
|
|
1390
|
+
onNetworkChanged
|
|
1391
|
+
}) {
|
|
1392
|
+
super({
|
|
1393
|
+
config,
|
|
1394
|
+
state
|
|
1221
1395
|
});
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
};
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1396
|
+
_defineProperty(this, "conversionInterval", void 0);
|
|
1397
|
+
this.defaultState = _objectSpread(_objectSpread({}, this.defaultState), {}, {
|
|
1398
|
+
commonDenomination: "USD",
|
|
1399
|
+
commonDenominatorPrice: 0
|
|
1400
|
+
});
|
|
1401
|
+
this.initialize();
|
|
1402
|
+
onNetworkChanged(networkState => {
|
|
1403
|
+
// to be called as (listener) => this.networkController.on('networkDidChange', listener);
|
|
1404
|
+
if (networkState.providerConfig.ticker.toUpperCase() !== this.state.nativeCurrency.toUpperCase()) {
|
|
1405
|
+
this.setNativeCurrency(networkState.providerConfig.ticker);
|
|
1406
|
+
this.updateConversionRate();
|
|
1407
|
+
}
|
|
1233
1408
|
});
|
|
1234
|
-
if (txDesc) return {
|
|
1235
|
-
name: txDesc.name,
|
|
1236
|
-
methodParams: txDesc.args.toArray(),
|
|
1237
|
-
type: CONTRACT_TYPE_ERC721
|
|
1238
|
-
};
|
|
1239
|
-
} catch {
|
|
1240
|
-
// ignore and next try to parse with erc1155 ABI
|
|
1241
1409
|
}
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1410
|
+
setCommonDenomination(commonDenomination) {
|
|
1411
|
+
this.update({
|
|
1412
|
+
commonDenomination
|
|
1245
1413
|
});
|
|
1246
|
-
if (txDesc) return {
|
|
1247
|
-
name: txDesc.name,
|
|
1248
|
-
methodParams: txDesc.args.toArray(),
|
|
1249
|
-
type: CONTRACT_TYPE_ERC1155
|
|
1250
|
-
};
|
|
1251
|
-
} catch {
|
|
1252
|
-
// ignore and return undefined
|
|
1253
1414
|
}
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
method: METHOD_TYPES.ETH_GET_CODE,
|
|
1261
|
-
params: [address, "latest"]
|
|
1415
|
+
getCommonDenomination() {
|
|
1416
|
+
return this.state.commonDenomination;
|
|
1417
|
+
}
|
|
1418
|
+
setCommonDenominatorPrice(commonDenominatorPrice) {
|
|
1419
|
+
this.update({
|
|
1420
|
+
commonDenominatorPrice
|
|
1262
1421
|
});
|
|
1263
|
-
} catch (e) {
|
|
1264
|
-
contractCode = null;
|
|
1265
1422
|
}
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
contractCode,
|
|
1269
|
-
isContractAddress
|
|
1270
|
-
};
|
|
1271
|
-
};
|
|
1272
|
-
async function determineTransactionType(txParams, provider) {
|
|
1273
|
-
const {
|
|
1274
|
-
data,
|
|
1275
|
-
to
|
|
1276
|
-
} = txParams;
|
|
1277
|
-
let name = "";
|
|
1278
|
-
let methodParams = [];
|
|
1279
|
-
let type = "";
|
|
1280
|
-
try {
|
|
1281
|
-
({
|
|
1282
|
-
name,
|
|
1283
|
-
methodParams,
|
|
1284
|
-
type
|
|
1285
|
-
} = data && parseStandardTokenTransactionData(data) || {});
|
|
1286
|
-
} catch (error) {
|
|
1287
|
-
log.debug("Failed to parse transaction data", error);
|
|
1423
|
+
getCommonDenominatorPrice() {
|
|
1424
|
+
return this.state.commonDenominatorPrice;
|
|
1288
1425
|
}
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1426
|
+
|
|
1427
|
+
/**
|
|
1428
|
+
* Creates a new poll, using setInterval, to periodically call updateConversionRate. The id of the interval is
|
|
1429
|
+
* stored at the controller's conversionInterval property. If it is called and such an id already exists, the
|
|
1430
|
+
* previous interval is clear and a new one is created.
|
|
1431
|
+
*/
|
|
1432
|
+
scheduleConversionInterval() {
|
|
1433
|
+
if (this.conversionInterval) {
|
|
1434
|
+
window.clearInterval(this.conversionInterval);
|
|
1435
|
+
}
|
|
1436
|
+
this.conversionInterval = window.setInterval(() => {
|
|
1437
|
+
if (!idleTimeTracker.checkIfIdle()) {
|
|
1438
|
+
this.updateConversionRate();
|
|
1439
|
+
}
|
|
1440
|
+
}, this.config.pollInterval);
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
/**
|
|
1444
|
+
* Updates the conversionRate and conversionDate properties associated with the currentCurrency. Updated info is
|
|
1445
|
+
* fetched from an external API
|
|
1446
|
+
*/
|
|
1447
|
+
async updateConversionRate() {
|
|
1448
|
+
const currentCurrency = this.getCurrentCurrency();
|
|
1449
|
+
const nativeCurrency = this.getNativeCurrency();
|
|
1450
|
+
const commonDenomination = this.getCommonDenomination();
|
|
1451
|
+
const conversionRate = await this.retrieveConversionRate(nativeCurrency, currentCurrency, commonDenomination);
|
|
1452
|
+
const currentCurrencyRate = Number.parseFloat(conversionRate[currentCurrency.toUpperCase()]);
|
|
1453
|
+
const commonDenominationRate = Number.parseFloat(conversionRate[commonDenomination.toUpperCase()]);
|
|
1454
|
+
// set conversion rate
|
|
1455
|
+
if (currentCurrencyRate || commonDenominationRate) {
|
|
1456
|
+
// ETC
|
|
1457
|
+
this.setConversionRate(currentCurrencyRate);
|
|
1458
|
+
this.setConversionDate(Math.floor(Date.now() / 1000).toString());
|
|
1459
|
+
if (currentCurrency.toUpperCase() === commonDenomination.toUpperCase()) {
|
|
1460
|
+
this.setCommonDenominatorPrice(currentCurrencyRate);
|
|
1461
|
+
} else {
|
|
1462
|
+
this.setCommonDenominatorPrice(commonDenominationRate);
|
|
1463
|
+
}
|
|
1306
1464
|
} else {
|
|
1307
|
-
|
|
1465
|
+
this.setConversionRate(0);
|
|
1466
|
+
this.setConversionDate("N/A");
|
|
1308
1467
|
}
|
|
1309
1468
|
}
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1469
|
+
async retrieveConversionRate(fromCurrency, toCurrency, commonDenomination) {
|
|
1470
|
+
try {
|
|
1471
|
+
let apiUrl = `${this.config.api}/currency?fsym=${fromCurrency.toUpperCase()}&tsyms=${toCurrency.toUpperCase()}`;
|
|
1472
|
+
if (commonDenomination && commonDenomination.toUpperCase() !== toCurrency.toUpperCase()) {
|
|
1473
|
+
apiUrl += `,${commonDenomination.toUpperCase()}`;
|
|
1474
|
+
}
|
|
1475
|
+
const parsedResponse = await get(apiUrl);
|
|
1476
|
+
return parsedResponse;
|
|
1477
|
+
} catch (error) {
|
|
1478
|
+
log.error(error, `CurrencyController - updateCommonDenominatorPrice: Failed to query rate for currency: ${fromCurrency}/ ${toCurrency}`);
|
|
1479
|
+
}
|
|
1480
|
+
return {
|
|
1481
|
+
[toCurrency.toUpperCase()]: "0",
|
|
1482
|
+
[commonDenomination.toUpperCase()]: "0"
|
|
1483
|
+
};
|
|
1484
|
+
}
|
|
1316
1485
|
}
|
|
1317
1486
|
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
action: lowerCaseSelectedAddress === ((_transaction$to = transaction.to) === null || _transaction$to === void 0 ? void 0 : _transaction$to.toLowerCase()) || "" ? ACTIVITY_ACTION_RECEIVE : ACTIVITY_ACTION_SEND,
|
|
1347
|
-
totalAmount: transaction.total_amount,
|
|
1348
|
-
totalAmountString,
|
|
1349
|
-
currencyAmount: transaction.currency_amount,
|
|
1350
|
-
currencyAmountString,
|
|
1351
|
-
amount: `${totalAmountString} / ${currencyAmountString}`,
|
|
1352
|
-
status: transaction.status,
|
|
1353
|
-
etherscanLink: blockExplorerUrl ? `${blockExplorerUrl}/tx/${transaction.transaction_hash}` : "",
|
|
1354
|
-
chainId: transaction.chain_id,
|
|
1355
|
-
ethRate: Number.parseFloat(transaction === null || transaction === void 0 ? void 0 : transaction.total_amount) && Number.parseFloat(transaction === null || transaction === void 0 ? void 0 : transaction.currency_amount) ? `1 ${transaction.symbol} = ${significantDigits(Number.parseFloat(transaction.currency_amount) / Number.parseFloat(transaction.total_amount))}` : "",
|
|
1356
|
-
currencyUsed: transaction.selected_currency,
|
|
1357
|
-
type: transaction.type,
|
|
1358
|
-
type_name: transaction.type_name,
|
|
1359
|
-
type_image_link: transaction.type_image_link,
|
|
1360
|
-
transaction_hash: transaction.transaction_hash,
|
|
1361
|
-
transaction_category: transaction.transaction_category,
|
|
1362
|
-
isEtherscan: transaction.isEtherscan,
|
|
1363
|
-
input: transaction.input || "",
|
|
1364
|
-
token_id: transaction.token_id || "",
|
|
1365
|
-
contract_address: transaction.contract_address || "",
|
|
1366
|
-
nonce: transaction.nonce || "",
|
|
1367
|
-
is_cancel: !!transaction.is_cancel || false,
|
|
1368
|
-
gas: transaction.gas || "",
|
|
1369
|
-
gasPrice: transaction.gasPrice || ""
|
|
1370
|
-
};
|
|
1371
|
-
return finalObject;
|
|
1487
|
+
const _excluded$1 = ["aBase", "bBase"],
|
|
1488
|
+
_excluded2 = ["aBase", "bBase"],
|
|
1489
|
+
_excluded3 = ["multiplicandBase", "multiplierBase"];
|
|
1490
|
+
|
|
1491
|
+
// Big Number Constants
|
|
1492
|
+
const BIG_NUMBER_WEI_MULTIPLIER = new BigNumber("1000000000000000000");
|
|
1493
|
+
const BIG_NUMBER_GWEI_MULTIPLIER = new BigNumber("1000000000");
|
|
1494
|
+
const BIG_NUMBER_ETH_MULTIPLIER = new BigNumber("1");
|
|
1495
|
+
// Setter Maps
|
|
1496
|
+
const toBigNumber = {
|
|
1497
|
+
hex: n => new BigNumber(stripHexPrefix(n), 16),
|
|
1498
|
+
dec: n => new BigNumber(String(n), 10),
|
|
1499
|
+
BN: n => new BigNumber(n.toString(16), 16)
|
|
1500
|
+
};
|
|
1501
|
+
const toNormalizedDenomination = {
|
|
1502
|
+
WEI: bigNumber => bigNumber.div(BIG_NUMBER_WEI_MULTIPLIER),
|
|
1503
|
+
GWEI: bigNumber => bigNumber.div(BIG_NUMBER_GWEI_MULTIPLIER),
|
|
1504
|
+
ETH: bigNumber => bigNumber.div(BIG_NUMBER_ETH_MULTIPLIER)
|
|
1505
|
+
};
|
|
1506
|
+
const toSpecifiedDenomination = {
|
|
1507
|
+
WEI: bigNumber => bigNumber.times(BIG_NUMBER_WEI_MULTIPLIER).dp(0, BigNumber.ROUND_HALF_UP),
|
|
1508
|
+
GWEI: bigNumber => bigNumber.times(BIG_NUMBER_GWEI_MULTIPLIER).dp(9, BigNumber.ROUND_HALF_UP),
|
|
1509
|
+
ETH: bigNumber => bigNumber.times(BIG_NUMBER_ETH_MULTIPLIER).dp(9, BigNumber.ROUND_HALF_UP)
|
|
1510
|
+
};
|
|
1511
|
+
const baseChange = {
|
|
1512
|
+
hex: n => n.toString(16),
|
|
1513
|
+
dec: n => new BigNumber(n).toString(10),
|
|
1514
|
+
BN: n => new BN(n.toString(16))
|
|
1372
1515
|
};
|
|
1373
1516
|
|
|
1517
|
+
// Utility function for checking base types
|
|
1518
|
+
const isValidBase = base => Number.isInteger(base) && base > 1;
|
|
1519
|
+
|
|
1374
1520
|
/**
|
|
1375
|
-
*
|
|
1521
|
+
* Utility method to convert a value between denominations, formats and currencies.
|
|
1376
1522
|
*/
|
|
1377
|
-
const
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1523
|
+
const converter = ({
|
|
1524
|
+
value,
|
|
1525
|
+
fromNumericBase,
|
|
1526
|
+
fromDenomination,
|
|
1527
|
+
fromCurrency,
|
|
1528
|
+
toNumericBase,
|
|
1529
|
+
toDenomination,
|
|
1530
|
+
toCurrency,
|
|
1531
|
+
numberOfDecimals,
|
|
1532
|
+
conversionRate,
|
|
1533
|
+
invertConversionRate,
|
|
1534
|
+
roundDown
|
|
1535
|
+
}) => {
|
|
1536
|
+
let convertedValue = fromNumericBase ? toBigNumber[fromNumericBase](value) : value;
|
|
1537
|
+
if (fromDenomination) {
|
|
1538
|
+
convertedValue = toNormalizedDenomination[fromDenomination](convertedValue);
|
|
1390
1539
|
}
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
const idleTimeTracker = (activityThresholdTime => {
|
|
1404
|
-
let isIdle = false;
|
|
1405
|
-
let idleTimeout = null;
|
|
1406
|
-
const resetTimer = () => {
|
|
1407
|
-
if (idleTimeout) {
|
|
1408
|
-
window.clearTimeout(idleTimeout);
|
|
1409
|
-
}
|
|
1410
|
-
isIdle = false;
|
|
1411
|
-
idleTimeout = window.setTimeout(() => {
|
|
1412
|
-
isIdle = true;
|
|
1413
|
-
}, activityThresholdTime * 1000);
|
|
1414
|
-
};
|
|
1415
|
-
if (typeof window !== "undefined" && typeof document !== "undefined") {
|
|
1416
|
-
window.addEventListener("load", resetTimer);
|
|
1417
|
-
document.addEventListener("mousemove", resetTimer);
|
|
1418
|
-
document.addEventListener("keydown", resetTimer);
|
|
1540
|
+
if (fromCurrency !== toCurrency) {
|
|
1541
|
+
if (conversionRate === null || conversionRate === undefined) {
|
|
1542
|
+
throw new Error(`Converting from ${fromCurrency} to ${toCurrency} requires a conversionRate, but one was not provided`);
|
|
1543
|
+
}
|
|
1544
|
+
let rate = toBigNumber.dec(conversionRate);
|
|
1545
|
+
if (invertConversionRate) {
|
|
1546
|
+
rate = new BigNumber(1).div(conversionRate);
|
|
1547
|
+
}
|
|
1548
|
+
convertedValue = convertedValue.times(rate);
|
|
1549
|
+
}
|
|
1550
|
+
if (toDenomination) {
|
|
1551
|
+
convertedValue = toSpecifiedDenomination[toDenomination](convertedValue);
|
|
1419
1552
|
}
|
|
1420
|
-
|
|
1421
|
-
|
|
1553
|
+
if (numberOfDecimals) {
|
|
1554
|
+
convertedValue = convertedValue.dp(numberOfDecimals, BigNumber.ROUND_HALF_DOWN);
|
|
1422
1555
|
}
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
}
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
return
|
|
1430
|
-
}
|
|
1431
|
-
function toChecksumAddressByChainId(address, chainId) {
|
|
1432
|
-
// TOOD: add rsk network checks.
|
|
1433
|
-
if (!isAddressByChainId(address)) return address;
|
|
1434
|
-
return toChecksumAddress(address);
|
|
1435
|
-
}
|
|
1436
|
-
const GAS_LIMITS = {
|
|
1437
|
-
// maximum gasLimit of a simple send
|
|
1438
|
-
SIMPLE: addHexPrefix(21000 .toString(16)),
|
|
1439
|
-
// a base estimate for token transfers.
|
|
1440
|
-
BASE_TOKEN_ESTIMATE: addHexPrefix(100000 .toString(16))
|
|
1556
|
+
if (roundDown) {
|
|
1557
|
+
convertedValue = convertedValue.dp(roundDown, BigNumber.ROUND_DOWN);
|
|
1558
|
+
}
|
|
1559
|
+
if (toNumericBase) {
|
|
1560
|
+
convertedValue = baseChange[toNumericBase](convertedValue);
|
|
1561
|
+
}
|
|
1562
|
+
return convertedValue;
|
|
1441
1563
|
};
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1564
|
+
const conversionUtil = (value, {
|
|
1565
|
+
fromCurrency = null,
|
|
1566
|
+
toCurrency = fromCurrency,
|
|
1567
|
+
fromNumericBase,
|
|
1568
|
+
toNumericBase,
|
|
1569
|
+
fromDenomination,
|
|
1570
|
+
toDenomination,
|
|
1571
|
+
numberOfDecimals,
|
|
1572
|
+
conversionRate,
|
|
1573
|
+
invertConversionRate
|
|
1574
|
+
}) => {
|
|
1575
|
+
if (fromCurrency !== toCurrency && !conversionRate) {
|
|
1576
|
+
return 0;
|
|
1445
1577
|
}
|
|
1446
|
-
return
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1578
|
+
return converter({
|
|
1579
|
+
fromCurrency,
|
|
1580
|
+
toCurrency,
|
|
1581
|
+
fromNumericBase,
|
|
1582
|
+
toNumericBase,
|
|
1583
|
+
fromDenomination,
|
|
1584
|
+
toDenomination,
|
|
1585
|
+
numberOfDecimals,
|
|
1586
|
+
conversionRate,
|
|
1587
|
+
invertConversionRate,
|
|
1588
|
+
value
|
|
1589
|
+
});
|
|
1590
|
+
};
|
|
1591
|
+
const getBigNumber = (value, base) => {
|
|
1592
|
+
if (!isValidBase(base)) {
|
|
1593
|
+
throw new Error("Must specificy valid base");
|
|
1454
1594
|
}
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
if (
|
|
1459
|
-
return
|
|
1460
|
-
} else if (TEST_CHAINS.includes(chainId)) {
|
|
1461
|
-
return "testnet";
|
|
1595
|
+
|
|
1596
|
+
// We don't include 'number' here, because BigNumber will throw if passed
|
|
1597
|
+
// a number primitive it considers unsafe.
|
|
1598
|
+
if (typeof value === "string" || value instanceof BigNumber) {
|
|
1599
|
+
return new BigNumber(value, base);
|
|
1462
1600
|
}
|
|
1463
|
-
return
|
|
1464
|
-
}
|
|
1465
|
-
const
|
|
1466
|
-
const {
|
|
1467
|
-
txn,
|
|
1468
|
-
lowerCaseSelectedAddress,
|
|
1469
|
-
provider,
|
|
1470
|
-
chainId,
|
|
1471
|
-
blockExplorerUrl
|
|
1472
|
-
} = params;
|
|
1473
|
-
const transactionPromises = await Promise.all(txn.map(async tx => {
|
|
1474
|
-
var _SUPPORTED_NETWORKS$c, _SUPPORTED_NETWORKS$c2;
|
|
1475
|
-
const {
|
|
1476
|
-
category,
|
|
1477
|
-
type
|
|
1478
|
-
} = await determineTransactionType(_objectSpread(_objectSpread({}, tx), {}, {
|
|
1479
|
-
data: tx.input
|
|
1480
|
-
}), provider);
|
|
1481
|
-
tx.transaction_category = tx.transaction_category || category;
|
|
1482
|
-
tx.type_image_link = ((_SUPPORTED_NETWORKS$c = SUPPORTED_NETWORKS[chainId]) === null || _SUPPORTED_NETWORKS$c === void 0 ? void 0 : _SUPPORTED_NETWORKS$c.logo) || "";
|
|
1483
|
-
tx.type_name = (_SUPPORTED_NETWORKS$c2 = SUPPORTED_NETWORKS[chainId]) === null || _SUPPORTED_NETWORKS$c2 === void 0 ? void 0 : _SUPPORTED_NETWORKS$c2.ticker;
|
|
1484
|
-
tx.type = type;
|
|
1485
|
-
return tx;
|
|
1486
|
-
}));
|
|
1487
|
-
const finalTxs = transactionPromises.reduce((accumulator, x) => {
|
|
1488
|
-
var _SUPPORTED_NETWORKS$c3, _SUPPORTED_NETWORKS$c4;
|
|
1489
|
-
let totalAmountString = x.value ? new BigNumber(x.value).div(new BigNumber(10).pow(new BigNumber(x.tokenDecimal || 18))).toString() : "";
|
|
1490
|
-
let type = CONTRACT_TYPE_ETH;
|
|
1491
|
-
if (x.contractAddress !== "") {
|
|
1492
|
-
if (x.tokenID) {
|
|
1493
|
-
type = x.tokenValue ? CONTRACT_TYPE_ERC1155 : CONTRACT_TYPE_ERC721;
|
|
1494
|
-
} else {
|
|
1495
|
-
type = CONTRACT_TYPE_ERC20;
|
|
1496
|
-
}
|
|
1497
|
-
}
|
|
1498
|
-
if (type === CONTRACT_TYPE_ERC1155) {
|
|
1499
|
-
totalAmountString = x.tokenValue;
|
|
1500
|
-
}
|
|
1501
|
-
const etherscanTransaction = {
|
|
1502
|
-
type,
|
|
1503
|
-
type_image_link: x.type_image_link || "n/a",
|
|
1504
|
-
type_name: x.tokenName || ((_SUPPORTED_NETWORKS$c3 = SUPPORTED_NETWORKS[chainId]) === null || _SUPPORTED_NETWORKS$c3 === void 0 ? void 0 : _SUPPORTED_NETWORKS$c3.ticker) || "n/a",
|
|
1505
|
-
symbol: x.tokenSymbol || ((_SUPPORTED_NETWORKS$c4 = SUPPORTED_NETWORKS[chainId]) === null || _SUPPORTED_NETWORKS$c4 === void 0 ? void 0 : _SUPPORTED_NETWORKS$c4.ticker),
|
|
1506
|
-
token_id: x.tokenID || "",
|
|
1507
|
-
total_amount: totalAmountString,
|
|
1508
|
-
created_at: new Date(Number(x.timeStamp) * 1000),
|
|
1509
|
-
from: x.from,
|
|
1510
|
-
to: x.to,
|
|
1511
|
-
transaction_hash: x.hash,
|
|
1512
|
-
status: x.txreceipt_status && x.txreceipt_status === "0" ? TransactionStatus.failed : TransactionStatus.confirmed,
|
|
1513
|
-
isEtherscan: true,
|
|
1514
|
-
input: x.input,
|
|
1515
|
-
contract_address: x.contractAddress,
|
|
1516
|
-
transaction_category: x.transaction_category,
|
|
1517
|
-
gas: `0x${new BigNumber(x.gasUsed || 0, 10).toString(16)}`,
|
|
1518
|
-
gasPrice: `0x${new BigNumber(x.gasPrice || 0, 10).toString(16)}`,
|
|
1519
|
-
chain_id: chainId,
|
|
1520
|
-
currency_amount: "",
|
|
1521
|
-
nonce: x.nonce,
|
|
1522
|
-
from_aa_address: "",
|
|
1523
|
-
is_cancel: false,
|
|
1524
|
-
selected_currency: ""
|
|
1525
|
-
};
|
|
1526
|
-
accumulator.push(formatPastTx({
|
|
1527
|
-
transaction: etherscanTransaction,
|
|
1528
|
-
lowerCaseSelectedAddress,
|
|
1529
|
-
blockExplorerUrl
|
|
1530
|
-
}));
|
|
1531
|
-
return accumulator;
|
|
1532
|
-
}, []);
|
|
1533
|
-
return finalTxs;
|
|
1534
|
-
};
|
|
1535
|
-
|
|
1536
|
-
const DEFAULT_POLLING_INTERVAL = 20;
|
|
1537
|
-
const DEFAULT_RETRY_TIMEOUT = 2;
|
|
1538
|
-
const SEC = 1000;
|
|
1539
|
-
class PollingBlockTracker extends BaseBlockTracker {
|
|
1540
|
-
constructor({
|
|
1541
|
-
config,
|
|
1542
|
-
state = {}
|
|
1543
|
-
}) {
|
|
1544
|
-
if (!config.provider) {
|
|
1545
|
-
throw new Error("PollingBlockTracker - no provider specified.");
|
|
1546
|
-
}
|
|
1547
|
-
super({
|
|
1548
|
-
config,
|
|
1549
|
-
state
|
|
1550
|
-
});
|
|
1551
|
-
const pollingInterval = config.pollingInterval || DEFAULT_POLLING_INTERVAL;
|
|
1552
|
-
const retryTimeout = config.retryTimeout || DEFAULT_RETRY_TIMEOUT;
|
|
1553
|
-
|
|
1554
|
-
// merge default + provided config.
|
|
1555
|
-
this.defaultConfig = {
|
|
1556
|
-
provider: config.provider,
|
|
1557
|
-
pollingInterval: pollingInterval * SEC,
|
|
1558
|
-
retryTimeout: retryTimeout * SEC,
|
|
1559
|
-
setSkipCacheFlag: config.setSkipCacheFlag || false
|
|
1560
|
-
};
|
|
1561
|
-
this.initialize();
|
|
1562
|
-
}
|
|
1563
|
-
async checkForLatestBlock() {
|
|
1564
|
-
await this._updateLatestBlock();
|
|
1565
|
-
return this.getLatestBlock();
|
|
1566
|
-
}
|
|
1567
|
-
|
|
1568
|
-
// overrides the BaseBlockTracker._start method.
|
|
1569
|
-
_start() {
|
|
1570
|
-
this._synchronize().catch(err => this.emit("error", err));
|
|
1571
|
-
}
|
|
1572
|
-
async _synchronize() {
|
|
1573
|
-
while (this.state._isRunning) {
|
|
1574
|
-
if (idleTimeTracker.checkIfIdle()) return;
|
|
1575
|
-
try {
|
|
1576
|
-
await this._updateLatestBlock();
|
|
1577
|
-
await timeout(this.config.pollingInterval);
|
|
1578
|
-
} catch (err) {
|
|
1579
|
-
const newErr = new Error(`PollingBlockTracker - encountered an error while attempting to update latest block:\n${err.stack}`);
|
|
1580
|
-
try {
|
|
1581
|
-
this.emit("error", newErr);
|
|
1582
|
-
} catch (emitErr) {
|
|
1583
|
-
log.error(newErr);
|
|
1584
|
-
}
|
|
1585
|
-
await timeout(this.config.retryTimeout);
|
|
1586
|
-
}
|
|
1587
|
-
}
|
|
1588
|
-
}
|
|
1589
|
-
async _updateLatestBlock() {
|
|
1590
|
-
// fetch + set latest block
|
|
1591
|
-
const latestBlock = await this._fetchLatestBlock();
|
|
1592
|
-
this._newPotentialLatest(latestBlock);
|
|
1593
|
-
}
|
|
1594
|
-
async _fetchLatestBlock() {
|
|
1595
|
-
try {
|
|
1596
|
-
const block = await this.config.provider.request({
|
|
1597
|
-
method: "eth_getBlockByNumber",
|
|
1598
|
-
params: ["latest", false]
|
|
1599
|
-
});
|
|
1600
|
-
return {
|
|
1601
|
-
blockHash: block.hash,
|
|
1602
|
-
idempotencyKey: block.number,
|
|
1603
|
-
timestamp: block.timestamp,
|
|
1604
|
-
baseFeePerGas: block.baseFeePerGas,
|
|
1605
|
-
gasLimit: block.gasLimit
|
|
1606
|
-
};
|
|
1607
|
-
} catch (error) {
|
|
1608
|
-
log.error("Polling Block Tracker: ", error);
|
|
1609
|
-
throw new Error(`PollingBlockTracker - encountered error fetching block:\n${error.message}`);
|
|
1610
|
-
}
|
|
1611
|
-
}
|
|
1612
|
-
}
|
|
1613
|
-
|
|
1614
|
-
class CurrencyController extends BaseCurrencyController {
|
|
1615
|
-
constructor({
|
|
1616
|
-
config,
|
|
1617
|
-
state,
|
|
1618
|
-
onNetworkChanged
|
|
1619
|
-
}) {
|
|
1620
|
-
super({
|
|
1621
|
-
config,
|
|
1622
|
-
state
|
|
1623
|
-
});
|
|
1624
|
-
_defineProperty(this, "conversionInterval", void 0);
|
|
1625
|
-
this.defaultState = _objectSpread(_objectSpread({}, this.defaultState), {}, {
|
|
1626
|
-
commonDenomination: "USD",
|
|
1627
|
-
commonDenominatorPrice: 0
|
|
1628
|
-
});
|
|
1629
|
-
this.initialize();
|
|
1630
|
-
onNetworkChanged(networkState => {
|
|
1631
|
-
// to be called as (listener) => this.networkController.on('networkDidChange', listener);
|
|
1632
|
-
if (networkState.providerConfig.ticker.toUpperCase() !== this.state.nativeCurrency.toUpperCase()) {
|
|
1633
|
-
this.setNativeCurrency(networkState.providerConfig.ticker);
|
|
1634
|
-
this.updateConversionRate();
|
|
1635
|
-
}
|
|
1636
|
-
});
|
|
1637
|
-
}
|
|
1638
|
-
setCommonDenomination(commonDenomination) {
|
|
1639
|
-
this.update({
|
|
1640
|
-
commonDenomination
|
|
1641
|
-
});
|
|
1642
|
-
}
|
|
1643
|
-
getCommonDenomination() {
|
|
1644
|
-
return this.state.commonDenomination;
|
|
1645
|
-
}
|
|
1646
|
-
setCommonDenominatorPrice(commonDenominatorPrice) {
|
|
1647
|
-
this.update({
|
|
1648
|
-
commonDenominatorPrice
|
|
1649
|
-
});
|
|
1650
|
-
}
|
|
1651
|
-
getCommonDenominatorPrice() {
|
|
1652
|
-
return this.state.commonDenominatorPrice;
|
|
1653
|
-
}
|
|
1654
|
-
|
|
1655
|
-
/**
|
|
1656
|
-
* Creates a new poll, using setInterval, to periodically call updateConversionRate. The id of the interval is
|
|
1657
|
-
* stored at the controller's conversionInterval property. If it is called and such an id already exists, the
|
|
1658
|
-
* previous interval is clear and a new one is created.
|
|
1659
|
-
*/
|
|
1660
|
-
scheduleConversionInterval() {
|
|
1661
|
-
if (this.conversionInterval) {
|
|
1662
|
-
window.clearInterval(this.conversionInterval);
|
|
1663
|
-
}
|
|
1664
|
-
this.conversionInterval = window.setInterval(() => {
|
|
1665
|
-
if (!idleTimeTracker.checkIfIdle()) {
|
|
1666
|
-
this.updateConversionRate();
|
|
1667
|
-
}
|
|
1668
|
-
}, this.config.pollInterval);
|
|
1669
|
-
}
|
|
1670
|
-
|
|
1671
|
-
/**
|
|
1672
|
-
* Updates the conversionRate and conversionDate properties associated with the currentCurrency. Updated info is
|
|
1673
|
-
* fetched from an external API
|
|
1674
|
-
*/
|
|
1675
|
-
async updateConversionRate() {
|
|
1676
|
-
const currentCurrency = this.getCurrentCurrency();
|
|
1677
|
-
const nativeCurrency = this.getNativeCurrency();
|
|
1678
|
-
const commonDenomination = this.getCommonDenomination();
|
|
1679
|
-
const conversionRate = await this.retrieveConversionRate(nativeCurrency, currentCurrency, commonDenomination);
|
|
1680
|
-
const currentCurrencyRate = Number.parseFloat(conversionRate[currentCurrency.toUpperCase()]);
|
|
1681
|
-
const commonDenominationRate = Number.parseFloat(conversionRate[commonDenomination.toUpperCase()]);
|
|
1682
|
-
// set conversion rate
|
|
1683
|
-
if (currentCurrencyRate || commonDenominationRate) {
|
|
1684
|
-
// ETC
|
|
1685
|
-
this.setConversionRate(currentCurrencyRate);
|
|
1686
|
-
this.setConversionDate(Math.floor(Date.now() / 1000).toString());
|
|
1687
|
-
if (currentCurrency.toUpperCase() === commonDenomination.toUpperCase()) {
|
|
1688
|
-
this.setCommonDenominatorPrice(currentCurrencyRate);
|
|
1689
|
-
} else {
|
|
1690
|
-
this.setCommonDenominatorPrice(commonDenominationRate);
|
|
1691
|
-
}
|
|
1692
|
-
} else {
|
|
1693
|
-
this.setConversionRate(0);
|
|
1694
|
-
this.setConversionDate("N/A");
|
|
1695
|
-
}
|
|
1696
|
-
}
|
|
1697
|
-
async retrieveConversionRate(fromCurrency, toCurrency, commonDenomination) {
|
|
1698
|
-
try {
|
|
1699
|
-
let apiUrl = `${this.config.api}/currency?fsym=${fromCurrency.toUpperCase()}&tsyms=${toCurrency.toUpperCase()}`;
|
|
1700
|
-
if (commonDenomination && commonDenomination.toUpperCase() !== toCurrency.toUpperCase()) {
|
|
1701
|
-
apiUrl += `,${commonDenomination.toUpperCase()}`;
|
|
1702
|
-
}
|
|
1703
|
-
const parsedResponse = await get(apiUrl);
|
|
1704
|
-
return parsedResponse;
|
|
1705
|
-
} catch (error) {
|
|
1706
|
-
log.error(error, `CurrencyController - updateCommonDenominatorPrice: Failed to query rate for currency: ${fromCurrency}/ ${toCurrency}`);
|
|
1707
|
-
}
|
|
1708
|
-
return {
|
|
1709
|
-
[toCurrency.toUpperCase()]: "0",
|
|
1710
|
-
[commonDenomination.toUpperCase()]: "0"
|
|
1711
|
-
};
|
|
1712
|
-
}
|
|
1713
|
-
}
|
|
1714
|
-
|
|
1715
|
-
const _excluded$1 = ["aBase", "bBase"],
|
|
1716
|
-
_excluded2 = ["aBase", "bBase"],
|
|
1717
|
-
_excluded3 = ["multiplicandBase", "multiplierBase"];
|
|
1718
|
-
|
|
1719
|
-
// Big Number Constants
|
|
1720
|
-
const BIG_NUMBER_WEI_MULTIPLIER = new BigNumber("1000000000000000000");
|
|
1721
|
-
const BIG_NUMBER_GWEI_MULTIPLIER = new BigNumber("1000000000");
|
|
1722
|
-
const BIG_NUMBER_ETH_MULTIPLIER = new BigNumber("1");
|
|
1723
|
-
// Setter Maps
|
|
1724
|
-
const toBigNumber = {
|
|
1725
|
-
hex: n => new BigNumber(stripHexPrefix(n), 16),
|
|
1726
|
-
dec: n => new BigNumber(String(n), 10),
|
|
1727
|
-
BN: n => new BigNumber(n.toString(16), 16)
|
|
1728
|
-
};
|
|
1729
|
-
const toNormalizedDenomination = {
|
|
1730
|
-
WEI: bigNumber => bigNumber.div(BIG_NUMBER_WEI_MULTIPLIER),
|
|
1731
|
-
GWEI: bigNumber => bigNumber.div(BIG_NUMBER_GWEI_MULTIPLIER),
|
|
1732
|
-
ETH: bigNumber => bigNumber.div(BIG_NUMBER_ETH_MULTIPLIER)
|
|
1733
|
-
};
|
|
1734
|
-
const toSpecifiedDenomination = {
|
|
1735
|
-
WEI: bigNumber => bigNumber.times(BIG_NUMBER_WEI_MULTIPLIER).dp(0, BigNumber.ROUND_HALF_UP),
|
|
1736
|
-
GWEI: bigNumber => bigNumber.times(BIG_NUMBER_GWEI_MULTIPLIER).dp(9, BigNumber.ROUND_HALF_UP),
|
|
1737
|
-
ETH: bigNumber => bigNumber.times(BIG_NUMBER_ETH_MULTIPLIER).dp(9, BigNumber.ROUND_HALF_UP)
|
|
1738
|
-
};
|
|
1739
|
-
const baseChange = {
|
|
1740
|
-
hex: n => n.toString(16),
|
|
1741
|
-
dec: n => new BigNumber(n).toString(10),
|
|
1742
|
-
BN: n => new BN(n.toString(16))
|
|
1743
|
-
};
|
|
1744
|
-
|
|
1745
|
-
// Utility function for checking base types
|
|
1746
|
-
const isValidBase = base => Number.isInteger(base) && base > 1;
|
|
1747
|
-
|
|
1748
|
-
/**
|
|
1749
|
-
* Utility method to convert a value between denominations, formats and currencies.
|
|
1750
|
-
*/
|
|
1751
|
-
const converter = ({
|
|
1752
|
-
value,
|
|
1753
|
-
fromNumericBase,
|
|
1754
|
-
fromDenomination,
|
|
1755
|
-
fromCurrency,
|
|
1756
|
-
toNumericBase,
|
|
1757
|
-
toDenomination,
|
|
1758
|
-
toCurrency,
|
|
1759
|
-
numberOfDecimals,
|
|
1760
|
-
conversionRate,
|
|
1761
|
-
invertConversionRate,
|
|
1762
|
-
roundDown
|
|
1763
|
-
}) => {
|
|
1764
|
-
let convertedValue = fromNumericBase ? toBigNumber[fromNumericBase](value) : value;
|
|
1765
|
-
if (fromDenomination) {
|
|
1766
|
-
convertedValue = toNormalizedDenomination[fromDenomination](convertedValue);
|
|
1767
|
-
}
|
|
1768
|
-
if (fromCurrency !== toCurrency) {
|
|
1769
|
-
if (conversionRate === null || conversionRate === undefined) {
|
|
1770
|
-
throw new Error(`Converting from ${fromCurrency} to ${toCurrency} requires a conversionRate, but one was not provided`);
|
|
1771
|
-
}
|
|
1772
|
-
let rate = toBigNumber.dec(conversionRate);
|
|
1773
|
-
if (invertConversionRate) {
|
|
1774
|
-
rate = new BigNumber(1).div(conversionRate);
|
|
1775
|
-
}
|
|
1776
|
-
convertedValue = convertedValue.times(rate);
|
|
1777
|
-
}
|
|
1778
|
-
if (toDenomination) {
|
|
1779
|
-
convertedValue = toSpecifiedDenomination[toDenomination](convertedValue);
|
|
1780
|
-
}
|
|
1781
|
-
if (numberOfDecimals) {
|
|
1782
|
-
convertedValue = convertedValue.dp(numberOfDecimals, BigNumber.ROUND_HALF_DOWN);
|
|
1783
|
-
}
|
|
1784
|
-
if (roundDown) {
|
|
1785
|
-
convertedValue = convertedValue.dp(roundDown, BigNumber.ROUND_DOWN);
|
|
1786
|
-
}
|
|
1787
|
-
if (toNumericBase) {
|
|
1788
|
-
convertedValue = baseChange[toNumericBase](convertedValue);
|
|
1789
|
-
}
|
|
1790
|
-
return convertedValue;
|
|
1791
|
-
};
|
|
1792
|
-
const conversionUtil = (value, {
|
|
1793
|
-
fromCurrency = null,
|
|
1794
|
-
toCurrency = fromCurrency,
|
|
1795
|
-
fromNumericBase,
|
|
1796
|
-
toNumericBase,
|
|
1797
|
-
fromDenomination,
|
|
1798
|
-
toDenomination,
|
|
1799
|
-
numberOfDecimals,
|
|
1800
|
-
conversionRate,
|
|
1801
|
-
invertConversionRate
|
|
1802
|
-
}) => {
|
|
1803
|
-
if (fromCurrency !== toCurrency && !conversionRate) {
|
|
1804
|
-
return 0;
|
|
1805
|
-
}
|
|
1806
|
-
return converter({
|
|
1807
|
-
fromCurrency,
|
|
1808
|
-
toCurrency,
|
|
1809
|
-
fromNumericBase,
|
|
1810
|
-
toNumericBase,
|
|
1811
|
-
fromDenomination,
|
|
1812
|
-
toDenomination,
|
|
1813
|
-
numberOfDecimals,
|
|
1814
|
-
conversionRate,
|
|
1815
|
-
invertConversionRate,
|
|
1816
|
-
value
|
|
1817
|
-
});
|
|
1818
|
-
};
|
|
1819
|
-
const getBigNumber = (value, base) => {
|
|
1820
|
-
if (!isValidBase(base)) {
|
|
1821
|
-
throw new Error("Must specificy valid base");
|
|
1822
|
-
}
|
|
1823
|
-
|
|
1824
|
-
// We don't include 'number' here, because BigNumber will throw if passed
|
|
1825
|
-
// a number primitive it considers unsafe.
|
|
1826
|
-
if (typeof value === "string" || value instanceof BigNumber) {
|
|
1827
|
-
return new BigNumber(value, base);
|
|
1828
|
-
}
|
|
1829
|
-
return new BigNumber(String(value), base);
|
|
1830
|
-
};
|
|
1831
|
-
const addCurrencies = (a, b, options = {}) => {
|
|
1601
|
+
return new BigNumber(String(value), base);
|
|
1602
|
+
};
|
|
1603
|
+
const addCurrencies = (a, b, options = {}) => {
|
|
1832
1604
|
const {
|
|
1833
1605
|
aBase,
|
|
1834
1606
|
bBase
|
|
@@ -2171,7 +1943,7 @@ class GasFeeController extends BaseController {
|
|
|
2171
1943
|
const chainId = this.getNetworkIdentifier();
|
|
2172
1944
|
if (chainId === "loading") return;
|
|
2173
1945
|
let chainIdInt;
|
|
2174
|
-
if (typeof chainId === "string" && isHexString(addHexPrefix(chainId))) {
|
|
1946
|
+
if (typeof chainId === "string" && isHexString$1(addHexPrefix(chainId))) {
|
|
2175
1947
|
chainIdInt = Number.parseInt(chainId, 16);
|
|
2176
1948
|
}
|
|
2177
1949
|
try {
|
|
@@ -2328,7 +2100,7 @@ class KeyringController extends BaseKeyringController {
|
|
|
2328
2100
|
// we need to check if the data is hex or not
|
|
2329
2101
|
// For historical reasons, you must submit the message to sign in hex-encoded UTF-8.
|
|
2330
2102
|
// https://docs.metamask.io/wallet/how-to/sign-data/#use-personal_sign
|
|
2331
|
-
const message = isHexString(data) ? Buffer.from(stripHexPrefix(data), "hex") : Buffer.from(data);
|
|
2103
|
+
const message = isHexString$1(data) ? Buffer.from(stripHexPrefix(data), "hex") : Buffer.from(data);
|
|
2332
2104
|
const signature = privKey.sign(hashMessage(message)).serialized;
|
|
2333
2105
|
return signature;
|
|
2334
2106
|
}
|
|
@@ -2349,105 +2121,6 @@ class KeyringController extends BaseKeyringController {
|
|
|
2349
2121
|
}
|
|
2350
2122
|
}
|
|
2351
2123
|
|
|
2352
|
-
class AbstractMessageController extends BaseController {
|
|
2353
|
-
/**
|
|
2354
|
-
* Controller in charge of managing - storing, adding, removing, updating - Messages.
|
|
2355
|
-
*
|
|
2356
|
-
*/
|
|
2357
|
-
constructor({
|
|
2358
|
-
config,
|
|
2359
|
-
state,
|
|
2360
|
-
getNetworkIdentifier
|
|
2361
|
-
}) {
|
|
2362
|
-
super({
|
|
2363
|
-
config,
|
|
2364
|
-
state
|
|
2365
|
-
});
|
|
2366
|
-
_defineProperty(this, "messages", void 0);
|
|
2367
|
-
_defineProperty(this, "getNetworkIdentifier", void 0);
|
|
2368
|
-
this.defaultState = {
|
|
2369
|
-
unapprovedMessages: {},
|
|
2370
|
-
unapprovedMessagesCount: 0
|
|
2371
|
-
};
|
|
2372
|
-
this.messages = [];
|
|
2373
|
-
this.defaultConfig = {};
|
|
2374
|
-
this.getNetworkIdentifier = getNetworkIdentifier;
|
|
2375
|
-
super.initialize();
|
|
2376
|
-
}
|
|
2377
|
-
getMessage(messageId) {
|
|
2378
|
-
return this.messages.find(message => message.id === messageId);
|
|
2379
|
-
}
|
|
2380
|
-
getAllMessages() {
|
|
2381
|
-
return this.messages;
|
|
2382
|
-
}
|
|
2383
|
-
setMetadata(messageId, metadata) {
|
|
2384
|
-
const message = this.getMessage(messageId);
|
|
2385
|
-
if (!message) {
|
|
2386
|
-
throw new Error(`${this.name}: Message not found for id: ${messageId}.`);
|
|
2387
|
-
}
|
|
2388
|
-
message.metadata = metadata;
|
|
2389
|
-
this.updateMessage(message);
|
|
2390
|
-
}
|
|
2391
|
-
getUnapprovedMessages() {
|
|
2392
|
-
return this.messages.filter(message => message.status === MessageStatus.UNAPPROVED).reduce((result, message) => {
|
|
2393
|
-
result[message.id] = message;
|
|
2394
|
-
return result;
|
|
2395
|
-
}, {});
|
|
2396
|
-
}
|
|
2397
|
-
async addMessage(message) {
|
|
2398
|
-
this.messages.push(message);
|
|
2399
|
-
this.saveMessageList();
|
|
2400
|
-
}
|
|
2401
|
-
approveMessage(messageId, messageParams) {
|
|
2402
|
-
this.setMessageStatus(messageId, MessageStatus.APPROVED);
|
|
2403
|
-
return this.prepMessageForSigning(messageParams);
|
|
2404
|
-
}
|
|
2405
|
-
setMessageStatus(messageId, status) {
|
|
2406
|
-
const message = this.getMessage(messageId);
|
|
2407
|
-
if (!message) {
|
|
2408
|
-
throw new Error(`${this.name}: Message not found for id: ${messageId}.`);
|
|
2409
|
-
}
|
|
2410
|
-
message.status = status;
|
|
2411
|
-
this.updateMessage(message);
|
|
2412
|
-
this.emit(`${messageId}:${status}`, message);
|
|
2413
|
-
if (status === MessageStatus.REJECTED || status === MessageStatus.SIGNED || status === MessageStatus.FAILED) {
|
|
2414
|
-
this.emit(`${messageId}:finished`, message);
|
|
2415
|
-
}
|
|
2416
|
-
}
|
|
2417
|
-
async waitForFinishStatus(msgParams, messageName) {
|
|
2418
|
-
return new Promise((resolve, reject) => {
|
|
2419
|
-
const handleFinished = msg => {
|
|
2420
|
-
if (msg.status === MessageStatus.REJECTED) {
|
|
2421
|
-
return reject(providerErrors.userRejectedRequest(`${messageName} Signature: User denied message signature`));
|
|
2422
|
-
}
|
|
2423
|
-
if (msg.status === MessageStatus.FAILED) {
|
|
2424
|
-
return reject(rpcErrors.internal(`${messageName} Signature: failed to sign message ${msg.error}`));
|
|
2425
|
-
}
|
|
2426
|
-
if (msg.status === MessageStatus.SIGNED) {
|
|
2427
|
-
return resolve(msg.rawSig);
|
|
2428
|
-
}
|
|
2429
|
-
return reject(rpcErrors.internal(`${messageName} Signature: Unknown problem: ${JSON.stringify(msgParams)}`));
|
|
2430
|
-
};
|
|
2431
|
-
this.once(`${msgParams.id}:finished`, handleFinished);
|
|
2432
|
-
});
|
|
2433
|
-
}
|
|
2434
|
-
updateMessage(message) {
|
|
2435
|
-
const index = this.messages.findIndex(msg => message.id === msg.id);
|
|
2436
|
-
if (index !== -1) {
|
|
2437
|
-
this.messages[index] = message;
|
|
2438
|
-
}
|
|
2439
|
-
this.saveMessageList();
|
|
2440
|
-
}
|
|
2441
|
-
saveMessageList() {
|
|
2442
|
-
const unapprovedMessages = this.getUnapprovedMessages();
|
|
2443
|
-
const unapprovedMessagesCount = Object.keys(unapprovedMessages).length;
|
|
2444
|
-
this.update({
|
|
2445
|
-
unapprovedMessages,
|
|
2446
|
-
unapprovedMessagesCount
|
|
2447
|
-
});
|
|
2448
|
-
}
|
|
2449
|
-
}
|
|
2450
|
-
|
|
2451
2124
|
const hexRe = /^[0-9A-Fa-f]+$/gu;
|
|
2452
2125
|
function validateAddress(address, propertyName) {
|
|
2453
2126
|
if (!address || typeof address !== "string" || !isValidAddress(address)) {
|
|
@@ -2516,7 +2189,7 @@ async function validateAddChainData(data) {
|
|
|
2516
2189
|
if (!chainId) {
|
|
2517
2190
|
throw new Error("Invalid add chain params: please pass chainId in params");
|
|
2518
2191
|
}
|
|
2519
|
-
if (!isHexString
|
|
2192
|
+
if (!isHexString(chainId)) {
|
|
2520
2193
|
throw new Error("Invalid add chain params: please pass a valid hex chainId in params, for: ex: 0x1");
|
|
2521
2194
|
}
|
|
2522
2195
|
if (!rpcUrls || rpcUrls.length === 0) throw new Error("params.rpcUrls not provided");
|
|
@@ -2544,7 +2217,7 @@ function validateSwitchChainData(data) {
|
|
|
2544
2217
|
if (!chainId) {
|
|
2545
2218
|
throw new Error("Invalid switch chain params: please pass chainId in params");
|
|
2546
2219
|
}
|
|
2547
|
-
if (!isHexString
|
|
2220
|
+
if (!isHexString(chainId)) {
|
|
2548
2221
|
throw new Error("Invalid switch chain params: please pass a valid hex chainId in params, for: ex: 0x1");
|
|
2549
2222
|
}
|
|
2550
2223
|
}
|
|
@@ -2553,13 +2226,11 @@ class AddChainController extends AbstractMessageController {
|
|
|
2553
2226
|
constructor({
|
|
2554
2227
|
config,
|
|
2555
2228
|
state,
|
|
2556
|
-
getNetworkIdentifier,
|
|
2557
2229
|
addChain
|
|
2558
2230
|
}) {
|
|
2559
2231
|
super({
|
|
2560
2232
|
config,
|
|
2561
|
-
state
|
|
2562
|
-
getNetworkIdentifier
|
|
2233
|
+
state
|
|
2563
2234
|
});
|
|
2564
2235
|
_defineProperty(this, "name", "AddChainController");
|
|
2565
2236
|
_defineProperty(this, "addChain", void 0);
|
|
@@ -2620,13 +2291,11 @@ class MessageController extends AbstractMessageController {
|
|
|
2620
2291
|
constructor({
|
|
2621
2292
|
config,
|
|
2622
2293
|
state,
|
|
2623
|
-
signMessage
|
|
2624
|
-
getNetworkIdentifier
|
|
2294
|
+
signMessage
|
|
2625
2295
|
}) {
|
|
2626
2296
|
super({
|
|
2627
2297
|
config,
|
|
2628
|
-
state
|
|
2629
|
-
getNetworkIdentifier
|
|
2298
|
+
state
|
|
2630
2299
|
});
|
|
2631
2300
|
_defineProperty(this, "name", "MessageController");
|
|
2632
2301
|
_defineProperty(this, "signMessage", void 0);
|
|
@@ -2686,27 +2355,158 @@ class PersonalMessageController extends AbstractMessageController {
|
|
|
2686
2355
|
constructor({
|
|
2687
2356
|
config,
|
|
2688
2357
|
state,
|
|
2689
|
-
signPersonalMessage
|
|
2690
|
-
getNetworkIdentifier
|
|
2358
|
+
signPersonalMessage
|
|
2691
2359
|
}) {
|
|
2692
2360
|
super({
|
|
2693
2361
|
config,
|
|
2694
|
-
state
|
|
2695
|
-
getNetworkIdentifier
|
|
2362
|
+
state
|
|
2696
2363
|
});
|
|
2697
2364
|
_defineProperty(this, "name", "PersonalMessageController");
|
|
2698
2365
|
_defineProperty(this, "signPersonalMessage", void 0);
|
|
2699
2366
|
this.signPersonalMessage = signPersonalMessage;
|
|
2700
2367
|
this.initialize();
|
|
2701
2368
|
}
|
|
2702
|
-
async processSignPersonalMessage(messageId) {
|
|
2369
|
+
async processSignPersonalMessage(messageId) {
|
|
2370
|
+
const msgObject = this.getMessage(messageId);
|
|
2371
|
+
if (!msgObject) {
|
|
2372
|
+
throw new Error(`Message not found`);
|
|
2373
|
+
}
|
|
2374
|
+
try {
|
|
2375
|
+
const cleanMsgParams = await this.approveMessage(messageId, msgObject.messageParams);
|
|
2376
|
+
const rawSig = await this.signPersonalMessage(cleanMsgParams.data, cleanMsgParams.from);
|
|
2377
|
+
this.updateMessage(_objectSpread(_objectSpread({}, msgObject), {}, {
|
|
2378
|
+
rawSig
|
|
2379
|
+
}));
|
|
2380
|
+
this.setMessageStatus(messageId, MessageStatus.SIGNED);
|
|
2381
|
+
return rawSig;
|
|
2382
|
+
} catch (error) {
|
|
2383
|
+
log.error(error);
|
|
2384
|
+
msgObject.error = (error === null || error === void 0 ? void 0 : error.message) || (error === null || error === void 0 ? void 0 : error.toString());
|
|
2385
|
+
this.setMessageStatus(messageId, MessageStatus.FAILED);
|
|
2386
|
+
}
|
|
2387
|
+
}
|
|
2388
|
+
async addNewUnapprovedMessage(messageParams, req) {
|
|
2389
|
+
await this.addUnapprovedMessage(messageParams, req);
|
|
2390
|
+
return this.waitForFinishStatus(messageParams, this.name);
|
|
2391
|
+
}
|
|
2392
|
+
async addUnapprovedMessage(messageParams, req) {
|
|
2393
|
+
validateSignMessageData(messageParams);
|
|
2394
|
+
if (req) {
|
|
2395
|
+
messageParams.origin = req.origin;
|
|
2396
|
+
}
|
|
2397
|
+
messageParams.data = normalizeMessageData(messageParams.data);
|
|
2398
|
+
const messageId = messageParams.id || randomId();
|
|
2399
|
+
const messageData = {
|
|
2400
|
+
id: messageId,
|
|
2401
|
+
messageParams,
|
|
2402
|
+
status: MessageStatus.UNAPPROVED,
|
|
2403
|
+
time: Date.now(),
|
|
2404
|
+
type: METHOD_TYPES.PERSONAL_SIGN
|
|
2405
|
+
};
|
|
2406
|
+
await this.addMessage(messageData);
|
|
2407
|
+
this.emit(MESSAGE_EVENTS.UNAPPROVED_MESSAGE, {
|
|
2408
|
+
messageData,
|
|
2409
|
+
req
|
|
2410
|
+
});
|
|
2411
|
+
return messageId;
|
|
2412
|
+
}
|
|
2413
|
+
prepMessageForSigning(messageParams) {
|
|
2414
|
+
return Promise.resolve(messageParams);
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
|
|
2418
|
+
class SwitchChainController extends AbstractMessageController {
|
|
2419
|
+
constructor({
|
|
2420
|
+
config,
|
|
2421
|
+
state,
|
|
2422
|
+
switchChain
|
|
2423
|
+
}) {
|
|
2424
|
+
super({
|
|
2425
|
+
config,
|
|
2426
|
+
state
|
|
2427
|
+
});
|
|
2428
|
+
_defineProperty(this, "name", "SwitchChainController");
|
|
2429
|
+
_defineProperty(this, "switchChain", void 0);
|
|
2430
|
+
this.switchChain = switchChain;
|
|
2431
|
+
this.initialize();
|
|
2432
|
+
}
|
|
2433
|
+
async processSwitchChain(messageId) {
|
|
2434
|
+
const msgObject = this.getMessage(messageId);
|
|
2435
|
+
if (!msgObject) {
|
|
2436
|
+
throw new Error(`Message not found`);
|
|
2437
|
+
}
|
|
2438
|
+
try {
|
|
2439
|
+
await this.approveMessage(messageId, msgObject.messageParams);
|
|
2440
|
+
this.switchChain({
|
|
2441
|
+
chainId: msgObject.messageParams.chainId
|
|
2442
|
+
});
|
|
2443
|
+
this.updateMessage(_objectSpread(_objectSpread({}, msgObject), {}, {
|
|
2444
|
+
rawSig: JSON.stringify(msgObject.messageParams)
|
|
2445
|
+
}));
|
|
2446
|
+
this.setMessageStatus(messageId, MessageStatus.SIGNED);
|
|
2447
|
+
return null;
|
|
2448
|
+
} catch (error) {
|
|
2449
|
+
log.error(error);
|
|
2450
|
+
msgObject.error = (error === null || error === void 0 ? void 0 : error.message) || (error === null || error === void 0 ? void 0 : error.toString());
|
|
2451
|
+
this.setMessageStatus(messageId, MessageStatus.FAILED);
|
|
2452
|
+
}
|
|
2453
|
+
}
|
|
2454
|
+
async addNewUnapprovedMessage(messageParams, req) {
|
|
2455
|
+
await this.addUnapprovedMessage(messageParams, req);
|
|
2456
|
+
return this.waitForFinishStatus(messageParams, this.name);
|
|
2457
|
+
}
|
|
2458
|
+
async addUnapprovedMessage(messageParams, req) {
|
|
2459
|
+
validateSwitchChainData(messageParams);
|
|
2460
|
+
if (req) {
|
|
2461
|
+
messageParams.origin = req.origin;
|
|
2462
|
+
}
|
|
2463
|
+
const messageId = messageParams.id || randomId();
|
|
2464
|
+
const messageData = {
|
|
2465
|
+
id: messageId,
|
|
2466
|
+
messageParams,
|
|
2467
|
+
status: MessageStatus.UNAPPROVED,
|
|
2468
|
+
time: Date.now(),
|
|
2469
|
+
type: METHOD_TYPES.SWITCH_CHAIN
|
|
2470
|
+
};
|
|
2471
|
+
await this.addMessage(messageData);
|
|
2472
|
+
this.emit(MESSAGE_EVENTS.UNAPPROVED_MESSAGE, {
|
|
2473
|
+
messageData,
|
|
2474
|
+
req
|
|
2475
|
+
});
|
|
2476
|
+
return messageId;
|
|
2477
|
+
}
|
|
2478
|
+
prepMessageForSigning(messageParams) {
|
|
2479
|
+
return Promise.resolve(messageParams);
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
|
|
2483
|
+
class TypedMessageController extends AbstractMessageController {
|
|
2484
|
+
constructor({
|
|
2485
|
+
config,
|
|
2486
|
+
state,
|
|
2487
|
+
signTypedData,
|
|
2488
|
+
getNetworkIdentifier
|
|
2489
|
+
}) {
|
|
2490
|
+
super({
|
|
2491
|
+
config,
|
|
2492
|
+
state
|
|
2493
|
+
});
|
|
2494
|
+
_defineProperty(this, "name", "TypedMessageController");
|
|
2495
|
+
_defineProperty(this, "signTypedData", void 0);
|
|
2496
|
+
_defineProperty(this, "getNetworkIdentifier", void 0);
|
|
2497
|
+
this.signTypedData = signTypedData;
|
|
2498
|
+
this.getNetworkIdentifier = getNetworkIdentifier;
|
|
2499
|
+
this.initialize();
|
|
2500
|
+
}
|
|
2501
|
+
async processSignTypedMessage(messageId) {
|
|
2703
2502
|
const msgObject = this.getMessage(messageId);
|
|
2704
2503
|
if (!msgObject) {
|
|
2705
2504
|
throw new Error(`Message not found`);
|
|
2706
2505
|
}
|
|
2707
2506
|
try {
|
|
2708
2507
|
const cleanMsgParams = await this.approveMessage(messageId, msgObject.messageParams);
|
|
2709
|
-
const
|
|
2508
|
+
const msgData = JSON.parse(cleanMsgParams.data);
|
|
2509
|
+
const rawSig = await this.signTypedData(msgData, cleanMsgParams.from);
|
|
2710
2510
|
this.updateMessage(_objectSpread(_objectSpread({}, msgObject), {}, {
|
|
2711
2511
|
rawSig
|
|
2712
2512
|
}));
|
|
@@ -2723,18 +2523,21 @@ class PersonalMessageController extends AbstractMessageController {
|
|
|
2723
2523
|
return this.waitForFinishStatus(messageParams, this.name);
|
|
2724
2524
|
}
|
|
2725
2525
|
async addUnapprovedMessage(messageParams, req) {
|
|
2726
|
-
|
|
2526
|
+
const currentChainId = this.getNetworkIdentifier();
|
|
2527
|
+
await validateTypedSignMessageDataV4(messageParams, currentChainId);
|
|
2528
|
+
if (typeof messageParams.data !== "string") {
|
|
2529
|
+
messageParams.data = JSON.stringify(messageParams.data);
|
|
2530
|
+
}
|
|
2727
2531
|
if (req) {
|
|
2728
2532
|
messageParams.origin = req.origin;
|
|
2729
2533
|
}
|
|
2730
|
-
messageParams.data = normalizeMessageData(messageParams.data);
|
|
2731
2534
|
const messageId = messageParams.id || randomId();
|
|
2732
2535
|
const messageData = {
|
|
2733
2536
|
id: messageId,
|
|
2734
2537
|
messageParams,
|
|
2735
2538
|
status: MessageStatus.UNAPPROVED,
|
|
2736
2539
|
time: Date.now(),
|
|
2737
|
-
type: METHOD_TYPES.
|
|
2540
|
+
type: METHOD_TYPES.ETH_SIGN_TYPED_DATA_V4
|
|
2738
2541
|
};
|
|
2739
2542
|
await this.addMessage(messageData);
|
|
2740
2543
|
this.emit(MESSAGE_EVENTS.UNAPPROVED_MESSAGE, {
|
|
@@ -2748,770 +2551,1144 @@ class PersonalMessageController extends AbstractMessageController {
|
|
|
2748
2551
|
}
|
|
2749
2552
|
}
|
|
2750
2553
|
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2554
|
+
function createGetAccountsMiddleware({
|
|
2555
|
+
getAccounts
|
|
2556
|
+
}) {
|
|
2557
|
+
return createAsyncMiddleware(async (request, response, next) => {
|
|
2558
|
+
const {
|
|
2559
|
+
method
|
|
2560
|
+
} = request;
|
|
2561
|
+
if (method !== METHOD_TYPES.GET_ACCOUNTS) return next();
|
|
2562
|
+
if (!getAccounts) throw new Error("WalletMiddleware - opts.getAccounts not provided");
|
|
2563
|
+
const accounts = await getAccounts(request);
|
|
2564
|
+
response.result = accounts;
|
|
2565
|
+
});
|
|
2566
|
+
}
|
|
2567
|
+
function createProcessTransactionMiddleware({
|
|
2568
|
+
processTransaction
|
|
2569
|
+
}) {
|
|
2570
|
+
return createAsyncMiddleware(async (request, response, next) => {
|
|
2571
|
+
const {
|
|
2572
|
+
method
|
|
2573
|
+
} = request;
|
|
2574
|
+
if (method !== METHOD_TYPES.ETH_TRANSACTION) return next();
|
|
2575
|
+
if (!processTransaction) throw new Error("WalletMiddleware - opts.processTransaction not provided");
|
|
2576
|
+
response.result = await processTransaction(request.params, request);
|
|
2577
|
+
});
|
|
2578
|
+
}
|
|
2579
|
+
function createProcessEthSignMessage({
|
|
2580
|
+
processEthSignMessage
|
|
2581
|
+
}) {
|
|
2582
|
+
return createAsyncMiddleware(async (request, response, next) => {
|
|
2583
|
+
const {
|
|
2584
|
+
method
|
|
2585
|
+
} = request;
|
|
2586
|
+
if (method !== METHOD_TYPES.ETH_SIGN) return next();
|
|
2587
|
+
if (!processEthSignMessage) throw new Error("WalletMiddleware - opts.processEthSignMessage not provided");
|
|
2588
|
+
if (!(request !== null && request !== void 0 && request.params)) throw new Error("WalletMiddleware - missing params");
|
|
2589
|
+
let msgParams = request.params;
|
|
2590
|
+
if (Array.isArray(request.params)) {
|
|
2591
|
+
if (!(request.params.length === 2)) throw new Error(`WalletMiddleware - incorrect params for ${method} method. expected [address, message]`);
|
|
2592
|
+
const params = request.params;
|
|
2593
|
+
const address = params[0];
|
|
2594
|
+
const message = params[1];
|
|
2595
|
+
msgParams = {
|
|
2596
|
+
from: address,
|
|
2597
|
+
data: message
|
|
2598
|
+
};
|
|
2599
|
+
}
|
|
2600
|
+
response.result = await processEthSignMessage(msgParams, request);
|
|
2601
|
+
});
|
|
2602
|
+
}
|
|
2603
|
+
function createProcessTypedMessageV4({
|
|
2604
|
+
processTypedMessageV4
|
|
2605
|
+
}) {
|
|
2606
|
+
return createAsyncMiddleware(async (request, response, next) => {
|
|
2607
|
+
const {
|
|
2608
|
+
method
|
|
2609
|
+
} = request;
|
|
2610
|
+
if (method !== METHOD_TYPES.ETH_SIGN_TYPED_DATA_V4) return next();
|
|
2611
|
+
if (!processTypedMessageV4) throw new Error("WalletMiddleware - opts.processTypedMessageV4 is not provided");
|
|
2612
|
+
if (!(request !== null && request !== void 0 && request.params)) throw new Error("WalletMiddleware - missing params");
|
|
2613
|
+
let msgParams = request.params;
|
|
2614
|
+
if (Array.isArray(request.params)) {
|
|
2615
|
+
if (!(request.params.length === 2)) throw new Error(`WalletMiddleware - incorrect params for ${method} method. expected [address, typedData]`);
|
|
2616
|
+
const params = request.params;
|
|
2617
|
+
const address = params[0];
|
|
2618
|
+
const message = params[1];
|
|
2619
|
+
msgParams = {
|
|
2620
|
+
from: address,
|
|
2621
|
+
data: message
|
|
2622
|
+
};
|
|
2623
|
+
}
|
|
2624
|
+
response.result = await processTypedMessageV4(msgParams, request);
|
|
2625
|
+
});
|
|
2626
|
+
}
|
|
2627
|
+
function createProcessPersonalMessage({
|
|
2628
|
+
processPersonalMessage
|
|
2629
|
+
}) {
|
|
2630
|
+
return createAsyncMiddleware(async (request, response, next) => {
|
|
2631
|
+
const {
|
|
2632
|
+
method
|
|
2633
|
+
} = request;
|
|
2634
|
+
if (method !== METHOD_TYPES.PERSONAL_SIGN) return next();
|
|
2635
|
+
if (!processPersonalMessage) throw new Error("WalletMiddleware - opts.processPersonalMessage is not provided");
|
|
2636
|
+
if (!(request !== null && request !== void 0 && request.params)) throw new Error("WalletMiddleware - missing params");
|
|
2637
|
+
let msgParams = request.params;
|
|
2638
|
+
if (Array.isArray(request.params)) {
|
|
2639
|
+
if (!(request.params.length >= 2)) throw new Error(`WalletMiddleware - incorrect params for ${method} method. expected [message, address]`);
|
|
2640
|
+
const params = request.params;
|
|
2641
|
+
if (typeof params[0] === "object") {
|
|
2642
|
+
const {
|
|
2643
|
+
challenge,
|
|
2644
|
+
address
|
|
2645
|
+
} = params[0];
|
|
2646
|
+
msgParams = {
|
|
2647
|
+
from: address,
|
|
2648
|
+
data: challenge
|
|
2649
|
+
};
|
|
2650
|
+
} else {
|
|
2651
|
+
const message = params[0];
|
|
2652
|
+
const address = params[1];
|
|
2653
|
+
msgParams = {
|
|
2654
|
+
from: address,
|
|
2655
|
+
data: message
|
|
2656
|
+
};
|
|
2657
|
+
}
|
|
2658
|
+
}
|
|
2659
|
+
response.result = await processPersonalMessage(msgParams, request);
|
|
2660
|
+
});
|
|
2661
|
+
}
|
|
2662
|
+
function createPendingNonceMiddleware({
|
|
2663
|
+
getPendingNonce
|
|
2664
|
+
}) {
|
|
2665
|
+
return createAsyncMiddleware(async (request, response, next) => {
|
|
2666
|
+
const {
|
|
2667
|
+
params,
|
|
2668
|
+
method
|
|
2669
|
+
} = request;
|
|
2670
|
+
if (method !== METHOD_TYPES.ETH_GET_TRANSACTION_COUNT) return next();
|
|
2671
|
+
const {
|
|
2672
|
+
blockReference
|
|
2673
|
+
} = params;
|
|
2674
|
+
if (blockReference !== "pending") return next();
|
|
2675
|
+
response.result = await getPendingNonce(params, request);
|
|
2676
|
+
});
|
|
2677
|
+
}
|
|
2678
|
+
function formatTxMetaForRpcResult(txMeta) {
|
|
2679
|
+
const {
|
|
2680
|
+
r,
|
|
2681
|
+
s,
|
|
2682
|
+
v,
|
|
2683
|
+
txReceipt,
|
|
2684
|
+
transaction,
|
|
2685
|
+
transactionHash,
|
|
2686
|
+
accessList
|
|
2687
|
+
} = txMeta;
|
|
2688
|
+
const {
|
|
2689
|
+
to,
|
|
2690
|
+
data,
|
|
2691
|
+
nonce,
|
|
2692
|
+
gas,
|
|
2693
|
+
from,
|
|
2694
|
+
value,
|
|
2695
|
+
gasPrice,
|
|
2696
|
+
maxFeePerGas,
|
|
2697
|
+
maxPriorityFeePerGas
|
|
2698
|
+
} = transaction;
|
|
2699
|
+
const formattedTxMeta = {
|
|
2700
|
+
v,
|
|
2701
|
+
r,
|
|
2702
|
+
s,
|
|
2703
|
+
to,
|
|
2704
|
+
gas,
|
|
2705
|
+
from,
|
|
2706
|
+
hash: transactionHash,
|
|
2707
|
+
nonce,
|
|
2708
|
+
input: data || "0x",
|
|
2709
|
+
value: value || "0x0",
|
|
2710
|
+
accessList: accessList || null,
|
|
2711
|
+
blockHash: (txReceipt === null || txReceipt === void 0 ? void 0 : txReceipt.blockHash) || null,
|
|
2712
|
+
blockNumber: (txReceipt === null || txReceipt === void 0 ? void 0 : txReceipt.blockNumber) || null,
|
|
2713
|
+
transactionIndex: (txReceipt === null || txReceipt === void 0 ? void 0 : txReceipt.transactionIndex) || null,
|
|
2714
|
+
type: null
|
|
2715
|
+
};
|
|
2716
|
+
if (maxFeePerGas && maxPriorityFeePerGas) {
|
|
2717
|
+
formattedTxMeta.maxFeePerGas = maxFeePerGas;
|
|
2718
|
+
formattedTxMeta.maxPriorityFeePerGas = maxPriorityFeePerGas;
|
|
2719
|
+
formattedTxMeta.type = TRANSACTION_ENVELOPE_TYPES.FEE_MARKET;
|
|
2720
|
+
} else {
|
|
2721
|
+
formattedTxMeta.gasPrice = gasPrice;
|
|
2722
|
+
formattedTxMeta.type = TRANSACTION_ENVELOPE_TYPES.LEGACY;
|
|
2767
2723
|
}
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2724
|
+
return formattedTxMeta;
|
|
2725
|
+
}
|
|
2726
|
+
function createPendingTxMiddleware({
|
|
2727
|
+
getPendingTransactionByHash
|
|
2728
|
+
}) {
|
|
2729
|
+
return createAsyncMiddleware(async (request, response, next) => {
|
|
2730
|
+
const {
|
|
2731
|
+
params,
|
|
2732
|
+
method
|
|
2733
|
+
} = request;
|
|
2734
|
+
if (method !== METHOD_TYPES.ETH_GET_TRANSACTION_BY_HASH) return next();
|
|
2735
|
+
if (!getPendingTransactionByHash) throw new Error("WalletMiddleware - opts.getPendingTransactionByHash not provided");
|
|
2736
|
+
const txMeta = await getPendingTransactionByHash(params, request);
|
|
2737
|
+
if (!txMeta) {
|
|
2738
|
+
return next();
|
|
2772
2739
|
}
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
}
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2740
|
+
response.result = formatTxMetaForRpcResult(txMeta);
|
|
2741
|
+
return undefined;
|
|
2742
|
+
});
|
|
2743
|
+
}
|
|
2744
|
+
function createProcessSwitchEthereumChain({
|
|
2745
|
+
processSwitchEthereumChain
|
|
2746
|
+
}) {
|
|
2747
|
+
return createAsyncMiddleware(async (request, response, next) => {
|
|
2748
|
+
const {
|
|
2749
|
+
method
|
|
2750
|
+
} = request;
|
|
2751
|
+
if (method !== METHOD_TYPES.SWITCH_CHAIN) return next();
|
|
2752
|
+
if (!processSwitchEthereumChain) throw new Error("WalletMiddleware - opts.processSwitchEthereumChain not provided");
|
|
2753
|
+
if (!(request !== null && request !== void 0 && request.params)) throw new Error("WalletMiddleware - missing params");
|
|
2754
|
+
let msgParams = request.params;
|
|
2755
|
+
if (Array.isArray(request.params)) {
|
|
2756
|
+
if (!(request.params.length === 1)) throw new Error(`WalletMiddleware - incorrect params for ${method} method. expected [data]`);
|
|
2757
|
+
const [message] = request.params;
|
|
2758
|
+
msgParams = message;
|
|
2787
2759
|
}
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2760
|
+
response.result = await processSwitchEthereumChain(msgParams, request);
|
|
2761
|
+
});
|
|
2762
|
+
}
|
|
2763
|
+
function createProcessAddEthereumChain({
|
|
2764
|
+
processAddEthereumChain
|
|
2765
|
+
}) {
|
|
2766
|
+
return createAsyncMiddleware(async (request, response, next) => {
|
|
2767
|
+
const {
|
|
2768
|
+
method
|
|
2769
|
+
} = request;
|
|
2770
|
+
if (method !== METHOD_TYPES.ADD_CHAIN) return next();
|
|
2771
|
+
if (!processAddEthereumChain) throw new Error("WalletMiddleware - opts.processAddEthereumChain not provided");
|
|
2772
|
+
if (!(request !== null && request !== void 0 && request.params)) throw new Error("WalletMiddleware - missing params");
|
|
2773
|
+
let msgParams = request.params;
|
|
2774
|
+
if (Array.isArray(request.params)) {
|
|
2775
|
+
if (!(request.params.length === 1)) throw new Error(`WalletMiddleware - incorrect params for ${method} method. expected [data]`);
|
|
2776
|
+
const [message] = request.params;
|
|
2777
|
+
msgParams = message;
|
|
2797
2778
|
}
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2779
|
+
response.result = await processAddEthereumChain(msgParams, request);
|
|
2780
|
+
});
|
|
2781
|
+
}
|
|
2782
|
+
function createRequestAccountsMiddleware({
|
|
2783
|
+
requestAccounts
|
|
2784
|
+
}) {
|
|
2785
|
+
return createAsyncMiddleware(async (request, response, next) => {
|
|
2786
|
+
const {
|
|
2787
|
+
method
|
|
2788
|
+
} = request;
|
|
2789
|
+
if (method !== "eth_requestAccounts") return next();
|
|
2790
|
+
if (!requestAccounts) throw new Error("WalletMiddleware - opts.requestAccounts not provided");
|
|
2791
|
+
// This calls the UI login function
|
|
2792
|
+
const accounts = await requestAccounts(request);
|
|
2793
|
+
response.result = accounts;
|
|
2794
|
+
return undefined;
|
|
2795
|
+
});
|
|
2796
|
+
}
|
|
2797
|
+
function createEthereumMiddleware(providerHandlers) {
|
|
2798
|
+
const {
|
|
2799
|
+
requestAccounts,
|
|
2800
|
+
getAccounts,
|
|
2801
|
+
processTransaction,
|
|
2802
|
+
processEthSignMessage,
|
|
2803
|
+
processTypedMessageV4,
|
|
2804
|
+
processPersonalMessage,
|
|
2805
|
+
getPendingNonce,
|
|
2806
|
+
getPendingTransactionByHash,
|
|
2807
|
+
processSwitchEthereumChain,
|
|
2808
|
+
processAddEthereumChain,
|
|
2809
|
+
getProviderState,
|
|
2810
|
+
version
|
|
2811
|
+
} = providerHandlers;
|
|
2812
|
+
return mergeMiddleware([createScaffoldMiddleware({
|
|
2813
|
+
version,
|
|
2814
|
+
[PROVIDER_JRPC_METHODS.GET_PROVIDER_STATE]: getProviderState
|
|
2815
|
+
}), createRequestAccountsMiddleware({
|
|
2816
|
+
requestAccounts
|
|
2817
|
+
}), createGetAccountsMiddleware({
|
|
2818
|
+
getAccounts
|
|
2819
|
+
}), createProcessTransactionMiddleware({
|
|
2820
|
+
processTransaction
|
|
2821
|
+
}), createProcessEthSignMessage({
|
|
2822
|
+
processEthSignMessage
|
|
2823
|
+
}), createProcessTypedMessageV4({
|
|
2824
|
+
processTypedMessageV4
|
|
2825
|
+
}), createProcessPersonalMessage({
|
|
2826
|
+
processPersonalMessage
|
|
2827
|
+
}), createPendingNonceMiddleware({
|
|
2828
|
+
getPendingNonce
|
|
2829
|
+
}), createPendingTxMiddleware({
|
|
2830
|
+
getPendingTransactionByHash
|
|
2831
|
+
}), createProcessSwitchEthereumChain({
|
|
2832
|
+
processSwitchEthereumChain
|
|
2833
|
+
}), createProcessAddEthereumChain({
|
|
2834
|
+
processAddEthereumChain
|
|
2835
|
+
})]);
|
|
2836
|
+
}
|
|
2837
|
+
|
|
2838
|
+
let CacheStrategy = /*#__PURE__*/function (CacheStrategy) {
|
|
2839
|
+
CacheStrategy["Block"] = "block";
|
|
2840
|
+
CacheStrategy["Fork"] = "fork";
|
|
2841
|
+
CacheStrategy["Never"] = "never";
|
|
2842
|
+
CacheStrategy["Permanent"] = "perma";
|
|
2843
|
+
return CacheStrategy;
|
|
2844
|
+
}({});
|
|
2845
|
+
function blockTagParamIndex(method) {
|
|
2846
|
+
switch (method) {
|
|
2847
|
+
// blockTag is at index 2
|
|
2848
|
+
case "eth_getStorageAt":
|
|
2849
|
+
return 2;
|
|
2850
|
+
// blockTag is at index 1
|
|
2851
|
+
case "eth_getBalance":
|
|
2852
|
+
case "eth_getCode":
|
|
2853
|
+
case "eth_getTransactionCount":
|
|
2854
|
+
case "eth_call":
|
|
2855
|
+
return 1;
|
|
2856
|
+
// blockTag is at index 0
|
|
2857
|
+
case "eth_getBlockByNumber":
|
|
2858
|
+
return 0;
|
|
2859
|
+
// there is no blockTag
|
|
2860
|
+
default:
|
|
2861
|
+
return undefined;
|
|
2815
2862
|
}
|
|
2816
2863
|
}
|
|
2864
|
+
function cacheTypeForMethod(method) {
|
|
2865
|
+
switch (method) {
|
|
2866
|
+
// cache permanently
|
|
2867
|
+
case "web3_clientVersion":
|
|
2868
|
+
case "web3_sha3":
|
|
2869
|
+
case "eth_protocolVersion":
|
|
2870
|
+
case "eth_getBlockTransactionCountByHash":
|
|
2871
|
+
case "eth_getUncleCountByBlockHash":
|
|
2872
|
+
case "eth_getCode":
|
|
2873
|
+
case "eth_getBlockByHash":
|
|
2874
|
+
case "eth_getTransactionByHash":
|
|
2875
|
+
case "eth_getTransactionByBlockHashAndIndex":
|
|
2876
|
+
case "eth_getTransactionReceipt":
|
|
2877
|
+
case "eth_getUncleByBlockHashAndIndex":
|
|
2878
|
+
case "eth_getCompilers":
|
|
2879
|
+
case "eth_compileLLL":
|
|
2880
|
+
case "eth_compileSolidity":
|
|
2881
|
+
case "eth_compileSerpent":
|
|
2882
|
+
case "shh_version":
|
|
2883
|
+
case "test_permaCache":
|
|
2884
|
+
return CacheStrategy.Permanent;
|
|
2817
2885
|
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2886
|
+
// cache until fork
|
|
2887
|
+
case "eth_getBlockByNumber":
|
|
2888
|
+
case "eth_getBlockTransactionCountByNumber":
|
|
2889
|
+
case "eth_getUncleCountByBlockNumber":
|
|
2890
|
+
case "eth_getTransactionByBlockNumberAndIndex":
|
|
2891
|
+
case "eth_getUncleByBlockNumberAndIndex":
|
|
2892
|
+
case "test_forkCache":
|
|
2893
|
+
return CacheStrategy.Fork;
|
|
2894
|
+
|
|
2895
|
+
// cache for block
|
|
2896
|
+
case "eth_gasPrice":
|
|
2897
|
+
case "eth_blockNumber":
|
|
2898
|
+
case "eth_getBalance":
|
|
2899
|
+
case "eth_getStorageAt":
|
|
2900
|
+
case "eth_getTransactionCount":
|
|
2901
|
+
case "eth_call":
|
|
2902
|
+
case "eth_estimateGas":
|
|
2903
|
+
case "eth_getFilterLogs":
|
|
2904
|
+
case "eth_getLogs":
|
|
2905
|
+
case "test_blockCache":
|
|
2906
|
+
return CacheStrategy.Block;
|
|
2907
|
+
|
|
2908
|
+
// never cache
|
|
2909
|
+
default:
|
|
2910
|
+
return CacheStrategy.Never;
|
|
2834
2911
|
}
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
const msgData = JSON.parse(cleanMsgParams.data);
|
|
2843
|
-
const rawSig = await this.signTypedData(msgData, cleanMsgParams.from);
|
|
2844
|
-
this.updateMessage(_objectSpread(_objectSpread({}, msgObject), {}, {
|
|
2845
|
-
rawSig
|
|
2846
|
-
}));
|
|
2847
|
-
this.setMessageStatus(messageId, MessageStatus.SIGNED);
|
|
2848
|
-
return rawSig;
|
|
2849
|
-
} catch (error) {
|
|
2850
|
-
log.error(error);
|
|
2851
|
-
msgObject.error = (error === null || error === void 0 ? void 0 : error.message) || (error === null || error === void 0 ? void 0 : error.toString());
|
|
2852
|
-
this.setMessageStatus(messageId, MessageStatus.FAILED);
|
|
2853
|
-
}
|
|
2912
|
+
}
|
|
2913
|
+
function canCache(method) {
|
|
2914
|
+
return cacheTypeForMethod(method) !== CacheStrategy.Never;
|
|
2915
|
+
}
|
|
2916
|
+
function paramsWithoutBlockTag(request) {
|
|
2917
|
+
if (!request.params) {
|
|
2918
|
+
return [];
|
|
2854
2919
|
}
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2920
|
+
const index = blockTagParamIndex(request.method);
|
|
2921
|
+
|
|
2922
|
+
// Block tag param not passed.
|
|
2923
|
+
if (index === undefined || !Array.isArray(request.params) || index >= request.params.length) {
|
|
2924
|
+
return request.params;
|
|
2858
2925
|
}
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
messageParams.data = JSON.stringify(messageParams.data);
|
|
2864
|
-
}
|
|
2865
|
-
if (req) {
|
|
2866
|
-
messageParams.origin = req.origin;
|
|
2867
|
-
}
|
|
2868
|
-
const messageId = messageParams.id || randomId();
|
|
2869
|
-
const messageData = {
|
|
2870
|
-
id: messageId,
|
|
2871
|
-
messageParams,
|
|
2872
|
-
status: MessageStatus.UNAPPROVED,
|
|
2873
|
-
time: Date.now(),
|
|
2874
|
-
type: METHOD_TYPES.ETH_SIGN_TYPED_DATA_V4
|
|
2875
|
-
};
|
|
2876
|
-
await this.addMessage(messageData);
|
|
2877
|
-
this.emit(MESSAGE_EVENTS.UNAPPROVED_MESSAGE, {
|
|
2878
|
-
messageData,
|
|
2879
|
-
req
|
|
2880
|
-
});
|
|
2881
|
-
return messageId;
|
|
2926
|
+
|
|
2927
|
+
// eth_getBlockByNumber has the block tag first, then the optional includeTx? param
|
|
2928
|
+
if (request.method === "eth_getBlockByNumber") {
|
|
2929
|
+
return request.params.slice(1);
|
|
2882
2930
|
}
|
|
2883
|
-
|
|
2884
|
-
|
|
2931
|
+
return request.params.slice(0, index);
|
|
2932
|
+
}
|
|
2933
|
+
function cacheIdentifierForRequest(request, skipBlockRef) {
|
|
2934
|
+
var _request$params;
|
|
2935
|
+
const simpleParams = skipBlockRef ? paramsWithoutBlockTag(request) : (_request$params = request.params) !== null && _request$params !== void 0 ? _request$params : [];
|
|
2936
|
+
if (canCache(request.method)) {
|
|
2937
|
+
return `${request.method}:${stringify(simpleParams)}`;
|
|
2885
2938
|
}
|
|
2939
|
+
return null;
|
|
2886
2940
|
}
|
|
2887
2941
|
|
|
2888
|
-
function
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
method
|
|
2894
|
-
} = request;
|
|
2895
|
-
if (method !== METHOD_TYPES.GET_ACCOUNTS) return next();
|
|
2896
|
-
if (!getAccounts) throw new Error("WalletMiddleware - opts.getAccounts not provided");
|
|
2897
|
-
const accounts = await getAccounts(request);
|
|
2898
|
-
response.result = accounts;
|
|
2899
|
-
});
|
|
2900
|
-
}
|
|
2901
|
-
function createProcessTransactionMiddleware({
|
|
2902
|
-
processTransaction
|
|
2903
|
-
}) {
|
|
2904
|
-
return createAsyncMiddleware(async (request, response, next) => {
|
|
2905
|
-
const {
|
|
2906
|
-
method
|
|
2907
|
-
} = request;
|
|
2908
|
-
if (method !== METHOD_TYPES.ETH_TRANSACTION) return next();
|
|
2909
|
-
if (!processTransaction) throw new Error("WalletMiddleware - opts.processTransaction not provided");
|
|
2910
|
-
response.result = await processTransaction(request.params, request);
|
|
2911
|
-
});
|
|
2912
|
-
}
|
|
2913
|
-
function createProcessEthSignMessage({
|
|
2914
|
-
processEthSignMessage
|
|
2915
|
-
}) {
|
|
2916
|
-
return createAsyncMiddleware(async (request, response, next) => {
|
|
2917
|
-
const {
|
|
2918
|
-
method
|
|
2919
|
-
} = request;
|
|
2920
|
-
if (method !== METHOD_TYPES.ETH_SIGN) return next();
|
|
2921
|
-
if (!processEthSignMessage) throw new Error("WalletMiddleware - opts.processEthSignMessage not provided");
|
|
2922
|
-
if (!(request !== null && request !== void 0 && request.params)) throw new Error("WalletMiddleware - missing params");
|
|
2923
|
-
let msgParams = request.params;
|
|
2924
|
-
if (Array.isArray(request.params)) {
|
|
2925
|
-
if (!(request.params.length === 2)) throw new Error(`WalletMiddleware - incorrect params for ${method} method. expected [address, message]`);
|
|
2926
|
-
const params = request.params;
|
|
2927
|
-
const address = params[0];
|
|
2928
|
-
const message = params[1];
|
|
2929
|
-
msgParams = {
|
|
2930
|
-
from: address,
|
|
2931
|
-
data: message
|
|
2932
|
-
};
|
|
2942
|
+
function createChainIdMiddleware(chainId) {
|
|
2943
|
+
return (req, res, next, end) => {
|
|
2944
|
+
if (req.method === "eth_chainId") {
|
|
2945
|
+
res.result = chainId;
|
|
2946
|
+
return end();
|
|
2933
2947
|
}
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
processTypedMessageV4
|
|
2939
|
-
}) {
|
|
2940
|
-
return createAsyncMiddleware(async (request, response, next) => {
|
|
2941
|
-
const {
|
|
2942
|
-
method
|
|
2943
|
-
} = request;
|
|
2944
|
-
if (method !== METHOD_TYPES.ETH_SIGN_TYPED_DATA_V4) return next();
|
|
2945
|
-
if (!processTypedMessageV4) throw new Error("WalletMiddleware - opts.processTypedMessageV4 is not provided");
|
|
2946
|
-
if (!(request !== null && request !== void 0 && request.params)) throw new Error("WalletMiddleware - missing params");
|
|
2947
|
-
let msgParams = request.params;
|
|
2948
|
-
if (Array.isArray(request.params)) {
|
|
2949
|
-
if (!(request.params.length === 2)) throw new Error(`WalletMiddleware - incorrect params for ${method} method. expected [address, typedData]`);
|
|
2950
|
-
const params = request.params;
|
|
2951
|
-
const address = params[0];
|
|
2952
|
-
const message = params[1];
|
|
2953
|
-
msgParams = {
|
|
2954
|
-
from: address,
|
|
2955
|
-
data: message
|
|
2956
|
-
};
|
|
2948
|
+
if (req.method === "net_version") {
|
|
2949
|
+
// convert to decimal
|
|
2950
|
+
res.result = Number.parseInt(chainId, 16).toString(10);
|
|
2951
|
+
return end();
|
|
2957
2952
|
}
|
|
2958
|
-
|
|
2959
|
-
}
|
|
2953
|
+
return next();
|
|
2954
|
+
};
|
|
2960
2955
|
}
|
|
2961
|
-
function
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
method
|
|
2967
|
-
} = request;
|
|
2968
|
-
if (method !== METHOD_TYPES.PERSONAL_SIGN) return next();
|
|
2969
|
-
if (!processPersonalMessage) throw new Error("WalletMiddleware - opts.processPersonalMessage is not provided");
|
|
2970
|
-
if (!(request !== null && request !== void 0 && request.params)) throw new Error("WalletMiddleware - missing params");
|
|
2971
|
-
let msgParams = request.params;
|
|
2972
|
-
if (Array.isArray(request.params)) {
|
|
2973
|
-
if (!(request.params.length >= 2)) throw new Error(`WalletMiddleware - incorrect params for ${method} method. expected [message, address]`);
|
|
2974
|
-
const params = request.params;
|
|
2975
|
-
if (typeof params[0] === "object") {
|
|
2976
|
-
const {
|
|
2977
|
-
challenge,
|
|
2978
|
-
address
|
|
2979
|
-
} = params[0];
|
|
2980
|
-
msgParams = {
|
|
2981
|
-
from: address,
|
|
2982
|
-
data: challenge
|
|
2983
|
-
};
|
|
2984
|
-
} else {
|
|
2985
|
-
const message = params[0];
|
|
2986
|
-
const address = params[1];
|
|
2987
|
-
msgParams = {
|
|
2988
|
-
from: address,
|
|
2989
|
-
data: message
|
|
2990
|
-
};
|
|
2991
|
-
}
|
|
2956
|
+
function createProviderConfigMiddleware(providerConfig) {
|
|
2957
|
+
return (req, res, next, end) => {
|
|
2958
|
+
if (req.method === "eth_provider_config") {
|
|
2959
|
+
res.result = providerConfig;
|
|
2960
|
+
return end();
|
|
2992
2961
|
}
|
|
2993
|
-
|
|
2994
|
-
}
|
|
2995
|
-
}
|
|
2996
|
-
function createPendingNonceMiddleware({
|
|
2997
|
-
getPendingNonce
|
|
2998
|
-
}) {
|
|
2999
|
-
return createAsyncMiddleware(async (request, response, next) => {
|
|
3000
|
-
const {
|
|
3001
|
-
params,
|
|
3002
|
-
method
|
|
3003
|
-
} = request;
|
|
3004
|
-
if (method !== METHOD_TYPES.ETH_GET_TRANSACTION_COUNT) return next();
|
|
3005
|
-
const {
|
|
3006
|
-
blockReference
|
|
3007
|
-
} = params;
|
|
3008
|
-
if (blockReference !== "pending") return next();
|
|
3009
|
-
response.result = await getPendingNonce(params, request);
|
|
3010
|
-
});
|
|
2962
|
+
return next();
|
|
2963
|
+
};
|
|
3011
2964
|
}
|
|
3012
|
-
function
|
|
3013
|
-
const {
|
|
3014
|
-
r,
|
|
3015
|
-
s,
|
|
3016
|
-
v,
|
|
3017
|
-
txReceipt,
|
|
3018
|
-
transaction,
|
|
3019
|
-
transactionHash,
|
|
3020
|
-
accessList
|
|
3021
|
-
} = txMeta;
|
|
2965
|
+
function createJsonRpcClient(providerConfig, networkConfig) {
|
|
3022
2966
|
const {
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
type: null
|
|
2967
|
+
chainId,
|
|
2968
|
+
rpcTarget
|
|
2969
|
+
} = providerConfig;
|
|
2970
|
+
const fetchMiddleware = createFetchMiddleware({
|
|
2971
|
+
rpcTarget
|
|
2972
|
+
});
|
|
2973
|
+
const blockProvider = providerFromMiddleware(fetchMiddleware);
|
|
2974
|
+
const blockTracker = new PollingBlockTracker({
|
|
2975
|
+
config: _objectSpread(_objectSpread({}, networkConfig), {}, {
|
|
2976
|
+
provider: blockProvider
|
|
2977
|
+
}),
|
|
2978
|
+
state: {}
|
|
2979
|
+
});
|
|
2980
|
+
const networkMiddleware = mergeMiddleware([createChainIdMiddleware(chainId), createProviderConfigMiddleware(providerConfig),
|
|
2981
|
+
// No need for the following middlewares for web because all browser sessions are quite short lived and each session is limited to scope of a window/tab
|
|
2982
|
+
// createBlockRefRewriteMiddleware({ blockTracker }),
|
|
2983
|
+
// createBlockCacheMiddleware({ blockTracker }),
|
|
2984
|
+
createInflightCacheMiddleware({
|
|
2985
|
+
cacheIdentifierForRequest
|
|
2986
|
+
}),
|
|
2987
|
+
// createBlockTrackerInspectorMiddleware({ blockTracker }),
|
|
2988
|
+
fetchMiddleware]);
|
|
2989
|
+
return {
|
|
2990
|
+
networkMiddleware,
|
|
2991
|
+
blockTracker
|
|
3049
2992
|
};
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
2993
|
+
}
|
|
2994
|
+
|
|
2995
|
+
const _excluded = ["chainId", "rpcTarget"];
|
|
2996
|
+
class NetworkController extends BaseController {
|
|
2997
|
+
constructor({
|
|
2998
|
+
config,
|
|
2999
|
+
state
|
|
3000
|
+
}) {
|
|
3001
|
+
super({
|
|
3002
|
+
config,
|
|
3003
|
+
state
|
|
3004
|
+
});
|
|
3005
|
+
_defineProperty(this, "name", "NetworkController");
|
|
3006
|
+
_defineProperty(this, "providerProxy", void 0);
|
|
3007
|
+
_defineProperty(this, "blockTrackerProxy", void 0);
|
|
3008
|
+
_defineProperty(this, "mutex", new Mutex());
|
|
3009
|
+
_defineProperty(this, "provider", null);
|
|
3010
|
+
_defineProperty(this, "blockTracker", null);
|
|
3011
|
+
_defineProperty(this, "baseProviderHandlers", void 0);
|
|
3012
|
+
this.defaultState = {
|
|
3013
|
+
chainId: "loading",
|
|
3014
|
+
properties: {
|
|
3015
|
+
EIPS_1559: undefined
|
|
3016
|
+
},
|
|
3017
|
+
providerConfig: SUPPORTED_NETWORKS[MAINNET_CHAIN_ID]
|
|
3018
|
+
};
|
|
3019
|
+
|
|
3020
|
+
// when a new network is set,
|
|
3021
|
+
// we set to loading first and
|
|
3022
|
+
// then when connection succeeds,
|
|
3023
|
+
// we update the network
|
|
3024
|
+
this.initialize();
|
|
3025
|
+
}
|
|
3026
|
+
getNetworkIdentifier() {
|
|
3027
|
+
return this.state.chainId;
|
|
3028
|
+
}
|
|
3029
|
+
getNetworkRPCUrl() {
|
|
3030
|
+
return this.state.providerConfig.rpcTarget;
|
|
3031
|
+
}
|
|
3032
|
+
|
|
3033
|
+
/**
|
|
3034
|
+
* Called by orchestrator once while initializing the class
|
|
3035
|
+
* @param providerHandlers - JRPC handlers for provider
|
|
3036
|
+
* @returns - provider - Returns the providerProxy
|
|
3037
|
+
*/
|
|
3038
|
+
initializeProvider(providerHandlers) {
|
|
3039
|
+
this.baseProviderHandlers = providerHandlers;
|
|
3040
|
+
this.configureProvider();
|
|
3041
|
+
this.lookupNetwork(); // Not awaiting this, because we don't want to block the initialization
|
|
3042
|
+
return this.providerProxy;
|
|
3057
3043
|
}
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3044
|
+
getProvider() {
|
|
3045
|
+
return this.providerProxy;
|
|
3046
|
+
}
|
|
3047
|
+
getBlockTracker() {
|
|
3048
|
+
return this.blockTrackerProxy;
|
|
3049
|
+
}
|
|
3050
|
+
getProviderConfig() {
|
|
3051
|
+
return this.state.providerConfig;
|
|
3052
|
+
}
|
|
3053
|
+
setProviderConfig(config) {
|
|
3054
|
+
this.update({
|
|
3055
|
+
providerConfig: _objectSpread({}, config)
|
|
3056
|
+
});
|
|
3057
|
+
this.refreshNetwork();
|
|
3058
|
+
}
|
|
3059
|
+
async getEIP1559Compatibility() {
|
|
3064
3060
|
const {
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
if (
|
|
3069
|
-
|
|
3070
|
-
const txMeta = await getPendingTransactionByHash(params, request);
|
|
3071
|
-
if (!txMeta) {
|
|
3072
|
-
return next();
|
|
3061
|
+
EIPS_1559
|
|
3062
|
+
} = this.state.properties;
|
|
3063
|
+
// log.info('checking eip 1559 compatibility')
|
|
3064
|
+
if (EIPS_1559 !== undefined) {
|
|
3065
|
+
return EIPS_1559;
|
|
3073
3066
|
}
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
})
|
|
3081
|
-
|
|
3067
|
+
const latestBlock = await this.blockTracker.getLatestBlock();
|
|
3068
|
+
const supportsEIP1559 = latestBlock && latestBlock.baseFeePerGas !== undefined;
|
|
3069
|
+
this.update({
|
|
3070
|
+
properties: {
|
|
3071
|
+
EIPS_1559: supportsEIP1559
|
|
3072
|
+
}
|
|
3073
|
+
});
|
|
3074
|
+
return supportsEIP1559;
|
|
3075
|
+
}
|
|
3076
|
+
|
|
3077
|
+
/**
|
|
3078
|
+
* Refreshes the current network code
|
|
3079
|
+
*/
|
|
3080
|
+
async lookupNetwork() {
|
|
3082
3081
|
const {
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
if (!
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
msgParams = message;
|
|
3082
|
+
chainId,
|
|
3083
|
+
rpcTarget
|
|
3084
|
+
} = this.getProviderConfig();
|
|
3085
|
+
if (!chainId || !rpcTarget || !this.provider) {
|
|
3086
|
+
this.update({
|
|
3087
|
+
chainId: "loading",
|
|
3088
|
+
properties: {}
|
|
3089
|
+
});
|
|
3090
|
+
return;
|
|
3093
3091
|
}
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
})
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3092
|
+
const releaseLock = await this.mutex.acquire();
|
|
3093
|
+
try {
|
|
3094
|
+
// use eth_chainId
|
|
3095
|
+
const [networkChainId] = await Promise.all([this.provider.request({
|
|
3096
|
+
method: "eth_chainId"
|
|
3097
|
+
}), this.getEIP1559Compatibility()]);
|
|
3098
|
+
log.info("network fetched chain id", networkChainId);
|
|
3099
|
+
// update chain ID
|
|
3100
|
+
this.update({
|
|
3101
|
+
chainId: networkChainId
|
|
3102
|
+
});
|
|
3103
|
+
this.emit("networkDidChange");
|
|
3104
|
+
} catch {
|
|
3105
|
+
this.update({
|
|
3106
|
+
chainId: "loading"
|
|
3107
|
+
});
|
|
3108
|
+
} finally {
|
|
3109
|
+
releaseLock();
|
|
3110
|
+
}
|
|
3111
|
+
}
|
|
3112
|
+
configureProvider() {
|
|
3113
|
+
const _this$getProviderConf = this.getProviderConfig(),
|
|
3114
|
+
{
|
|
3115
|
+
chainId,
|
|
3116
|
+
rpcTarget
|
|
3117
|
+
} = _this$getProviderConf,
|
|
3118
|
+
rest = _objectWithoutProperties(_this$getProviderConf, _excluded);
|
|
3119
|
+
if (!chainId || !rpcTarget) {
|
|
3120
|
+
throw new Error("chainId and rpcTarget must be provider in providerConfig");
|
|
3121
|
+
}
|
|
3122
|
+
this.configureStandardProvider(_objectSpread({
|
|
3123
|
+
chainId,
|
|
3124
|
+
rpcTarget
|
|
3125
|
+
}, rest));
|
|
3126
|
+
}
|
|
3127
|
+
setNetworkClient({
|
|
3128
|
+
networkMiddleware,
|
|
3129
|
+
blockTracker
|
|
3130
|
+
}) {
|
|
3131
|
+
const ethereumMiddleware = createEthereumMiddleware(this.baseProviderHandlers);
|
|
3132
|
+
const engine = new JRPCEngine();
|
|
3133
|
+
engine.push(ethereumMiddleware);
|
|
3134
|
+
engine.push(networkMiddleware);
|
|
3135
|
+
const provider = providerFromEngine(engine);
|
|
3136
|
+
this.setProvider({
|
|
3137
|
+
provider,
|
|
3138
|
+
blockTracker
|
|
3139
|
+
});
|
|
3140
|
+
}
|
|
3141
|
+
setProvider({
|
|
3142
|
+
provider,
|
|
3143
|
+
blockTracker
|
|
3144
|
+
}) {
|
|
3145
|
+
if (this.providerProxy) {
|
|
3146
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
3147
|
+
// @ts-ignore
|
|
3148
|
+
this.providerProxy.setTarget(provider);
|
|
3149
|
+
} else {
|
|
3150
|
+
this.providerProxy = createSwappableProxy(provider);
|
|
3151
|
+
}
|
|
3152
|
+
if (this.blockTrackerProxy) {
|
|
3153
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
3154
|
+
// @ts-ignore
|
|
3155
|
+
this.blockTrackerProxy.setTarget(blockTracker);
|
|
3156
|
+
} else {
|
|
3157
|
+
this.blockTrackerProxy = createEventEmitterProxy(blockTracker, {
|
|
3158
|
+
eventFilter: "skipInternal"
|
|
3159
|
+
});
|
|
3112
3160
|
}
|
|
3113
|
-
response.result = await processAddEthereumChain(msgParams, request);
|
|
3114
|
-
});
|
|
3115
|
-
}
|
|
3116
|
-
function createRequestAccountsMiddleware({
|
|
3117
|
-
requestAccounts
|
|
3118
|
-
}) {
|
|
3119
|
-
return createAsyncMiddleware(async (request, response, next) => {
|
|
3120
|
-
const {
|
|
3121
|
-
method
|
|
3122
|
-
} = request;
|
|
3123
|
-
if (method !== "eth_requestAccounts") return next();
|
|
3124
|
-
if (!requestAccounts) throw new Error("WalletMiddleware - opts.requestAccounts not provided");
|
|
3125
|
-
// This calls the UI login function
|
|
3126
|
-
const accounts = await requestAccounts(request);
|
|
3127
|
-
response.result = accounts;
|
|
3128
|
-
return undefined;
|
|
3129
|
-
});
|
|
3130
|
-
}
|
|
3131
|
-
function createEthereumMiddleware(providerHandlers) {
|
|
3132
|
-
const {
|
|
3133
|
-
requestAccounts,
|
|
3134
|
-
getAccounts,
|
|
3135
|
-
processTransaction,
|
|
3136
|
-
processEthSignMessage,
|
|
3137
|
-
processTypedMessageV4,
|
|
3138
|
-
processPersonalMessage,
|
|
3139
|
-
getPendingNonce,
|
|
3140
|
-
getPendingTransactionByHash,
|
|
3141
|
-
processSwitchEthereumChain,
|
|
3142
|
-
processAddEthereumChain,
|
|
3143
|
-
getProviderState,
|
|
3144
|
-
version
|
|
3145
|
-
} = providerHandlers;
|
|
3146
|
-
return mergeMiddleware([createScaffoldMiddleware({
|
|
3147
|
-
version,
|
|
3148
|
-
[PROVIDER_JRPC_METHODS.GET_PROVIDER_STATE]: getProviderState
|
|
3149
|
-
}), createRequestAccountsMiddleware({
|
|
3150
|
-
requestAccounts
|
|
3151
|
-
}), createGetAccountsMiddleware({
|
|
3152
|
-
getAccounts
|
|
3153
|
-
}), createProcessTransactionMiddleware({
|
|
3154
|
-
processTransaction
|
|
3155
|
-
}), createProcessEthSignMessage({
|
|
3156
|
-
processEthSignMessage
|
|
3157
|
-
}), createProcessTypedMessageV4({
|
|
3158
|
-
processTypedMessageV4
|
|
3159
|
-
}), createProcessPersonalMessage({
|
|
3160
|
-
processPersonalMessage
|
|
3161
|
-
}), createPendingNonceMiddleware({
|
|
3162
|
-
getPendingNonce
|
|
3163
|
-
}), createPendingTxMiddleware({
|
|
3164
|
-
getPendingTransactionByHash
|
|
3165
|
-
}), createProcessSwitchEthereumChain({
|
|
3166
|
-
processSwitchEthereumChain
|
|
3167
|
-
}), createProcessAddEthereumChain({
|
|
3168
|
-
processAddEthereumChain
|
|
3169
|
-
})]);
|
|
3170
|
-
}
|
|
3171
3161
|
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
return 1;
|
|
3190
|
-
// blockTag is at index 0
|
|
3191
|
-
case "eth_getBlockByNumber":
|
|
3192
|
-
return 0;
|
|
3193
|
-
// there is no blockTag
|
|
3194
|
-
default:
|
|
3195
|
-
return undefined;
|
|
3162
|
+
// set new provider and blockTracker
|
|
3163
|
+
this.provider = provider;
|
|
3164
|
+
provider.setMaxListeners(10);
|
|
3165
|
+
this.blockTracker = blockTracker;
|
|
3166
|
+
}
|
|
3167
|
+
configureStandardProvider(providerConfig) {
|
|
3168
|
+
const networkClient = createJsonRpcClient(providerConfig, this.config);
|
|
3169
|
+
log.info("networkClient", networkClient);
|
|
3170
|
+
this.setNetworkClient(networkClient);
|
|
3171
|
+
}
|
|
3172
|
+
refreshNetwork() {
|
|
3173
|
+
this.update({
|
|
3174
|
+
chainId: "loading",
|
|
3175
|
+
properties: {}
|
|
3176
|
+
});
|
|
3177
|
+
this.configureProvider();
|
|
3178
|
+
this.lookupNetwork();
|
|
3196
3179
|
}
|
|
3197
3180
|
}
|
|
3198
|
-
function cacheTypeForMethod(method) {
|
|
3199
|
-
switch (method) {
|
|
3200
|
-
// cache permanently
|
|
3201
|
-
case "web3_clientVersion":
|
|
3202
|
-
case "web3_sha3":
|
|
3203
|
-
case "eth_protocolVersion":
|
|
3204
|
-
case "eth_getBlockTransactionCountByHash":
|
|
3205
|
-
case "eth_getUncleCountByBlockHash":
|
|
3206
|
-
case "eth_getCode":
|
|
3207
|
-
case "eth_getBlockByHash":
|
|
3208
|
-
case "eth_getTransactionByHash":
|
|
3209
|
-
case "eth_getTransactionByBlockHashAndIndex":
|
|
3210
|
-
case "eth_getTransactionReceipt":
|
|
3211
|
-
case "eth_getUncleByBlockHashAndIndex":
|
|
3212
|
-
case "eth_getCompilers":
|
|
3213
|
-
case "eth_compileLLL":
|
|
3214
|
-
case "eth_compileSolidity":
|
|
3215
|
-
case "eth_compileSerpent":
|
|
3216
|
-
case "shh_version":
|
|
3217
|
-
case "test_permaCache":
|
|
3218
|
-
return CacheStrategy.Permanent;
|
|
3219
|
-
|
|
3220
|
-
// cache until fork
|
|
3221
|
-
case "eth_getBlockByNumber":
|
|
3222
|
-
case "eth_getBlockTransactionCountByNumber":
|
|
3223
|
-
case "eth_getUncleCountByBlockNumber":
|
|
3224
|
-
case "eth_getTransactionByBlockNumberAndIndex":
|
|
3225
|
-
case "eth_getUncleByBlockNumberAndIndex":
|
|
3226
|
-
case "test_forkCache":
|
|
3227
|
-
return CacheStrategy.Fork;
|
|
3228
3181
|
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
case "eth_getBalance":
|
|
3233
|
-
case "eth_getStorageAt":
|
|
3234
|
-
case "eth_getTransactionCount":
|
|
3235
|
-
case "eth_call":
|
|
3236
|
-
case "eth_estimateGas":
|
|
3237
|
-
case "eth_getFilterLogs":
|
|
3238
|
-
case "eth_getLogs":
|
|
3239
|
-
case "test_blockCache":
|
|
3240
|
-
return CacheStrategy.Block;
|
|
3182
|
+
const erc20Interface = new Interface(erc20Abi);
|
|
3183
|
+
const erc721Interface = new Interface(erc721Abi);
|
|
3184
|
+
const erc1155Interface = new Interface(erc1155Abi);
|
|
3241
3185
|
|
|
3242
|
-
|
|
3243
|
-
default:
|
|
3244
|
-
return CacheStrategy.Never;
|
|
3245
|
-
}
|
|
3246
|
-
}
|
|
3247
|
-
function canCache(method) {
|
|
3248
|
-
return cacheTypeForMethod(method) !== CacheStrategy.Never;
|
|
3249
|
-
}
|
|
3250
|
-
function paramsWithoutBlockTag(request) {
|
|
3251
|
-
if (!request.params) {
|
|
3252
|
-
return [];
|
|
3253
|
-
}
|
|
3254
|
-
const index = blockTagParamIndex(request.method);
|
|
3186
|
+
// functions that handle normalizing of that key in txParams
|
|
3255
3187
|
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3188
|
+
const normalizers = {
|
|
3189
|
+
from: (from, LowerCase = true) => LowerCase ? addHexPrefix(from).toLowerCase() : addHexPrefix(from),
|
|
3190
|
+
to: (to, LowerCase = true) => LowerCase ? addHexPrefix(to).toLowerCase() : addHexPrefix(to),
|
|
3191
|
+
nonce: nonce => addHexPrefix(nonce),
|
|
3192
|
+
customNonceValue: nonce => addHexPrefix(nonce),
|
|
3193
|
+
value: value => addHexPrefix(value),
|
|
3194
|
+
data: data => addHexPrefix(data),
|
|
3195
|
+
gas: gas => addHexPrefix(gas),
|
|
3196
|
+
gasPrice: gasPrice => addHexPrefix(gasPrice),
|
|
3197
|
+
type: addHexPrefix,
|
|
3198
|
+
maxFeePerGas: addHexPrefix,
|
|
3199
|
+
maxPriorityFeePerGas: addHexPrefix
|
|
3200
|
+
};
|
|
3260
3201
|
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3202
|
+
/**
|
|
3203
|
+
* normalizes txParams
|
|
3204
|
+
*/
|
|
3205
|
+
function normalizeTxParameters(txParameters, lowerCase = true) {
|
|
3206
|
+
// apply only keys in the normalizers
|
|
3207
|
+
const normalizedTxParameters = {
|
|
3208
|
+
id: txParameters.id || randomId(),
|
|
3209
|
+
from: txParameters.from
|
|
3210
|
+
};
|
|
3211
|
+
for (const key in normalizers) {
|
|
3212
|
+
const currentKey = key;
|
|
3213
|
+
if (txParameters[currentKey])
|
|
3214
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3215
|
+
normalizedTxParameters[currentKey] = normalizers[currentKey](txParameters[currentKey], lowerCase);
|
|
3264
3216
|
}
|
|
3265
|
-
return
|
|
3217
|
+
return normalizedTxParameters;
|
|
3266
3218
|
}
|
|
3267
|
-
function
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
if (canCache(request.method)) {
|
|
3271
|
-
return `${request.method}:${stringify(simpleParams)}`;
|
|
3219
|
+
function transactionMatchesNetwork(transaction, chainId) {
|
|
3220
|
+
if (typeof transaction.chainId !== "undefined") {
|
|
3221
|
+
return transaction.chainId === chainId;
|
|
3272
3222
|
}
|
|
3273
|
-
return
|
|
3223
|
+
return false;
|
|
3274
3224
|
}
|
|
3275
3225
|
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
return end();
|
|
3286
|
-
}
|
|
3287
|
-
return next();
|
|
3288
|
-
};
|
|
3226
|
+
/**
|
|
3227
|
+
* Determines if the maxFeePerGas and maxPriorityFeePerGas fields are supplied
|
|
3228
|
+
* and valid inputs. This will return false for non hex string inputs.
|
|
3229
|
+
* the transaction to check
|
|
3230
|
+
* @returns true if transaction uses valid EIP1559 fields
|
|
3231
|
+
*/
|
|
3232
|
+
function isEIP1559Transaction(transaction) {
|
|
3233
|
+
var _transaction$transact, _transaction$transact2;
|
|
3234
|
+
return isHexString$1(addHexPrefix(transaction === null || transaction === void 0 || (_transaction$transact = transaction.transaction) === null || _transaction$transact === void 0 ? void 0 : _transaction$transact.maxFeePerGas)) && isHexString$1(addHexPrefix(transaction === null || transaction === void 0 || (_transaction$transact2 = transaction.transaction) === null || _transaction$transact2 === void 0 ? void 0 : _transaction$transact2.maxPriorityFeePerGas));
|
|
3289
3235
|
}
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3236
|
+
|
|
3237
|
+
/**
|
|
3238
|
+
* Determine if the maxFeePerGas and maxPriorityFeePerGas fields are not
|
|
3239
|
+
* supplied and that the gasPrice field is valid if it is provided. This will
|
|
3240
|
+
* return false if gasPrice is a non hex string.
|
|
3241
|
+
* transaction -
|
|
3242
|
+
* the transaction to check
|
|
3243
|
+
* @returns true if transaction uses valid Legacy fields OR lacks
|
|
3244
|
+
* EIP1559 fields
|
|
3245
|
+
*/
|
|
3246
|
+
function isLegacyTransaction(transaction) {
|
|
3247
|
+
return typeof transaction.transaction.maxFeePerGas === "undefined" && typeof transaction.transaction.maxPriorityFeePerGas === "undefined" && (typeof transaction.transaction.gasPrice === "undefined" || isHexString$1(addHexPrefix(transaction.transaction.gasPrice)));
|
|
3298
3248
|
}
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
const blockTracker = new PollingBlockTracker({
|
|
3309
|
-
config: _objectSpread(_objectSpread({}, networkConfig), {}, {
|
|
3310
|
-
provider: blockProvider
|
|
3311
|
-
}),
|
|
3312
|
-
state: {}
|
|
3313
|
-
});
|
|
3314
|
-
const networkMiddleware = mergeMiddleware([createChainIdMiddleware(chainId), createProviderConfigMiddleware(providerConfig),
|
|
3315
|
-
// No need for the following middlewares for web because all browser sessions are quite short lived and each session is limited to scope of a window/tab
|
|
3316
|
-
// createBlockRefRewriteMiddleware({ blockTracker }),
|
|
3317
|
-
// createBlockCacheMiddleware({ blockTracker }),
|
|
3318
|
-
createInflightCacheMiddleware({
|
|
3319
|
-
cacheIdentifierForRequest
|
|
3320
|
-
}),
|
|
3321
|
-
// createBlockTrackerInspectorMiddleware({ blockTracker }),
|
|
3322
|
-
fetchMiddleware]);
|
|
3323
|
-
return {
|
|
3324
|
-
networkMiddleware,
|
|
3325
|
-
blockTracker
|
|
3326
|
-
};
|
|
3249
|
+
|
|
3250
|
+
/**
|
|
3251
|
+
* Given two fields, ensure that the second field is not included in txParams,
|
|
3252
|
+
* and if it is throw an invalidParams error.
|
|
3253
|
+
*/
|
|
3254
|
+
function ensureMutuallyExclusiveFieldsNotProvided(txParams, fieldBeingValidated, mutuallyExclusiveField) {
|
|
3255
|
+
if (typeof txParams[mutuallyExclusiveField] !== "undefined") {
|
|
3256
|
+
throw rpcErrors.invalidParams(`Invalid transaction params: specified ${fieldBeingValidated} but also included ${mutuallyExclusiveField}, these cannot be mixed`);
|
|
3257
|
+
}
|
|
3327
3258
|
}
|
|
3328
3259
|
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
});
|
|
3339
|
-
_defineProperty(this, "name", "NetworkController");
|
|
3340
|
-
_defineProperty(this, "providerProxy", void 0);
|
|
3341
|
-
_defineProperty(this, "blockTrackerProxy", void 0);
|
|
3342
|
-
_defineProperty(this, "mutex", new Mutex());
|
|
3343
|
-
_defineProperty(this, "provider", null);
|
|
3344
|
-
_defineProperty(this, "blockTracker", null);
|
|
3345
|
-
_defineProperty(this, "baseProviderHandlers", void 0);
|
|
3346
|
-
this.defaultState = {
|
|
3347
|
-
chainId: "loading",
|
|
3348
|
-
properties: {
|
|
3349
|
-
EIPS_1559: undefined
|
|
3350
|
-
},
|
|
3351
|
-
providerConfig: SUPPORTED_NETWORKS[MAINNET_CHAIN_ID]
|
|
3352
|
-
};
|
|
3260
|
+
/**
|
|
3261
|
+
* Ensures that the provided value for field is a string, throws an
|
|
3262
|
+
* invalidParams error if field is not a string.
|
|
3263
|
+
*/
|
|
3264
|
+
function ensureFieldIsString(txParams, field) {
|
|
3265
|
+
if (typeof txParams[field] !== "string") {
|
|
3266
|
+
throw rpcErrors.invalidParams(`Invalid transaction params: ${field} is not a string. got: (${txParams[field]})`);
|
|
3267
|
+
}
|
|
3268
|
+
}
|
|
3353
3269
|
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3270
|
+
/**
|
|
3271
|
+
* Ensures that the provided txParams has the proper 'type' specified for the
|
|
3272
|
+
* given field, if it is provided. If types do not match throws an
|
|
3273
|
+
* invalidParams error.
|
|
3274
|
+
*/
|
|
3275
|
+
function ensureProperTransactionEnvelopeTypeProvided(txParams, field) {
|
|
3276
|
+
switch (field) {
|
|
3277
|
+
case "maxFeePerGas":
|
|
3278
|
+
case "maxPriorityFeePerGas":
|
|
3279
|
+
if (txParams.type && txParams.type !== TRANSACTION_ENVELOPE_TYPES.FEE_MARKET) {
|
|
3280
|
+
throw rpcErrors.invalidParams(`Invalid transaction envelope type: specified type "${txParams.type}" but ` + `including maxFeePerGas and maxPriorityFeePerGas requires type: "${TRANSACTION_ENVELOPE_TYPES.FEE_MARKET}"`);
|
|
3281
|
+
}
|
|
3282
|
+
break;
|
|
3283
|
+
case "gasPrice":
|
|
3284
|
+
default:
|
|
3285
|
+
if (txParams.type && txParams.type === TRANSACTION_ENVELOPE_TYPES.FEE_MARKET) {
|
|
3286
|
+
throw rpcErrors.invalidParams(`Invalid transaction envelope type: specified type "${txParams.type}" but ` + "included a gasPrice instead of maxFeePerGas and maxPriorityFeePerGas");
|
|
3287
|
+
}
|
|
3359
3288
|
}
|
|
3360
|
-
|
|
3361
|
-
|
|
3289
|
+
}
|
|
3290
|
+
|
|
3291
|
+
/**
|
|
3292
|
+
* validates the from field in txParams
|
|
3293
|
+
*/
|
|
3294
|
+
function validateFrom(txParams) {
|
|
3295
|
+
if (!(typeof txParams.from === "string")) {
|
|
3296
|
+
throw rpcErrors.invalidParams(`Invalid "from" address "${txParams.from}": not a string.`);
|
|
3362
3297
|
}
|
|
3363
|
-
|
|
3364
|
-
|
|
3298
|
+
if (!isValidAddress(txParams.from)) {
|
|
3299
|
+
throw rpcErrors.invalidParams('Invalid "from" address.');
|
|
3365
3300
|
}
|
|
3301
|
+
}
|
|
3366
3302
|
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
}
|
|
3378
|
-
|
|
3379
|
-
return this.providerProxy;
|
|
3303
|
+
/**
|
|
3304
|
+
* validates the to field in txParams
|
|
3305
|
+
*/
|
|
3306
|
+
function validateRecipient(txParameters) {
|
|
3307
|
+
if (txParameters.to === "0x" || txParameters.to === null) {
|
|
3308
|
+
if (txParameters.data) {
|
|
3309
|
+
delete txParameters.to;
|
|
3310
|
+
} else {
|
|
3311
|
+
throw rpcErrors.invalidParams('Invalid "to" address.');
|
|
3312
|
+
}
|
|
3313
|
+
} else if (txParameters.to !== undefined && !isValidAddress(txParameters.to)) {
|
|
3314
|
+
throw rpcErrors.invalidParams('Invalid "to" address.');
|
|
3380
3315
|
}
|
|
3381
|
-
|
|
3382
|
-
|
|
3316
|
+
return txParameters;
|
|
3317
|
+
}
|
|
3318
|
+
|
|
3319
|
+
/**
|
|
3320
|
+
* Validates the given tx parameters
|
|
3321
|
+
* @throws if the tx params contains invalid fields
|
|
3322
|
+
*/
|
|
3323
|
+
function validateTxParameters(txParams, eip1559Compatibility = true) {
|
|
3324
|
+
if (!txParams || typeof txParams !== "object" || Array.isArray(txParams)) {
|
|
3325
|
+
throw rpcErrors.invalidParams("Invalid transaction params: must be an object.");
|
|
3383
3326
|
}
|
|
3384
|
-
|
|
3385
|
-
|
|
3327
|
+
if (!txParams.to && !txParams.data) {
|
|
3328
|
+
throw rpcErrors.invalidParams('Invalid transaction params: must specify "data" for contract deployments, or "to" (and optionally "data") for all other types of transactions.');
|
|
3386
3329
|
}
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
this.refreshNetwork();
|
|
3330
|
+
if (isEIP1559Transaction({
|
|
3331
|
+
transaction: txParams
|
|
3332
|
+
}) && !eip1559Compatibility) {
|
|
3333
|
+
throw rpcErrors.invalidParams("Invalid transaction params: params specify an EIP-1559 transaction but the current network does not support EIP-1559");
|
|
3392
3334
|
}
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3335
|
+
Object.entries(txParams).forEach(([key, value]) => {
|
|
3336
|
+
// validate types
|
|
3337
|
+
switch (key) {
|
|
3338
|
+
case "from":
|
|
3339
|
+
validateFrom(txParams);
|
|
3340
|
+
break;
|
|
3341
|
+
case "to":
|
|
3342
|
+
validateRecipient(txParams);
|
|
3343
|
+
break;
|
|
3344
|
+
case "gasPrice":
|
|
3345
|
+
ensureProperTransactionEnvelopeTypeProvided(txParams, "gasPrice");
|
|
3346
|
+
ensureMutuallyExclusiveFieldsNotProvided(txParams, "gasPrice", "maxFeePerGas");
|
|
3347
|
+
ensureMutuallyExclusiveFieldsNotProvided(txParams, "gasPrice", "maxPriorityFeePerGas");
|
|
3348
|
+
ensureFieldIsString(txParams, "gasPrice");
|
|
3349
|
+
break;
|
|
3350
|
+
case "maxFeePerGas":
|
|
3351
|
+
ensureProperTransactionEnvelopeTypeProvided(txParams, "maxFeePerGas");
|
|
3352
|
+
ensureMutuallyExclusiveFieldsNotProvided(txParams, "maxFeePerGas", "gasPrice");
|
|
3353
|
+
ensureFieldIsString(txParams, "maxFeePerGas");
|
|
3354
|
+
break;
|
|
3355
|
+
case "maxPriorityFeePerGas":
|
|
3356
|
+
ensureProperTransactionEnvelopeTypeProvided(txParams, "maxPriorityFeePerGas");
|
|
3357
|
+
ensureMutuallyExclusiveFieldsNotProvided(txParams, "maxPriorityFeePerGas", "gasPrice");
|
|
3358
|
+
ensureFieldIsString(txParams, "maxPriorityFeePerGas");
|
|
3359
|
+
break;
|
|
3360
|
+
case "value":
|
|
3361
|
+
ensureFieldIsString(txParams, "value");
|
|
3362
|
+
if (value.toString().includes("-")) {
|
|
3363
|
+
throw rpcErrors.invalidParams(`Invalid transaction value "${value}": not a positive number.`);
|
|
3364
|
+
}
|
|
3365
|
+
if (value.toString().includes(".")) {
|
|
3366
|
+
throw rpcErrors.invalidParams(`Invalid transaction value of "${value}": number must be in wei.`);
|
|
3367
|
+
}
|
|
3368
|
+
break;
|
|
3369
|
+
case "chainId":
|
|
3370
|
+
if (typeof value !== "number" && typeof value !== "string") {
|
|
3371
|
+
throw rpcErrors.invalidParams(`Invalid transaction params: ${key} is not a Number or hex string. got: (${value})`);
|
|
3372
|
+
}
|
|
3373
|
+
break;
|
|
3374
|
+
default:
|
|
3375
|
+
ensureFieldIsString(txParams, key);
|
|
3400
3376
|
}
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3377
|
+
});
|
|
3378
|
+
}
|
|
3379
|
+
function normalizeAndValidateTxParams(txParams, lowerCase = true) {
|
|
3380
|
+
const normalizedTxParams = normalizeTxParameters(txParams, lowerCase);
|
|
3381
|
+
validateTxParameters(normalizedTxParams);
|
|
3382
|
+
return normalizedTxParams;
|
|
3383
|
+
}
|
|
3384
|
+
|
|
3385
|
+
/**
|
|
3386
|
+
* @returns an array of states that can be considered final
|
|
3387
|
+
*/
|
|
3388
|
+
function getFinalStates() {
|
|
3389
|
+
return [TransactionStatus.rejected,
|
|
3390
|
+
// the user has responded no!
|
|
3391
|
+
TransactionStatus.confirmed,
|
|
3392
|
+
// the tx has been included in a block.
|
|
3393
|
+
TransactionStatus.failed,
|
|
3394
|
+
// the tx failed for some reason, included on tx data.
|
|
3395
|
+
TransactionStatus.dropped // the tx nonce was already used
|
|
3396
|
+
];
|
|
3397
|
+
}
|
|
3398
|
+
function parseStandardTokenTransactionData(data) {
|
|
3399
|
+
try {
|
|
3400
|
+
const txDesc = erc20Interface.parseTransaction({
|
|
3401
|
+
data
|
|
3407
3402
|
});
|
|
3408
|
-
return
|
|
3403
|
+
if (txDesc) return {
|
|
3404
|
+
name: txDesc.name,
|
|
3405
|
+
methodParams: txDesc.args.toArray(),
|
|
3406
|
+
type: CONTRACT_TYPE_ERC20
|
|
3407
|
+
};
|
|
3408
|
+
} catch {
|
|
3409
|
+
// ignore and next try to parse with erc721 ABI
|
|
3409
3410
|
}
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
}
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
chainId: "loading",
|
|
3422
|
-
properties: {}
|
|
3423
|
-
});
|
|
3424
|
-
return;
|
|
3425
|
-
}
|
|
3426
|
-
const releaseLock = await this.mutex.acquire();
|
|
3427
|
-
try {
|
|
3428
|
-
// use eth_chainId
|
|
3429
|
-
const [networkChainId] = await Promise.all([this.provider.request({
|
|
3430
|
-
method: "eth_chainId"
|
|
3431
|
-
}), this.getEIP1559Compatibility()]);
|
|
3432
|
-
log.info("network fetched chain id", networkChainId);
|
|
3433
|
-
// update chain ID
|
|
3434
|
-
this.update({
|
|
3435
|
-
chainId: networkChainId
|
|
3436
|
-
});
|
|
3437
|
-
this.emit("networkDidChange");
|
|
3438
|
-
} catch {
|
|
3439
|
-
this.update({
|
|
3440
|
-
chainId: "loading"
|
|
3441
|
-
});
|
|
3442
|
-
} finally {
|
|
3443
|
-
releaseLock();
|
|
3444
|
-
}
|
|
3411
|
+
try {
|
|
3412
|
+
const txDesc = erc721Interface.parseTransaction({
|
|
3413
|
+
data
|
|
3414
|
+
});
|
|
3415
|
+
if (txDesc) return {
|
|
3416
|
+
name: txDesc.name,
|
|
3417
|
+
methodParams: txDesc.args.toArray(),
|
|
3418
|
+
type: CONTRACT_TYPE_ERC721
|
|
3419
|
+
};
|
|
3420
|
+
} catch {
|
|
3421
|
+
// ignore and next try to parse with erc1155 ABI
|
|
3445
3422
|
}
|
|
3446
|
-
|
|
3447
|
-
const
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
chainId,
|
|
3458
|
-
rpcTarget
|
|
3459
|
-
}, rest));
|
|
3423
|
+
try {
|
|
3424
|
+
const txDesc = erc1155Interface.parseTransaction({
|
|
3425
|
+
data
|
|
3426
|
+
});
|
|
3427
|
+
if (txDesc) return {
|
|
3428
|
+
name: txDesc.name,
|
|
3429
|
+
methodParams: txDesc.args.toArray(),
|
|
3430
|
+
type: CONTRACT_TYPE_ERC1155
|
|
3431
|
+
};
|
|
3432
|
+
} catch {
|
|
3433
|
+
// ignore and return undefined
|
|
3460
3434
|
}
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
const provider = providerFromEngine(engine);
|
|
3470
|
-
this.setProvider({
|
|
3471
|
-
provider,
|
|
3472
|
-
blockTracker
|
|
3435
|
+
return undefined;
|
|
3436
|
+
}
|
|
3437
|
+
const readAddressAsContract = async (provider, address) => {
|
|
3438
|
+
let contractCode;
|
|
3439
|
+
try {
|
|
3440
|
+
contractCode = await provider.request({
|
|
3441
|
+
method: METHOD_TYPES.ETH_GET_CODE,
|
|
3442
|
+
params: [address, "latest"]
|
|
3473
3443
|
});
|
|
3444
|
+
} catch (e) {
|
|
3445
|
+
contractCode = null;
|
|
3446
|
+
}
|
|
3447
|
+
const isContractAddress = contractCode ? contractCode !== "0x" && contractCode !== "0x0" : false;
|
|
3448
|
+
return {
|
|
3449
|
+
contractCode,
|
|
3450
|
+
isContractAddress
|
|
3451
|
+
};
|
|
3452
|
+
};
|
|
3453
|
+
async function determineTransactionType(txParams, provider) {
|
|
3454
|
+
const {
|
|
3455
|
+
data,
|
|
3456
|
+
to
|
|
3457
|
+
} = txParams;
|
|
3458
|
+
let name = "";
|
|
3459
|
+
let methodParams = [];
|
|
3460
|
+
let type = "";
|
|
3461
|
+
try {
|
|
3462
|
+
({
|
|
3463
|
+
name,
|
|
3464
|
+
methodParams,
|
|
3465
|
+
type
|
|
3466
|
+
} = data && parseStandardTokenTransactionData(data) || {});
|
|
3467
|
+
} catch (error) {
|
|
3468
|
+
log.debug("Failed to parse transaction data", error);
|
|
3474
3469
|
}
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
}
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
} else {
|
|
3491
|
-
this.blockTrackerProxy = createEventEmitterProxy(blockTracker, {
|
|
3492
|
-
eventFilter: "skipInternal"
|
|
3470
|
+
let result;
|
|
3471
|
+
let contractCode = "";
|
|
3472
|
+
if (data && !to) {
|
|
3473
|
+
result = TRANSACTION_TYPES.DEPLOY_CONTRACT;
|
|
3474
|
+
} else {
|
|
3475
|
+
const {
|
|
3476
|
+
contractCode: resultCode,
|
|
3477
|
+
isContractAddress
|
|
3478
|
+
} = await readAddressAsContract(provider, to);
|
|
3479
|
+
contractCode = resultCode;
|
|
3480
|
+
if (isContractAddress) {
|
|
3481
|
+
const valueExists = txParams.value && Number(txParams.value) !== 0;
|
|
3482
|
+
const tokenMethodName = [TRANSACTION_TYPES.TOKEN_METHOD_APPROVE, TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER, TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM, TRANSACTION_TYPES.COLLECTIBLE_METHOD_SAFE_TRANSFER_FROM, TRANSACTION_TYPES.SET_APPROVAL_FOR_ALL].find(x => {
|
|
3483
|
+
var _name;
|
|
3484
|
+
return x.toLowerCase() === ((_name = name) === null || _name === void 0 ? void 0 : _name.toLowerCase());
|
|
3493
3485
|
});
|
|
3486
|
+
result = data && tokenMethodName && !valueExists ? tokenMethodName : TRANSACTION_TYPES.CONTRACT_INTERACTION;
|
|
3487
|
+
} else {
|
|
3488
|
+
result = TRANSACTION_TYPES.SENT_ETHER;
|
|
3494
3489
|
}
|
|
3490
|
+
}
|
|
3491
|
+
return {
|
|
3492
|
+
type: type || CONTRACT_TYPE_ETH,
|
|
3493
|
+
category: result,
|
|
3494
|
+
methodParams,
|
|
3495
|
+
getCodeResponse: contractCode
|
|
3496
|
+
};
|
|
3497
|
+
}
|
|
3495
3498
|
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3499
|
+
function hexToBn(hex) {
|
|
3500
|
+
return new BigNumber(stripHexPrefix(hex), 16);
|
|
3501
|
+
}
|
|
3502
|
+
function BNToHex(bn) {
|
|
3503
|
+
return addHexPrefix(bn.toString(16));
|
|
3504
|
+
}
|
|
3505
|
+
function getEtherScanHashLink(txHash, chainId) {
|
|
3506
|
+
if (!SUPPORTED_NETWORKS[chainId]) return "";
|
|
3507
|
+
return `${SUPPORTED_NETWORKS[chainId].blockExplorerUrl}/tx/${txHash}`;
|
|
3508
|
+
}
|
|
3509
|
+
const formatPastTx = params => {
|
|
3510
|
+
var _transaction$to;
|
|
3511
|
+
const {
|
|
3512
|
+
transaction,
|
|
3513
|
+
lowerCaseSelectedAddress,
|
|
3514
|
+
blockExplorerUrl
|
|
3515
|
+
} = params;
|
|
3516
|
+
let totalAmountString = "";
|
|
3517
|
+
if (transaction.type === CONTRACT_TYPE_ERC721 || transaction.type === CONTRACT_TYPE_ERC1155) totalAmountString = transaction.symbol;else if (transaction.type === CONTRACT_TYPE_ERC20) totalAmountString = formatSmallNumbers(Number.parseFloat(transaction.total_amount), transaction.symbol, true);else totalAmountString = formatSmallNumbers(Number.parseFloat(transaction.total_amount), transaction.type_name, true);
|
|
3518
|
+
const currencyAmountString = transaction.type === CONTRACT_TYPE_ERC721 || transaction.type === CONTRACT_TYPE_ERC1155 || transaction.isEtherscan ? "" : formatSmallNumbers(Number.parseFloat(transaction.currency_amount), transaction.selected_currency, true);
|
|
3519
|
+
const finalObject = {
|
|
3520
|
+
id: transaction.created_at.toString(),
|
|
3521
|
+
date: new Date(transaction.created_at).toString(),
|
|
3522
|
+
from: transaction.from,
|
|
3523
|
+
from_aa_address: transaction.from_aa_address,
|
|
3524
|
+
slicedFrom: typeof transaction.from === "string" ? addressSlicer(transaction.from) : "",
|
|
3525
|
+
to: transaction.to,
|
|
3526
|
+
slicedTo: typeof transaction.to === "string" ? addressSlicer(transaction.to) : "",
|
|
3527
|
+
action: lowerCaseSelectedAddress === ((_transaction$to = transaction.to) === null || _transaction$to === void 0 ? void 0 : _transaction$to.toLowerCase()) || "" ? ACTIVITY_ACTION_RECEIVE : ACTIVITY_ACTION_SEND,
|
|
3528
|
+
totalAmount: transaction.total_amount,
|
|
3529
|
+
totalAmountString,
|
|
3530
|
+
currencyAmount: transaction.currency_amount,
|
|
3531
|
+
currencyAmountString,
|
|
3532
|
+
amount: `${totalAmountString} / ${currencyAmountString}`,
|
|
3533
|
+
status: transaction.status,
|
|
3534
|
+
etherscanLink: blockExplorerUrl ? `${blockExplorerUrl}/tx/${transaction.transaction_hash}` : "",
|
|
3535
|
+
chainId: transaction.chain_id,
|
|
3536
|
+
ethRate: Number.parseFloat(transaction === null || transaction === void 0 ? void 0 : transaction.total_amount) && Number.parseFloat(transaction === null || transaction === void 0 ? void 0 : transaction.currency_amount) ? `1 ${transaction.symbol} = ${significantDigits(Number.parseFloat(transaction.currency_amount) / Number.parseFloat(transaction.total_amount))}` : "",
|
|
3537
|
+
currencyUsed: transaction.selected_currency,
|
|
3538
|
+
type: transaction.type,
|
|
3539
|
+
type_name: transaction.type_name,
|
|
3540
|
+
type_image_link: transaction.type_image_link,
|
|
3541
|
+
transaction_hash: transaction.transaction_hash,
|
|
3542
|
+
transaction_category: transaction.transaction_category,
|
|
3543
|
+
isEtherscan: transaction.isEtherscan,
|
|
3544
|
+
input: transaction.input || "",
|
|
3545
|
+
token_id: transaction.token_id || "",
|
|
3546
|
+
contract_address: transaction.contract_address || "",
|
|
3547
|
+
nonce: transaction.nonce || "",
|
|
3548
|
+
is_cancel: !!transaction.is_cancel || false,
|
|
3549
|
+
gas: transaction.gas || "",
|
|
3550
|
+
gasPrice: transaction.gasPrice || ""
|
|
3551
|
+
};
|
|
3552
|
+
return finalObject;
|
|
3553
|
+
};
|
|
3554
|
+
|
|
3555
|
+
/**
|
|
3556
|
+
* Ref - https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionreceipt
|
|
3557
|
+
*/
|
|
3558
|
+
const getEthTxStatus = async (hash, provider) => {
|
|
3559
|
+
try {
|
|
3560
|
+
const result = await provider.request({
|
|
3561
|
+
method: METHOD_TYPES.ETH_GET_TRANSACTION_RECEIPT,
|
|
3562
|
+
params: [hash]
|
|
3563
|
+
});
|
|
3564
|
+
if (result === null) return TransactionStatus.submitted;
|
|
3565
|
+
if (result && result.status === "0x1") return TransactionStatus.confirmed;
|
|
3566
|
+
if (result && result.status === "0x0") return TransactionStatus.rejected;
|
|
3567
|
+
return undefined;
|
|
3568
|
+
} catch (err) {
|
|
3569
|
+
log.warn("unable to fetch transaction status", err);
|
|
3570
|
+
return undefined;
|
|
3500
3571
|
}
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3572
|
+
};
|
|
3573
|
+
function formatDate(inputDate) {
|
|
3574
|
+
const monthList = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
3575
|
+
const date = new Date(inputDate);
|
|
3576
|
+
const day = date.getDate();
|
|
3577
|
+
const month = monthList[date.getMonth()];
|
|
3578
|
+
const year = date.getFullYear();
|
|
3579
|
+
return `${day} ${month} ${year}`;
|
|
3580
|
+
}
|
|
3581
|
+
function formatTime(time) {
|
|
3582
|
+
return new Date(time).toTimeString().slice(0, 8);
|
|
3583
|
+
}
|
|
3584
|
+
function isAddressByChainId(address, _chainId) {
|
|
3585
|
+
// TOOD: add rsk network checks.
|
|
3586
|
+
return isValidAddress(address);
|
|
3587
|
+
}
|
|
3588
|
+
function toChecksumAddressByChainId(address, chainId) {
|
|
3589
|
+
// TOOD: add rsk network checks.
|
|
3590
|
+
if (!isAddressByChainId(address)) return address;
|
|
3591
|
+
return toChecksumAddress(address);
|
|
3592
|
+
}
|
|
3593
|
+
const GAS_LIMITS = {
|
|
3594
|
+
// maximum gasLimit of a simple send
|
|
3595
|
+
SIMPLE: addHexPrefix(21000 .toString(16)),
|
|
3596
|
+
// a base estimate for token transfers.
|
|
3597
|
+
BASE_TOKEN_ESTIMATE: addHexPrefix(100000 .toString(16))
|
|
3598
|
+
};
|
|
3599
|
+
function bnLessThan(a, b) {
|
|
3600
|
+
if (a === null || a === undefined || b === null || b === undefined) {
|
|
3601
|
+
return null;
|
|
3505
3602
|
}
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3603
|
+
return new BigNumber(a, 10).lt(b, 10);
|
|
3604
|
+
}
|
|
3605
|
+
const getIpfsEndpoint = path => `https://infura-ipfs.io/${path}`;
|
|
3606
|
+
function sanitizeNftMetdataUrl(url) {
|
|
3607
|
+
let finalUri = url;
|
|
3608
|
+
if (url !== null && url !== void 0 && url.startsWith("ipfs")) {
|
|
3609
|
+
const ipfsPath = url.split("ipfs://")[1];
|
|
3610
|
+
finalUri = getIpfsEndpoint(ipfsPath);
|
|
3611
|
+
}
|
|
3612
|
+
return finalUri;
|
|
3613
|
+
}
|
|
3614
|
+
function getChainType(chainId) {
|
|
3615
|
+
if (chainId === MAINNET_CHAIN_ID) {
|
|
3616
|
+
return "mainnet";
|
|
3617
|
+
} else if (TEST_CHAINS.includes(chainId)) {
|
|
3618
|
+
return "testnet";
|
|
3513
3619
|
}
|
|
3620
|
+
return "custom";
|
|
3514
3621
|
}
|
|
3622
|
+
const addEtherscanTransactions = async params => {
|
|
3623
|
+
const {
|
|
3624
|
+
txn,
|
|
3625
|
+
lowerCaseSelectedAddress,
|
|
3626
|
+
provider,
|
|
3627
|
+
chainId,
|
|
3628
|
+
blockExplorerUrl
|
|
3629
|
+
} = params;
|
|
3630
|
+
const transactionPromises = await Promise.all(txn.map(async tx => {
|
|
3631
|
+
var _SUPPORTED_NETWORKS$c, _SUPPORTED_NETWORKS$c2;
|
|
3632
|
+
const {
|
|
3633
|
+
category,
|
|
3634
|
+
type
|
|
3635
|
+
} = await determineTransactionType(_objectSpread(_objectSpread({}, tx), {}, {
|
|
3636
|
+
data: tx.input
|
|
3637
|
+
}), provider);
|
|
3638
|
+
tx.transaction_category = tx.transaction_category || category;
|
|
3639
|
+
tx.type_image_link = ((_SUPPORTED_NETWORKS$c = SUPPORTED_NETWORKS[chainId]) === null || _SUPPORTED_NETWORKS$c === void 0 ? void 0 : _SUPPORTED_NETWORKS$c.logo) || "";
|
|
3640
|
+
tx.type_name = (_SUPPORTED_NETWORKS$c2 = SUPPORTED_NETWORKS[chainId]) === null || _SUPPORTED_NETWORKS$c2 === void 0 ? void 0 : _SUPPORTED_NETWORKS$c2.ticker;
|
|
3641
|
+
tx.type = type;
|
|
3642
|
+
return tx;
|
|
3643
|
+
}));
|
|
3644
|
+
const finalTxs = transactionPromises.reduce((accumulator, x) => {
|
|
3645
|
+
var _SUPPORTED_NETWORKS$c3, _SUPPORTED_NETWORKS$c4;
|
|
3646
|
+
let totalAmountString = x.value ? new BigNumber(x.value).div(new BigNumber(10).pow(new BigNumber(x.tokenDecimal || 18))).toString() : "";
|
|
3647
|
+
let type = CONTRACT_TYPE_ETH;
|
|
3648
|
+
if (x.contractAddress !== "") {
|
|
3649
|
+
if (x.tokenID) {
|
|
3650
|
+
type = x.tokenValue ? CONTRACT_TYPE_ERC1155 : CONTRACT_TYPE_ERC721;
|
|
3651
|
+
} else {
|
|
3652
|
+
type = CONTRACT_TYPE_ERC20;
|
|
3653
|
+
}
|
|
3654
|
+
}
|
|
3655
|
+
if (type === CONTRACT_TYPE_ERC1155) {
|
|
3656
|
+
totalAmountString = x.tokenValue;
|
|
3657
|
+
}
|
|
3658
|
+
const etherscanTransaction = {
|
|
3659
|
+
type,
|
|
3660
|
+
type_image_link: x.type_image_link || "n/a",
|
|
3661
|
+
type_name: x.tokenName || ((_SUPPORTED_NETWORKS$c3 = SUPPORTED_NETWORKS[chainId]) === null || _SUPPORTED_NETWORKS$c3 === void 0 ? void 0 : _SUPPORTED_NETWORKS$c3.ticker) || "n/a",
|
|
3662
|
+
symbol: x.tokenSymbol || ((_SUPPORTED_NETWORKS$c4 = SUPPORTED_NETWORKS[chainId]) === null || _SUPPORTED_NETWORKS$c4 === void 0 ? void 0 : _SUPPORTED_NETWORKS$c4.ticker),
|
|
3663
|
+
token_id: x.tokenID || "",
|
|
3664
|
+
total_amount: totalAmountString,
|
|
3665
|
+
created_at: new Date(Number(x.timeStamp) * 1000),
|
|
3666
|
+
from: x.from,
|
|
3667
|
+
to: x.to,
|
|
3668
|
+
transaction_hash: x.hash,
|
|
3669
|
+
status: x.txreceipt_status && x.txreceipt_status === "0" ? TransactionStatus.failed : TransactionStatus.confirmed,
|
|
3670
|
+
isEtherscan: true,
|
|
3671
|
+
input: x.input,
|
|
3672
|
+
contract_address: x.contractAddress,
|
|
3673
|
+
transaction_category: x.transaction_category,
|
|
3674
|
+
gas: `0x${new BigNumber(x.gasUsed || 0, 10).toString(16)}`,
|
|
3675
|
+
gasPrice: `0x${new BigNumber(x.gasPrice || 0, 10).toString(16)}`,
|
|
3676
|
+
chain_id: chainId,
|
|
3677
|
+
currency_amount: "",
|
|
3678
|
+
nonce: x.nonce,
|
|
3679
|
+
from_aa_address: "",
|
|
3680
|
+
is_cancel: false,
|
|
3681
|
+
selected_currency: ""
|
|
3682
|
+
};
|
|
3683
|
+
accumulator.push(formatPastTx({
|
|
3684
|
+
transaction: etherscanTransaction,
|
|
3685
|
+
lowerCaseSelectedAddress,
|
|
3686
|
+
blockExplorerUrl
|
|
3687
|
+
}));
|
|
3688
|
+
return accumulator;
|
|
3689
|
+
}, []);
|
|
3690
|
+
return finalTxs;
|
|
3691
|
+
};
|
|
3515
3692
|
|
|
3516
3693
|
class NftHandler {
|
|
3517
3694
|
constructor({
|
|
@@ -3943,8 +4120,13 @@ class PreferencesController extends BasePreferencesController {
|
|
|
3943
4120
|
web3AuthClientId,
|
|
3944
4121
|
web3AuthNetwork,
|
|
3945
4122
|
loginMode,
|
|
3946
|
-
sessionPubKey
|
|
4123
|
+
sessionPubKey,
|
|
4124
|
+
aaProvider,
|
|
4125
|
+
eoaAddress
|
|
3947
4126
|
} = params;
|
|
4127
|
+
const {
|
|
4128
|
+
chainId
|
|
4129
|
+
} = this.getProviderConfig();
|
|
3948
4130
|
await super.init({
|
|
3949
4131
|
address,
|
|
3950
4132
|
userInfo,
|
|
@@ -3953,7 +4135,10 @@ class PreferencesController extends BasePreferencesController {
|
|
|
3953
4135
|
metadata: {
|
|
3954
4136
|
email: userInfo.email,
|
|
3955
4137
|
signatures,
|
|
3956
|
-
network: web3AuthNetwork
|
|
4138
|
+
network: web3AuthNetwork,
|
|
4139
|
+
eoa_address: eoaAddress,
|
|
4140
|
+
aa_provider: aaProvider,
|
|
4141
|
+
chain_id: chainId
|
|
3957
4142
|
}
|
|
3958
4143
|
});
|
|
3959
4144
|
const {
|
|
@@ -3972,9 +4157,17 @@ class PreferencesController extends BasePreferencesController {
|
|
|
3972
4157
|
locale,
|
|
3973
4158
|
address,
|
|
3974
4159
|
type,
|
|
3975
|
-
web3AuthNetwork
|
|
4160
|
+
web3AuthNetwork,
|
|
4161
|
+
metadata: {
|
|
4162
|
+
aa_provider: aaProvider,
|
|
4163
|
+
chain_id: chainId,
|
|
4164
|
+
eoa_address: eoaAddress
|
|
4165
|
+
}
|
|
3976
4166
|
});
|
|
3977
4167
|
}
|
|
4168
|
+
if (eoaAddress) this.updateState({
|
|
4169
|
+
eoaAddress
|
|
4170
|
+
}, address);
|
|
3978
4171
|
this.storeUserLogin({
|
|
3979
4172
|
verifier: aggregateVerifier || verifier,
|
|
3980
4173
|
verifierId,
|
|
@@ -4971,6 +5164,7 @@ class PendingTransactionTracker extends SafeEventEmitter {
|
|
|
4971
5164
|
}
|
|
4972
5165
|
}
|
|
4973
5166
|
async _resubmitTx(txMeta, latestBlockNumber) {
|
|
5167
|
+
if (txMeta.userOpHash) return;
|
|
4974
5168
|
if (!txMeta.firstRetryBlockNumber) {
|
|
4975
5169
|
this.emit(TX_EVENTS.TX_BLOCK_UPDATE, {
|
|
4976
5170
|
txMeta,
|
|
@@ -5005,7 +5199,7 @@ class PendingTransactionTracker extends SafeEventEmitter {
|
|
|
5005
5199
|
const txId = txMeta.id;
|
|
5006
5200
|
|
|
5007
5201
|
// Only check submitted txs
|
|
5008
|
-
if (txMeta.status !== TransactionStatus.submitted) return;
|
|
5202
|
+
if (txMeta.status !== TransactionStatus.submitted || txMeta.isUserOperation) return;
|
|
5009
5203
|
|
|
5010
5204
|
// extra check in case there was an uncaught error during the
|
|
5011
5205
|
// signature and submission process
|
|
@@ -5989,4 +6183,4 @@ class TransactionController extends TransactionStateManager {
|
|
|
5989
6183
|
}
|
|
5990
6184
|
}
|
|
5991
6185
|
|
|
5992
|
-
export { ARBITRUM_MAINNET_CHAIN_ID, ARBITRUM_TESTNET_CHAIN_ID, AVALANCHE_MAINNET_CHAIN_ID, AVALANCHE_TESTNET_CHAIN_ID,
|
|
6186
|
+
export { ARBITRUM_MAINNET_CHAIN_ID, ARBITRUM_TESTNET_CHAIN_ID, AVALANCHE_MAINNET_CHAIN_ID, AVALANCHE_TESTNET_CHAIN_ID, AccountAbstractionController, AccountTrackerController, AddChainController, BASE_CHAIN_ID, BASE_TESTNET_CHAIN_ID, BNToHex, BSC_MAINNET_CHAIN_ID, BSC_TESTNET_CHAIN_ID, BiconomySmartAccount, CELO_MAINNET_CHAIN_ID, CHAIN_ID_TO_GAS_LIMIT_BUFFER_MAP, COINGECKO_PLATFORMS_CHAIN_CODE_MAP, COINGECKO_SUPPORTED_CURRENCIES, CONTRACT_TYPE_ERC1155, CONTRACT_TYPE_ERC20, CONTRACT_TYPE_ERC721, CONTRACT_TYPE_ETH, CurrencyController, DEFAULT_CURRENCY, ERC1155_INTERFACE_ID, ERC721_ENUMERABLE_INTERFACE_ID, ERC721_INTERFACE_ID, ERC721_METADATA_INTERFACE_ID, ETHERSCAN_SUPPORTED_CHAINS, GAS_ESTIMATE_TYPES, GAS_LIMITS, GasFeeController, KernelSmartAccount, KeyringController, LOCALHOST, MAINNET_CHAIN_ID, METHOD_TYPES, MessageController, NetworkController, NexusSmartAccount, NftHandler, NftsController, NonceTracker, OLD_ERC721_LIST, OPTIMISM_MAINNET_CHAIN_ID, OPTIMISM_TESTNET_CHAIN_ID, POLYGON_AMOY_CHAIN_ID, POLYGON_CHAIN_ID, PendingTransactionTracker, PersonalMessageController, PollingBlockTracker, PreferencesController, SEPOLIA_CHAIN_ID, SIMPLEHASH_SUPPORTED_CHAINS, SMART_ACCOUNT, SUPPORTED_NETWORKS, SafeSmartAccount, SwitchChainController, TEST_CHAINS, TRANSACTION_ENVELOPE_TYPES, TokenHandler, TokenRatesController, TokensController, TransactionController, TransactionGasUtil, TransactionStateManager, TrustSmartAccount, TypedMessageController, XDAI_CHAIN_ID, addCurrencies, addEtherscanTransactions, bnLessThan, conversionGTE, conversionGreaterThan, conversionLTE, conversionLessThan, conversionMax, conversionUtil, createChainIdMiddleware, createEthereumMiddleware, createGetAccountsMiddleware, createJsonRpcClient, createPendingNonceMiddleware, createPendingTxMiddleware, createProcessAddEthereumChain, createProcessEthSignMessage, createProcessPersonalMessage, createProcessSwitchEthereumChain, createProcessTransactionMiddleware, createProcessTypedMessageV4, createProviderConfigMiddleware, createRequestAccountsMiddleware, decGWEIToHexWEI, determineTransactionType, ensureFieldIsString, ensureMutuallyExclusiveFieldsNotProvided, eoaInterceptorMiddleware, eoaProviderAsMiddleware, erc1155Abi, erc20Abi, erc721Abi, formatDate, formatPastTx, formatTime, formatTxMetaForRpcResult, generateHistoryEntry, getBigNumber, getChainType, getEthTxStatus, getEtherScanHashLink, getFinalStates, getIpfsEndpoint, hexToBn, hexWEIToDecGWEI, isAddressByChainId, isEIP1559Transaction, isLegacyTransaction, multiplyCurrencies, normalizeAndValidateTxParams, normalizeMessageData, normalizeTxParameters, parseStandardTokenTransactionData, readAddressAsContract, replayHistory, sanitizeNftMetdataUrl, singleBalanceCheckerAbi, snapshotFromTxMeta, subtractCurrencies, toChecksumAddressByChainId, toNegative, transactionMatchesNetwork, validateAddChainData, validateAddress, validateFrom, validateRecipient, validateSignMessageData, validateSwitchChainData, validateTxParameters, validateTypedSignMessageDataV4 };
|