@metamask/transaction-controller 57.4.0 → 58.1.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 +27 -1
- package/dist/TransactionController.cjs +27 -12
- package/dist/TransactionController.cjs.map +1 -1
- package/dist/TransactionController.d.cts +5 -3
- package/dist/TransactionController.d.cts.map +1 -1
- package/dist/TransactionController.d.mts +5 -3
- package/dist/TransactionController.d.mts.map +1 -1
- package/dist/TransactionController.mjs +27 -12
- package/dist/TransactionController.mjs.map +1 -1
- package/dist/api/accounts-api.cjs.map +1 -1
- package/dist/api/accounts-api.d.cts +1 -1
- package/dist/api/accounts-api.d.cts.map +1 -1
- package/dist/api/accounts-api.d.mts +1 -1
- package/dist/api/accounts-api.d.mts.map +1 -1
- package/dist/api/accounts-api.mjs.map +1 -1
- package/dist/helpers/AccountsApiRemoteTransactionSource.cjs +39 -105
- package/dist/helpers/AccountsApiRemoteTransactionSource.cjs.map +1 -1
- package/dist/helpers/AccountsApiRemoteTransactionSource.d.cts.map +1 -1
- package/dist/helpers/AccountsApiRemoteTransactionSource.d.mts.map +1 -1
- package/dist/helpers/AccountsApiRemoteTransactionSource.mjs +39 -105
- package/dist/helpers/AccountsApiRemoteTransactionSource.mjs.map +1 -1
- package/dist/helpers/GasFeePoller.cjs +60 -4
- package/dist/helpers/GasFeePoller.cjs.map +1 -1
- package/dist/helpers/GasFeePoller.d.cts +4 -2
- package/dist/helpers/GasFeePoller.d.cts.map +1 -1
- package/dist/helpers/GasFeePoller.d.mts +4 -2
- package/dist/helpers/GasFeePoller.d.mts.map +1 -1
- package/dist/helpers/GasFeePoller.mjs +60 -4
- package/dist/helpers/GasFeePoller.mjs.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.cjs +7 -18
- package/dist/helpers/IncomingTransactionHelper.cjs.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.d.cts +6 -4
- package/dist/helpers/IncomingTransactionHelper.d.cts.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.d.mts +6 -4
- package/dist/helpers/IncomingTransactionHelper.d.mts.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.mjs +7 -18
- package/dist/helpers/IncomingTransactionHelper.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +2 -13
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +2 -13
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/batch.cjs +17 -7
- package/dist/utils/batch.cjs.map +1 -1
- package/dist/utils/batch.d.cts.map +1 -1
- package/dist/utils/batch.d.mts.map +1 -1
- package/dist/utils/batch.mjs +18 -8
- package/dist/utils/batch.mjs.map +1 -1
- package/dist/utils/gas.cjs +46 -7
- package/dist/utils/gas.cjs.map +1 -1
- package/dist/utils/gas.d.cts.map +1 -1
- package/dist/utils/gas.d.mts.map +1 -1
- package/dist/utils/gas.mjs +46 -7
- package/dist/utils/gas.mjs.map +1 -1
- package/dist/utils/transaction-type.cjs +23 -27
- package/dist/utils/transaction-type.cjs.map +1 -1
- package/dist/utils/transaction-type.d.cts +1 -1
- package/dist/utils/transaction-type.d.cts.map +1 -1
- package/dist/utils/transaction-type.d.mts +1 -1
- package/dist/utils/transaction-type.d.mts.map +1 -1
- package/dist/utils/transaction-type.mjs +23 -27
- package/dist/utils/transaction-type.mjs.map +1 -1
- package/package.json +7 -7
|
@@ -3,7 +3,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
3
3
|
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");
|
|
4
4
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
5
|
};
|
|
6
|
-
var _AccountsApiRemoteTransactionSource_instances,
|
|
6
|
+
var _AccountsApiRemoteTransactionSource_instances, _AccountsApiRemoteTransactionSource_queryTransactions, _AccountsApiRemoteTransactionSource_filterTransactions, _AccountsApiRemoteTransactionSource_normalizeTransaction;
|
|
7
7
|
function $importDefault(module) {
|
|
8
8
|
if (module?.__esModule) {
|
|
9
9
|
return module.default;
|
|
@@ -14,11 +14,11 @@ import { BNToHex } from "@metamask/controller-utils";
|
|
|
14
14
|
import $BN from "bn.js";
|
|
15
15
|
const BN = $importDefault($BN);
|
|
16
16
|
import { v1 as random } from "uuid";
|
|
17
|
+
import { determineTransactionType } from "../index.mjs";
|
|
17
18
|
import { getAccountTransactions } from "../api/accounts-api.mjs";
|
|
18
19
|
import { CHAIN_IDS } from "../constants.mjs";
|
|
19
20
|
import { createModuleLogger, incomingTransactionsLogger } from "../logger.mjs";
|
|
20
21
|
import { TransactionStatus, TransactionType } from "../types.mjs";
|
|
21
|
-
const RECENT_HISTORY_DURATION_MS = 1000 * 60 * 60 * 24; // 1 Day
|
|
22
22
|
export const SUPPORTED_CHAIN_IDS = [
|
|
23
23
|
CHAIN_IDS.MAINNET,
|
|
24
24
|
CHAIN_IDS.POLYGON,
|
|
@@ -43,70 +43,32 @@ export class AccountsApiRemoteTransactionSource {
|
|
|
43
43
|
}
|
|
44
44
|
async fetchTransactions(request) {
|
|
45
45
|
const { address } = request;
|
|
46
|
-
const responseTransactions = await __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m",
|
|
46
|
+
const responseTransactions = await __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_queryTransactions).call(this, request, SUPPORTED_CHAIN_IDS);
|
|
47
47
|
log('Fetched transactions', responseTransactions.length, responseTransactions);
|
|
48
|
-
const normalizedTransactions = responseTransactions.map((tx) => __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_normalizeTransaction).call(this, address, tx));
|
|
48
|
+
const normalizedTransactions = await Promise.all(responseTransactions.map((tx) => __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_normalizeTransaction).call(this, address, tx)));
|
|
49
49
|
log('Normalized transactions', normalizedTransactions);
|
|
50
50
|
const filteredTransactions = __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_filterTransactions).call(this, request, normalizedTransactions);
|
|
51
51
|
log('Filtered transactions', filteredTransactions.length, filteredTransactions);
|
|
52
52
|
return filteredTransactions;
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
-
_AccountsApiRemoteTransactionSource_instances = new WeakSet(),
|
|
56
|
-
|
|
57
|
-
const { address, cache } = request;
|
|
58
|
-
const cursor = __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_getCacheCursor).call(this, cache, SUPPORTED_CHAIN_IDS, address);
|
|
59
|
-
const timestamp = __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_getCacheTimestamp).call(this, cache, SUPPORTED_CHAIN_IDS, address);
|
|
60
|
-
if (cursor) {
|
|
61
|
-
log('Using cached cursor', cursor);
|
|
62
|
-
}
|
|
63
|
-
else if (timestamp) {
|
|
64
|
-
log('Using cached timestamp', timestamp);
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
log('No cached cursor or timestamp found');
|
|
68
|
-
}
|
|
69
|
-
return await __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_queryTransactions).call(this, request, SUPPORTED_CHAIN_IDS, cursor, timestamp);
|
|
70
|
-
}, _AccountsApiRemoteTransactionSource_queryTransactions = async function _AccountsApiRemoteTransactionSource_queryTransactions(request, chainIds, cursor, timestamp) {
|
|
71
|
-
const { address, queryEntireHistory, tags } = request;
|
|
55
|
+
_AccountsApiRemoteTransactionSource_instances = new WeakSet(), _AccountsApiRemoteTransactionSource_queryTransactions = async function _AccountsApiRemoteTransactionSource_queryTransactions(request, chainIds) {
|
|
56
|
+
const { address, tags } = request;
|
|
72
57
|
const transactions = [];
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
});
|
|
83
|
-
const response = await getAccountTransactions({
|
|
84
|
-
address,
|
|
85
|
-
chainIds,
|
|
86
|
-
cursor: currentCursor,
|
|
87
|
-
sortDirection: 'ASC',
|
|
88
|
-
startTimestamp,
|
|
89
|
-
tags,
|
|
90
|
-
});
|
|
91
|
-
pageCount += 1;
|
|
92
|
-
if (response?.data) {
|
|
93
|
-
transactions.push(...response.data);
|
|
94
|
-
}
|
|
95
|
-
hasNextPage = response?.pageInfo?.hasNextPage;
|
|
96
|
-
currentCursor = response?.pageInfo?.cursor;
|
|
97
|
-
__classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_updateCache).call(this, {
|
|
98
|
-
chainIds,
|
|
99
|
-
cursor: currentCursor,
|
|
100
|
-
request,
|
|
101
|
-
startTimestamp,
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
catch (error) {
|
|
105
|
-
log('Error while fetching transactions', error);
|
|
106
|
-
break;
|
|
58
|
+
try {
|
|
59
|
+
const response = await getAccountTransactions({
|
|
60
|
+
address,
|
|
61
|
+
chainIds,
|
|
62
|
+
sortDirection: 'DESC',
|
|
63
|
+
tags,
|
|
64
|
+
});
|
|
65
|
+
if (response?.data) {
|
|
66
|
+
transactions.push(...response.data);
|
|
107
67
|
}
|
|
108
68
|
}
|
|
109
|
-
|
|
69
|
+
catch (error) {
|
|
70
|
+
log('Error while fetching transactions', error);
|
|
71
|
+
}
|
|
110
72
|
return transactions;
|
|
111
73
|
}, _AccountsApiRemoteTransactionSource_filterTransactions = function _AccountsApiRemoteTransactionSource_filterTransactions(request, transactions) {
|
|
112
74
|
const { address, includeTokenTransfers, updateTransactions } = request;
|
|
@@ -118,7 +80,7 @@ _AccountsApiRemoteTransactionSource_instances = new WeakSet(), _AccountsApiRemot
|
|
|
118
80
|
filteredTransactions = filteredTransactions.filter((tx) => !tx.isTransfer);
|
|
119
81
|
}
|
|
120
82
|
return filteredTransactions;
|
|
121
|
-
}, _AccountsApiRemoteTransactionSource_normalizeTransaction = function _AccountsApiRemoteTransactionSource_normalizeTransaction(address, responseTransaction) {
|
|
83
|
+
}, _AccountsApiRemoteTransactionSource_normalizeTransaction = async function _AccountsApiRemoteTransactionSource_normalizeTransaction(address, responseTransaction) {
|
|
122
84
|
const blockNumber = String(responseTransaction.blockNumber);
|
|
123
85
|
const chainId = `0x${responseTransaction.chainId.toString(16)}`;
|
|
124
86
|
const { hash } = responseTransaction;
|
|
@@ -129,35 +91,44 @@ _AccountsApiRemoteTransactionSource_instances = new WeakSet(), _AccountsApiRemot
|
|
|
129
91
|
const gasPrice = BNToHex(new BN(responseTransaction.gasPrice));
|
|
130
92
|
const gasUsed = BNToHex(new BN(responseTransaction.gasUsed));
|
|
131
93
|
const nonce = BNToHex(new BN(responseTransaction.nonce));
|
|
94
|
+
const data = responseTransaction.methodId;
|
|
132
95
|
const type = TransactionType.incoming;
|
|
133
96
|
const verifiedOnBlockchain = false;
|
|
134
97
|
const status = responseTransaction.isError
|
|
135
98
|
? TransactionStatus.failed
|
|
136
99
|
: TransactionStatus.confirmed;
|
|
137
|
-
const valueTransfer = responseTransaction.valueTransfers.find((vt) => vt.to.toLowerCase() === address.toLowerCase()
|
|
138
|
-
|
|
100
|
+
const valueTransfer = responseTransaction.valueTransfers.find((vt) => (vt.to.toLowerCase() === address.toLowerCase() ||
|
|
101
|
+
vt.from.toLowerCase() === address.toLowerCase()) &&
|
|
102
|
+
vt.contractAddress);
|
|
103
|
+
const isIncomingTokenTransfer = valueTransfer?.to.toLowerCase() === address.toLowerCase() &&
|
|
104
|
+
from.toLowerCase() !== address.toLowerCase();
|
|
105
|
+
const isOutgoing = from.toLowerCase() === address.toLowerCase();
|
|
106
|
+
const amount = valueTransfer?.amount;
|
|
139
107
|
const contractAddress = valueTransfer?.contractAddress;
|
|
140
108
|
const decimals = valueTransfer?.decimal;
|
|
141
109
|
const symbol = valueTransfer?.symbol;
|
|
142
|
-
const value = BNToHex(new BN(
|
|
143
|
-
|
|
110
|
+
const value = BNToHex(new BN(isIncomingTokenTransfer
|
|
111
|
+
? (valueTransfer?.amount ?? responseTransaction.value)
|
|
112
|
+
: responseTransaction.value));
|
|
113
|
+
const to = isIncomingTokenTransfer ? address : responseTransaction.to;
|
|
144
114
|
const error = status === TransactionStatus.failed
|
|
145
115
|
? new Error('Transaction failed')
|
|
146
116
|
: undefined;
|
|
147
|
-
const transferInformation =
|
|
117
|
+
const transferInformation = valueTransfer
|
|
148
118
|
? {
|
|
119
|
+
amount,
|
|
149
120
|
contractAddress,
|
|
150
121
|
decimals,
|
|
151
122
|
symbol,
|
|
152
123
|
}
|
|
153
124
|
: undefined;
|
|
154
|
-
|
|
125
|
+
const meta = {
|
|
155
126
|
blockNumber,
|
|
156
127
|
chainId,
|
|
157
128
|
error,
|
|
158
129
|
hash,
|
|
159
130
|
id,
|
|
160
|
-
isTransfer,
|
|
131
|
+
isTransfer: isIncomingTokenTransfer,
|
|
161
132
|
// Populated by TransactionController when added to state
|
|
162
133
|
networkClientId: '',
|
|
163
134
|
status,
|
|
@@ -166,6 +137,7 @@ _AccountsApiRemoteTransactionSource_instances = new WeakSet(), _AccountsApiRemot
|
|
|
166
137
|
transferInformation,
|
|
167
138
|
txParams: {
|
|
168
139
|
chainId,
|
|
140
|
+
data,
|
|
169
141
|
from,
|
|
170
142
|
gas,
|
|
171
143
|
gasPrice,
|
|
@@ -177,47 +149,9 @@ _AccountsApiRemoteTransactionSource_instances = new WeakSet(), _AccountsApiRemot
|
|
|
177
149
|
type,
|
|
178
150
|
verifiedOnBlockchain,
|
|
179
151
|
};
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
log('Cache not updated');
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
const { address, updateCache } = request;
|
|
186
|
-
const cursorCacheKey = __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_getCursorCacheKey).call(this, chainIds, address);
|
|
187
|
-
const timestampCacheKey = __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_getTimestampCacheKey).call(this, chainIds, address);
|
|
188
|
-
updateCache((cache) => {
|
|
189
|
-
if (cursor) {
|
|
190
|
-
cache[cursorCacheKey] = cursor;
|
|
191
|
-
delete cache[timestampCacheKey];
|
|
192
|
-
log('Updated cursor in cache', { cursorCacheKey, newCursor: cursor });
|
|
193
|
-
}
|
|
194
|
-
else {
|
|
195
|
-
cache[timestampCacheKey] = startTimestamp;
|
|
196
|
-
log('Updated timestamp in cache', {
|
|
197
|
-
timestampCacheKey,
|
|
198
|
-
newTimestamp: startTimestamp,
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
}, _AccountsApiRemoteTransactionSource_getStartTimestamp = function _AccountsApiRemoteTransactionSource_getStartTimestamp({ cursor, queryEntireHistory, timestamp, }) {
|
|
203
|
-
if (queryEntireHistory || cursor) {
|
|
204
|
-
return undefined;
|
|
205
|
-
}
|
|
206
|
-
if (timestamp) {
|
|
207
|
-
return timestamp;
|
|
152
|
+
if (isOutgoing) {
|
|
153
|
+
meta.type = (await determineTransactionType(meta.txParams)).type;
|
|
208
154
|
}
|
|
209
|
-
return
|
|
210
|
-
}, _AccountsApiRemoteTransactionSource_getCursorCacheKey = function _AccountsApiRemoteTransactionSource_getCursorCacheKey(chainIds, address) {
|
|
211
|
-
return `accounts-api#${chainIds.join(',')}#${address}`;
|
|
212
|
-
}, _AccountsApiRemoteTransactionSource_getCacheCursor = function _AccountsApiRemoteTransactionSource_getCacheCursor(cache, chainIds, address) {
|
|
213
|
-
const key = __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_getCursorCacheKey).call(this, chainIds, address);
|
|
214
|
-
return cache[key];
|
|
215
|
-
}, _AccountsApiRemoteTransactionSource_getTimestampCacheKey = function _AccountsApiRemoteTransactionSource_getTimestampCacheKey(chainIds, address) {
|
|
216
|
-
return `accounts-api#timestamp#${chainIds.join(',')}#${address}`;
|
|
217
|
-
}, _AccountsApiRemoteTransactionSource_getCacheTimestamp = function _AccountsApiRemoteTransactionSource_getCacheTimestamp(cache, chainIds, address) {
|
|
218
|
-
const key = __classPrivateFieldGet(this, _AccountsApiRemoteTransactionSource_instances, "m", _AccountsApiRemoteTransactionSource_getTimestampCacheKey).call(this, chainIds, address);
|
|
219
|
-
return cache[key];
|
|
220
|
-
}, _AccountsApiRemoteTransactionSource_getTimestampSeconds = function _AccountsApiRemoteTransactionSource_getTimestampSeconds(timestampMs) {
|
|
221
|
-
return Math.floor(timestampMs / 1000);
|
|
155
|
+
return meta;
|
|
222
156
|
};
|
|
223
157
|
//# sourceMappingURL=AccountsApiRemoteTransactionSource.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccountsApiRemoteTransactionSource.mjs","sourceRoot":"","sources":["../../src/helpers/AccountsApiRemoteTransactionSource.ts"],"names":[],"mappings":"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","sourcesContent":["import { BNToHex } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport BN from 'bn.js';\nimport { v1 as random } from 'uuid';\n\nimport type {\n GetAccountTransactionsResponse,\n TransactionResponse,\n} from '../api/accounts-api';\nimport { getAccountTransactions } from '../api/accounts-api';\nimport { CHAIN_IDS } from '../constants';\nimport { createModuleLogger, incomingTransactionsLogger } from '../logger';\nimport type {\n RemoteTransactionSource,\n RemoteTransactionSourceRequest,\n TransactionError,\n TransactionMeta,\n} from '../types';\nimport { TransactionStatus, TransactionType } from '../types';\n\nconst RECENT_HISTORY_DURATION_MS = 1000 * 60 * 60 * 24; // 1 Day\n\nexport const SUPPORTED_CHAIN_IDS: Hex[] = [\n CHAIN_IDS.MAINNET,\n CHAIN_IDS.POLYGON,\n CHAIN_IDS.BSC,\n CHAIN_IDS.LINEA_MAINNET,\n CHAIN_IDS.BASE,\n CHAIN_IDS.OPTIMISM,\n CHAIN_IDS.ARBITRUM,\n CHAIN_IDS.SCROLL,\n CHAIN_IDS.SEI,\n];\n\nconst log = createModuleLogger(\n incomingTransactionsLogger,\n 'accounts-api-source',\n);\n\n/**\n * A RemoteTransactionSource that fetches incoming transactions using the Accounts API.\n */\nexport class AccountsApiRemoteTransactionSource\n implements RemoteTransactionSource\n{\n getSupportedChains(): Hex[] {\n return SUPPORTED_CHAIN_IDS;\n }\n\n async fetchTransactions(\n request: RemoteTransactionSourceRequest,\n ): Promise<TransactionMeta[]> {\n const { address } = request;\n\n const responseTransactions = await this.#getTransactions(request);\n\n log(\n 'Fetched transactions',\n responseTransactions.length,\n responseTransactions,\n );\n\n const normalizedTransactions = responseTransactions.map((tx) =>\n this.#normalizeTransaction(address, tx),\n );\n\n log('Normalized transactions', normalizedTransactions);\n\n const filteredTransactions = this.#filterTransactions(\n request,\n normalizedTransactions,\n );\n\n log(\n 'Filtered transactions',\n filteredTransactions.length,\n filteredTransactions,\n );\n\n return filteredTransactions;\n }\n\n async #getTransactions(request: RemoteTransactionSourceRequest) {\n log('Getting transactions', request);\n\n const { address, cache } = request;\n\n const cursor = this.#getCacheCursor(cache, SUPPORTED_CHAIN_IDS, address);\n\n const timestamp = this.#getCacheTimestamp(\n cache,\n SUPPORTED_CHAIN_IDS,\n address,\n );\n\n if (cursor) {\n log('Using cached cursor', cursor);\n } else if (timestamp) {\n log('Using cached timestamp', timestamp);\n } else {\n log('No cached cursor or timestamp found');\n }\n\n return await this.#queryTransactions(\n request,\n SUPPORTED_CHAIN_IDS,\n cursor,\n timestamp,\n );\n }\n\n async #queryTransactions(\n request: RemoteTransactionSourceRequest,\n chainIds: Hex[],\n cursor?: string,\n timestamp?: number,\n ): Promise<TransactionResponse[]> {\n const { address, queryEntireHistory, tags } = request;\n const transactions: TransactionResponse[] = [];\n\n let hasNextPage = true;\n let currentCursor = cursor;\n let pageCount = 0;\n\n while (hasNextPage) {\n try {\n const startTimestamp = this.#getStartTimestamp({\n cursor: currentCursor,\n queryEntireHistory,\n timestamp,\n });\n\n const response = await getAccountTransactions({\n address,\n chainIds,\n cursor: currentCursor,\n sortDirection: 'ASC',\n startTimestamp,\n tags,\n });\n\n pageCount += 1;\n\n if (response?.data) {\n transactions.push(...response.data);\n }\n\n hasNextPage = response?.pageInfo?.hasNextPage;\n currentCursor = response?.pageInfo?.cursor;\n\n this.#updateCache({\n chainIds,\n cursor: currentCursor,\n request,\n startTimestamp,\n });\n } catch (error) {\n log('Error while fetching transactions', error);\n break;\n }\n }\n\n log('Queried transactions', { pageCount });\n\n return transactions;\n }\n\n #filterTransactions(\n request: RemoteTransactionSourceRequest,\n transactions: TransactionMeta[],\n ) {\n const { address, includeTokenTransfers, updateTransactions } = request;\n\n let filteredTransactions = transactions;\n\n if (!updateTransactions) {\n filteredTransactions = filteredTransactions.filter(\n (tx) => tx.txParams.to === address,\n );\n }\n\n if (!includeTokenTransfers) {\n filteredTransactions = filteredTransactions.filter(\n (tx) => !tx.isTransfer,\n );\n }\n\n return filteredTransactions;\n }\n\n #normalizeTransaction(\n address: Hex,\n responseTransaction: GetAccountTransactionsResponse['data'][0],\n ): TransactionMeta {\n const blockNumber = String(responseTransaction.blockNumber);\n const chainId = `0x${responseTransaction.chainId.toString(16)}` as Hex;\n const { hash } = responseTransaction;\n const time = new Date(responseTransaction.timestamp).getTime();\n const id = random({ msecs: time });\n const { from } = responseTransaction;\n const gas = BNToHex(new BN(responseTransaction.gas));\n const gasPrice = BNToHex(new BN(responseTransaction.gasPrice));\n const gasUsed = BNToHex(new BN(responseTransaction.gasUsed));\n const nonce = BNToHex(new BN(responseTransaction.nonce));\n const type = TransactionType.incoming;\n const verifiedOnBlockchain = false;\n\n const status = responseTransaction.isError\n ? TransactionStatus.failed\n : TransactionStatus.confirmed;\n\n const valueTransfer = responseTransaction.valueTransfers.find(\n (vt) =>\n vt.to.toLowerCase() === address.toLowerCase() && vt.contractAddress,\n );\n\n const isTransfer = Boolean(valueTransfer);\n const contractAddress = valueTransfer?.contractAddress as string;\n const decimals = valueTransfer?.decimal as number;\n const symbol = valueTransfer?.symbol as string;\n\n const value = BNToHex(\n new BN(valueTransfer?.amount ?? responseTransaction.value),\n );\n\n const to = valueTransfer ? address : responseTransaction.to;\n\n const error =\n status === TransactionStatus.failed\n ? new Error('Transaction failed')\n : (undefined as unknown as TransactionError);\n\n const transferInformation = isTransfer\n ? {\n contractAddress,\n decimals,\n symbol,\n }\n : undefined;\n\n return {\n blockNumber,\n chainId,\n error,\n hash,\n id,\n isTransfer,\n // Populated by TransactionController when added to state\n networkClientId: '',\n status,\n time,\n toSmartContract: false,\n transferInformation,\n txParams: {\n chainId,\n from,\n gas,\n gasPrice,\n gasUsed,\n nonce,\n to,\n value,\n },\n type,\n verifiedOnBlockchain,\n };\n }\n\n #updateCache({\n chainIds,\n cursor,\n request,\n startTimestamp,\n }: {\n chainIds: Hex[];\n cursor?: string;\n request: RemoteTransactionSourceRequest;\n startTimestamp?: number;\n }) {\n if (!cursor && !startTimestamp) {\n log('Cache not updated');\n return;\n }\n\n const { address, updateCache } = request;\n const cursorCacheKey = this.#getCursorCacheKey(chainIds, address);\n const timestampCacheKey = this.#getTimestampCacheKey(chainIds, address);\n\n updateCache((cache) => {\n if (cursor) {\n cache[cursorCacheKey] = cursor;\n delete cache[timestampCacheKey];\n\n log('Updated cursor in cache', { cursorCacheKey, newCursor: cursor });\n } else {\n cache[timestampCacheKey] = startTimestamp;\n\n log('Updated timestamp in cache', {\n timestampCacheKey,\n newTimestamp: startTimestamp,\n });\n }\n });\n }\n\n #getStartTimestamp({\n cursor,\n queryEntireHistory,\n timestamp,\n }: {\n cursor?: string;\n queryEntireHistory: boolean;\n timestamp?: number;\n }): number | undefined {\n if (queryEntireHistory || cursor) {\n return undefined;\n }\n\n if (timestamp) {\n return timestamp;\n }\n\n return this.#getTimestampSeconds(Date.now() - RECENT_HISTORY_DURATION_MS);\n }\n\n #getCursorCacheKey(chainIds: Hex[], address: Hex): string {\n return `accounts-api#${chainIds.join(',')}#${address}`;\n }\n\n #getCacheCursor(\n cache: Record<string, unknown>,\n chainIds: Hex[],\n address: Hex,\n ): string | undefined {\n const key = this.#getCursorCacheKey(chainIds, address);\n return cache[key] as string | undefined;\n }\n\n #getTimestampCacheKey(chainIds: Hex[], address: Hex): string {\n return `accounts-api#timestamp#${chainIds.join(',')}#${address}`;\n }\n\n #getCacheTimestamp(\n cache: Record<string, unknown>,\n chainIds: Hex[],\n address: Hex,\n ): number | undefined {\n const key = this.#getTimestampCacheKey(chainIds, address);\n return cache[key] as number | undefined;\n }\n\n #getTimestampSeconds(timestampMs: number): number {\n return Math.floor(timestampMs / 1000);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"AccountsApiRemoteTransactionSource.mjs","sourceRoot":"","sources":["../../src/helpers/AccountsApiRemoteTransactionSource.ts"],"names":[],"mappings":"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","sourcesContent":["import { BNToHex } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport BN from 'bn.js';\nimport { v1 as random } from 'uuid';\n\nimport { determineTransactionType } from '..';\nimport type {\n GetAccountTransactionsResponse,\n TransactionResponse,\n} from '../api/accounts-api';\nimport { getAccountTransactions } from '../api/accounts-api';\nimport { CHAIN_IDS } from '../constants';\nimport { createModuleLogger, incomingTransactionsLogger } from '../logger';\nimport type {\n RemoteTransactionSource,\n RemoteTransactionSourceRequest,\n TransactionError,\n TransactionMeta,\n} from '../types';\nimport { TransactionStatus, TransactionType } from '../types';\n\nexport const SUPPORTED_CHAIN_IDS: Hex[] = [\n CHAIN_IDS.MAINNET,\n CHAIN_IDS.POLYGON,\n CHAIN_IDS.BSC,\n CHAIN_IDS.LINEA_MAINNET,\n CHAIN_IDS.BASE,\n CHAIN_IDS.OPTIMISM,\n CHAIN_IDS.ARBITRUM,\n CHAIN_IDS.SCROLL,\n CHAIN_IDS.SEI,\n];\n\nconst log = createModuleLogger(\n incomingTransactionsLogger,\n 'accounts-api-source',\n);\n\n/**\n * A RemoteTransactionSource that fetches incoming transactions using the Accounts API.\n */\nexport class AccountsApiRemoteTransactionSource\n implements RemoteTransactionSource\n{\n getSupportedChains(): Hex[] {\n return SUPPORTED_CHAIN_IDS;\n }\n\n async fetchTransactions(\n request: RemoteTransactionSourceRequest,\n ): Promise<TransactionMeta[]> {\n const { address } = request;\n\n const responseTransactions = await this.#queryTransactions(\n request,\n SUPPORTED_CHAIN_IDS,\n );\n\n log(\n 'Fetched transactions',\n responseTransactions.length,\n responseTransactions,\n );\n\n const normalizedTransactions = await Promise.all(\n responseTransactions.map((tx) => this.#normalizeTransaction(address, tx)),\n );\n\n log('Normalized transactions', normalizedTransactions);\n\n const filteredTransactions = this.#filterTransactions(\n request,\n normalizedTransactions,\n );\n\n log(\n 'Filtered transactions',\n filteredTransactions.length,\n filteredTransactions,\n );\n\n return filteredTransactions;\n }\n\n async #queryTransactions(\n request: RemoteTransactionSourceRequest,\n chainIds: Hex[],\n ): Promise<TransactionResponse[]> {\n const { address, tags } = request;\n const transactions: TransactionResponse[] = [];\n\n try {\n const response = await getAccountTransactions({\n address,\n chainIds,\n sortDirection: 'DESC',\n tags,\n });\n\n if (response?.data) {\n transactions.push(...response.data);\n }\n } catch (error) {\n log('Error while fetching transactions', error);\n }\n\n return transactions;\n }\n\n #filterTransactions(\n request: RemoteTransactionSourceRequest,\n transactions: TransactionMeta[],\n ) {\n const { address, includeTokenTransfers, updateTransactions } = request;\n\n let filteredTransactions = transactions;\n\n if (!updateTransactions) {\n filteredTransactions = filteredTransactions.filter(\n (tx) => tx.txParams.to === address,\n );\n }\n\n if (!includeTokenTransfers) {\n filteredTransactions = filteredTransactions.filter(\n (tx) => !tx.isTransfer,\n );\n }\n\n return filteredTransactions;\n }\n\n async #normalizeTransaction(\n address: Hex,\n responseTransaction: GetAccountTransactionsResponse['data'][0],\n ): Promise<TransactionMeta> {\n const blockNumber = String(responseTransaction.blockNumber);\n const chainId = `0x${responseTransaction.chainId.toString(16)}` as Hex;\n const { hash } = responseTransaction;\n const time = new Date(responseTransaction.timestamp).getTime();\n const id = random({ msecs: time });\n const { from } = responseTransaction;\n const gas = BNToHex(new BN(responseTransaction.gas));\n const gasPrice = BNToHex(new BN(responseTransaction.gasPrice));\n const gasUsed = BNToHex(new BN(responseTransaction.gasUsed));\n const nonce = BNToHex(new BN(responseTransaction.nonce));\n const data = responseTransaction.methodId;\n const type = TransactionType.incoming;\n const verifiedOnBlockchain = false;\n\n const status = responseTransaction.isError\n ? TransactionStatus.failed\n : TransactionStatus.confirmed;\n\n const valueTransfer = responseTransaction.valueTransfers.find(\n (vt) =>\n (vt.to.toLowerCase() === address.toLowerCase() ||\n vt.from.toLowerCase() === address.toLowerCase()) &&\n vt.contractAddress,\n );\n\n const isIncomingTokenTransfer =\n valueTransfer?.to.toLowerCase() === address.toLowerCase() &&\n from.toLowerCase() !== address.toLowerCase();\n\n const isOutgoing = from.toLowerCase() === address.toLowerCase();\n const amount = valueTransfer?.amount;\n const contractAddress = valueTransfer?.contractAddress as string;\n const decimals = valueTransfer?.decimal as number;\n const symbol = valueTransfer?.symbol as string;\n\n const value = BNToHex(\n new BN(\n isIncomingTokenTransfer\n ? (valueTransfer?.amount ?? responseTransaction.value)\n : responseTransaction.value,\n ),\n );\n\n const to = isIncomingTokenTransfer ? address : responseTransaction.to;\n\n const error =\n status === TransactionStatus.failed\n ? new Error('Transaction failed')\n : (undefined as unknown as TransactionError);\n\n const transferInformation = valueTransfer\n ? {\n amount,\n contractAddress,\n decimals,\n symbol,\n }\n : undefined;\n\n const meta: TransactionMeta = {\n blockNumber,\n chainId,\n error,\n hash,\n id,\n isTransfer: isIncomingTokenTransfer,\n // Populated by TransactionController when added to state\n networkClientId: '',\n status,\n time,\n toSmartContract: false,\n transferInformation,\n txParams: {\n chainId,\n data,\n from,\n gas,\n gasPrice,\n gasUsed,\n nonce,\n to,\n value,\n },\n type,\n verifiedOnBlockchain,\n };\n\n if (isOutgoing) {\n meta.type = (await determineTransactionType(meta.txParams)).type;\n }\n\n return meta;\n }\n}\n"]}
|
|
@@ -13,7 +13,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
13
13
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
15
|
};
|
|
16
|
-
var _GasFeePoller_instances, _GasFeePoller_findNetworkClientIdByChainId, _GasFeePoller_gasFeeFlows, _GasFeePoller_getGasFeeControllerEstimates, _GasFeePoller_getProvider, _GasFeePoller_getTransactions, _GasFeePoller_layer1GasFeeFlows, _GasFeePoller_messenger, _GasFeePoller_timeout, _GasFeePoller_running, _GasFeePoller_start, _GasFeePoller_stop, _GasFeePoller_onTimeout, _GasFeePoller_updateUnapprovedTransactions, _GasFeePoller_updateUnapprovedTransaction, _GasFeePoller_updateTransactionGasFeeEstimates, _GasFeePoller_updateTransactionLayer1GasFee, _GasFeePoller_getUnapprovedTransactions, _GasFeePoller_getGasFeeControllerData;
|
|
16
|
+
var _GasFeePoller_instances, _GasFeePoller_findNetworkClientIdByChainId, _GasFeePoller_gasFeeFlows, _GasFeePoller_getGasFeeControllerEstimates, _GasFeePoller_getProvider, _GasFeePoller_getTransactions, _GasFeePoller_getTransactionBatches, _GasFeePoller_layer1GasFeeFlows, _GasFeePoller_messenger, _GasFeePoller_timeout, _GasFeePoller_running, _GasFeePoller_start, _GasFeePoller_stop, _GasFeePoller_onTimeout, _GasFeePoller_updateUnapprovedTransactions, _GasFeePoller_updateUnapprovedTransactionBatches, _GasFeePoller_updateUnapprovedTransaction, _GasFeePoller_updateUnapprovedTransactionBatch, _GasFeePoller_updateTransactionGasFeeEstimates, _GasFeePoller_updateTransactionLayer1GasFee, _GasFeePoller_getUnapprovedTransactions, _GasFeePoller_getUnapprovedTransactionBatches, _GasFeePoller_getGasFeeControllerData;
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.updateTransactionGasEstimates = exports.updateTransactionGasProperties = exports.GasFeePoller = void 0;
|
|
19
19
|
const eth_query_1 = __importDefault(require("@metamask/eth-query"));
|
|
@@ -21,6 +21,7 @@ const utils_1 = require("@metamask/utils");
|
|
|
21
21
|
// This package purposefully relies on Node's EventEmitter module.
|
|
22
22
|
// eslint-disable-next-line import-x/no-nodejs-modules
|
|
23
23
|
const events_1 = __importDefault(require("events"));
|
|
24
|
+
const DefaultGasFeeFlow_1 = require("../gas-flows/DefaultGasFeeFlow.cjs");
|
|
24
25
|
const logger_1 = require("../logger.cjs");
|
|
25
26
|
const types_1 = require("../types.cjs");
|
|
26
27
|
const gas_flow_1 = require("../utils/gas-flow.cjs");
|
|
@@ -40,11 +41,12 @@ class GasFeePoller {
|
|
|
40
41
|
* @param options.getGasFeeControllerEstimates - Callback to obtain the default fee estimates.
|
|
41
42
|
* @param options.getProvider - Callback to obtain a provider instance.
|
|
42
43
|
* @param options.getTransactions - Callback to obtain the transaction data.
|
|
44
|
+
* @param options.getTransactionBatches - Callback to obtain the transaction batch data.
|
|
43
45
|
* @param options.layer1GasFeeFlows - The layer 1 gas fee flows to use to obtain suitable layer 1 gas fees.
|
|
44
46
|
* @param options.messenger - The TransactionControllerMessenger instance.
|
|
45
47
|
* @param options.onStateChange - Callback to register a listener for controller state changes.
|
|
46
48
|
*/
|
|
47
|
-
constructor({ findNetworkClientIdByChainId, gasFeeFlows, getGasFeeControllerEstimates, getProvider, getTransactions, layer1GasFeeFlows, messenger, onStateChange, }) {
|
|
49
|
+
constructor({ findNetworkClientIdByChainId, gasFeeFlows, getGasFeeControllerEstimates, getProvider, getTransactions, getTransactionBatches, layer1GasFeeFlows, messenger, onStateChange, }) {
|
|
48
50
|
_GasFeePoller_instances.add(this);
|
|
49
51
|
this.hub = new events_1.default();
|
|
50
52
|
_GasFeePoller_findNetworkClientIdByChainId.set(this, void 0);
|
|
@@ -52,6 +54,7 @@ class GasFeePoller {
|
|
|
52
54
|
_GasFeePoller_getGasFeeControllerEstimates.set(this, void 0);
|
|
53
55
|
_GasFeePoller_getProvider.set(this, void 0);
|
|
54
56
|
_GasFeePoller_getTransactions.set(this, void 0);
|
|
57
|
+
_GasFeePoller_getTransactionBatches.set(this, void 0);
|
|
55
58
|
_GasFeePoller_layer1GasFeeFlows.set(this, void 0);
|
|
56
59
|
_GasFeePoller_messenger.set(this, void 0);
|
|
57
60
|
_GasFeePoller_timeout.set(this, void 0);
|
|
@@ -62,10 +65,13 @@ class GasFeePoller {
|
|
|
62
65
|
__classPrivateFieldSet(this, _GasFeePoller_getGasFeeControllerEstimates, getGasFeeControllerEstimates, "f");
|
|
63
66
|
__classPrivateFieldSet(this, _GasFeePoller_getProvider, getProvider, "f");
|
|
64
67
|
__classPrivateFieldSet(this, _GasFeePoller_getTransactions, getTransactions, "f");
|
|
68
|
+
__classPrivateFieldSet(this, _GasFeePoller_getTransactionBatches, getTransactionBatches, "f");
|
|
65
69
|
__classPrivateFieldSet(this, _GasFeePoller_messenger, messenger, "f");
|
|
66
70
|
onStateChange(() => {
|
|
67
71
|
const unapprovedTransactions = __classPrivateFieldGet(this, _GasFeePoller_instances, "m", _GasFeePoller_getUnapprovedTransactions).call(this);
|
|
68
|
-
|
|
72
|
+
const unapprovedTransactionBatches = __classPrivateFieldGet(this, _GasFeePoller_instances, "m", _GasFeePoller_getUnapprovedTransactionBatches).call(this);
|
|
73
|
+
if (unapprovedTransactions.length ||
|
|
74
|
+
unapprovedTransactionBatches.length) {
|
|
69
75
|
__classPrivateFieldGet(this, _GasFeePoller_instances, "m", _GasFeePoller_start).call(this);
|
|
70
76
|
}
|
|
71
77
|
else {
|
|
@@ -75,7 +81,7 @@ class GasFeePoller {
|
|
|
75
81
|
}
|
|
76
82
|
}
|
|
77
83
|
exports.GasFeePoller = GasFeePoller;
|
|
78
|
-
_GasFeePoller_findNetworkClientIdByChainId = new WeakMap(), _GasFeePoller_gasFeeFlows = new WeakMap(), _GasFeePoller_getGasFeeControllerEstimates = new WeakMap(), _GasFeePoller_getProvider = new WeakMap(), _GasFeePoller_getTransactions = new WeakMap(), _GasFeePoller_layer1GasFeeFlows = new WeakMap(), _GasFeePoller_messenger = new WeakMap(), _GasFeePoller_timeout = new WeakMap(), _GasFeePoller_running = new WeakMap(), _GasFeePoller_instances = new WeakSet(), _GasFeePoller_start = function _GasFeePoller_start() {
|
|
84
|
+
_GasFeePoller_findNetworkClientIdByChainId = new WeakMap(), _GasFeePoller_gasFeeFlows = new WeakMap(), _GasFeePoller_getGasFeeControllerEstimates = new WeakMap(), _GasFeePoller_getProvider = new WeakMap(), _GasFeePoller_getTransactions = new WeakMap(), _GasFeePoller_getTransactionBatches = new WeakMap(), _GasFeePoller_layer1GasFeeFlows = new WeakMap(), _GasFeePoller_messenger = new WeakMap(), _GasFeePoller_timeout = new WeakMap(), _GasFeePoller_running = new WeakMap(), _GasFeePoller_instances = new WeakSet(), _GasFeePoller_start = function _GasFeePoller_start() {
|
|
79
85
|
if (__classPrivateFieldGet(this, _GasFeePoller_running, "f")) {
|
|
80
86
|
return;
|
|
81
87
|
}
|
|
@@ -94,6 +100,7 @@ _GasFeePoller_findNetworkClientIdByChainId = new WeakMap(), _GasFeePoller_gasFee
|
|
|
94
100
|
log('Stopped polling');
|
|
95
101
|
}, _GasFeePoller_onTimeout = async function _GasFeePoller_onTimeout() {
|
|
96
102
|
await __classPrivateFieldGet(this, _GasFeePoller_instances, "m", _GasFeePoller_updateUnapprovedTransactions).call(this);
|
|
103
|
+
await __classPrivateFieldGet(this, _GasFeePoller_instances, "m", _GasFeePoller_updateUnapprovedTransactionBatches).call(this);
|
|
97
104
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
98
105
|
__classPrivateFieldSet(this, _GasFeePoller_timeout, setTimeout(() => __classPrivateFieldGet(this, _GasFeePoller_instances, "m", _GasFeePoller_onTimeout).call(this), INTERVAL_MILLISECONDS), "f");
|
|
99
106
|
}, _GasFeePoller_updateUnapprovedTransactions = async function _GasFeePoller_updateUnapprovedTransactions() {
|
|
@@ -109,6 +116,19 @@ _GasFeePoller_findNetworkClientIdByChainId = new WeakMap(), _GasFeePoller_gasFee
|
|
|
109
116
|
const gasFeeControllerData = gasFeeControllerDataByChainId.get(chainId);
|
|
110
117
|
return __classPrivateFieldGet(this, _GasFeePoller_instances, "m", _GasFeePoller_updateUnapprovedTransaction).call(this, tx, gasFeeControllerData);
|
|
111
118
|
}));
|
|
119
|
+
}, _GasFeePoller_updateUnapprovedTransactionBatches = async function _GasFeePoller_updateUnapprovedTransactionBatches() {
|
|
120
|
+
const unapprovedTransactionBatches = __classPrivateFieldGet(this, _GasFeePoller_instances, "m", _GasFeePoller_getUnapprovedTransactionBatches).call(this);
|
|
121
|
+
if (!unapprovedTransactionBatches.length) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
log('Found unapproved transaction batches', unapprovedTransactionBatches.length);
|
|
125
|
+
const gasFeeControllerDataByChainId = await __classPrivateFieldGet(this, _GasFeePoller_instances, "m", _GasFeePoller_getGasFeeControllerData).call(this, unapprovedTransactionBatches);
|
|
126
|
+
log('Retrieved gas fee controller data', gasFeeControllerDataByChainId);
|
|
127
|
+
await Promise.all(unapprovedTransactionBatches.flatMap((txBatch) => {
|
|
128
|
+
const { chainId } = txBatch;
|
|
129
|
+
const gasFeeControllerData = gasFeeControllerDataByChainId.get(chainId);
|
|
130
|
+
return __classPrivateFieldGet(this, _GasFeePoller_instances, "m", _GasFeePoller_updateUnapprovedTransactionBatch).call(this, txBatch, gasFeeControllerData);
|
|
131
|
+
}));
|
|
112
132
|
}, _GasFeePoller_updateUnapprovedTransaction = async function _GasFeePoller_updateUnapprovedTransaction(transactionMeta, gasFeeControllerData) {
|
|
113
133
|
const { id } = transactionMeta;
|
|
114
134
|
const [gasFeeEstimatesResponse, layer1GasFee] = await Promise.all([
|
|
@@ -124,6 +144,40 @@ _GasFeePoller_findNetworkClientIdByChainId = new WeakMap(), _GasFeePoller_gasFee
|
|
|
124
144
|
gasFeeEstimatesLoaded: gasFeeEstimatesResponse?.gasFeeEstimatesLoaded,
|
|
125
145
|
layer1GasFee,
|
|
126
146
|
});
|
|
147
|
+
}, _GasFeePoller_updateUnapprovedTransactionBatch = async function _GasFeePoller_updateUnapprovedTransactionBatch(txBatchMeta, gasFeeControllerData) {
|
|
148
|
+
const { id } = txBatchMeta;
|
|
149
|
+
const ethQuery = new eth_query_1.default(__classPrivateFieldGet(this, _GasFeePoller_getProvider, "f").call(this, txBatchMeta.networkClientId));
|
|
150
|
+
const defaultGasFeeFlow = new DefaultGasFeeFlow_1.DefaultGasFeeFlow();
|
|
151
|
+
const request = {
|
|
152
|
+
ethQuery,
|
|
153
|
+
gasFeeControllerData,
|
|
154
|
+
messenger: __classPrivateFieldGet(this, _GasFeePoller_messenger, "f"),
|
|
155
|
+
transactionMeta: {
|
|
156
|
+
...txBatchMeta,
|
|
157
|
+
txParams: {
|
|
158
|
+
...txBatchMeta.transactions?.[0],
|
|
159
|
+
from: txBatchMeta.from,
|
|
160
|
+
gas: txBatchMeta.gas,
|
|
161
|
+
},
|
|
162
|
+
time: Date.now(),
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
let gasFeeEstimates;
|
|
166
|
+
try {
|
|
167
|
+
const response = await defaultGasFeeFlow.getGasFees(request);
|
|
168
|
+
gasFeeEstimates = response.estimates;
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
log('Failed to get gas fees for batch', txBatchMeta.id, error);
|
|
172
|
+
}
|
|
173
|
+
if (!gasFeeEstimates) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
this.hub.emit('transaction-batch-updated', {
|
|
177
|
+
transactionBatchId: id,
|
|
178
|
+
gasFeeEstimates,
|
|
179
|
+
gasFeeEstimatesLoaded: true,
|
|
180
|
+
});
|
|
127
181
|
}, _GasFeePoller_updateTransactionGasFeeEstimates = async function _GasFeePoller_updateTransactionGasFeeEstimates(transactionMeta, gasFeeControllerData) {
|
|
128
182
|
const { networkClientId } = transactionMeta;
|
|
129
183
|
const ethQuery = new eth_query_1.default(__classPrivateFieldGet(this, _GasFeePoller_getProvider, "f").call(this, networkClientId));
|
|
@@ -170,6 +224,8 @@ _GasFeePoller_findNetworkClientIdByChainId = new WeakMap(), _GasFeePoller_gasFee
|
|
|
170
224
|
return layer1GasFee;
|
|
171
225
|
}, _GasFeePoller_getUnapprovedTransactions = function _GasFeePoller_getUnapprovedTransactions() {
|
|
172
226
|
return __classPrivateFieldGet(this, _GasFeePoller_getTransactions, "f").call(this).filter((tx) => tx.status === types_1.TransactionStatus.unapproved);
|
|
227
|
+
}, _GasFeePoller_getUnapprovedTransactionBatches = function _GasFeePoller_getUnapprovedTransactionBatches() {
|
|
228
|
+
return __classPrivateFieldGet(this, _GasFeePoller_getTransactionBatches, "f").call(this).filter((batch) => batch.status === types_1.TransactionStatus.unapproved);
|
|
173
229
|
}, _GasFeePoller_getGasFeeControllerData = async function _GasFeePoller_getGasFeeControllerData(transactions) {
|
|
174
230
|
const networkClientIdsByChainId = new Map();
|
|
175
231
|
for (const transaction of transactions) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GasFeePoller.cjs","sourceRoot":"","sources":["../../src/helpers/GasFeePoller.ts"],"names":[],"mappings":"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","sourcesContent":["import EthQuery from '@metamask/eth-query';\nimport type {\n FetchGasFeeEstimateOptions,\n GasFeeState,\n} from '@metamask/gas-fee-controller';\nimport type { NetworkClientId, Provider } from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\n// This package purposefully relies on Node's EventEmitter module.\n// eslint-disable-next-line import-x/no-nodejs-modules\nimport EventEmitter from 'events';\n\nimport { projectLogger } from '../logger';\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type {\n GasFeeEstimates,\n GasFeeFlow,\n GasFeeFlowRequest,\n GasPriceGasFeeEstimates,\n FeeMarketGasFeeEstimates,\n Layer1GasFeeFlow,\n LegacyGasFeeEstimates,\n TransactionMeta,\n TransactionParams,\n} from '../types';\nimport {\n GasFeeEstimateLevel,\n GasFeeEstimateType,\n TransactionStatus,\n TransactionEnvelopeType,\n} from '../types';\nimport { getGasFeeFlow } from '../utils/gas-flow';\nimport { getTransactionLayer1GasFee } from '../utils/layer1-gas-fee-flow';\n\nconst log = createModuleLogger(projectLogger, 'gas-fee-poller');\n\nconst INTERVAL_MILLISECONDS = 10000;\n\n/**\n * Automatically polls and updates suggested gas fees on unapproved transactions.\n */\nexport class GasFeePoller {\n hub: EventEmitter = new EventEmitter();\n\n readonly #findNetworkClientIdByChainId: (\n chainId: Hex,\n ) => NetworkClientId | undefined;\n\n readonly #gasFeeFlows: GasFeeFlow[];\n\n readonly #getGasFeeControllerEstimates: (\n options: FetchGasFeeEstimateOptions,\n ) => Promise<GasFeeState>;\n\n readonly #getProvider: (networkClientId: NetworkClientId) => Provider;\n\n readonly #getTransactions: () => TransactionMeta[];\n\n readonly #layer1GasFeeFlows: Layer1GasFeeFlow[];\n\n readonly #messenger: TransactionControllerMessenger;\n\n #timeout: ReturnType<typeof setTimeout> | undefined;\n\n #running = false;\n\n /**\n * Constructs a new instance of the GasFeePoller.\n *\n * @param options - The options for this instance.\n * @param options.findNetworkClientIdByChainId - Callback to find the network client ID by chain ID.\n * @param options.gasFeeFlows - The gas fee flows to use to obtain suitable gas fees.\n * @param options.getGasFeeControllerEstimates - Callback to obtain the default fee estimates.\n * @param options.getProvider - Callback to obtain a provider instance.\n * @param options.getTransactions - Callback to obtain the transaction data.\n * @param options.layer1GasFeeFlows - The layer 1 gas fee flows to use to obtain suitable layer 1 gas fees.\n * @param options.messenger - The TransactionControllerMessenger instance.\n * @param options.onStateChange - Callback to register a listener for controller state changes.\n */\n constructor({\n findNetworkClientIdByChainId,\n gasFeeFlows,\n getGasFeeControllerEstimates,\n getProvider,\n getTransactions,\n layer1GasFeeFlows,\n messenger,\n onStateChange,\n }: {\n findNetworkClientIdByChainId: (chainId: Hex) => NetworkClientId | undefined;\n gasFeeFlows: GasFeeFlow[];\n getGasFeeControllerEstimates: (\n options: FetchGasFeeEstimateOptions,\n ) => Promise<GasFeeState>;\n getProvider: (networkClientId: NetworkClientId) => Provider;\n getTransactions: () => TransactionMeta[];\n layer1GasFeeFlows: Layer1GasFeeFlow[];\n messenger: TransactionControllerMessenger;\n onStateChange: (listener: () => void) => void;\n }) {\n this.#findNetworkClientIdByChainId = findNetworkClientIdByChainId;\n this.#gasFeeFlows = gasFeeFlows;\n this.#layer1GasFeeFlows = layer1GasFeeFlows;\n this.#getGasFeeControllerEstimates = getGasFeeControllerEstimates;\n this.#getProvider = getProvider;\n this.#getTransactions = getTransactions;\n this.#messenger = messenger;\n\n onStateChange(() => {\n const unapprovedTransactions = this.#getUnapprovedTransactions();\n\n if (unapprovedTransactions.length) {\n this.#start();\n } else {\n this.#stop();\n }\n });\n }\n\n #start() {\n if (this.#running) {\n return;\n }\n\n // Intentionally not awaiting since this starts the timeout chain.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.#onTimeout();\n\n this.#running = true;\n\n log('Started polling');\n }\n\n #stop() {\n if (!this.#running) {\n return;\n }\n\n clearTimeout(this.#timeout);\n\n this.#timeout = undefined;\n this.#running = false;\n\n log('Stopped polling');\n }\n\n async #onTimeout() {\n await this.#updateUnapprovedTransactions();\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#timeout = setTimeout(() => this.#onTimeout(), INTERVAL_MILLISECONDS);\n }\n\n async #updateUnapprovedTransactions() {\n const unapprovedTransactions = this.#getUnapprovedTransactions();\n\n if (!unapprovedTransactions.length) {\n return;\n }\n\n log('Found unapproved transactions', unapprovedTransactions.length);\n\n const gasFeeControllerDataByChainId = await this.#getGasFeeControllerData(\n unapprovedTransactions,\n );\n\n log('Retrieved gas fee controller data', gasFeeControllerDataByChainId);\n\n await Promise.all(\n unapprovedTransactions.flatMap((tx) => {\n const { chainId } = tx;\n\n const gasFeeControllerData = gasFeeControllerDataByChainId.get(\n chainId,\n ) as GasFeeState;\n\n return this.#updateUnapprovedTransaction(tx, gasFeeControllerData);\n }),\n );\n }\n\n async #updateUnapprovedTransaction(\n transactionMeta: TransactionMeta,\n gasFeeControllerData: GasFeeState,\n ) {\n const { id } = transactionMeta;\n\n const [gasFeeEstimatesResponse, layer1GasFee] = await Promise.all([\n this.#updateTransactionGasFeeEstimates(\n transactionMeta,\n gasFeeControllerData,\n ),\n this.#updateTransactionLayer1GasFee(transactionMeta),\n ]);\n\n if (!gasFeeEstimatesResponse && !layer1GasFee) {\n return;\n }\n\n this.hub.emit('transaction-updated', {\n transactionId: id,\n gasFeeEstimates: gasFeeEstimatesResponse?.gasFeeEstimates,\n gasFeeEstimatesLoaded: gasFeeEstimatesResponse?.gasFeeEstimatesLoaded,\n layer1GasFee,\n });\n }\n\n async #updateTransactionGasFeeEstimates(\n transactionMeta: TransactionMeta,\n gasFeeControllerData: GasFeeState,\n ): Promise<\n | { gasFeeEstimates?: GasFeeEstimates; gasFeeEstimatesLoaded: boolean }\n | undefined\n > {\n const { networkClientId } = transactionMeta;\n\n const ethQuery = new EthQuery(this.#getProvider(networkClientId));\n const gasFeeFlow = getGasFeeFlow(\n transactionMeta,\n this.#gasFeeFlows,\n this.#messenger,\n );\n\n if (gasFeeFlow) {\n log(\n 'Found gas fee flow',\n gasFeeFlow.constructor.name,\n transactionMeta.id,\n );\n }\n\n const request: GasFeeFlowRequest = {\n ethQuery,\n gasFeeControllerData,\n messenger: this.#messenger,\n transactionMeta,\n };\n\n let gasFeeEstimates: GasFeeEstimates | undefined;\n\n if (gasFeeFlow) {\n try {\n const response = await gasFeeFlow.getGasFees(request);\n gasFeeEstimates = response.estimates;\n } catch (error) {\n log('Failed to get suggested gas fees', transactionMeta.id, error);\n }\n }\n\n if (!gasFeeEstimates && transactionMeta.gasFeeEstimatesLoaded) {\n return undefined;\n }\n\n log('Updated gas fee estimates', {\n gasFeeEstimates,\n transaction: transactionMeta.id,\n });\n\n return { gasFeeEstimates, gasFeeEstimatesLoaded: true };\n }\n\n async #updateTransactionLayer1GasFee(\n transactionMeta: TransactionMeta,\n ): Promise<Hex | undefined> {\n const { networkClientId } = transactionMeta;\n const provider = this.#getProvider(networkClientId);\n\n const layer1GasFee = await getTransactionLayer1GasFee({\n layer1GasFeeFlows: this.#layer1GasFeeFlows,\n messenger: this.#messenger,\n provider,\n transactionMeta,\n });\n\n if (layer1GasFee) {\n log('Updated layer 1 gas fee', layer1GasFee, transactionMeta.id);\n }\n\n return layer1GasFee;\n }\n\n #getUnapprovedTransactions() {\n return this.#getTransactions().filter(\n (tx) => tx.status === TransactionStatus.unapproved,\n );\n }\n\n async #getGasFeeControllerData(\n transactions: TransactionMeta[],\n ): Promise<Map<string, GasFeeState>> {\n const networkClientIdsByChainId = new Map<Hex, NetworkClientId>();\n\n for (const transaction of transactions) {\n const { chainId, networkClientId: transactionNetworkClientId } =\n transaction;\n\n if (networkClientIdsByChainId.has(chainId)) {\n continue;\n }\n\n const networkClientId =\n transactionNetworkClientId ??\n (this.#findNetworkClientIdByChainId(chainId) as string);\n\n networkClientIdsByChainId.set(chainId, networkClientId);\n }\n\n log('Extracted network client IDs by chain ID', networkClientIdsByChainId);\n\n const entryPromises = Array.from(networkClientIdsByChainId.entries()).map(\n async ([chainId, networkClientId]) => {\n return [\n chainId,\n await this.#getGasFeeControllerEstimates({ networkClientId }),\n ] as const;\n },\n );\n\n return new Map(await Promise.all(entryPromises));\n }\n}\n\n/**\n * Updates gas properties for transaction.\n *\n * @param args - Argument bag.\n * @param args.txMeta - The transaction meta.\n * @param args.gasFeeEstimates - The gas fee estimates.\n * @param args.gasFeeEstimatesLoaded - Whether the gas fee estimates are loaded.\n * @param args.isTxParamsGasFeeUpdatesEnabled - Whether to update the gas fee properties in `txParams`.\n * @param args.layer1GasFee - The layer 1 gas fee.\n */\nexport function updateTransactionGasProperties({\n gasFeeEstimates,\n gasFeeEstimatesLoaded,\n isTxParamsGasFeeUpdatesEnabled,\n layer1GasFee,\n txMeta,\n}: {\n gasFeeEstimates?: GasFeeEstimates;\n gasFeeEstimatesLoaded?: boolean;\n isTxParamsGasFeeUpdatesEnabled: (transactionMeta: TransactionMeta) => boolean;\n layer1GasFee?: Hex;\n txMeta: TransactionMeta;\n}): void {\n const userFeeLevel = txMeta.userFeeLevel as GasFeeEstimateLevel;\n const isUsingGasFeeEstimateLevel =\n Object.values(GasFeeEstimateLevel).includes(userFeeLevel);\n const shouldUpdateTxParamsGasFees = isTxParamsGasFeeUpdatesEnabled(txMeta);\n\n if (\n shouldUpdateTxParamsGasFees &&\n isUsingGasFeeEstimateLevel &&\n gasFeeEstimates\n ) {\n const isEIP1559Compatible =\n txMeta.txParams.type !== TransactionEnvelopeType.legacy;\n\n updateGasFeeParameters(\n txMeta.txParams,\n gasFeeEstimates,\n userFeeLevel,\n isEIP1559Compatible,\n );\n }\n\n if (gasFeeEstimates) {\n txMeta.gasFeeEstimates = gasFeeEstimates;\n }\n\n if (gasFeeEstimatesLoaded !== undefined) {\n txMeta.gasFeeEstimatesLoaded = gasFeeEstimatesLoaded;\n }\n\n if (layer1GasFee) {\n txMeta.layer1GasFee = layer1GasFee;\n }\n}\n\n/**\n * Updates `txParams` gas values accordingly with given `userFeeLevel` from `txMeta.gasFeeEstimates`.\n *\n * @param args - Argument bag.\n * @param args.txMeta - The transaction meta.\n * @param args.userFeeLevel - The user fee level.\n */\nexport function updateTransactionGasEstimates({\n txMeta,\n userFeeLevel,\n}: {\n txMeta: TransactionMeta;\n userFeeLevel: GasFeeEstimateLevel;\n}): void {\n const { txParams, gasFeeEstimates } = txMeta;\n\n if (!gasFeeEstimates) {\n return;\n }\n\n const isEIP1559Compatible =\n txMeta.txParams.type !== TransactionEnvelopeType.legacy;\n\n updateGasFeeParameters(\n txParams,\n gasFeeEstimates,\n userFeeLevel,\n isEIP1559Compatible,\n );\n}\n\n/**\n * Updates gas fee parameters based on transaction type and gas estimate type\n *\n * @param txParams - The transaction parameters to update\n * @param gasFeeEstimates - The gas fee estimates\n * @param userFeeLevel - The user fee level\n * @param isEIP1559Compatible - Whether the transaction is EIP-1559 compatible\n */\nfunction updateGasFeeParameters(\n txParams: TransactionParams,\n gasFeeEstimates: GasFeeEstimates,\n userFeeLevel: GasFeeEstimateLevel,\n isEIP1559Compatible: boolean,\n): void {\n const { type: gasEstimateType } = gasFeeEstimates;\n\n if (isEIP1559Compatible) {\n // Handle EIP-1559 compatible transactions\n if (gasEstimateType === GasFeeEstimateType.FeeMarket) {\n const feeMarketGasFeeEstimates =\n gasFeeEstimates as FeeMarketGasFeeEstimates;\n txParams.maxFeePerGas =\n feeMarketGasFeeEstimates[userFeeLevel]?.maxFeePerGas;\n txParams.maxPriorityFeePerGas =\n feeMarketGasFeeEstimates[userFeeLevel]?.maxPriorityFeePerGas;\n }\n\n if (gasEstimateType === GasFeeEstimateType.GasPrice) {\n const gasPriceGasFeeEstimates =\n gasFeeEstimates as GasPriceGasFeeEstimates;\n txParams.maxFeePerGas = gasPriceGasFeeEstimates.gasPrice;\n txParams.maxPriorityFeePerGas = gasPriceGasFeeEstimates.gasPrice;\n }\n\n if (gasEstimateType === GasFeeEstimateType.Legacy) {\n const legacyGasFeeEstimates = gasFeeEstimates as LegacyGasFeeEstimates;\n const gasPrice = legacyGasFeeEstimates[userFeeLevel];\n txParams.maxFeePerGas = gasPrice;\n txParams.maxPriorityFeePerGas = gasPrice;\n }\n\n // Remove gasPrice for EIP-1559 transactions\n delete txParams.gasPrice;\n } else {\n // Handle non-EIP-1559 transactions\n if (gasEstimateType === GasFeeEstimateType.FeeMarket) {\n const feeMarketGasFeeEstimates =\n gasFeeEstimates as FeeMarketGasFeeEstimates;\n txParams.gasPrice = feeMarketGasFeeEstimates[userFeeLevel]?.maxFeePerGas;\n }\n\n if (gasEstimateType === GasFeeEstimateType.GasPrice) {\n const gasPriceGasFeeEstimates =\n gasFeeEstimates as GasPriceGasFeeEstimates;\n txParams.gasPrice = gasPriceGasFeeEstimates.gasPrice;\n }\n\n if (gasEstimateType === GasFeeEstimateType.Legacy) {\n const legacyGasFeeEstimates = gasFeeEstimates as LegacyGasFeeEstimates;\n txParams.gasPrice = legacyGasFeeEstimates[userFeeLevel];\n }\n\n // Remove EIP-1559 specific parameters for legacy transactions\n delete txParams.maxFeePerGas;\n delete txParams.maxPriorityFeePerGas;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"GasFeePoller.cjs","sourceRoot":"","sources":["../../src/helpers/GasFeePoller.ts"],"names":[],"mappings":"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","sourcesContent":["import EthQuery from '@metamask/eth-query';\nimport type {\n FetchGasFeeEstimateOptions,\n GasFeeState,\n} from '@metamask/gas-fee-controller';\nimport type { NetworkClientId, Provider } from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\n// This package purposefully relies on Node's EventEmitter module.\n// eslint-disable-next-line import-x/no-nodejs-modules\nimport EventEmitter from 'events';\n\nimport { DefaultGasFeeFlow } from '../gas-flows/DefaultGasFeeFlow';\nimport { projectLogger } from '../logger';\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type {\n GasFeeEstimates,\n GasFeeFlow,\n GasFeeFlowRequest,\n GasPriceGasFeeEstimates,\n FeeMarketGasFeeEstimates,\n Layer1GasFeeFlow,\n LegacyGasFeeEstimates,\n TransactionMeta,\n TransactionParams,\n TransactionBatchMeta,\n} from '../types';\nimport {\n GasFeeEstimateLevel,\n GasFeeEstimateType,\n TransactionStatus,\n TransactionEnvelopeType,\n} from '../types';\nimport { getGasFeeFlow } from '../utils/gas-flow';\nimport { getTransactionLayer1GasFee } from '../utils/layer1-gas-fee-flow';\n\nconst log = createModuleLogger(projectLogger, 'gas-fee-poller');\n\nconst INTERVAL_MILLISECONDS = 10000;\n\n/**\n * Automatically polls and updates suggested gas fees on unapproved transactions.\n */\nexport class GasFeePoller {\n hub: EventEmitter = new EventEmitter();\n\n readonly #findNetworkClientIdByChainId: (\n chainId: Hex,\n ) => NetworkClientId | undefined;\n\n readonly #gasFeeFlows: GasFeeFlow[];\n\n readonly #getGasFeeControllerEstimates: (\n options: FetchGasFeeEstimateOptions,\n ) => Promise<GasFeeState>;\n\n readonly #getProvider: (networkClientId: NetworkClientId) => Provider;\n\n readonly #getTransactions: () => TransactionMeta[];\n\n readonly #getTransactionBatches: () => TransactionBatchMeta[];\n\n readonly #layer1GasFeeFlows: Layer1GasFeeFlow[];\n\n readonly #messenger: TransactionControllerMessenger;\n\n #timeout: ReturnType<typeof setTimeout> | undefined;\n\n #running = false;\n\n /**\n * Constructs a new instance of the GasFeePoller.\n *\n * @param options - The options for this instance.\n * @param options.findNetworkClientIdByChainId - Callback to find the network client ID by chain ID.\n * @param options.gasFeeFlows - The gas fee flows to use to obtain suitable gas fees.\n * @param options.getGasFeeControllerEstimates - Callback to obtain the default fee estimates.\n * @param options.getProvider - Callback to obtain a provider instance.\n * @param options.getTransactions - Callback to obtain the transaction data.\n * @param options.getTransactionBatches - Callback to obtain the transaction batch data.\n * @param options.layer1GasFeeFlows - The layer 1 gas fee flows to use to obtain suitable layer 1 gas fees.\n * @param options.messenger - The TransactionControllerMessenger instance.\n * @param options.onStateChange - Callback to register a listener for controller state changes.\n */\n constructor({\n findNetworkClientIdByChainId,\n gasFeeFlows,\n getGasFeeControllerEstimates,\n getProvider,\n getTransactions,\n getTransactionBatches,\n layer1GasFeeFlows,\n messenger,\n onStateChange,\n }: {\n findNetworkClientIdByChainId: (chainId: Hex) => NetworkClientId | undefined;\n gasFeeFlows: GasFeeFlow[];\n getGasFeeControllerEstimates: (\n options: FetchGasFeeEstimateOptions,\n ) => Promise<GasFeeState>;\n getProvider: (networkClientId: NetworkClientId) => Provider;\n getTransactions: () => TransactionMeta[];\n getTransactionBatches: () => TransactionBatchMeta[];\n layer1GasFeeFlows: Layer1GasFeeFlow[];\n messenger: TransactionControllerMessenger;\n onStateChange: (listener: () => void) => void;\n }) {\n this.#findNetworkClientIdByChainId = findNetworkClientIdByChainId;\n this.#gasFeeFlows = gasFeeFlows;\n this.#layer1GasFeeFlows = layer1GasFeeFlows;\n this.#getGasFeeControllerEstimates = getGasFeeControllerEstimates;\n this.#getProvider = getProvider;\n this.#getTransactions = getTransactions;\n this.#getTransactionBatches = getTransactionBatches;\n this.#messenger = messenger;\n\n onStateChange(() => {\n const unapprovedTransactions = this.#getUnapprovedTransactions();\n const unapprovedTransactionBatches =\n this.#getUnapprovedTransactionBatches();\n\n if (\n unapprovedTransactions.length ||\n unapprovedTransactionBatches.length\n ) {\n this.#start();\n } else {\n this.#stop();\n }\n });\n }\n\n #start() {\n if (this.#running) {\n return;\n }\n\n // Intentionally not awaiting since this starts the timeout chain.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.#onTimeout();\n\n this.#running = true;\n\n log('Started polling');\n }\n\n #stop() {\n if (!this.#running) {\n return;\n }\n\n clearTimeout(this.#timeout);\n\n this.#timeout = undefined;\n this.#running = false;\n\n log('Stopped polling');\n }\n\n async #onTimeout() {\n await this.#updateUnapprovedTransactions();\n await this.#updateUnapprovedTransactionBatches();\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#timeout = setTimeout(() => this.#onTimeout(), INTERVAL_MILLISECONDS);\n }\n\n async #updateUnapprovedTransactions() {\n const unapprovedTransactions = this.#getUnapprovedTransactions();\n\n if (!unapprovedTransactions.length) {\n return;\n }\n\n log('Found unapproved transactions', unapprovedTransactions.length);\n\n const gasFeeControllerDataByChainId = await this.#getGasFeeControllerData(\n unapprovedTransactions,\n );\n\n log('Retrieved gas fee controller data', gasFeeControllerDataByChainId);\n\n await Promise.all(\n unapprovedTransactions.flatMap((tx) => {\n const { chainId } = tx;\n\n const gasFeeControllerData = gasFeeControllerDataByChainId.get(\n chainId,\n ) as GasFeeState;\n\n return this.#updateUnapprovedTransaction(tx, gasFeeControllerData);\n }),\n );\n }\n\n async #updateUnapprovedTransactionBatches() {\n const unapprovedTransactionBatches =\n this.#getUnapprovedTransactionBatches();\n\n if (!unapprovedTransactionBatches.length) {\n return;\n }\n\n log(\n 'Found unapproved transaction batches',\n unapprovedTransactionBatches.length,\n );\n\n const gasFeeControllerDataByChainId = await this.#getGasFeeControllerData(\n unapprovedTransactionBatches,\n );\n\n log('Retrieved gas fee controller data', gasFeeControllerDataByChainId);\n\n await Promise.all(\n unapprovedTransactionBatches.flatMap((txBatch) => {\n const { chainId } = txBatch;\n\n const gasFeeControllerData = gasFeeControllerDataByChainId.get(\n chainId,\n ) as GasFeeState;\n\n return this.#updateUnapprovedTransactionBatch(\n txBatch,\n gasFeeControllerData,\n );\n }),\n );\n }\n\n async #updateUnapprovedTransaction(\n transactionMeta: TransactionMeta,\n gasFeeControllerData: GasFeeState,\n ) {\n const { id } = transactionMeta;\n\n const [gasFeeEstimatesResponse, layer1GasFee] = await Promise.all([\n this.#updateTransactionGasFeeEstimates(\n transactionMeta,\n gasFeeControllerData,\n ),\n this.#updateTransactionLayer1GasFee(transactionMeta),\n ]);\n\n if (!gasFeeEstimatesResponse && !layer1GasFee) {\n return;\n }\n\n this.hub.emit('transaction-updated', {\n transactionId: id,\n gasFeeEstimates: gasFeeEstimatesResponse?.gasFeeEstimates,\n gasFeeEstimatesLoaded: gasFeeEstimatesResponse?.gasFeeEstimatesLoaded,\n layer1GasFee,\n });\n }\n\n async #updateUnapprovedTransactionBatch(\n txBatchMeta: TransactionBatchMeta,\n gasFeeControllerData: GasFeeState,\n ) {\n const { id } = txBatchMeta;\n\n const ethQuery = new EthQuery(\n this.#getProvider(txBatchMeta.networkClientId),\n );\n const defaultGasFeeFlow = new DefaultGasFeeFlow();\n const request: GasFeeFlowRequest = {\n ethQuery,\n gasFeeControllerData,\n messenger: this.#messenger,\n transactionMeta: {\n ...txBatchMeta,\n txParams: {\n ...txBatchMeta.transactions?.[0],\n from: txBatchMeta.from,\n gas: txBatchMeta.gas,\n },\n time: Date.now(),\n },\n };\n\n let gasFeeEstimates: GasFeeEstimates | undefined;\n\n try {\n const response = await defaultGasFeeFlow.getGasFees(request);\n\n gasFeeEstimates = response.estimates;\n } catch (error) {\n log('Failed to get gas fees for batch', txBatchMeta.id, error);\n }\n\n if (!gasFeeEstimates) {\n return;\n }\n\n this.hub.emit('transaction-batch-updated', {\n transactionBatchId: id,\n gasFeeEstimates,\n gasFeeEstimatesLoaded: true,\n });\n }\n\n async #updateTransactionGasFeeEstimates(\n transactionMeta: TransactionMeta,\n gasFeeControllerData: GasFeeState,\n ): Promise<\n | { gasFeeEstimates?: GasFeeEstimates; gasFeeEstimatesLoaded: boolean }\n | undefined\n > {\n const { networkClientId } = transactionMeta;\n\n const ethQuery = new EthQuery(this.#getProvider(networkClientId));\n const gasFeeFlow = getGasFeeFlow(\n transactionMeta,\n this.#gasFeeFlows,\n this.#messenger,\n );\n\n if (gasFeeFlow) {\n log(\n 'Found gas fee flow',\n gasFeeFlow.constructor.name,\n transactionMeta.id,\n );\n }\n\n const request: GasFeeFlowRequest = {\n ethQuery,\n gasFeeControllerData,\n messenger: this.#messenger,\n transactionMeta,\n };\n\n let gasFeeEstimates: GasFeeEstimates | undefined;\n\n if (gasFeeFlow) {\n try {\n const response = await gasFeeFlow.getGasFees(request);\n gasFeeEstimates = response.estimates;\n } catch (error) {\n log('Failed to get suggested gas fees', transactionMeta.id, error);\n }\n }\n\n if (!gasFeeEstimates && transactionMeta.gasFeeEstimatesLoaded) {\n return undefined;\n }\n\n log('Updated gas fee estimates', {\n gasFeeEstimates,\n transaction: transactionMeta.id,\n });\n\n return { gasFeeEstimates, gasFeeEstimatesLoaded: true };\n }\n\n async #updateTransactionLayer1GasFee(\n transactionMeta: TransactionMeta,\n ): Promise<Hex | undefined> {\n const { networkClientId } = transactionMeta;\n const provider = this.#getProvider(networkClientId);\n\n const layer1GasFee = await getTransactionLayer1GasFee({\n layer1GasFeeFlows: this.#layer1GasFeeFlows,\n messenger: this.#messenger,\n provider,\n transactionMeta,\n });\n\n if (layer1GasFee) {\n log('Updated layer 1 gas fee', layer1GasFee, transactionMeta.id);\n }\n\n return layer1GasFee;\n }\n\n #getUnapprovedTransactions() {\n return this.#getTransactions().filter(\n (tx) => tx.status === TransactionStatus.unapproved,\n );\n }\n\n #getUnapprovedTransactionBatches() {\n return this.#getTransactionBatches().filter(\n (batch) => batch.status === TransactionStatus.unapproved,\n );\n }\n\n async #getGasFeeControllerData(\n transactions: TransactionMeta[] | TransactionBatchMeta[],\n ): Promise<Map<string, GasFeeState>> {\n const networkClientIdsByChainId = new Map<Hex, NetworkClientId>();\n\n for (const transaction of transactions) {\n const { chainId, networkClientId: transactionNetworkClientId } =\n transaction;\n\n if (networkClientIdsByChainId.has(chainId)) {\n continue;\n }\n\n const networkClientId =\n transactionNetworkClientId ??\n (this.#findNetworkClientIdByChainId(chainId) as string);\n\n networkClientIdsByChainId.set(chainId, networkClientId);\n }\n\n log('Extracted network client IDs by chain ID', networkClientIdsByChainId);\n\n const entryPromises = Array.from(networkClientIdsByChainId.entries()).map(\n async ([chainId, networkClientId]) => {\n return [\n chainId,\n await this.#getGasFeeControllerEstimates({ networkClientId }),\n ] as const;\n },\n );\n\n return new Map(await Promise.all(entryPromises));\n }\n}\n\n/**\n * Updates gas properties for transaction.\n *\n * @param args - Argument bag.\n * @param args.txMeta - The transaction meta.\n * @param args.gasFeeEstimates - The gas fee estimates.\n * @param args.gasFeeEstimatesLoaded - Whether the gas fee estimates are loaded.\n * @param args.isTxParamsGasFeeUpdatesEnabled - Whether to update the gas fee properties in `txParams`.\n * @param args.layer1GasFee - The layer 1 gas fee.\n */\nexport function updateTransactionGasProperties({\n gasFeeEstimates,\n gasFeeEstimatesLoaded,\n isTxParamsGasFeeUpdatesEnabled,\n layer1GasFee,\n txMeta,\n}: {\n gasFeeEstimates?: GasFeeEstimates;\n gasFeeEstimatesLoaded?: boolean;\n isTxParamsGasFeeUpdatesEnabled: (transactionMeta: TransactionMeta) => boolean;\n layer1GasFee?: Hex;\n txMeta: TransactionMeta;\n}): void {\n const userFeeLevel = txMeta.userFeeLevel as GasFeeEstimateLevel;\n const isUsingGasFeeEstimateLevel =\n Object.values(GasFeeEstimateLevel).includes(userFeeLevel);\n const shouldUpdateTxParamsGasFees = isTxParamsGasFeeUpdatesEnabled(txMeta);\n\n if (\n shouldUpdateTxParamsGasFees &&\n isUsingGasFeeEstimateLevel &&\n gasFeeEstimates\n ) {\n const isEIP1559Compatible =\n txMeta.txParams.type !== TransactionEnvelopeType.legacy;\n\n updateGasFeeParameters(\n txMeta.txParams,\n gasFeeEstimates,\n userFeeLevel,\n isEIP1559Compatible,\n );\n }\n\n if (gasFeeEstimates) {\n txMeta.gasFeeEstimates = gasFeeEstimates;\n }\n\n if (gasFeeEstimatesLoaded !== undefined) {\n txMeta.gasFeeEstimatesLoaded = gasFeeEstimatesLoaded;\n }\n\n if (layer1GasFee) {\n txMeta.layer1GasFee = layer1GasFee;\n }\n}\n\n/**\n * Updates `txParams` gas values accordingly with given `userFeeLevel` from `txMeta.gasFeeEstimates`.\n *\n * @param args - Argument bag.\n * @param args.txMeta - The transaction meta.\n * @param args.userFeeLevel - The user fee level.\n */\nexport function updateTransactionGasEstimates({\n txMeta,\n userFeeLevel,\n}: {\n txMeta: TransactionMeta;\n userFeeLevel: GasFeeEstimateLevel;\n}): void {\n const { txParams, gasFeeEstimates } = txMeta;\n\n if (!gasFeeEstimates) {\n return;\n }\n\n const isEIP1559Compatible =\n txMeta.txParams.type !== TransactionEnvelopeType.legacy;\n\n updateGasFeeParameters(\n txParams,\n gasFeeEstimates,\n userFeeLevel,\n isEIP1559Compatible,\n );\n}\n\n/**\n * Updates gas fee parameters based on transaction type and gas estimate type\n *\n * @param txParams - The transaction parameters to update\n * @param gasFeeEstimates - The gas fee estimates\n * @param userFeeLevel - The user fee level\n * @param isEIP1559Compatible - Whether the transaction is EIP-1559 compatible\n */\nfunction updateGasFeeParameters(\n txParams: TransactionParams,\n gasFeeEstimates: GasFeeEstimates,\n userFeeLevel: GasFeeEstimateLevel,\n isEIP1559Compatible: boolean,\n): void {\n const { type: gasEstimateType } = gasFeeEstimates;\n\n if (isEIP1559Compatible) {\n // Handle EIP-1559 compatible transactions\n if (gasEstimateType === GasFeeEstimateType.FeeMarket) {\n const feeMarketGasFeeEstimates =\n gasFeeEstimates as FeeMarketGasFeeEstimates;\n txParams.maxFeePerGas =\n feeMarketGasFeeEstimates[userFeeLevel]?.maxFeePerGas;\n txParams.maxPriorityFeePerGas =\n feeMarketGasFeeEstimates[userFeeLevel]?.maxPriorityFeePerGas;\n }\n\n if (gasEstimateType === GasFeeEstimateType.GasPrice) {\n const gasPriceGasFeeEstimates =\n gasFeeEstimates as GasPriceGasFeeEstimates;\n txParams.maxFeePerGas = gasPriceGasFeeEstimates.gasPrice;\n txParams.maxPriorityFeePerGas = gasPriceGasFeeEstimates.gasPrice;\n }\n\n if (gasEstimateType === GasFeeEstimateType.Legacy) {\n const legacyGasFeeEstimates = gasFeeEstimates as LegacyGasFeeEstimates;\n const gasPrice = legacyGasFeeEstimates[userFeeLevel];\n txParams.maxFeePerGas = gasPrice;\n txParams.maxPriorityFeePerGas = gasPrice;\n }\n\n // Remove gasPrice for EIP-1559 transactions\n delete txParams.gasPrice;\n } else {\n // Handle non-EIP-1559 transactions\n if (gasEstimateType === GasFeeEstimateType.FeeMarket) {\n const feeMarketGasFeeEstimates =\n gasFeeEstimates as FeeMarketGasFeeEstimates;\n txParams.gasPrice = feeMarketGasFeeEstimates[userFeeLevel]?.maxFeePerGas;\n }\n\n if (gasEstimateType === GasFeeEstimateType.GasPrice) {\n const gasPriceGasFeeEstimates =\n gasFeeEstimates as GasPriceGasFeeEstimates;\n txParams.gasPrice = gasPriceGasFeeEstimates.gasPrice;\n }\n\n if (gasEstimateType === GasFeeEstimateType.Legacy) {\n const legacyGasFeeEstimates = gasFeeEstimates as LegacyGasFeeEstimates;\n txParams.gasPrice = legacyGasFeeEstimates[userFeeLevel];\n }\n\n // Remove EIP-1559 specific parameters for legacy transactions\n delete txParams.maxFeePerGas;\n delete txParams.maxPriorityFeePerGas;\n }\n}\n"]}
|
|
@@ -4,7 +4,7 @@ import type { NetworkClientId, Provider } from "@metamask/network-controller";
|
|
|
4
4
|
import type { Hex } from "@metamask/utils";
|
|
5
5
|
import EventEmitter from "events";
|
|
6
6
|
import type { TransactionControllerMessenger } from "../TransactionController.cjs";
|
|
7
|
-
import type { GasFeeEstimates, GasFeeFlow, Layer1GasFeeFlow, TransactionMeta } from "../types.cjs";
|
|
7
|
+
import type { GasFeeEstimates, GasFeeFlow, Layer1GasFeeFlow, TransactionMeta, TransactionBatchMeta } from "../types.cjs";
|
|
8
8
|
import { GasFeeEstimateLevel } from "../types.cjs";
|
|
9
9
|
/**
|
|
10
10
|
* Automatically polls and updates suggested gas fees on unapproved transactions.
|
|
@@ -21,16 +21,18 @@ export declare class GasFeePoller {
|
|
|
21
21
|
* @param options.getGasFeeControllerEstimates - Callback to obtain the default fee estimates.
|
|
22
22
|
* @param options.getProvider - Callback to obtain a provider instance.
|
|
23
23
|
* @param options.getTransactions - Callback to obtain the transaction data.
|
|
24
|
+
* @param options.getTransactionBatches - Callback to obtain the transaction batch data.
|
|
24
25
|
* @param options.layer1GasFeeFlows - The layer 1 gas fee flows to use to obtain suitable layer 1 gas fees.
|
|
25
26
|
* @param options.messenger - The TransactionControllerMessenger instance.
|
|
26
27
|
* @param options.onStateChange - Callback to register a listener for controller state changes.
|
|
27
28
|
*/
|
|
28
|
-
constructor({ findNetworkClientIdByChainId, gasFeeFlows, getGasFeeControllerEstimates, getProvider, getTransactions, layer1GasFeeFlows, messenger, onStateChange, }: {
|
|
29
|
+
constructor({ findNetworkClientIdByChainId, gasFeeFlows, getGasFeeControllerEstimates, getProvider, getTransactions, getTransactionBatches, layer1GasFeeFlows, messenger, onStateChange, }: {
|
|
29
30
|
findNetworkClientIdByChainId: (chainId: Hex) => NetworkClientId | undefined;
|
|
30
31
|
gasFeeFlows: GasFeeFlow[];
|
|
31
32
|
getGasFeeControllerEstimates: (options: FetchGasFeeEstimateOptions) => Promise<GasFeeState>;
|
|
32
33
|
getProvider: (networkClientId: NetworkClientId) => Provider;
|
|
33
34
|
getTransactions: () => TransactionMeta[];
|
|
35
|
+
getTransactionBatches: () => TransactionBatchMeta[];
|
|
34
36
|
layer1GasFeeFlows: Layer1GasFeeFlow[];
|
|
35
37
|
messenger: TransactionControllerMessenger;
|
|
36
38
|
onStateChange: (listener: () => void) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GasFeePoller.d.cts","sourceRoot":"","sources":["../../src/helpers/GasFeePoller.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EACV,0BAA0B,EAC1B,WAAW,EACZ,qCAAqC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,qCAAqC;AAC9E,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAI3C,OAAO,YAAY,eAAe;
|
|
1
|
+
{"version":3,"file":"GasFeePoller.d.cts","sourceRoot":"","sources":["../../src/helpers/GasFeePoller.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EACV,0BAA0B,EAC1B,WAAW,EACZ,qCAAqC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,qCAAqC;AAC9E,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAI3C,OAAO,YAAY,eAAe;AAIlC,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EAIV,gBAAgB,EAEhB,eAAe,EAEf,oBAAoB,EACrB,qBAAiB;AAClB,OAAO,EACL,mBAAmB,EAIpB,qBAAiB;AAQlB;;GAEG;AACH,qBAAa,YAAY;;IACvB,GAAG,EAAE,YAAY,CAAsB;IA0BvC;;;;;;;;;;;;;OAaG;gBACS,EACV,4BAA4B,EAC5B,WAAW,EACX,4BAA4B,EAC5B,WAAW,EACX,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,SAAS,EACT,aAAa,GACd,EAAE;QACD,4BAA4B,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,eAAe,GAAG,SAAS,CAAC;QAC5E,WAAW,EAAE,UAAU,EAAE,CAAC;QAC1B,4BAA4B,EAAE,CAC5B,OAAO,EAAE,0BAA0B,KAChC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC1B,WAAW,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,QAAQ,CAAC;QAC5D,eAAe,EAAE,MAAM,eAAe,EAAE,CAAC;QACzC,qBAAqB,EAAE,MAAM,oBAAoB,EAAE,CAAC;QACpD,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;QACtC,SAAS,EAAE,8BAA8B,CAAC;QAC1C,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;KAC/C;CA2TF;AAED;;;;;;;;;GASG;AACH,wBAAgB,8BAA8B,CAAC,EAC7C,eAAe,EACf,qBAAqB,EACrB,8BAA8B,EAC9B,YAAY,EACZ,MAAM,GACP,EAAE;IACD,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,8BAA8B,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,OAAO,CAAC;IAC9E,YAAY,CAAC,EAAE,GAAG,CAAC;IACnB,MAAM,EAAE,eAAe,CAAC;CACzB,GAAG,IAAI,CAiCP;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAAC,EAC5C,MAAM,EACN,YAAY,GACb,EAAE;IACD,MAAM,EAAE,eAAe,CAAC;IACxB,YAAY,EAAE,mBAAmB,CAAC;CACnC,GAAG,IAAI,CAgBP"}
|