@toruslabs/ethereum-controllers 5.3.4 → 5.3.5
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/ethereumControllers.cjs.js +614 -554
- package/dist/ethereumControllers.cjs.js.map +1 -1
- package/dist/ethereumControllers.esm.js +1116 -1060
- package/dist/ethereumControllers.esm.js.map +1 -1
- package/dist/ethereumControllers.umd.min.js +1 -1
- package/dist/ethereumControllers.umd.min.js.map +1 -1
- package/dist/types/Preferences/PreferencesController.d.ts +2 -2
- package/dist/types/utils/helpers.d.ts +2 -1
- package/dist/types/utils/interfaces.d.ts +34 -0
- package/package.json +2 -2
- package/src/Preferences/PreferencesController.ts +16 -3
- package/src/utils/constants.ts +3 -3
- package/src/utils/helpers.ts +59 -4
- package/src/utils/interfaces.ts +35 -0
|
@@ -116,6 +116,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
116
116
|
TypedMessageController: () => (/* reexport */ TypedMessageController),
|
|
117
117
|
XDAI_CHAIN_ID: () => (/* reexport */ XDAI_CHAIN_ID),
|
|
118
118
|
addCurrencies: () => (/* reexport */ addCurrencies),
|
|
119
|
+
addEtherscanTransactions: () => (/* reexport */ addEtherscanTransactions),
|
|
119
120
|
bnLessThan: () => (/* reexport */ bnLessThan),
|
|
120
121
|
conversionGTE: () => (/* reexport */ conversionGTE),
|
|
121
122
|
conversionGreaterThan: () => (/* reexport */ conversionGreaterThan),
|
|
@@ -768,7 +769,7 @@ const SUPPORTED_NETWORKS = {
|
|
|
768
769
|
blockExplorerUrl: "https://bscscan.com",
|
|
769
770
|
chainId: BSC_MAINNET_CHAIN_ID,
|
|
770
771
|
displayName: "Binance Smart Chain (BSC)",
|
|
771
|
-
logo: "bnb_logo.
|
|
772
|
+
logo: "bnb_logo.svg",
|
|
772
773
|
rpcTarget: `https://bsc-dataseed.binance.org`,
|
|
773
774
|
ticker: "BNB",
|
|
774
775
|
tickerName: "Binance Coin"
|
|
@@ -823,7 +824,7 @@ const SUPPORTED_NETWORKS = {
|
|
|
823
824
|
blockExplorerUrl: "https://gnosis.blockscout.com",
|
|
824
825
|
chainId: XDAI_CHAIN_ID,
|
|
825
826
|
displayName: "xDai",
|
|
826
|
-
logo: "
|
|
827
|
+
logo: "xDai.svg",
|
|
827
828
|
rpcTarget: `https://rpc.gnosischain.com`,
|
|
828
829
|
ticker: "DAI",
|
|
829
830
|
tickerName: "xDai Token"
|
|
@@ -869,7 +870,7 @@ const SUPPORTED_NETWORKS = {
|
|
|
869
870
|
blockExplorerUrl: "https://testnet.bscscan.com",
|
|
870
871
|
chainId: BSC_TESTNET_CHAIN_ID,
|
|
871
872
|
displayName: "Binance Smart Chain Testnet",
|
|
872
|
-
logo: "bnb_logo.
|
|
873
|
+
logo: "bnb_logo.svg",
|
|
873
874
|
rpcTarget: `https://data-seed-prebsc-1-s1.binance.org:8545`,
|
|
874
875
|
ticker: "BNB",
|
|
875
876
|
tickerName: "Binance Coin",
|
|
@@ -1219,260 +1220,648 @@ const util_namespaceObject = require("@ethereumjs/util");
|
|
|
1219
1220
|
;// CONCATENATED MODULE: external "bignumber.js"
|
|
1220
1221
|
const external_bignumber_js_namespaceObject = require("bignumber.js");
|
|
1221
1222
|
var external_bignumber_js_default = /*#__PURE__*/__webpack_require__.n(external_bignumber_js_namespaceObject);
|
|
1222
|
-
;// CONCATENATED MODULE:
|
|
1223
|
+
;// CONCATENATED MODULE: external "@metamask/rpc-errors"
|
|
1224
|
+
const rpc_errors_namespaceObject = require("@metamask/rpc-errors");
|
|
1225
|
+
;// CONCATENATED MODULE: ./src/Transaction/TransactionUtils.ts
|
|
1223
1226
|
|
|
1224
1227
|
|
|
1225
1228
|
|
|
1226
1229
|
|
|
1227
1230
|
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
const
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
to:
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
ethRate: Number.parseFloat(x === null || x === void 0 ? void 0 : x.total_amount) && Number.parseFloat(x === null || x === void 0 ? void 0 : x.currency_amount) ? `1 ${x.symbol} = ${(0,base_controllers_namespaceObject.significantDigits)(Number.parseFloat(x.currency_amount) / Number.parseFloat(x.total_amount))}` : "",
|
|
1255
|
-
currencyUsed: x.selected_currency,
|
|
1256
|
-
type: x.type,
|
|
1257
|
-
type_name: x.type_name,
|
|
1258
|
-
type_image_link: x.type_image_link,
|
|
1259
|
-
transaction_hash: x.transaction_hash,
|
|
1260
|
-
transaction_category: x.transaction_category,
|
|
1261
|
-
// TODO: // figure out how to handle these values.
|
|
1262
|
-
// isEtherscan: x.isEtherscan,
|
|
1263
|
-
// input: x.input || "",
|
|
1264
|
-
// token_id: x.token_id || "",
|
|
1265
|
-
contract_address: x.contract_address || "",
|
|
1266
|
-
nonce: x.nonce || "",
|
|
1267
|
-
is_cancel: !!x.is_cancel || false,
|
|
1268
|
-
gas: x.gas || "",
|
|
1269
|
-
gasPrice: x.gasPrice || ""
|
|
1270
|
-
};
|
|
1271
|
-
return finalObject;
|
|
1231
|
+
|
|
1232
|
+
|
|
1233
|
+
const erc20Interface = new external_ethers_namespaceObject.Interface(erc20Abi);
|
|
1234
|
+
const erc721Interface = new external_ethers_namespaceObject.Interface(erc721Abi);
|
|
1235
|
+
const erc1155Interface = new external_ethers_namespaceObject.Interface(erc1155Abi);
|
|
1236
|
+
|
|
1237
|
+
// functions that handle normalizing of that key in txParams
|
|
1238
|
+
|
|
1239
|
+
const normalizers = {
|
|
1240
|
+
from: function (from) {
|
|
1241
|
+
let LowerCase = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
1242
|
+
return LowerCase ? (0,util_namespaceObject.addHexPrefix)(from).toLowerCase() : (0,util_namespaceObject.addHexPrefix)(from);
|
|
1243
|
+
},
|
|
1244
|
+
to: function (to) {
|
|
1245
|
+
let LowerCase = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
1246
|
+
return LowerCase ? (0,util_namespaceObject.addHexPrefix)(to).toLowerCase() : (0,util_namespaceObject.addHexPrefix)(to);
|
|
1247
|
+
},
|
|
1248
|
+
nonce: nonce => (0,util_namespaceObject.addHexPrefix)(nonce),
|
|
1249
|
+
customNonceValue: nonce => (0,util_namespaceObject.addHexPrefix)(nonce),
|
|
1250
|
+
value: value => (0,util_namespaceObject.addHexPrefix)(value),
|
|
1251
|
+
data: data => (0,util_namespaceObject.addHexPrefix)(data),
|
|
1252
|
+
gas: gas => (0,util_namespaceObject.addHexPrefix)(gas),
|
|
1253
|
+
gasPrice: gasPrice => (0,util_namespaceObject.addHexPrefix)(gasPrice),
|
|
1254
|
+
type: util_namespaceObject.addHexPrefix,
|
|
1255
|
+
maxFeePerGas: util_namespaceObject.addHexPrefix,
|
|
1256
|
+
maxPriorityFeePerGas: util_namespaceObject.addHexPrefix
|
|
1272
1257
|
};
|
|
1273
1258
|
|
|
1274
1259
|
/**
|
|
1275
|
-
*
|
|
1260
|
+
* normalizes txParams
|
|
1276
1261
|
*/
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
if (result === null) return base_controllers_namespaceObject.TransactionStatus.submitted;
|
|
1284
|
-
if (result && result.status === "0x1") return base_controllers_namespaceObject.TransactionStatus.confirmed;
|
|
1285
|
-
if (result && result.status === "0x0") return base_controllers_namespaceObject.TransactionStatus.rejected;
|
|
1286
|
-
return undefined;
|
|
1287
|
-
} catch (err) {
|
|
1288
|
-
external_loglevel_default().warn("unable to fetch transaction status", err);
|
|
1289
|
-
return undefined;
|
|
1290
|
-
}
|
|
1291
|
-
};
|
|
1292
|
-
function formatDate(inputDate) {
|
|
1293
|
-
const monthList = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
1294
|
-
const date = new Date(inputDate);
|
|
1295
|
-
const day = date.getDate();
|
|
1296
|
-
const month = monthList[date.getMonth()];
|
|
1297
|
-
const year = date.getFullYear();
|
|
1298
|
-
return `${day} ${month} ${year}`;
|
|
1299
|
-
}
|
|
1300
|
-
function formatTime(time) {
|
|
1301
|
-
return new Date(time).toTimeString().slice(0, 8);
|
|
1302
|
-
}
|
|
1303
|
-
const idleTimeTracker = (activityThresholdTime => {
|
|
1304
|
-
let isIdle = false;
|
|
1305
|
-
let idleTimeout = null;
|
|
1306
|
-
const resetTimer = () => {
|
|
1307
|
-
if (idleTimeout) {
|
|
1308
|
-
window.clearTimeout(idleTimeout);
|
|
1309
|
-
}
|
|
1310
|
-
isIdle = false;
|
|
1311
|
-
idleTimeout = window.setTimeout(() => {
|
|
1312
|
-
isIdle = true;
|
|
1313
|
-
}, activityThresholdTime * 1000);
|
|
1262
|
+
function normalizeTxParameters(txParameters) {
|
|
1263
|
+
let lowerCase = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
1264
|
+
// apply only keys in the normalizers
|
|
1265
|
+
const normalizedTxParameters = {
|
|
1266
|
+
id: txParameters.id || (0,base_controllers_namespaceObject.randomId)(),
|
|
1267
|
+
from: txParameters.from
|
|
1314
1268
|
};
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1269
|
+
for (const key in normalizers) {
|
|
1270
|
+
const currentKey = key;
|
|
1271
|
+
if (txParameters[currentKey])
|
|
1272
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1273
|
+
normalizedTxParameters[currentKey] = normalizers[currentKey](txParameters[currentKey], lowerCase);
|
|
1319
1274
|
}
|
|
1320
|
-
|
|
1321
|
-
|
|
1275
|
+
return normalizedTxParameters;
|
|
1276
|
+
}
|
|
1277
|
+
function transactionMatchesNetwork(transaction, chainId) {
|
|
1278
|
+
if (typeof transaction.chainId !== "undefined") {
|
|
1279
|
+
return transaction.chainId === chainId;
|
|
1322
1280
|
}
|
|
1323
|
-
return
|
|
1324
|
-
checkIfIdle
|
|
1325
|
-
};
|
|
1326
|
-
})(60 * 3);
|
|
1327
|
-
function isAddressByChainId(address, _chainId) {
|
|
1328
|
-
// TOOD: add rsk network checks.
|
|
1329
|
-
return (0,util_namespaceObject.isValidAddress)(address);
|
|
1281
|
+
return false;
|
|
1330
1282
|
}
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1283
|
+
|
|
1284
|
+
/**
|
|
1285
|
+
* Determines if the maxFeePerGas and maxPriorityFeePerGas fields are supplied
|
|
1286
|
+
* and valid inputs. This will return false for non hex string inputs.
|
|
1287
|
+
* the transaction to check
|
|
1288
|
+
* @returns true if transaction uses valid EIP1559 fields
|
|
1289
|
+
*/
|
|
1290
|
+
function isEIP1559Transaction(transaction) {
|
|
1291
|
+
var _transaction$transact, _transaction$transact2;
|
|
1292
|
+
return (0,util_namespaceObject.isHexString)((0,util_namespaceObject.addHexPrefix)(transaction === null || transaction === void 0 || (_transaction$transact = transaction.transaction) === null || _transaction$transact === void 0 ? void 0 : _transaction$transact.maxFeePerGas)) && (0,util_namespaceObject.isHexString)((0,util_namespaceObject.addHexPrefix)(transaction === null || transaction === void 0 || (_transaction$transact2 = transaction.transaction) === null || _transaction$transact2 === void 0 ? void 0 : _transaction$transact2.maxPriorityFeePerGas));
|
|
1335
1293
|
}
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1294
|
+
|
|
1295
|
+
/**
|
|
1296
|
+
* Determine if the maxFeePerGas and maxPriorityFeePerGas fields are not
|
|
1297
|
+
* supplied and that the gasPrice field is valid if it is provided. This will
|
|
1298
|
+
* return false if gasPrice is a non hex string.
|
|
1299
|
+
* transaction -
|
|
1300
|
+
* the transaction to check
|
|
1301
|
+
* @returns true if transaction uses valid Legacy fields OR lacks
|
|
1302
|
+
* EIP1559 fields
|
|
1303
|
+
*/
|
|
1304
|
+
function isLegacyTransaction(transaction) {
|
|
1305
|
+
return typeof transaction.transaction.maxFeePerGas === "undefined" && typeof transaction.transaction.maxPriorityFeePerGas === "undefined" && (typeof transaction.transaction.gasPrice === "undefined" || (0,util_namespaceObject.isHexString)((0,util_namespaceObject.addHexPrefix)(transaction.transaction.gasPrice)));
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
/**
|
|
1309
|
+
* Given two fields, ensure that the second field is not included in txParams,
|
|
1310
|
+
* and if it is throw an invalidParams error.
|
|
1311
|
+
*/
|
|
1312
|
+
function ensureMutuallyExclusiveFieldsNotProvided(txParams, fieldBeingValidated, mutuallyExclusiveField) {
|
|
1313
|
+
if (typeof txParams[mutuallyExclusiveField] !== "undefined") {
|
|
1314
|
+
throw rpc_errors_namespaceObject.rpcErrors.invalidParams(`Invalid transaction params: specified ${fieldBeingValidated} but also included ${mutuallyExclusiveField}, these cannot be mixed`);
|
|
1345
1315
|
}
|
|
1346
|
-
return new (external_bignumber_js_default())(a, 10).lt(b, 10);
|
|
1347
1316
|
}
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1317
|
+
|
|
1318
|
+
/**
|
|
1319
|
+
* Ensures that the provided value for field is a string, throws an
|
|
1320
|
+
* invalidParams error if field is not a string.
|
|
1321
|
+
*/
|
|
1322
|
+
function ensureFieldIsString(txParams, field) {
|
|
1323
|
+
if (typeof txParams[field] !== "string") {
|
|
1324
|
+
throw rpc_errors_namespaceObject.rpcErrors.invalidParams(`Invalid transaction params: ${field} is not a string. got: (${txParams[field]})`);
|
|
1354
1325
|
}
|
|
1355
|
-
return finalUri;
|
|
1356
1326
|
}
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1327
|
+
|
|
1328
|
+
/**
|
|
1329
|
+
* Ensures that the provided txParams has the proper 'type' specified for the
|
|
1330
|
+
* given field, if it is provided. If types do not match throws an
|
|
1331
|
+
* invalidParams error.
|
|
1332
|
+
*/
|
|
1333
|
+
function ensureProperTransactionEnvelopeTypeProvided(txParams, field) {
|
|
1334
|
+
switch (field) {
|
|
1335
|
+
case "maxFeePerGas":
|
|
1336
|
+
case "maxPriorityFeePerGas":
|
|
1337
|
+
if (txParams.type && txParams.type !== TRANSACTION_ENVELOPE_TYPES.FEE_MARKET) {
|
|
1338
|
+
throw rpc_errors_namespaceObject.rpcErrors.invalidParams(`Invalid transaction envelope type: specified type "${txParams.type}" but ` + `including maxFeePerGas and maxPriorityFeePerGas requires type: "${TRANSACTION_ENVELOPE_TYPES.FEE_MARKET}"`);
|
|
1339
|
+
}
|
|
1340
|
+
break;
|
|
1341
|
+
case "gasPrice":
|
|
1342
|
+
default:
|
|
1343
|
+
if (txParams.type && txParams.type === TRANSACTION_ENVELOPE_TYPES.FEE_MARKET) {
|
|
1344
|
+
throw rpc_errors_namespaceObject.rpcErrors.invalidParams(`Invalid transaction envelope type: specified type "${txParams.type}" but ` + "included a gasPrice instead of maxFeePerGas and maxPriorityFeePerGas");
|
|
1345
|
+
}
|
|
1362
1346
|
}
|
|
1363
|
-
return "custom";
|
|
1364
1347
|
}
|
|
1365
|
-
;// CONCATENATED MODULE: ./src/Block/PollingBlockTracker.ts
|
|
1366
1348
|
|
|
1349
|
+
/**
|
|
1350
|
+
* validates the from field in txParams
|
|
1351
|
+
*/
|
|
1352
|
+
function validateFrom(txParams) {
|
|
1353
|
+
if (!(typeof txParams.from === "string")) {
|
|
1354
|
+
throw rpc_errors_namespaceObject.rpcErrors.invalidParams(`Invalid "from" address "${txParams.from}": not a string.`);
|
|
1355
|
+
}
|
|
1356
|
+
if (!(0,util_namespaceObject.isValidAddress)(txParams.from)) {
|
|
1357
|
+
throw rpc_errors_namespaceObject.rpcErrors.invalidParams('Invalid "from" address.');
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1367
1360
|
|
|
1361
|
+
/**
|
|
1362
|
+
* validates the to field in txParams
|
|
1363
|
+
*/
|
|
1364
|
+
function validateRecipient(txParameters) {
|
|
1365
|
+
if (txParameters.to === "0x" || txParameters.to === null) {
|
|
1366
|
+
if (txParameters.data) {
|
|
1367
|
+
delete txParameters.to;
|
|
1368
|
+
} else {
|
|
1369
|
+
throw rpc_errors_namespaceObject.rpcErrors.invalidParams('Invalid "to" address.');
|
|
1370
|
+
}
|
|
1371
|
+
} else if (txParameters.to !== undefined && !(0,util_namespaceObject.isValidAddress)(txParameters.to)) {
|
|
1372
|
+
throw rpc_errors_namespaceObject.rpcErrors.invalidParams('Invalid "to" address.');
|
|
1373
|
+
}
|
|
1374
|
+
return txParameters;
|
|
1375
|
+
}
|
|
1368
1376
|
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1377
|
+
/**
|
|
1378
|
+
* Validates the given tx parameters
|
|
1379
|
+
* @throws if the tx params contains invalid fields
|
|
1380
|
+
*/
|
|
1381
|
+
function validateTxParameters(txParams) {
|
|
1382
|
+
let eip1559Compatibility = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
1383
|
+
if (!txParams || typeof txParams !== "object" || Array.isArray(txParams)) {
|
|
1384
|
+
throw rpc_errors_namespaceObject.rpcErrors.invalidParams("Invalid transaction params: must be an object.");
|
|
1385
|
+
}
|
|
1386
|
+
if (!txParams.to && !txParams.data) {
|
|
1387
|
+
throw rpc_errors_namespaceObject.rpcErrors.invalidParams('Invalid transaction params: must specify "data" for contract deployments, or "to" (and optionally "data") for all other types of transactions.');
|
|
1388
|
+
}
|
|
1389
|
+
if (isEIP1559Transaction({
|
|
1390
|
+
transaction: txParams
|
|
1391
|
+
}) && !eip1559Compatibility) {
|
|
1392
|
+
throw rpc_errors_namespaceObject.rpcErrors.invalidParams("Invalid transaction params: params specify an EIP-1559 transaction but the current network does not support EIP-1559");
|
|
1393
|
+
}
|
|
1394
|
+
Object.entries(txParams).forEach(_ref => {
|
|
1395
|
+
let [key, value] = _ref;
|
|
1396
|
+
// validate types
|
|
1397
|
+
switch (key) {
|
|
1398
|
+
case "from":
|
|
1399
|
+
validateFrom(txParams);
|
|
1400
|
+
break;
|
|
1401
|
+
case "to":
|
|
1402
|
+
validateRecipient(txParams);
|
|
1403
|
+
break;
|
|
1404
|
+
case "gasPrice":
|
|
1405
|
+
ensureProperTransactionEnvelopeTypeProvided(txParams, "gasPrice");
|
|
1406
|
+
ensureMutuallyExclusiveFieldsNotProvided(txParams, "gasPrice", "maxFeePerGas");
|
|
1407
|
+
ensureMutuallyExclusiveFieldsNotProvided(txParams, "gasPrice", "maxPriorityFeePerGas");
|
|
1408
|
+
ensureFieldIsString(txParams, "gasPrice");
|
|
1409
|
+
break;
|
|
1410
|
+
case "maxFeePerGas":
|
|
1411
|
+
ensureProperTransactionEnvelopeTypeProvided(txParams, "maxFeePerGas");
|
|
1412
|
+
ensureMutuallyExclusiveFieldsNotProvided(txParams, "maxFeePerGas", "gasPrice");
|
|
1413
|
+
ensureFieldIsString(txParams, "maxFeePerGas");
|
|
1414
|
+
break;
|
|
1415
|
+
case "maxPriorityFeePerGas":
|
|
1416
|
+
ensureProperTransactionEnvelopeTypeProvided(txParams, "maxPriorityFeePerGas");
|
|
1417
|
+
ensureMutuallyExclusiveFieldsNotProvided(txParams, "maxPriorityFeePerGas", "gasPrice");
|
|
1418
|
+
ensureFieldIsString(txParams, "maxPriorityFeePerGas");
|
|
1419
|
+
break;
|
|
1420
|
+
case "value":
|
|
1421
|
+
ensureFieldIsString(txParams, "value");
|
|
1422
|
+
if (value.toString().includes("-")) {
|
|
1423
|
+
throw rpc_errors_namespaceObject.rpcErrors.invalidParams(`Invalid transaction value "${value}": not a positive number.`);
|
|
1424
|
+
}
|
|
1425
|
+
if (value.toString().includes(".")) {
|
|
1426
|
+
throw rpc_errors_namespaceObject.rpcErrors.invalidParams(`Invalid transaction value of "${value}": number must be in wei.`);
|
|
1427
|
+
}
|
|
1428
|
+
break;
|
|
1429
|
+
case "chainId":
|
|
1430
|
+
if (typeof value !== "number" && typeof value !== "string") {
|
|
1431
|
+
throw rpc_errors_namespaceObject.rpcErrors.invalidParams(`Invalid transaction params: ${key} is not a Number or hex string. got: (${value})`);
|
|
1432
|
+
}
|
|
1433
|
+
break;
|
|
1434
|
+
default:
|
|
1435
|
+
ensureFieldIsString(txParams, key);
|
|
1380
1436
|
}
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1437
|
+
});
|
|
1438
|
+
}
|
|
1439
|
+
function normalizeAndValidateTxParams(txParams) {
|
|
1440
|
+
let lowerCase = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
1441
|
+
const normalizedTxParams = normalizeTxParameters(txParams, lowerCase);
|
|
1442
|
+
validateTxParameters(normalizedTxParams);
|
|
1443
|
+
return normalizedTxParams;
|
|
1444
|
+
}
|
|
1387
1445
|
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1446
|
+
/**
|
|
1447
|
+
* @returns an array of states that can be considered final
|
|
1448
|
+
*/
|
|
1449
|
+
function getFinalStates() {
|
|
1450
|
+
return [base_controllers_namespaceObject.TransactionStatus.rejected,
|
|
1451
|
+
// the user has responded no!
|
|
1452
|
+
base_controllers_namespaceObject.TransactionStatus.confirmed,
|
|
1453
|
+
// the tx has been included in a block.
|
|
1454
|
+
base_controllers_namespaceObject.TransactionStatus.failed,
|
|
1455
|
+
// the tx failed for some reason, included on tx data.
|
|
1456
|
+
base_controllers_namespaceObject.TransactionStatus.dropped // the tx nonce was already used
|
|
1457
|
+
];
|
|
1458
|
+
}
|
|
1459
|
+
function parseStandardTokenTransactionData(data) {
|
|
1460
|
+
try {
|
|
1461
|
+
const txDesc = erc20Interface.parseTransaction({
|
|
1462
|
+
data
|
|
1463
|
+
});
|
|
1464
|
+
if (txDesc) return {
|
|
1465
|
+
name: txDesc.name,
|
|
1466
|
+
methodParams: txDesc.args.toArray(),
|
|
1467
|
+
type: CONTRACT_TYPE_ERC20
|
|
1394
1468
|
};
|
|
1395
|
-
|
|
1469
|
+
} catch {
|
|
1470
|
+
// ignore and next try to parse with erc721 ABI
|
|
1396
1471
|
}
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1472
|
+
try {
|
|
1473
|
+
const txDesc = erc721Interface.parseTransaction({
|
|
1474
|
+
data
|
|
1475
|
+
});
|
|
1476
|
+
if (txDesc) return {
|
|
1477
|
+
name: txDesc.name,
|
|
1478
|
+
methodParams: txDesc.args.toArray(),
|
|
1479
|
+
type: CONTRACT_TYPE_ERC721
|
|
1480
|
+
};
|
|
1481
|
+
} catch {
|
|
1482
|
+
// ignore and next try to parse with erc1155 ABI
|
|
1400
1483
|
}
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1484
|
+
try {
|
|
1485
|
+
const txDesc = erc1155Interface.parseTransaction({
|
|
1486
|
+
data
|
|
1487
|
+
});
|
|
1488
|
+
if (txDesc) return {
|
|
1489
|
+
name: txDesc.name,
|
|
1490
|
+
methodParams: txDesc.args.toArray(),
|
|
1491
|
+
type: CONTRACT_TYPE_ERC1155
|
|
1492
|
+
};
|
|
1493
|
+
} catch {
|
|
1494
|
+
// ignore and return undefined
|
|
1405
1495
|
}
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
external_loglevel_default().error(newErr);
|
|
1418
|
-
}
|
|
1419
|
-
await (0,base_controllers_namespaceObject.timeout)(this.config.retryTimeout);
|
|
1420
|
-
}
|
|
1421
|
-
}
|
|
1496
|
+
return undefined;
|
|
1497
|
+
}
|
|
1498
|
+
const readAddressAsContract = async (provider, address) => {
|
|
1499
|
+
let contractCode;
|
|
1500
|
+
try {
|
|
1501
|
+
contractCode = await provider.request({
|
|
1502
|
+
method: METHOD_TYPES.ETH_GET_CODE,
|
|
1503
|
+
params: [address, "latest"]
|
|
1504
|
+
});
|
|
1505
|
+
} catch (e) {
|
|
1506
|
+
contractCode = null;
|
|
1422
1507
|
}
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1508
|
+
const isContractAddress = contractCode ? contractCode !== "0x" && contractCode !== "0x0" : false;
|
|
1509
|
+
return {
|
|
1510
|
+
contractCode,
|
|
1511
|
+
isContractAddress
|
|
1512
|
+
};
|
|
1513
|
+
};
|
|
1514
|
+
async function determineTransactionType(txParams, provider) {
|
|
1515
|
+
const {
|
|
1516
|
+
data,
|
|
1517
|
+
to
|
|
1518
|
+
} = txParams;
|
|
1519
|
+
let name = "";
|
|
1520
|
+
let methodParams = [];
|
|
1521
|
+
let type = "";
|
|
1522
|
+
try {
|
|
1523
|
+
({
|
|
1524
|
+
name,
|
|
1525
|
+
methodParams,
|
|
1526
|
+
type
|
|
1527
|
+
} = data && parseStandardTokenTransactionData(data) || {});
|
|
1528
|
+
} catch (error) {
|
|
1529
|
+
external_loglevel_default().debug("Failed to parse transaction data", error);
|
|
1427
1530
|
}
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1531
|
+
let result;
|
|
1532
|
+
let contractCode = "";
|
|
1533
|
+
if (data && !to) {
|
|
1534
|
+
result = base_controllers_namespaceObject.TRANSACTION_TYPES.DEPLOY_CONTRACT;
|
|
1535
|
+
} else {
|
|
1536
|
+
const {
|
|
1537
|
+
contractCode: resultCode,
|
|
1538
|
+
isContractAddress
|
|
1539
|
+
} = await readAddressAsContract(provider, to);
|
|
1540
|
+
contractCode = resultCode;
|
|
1541
|
+
if (isContractAddress) {
|
|
1542
|
+
const valueExists = txParams.value && Number(txParams.value) !== 0;
|
|
1543
|
+
const tokenMethodName = [base_controllers_namespaceObject.TRANSACTION_TYPES.TOKEN_METHOD_APPROVE, base_controllers_namespaceObject.TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER, base_controllers_namespaceObject.TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM, base_controllers_namespaceObject.TRANSACTION_TYPES.COLLECTIBLE_METHOD_SAFE_TRANSFER_FROM, base_controllers_namespaceObject.TRANSACTION_TYPES.SET_APPROVAL_FOR_ALL].find(x => {
|
|
1544
|
+
var _name;
|
|
1545
|
+
return x.toLowerCase() === ((_name = name) === null || _name === void 0 ? void 0 : _name.toLowerCase());
|
|
1433
1546
|
});
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
timestamp: block.timestamp,
|
|
1438
|
-
baseFeePerGas: block.baseFeePerGas,
|
|
1439
|
-
gasLimit: block.gasLimit
|
|
1440
|
-
};
|
|
1441
|
-
} catch (error) {
|
|
1442
|
-
external_loglevel_default().error("Polling Block Tracker: ", error);
|
|
1443
|
-
throw new Error(`PollingBlockTracker - encountered error fetching block:\n${error.message}`);
|
|
1547
|
+
result = data && tokenMethodName && !valueExists ? tokenMethodName : base_controllers_namespaceObject.TRANSACTION_TYPES.CONTRACT_INTERACTION;
|
|
1548
|
+
} else {
|
|
1549
|
+
result = base_controllers_namespaceObject.TRANSACTION_TYPES.SENT_ETHER;
|
|
1444
1550
|
}
|
|
1445
1551
|
}
|
|
1552
|
+
return {
|
|
1553
|
+
type: type || CONTRACT_TYPE_ETH,
|
|
1554
|
+
category: result,
|
|
1555
|
+
methodParams,
|
|
1556
|
+
getCodeResponse: contractCode
|
|
1557
|
+
};
|
|
1446
1558
|
}
|
|
1447
|
-
|
|
1448
|
-
;// CONCATENATED MODULE: external "@toruslabs/http-helpers"
|
|
1449
|
-
const http_helpers_namespaceObject = require("@toruslabs/http-helpers");
|
|
1450
|
-
;// CONCATENATED MODULE: ./src/Currency/CurrencyController.ts
|
|
1559
|
+
;// CONCATENATED MODULE: ./src/utils/helpers.ts
|
|
1451
1560
|
|
|
1452
1561
|
|
|
1453
1562
|
|
|
1454
1563
|
|
|
1455
1564
|
|
|
1456
1565
|
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1566
|
+
|
|
1567
|
+
|
|
1568
|
+
function getEtherScanHashLink(txHash, chainId) {
|
|
1569
|
+
if (!SUPPORTED_NETWORKS[chainId]) return "";
|
|
1570
|
+
return `${SUPPORTED_NETWORKS[chainId].blockExplorerUrl}/tx/${txHash}`;
|
|
1571
|
+
}
|
|
1572
|
+
const formatPastTx = (x, lowerCaseSelectedAddress) => {
|
|
1573
|
+
var _x$to;
|
|
1574
|
+
let totalAmountString = "";
|
|
1575
|
+
if (x.type === CONTRACT_TYPE_ERC721 || x.type === CONTRACT_TYPE_ERC1155) totalAmountString = x.symbol;else if (x.type === CONTRACT_TYPE_ERC20) totalAmountString = (0,base_controllers_namespaceObject.formatSmallNumbers)(Number.parseFloat(x.total_amount), x.symbol, true);else totalAmountString = (0,base_controllers_namespaceObject.formatSmallNumbers)(Number.parseFloat(x.total_amount), x.type_name, true);
|
|
1576
|
+
const currencyAmountString = x.type === CONTRACT_TYPE_ERC721 || x.type === CONTRACT_TYPE_ERC1155 ? "" : (0,base_controllers_namespaceObject.formatSmallNumbers)(Number.parseFloat(x.currency_amount), x.selected_currency, true);
|
|
1577
|
+
const finalObject = {
|
|
1578
|
+
id: x.created_at.toString(),
|
|
1579
|
+
date: new Date(x.created_at).toString(),
|
|
1580
|
+
from: x.from,
|
|
1581
|
+
from_aa_address: x.from_aa_address,
|
|
1582
|
+
slicedFrom: typeof x.from === "string" ? (0,base_controllers_namespaceObject.addressSlicer)(x.from) : "",
|
|
1583
|
+
to: x.to,
|
|
1584
|
+
slicedTo: typeof x.to === "string" ? (0,base_controllers_namespaceObject.addressSlicer)(x.to) : "",
|
|
1585
|
+
action: lowerCaseSelectedAddress === ((_x$to = x.to) === null || _x$to === void 0 ? void 0 : _x$to.toLowerCase()) || "" ? base_controllers_namespaceObject.ACTIVITY_ACTION_RECEIVE : base_controllers_namespaceObject.ACTIVITY_ACTION_SEND,
|
|
1586
|
+
totalAmount: x.total_amount,
|
|
1587
|
+
totalAmountString,
|
|
1588
|
+
currencyAmount: x.currency_amount,
|
|
1589
|
+
currencyAmountString,
|
|
1590
|
+
amount: `${totalAmountString} / ${currencyAmountString}`,
|
|
1591
|
+
status: x.status,
|
|
1592
|
+
etherscanLink: getEtherScanHashLink(x.transaction_hash, x.chain_id || MAINNET_CHAIN_ID),
|
|
1593
|
+
chainId: x.chain_id,
|
|
1594
|
+
ethRate: Number.parseFloat(x === null || x === void 0 ? void 0 : x.total_amount) && Number.parseFloat(x === null || x === void 0 ? void 0 : x.currency_amount) ? `1 ${x.symbol} = ${(0,base_controllers_namespaceObject.significantDigits)(Number.parseFloat(x.currency_amount) / Number.parseFloat(x.total_amount))}` : "",
|
|
1595
|
+
currencyUsed: x.selected_currency,
|
|
1596
|
+
type: x.type,
|
|
1597
|
+
type_name: x.type_name,
|
|
1598
|
+
type_image_link: x.type_image_link,
|
|
1599
|
+
transaction_hash: x.transaction_hash,
|
|
1600
|
+
transaction_category: x.transaction_category,
|
|
1601
|
+
// TODO: // figure out how to handle these values.
|
|
1602
|
+
isEtherscan: x.isEtherscan,
|
|
1603
|
+
input: x.input || "",
|
|
1604
|
+
token_id: x.token_id || "",
|
|
1605
|
+
contract_address: x.contract_address || "",
|
|
1606
|
+
nonce: x.nonce || "",
|
|
1607
|
+
is_cancel: !!x.is_cancel || false,
|
|
1608
|
+
gas: x.gas || "",
|
|
1609
|
+
gasPrice: x.gasPrice || ""
|
|
1610
|
+
};
|
|
1611
|
+
return finalObject;
|
|
1612
|
+
};
|
|
1613
|
+
|
|
1614
|
+
/**
|
|
1615
|
+
* Ref - https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionreceipt
|
|
1616
|
+
*/
|
|
1617
|
+
const getEthTxStatus = async (hash, provider) => {
|
|
1618
|
+
try {
|
|
1619
|
+
const result = await provider.request({
|
|
1620
|
+
method: METHOD_TYPES.ETH_GET_TRANSACTION_RECEIPT,
|
|
1621
|
+
params: [hash]
|
|
1622
|
+
});
|
|
1623
|
+
if (result === null) return base_controllers_namespaceObject.TransactionStatus.submitted;
|
|
1624
|
+
if (result && result.status === "0x1") return base_controllers_namespaceObject.TransactionStatus.confirmed;
|
|
1625
|
+
if (result && result.status === "0x0") return base_controllers_namespaceObject.TransactionStatus.rejected;
|
|
1626
|
+
return undefined;
|
|
1627
|
+
} catch (err) {
|
|
1628
|
+
external_loglevel_default().warn("unable to fetch transaction status", err);
|
|
1629
|
+
return undefined;
|
|
1630
|
+
}
|
|
1631
|
+
};
|
|
1632
|
+
function formatDate(inputDate) {
|
|
1633
|
+
const monthList = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
1634
|
+
const date = new Date(inputDate);
|
|
1635
|
+
const day = date.getDate();
|
|
1636
|
+
const month = monthList[date.getMonth()];
|
|
1637
|
+
const year = date.getFullYear();
|
|
1638
|
+
return `${day} ${month} ${year}`;
|
|
1639
|
+
}
|
|
1640
|
+
function formatTime(time) {
|
|
1641
|
+
return new Date(time).toTimeString().slice(0, 8);
|
|
1642
|
+
}
|
|
1643
|
+
const idleTimeTracker = (activityThresholdTime => {
|
|
1644
|
+
let isIdle = false;
|
|
1645
|
+
let idleTimeout = null;
|
|
1646
|
+
const resetTimer = () => {
|
|
1647
|
+
if (idleTimeout) {
|
|
1648
|
+
window.clearTimeout(idleTimeout);
|
|
1649
|
+
}
|
|
1650
|
+
isIdle = false;
|
|
1651
|
+
idleTimeout = window.setTimeout(() => {
|
|
1652
|
+
isIdle = true;
|
|
1653
|
+
}, activityThresholdTime * 1000);
|
|
1654
|
+
};
|
|
1655
|
+
if (typeof window !== "undefined" && typeof document !== "undefined") {
|
|
1656
|
+
window.addEventListener("load", resetTimer);
|
|
1657
|
+
document.addEventListener("mousemove", resetTimer);
|
|
1658
|
+
document.addEventListener("keydown", resetTimer);
|
|
1659
|
+
}
|
|
1660
|
+
function checkIfIdle() {
|
|
1661
|
+
return isIdle;
|
|
1662
|
+
}
|
|
1663
|
+
return {
|
|
1664
|
+
checkIfIdle
|
|
1665
|
+
};
|
|
1666
|
+
})(60 * 3);
|
|
1667
|
+
function isAddressByChainId(address, _chainId) {
|
|
1668
|
+
// TOOD: add rsk network checks.
|
|
1669
|
+
return (0,util_namespaceObject.isValidAddress)(address);
|
|
1670
|
+
}
|
|
1671
|
+
function toChecksumAddressByChainId(address, chainId) {
|
|
1672
|
+
// TOOD: add rsk network checks.
|
|
1673
|
+
if (!isAddressByChainId(address, chainId)) return address;
|
|
1674
|
+
return (0,util_namespaceObject.toChecksumAddress)(address);
|
|
1675
|
+
}
|
|
1676
|
+
const GAS_LIMITS = {
|
|
1677
|
+
// maximum gasLimit of a simple send
|
|
1678
|
+
SIMPLE: (0,util_namespaceObject.addHexPrefix)(21000 .toString(16)),
|
|
1679
|
+
// a base estimate for token transfers.
|
|
1680
|
+
BASE_TOKEN_ESTIMATE: (0,util_namespaceObject.addHexPrefix)(100000 .toString(16))
|
|
1681
|
+
};
|
|
1682
|
+
function bnLessThan(a, b) {
|
|
1683
|
+
if (a === null || a === undefined || b === null || b === undefined) {
|
|
1684
|
+
return null;
|
|
1685
|
+
}
|
|
1686
|
+
return new (external_bignumber_js_default())(a, 10).lt(b, 10);
|
|
1687
|
+
}
|
|
1688
|
+
const getIpfsEndpoint = path => `https://infura-ipfs.io/${path}`;
|
|
1689
|
+
function sanitizeNftMetdataUrl(url) {
|
|
1690
|
+
let finalUri = url;
|
|
1691
|
+
if (url !== null && url !== void 0 && url.startsWith("ipfs")) {
|
|
1692
|
+
const ipfsPath = url.split("ipfs://")[1];
|
|
1693
|
+
finalUri = getIpfsEndpoint(ipfsPath);
|
|
1694
|
+
}
|
|
1695
|
+
return finalUri;
|
|
1696
|
+
}
|
|
1697
|
+
function getChainType(chainId) {
|
|
1698
|
+
if (chainId === MAINNET_CHAIN_ID) {
|
|
1699
|
+
return "mainnet";
|
|
1700
|
+
} else if (TEST_CHAINS.includes(chainId)) {
|
|
1701
|
+
return "testnet";
|
|
1702
|
+
}
|
|
1703
|
+
return "custom";
|
|
1704
|
+
}
|
|
1705
|
+
const addEtherscanTransactions = async (txn, lowerCaseSelectedAddress, provider, chainId) => {
|
|
1706
|
+
const transactionPromises = await Promise.all(txn.map(async tx => {
|
|
1707
|
+
var _SUPPORTED_NETWORKS$c, _SUPPORTED_NETWORKS$c2;
|
|
1708
|
+
const {
|
|
1709
|
+
category,
|
|
1710
|
+
type
|
|
1711
|
+
} = await determineTransactionType(objectSpread2_default()(objectSpread2_default()({}, tx), {}, {
|
|
1712
|
+
data: tx.input
|
|
1713
|
+
}), provider);
|
|
1714
|
+
tx.transaction_category = tx.transaction_category || category;
|
|
1715
|
+
tx.type_image_link = ((_SUPPORTED_NETWORKS$c = SUPPORTED_NETWORKS[chainId]) === null || _SUPPORTED_NETWORKS$c === void 0 ? void 0 : _SUPPORTED_NETWORKS$c.logo) || "";
|
|
1716
|
+
tx.type_name = (_SUPPORTED_NETWORKS$c2 = SUPPORTED_NETWORKS[chainId]) === null || _SUPPORTED_NETWORKS$c2 === void 0 ? void 0 : _SUPPORTED_NETWORKS$c2.ticker;
|
|
1717
|
+
tx.type = type;
|
|
1718
|
+
return tx;
|
|
1719
|
+
}));
|
|
1720
|
+
const finalTxs = transactionPromises.reduce((accumulator, x) => {
|
|
1721
|
+
var _SUPPORTED_NETWORKS$c3, _SUPPORTED_NETWORKS$c4;
|
|
1722
|
+
const totalAmount = x.value ? (0,external_ethers_namespaceObject.formatEther)(x.value) : "";
|
|
1723
|
+
const etherscanTransaction = {
|
|
1724
|
+
etherscanLink: getEtherScanHashLink(x.hash, chainId),
|
|
1725
|
+
type: x.type || ((_SUPPORTED_NETWORKS$c3 = SUPPORTED_NETWORKS[chainId]) === null || _SUPPORTED_NETWORKS$c3 === void 0 ? void 0 : _SUPPORTED_NETWORKS$c3.ticker) || CONTRACT_TYPE_ETH,
|
|
1726
|
+
type_image_link: x.type_image_link || "n/a",
|
|
1727
|
+
type_name: x.type_name || "n/a",
|
|
1728
|
+
symbol: (_SUPPORTED_NETWORKS$c4 = SUPPORTED_NETWORKS[chainId]) === null || _SUPPORTED_NETWORKS$c4 === void 0 ? void 0 : _SUPPORTED_NETWORKS$c4.ticker,
|
|
1729
|
+
token_id: x.tokenID || "",
|
|
1730
|
+
total_amount: totalAmount,
|
|
1731
|
+
created_at: new Date(Number(x.timeStamp) * 1000),
|
|
1732
|
+
from: x.from,
|
|
1733
|
+
to: x.to,
|
|
1734
|
+
transaction_hash: x.hash,
|
|
1735
|
+
status: x.txreceipt_status && x.txreceipt_status === "0" ? base_controllers_namespaceObject.TransactionStatus.failed : base_controllers_namespaceObject.TransactionStatus.approved,
|
|
1736
|
+
isEtherscan: true,
|
|
1737
|
+
input: x.input,
|
|
1738
|
+
contract_address: x.contractAddress,
|
|
1739
|
+
transaction_category: x.transaction_category,
|
|
1740
|
+
gas: x.gas,
|
|
1741
|
+
gasPrice: x.gasPrice,
|
|
1742
|
+
chain_id: chainId,
|
|
1743
|
+
currency_amount: "",
|
|
1744
|
+
nonce: x.nonce,
|
|
1745
|
+
from_aa_address: "",
|
|
1746
|
+
is_cancel: false,
|
|
1747
|
+
selected_currency: ""
|
|
1748
|
+
};
|
|
1749
|
+
accumulator.push(formatPastTx(etherscanTransaction, lowerCaseSelectedAddress));
|
|
1750
|
+
return accumulator;
|
|
1751
|
+
}, []);
|
|
1752
|
+
return finalTxs;
|
|
1753
|
+
};
|
|
1754
|
+
;// CONCATENATED MODULE: ./src/Block/PollingBlockTracker.ts
|
|
1755
|
+
|
|
1756
|
+
|
|
1757
|
+
|
|
1758
|
+
const DEFAULT_POLLING_INTERVAL = 20;
|
|
1759
|
+
const DEFAULT_RETRY_TIMEOUT = 2;
|
|
1760
|
+
const SEC = 1000;
|
|
1761
|
+
class PollingBlockTracker extends base_controllers_namespaceObject.BaseBlockTracker {
|
|
1762
|
+
constructor(_ref) {
|
|
1763
|
+
let {
|
|
1764
|
+
config,
|
|
1765
|
+
state = {}
|
|
1766
|
+
} = _ref;
|
|
1767
|
+
if (!config.provider) {
|
|
1768
|
+
throw new Error("PollingBlockTracker - no provider specified.");
|
|
1769
|
+
}
|
|
1770
|
+
super({
|
|
1771
|
+
config,
|
|
1772
|
+
state
|
|
1773
|
+
});
|
|
1774
|
+
const pollingInterval = config.pollingInterval || DEFAULT_POLLING_INTERVAL;
|
|
1775
|
+
const retryTimeout = config.retryTimeout || DEFAULT_RETRY_TIMEOUT;
|
|
1776
|
+
|
|
1777
|
+
// merge default + provided config.
|
|
1778
|
+
this.defaultConfig = {
|
|
1779
|
+
provider: config.provider,
|
|
1780
|
+
pollingInterval: pollingInterval * SEC,
|
|
1781
|
+
retryTimeout: retryTimeout * SEC,
|
|
1782
|
+
setSkipCacheFlag: config.setSkipCacheFlag || false
|
|
1783
|
+
};
|
|
1784
|
+
this.initialize();
|
|
1785
|
+
}
|
|
1786
|
+
async checkForLatestBlock() {
|
|
1787
|
+
await this._updateLatestBlock();
|
|
1788
|
+
return this.getLatestBlock();
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1791
|
+
// overrides the BaseBlockTracker._start method.
|
|
1792
|
+
_start() {
|
|
1793
|
+
this._synchronize().catch(err => this.emit("error", err));
|
|
1794
|
+
}
|
|
1795
|
+
async _synchronize() {
|
|
1796
|
+
while (this.state._isRunning) {
|
|
1797
|
+
if (idleTimeTracker.checkIfIdle()) return;
|
|
1798
|
+
try {
|
|
1799
|
+
await this._updateLatestBlock();
|
|
1800
|
+
await (0,base_controllers_namespaceObject.timeout)(this.config.pollingInterval);
|
|
1801
|
+
} catch (err) {
|
|
1802
|
+
const newErr = new Error(`PollingBlockTracker - encountered an error while attempting to update latest block:\n${err.stack}`);
|
|
1803
|
+
try {
|
|
1804
|
+
this.emit("error", newErr);
|
|
1805
|
+
} catch (emitErr) {
|
|
1806
|
+
external_loglevel_default().error(newErr);
|
|
1807
|
+
}
|
|
1808
|
+
await (0,base_controllers_namespaceObject.timeout)(this.config.retryTimeout);
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
}
|
|
1812
|
+
async _updateLatestBlock() {
|
|
1813
|
+
// fetch + set latest block
|
|
1814
|
+
const latestBlock = await this._fetchLatestBlock();
|
|
1815
|
+
this._newPotentialLatest(latestBlock);
|
|
1816
|
+
}
|
|
1817
|
+
async _fetchLatestBlock() {
|
|
1818
|
+
try {
|
|
1819
|
+
const block = await this.config.provider.request({
|
|
1820
|
+
method: "eth_getBlockByNumber",
|
|
1821
|
+
params: ["latest", false]
|
|
1822
|
+
});
|
|
1823
|
+
return {
|
|
1824
|
+
blockHash: block.hash,
|
|
1825
|
+
idempotencyKey: block.number,
|
|
1826
|
+
timestamp: block.timestamp,
|
|
1827
|
+
baseFeePerGas: block.baseFeePerGas,
|
|
1828
|
+
gasLimit: block.gasLimit
|
|
1829
|
+
};
|
|
1830
|
+
} catch (error) {
|
|
1831
|
+
external_loglevel_default().error("Polling Block Tracker: ", error);
|
|
1832
|
+
throw new Error(`PollingBlockTracker - encountered error fetching block:\n${error.message}`);
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
/* harmony default export */ const Block_PollingBlockTracker = (PollingBlockTracker);
|
|
1837
|
+
;// CONCATENATED MODULE: external "@toruslabs/http-helpers"
|
|
1838
|
+
const http_helpers_namespaceObject = require("@toruslabs/http-helpers");
|
|
1839
|
+
;// CONCATENATED MODULE: ./src/Currency/CurrencyController.ts
|
|
1840
|
+
|
|
1841
|
+
|
|
1842
|
+
|
|
1843
|
+
|
|
1844
|
+
|
|
1845
|
+
|
|
1846
|
+
class CurrencyController extends base_controllers_namespaceObject.BaseCurrencyController {
|
|
1847
|
+
constructor(_ref) {
|
|
1848
|
+
let {
|
|
1849
|
+
config,
|
|
1850
|
+
state,
|
|
1851
|
+
onNetworkChanged
|
|
1852
|
+
} = _ref;
|
|
1853
|
+
super({
|
|
1854
|
+
config,
|
|
1855
|
+
state
|
|
1856
|
+
});
|
|
1857
|
+
defineProperty_default()(this, "conversionInterval", void 0);
|
|
1858
|
+
this.defaultState = objectSpread2_default()(objectSpread2_default()({}, this.defaultState), {}, {
|
|
1859
|
+
commonDenomination: "USD",
|
|
1860
|
+
commonDenominatorPrice: 0
|
|
1861
|
+
});
|
|
1862
|
+
this.initialize();
|
|
1863
|
+
onNetworkChanged(networkState => {
|
|
1864
|
+
// to be called as (listener) => this.networkController.on('networkDidChange', listener);
|
|
1476
1865
|
if (networkState.providerConfig.ticker.toUpperCase() !== this.state.nativeCurrency.toUpperCase()) {
|
|
1477
1866
|
this.setNativeCurrency(networkState.providerConfig.ticker);
|
|
1478
1867
|
this.updateConversionRate();
|
|
@@ -2281,8 +2670,6 @@ class KeyringController extends base_controllers_namespaceObject.BaseKeyringCont
|
|
|
2281
2670
|
return wallet;
|
|
2282
2671
|
}
|
|
2283
2672
|
}
|
|
2284
|
-
;// CONCATENATED MODULE: external "@metamask/rpc-errors"
|
|
2285
|
-
const rpc_errors_namespaceObject = require("@metamask/rpc-errors");
|
|
2286
2673
|
;// CONCATENATED MODULE: ./src/Message/AbstractMessageController.ts
|
|
2287
2674
|
|
|
2288
2675
|
|
|
@@ -4113,7 +4500,8 @@ class PreferencesController extends base_controllers_namespaceObject.BasePrefere
|
|
|
4113
4500
|
defaultPreferences: {
|
|
4114
4501
|
formattedPastTransactions: [],
|
|
4115
4502
|
fetchedPastTx: [],
|
|
4116
|
-
paymentTx: []
|
|
4503
|
+
paymentTx: [],
|
|
4504
|
+
etherscanTransactions: []
|
|
4117
4505
|
},
|
|
4118
4506
|
signAuthMessage
|
|
4119
4507
|
});
|
|
@@ -4294,10 +4682,15 @@ class PreferencesController extends base_controllers_namespaceObject.BasePrefere
|
|
|
4294
4682
|
chainId
|
|
4295
4683
|
} = this.getProviderConfig();
|
|
4296
4684
|
if (ETHERSCAN_SUPPORTED_CHAINS.includes(chainId)) {
|
|
4297
|
-
|
|
4685
|
+
const etherscanTxn = await this.fetchEtherscanTx({
|
|
4298
4686
|
selectedAddress,
|
|
4299
4687
|
chainId: this.getProviderConfig().chainId
|
|
4300
4688
|
});
|
|
4689
|
+
const finalEthScanTxn = await addEtherscanTransactions(etherscanTxn, selectedAddress, this.provider, chainId);
|
|
4690
|
+
this.updateState({
|
|
4691
|
+
etherscanTransactions: finalEthScanTxn
|
|
4692
|
+
});
|
|
4693
|
+
return etherscanTxn;
|
|
4301
4694
|
}
|
|
4302
4695
|
}
|
|
4303
4696
|
}
|
|
@@ -4306,6 +4699,7 @@ class PreferencesController extends base_controllers_namespaceObject.BasePrefere
|
|
|
4306
4699
|
const url = new URL(`${this.config.api}/etherscan`);
|
|
4307
4700
|
url.searchParams.append("chainId", parameters.chainId);
|
|
4308
4701
|
const response = await (0,http_helpers_namespaceObject.get)(url.href, this.headers(parameters.selectedAddress));
|
|
4702
|
+
external_loglevel_default().info("Etherscan Response", response);
|
|
4309
4703
|
return response.success ? response.data : [];
|
|
4310
4704
|
} catch (error) {
|
|
4311
4705
|
external_loglevel_default().error("unable to fetch etherscan tx", error);
|
|
@@ -5445,340 +5839,6 @@ function snapshotFromTxMeta(txMeta) {
|
|
|
5445
5839
|
return (0,external_lodash_namespaceObject.cloneDeep)(shallow);
|
|
5446
5840
|
}
|
|
5447
5841
|
|
|
5448
|
-
;// CONCATENATED MODULE: ./src/Transaction/TransactionUtils.ts
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
const erc20Interface = new external_ethers_namespaceObject.Interface(erc20Abi);
|
|
5457
|
-
const erc721Interface = new external_ethers_namespaceObject.Interface(erc721Abi);
|
|
5458
|
-
const erc1155Interface = new external_ethers_namespaceObject.Interface(erc1155Abi);
|
|
5459
|
-
|
|
5460
|
-
// functions that handle normalizing of that key in txParams
|
|
5461
|
-
|
|
5462
|
-
const normalizers = {
|
|
5463
|
-
from: function (from) {
|
|
5464
|
-
let LowerCase = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
5465
|
-
return LowerCase ? (0,util_namespaceObject.addHexPrefix)(from).toLowerCase() : (0,util_namespaceObject.addHexPrefix)(from);
|
|
5466
|
-
},
|
|
5467
|
-
to: function (to) {
|
|
5468
|
-
let LowerCase = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
5469
|
-
return LowerCase ? (0,util_namespaceObject.addHexPrefix)(to).toLowerCase() : (0,util_namespaceObject.addHexPrefix)(to);
|
|
5470
|
-
},
|
|
5471
|
-
nonce: nonce => (0,util_namespaceObject.addHexPrefix)(nonce),
|
|
5472
|
-
customNonceValue: nonce => (0,util_namespaceObject.addHexPrefix)(nonce),
|
|
5473
|
-
value: value => (0,util_namespaceObject.addHexPrefix)(value),
|
|
5474
|
-
data: data => (0,util_namespaceObject.addHexPrefix)(data),
|
|
5475
|
-
gas: gas => (0,util_namespaceObject.addHexPrefix)(gas),
|
|
5476
|
-
gasPrice: gasPrice => (0,util_namespaceObject.addHexPrefix)(gasPrice),
|
|
5477
|
-
type: util_namespaceObject.addHexPrefix,
|
|
5478
|
-
maxFeePerGas: util_namespaceObject.addHexPrefix,
|
|
5479
|
-
maxPriorityFeePerGas: util_namespaceObject.addHexPrefix
|
|
5480
|
-
};
|
|
5481
|
-
|
|
5482
|
-
/**
|
|
5483
|
-
* normalizes txParams
|
|
5484
|
-
*/
|
|
5485
|
-
function normalizeTxParameters(txParameters) {
|
|
5486
|
-
let lowerCase = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
5487
|
-
// apply only keys in the normalizers
|
|
5488
|
-
const normalizedTxParameters = {
|
|
5489
|
-
id: txParameters.id || (0,base_controllers_namespaceObject.randomId)(),
|
|
5490
|
-
from: txParameters.from
|
|
5491
|
-
};
|
|
5492
|
-
for (const key in normalizers) {
|
|
5493
|
-
const currentKey = key;
|
|
5494
|
-
if (txParameters[currentKey])
|
|
5495
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5496
|
-
normalizedTxParameters[currentKey] = normalizers[currentKey](txParameters[currentKey], lowerCase);
|
|
5497
|
-
}
|
|
5498
|
-
return normalizedTxParameters;
|
|
5499
|
-
}
|
|
5500
|
-
function transactionMatchesNetwork(transaction, chainId) {
|
|
5501
|
-
if (typeof transaction.chainId !== "undefined") {
|
|
5502
|
-
return transaction.chainId === chainId;
|
|
5503
|
-
}
|
|
5504
|
-
return false;
|
|
5505
|
-
}
|
|
5506
|
-
|
|
5507
|
-
/**
|
|
5508
|
-
* Determines if the maxFeePerGas and maxPriorityFeePerGas fields are supplied
|
|
5509
|
-
* and valid inputs. This will return false for non hex string inputs.
|
|
5510
|
-
* the transaction to check
|
|
5511
|
-
* @returns true if transaction uses valid EIP1559 fields
|
|
5512
|
-
*/
|
|
5513
|
-
function isEIP1559Transaction(transaction) {
|
|
5514
|
-
var _transaction$transact, _transaction$transact2;
|
|
5515
|
-
return (0,util_namespaceObject.isHexString)((0,util_namespaceObject.addHexPrefix)(transaction === null || transaction === void 0 || (_transaction$transact = transaction.transaction) === null || _transaction$transact === void 0 ? void 0 : _transaction$transact.maxFeePerGas)) && (0,util_namespaceObject.isHexString)((0,util_namespaceObject.addHexPrefix)(transaction === null || transaction === void 0 || (_transaction$transact2 = transaction.transaction) === null || _transaction$transact2 === void 0 ? void 0 : _transaction$transact2.maxPriorityFeePerGas));
|
|
5516
|
-
}
|
|
5517
|
-
|
|
5518
|
-
/**
|
|
5519
|
-
* Determine if the maxFeePerGas and maxPriorityFeePerGas fields are not
|
|
5520
|
-
* supplied and that the gasPrice field is valid if it is provided. This will
|
|
5521
|
-
* return false if gasPrice is a non hex string.
|
|
5522
|
-
* transaction -
|
|
5523
|
-
* the transaction to check
|
|
5524
|
-
* @returns true if transaction uses valid Legacy fields OR lacks
|
|
5525
|
-
* EIP1559 fields
|
|
5526
|
-
*/
|
|
5527
|
-
function isLegacyTransaction(transaction) {
|
|
5528
|
-
return typeof transaction.transaction.maxFeePerGas === "undefined" && typeof transaction.transaction.maxPriorityFeePerGas === "undefined" && (typeof transaction.transaction.gasPrice === "undefined" || (0,util_namespaceObject.isHexString)((0,util_namespaceObject.addHexPrefix)(transaction.transaction.gasPrice)));
|
|
5529
|
-
}
|
|
5530
|
-
|
|
5531
|
-
/**
|
|
5532
|
-
* Given two fields, ensure that the second field is not included in txParams,
|
|
5533
|
-
* and if it is throw an invalidParams error.
|
|
5534
|
-
*/
|
|
5535
|
-
function ensureMutuallyExclusiveFieldsNotProvided(txParams, fieldBeingValidated, mutuallyExclusiveField) {
|
|
5536
|
-
if (typeof txParams[mutuallyExclusiveField] !== "undefined") {
|
|
5537
|
-
throw rpc_errors_namespaceObject.rpcErrors.invalidParams(`Invalid transaction params: specified ${fieldBeingValidated} but also included ${mutuallyExclusiveField}, these cannot be mixed`);
|
|
5538
|
-
}
|
|
5539
|
-
}
|
|
5540
|
-
|
|
5541
|
-
/**
|
|
5542
|
-
* Ensures that the provided value for field is a string, throws an
|
|
5543
|
-
* invalidParams error if field is not a string.
|
|
5544
|
-
*/
|
|
5545
|
-
function ensureFieldIsString(txParams, field) {
|
|
5546
|
-
if (typeof txParams[field] !== "string") {
|
|
5547
|
-
throw rpc_errors_namespaceObject.rpcErrors.invalidParams(`Invalid transaction params: ${field} is not a string. got: (${txParams[field]})`);
|
|
5548
|
-
}
|
|
5549
|
-
}
|
|
5550
|
-
|
|
5551
|
-
/**
|
|
5552
|
-
* Ensures that the provided txParams has the proper 'type' specified for the
|
|
5553
|
-
* given field, if it is provided. If types do not match throws an
|
|
5554
|
-
* invalidParams error.
|
|
5555
|
-
*/
|
|
5556
|
-
function ensureProperTransactionEnvelopeTypeProvided(txParams, field) {
|
|
5557
|
-
switch (field) {
|
|
5558
|
-
case "maxFeePerGas":
|
|
5559
|
-
case "maxPriorityFeePerGas":
|
|
5560
|
-
if (txParams.type && txParams.type !== TRANSACTION_ENVELOPE_TYPES.FEE_MARKET) {
|
|
5561
|
-
throw rpc_errors_namespaceObject.rpcErrors.invalidParams(`Invalid transaction envelope type: specified type "${txParams.type}" but ` + `including maxFeePerGas and maxPriorityFeePerGas requires type: "${TRANSACTION_ENVELOPE_TYPES.FEE_MARKET}"`);
|
|
5562
|
-
}
|
|
5563
|
-
break;
|
|
5564
|
-
case "gasPrice":
|
|
5565
|
-
default:
|
|
5566
|
-
if (txParams.type && txParams.type === TRANSACTION_ENVELOPE_TYPES.FEE_MARKET) {
|
|
5567
|
-
throw rpc_errors_namespaceObject.rpcErrors.invalidParams(`Invalid transaction envelope type: specified type "${txParams.type}" but ` + "included a gasPrice instead of maxFeePerGas and maxPriorityFeePerGas");
|
|
5568
|
-
}
|
|
5569
|
-
}
|
|
5570
|
-
}
|
|
5571
|
-
|
|
5572
|
-
/**
|
|
5573
|
-
* validates the from field in txParams
|
|
5574
|
-
*/
|
|
5575
|
-
function validateFrom(txParams) {
|
|
5576
|
-
if (!(typeof txParams.from === "string")) {
|
|
5577
|
-
throw rpc_errors_namespaceObject.rpcErrors.invalidParams(`Invalid "from" address "${txParams.from}": not a string.`);
|
|
5578
|
-
}
|
|
5579
|
-
if (!(0,util_namespaceObject.isValidAddress)(txParams.from)) {
|
|
5580
|
-
throw rpc_errors_namespaceObject.rpcErrors.invalidParams('Invalid "from" address.');
|
|
5581
|
-
}
|
|
5582
|
-
}
|
|
5583
|
-
|
|
5584
|
-
/**
|
|
5585
|
-
* validates the to field in txParams
|
|
5586
|
-
*/
|
|
5587
|
-
function validateRecipient(txParameters) {
|
|
5588
|
-
if (txParameters.to === "0x" || txParameters.to === null) {
|
|
5589
|
-
if (txParameters.data) {
|
|
5590
|
-
delete txParameters.to;
|
|
5591
|
-
} else {
|
|
5592
|
-
throw rpc_errors_namespaceObject.rpcErrors.invalidParams('Invalid "to" address.');
|
|
5593
|
-
}
|
|
5594
|
-
} else if (txParameters.to !== undefined && !(0,util_namespaceObject.isValidAddress)(txParameters.to)) {
|
|
5595
|
-
throw rpc_errors_namespaceObject.rpcErrors.invalidParams('Invalid "to" address.');
|
|
5596
|
-
}
|
|
5597
|
-
return txParameters;
|
|
5598
|
-
}
|
|
5599
|
-
|
|
5600
|
-
/**
|
|
5601
|
-
* Validates the given tx parameters
|
|
5602
|
-
* @throws if the tx params contains invalid fields
|
|
5603
|
-
*/
|
|
5604
|
-
function validateTxParameters(txParams) {
|
|
5605
|
-
let eip1559Compatibility = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
5606
|
-
if (!txParams || typeof txParams !== "object" || Array.isArray(txParams)) {
|
|
5607
|
-
throw rpc_errors_namespaceObject.rpcErrors.invalidParams("Invalid transaction params: must be an object.");
|
|
5608
|
-
}
|
|
5609
|
-
if (!txParams.to && !txParams.data) {
|
|
5610
|
-
throw rpc_errors_namespaceObject.rpcErrors.invalidParams('Invalid transaction params: must specify "data" for contract deployments, or "to" (and optionally "data") for all other types of transactions.');
|
|
5611
|
-
}
|
|
5612
|
-
if (isEIP1559Transaction({
|
|
5613
|
-
transaction: txParams
|
|
5614
|
-
}) && !eip1559Compatibility) {
|
|
5615
|
-
throw rpc_errors_namespaceObject.rpcErrors.invalidParams("Invalid transaction params: params specify an EIP-1559 transaction but the current network does not support EIP-1559");
|
|
5616
|
-
}
|
|
5617
|
-
Object.entries(txParams).forEach(_ref => {
|
|
5618
|
-
let [key, value] = _ref;
|
|
5619
|
-
// validate types
|
|
5620
|
-
switch (key) {
|
|
5621
|
-
case "from":
|
|
5622
|
-
validateFrom(txParams);
|
|
5623
|
-
break;
|
|
5624
|
-
case "to":
|
|
5625
|
-
validateRecipient(txParams);
|
|
5626
|
-
break;
|
|
5627
|
-
case "gasPrice":
|
|
5628
|
-
ensureProperTransactionEnvelopeTypeProvided(txParams, "gasPrice");
|
|
5629
|
-
ensureMutuallyExclusiveFieldsNotProvided(txParams, "gasPrice", "maxFeePerGas");
|
|
5630
|
-
ensureMutuallyExclusiveFieldsNotProvided(txParams, "gasPrice", "maxPriorityFeePerGas");
|
|
5631
|
-
ensureFieldIsString(txParams, "gasPrice");
|
|
5632
|
-
break;
|
|
5633
|
-
case "maxFeePerGas":
|
|
5634
|
-
ensureProperTransactionEnvelopeTypeProvided(txParams, "maxFeePerGas");
|
|
5635
|
-
ensureMutuallyExclusiveFieldsNotProvided(txParams, "maxFeePerGas", "gasPrice");
|
|
5636
|
-
ensureFieldIsString(txParams, "maxFeePerGas");
|
|
5637
|
-
break;
|
|
5638
|
-
case "maxPriorityFeePerGas":
|
|
5639
|
-
ensureProperTransactionEnvelopeTypeProvided(txParams, "maxPriorityFeePerGas");
|
|
5640
|
-
ensureMutuallyExclusiveFieldsNotProvided(txParams, "maxPriorityFeePerGas", "gasPrice");
|
|
5641
|
-
ensureFieldIsString(txParams, "maxPriorityFeePerGas");
|
|
5642
|
-
break;
|
|
5643
|
-
case "value":
|
|
5644
|
-
ensureFieldIsString(txParams, "value");
|
|
5645
|
-
if (value.toString().includes("-")) {
|
|
5646
|
-
throw rpc_errors_namespaceObject.rpcErrors.invalidParams(`Invalid transaction value "${value}": not a positive number.`);
|
|
5647
|
-
}
|
|
5648
|
-
if (value.toString().includes(".")) {
|
|
5649
|
-
throw rpc_errors_namespaceObject.rpcErrors.invalidParams(`Invalid transaction value of "${value}": number must be in wei.`);
|
|
5650
|
-
}
|
|
5651
|
-
break;
|
|
5652
|
-
case "chainId":
|
|
5653
|
-
if (typeof value !== "number" && typeof value !== "string") {
|
|
5654
|
-
throw rpc_errors_namespaceObject.rpcErrors.invalidParams(`Invalid transaction params: ${key} is not a Number or hex string. got: (${value})`);
|
|
5655
|
-
}
|
|
5656
|
-
break;
|
|
5657
|
-
default:
|
|
5658
|
-
ensureFieldIsString(txParams, key);
|
|
5659
|
-
}
|
|
5660
|
-
});
|
|
5661
|
-
}
|
|
5662
|
-
function normalizeAndValidateTxParams(txParams) {
|
|
5663
|
-
let lowerCase = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
5664
|
-
const normalizedTxParams = normalizeTxParameters(txParams, lowerCase);
|
|
5665
|
-
validateTxParameters(normalizedTxParams);
|
|
5666
|
-
return normalizedTxParams;
|
|
5667
|
-
}
|
|
5668
|
-
|
|
5669
|
-
/**
|
|
5670
|
-
* @returns an array of states that can be considered final
|
|
5671
|
-
*/
|
|
5672
|
-
function getFinalStates() {
|
|
5673
|
-
return [base_controllers_namespaceObject.TransactionStatus.rejected,
|
|
5674
|
-
// the user has responded no!
|
|
5675
|
-
base_controllers_namespaceObject.TransactionStatus.confirmed,
|
|
5676
|
-
// the tx has been included in a block.
|
|
5677
|
-
base_controllers_namespaceObject.TransactionStatus.failed,
|
|
5678
|
-
// the tx failed for some reason, included on tx data.
|
|
5679
|
-
base_controllers_namespaceObject.TransactionStatus.dropped // the tx nonce was already used
|
|
5680
|
-
];
|
|
5681
|
-
}
|
|
5682
|
-
function parseStandardTokenTransactionData(data) {
|
|
5683
|
-
try {
|
|
5684
|
-
const txDesc = erc20Interface.parseTransaction({
|
|
5685
|
-
data
|
|
5686
|
-
});
|
|
5687
|
-
if (txDesc) return {
|
|
5688
|
-
name: txDesc.name,
|
|
5689
|
-
methodParams: txDesc.args.toArray(),
|
|
5690
|
-
type: CONTRACT_TYPE_ERC20
|
|
5691
|
-
};
|
|
5692
|
-
} catch {
|
|
5693
|
-
// ignore and next try to parse with erc721 ABI
|
|
5694
|
-
}
|
|
5695
|
-
try {
|
|
5696
|
-
const txDesc = erc721Interface.parseTransaction({
|
|
5697
|
-
data
|
|
5698
|
-
});
|
|
5699
|
-
if (txDesc) return {
|
|
5700
|
-
name: txDesc.name,
|
|
5701
|
-
methodParams: txDesc.args.toArray(),
|
|
5702
|
-
type: CONTRACT_TYPE_ERC721
|
|
5703
|
-
};
|
|
5704
|
-
} catch {
|
|
5705
|
-
// ignore and next try to parse with erc1155 ABI
|
|
5706
|
-
}
|
|
5707
|
-
try {
|
|
5708
|
-
const txDesc = erc1155Interface.parseTransaction({
|
|
5709
|
-
data
|
|
5710
|
-
});
|
|
5711
|
-
if (txDesc) return {
|
|
5712
|
-
name: txDesc.name,
|
|
5713
|
-
methodParams: txDesc.args.toArray(),
|
|
5714
|
-
type: CONTRACT_TYPE_ERC1155
|
|
5715
|
-
};
|
|
5716
|
-
} catch {
|
|
5717
|
-
// ignore and return undefined
|
|
5718
|
-
}
|
|
5719
|
-
return undefined;
|
|
5720
|
-
}
|
|
5721
|
-
const readAddressAsContract = async (provider, address) => {
|
|
5722
|
-
let contractCode;
|
|
5723
|
-
try {
|
|
5724
|
-
contractCode = await provider.request({
|
|
5725
|
-
method: METHOD_TYPES.ETH_GET_CODE,
|
|
5726
|
-
params: [address, "latest"]
|
|
5727
|
-
});
|
|
5728
|
-
} catch (e) {
|
|
5729
|
-
contractCode = null;
|
|
5730
|
-
}
|
|
5731
|
-
const isContractAddress = contractCode ? contractCode !== "0x" && contractCode !== "0x0" : false;
|
|
5732
|
-
return {
|
|
5733
|
-
contractCode,
|
|
5734
|
-
isContractAddress
|
|
5735
|
-
};
|
|
5736
|
-
};
|
|
5737
|
-
async function determineTransactionType(txParams, provider) {
|
|
5738
|
-
const {
|
|
5739
|
-
data,
|
|
5740
|
-
to
|
|
5741
|
-
} = txParams;
|
|
5742
|
-
let name = "";
|
|
5743
|
-
let methodParams = [];
|
|
5744
|
-
let type = "";
|
|
5745
|
-
try {
|
|
5746
|
-
({
|
|
5747
|
-
name,
|
|
5748
|
-
methodParams,
|
|
5749
|
-
type
|
|
5750
|
-
} = data && parseStandardTokenTransactionData(data) || {});
|
|
5751
|
-
} catch (error) {
|
|
5752
|
-
external_loglevel_default().debug("Failed to parse transaction data", error);
|
|
5753
|
-
}
|
|
5754
|
-
let result;
|
|
5755
|
-
let contractCode = "";
|
|
5756
|
-
if (data && !to) {
|
|
5757
|
-
result = base_controllers_namespaceObject.TRANSACTION_TYPES.DEPLOY_CONTRACT;
|
|
5758
|
-
} else {
|
|
5759
|
-
const {
|
|
5760
|
-
contractCode: resultCode,
|
|
5761
|
-
isContractAddress
|
|
5762
|
-
} = await readAddressAsContract(provider, to);
|
|
5763
|
-
contractCode = resultCode;
|
|
5764
|
-
if (isContractAddress) {
|
|
5765
|
-
const valueExists = txParams.value && Number(txParams.value) !== 0;
|
|
5766
|
-
const tokenMethodName = [base_controllers_namespaceObject.TRANSACTION_TYPES.TOKEN_METHOD_APPROVE, base_controllers_namespaceObject.TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER, base_controllers_namespaceObject.TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM, base_controllers_namespaceObject.TRANSACTION_TYPES.COLLECTIBLE_METHOD_SAFE_TRANSFER_FROM, base_controllers_namespaceObject.TRANSACTION_TYPES.SET_APPROVAL_FOR_ALL].find(x => {
|
|
5767
|
-
var _name;
|
|
5768
|
-
return x.toLowerCase() === ((_name = name) === null || _name === void 0 ? void 0 : _name.toLowerCase());
|
|
5769
|
-
});
|
|
5770
|
-
result = data && tokenMethodName && !valueExists ? tokenMethodName : base_controllers_namespaceObject.TRANSACTION_TYPES.CONTRACT_INTERACTION;
|
|
5771
|
-
} else {
|
|
5772
|
-
result = base_controllers_namespaceObject.TRANSACTION_TYPES.SENT_ETHER;
|
|
5773
|
-
}
|
|
5774
|
-
}
|
|
5775
|
-
return {
|
|
5776
|
-
type: type || CONTRACT_TYPE_ETH,
|
|
5777
|
-
category: result,
|
|
5778
|
-
methodParams,
|
|
5779
|
-
getCodeResponse: contractCode
|
|
5780
|
-
};
|
|
5781
|
-
}
|
|
5782
5842
|
;// CONCATENATED MODULE: ./src/Transaction/TransactionStateManager.ts
|
|
5783
5843
|
|
|
5784
5844
|
|