@metamask/transaction-controller 15.0.0 → 17.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -1
- package/dist/TransactionController.d.ts +159 -20
- package/dist/TransactionController.d.ts.map +1 -1
- package/dist/TransactionController.js +489 -151
- package/dist/TransactionController.js.map +1 -1
- package/dist/constants.d.ts +2 -3
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +3 -15
- package/dist/constants.js.map +1 -1
- package/dist/{EtherscanRemoteTransactionSource.d.ts → helpers/EtherscanRemoteTransactionSource.d.ts} +1 -1
- package/dist/helpers/EtherscanRemoteTransactionSource.d.ts.map +1 -0
- package/dist/{EtherscanRemoteTransactionSource.js → helpers/EtherscanRemoteTransactionSource.js} +4 -4
- package/dist/helpers/EtherscanRemoteTransactionSource.js.map +1 -0
- package/dist/{IncomingTransactionHelper.d.ts → helpers/IncomingTransactionHelper.d.ts} +1 -1
- package/dist/helpers/IncomingTransactionHelper.d.ts.map +1 -0
- package/dist/{IncomingTransactionHelper.js → helpers/IncomingTransactionHelper.js} +1 -1
- package/dist/helpers/IncomingTransactionHelper.js.map +1 -0
- package/dist/helpers/PendingTransactionTracker.d.ts +38 -0
- package/dist/helpers/PendingTransactionTracker.d.ts.map +1 -0
- package/dist/helpers/PendingTransactionTracker.js +329 -0
- package/dist/helpers/PendingTransactionTracker.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +0 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +1 -2
- package/dist/logger.js.map +1 -1
- package/dist/types.d.ts +290 -8
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +37 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/etherscan.d.ts.map +1 -0
- package/dist/{etherscan.js → utils/etherscan.js} +3 -4
- package/dist/utils/etherscan.js.map +1 -0
- package/dist/{external-transactions.d.ts → utils/external-transactions.d.ts} +1 -1
- package/dist/utils/external-transactions.d.ts.map +1 -0
- package/dist/{external-transactions.js → utils/external-transactions.js} +1 -1
- package/dist/utils/external-transactions.js.map +1 -0
- package/dist/utils/gas-fees.d.ts +31 -0
- package/dist/utils/gas-fees.d.ts.map +1 -0
- package/dist/utils/gas-fees.js +212 -0
- package/dist/utils/gas-fees.js.map +1 -0
- package/dist/utils/gas.d.ts +27 -0
- package/dist/utils/gas.d.ts.map +1 -0
- package/dist/utils/gas.js +134 -0
- package/dist/utils/gas.js.map +1 -0
- package/dist/{history.d.ts → utils/history.d.ts} +1 -1
- package/dist/utils/history.d.ts.map +1 -0
- package/dist/utils/history.js.map +1 -0
- package/dist/utils/swaps.d.ts +81 -0
- package/dist/utils/swaps.d.ts.map +1 -0
- package/dist/utils/swaps.js +240 -0
- package/dist/utils/swaps.js.map +1 -0
- package/dist/{transaction-type.d.ts → utils/transaction-type.d.ts} +1 -1
- package/dist/utils/transaction-type.d.ts.map +1 -0
- package/dist/{transaction-type.js → utils/transaction-type.js} +1 -1
- package/dist/utils/transaction-type.js.map +1 -0
- package/dist/{utils.d.ts → utils/utils.d.ts} +13 -3
- package/dist/utils/utils.d.ts.map +1 -0
- package/dist/{utils.js → utils/utils.js} +21 -5
- package/dist/utils/utils.js.map +1 -0
- package/dist/{validation.d.ts → utils/validation.d.ts} +1 -1
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/{validation.js → utils/validation.js} +90 -7
- package/dist/utils/validation.js.map +1 -0
- package/package.json +12 -9
- package/dist/EtherscanRemoteTransactionSource.d.ts.map +0 -1
- package/dist/EtherscanRemoteTransactionSource.js.map +0 -1
- package/dist/IncomingTransactionHelper.d.ts.map +0 -1
- package/dist/IncomingTransactionHelper.js.map +0 -1
- package/dist/PendingTransactionTracker.d.ts +0 -18
- package/dist/PendingTransactionTracker.d.ts.map +0 -1
- package/dist/PendingTransactionTracker.js +0 -144
- package/dist/PendingTransactionTracker.js.map +0 -1
- package/dist/etherscan.d.ts.map +0 -1
- package/dist/etherscan.js.map +0 -1
- package/dist/external-transactions.d.ts.map +0 -1
- package/dist/external-transactions.js.map +0 -1
- package/dist/history.d.ts.map +0 -1
- package/dist/history.js.map +0 -1
- package/dist/transaction-type.d.ts.map +0 -1
- package/dist/transaction-type.js.map +0 -1
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js.map +0 -1
- package/dist/validation.d.ts.map +0 -1
- package/dist/validation.js.map +0 -1
- /package/dist/{etherscan.d.ts → utils/etherscan.d.ts} +0 -0
- /package/dist/{history.js → utils/history.js} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask/transaction-controller",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "17.0.0",
|
|
4
4
|
"description": "Stores transactions alongside their periodically updated statuses and manages interactions such as approval and cancellation",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"MetaMask",
|
|
@@ -24,22 +24,24 @@
|
|
|
24
24
|
"build:docs": "typedoc",
|
|
25
25
|
"changelog:validate": "../../scripts/validate-changelog.sh @metamask/transaction-controller",
|
|
26
26
|
"publish:preview": "yarn npm publish --tag preview",
|
|
27
|
-
"test": "jest",
|
|
27
|
+
"test": "jest --reporters=jest-silent-reporter",
|
|
28
28
|
"test:clean": "jest --clearCache",
|
|
29
|
+
"test:verbose": "jest --verbose",
|
|
29
30
|
"test:watch": "jest --watch"
|
|
30
31
|
},
|
|
31
32
|
"dependencies": {
|
|
32
33
|
"@ethereumjs/common": "^3.2.0",
|
|
33
34
|
"@ethereumjs/tx": "^4.2.0",
|
|
34
35
|
"@ethersproject/abi": "^5.7.0",
|
|
35
|
-
"@metamask/approval-controller": "^4.0
|
|
36
|
+
"@metamask/approval-controller": "^4.1.0",
|
|
36
37
|
"@metamask/base-controller": "^3.2.3",
|
|
37
38
|
"@metamask/controller-utils": "^5.0.2",
|
|
38
|
-
"@metamask/eth-query": "^
|
|
39
|
+
"@metamask/eth-query": "^4.0.0",
|
|
40
|
+
"@metamask/gas-fee-controller": "^10.0.1",
|
|
39
41
|
"@metamask/metamask-eth-abis": "^3.0.0",
|
|
40
|
-
"@metamask/network-controller": "^
|
|
42
|
+
"@metamask/network-controller": "^16.0.0",
|
|
41
43
|
"@metamask/rpc-errors": "^6.1.0",
|
|
42
|
-
"@metamask/utils": "^8.
|
|
44
|
+
"@metamask/utils": "^8.2.0",
|
|
43
45
|
"async-mutex": "^0.2.6",
|
|
44
46
|
"eth-method-registry": "1.1.0",
|
|
45
47
|
"ethereumjs-util": "^7.0.10",
|
|
@@ -49,7 +51,7 @@
|
|
|
49
51
|
"uuid": "^8.3.2"
|
|
50
52
|
},
|
|
51
53
|
"devDependencies": {
|
|
52
|
-
"@metamask/auto-changelog": "^3.
|
|
54
|
+
"@metamask/auto-changelog": "^3.4.3",
|
|
53
55
|
"@types/jest": "^27.4.1",
|
|
54
56
|
"@types/node": "^16.18.54",
|
|
55
57
|
"babel-runtime": "^6.26.0",
|
|
@@ -63,8 +65,9 @@
|
|
|
63
65
|
"typescript": "~4.8.4"
|
|
64
66
|
},
|
|
65
67
|
"peerDependencies": {
|
|
66
|
-
"@metamask/approval-controller": "^4.0
|
|
67
|
-
"@metamask/
|
|
68
|
+
"@metamask/approval-controller": "^4.1.0",
|
|
69
|
+
"@metamask/gas-fee-controller": "^10.0.1",
|
|
70
|
+
"@metamask/network-controller": "^16.0.0",
|
|
68
71
|
"babel-runtime": "^6.26.0"
|
|
69
72
|
},
|
|
70
73
|
"engines": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EtherscanRemoteTransactionSource.d.ts","sourceRoot":"","sources":["../src/EtherscanRemoteTransactionSource.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAiB3C,OAAO,KAAK,EACV,uBAAuB,EACvB,8BAA8B,EAC9B,eAAe,EAChB,MAAM,SAAS,CAAC;AAGjB;;GAEG;AACH,qBAAa,gCACX,YAAW,uBAAuB;;gBAMtB,EACV,qBAAqB,GACtB,GAAE;QAAE,qBAAqB,CAAC,EAAE,OAAO,CAAA;KAAO;IAK3C,kBAAkB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO;IAIzC,sBAAsB,IAAI,MAAM,EAAE;IAI5B,iBAAiB,CACrB,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,eAAe,EAAE,CAAC;CAkI9B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EtherscanRemoteTransactionSource.js","sourceRoot":"","sources":["../src/EtherscanRemoteTransactionSource.ts"],"names":[],"mappings":"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","sourcesContent":["import { BNToHex } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport { BN } from 'ethereumjs-util';\nimport { v1 as random } from 'uuid';\n\nimport { ETHERSCAN_SUPPORTED_NETWORKS } from './constants';\nimport type {\n EtherscanTokenTransactionMeta,\n EtherscanTransactionMeta,\n EtherscanTransactionMetaBase,\n EtherscanTransactionRequest,\n EtherscanTransactionResponse,\n} from './etherscan';\nimport {\n fetchEtherscanTokenTransactions,\n fetchEtherscanTransactions,\n} from './etherscan';\nimport { incomingTransactionsLogger as log } from './logger';\nimport type {\n RemoteTransactionSource,\n RemoteTransactionSourceRequest,\n TransactionMeta,\n} from './types';\nimport { TransactionStatus } from './types';\n\n/**\n * A RemoteTransactionSource that fetches transaction data from Etherscan.\n */\nexport class EtherscanRemoteTransactionSource\n implements RemoteTransactionSource\n{\n #includeTokenTransfers: boolean;\n\n #isTokenRequestPending: boolean;\n\n constructor({\n includeTokenTransfers,\n }: { includeTokenTransfers?: boolean } = {}) {\n this.#includeTokenTransfers = includeTokenTransfers ?? true;\n this.#isTokenRequestPending = false;\n }\n\n isSupportedNetwork(chainId: Hex): boolean {\n return Object.keys(ETHERSCAN_SUPPORTED_NETWORKS).includes(chainId);\n }\n\n getLastBlockVariations(): string[] {\n return [this.#isTokenRequestPending ? 'token' : 'normal'];\n }\n\n async fetchTransactions(\n request: RemoteTransactionSourceRequest,\n ): Promise<TransactionMeta[]> {\n const etherscanRequest: EtherscanTransactionRequest = {\n ...request,\n chainId: request.currentChainId,\n };\n\n const transactions = this.#isTokenRequestPending\n ? await this.#fetchTokenTransactions(request, etherscanRequest)\n : await this.#fetchNormalTransactions(request, etherscanRequest);\n\n if (this.#includeTokenTransfers) {\n this.#isTokenRequestPending = !this.#isTokenRequestPending;\n }\n\n return transactions;\n }\n\n #fetchNormalTransactions = async (\n request: RemoteTransactionSourceRequest,\n etherscanRequest: EtherscanTransactionRequest,\n ) => {\n const { currentChainId } = request;\n\n const etherscanTransactions = await fetchEtherscanTransactions(\n etherscanRequest,\n );\n\n return this.#getResponseTransactions(etherscanTransactions).map((tx) =>\n this.#normalizeTransaction(tx, currentChainId),\n );\n };\n\n #fetchTokenTransactions = async (\n request: RemoteTransactionSourceRequest,\n etherscanRequest: EtherscanTransactionRequest,\n ) => {\n const { currentChainId } = request;\n\n const etherscanTransactions = await fetchEtherscanTokenTransactions(\n etherscanRequest,\n );\n\n return this.#getResponseTransactions(etherscanTransactions).map((tx) =>\n this.#normalizeTokenTransaction(tx, currentChainId),\n );\n };\n\n #getResponseTransactions<T extends EtherscanTransactionMetaBase>(\n response: EtherscanTransactionResponse<T>,\n ): T[] {\n let result = response.result as T[];\n\n if (response.status === '0') {\n result = [];\n\n if (response.result.length) {\n log('Ignored Etherscan request error', {\n message: response.result,\n type: this.#isTokenRequestPending ? 'token' : 'normal',\n });\n }\n }\n\n return result;\n }\n\n #normalizeTransaction(\n txMeta: EtherscanTransactionMeta,\n currentChainId: Hex,\n ): TransactionMeta {\n const base = this.#normalizeTransactionBase(txMeta, currentChainId);\n\n return {\n ...base,\n txParams: {\n ...base.txParams,\n data: txMeta.input,\n },\n ...(txMeta.isError === '0'\n ? { status: TransactionStatus.confirmed }\n : {\n error: new Error('Transaction failed'),\n status: TransactionStatus.failed,\n }),\n };\n }\n\n #normalizeTokenTransaction(\n txMeta: EtherscanTokenTransactionMeta,\n currentChainId: Hex,\n ): TransactionMeta {\n const base = this.#normalizeTransactionBase(txMeta, currentChainId);\n\n return {\n ...base,\n isTransfer: true,\n transferInformation: {\n contractAddress: txMeta.contractAddress,\n decimals: Number(txMeta.tokenDecimal),\n symbol: txMeta.tokenSymbol,\n },\n };\n }\n\n #normalizeTransactionBase(\n txMeta: EtherscanTransactionMetaBase,\n currentChainId: Hex,\n ): TransactionMeta {\n const time = parseInt(txMeta.timeStamp, 10) * 1000;\n\n return {\n blockNumber: txMeta.blockNumber,\n chainId: currentChainId,\n hash: txMeta.hash,\n id: random({ msecs: time }),\n status: TransactionStatus.confirmed,\n time,\n txParams: {\n chainId: currentChainId,\n from: txMeta.from,\n gas: BNToHex(new BN(txMeta.gas)),\n gasPrice: BNToHex(new BN(txMeta.gasPrice)),\n gasUsed: BNToHex(new BN(txMeta.gasUsed)),\n nonce: BNToHex(new BN(txMeta.nonce)),\n to: txMeta.to,\n value: BNToHex(new BN(txMeta.value)),\n },\n verifiedOnBlockchain: false,\n };\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"IncomingTransactionHelper.d.ts","sourceRoot":"","sources":["../src/IncomingTransactionHelper.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC/E,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAE3C,OAAO,YAAY,MAAM,QAAQ,CAAC;AAGlC,OAAO,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AASxE,qBAAa,yBAAyB;;IACpC,GAAG,EAAE,YAAY,CAAC;gBA4BN,EACV,YAAY,EACZ,iBAAiB,EACjB,0BAA0B,EAC1B,oBAAoB,EACpB,eAAe,EACf,SAAS,EACT,kBAAkB,EAClB,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,GACnB,EAAE;QACD,YAAY,EAAE,YAAY,CAAC;QAC3B,iBAAiB,EAAE,MAAM,MAAM,CAAC;QAChC,0BAA0B,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACzD,oBAAoB,CAAC,EAAE,MAAM,eAAe,EAAE,CAAC;QAC/C,eAAe,EAAE,MAAM,YAAY,CAAC;QACpC,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;QAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,uBAAuB,EAAE,uBAAuB,CAAC;QACjD,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;KAC9B;IA0BD,KAAK;IAaL,IAAI;IAKE,MAAM,CAAC,oBAAoB,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;CAmMxD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"IncomingTransactionHelper.js","sourceRoot":"","sources":["../src/IncomingTransactionHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BlockTracker, NetworkState } from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport EventEmitter from 'events';\n\nimport { incomingTransactionsLogger as log } from './logger';\nimport type { RemoteTransactionSource, TransactionMeta } from './types';\n\nconst RECENT_HISTORY_BLOCK_RANGE = 10;\n\nconst UPDATE_CHECKS: ((txMeta: TransactionMeta) => any)[] = [\n (txMeta) => txMeta.status,\n (txMeta) => txMeta.txParams.gasUsed,\n];\n\nexport class IncomingTransactionHelper {\n hub: EventEmitter;\n\n #blockTracker: BlockTracker;\n\n #getCurrentAccount: () => string;\n\n #getLastFetchedBlockNumbers: () => Record<string, number>;\n\n #getLocalTransactions: () => TransactionMeta[];\n\n #getNetworkState: () => NetworkState;\n\n #isEnabled: () => boolean;\n\n #isRunning: boolean;\n\n #mutex = new Mutex();\n\n #onLatestBlock: (blockNumberHex: Hex) => Promise<void>;\n\n #queryEntireHistory: boolean;\n\n #remoteTransactionSource: RemoteTransactionSource;\n\n #transactionLimit?: number;\n\n #updateTransactions: boolean;\n\n constructor({\n blockTracker,\n getCurrentAccount,\n getLastFetchedBlockNumbers,\n getLocalTransactions,\n getNetworkState,\n isEnabled,\n queryEntireHistory,\n remoteTransactionSource,\n transactionLimit,\n updateTransactions,\n }: {\n blockTracker: BlockTracker;\n getCurrentAccount: () => string;\n getLastFetchedBlockNumbers: () => Record<string, number>;\n getLocalTransactions?: () => TransactionMeta[];\n getNetworkState: () => NetworkState;\n isEnabled?: () => boolean;\n queryEntireHistory?: boolean;\n remoteTransactionSource: RemoteTransactionSource;\n transactionLimit?: number;\n updateTransactions?: boolean;\n }) {\n this.hub = new EventEmitter();\n\n this.#blockTracker = blockTracker;\n this.#getCurrentAccount = getCurrentAccount;\n this.#getLastFetchedBlockNumbers = getLastFetchedBlockNumbers;\n this.#getLocalTransactions = getLocalTransactions || (() => []);\n this.#getNetworkState = getNetworkState;\n this.#isEnabled = isEnabled ?? (() => true);\n this.#isRunning = false;\n this.#queryEntireHistory = queryEntireHistory ?? true;\n this.#remoteTransactionSource = remoteTransactionSource;\n this.#transactionLimit = transactionLimit;\n this.#updateTransactions = updateTransactions ?? false;\n\n // Using a property instead of a method to provide a listener reference\n // with the correct scope that we can remove later if stopped.\n this.#onLatestBlock = async (blockNumberHex: Hex) => {\n try {\n await this.update(blockNumberHex);\n } catch (error) {\n console.error('Error while checking incoming transactions', error);\n }\n };\n }\n\n start() {\n if (this.#isRunning) {\n return;\n }\n\n if (!this.#canStart()) {\n return;\n }\n\n this.#blockTracker.addListener('latest', this.#onLatestBlock);\n this.#isRunning = true;\n }\n\n stop() {\n this.#blockTracker.removeListener('latest', this.#onLatestBlock);\n this.#isRunning = false;\n }\n\n async update(latestBlockNumberHex?: Hex): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n\n log('Checking for incoming transactions');\n\n try {\n if (!this.#canStart()) {\n return;\n }\n\n const latestBlockNumber = parseInt(\n latestBlockNumberHex || (await this.#blockTracker.getLatestBlock()),\n 16,\n );\n\n const additionalLastFetchedKeys =\n this.#remoteTransactionSource.getLastBlockVariations?.() ?? [];\n\n const fromBlock = this.#getFromBlock(\n latestBlockNumber,\n additionalLastFetchedKeys,\n );\n\n const address = this.#getCurrentAccount();\n const currentChainId = this.#getCurrentChainId();\n\n let remoteTransactions = [];\n\n try {\n remoteTransactions =\n await this.#remoteTransactionSource.fetchTransactions({\n address,\n currentChainId,\n fromBlock,\n limit: this.#transactionLimit,\n });\n } catch (error: any) {\n log('Error while fetching remote transactions', error);\n return;\n }\n\n if (!this.#updateTransactions) {\n remoteTransactions = remoteTransactions.filter(\n (tx) => tx.txParams.to?.toLowerCase() === address.toLowerCase(),\n );\n }\n\n const localTransactions = !this.#updateTransactions\n ? []\n : this.#getLocalTransactions();\n\n const newTransactions = this.#getNewTransactions(\n remoteTransactions,\n localTransactions,\n );\n\n const updatedTransactions = this.#getUpdatedTransactions(\n remoteTransactions,\n localTransactions,\n );\n\n if (newTransactions.length > 0 || updatedTransactions.length > 0) {\n this.#sortTransactionsByTime(newTransactions);\n this.#sortTransactionsByTime(updatedTransactions);\n\n log('Found incoming transactions', {\n new: newTransactions,\n updated: updatedTransactions,\n });\n\n this.hub.emit('transactions', {\n added: newTransactions,\n updated: updatedTransactions,\n });\n }\n\n this.#updateLastFetchedBlockNumber(\n remoteTransactions,\n additionalLastFetchedKeys,\n );\n } finally {\n releaseLock();\n }\n }\n\n #sortTransactionsByTime(transactions: TransactionMeta[]) {\n transactions.sort((a, b) => (a.time < b.time ? -1 : 1));\n }\n\n #getNewTransactions(\n remoteTxs: TransactionMeta[],\n localTxs: TransactionMeta[],\n ): TransactionMeta[] {\n return remoteTxs.filter(\n (tx) => !localTxs.some(({ hash }) => hash === tx.hash),\n );\n }\n\n #getUpdatedTransactions(\n remoteTxs: TransactionMeta[],\n localTxs: TransactionMeta[],\n ): TransactionMeta[] {\n return remoteTxs.filter((remoteTx) =>\n localTxs.some(\n (localTx) =>\n remoteTx.hash === localTx.hash &&\n this.#isTransactionOutdated(remoteTx, localTx),\n ),\n );\n }\n\n #isTransactionOutdated(\n remoteTx: TransactionMeta,\n localTx: TransactionMeta,\n ): boolean {\n return UPDATE_CHECKS.some(\n (getValue) => getValue(remoteTx) !== getValue(localTx),\n );\n }\n\n #getFromBlock(\n latestBlockNumber: number,\n additionalKeys: string[],\n ): number | undefined {\n const lastFetchedKey = this.#getBlockNumberKey(additionalKeys);\n\n const lastFetchedBlockNumber =\n this.#getLastFetchedBlockNumbers()[lastFetchedKey];\n\n if (lastFetchedBlockNumber) {\n return lastFetchedBlockNumber + 1;\n }\n\n return this.#queryEntireHistory\n ? undefined\n : latestBlockNumber - RECENT_HISTORY_BLOCK_RANGE;\n }\n\n #updateLastFetchedBlockNumber(\n remoteTxs: TransactionMeta[],\n additionalKeys: string[],\n ) {\n let lastFetchedBlockNumber = -1;\n\n for (const tx of remoteTxs) {\n const currentBlockNumberValue = tx.blockNumber\n ? parseInt(tx.blockNumber, 10)\n : -1;\n\n lastFetchedBlockNumber = Math.max(\n lastFetchedBlockNumber,\n currentBlockNumberValue,\n );\n }\n\n if (lastFetchedBlockNumber === -1) {\n return;\n }\n\n const lastFetchedKey = this.#getBlockNumberKey(additionalKeys);\n const lastFetchedBlockNumbers = this.#getLastFetchedBlockNumbers();\n const previousValue = lastFetchedBlockNumbers[lastFetchedKey];\n\n if (previousValue >= lastFetchedBlockNumber) {\n return;\n }\n\n lastFetchedBlockNumbers[lastFetchedKey] = lastFetchedBlockNumber;\n\n this.hub.emit('updatedLastFetchedBlockNumbers', {\n lastFetchedBlockNumbers,\n blockNumber: lastFetchedBlockNumber,\n });\n }\n\n #getBlockNumberKey(additionalKeys: string[]): string {\n const currentChainId = this.#getCurrentChainId();\n const currentAccount = this.#getCurrentAccount().toLowerCase();\n\n return [currentChainId, currentAccount, ...additionalKeys].join('#');\n }\n\n #canStart(): boolean {\n const isEnabled = this.#isEnabled();\n const currentChainId = this.#getCurrentChainId();\n\n const isSupportedNetwork =\n this.#remoteTransactionSource.isSupportedNetwork(currentChainId);\n\n return isEnabled && isSupportedNetwork;\n }\n\n #getCurrentChainId(): Hex {\n return this.#getNetworkState().providerConfig.chainId;\n }\n}\n"]}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import type EthQuery from '@metamask/eth-query';
|
|
3
|
-
import type { BlockTracker } from '@metamask/network-controller';
|
|
4
|
-
import EventEmitter from 'events';
|
|
5
|
-
import type { TransactionMeta } from './types';
|
|
6
|
-
export declare class PendingTransactionTracker {
|
|
7
|
-
#private;
|
|
8
|
-
hub: EventEmitter;
|
|
9
|
-
constructor({ blockTracker, failTransaction, getChainId, getEthQuery, getTransactions, }: {
|
|
10
|
-
blockTracker: BlockTracker;
|
|
11
|
-
failTransaction: (txMeta: TransactionMeta, error: Error) => void;
|
|
12
|
-
getChainId: () => string;
|
|
13
|
-
getEthQuery: () => EthQuery;
|
|
14
|
-
getTransactions: () => TransactionMeta[];
|
|
15
|
-
});
|
|
16
|
-
start(): void;
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=PendingTransactionTracker.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PendingTransactionTracker.d.ts","sourceRoot":"","sources":["../src/PendingTransactionTracker.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,YAAY,MAAM,QAAQ,CAAC;AAGlC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAG/C,qBAAa,yBAAyB;;IACpC,GAAG,EAAE,YAAY,CAAC;gBAYN,EACV,YAAY,EACZ,eAAe,EACf,UAAU,EACV,WAAW,EACX,eAAe,GAChB,EAAE;QACD,YAAY,EAAE,YAAY,CAAC;QAC3B,eAAe,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;QACjE,UAAU,EAAE,MAAM,MAAM,CAAC;QACzB,WAAW,EAAE,MAAM,QAAQ,CAAC;QAC5B,eAAe,EAAE,MAAM,eAAe,EAAE,CAAC;KAC1C;IAUD,KAAK;CA4JN"}
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
12
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
13
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
14
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
15
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
16
|
-
};
|
|
17
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
18
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
19
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
20
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
21
|
-
};
|
|
22
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
|
-
};
|
|
25
|
-
var _PendingTransactionTracker_instances, _PendingTransactionTracker_blockTracker, _PendingTransactionTracker_failTransaction, _PendingTransactionTracker_getChainId, _PendingTransactionTracker_getEthQuery, _PendingTransactionTracker_getTransactions, _PendingTransactionTracker_onLatestBlock, _PendingTransactionTracker_blockchainTransactionStateReconciler, _PendingTransactionTracker_checkTxReceiptStatusIsFailed;
|
|
26
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
-
exports.PendingTransactionTracker = void 0;
|
|
28
|
-
const controller_utils_1 = require("@metamask/controller-utils");
|
|
29
|
-
const events_1 = __importDefault(require("events"));
|
|
30
|
-
const logger_1 = require("./logger");
|
|
31
|
-
const types_1 = require("./types");
|
|
32
|
-
class PendingTransactionTracker {
|
|
33
|
-
constructor({ blockTracker, failTransaction, getChainId, getEthQuery, getTransactions, }) {
|
|
34
|
-
_PendingTransactionTracker_instances.add(this);
|
|
35
|
-
_PendingTransactionTracker_blockTracker.set(this, void 0);
|
|
36
|
-
_PendingTransactionTracker_failTransaction.set(this, void 0);
|
|
37
|
-
_PendingTransactionTracker_getChainId.set(this, void 0);
|
|
38
|
-
_PendingTransactionTracker_getEthQuery.set(this, void 0);
|
|
39
|
-
_PendingTransactionTracker_getTransactions.set(this, void 0);
|
|
40
|
-
this.hub = new events_1.default();
|
|
41
|
-
__classPrivateFieldSet(this, _PendingTransactionTracker_blockTracker, blockTracker, "f");
|
|
42
|
-
__classPrivateFieldSet(this, _PendingTransactionTracker_failTransaction, failTransaction, "f");
|
|
43
|
-
__classPrivateFieldSet(this, _PendingTransactionTracker_getChainId, getChainId, "f");
|
|
44
|
-
__classPrivateFieldSet(this, _PendingTransactionTracker_getEthQuery, getEthQuery, "f");
|
|
45
|
-
__classPrivateFieldSet(this, _PendingTransactionTracker_getTransactions, getTransactions, "f");
|
|
46
|
-
}
|
|
47
|
-
start() {
|
|
48
|
-
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
49
|
-
__classPrivateFieldGet(this, _PendingTransactionTracker_blockTracker, "f").addListener('latest', () => __awaiter(this, void 0, void 0, function* () {
|
|
50
|
-
yield (0, controller_utils_1.safelyExecute)(() => __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_onLatestBlock).call(this));
|
|
51
|
-
}));
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
exports.PendingTransactionTracker = PendingTransactionTracker;
|
|
55
|
-
_PendingTransactionTracker_blockTracker = new WeakMap(), _PendingTransactionTracker_failTransaction = new WeakMap(), _PendingTransactionTracker_getChainId = new WeakMap(), _PendingTransactionTracker_getEthQuery = new WeakMap(), _PendingTransactionTracker_getTransactions = new WeakMap(), _PendingTransactionTracker_instances = new WeakSet(), _PendingTransactionTracker_onLatestBlock = function _PendingTransactionTracker_onLatestBlock() {
|
|
56
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
57
|
-
(0, logger_1.pendingTransactionsLogger)('Checking transactions');
|
|
58
|
-
const transactions = __classPrivateFieldGet(this, _PendingTransactionTracker_getTransactions, "f").call(this);
|
|
59
|
-
const currentChainId = __classPrivateFieldGet(this, _PendingTransactionTracker_getChainId, "f").call(this);
|
|
60
|
-
let gotUpdates = false;
|
|
61
|
-
yield (0, controller_utils_1.safelyExecute)(() => Promise.all(transactions.map((meta, index) => __awaiter(this, void 0, void 0, function* () {
|
|
62
|
-
if (!meta.verifiedOnBlockchain && meta.chainId === currentChainId) {
|
|
63
|
-
const [reconciledTx, updateRequired] = yield __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_blockchainTransactionStateReconciler).call(this, meta);
|
|
64
|
-
if (updateRequired) {
|
|
65
|
-
transactions[index] = reconciledTx;
|
|
66
|
-
gotUpdates = updateRequired;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}))));
|
|
70
|
-
/* istanbul ignore else */
|
|
71
|
-
if (gotUpdates) {
|
|
72
|
-
this.hub.emit('transactions', transactions);
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
}, _PendingTransactionTracker_blockchainTransactionStateReconciler = function _PendingTransactionTracker_blockchainTransactionStateReconciler(meta) {
|
|
76
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
77
|
-
const { status, hash, id, chainId, txParams: { to }, } = meta;
|
|
78
|
-
switch (status) {
|
|
79
|
-
case types_1.TransactionStatus.confirmed:
|
|
80
|
-
(0, logger_1.pendingTransactionsLogger)('Checking confirmed transaction', {
|
|
81
|
-
id,
|
|
82
|
-
chainId,
|
|
83
|
-
to,
|
|
84
|
-
});
|
|
85
|
-
const txReceipt = yield (0, controller_utils_1.query)(__classPrivateFieldGet(this, _PendingTransactionTracker_getEthQuery, "f").call(this), 'getTransactionReceipt', [hash]);
|
|
86
|
-
if (!txReceipt) {
|
|
87
|
-
return [meta, false];
|
|
88
|
-
}
|
|
89
|
-
const txBlock = yield (0, controller_utils_1.query)(__classPrivateFieldGet(this, _PendingTransactionTracker_getEthQuery, "f").call(this), 'getBlockByHash', [
|
|
90
|
-
txReceipt.blockHash,
|
|
91
|
-
]);
|
|
92
|
-
meta.verifiedOnBlockchain = true;
|
|
93
|
-
meta.txParams.gasUsed = txReceipt.gasUsed;
|
|
94
|
-
meta.txReceipt = txReceipt;
|
|
95
|
-
meta.baseFeePerGas = txBlock === null || txBlock === void 0 ? void 0 : txBlock.baseFeePerGas;
|
|
96
|
-
meta.blockTimestamp = txBlock === null || txBlock === void 0 ? void 0 : txBlock.timestamp;
|
|
97
|
-
// According to the Web3 docs:
|
|
98
|
-
// TRUE if the transaction was successful, FALSE if the EVM reverted the transaction.
|
|
99
|
-
if (Number(txReceipt.status) === 0) {
|
|
100
|
-
const error = new Error('Transaction failed. The transaction was reversed');
|
|
101
|
-
__classPrivateFieldGet(this, _PendingTransactionTracker_failTransaction, "f").call(this, meta, error);
|
|
102
|
-
return [meta, false];
|
|
103
|
-
}
|
|
104
|
-
return [meta, true];
|
|
105
|
-
case types_1.TransactionStatus.submitted:
|
|
106
|
-
(0, logger_1.pendingTransactionsLogger)('Checking submitted transaction', {
|
|
107
|
-
id,
|
|
108
|
-
chainId,
|
|
109
|
-
to,
|
|
110
|
-
});
|
|
111
|
-
const txObj = yield (0, controller_utils_1.query)(__classPrivateFieldGet(this, _PendingTransactionTracker_getEthQuery, "f").call(this), 'getTransactionByHash', [
|
|
112
|
-
hash,
|
|
113
|
-
]);
|
|
114
|
-
if (!txObj) {
|
|
115
|
-
const receiptShowsFailedStatus = yield __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_checkTxReceiptStatusIsFailed).call(this, hash);
|
|
116
|
-
// Case the txObj is evaluated as false, a second check will
|
|
117
|
-
// determine if the tx failed or it is pending or confirmed
|
|
118
|
-
if (receiptShowsFailedStatus) {
|
|
119
|
-
const error = new Error('Transaction failed. The transaction was dropped or replaced by a new one');
|
|
120
|
-
__classPrivateFieldGet(this, _PendingTransactionTracker_failTransaction, "f").call(this, meta, error);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
/* istanbul ignore next */
|
|
124
|
-
if (txObj === null || txObj === void 0 ? void 0 : txObj.blockNumber) {
|
|
125
|
-
meta.status = types_1.TransactionStatus.confirmed;
|
|
126
|
-
this.hub.emit('transaction-confirmed', meta);
|
|
127
|
-
return [meta, true];
|
|
128
|
-
}
|
|
129
|
-
return [meta, false];
|
|
130
|
-
default:
|
|
131
|
-
return [meta, false];
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
}, _PendingTransactionTracker_checkTxReceiptStatusIsFailed = function _PendingTransactionTracker_checkTxReceiptStatusIsFailed(txHash) {
|
|
135
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
136
|
-
const txReceipt = yield (0, controller_utils_1.query)(__classPrivateFieldGet(this, _PendingTransactionTracker_getEthQuery, "f").call(this), 'getTransactionReceipt', [txHash]);
|
|
137
|
-
if (!txReceipt) {
|
|
138
|
-
// Transaction is pending
|
|
139
|
-
return false;
|
|
140
|
-
}
|
|
141
|
-
return Number(txReceipt.status) === 0;
|
|
142
|
-
});
|
|
143
|
-
};
|
|
144
|
-
//# sourceMappingURL=PendingTransactionTracker.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PendingTransactionTracker.js","sourceRoot":"","sources":["../src/PendingTransactionTracker.ts"],"names":[],"mappings":"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","sourcesContent":["import { query, safelyExecute } from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport type { BlockTracker } from '@metamask/network-controller';\nimport EventEmitter from 'events';\n\nimport { pendingTransactionsLogger as log } from './logger';\nimport type { TransactionMeta } from './types';\nimport { TransactionStatus } from './types';\n\nexport class PendingTransactionTracker {\n hub: EventEmitter;\n\n #blockTracker: BlockTracker;\n\n #failTransaction: (txMeta: TransactionMeta, error: Error) => void;\n\n #getChainId: () => string;\n\n #getEthQuery: () => EthQuery;\n\n #getTransactions: () => TransactionMeta[];\n\n constructor({\n blockTracker,\n failTransaction,\n getChainId,\n getEthQuery,\n getTransactions,\n }: {\n blockTracker: BlockTracker;\n failTransaction: (txMeta: TransactionMeta, error: Error) => void;\n getChainId: () => string;\n getEthQuery: () => EthQuery;\n getTransactions: () => TransactionMeta[];\n }) {\n this.hub = new EventEmitter();\n\n this.#blockTracker = blockTracker;\n this.#failTransaction = failTransaction;\n this.#getChainId = getChainId;\n this.#getEthQuery = getEthQuery;\n this.#getTransactions = getTransactions;\n }\n\n start() {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#blockTracker.addListener('latest', async () => {\n await safelyExecute(() => this.#onLatestBlock());\n });\n }\n\n /**\n * Check the status of submitted transactions on the network to determine whether they have\n * been included in a block. Any that have been included in a block are marked as confirmed.\n */\n async #onLatestBlock() {\n log('Checking transactions');\n\n const transactions = this.#getTransactions();\n const currentChainId = this.#getChainId();\n let gotUpdates = false;\n\n await safelyExecute(() =>\n Promise.all(\n transactions.map(async (meta, index) => {\n if (!meta.verifiedOnBlockchain && meta.chainId === currentChainId) {\n const [reconciledTx, updateRequired] =\n await this.#blockchainTransactionStateReconciler(meta);\n if (updateRequired) {\n transactions[index] = reconciledTx;\n gotUpdates = updateRequired;\n }\n }\n }),\n ),\n );\n\n /* istanbul ignore else */\n if (gotUpdates) {\n this.hub.emit('transactions', transactions);\n }\n }\n\n /**\n * Method to verify the state of a transaction using the Blockchain as a source of truth.\n *\n * @param meta - The local transaction to verify on the blockchain.\n * @returns A tuple containing the updated transaction, and whether or not an update was required.\n */\n async #blockchainTransactionStateReconciler(\n meta: TransactionMeta,\n ): Promise<[TransactionMeta, boolean]> {\n const {\n status,\n hash,\n id,\n chainId,\n txParams: { to },\n } = meta;\n\n switch (status) {\n case TransactionStatus.confirmed:\n log('Checking confirmed transaction', {\n id,\n chainId,\n to,\n });\n\n const txReceipt = await query(\n this.#getEthQuery(),\n 'getTransactionReceipt',\n [hash],\n );\n\n if (!txReceipt) {\n return [meta, false];\n }\n\n const txBlock = await query(this.#getEthQuery(), 'getBlockByHash', [\n txReceipt.blockHash,\n ]);\n\n meta.verifiedOnBlockchain = true;\n meta.txParams.gasUsed = txReceipt.gasUsed;\n meta.txReceipt = txReceipt;\n meta.baseFeePerGas = txBlock?.baseFeePerGas;\n meta.blockTimestamp = txBlock?.timestamp;\n\n // According to the Web3 docs:\n // TRUE if the transaction was successful, FALSE if the EVM reverted the transaction.\n if (Number(txReceipt.status) === 0) {\n const error: Error = new Error(\n 'Transaction failed. The transaction was reversed',\n );\n this.#failTransaction(meta, error);\n return [meta, false];\n }\n\n return [meta, true];\n case TransactionStatus.submitted:\n log('Checking submitted transaction', {\n id,\n chainId,\n to,\n });\n\n const txObj = await query(this.#getEthQuery(), 'getTransactionByHash', [\n hash,\n ]);\n\n if (!txObj) {\n const receiptShowsFailedStatus =\n await this.#checkTxReceiptStatusIsFailed(hash);\n\n // Case the txObj is evaluated as false, a second check will\n // determine if the tx failed or it is pending or confirmed\n if (receiptShowsFailedStatus) {\n const error: Error = new Error(\n 'Transaction failed. The transaction was dropped or replaced by a new one',\n );\n this.#failTransaction(meta, error);\n }\n }\n\n /* istanbul ignore next */\n if (txObj?.blockNumber) {\n meta.status = TransactionStatus.confirmed;\n this.hub.emit('transaction-confirmed', meta);\n return [meta, true];\n }\n\n return [meta, false];\n default:\n return [meta, false];\n }\n }\n\n /**\n * Method to check if a tx has failed according to their receipt\n * According to the Web3 docs:\n * TRUE if the transaction was successful, FALSE if the EVM reverted the transaction.\n * The receipt is not available for pending transactions and returns null.\n *\n * @param txHash - The transaction hash.\n * @returns Whether the transaction has failed.\n */\n async #checkTxReceiptStatusIsFailed(\n txHash: string | undefined,\n ): Promise<boolean> {\n const txReceipt = await query(\n this.#getEthQuery(),\n 'getTransactionReceipt',\n [txHash],\n );\n if (!txReceipt) {\n // Transaction is pending\n return false;\n }\n return Number(txReceipt.status) === 0;\n }\n}\n"]}
|
package/dist/etherscan.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"etherscan.d.ts","sourceRoot":"","sources":["../src/etherscan.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAK3C,MAAM,WAAW,4BAA4B;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,wBAAyB,SAAQ,4BAA4B;IAC5E,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,6BACf,SAAQ,4BAA4B;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,4BAA4B,CAC3C,CAAC,SAAS,4BAA4B;IAEtC,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,GAAG,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;GASG;AACH,wBAAsB,0BAA0B,CAAC,EAC/C,OAAO,EACP,OAAO,EACP,SAAS,EACT,KAAK,GACN,EAAE,2BAA2B,GAAG,OAAO,CACtC,4BAA4B,CAAC,wBAAwB,CAAC,CACvD,CAOA;AAED;;;;;;;;;GASG;AACH,wBAAsB,+BAA+B,CAAC,EACpD,OAAO,EACP,OAAO,EACP,SAAS,EACT,KAAK,GACN,EAAE,2BAA2B,GAAG,OAAO,CACtC,4BAA4B,CAAC,6BAA6B,CAAC,CAC5D,CAOA"}
|
package/dist/etherscan.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"etherscan.js","sourceRoot":"","sources":["../src/etherscan.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,iEAAyD;AAGzD,2CAA2D;AAC3D,qCAA6D;AAkD7D;;;;;;;;;GASG;AACH,SAAsB,0BAA0B,CAAC,EAC/C,OAAO,EACP,OAAO,EACP,SAAS,EACT,KAAK,GACuB;;QAG5B,OAAO,MAAM,iBAAiB,CAAC,QAAQ,EAAE;YACvC,OAAO;YACP,OAAO;YACP,SAAS;YACT,KAAK;SACN,CAAC,CAAC;IACL,CAAC;CAAA;AAdD,gEAcC;AAED;;;;;;;;;GASG;AACH,SAAsB,+BAA+B,CAAC,EACpD,OAAO,EACP,OAAO,EACP,SAAS,EACT,KAAK,GACuB;;QAG5B,OAAO,MAAM,iBAAiB,CAAC,SAAS,EAAE;YACxC,OAAO;YACP,OAAO;YACP,SAAS;YACT,KAAK;SACN,CAAC,CAAC;IACL,CAAC;CAAA;AAdD,0EAcC;AAED;;;;;;;;;;GAUG;AACH,SAAe,iBAAiB,CAC9B,MAAc,EACd,EACE,OAAO,EACP,OAAO,EACP,SAAS,EACT,KAAK,GAMN;;QAED,MAAM,SAAS,GAAG;YAChB,MAAM,EAAE,SAAS;YACjB,OAAO;YACP,UAAU,EAAE,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,QAAQ,EAAE;YACjC,MAAM,EAAE,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,QAAQ,EAAE;YACzB,IAAI,EAAE,MAAM;SACb,CAAC;QAEF,MAAM,cAAc,GAAG,kBAAkB,CAAC,OAAO,kCAC5C,SAAS,KACZ,MAAM,IACN,CAAC;QAEH,IAAA,mCAAG,EAAC,2BAA2B,EAAE,cAAc,CAAC,CAAC;QAEjD,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAA,8BAAW,EACjC,cAAc,CACf,CAAoC,CAAC;QAEtC,OAAO,QAAQ,CAAC;IAClB,CAAC;CAAA;AAED;;;;;;GAMG;AACH,SAAS,kBAAkB,CACzB,OAAY,EACZ,SAA6C;IAI7C,MAAM,WAAW,GAAG,wCAA4B,CAAC,OAA2B,CAAC,CAAC;IAE9E,IAAI,CAAC,WAAW,EAAE;QAChB,MAAM,IAAI,KAAK,CAAC,6CAA6C,OAAO,EAAE,CAAC,CAAC;KACzE;IAED,MAAM,MAAM,GAAG,WAAW,WAAW,CAAC,SAAS,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;IACxE,IAAI,GAAG,GAAG,GAAG,MAAM,OAAO,CAAC;IAE3B,wCAAwC;IACxC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE;QAChC,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;QAElC,IAAI,CAAC,KAAK,EAAE;YACV,SAAS;SACV;QAED,GAAG,IAAI,GAAG,QAAQ,IAAI,KAAK,GAAG,CAAC;KAChC;IAED,GAAG,IAAI,mBAAmB,CAAC;IAE3B,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["import { handleFetch } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\n\nimport { ETHERSCAN_SUPPORTED_NETWORKS } from './constants';\nimport { incomingTransactionsLogger as log } from './logger';\n\nexport interface EtherscanTransactionMetaBase {\n blockNumber: string;\n blockHash: string;\n confirmations: string;\n contractAddress: string;\n cumulativeGasUsed: string;\n from: string;\n gas: string;\n gasPrice: string;\n gasUsed: string;\n hash: string;\n nonce: string;\n timeStamp: string;\n to: string;\n transactionIndex: string;\n value: string;\n}\n\nexport interface EtherscanTransactionMeta extends EtherscanTransactionMetaBase {\n functionName: string;\n input: string;\n isError: string;\n methodId: string;\n txreceipt_status: string;\n}\n\nexport interface EtherscanTokenTransactionMeta\n extends EtherscanTransactionMetaBase {\n tokenDecimal: string;\n tokenName: string;\n tokenSymbol: string;\n}\n\nexport interface EtherscanTransactionResponse<\n T extends EtherscanTransactionMetaBase,\n> {\n status: '0' | '1';\n message?: string;\n result: string | T[];\n}\n\nexport interface EtherscanTransactionRequest {\n address: string;\n chainId: Hex;\n fromBlock?: number;\n limit?: number;\n}\n\n/**\n * Retrieves transaction data from Etherscan.\n *\n * @param request - Configuration required to fetch transactions.\n * @param request.address - Address to retrieve transactions for.\n * @param request.chainId - Current chain ID used to determine subdomain and domain.\n * @param request.fromBlock - Block number to start fetching transactions from.\n * @param request.limit - Number of transactions to retrieve.\n * @returns An Etherscan response object containing the request status and an array of token transaction data.\n */\nexport async function fetchEtherscanTransactions({\n address,\n chainId,\n fromBlock,\n limit,\n}: EtherscanTransactionRequest): Promise<\n EtherscanTransactionResponse<EtherscanTransactionMeta>\n> {\n return await fetchTransactions('txlist', {\n address,\n chainId,\n fromBlock,\n limit,\n });\n}\n\n/**\n * Retrieves token transaction data from Etherscan.\n *\n * @param request - Configuration required to fetch token transactions.\n * @param request.address - Address to retrieve token transactions for.\n * @param request.chainId - Current chain ID used to determine subdomain and domain.\n * @param request.fromBlock - Block number to start fetching token transactions from.\n * @param request.limit - Number of token transactions to retrieve.\n * @returns An Etherscan response object containing the request status and an array of token transaction data.\n */\nexport async function fetchEtherscanTokenTransactions({\n address,\n chainId,\n fromBlock,\n limit,\n}: EtherscanTransactionRequest): Promise<\n EtherscanTransactionResponse<EtherscanTokenTransactionMeta>\n> {\n return await fetchTransactions('tokentx', {\n address,\n chainId,\n fromBlock,\n limit,\n });\n}\n\n/**\n * Retrieves transaction data from Etherscan from a specific endpoint.\n *\n * @param action - The Etherscan endpoint to use.\n * @param options - Options bag.\n * @param options.address - Address to retrieve transactions for.\n * @param options.chainId - Current chain ID used to determine subdomain and domain.\n * @param options.fromBlock - Block number to start fetching transactions from.\n * @param options.limit - Number of transactions to retrieve.\n * @returns An object containing the request status and an array of transaction data.\n */\nasync function fetchTransactions<T extends EtherscanTransactionMetaBase>(\n action: string,\n {\n address,\n chainId,\n fromBlock,\n limit,\n }: {\n address: string;\n chainId: Hex;\n fromBlock?: number;\n limit?: number;\n },\n): Promise<EtherscanTransactionResponse<T>> {\n const urlParams = {\n module: 'account',\n address,\n startBlock: fromBlock?.toString(),\n offset: limit?.toString(),\n sort: 'desc',\n };\n\n const etherscanTxUrl = getEtherscanApiUrl(chainId, {\n ...urlParams,\n action,\n });\n\n log('Sending Etherscan request', etherscanTxUrl);\n\n const response = (await handleFetch(\n etherscanTxUrl,\n )) as EtherscanTransactionResponse<T>;\n\n return response;\n}\n\n/**\n * Return a URL that can be used to fetch data from Etherscan.\n *\n * @param chainId - Current chain ID used to determine subdomain and domain.\n * @param urlParams - The parameters used to construct the URL.\n * @returns URL to access Etherscan data.\n */\nfunction getEtherscanApiUrl(\n chainId: Hex,\n urlParams: Record<string, string | undefined>,\n): string {\n type SupportedChainId = keyof typeof ETHERSCAN_SUPPORTED_NETWORKS;\n\n const networkInfo = ETHERSCAN_SUPPORTED_NETWORKS[chainId as SupportedChainId];\n\n if (!networkInfo) {\n throw new Error(`Etherscan does not support chain with ID: ${chainId}`);\n }\n\n const apiUrl = `https://${networkInfo.subdomain}.${networkInfo.domain}`;\n let url = `${apiUrl}/api?`;\n\n // eslint-disable-next-line guard-for-in\n for (const paramKey in urlParams) {\n const value = urlParams[paramKey];\n\n if (!value) {\n continue;\n }\n\n url += `${paramKey}=${value}&`;\n }\n\n url += 'tag=latest&page=1';\n\n return url;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"external-transactions.d.ts","sourceRoot":"","sources":["../src/external-transactions.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C;;;;;;GAMG;AACH,wBAAgB,oCAAoC,CAClD,eAAe,CAAC,EAAE,eAAe,EACjC,YAAY,CAAC,EAAE,eAAe,EAAE,EAChC,UAAU,CAAC,EAAE,eAAe,EAAE,QAoC/B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"external-transactions.js","sourceRoot":"","sources":["../src/external-transactions.ts"],"names":[],"mappings":";;;AAAA,oGAAoG;AACpG,qDAAiD;AAEjD,mCAA4C;AAG5C;;;;;;GAMG;AACH,SAAgB,oCAAoC,CAClD,eAAiC,EACjC,YAAgC,EAChC,UAA8B;IAE9B,IAAI,CAAC,eAAe,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE;QACjD,MAAM,sBAAS,CAAC,aAAa,CAC3B,4DAA4D,CAC7D,CAAC;KACH;IAED,IAAI,eAAe,CAAC,MAAM,KAAK,yBAAiB,CAAC,SAAS,EAAE;QAC1D,MAAM,sBAAS,CAAC,aAAa,CAC3B,mDAAmD,CACpD,CAAC;KACH;IAED,MAAM,eAAe,GAAG,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC;IACvD,IAAI,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;QACvC,MAAM,qBAAqB,GAAG,UAAU,CAAC,IAAI,CAC3C,CAAC,EAAE,EAAE,EAAE,WAAC,OAAA,CAAA,MAAA,EAAE,CAAC,QAAQ,0CAAE,KAAK,MAAK,eAAe,CAAA,EAAA,CAC/C,CAAC;QACF,IAAI,qBAAqB,EAAE;YACzB,MAAM,sBAAS,CAAC,aAAa,CAC3B,yDAAyD,CAC1D,CAAC;SACH;KACF;IAED,IAAI,YAAY,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE;QAC3C,MAAM,uBAAuB,GAAG,YAAY,CAAC,IAAI,CAC/C,CAAC,EAAE,EAAE,EAAE,WAAC,OAAA,CAAA,MAAA,EAAE,CAAC,QAAQ,0CAAE,KAAK,MAAK,eAAe,CAAA,EAAA,CAC/C,CAAC;QACF,IAAI,uBAAuB,EAAE;YAC3B,MAAM,sBAAS,CAAC,aAAa,CAC3B,2DAA2D,CAC5D,CAAC;SACH;KACF;AACH,CAAC;AAvCD,oFAuCC","sourcesContent":["// These utility functions are exclusively used by `confirmExternalTransaction` method in controller\nimport { rpcErrors } from '@metamask/rpc-errors';\n\nimport { TransactionStatus } from './types';\nimport type { TransactionMeta } from './types';\n\n/**\n * Validates the external provided transaction meta.\n *\n * @param transactionMeta - The transaction meta to validate.\n * @param confirmedTxs - The confirmed transactions in controller state.\n * @param pendingTxs - The submitted transactions in controller state.\n */\nexport function validateConfirmedExternalTransaction(\n transactionMeta?: TransactionMeta,\n confirmedTxs?: TransactionMeta[],\n pendingTxs?: TransactionMeta[],\n) {\n if (!transactionMeta || !transactionMeta.txParams) {\n throw rpcErrors.invalidParams(\n '\"transactionMeta\" or \"transactionMeta.txParams\" is missing',\n );\n }\n\n if (transactionMeta.status !== TransactionStatus.confirmed) {\n throw rpcErrors.invalidParams(\n 'External transaction status should be \"confirmed\"',\n );\n }\n\n const externalTxNonce = transactionMeta.txParams.nonce;\n if (pendingTxs && pendingTxs.length > 0) {\n const foundPendingTxByNonce = pendingTxs.find(\n (tx) => tx.txParams?.nonce === externalTxNonce,\n );\n if (foundPendingTxByNonce) {\n throw rpcErrors.invalidParams(\n 'External transaction nonce should not be in pending txs',\n );\n }\n }\n\n if (confirmedTxs && confirmedTxs.length > 0) {\n const foundConfirmedTxByNonce = confirmedTxs.find(\n (tx) => tx.txParams?.nonce === externalTxNonce,\n );\n if (foundConfirmedTxByNonce) {\n throw rpcErrors.invalidParams(\n 'External transaction nonce should not be in confirmed txs',\n );\n }\n }\n}\n"]}
|
package/dist/history.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../src/history.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAGV,eAAe,EAChB,MAAM,SAAS,CAAC;AAEjB;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,eAAe,EAAE,eAAe,QAGzE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,eAAe,EAAE,eAAe,EAChC,IAAI,EAAE,MAAM,GACX,IAAI,CAWN"}
|
package/dist/history.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"history.js","sourceRoot":"","sources":["../src/history.ts"],"names":[],"mappings":";;;;;;AAAA,sEAAyC;AACzC,mCAAmC;AAQnC;;;;GAIG;AACH,SAAgB,yBAAyB,CAAC,eAAgC;IACxE,MAAM,QAAQ,GAAG,2BAA2B,CAAC,eAAe,CAAC,CAAC;IAC9D,eAAe,CAAC,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAC;AACvC,CAAC;AAHD,8DAGC;AAED;;;;;GAKG;AACH,SAAgB,wBAAwB,CACtC,eAAgC,EAChC,IAAY;;IAEZ,MAAM,YAAY,GAAG,2BAA2B,CAAC,eAAe,CAAC,CAAC;IAClE,MAAM,aAAa,GAAG,aAAa,CACjC,eAAe,CAAC,OAA6B,CAC9C,CAAC;IAEF,MAAM,YAAY,GAAG,oBAAoB,CAAC,aAAa,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;IAE7E,IAAI,YAAY,CAAC,MAAM,EAAE;QACvB,MAAA,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,OAAO,0CAAE,IAAI,CAAC,YAAY,CAAC,CAAC;KAC9C;AACH,CAAC;AAdD,4DAcC;AAED;;;;;;;GAOG;AACH,SAAS,oBAAoB,CAC3B,aAAkB,EAClB,YAA6B,EAC7B,IAAY;IAEZ,MAAM,sBAAsB,GAAG,yBAAU,CAAC,OAAO,CAC/C,aAAa,EACb,YAAY,CACc,CAAC;IAC7B,kFAAkF;IAClF,IAAI,sBAAsB,CAAC,CAAC,CAAC,EAAE;QAC7B,IAAI,IAAI,EAAE;YACR,sBAAsB,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC;SACvC;QACD,sBAAsB,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;KAClD;IACD,OAAO,sBAAsB,CAAC;AAChC,CAAC;AAED;;;;;GAKG;AACH,SAAS,aAAa,CACpB,kBAAsC;IAEtC,MAAM,YAAY,GAAG,IAAA,kBAAS,EAAC,kBAAkB,CAAC,CAAC;IACnD,OAAO,YAAY,CAAC,MAAM,CACxB,CAAC,GAAG,EAAE,KAAU,EAAE,EAAE,CAAC,yBAAU,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,WAAW,CAChD,CAAC;AACvB,CAAC;AAED;;;;;GAKG;AACH,SAAS,2BAA2B,CAClC,eAAgC;IAEhC,MAAM,QAAQ,qBAAQ,eAAe,CAAE,CAAC;IACxC,OAAO,QAAQ,CAAC,OAAO,CAAC;IACxB,OAAO,IAAA,kBAAS,EAAC,QAAQ,CAAC,CAAC;AAC7B,CAAC","sourcesContent":["import jsonDiffer from 'fast-json-patch';\nimport { cloneDeep } from 'lodash';\n\nimport type {\n TransactionHistory,\n TransactionHistoryEntry,\n TransactionMeta,\n} from './types';\n\n/**\n * Add initial history snapshot to the provided transactionMeta history.\n *\n * @param transactionMeta - TransactionMeta to add initial history snapshot to.\n */\nexport function addInitialHistorySnapshot(transactionMeta: TransactionMeta) {\n const snapshot = snapshotFromTransactionMeta(transactionMeta);\n transactionMeta.history = [snapshot];\n}\n\n/**\n * Compares and adds history entry to the provided transactionMeta history.\n *\n * @param transactionMeta - TransactionMeta to add history entry to.\n * @param note - Note to add to history entry.\n */\nexport function updateTransactionHistory(\n transactionMeta: TransactionMeta,\n note: string,\n): void {\n const currentState = snapshotFromTransactionMeta(transactionMeta);\n const previousState = replayHistory(\n transactionMeta.history as TransactionHistory,\n );\n\n const historyEntry = generateHistoryEntry(previousState, currentState, note);\n\n if (historyEntry.length) {\n transactionMeta?.history?.push(historyEntry);\n }\n}\n\n/**\n * Generates a history entry from the previous and new transaction metadata.\n *\n * @param previousState - The previous transaction metadata.\n * @param currentState - The new transaction metadata.\n * @param note - A note for the transaction metada update.\n * @returns An array of history operation.\n */\nfunction generateHistoryEntry(\n previousState: any,\n currentState: TransactionMeta,\n note: string,\n): TransactionHistoryEntry {\n const historyOperationsEntry = jsonDiffer.compare(\n previousState,\n currentState,\n ) as TransactionHistoryEntry;\n // Add a note to the first operation, since it breaks if we append it to the entry\n if (historyOperationsEntry[0]) {\n if (note) {\n historyOperationsEntry[0].note = note;\n }\n historyOperationsEntry[0].timestamp = Date.now();\n }\n return historyOperationsEntry;\n}\n\n/**\n * Recovers previous transactionMeta from passed history array.\n *\n * @param transactionHistory - The transaction metadata to replay.\n * @returns The transaction metadata.\n */\nfunction replayHistory(\n transactionHistory: TransactionHistory,\n): TransactionMeta {\n const shortHistory = cloneDeep(transactionHistory);\n return shortHistory.reduce(\n (val, entry: any) => jsonDiffer.applyPatch(val, entry).newDocument,\n ) as TransactionMeta;\n}\n\n/**\n * Clone the transaction meta data without the history property.\n *\n * @param transactionMeta - The transaction metadata to snapshot.\n * @returns A deep clone of transaction metadata without history property.\n */\nfunction snapshotFromTransactionMeta(\n transactionMeta: TransactionMeta,\n): TransactionMeta {\n const snapshot = { ...transactionMeta };\n delete snapshot.history;\n return cloneDeep(snapshot);\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"transaction-type.d.ts","sourceRoot":"","sources":["../src/transaction-type.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAGhD,OAAO,KAAK,EAAE,0BAA0B,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAG7E,eAAO,MAAM,kBAAkB,qCAAqC,CAAC;AAMrE;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,0BAA0B,CAAC,CAiCrC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"transaction-type.js","sourceRoot":"","sources":["../src/transaction-type.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TransactionDescription } from '@ethersproject/abi';\nimport { Interface } from '@ethersproject/abi';\nimport { query } from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport { abiERC721, abiERC20, abiERC1155 } from '@metamask/metamask-eth-abis';\n\nimport type { InferTransactionTypeResult, TransactionParams } from './types';\nimport { TransactionType } from './types';\n\nexport const ESTIMATE_GAS_ERROR = 'eth_estimateGas rpc method error';\n\nconst ERC20Interface = new Interface(abiERC20);\nconst ERC721Interface = new Interface(abiERC721);\nconst ERC1155Interface = new Interface(abiERC1155);\n\n/**\n * Determines the type of the transaction by analyzing the txParams.\n * It will never return TRANSACTION_TYPE_CANCEL or TRANSACTION_TYPE_RETRY as these\n * represent specific events that we specify manually at transaction creation.\n *\n * @param txParams - Parameters for the transaction.\n * @param ethQuery - EthQuery instance.\n * @returns A object with the transaction type and the contract code response in Hex.\n */\nexport async function determineTransactionType(\n txParams: TransactionParams,\n ethQuery: EthQuery,\n): Promise<InferTransactionTypeResult> {\n const { data, to } = txParams;\n const name = parseStandardTokenTransactionData(data)?.name;\n\n if (data && !to) {\n return { type: TransactionType.deployContract, getCodeResponse: undefined };\n }\n\n const { contractCode: resultCode, isContractAddress } =\n await readAddressAsContract(ethQuery, to);\n\n if (!isContractAddress) {\n return { type: TransactionType.simpleSend, getCodeResponse: resultCode };\n }\n\n const hasValue = txParams.value && Number(txParams.value) !== 0;\n\n const tokenMethodName = [\n TransactionType.tokenMethodApprove,\n TransactionType.tokenMethodSetApprovalForAll,\n TransactionType.tokenMethodTransfer,\n TransactionType.tokenMethodTransferFrom,\n TransactionType.tokenMethodSafeTransferFrom,\n ].find((methodName) => methodName.toLowerCase() === name?.toLowerCase());\n\n if (data && tokenMethodName && !hasValue) {\n return { type: tokenMethodName, getCodeResponse: resultCode };\n }\n\n return {\n type: TransactionType.contractInteraction,\n getCodeResponse: resultCode,\n };\n}\n\n/**\n * Attempts to decode transaction data using ABIs for three different token standards: ERC20, ERC721, ERC1155.\n * The data will decode correctly if the transaction is an interaction with a contract that matches one of these\n * contract standards\n *\n * @param data - Encoded transaction data.\n * @returns A representation of an ethereum contract call.\n */\nfunction parseStandardTokenTransactionData(\n data?: string,\n): TransactionDescription | undefined {\n if (!data) {\n return undefined;\n }\n\n try {\n return ERC20Interface.parseTransaction({ data });\n } catch {\n // ignore and next try to parse with erc721 ABI\n }\n\n try {\n return ERC721Interface.parseTransaction({ data });\n } catch {\n // ignore and next try to parse with erc1155 ABI\n }\n\n try {\n return ERC1155Interface.parseTransaction({ data });\n } catch {\n // ignore and return undefined\n }\n\n return undefined;\n}\n\n/**\n * Reads an Ethereum address and determines if it is a contract address.\n *\n * @param ethQuery - The Ethereum query object used to interact with the Ethereum blockchain.\n * @param address - The Ethereum address.\n * @returns An object containing the contract code and a boolean indicating if it is a contract address.\n */\nasync function readAddressAsContract(\n ethQuery: EthQuery,\n address?: string,\n): Promise<{\n contractCode: string | null;\n isContractAddress: boolean;\n}> {\n let contractCode;\n try {\n contractCode = await query(ethQuery, 'getCode', [address]);\n } catch (e) {\n contractCode = null;\n }\n\n const isContractAddress = contractCode\n ? contractCode !== '0x' && contractCode !== '0x0'\n : false;\n return { contractCode, isContractAddress };\n}\n"]}
|
package/dist/utils.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,IAAI,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE9F,OAAO,KAAK,EACV,aAAa,EACb,sBAAsB,EACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAElE,eAAO,MAAM,kBAAkB,qCAAqC,CAAC;AAmBrE;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,iBAAiB,qBAS5D;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAOzE;AAED,eAAO,MAAM,iBAAiB,cACjB,aAAa,GAAG,sBAAsB,SAUlD,CAAC;AAEF,eAAO,MAAM,wBAAwB,eACvB,aAAa,GAAG,sBAAsB,wCAGuB,CAAC;AAE5E,eAAO,MAAM,eAAe,eACd,aAAa,GAAG,sBAAsB,+BAEE,CAAC;AAEvD,eAAO,MAAM,oBAAoB,UAAW,MAAM,QAAQ,MAAM,KAAG,MACF,CAAC;AAElE,eAAO,MAAM,6BAA6B,UACjC,MAAM,GAAG,SAAS,QACnB,MAAM,KACX,MAEF,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,UAQpE;AAED;;;;;;;GAOG;AACH,wBAAgB,uCAAuC,CACrD,WAAW,EAAE,MAAM,EACnB,iBAAiB,EAAE,iBAAiB,EACpC,YAAY,EAAE,eAAe,EAAE,GAC9B,uBAAuB,EAAE,CAsB3B;AAED;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAC7C,eAAe,EAAE,eAAe,GAAG,SAAS,EAC5C,MAAM,EAAE,MAAM,QAQf"}
|
package/dist/utils.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { convertHexToDecimal } from '@metamask/controller-utils';\nimport { addHexPrefix, isHexString } from 'ethereumjs-util';\nimport type { Transaction as NonceTrackerTransaction } from 'nonce-tracker/dist/NonceTracker';\n\nimport type {\n GasPriceValue,\n FeeMarketEIP1559Values,\n} from './TransactionController';\nimport { TransactionStatus } from './types';\nimport type { TransactionParams, TransactionMeta } from './types';\n\nexport const ESTIMATE_GAS_ERROR = 'eth_estimateGas rpc method error';\n\nconst NORMALIZERS: { [param in keyof TransactionParams]: any } = {\n data: (data: string) => addHexPrefix(data),\n from: (from: string) => addHexPrefix(from).toLowerCase(),\n gas: (gas: string) => addHexPrefix(gas),\n gasLimit: (gas: string) => addHexPrefix(gas),\n gasPrice: (gasPrice: string) => addHexPrefix(gasPrice),\n nonce: (nonce: string) => addHexPrefix(nonce),\n to: (to: string) => addHexPrefix(to).toLowerCase(),\n value: (value: string) => addHexPrefix(value),\n maxFeePerGas: (maxFeePerGas: string) => addHexPrefix(maxFeePerGas),\n maxPriorityFeePerGas: (maxPriorityFeePerGas: string) =>\n addHexPrefix(maxPriorityFeePerGas),\n estimatedBaseFee: (maxPriorityFeePerGas: string) =>\n addHexPrefix(maxPriorityFeePerGas),\n type: (type: string) => (type === '0x0' ? '0x0' : undefined),\n};\n\n/**\n * Normalizes properties on transaction params.\n *\n * @param txParams - The transaction params to normalize.\n * @returns Normalized transaction params.\n */\nexport function normalizeTxParams(txParams: TransactionParams) {\n const normalizedTxParams: TransactionParams = { from: '' };\n let key: keyof TransactionParams;\n for (key in NORMALIZERS) {\n if (txParams[key as keyof TransactionParams]) {\n normalizedTxParams[key] = NORMALIZERS[key](txParams[key]) as never;\n }\n }\n return normalizedTxParams;\n}\n\n/**\n * Checks if a transaction is EIP-1559 by checking for the existence of\n * maxFeePerGas and maxPriorityFeePerGas within its parameters.\n *\n * @param txParams - Transaction params object to add.\n * @returns Boolean that is true if the transaction is EIP-1559 (has maxFeePerGas and maxPriorityFeePerGas), otherwise returns false.\n */\nexport function isEIP1559Transaction(txParams: TransactionParams): boolean {\n const hasOwnProp = (obj: TransactionParams, key: string) =>\n Object.prototype.hasOwnProperty.call(obj, key);\n return (\n hasOwnProp(txParams, 'maxFeePerGas') &&\n hasOwnProp(txParams, 'maxPriorityFeePerGas')\n );\n}\n\nexport const validateGasValues = (\n gasValues: GasPriceValue | FeeMarketEIP1559Values,\n) => {\n Object.keys(gasValues).forEach((key) => {\n const value = (gasValues as any)[key];\n if (typeof value !== 'string' || !isHexString(value)) {\n throw new TypeError(\n `expected hex string for ${key} but received: ${value}`,\n );\n }\n });\n};\n\nexport const isFeeMarketEIP1559Values = (\n gasValues?: GasPriceValue | FeeMarketEIP1559Values,\n): gasValues is FeeMarketEIP1559Values =>\n (gasValues as FeeMarketEIP1559Values)?.maxFeePerGas !== undefined ||\n (gasValues as FeeMarketEIP1559Values)?.maxPriorityFeePerGas !== undefined;\n\nexport const isGasPriceValue = (\n gasValues?: GasPriceValue | FeeMarketEIP1559Values,\n): gasValues is GasPriceValue =>\n (gasValues as GasPriceValue)?.gasPrice !== undefined;\n\nexport const getIncreasedPriceHex = (value: number, rate: number): string =>\n addHexPrefix(`${parseInt(`${value * rate}`, 10).toString(16)}`);\n\nexport const getIncreasedPriceFromExisting = (\n value: string | undefined,\n rate: number,\n): string => {\n return getIncreasedPriceHex(convertHexToDecimal(value), rate);\n};\n\n/**\n * Validates that the proposed value is greater than or equal to the minimum value.\n *\n * @param proposed - The proposed value.\n * @param min - The minimum value.\n * @returns The proposed value.\n * @throws Will throw if the proposed value is too low.\n */\nexport function validateMinimumIncrease(proposed: string, min: string) {\n const proposedDecimal = convertHexToDecimal(proposed);\n const minDecimal = convertHexToDecimal(min);\n if (proposedDecimal >= minDecimal) {\n return proposed;\n }\n const errorMsg = `The proposed value: ${proposedDecimal} should meet or exceed the minimum value: ${minDecimal}`;\n throw new Error(errorMsg);\n}\n\n/**\n * Helper function to filter and format transactions for the nonce tracker.\n *\n * @param fromAddress - Address of the account from which the transactions to filter from are sent.\n * @param transactionStatus - Status of the transactions for which to filter.\n * @param transactions - Array of transactionMeta objects that have been prefiltered.\n * @returns Array of transactions formatted for the nonce tracker.\n */\nexport function getAndFormatTransactionsForNonceTracker(\n fromAddress: string,\n transactionStatus: TransactionStatus,\n transactions: TransactionMeta[],\n): NonceTrackerTransaction[] {\n return transactions\n .filter(\n ({ status, txParams: { from } }) =>\n status === transactionStatus &&\n from.toLowerCase() === fromAddress.toLowerCase(),\n )\n .map(({ status, txParams: { from, gas, value, nonce } }) => {\n // the only value we care about is the nonce\n // but we need to return the other values to satisfy the type\n // TODO: refactor nonceTracker to not require this\n return {\n status,\n history: [{}],\n txParams: {\n from: from ?? '',\n gas: gas ?? '',\n value: value ?? '',\n nonce: nonce ?? '',\n },\n };\n });\n}\n\n/**\n * Validates that a transaction is unapproved.\n * Throws if the transaction is not unapproved.\n *\n * @param transactionMeta - The transaction metadata to check.\n * @param fnName - The name of the function calling this helper.\n */\nexport function validateIfTransactionUnapproved(\n transactionMeta: TransactionMeta | undefined,\n fnName: string,\n) {\n if (transactionMeta?.status !== TransactionStatus.unapproved) {\n throw new Error(\n `Can only call ${fnName} on an unapproved transaction.\n Current tx status: ${transactionMeta?.status}`,\n );\n }\n}\n"]}
|
package/dist/validation.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAGjD;;;;;;;;GAQG;AACH,wBAAsB,yBAAyB,CAC7C,kBAAkB,EAAE,MAAM,EAAE,EAC5B,eAAe,EAAE,MAAM,EACvB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,iBAqBf;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,iBAAiB,EAC3B,mBAAmB,UAAO,QAQ3B"}
|
package/dist/validation.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { ORIGIN_METAMASK, isValidHexAddress } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport { providerErrors, rpcErrors } from '@metamask/rpc-errors';\n\nimport type { TransactionParams } from './types';\nimport { isEIP1559Transaction } from './utils';\n\n/**\n * Validates whether a transaction initiated by a specific 'from' address is permitted by the origin.\n *\n * @param permittedAddresses - The permitted accounts for the given origin.\n * @param selectedAddress - The currently selected Ethereum address in the wallet.\n * @param from - The address from which the transaction is initiated.\n * @param origin - The origin or source of the transaction.\n * @throws Throws an error if the transaction is not permitted.\n */\nexport async function validateTransactionOrigin(\n permittedAddresses: string[],\n selectedAddress: string,\n from: string,\n origin: string,\n) {\n if (origin === ORIGIN_METAMASK) {\n // Ensure the 'from' address matches the currently selected address\n if (from !== selectedAddress) {\n throw rpcErrors.internal({\n message: `Internally initiated transaction is using invalid account.`,\n data: {\n origin,\n fromAddress: from,\n selectedAddress,\n },\n });\n }\n return;\n }\n\n // Check if the origin has permissions to initiate transactions from the specified address\n if (!permittedAddresses.includes(from)) {\n throw providerErrors.unauthorized({ data: { origin } });\n }\n}\n\n/**\n * Validates the transaction params for required properties and throws in\n * the event of any validation error.\n *\n * @param txParams - Transaction params object to validate.\n * @param isEIP1559Compatible - whether or not the current network supports EIP-1559 transactions.\n */\nexport function validateTxParams(\n txParams: TransactionParams,\n isEIP1559Compatible = true,\n) {\n validateEIP1559Compatibility(txParams, isEIP1559Compatible);\n validateParamFrom(txParams.from);\n validateParamRecipient(txParams);\n validateParamValue(txParams.value);\n validateParamData(txParams.data);\n validateParamChainId(txParams.chainId);\n}\n\n/**\n * Validates EIP-1559 compatibility for transaction creation.\n *\n * @param txParams - The transaction parameters to validate.\n * @param isEIP1559Compatible - Indicates if the current network supports EIP-1559.\n * @throws Throws invalid params if the transaction specifies EIP-1559 but the network does not support it.\n */\nfunction validateEIP1559Compatibility(\n txParams: TransactionParams,\n isEIP1559Compatible: boolean,\n) {\n if (isEIP1559Transaction(txParams) && !isEIP1559Compatible) {\n throw rpcErrors.invalidParams(\n 'Invalid transaction params: params specify an EIP-1559 transaction but the current network does not support EIP-1559',\n );\n }\n}\n\n/**\n * Validates value property, ensuring it is a valid positive integer number\n * denominated in wei.\n *\n * @param value - The value to validate, expressed as a string.\n * @throws Throws an error if the value is not a valid positive integer\n * number denominated in wei.\n * - If the value contains a hyphen (-), it is considered invalid.\n * - If the value contains a decimal point (.), it is considered invalid.\n * - If the value is not a finite number, is NaN, or is not a safe integer, it is considered invalid.\n */\nfunction validateParamValue(value?: string) {\n if (value !== undefined) {\n if (value.includes('-')) {\n throw rpcErrors.invalidParams(\n `Invalid \"value\": ${value} is not a positive number.`,\n );\n }\n\n if (value.includes('.')) {\n throw rpcErrors.invalidParams(\n `Invalid \"value\": ${value} number must be denominated in wei.`,\n );\n }\n const intValue = parseInt(value, 10);\n const isValid =\n Number.isFinite(intValue) &&\n !Number.isNaN(intValue) &&\n !isNaN(Number(value)) &&\n Number.isSafeInteger(intValue);\n if (!isValid) {\n throw rpcErrors.invalidParams(\n `Invalid \"value\": ${value} number must be a valid number.`,\n );\n }\n }\n}\n\n/**\n * Validates the recipient address in a transaction's parameters.\n *\n * @param txParams - The transaction parameters object to validate.\n * @throws Throws an error if the recipient address is invalid:\n * - If the recipient address is an empty string ('0x') or undefined and the transaction contains data,\n * the \"to\" field is removed from the transaction parameters.\n * - If the recipient address is not a valid hexadecimal Ethereum address, an error is thrown.\n */\nfunction validateParamRecipient(txParams: TransactionParams) {\n if (txParams.to === '0x' || txParams.to === undefined) {\n if (txParams.data) {\n delete txParams.to;\n } else {\n throw new Error(\n `Invalid \"to\" address: ${txParams.to} must be a valid string.`,\n );\n }\n } else if (txParams.to !== undefined && !isValidHexAddress(txParams.to)) {\n throw new Error(\n `Invalid \"to\" address: ${txParams.to} must be a valid string.`,\n );\n }\n}\n\n/**\n * Validates the recipient address in a transaction's parameters.\n *\n * @param from - The from property to validate.\n * @throws Throws an error if the recipient address is invalid:\n * - If the recipient address is an empty string ('0x') or undefined and the transaction contains data,\n * the \"to\" field is removed from the transaction parameters.\n * - If the recipient address is not a valid hexadecimal Ethereum address, an error is thrown.\n */\nfunction validateParamFrom(from: string) {\n if (!from || typeof from !== 'string' || !isValidHexAddress(from)) {\n throw new Error(`Invalid \"from\" address: ${from} must be a valid string.`);\n }\n}\n\n/**\n * Validates input data for transactions.\n *\n * @param value - The input data to validate.\n * @throws Throws invalid params if the input data is invalid.\n */\nfunction validateParamData(value?: string) {\n if (value) {\n const ERC20Interface = new Interface(abiERC20);\n try {\n ERC20Interface.parseTransaction({ data: value });\n } catch (error: any) {\n if (error.message.match(/BUFFER_OVERRUN/u)) {\n throw rpcErrors.invalidParams(\n 'Invalid transaction params: data out-of-bounds, BUFFER_OVERRUN.',\n );\n }\n }\n }\n}\n\n/**\n * Validates chainId type.\n *\n * @param chainId - The chainId to validate.\n */\nfunction validateParamChainId(chainId: number | string | undefined) {\n if (\n chainId !== undefined &&\n typeof chainId !== 'number' &&\n typeof chainId !== 'string'\n ) {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: chainId is not a Number or hex string. got: (${chainId})`,\n );\n }\n}\n"]}
|
|
File without changes
|
|
File without changes
|