@metamask-previews/client-utils 3.0.4-preview-c9f31ce → 3.0.4-preview-5e24e4d22
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
CHANGED
|
@@ -15,6 +15,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
15
15
|
- Bump `@metamask/slip44` from `^4.3.0` to `^4.5.0` ([#10736](https://github.com/MetaMask/core/pull/10736))
|
|
16
16
|
- Bump `@metamask/keyring-api` from `^24.0.0` to `^24.3.0` ([#10717](https://github.com/MetaMask/core/pull/10717), [#10792](https://github.com/MetaMask/core/pull/10792), [#10844](https://github.com/MetaMask/core/pull/10844))
|
|
17
17
|
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- Add the L1 fee and operator fee from the transaction receipt to the base network fee returned by `getLocalTransactionFees`, so Mantle and other OP Stack activity shows the fee paid onchain ([#9630](https://github.com/MetaMask/core/pull/9630))
|
|
21
|
+
- The operator fee uses the Jovian formula when the receipt has `daFootprintGasScalar`, and the Isthmus formula otherwise
|
|
22
|
+
|
|
18
23
|
## [3.0.4]
|
|
19
24
|
|
|
20
25
|
### Changed
|
|
@@ -13,6 +13,15 @@ export type TransactionGroup = {
|
|
|
13
13
|
transactions: TransactionMeta[];
|
|
14
14
|
};
|
|
15
15
|
export declare function getFees(transaction: V1TransactionByHashResponse): Fee[] | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Builds the base network fee (in the chain's native token) for a local
|
|
18
|
+
* transaction from its receipt (`gasUsed × effectiveGasPrice`), plus the
|
|
19
|
+
* L1 and operator fees from the receipt. Falls back to `txParams.gasPrice`
|
|
20
|
+
* while pending.
|
|
21
|
+
*
|
|
22
|
+
* @param transactionGroup - Transaction group with the primary transaction.
|
|
23
|
+
* @returns Activity fee list with a single base network fee, or undefined.
|
|
24
|
+
*/
|
|
16
25
|
export declare function getLocalTransactionFees(transactionGroup: Pick<TransactionGroup, 'primaryTransaction'> & {
|
|
17
26
|
nativeAssetSymbol?: string;
|
|
18
27
|
}): Fee[] | undefined;
|
|
@@ -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,
|
|
1
|
+
{"version":3,"file":"transactions.d.ts","sourceRoot":"","sources":["../../../src/mappers/helpers/transactions.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,42 @@ function calculateNetworkFee(gasUsed, gasPrice) {
|
|
|
14
14
|
return undefined;
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Calculates the OP Stack / Mantle operator fee from the receipt.
|
|
19
|
+
*
|
|
20
|
+
* Jovian receipts (with `daFootprintGasScalar`):
|
|
21
|
+
* `gasUsed * operatorFeeScalar * 100 + operatorFeeConstant`.
|
|
22
|
+
* Isthmus receipts: `gasUsed * operatorFeeScalar / 1e6 + operatorFeeConstant`.
|
|
23
|
+
*
|
|
24
|
+
* @param txReceipt - Transaction receipt.
|
|
25
|
+
* @returns Operator fee in wei, or 0 when the receipt has no operator fee fields.
|
|
26
|
+
*/
|
|
27
|
+
function calculateOperatorFee(txReceipt) {
|
|
28
|
+
const { daFootprintGasScalar, gasUsed, operatorFeeConstant, operatorFeeScalar, } = txReceipt ?? {};
|
|
29
|
+
if (!gasUsed || !operatorFeeScalar || !operatorFeeConstant) {
|
|
30
|
+
return 0n;
|
|
31
|
+
}
|
|
32
|
+
const fee = BigInt(gasUsed) * BigInt(operatorFeeScalar);
|
|
33
|
+
const scaledFee = daFootprintGasScalar === undefined ? fee / 1000000n : fee * 100n;
|
|
34
|
+
return scaledFee + BigInt(operatorFeeConstant);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Sums the L2, L1, and operator fees from the receipt.
|
|
38
|
+
*
|
|
39
|
+
* @param l2Fee - L2 network fee in decimal wei.
|
|
40
|
+
* @param txReceipt - Transaction receipt.
|
|
41
|
+
* @returns Total fee in decimal wei, or the L2 fee if a receipt value is invalid.
|
|
42
|
+
*/
|
|
43
|
+
function calculateTotalFee(l2Fee, txReceipt) {
|
|
44
|
+
try {
|
|
45
|
+
const l1Fee = BigInt(txReceipt?.l1Fee ?? 0);
|
|
46
|
+
const operatorFee = calculateOperatorFee(txReceipt);
|
|
47
|
+
return String(BigInt(l2Fee) + l1Fee + operatorFee);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return l2Fee;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
17
53
|
function toNetworkFee(amount, chainId, symbol) {
|
|
18
54
|
const nativeAsset = getNativeAsset(chainId);
|
|
19
55
|
if (nativeAsset) {
|
|
@@ -66,17 +102,27 @@ export function getFees(transaction) {
|
|
|
66
102
|
const networkFee = getNetworkFee(transaction);
|
|
67
103
|
return networkFee ? [networkFee] : undefined;
|
|
68
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Builds the base network fee (in the chain's native token) for a local
|
|
107
|
+
* transaction from its receipt (`gasUsed × effectiveGasPrice`), plus the
|
|
108
|
+
* L1 and operator fees from the receipt. Falls back to `txParams.gasPrice`
|
|
109
|
+
* while pending.
|
|
110
|
+
*
|
|
111
|
+
* @param transactionGroup - Transaction group with the primary transaction.
|
|
112
|
+
* @returns Activity fee list with a single base network fee, or undefined.
|
|
113
|
+
*/
|
|
69
114
|
export function getLocalTransactionFees(transactionGroup) {
|
|
70
115
|
const { primaryTransaction, nativeAssetSymbol } = transactionGroup;
|
|
71
116
|
const chainId = formatChainIdToCaip(primaryTransaction.chainId);
|
|
72
117
|
if (!chainId) {
|
|
73
118
|
return undefined;
|
|
74
119
|
}
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
if (!
|
|
120
|
+
const { txReceipt } = primaryTransaction;
|
|
121
|
+
const l2Fee = calculateNetworkFee(txReceipt?.gasUsed, txReceipt?.effectiveGasPrice ?? primaryTransaction.txParams?.gasPrice);
|
|
122
|
+
if (!l2Fee) {
|
|
78
123
|
return undefined;
|
|
79
124
|
}
|
|
125
|
+
const amount = calculateTotalFee(l2Fee, txReceipt);
|
|
80
126
|
return [toNetworkFee(amount, chainId, nativeAssetSymbol)];
|
|
81
127
|
}
|
|
82
128
|
const inProgressTransactionStatuses = [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transactions.js","sourceRoot":"","sources":["../../../src/mappers/helpers/transactions.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,OAAO,EACP,sBAAsB,IAAI,gBAAgB,GAC3C,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EACL,iBAAiB,EACjB,eAAe,GAChB,MAAM,kCAAkC,CAAC;AAU1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,oBAAoB,GACrB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAY5D,SAAS,mBAAmB,CAC1B,OAAoC,EACpC,QAAqC;IAErC,IAAI,OAAO,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QACpD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CACnB,MAAc,EACd,OAAoB,EACpB,MAAe;IAEf,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAE5C,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,MAAM;YACN,QAAQ,EAAE,mBAAmB;YAC7B,SAAS,EAAE,QAAQ;YACnB,MAAM,EAAE,MAAM,IAAI,WAAW,CAAC,MAAM;YACpC,OAAO,EAAE,WAAW,CAAC,OAAO;SAC7B,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAE3E,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,MAAM;QACN,QAAQ,EAAE,mBAAmB;QAC7B,SAAS,EAAE,QAAQ;QACnB,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7B,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChC,CAAC;AACJ,CAAC;AAED,SAAS,4BAA4B,CACnC,YAAgC;IAEhC,IAAI,YAAY,KAAK,QAAQ,IAAI,YAAY,KAAK,UAAU,EAAE,CAAC;QAC7D,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,IAAI,YAAY,KAAK,OAAO,EAAE,CAAC;QAC7B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,YAAY,KAAK,MAAM,CAAC,WAAW,EAAE,IAAI,YAAY,KAAK,QAAQ,EAAE,CAAC;QACvE,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,IAAI,YAAY,KAAK,OAAO,CAAC,WAAW,EAAE,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QACzE,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,aAAa,CACpB,WAAwC;IAExC,MAAM,OAAO,GAAG,mBAAmB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAEzD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,MAAM,GAAG,mBAAmB,CAChC,WAAW,CAAC,OAAO,EACnB,WAAW,CAAC,iBAAiB,CAC9B,CAAC;IAEF,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,OAAO,CACrB,WAAwC;IAExC,MAAM,UAAU,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAE9C,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,gBAEC;IAED,MAAM,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,GAAG,gBAAgB,CAAC;IACnE,MAAM,OAAO,GAAG,mBAAmB,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAEhE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,MAAM,GAAG,mBAAmB,CAChC,kBAAkB,CAAC,SAAS,EAAE,OAAO,EACrC,kBAAkB,CAAC,SAAS,EAAE,iBAAiB;QAC7C,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,CACxC,CAAC;IAEF,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,6BAA6B,GAAG;IACpC,iBAAiB,CAAC,UAAU;IAC5B,iBAAiB,CAAC,QAAQ;IAC1B,iBAAiB,CAAC,MAAM;IACxB,iBAAiB,CAAC,SAAS;CAC5B,CAAC;AAEF,MAAM,+BAA+B,GAAG,WAAW,CAAC;AAEpD,MAAM,sBAAsB,GAAG;IAC7B,SAAS,EAAE,WAAW;IACtB,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;CACV,CAAC;AAEX,SAAS,uBAAuB,CAC9B,WAAmD;IAEnD,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC;IACrC,MAAM,aAAa,GAAG,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC;IAEpD,IAAI,aAAa,KAAK,KAAK,EAAE,CAAC;QAC5B,OAAO,iBAAiB,CAAC,MAAM,CAAC;IAClC,CAAC;IAED,IACE,MAAM,KAAK,iBAAiB,CAAC,SAAS;QACtC,IAAI,KAAK,eAAe,CAAC,MAAM,EAC/B,CAAC;QACD,OAAO,+BAA+B,CAAC;IACzC,CAAC;IAED,OAAO,WAAW,CAAC,MAAM,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,EACxC,kBAAkB,EAClB,kBAAkB,GAInB;IACC,IAAI,kBAAkB,CAAC,kBAAkB,EAAE,CAAC;QAC1C,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAA4B,CAAC;QAEpE,IAAI,WAAW,KAAK,sBAAsB,CAAC,OAAO,EAAE,CAAC;YACnD,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,IAAI,WAAW,KAAK,sBAAsB,CAAC,OAAO,EAAE,CAAC;YACnD,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,IAAI,WAAW,KAAK,sBAAsB,CAAC,SAAS,EAAE,CAAC;YACrD,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,SAAS,GAAG,uBAAuB,CAAC,kBAAkB,CAAC,CAAC;IAE9D,IAAI,SAAS,KAAK,iBAAiB,CAAC,SAAS,EAAE,CAAC;QAC9C,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IACE,SAAS,KAAK,iBAAiB,CAAC,SAAS;QACzC,SAAS,KAAK,+BAA+B;QAC7C,SAAS,KAAK,iBAAiB,CAAC,OAAO;QACvC,SAAS,KAAK,iBAAiB,CAAC,MAAM;QACtC,SAAS,KAAK,iBAAiB,CAAC,QAAQ,EACxC,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,IACE,6BAA6B,CAAC,QAAQ,CACpC,SAA2D,CAC5D,EACD,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,KAAK,KAAK,MAAM,CAAC,WAAW,EAAE,IAAI,KAAK,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,EACpC,IAAI,EACJ,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,aAAa,EACb,cAAc,GAUf;IACC,MAAM,UAAU,GAAG,CAAC,QAAwB,EAAW,EAAE,CACvD,OAAO,CAAC,QAAQ,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;IAE7D,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QACnB,KAAK,MAAM,QAAQ,IAAI,CAAC,kBAAkB,EAAE,YAAY,CAAC,EAAE,CAAC;YAC1D,IAAI,CAAC,QAAQ,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACvC,SAAS;YACX,CAAC;YAED,0EAA0E;YAC1E,0EAA0E;YAC1E,uEAAuE;YACvE,IACE,gBAAgB,CAAC,QAAQ,CAAC,EAAE,EAAE,eAAe,CAAC;gBAC9C,gBAAgB,CAAC,QAAQ,CAAC,EAAE,EAAE,aAAuB,CAAC,EACtD,CAAC;gBACD,OAAO,QAAQ,CAAC;YAClB,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,CAAC,gBAAgB,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACvD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IACE,gBAAgB,CAAC,gBAAgB,CAAC,IAAI,EAAE,eAAe,CAAC;QACxD,CAAC,eAAe;YACd,CAAC,gBAAgB,CAAC,eAAe,EAAE,cAAc,CAAC;YAClD,gBAAgB,CAAC,gBAAgB,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,EAC3D,CAAC;QACD,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,cAAc,GAAG,CACrB,OAAoB,EACpB,eAAmC,EACf,EAAE;IACtB,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,sBAAsB,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;AAC1D,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CACjC,cAA2C,EAC3C,cAAsB;IAQtB,MAAM,IAAI,GAAG,cAAc,EAAE,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAC/C,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,CACvC,CAAC;IACF,MAAM,QAAQ,GAAG,cAAc,EAAE,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CACjD,gBAAgB,CAAC,EAAE,EAAE,cAAc,CAAC,CACrC,CAAC;IAEF,MAAM,YAAY,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAE/B,MAAM,gBAAgB,GACpB,QAAQ,EAAE,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,KAAK,YAAY,EAAE,MAAM,CAAC;QAC/D,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;IAEhB,MAAM,kBAAkB,GAAG,IAAI,EAAE,IAAI,CACnC,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,YAAY,KAAK,QAAQ,CAChD,CAAC;IAEF,MAAM,eAAe,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,CACtD,aAAa,CAAC,YAAY,CAAC,CAC5B,CAAC;IACF,MAAM,mBAAmB,GAAG,QAAQ,EAAE,IAAI,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,CAC9D,aAAa,CAAC,YAAY,CAAC,CAC5B,CAAC;IAEF,OAAO;QACL,YAAY;QACZ,gBAAgB;QAChB,kBAAkB;QAClB,eAAe;QACf,mBAAmB;KACpB,CAAC;AACJ,CAAC;AAcD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,0BAA0B,CACxC,QAAmC,EACnC,SAAmC,EACnC,OAAoB,EACpB,qBAA6C;IAE7C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC;IAC1C,MAAM,aAAa,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,4BAA4B,CAAC,YAAY,CAAC,CAAC;IAC7D,MAAM,QAAQ,GAAG,SAAS,KAAK,QAAQ,CAAC;IAExC,MAAM,UAAU,GACd,CAAC,aAAa,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,eAAe;QACrD,CAAC,CAAC,qBAAqB,CAAC,OAAO,EAAE,QAAQ,CAAC,eAAe,CAAC;QAC1D,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,SAAS,GACb,CAAC,aAAa,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,eAAe;QACrD,CAAC,CAAC,qBAAqB,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,eAAe,CAAC;QAC5D,CAAC,CAAC,SAAS,CAAC;IAEhB,MAAM,MAAM,GAAG,aAAa;QAC1B,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,MAAM,CAAC;QACpC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,IAAI,UAAU,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,CAAC,CAAC;IAEjE,IAAI,QAA4B,CAAC;IACjC,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACnC,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC;IAC9B,CAAC;SAAM,IAAI,QAAQ,EAAE,CAAC;QACpB,QAAQ,GAAG,mBAAmB,CAAC;IACjC,CAAC;SAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC1B,QAAQ,GAAG,UAAU,EAAE,QAAQ,IAAI,SAAS,EAAE,QAAQ,CAAC;IACzD,CAAC;IAED,MAAM,eAAe,GACnB,CAAC,aAAa;QACd,MAAM,KAAK,IAAI;QACf,MAAM,KAAK,SAAS;QACpB,QAAQ,KAAK,SAAS,CAAC;IACzB,4EAA4E;IAC5E,MAAM,YAAY,GAAG,aAAa,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS,CAAC;IAE9E,IAAI,OAA2B,CAAC;IAChC,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,GAAG,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC;SAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC1B,OAAO,GAAG,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,CAAC,MAAM,IAAI,CAAC,eAAe,IAAI,CAAC,YAAY,IAAI,CAAC,OAAO,EAAE,CAAC;QAC7D,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO;QACL,SAAS;QACT,GAAG,CAAC,eAAe,IAAI,YAAY,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;QAC/C,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7B,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/B,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,8BAA8B,CAC5C,eAAmC,EACnC,SAAmC,EACnC,OAAoB;IAEpB,MAAM,aAAa,GAAG,qBAAqB,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAEtE,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO;QACL,SAAS;QACT,SAAS,EAAE,OAAO;QAClB,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,GAAG,CAAC,aAAa,CAAC,QAAQ,KAAK,SAAS;YACtC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,QAAQ,EAAE,aAAa,CAAC,QAAQ,EAAE,CAAC;QACzC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACrE,CAAC;AACJ,CAAC","sourcesContent":["import {\n ERC721,\n ERC1155,\n isEqualCaseInsensitive as equalsIgnoreCase,\n} from '@metamask/controller-utils';\nimport type { V1TransactionByHashResponse } from '@metamask/core-backend';\nimport type { TransactionMeta } 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\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\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 amount = calculateNetworkFee(\n primaryTransaction.txReceipt?.gasUsed,\n primaryTransaction.txReceipt?.effectiveGasPrice ??\n primaryTransaction.txParams?.gasPrice,\n );\n\n if (!amount) {\n return undefined;\n }\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 {\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"]}
|
package/package.json
CHANGED