@metamask-previews/transaction-pay-controller 30.3.3-preview-543acb9 → 30.3.3-preview-fbb37663c

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
@@ -7,11 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- ### Added
10
+ ### Changed
11
11
 
12
- - Support fiat payments for `membershipSubscription` transactions ([#11256](https://github.com/MetaMask/core/pull/11256))
13
- - Add `membershipSubscription` to the default fiat-enabled transaction types and fiat asset map.
14
- - Treat `membershipSubscription` as a Money Account deposit, so it uses the direct mUSD on-ramp when `directMoneyMusdEnabled` is set, and CHOMP vault recovery on the second leg.
12
+ - Bump `@metamask/assets-controller` from `^20.1.0` to `^20.2.0` ([#11255](https://github.com/MetaMask/core/pull/11255))
15
13
 
16
14
  ## [30.3.3]
17
15
 
@@ -7,11 +7,6 @@ export type TransactionPayFiatAsset = {
7
7
  };
8
8
  export declare const ETH_MAINNET_FIAT_ASSET: TransactionPayFiatAsset;
9
9
  export declare const FIAT_ASSET_ID_BY_TX_TYPE: Partial<Record<TransactionType, TransactionPayFiatAsset>>;
10
- /**
11
- * Transaction types that deposit into the Money Account vault, so share the
12
- * Money Account fiat handling (direct mUSD on-ramp and CHOMP recovery).
13
- */
14
- export declare const MONEY_ACCOUNT_DEPOSIT_TYPES: TransactionType[];
15
10
  export declare const FIAT_ENABLED_TYPES: TransactionType[];
16
11
  /** Fiat asset descriptor for mUSD on Monad. */
17
12
  export declare const MUSD_MONAD_FIAT_ASSET: TransactionPayFiatAsset;
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/strategy/fiat/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAW3C,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAE3C,MAAM,MAAM,uBAAuB,GAAG;IACpC,OAAO,EAAE,GAAG,CAAC;IACb,OAAO,EAAE,GAAG,CAAC;CACd,CAAC;AAYF,eAAO,MAAM,sBAAsB,EAAE,uBAGpC,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,OAAO,CAC5C,MAAM,CAAC,eAAe,EAAE,uBAAuB,CAAC,CAMjD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,2BAA2B,EAAE,eAAe,EAGxD,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eAAe,EAI/C,CAAC;AAEF,+CAA+C;AAC/C,eAAO,MAAM,qBAAqB,EAAE,uBAGnC,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/strategy/fiat/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAW3C,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAE3C,MAAM,MAAM,uBAAuB,GAAG;IACpC,OAAO,EAAE,GAAG,CAAC;IACb,OAAO,EAAE,GAAG,CAAC;CACd,CAAC;AAYF,eAAO,MAAM,sBAAsB,EAAE,uBAGpC,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,OAAO,CAC5C,MAAM,CAAC,eAAe,EAAE,uBAAuB,CAAC,CAKjD,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eAAe,EAI/C,CAAC;AAEF,+CAA+C;AAC/C,eAAO,MAAM,qBAAqB,EAAE,uBAGnC,CAAC"}
@@ -14,21 +14,12 @@ export const ETH_MAINNET_FIAT_ASSET = {
14
14
  chainId: CHAIN_ID_MAINNET,
15
15
  };
16
16
  export const FIAT_ASSET_ID_BY_TX_TYPE = {
17
- [TransactionType.membershipSubscription]: ETH_MAINNET_FIAT_ASSET,
18
17
  [TransactionType.moneyAccountDeposit]: ETH_MAINNET_FIAT_ASSET,
19
18
  [TransactionType.perpsDeposit]: ARBITRUM_ETH_FIAT_ASSET,
20
19
  [TransactionType.predictDeposit]: POLYGON_POL_FIAT_ASSET,
21
20
  };
22
- /**
23
- * Transaction types that deposit into the Money Account vault, so share the
24
- * Money Account fiat handling (direct mUSD on-ramp and CHOMP recovery).
25
- */
26
- export const MONEY_ACCOUNT_DEPOSIT_TYPES = [
27
- TransactionType.membershipSubscription,
28
- TransactionType.moneyAccountDeposit,
29
- ];
30
21
  export const FIAT_ENABLED_TYPES = [
31
- ...MONEY_ACCOUNT_DEPOSIT_TYPES,
22
+ TransactionType.moneyAccountDeposit,
32
23
  TransactionType.perpsDeposit,
33
24
  TransactionType.predictDeposit,
34
25
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/strategy/fiat/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAGnE,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAO3C,MAAM,sBAAsB,GAA4B;IACtD,OAAO,EAAE,4CAA4C;IACrD,OAAO,EAAE,gBAAgB;CAC1B,CAAC;AAEF,MAAM,uBAAuB,GAA4B;IACvD,OAAO,EAAE,oBAAoB;IAC7B,OAAO,EAAE,iBAAiB;CAC3B,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAA4B;IAC7D,OAAO,EAAE,oBAAoB;IAC7B,OAAO,EAAE,gBAAgB;CAC1B,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAEjC;IACF,CAAC,eAAe,CAAC,sBAAsB,CAAC,EAAE,sBAAsB;IAChE,CAAC,eAAe,CAAC,mBAAmB,CAAC,EAAE,sBAAsB;IAC7D,CAAC,eAAe,CAAC,YAAY,CAAC,EAAE,uBAAuB;IACvD,CAAC,eAAe,CAAC,cAAc,CAAC,EAAE,sBAAsB;CACzD,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAsB;IAC5D,eAAe,CAAC,sBAAsB;IACtC,eAAe,CAAC,mBAAmB;CACpC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAsB;IACnD,GAAG,2BAA2B;IAC9B,eAAe,CAAC,YAAY;IAC5B,eAAe,CAAC,cAAc;CAC/B,CAAC;AAEF,+CAA+C;AAC/C,MAAM,CAAC,MAAM,qBAAqB,GAA4B;IAC5D,OAAO,EAAE,kBAAkB;IAC3B,OAAO,EAAE,cAAc;CACxB,CAAC","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport {\n CHAIN_ID_ARBITRUM,\n CHAIN_ID_MAINNET,\n CHAIN_ID_MONAD,\n CHAIN_ID_POLYGON,\n MUSD_MONAD_ADDRESS,\n NATIVE_TOKEN_ADDRESS,\n} from '../../constants.js';\n\nexport const DEFAULT_FIAT_CURRENCY = 'USD';\n\nexport type TransactionPayFiatAsset = {\n address: Hex;\n chainId: Hex;\n};\n\nconst POLYGON_POL_FIAT_ASSET: TransactionPayFiatAsset = {\n address: '0x0000000000000000000000000000000000001010',\n chainId: CHAIN_ID_POLYGON,\n};\n\nconst ARBITRUM_ETH_FIAT_ASSET: TransactionPayFiatAsset = {\n address: NATIVE_TOKEN_ADDRESS,\n chainId: CHAIN_ID_ARBITRUM,\n};\n\nexport const ETH_MAINNET_FIAT_ASSET: TransactionPayFiatAsset = {\n address: NATIVE_TOKEN_ADDRESS,\n chainId: CHAIN_ID_MAINNET,\n};\n\nexport const FIAT_ASSET_ID_BY_TX_TYPE: Partial<\n Record<TransactionType, TransactionPayFiatAsset>\n> = {\n [TransactionType.membershipSubscription]: ETH_MAINNET_FIAT_ASSET,\n [TransactionType.moneyAccountDeposit]: ETH_MAINNET_FIAT_ASSET,\n [TransactionType.perpsDeposit]: ARBITRUM_ETH_FIAT_ASSET,\n [TransactionType.predictDeposit]: POLYGON_POL_FIAT_ASSET,\n};\n\n/**\n * Transaction types that deposit into the Money Account vault, so share the\n * Money Account fiat handling (direct mUSD on-ramp and CHOMP recovery).\n */\nexport const MONEY_ACCOUNT_DEPOSIT_TYPES: TransactionType[] = [\n TransactionType.membershipSubscription,\n TransactionType.moneyAccountDeposit,\n];\n\nexport const FIAT_ENABLED_TYPES: TransactionType[] = [\n ...MONEY_ACCOUNT_DEPOSIT_TYPES,\n TransactionType.perpsDeposit,\n TransactionType.predictDeposit,\n];\n\n/** Fiat asset descriptor for mUSD on Monad. */\nexport const MUSD_MONAD_FIAT_ASSET: TransactionPayFiatAsset = {\n address: MUSD_MONAD_ADDRESS,\n chainId: CHAIN_ID_MONAD,\n};\n"]}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/strategy/fiat/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAGnE,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAO3C,MAAM,sBAAsB,GAA4B;IACtD,OAAO,EAAE,4CAA4C;IACrD,OAAO,EAAE,gBAAgB;CAC1B,CAAC;AAEF,MAAM,uBAAuB,GAA4B;IACvD,OAAO,EAAE,oBAAoB;IAC7B,OAAO,EAAE,iBAAiB;CAC3B,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAA4B;IAC7D,OAAO,EAAE,oBAAoB;IAC7B,OAAO,EAAE,gBAAgB;CAC1B,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAEjC;IACF,CAAC,eAAe,CAAC,mBAAmB,CAAC,EAAE,sBAAsB;IAC7D,CAAC,eAAe,CAAC,YAAY,CAAC,EAAE,uBAAuB;IACvD,CAAC,eAAe,CAAC,cAAc,CAAC,EAAE,sBAAsB;CACzD,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAsB;IACnD,eAAe,CAAC,mBAAmB;IACnC,eAAe,CAAC,YAAY;IAC5B,eAAe,CAAC,cAAc;CAC/B,CAAC;AAEF,+CAA+C;AAC/C,MAAM,CAAC,MAAM,qBAAqB,GAA4B;IAC5D,OAAO,EAAE,kBAAkB;IAC3B,OAAO,EAAE,cAAc;CACxB,CAAC","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport {\n CHAIN_ID_ARBITRUM,\n CHAIN_ID_MAINNET,\n CHAIN_ID_MONAD,\n CHAIN_ID_POLYGON,\n MUSD_MONAD_ADDRESS,\n NATIVE_TOKEN_ADDRESS,\n} from '../../constants.js';\n\nexport const DEFAULT_FIAT_CURRENCY = 'USD';\n\nexport type TransactionPayFiatAsset = {\n address: Hex;\n chainId: Hex;\n};\n\nconst POLYGON_POL_FIAT_ASSET: TransactionPayFiatAsset = {\n address: '0x0000000000000000000000000000000000001010',\n chainId: CHAIN_ID_POLYGON,\n};\n\nconst ARBITRUM_ETH_FIAT_ASSET: TransactionPayFiatAsset = {\n address: NATIVE_TOKEN_ADDRESS,\n chainId: CHAIN_ID_ARBITRUM,\n};\n\nexport const ETH_MAINNET_FIAT_ASSET: TransactionPayFiatAsset = {\n address: NATIVE_TOKEN_ADDRESS,\n chainId: CHAIN_ID_MAINNET,\n};\n\nexport const FIAT_ASSET_ID_BY_TX_TYPE: Partial<\n Record<TransactionType, TransactionPayFiatAsset>\n> = {\n [TransactionType.moneyAccountDeposit]: ETH_MAINNET_FIAT_ASSET,\n [TransactionType.perpsDeposit]: ARBITRUM_ETH_FIAT_ASSET,\n [TransactionType.predictDeposit]: POLYGON_POL_FIAT_ASSET,\n};\n\nexport const FIAT_ENABLED_TYPES: TransactionType[] = [\n TransactionType.moneyAccountDeposit,\n TransactionType.perpsDeposit,\n TransactionType.predictDeposit,\n];\n\n/** Fiat asset descriptor for mUSD on Monad. */\nexport const MUSD_MONAD_FIAT_ASSET: TransactionPayFiatAsset = {\n address: MUSD_MONAD_ADDRESS,\n chainId: CHAIN_ID_MONAD,\n};\n"]}
@@ -22,9 +22,8 @@ export declare function resolveTransactionType(transaction: TransactionMeta, ena
22
22
  /**
23
23
  * Checks whether a transaction is a Money Account deposit.
24
24
  *
25
- * Matches any of `MONEY_ACCOUNT_DEPOSIT_TYPES` (`moneyAccountDeposit` and
26
- * `membershipSubscription`), either as the transaction type or as a nested
27
- * call in an EIP-7702 batch.
25
+ * Handles both direct `moneyAccountDeposit` transactions and EIP-7702
26
+ * batch transactions that contain a `moneyAccountDeposit` nested call.
28
27
  * Uses {@link resolveTransactionType} with `FIAT_ENABLED_TYPES` to
29
28
  * correctly skip non-deposit nested types (e.g. `tokenMethodApprove`).
30
29
  *
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/strategy/fiat/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,IAAI,UAAU,EACnB,UAAU,EACV,wBAAwB,EACzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAK3C,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,gBAAgB,CAAC;AAOxE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAS9D,wBAAgB,6BAA6B,CAC3C,WAAW,EAAE,eAAe,EAC5B,SAAS,EAAE,iCAAiC,GAC3C,uBAAuB,CAKzB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,eAAe,EAC5B,YAAY,EAAE,eAAe,EAAE,GAC9B,eAAe,GAAG,SAAS,CAU7B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gCAAgC,CAC9C,WAAW,EAAE,eAAe,GAC3B,OAAO,CAIT;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,aAAa,CAAC,EAClC,cAAc,EACd,YAAoE,EACpE,SAAS,EACT,iBAAiB,EACjB,SAAS,EACT,aAAa,GACd,EAAE;IACD,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,uBAAuB,CAAC;IACnC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,iCAAiC,CAAC;IAC7C,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,UAAU,CAAC,CAmBtB;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,aAAa,EACb,WAAW,EACX,aAAa,GACd,EAAE;IACD,aAAa,EAAE,uBAAuB,CAAC;IACvC,WAAW,EAAE,wBAAwB,GAAG,SAAS,CAAC;IAClD,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,IAAI,CAsBP;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,sBAAsB,CAAC,EAC3C,SAAS,EACT,KAAK,EACL,SAAS,EACT,aAAa,GACd,EAAE;IACD,SAAS,EAAE,iCAAiC,CAAC;IAC7C,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,uBAAuB,CAAC;IACnC,aAAa,EAAE,GAAG,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBlB;AAED;;;;;;;GAOG;AACH,wBAAgB,uCAAuC,CAAC,EACtD,YAAY,EACZ,QAAQ,GACT,EAAE;IACD,YAAY,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,MAAM,CAmBT;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,aAAa,GACd,EAAE;IACD,aAAa,EAAE,UAAU,CAAC;IAC1B,cAAc,EAAE,UAAU,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,IAAI,CA2CP;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,GAAG,IAAI,CAYf"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/strategy/fiat/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,IAAI,UAAU,EACnB,UAAU,EACV,wBAAwB,EACzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAK3C,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,gBAAgB,CAAC;AAOxE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAK9D,wBAAgB,6BAA6B,CAC3C,WAAW,EAAE,eAAe,EAC5B,SAAS,EAAE,iCAAiC,GAC3C,uBAAuB,CAKzB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,eAAe,EAC5B,YAAY,EAAE,eAAe,EAAE,GAC9B,eAAe,GAAG,SAAS,CAU7B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gCAAgC,CAC9C,WAAW,EAAE,eAAe,GAC3B,OAAO,CAKT;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,aAAa,CAAC,EAClC,cAAc,EACd,YAAoE,EACpE,SAAS,EACT,iBAAiB,EACjB,SAAS,EACT,aAAa,GACd,EAAE;IACD,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,uBAAuB,CAAC;IACnC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,iCAAiC,CAAC;IAC7C,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,UAAU,CAAC,CAmBtB;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,aAAa,EACb,WAAW,EACX,aAAa,GACd,EAAE;IACD,aAAa,EAAE,uBAAuB,CAAC;IACvC,WAAW,EAAE,wBAAwB,GAAG,SAAS,CAAC;IAClD,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,IAAI,CAsBP;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,sBAAsB,CAAC,EAC3C,SAAS,EACT,KAAK,EACL,SAAS,EACT,aAAa,GACd,EAAE;IACD,SAAS,EAAE,iCAAiC,CAAC;IAC7C,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,uBAAuB,CAAC;IACnC,aAAa,EAAE,GAAG,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBlB;AAED;;;;;;;GAOG;AACH,wBAAgB,uCAAuC,CAAC,EACtD,YAAY,EACZ,QAAQ,GACT,EAAE;IACD,YAAY,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,MAAM,CAmBT;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,aAAa,GACd,EAAE;IACD,aAAa,EAAE,UAAU,CAAC;IAC1B,cAAc,EAAE,UAAU,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,IAAI,CA2CP;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,GAAG,IAAI,CAYf"}
@@ -5,7 +5,7 @@ import { projectLogger } from '../../logger.js';
5
5
  import { getFiatAssetPerTransactionType, getFiatEnabledTypes, } from '../../utils/feature-flags.js';
6
6
  import { buildCaipAssetType } from '../../utils/token.js';
7
7
  import { getTransferredAmountFromTxHash } from '../../utils/transaction.js';
8
- import { DEFAULT_FIAT_CURRENCY, FIAT_ENABLED_TYPES, MONEY_ACCOUNT_DEPOSIT_TYPES, } from './constants.js';
8
+ import { DEFAULT_FIAT_CURRENCY, FIAT_ENABLED_TYPES } from './constants.js';
9
9
  const log = createModuleLogger(projectLogger, 'fiat-utils');
10
10
  export function deriveFiatAssetForFiatPayment(transaction, messenger) {
11
11
  const enabledTypes = getFiatEnabledTypes(messenger);
@@ -34,9 +34,8 @@ export function resolveTransactionType(transaction, enabledTypes) {
34
34
  /**
35
35
  * Checks whether a transaction is a Money Account deposit.
36
36
  *
37
- * Matches any of `MONEY_ACCOUNT_DEPOSIT_TYPES` (`moneyAccountDeposit` and
38
- * `membershipSubscription`), either as the transaction type or as a nested
39
- * call in an EIP-7702 batch.
37
+ * Handles both direct `moneyAccountDeposit` transactions and EIP-7702
38
+ * batch transactions that contain a `moneyAccountDeposit` nested call.
40
39
  * Uses {@link resolveTransactionType} with `FIAT_ENABLED_TYPES` to
41
40
  * correctly skip non-deposit nested types (e.g. `tokenMethodApprove`).
42
41
  *
@@ -44,8 +43,8 @@ export function resolveTransactionType(transaction, enabledTypes) {
44
43
  * @returns `true` if the transaction is a Money Account deposit.
45
44
  */
46
45
  export function isMoneyAccountDepositTransaction(transaction) {
47
- const type = resolveTransactionType(transaction, FIAT_ENABLED_TYPES);
48
- return type !== undefined && MONEY_ACCOUNT_DEPOSIT_TYPES.includes(type);
46
+ return (resolveTransactionType(transaction, FIAT_ENABLED_TYPES) ===
47
+ TransactionType.moneyAccountDeposit);
49
48
  }
50
49
  /**
51
50
  * Fetches the best matching Ramps quote for a fiat asset and payment method,
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/strategy/fiat/utils.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAEnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EACL,8BAA8B,EAC9B,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,8BAA8B,EAAE,MAAM,4BAA4B,CAAC;AAG5E,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,2BAA2B,GAC5B,MAAM,gBAAgB,CAAC;AAExB,MAAM,GAAG,GAAG,kBAAkB,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;AAE5D,MAAM,UAAU,6BAA6B,CAC3C,WAA4B,EAC5B,SAA4C;IAE5C,MAAM,YAAY,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,sBAAsB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAEjE,OAAO,8BAA8B,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,sBAAsB,CACpC,WAA4B,EAC5B,YAA+B;IAE/B,IAAI,WAAW,CAAC,IAAI,KAAK,eAAe,CAAC,KAAK,EAAE,CAAC;QAC/C,OAAO,WAAW,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED,MAAM,UAAU,GAAG,WAAW,CAAC,kBAAkB,EAAE,IAAI,CACrD,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,IAAI,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,CAClD,EAAE,IAAI,CAAC;IAER,OAAO,UAAU,IAAI,WAAW,CAAC,IAAI,CAAC;AACxC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gCAAgC,CAC9C,WAA4B;IAE5B,MAAM,IAAI,GAAG,sBAAsB,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;IAErE,OAAO,IAAI,KAAK,SAAS,IAAI,2BAA2B,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC1E,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAClC,cAAc,EACd,YAAY,GAAG,qDAAqD,EACpE,SAAS,EACT,iBAAiB,EACjB,SAAS,EACT,aAAa,GAQd;IACC,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,kCAAkC,EAAE;QACrE,MAAM,EAAE,cAAc;QACtB,OAAO,EAAE,kBAAkB,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC;QACjE,kBAAkB,EAAE,IAAI;QACxB,IAAI,EAAE,qBAAqB;QAC3B,qBAAqB,EAAE,IAAI;QAC3B,cAAc,EAAE,CAAC,iBAAiB,CAAC;QACnC,gCAAgC,EAAE,IAAI;QACtC,aAAa;KACd,CAAC,CAAC;IAEH,GAAG,CAAC,qBAAqB,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAEzD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,EACjC,aAAa,EACb,WAAW,EACX,aAAa,GAKd;IACC,MAAM,YAAY,GAAG,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IACzD,MAAM,eAAe,GAAG,kBAAkB,CACxC,aAAa,CAAC,OAAO,EACrB,aAAa,CAAC,OAAO,CACtB,CAAC,WAAW,EAAE,CAAC;IAChB,MAAM,eAAe,GAAG,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,MAAM,YAAY,GAAG,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IAEzD,IAAI,YAAY,IAAI,YAAY,KAAK,eAAe,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CACb,wCAAwC,aAAa,IAAI;YACvD,YAAY,eAAe,SAAS,YAAY,EAAE,CACrD,CAAC;IACJ,CAAC;IAED,IAAI,YAAY,IAAI,YAAY,KAAK,eAAe,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CACb,wCAAwC,aAAa,IAAI;YACvD,YAAY,eAAe,SAAS,YAAY,EAAE,CACrD,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,EAC3C,SAAS,EACT,KAAK,EACL,SAAS,EACT,aAAa,GAMd;IACC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,8BAA8B,CAAC;QACzD,SAAS;QACT,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE,SAAS,CAAC,OAAO;QAC1B,YAAY,EAAE,SAAS,CAAC,OAAO;QAC/B,aAAa;KACd,CAAC,CAAC;IAEH,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,2DAA2D,KAAK,CAAC,MAAM,EAAE,CAC1E,CAAC;IACJ,CAAC;IAED,GAAG,CAAC,kDAAkD,EAAE;QACtD,SAAS;QACT,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC,CAAC;IAEH,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,uCAAuC,CAAC,EACtD,YAAY,EACZ,QAAQ,GAIT;IACC,MAAM,gBAAgB,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;IAE7D,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CACb,qCAAqC,MAAM,CAAC,YAAY,CAAC,EAAE,CAC5D,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,gBAAgB;SAC/B,SAAS,CAAC,QAAQ,CAAC;SACnB,aAAa,CAAC,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC;SACtC,OAAO,CAAC,CAAC,CAAC,CAAC;IAEd,IAAI,CAAC,IAAI,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,sBAAsB,CAAC,EACrC,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,aAAa,GAMd;IACC,MAAM,UAAU,GAAG,IAAI,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAC7E,MAAM,WAAW,GAAG,IAAI,SAAS,CAC/B,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC,SAAS,CAC5C,CAAC;IACF,MAAM,WAAW,GAAG,IAAI,SAAS,CAC/B,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAC5C,CAAC;IACF,MAAM,YAAY,GAAG,IAAI,SAAS,CAChC,cAAc,CAAC,OAAO,CAAC,WAAW,CAAC,SAAS,CAC7C,CAAC;IAEF,IACE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;QACjB,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;QAClB,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;QAClB,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,EACnB,CAAC;QACD,OAAO;IACT,CAAC;IAED,MAAM,YAAY,GAAG,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IACvD,MAAM,aAAa,GAAG,YAAY,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAE1D,MAAM,YAAY,GAAG,YAAY;SAC9B,KAAK,CAAC,aAAa,CAAC;SACpB,SAAS,CAAC,YAAY,CAAC;SACvB,YAAY,CAAC,GAAG,CAAC,CAAC;IAErB,GAAG,CAAC,wBAAwB,EAAE;QAC5B,YAAY,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;QACrC,aAAa,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;QACvC,YAAY,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;QACrC,mBAAmB;QACnB,aAAa;KACd,CAAC,CAAC;IAEH,IAAI,YAAY,CAAC,EAAE,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CACb,4CAA4C;YAC1C,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,mBAAmB,OAAO,CACpE,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAA4B;IAE5B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAElD,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,WAAW,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IAC1B,CAAC;IAED,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9C,CAAC","sourcesContent":["import type {\n Quote as RampsQuote,\n RampsOrder,\n RampsOrderCryptoCurrency,\n} from '@metamask/ramps-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { projectLogger } from '../../logger.js';\nimport type { TransactionPayControllerMessenger } from '../../types.js';\nimport {\n getFiatAssetPerTransactionType,\n getFiatEnabledTypes,\n} from '../../utils/feature-flags.js';\nimport { buildCaipAssetType } from '../../utils/token.js';\nimport { getTransferredAmountFromTxHash } from '../../utils/transaction.js';\nimport type { RelayQuote } from '../relay/types.js';\nimport type { TransactionPayFiatAsset } from './constants.js';\nimport {\n DEFAULT_FIAT_CURRENCY,\n FIAT_ENABLED_TYPES,\n MONEY_ACCOUNT_DEPOSIT_TYPES,\n} from './constants.js';\n\nconst log = createModuleLogger(projectLogger, 'fiat-utils');\n\nexport function deriveFiatAssetForFiatPayment(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): TransactionPayFiatAsset {\n const enabledTypes = getFiatEnabledTypes(messenger);\n const txType = resolveTransactionType(transaction, enabledTypes);\n\n return getFiatAssetPerTransactionType(messenger, txType);\n}\n\n/**\n * Resolves the effective transaction type for fiat strategy purposes.\n *\n * For non-batch transactions returns the transaction's own type.\n * For batch transactions returns the first nested transaction type\n * that appears in the enabled types list, or the batch type itself\n * if no nested type matches.\n *\n * @param transaction - The transaction metadata to inspect.\n * @param enabledTypes - Transaction types eligible for fiat payment.\n * @returns The resolved transaction type, or `undefined`.\n */\nexport function resolveTransactionType(\n transaction: TransactionMeta,\n enabledTypes: TransactionType[],\n): TransactionType | undefined {\n if (transaction.type !== TransactionType.batch) {\n return transaction.type;\n }\n\n const nestedType = transaction.nestedTransactions?.find(\n (tx) => tx.type && enabledTypes.includes(tx.type),\n )?.type;\n\n return nestedType ?? transaction.type;\n}\n\n/**\n * Checks whether a transaction is a Money Account deposit.\n *\n * Matches any of `MONEY_ACCOUNT_DEPOSIT_TYPES` (`moneyAccountDeposit` and\n * `membershipSubscription`), either as the transaction type or as a nested\n * call in an EIP-7702 batch.\n * Uses {@link resolveTransactionType} with `FIAT_ENABLED_TYPES` to\n * correctly skip non-deposit nested types (e.g. `tokenMethodApprove`).\n *\n * @param transaction - The transaction metadata to inspect.\n * @returns `true` if the transaction is a Money Account deposit.\n */\nexport function isMoneyAccountDepositTransaction(\n transaction: TransactionMeta,\n): boolean {\n const type = resolveTransactionType(transaction, FIAT_ENABLED_TYPES);\n\n return type !== undefined && MONEY_ACCOUNT_DEPOSIT_TYPES.includes(type);\n}\n\n/**\n * Fetches the best matching Ramps quote for a fiat asset and payment method,\n * with provider fees reconciled to what the resolved provider actually charges.\n *\n * The `RampsController:getQuoteWithFees` action owns the provider check and the\n * native buy-quote lookup, so a Transak Native quote already carries the native\n * fee in its `providerFee`/`networkFee`/`totalFees` fields. MM Pay deposits are\n * fee-on-top, so the quote is requested with `isFeeExcludedFromFiat: true`.\n *\n * @param options - Quote options.\n * @param options.adjustedAmount - Fiat amount sent to Ramps.\n * @param options.errorMessage - Error thrown when no matching quote is returned.\n * @param options.fiatAsset - Fiat asset to buy.\n * @param options.fiatPaymentMethod - Selected fiat payment method.\n * @param options.messenger - Controller messenger.\n * @param options.walletAddress - Wallet address that receives the on-ramped asset.\n * @returns The best matching Ramps quote with reconciled fees.\n */\nexport async function getRampsQuote({\n adjustedAmount,\n errorMessage = 'No matching ramps quote found for selected provider',\n fiatAsset,\n fiatPaymentMethod,\n messenger,\n walletAddress,\n}: {\n adjustedAmount: number;\n errorMessage?: string;\n fiatAsset: TransactionPayFiatAsset;\n fiatPaymentMethod: string;\n messenger: TransactionPayControllerMessenger;\n walletAddress: string;\n}): Promise<RampsQuote> {\n const quote = await messenger.call('RampsController:getQuoteWithFees', {\n amount: adjustedAmount,\n assetId: buildCaipAssetType(fiatAsset.chainId, fiatAsset.address),\n autoSelectProvider: true,\n fiat: DEFAULT_FIAT_CURRENCY,\n isFeeExcludedFromFiat: true,\n paymentMethods: [fiatPaymentMethod],\n restrictToKnownOrNativeProviders: true,\n walletAddress,\n });\n\n log('Fetched ramps quote', { hasQuote: Boolean(quote) });\n\n if (!quote) {\n throw new Error(errorMessage);\n }\n\n return quote;\n}\n\n/**\n * Validates that a completed order's crypto asset matches the expected fiat asset.\n *\n * @param options - The validation options.\n * @param options.expectedAsset - The expected fiat asset derived from the transaction type.\n * @param options.orderCrypto - The crypto currency information from the completed order.\n * @param options.transactionId - Transaction ID for error reporting.\n */\nexport function validateOrderAsset({\n expectedAsset,\n orderCrypto,\n transactionId,\n}: {\n expectedAsset: TransactionPayFiatAsset;\n orderCrypto: RampsOrderCryptoCurrency | undefined;\n transactionId: string;\n}): void {\n const orderAssetId = orderCrypto?.assetId?.toLowerCase();\n const expectedAssetId = buildCaipAssetType(\n expectedAsset.chainId,\n expectedAsset.address,\n ).toLowerCase();\n const expectedChainId = expectedAssetId.split('/')[0];\n const orderChainId = orderCrypto?.chainId?.toLowerCase();\n\n if (orderAssetId && orderAssetId !== expectedAssetId) {\n throw new Error(\n `Order asset mismatch for transaction ${transactionId}: ` +\n `expected ${expectedAssetId}, got ${orderAssetId}`,\n );\n }\n\n if (orderChainId && orderChainId !== expectedChainId) {\n throw new Error(\n `Order chain mismatch for transaction ${transactionId}: ` +\n `expected ${expectedChainId}, got ${orderChainId}`,\n );\n }\n}\n\n/**\n * Resolves the raw source amount for a completed fiat order, read from the\n * on-chain transfer identified by `order.txHash`.\n *\n * Throws when the order has no transaction hash or no matching transfer,\n * rather than trusting the provider-reported `order.cryptoAmount`.\n *\n * @param options - The resolution options.\n * @param options.messenger - Controller messenger for network access.\n * @param options.order - The completed on-ramp order.\n * @param options.fiatAsset - The fiat asset describing the expected token.\n * @param options.walletAddress - Recipient wallet address for on-chain lookup.\n * @returns The raw (atomic) source amount.\n */\nexport async function resolveSourceAmountRaw({\n messenger,\n order,\n fiatAsset,\n walletAddress,\n}: {\n messenger: TransactionPayControllerMessenger;\n order: RampsOrder;\n fiatAsset: TransactionPayFiatAsset;\n walletAddress: Hex;\n}): Promise<string> {\n if (!order.txHash) {\n throw new Error('Missing fiat order transaction hash');\n }\n\n const { amountRaw } = await getTransferredAmountFromTxHash({\n messenger,\n txHash: order.txHash,\n chainId: fiatAsset.chainId,\n tokenAddress: fiatAsset.address,\n walletAddress,\n });\n\n if (!amountRaw) {\n throw new Error(\n `Could not determine transferred amount from transaction ${order.txHash}`,\n );\n }\n\n log('Resolved source amount from on-chain transaction', {\n amountRaw,\n txHash: order.txHash,\n });\n\n return amountRaw;\n}\n\n/**\n * Converts the order's human-readable crypto amount to a raw token amount.\n *\n * @param options - The conversion options.\n * @param options.cryptoAmount - Human-readable crypto amount from the completed order.\n * @param options.decimals - Token decimals for the fiat asset.\n * @returns The raw token amount as a string.\n */\nexport function getRawSourceAmountFromOrderCryptoAmount({\n cryptoAmount,\n decimals,\n}: {\n cryptoAmount: RampsOrder['cryptoAmount'];\n decimals: number;\n}): string {\n const normalizedAmount = new BigNumber(String(cryptoAmount));\n\n if (!normalizedAmount.isFinite() || normalizedAmount.lte(0)) {\n throw new Error(\n `Invalid fiat order crypto amount: ${String(cryptoAmount)}`,\n );\n }\n\n const rawAmount = normalizedAmount\n .shiftedBy(decimals)\n .decimalPlaces(0, BigNumber.ROUND_DOWN)\n .toFixed(0);\n\n if (!new BigNumber(rawAmount).gt(0)) {\n throw new Error('Computed fiat order source amount is not positive');\n }\n\n return rawAmount;\n}\n\n/**\n * Validates that the relay exchange rate hasn't drifted significantly between\n * the original quoting phase and the post-settlement discovery quote.\n *\n * Compares the USD output/input ratio from both quotes. This normalises for\n * different source amounts (quoting phase uses a theoretical amount, discovery\n * uses the actual settled amount) so the comparison reflects genuine rate\n * movement rather than amount differences.\n *\n * @param options - The validation options.\n * @param options.originalQuote - Relay quote from the original quoting phase.\n * @param options.discoveryQuote - Relay quote from the post-settlement discovery.\n * @param options.maxRateDriftPercent - Maximum allowed rate drift percentage.\n * @param options.transactionId - Transaction ID for error reporting.\n */\nexport function validateRelayRateDrift({\n originalQuote,\n discoveryQuote,\n maxRateDriftPercent,\n transactionId,\n}: {\n originalQuote: RelayQuote;\n discoveryQuote: RelayQuote;\n maxRateDriftPercent: number;\n transactionId: string;\n}): void {\n const originalIn = new BigNumber(originalQuote.details.currencyIn.amountUsd);\n const originalOut = new BigNumber(\n originalQuote.details.currencyOut.amountUsd,\n );\n const discoveryIn = new BigNumber(\n discoveryQuote.details.currencyIn.amountUsd,\n );\n const discoveryOut = new BigNumber(\n discoveryQuote.details.currencyOut.amountUsd,\n );\n\n if (\n !originalIn.gt(0) ||\n !originalOut.gt(0) ||\n !discoveryIn.gt(0) ||\n !discoveryOut.gt(0)\n ) {\n return;\n }\n\n const originalRate = originalOut.dividedBy(originalIn);\n const discoveryRate = discoveryOut.dividedBy(discoveryIn);\n\n const driftPercent = originalRate\n .minus(discoveryRate)\n .dividedBy(originalRate)\n .multipliedBy(100);\n\n log('Relay rate drift check', {\n originalRate: originalRate.toFixed(6),\n discoveryRate: discoveryRate.toFixed(6),\n driftPercent: driftPercent.toFixed(2),\n maxRateDriftPercent,\n transactionId,\n });\n\n if (driftPercent.gt(maxRateDriftPercent)) {\n throw new Error(\n `Relay rate drift too high for transaction ` +\n `${driftPercent.toFixed(2)}% exceeds ${maxRateDriftPercent}% max`,\n );\n }\n}\n\n/**\n * Extracts the provider code from a ramps provider string.\n *\n * Accepts the canonical provider code (e.g. `transak-native`) and, for\n * backwards compatibility, the legacy path form (e.g. `/providers/transak-native`).\n *\n * @param provider - Canonical provider code, or legacy provider path.\n * @returns The provider code, or `null` if the format is invalid.\n */\nexport function extractProviderCode(\n provider: string | undefined,\n): string | null {\n if (!provider) {\n return null;\n }\n\n const parts = provider.split('/').filter(Boolean);\n\n if (parts[0] === 'providers') {\n return parts[1] ?? null;\n }\n\n return parts.length === 1 ? parts[0] : null;\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/strategy/fiat/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n Quote as RampsQuote,\n RampsOrder,\n RampsOrderCryptoCurrency,\n} from '@metamask/ramps-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { projectLogger } from '../../logger.js';\nimport type { TransactionPayControllerMessenger } from '../../types.js';\nimport {\n getFiatAssetPerTransactionType,\n getFiatEnabledTypes,\n} from '../../utils/feature-flags.js';\nimport { buildCaipAssetType } from '../../utils/token.js';\nimport { getTransferredAmountFromTxHash } from '../../utils/transaction.js';\nimport type { RelayQuote } from '../relay/types.js';\nimport type { TransactionPayFiatAsset } from './constants.js';\nimport { DEFAULT_FIAT_CURRENCY, FIAT_ENABLED_TYPES } from './constants.js';\n\nconst log = createModuleLogger(projectLogger, 'fiat-utils');\n\nexport function deriveFiatAssetForFiatPayment(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): TransactionPayFiatAsset {\n const enabledTypes = getFiatEnabledTypes(messenger);\n const txType = resolveTransactionType(transaction, enabledTypes);\n\n return getFiatAssetPerTransactionType(messenger, txType);\n}\n\n/**\n * Resolves the effective transaction type for fiat strategy purposes.\n *\n * For non-batch transactions returns the transaction's own type.\n * For batch transactions returns the first nested transaction type\n * that appears in the enabled types list, or the batch type itself\n * if no nested type matches.\n *\n * @param transaction - The transaction metadata to inspect.\n * @param enabledTypes - Transaction types eligible for fiat payment.\n * @returns The resolved transaction type, or `undefined`.\n */\nexport function resolveTransactionType(\n transaction: TransactionMeta,\n enabledTypes: TransactionType[],\n): TransactionType | undefined {\n if (transaction.type !== TransactionType.batch) {\n return transaction.type;\n }\n\n const nestedType = transaction.nestedTransactions?.find(\n (tx) => tx.type && enabledTypes.includes(tx.type),\n )?.type;\n\n return nestedType ?? transaction.type;\n}\n\n/**\n * Checks whether a transaction is a Money Account deposit.\n *\n * Handles both direct `moneyAccountDeposit` transactions and EIP-7702\n * batch transactions that contain a `moneyAccountDeposit` nested call.\n * Uses {@link resolveTransactionType} with `FIAT_ENABLED_TYPES` to\n * correctly skip non-deposit nested types (e.g. `tokenMethodApprove`).\n *\n * @param transaction - The transaction metadata to inspect.\n * @returns `true` if the transaction is a Money Account deposit.\n */\nexport function isMoneyAccountDepositTransaction(\n transaction: TransactionMeta,\n): boolean {\n return (\n resolveTransactionType(transaction, FIAT_ENABLED_TYPES) ===\n TransactionType.moneyAccountDeposit\n );\n}\n\n/**\n * Fetches the best matching Ramps quote for a fiat asset and payment method,\n * with provider fees reconciled to what the resolved provider actually charges.\n *\n * The `RampsController:getQuoteWithFees` action owns the provider check and the\n * native buy-quote lookup, so a Transak Native quote already carries the native\n * fee in its `providerFee`/`networkFee`/`totalFees` fields. MM Pay deposits are\n * fee-on-top, so the quote is requested with `isFeeExcludedFromFiat: true`.\n *\n * @param options - Quote options.\n * @param options.adjustedAmount - Fiat amount sent to Ramps.\n * @param options.errorMessage - Error thrown when no matching quote is returned.\n * @param options.fiatAsset - Fiat asset to buy.\n * @param options.fiatPaymentMethod - Selected fiat payment method.\n * @param options.messenger - Controller messenger.\n * @param options.walletAddress - Wallet address that receives the on-ramped asset.\n * @returns The best matching Ramps quote with reconciled fees.\n */\nexport async function getRampsQuote({\n adjustedAmount,\n errorMessage = 'No matching ramps quote found for selected provider',\n fiatAsset,\n fiatPaymentMethod,\n messenger,\n walletAddress,\n}: {\n adjustedAmount: number;\n errorMessage?: string;\n fiatAsset: TransactionPayFiatAsset;\n fiatPaymentMethod: string;\n messenger: TransactionPayControllerMessenger;\n walletAddress: string;\n}): Promise<RampsQuote> {\n const quote = await messenger.call('RampsController:getQuoteWithFees', {\n amount: adjustedAmount,\n assetId: buildCaipAssetType(fiatAsset.chainId, fiatAsset.address),\n autoSelectProvider: true,\n fiat: DEFAULT_FIAT_CURRENCY,\n isFeeExcludedFromFiat: true,\n paymentMethods: [fiatPaymentMethod],\n restrictToKnownOrNativeProviders: true,\n walletAddress,\n });\n\n log('Fetched ramps quote', { hasQuote: Boolean(quote) });\n\n if (!quote) {\n throw new Error(errorMessage);\n }\n\n return quote;\n}\n\n/**\n * Validates that a completed order's crypto asset matches the expected fiat asset.\n *\n * @param options - The validation options.\n * @param options.expectedAsset - The expected fiat asset derived from the transaction type.\n * @param options.orderCrypto - The crypto currency information from the completed order.\n * @param options.transactionId - Transaction ID for error reporting.\n */\nexport function validateOrderAsset({\n expectedAsset,\n orderCrypto,\n transactionId,\n}: {\n expectedAsset: TransactionPayFiatAsset;\n orderCrypto: RampsOrderCryptoCurrency | undefined;\n transactionId: string;\n}): void {\n const orderAssetId = orderCrypto?.assetId?.toLowerCase();\n const expectedAssetId = buildCaipAssetType(\n expectedAsset.chainId,\n expectedAsset.address,\n ).toLowerCase();\n const expectedChainId = expectedAssetId.split('/')[0];\n const orderChainId = orderCrypto?.chainId?.toLowerCase();\n\n if (orderAssetId && orderAssetId !== expectedAssetId) {\n throw new Error(\n `Order asset mismatch for transaction ${transactionId}: ` +\n `expected ${expectedAssetId}, got ${orderAssetId}`,\n );\n }\n\n if (orderChainId && orderChainId !== expectedChainId) {\n throw new Error(\n `Order chain mismatch for transaction ${transactionId}: ` +\n `expected ${expectedChainId}, got ${orderChainId}`,\n );\n }\n}\n\n/**\n * Resolves the raw source amount for a completed fiat order, read from the\n * on-chain transfer identified by `order.txHash`.\n *\n * Throws when the order has no transaction hash or no matching transfer,\n * rather than trusting the provider-reported `order.cryptoAmount`.\n *\n * @param options - The resolution options.\n * @param options.messenger - Controller messenger for network access.\n * @param options.order - The completed on-ramp order.\n * @param options.fiatAsset - The fiat asset describing the expected token.\n * @param options.walletAddress - Recipient wallet address for on-chain lookup.\n * @returns The raw (atomic) source amount.\n */\nexport async function resolveSourceAmountRaw({\n messenger,\n order,\n fiatAsset,\n walletAddress,\n}: {\n messenger: TransactionPayControllerMessenger;\n order: RampsOrder;\n fiatAsset: TransactionPayFiatAsset;\n walletAddress: Hex;\n}): Promise<string> {\n if (!order.txHash) {\n throw new Error('Missing fiat order transaction hash');\n }\n\n const { amountRaw } = await getTransferredAmountFromTxHash({\n messenger,\n txHash: order.txHash,\n chainId: fiatAsset.chainId,\n tokenAddress: fiatAsset.address,\n walletAddress,\n });\n\n if (!amountRaw) {\n throw new Error(\n `Could not determine transferred amount from transaction ${order.txHash}`,\n );\n }\n\n log('Resolved source amount from on-chain transaction', {\n amountRaw,\n txHash: order.txHash,\n });\n\n return amountRaw;\n}\n\n/**\n * Converts the order's human-readable crypto amount to a raw token amount.\n *\n * @param options - The conversion options.\n * @param options.cryptoAmount - Human-readable crypto amount from the completed order.\n * @param options.decimals - Token decimals for the fiat asset.\n * @returns The raw token amount as a string.\n */\nexport function getRawSourceAmountFromOrderCryptoAmount({\n cryptoAmount,\n decimals,\n}: {\n cryptoAmount: RampsOrder['cryptoAmount'];\n decimals: number;\n}): string {\n const normalizedAmount = new BigNumber(String(cryptoAmount));\n\n if (!normalizedAmount.isFinite() || normalizedAmount.lte(0)) {\n throw new Error(\n `Invalid fiat order crypto amount: ${String(cryptoAmount)}`,\n );\n }\n\n const rawAmount = normalizedAmount\n .shiftedBy(decimals)\n .decimalPlaces(0, BigNumber.ROUND_DOWN)\n .toFixed(0);\n\n if (!new BigNumber(rawAmount).gt(0)) {\n throw new Error('Computed fiat order source amount is not positive');\n }\n\n return rawAmount;\n}\n\n/**\n * Validates that the relay exchange rate hasn't drifted significantly between\n * the original quoting phase and the post-settlement discovery quote.\n *\n * Compares the USD output/input ratio from both quotes. This normalises for\n * different source amounts (quoting phase uses a theoretical amount, discovery\n * uses the actual settled amount) so the comparison reflects genuine rate\n * movement rather than amount differences.\n *\n * @param options - The validation options.\n * @param options.originalQuote - Relay quote from the original quoting phase.\n * @param options.discoveryQuote - Relay quote from the post-settlement discovery.\n * @param options.maxRateDriftPercent - Maximum allowed rate drift percentage.\n * @param options.transactionId - Transaction ID for error reporting.\n */\nexport function validateRelayRateDrift({\n originalQuote,\n discoveryQuote,\n maxRateDriftPercent,\n transactionId,\n}: {\n originalQuote: RelayQuote;\n discoveryQuote: RelayQuote;\n maxRateDriftPercent: number;\n transactionId: string;\n}): void {\n const originalIn = new BigNumber(originalQuote.details.currencyIn.amountUsd);\n const originalOut = new BigNumber(\n originalQuote.details.currencyOut.amountUsd,\n );\n const discoveryIn = new BigNumber(\n discoveryQuote.details.currencyIn.amountUsd,\n );\n const discoveryOut = new BigNumber(\n discoveryQuote.details.currencyOut.amountUsd,\n );\n\n if (\n !originalIn.gt(0) ||\n !originalOut.gt(0) ||\n !discoveryIn.gt(0) ||\n !discoveryOut.gt(0)\n ) {\n return;\n }\n\n const originalRate = originalOut.dividedBy(originalIn);\n const discoveryRate = discoveryOut.dividedBy(discoveryIn);\n\n const driftPercent = originalRate\n .minus(discoveryRate)\n .dividedBy(originalRate)\n .multipliedBy(100);\n\n log('Relay rate drift check', {\n originalRate: originalRate.toFixed(6),\n discoveryRate: discoveryRate.toFixed(6),\n driftPercent: driftPercent.toFixed(2),\n maxRateDriftPercent,\n transactionId,\n });\n\n if (driftPercent.gt(maxRateDriftPercent)) {\n throw new Error(\n `Relay rate drift too high for transaction ` +\n `${driftPercent.toFixed(2)}% exceeds ${maxRateDriftPercent}% max`,\n );\n }\n}\n\n/**\n * Extracts the provider code from a ramps provider string.\n *\n * Accepts the canonical provider code (e.g. `transak-native`) and, for\n * backwards compatibility, the legacy path form (e.g. `/providers/transak-native`).\n *\n * @param provider - Canonical provider code, or legacy provider path.\n * @returns The provider code, or `null` if the format is invalid.\n */\nexport function extractProviderCode(\n provider: string | undefined,\n): string | null {\n if (!provider) {\n return null;\n }\n\n const parts = provider.split('/').filter(Boolean);\n\n if (parts[0] === 'providers') {\n return parts[1] ?? null;\n }\n\n return parts.length === 1 ? parts[0] : null;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/transaction-pay-controller",
3
- "version": "30.3.3-preview-543acb9",
3
+ "version": "30.3.3-preview-fbb37663c",
4
4
  "description": "Manages alternate payment strategies to provide required funds for transactions in MetaMask",
5
5
  "keywords": [
6
6
  "Ethereum",
@@ -55,7 +55,7 @@
55
55
  "@ethersproject/contracts": "^5.7.0",
56
56
  "@ethersproject/providers": "^5.8.0",
57
57
  "@metamask/accounts-controller": "^40.1.0",
58
- "@metamask/assets-controller": "^20.1.0",
58
+ "@metamask/assets-controller": "^20.2.0",
59
59
  "@metamask/base-controller": "^10.1.0",
60
60
  "@metamask/controller-utils": "^13.0.0",
61
61
  "@metamask/gas-fee-controller": "^27.0.0",