@metamask-previews/client-utils 3.1.1-preview-4dd847ca3 → 3.1.1-preview-effabf81d
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 +6 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mappers/api-transaction-mapper.d.ts +5 -1
- package/dist/mappers/api-transaction-mapper.d.ts.map +1 -1
- package/dist/mappers/api-transaction-mapper.js +27 -17
- package/dist/mappers/api-transaction-mapper.js.map +1 -1
- package/dist/mappers/helpers/indexed-transaction.d.ts +43 -0
- package/dist/mappers/helpers/indexed-transaction.d.ts.map +1 -0
- package/dist/mappers/helpers/indexed-transaction.js +97 -0
- package/dist/mappers/helpers/indexed-transaction.js.map +1 -0
- package/dist/mappers/helpers/transactions.d.ts +13 -12
- package/dist/mappers/helpers/transactions.d.ts.map +1 -1
- package/dist/mappers/helpers/transactions.js +3 -3
- package/dist/mappers/helpers/transactions.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Add `mapV5ApiTransaction`, which maps a `V5TransactionRecord` from Accounts API `GET /v5/multiaccount/transactions` to an `ActivityItem` ([#11379](https://github.com/MetaMask/core/pull/11379))
|
|
13
|
+
- It uses the same classification as `mapApiTransaction`, takes the subject account from the record's `accountId`, and reads network fees from the record's `fee`
|
|
14
|
+
- Request records with `includeTxMetadata: true` so they include `transactionCategory`
|
|
15
|
+
|
|
10
16
|
## [3.1.1]
|
|
11
17
|
|
|
12
18
|
### Changed
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { createFormatters } from './formatters/create-formatters.js';
|
|
2
2
|
export type { Formatters } from './formatters/create-formatters.js';
|
|
3
|
-
export { mapApiTransaction } from './mappers/api-transaction-mapper.js';
|
|
3
|
+
export { mapApiTransaction, mapV5ApiTransaction, } from './mappers/api-transaction-mapper.js';
|
|
4
4
|
export { mapKeyringTransaction } from './mappers/keyring-transaction-mapper.js';
|
|
5
5
|
export { mapLocalTransaction } from './mappers/local-transaction-mapper.js';
|
|
6
6
|
export { mapRampsOrder } from './mappers/ramps-order-mapper.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,YAAY,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAEpE,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,YAAY,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAEpE,OAAO,EACL,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,YAAY,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,YAAY,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAE/E,mBAAmB,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { createFormatters } from './formatters/create-formatters.js';
|
|
2
|
-
export { mapApiTransaction } from './mappers/api-transaction-mapper.js';
|
|
2
|
+
export { mapApiTransaction, mapV5ApiTransaction, } from './mappers/api-transaction-mapper.js';
|
|
3
3
|
export { mapKeyringTransaction } from './mappers/keyring-transaction-mapper.js';
|
|
4
4
|
export { mapLocalTransaction } from './mappers/local-transaction-mapper.js';
|
|
5
5
|
export { mapRampsOrder } from './mappers/ramps-order-mapper.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAGrE,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAGrE,OAAO,EACL,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC","sourcesContent":["export { createFormatters } from './formatters/create-formatters.js';\nexport type { Formatters } from './formatters/create-formatters.js';\n\nexport {\n mapApiTransaction,\n mapV5ApiTransaction,\n} from './mappers/api-transaction-mapper.js';\nexport { mapKeyringTransaction } from './mappers/keyring-transaction-mapper.js';\nexport { mapLocalTransaction } from './mappers/local-transaction-mapper.js';\nexport { mapRampsOrder } from './mappers/ramps-order-mapper.js';\nexport type { RampsOrderLike } from './mappers/ramps-order-mapper.js';\nexport type { GetKnownTokenDecimals } from './mappers/helpers/transactions.js';\n\nexport type * from './types.js';\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { V1TransactionByHashResponse } from '@metamask/core-backend';
|
|
1
|
+
import type { V1TransactionByHashResponse, V5TransactionRecord } from '@metamask/core-backend';
|
|
2
2
|
import type { ActivityItem } from '../types.js';
|
|
3
3
|
import type { GetKnownTokenDecimals } from './helpers/transactions.js';
|
|
4
4
|
/**
|
|
@@ -20,4 +20,8 @@ export declare function mapApiTransaction({ transaction, subjectAddress, getKnow
|
|
|
20
20
|
subjectAddress: string;
|
|
21
21
|
getKnownTokenDecimals?: GetKnownTokenDecimals;
|
|
22
22
|
}): ActivityItem;
|
|
23
|
+
export declare function mapV5ApiTransaction({ transaction, getKnownTokenDecimals, }: {
|
|
24
|
+
transaction: V5TransactionRecord;
|
|
25
|
+
getKnownTokenDecimals?: GetKnownTokenDecimals;
|
|
26
|
+
}): ActivityItem;
|
|
23
27
|
//# sourceMappingURL=api-transaction-mapper.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-transaction-mapper.d.ts","sourceRoot":"","sources":["../../src/mappers/api-transaction-mapper.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"api-transaction-mapper.d.ts","sourceRoot":"","sources":["../../src/mappers/api-transaction-mapper.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,2BAA2B,EAC3B,mBAAmB,EACpB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,aAAa,CAAC;AAwB7D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAQvE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,WAAW,EACX,cAAc,EACd,qBAAqB,GACtB,EAAE;IACD,WAAW,EAAE,2BAA2B,CAAC;IACzC,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;CAC/C,GAAG,YAAY,CAMf;AAED,wBAAgB,mBAAmB,CAAC,EAClC,WAAW,EACX,qBAAqB,GACtB,EAAE;IACD,WAAW,EAAE,mBAAmB,CAAC;IACjC,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;CAC/C,GAAG,YAAY,CAKf"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { isEqualCaseInsensitive as equalsIgnoreCase, isValidHexAddress, } from '@metamask/controller-utils';
|
|
2
|
-
import { KnownCaipNamespace, toCaipChainId } from '@metamask/utils';
|
|
3
2
|
import { nativeTokenAddress, supplyMethodIds, swapsWrappedTokensAddresses, withdrawMethodIds, wrapMethodIds, } from './constants.js';
|
|
4
3
|
import { formatAddressToAssetId, getNativeAsset } from './helpers/caip.js';
|
|
5
|
-
import {
|
|
4
|
+
import { fromV1Transaction, fromV5TransactionRecord, toHexChainId, } from './helpers/indexed-transaction.js';
|
|
5
|
+
import { getNftPaymentTransfer, getTokenAmountFromTransfer, getTokenMetadataFromKnownToken, parseValueTransfers, } from './helpers/transactions.js';
|
|
6
6
|
/**
|
|
7
7
|
* Maps an indexed API transaction into the shared activity item shape.
|
|
8
8
|
*
|
|
@@ -18,11 +18,21 @@ import { getFees, getNftPaymentTransfer, getTokenAmountFromTransfer, getTokenMet
|
|
|
18
18
|
* @returns The normalized activity item.
|
|
19
19
|
*/
|
|
20
20
|
export function mapApiTransaction({ transaction, subjectAddress, getKnownTokenDecimals, }) {
|
|
21
|
-
|
|
21
|
+
return mapIndexedTransaction({
|
|
22
|
+
transaction: fromV1Transaction(transaction),
|
|
23
|
+
subjectAddress,
|
|
24
|
+
getKnownTokenDecimals,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
export function mapV5ApiTransaction({ transaction, getKnownTokenDecimals, }) {
|
|
28
|
+
return mapIndexedTransaction({
|
|
29
|
+
...fromV5TransactionRecord(transaction),
|
|
30
|
+
getKnownTokenDecimals,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function mapIndexedTransaction({ transaction, subjectAddress, getKnownTokenDecimals, }) {
|
|
34
|
+
const { hash, chainId, status, timestamp, transactionCategory, valueTransfers, from, methodId, fees, } = transaction;
|
|
22
35
|
const normalizedMethodId = methodId?.toLowerCase() ?? '';
|
|
23
|
-
const status = transaction.isError ? 'failed' : 'success';
|
|
24
|
-
const timestamp = new Date(transaction.timestamp).getTime();
|
|
25
|
-
const chainId = toCaipChainId(KnownCaipNamespace.Eip155, transaction.chainId.toString());
|
|
26
36
|
const getToken = (transfer, direction) => getTokenAmountFromTransfer(transfer, direction, chainId, getKnownTokenDecimals);
|
|
27
37
|
const { sentTransfer, receivedTransfer, sentNativeTransfer, sentNftTransfer, receivedNftTransfer, } = parseValueTransfers(valueTransfers, subjectAddress);
|
|
28
38
|
const common = { chainId, status, timestamp, hash };
|
|
@@ -33,7 +43,7 @@ export function mapApiTransaction({ transaction, subjectAddress, getKnownTokenDe
|
|
|
33
43
|
data: {
|
|
34
44
|
sourceToken: getToken(sentTransfer, 'out'),
|
|
35
45
|
destinationToken: getToken(receivedTransfer, 'in'),
|
|
36
|
-
fees
|
|
46
|
+
fees,
|
|
37
47
|
from,
|
|
38
48
|
},
|
|
39
49
|
};
|
|
@@ -64,7 +74,7 @@ export function mapApiTransaction({ transaction, subjectAddress, getKnownTokenDe
|
|
|
64
74
|
data: {
|
|
65
75
|
from,
|
|
66
76
|
token,
|
|
67
|
-
fees
|
|
77
|
+
fees,
|
|
68
78
|
},
|
|
69
79
|
};
|
|
70
80
|
}
|
|
@@ -186,7 +196,7 @@ export function mapApiTransaction({ transaction, subjectAddress, getKnownTokenDe
|
|
|
186
196
|
from: transfer?.from ?? from,
|
|
187
197
|
to: transfer?.to ?? transaction.to,
|
|
188
198
|
token,
|
|
189
|
-
fees
|
|
199
|
+
fees,
|
|
190
200
|
},
|
|
191
201
|
};
|
|
192
202
|
}
|
|
@@ -217,7 +227,7 @@ export function mapApiTransaction({ transaction, subjectAddress, getKnownTokenDe
|
|
|
217
227
|
data: {
|
|
218
228
|
from,
|
|
219
229
|
sourceToken: getToken(sentTransfer, 'out'),
|
|
220
|
-
fees
|
|
230
|
+
fees,
|
|
221
231
|
},
|
|
222
232
|
};
|
|
223
233
|
}
|
|
@@ -230,7 +240,7 @@ export function mapApiTransaction({ transaction, subjectAddress, getKnownTokenDe
|
|
|
230
240
|
from,
|
|
231
241
|
sourceToken: getToken(sentTransfer, 'out'),
|
|
232
242
|
destinationToken: getToken(receivedTransfer, 'in'),
|
|
233
|
-
fees
|
|
243
|
+
fees,
|
|
234
244
|
},
|
|
235
245
|
};
|
|
236
246
|
}
|
|
@@ -243,11 +253,11 @@ export function mapApiTransaction({ transaction, subjectAddress, getKnownTokenDe
|
|
|
243
253
|
from,
|
|
244
254
|
sourceToken: getToken(sentTransfer, 'out'),
|
|
245
255
|
destinationToken: getToken(receivedTransfer, 'in'),
|
|
246
|
-
fees
|
|
256
|
+
fees,
|
|
247
257
|
},
|
|
248
258
|
};
|
|
249
259
|
}
|
|
250
|
-
const wrappedNativeAddress = swapsWrappedTokensAddresses[
|
|
260
|
+
const wrappedNativeAddress = swapsWrappedTokensAddresses[toHexChainId(chainId)];
|
|
251
261
|
if (receivedTransfer &&
|
|
252
262
|
wrapMethodIds.has(normalizedMethodId) &&
|
|
253
263
|
wrappedNativeAddress &&
|
|
@@ -259,7 +269,7 @@ export function mapApiTransaction({ transaction, subjectAddress, getKnownTokenDe
|
|
|
259
269
|
from,
|
|
260
270
|
sourceToken: getToken(sentTransfer, 'out'),
|
|
261
271
|
destinationToken: getToken(receivedTransfer, 'in'),
|
|
262
|
-
fees
|
|
272
|
+
fees,
|
|
263
273
|
},
|
|
264
274
|
};
|
|
265
275
|
}
|
|
@@ -271,7 +281,7 @@ export function mapApiTransaction({ transaction, subjectAddress, getKnownTokenDe
|
|
|
271
281
|
from,
|
|
272
282
|
sourceToken: getToken(sentTransfer, 'out'),
|
|
273
283
|
destinationToken: getToken(receivedTransfer, 'in'),
|
|
274
|
-
fees
|
|
284
|
+
fees,
|
|
275
285
|
},
|
|
276
286
|
};
|
|
277
287
|
}
|
|
@@ -287,7 +297,7 @@ export function mapApiTransaction({ transaction, subjectAddress, getKnownTokenDe
|
|
|
287
297
|
from,
|
|
288
298
|
sourceToken: getToken(sentTransfer, 'out'),
|
|
289
299
|
destinationToken: getToken(receivedTransfer, 'in'),
|
|
290
|
-
fees
|
|
300
|
+
fees,
|
|
291
301
|
},
|
|
292
302
|
};
|
|
293
303
|
}
|
|
@@ -312,7 +322,7 @@ export function mapApiTransaction({ transaction, subjectAddress, getKnownTokenDe
|
|
|
312
322
|
transactionCategory,
|
|
313
323
|
transactionProtocol: transaction.transactionProtocol,
|
|
314
324
|
...(token ? { token } : {}),
|
|
315
|
-
fees
|
|
325
|
+
fees,
|
|
316
326
|
},
|
|
317
327
|
};
|
|
318
328
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-transaction-mapper.js","sourceRoot":"","sources":["../../src/mappers/api-transaction-mapper.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n isEqualCaseInsensitive as equalsIgnoreCase,\n isValidHexAddress,\n} from '@metamask/controller-utils';\nimport type { V1TransactionByHashResponse } from '@metamask/core-backend';\nimport { KnownCaipNamespace, toCaipChainId } from '@metamask/utils';\n\nimport type {\n ActivityItem,\n Status,\n TokenAmount,\n ValueTransfer,\n} from '../types.js';\nimport {\n nativeTokenAddress,\n supplyMethodIds,\n swapsWrappedTokensAddresses,\n withdrawMethodIds,\n wrapMethodIds,\n} from './constants.js';\nimport { formatAddressToAssetId, getNativeAsset } from './helpers/caip.js';\nimport {\n getFees,\n getNftPaymentTransfer,\n getTokenAmountFromTransfer,\n getTokenMetadataFromKnownToken,\n parseValueTransfers,\n} from './helpers/transactions.js';\nimport type { GetKnownTokenDecimals } from './helpers/transactions.js';\n\n/**\n * Maps an indexed API transaction into the shared activity item shape.\n *\n * Fungible token amounts are only emitted when a decimals scale is known\n * (transfer enrichment, native defaults, static metadata, or\n * `getKnownTokenDecimals`). Pass that optional hook so hosts can recover\n * decimals/symbol from on-device token state when the Accounts API omits them.\n *\n * @param options - The mapping options.\n * @param options.transaction - The indexed API transaction to map.\n * @param options.subjectAddress - The account the activity is being mapped for.\n * @param options.getKnownTokenDecimals - Optional host lookup for missing ERC-20 metadata.\n * @returns The normalized activity item.\n */\nexport function mapApiTransaction({\n transaction,\n subjectAddress,\n getKnownTokenDecimals,\n}: {\n transaction: V1TransactionByHashResponse;\n subjectAddress: string;\n getKnownTokenDecimals?: GetKnownTokenDecimals;\n}): ActivityItem {\n const { hash, transactionCategory, valueTransfers, from, methodId } =\n transaction;\n const normalizedMethodId = methodId?.toLowerCase() ?? '';\n const status: Status = transaction.isError ? 'failed' : 'success';\n const timestamp = new Date(transaction.timestamp).getTime();\n const chainId = toCaipChainId(\n KnownCaipNamespace.Eip155,\n transaction.chainId.toString(),\n );\n const getToken = (\n transfer: ValueTransfer | undefined,\n direction: TokenAmount['direction'],\n ): TokenAmount | undefined =>\n getTokenAmountFromTransfer(\n transfer,\n direction,\n chainId,\n getKnownTokenDecimals,\n );\n\n const {\n sentTransfer,\n receivedTransfer,\n sentNativeTransfer,\n sentNftTransfer,\n receivedNftTransfer,\n } = parseValueTransfers(valueTransfers, subjectAddress);\n\n const common = { chainId, status, timestamp, hash };\n\n if (transactionCategory === 'SWAP' || transactionCategory === 'EXCHANGE') {\n return {\n type: 'swap',\n ...common,\n data: {\n sourceToken: getToken(sentTransfer, 'out'),\n destinationToken: getToken(receivedTransfer, 'in'),\n fees: getFees(transaction),\n from,\n },\n };\n }\n\n if (transactionCategory === 'APPROVE') {\n // Note: Categorize REVOKE in the backend\n const direction = receivedTransfer && !sentTransfer ? 'in' : 'out';\n const valueTransferContractAddress = valueTransfers?.find(\n ({ contractAddress, transferType }) =>\n contractAddress &&\n transferType !== 'normal' &&\n transferType !== 'internal',\n )?.contractAddress;\n const contractAddress =\n (isValidHexAddress(transaction.to, { allowNonPrefixed: false })\n ? transaction.to\n : undefined) ??\n (valueTransferContractAddress &&\n isValidHexAddress(valueTransferContractAddress, {\n allowNonPrefixed: false,\n })\n ? valueTransferContractAddress\n : undefined);\n const assetId = contractAddress\n ? formatAddressToAssetId(contractAddress, chainId)\n : undefined;\n const token =\n getTokenMetadataFromKnownToken(contractAddress, direction, chainId) ??\n (assetId ? { direction, assetId } : undefined);\n\n return {\n type: 'approveSpendingCap',\n ...common,\n data: {\n from,\n token,\n fees: getFees(transaction),\n },\n };\n }\n\n // Note: Categorize NFT in the backend\n const isNftExchange = transactionCategory === 'NFT_EXCHANGE';\n\n if (receivedNftTransfer) {\n if (receivedNftTransfer.from === nativeTokenAddress) {\n return {\n type: 'nftMint',\n ...common,\n data: {\n from: receivedNftTransfer.from,\n to: receivedNftTransfer.to,\n token: getToken(receivedNftTransfer, 'in'),\n },\n };\n }\n\n const purchasePaymentTransfer = getNftPaymentTransfer({\n side: 'buy',\n sentTransfer,\n sentNativeTransfer,\n nftCounterparty: receivedNftTransfer.from,\n transactionTo: transaction.to,\n subjectAddress,\n });\n\n if (isNftExchange || purchasePaymentTransfer) {\n return {\n type: 'nftBuy',\n ...common,\n data: {\n from: receivedNftTransfer.from,\n to: receivedNftTransfer.to,\n token: getToken(receivedNftTransfer, 'in'),\n paymentToken: getToken(purchasePaymentTransfer, 'out'),\n },\n };\n }\n\n return {\n type: 'receive',\n ...common,\n data: {\n from: receivedNftTransfer.from,\n to: receivedNftTransfer.to,\n token: getToken(receivedNftTransfer, 'in'),\n },\n };\n }\n\n if (sentNftTransfer) {\n const saleProceedsTransfer = getNftPaymentTransfer({\n side: 'sell',\n receivedTransfer,\n nftCounterparty: sentNftTransfer.to,\n transactionFrom: from,\n subjectAddress,\n });\n\n if (isNftExchange || saleProceedsTransfer) {\n return {\n type: 'nftSell',\n ...common,\n data: {\n from: sentNftTransfer.from,\n to: sentNftTransfer.to,\n token: getToken(sentNftTransfer, 'out'),\n paymentToken: getToken(saleProceedsTransfer, 'in'),\n },\n };\n }\n\n return {\n type: 'send',\n ...common,\n data: {\n from: sentNftTransfer.from,\n to: sentNftTransfer.to,\n token: getToken(sentNftTransfer, 'out'),\n },\n };\n }\n\n const hasNativeTransferWithoutMethod =\n transactionCategory === 'CONTRACT_CALL' &&\n !methodId &&\n valueTransfers?.some(({ transferType }) => transferType === 'normal');\n\n if (\n transactionCategory === 'TRANSFER' ||\n transactionCategory === 'STANDARD' ||\n hasNativeTransferWithoutMethod\n ) {\n const isReceive =\n Boolean(receivedTransfer && !sentTransfer) ||\n (equalsIgnoreCase(transaction.to, subjectAddress) &&\n !equalsIgnoreCase(from, subjectAddress));\n\n const transfer = isReceive ? receivedTransfer : sentTransfer;\n const direction: TokenAmount['direction'] = isReceive ? 'in' : 'out';\n let token = getToken(transfer, direction);\n\n if (!token) {\n // Zero-value sends can omit valueTransfers\n if (transactionCategory === 'STANDARD') {\n const nativeAsset = getNativeAsset(chainId);\n if (nativeAsset) {\n token = {\n symbol: nativeAsset.symbol,\n decimals: nativeAsset.decimals,\n assetId: nativeAsset.assetId,\n amount: transaction.value,\n direction,\n assetType: 'native',\n };\n }\n }\n } else if (\n !token.assetId &&\n transfer?.transferType !== 'normal' &&\n transfer?.transferType !== 'internal'\n ) {\n // ERC-20 transfer missing contractAddress — fall back to tx.to.\n const assetId = formatAddressToAssetId(transaction.to, chainId);\n if (assetId) {\n token = { ...token, assetId };\n }\n }\n\n return {\n type: isReceive ? 'receive' : 'send',\n ...common,\n data: {\n from: transfer?.from ?? from,\n to: transfer?.to ?? transaction.to,\n token,\n fees: getFees(transaction),\n },\n };\n }\n\n if (transactionCategory === 'CLAIM_BONUS') {\n return {\n type: 'claimMusdBonus',\n ...common,\n data: {\n from,\n token: getToken(receivedTransfer, 'in'),\n },\n };\n }\n\n if (transactionCategory === 'CLAIM') {\n return {\n type: 'claim',\n ...common,\n data: {\n from,\n token: getToken(\n receivedTransfer ?? sentTransfer,\n receivedTransfer ? 'in' : 'out',\n ),\n },\n };\n }\n\n if (transactionCategory === 'BRIDGE_WITHDRAW') {\n return {\n type: 'bridge',\n ...common,\n data: {\n from,\n sourceToken: getToken(sentTransfer, 'out'),\n fees: getFees(transaction),\n },\n };\n }\n\n if (\n transactionCategory === 'WITHDRAW' &&\n withdrawMethodIds.has(normalizedMethodId)\n ) {\n return {\n type: 'lendingWithdrawal',\n ...common,\n data: {\n from,\n sourceToken: getToken(sentTransfer, 'out'),\n destinationToken: getToken(receivedTransfer, 'in'),\n fees: getFees(transaction),\n },\n };\n }\n\n // Note: Categorize Deposit/Stake in the backend\n if (sentTransfer && supplyMethodIds.has(normalizedMethodId)) {\n return {\n type: 'lendingDeposit',\n ...common,\n data: {\n from,\n sourceToken: getToken(sentTransfer, 'out'),\n destinationToken: getToken(receivedTransfer, 'in'),\n fees: getFees(transaction),\n },\n };\n }\n\n const wrappedNativeAddress =\n swapsWrappedTokensAddresses[\n `0x${transaction.chainId.toString(\n 16,\n )}` as keyof typeof swapsWrappedTokensAddresses\n ];\n\n if (\n receivedTransfer &&\n wrapMethodIds.has(normalizedMethodId) &&\n wrappedNativeAddress &&\n equalsIgnoreCase(transaction.to, wrappedNativeAddress)\n ) {\n return {\n type: 'wrap',\n ...common,\n data: {\n from,\n sourceToken: getToken(sentTransfer, 'out'),\n destinationToken: getToken(receivedTransfer, 'in'),\n fees: getFees(transaction),\n },\n };\n }\n\n if (transactionCategory === 'UNWRAP') {\n return {\n type: 'unwrap',\n ...common,\n data: {\n from,\n sourceToken: getToken(sentTransfer, 'out'),\n destinationToken: getToken(receivedTransfer, 'in'),\n fees: getFees(transaction),\n },\n };\n }\n\n // Note: Categorize these Swaps in the backend\n if (\n transactionCategory === 'CONTRACT_CALL' &&\n sentTransfer?.symbol &&\n receivedTransfer?.symbol &&\n sentTransfer.symbol !== receivedTransfer.symbol\n ) {\n return {\n type: 'swap',\n ...common,\n data: {\n from,\n sourceToken: getToken(sentTransfer, 'out'),\n destinationToken: getToken(receivedTransfer, 'in'),\n fees: getFees(transaction),\n },\n };\n }\n\n if (transactionCategory === 'DEPOSIT') {\n return {\n type: 'deposit',\n ...common,\n data: {\n from,\n token: getToken(sentTransfer, 'out'),\n },\n };\n }\n\n const token = getToken(\n sentTransfer ?? receivedTransfer,\n sentTransfer ? 'out' : 'in',\n );\n\n return {\n type: 'contractInteraction',\n ...common,\n data: {\n methodId,\n from,\n to: transaction.to,\n transactionCategory,\n transactionProtocol: transaction.transactionProtocol,\n ...(token ? { token } : {}),\n fees: getFees(transaction),\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"api-transaction-mapper.js","sourceRoot":"","sources":["../../src/mappers/api-transaction-mapper.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n isEqualCaseInsensitive as equalsIgnoreCase,\n isValidHexAddress,\n} from '@metamask/controller-utils';\nimport type {\n V1TransactionByHashResponse,\n V5TransactionRecord,\n} from '@metamask/core-backend';\n\nimport type { ActivityItem, TokenAmount } from '../types.js';\nimport {\n nativeTokenAddress,\n supplyMethodIds,\n swapsWrappedTokensAddresses,\n withdrawMethodIds,\n wrapMethodIds,\n} from './constants.js';\nimport { formatAddressToAssetId, getNativeAsset } from './helpers/caip.js';\nimport {\n fromV1Transaction,\n fromV5TransactionRecord,\n toHexChainId,\n} from './helpers/indexed-transaction.js';\nimport type {\n IndexedTransaction,\n IndexedValueTransfer,\n} from './helpers/indexed-transaction.js';\nimport {\n getNftPaymentTransfer,\n getTokenAmountFromTransfer,\n getTokenMetadataFromKnownToken,\n parseValueTransfers,\n} from './helpers/transactions.js';\nimport type { GetKnownTokenDecimals } from './helpers/transactions.js';\n\ntype MapIndexedTransactionOptions = {\n transaction: IndexedTransaction;\n subjectAddress: string;\n getKnownTokenDecimals?: GetKnownTokenDecimals;\n};\n\n/**\n * Maps an indexed API transaction into the shared activity item shape.\n *\n * Fungible token amounts are only emitted when a decimals scale is known\n * (transfer enrichment, native defaults, static metadata, or\n * `getKnownTokenDecimals`). Pass that optional hook so hosts can recover\n * decimals/symbol from on-device token state when the Accounts API omits them.\n *\n * @param options - The mapping options.\n * @param options.transaction - The indexed API transaction to map.\n * @param options.subjectAddress - The account the activity is being mapped for.\n * @param options.getKnownTokenDecimals - Optional host lookup for missing ERC-20 metadata.\n * @returns The normalized activity item.\n */\nexport function mapApiTransaction({\n transaction,\n subjectAddress,\n getKnownTokenDecimals,\n}: {\n transaction: V1TransactionByHashResponse;\n subjectAddress: string;\n getKnownTokenDecimals?: GetKnownTokenDecimals;\n}): ActivityItem {\n return mapIndexedTransaction({\n transaction: fromV1Transaction(transaction),\n subjectAddress,\n getKnownTokenDecimals,\n });\n}\n\nexport function mapV5ApiTransaction({\n transaction,\n getKnownTokenDecimals,\n}: {\n transaction: V5TransactionRecord;\n getKnownTokenDecimals?: GetKnownTokenDecimals;\n}): ActivityItem {\n return mapIndexedTransaction({\n ...fromV5TransactionRecord(transaction),\n getKnownTokenDecimals,\n });\n}\n\nfunction mapIndexedTransaction({\n transaction,\n subjectAddress,\n getKnownTokenDecimals,\n}: MapIndexedTransactionOptions): ActivityItem {\n const {\n hash,\n chainId,\n status,\n timestamp,\n transactionCategory,\n valueTransfers,\n from,\n methodId,\n fees,\n } = transaction;\n const normalizedMethodId = methodId?.toLowerCase() ?? '';\n const getToken = (\n transfer: IndexedValueTransfer | undefined,\n direction: TokenAmount['direction'],\n ): TokenAmount | undefined =>\n getTokenAmountFromTransfer(\n transfer,\n direction,\n chainId,\n getKnownTokenDecimals,\n );\n\n const {\n sentTransfer,\n receivedTransfer,\n sentNativeTransfer,\n sentNftTransfer,\n receivedNftTransfer,\n } = parseValueTransfers(valueTransfers, subjectAddress);\n\n const common = { chainId, status, timestamp, hash };\n\n if (transactionCategory === 'SWAP' || transactionCategory === 'EXCHANGE') {\n return {\n type: 'swap',\n ...common,\n data: {\n sourceToken: getToken(sentTransfer, 'out'),\n destinationToken: getToken(receivedTransfer, 'in'),\n fees,\n from,\n },\n };\n }\n\n if (transactionCategory === 'APPROVE') {\n // Note: Categorize REVOKE in the backend\n const direction = receivedTransfer && !sentTransfer ? 'in' : 'out';\n const valueTransferContractAddress = valueTransfers?.find(\n ({ contractAddress, transferType }) =>\n contractAddress &&\n transferType !== 'normal' &&\n transferType !== 'internal',\n )?.contractAddress;\n const contractAddress =\n (isValidHexAddress(transaction.to, { allowNonPrefixed: false })\n ? transaction.to\n : undefined) ??\n (valueTransferContractAddress &&\n isValidHexAddress(valueTransferContractAddress, {\n allowNonPrefixed: false,\n })\n ? valueTransferContractAddress\n : undefined);\n const assetId = contractAddress\n ? formatAddressToAssetId(contractAddress, chainId)\n : undefined;\n const token =\n getTokenMetadataFromKnownToken(contractAddress, direction, chainId) ??\n (assetId ? { direction, assetId } : undefined);\n\n return {\n type: 'approveSpendingCap',\n ...common,\n data: {\n from,\n token,\n fees,\n },\n };\n }\n\n // Note: Categorize NFT in the backend\n const isNftExchange = transactionCategory === 'NFT_EXCHANGE';\n\n if (receivedNftTransfer) {\n if (receivedNftTransfer.from === nativeTokenAddress) {\n return {\n type: 'nftMint',\n ...common,\n data: {\n from: receivedNftTransfer.from,\n to: receivedNftTransfer.to,\n token: getToken(receivedNftTransfer, 'in'),\n },\n };\n }\n\n const purchasePaymentTransfer = getNftPaymentTransfer({\n side: 'buy',\n sentTransfer,\n sentNativeTransfer,\n nftCounterparty: receivedNftTransfer.from,\n transactionTo: transaction.to,\n subjectAddress,\n });\n\n if (isNftExchange || purchasePaymentTransfer) {\n return {\n type: 'nftBuy',\n ...common,\n data: {\n from: receivedNftTransfer.from,\n to: receivedNftTransfer.to,\n token: getToken(receivedNftTransfer, 'in'),\n paymentToken: getToken(purchasePaymentTransfer, 'out'),\n },\n };\n }\n\n return {\n type: 'receive',\n ...common,\n data: {\n from: receivedNftTransfer.from,\n to: receivedNftTransfer.to,\n token: getToken(receivedNftTransfer, 'in'),\n },\n };\n }\n\n if (sentNftTransfer) {\n const saleProceedsTransfer = getNftPaymentTransfer({\n side: 'sell',\n receivedTransfer,\n nftCounterparty: sentNftTransfer.to,\n transactionFrom: from,\n subjectAddress,\n });\n\n if (isNftExchange || saleProceedsTransfer) {\n return {\n type: 'nftSell',\n ...common,\n data: {\n from: sentNftTransfer.from,\n to: sentNftTransfer.to,\n token: getToken(sentNftTransfer, 'out'),\n paymentToken: getToken(saleProceedsTransfer, 'in'),\n },\n };\n }\n\n return {\n type: 'send',\n ...common,\n data: {\n from: sentNftTransfer.from,\n to: sentNftTransfer.to,\n token: getToken(sentNftTransfer, 'out'),\n },\n };\n }\n\n const hasNativeTransferWithoutMethod =\n transactionCategory === 'CONTRACT_CALL' &&\n !methodId &&\n valueTransfers?.some(({ transferType }) => transferType === 'normal');\n\n if (\n transactionCategory === 'TRANSFER' ||\n transactionCategory === 'STANDARD' ||\n hasNativeTransferWithoutMethod\n ) {\n const isReceive =\n Boolean(receivedTransfer && !sentTransfer) ||\n (equalsIgnoreCase(transaction.to, subjectAddress) &&\n !equalsIgnoreCase(from, subjectAddress));\n\n const transfer = isReceive ? receivedTransfer : sentTransfer;\n const direction: TokenAmount['direction'] = isReceive ? 'in' : 'out';\n let token = getToken(transfer, direction);\n\n if (!token) {\n // Zero-value sends can omit valueTransfers\n if (transactionCategory === 'STANDARD') {\n const nativeAsset = getNativeAsset(chainId);\n if (nativeAsset) {\n token = {\n symbol: nativeAsset.symbol,\n decimals: nativeAsset.decimals,\n assetId: nativeAsset.assetId,\n amount: transaction.value,\n direction,\n assetType: 'native',\n };\n }\n }\n } else if (\n !token.assetId &&\n transfer?.transferType !== 'normal' &&\n transfer?.transferType !== 'internal'\n ) {\n // ERC-20 transfer missing contractAddress — fall back to tx.to.\n const assetId = formatAddressToAssetId(transaction.to, chainId);\n if (assetId) {\n token = { ...token, assetId };\n }\n }\n\n return {\n type: isReceive ? 'receive' : 'send',\n ...common,\n data: {\n from: transfer?.from ?? from,\n to: transfer?.to ?? transaction.to,\n token,\n fees,\n },\n };\n }\n\n if (transactionCategory === 'CLAIM_BONUS') {\n return {\n type: 'claimMusdBonus',\n ...common,\n data: {\n from,\n token: getToken(receivedTransfer, 'in'),\n },\n };\n }\n\n if (transactionCategory === 'CLAIM') {\n return {\n type: 'claim',\n ...common,\n data: {\n from,\n token: getToken(\n receivedTransfer ?? sentTransfer,\n receivedTransfer ? 'in' : 'out',\n ),\n },\n };\n }\n\n if (transactionCategory === 'BRIDGE_WITHDRAW') {\n return {\n type: 'bridge',\n ...common,\n data: {\n from,\n sourceToken: getToken(sentTransfer, 'out'),\n fees,\n },\n };\n }\n\n if (\n transactionCategory === 'WITHDRAW' &&\n withdrawMethodIds.has(normalizedMethodId)\n ) {\n return {\n type: 'lendingWithdrawal',\n ...common,\n data: {\n from,\n sourceToken: getToken(sentTransfer, 'out'),\n destinationToken: getToken(receivedTransfer, 'in'),\n fees,\n },\n };\n }\n\n // Note: Categorize Deposit/Stake in the backend\n if (sentTransfer && supplyMethodIds.has(normalizedMethodId)) {\n return {\n type: 'lendingDeposit',\n ...common,\n data: {\n from,\n sourceToken: getToken(sentTransfer, 'out'),\n destinationToken: getToken(receivedTransfer, 'in'),\n fees,\n },\n };\n }\n\n const wrappedNativeAddress =\n swapsWrappedTokensAddresses[\n toHexChainId(chainId) as keyof typeof swapsWrappedTokensAddresses\n ];\n\n if (\n receivedTransfer &&\n wrapMethodIds.has(normalizedMethodId) &&\n wrappedNativeAddress &&\n equalsIgnoreCase(transaction.to, wrappedNativeAddress)\n ) {\n return {\n type: 'wrap',\n ...common,\n data: {\n from,\n sourceToken: getToken(sentTransfer, 'out'),\n destinationToken: getToken(receivedTransfer, 'in'),\n fees,\n },\n };\n }\n\n if (transactionCategory === 'UNWRAP') {\n return {\n type: 'unwrap',\n ...common,\n data: {\n from,\n sourceToken: getToken(sentTransfer, 'out'),\n destinationToken: getToken(receivedTransfer, 'in'),\n fees,\n },\n };\n }\n\n // Note: Categorize these Swaps in the backend\n if (\n transactionCategory === 'CONTRACT_CALL' &&\n sentTransfer?.symbol &&\n receivedTransfer?.symbol &&\n sentTransfer.symbol !== receivedTransfer.symbol\n ) {\n return {\n type: 'swap',\n ...common,\n data: {\n from,\n sourceToken: getToken(sentTransfer, 'out'),\n destinationToken: getToken(receivedTransfer, 'in'),\n fees,\n },\n };\n }\n\n if (transactionCategory === 'DEPOSIT') {\n return {\n type: 'deposit',\n ...common,\n data: {\n from,\n token: getToken(sentTransfer, 'out'),\n },\n };\n }\n\n const token = getToken(\n sentTransfer ?? receivedTransfer,\n sentTransfer ? 'out' : 'in',\n );\n\n return {\n type: 'contractInteraction',\n ...common,\n data: {\n methodId,\n from,\n to: transaction.to,\n transactionCategory,\n transactionProtocol: transaction.transactionProtocol,\n ...(token ? { token } : {}),\n fees,\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { V1TransactionByHashResponse, V5TransactionRecord } from '@metamask/core-backend';
|
|
2
|
+
import type { CaipChainId } from '@metamask/utils';
|
|
3
|
+
import type { Fee, Status } from '../../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Value transfer in the shape the API mapper classifies, independent of the
|
|
6
|
+
* Accounts API version it came from.
|
|
7
|
+
*
|
|
8
|
+
* `transferType` uses the V1 vocabulary (`normal`, `internal`, `erc20`,
|
|
9
|
+
* `erc721`, `erc1155`). `assetId` is only set when it can't be derived from
|
|
10
|
+
* `contractAddress` (non-EVM assets).
|
|
11
|
+
*/
|
|
12
|
+
export type IndexedValueTransfer = {
|
|
13
|
+
from: string;
|
|
14
|
+
to: string;
|
|
15
|
+
transferType: string;
|
|
16
|
+
amount?: string | number;
|
|
17
|
+
decimal?: number;
|
|
18
|
+
contractAddress?: string;
|
|
19
|
+
symbol?: string;
|
|
20
|
+
name?: string;
|
|
21
|
+
assetId?: string;
|
|
22
|
+
};
|
|
23
|
+
export type IndexedTransaction = {
|
|
24
|
+
hash: string;
|
|
25
|
+
chainId: CaipChainId;
|
|
26
|
+
status: Status;
|
|
27
|
+
timestamp: number;
|
|
28
|
+
from: string;
|
|
29
|
+
to: string;
|
|
30
|
+
value?: string;
|
|
31
|
+
methodId?: string;
|
|
32
|
+
transactionCategory?: string;
|
|
33
|
+
transactionProtocol?: string;
|
|
34
|
+
valueTransfers?: IndexedValueTransfer[];
|
|
35
|
+
fees?: Fee[];
|
|
36
|
+
};
|
|
37
|
+
export declare function fromV1Transaction(transaction: V1TransactionByHashResponse): IndexedTransaction;
|
|
38
|
+
export declare function fromV5TransactionRecord(record: V5TransactionRecord): {
|
|
39
|
+
transaction: IndexedTransaction;
|
|
40
|
+
subjectAddress: string;
|
|
41
|
+
};
|
|
42
|
+
export declare function toHexChainId(chainId: CaipChainId): string | undefined;
|
|
43
|
+
//# sourceMappingURL=indexed-transaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexed-transaction.d.ts","sourceRoot":"","sources":["../../../src/mappers/helpers/indexed-transaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,2BAA2B,EAE3B,mBAAmB,EAEpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAGV,WAAW,EACZ,MAAM,iBAAiB,CAAC;AASzB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAGlD;;;;;;;GAOG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,cAAc,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACxC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;CACd,CAAC;AAEF,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,2BAA2B,GACvC,kBAAkB,CAkBpB;AA6ED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,mBAAmB,GAAG;IACpE,WAAW,EAAE,kBAAkB,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;CACxB,CAqBA;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAMrE"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { KnownCaipNamespace, parseCaipAccountId, parseCaipAssetType, parseCaipChainId, toCaipChainId, } from '@metamask/utils';
|
|
2
|
+
import { getFees } from './transactions.js';
|
|
3
|
+
export function fromV1Transaction(transaction) {
|
|
4
|
+
return {
|
|
5
|
+
hash: transaction.hash,
|
|
6
|
+
chainId: toCaipChainId(KnownCaipNamespace.Eip155, transaction.chainId.toString()),
|
|
7
|
+
status: transaction.isError ? 'failed' : 'success',
|
|
8
|
+
timestamp: new Date(transaction.timestamp).getTime(),
|
|
9
|
+
from: transaction.from,
|
|
10
|
+
to: transaction.to,
|
|
11
|
+
value: transaction.value,
|
|
12
|
+
methodId: transaction.methodId,
|
|
13
|
+
transactionCategory: transaction.transactionCategory,
|
|
14
|
+
transactionProtocol: transaction.transactionProtocol,
|
|
15
|
+
valueTransfers: transaction.valueTransfers,
|
|
16
|
+
fees: getFees(transaction),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const evmContractTokenNamespaces = new Set(['erc20', 'erc721', 'erc1155']);
|
|
20
|
+
function getTransferType(assetClass, assetNamespace) {
|
|
21
|
+
if (assetClass === 'eip155Internal') {
|
|
22
|
+
return 'internal';
|
|
23
|
+
}
|
|
24
|
+
if (assetNamespace === 'slip44') {
|
|
25
|
+
return 'normal';
|
|
26
|
+
}
|
|
27
|
+
return assetNamespace;
|
|
28
|
+
}
|
|
29
|
+
function fromV5ValueTransfer({ assetClass, assetId, from, to, amount, decimal, symbol, name, }) {
|
|
30
|
+
const { chain, assetNamespace, assetReference } = parseCaipAssetType(assetId);
|
|
31
|
+
const isEvm = chain.namespace === KnownCaipNamespace.Eip155;
|
|
32
|
+
const isContractToken = isEvm && evmContractTokenNamespaces.has(assetNamespace);
|
|
33
|
+
return {
|
|
34
|
+
from,
|
|
35
|
+
to,
|
|
36
|
+
transferType: getTransferType(assetClass, assetNamespace),
|
|
37
|
+
amount,
|
|
38
|
+
decimal,
|
|
39
|
+
symbol,
|
|
40
|
+
name,
|
|
41
|
+
...(isContractToken ? { contractAddress: assetReference } : {}),
|
|
42
|
+
...(isEvm ? {} : { assetId }),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function fromV5Status(status) {
|
|
46
|
+
if (status === 'confirmed') {
|
|
47
|
+
return 'success';
|
|
48
|
+
}
|
|
49
|
+
if (status === 'failed') {
|
|
50
|
+
return 'failed';
|
|
51
|
+
}
|
|
52
|
+
return 'pending';
|
|
53
|
+
}
|
|
54
|
+
function fromV5Fee(fee) {
|
|
55
|
+
if (!fee) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
const { assetId, amount, decimals, symbol } = fee.asset;
|
|
59
|
+
return [
|
|
60
|
+
{
|
|
61
|
+
type: 'base',
|
|
62
|
+
amount,
|
|
63
|
+
decimals,
|
|
64
|
+
assetType: 'native',
|
|
65
|
+
assetId,
|
|
66
|
+
...(symbol ? { symbol } : {}),
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
export function fromV5TransactionRecord(record) {
|
|
71
|
+
const { tx, valueTransfers, fee } = record;
|
|
72
|
+
return {
|
|
73
|
+
subjectAddress: parseCaipAccountId(record.accountId)
|
|
74
|
+
.address,
|
|
75
|
+
transaction: {
|
|
76
|
+
hash: tx.id,
|
|
77
|
+
chainId: tx.chainId,
|
|
78
|
+
status: fromV5Status(tx.status),
|
|
79
|
+
timestamp: tx.timestamp,
|
|
80
|
+
from: tx.from,
|
|
81
|
+
to: tx.to ?? '',
|
|
82
|
+
value: tx.value,
|
|
83
|
+
methodId: tx.methodId ?? undefined,
|
|
84
|
+
transactionCategory: tx.transactionCategory,
|
|
85
|
+
transactionProtocol: tx.transactionProtocol,
|
|
86
|
+
valueTransfers: valueTransfers.map(fromV5ValueTransfer),
|
|
87
|
+
fees: fromV5Fee(fee),
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
export function toHexChainId(chainId) {
|
|
92
|
+
const { namespace, reference } = parseCaipChainId(chainId);
|
|
93
|
+
return namespace === KnownCaipNamespace.Eip155
|
|
94
|
+
? `0x${Number(reference).toString(16)}`
|
|
95
|
+
: undefined;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=indexed-transaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexed-transaction.js","sourceRoot":"","sources":["../../../src/mappers/helpers/indexed-transaction.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n V1TransactionByHashResponse,\n V5TransactionFee,\n V5TransactionRecord,\n V5TransactionValueTransfer,\n} from '@metamask/core-backend';\nimport type {\n CaipAccountId,\n CaipAssetType,\n CaipChainId,\n} from '@metamask/utils';\nimport {\n KnownCaipNamespace,\n parseCaipAccountId,\n parseCaipAssetType,\n parseCaipChainId,\n toCaipChainId,\n} from '@metamask/utils';\n\nimport type { Fee, Status } from '../../types.js';\nimport { getFees } from './transactions.js';\n\n/**\n * Value transfer in the shape the API mapper classifies, independent of the\n * Accounts API version it came from.\n *\n * `transferType` uses the V1 vocabulary (`normal`, `internal`, `erc20`,\n * `erc721`, `erc1155`). `assetId` is only set when it can't be derived from\n * `contractAddress` (non-EVM assets).\n */\nexport type IndexedValueTransfer = {\n from: string;\n to: string;\n transferType: string;\n amount?: string | number;\n decimal?: number;\n contractAddress?: string;\n symbol?: string;\n name?: string;\n assetId?: string;\n};\n\nexport type IndexedTransaction = {\n hash: string;\n chainId: CaipChainId;\n status: Status;\n timestamp: number;\n from: string;\n to: string;\n value?: string;\n methodId?: string;\n transactionCategory?: string;\n transactionProtocol?: string;\n valueTransfers?: IndexedValueTransfer[];\n fees?: Fee[];\n};\n\nexport function fromV1Transaction(\n transaction: V1TransactionByHashResponse,\n): IndexedTransaction {\n return {\n hash: transaction.hash,\n chainId: toCaipChainId(\n KnownCaipNamespace.Eip155,\n transaction.chainId.toString(),\n ),\n status: transaction.isError ? 'failed' : 'success',\n timestamp: new Date(transaction.timestamp).getTime(),\n from: transaction.from,\n to: transaction.to,\n value: transaction.value,\n methodId: transaction.methodId,\n transactionCategory: transaction.transactionCategory,\n transactionProtocol: transaction.transactionProtocol,\n valueTransfers: transaction.valueTransfers,\n fees: getFees(transaction),\n };\n}\n\nconst evmContractTokenNamespaces = new Set(['erc20', 'erc721', 'erc1155']);\n\nfunction getTransferType(assetClass: string, assetNamespace: string): string {\n if (assetClass === 'eip155Internal') {\n return 'internal';\n }\n\n if (assetNamespace === 'slip44') {\n return 'normal';\n }\n\n return assetNamespace;\n}\n\nfunction fromV5ValueTransfer({\n assetClass,\n assetId,\n from,\n to,\n amount,\n decimal,\n symbol,\n name,\n}: V5TransactionValueTransfer): IndexedValueTransfer {\n const { chain, assetNamespace, assetReference } = parseCaipAssetType(\n assetId as CaipAssetType,\n );\n const isEvm = chain.namespace === KnownCaipNamespace.Eip155;\n const isContractToken =\n isEvm && evmContractTokenNamespaces.has(assetNamespace);\n\n return {\n from,\n to,\n transferType: getTransferType(assetClass, assetNamespace),\n amount,\n decimal,\n symbol,\n name,\n ...(isContractToken ? { contractAddress: assetReference } : {}),\n ...(isEvm ? {} : { assetId }),\n };\n}\n\nfunction fromV5Status(status: string): Status {\n if (status === 'confirmed') {\n return 'success';\n }\n\n if (status === 'failed') {\n return 'failed';\n }\n\n return 'pending';\n}\n\nfunction fromV5Fee(fee: V5TransactionFee | null): Fee[] | undefined {\n if (!fee) {\n return undefined;\n }\n\n const { assetId, amount, decimals, symbol } = fee.asset;\n\n return [\n {\n type: 'base',\n amount,\n decimals,\n assetType: 'native',\n assetId,\n ...(symbol ? { symbol } : {}),\n },\n ];\n}\n\nexport function fromV5TransactionRecord(record: V5TransactionRecord): {\n transaction: IndexedTransaction;\n subjectAddress: string;\n} {\n const { tx, valueTransfers, fee } = record;\n\n return {\n subjectAddress: parseCaipAccountId(record.accountId as CaipAccountId)\n .address,\n transaction: {\n hash: tx.id,\n chainId: tx.chainId as CaipChainId,\n status: fromV5Status(tx.status),\n timestamp: tx.timestamp,\n from: tx.from,\n to: tx.to ?? '',\n value: tx.value,\n methodId: tx.methodId ?? undefined,\n transactionCategory: tx.transactionCategory,\n transactionProtocol: tx.transactionProtocol,\n valueTransfers: valueTransfers.map(fromV5ValueTransfer),\n fees: fromV5Fee(fee),\n },\n };\n}\n\nexport function toHexChainId(chainId: CaipChainId): string | undefined {\n const { namespace, reference } = parseCaipChainId(chainId);\n\n return namespace === KnownCaipNamespace.Eip155\n ? `0x${Number(reference).toString(16)}`\n : undefined;\n}\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { V1TransactionByHashResponse } from '@metamask/core-backend';
|
|
2
2
|
import type { TransactionMeta } from '@metamask/transaction-controller';
|
|
3
3
|
import type { CaipChainId, Hex } from '@metamask/utils';
|
|
4
|
-
import type { Fee, Status, TokenAmount
|
|
4
|
+
import type { Fee, Status, TokenAmount } from '../../types.js';
|
|
5
|
+
import type { IndexedValueTransfer } from './indexed-transaction.js';
|
|
5
6
|
export type TransactionGroup = {
|
|
6
7
|
hasCancelled: boolean;
|
|
7
8
|
hasRetried: boolean;
|
|
@@ -32,14 +33,14 @@ export declare function getLocalTransactionStatus({ primaryTransaction, initialT
|
|
|
32
33
|
export declare function isNftStandard(value?: string): boolean;
|
|
33
34
|
export declare function getNftPaymentTransfer({ side, sentTransfer, receivedTransfer, sentNativeTransfer, nftCounterparty, transactionFrom, transactionTo, subjectAddress, }: {
|
|
34
35
|
side: 'buy' | 'sell';
|
|
35
|
-
sentTransfer?:
|
|
36
|
-
receivedTransfer?:
|
|
37
|
-
sentNativeTransfer?:
|
|
36
|
+
sentTransfer?: IndexedValueTransfer;
|
|
37
|
+
receivedTransfer?: IndexedValueTransfer;
|
|
38
|
+
sentNativeTransfer?: IndexedValueTransfer;
|
|
38
39
|
nftCounterparty: string;
|
|
39
40
|
transactionFrom?: string;
|
|
40
41
|
transactionTo?: string;
|
|
41
42
|
subjectAddress: string;
|
|
42
|
-
}):
|
|
43
|
+
}): IndexedValueTransfer | undefined;
|
|
43
44
|
/**
|
|
44
45
|
* Resolves the user's primary send and receive legs from indexed value transfers.
|
|
45
46
|
* Prefers a receive whose symbol differs from the sent leg so dust does not win.
|
|
@@ -48,12 +49,12 @@ export declare function getNftPaymentTransfer({ side, sentTransfer, receivedTran
|
|
|
48
49
|
* @param subjectAddress - The account address to match transfers against.
|
|
49
50
|
* @returns The primary sent and received transfers for the account.
|
|
50
51
|
*/
|
|
51
|
-
export declare function parseValueTransfers(valueTransfers:
|
|
52
|
-
sentTransfer:
|
|
53
|
-
receivedTransfer:
|
|
54
|
-
sentNativeTransfer:
|
|
55
|
-
sentNftTransfer:
|
|
56
|
-
receivedNftTransfer:
|
|
52
|
+
export declare function parseValueTransfers(valueTransfers: IndexedValueTransfer[] | undefined, subjectAddress: string): {
|
|
53
|
+
sentTransfer: IndexedValueTransfer | undefined;
|
|
54
|
+
receivedTransfer: IndexedValueTransfer | undefined;
|
|
55
|
+
sentNativeTransfer: IndexedValueTransfer | undefined;
|
|
56
|
+
sentNftTransfer: IndexedValueTransfer | undefined;
|
|
57
|
+
receivedNftTransfer: IndexedValueTransfer | undefined;
|
|
57
58
|
};
|
|
58
59
|
/**
|
|
59
60
|
* Optional host callback that resolves ERC-20 decimals (and optionally symbol)
|
|
@@ -79,6 +80,6 @@ export type GetKnownTokenDecimals = (chainId: CaipChainId, contractAddress: stri
|
|
|
79
80
|
* @param getKnownTokenDecimals - Optional host lookup for missing ERC-20 metadata.
|
|
80
81
|
* @returns A token amount, or undefined when nothing useful can be derived.
|
|
81
82
|
*/
|
|
82
|
-
export declare function getTokenAmountFromTransfer(transfer:
|
|
83
|
+
export declare function getTokenAmountFromTransfer(transfer: IndexedValueTransfer | undefined, direction: TokenAmount['direction'], chainId: CaipChainId, getKnownTokenDecimals?: GetKnownTokenDecimals): TokenAmount | undefined;
|
|
83
84
|
export declare function getTokenMetadataFromKnownToken(contractAddress: string | undefined, direction: TokenAmount['direction'], chainId: CaipChainId): TokenAmount | undefined;
|
|
84
85
|
//# sourceMappingURL=transactions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transactions.d.ts","sourceRoot":"","sources":["../../../src/mappers/helpers/transactions.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,KAAK,EACV,eAAe,EAEhB,MAAM,kCAAkC,CAAC;AAK1C,OAAO,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAExD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"transactions.d.ts","sourceRoot":"","sources":["../../../src/mappers/helpers/transactions.ts"],"names":[],"mappings":"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"}
|
|
@@ -287,11 +287,11 @@ export function getTokenAmountFromTransfer(transfer, direction, chainId, getKnow
|
|
|
287
287
|
decimals !== undefined;
|
|
288
288
|
// NFT amounts are counts, not base units — keep them even without decimals.
|
|
289
289
|
const hasNftAmount = isNftTransfer && amount !== null && amount !== undefined;
|
|
290
|
-
let assetId;
|
|
291
|
-
if (isNative) {
|
|
290
|
+
let { assetId } = transfer;
|
|
291
|
+
if (!assetId && isNative) {
|
|
292
292
|
assetId = resolveNativeAssetId(chainId, symbol);
|
|
293
293
|
}
|
|
294
|
-
else if (!isNftTransfer) {
|
|
294
|
+
else if (!assetId && !isNftTransfer) {
|
|
295
295
|
assetId = resolveAssetId(chainId, transfer.contractAddress);
|
|
296
296
|
}
|
|
297
297
|
if (!symbol && !hasScaledAmount && !hasNftAmount && !assetId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transactions.js","sourceRoot":"","sources":["../../../src/mappers/helpers/transactions.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ERC721,\n ERC1155,\n isEqualCaseInsensitive as equalsIgnoreCase,\n} from '@metamask/controller-utils';\nimport type { V1TransactionByHashResponse } from '@metamask/core-backend';\nimport type {\n TransactionMeta,\n TransactionReceipt,\n} from '@metamask/transaction-controller';\nimport {\n TransactionStatus,\n TransactionType,\n} from '@metamask/transaction-controller';\nimport type { CaipChainId, Hex } from '@metamask/utils';\n\nimport type {\n AssetType,\n Fee,\n Status,\n TokenAmount,\n ValueTransfer,\n} from '../../types.js';\nimport { nativeTokenDecimals } from '../constants.js';\nimport {\n formatAddressToAssetId,\n formatChainIdToCaip,\n getNativeAsset,\n resolveNativeAssetId,\n} from './caip.js';\nimport { getKnownTokenMetadata } from './token-metadata.js';\n\n// Adds optional `isSmartTransaction` to `TransactionMeta`.\nexport type TransactionGroup = {\n hasCancelled: boolean;\n hasRetried: boolean;\n initialTransaction: TransactionMeta & { isSmartTransaction?: boolean };\n nonce: Hex;\n primaryTransaction: TransactionMeta;\n transactions: TransactionMeta[];\n};\n\nfunction calculateNetworkFee(\n gasUsed: string | number | undefined,\n gasPrice: string | number | undefined,\n): string | undefined {\n if (gasUsed === undefined || gasPrice === undefined) {\n return undefined;\n }\n\n try {\n return String(BigInt(gasUsed) * BigInt(gasPrice));\n } catch {\n return undefined;\n }\n}\n\n/**\n * Calculates the OP Stack / Mantle operator fee from the receipt.\n *\n * Jovian receipts (with `daFootprintGasScalar`):\n * `gasUsed * operatorFeeScalar * 100 + operatorFeeConstant`.\n * Isthmus receipts: `gasUsed * operatorFeeScalar / 1e6 + operatorFeeConstant`.\n *\n * @param txReceipt - Transaction receipt.\n * @returns Operator fee in wei, or 0 when the receipt has no operator fee fields.\n */\nfunction calculateOperatorFee(\n txReceipt: TransactionReceipt | undefined,\n): bigint {\n const {\n daFootprintGasScalar,\n gasUsed,\n operatorFeeConstant,\n operatorFeeScalar,\n } = txReceipt ?? {};\n\n if (!gasUsed || !operatorFeeScalar || !operatorFeeConstant) {\n return 0n;\n }\n\n const fee = BigInt(gasUsed) * BigInt(operatorFeeScalar);\n const scaledFee =\n daFootprintGasScalar === undefined ? fee / 1_000_000n : fee * 100n;\n\n return scaledFee + BigInt(operatorFeeConstant);\n}\n\n/**\n * Sums the L2, L1, and operator fees from the receipt.\n *\n * @param l2Fee - L2 network fee in decimal wei.\n * @param txReceipt - Transaction receipt.\n * @returns Total fee in decimal wei, or the L2 fee if a receipt value is invalid.\n */\nfunction calculateTotalFee(\n l2Fee: string,\n txReceipt: TransactionReceipt | undefined,\n): string {\n try {\n const l1Fee = BigInt(txReceipt?.l1Fee ?? 0);\n const operatorFee = calculateOperatorFee(txReceipt);\n\n return String(BigInt(l2Fee) + l1Fee + operatorFee);\n } catch {\n return l2Fee;\n }\n}\n\nfunction toNetworkFee(\n amount: string,\n chainId: CaipChainId,\n symbol?: string,\n): Fee {\n const nativeAsset = getNativeAsset(chainId);\n\n if (nativeAsset) {\n return {\n type: 'base',\n amount,\n decimals: nativeTokenDecimals,\n assetType: 'native',\n symbol: symbol ?? nativeAsset.symbol,\n assetId: nativeAsset.assetId,\n };\n }\n\n const assetId = symbol ? resolveNativeAssetId(chainId, symbol) : undefined;\n\n return {\n type: 'base',\n amount,\n decimals: nativeTokenDecimals,\n assetType: 'native',\n ...(symbol ? { symbol } : {}),\n ...(assetId ? { assetId } : {}),\n };\n}\n\nfunction getAssetTypeFromTransferType(\n transferType: string | undefined,\n): AssetType | undefined {\n if (transferType === 'normal' || transferType === 'internal') {\n return 'native';\n }\n\n if (transferType === 'erc20') {\n return 'erc20';\n }\n\n if (transferType === ERC721.toLowerCase() || transferType === 'erc721') {\n return 'erc721';\n }\n\n if (transferType === ERC1155.toLowerCase() || transferType === 'erc1155') {\n return 'erc1155';\n }\n\n return undefined;\n}\n\nfunction getNetworkFee(\n transaction: V1TransactionByHashResponse,\n): Fee | undefined {\n const chainId = formatChainIdToCaip(transaction.chainId);\n\n if (!chainId) {\n return undefined;\n }\n\n const amount = calculateNetworkFee(\n transaction.gasUsed,\n transaction.effectiveGasPrice,\n );\n\n if (!amount) {\n return undefined;\n }\n\n return toNetworkFee(amount, chainId);\n}\n\nexport function getFees(\n transaction: V1TransactionByHashResponse,\n): Fee[] | undefined {\n const networkFee = getNetworkFee(transaction);\n\n return networkFee ? [networkFee] : undefined;\n}\n\n/**\n * Builds the base network fee (in the chain's native token) for a local\n * transaction from its receipt (`gasUsed × effectiveGasPrice`), plus the\n * L1 and operator fees from the receipt. Falls back to `txParams.gasPrice`\n * while pending.\n *\n * @param transactionGroup - Transaction group with the primary transaction.\n * @returns Activity fee list with a single base network fee, or undefined.\n */\nexport function getLocalTransactionFees(\n transactionGroup: Pick<TransactionGroup, 'primaryTransaction'> & {\n nativeAssetSymbol?: string;\n },\n): Fee[] | undefined {\n const { primaryTransaction, nativeAssetSymbol } = transactionGroup;\n const chainId = formatChainIdToCaip(primaryTransaction.chainId);\n\n if (!chainId) {\n return undefined;\n }\n\n const { txReceipt } = primaryTransaction;\n\n const l2Fee = calculateNetworkFee(\n txReceipt?.gasUsed,\n txReceipt?.effectiveGasPrice ?? primaryTransaction.txParams?.gasPrice,\n );\n\n if (!l2Fee) {\n return undefined;\n }\n\n const amount = calculateTotalFee(l2Fee, txReceipt);\n\n return [toNetworkFee(amount, chainId, nativeAssetSymbol)];\n}\n\nconst inProgressTransactionStatuses = [\n TransactionStatus.unapproved,\n TransactionStatus.approved,\n TransactionStatus.signed,\n TransactionStatus.submitted,\n];\n\nconst transactionGroupCancelledStatus = 'cancelled';\n\nconst smartTransactionStatus = {\n cancelled: 'cancelled',\n pending: 'pending',\n success: 'success',\n} as const;\n\nfunction getTransactionStatusKey(\n transaction: TransactionGroup['primaryTransaction'],\n): string {\n const { type, status } = transaction;\n const receiptStatus = transaction.txReceipt?.status;\n\n if (receiptStatus === '0x0') {\n return TransactionStatus.failed;\n }\n\n if (\n status === TransactionStatus.confirmed &&\n type === TransactionType.cancel\n ) {\n return transactionGroupCancelledStatus;\n }\n\n return transaction.status;\n}\n\nexport function getLocalTransactionStatus({\n primaryTransaction,\n initialTransaction,\n}: {\n primaryTransaction: TransactionGroup['primaryTransaction'];\n initialTransaction: TransactionGroup['initialTransaction'];\n}): Status {\n if (initialTransaction.isSmartTransaction) {\n const smartStatus = initialTransaction.status as string | undefined;\n\n if (smartStatus === smartTransactionStatus.pending) {\n return 'pending';\n }\n\n if (smartStatus === smartTransactionStatus.success) {\n return 'success';\n }\n\n if (smartStatus === smartTransactionStatus.cancelled) {\n return 'failed';\n }\n\n return 'pending';\n }\n\n const statusKey = getTransactionStatusKey(primaryTransaction);\n\n if (statusKey === TransactionStatus.confirmed) {\n return 'success';\n }\n\n if (\n statusKey === TransactionStatus.cancelled ||\n statusKey === transactionGroupCancelledStatus ||\n statusKey === TransactionStatus.dropped ||\n statusKey === TransactionStatus.failed ||\n statusKey === TransactionStatus.rejected\n ) {\n return 'failed';\n }\n\n if (\n inProgressTransactionStatuses.includes(\n statusKey as (typeof inProgressTransactionStatuses)[number],\n )\n ) {\n return 'pending';\n }\n\n return 'pending';\n}\n\nexport function isNftStandard(value?: string): boolean {\n return value === ERC721.toLowerCase() || value === ERC1155.toLowerCase();\n}\n\nexport function getNftPaymentTransfer({\n side,\n sentTransfer,\n receivedTransfer,\n sentNativeTransfer,\n nftCounterparty,\n transactionFrom,\n transactionTo,\n subjectAddress,\n}: {\n side: 'buy' | 'sell';\n sentTransfer?: ValueTransfer;\n receivedTransfer?: ValueTransfer;\n sentNativeTransfer?: ValueTransfer;\n nftCounterparty: string;\n transactionFrom?: string;\n transactionTo?: string;\n subjectAddress: string;\n}): ValueTransfer | undefined {\n const isFungible = (transfer?: ValueTransfer): boolean =>\n Boolean(transfer && !isNftStandard(transfer.transferType));\n\n if (side === 'buy') {\n for (const transfer of [sentNativeTransfer, sentTransfer]) {\n if (!transfer || !isFungible(transfer)) {\n continue;\n }\n\n // Only count a payment that goes to the NFT counterparty (direct sale) or\n // to the contract being called (marketplace/router). This avoids treating\n // an unrelated native send in the same transaction as the NFT payment.\n if (\n equalsIgnoreCase(transfer.to, nftCounterparty) ||\n equalsIgnoreCase(transfer.to, transactionTo as string)\n ) {\n return transfer;\n }\n }\n\n return undefined;\n }\n\n if (!receivedTransfer || !isFungible(receivedTransfer)) {\n return undefined;\n }\n\n if (\n equalsIgnoreCase(receivedTransfer.from, nftCounterparty) ||\n (transactionFrom &&\n !equalsIgnoreCase(transactionFrom, subjectAddress) &&\n equalsIgnoreCase(receivedTransfer.from, transactionFrom))\n ) {\n return receivedTransfer;\n }\n\n return undefined;\n}\n\nconst resolveAssetId = (\n chainId: CaipChainId,\n contractAddress: string | undefined,\n): string | undefined => {\n if (!contractAddress) {\n return undefined;\n }\n\n return formatAddressToAssetId(contractAddress, chainId);\n};\n\n/**\n * Resolves the user's primary send and receive legs from indexed value transfers.\n * Prefers a receive whose symbol differs from the sent leg so dust does not win.\n *\n * @param valueTransfers - Indexed value transfers from the Accounts API.\n * @param subjectAddress - The account address to match transfers against.\n * @returns The primary sent and received transfers for the account.\n */\nexport function parseValueTransfers(\n valueTransfers: ValueTransfer[] | undefined,\n subjectAddress: string,\n): {\n sentTransfer: ValueTransfer | undefined;\n receivedTransfer: ValueTransfer | undefined;\n sentNativeTransfer: ValueTransfer | undefined;\n sentNftTransfer: ValueTransfer | undefined;\n receivedNftTransfer: ValueTransfer | undefined;\n} {\n const sent = valueTransfers?.filter(({ from }) =>\n equalsIgnoreCase(from, subjectAddress),\n );\n const received = valueTransfers?.filter(({ to }) =>\n equalsIgnoreCase(to, subjectAddress),\n );\n\n const sentTransfer = sent?.[0];\n\n const receivedTransfer =\n received?.find(({ symbol }) => symbol !== sentTransfer?.symbol) ??\n received?.[0];\n\n const sentNativeTransfer = sent?.find(\n ({ transferType }) => transferType === 'normal',\n );\n\n const sentNftTransfer = sent?.find(({ transferType }) =>\n isNftStandard(transferType),\n );\n const receivedNftTransfer = received?.find(({ transferType }) =>\n isNftStandard(transferType),\n );\n\n return {\n sentTransfer,\n receivedTransfer,\n sentNativeTransfer,\n sentNftTransfer,\n receivedNftTransfer,\n };\n}\n\n/**\n * Optional host callback that resolves ERC-20 decimals (and optionally symbol)\n * when Accounts API enrichment omitted them on a value transfer.\n *\n * Hosts typically wire this to on-device token state (e.g. TokensController).\n * Do not use this to override a present-but-wrong `transfer.decimal`.\n */\nexport type GetKnownTokenDecimals = (\n chainId: CaipChainId,\n contractAddress: string,\n) => { decimals?: number; symbol?: string } | undefined;\n\n/**\n * Maps an Accounts API value transfer into a fungible/NFT {@link TokenAmount}.\n *\n * Fungible amounts are base units and are only emitted when a decimals scale is\n * known (from the transfer, native defaults, static metadata, or the optional\n * host hook). NFT amounts are token counts and are never fail-closed.\n *\n * @param transfer - Indexed value transfer, or undefined.\n * @param direction - Whether this leg is incoming or outgoing for the subject.\n * @param chainId - CAIP-2 chain id for the transaction.\n * @param getKnownTokenDecimals - Optional host lookup for missing ERC-20 metadata.\n * @returns A token amount, or undefined when nothing useful can be derived.\n */\nexport function getTokenAmountFromTransfer(\n transfer: ValueTransfer | undefined,\n direction: TokenAmount['direction'],\n chainId: CaipChainId,\n getKnownTokenDecimals?: GetKnownTokenDecimals,\n): TokenAmount | undefined {\n if (!transfer) {\n return undefined;\n }\n\n const { transferType, amount } = transfer;\n const isNftTransfer = isNftStandard(transferType);\n const assetType = getAssetTypeFromTransferType(transferType);\n const isNative = assetType === 'native';\n\n const knownToken =\n !isNftTransfer && !isNative && transfer.contractAddress\n ? getKnownTokenMetadata(chainId, transfer.contractAddress)\n : undefined;\n const hostToken =\n !isNftTransfer && !isNative && transfer.contractAddress\n ? getKnownTokenDecimals?.(chainId, transfer.contractAddress)\n : undefined;\n\n const symbol = isNftTransfer\n ? (transfer.name ?? transfer.symbol)\n : (transfer.symbol ?? knownToken?.symbol ?? hostToken?.symbol);\n\n let decimals: number | undefined;\n if (transfer.decimal !== undefined) {\n decimals = transfer.decimal;\n } else if (isNative) {\n decimals = nativeTokenDecimals;\n } else if (!isNftTransfer) {\n decimals = knownToken?.decimals ?? hostToken?.decimals;\n }\n\n const hasScaledAmount =\n !isNftTransfer &&\n amount !== null &&\n amount !== undefined &&\n decimals !== undefined;\n // NFT amounts are counts, not base units — keep them even without decimals.\n const hasNftAmount = isNftTransfer && amount !== null && amount !== undefined;\n\n let assetId: string | undefined;\n if (isNative) {\n assetId = resolveNativeAssetId(chainId, symbol);\n } else if (!isNftTransfer) {\n assetId = resolveAssetId(chainId, transfer.contractAddress);\n }\n\n if (!symbol && !hasScaledAmount && !hasNftAmount && !assetId) {\n return undefined;\n }\n\n return {\n direction,\n ...(hasScaledAmount || hasNftAmount ? { amount: String(amount) } : {}),\n ...(decimals === undefined ? {} : { decimals }),\n ...(symbol ? { symbol } : {}),\n ...(assetId ? { assetId } : {}),\n ...(assetType ? { assetType } : {}),\n };\n}\n\nexport function getTokenMetadataFromKnownToken(\n contractAddress: string | undefined,\n direction: TokenAmount['direction'],\n chainId: CaipChainId,\n): TokenAmount | undefined {\n const tokenMetadata = getKnownTokenMetadata(chainId, contractAddress);\n\n if (!tokenMetadata) {\n return undefined;\n }\n\n return {\n direction,\n assetType: 'erc20',\n ...(tokenMetadata.symbol ? { symbol: tokenMetadata.symbol } : {}),\n ...(tokenMetadata.decimals === undefined\n ? {}\n : { decimals: tokenMetadata.decimals }),\n ...(tokenMetadata.assetId ? { assetId: tokenMetadata.assetId } : {}),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"transactions.js","sourceRoot":"","sources":["../../../src/mappers/helpers/transactions.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ERC721,\n ERC1155,\n isEqualCaseInsensitive as equalsIgnoreCase,\n} from '@metamask/controller-utils';\nimport type { V1TransactionByHashResponse } from '@metamask/core-backend';\nimport type {\n TransactionMeta,\n TransactionReceipt,\n} from '@metamask/transaction-controller';\nimport {\n TransactionStatus,\n TransactionType,\n} from '@metamask/transaction-controller';\nimport type { CaipChainId, Hex } from '@metamask/utils';\n\nimport type { AssetType, Fee, Status, TokenAmount } from '../../types.js';\nimport { nativeTokenDecimals } from '../constants.js';\nimport {\n formatAddressToAssetId,\n formatChainIdToCaip,\n getNativeAsset,\n resolveNativeAssetId,\n} from './caip.js';\nimport type { IndexedValueTransfer } from './indexed-transaction.js';\nimport { getKnownTokenMetadata } from './token-metadata.js';\n\n// Adds optional `isSmartTransaction` to `TransactionMeta`.\nexport type TransactionGroup = {\n hasCancelled: boolean;\n hasRetried: boolean;\n initialTransaction: TransactionMeta & { isSmartTransaction?: boolean };\n nonce: Hex;\n primaryTransaction: TransactionMeta;\n transactions: TransactionMeta[];\n};\n\nfunction calculateNetworkFee(\n gasUsed: string | number | undefined,\n gasPrice: string | number | undefined,\n): string | undefined {\n if (gasUsed === undefined || gasPrice === undefined) {\n return undefined;\n }\n\n try {\n return String(BigInt(gasUsed) * BigInt(gasPrice));\n } catch {\n return undefined;\n }\n}\n\n/**\n * Calculates the OP Stack / Mantle operator fee from the receipt.\n *\n * Jovian receipts (with `daFootprintGasScalar`):\n * `gasUsed * operatorFeeScalar * 100 + operatorFeeConstant`.\n * Isthmus receipts: `gasUsed * operatorFeeScalar / 1e6 + operatorFeeConstant`.\n *\n * @param txReceipt - Transaction receipt.\n * @returns Operator fee in wei, or 0 when the receipt has no operator fee fields.\n */\nfunction calculateOperatorFee(\n txReceipt: TransactionReceipt | undefined,\n): bigint {\n const {\n daFootprintGasScalar,\n gasUsed,\n operatorFeeConstant,\n operatorFeeScalar,\n } = txReceipt ?? {};\n\n if (!gasUsed || !operatorFeeScalar || !operatorFeeConstant) {\n return 0n;\n }\n\n const fee = BigInt(gasUsed) * BigInt(operatorFeeScalar);\n const scaledFee =\n daFootprintGasScalar === undefined ? fee / 1_000_000n : fee * 100n;\n\n return scaledFee + BigInt(operatorFeeConstant);\n}\n\n/**\n * Sums the L2, L1, and operator fees from the receipt.\n *\n * @param l2Fee - L2 network fee in decimal wei.\n * @param txReceipt - Transaction receipt.\n * @returns Total fee in decimal wei, or the L2 fee if a receipt value is invalid.\n */\nfunction calculateTotalFee(\n l2Fee: string,\n txReceipt: TransactionReceipt | undefined,\n): string {\n try {\n const l1Fee = BigInt(txReceipt?.l1Fee ?? 0);\n const operatorFee = calculateOperatorFee(txReceipt);\n\n return String(BigInt(l2Fee) + l1Fee + operatorFee);\n } catch {\n return l2Fee;\n }\n}\n\nfunction toNetworkFee(\n amount: string,\n chainId: CaipChainId,\n symbol?: string,\n): Fee {\n const nativeAsset = getNativeAsset(chainId);\n\n if (nativeAsset) {\n return {\n type: 'base',\n amount,\n decimals: nativeTokenDecimals,\n assetType: 'native',\n symbol: symbol ?? nativeAsset.symbol,\n assetId: nativeAsset.assetId,\n };\n }\n\n const assetId = symbol ? resolveNativeAssetId(chainId, symbol) : undefined;\n\n return {\n type: 'base',\n amount,\n decimals: nativeTokenDecimals,\n assetType: 'native',\n ...(symbol ? { symbol } : {}),\n ...(assetId ? { assetId } : {}),\n };\n}\n\nfunction getAssetTypeFromTransferType(\n transferType: string | undefined,\n): AssetType | undefined {\n if (transferType === 'normal' || transferType === 'internal') {\n return 'native';\n }\n\n if (transferType === 'erc20') {\n return 'erc20';\n }\n\n if (transferType === ERC721.toLowerCase() || transferType === 'erc721') {\n return 'erc721';\n }\n\n if (transferType === ERC1155.toLowerCase() || transferType === 'erc1155') {\n return 'erc1155';\n }\n\n return undefined;\n}\n\nfunction getNetworkFee(\n transaction: V1TransactionByHashResponse,\n): Fee | undefined {\n const chainId = formatChainIdToCaip(transaction.chainId);\n\n if (!chainId) {\n return undefined;\n }\n\n const amount = calculateNetworkFee(\n transaction.gasUsed,\n transaction.effectiveGasPrice,\n );\n\n if (!amount) {\n return undefined;\n }\n\n return toNetworkFee(amount, chainId);\n}\n\nexport function getFees(\n transaction: V1TransactionByHashResponse,\n): Fee[] | undefined {\n const networkFee = getNetworkFee(transaction);\n\n return networkFee ? [networkFee] : undefined;\n}\n\n/**\n * Builds the base network fee (in the chain's native token) for a local\n * transaction from its receipt (`gasUsed × effectiveGasPrice`), plus the\n * L1 and operator fees from the receipt. Falls back to `txParams.gasPrice`\n * while pending.\n *\n * @param transactionGroup - Transaction group with the primary transaction.\n * @returns Activity fee list with a single base network fee, or undefined.\n */\nexport function getLocalTransactionFees(\n transactionGroup: Pick<TransactionGroup, 'primaryTransaction'> & {\n nativeAssetSymbol?: string;\n },\n): Fee[] | undefined {\n const { primaryTransaction, nativeAssetSymbol } = transactionGroup;\n const chainId = formatChainIdToCaip(primaryTransaction.chainId);\n\n if (!chainId) {\n return undefined;\n }\n\n const { txReceipt } = primaryTransaction;\n\n const l2Fee = calculateNetworkFee(\n txReceipt?.gasUsed,\n txReceipt?.effectiveGasPrice ?? primaryTransaction.txParams?.gasPrice,\n );\n\n if (!l2Fee) {\n return undefined;\n }\n\n const amount = calculateTotalFee(l2Fee, txReceipt);\n\n return [toNetworkFee(amount, chainId, nativeAssetSymbol)];\n}\n\nconst inProgressTransactionStatuses = [\n TransactionStatus.unapproved,\n TransactionStatus.approved,\n TransactionStatus.signed,\n TransactionStatus.submitted,\n];\n\nconst transactionGroupCancelledStatus = 'cancelled';\n\nconst smartTransactionStatus = {\n cancelled: 'cancelled',\n pending: 'pending',\n success: 'success',\n} as const;\n\nfunction getTransactionStatusKey(\n transaction: TransactionGroup['primaryTransaction'],\n): string {\n const { type, status } = transaction;\n const receiptStatus = transaction.txReceipt?.status;\n\n if (receiptStatus === '0x0') {\n return TransactionStatus.failed;\n }\n\n if (\n status === TransactionStatus.confirmed &&\n type === TransactionType.cancel\n ) {\n return transactionGroupCancelledStatus;\n }\n\n return transaction.status;\n}\n\nexport function getLocalTransactionStatus({\n primaryTransaction,\n initialTransaction,\n}: {\n primaryTransaction: TransactionGroup['primaryTransaction'];\n initialTransaction: TransactionGroup['initialTransaction'];\n}): Status {\n if (initialTransaction.isSmartTransaction) {\n const smartStatus = initialTransaction.status as string | undefined;\n\n if (smartStatus === smartTransactionStatus.pending) {\n return 'pending';\n }\n\n if (smartStatus === smartTransactionStatus.success) {\n return 'success';\n }\n\n if (smartStatus === smartTransactionStatus.cancelled) {\n return 'failed';\n }\n\n return 'pending';\n }\n\n const statusKey = getTransactionStatusKey(primaryTransaction);\n\n if (statusKey === TransactionStatus.confirmed) {\n return 'success';\n }\n\n if (\n statusKey === TransactionStatus.cancelled ||\n statusKey === transactionGroupCancelledStatus ||\n statusKey === TransactionStatus.dropped ||\n statusKey === TransactionStatus.failed ||\n statusKey === TransactionStatus.rejected\n ) {\n return 'failed';\n }\n\n if (\n inProgressTransactionStatuses.includes(\n statusKey as (typeof inProgressTransactionStatuses)[number],\n )\n ) {\n return 'pending';\n }\n\n return 'pending';\n}\n\nexport function isNftStandard(value?: string): boolean {\n return value === ERC721.toLowerCase() || value === ERC1155.toLowerCase();\n}\n\nexport function getNftPaymentTransfer({\n side,\n sentTransfer,\n receivedTransfer,\n sentNativeTransfer,\n nftCounterparty,\n transactionFrom,\n transactionTo,\n subjectAddress,\n}: {\n side: 'buy' | 'sell';\n sentTransfer?: IndexedValueTransfer;\n receivedTransfer?: IndexedValueTransfer;\n sentNativeTransfer?: IndexedValueTransfer;\n nftCounterparty: string;\n transactionFrom?: string;\n transactionTo?: string;\n subjectAddress: string;\n}): IndexedValueTransfer | undefined {\n const isFungible = (transfer?: IndexedValueTransfer): boolean =>\n Boolean(transfer && !isNftStandard(transfer.transferType));\n\n if (side === 'buy') {\n for (const transfer of [sentNativeTransfer, sentTransfer]) {\n if (!transfer || !isFungible(transfer)) {\n continue;\n }\n\n // Only count a payment that goes to the NFT counterparty (direct sale) or\n // to the contract being called (marketplace/router). This avoids treating\n // an unrelated native send in the same transaction as the NFT payment.\n if (\n equalsIgnoreCase(transfer.to, nftCounterparty) ||\n equalsIgnoreCase(transfer.to, transactionTo as string)\n ) {\n return transfer;\n }\n }\n\n return undefined;\n }\n\n if (!receivedTransfer || !isFungible(receivedTransfer)) {\n return undefined;\n }\n\n if (\n equalsIgnoreCase(receivedTransfer.from, nftCounterparty) ||\n (transactionFrom &&\n !equalsIgnoreCase(transactionFrom, subjectAddress) &&\n equalsIgnoreCase(receivedTransfer.from, transactionFrom))\n ) {\n return receivedTransfer;\n }\n\n return undefined;\n}\n\nconst resolveAssetId = (\n chainId: CaipChainId,\n contractAddress: string | undefined,\n): string | undefined => {\n if (!contractAddress) {\n return undefined;\n }\n\n return formatAddressToAssetId(contractAddress, chainId);\n};\n\n/**\n * Resolves the user's primary send and receive legs from indexed value transfers.\n * Prefers a receive whose symbol differs from the sent leg so dust does not win.\n *\n * @param valueTransfers - Indexed value transfers from the Accounts API.\n * @param subjectAddress - The account address to match transfers against.\n * @returns The primary sent and received transfers for the account.\n */\nexport function parseValueTransfers(\n valueTransfers: IndexedValueTransfer[] | undefined,\n subjectAddress: string,\n): {\n sentTransfer: IndexedValueTransfer | undefined;\n receivedTransfer: IndexedValueTransfer | undefined;\n sentNativeTransfer: IndexedValueTransfer | undefined;\n sentNftTransfer: IndexedValueTransfer | undefined;\n receivedNftTransfer: IndexedValueTransfer | undefined;\n} {\n const sent = valueTransfers?.filter(({ from }) =>\n equalsIgnoreCase(from, subjectAddress),\n );\n const received = valueTransfers?.filter(({ to }) =>\n equalsIgnoreCase(to, subjectAddress),\n );\n\n const sentTransfer = sent?.[0];\n\n const receivedTransfer =\n received?.find(({ symbol }) => symbol !== sentTransfer?.symbol) ??\n received?.[0];\n\n const sentNativeTransfer = sent?.find(\n ({ transferType }) => transferType === 'normal',\n );\n\n const sentNftTransfer = sent?.find(({ transferType }) =>\n isNftStandard(transferType),\n );\n const receivedNftTransfer = received?.find(({ transferType }) =>\n isNftStandard(transferType),\n );\n\n return {\n sentTransfer,\n receivedTransfer,\n sentNativeTransfer,\n sentNftTransfer,\n receivedNftTransfer,\n };\n}\n\n/**\n * Optional host callback that resolves ERC-20 decimals (and optionally symbol)\n * when Accounts API enrichment omitted them on a value transfer.\n *\n * Hosts typically wire this to on-device token state (e.g. TokensController).\n * Do not use this to override a present-but-wrong `transfer.decimal`.\n */\nexport type GetKnownTokenDecimals = (\n chainId: CaipChainId,\n contractAddress: string,\n) => { decimals?: number; symbol?: string } | undefined;\n\n/**\n * Maps an Accounts API value transfer into a fungible/NFT {@link TokenAmount}.\n *\n * Fungible amounts are base units and are only emitted when a decimals scale is\n * known (from the transfer, native defaults, static metadata, or the optional\n * host hook). NFT amounts are token counts and are never fail-closed.\n *\n * @param transfer - Indexed value transfer, or undefined.\n * @param direction - Whether this leg is incoming or outgoing for the subject.\n * @param chainId - CAIP-2 chain id for the transaction.\n * @param getKnownTokenDecimals - Optional host lookup for missing ERC-20 metadata.\n * @returns A token amount, or undefined when nothing useful can be derived.\n */\nexport function getTokenAmountFromTransfer(\n transfer: IndexedValueTransfer | undefined,\n direction: TokenAmount['direction'],\n chainId: CaipChainId,\n getKnownTokenDecimals?: GetKnownTokenDecimals,\n): TokenAmount | undefined {\n if (!transfer) {\n return undefined;\n }\n\n const { transferType, amount } = transfer;\n const isNftTransfer = isNftStandard(transferType);\n const assetType = getAssetTypeFromTransferType(transferType);\n const isNative = assetType === 'native';\n\n const knownToken =\n !isNftTransfer && !isNative && transfer.contractAddress\n ? getKnownTokenMetadata(chainId, transfer.contractAddress)\n : undefined;\n const hostToken =\n !isNftTransfer && !isNative && transfer.contractAddress\n ? getKnownTokenDecimals?.(chainId, transfer.contractAddress)\n : undefined;\n\n const symbol = isNftTransfer\n ? (transfer.name ?? transfer.symbol)\n : (transfer.symbol ?? knownToken?.symbol ?? hostToken?.symbol);\n\n let decimals: number | undefined;\n if (transfer.decimal !== undefined) {\n decimals = transfer.decimal;\n } else if (isNative) {\n decimals = nativeTokenDecimals;\n } else if (!isNftTransfer) {\n decimals = knownToken?.decimals ?? hostToken?.decimals;\n }\n\n const hasScaledAmount =\n !isNftTransfer &&\n amount !== null &&\n amount !== undefined &&\n decimals !== undefined;\n // NFT amounts are counts, not base units — keep them even without decimals.\n const hasNftAmount = isNftTransfer && amount !== null && amount !== undefined;\n\n let { assetId } = transfer;\n if (!assetId && isNative) {\n assetId = resolveNativeAssetId(chainId, symbol);\n } else if (!assetId && !isNftTransfer) {\n assetId = resolveAssetId(chainId, transfer.contractAddress);\n }\n\n if (!symbol && !hasScaledAmount && !hasNftAmount && !assetId) {\n return undefined;\n }\n\n return {\n direction,\n ...(hasScaledAmount || hasNftAmount ? { amount: String(amount) } : {}),\n ...(decimals === undefined ? {} : { decimals }),\n ...(symbol ? { symbol } : {}),\n ...(assetId ? { assetId } : {}),\n ...(assetType ? { assetType } : {}),\n };\n}\n\nexport function getTokenMetadataFromKnownToken(\n contractAddress: string | undefined,\n direction: TokenAmount['direction'],\n chainId: CaipChainId,\n): TokenAmount | undefined {\n const tokenMetadata = getKnownTokenMetadata(chainId, contractAddress);\n\n if (!tokenMetadata) {\n return undefined;\n }\n\n return {\n direction,\n assetType: 'erc20',\n ...(tokenMetadata.symbol ? { symbol: tokenMetadata.symbol } : {}),\n ...(tokenMetadata.decimals === undefined\n ? {}\n : { decimals: tokenMetadata.decimals }),\n ...(tokenMetadata.assetId ? { assetId: tokenMetadata.assetId } : {}),\n };\n}\n"]}
|
package/package.json
CHANGED