@toruslabs/ethereum-controllers 5.3.4 → 5.3.6

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.
@@ -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.png",
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: "xdai.svg",
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.png",
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: ./src/utils/helpers.ts
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
- function getEtherScanHashLink(txHash, chainId) {
1229
- if (!SUPPORTED_NETWORKS[chainId]) return "";
1230
- return `${SUPPORTED_NETWORKS[chainId].blockExplorerUrl}/tx/${txHash}`;
1231
- }
1232
- const formatPastTx = (x, lowerCaseSelectedAddress) => {
1233
- var _x$to;
1234
- let totalAmountString = "";
1235
- 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);
1236
- 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);
1237
- const finalObject = {
1238
- id: x.created_at.toString(),
1239
- date: new Date(x.created_at).toString(),
1240
- from: x.from,
1241
- from_aa_address: x.from_aa_address,
1242
- slicedFrom: typeof x.from === "string" ? (0,base_controllers_namespaceObject.addressSlicer)(x.from) : "",
1243
- to: x.to,
1244
- slicedTo: typeof x.to === "string" ? (0,base_controllers_namespaceObject.addressSlicer)(x.to) : "",
1245
- 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,
1246
- totalAmount: x.total_amount,
1247
- totalAmountString,
1248
- currencyAmount: x.currency_amount,
1249
- currencyAmountString,
1250
- amount: `${totalAmountString} / ${currencyAmountString}`,
1251
- status: x.status,
1252
- etherscanLink: getEtherScanHashLink(x.transaction_hash, x.chain_id || MAINNET_CHAIN_ID),
1253
- chainId: x.chain_id,
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
- * Ref - https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionreceipt
1260
+ * normalizes txParams
1276
1261
  */
1277
- const getEthTxStatus = async (hash, provider) => {
1278
- try {
1279
- const result = await provider.request({
1280
- method: METHOD_TYPES.ETH_GET_TRANSACTION_RECEIPT,
1281
- params: [hash]
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
- if (typeof window !== "undefined" && typeof document !== "undefined") {
1316
- window.addEventListener("load", resetTimer);
1317
- document.addEventListener("mousemove", resetTimer);
1318
- document.addEventListener("keydown", resetTimer);
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
- function checkIfIdle() {
1321
- return isIdle;
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
- function toChecksumAddressByChainId(address, chainId) {
1332
- // TOOD: add rsk network checks.
1333
- if (!isAddressByChainId(address, chainId)) return address;
1334
- return (0,util_namespaceObject.toChecksumAddress)(address);
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
- const GAS_LIMITS = {
1337
- // maximum gasLimit of a simple send
1338
- SIMPLE: (0,util_namespaceObject.addHexPrefix)(21000 .toString(16)),
1339
- // a base estimate for token transfers.
1340
- BASE_TOKEN_ESTIMATE: (0,util_namespaceObject.addHexPrefix)(100000 .toString(16))
1341
- };
1342
- function bnLessThan(a, b) {
1343
- if (a === null || a === undefined || b === null || b === undefined) {
1344
- return null;
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
- const getIpfsEndpoint = path => `https://infura-ipfs.io/${path}`;
1349
- function sanitizeNftMetdataUrl(url) {
1350
- let finalUri = url;
1351
- if (url !== null && url !== void 0 && url.startsWith("ipfs")) {
1352
- const ipfsPath = url.split("ipfs://")[1];
1353
- finalUri = getIpfsEndpoint(ipfsPath);
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
- function getChainType(chainId) {
1358
- if (chainId === MAINNET_CHAIN_ID) {
1359
- return "mainnet";
1360
- } else if (TEST_CHAINS.includes(chainId)) {
1361
- return "testnet";
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
- const DEFAULT_POLLING_INTERVAL = 20;
1370
- const DEFAULT_RETRY_TIMEOUT = 2;
1371
- const SEC = 1000;
1372
- class PollingBlockTracker extends base_controllers_namespaceObject.BaseBlockTracker {
1373
- constructor(_ref) {
1374
- let {
1375
- config,
1376
- state = {}
1377
- } = _ref;
1378
- if (!config.provider) {
1379
- throw new Error("PollingBlockTracker - no provider specified.");
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
- super({
1382
- config,
1383
- state
1384
- });
1385
- const pollingInterval = config.pollingInterval || DEFAULT_POLLING_INTERVAL;
1386
- const retryTimeout = config.retryTimeout || DEFAULT_RETRY_TIMEOUT;
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
- // merge default + provided config.
1389
- this.defaultConfig = {
1390
- provider: config.provider,
1391
- pollingInterval: pollingInterval * SEC,
1392
- retryTimeout: retryTimeout * SEC,
1393
- setSkipCacheFlag: config.setSkipCacheFlag || false
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
- this.initialize();
1469
+ } catch {
1470
+ // ignore and next try to parse with erc721 ABI
1396
1471
  }
1397
- async checkForLatestBlock() {
1398
- await this._updateLatestBlock();
1399
- return this.getLatestBlock();
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
- // overrides the BaseBlockTracker._start method.
1403
- _start() {
1404
- this._synchronize().catch(err => this.emit("error", err));
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
- async _synchronize() {
1407
- while (this.state._isRunning) {
1408
- if (idleTimeTracker.checkIfIdle()) return;
1409
- try {
1410
- await this._updateLatestBlock();
1411
- await (0,base_controllers_namespaceObject.timeout)(this.config.pollingInterval);
1412
- } catch (err) {
1413
- const newErr = new Error(`PollingBlockTracker - encountered an error while attempting to update latest block:\n${err.stack}`);
1414
- try {
1415
- this.emit("error", newErr);
1416
- } catch (emitErr) {
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
- async _updateLatestBlock() {
1424
- // fetch + set latest block
1425
- const latestBlock = await this._fetchLatestBlock();
1426
- this._newPotentialLatest(latestBlock);
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
- async _fetchLatestBlock() {
1429
- try {
1430
- const block = await this.config.provider.request({
1431
- method: "eth_getBlockByNumber",
1432
- params: ["latest", false]
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
- return {
1435
- blockHash: block.hash,
1436
- idempotencyKey: block.number,
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
- /* harmony default export */ const Block_PollingBlockTracker = (PollingBlockTracker);
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
- class CurrencyController extends base_controllers_namespaceObject.BaseCurrencyController {
1458
- constructor(_ref) {
1459
- let {
1460
- config,
1461
- state,
1462
- onNetworkChanged
1463
- } = _ref;
1464
- super({
1465
- config,
1466
- state
1467
- });
1468
- defineProperty_default()(this, "conversionInterval", void 0);
1469
- this.defaultState = objectSpread2_default()(objectSpread2_default()({}, this.defaultState), {}, {
1470
- commonDenomination: "USD",
1471
- commonDenominatorPrice: 0
1472
- });
1473
- this.initialize();
1474
- onNetworkChanged(networkState => {
1475
- // to be called as (listener) => this.networkController.on('networkDidChange', listener);
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
  });
@@ -4164,7 +4552,8 @@ class PreferencesController extends base_controllers_namespaceObject.BasePrefere
4164
4552
  type,
4165
4553
  metadata: {
4166
4554
  email: userInfo.email,
4167
- signatures
4555
+ signatures,
4556
+ network: web3AuthNetwork
4168
4557
  }
4169
4558
  });
4170
4559
  const {
@@ -4294,10 +4683,15 @@ class PreferencesController extends base_controllers_namespaceObject.BasePrefere
4294
4683
  chainId
4295
4684
  } = this.getProviderConfig();
4296
4685
  if (ETHERSCAN_SUPPORTED_CHAINS.includes(chainId)) {
4297
- return this.fetchEtherscanTx({
4686
+ const etherscanTxn = await this.fetchEtherscanTx({
4298
4687
  selectedAddress,
4299
4688
  chainId: this.getProviderConfig().chainId
4300
4689
  });
4690
+ const finalEthScanTxn = await addEtherscanTransactions(etherscanTxn, selectedAddress, this.provider, chainId);
4691
+ this.updateState({
4692
+ etherscanTransactions: finalEthScanTxn
4693
+ });
4694
+ return etherscanTxn;
4301
4695
  }
4302
4696
  }
4303
4697
  }
@@ -4306,6 +4700,7 @@ class PreferencesController extends base_controllers_namespaceObject.BasePrefere
4306
4700
  const url = new URL(`${this.config.api}/etherscan`);
4307
4701
  url.searchParams.append("chainId", parameters.chainId);
4308
4702
  const response = await (0,http_helpers_namespaceObject.get)(url.href, this.headers(parameters.selectedAddress));
4703
+ external_loglevel_default().info("Etherscan Response", response);
4309
4704
  return response.success ? response.data : [];
4310
4705
  } catch (error) {
4311
4706
  external_loglevel_default().error("unable to fetch etherscan tx", error);
@@ -5445,340 +5840,6 @@ function snapshotFromTxMeta(txMeta) {
5445
5840
  return (0,external_lodash_namespaceObject.cloneDeep)(shallow);
5446
5841
  }
5447
5842
 
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
5843
  ;// CONCATENATED MODULE: ./src/Transaction/TransactionStateManager.ts
5783
5844
 
5784
5845