@metamask/client-utils 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/LICENSE +6 -0
  3. package/LICENSE.APACHE2 +201 -0
  4. package/LICENSE.MIT +21 -0
  5. package/README.md +15 -0
  6. package/dist/index.cjs +10 -0
  7. package/dist/index.cjs.map +1 -0
  8. package/dist/index.d.cts +5 -0
  9. package/dist/index.d.cts.map +1 -0
  10. package/dist/index.d.mts +5 -0
  11. package/dist/index.d.mts.map +1 -0
  12. package/dist/index.mjs +4 -0
  13. package/dist/index.mjs.map +1 -0
  14. package/dist/mappers/api-transaction-mapper.cjs +300 -0
  15. package/dist/mappers/api-transaction-mapper.cjs.map +1 -0
  16. package/dist/mappers/api-transaction-mapper.d.cts +15 -0
  17. package/dist/mappers/api-transaction-mapper.d.cts.map +1 -0
  18. package/dist/mappers/api-transaction-mapper.d.mts +15 -0
  19. package/dist/mappers/api-transaction-mapper.d.mts.map +1 -0
  20. package/dist/mappers/api-transaction-mapper.mjs +296 -0
  21. package/dist/mappers/api-transaction-mapper.mjs.map +1 -0
  22. package/dist/mappers/constants.cjs +46 -0
  23. package/dist/mappers/constants.cjs.map +1 -0
  24. package/dist/mappers/constants.d.cts +25 -0
  25. package/dist/mappers/constants.d.cts.map +1 -0
  26. package/dist/mappers/constants.d.mts +25 -0
  27. package/dist/mappers/constants.d.mts.map +1 -0
  28. package/dist/mappers/constants.mjs +43 -0
  29. package/dist/mappers/constants.mjs.map +1 -0
  30. package/dist/mappers/helpers/caip.cjs +100 -0
  31. package/dist/mappers/helpers/caip.cjs.map +1 -0
  32. package/dist/mappers/helpers/caip.d.cts +32 -0
  33. package/dist/mappers/helpers/caip.d.cts.map +1 -0
  34. package/dist/mappers/helpers/caip.d.mts +32 -0
  35. package/dist/mappers/helpers/caip.d.mts.map +1 -0
  36. package/dist/mappers/helpers/caip.mjs +94 -0
  37. package/dist/mappers/helpers/caip.mjs.map +1 -0
  38. package/dist/mappers/helpers/token-metadata.cjs +31 -0
  39. package/dist/mappers/helpers/token-metadata.cjs.map +1 -0
  40. package/dist/mappers/helpers/token-metadata.d.cts +8 -0
  41. package/dist/mappers/helpers/token-metadata.d.cts.map +1 -0
  42. package/dist/mappers/helpers/token-metadata.d.mts +8 -0
  43. package/dist/mappers/helpers/token-metadata.d.mts.map +1 -0
  44. package/dist/mappers/helpers/token-metadata.mjs +31 -0
  45. package/dist/mappers/helpers/token-metadata.mjs.map +1 -0
  46. package/dist/mappers/helpers/transactions.cjs +240 -0
  47. package/dist/mappers/helpers/transactions.cjs.map +1 -0
  48. package/dist/mappers/helpers/transactions.d.cts +59 -0
  49. package/dist/mappers/helpers/transactions.d.cts.map +1 -0
  50. package/dist/mappers/helpers/transactions.d.mts +59 -0
  51. package/dist/mappers/helpers/transactions.d.mts.map +1 -0
  52. package/dist/mappers/helpers/transactions.mjs +228 -0
  53. package/dist/mappers/helpers/transactions.mjs.map +1 -0
  54. package/dist/mappers/keyring-transaction-mapper.cjs +143 -0
  55. package/dist/mappers/keyring-transaction-mapper.cjs.map +1 -0
  56. package/dist/mappers/keyring-transaction-mapper.d.cts +15 -0
  57. package/dist/mappers/keyring-transaction-mapper.d.cts.map +1 -0
  58. package/dist/mappers/keyring-transaction-mapper.d.mts +15 -0
  59. package/dist/mappers/keyring-transaction-mapper.d.mts.map +1 -0
  60. package/dist/mappers/keyring-transaction-mapper.mjs +139 -0
  61. package/dist/mappers/keyring-transaction-mapper.mjs.map +1 -0
  62. package/dist/mappers/local-transaction-mapper.cjs +420 -0
  63. package/dist/mappers/local-transaction-mapper.cjs.map +1 -0
  64. package/dist/mappers/local-transaction-mapper.d.cts +20 -0
  65. package/dist/mappers/local-transaction-mapper.d.cts.map +1 -0
  66. package/dist/mappers/local-transaction-mapper.d.mts +20 -0
  67. package/dist/mappers/local-transaction-mapper.d.mts.map +1 -0
  68. package/dist/mappers/local-transaction-mapper.mjs +416 -0
  69. package/dist/mappers/local-transaction-mapper.mjs.map +1 -0
  70. package/dist/types.cjs +3 -0
  71. package/dist/types.cjs.map +1 -0
  72. package/dist/types.d.cts +73 -0
  73. package/dist/types.d.cts.map +1 -0
  74. package/dist/types.d.mts +73 -0
  75. package/dist/types.d.mts.map +1 -0
  76. package/dist/types.mjs +2 -0
  77. package/dist/types.mjs.map +1 -0
  78. package/package.json +79 -0
@@ -0,0 +1,15 @@
1
+ import type { Transaction as KeyringTransaction } from "@metamask/keyring-api";
2
+ import type { ActivityItem } from "../types.mjs";
3
+ /**
4
+ * Maps a keyring transaction into the shared activity item shape.
5
+ *
6
+ * @param options - The mapping options.
7
+ * @param options.transaction - The keyring transaction to map.
8
+ * @param options.subjectAddress - Account address used for send/receive attribution.
9
+ * @returns The normalized activity item.
10
+ */
11
+ export declare function mapKeyringTransaction({ transaction, subjectAddress, }: {
12
+ transaction: KeyringTransaction;
13
+ subjectAddress?: string;
14
+ }): ActivityItem;
15
+ //# sourceMappingURL=keyring-transaction-mapper.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyring-transaction-mapper.d.mts","sourceRoot":"","sources":["../../src/mappers/keyring-transaction-mapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,IAAI,kBAAkB,EAAE,8BAA8B;AAM/E,OAAO,KAAK,EAAO,YAAY,EAAuB,qBAAiB;AA2EvE;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,WAAW,EACX,cAAc,GACf,EAAE;IACD,WAAW,EAAE,kBAAkB,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,YAAY,CA6Ff"}
@@ -0,0 +1,139 @@
1
+ import { TransactionStatus, TransactionType as KeyringTransactionType } from "@metamask/keyring-api";
2
+ function mapStatus(status) {
3
+ switch (status) {
4
+ case TransactionStatus.Confirmed:
5
+ return 'success';
6
+ case TransactionStatus.Failed:
7
+ return 'failed';
8
+ case TransactionStatus.Submitted:
9
+ case TransactionStatus.Unconfirmed:
10
+ default:
11
+ return 'pending';
12
+ }
13
+ }
14
+ function getAddress(movements) {
15
+ return movements[0]?.address ?? '';
16
+ }
17
+ function hasFungibleAsset(movement) {
18
+ return movement.asset?.fungible === true;
19
+ }
20
+ function getToken(movements, direction) {
21
+ const movement = movements.find(hasFungibleAsset);
22
+ if (!movement) {
23
+ return undefined;
24
+ }
25
+ return {
26
+ amount: movement.asset.amount,
27
+ symbol: movement.asset.unit,
28
+ assetId: movement.asset.type,
29
+ direction,
30
+ };
31
+ }
32
+ function getFee(fee) {
33
+ const { asset } = fee;
34
+ if (!asset.fungible) {
35
+ return undefined;
36
+ }
37
+ return {
38
+ type: fee.type,
39
+ amount: asset.amount,
40
+ symbol: asset.unit,
41
+ assetId: asset.type,
42
+ };
43
+ }
44
+ function getFees(transaction) {
45
+ return transaction.fees.flatMap((fee) => {
46
+ const mappedFee = getFee(fee);
47
+ return mappedFee ? [mappedFee] : [];
48
+ });
49
+ }
50
+ const approveAmountMaxIntegerDigits = 15;
51
+ /**
52
+ * Maps a keyring transaction into the shared activity item shape.
53
+ *
54
+ * @param options - The mapping options.
55
+ * @param options.transaction - The keyring transaction to map.
56
+ * @param options.subjectAddress - Account address used for send/receive attribution.
57
+ * @returns The normalized activity item.
58
+ */
59
+ export function mapKeyringTransaction({ transaction, subjectAddress, }) {
60
+ const { type, id } = transaction;
61
+ const status = mapStatus(transaction.status);
62
+ const timestamp = transaction.timestamp ? transaction.timestamp * 1000 : 0;
63
+ const chainId = transaction.chain;
64
+ const from = type === KeyringTransactionType.Send && subjectAddress
65
+ ? subjectAddress
66
+ : getAddress(transaction.from);
67
+ const to = type === KeyringTransactionType.Receive && subjectAddress
68
+ ? subjectAddress
69
+ : getAddress(transaction.to);
70
+ const fees = getFees(transaction);
71
+ const common = { chainId, status, timestamp, hash: id };
72
+ switch (type) {
73
+ case KeyringTransactionType.Send: {
74
+ const fromToken = getToken(transaction.from, 'out');
75
+ const token = !fromToken && chainId.startsWith('bip122:')
76
+ ? getToken(transaction.to, 'out')
77
+ : fromToken;
78
+ return {
79
+ type: 'send',
80
+ ...common,
81
+ data: {
82
+ from,
83
+ to,
84
+ token,
85
+ fees,
86
+ },
87
+ };
88
+ }
89
+ case KeyringTransactionType.Receive:
90
+ return {
91
+ type: 'receive',
92
+ ...common,
93
+ data: {
94
+ from,
95
+ to,
96
+ token: getToken(transaction.to, 'in'),
97
+ fees,
98
+ },
99
+ };
100
+ case KeyringTransactionType.Swap:
101
+ return {
102
+ type: 'swap',
103
+ ...common,
104
+ data: {
105
+ from,
106
+ destinationToken: getToken(transaction.to, 'in'),
107
+ sourceToken: getToken(transaction.from, 'out'),
108
+ fees,
109
+ },
110
+ };
111
+ case KeyringTransactionType.TokenApprove: {
112
+ const rawToken = getToken(transaction.from, 'out');
113
+ const isUnlimited = rawToken?.amount !== undefined &&
114
+ rawToken.amount.split('.')[0].length > approveAmountMaxIntegerDigits;
115
+ return {
116
+ type: 'approveSpendingCap',
117
+ ...common,
118
+ data: {
119
+ from,
120
+ token: rawToken
121
+ ? { ...rawToken, amount: isUnlimited ? undefined : rawToken.amount }
122
+ : rawToken,
123
+ fees,
124
+ },
125
+ };
126
+ }
127
+ default:
128
+ return {
129
+ type: 'contractInteraction',
130
+ ...common,
131
+ data: {
132
+ from,
133
+ to,
134
+ fees,
135
+ },
136
+ };
137
+ }
138
+ }
139
+ //# sourceMappingURL=keyring-transaction-mapper.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyring-transaction-mapper.mjs","sourceRoot":"","sources":["../../src/mappers/keyring-transaction-mapper.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Transaction as KeyringTransaction } from '@metamask/keyring-api';\nimport {\n TransactionStatus,\n TransactionType as KeyringTransactionType,\n} from '@metamask/keyring-api';\n\nimport type { Fee, ActivityItem, Status, TokenAmount } from '../types';\n\ntype Movement = KeyringTransaction['from'][number];\ntype KeyringFee = KeyringTransaction['fees'][number];\ntype FungibleAsset = Extract<\n NonNullable<Movement['asset']>,\n { fungible: true }\n>;\n\nfunction mapStatus(status: KeyringTransaction['status']): Status {\n switch (status) {\n case TransactionStatus.Confirmed:\n return 'success';\n case TransactionStatus.Failed:\n return 'failed';\n case TransactionStatus.Submitted:\n case TransactionStatus.Unconfirmed:\n default:\n return 'pending';\n }\n}\n\nfunction getAddress(movements: Movement[]): string {\n return movements[0]?.address ?? '';\n}\n\nfunction hasFungibleAsset(\n movement: Movement,\n): movement is Movement & { asset: FungibleAsset } {\n return movement.asset?.fungible === true;\n}\n\nfunction getToken(\n movements: Movement[],\n direction: TokenAmount['direction'],\n): TokenAmount | undefined {\n const movement = movements.find(hasFungibleAsset);\n\n if (!movement) {\n return undefined;\n }\n\n return {\n amount: movement.asset.amount,\n symbol: movement.asset.unit,\n assetId: movement.asset.type,\n direction,\n };\n}\n\nfunction getFee(fee: KeyringFee): Fee | undefined {\n const { asset } = fee;\n\n if (!asset.fungible) {\n return undefined;\n }\n\n return {\n type: fee.type,\n amount: asset.amount,\n symbol: asset.unit,\n assetId: asset.type,\n };\n}\n\nfunction getFees(transaction: KeyringTransaction): Fee[] {\n return transaction.fees.flatMap((fee) => {\n const mappedFee = getFee(fee);\n\n return mappedFee ? [mappedFee] : [];\n });\n}\n\nconst approveAmountMaxIntegerDigits = 15;\n\n/**\n * Maps a keyring transaction into the shared activity item shape.\n *\n * @param options - The mapping options.\n * @param options.transaction - The keyring transaction to map.\n * @param options.subjectAddress - Account address used for send/receive attribution.\n * @returns The normalized activity item.\n */\nexport function mapKeyringTransaction({\n transaction,\n subjectAddress,\n}: {\n transaction: KeyringTransaction;\n subjectAddress?: string;\n}): ActivityItem {\n const { type, id } = transaction;\n const status = mapStatus(transaction.status);\n const timestamp = transaction.timestamp ? transaction.timestamp * 1000 : 0;\n const chainId = transaction.chain;\n\n const from =\n type === KeyringTransactionType.Send && subjectAddress\n ? subjectAddress\n : getAddress(transaction.from);\n\n const to =\n type === KeyringTransactionType.Receive && subjectAddress\n ? subjectAddress\n : getAddress(transaction.to);\n\n const fees = getFees(transaction);\n const common = { chainId, status, timestamp, hash: id };\n\n switch (type) {\n case KeyringTransactionType.Send: {\n const fromToken = getToken(transaction.from, 'out');\n const token =\n !fromToken && chainId.startsWith('bip122:')\n ? getToken(transaction.to, 'out')\n : fromToken;\n\n return {\n type: 'send',\n ...common,\n data: {\n from,\n to,\n token,\n fees,\n },\n };\n }\n\n case KeyringTransactionType.Receive:\n return {\n type: 'receive',\n ...common,\n data: {\n from,\n to,\n token: getToken(transaction.to, 'in'),\n fees,\n },\n };\n\n case KeyringTransactionType.Swap:\n return {\n type: 'swap',\n ...common,\n data: {\n from,\n destinationToken: getToken(transaction.to, 'in'),\n sourceToken: getToken(transaction.from, 'out'),\n fees,\n },\n };\n\n case KeyringTransactionType.TokenApprove: {\n const rawToken = getToken(transaction.from, 'out');\n const isUnlimited =\n rawToken?.amount !== undefined &&\n rawToken.amount.split('.')[0].length > approveAmountMaxIntegerDigits;\n\n return {\n type: 'approveSpendingCap',\n ...common,\n data: {\n from,\n token: rawToken\n ? { ...rawToken, amount: isUnlimited ? undefined : rawToken.amount }\n : rawToken,\n fees,\n },\n };\n }\n\n default:\n return {\n type: 'contractInteraction',\n ...common,\n data: {\n from,\n to,\n fees,\n },\n };\n }\n}\n"]}
@@ -0,0 +1,420 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mapLocalTransaction = void 0;
4
+ const controller_utils_1 = require("@metamask/controller-utils");
5
+ const transaction_controller_1 = require("@metamask/transaction-controller");
6
+ const utils_1 = require("@metamask/utils");
7
+ const constants_1 = require("./constants.cjs");
8
+ const caip_1 = require("./helpers/caip.cjs");
9
+ const token_metadata_1 = require("./helpers/token-metadata.cjs");
10
+ const transactions_1 = require("./helpers/transactions.cjs");
11
+ const evmNativeDecimals = 18;
12
+ /**
13
+ * Maps a local TransactionController group into the shared activity item shape.
14
+ *
15
+ * @param transactionGroup - The transaction group to map, optionally enriched by the client.
16
+ * @returns The normalized activity item.
17
+ */
18
+ function mapLocalTransaction(transactionGroup) {
19
+ const fees = transactionGroup.fees ?? (0, transactions_1.getLocalTransactionFees)(transactionGroup);
20
+ const { initialTransaction, primaryTransaction } = transactionGroup;
21
+ const { transferInformation, type: transactionType, simulationData, txReceipt, metamaskPay, txParams: { from = '', to = '', data: txData, value: txValue } = {}, } = initialTransaction;
22
+ const { time: primaryTime, hash: primaryHash, id: primaryId, } = primaryTransaction;
23
+ const methodId = txData?.slice(0, 10);
24
+ // Permit2 approvals use the Permit2 contract as `to`, not the approved token.
25
+ // Keep this mapper thin: still classify the activity as an approve, but omit
26
+ // the token rather than surfacing the wrong one — the API mapper provides
27
+ // accurate token data.
28
+ const isPermit2Approve = methodId === constants_1.permit2ApproveMethodId;
29
+ const tokenContractAddress = isPermit2Approve
30
+ ? undefined
31
+ : (transferInformation?.contractAddress ?? (to || undefined));
32
+ const chainId = (0, utils_1.toCaipChainId)(utils_1.KnownCaipNamespace.Eip155, Number.parseInt(initialTransaction.chainId, 16).toString());
33
+ const nativeAsset = (0, caip_1.getNativeAsset)(initialTransaction.chainId);
34
+ const nativeSymbol = transactionGroup.nativeAssetSymbol ?? nativeAsset?.symbol;
35
+ const getNativeToken = (transaction, direction) => {
36
+ if (nativeSymbol === undefined) {
37
+ return undefined;
38
+ }
39
+ return {
40
+ direction,
41
+ symbol: nativeSymbol,
42
+ ...(transaction.txParams.value
43
+ ? { amount: transaction.txParams.value }
44
+ : {}),
45
+ ...(nativeAsset?.assetId ? { assetId: nativeAsset.assetId } : {}),
46
+ decimals: nativeAsset?.decimals ?? evmNativeDecimals,
47
+ };
48
+ };
49
+ const getContractTokenFromTransaction = ({ contractAddress, direction, transaction, }) => {
50
+ if (!contractAddress) {
51
+ return undefined;
52
+ }
53
+ const symbol = transaction.transferInformation?.symbol ??
54
+ transactionGroup.contractTokenMetadata?.symbol;
55
+ const decimals = transaction.transferInformation?.decimals ??
56
+ transactionGroup.contractTokenMetadata?.decimals;
57
+ const amount = transaction.transferInformation?.amount;
58
+ const assetId = (0, caip_1.formatAddressToAssetId)(contractAddress, chainId);
59
+ return {
60
+ direction,
61
+ ...(symbol ? { symbol } : {}),
62
+ ...(assetId ? { assetId } : {}),
63
+ ...(amount ? { amount } : {}),
64
+ ...(decimals === undefined ? {} : { decimals }),
65
+ };
66
+ };
67
+ const getContractTokenWithKnownMetadata = ({ amount, contractAddress, direction, transaction, }) => {
68
+ if (!contractAddress) {
69
+ return undefined;
70
+ }
71
+ const tokenMetadata = (0, token_metadata_1.getKnownTokenMetadata)(chainId, contractAddress);
72
+ const isWrappedNativeToken = (0, controller_utils_1.isEqualCaseInsensitive)(contractAddress, constants_1.swapsWrappedTokensAddresses[initialTransaction.chainId] || '');
73
+ const wrappedNativeTokenDecimals = isWrappedNativeToken
74
+ ? (nativeAsset?.decimals ?? evmNativeDecimals)
75
+ : undefined;
76
+ const decimals = transaction.transferInformation?.amount === undefined
77
+ ? (tokenMetadata?.decimals ??
78
+ transactionGroup.contractTokenMetadata?.decimals ??
79
+ wrappedNativeTokenDecimals)
80
+ : transaction.transferInformation.decimals;
81
+ const tokenAmount = transaction.transferInformation?.amount ?? amount;
82
+ const symbol = transaction.transferInformation?.symbol ??
83
+ tokenMetadata?.symbol ??
84
+ transactionGroup.contractTokenMetadata?.symbol;
85
+ const assetId = (0, caip_1.formatAddressToAssetId)(contractAddress, chainId);
86
+ return {
87
+ direction,
88
+ ...(symbol ? { symbol } : {}),
89
+ ...(assetId ? { assetId } : {}),
90
+ ...(tokenAmount ? { amount: tokenAmount } : {}),
91
+ ...(decimals === undefined ? {} : { decimals }),
92
+ };
93
+ };
94
+ const status = transactionGroup.activityStatus ??
95
+ (0, transactions_1.getLocalTransactionStatus)({
96
+ primaryTransaction,
97
+ initialTransaction,
98
+ });
99
+ const timestamp = primaryTime ?? initialTransaction.time;
100
+ const hash = primaryHash ?? initialTransaction.hash ?? primaryId;
101
+ const common = { chainId, status, timestamp, hash };
102
+ switch (transactionType) {
103
+ case transaction_controller_1.TransactionType.simpleSend: {
104
+ return {
105
+ type: 'send',
106
+ ...common,
107
+ data: {
108
+ from,
109
+ to,
110
+ token: getNativeToken(initialTransaction, 'out'),
111
+ },
112
+ };
113
+ }
114
+ case transaction_controller_1.TransactionType.swap:
115
+ case transaction_controller_1.TransactionType.swapAndSend:
116
+ case transaction_controller_1.TransactionType.bridge: {
117
+ const { sourceToken, destinationToken } = transactionGroup;
118
+ return {
119
+ type: transactionType === transaction_controller_1.TransactionType.bridge ? 'bridge' : 'swap',
120
+ ...common,
121
+ data: {
122
+ from,
123
+ sourceToken,
124
+ destinationToken,
125
+ fees,
126
+ },
127
+ };
128
+ }
129
+ case transaction_controller_1.TransactionType.tokenMethodSafeTransferFrom:
130
+ case transaction_controller_1.TransactionType.tokenMethodTransfer:
131
+ case transaction_controller_1.TransactionType.tokenMethodTransferFrom: {
132
+ return {
133
+ type: 'send',
134
+ ...common,
135
+ data: {
136
+ from,
137
+ to,
138
+ token: getContractTokenFromTransaction({
139
+ transaction: initialTransaction,
140
+ direction: 'out',
141
+ contractAddress: tokenContractAddress,
142
+ }),
143
+ },
144
+ };
145
+ }
146
+ case transaction_controller_1.TransactionType.lendingDeposit:
147
+ case transaction_controller_1.TransactionType.stakingDeposit:
148
+ return {
149
+ type: transactionType === transaction_controller_1.TransactionType.stakingDeposit
150
+ ? 'deposit'
151
+ : 'lendingDeposit',
152
+ ...common,
153
+ data: {
154
+ from,
155
+ },
156
+ };
157
+ case transaction_controller_1.TransactionType.incoming: {
158
+ return {
159
+ type: 'receive',
160
+ ...common,
161
+ data: {
162
+ from,
163
+ to,
164
+ token: transferInformation?.contractAddress
165
+ ? getContractTokenFromTransaction({
166
+ transaction: initialTransaction,
167
+ direction: 'in',
168
+ contractAddress: transferInformation.contractAddress,
169
+ })
170
+ : getNativeToken(initialTransaction, 'in'),
171
+ },
172
+ };
173
+ }
174
+ case transaction_controller_1.TransactionType.musdClaim:
175
+ return {
176
+ type: 'claimMusdBonus',
177
+ ...common,
178
+ data: {
179
+ from,
180
+ },
181
+ };
182
+ case transaction_controller_1.TransactionType.musdConversion: {
183
+ let conversionAmount;
184
+ if (txData && txData.length >= 138) {
185
+ try {
186
+ conversionAmount = BigInt(`0x${txData.slice(74, 138)}`).toString();
187
+ }
188
+ catch {
189
+ conversionAmount = undefined;
190
+ }
191
+ }
192
+ return {
193
+ type: 'convert',
194
+ ...common,
195
+ data: {
196
+ from,
197
+ sourceToken: transactionGroup.sourceToken,
198
+ destinationToken: getContractTokenWithKnownMetadata({
199
+ amount: conversionAmount,
200
+ transaction: initialTransaction,
201
+ direction: 'in',
202
+ contractAddress: to,
203
+ }),
204
+ },
205
+ };
206
+ }
207
+ case transaction_controller_1.TransactionType.bridgeApproval:
208
+ case transaction_controller_1.TransactionType.shieldSubscriptionApprove:
209
+ case transaction_controller_1.TransactionType.swapApproval:
210
+ case transaction_controller_1.TransactionType.tokenMethodSetApprovalForAll:
211
+ case transaction_controller_1.TransactionType.tokenMethodApprove:
212
+ case transaction_controller_1.TransactionType.tokenMethodIncreaseAllowance: {
213
+ const approvalToken = getContractTokenFromTransaction({
214
+ transaction: initialTransaction,
215
+ direction: 'out',
216
+ contractAddress: tokenContractAddress,
217
+ });
218
+ return {
219
+ type: transactionType === transaction_controller_1.TransactionType.tokenMethodIncreaseAllowance
220
+ ? 'increaseSpendingCap'
221
+ : 'approveSpendingCap',
222
+ ...common,
223
+ data: {
224
+ from,
225
+ token: approvalToken,
226
+ },
227
+ };
228
+ }
229
+ case transaction_controller_1.TransactionType.perpsDeposit:
230
+ case transaction_controller_1.TransactionType.perpsDepositAndOrder:
231
+ case transaction_controller_1.TransactionType.perpsWithdraw: {
232
+ const token = to
233
+ ? {
234
+ direction: 'out',
235
+ assetId: (0, caip_1.formatAddressToAssetId)(to, chainId),
236
+ }
237
+ : undefined;
238
+ const fiat = metamaskPay?.targetFiat
239
+ ? { amount: metamaskPay.targetFiat }
240
+ : undefined;
241
+ const networkFee = typeof metamaskPay?.networkFeeFiat === 'string'
242
+ ? { amount: metamaskPay.networkFeeFiat }
243
+ : undefined;
244
+ return {
245
+ type: transactionType === transaction_controller_1.TransactionType.perpsWithdraw
246
+ ? 'perpsWithdraw'
247
+ : 'perpsAddFunds',
248
+ ...common,
249
+ data: {
250
+ from,
251
+ token,
252
+ fiat,
253
+ networkFee,
254
+ },
255
+ };
256
+ }
257
+ default: {
258
+ const isSupplyContractInteraction = transactionType === transaction_controller_1.TransactionType.contractInteraction &&
259
+ methodId &&
260
+ constants_1.supplyMethodIds.has(methodId.toLowerCase());
261
+ const isWithdrawContractInteraction = transactionType === transaction_controller_1.TransactionType.contractInteraction &&
262
+ methodId &&
263
+ constants_1.withdrawMethodIds.has(methodId.toLowerCase());
264
+ let hasNativeValue = false;
265
+ try {
266
+ hasNativeValue = BigInt(txValue ?? '0') > 0n;
267
+ }
268
+ catch {
269
+ hasNativeValue = false;
270
+ }
271
+ // Confirm an outflow before labelling a supply, mirroring the API mapper's
272
+ // `sentTransfer` guard: native stakes (e.g. Lido) decrease the native
273
+ // balance, while ERC-20 supplies (e.g. Aave) show a token decrease.
274
+ const isSupply = isSupplyContractInteraction &&
275
+ (simulationData?.nativeBalanceChange?.isDecrease === true ||
276
+ simulationData?.tokenBalanceChanges?.some(({ isDecrease, standard }) => isDecrease && standard === 'erc20') === true);
277
+ const incomingNftBalanceChange = transactionType === transaction_controller_1.TransactionType.contractInteraction &&
278
+ simulationData?.tokenBalanceChanges?.find(({ isDecrease, standard }) => !isDecrease && (0, transactions_1.isNftStandard)(standard));
279
+ if (incomingNftBalanceChange && hasNativeValue) {
280
+ // Keep this mapper thin: classify the activity as an NFT buy and let the
281
+ // API mapper provide the token/payment details.
282
+ return {
283
+ type: 'nftBuy',
284
+ ...common,
285
+ data: {
286
+ from,
287
+ },
288
+ };
289
+ }
290
+ if (isSupply) {
291
+ return {
292
+ type: 'lendingDeposit',
293
+ ...common,
294
+ data: {
295
+ from,
296
+ },
297
+ };
298
+ }
299
+ // lending withdrawal - applies to Earn features only
300
+ if (isWithdrawContractInteraction) {
301
+ const fromAddress = from.toLowerCase();
302
+ const receivedTokenLog = (txReceipt?.logs ?? []).find(({ topics: [eventTopic, , logTo] = [] }) => {
303
+ const toAddress = logTo
304
+ ? `0x${logTo.slice(-40)}`.toLowerCase()
305
+ : undefined;
306
+ return (eventTopic?.toLowerCase() === constants_1.tokenTransferLogTopicHash &&
307
+ toAddress === fromAddress);
308
+ });
309
+ let receivedAmount;
310
+ if (receivedTokenLog) {
311
+ try {
312
+ receivedAmount = BigInt(String(receivedTokenLog.data)).toString();
313
+ }
314
+ catch {
315
+ receivedAmount = undefined;
316
+ }
317
+ }
318
+ const destinationToken = receivedTokenLog
319
+ ? getContractTokenWithKnownMetadata({
320
+ amount: receivedAmount,
321
+ transaction: initialTransaction,
322
+ direction: 'in',
323
+ contractAddress: receivedTokenLog.address,
324
+ })
325
+ : undefined;
326
+ return {
327
+ type: 'lendingWithdrawal',
328
+ ...common,
329
+ data: {
330
+ from,
331
+ destinationToken,
332
+ },
333
+ };
334
+ }
335
+ // wrap and unwrap
336
+ if (transactionType === transaction_controller_1.TransactionType.contractInteraction && methodId) {
337
+ const wrappedTokenAddress = constants_1.swapsWrappedTokensAddresses[initialTransaction.chainId];
338
+ if (wrappedTokenAddress && (0, controller_utils_1.isEqualCaseInsensitive)(to, wrappedTokenAddress)) {
339
+ const normalizedMethodId = methodId.toLowerCase();
340
+ if (constants_1.wrapMethodIds.has(normalizedMethodId)) {
341
+ try {
342
+ if (txValue && BigInt(txValue) > 0n) {
343
+ return {
344
+ type: 'wrap',
345
+ ...common,
346
+ data: {
347
+ from,
348
+ sourceToken: getNativeToken(initialTransaction, 'out'),
349
+ destinationToken: getContractTokenWithKnownMetadata({
350
+ amount: txValue,
351
+ transaction: initialTransaction,
352
+ direction: 'in',
353
+ contractAddress: wrappedTokenAddress,
354
+ }),
355
+ },
356
+ };
357
+ }
358
+ }
359
+ catch {
360
+ // Invalid native value — fall through.
361
+ }
362
+ }
363
+ if (constants_1.unwrapMethodIds.has(normalizedMethodId)) {
364
+ let unwrapAmount;
365
+ if (txData && txData.length >= 74) {
366
+ try {
367
+ unwrapAmount = BigInt(`0x${txData.slice(10, 74)}`).toString();
368
+ }
369
+ catch {
370
+ unwrapAmount = undefined;
371
+ }
372
+ }
373
+ const nativeToken = getNativeToken(initialTransaction, 'in');
374
+ return {
375
+ type: 'unwrap',
376
+ ...common,
377
+ data: {
378
+ from,
379
+ sourceToken: getContractTokenWithKnownMetadata({
380
+ amount: unwrapAmount,
381
+ transaction: initialTransaction,
382
+ direction: 'out',
383
+ contractAddress: wrappedTokenAddress,
384
+ }),
385
+ destinationToken: nativeToken && unwrapAmount
386
+ ? { ...nativeToken, amount: unwrapAmount }
387
+ : nativeToken,
388
+ },
389
+ };
390
+ }
391
+ }
392
+ }
393
+ const token = (() => {
394
+ if (txValue === undefined || txValue === '') {
395
+ return undefined;
396
+ }
397
+ try {
398
+ return BigInt(txValue) > 0n
399
+ ? getNativeToken(initialTransaction, 'out')
400
+ : undefined;
401
+ }
402
+ catch {
403
+ return undefined;
404
+ }
405
+ })();
406
+ return {
407
+ type: 'contractInteraction',
408
+ ...common,
409
+ data: {
410
+ from,
411
+ to,
412
+ ...(token ? { token } : {}),
413
+ methodId,
414
+ },
415
+ };
416
+ }
417
+ }
418
+ }
419
+ exports.mapLocalTransaction = mapLocalTransaction;
420
+ //# sourceMappingURL=local-transaction-mapper.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-transaction-mapper.cjs","sourceRoot":"","sources":["../../src/mappers/local-transaction-mapper.ts"],"names":[],"mappings":"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","sourcesContent":["import { isEqualCaseInsensitive as equalsIgnoreCase } from '@metamask/controller-utils';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport { KnownCaipNamespace, toCaipChainId } from '@metamask/utils';\n\nimport type { Fee, ActivityItem, TokenAmount } from '../types';\nimport {\n permit2ApproveMethodId,\n swapsWrappedTokensAddresses,\n supplyMethodIds,\n tokenTransferLogTopicHash,\n unwrapMethodIds,\n withdrawMethodIds,\n wrapMethodIds,\n} from './constants';\nimport { formatAddressToAssetId, getNativeAsset } from './helpers/caip';\nimport { getKnownTokenMetadata } from './helpers/token-metadata';\nimport {\n getLocalTransactionFees,\n getLocalTransactionStatus,\n isNftStandard,\n} from './helpers/transactions';\nimport type { TransactionGroup } from './helpers/transactions';\n\nconst evmNativeDecimals = 18;\n\n/**\n * Maps a local TransactionController group into the shared activity item shape.\n *\n * @param transactionGroup - The transaction group to map, optionally enriched by the client.\n * @returns The normalized activity item.\n */\nexport function mapLocalTransaction(\n transactionGroup: TransactionGroup & {\n sourceToken?: TokenAmount;\n destinationToken?: TokenAmount;\n nativeAssetSymbol?: string;\n contractTokenMetadata?: { symbol?: string; decimals?: number };\n activityStatus?: ActivityItem['status'];\n fees?: Fee[];\n },\n): ActivityItem {\n const fees =\n transactionGroup.fees ?? getLocalTransactionFees(transactionGroup);\n const { initialTransaction, primaryTransaction } = transactionGroup;\n const {\n transferInformation,\n type: transactionType,\n simulationData,\n txReceipt,\n metamaskPay,\n txParams: { from = '', to = '', data: txData, value: txValue } = {},\n } = initialTransaction;\n const {\n time: primaryTime,\n hash: primaryHash,\n id: primaryId,\n } = primaryTransaction;\n const methodId = txData?.slice(0, 10);\n // Permit2 approvals use the Permit2 contract as `to`, not the approved token.\n // Keep this mapper thin: still classify the activity as an approve, but omit\n // the token rather than surfacing the wrong one — the API mapper provides\n // accurate token data.\n const isPermit2Approve = methodId === permit2ApproveMethodId;\n const tokenContractAddress = isPermit2Approve\n ? undefined\n : (transferInformation?.contractAddress ?? (to || undefined));\n const chainId = toCaipChainId(\n KnownCaipNamespace.Eip155,\n Number.parseInt(initialTransaction.chainId, 16).toString(),\n );\n const nativeAsset = getNativeAsset(initialTransaction.chainId);\n const nativeSymbol =\n transactionGroup.nativeAssetSymbol ?? nativeAsset?.symbol;\n\n const getNativeToken = (\n transaction: TransactionGroup['initialTransaction'],\n direction: TokenAmount['direction'],\n ): TokenAmount | undefined => {\n if (nativeSymbol === undefined) {\n return undefined;\n }\n\n return {\n direction,\n symbol: nativeSymbol,\n ...(transaction.txParams.value\n ? { amount: transaction.txParams.value }\n : {}),\n ...(nativeAsset?.assetId ? { assetId: nativeAsset.assetId } : {}),\n decimals: nativeAsset?.decimals ?? evmNativeDecimals,\n };\n };\n\n const getContractTokenFromTransaction = ({\n contractAddress,\n direction,\n transaction,\n }: {\n contractAddress?: string;\n direction: TokenAmount['direction'];\n transaction: TransactionGroup['initialTransaction'];\n }): TokenAmount | undefined => {\n if (!contractAddress) {\n return undefined;\n }\n\n const symbol =\n transaction.transferInformation?.symbol ??\n transactionGroup.contractTokenMetadata?.symbol;\n const decimals =\n transaction.transferInformation?.decimals ??\n transactionGroup.contractTokenMetadata?.decimals;\n const amount = transaction.transferInformation?.amount;\n const assetId = formatAddressToAssetId(contractAddress, chainId);\n\n return {\n direction,\n ...(symbol ? { symbol } : {}),\n ...(assetId ? { assetId } : {}),\n ...(amount ? { amount } : {}),\n ...(decimals === undefined ? {} : { decimals }),\n };\n };\n\n const getContractTokenWithKnownMetadata = ({\n amount,\n contractAddress,\n direction,\n transaction,\n }: {\n amount?: string;\n contractAddress?: string;\n direction: TokenAmount['direction'];\n transaction: TransactionGroup['initialTransaction'];\n }): TokenAmount | undefined => {\n if (!contractAddress) {\n return undefined;\n }\n\n const tokenMetadata = getKnownTokenMetadata(chainId, contractAddress);\n\n const isWrappedNativeToken = equalsIgnoreCase(\n contractAddress,\n swapsWrappedTokensAddresses[\n initialTransaction.chainId as keyof typeof swapsWrappedTokensAddresses\n ] || '',\n );\n const wrappedNativeTokenDecimals = isWrappedNativeToken\n ? (nativeAsset?.decimals ?? evmNativeDecimals)\n : undefined;\n\n const decimals =\n transaction.transferInformation?.amount === undefined\n ? (tokenMetadata?.decimals ??\n transactionGroup.contractTokenMetadata?.decimals ??\n wrappedNativeTokenDecimals)\n : transaction.transferInformation.decimals;\n const tokenAmount = transaction.transferInformation?.amount ?? amount;\n const symbol =\n transaction.transferInformation?.symbol ??\n tokenMetadata?.symbol ??\n transactionGroup.contractTokenMetadata?.symbol;\n const assetId = formatAddressToAssetId(contractAddress, chainId);\n\n return {\n direction,\n ...(symbol ? { symbol } : {}),\n ...(assetId ? { assetId } : {}),\n ...(tokenAmount ? { amount: tokenAmount } : {}),\n ...(decimals === undefined ? {} : { decimals }),\n };\n };\n\n const status =\n transactionGroup.activityStatus ??\n getLocalTransactionStatus({\n primaryTransaction,\n initialTransaction,\n });\n const timestamp = primaryTime ?? initialTransaction.time;\n const hash = primaryHash ?? initialTransaction.hash ?? primaryId;\n const common = { chainId, status, timestamp, hash };\n\n switch (transactionType) {\n case TransactionType.simpleSend: {\n return {\n type: 'send',\n ...common,\n data: {\n from,\n to,\n token: getNativeToken(initialTransaction, 'out'),\n },\n };\n }\n\n case TransactionType.swap:\n case TransactionType.swapAndSend:\n case TransactionType.bridge: {\n const { sourceToken, destinationToken } = transactionGroup;\n\n return {\n type: transactionType === TransactionType.bridge ? 'bridge' : 'swap',\n ...common,\n data: {\n from,\n sourceToken,\n destinationToken,\n fees,\n },\n };\n }\n\n case TransactionType.tokenMethodSafeTransferFrom:\n case TransactionType.tokenMethodTransfer:\n case TransactionType.tokenMethodTransferFrom: {\n return {\n type: 'send',\n ...common,\n data: {\n from,\n to,\n token: getContractTokenFromTransaction({\n transaction: initialTransaction,\n direction: 'out',\n contractAddress: tokenContractAddress,\n }),\n },\n };\n }\n\n case TransactionType.lendingDeposit:\n case TransactionType.stakingDeposit:\n return {\n type:\n transactionType === TransactionType.stakingDeposit\n ? 'deposit'\n : 'lendingDeposit',\n ...common,\n data: {\n from,\n },\n };\n\n case TransactionType.incoming: {\n return {\n type: 'receive',\n ...common,\n data: {\n from,\n to,\n token: transferInformation?.contractAddress\n ? getContractTokenFromTransaction({\n transaction: initialTransaction,\n direction: 'in',\n contractAddress: transferInformation.contractAddress,\n })\n : getNativeToken(initialTransaction, 'in'),\n },\n };\n }\n case TransactionType.musdClaim:\n return {\n type: 'claimMusdBonus',\n ...common,\n data: {\n from,\n },\n };\n\n case TransactionType.musdConversion: {\n let conversionAmount: string | undefined;\n\n if (txData && txData.length >= 138) {\n try {\n conversionAmount = BigInt(`0x${txData.slice(74, 138)}`).toString();\n } catch {\n conversionAmount = undefined;\n }\n }\n\n return {\n type: 'convert',\n ...common,\n data: {\n from,\n sourceToken: transactionGroup.sourceToken,\n destinationToken: getContractTokenWithKnownMetadata({\n amount: conversionAmount,\n transaction: initialTransaction,\n direction: 'in',\n contractAddress: to,\n }),\n },\n };\n }\n\n case TransactionType.bridgeApproval:\n case TransactionType.shieldSubscriptionApprove:\n case TransactionType.swapApproval:\n case TransactionType.tokenMethodSetApprovalForAll:\n case TransactionType.tokenMethodApprove:\n case TransactionType.tokenMethodIncreaseAllowance: {\n const approvalToken = getContractTokenFromTransaction({\n transaction: initialTransaction,\n direction: 'out',\n contractAddress: tokenContractAddress,\n });\n\n return {\n type:\n transactionType === TransactionType.tokenMethodIncreaseAllowance\n ? 'increaseSpendingCap'\n : 'approveSpendingCap',\n ...common,\n data: {\n from,\n token: approvalToken,\n },\n };\n }\n\n case TransactionType.perpsDeposit:\n case TransactionType.perpsDepositAndOrder:\n case TransactionType.perpsWithdraw: {\n const token = to\n ? {\n direction: 'out' as const,\n assetId: formatAddressToAssetId(to, chainId),\n }\n : undefined;\n\n const fiat = metamaskPay?.targetFiat\n ? { amount: metamaskPay.targetFiat }\n : undefined;\n const networkFee =\n typeof metamaskPay?.networkFeeFiat === 'string'\n ? { amount: metamaskPay.networkFeeFiat }\n : undefined;\n\n return {\n type:\n transactionType === TransactionType.perpsWithdraw\n ? 'perpsWithdraw'\n : 'perpsAddFunds',\n ...common,\n data: {\n from,\n token,\n fiat,\n networkFee,\n },\n };\n }\n\n default: {\n const isSupplyContractInteraction =\n transactionType === TransactionType.contractInteraction &&\n methodId &&\n supplyMethodIds.has(methodId.toLowerCase());\n const isWithdrawContractInteraction =\n transactionType === TransactionType.contractInteraction &&\n methodId &&\n withdrawMethodIds.has(methodId.toLowerCase());\n\n let hasNativeValue = false;\n\n try {\n hasNativeValue = BigInt(txValue ?? '0') > 0n;\n } catch {\n hasNativeValue = false;\n }\n\n // Confirm an outflow before labelling a supply, mirroring the API mapper's\n // `sentTransfer` guard: native stakes (e.g. Lido) decrease the native\n // balance, while ERC-20 supplies (e.g. Aave) show a token decrease.\n const isSupply =\n isSupplyContractInteraction &&\n (simulationData?.nativeBalanceChange?.isDecrease === true ||\n simulationData?.tokenBalanceChanges?.some(\n ({ isDecrease, standard }) => isDecrease && standard === 'erc20',\n ) === true);\n const incomingNftBalanceChange =\n transactionType === TransactionType.contractInteraction &&\n simulationData?.tokenBalanceChanges?.find(\n ({ isDecrease, standard }) => !isDecrease && isNftStandard(standard),\n );\n\n if (incomingNftBalanceChange && hasNativeValue) {\n // Keep this mapper thin: classify the activity as an NFT buy and let the\n // API mapper provide the token/payment details.\n return {\n type: 'nftBuy',\n ...common,\n data: {\n from,\n },\n };\n }\n\n if (isSupply) {\n return {\n type: 'lendingDeposit',\n ...common,\n data: {\n from,\n },\n };\n }\n\n // lending withdrawal - applies to Earn features only\n if (isWithdrawContractInteraction) {\n const fromAddress = from.toLowerCase();\n const receivedTokenLog = (txReceipt?.logs ?? []).find(\n ({ topics: [eventTopic, , logTo] = [] }) => {\n const toAddress = logTo\n ? `0x${logTo.slice(-40)}`.toLowerCase()\n : undefined;\n\n return (\n eventTopic?.toLowerCase() === tokenTransferLogTopicHash &&\n toAddress === fromAddress\n );\n },\n );\n let receivedAmount: string | undefined;\n\n if (receivedTokenLog) {\n try {\n receivedAmount = BigInt(String(receivedTokenLog.data)).toString();\n } catch {\n receivedAmount = undefined;\n }\n }\n\n const destinationToken = receivedTokenLog\n ? getContractTokenWithKnownMetadata({\n amount: receivedAmount,\n transaction: initialTransaction,\n direction: 'in',\n contractAddress: receivedTokenLog.address,\n })\n : undefined;\n\n return {\n type: 'lendingWithdrawal',\n ...common,\n data: {\n from,\n destinationToken,\n },\n };\n }\n\n // wrap and unwrap\n if (transactionType === TransactionType.contractInteraction && methodId) {\n const wrappedTokenAddress =\n swapsWrappedTokensAddresses[\n initialTransaction.chainId as keyof typeof swapsWrappedTokensAddresses\n ];\n\n if (wrappedTokenAddress && equalsIgnoreCase(to, wrappedTokenAddress)) {\n const normalizedMethodId = methodId.toLowerCase();\n\n if (wrapMethodIds.has(normalizedMethodId)) {\n try {\n if (txValue && BigInt(txValue) > 0n) {\n return {\n type: 'wrap',\n ...common,\n data: {\n from,\n sourceToken: getNativeToken(initialTransaction, 'out'),\n destinationToken: getContractTokenWithKnownMetadata({\n amount: txValue,\n transaction: initialTransaction,\n direction: 'in',\n contractAddress: wrappedTokenAddress,\n }),\n },\n };\n }\n } catch {\n // Invalid native value — fall through.\n }\n }\n\n if (unwrapMethodIds.has(normalizedMethodId)) {\n let unwrapAmount: string | undefined;\n\n if (txData && txData.length >= 74) {\n try {\n unwrapAmount = BigInt(`0x${txData.slice(10, 74)}`).toString();\n } catch {\n unwrapAmount = undefined;\n }\n }\n\n const nativeToken = getNativeToken(initialTransaction, 'in');\n\n return {\n type: 'unwrap',\n ...common,\n data: {\n from,\n sourceToken: getContractTokenWithKnownMetadata({\n amount: unwrapAmount,\n transaction: initialTransaction,\n direction: 'out',\n contractAddress: wrappedTokenAddress,\n }),\n destinationToken:\n nativeToken && unwrapAmount\n ? { ...nativeToken, amount: unwrapAmount }\n : nativeToken,\n },\n };\n }\n }\n }\n\n const token = ((): TokenAmount | undefined => {\n if (txValue === undefined || txValue === '') {\n return undefined;\n }\n\n try {\n return BigInt(txValue) > 0n\n ? getNativeToken(initialTransaction, 'out')\n : undefined;\n } catch {\n return undefined;\n }\n })();\n\n return {\n type: 'contractInteraction',\n ...common,\n data: {\n from,\n to,\n ...(token ? { token } : {}),\n methodId,\n },\n };\n }\n }\n}\n"]}