@metamask/transaction-controller 66.0.0 → 67.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 (60) hide show
  1. package/CHANGELOG.md +30 -1
  2. package/dist/TransactionController.cjs +28 -111
  3. package/dist/TransactionController.cjs.map +1 -1
  4. package/dist/TransactionController.d.cts +8 -55
  5. package/dist/TransactionController.d.cts.map +1 -1
  6. package/dist/TransactionController.d.mts +8 -55
  7. package/dist/TransactionController.d.mts.map +1 -1
  8. package/dist/TransactionController.mjs +28 -111
  9. package/dist/TransactionController.mjs.map +1 -1
  10. package/dist/gas-flows/MantleLayer1GasFeeFlow.cjs +5 -0
  11. package/dist/gas-flows/MantleLayer1GasFeeFlow.cjs.map +1 -1
  12. package/dist/gas-flows/MantleLayer1GasFeeFlow.d.cts +1 -0
  13. package/dist/gas-flows/MantleLayer1GasFeeFlow.d.cts.map +1 -1
  14. package/dist/gas-flows/MantleLayer1GasFeeFlow.d.mts +1 -0
  15. package/dist/gas-flows/MantleLayer1GasFeeFlow.d.mts.map +1 -1
  16. package/dist/gas-flows/MantleLayer1GasFeeFlow.mjs +5 -0
  17. package/dist/gas-flows/MantleLayer1GasFeeFlow.mjs.map +1 -1
  18. package/dist/gas-flows/OracleLayer1GasFeeFlow.cjs +15 -3
  19. package/dist/gas-flows/OracleLayer1GasFeeFlow.cjs.map +1 -1
  20. package/dist/gas-flows/OracleLayer1GasFeeFlow.d.cts +10 -0
  21. package/dist/gas-flows/OracleLayer1GasFeeFlow.d.cts.map +1 -1
  22. package/dist/gas-flows/OracleLayer1GasFeeFlow.d.mts +10 -0
  23. package/dist/gas-flows/OracleLayer1GasFeeFlow.d.mts.map +1 -1
  24. package/dist/gas-flows/OracleLayer1GasFeeFlow.mjs +15 -3
  25. package/dist/gas-flows/OracleLayer1GasFeeFlow.mjs.map +1 -1
  26. package/dist/helpers/PendingTransactionTracker.cjs +4 -82
  27. package/dist/helpers/PendingTransactionTracker.cjs.map +1 -1
  28. package/dist/helpers/PendingTransactionTracker.d.cts +1 -3
  29. package/dist/helpers/PendingTransactionTracker.d.cts.map +1 -1
  30. package/dist/helpers/PendingTransactionTracker.d.mts +1 -3
  31. package/dist/helpers/PendingTransactionTracker.d.mts.map +1 -1
  32. package/dist/helpers/PendingTransactionTracker.mjs +5 -83
  33. package/dist/helpers/PendingTransactionTracker.mjs.map +1 -1
  34. package/dist/hooks/ExtraTransactionsPublishHook.cjs +1 -0
  35. package/dist/hooks/ExtraTransactionsPublishHook.cjs.map +1 -1
  36. package/dist/hooks/ExtraTransactionsPublishHook.d.cts.map +1 -1
  37. package/dist/hooks/ExtraTransactionsPublishHook.d.mts.map +1 -1
  38. package/dist/hooks/ExtraTransactionsPublishHook.mjs +1 -0
  39. package/dist/hooks/ExtraTransactionsPublishHook.mjs.map +1 -1
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.cts +1 -1
  42. package/dist/index.d.cts.map +1 -1
  43. package/dist/index.d.mts +1 -1
  44. package/dist/index.d.mts.map +1 -1
  45. package/dist/index.mjs.map +1 -1
  46. package/dist/types.cjs.map +1 -1
  47. package/dist/types.d.cts +0 -14
  48. package/dist/types.d.cts.map +1 -1
  49. package/dist/types.d.mts +0 -14
  50. package/dist/types.d.mts.map +1 -1
  51. package/dist/types.mjs.map +1 -1
  52. package/dist/utils/prepare.cjs +8 -4
  53. package/dist/utils/prepare.cjs.map +1 -1
  54. package/dist/utils/prepare.d.cts +5 -4
  55. package/dist/utils/prepare.d.cts.map +1 -1
  56. package/dist/utils/prepare.d.mts +5 -4
  57. package/dist/utils/prepare.d.mts.map +1 -1
  58. package/dist/utils/prepare.mjs +8 -4
  59. package/dist/utils/prepare.mjs.map +1 -1
  60. package/package.json +4 -4
@@ -34,6 +34,11 @@ class MantleLayer1GasFeeFlow extends OracleLayer1GasFeeFlow_1.OracleLayer1GasFee
34
34
  async matchesTransaction({ transactionMeta, }) {
35
35
  return MANTLE_CHAIN_IDS.includes(transactionMeta.chainId);
36
36
  }
37
+ getOperatorFeeGas(transactionMeta) {
38
+ return (transactionMeta.gasUsed ??
39
+ transactionMeta.txParams.gas ??
40
+ transactionMeta.txParams.gasLimit);
41
+ }
37
42
  async transformOracleFee(oracleFee, request) {
38
43
  const { provider, transactionMeta } = request;
39
44
  const oracleAddress = this.getOracleAddressForChain(transactionMeta.chainId);
@@ -1 +1 @@
1
- {"version":3,"file":"MantleLayer1GasFeeFlow.cjs","sourceRoot":"","sources":["../../src/gas-flows/MantleLayer1GasFeeFlow.ts"],"names":[],"mappings":";;;AAAA,wDAAoD;AACpD,wDAAwD;AAKxD,gDAAyC;AAGzC,8CAAsC;AACtC,yEAAkE;AAElE,MAAM,gBAAgB,GAAU,CAAC,qBAAS,CAAC,MAAM,EAAE,qBAAS,CAAC,cAAc,CAAC,CAAC;AAE7E,MAAM,eAAe,GAAG;IACtB;QACE,MAAM,EAAE,EAAE;QACV,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE;YACP;gBACE,YAAY,EAAE,SAAS;gBACvB,IAAI,EAAE,EAAE;gBACR,IAAI,EAAE,SAAS;aAChB;SACF;QACD,eAAe,EAAE,MAAM;QACvB,IAAI,EAAE,UAAU;KACjB;CACF,CAAC;AAEF;;;;;;;GAOG;AACH,MAAa,sBAAuB,SAAQ,+CAAsB;IAChE,KAAK,CAAC,kBAAkB,CAAC,EACvB,eAAe,GAIhB;QACC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IAC5D,CAAC;IAEkB,KAAK,CAAC,kBAAkB,CACzC,SAAa,EACb,OAAgC;QAEhC,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;QAC9C,MAAM,aAAa,GAAG,IAAI,CAAC,wBAAwB,CACjD,eAAe,CAAC,OAAO,CACxB,CAAC;QAEF,MAAM,QAAQ,GAAG,IAAI,oBAAQ,CAC3B,aAAa,EACb,eAAe,EACf,IAAI,wBAAY,CAAC,QAAuC,CAAC,CAC1D,CAAC;QAEF,MAAM,UAAU,GAAG,IAAA,YAAI,EAAC,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QACrD,OAAO,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;CACF;AA5BD,wDA4BC","sourcesContent":["import { Contract } from '@ethersproject/contracts';\nimport { Web3Provider } from '@ethersproject/providers';\nimport type { ExternalProvider } from '@ethersproject/providers';\nimport type { Hex } from '@metamask/utils';\nimport type BN from 'bn.js';\n\nimport { CHAIN_IDS } from '../constants';\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type { Layer1GasFeeFlowRequest, TransactionMeta } from '../types';\nimport { toBN } from '../utils/utils';\nimport { OracleLayer1GasFeeFlow } from './OracleLayer1GasFeeFlow';\n\nconst MANTLE_CHAIN_IDS: Hex[] = [CHAIN_IDS.MANTLE, CHAIN_IDS.MANTLE_SEPOLIA];\n\nconst TOKEN_RATIO_ABI = [\n {\n inputs: [],\n name: 'tokenRatio',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n];\n\n/**\n * Mantle layer 1 gas fee flow.\n *\n * Mantle uses MNT as its native gas token, but the oracle's getL1Fee returns\n * values denominated in ETH. This subclass multiplies the L1 fee by the\n * tokenRatio (ETH/MNT exchange rate) from the oracle contract to convert\n * the fee to MNT.\n */\nexport class MantleLayer1GasFeeFlow extends OracleLayer1GasFeeFlow {\n async matchesTransaction({\n transactionMeta,\n }: {\n transactionMeta: TransactionMeta;\n messenger: TransactionControllerMessenger;\n }): Promise<boolean> {\n return MANTLE_CHAIN_IDS.includes(transactionMeta.chainId);\n }\n\n protected override async transformOracleFee(\n oracleFee: BN,\n request: Layer1GasFeeFlowRequest,\n ): Promise<BN> {\n const { provider, transactionMeta } = request;\n const oracleAddress = this.getOracleAddressForChain(\n transactionMeta.chainId,\n );\n\n const contract = new Contract(\n oracleAddress,\n TOKEN_RATIO_ABI,\n new Web3Provider(provider as unknown as ExternalProvider),\n );\n\n const tokenRatio = toBN(await contract.tokenRatio());\n return oracleFee.mul(tokenRatio);\n }\n}\n"]}
1
+ {"version":3,"file":"MantleLayer1GasFeeFlow.cjs","sourceRoot":"","sources":["../../src/gas-flows/MantleLayer1GasFeeFlow.ts"],"names":[],"mappings":";;;AAAA,wDAAoD;AACpD,wDAAwD;AAKxD,gDAAyC;AAGzC,8CAAsC;AACtC,yEAAkE;AAElE,MAAM,gBAAgB,GAAU,CAAC,qBAAS,CAAC,MAAM,EAAE,qBAAS,CAAC,cAAc,CAAC,CAAC;AAE7E,MAAM,eAAe,GAAG;IACtB;QACE,MAAM,EAAE,EAAE;QACV,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE;YACP;gBACE,YAAY,EAAE,SAAS;gBACvB,IAAI,EAAE,EAAE;gBACR,IAAI,EAAE,SAAS;aAChB;SACF;QACD,eAAe,EAAE,MAAM;QACvB,IAAI,EAAE,UAAU;KACjB;CACF,CAAC;AAEF;;;;;;;GAOG;AACH,MAAa,sBAAuB,SAAQ,+CAAsB;IAChE,KAAK,CAAC,kBAAkB,CAAC,EACvB,eAAe,GAIhB;QACC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IAC5D,CAAC;IAEkB,iBAAiB,CAClC,eAAgC;QAEhC,OAAO,CACL,eAAe,CAAC,OAAO;YACvB,eAAe,CAAC,QAAQ,CAAC,GAAG;YAC5B,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAClC,CAAC;IACJ,CAAC;IAEkB,KAAK,CAAC,kBAAkB,CACzC,SAAa,EACb,OAAgC;QAEhC,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;QAC9C,MAAM,aAAa,GAAG,IAAI,CAAC,wBAAwB,CACjD,eAAe,CAAC,OAAO,CACxB,CAAC;QAEF,MAAM,QAAQ,GAAG,IAAI,oBAAQ,CAC3B,aAAa,EACb,eAAe,EACf,IAAI,wBAAY,CAAC,QAAuC,CAAC,CAC1D,CAAC;QAEF,MAAM,UAAU,GAAG,IAAA,YAAI,EAAC,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QACrD,OAAO,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;CACF;AAtCD,wDAsCC","sourcesContent":["import { Contract } from '@ethersproject/contracts';\nimport { Web3Provider } from '@ethersproject/providers';\nimport type { ExternalProvider } from '@ethersproject/providers';\nimport type { Hex } from '@metamask/utils';\nimport type BN from 'bn.js';\n\nimport { CHAIN_IDS } from '../constants';\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type { Layer1GasFeeFlowRequest, TransactionMeta } from '../types';\nimport { toBN } from '../utils/utils';\nimport { OracleLayer1GasFeeFlow } from './OracleLayer1GasFeeFlow';\n\nconst MANTLE_CHAIN_IDS: Hex[] = [CHAIN_IDS.MANTLE, CHAIN_IDS.MANTLE_SEPOLIA];\n\nconst TOKEN_RATIO_ABI = [\n {\n inputs: [],\n name: 'tokenRatio',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n];\n\n/**\n * Mantle layer 1 gas fee flow.\n *\n * Mantle uses MNT as its native gas token, but the oracle's getL1Fee returns\n * values denominated in ETH. This subclass multiplies the L1 fee by the\n * tokenRatio (ETH/MNT exchange rate) from the oracle contract to convert\n * the fee to MNT.\n */\nexport class MantleLayer1GasFeeFlow extends OracleLayer1GasFeeFlow {\n async matchesTransaction({\n transactionMeta,\n }: {\n transactionMeta: TransactionMeta;\n messenger: TransactionControllerMessenger;\n }): Promise<boolean> {\n return MANTLE_CHAIN_IDS.includes(transactionMeta.chainId);\n }\n\n protected override getOperatorFeeGas(\n transactionMeta: TransactionMeta,\n ): string | undefined {\n return (\n transactionMeta.gasUsed ??\n transactionMeta.txParams.gas ??\n transactionMeta.txParams.gasLimit\n );\n }\n\n protected override async transformOracleFee(\n oracleFee: BN,\n request: Layer1GasFeeFlowRequest,\n ): Promise<BN> {\n const { provider, transactionMeta } = request;\n const oracleAddress = this.getOracleAddressForChain(\n transactionMeta.chainId,\n );\n\n const contract = new Contract(\n oracleAddress,\n TOKEN_RATIO_ABI,\n new Web3Provider(provider as unknown as ExternalProvider),\n );\n\n const tokenRatio = toBN(await contract.tokenRatio());\n return oracleFee.mul(tokenRatio);\n }\n}\n"]}
@@ -15,6 +15,7 @@ export declare class MantleLayer1GasFeeFlow extends OracleLayer1GasFeeFlow {
15
15
  transactionMeta: TransactionMeta;
16
16
  messenger: TransactionControllerMessenger;
17
17
  }): Promise<boolean>;
18
+ protected getOperatorFeeGas(transactionMeta: TransactionMeta): string | undefined;
18
19
  protected transformOracleFee(oracleFee: BN, request: Layer1GasFeeFlowRequest): Promise<BN>;
19
20
  }
20
21
  //# sourceMappingURL=MantleLayer1GasFeeFlow.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MantleLayer1GasFeeFlow.d.cts","sourceRoot":"","sources":["../../src/gas-flows/MantleLayer1GasFeeFlow.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc;AAG5B,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAE,qBAAiB;AAEzE,OAAO,EAAE,sBAAsB,EAAE,qCAAiC;AAoBlE;;;;;;;GAOG;AACH,qBAAa,sBAAuB,SAAQ,sBAAsB;IAC1D,kBAAkB,CAAC,EACvB,eAAe,GAChB,EAAE;QACD,eAAe,EAAE,eAAe,CAAC;QACjC,SAAS,EAAE,8BAA8B,CAAC;KAC3C,GAAG,OAAO,CAAC,OAAO,CAAC;cAIK,kBAAkB,CACzC,SAAS,EAAE,EAAE,EACb,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,EAAE,CAAC;CAef"}
1
+ {"version":3,"file":"MantleLayer1GasFeeFlow.d.cts","sourceRoot":"","sources":["../../src/gas-flows/MantleLayer1GasFeeFlow.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc;AAG5B,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAE,qBAAiB;AAEzE,OAAO,EAAE,sBAAsB,EAAE,qCAAiC;AAoBlE;;;;;;;GAOG;AACH,qBAAa,sBAAuB,SAAQ,sBAAsB;IAC1D,kBAAkB,CAAC,EACvB,eAAe,GAChB,EAAE;QACD,eAAe,EAAE,eAAe,CAAC;QACjC,SAAS,EAAE,8BAA8B,CAAC;KAC3C,GAAG,OAAO,CAAC,OAAO,CAAC;cAID,iBAAiB,CAClC,eAAe,EAAE,eAAe,GAC/B,MAAM,GAAG,SAAS;cAQI,kBAAkB,CACzC,SAAS,EAAE,EAAE,EACb,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,EAAE,CAAC;CAef"}
@@ -15,6 +15,7 @@ export declare class MantleLayer1GasFeeFlow extends OracleLayer1GasFeeFlow {
15
15
  transactionMeta: TransactionMeta;
16
16
  messenger: TransactionControllerMessenger;
17
17
  }): Promise<boolean>;
18
+ protected getOperatorFeeGas(transactionMeta: TransactionMeta): string | undefined;
18
19
  protected transformOracleFee(oracleFee: BN, request: Layer1GasFeeFlowRequest): Promise<BN>;
19
20
  }
20
21
  //# sourceMappingURL=MantleLayer1GasFeeFlow.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MantleLayer1GasFeeFlow.d.mts","sourceRoot":"","sources":["../../src/gas-flows/MantleLayer1GasFeeFlow.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc;AAG5B,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAE,qBAAiB;AAEzE,OAAO,EAAE,sBAAsB,EAAE,qCAAiC;AAoBlE;;;;;;;GAOG;AACH,qBAAa,sBAAuB,SAAQ,sBAAsB;IAC1D,kBAAkB,CAAC,EACvB,eAAe,GAChB,EAAE;QACD,eAAe,EAAE,eAAe,CAAC;QACjC,SAAS,EAAE,8BAA8B,CAAC;KAC3C,GAAG,OAAO,CAAC,OAAO,CAAC;cAIK,kBAAkB,CACzC,SAAS,EAAE,EAAE,EACb,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,EAAE,CAAC;CAef"}
1
+ {"version":3,"file":"MantleLayer1GasFeeFlow.d.mts","sourceRoot":"","sources":["../../src/gas-flows/MantleLayer1GasFeeFlow.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc;AAG5B,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAE,qBAAiB;AAEzE,OAAO,EAAE,sBAAsB,EAAE,qCAAiC;AAoBlE;;;;;;;GAOG;AACH,qBAAa,sBAAuB,SAAQ,sBAAsB;IAC1D,kBAAkB,CAAC,EACvB,eAAe,GAChB,EAAE;QACD,eAAe,EAAE,eAAe,CAAC;QACjC,SAAS,EAAE,8BAA8B,CAAC;KAC3C,GAAG,OAAO,CAAC,OAAO,CAAC;cAID,iBAAiB,CAClC,eAAe,EAAE,eAAe,GAC/B,MAAM,GAAG,SAAS;cAQI,kBAAkB,CACzC,SAAS,EAAE,EAAE,EACb,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,EAAE,CAAC;CAef"}
@@ -31,6 +31,11 @@ export class MantleLayer1GasFeeFlow extends OracleLayer1GasFeeFlow {
31
31
  async matchesTransaction({ transactionMeta, }) {
32
32
  return MANTLE_CHAIN_IDS.includes(transactionMeta.chainId);
33
33
  }
34
+ getOperatorFeeGas(transactionMeta) {
35
+ return (transactionMeta.gasUsed ??
36
+ transactionMeta.txParams.gas ??
37
+ transactionMeta.txParams.gasLimit);
38
+ }
34
39
  async transformOracleFee(oracleFee, request) {
35
40
  const { provider, transactionMeta } = request;
36
41
  const oracleAddress = this.getOracleAddressForChain(transactionMeta.chainId);
@@ -1 +1 @@
1
- {"version":3,"file":"MantleLayer1GasFeeFlow.mjs","sourceRoot":"","sources":["../../src/gas-flows/MantleLayer1GasFeeFlow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,iCAAiC;AACpD,OAAO,EAAE,YAAY,EAAE,iCAAiC;AAKxD,OAAO,EAAE,SAAS,EAAE,yBAAqB;AAGzC,OAAO,EAAE,IAAI,EAAE,2BAAuB;AACtC,OAAO,EAAE,sBAAsB,EAAE,qCAAiC;AAElE,MAAM,gBAAgB,GAAU,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;AAE7E,MAAM,eAAe,GAAG;IACtB;QACE,MAAM,EAAE,EAAE;QACV,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE;YACP;gBACE,YAAY,EAAE,SAAS;gBACvB,IAAI,EAAE,EAAE;gBACR,IAAI,EAAE,SAAS;aAChB;SACF;QACD,eAAe,EAAE,MAAM;QACvB,IAAI,EAAE,UAAU;KACjB;CACF,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,OAAO,sBAAuB,SAAQ,sBAAsB;IAChE,KAAK,CAAC,kBAAkB,CAAC,EACvB,eAAe,GAIhB;QACC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IAC5D,CAAC;IAEkB,KAAK,CAAC,kBAAkB,CACzC,SAAa,EACb,OAAgC;QAEhC,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;QAC9C,MAAM,aAAa,GAAG,IAAI,CAAC,wBAAwB,CACjD,eAAe,CAAC,OAAO,CACxB,CAAC;QAEF,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAC3B,aAAa,EACb,eAAe,EACf,IAAI,YAAY,CAAC,QAAuC,CAAC,CAC1D,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QACrD,OAAO,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;CACF","sourcesContent":["import { Contract } from '@ethersproject/contracts';\nimport { Web3Provider } from '@ethersproject/providers';\nimport type { ExternalProvider } from '@ethersproject/providers';\nimport type { Hex } from '@metamask/utils';\nimport type BN from 'bn.js';\n\nimport { CHAIN_IDS } from '../constants';\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type { Layer1GasFeeFlowRequest, TransactionMeta } from '../types';\nimport { toBN } from '../utils/utils';\nimport { OracleLayer1GasFeeFlow } from './OracleLayer1GasFeeFlow';\n\nconst MANTLE_CHAIN_IDS: Hex[] = [CHAIN_IDS.MANTLE, CHAIN_IDS.MANTLE_SEPOLIA];\n\nconst TOKEN_RATIO_ABI = [\n {\n inputs: [],\n name: 'tokenRatio',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n];\n\n/**\n * Mantle layer 1 gas fee flow.\n *\n * Mantle uses MNT as its native gas token, but the oracle's getL1Fee returns\n * values denominated in ETH. This subclass multiplies the L1 fee by the\n * tokenRatio (ETH/MNT exchange rate) from the oracle contract to convert\n * the fee to MNT.\n */\nexport class MantleLayer1GasFeeFlow extends OracleLayer1GasFeeFlow {\n async matchesTransaction({\n transactionMeta,\n }: {\n transactionMeta: TransactionMeta;\n messenger: TransactionControllerMessenger;\n }): Promise<boolean> {\n return MANTLE_CHAIN_IDS.includes(transactionMeta.chainId);\n }\n\n protected override async transformOracleFee(\n oracleFee: BN,\n request: Layer1GasFeeFlowRequest,\n ): Promise<BN> {\n const { provider, transactionMeta } = request;\n const oracleAddress = this.getOracleAddressForChain(\n transactionMeta.chainId,\n );\n\n const contract = new Contract(\n oracleAddress,\n TOKEN_RATIO_ABI,\n new Web3Provider(provider as unknown as ExternalProvider),\n );\n\n const tokenRatio = toBN(await contract.tokenRatio());\n return oracleFee.mul(tokenRatio);\n }\n}\n"]}
1
+ {"version":3,"file":"MantleLayer1GasFeeFlow.mjs","sourceRoot":"","sources":["../../src/gas-flows/MantleLayer1GasFeeFlow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,iCAAiC;AACpD,OAAO,EAAE,YAAY,EAAE,iCAAiC;AAKxD,OAAO,EAAE,SAAS,EAAE,yBAAqB;AAGzC,OAAO,EAAE,IAAI,EAAE,2BAAuB;AACtC,OAAO,EAAE,sBAAsB,EAAE,qCAAiC;AAElE,MAAM,gBAAgB,GAAU,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;AAE7E,MAAM,eAAe,GAAG;IACtB;QACE,MAAM,EAAE,EAAE;QACV,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE;YACP;gBACE,YAAY,EAAE,SAAS;gBACvB,IAAI,EAAE,EAAE;gBACR,IAAI,EAAE,SAAS;aAChB;SACF;QACD,eAAe,EAAE,MAAM;QACvB,IAAI,EAAE,UAAU;KACjB;CACF,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,OAAO,sBAAuB,SAAQ,sBAAsB;IAChE,KAAK,CAAC,kBAAkB,CAAC,EACvB,eAAe,GAIhB;QACC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IAC5D,CAAC;IAEkB,iBAAiB,CAClC,eAAgC;QAEhC,OAAO,CACL,eAAe,CAAC,OAAO;YACvB,eAAe,CAAC,QAAQ,CAAC,GAAG;YAC5B,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAClC,CAAC;IACJ,CAAC;IAEkB,KAAK,CAAC,kBAAkB,CACzC,SAAa,EACb,OAAgC;QAEhC,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;QAC9C,MAAM,aAAa,GAAG,IAAI,CAAC,wBAAwB,CACjD,eAAe,CAAC,OAAO,CACxB,CAAC;QAEF,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAC3B,aAAa,EACb,eAAe,EACf,IAAI,YAAY,CAAC,QAAuC,CAAC,CAC1D,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QACrD,OAAO,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;CACF","sourcesContent":["import { Contract } from '@ethersproject/contracts';\nimport { Web3Provider } from '@ethersproject/providers';\nimport type { ExternalProvider } from '@ethersproject/providers';\nimport type { Hex } from '@metamask/utils';\nimport type BN from 'bn.js';\n\nimport { CHAIN_IDS } from '../constants';\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type { Layer1GasFeeFlowRequest, TransactionMeta } from '../types';\nimport { toBN } from '../utils/utils';\nimport { OracleLayer1GasFeeFlow } from './OracleLayer1GasFeeFlow';\n\nconst MANTLE_CHAIN_IDS: Hex[] = [CHAIN_IDS.MANTLE, CHAIN_IDS.MANTLE_SEPOLIA];\n\nconst TOKEN_RATIO_ABI = [\n {\n inputs: [],\n name: 'tokenRatio',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n];\n\n/**\n * Mantle layer 1 gas fee flow.\n *\n * Mantle uses MNT as its native gas token, but the oracle's getL1Fee returns\n * values denominated in ETH. This subclass multiplies the L1 fee by the\n * tokenRatio (ETH/MNT exchange rate) from the oracle contract to convert\n * the fee to MNT.\n */\nexport class MantleLayer1GasFeeFlow extends OracleLayer1GasFeeFlow {\n async matchesTransaction({\n transactionMeta,\n }: {\n transactionMeta: TransactionMeta;\n messenger: TransactionControllerMessenger;\n }): Promise<boolean> {\n return MANTLE_CHAIN_IDS.includes(transactionMeta.chainId);\n }\n\n protected override getOperatorFeeGas(\n transactionMeta: TransactionMeta,\n ): string | undefined {\n return (\n transactionMeta.gasUsed ??\n transactionMeta.txParams.gas ??\n transactionMeta.txParams.gasLimit\n );\n }\n\n protected override async transformOracleFee(\n oracleFee: BN,\n request: Layer1GasFeeFlowRequest,\n ): Promise<BN> {\n const { provider, transactionMeta } = request;\n const oracleAddress = this.getOracleAddressForChain(\n transactionMeta.chainId,\n );\n\n const contract = new Contract(\n oracleAddress,\n TOKEN_RATIO_ABI,\n new Web3Provider(provider as unknown as ExternalProvider),\n );\n\n const tokenRatio = toBN(await contract.tokenRatio());\n return oracleFee.mul(tokenRatio);\n }\n}\n"]}
@@ -123,6 +123,18 @@ class OracleLayer1GasFeeFlow {
123
123
  throw new Error(`Failed to get oracle layer 1 gas fee`);
124
124
  }
125
125
  }
126
+ /**
127
+ * Returns the gas value to pass to the operator-fee oracle, or undefined
128
+ * to skip the operator-fee call entirely. Defaults to the simulated
129
+ * `gasUsed` on the transaction. Subclasses can override to supply a
130
+ * fallback (e.g. estimated gas limit) when `gasUsed` is unavailable.
131
+ *
132
+ * @param transactionMeta - The transaction metadata.
133
+ * @returns The gas value, or undefined to skip the operator-fee call.
134
+ */
135
+ getOperatorFeeGas(transactionMeta) {
136
+ return transactionMeta.gasUsed;
137
+ }
126
138
  }
127
139
  exports.OracleLayer1GasFeeFlow = OracleLayer1GasFeeFlow;
128
140
  _OracleLayer1GasFeeFlow_instances = new WeakSet(), _OracleLayer1GasFeeFlow_getOracleLayer1GasFee = async function _OracleLayer1GasFeeFlow_getOracleLayer1GasFee(contract, transactionMeta) {
@@ -133,12 +145,12 @@ _OracleLayer1GasFeeFlow_instances = new WeakSet(), _OracleLayer1GasFeeFlow_getOr
133
145
  }
134
146
  return (0, utils_2.toBN)(result);
135
147
  }, _OracleLayer1GasFeeFlow_getOperatorLayer1GasFee = async function _OracleLayer1GasFeeFlow_getOperatorLayer1GasFee(contract, transactionMeta) {
136
- const { gasUsed } = transactionMeta;
137
- if (!gasUsed) {
148
+ const gas = this.getOperatorFeeGas(transactionMeta);
149
+ if (!gas) {
138
150
  return ZERO;
139
151
  }
140
152
  try {
141
- const result = await contract.getOperatorFee(gasUsed);
153
+ const result = await contract.getOperatorFee(gas);
142
154
  if (result === undefined) {
143
155
  return ZERO;
144
156
  }
@@ -1 +1 @@
1
- {"version":3,"file":"OracleLayer1GasFeeFlow.cjs","sourceRoot":"","sources":["../../src/gas-flows/OracleLayer1GasFeeFlow.ts"],"names":[],"mappings":"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","sourcesContent":["import { Contract } from '@ethersproject/contracts';\nimport { Web3Provider } from '@ethersproject/providers';\nimport type { ExternalProvider } from '@ethersproject/providers';\nimport type { Hex } from '@metamask/utils';\nimport { add0x, createModuleLogger } from '@metamask/utils';\nimport BN from 'bn.js';\n\nimport { projectLogger } from '../logger';\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type {\n Layer1GasFeeFlow,\n Layer1GasFeeFlowRequest,\n Layer1GasFeeFlowResponse,\n TransactionMeta,\n} from '../types';\nimport { prepareTransaction } from '../utils/prepare';\nimport { padHexToEvenLength, toBN } from '../utils/utils';\n\nconst log = createModuleLogger(projectLogger, 'oracle-layer1-gas-fee-flow');\n\nconst ZERO = new BN(0);\n\nconst DUMMY_KEY =\n 'abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789';\n\nconst GAS_PRICE_ORACLE_ABI = [\n {\n inputs: [\n {\n internalType: 'bytes',\n name: '_data',\n type: 'bytes',\n },\n ],\n name: 'getL1Fee',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n // only available post Isthmus\n {\n inputs: [\n {\n internalType: 'uint256',\n name: '_gasUsed',\n type: 'uint256',\n },\n ],\n name: 'getOperatorFee',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n];\n\n// Default OP Stack gas price oracle address used across supported networks\nconst DEFAULT_GAS_PRICE_ORACLE_ADDRESS =\n '0x420000000000000000000000000000000000000F' as Hex;\n\n/**\n * Layer 1 gas fee flow that obtains gas fee estimate using an oracle smart contract.\n */\nexport abstract class OracleLayer1GasFeeFlow implements Layer1GasFeeFlow {\n /**\n * Resolves the oracle address for the given chain. Subclasses can override\n * this method to provide chain-specific oracle addresses. By default, this\n * returns the standard OP Stack gas price oracle address.\n *\n * @param _chainId - The chain ID to resolve the oracle address for.\n * @returns The oracle address for the given chain.\n */\n protected getOracleAddressForChain(_chainId: Hex): Hex {\n return DEFAULT_GAS_PRICE_ORACLE_ADDRESS;\n }\n\n /**\n * Whether to sign the transaction with a dummy key prior to calling the\n * oracle contract. Some oracle contracts require a signed payload even for\n * read-only methods.\n *\n * Subclasses can override to enable signing when needed. Defaults to false.\n *\n * @returns Whether the transaction should be signed prior to the oracle call.\n */\n protected shouldSignTransaction(): boolean {\n return false;\n }\n\n abstract matchesTransaction({\n transactionMeta,\n messenger,\n }: {\n transactionMeta: TransactionMeta;\n messenger: TransactionControllerMessenger;\n }): Promise<boolean>;\n\n /**\n * Transforms the raw oracle L1 fee before it is combined with the operator\n * fee. Subclasses can override this to apply chain-specific conversions\n * (e.g. currency conversion via an on-chain exchange rate).\n *\n * Defaults to returning the fee unchanged.\n *\n * @param oracleFee - The raw L1 fee returned by the oracle contract.\n * @param _request - The original fee flow request (provider + transaction).\n * @returns The transformed fee.\n */\n protected async transformOracleFee(\n oracleFee: BN,\n _request: Layer1GasFeeFlowRequest,\n ): Promise<BN> {\n return oracleFee;\n }\n\n async getLayer1Fee(\n request: Layer1GasFeeFlowRequest,\n ): Promise<Layer1GasFeeFlowResponse> {\n try {\n const { provider, transactionMeta } = request;\n\n const contract = this.#getGasPriceOracleContract(\n provider,\n transactionMeta.chainId,\n );\n\n const oracleFee = await this.#getOracleLayer1GasFee(\n contract,\n transactionMeta,\n );\n const transformedFee = await this.transformOracleFee(oracleFee, request);\n const operatorFee = await this.#getOperatorLayer1GasFee(\n contract,\n transactionMeta,\n );\n\n return {\n layer1Fee: add0x(\n padHexToEvenLength(transformedFee.add(operatorFee).toString(16)),\n ),\n };\n } catch (error) {\n log('Failed to get oracle layer 1 gas fee', error);\n throw new Error(`Failed to get oracle layer 1 gas fee`);\n }\n }\n\n async #getOracleLayer1GasFee(\n contract: Contract,\n transactionMeta: TransactionMeta,\n ): Promise<BN> {\n const serializedTransaction = this.#buildUnserializedTransaction(\n transactionMeta,\n this.shouldSignTransaction(),\n ).serialize();\n\n const result = await contract.getL1Fee(serializedTransaction);\n\n if (result === undefined) {\n throw new Error('No value returned from oracle contract');\n }\n\n return toBN(result);\n }\n\n async #getOperatorLayer1GasFee(\n contract: Contract,\n transactionMeta: TransactionMeta,\n ): Promise<BN> {\n const { gasUsed } = transactionMeta;\n\n if (!gasUsed) {\n return ZERO;\n }\n\n try {\n const result = await contract.getOperatorFee(gasUsed);\n\n if (result === undefined) {\n return ZERO;\n }\n\n return toBN(result);\n } catch (error) {\n log('Failed to get operator layer 1 gas fee', error);\n return ZERO;\n }\n }\n\n #buildUnserializedTransaction(\n transactionMeta: TransactionMeta,\n sign: boolean,\n ): ReturnType<typeof prepareTransaction> {\n const txParams = this.#buildTransactionParams(transactionMeta);\n const { chainId } = transactionMeta;\n\n let unserializedTransaction = prepareTransaction(chainId, txParams);\n\n if (sign) {\n // eslint-disable-next-line no-restricted-globals\n const keyBuffer = Buffer.from(DUMMY_KEY, 'hex');\n const keyBytes = Uint8Array.from(keyBuffer);\n unserializedTransaction = unserializedTransaction.sign(keyBytes);\n }\n\n return unserializedTransaction;\n }\n\n #buildTransactionParams(\n transactionMeta: TransactionMeta,\n ): TransactionMeta['txParams'] {\n return {\n ...transactionMeta.txParams,\n gasLimit: transactionMeta.txParams.gas,\n };\n }\n\n #getGasPriceOracleContract(\n provider: Layer1GasFeeFlowRequest['provider'],\n chainId: Hex,\n ): Contract {\n return new Contract(\n this.getOracleAddressForChain(chainId),\n GAS_PRICE_ORACLE_ABI,\n // Network controller provider type is incompatible with ethers provider\n new Web3Provider(provider as unknown as ExternalProvider),\n );\n }\n}\n"]}
1
+ {"version":3,"file":"OracleLayer1GasFeeFlow.cjs","sourceRoot":"","sources":["../../src/gas-flows/OracleLayer1GasFeeFlow.ts"],"names":[],"mappings":"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","sourcesContent":["import { Contract } from '@ethersproject/contracts';\nimport { Web3Provider } from '@ethersproject/providers';\nimport type { ExternalProvider } from '@ethersproject/providers';\nimport type { Hex } from '@metamask/utils';\nimport { add0x, createModuleLogger } from '@metamask/utils';\nimport BN from 'bn.js';\n\nimport { projectLogger } from '../logger';\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type {\n Layer1GasFeeFlow,\n Layer1GasFeeFlowRequest,\n Layer1GasFeeFlowResponse,\n TransactionMeta,\n} from '../types';\nimport { prepareTransaction } from '../utils/prepare';\nimport { padHexToEvenLength, toBN } from '../utils/utils';\n\nconst log = createModuleLogger(projectLogger, 'oracle-layer1-gas-fee-flow');\n\nconst ZERO = new BN(0);\n\nconst DUMMY_KEY =\n 'abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789';\n\nconst GAS_PRICE_ORACLE_ABI = [\n {\n inputs: [\n {\n internalType: 'bytes',\n name: '_data',\n type: 'bytes',\n },\n ],\n name: 'getL1Fee',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n // only available post Isthmus\n {\n inputs: [\n {\n internalType: 'uint256',\n name: '_gasUsed',\n type: 'uint256',\n },\n ],\n name: 'getOperatorFee',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n];\n\n// Default OP Stack gas price oracle address used across supported networks\nconst DEFAULT_GAS_PRICE_ORACLE_ADDRESS =\n '0x420000000000000000000000000000000000000F' as Hex;\n\n/**\n * Layer 1 gas fee flow that obtains gas fee estimate using an oracle smart contract.\n */\nexport abstract class OracleLayer1GasFeeFlow implements Layer1GasFeeFlow {\n /**\n * Resolves the oracle address for the given chain. Subclasses can override\n * this method to provide chain-specific oracle addresses. By default, this\n * returns the standard OP Stack gas price oracle address.\n *\n * @param _chainId - The chain ID to resolve the oracle address for.\n * @returns The oracle address for the given chain.\n */\n protected getOracleAddressForChain(_chainId: Hex): Hex {\n return DEFAULT_GAS_PRICE_ORACLE_ADDRESS;\n }\n\n /**\n * Whether to sign the transaction with a dummy key prior to calling the\n * oracle contract. Some oracle contracts require a signed payload even for\n * read-only methods.\n *\n * Subclasses can override to enable signing when needed. Defaults to false.\n *\n * @returns Whether the transaction should be signed prior to the oracle call.\n */\n protected shouldSignTransaction(): boolean {\n return false;\n }\n\n abstract matchesTransaction({\n transactionMeta,\n messenger,\n }: {\n transactionMeta: TransactionMeta;\n messenger: TransactionControllerMessenger;\n }): Promise<boolean>;\n\n /**\n * Transforms the raw oracle L1 fee before it is combined with the operator\n * fee. Subclasses can override this to apply chain-specific conversions\n * (e.g. currency conversion via an on-chain exchange rate).\n *\n * Defaults to returning the fee unchanged.\n *\n * @param oracleFee - The raw L1 fee returned by the oracle contract.\n * @param _request - The original fee flow request (provider + transaction).\n * @returns The transformed fee.\n */\n protected async transformOracleFee(\n oracleFee: BN,\n _request: Layer1GasFeeFlowRequest,\n ): Promise<BN> {\n return oracleFee;\n }\n\n async getLayer1Fee(\n request: Layer1GasFeeFlowRequest,\n ): Promise<Layer1GasFeeFlowResponse> {\n try {\n const { provider, transactionMeta } = request;\n\n const contract = this.#getGasPriceOracleContract(\n provider,\n transactionMeta.chainId,\n );\n\n const oracleFee = await this.#getOracleLayer1GasFee(\n contract,\n transactionMeta,\n );\n const transformedFee = await this.transformOracleFee(oracleFee, request);\n const operatorFee = await this.#getOperatorLayer1GasFee(\n contract,\n transactionMeta,\n );\n\n return {\n layer1Fee: add0x(\n padHexToEvenLength(transformedFee.add(operatorFee).toString(16)),\n ),\n };\n } catch (error) {\n log('Failed to get oracle layer 1 gas fee', error);\n throw new Error(`Failed to get oracle layer 1 gas fee`);\n }\n }\n\n async #getOracleLayer1GasFee(\n contract: Contract,\n transactionMeta: TransactionMeta,\n ): Promise<BN> {\n const serializedTransaction = this.#buildUnserializedTransaction(\n transactionMeta,\n this.shouldSignTransaction(),\n ).serialize();\n\n const result = await contract.getL1Fee(serializedTransaction);\n\n if (result === undefined) {\n throw new Error('No value returned from oracle contract');\n }\n\n return toBN(result);\n }\n\n /**\n * Returns the gas value to pass to the operator-fee oracle, or undefined\n * to skip the operator-fee call entirely. Defaults to the simulated\n * `gasUsed` on the transaction. Subclasses can override to supply a\n * fallback (e.g. estimated gas limit) when `gasUsed` is unavailable.\n *\n * @param transactionMeta - The transaction metadata.\n * @returns The gas value, or undefined to skip the operator-fee call.\n */\n protected getOperatorFeeGas(\n transactionMeta: TransactionMeta,\n ): string | undefined {\n return transactionMeta.gasUsed;\n }\n\n async #getOperatorLayer1GasFee(\n contract: Contract,\n transactionMeta: TransactionMeta,\n ): Promise<BN> {\n const gas = this.getOperatorFeeGas(transactionMeta);\n\n if (!gas) {\n return ZERO;\n }\n\n try {\n const result = await contract.getOperatorFee(gas);\n\n if (result === undefined) {\n return ZERO;\n }\n\n return toBN(result);\n } catch (error) {\n log('Failed to get operator layer 1 gas fee', error);\n return ZERO;\n }\n }\n\n #buildUnserializedTransaction(\n transactionMeta: TransactionMeta,\n sign: boolean,\n ): ReturnType<typeof prepareTransaction> {\n const txParams = this.#buildTransactionParams(transactionMeta);\n const { chainId } = transactionMeta;\n\n let unserializedTransaction = prepareTransaction(chainId, txParams);\n\n if (sign) {\n // eslint-disable-next-line no-restricted-globals\n const keyBuffer = Buffer.from(DUMMY_KEY, 'hex');\n const keyBytes = Uint8Array.from(keyBuffer);\n unserializedTransaction = unserializedTransaction.sign(keyBytes);\n }\n\n return unserializedTransaction;\n }\n\n #buildTransactionParams(\n transactionMeta: TransactionMeta,\n ): TransactionMeta['txParams'] {\n return {\n ...transactionMeta.txParams,\n gasLimit: transactionMeta.txParams.gas,\n };\n }\n\n #getGasPriceOracleContract(\n provider: Layer1GasFeeFlowRequest['provider'],\n chainId: Hex,\n ): Contract {\n return new Contract(\n this.getOracleAddressForChain(chainId),\n GAS_PRICE_ORACLE_ABI,\n // Network controller provider type is incompatible with ethers provider\n new Web3Provider(provider as unknown as ExternalProvider),\n );\n }\n}\n"]}
@@ -43,5 +43,15 @@ export declare abstract class OracleLayer1GasFeeFlow implements Layer1GasFeeFlow
43
43
  */
44
44
  protected transformOracleFee(oracleFee: BN, _request: Layer1GasFeeFlowRequest): Promise<BN>;
45
45
  getLayer1Fee(request: Layer1GasFeeFlowRequest): Promise<Layer1GasFeeFlowResponse>;
46
+ /**
47
+ * Returns the gas value to pass to the operator-fee oracle, or undefined
48
+ * to skip the operator-fee call entirely. Defaults to the simulated
49
+ * `gasUsed` on the transaction. Subclasses can override to supply a
50
+ * fallback (e.g. estimated gas limit) when `gasUsed` is unavailable.
51
+ *
52
+ * @param transactionMeta - The transaction metadata.
53
+ * @returns The gas value, or undefined to skip the operator-fee call.
54
+ */
55
+ protected getOperatorFeeGas(transactionMeta: TransactionMeta): string | undefined;
46
56
  }
47
57
  //# sourceMappingURL=OracleLayer1GasFeeFlow.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"OracleLayer1GasFeeFlow.d.cts","sourceRoot":"","sources":["../../src/gas-flows/OracleLayer1GasFeeFlow.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,EAAE,cAAc;AAGvB,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EACV,gBAAgB,EAChB,uBAAuB,EACvB,wBAAwB,EACxB,eAAe,EAChB,qBAAiB;AAyDlB;;GAEG;AACH,8BAAsB,sBAAuB,YAAW,gBAAgB;;IACtE;;;;;;;OAOG;IACH,SAAS,CAAC,wBAAwB,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG;IAItD;;;;;;;;OAQG;IACH,SAAS,CAAC,qBAAqB,IAAI,OAAO;IAI1C,QAAQ,CAAC,kBAAkB,CAAC,EAC1B,eAAe,EACf,SAAS,GACV,EAAE;QACD,eAAe,EAAE,eAAe,CAAC;QACjC,SAAS,EAAE,8BAA8B,CAAC;KAC3C,GAAG,OAAO,CAAC,OAAO,CAAC;IAEpB;;;;;;;;;;OAUG;cACa,kBAAkB,CAChC,SAAS,EAAE,EAAE,EACb,QAAQ,EAAE,uBAAuB,GAChC,OAAO,CAAC,EAAE,CAAC;IAIR,YAAY,CAChB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,wBAAwB,CAAC;CA+GrC"}
1
+ {"version":3,"file":"OracleLayer1GasFeeFlow.d.cts","sourceRoot":"","sources":["../../src/gas-flows/OracleLayer1GasFeeFlow.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,EAAE,cAAc;AAGvB,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EACV,gBAAgB,EAChB,uBAAuB,EACvB,wBAAwB,EACxB,eAAe,EAChB,qBAAiB;AAyDlB;;GAEG;AACH,8BAAsB,sBAAuB,YAAW,gBAAgB;;IACtE;;;;;;;OAOG;IACH,SAAS,CAAC,wBAAwB,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG;IAItD;;;;;;;;OAQG;IACH,SAAS,CAAC,qBAAqB,IAAI,OAAO;IAI1C,QAAQ,CAAC,kBAAkB,CAAC,EAC1B,eAAe,EACf,SAAS,GACV,EAAE;QACD,eAAe,EAAE,eAAe,CAAC;QACjC,SAAS,EAAE,8BAA8B,CAAC;KAC3C,GAAG,OAAO,CAAC,OAAO,CAAC;IAEpB;;;;;;;;;;OAUG;cACa,kBAAkB,CAChC,SAAS,EAAE,EAAE,EACb,QAAQ,EAAE,uBAAuB,GAChC,OAAO,CAAC,EAAE,CAAC;IAIR,YAAY,CAChB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,wBAAwB,CAAC;IAgDpC;;;;;;;;OAQG;IACH,SAAS,CAAC,iBAAiB,CACzB,eAAe,EAAE,eAAe,GAC/B,MAAM,GAAG,SAAS;CAmEtB"}
@@ -43,5 +43,15 @@ export declare abstract class OracleLayer1GasFeeFlow implements Layer1GasFeeFlow
43
43
  */
44
44
  protected transformOracleFee(oracleFee: BN, _request: Layer1GasFeeFlowRequest): Promise<BN>;
45
45
  getLayer1Fee(request: Layer1GasFeeFlowRequest): Promise<Layer1GasFeeFlowResponse>;
46
+ /**
47
+ * Returns the gas value to pass to the operator-fee oracle, or undefined
48
+ * to skip the operator-fee call entirely. Defaults to the simulated
49
+ * `gasUsed` on the transaction. Subclasses can override to supply a
50
+ * fallback (e.g. estimated gas limit) when `gasUsed` is unavailable.
51
+ *
52
+ * @param transactionMeta - The transaction metadata.
53
+ * @returns The gas value, or undefined to skip the operator-fee call.
54
+ */
55
+ protected getOperatorFeeGas(transactionMeta: TransactionMeta): string | undefined;
46
56
  }
47
57
  //# sourceMappingURL=OracleLayer1GasFeeFlow.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"OracleLayer1GasFeeFlow.d.mts","sourceRoot":"","sources":["../../src/gas-flows/OracleLayer1GasFeeFlow.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,EAAE,cAAc;AAGvB,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EACV,gBAAgB,EAChB,uBAAuB,EACvB,wBAAwB,EACxB,eAAe,EAChB,qBAAiB;AAyDlB;;GAEG;AACH,8BAAsB,sBAAuB,YAAW,gBAAgB;;IACtE;;;;;;;OAOG;IACH,SAAS,CAAC,wBAAwB,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG;IAItD;;;;;;;;OAQG;IACH,SAAS,CAAC,qBAAqB,IAAI,OAAO;IAI1C,QAAQ,CAAC,kBAAkB,CAAC,EAC1B,eAAe,EACf,SAAS,GACV,EAAE;QACD,eAAe,EAAE,eAAe,CAAC;QACjC,SAAS,EAAE,8BAA8B,CAAC;KAC3C,GAAG,OAAO,CAAC,OAAO,CAAC;IAEpB;;;;;;;;;;OAUG;cACa,kBAAkB,CAChC,SAAS,EAAE,EAAE,EACb,QAAQ,EAAE,uBAAuB,GAChC,OAAO,CAAC,EAAE,CAAC;IAIR,YAAY,CAChB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,wBAAwB,CAAC;CA+GrC"}
1
+ {"version":3,"file":"OracleLayer1GasFeeFlow.d.mts","sourceRoot":"","sources":["../../src/gas-flows/OracleLayer1GasFeeFlow.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,EAAE,cAAc;AAGvB,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EACV,gBAAgB,EAChB,uBAAuB,EACvB,wBAAwB,EACxB,eAAe,EAChB,qBAAiB;AAyDlB;;GAEG;AACH,8BAAsB,sBAAuB,YAAW,gBAAgB;;IACtE;;;;;;;OAOG;IACH,SAAS,CAAC,wBAAwB,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG;IAItD;;;;;;;;OAQG;IACH,SAAS,CAAC,qBAAqB,IAAI,OAAO;IAI1C,QAAQ,CAAC,kBAAkB,CAAC,EAC1B,eAAe,EACf,SAAS,GACV,EAAE;QACD,eAAe,EAAE,eAAe,CAAC;QACjC,SAAS,EAAE,8BAA8B,CAAC;KAC3C,GAAG,OAAO,CAAC,OAAO,CAAC;IAEpB;;;;;;;;;;OAUG;cACa,kBAAkB,CAChC,SAAS,EAAE,EAAE,EACb,QAAQ,EAAE,uBAAuB,GAChC,OAAO,CAAC,EAAE,CAAC;IAIR,YAAY,CAChB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,wBAAwB,CAAC;IAgDpC;;;;;;;;OAQG;IACH,SAAS,CAAC,iBAAiB,CACzB,eAAe,EAAE,eAAe,GAC/B,MAAM,GAAG,SAAS;CAmEtB"}
@@ -124,6 +124,18 @@ export class OracleLayer1GasFeeFlow {
124
124
  throw new Error(`Failed to get oracle layer 1 gas fee`);
125
125
  }
126
126
  }
127
+ /**
128
+ * Returns the gas value to pass to the operator-fee oracle, or undefined
129
+ * to skip the operator-fee call entirely. Defaults to the simulated
130
+ * `gasUsed` on the transaction. Subclasses can override to supply a
131
+ * fallback (e.g. estimated gas limit) when `gasUsed` is unavailable.
132
+ *
133
+ * @param transactionMeta - The transaction metadata.
134
+ * @returns The gas value, or undefined to skip the operator-fee call.
135
+ */
136
+ getOperatorFeeGas(transactionMeta) {
137
+ return transactionMeta.gasUsed;
138
+ }
127
139
  }
128
140
  _OracleLayer1GasFeeFlow_instances = new WeakSet(), _OracleLayer1GasFeeFlow_getOracleLayer1GasFee = async function _OracleLayer1GasFeeFlow_getOracleLayer1GasFee(contract, transactionMeta) {
129
141
  const serializedTransaction = __classPrivateFieldGet(this, _OracleLayer1GasFeeFlow_instances, "m", _OracleLayer1GasFeeFlow_buildUnserializedTransaction).call(this, transactionMeta, this.shouldSignTransaction()).serialize();
@@ -133,12 +145,12 @@ _OracleLayer1GasFeeFlow_instances = new WeakSet(), _OracleLayer1GasFeeFlow_getOr
133
145
  }
134
146
  return toBN(result);
135
147
  }, _OracleLayer1GasFeeFlow_getOperatorLayer1GasFee = async function _OracleLayer1GasFeeFlow_getOperatorLayer1GasFee(contract, transactionMeta) {
136
- const { gasUsed } = transactionMeta;
137
- if (!gasUsed) {
148
+ const gas = this.getOperatorFeeGas(transactionMeta);
149
+ if (!gas) {
138
150
  return ZERO;
139
151
  }
140
152
  try {
141
- const result = await contract.getOperatorFee(gasUsed);
153
+ const result = await contract.getOperatorFee(gas);
142
154
  if (result === undefined) {
143
155
  return ZERO;
144
156
  }
@@ -1 +1 @@
1
- {"version":3,"file":"OracleLayer1GasFeeFlow.mjs","sourceRoot":"","sources":["../../src/gas-flows/OracleLayer1GasFeeFlow.ts"],"names":[],"mappings":"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","sourcesContent":["import { Contract } from '@ethersproject/contracts';\nimport { Web3Provider } from '@ethersproject/providers';\nimport type { ExternalProvider } from '@ethersproject/providers';\nimport type { Hex } from '@metamask/utils';\nimport { add0x, createModuleLogger } from '@metamask/utils';\nimport BN from 'bn.js';\n\nimport { projectLogger } from '../logger';\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type {\n Layer1GasFeeFlow,\n Layer1GasFeeFlowRequest,\n Layer1GasFeeFlowResponse,\n TransactionMeta,\n} from '../types';\nimport { prepareTransaction } from '../utils/prepare';\nimport { padHexToEvenLength, toBN } from '../utils/utils';\n\nconst log = createModuleLogger(projectLogger, 'oracle-layer1-gas-fee-flow');\n\nconst ZERO = new BN(0);\n\nconst DUMMY_KEY =\n 'abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789';\n\nconst GAS_PRICE_ORACLE_ABI = [\n {\n inputs: [\n {\n internalType: 'bytes',\n name: '_data',\n type: 'bytes',\n },\n ],\n name: 'getL1Fee',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n // only available post Isthmus\n {\n inputs: [\n {\n internalType: 'uint256',\n name: '_gasUsed',\n type: 'uint256',\n },\n ],\n name: 'getOperatorFee',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n];\n\n// Default OP Stack gas price oracle address used across supported networks\nconst DEFAULT_GAS_PRICE_ORACLE_ADDRESS =\n '0x420000000000000000000000000000000000000F' as Hex;\n\n/**\n * Layer 1 gas fee flow that obtains gas fee estimate using an oracle smart contract.\n */\nexport abstract class OracleLayer1GasFeeFlow implements Layer1GasFeeFlow {\n /**\n * Resolves the oracle address for the given chain. Subclasses can override\n * this method to provide chain-specific oracle addresses. By default, this\n * returns the standard OP Stack gas price oracle address.\n *\n * @param _chainId - The chain ID to resolve the oracle address for.\n * @returns The oracle address for the given chain.\n */\n protected getOracleAddressForChain(_chainId: Hex): Hex {\n return DEFAULT_GAS_PRICE_ORACLE_ADDRESS;\n }\n\n /**\n * Whether to sign the transaction with a dummy key prior to calling the\n * oracle contract. Some oracle contracts require a signed payload even for\n * read-only methods.\n *\n * Subclasses can override to enable signing when needed. Defaults to false.\n *\n * @returns Whether the transaction should be signed prior to the oracle call.\n */\n protected shouldSignTransaction(): boolean {\n return false;\n }\n\n abstract matchesTransaction({\n transactionMeta,\n messenger,\n }: {\n transactionMeta: TransactionMeta;\n messenger: TransactionControllerMessenger;\n }): Promise<boolean>;\n\n /**\n * Transforms the raw oracle L1 fee before it is combined with the operator\n * fee. Subclasses can override this to apply chain-specific conversions\n * (e.g. currency conversion via an on-chain exchange rate).\n *\n * Defaults to returning the fee unchanged.\n *\n * @param oracleFee - The raw L1 fee returned by the oracle contract.\n * @param _request - The original fee flow request (provider + transaction).\n * @returns The transformed fee.\n */\n protected async transformOracleFee(\n oracleFee: BN,\n _request: Layer1GasFeeFlowRequest,\n ): Promise<BN> {\n return oracleFee;\n }\n\n async getLayer1Fee(\n request: Layer1GasFeeFlowRequest,\n ): Promise<Layer1GasFeeFlowResponse> {\n try {\n const { provider, transactionMeta } = request;\n\n const contract = this.#getGasPriceOracleContract(\n provider,\n transactionMeta.chainId,\n );\n\n const oracleFee = await this.#getOracleLayer1GasFee(\n contract,\n transactionMeta,\n );\n const transformedFee = await this.transformOracleFee(oracleFee, request);\n const operatorFee = await this.#getOperatorLayer1GasFee(\n contract,\n transactionMeta,\n );\n\n return {\n layer1Fee: add0x(\n padHexToEvenLength(transformedFee.add(operatorFee).toString(16)),\n ),\n };\n } catch (error) {\n log('Failed to get oracle layer 1 gas fee', error);\n throw new Error(`Failed to get oracle layer 1 gas fee`);\n }\n }\n\n async #getOracleLayer1GasFee(\n contract: Contract,\n transactionMeta: TransactionMeta,\n ): Promise<BN> {\n const serializedTransaction = this.#buildUnserializedTransaction(\n transactionMeta,\n this.shouldSignTransaction(),\n ).serialize();\n\n const result = await contract.getL1Fee(serializedTransaction);\n\n if (result === undefined) {\n throw new Error('No value returned from oracle contract');\n }\n\n return toBN(result);\n }\n\n async #getOperatorLayer1GasFee(\n contract: Contract,\n transactionMeta: TransactionMeta,\n ): Promise<BN> {\n const { gasUsed } = transactionMeta;\n\n if (!gasUsed) {\n return ZERO;\n }\n\n try {\n const result = await contract.getOperatorFee(gasUsed);\n\n if (result === undefined) {\n return ZERO;\n }\n\n return toBN(result);\n } catch (error) {\n log('Failed to get operator layer 1 gas fee', error);\n return ZERO;\n }\n }\n\n #buildUnserializedTransaction(\n transactionMeta: TransactionMeta,\n sign: boolean,\n ): ReturnType<typeof prepareTransaction> {\n const txParams = this.#buildTransactionParams(transactionMeta);\n const { chainId } = transactionMeta;\n\n let unserializedTransaction = prepareTransaction(chainId, txParams);\n\n if (sign) {\n // eslint-disable-next-line no-restricted-globals\n const keyBuffer = Buffer.from(DUMMY_KEY, 'hex');\n const keyBytes = Uint8Array.from(keyBuffer);\n unserializedTransaction = unserializedTransaction.sign(keyBytes);\n }\n\n return unserializedTransaction;\n }\n\n #buildTransactionParams(\n transactionMeta: TransactionMeta,\n ): TransactionMeta['txParams'] {\n return {\n ...transactionMeta.txParams,\n gasLimit: transactionMeta.txParams.gas,\n };\n }\n\n #getGasPriceOracleContract(\n provider: Layer1GasFeeFlowRequest['provider'],\n chainId: Hex,\n ): Contract {\n return new Contract(\n this.getOracleAddressForChain(chainId),\n GAS_PRICE_ORACLE_ABI,\n // Network controller provider type is incompatible with ethers provider\n new Web3Provider(provider as unknown as ExternalProvider),\n );\n }\n}\n"]}
1
+ {"version":3,"file":"OracleLayer1GasFeeFlow.mjs","sourceRoot":"","sources":["../../src/gas-flows/OracleLayer1GasFeeFlow.ts"],"names":[],"mappings":"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","sourcesContent":["import { Contract } from '@ethersproject/contracts';\nimport { Web3Provider } from '@ethersproject/providers';\nimport type { ExternalProvider } from '@ethersproject/providers';\nimport type { Hex } from '@metamask/utils';\nimport { add0x, createModuleLogger } from '@metamask/utils';\nimport BN from 'bn.js';\n\nimport { projectLogger } from '../logger';\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type {\n Layer1GasFeeFlow,\n Layer1GasFeeFlowRequest,\n Layer1GasFeeFlowResponse,\n TransactionMeta,\n} from '../types';\nimport { prepareTransaction } from '../utils/prepare';\nimport { padHexToEvenLength, toBN } from '../utils/utils';\n\nconst log = createModuleLogger(projectLogger, 'oracle-layer1-gas-fee-flow');\n\nconst ZERO = new BN(0);\n\nconst DUMMY_KEY =\n 'abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789';\n\nconst GAS_PRICE_ORACLE_ABI = [\n {\n inputs: [\n {\n internalType: 'bytes',\n name: '_data',\n type: 'bytes',\n },\n ],\n name: 'getL1Fee',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n // only available post Isthmus\n {\n inputs: [\n {\n internalType: 'uint256',\n name: '_gasUsed',\n type: 'uint256',\n },\n ],\n name: 'getOperatorFee',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n];\n\n// Default OP Stack gas price oracle address used across supported networks\nconst DEFAULT_GAS_PRICE_ORACLE_ADDRESS =\n '0x420000000000000000000000000000000000000F' as Hex;\n\n/**\n * Layer 1 gas fee flow that obtains gas fee estimate using an oracle smart contract.\n */\nexport abstract class OracleLayer1GasFeeFlow implements Layer1GasFeeFlow {\n /**\n * Resolves the oracle address for the given chain. Subclasses can override\n * this method to provide chain-specific oracle addresses. By default, this\n * returns the standard OP Stack gas price oracle address.\n *\n * @param _chainId - The chain ID to resolve the oracle address for.\n * @returns The oracle address for the given chain.\n */\n protected getOracleAddressForChain(_chainId: Hex): Hex {\n return DEFAULT_GAS_PRICE_ORACLE_ADDRESS;\n }\n\n /**\n * Whether to sign the transaction with a dummy key prior to calling the\n * oracle contract. Some oracle contracts require a signed payload even for\n * read-only methods.\n *\n * Subclasses can override to enable signing when needed. Defaults to false.\n *\n * @returns Whether the transaction should be signed prior to the oracle call.\n */\n protected shouldSignTransaction(): boolean {\n return false;\n }\n\n abstract matchesTransaction({\n transactionMeta,\n messenger,\n }: {\n transactionMeta: TransactionMeta;\n messenger: TransactionControllerMessenger;\n }): Promise<boolean>;\n\n /**\n * Transforms the raw oracle L1 fee before it is combined with the operator\n * fee. Subclasses can override this to apply chain-specific conversions\n * (e.g. currency conversion via an on-chain exchange rate).\n *\n * Defaults to returning the fee unchanged.\n *\n * @param oracleFee - The raw L1 fee returned by the oracle contract.\n * @param _request - The original fee flow request (provider + transaction).\n * @returns The transformed fee.\n */\n protected async transformOracleFee(\n oracleFee: BN,\n _request: Layer1GasFeeFlowRequest,\n ): Promise<BN> {\n return oracleFee;\n }\n\n async getLayer1Fee(\n request: Layer1GasFeeFlowRequest,\n ): Promise<Layer1GasFeeFlowResponse> {\n try {\n const { provider, transactionMeta } = request;\n\n const contract = this.#getGasPriceOracleContract(\n provider,\n transactionMeta.chainId,\n );\n\n const oracleFee = await this.#getOracleLayer1GasFee(\n contract,\n transactionMeta,\n );\n const transformedFee = await this.transformOracleFee(oracleFee, request);\n const operatorFee = await this.#getOperatorLayer1GasFee(\n contract,\n transactionMeta,\n );\n\n return {\n layer1Fee: add0x(\n padHexToEvenLength(transformedFee.add(operatorFee).toString(16)),\n ),\n };\n } catch (error) {\n log('Failed to get oracle layer 1 gas fee', error);\n throw new Error(`Failed to get oracle layer 1 gas fee`);\n }\n }\n\n async #getOracleLayer1GasFee(\n contract: Contract,\n transactionMeta: TransactionMeta,\n ): Promise<BN> {\n const serializedTransaction = this.#buildUnserializedTransaction(\n transactionMeta,\n this.shouldSignTransaction(),\n ).serialize();\n\n const result = await contract.getL1Fee(serializedTransaction);\n\n if (result === undefined) {\n throw new Error('No value returned from oracle contract');\n }\n\n return toBN(result);\n }\n\n /**\n * Returns the gas value to pass to the operator-fee oracle, or undefined\n * to skip the operator-fee call entirely. Defaults to the simulated\n * `gasUsed` on the transaction. Subclasses can override to supply a\n * fallback (e.g. estimated gas limit) when `gasUsed` is unavailable.\n *\n * @param transactionMeta - The transaction metadata.\n * @returns The gas value, or undefined to skip the operator-fee call.\n */\n protected getOperatorFeeGas(\n transactionMeta: TransactionMeta,\n ): string | undefined {\n return transactionMeta.gasUsed;\n }\n\n async #getOperatorLayer1GasFee(\n contract: Contract,\n transactionMeta: TransactionMeta,\n ): Promise<BN> {\n const gas = this.getOperatorFeeGas(transactionMeta);\n\n if (!gas) {\n return ZERO;\n }\n\n try {\n const result = await contract.getOperatorFee(gas);\n\n if (result === undefined) {\n return ZERO;\n }\n\n return toBN(result);\n } catch (error) {\n log('Failed to get operator layer 1 gas fee', error);\n return ZERO;\n }\n }\n\n #buildUnserializedTransaction(\n transactionMeta: TransactionMeta,\n sign: boolean,\n ): ReturnType<typeof prepareTransaction> {\n const txParams = this.#buildTransactionParams(transactionMeta);\n const { chainId } = transactionMeta;\n\n let unserializedTransaction = prepareTransaction(chainId, txParams);\n\n if (sign) {\n // eslint-disable-next-line no-restricted-globals\n const keyBuffer = Buffer.from(DUMMY_KEY, 'hex');\n const keyBytes = Uint8Array.from(keyBuffer);\n unserializedTransaction = unserializedTransaction.sign(keyBytes);\n }\n\n return unserializedTransaction;\n }\n\n #buildTransactionParams(\n transactionMeta: TransactionMeta,\n ): TransactionMeta['txParams'] {\n return {\n ...transactionMeta.txParams,\n gasLimit: transactionMeta.txParams.gas,\n };\n }\n\n #getGasPriceOracleContract(\n provider: Layer1GasFeeFlowRequest['provider'],\n chainId: Hex,\n ): Contract {\n return new Contract(\n this.getOracleAddressForChain(chainId),\n GAS_PRICE_ORACLE_ABI,\n // Network controller provider type is incompatible with ethers provider\n new Web3Provider(provider as unknown as ExternalProvider),\n );\n }\n}\n"]}
@@ -13,7 +13,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
13
13
  var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
15
  };
16
- var _PendingTransactionTracker_instances, _PendingTransactionTracker_beforeCheckPendingTransaction, _PendingTransactionTracker_droppedBlockCountByHash, _PendingTransactionTracker_isTimeoutEnabled, _PendingTransactionTracker_getGlobalLock, _PendingTransactionTracker_chainId, _PendingTransactionTracker_networkClientId, _PendingTransactionTracker_getTransactions, _PendingTransactionTracker_isResubmitEnabled, _PendingTransactionTracker_lastSeenTimestampByHash, _PendingTransactionTracker_listener, _PendingTransactionTracker_log, _PendingTransactionTracker_messenger, _PendingTransactionTracker_publishTransaction, _PendingTransactionTracker_running, _PendingTransactionTracker_transactionPoller, _PendingTransactionTracker_transactionToForcePoll, _PendingTransactionTracker_start, _PendingTransactionTracker_onLatestBlock, _PendingTransactionTracker_checkTransactions, _PendingTransactionTracker_resubmitTransactions, _PendingTransactionTracker_isKnownTransactionError, _PendingTransactionTracker_resubmitTransaction, _PendingTransactionTracker_isResubmitDue, _PendingTransactionTracker_cleanTransaction, _PendingTransactionTracker_checkTransaction, _PendingTransactionTracker_onTransactionConfirmed, _PendingTransactionTracker_isTransactionTimeout, _PendingTransactionTracker_isTransactionDropped, _PendingTransactionTracker_isNonceTaken, _PendingTransactionTracker_getPendingTransactions, _PendingTransactionTracker_warnTransaction, _PendingTransactionTracker_failTransaction, _PendingTransactionTracker_dropTransaction, _PendingTransactionTracker_updateTransaction, _PendingTransactionTracker_getTransactionReceipt, _PendingTransactionTracker_getTransactionByHash, _PendingTransactionTracker_getBlockByHash, _PendingTransactionTracker_getNetworkTransactionCount, _PendingTransactionTracker_getChainTransactions, _PendingTransactionTracker_getNetworkClientTransactions;
16
+ var _PendingTransactionTracker_instances, _PendingTransactionTracker_beforeCheckPendingTransaction, _PendingTransactionTracker_droppedBlockCountByHash, _PendingTransactionTracker_isTimeoutEnabled, _PendingTransactionTracker_getGlobalLock, _PendingTransactionTracker_chainId, _PendingTransactionTracker_networkClientId, _PendingTransactionTracker_getTransactions, _PendingTransactionTracker_lastSeenTimestampByHash, _PendingTransactionTracker_listener, _PendingTransactionTracker_log, _PendingTransactionTracker_messenger, _PendingTransactionTracker_running, _PendingTransactionTracker_transactionPoller, _PendingTransactionTracker_transactionToForcePoll, _PendingTransactionTracker_start, _PendingTransactionTracker_onLatestBlock, _PendingTransactionTracker_checkTransactions, _PendingTransactionTracker_cleanTransaction, _PendingTransactionTracker_checkTransaction, _PendingTransactionTracker_onTransactionConfirmed, _PendingTransactionTracker_isTransactionTimeout, _PendingTransactionTracker_isTransactionDropped, _PendingTransactionTracker_isNonceTaken, _PendingTransactionTracker_getPendingTransactions, _PendingTransactionTracker_warnTransaction, _PendingTransactionTracker_failTransaction, _PendingTransactionTracker_dropTransaction, _PendingTransactionTracker_updateTransaction, _PendingTransactionTracker_getTransactionReceipt, _PendingTransactionTracker_getTransactionByHash, _PendingTransactionTracker_getBlockByHash, _PendingTransactionTracker_getNetworkTransactionCount, _PendingTransactionTracker_getChainTransactions, _PendingTransactionTracker_getNetworkClientTransactions;
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.PendingTransactionTracker = void 0;
19
19
  // This package purposefully relies on Node's EventEmitter module.
@@ -33,18 +33,9 @@ const TransactionPoller_1 = require("./TransactionPoller.cjs");
33
33
  const DROPPED_BLOCK_COUNT = 3;
34
34
  const RECEIPT_STATUS_SUCCESS = '0x1';
35
35
  const RECEIPT_STATUS_FAILURE = '0x0';
36
- const MAX_RETRY_BLOCK_DISTANCE = 50;
37
- const KNOWN_TRANSACTION_ERRORS = [
38
- 'replacement transaction underpriced',
39
- 'known transaction',
40
- 'gas price too low to replace',
41
- 'transaction with the same hash was already imported',
42
- 'gateway timeout',
43
- 'nonce too low',
44
- ];
45
36
  const log = (0, logger_1.createModuleLogger)(logger_1.projectLogger, 'pending-transactions');
46
37
  class PendingTransactionTracker {
47
- constructor({ blockTracker, getGlobalLock, getTransactions, isTimeoutEnabled, hooks, isResubmitEnabled, messenger, networkClientId, publishTransaction, }) {
38
+ constructor({ blockTracker, getGlobalLock, getTransactions, isTimeoutEnabled, hooks, messenger, networkClientId, }) {
48
39
  _PendingTransactionTracker_instances.add(this);
49
40
  _PendingTransactionTracker_beforeCheckPendingTransaction.set(this, void 0);
50
41
  _PendingTransactionTracker_droppedBlockCountByHash.set(this, void 0);
@@ -53,14 +44,12 @@ class PendingTransactionTracker {
53
44
  _PendingTransactionTracker_chainId.set(this, void 0);
54
45
  _PendingTransactionTracker_networkClientId.set(this, void 0);
55
46
  _PendingTransactionTracker_getTransactions.set(this, void 0);
56
- _PendingTransactionTracker_isResubmitEnabled.set(this, void 0);
57
47
  _PendingTransactionTracker_lastSeenTimestampByHash.set(this, void 0);
58
48
  // TODO: Replace `any` with type
59
49
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
60
50
  _PendingTransactionTracker_listener.set(this, void 0);
61
51
  _PendingTransactionTracker_log.set(this, void 0);
62
52
  _PendingTransactionTracker_messenger.set(this, void 0);
63
- _PendingTransactionTracker_publishTransaction.set(this, void 0);
64
53
  _PendingTransactionTracker_running.set(this, void 0);
65
54
  _PendingTransactionTracker_transactionPoller.set(this, void 0);
66
55
  _PendingTransactionTracker_transactionToForcePoll.set(this, void 0);
@@ -80,11 +69,9 @@ class PendingTransactionTracker {
80
69
  __classPrivateFieldSet(this, _PendingTransactionTracker_getGlobalLock, getGlobalLock, "f");
81
70
  __classPrivateFieldSet(this, _PendingTransactionTracker_networkClientId, networkClientId, "f");
82
71
  __classPrivateFieldSet(this, _PendingTransactionTracker_getTransactions, getTransactions, "f");
83
- __classPrivateFieldSet(this, _PendingTransactionTracker_isResubmitEnabled, isResubmitEnabled ?? (() => true), "f");
84
72
  __classPrivateFieldSet(this, _PendingTransactionTracker_lastSeenTimestampByHash, new Map(), "f");
85
73
  __classPrivateFieldSet(this, _PendingTransactionTracker_listener, __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_onLatestBlock).bind(this), "f");
86
74
  __classPrivateFieldSet(this, _PendingTransactionTracker_messenger, messenger, "f");
87
- __classPrivateFieldSet(this, _PendingTransactionTracker_publishTransaction, publishTransaction, "f");
88
75
  __classPrivateFieldSet(this, _PendingTransactionTracker_running, false, "f");
89
76
  __classPrivateFieldSet(this, _PendingTransactionTracker_transactionToForcePoll, undefined, "f");
90
77
  __classPrivateFieldSet(this, _PendingTransactionTracker_transactionPoller, new TransactionPoller_1.TransactionPoller({
@@ -141,7 +128,7 @@ class PendingTransactionTracker {
141
128
  }
142
129
  }
143
130
  exports.PendingTransactionTracker = PendingTransactionTracker;
144
- _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _PendingTransactionTracker_droppedBlockCountByHash = new WeakMap(), _PendingTransactionTracker_isTimeoutEnabled = new WeakMap(), _PendingTransactionTracker_getGlobalLock = new WeakMap(), _PendingTransactionTracker_chainId = new WeakMap(), _PendingTransactionTracker_networkClientId = new WeakMap(), _PendingTransactionTracker_getTransactions = new WeakMap(), _PendingTransactionTracker_isResubmitEnabled = new WeakMap(), _PendingTransactionTracker_lastSeenTimestampByHash = new WeakMap(), _PendingTransactionTracker_listener = new WeakMap(), _PendingTransactionTracker_log = new WeakMap(), _PendingTransactionTracker_messenger = new WeakMap(), _PendingTransactionTracker_publishTransaction = new WeakMap(), _PendingTransactionTracker_running = new WeakMap(), _PendingTransactionTracker_transactionPoller = new WeakMap(), _PendingTransactionTracker_transactionToForcePoll = new WeakMap(), _PendingTransactionTracker_instances = new WeakSet(), _PendingTransactionTracker_start = function _PendingTransactionTracker_start(pendingTransactions) {
131
+ _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _PendingTransactionTracker_droppedBlockCountByHash = new WeakMap(), _PendingTransactionTracker_isTimeoutEnabled = new WeakMap(), _PendingTransactionTracker_getGlobalLock = new WeakMap(), _PendingTransactionTracker_chainId = new WeakMap(), _PendingTransactionTracker_networkClientId = new WeakMap(), _PendingTransactionTracker_getTransactions = new WeakMap(), _PendingTransactionTracker_lastSeenTimestampByHash = new WeakMap(), _PendingTransactionTracker_listener = new WeakMap(), _PendingTransactionTracker_log = new WeakMap(), _PendingTransactionTracker_messenger = new WeakMap(), _PendingTransactionTracker_running = new WeakMap(), _PendingTransactionTracker_transactionPoller = new WeakMap(), _PendingTransactionTracker_transactionToForcePoll = new WeakMap(), _PendingTransactionTracker_instances = new WeakSet(), _PendingTransactionTracker_start = function _PendingTransactionTracker_start(pendingTransactions) {
145
132
  __classPrivateFieldGet(this, _PendingTransactionTracker_transactionPoller, "f").setPendingTransactions(pendingTransactions);
146
133
  if (__classPrivateFieldGet(this, _PendingTransactionTracker_running, "f")) {
147
134
  return;
@@ -149,7 +136,7 @@ _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _Pendi
149
136
  __classPrivateFieldGet(this, _PendingTransactionTracker_transactionPoller, "f").start(__classPrivateFieldGet(this, _PendingTransactionTracker_listener, "f"));
150
137
  __classPrivateFieldSet(this, _PendingTransactionTracker_running, true, "f");
151
138
  __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Started polling');
152
- }, _PendingTransactionTracker_onLatestBlock = async function _PendingTransactionTracker_onLatestBlock(latestBlockNumber) {
139
+ }, _PendingTransactionTracker_onLatestBlock = async function _PendingTransactionTracker_onLatestBlock(_latestBlockNumber) {
153
140
  const releaseLock = await __classPrivateFieldGet(this, _PendingTransactionTracker_getGlobalLock, "f").call(this);
154
141
  try {
155
142
  await __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_checkTransactions).call(this);
@@ -161,13 +148,6 @@ _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _Pendi
161
148
  finally {
162
149
  releaseLock();
163
150
  }
164
- try {
165
- await __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_resubmitTransactions).call(this, latestBlockNumber);
166
- }
167
- catch (error) {
168
- /* istanbul ignore next */
169
- __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Failed to resubmit transactions', error);
170
- }
171
151
  }, _PendingTransactionTracker_checkTransactions = async function _PendingTransactionTracker_checkTransactions() {
172
152
  __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Checking transactions');
173
153
  const pendingTransactions = [
@@ -183,64 +163,6 @@ _PendingTransactionTracker_beforeCheckPendingTransaction = new WeakMap(), _Pendi
183
163
  ids: pendingTransactions.map((tx) => tx.id),
184
164
  });
185
165
  await Promise.all(pendingTransactions.map((tx) => __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_checkTransaction).call(this, tx)));
186
- }, _PendingTransactionTracker_resubmitTransactions = async function _PendingTransactionTracker_resubmitTransactions(latestBlockNumber) {
187
- if (!__classPrivateFieldGet(this, _PendingTransactionTracker_isResubmitEnabled, "f").call(this) || !__classPrivateFieldGet(this, _PendingTransactionTracker_running, "f")) {
188
- return;
189
- }
190
- __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Resubmitting transactions');
191
- const pendingTransactions = __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_getPendingTransactions).call(this);
192
- if (!pendingTransactions.length) {
193
- __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'No pending transactions to resubmit');
194
- return;
195
- }
196
- __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Found pending transactions to resubmit', {
197
- count: pendingTransactions.length,
198
- ids: pendingTransactions.map((tx) => tx.id),
199
- });
200
- for (const txMeta of pendingTransactions) {
201
- try {
202
- await __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_resubmitTransaction).call(this, txMeta, latestBlockNumber);
203
- // TODO: Replace `any` with type
204
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
205
- }
206
- catch (error) {
207
- /* istanbul ignore next */
208
- const errorMessage = error.value?.message?.toLowerCase() ??
209
- error.message?.toLowerCase() ??
210
- String(error);
211
- if (__classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_isKnownTransactionError).call(this, errorMessage)) {
212
- __classPrivateFieldGet(this, _PendingTransactionTracker_log, "f").call(this, 'Ignoring known transaction error', errorMessage);
213
- continue;
214
- }
215
- __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_warnTransaction).call(this, txMeta, error.message, 'There was an error when resubmitting this transaction.');
216
- }
217
- }
218
- }, _PendingTransactionTracker_isKnownTransactionError = function _PendingTransactionTracker_isKnownTransactionError(errorMessage) {
219
- return KNOWN_TRANSACTION_ERRORS.some((knownError) => errorMessage.includes(knownError));
220
- }, _PendingTransactionTracker_resubmitTransaction = async function _PendingTransactionTracker_resubmitTransaction(txMeta, latestBlockNumber) {
221
- if (!__classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_isResubmitDue).call(this, txMeta, latestBlockNumber)) {
222
- return;
223
- }
224
- if (!(await __classPrivateFieldGet(this, _PendingTransactionTracker_beforeCheckPendingTransaction, "f").call(this, txMeta))) {
225
- return;
226
- }
227
- await __classPrivateFieldGet(this, _PendingTransactionTracker_publishTransaction, "f").call(this, txMeta);
228
- const retryCount = (txMeta.retryCount ?? 0) + 1;
229
- __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_updateTransaction).call(this, (0, lodash_1.merge)({}, txMeta, { retryCount }), 'PendingTransactionTracker:transaction-retry - Retry count increased');
230
- }, _PendingTransactionTracker_isResubmitDue = function _PendingTransactionTracker_isResubmitDue(txMeta, latestBlockNumber) {
231
- const txMetaWithFirstRetryBlockNumber = (0, lodash_1.cloneDeep)(txMeta);
232
- if (!txMetaWithFirstRetryBlockNumber.firstRetryBlockNumber) {
233
- txMetaWithFirstRetryBlockNumber.firstRetryBlockNumber = latestBlockNumber;
234
- __classPrivateFieldGet(this, _PendingTransactionTracker_instances, "m", _PendingTransactionTracker_updateTransaction).call(this, txMetaWithFirstRetryBlockNumber, 'PendingTransactionTracker:#isResubmitDue - First retry block number set');
235
- }
236
- const { firstRetryBlockNumber } = txMetaWithFirstRetryBlockNumber;
237
- const blocksSinceFirstRetry = Number.parseInt(latestBlockNumber, 16) -
238
- Number.parseInt(firstRetryBlockNumber, 16);
239
- const retryCount = txMeta.retryCount ?? 0;
240
- // Exponential backoff to limit retries at publishing
241
- // Capped at ~15 minutes between retries
242
- const requiredBlocksSinceFirstRetry = Math.min(MAX_RETRY_BLOCK_DISTANCE, Math.pow(2, retryCount));
243
- return blocksSinceFirstRetry >= requiredBlocksSinceFirstRetry;
244
166
  }, _PendingTransactionTracker_cleanTransaction = function _PendingTransactionTracker_cleanTransaction(txMeta) {
245
167
  const { hash, id } = txMeta;
246
168
  if (__classPrivateFieldGet(this, _PendingTransactionTracker_transactionToForcePoll, "f")?.id === id) {