@metamask-previews/transaction-pay-controller 19.0.3-preview-b6a517f5e → 19.0.3-preview-119723bcd

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 (34) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/strategy/across/AcrossStrategy.cjs +3 -2
  3. package/dist/strategy/across/AcrossStrategy.cjs.map +1 -1
  4. package/dist/strategy/across/AcrossStrategy.d.cts.map +1 -1
  5. package/dist/strategy/across/AcrossStrategy.d.mts.map +1 -1
  6. package/dist/strategy/across/AcrossStrategy.mjs +3 -2
  7. package/dist/strategy/across/AcrossStrategy.mjs.map +1 -1
  8. package/dist/strategy/across/across-actions.cjs +7 -0
  9. package/dist/strategy/across/across-actions.cjs.map +1 -1
  10. package/dist/strategy/across/across-actions.d.cts.map +1 -1
  11. package/dist/strategy/across/across-actions.d.mts.map +1 -1
  12. package/dist/strategy/across/across-actions.mjs +7 -0
  13. package/dist/strategy/across/across-actions.mjs.map +1 -1
  14. package/dist/strategy/across/across-quotes.cjs +4 -2
  15. package/dist/strategy/across/across-quotes.cjs.map +1 -1
  16. package/dist/strategy/across/across-quotes.d.cts.map +1 -1
  17. package/dist/strategy/across/across-quotes.d.mts.map +1 -1
  18. package/dist/strategy/across/across-quotes.mjs +4 -2
  19. package/dist/strategy/across/across-quotes.mjs.map +1 -1
  20. package/dist/strategy/across/perps.cjs +56 -0
  21. package/dist/strategy/across/perps.cjs.map +1 -0
  22. package/dist/strategy/across/perps.d.cts +32 -0
  23. package/dist/strategy/across/perps.d.cts.map +1 -0
  24. package/dist/strategy/across/perps.d.mts +32 -0
  25. package/dist/strategy/across/perps.d.mts.map +1 -0
  26. package/dist/strategy/across/perps.mjs +51 -0
  27. package/dist/strategy/across/perps.mjs.map +1 -0
  28. package/dist/utils/source-amounts.cjs +23 -17
  29. package/dist/utils/source-amounts.cjs.map +1 -1
  30. package/dist/utils/source-amounts.d.cts.map +1 -1
  31. package/dist/utils/source-amounts.d.mts.map +1 -1
  32. package/dist/utils/source-amounts.mjs +23 -17
  33. package/dist/utils/source-amounts.mjs.map +1 -1
  34. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Added
11
+
12
+ - Support for perps deposit for Across ([#8334](https://github.com/MetaMask/core/pull/8334))
13
+
14
+ ### Fixed
15
+
16
+ - Fix perps withdraw to Arbitrum USDC showing inflated transaction fee by bypassing same-token filter when `isHyperliquidSource` is set ([#8387](https://github.com/MetaMask/core/pull/8387))
17
+
10
18
  ## [19.0.3]
11
19
 
12
20
  ### Changed
@@ -4,6 +4,7 @@ exports.AcrossStrategy = void 0;
4
4
  const transaction_controller_1 = require("@metamask/transaction-controller");
5
5
  const across_quotes_1 = require("./across-quotes.cjs");
6
6
  const across_submit_1 = require("./across-submit.cjs");
7
+ const perps_1 = require("./perps.cjs");
7
8
  const feature_flags_1 = require("../../utils/feature-flags.cjs");
8
9
  class AcrossStrategy {
9
10
  supports(request) {
@@ -11,8 +12,8 @@ class AcrossStrategy {
11
12
  if (!config.across.enabled) {
12
13
  return false;
13
14
  }
14
- if (request.transaction?.type === transaction_controller_1.TransactionType.perpsAcrossDeposit) {
15
- return false;
15
+ if (request.transaction?.type === transaction_controller_1.TransactionType.perpsDeposit) {
16
+ return request.requests.every((singleRequest) => (0, perps_1.isSupportedAcrossPerpsDepositRequest)(singleRequest, request.transaction?.type));
16
17
  }
17
18
  // Across doesn't support same-chain swaps (e.g. mUSD conversions).
18
19
  return request.requests.every((singleRequest) => singleRequest.sourceChainId !== singleRequest.targetChainId);
@@ -1 +1 @@
1
- {"version":3,"file":"AcrossStrategy.cjs","sourceRoot":"","sources":["../../../src/strategy/across/AcrossStrategy.ts"],"names":[],"mappings":";;;AAAA,6EAAmE;AAEnE,uDAAkD;AAClD,uDAAqD;AAQrD,iEAAmE;AAEnE,MAAa,cAAc;IACzB,QAAQ,CAAC,OAAoC;QAC3C,MAAM,MAAM,GAAG,IAAA,sCAAsB,EAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAEzD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,OAAO,CAAC,WAAW,EAAE,IAAI,KAAK,wCAAe,CAAC,kBAAkB,EAAE,CAAC;YACrE,OAAO,KAAK,CAAC;QACf,CAAC;QAED,mEAAmE;QACnE,OAAO,OAAO,CAAC,QAAQ,CAAC,KAAK,CAC3B,CAAC,aAAa,EAAE,EAAE,CAChB,aAAa,CAAC,aAAa,KAAK,aAAa,CAAC,aAAa,CAC9D,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,SAAS,CACb,OAAoC;QAEpC,OAAO,IAAA,+BAAe,EAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,OAAO,CACX,OAA+C;QAE/C,OAAO,IAAA,kCAAkB,EAAC,OAAO,CAAC,CAAC;IACrC,CAAC;CACF;AA9BD,wCA8BC","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\n\nimport { getAcrossQuotes } from './across-quotes';\nimport { submitAcrossQuotes } from './across-submit';\nimport type { AcrossQuote } from './types';\nimport type {\n PayStrategy,\n PayStrategyExecuteRequest,\n PayStrategyGetQuotesRequest,\n TransactionPayQuote,\n} from '../../types';\nimport { getPayStrategiesConfig } from '../../utils/feature-flags';\n\nexport class AcrossStrategy implements PayStrategy<AcrossQuote> {\n supports(request: PayStrategyGetQuotesRequest): boolean {\n const config = getPayStrategiesConfig(request.messenger);\n\n if (!config.across.enabled) {\n return false;\n }\n\n if (request.transaction?.type === TransactionType.perpsAcrossDeposit) {\n return false;\n }\n\n // Across doesn't support same-chain swaps (e.g. mUSD conversions).\n return request.requests.every(\n (singleRequest) =>\n singleRequest.sourceChainId !== singleRequest.targetChainId,\n );\n }\n\n async getQuotes(\n request: PayStrategyGetQuotesRequest,\n ): Promise<TransactionPayQuote<AcrossQuote>[]> {\n return getAcrossQuotes(request);\n }\n\n async execute(\n request: PayStrategyExecuteRequest<AcrossQuote>,\n ): ReturnType<PayStrategy<AcrossQuote>['execute']> {\n return submitAcrossQuotes(request);\n }\n}\n"]}
1
+ {"version":3,"file":"AcrossStrategy.cjs","sourceRoot":"","sources":["../../../src/strategy/across/AcrossStrategy.ts"],"names":[],"mappings":";;;AAAA,6EAAmE;AAEnE,uDAAkD;AAClD,uDAAqD;AACrD,uCAA+D;AAQ/D,iEAAmE;AAEnE,MAAa,cAAc;IACzB,QAAQ,CAAC,OAAoC;QAC3C,MAAM,MAAM,GAAG,IAAA,sCAAsB,EAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAEzD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,OAAO,CAAC,WAAW,EAAE,IAAI,KAAK,wCAAe,CAAC,YAAY,EAAE,CAAC;YAC/D,OAAO,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,aAAa,EAAE,EAAE,CAC9C,IAAA,4CAAoC,EAClC,aAAa,EACb,OAAO,CAAC,WAAW,EAAE,IAAI,CAC1B,CACF,CAAC;QACJ,CAAC;QAED,mEAAmE;QACnE,OAAO,OAAO,CAAC,QAAQ,CAAC,KAAK,CAC3B,CAAC,aAAa,EAAE,EAAE,CAChB,aAAa,CAAC,aAAa,KAAK,aAAa,CAAC,aAAa,CAC9D,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,SAAS,CACb,OAAoC;QAEpC,OAAO,IAAA,+BAAe,EAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,OAAO,CACX,OAA+C;QAE/C,OAAO,IAAA,kCAAkB,EAAC,OAAO,CAAC,CAAC;IACrC,CAAC;CACF;AAnCD,wCAmCC","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\n\nimport { getAcrossQuotes } from './across-quotes';\nimport { submitAcrossQuotes } from './across-submit';\nimport { isSupportedAcrossPerpsDepositRequest } from './perps';\nimport type { AcrossQuote } from './types';\nimport type {\n PayStrategy,\n PayStrategyExecuteRequest,\n PayStrategyGetQuotesRequest,\n TransactionPayQuote,\n} from '../../types';\nimport { getPayStrategiesConfig } from '../../utils/feature-flags';\n\nexport class AcrossStrategy implements PayStrategy<AcrossQuote> {\n supports(request: PayStrategyGetQuotesRequest): boolean {\n const config = getPayStrategiesConfig(request.messenger);\n\n if (!config.across.enabled) {\n return false;\n }\n\n if (request.transaction?.type === TransactionType.perpsDeposit) {\n return request.requests.every((singleRequest) =>\n isSupportedAcrossPerpsDepositRequest(\n singleRequest,\n request.transaction?.type,\n ),\n );\n }\n\n // Across doesn't support same-chain swaps (e.g. mUSD conversions).\n return request.requests.every(\n (singleRequest) =>\n singleRequest.sourceChainId !== singleRequest.targetChainId,\n );\n }\n\n async getQuotes(\n request: PayStrategyGetQuotesRequest,\n ): Promise<TransactionPayQuote<AcrossQuote>[]> {\n return getAcrossQuotes(request);\n }\n\n async execute(\n request: PayStrategyExecuteRequest<AcrossQuote>,\n ): ReturnType<PayStrategy<AcrossQuote>['execute']> {\n return submitAcrossQuotes(request);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"AcrossStrategy.d.cts","sourceRoot":"","sources":["../../../src/strategy/across/AcrossStrategy.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAgB;AAC3C,OAAO,KAAK,EACV,WAAW,EACX,yBAAyB,EACzB,2BAA2B,EAC3B,mBAAmB,EACpB,wBAAoB;AAGrB,qBAAa,cAAe,YAAW,WAAW,CAAC,WAAW,CAAC;IAC7D,QAAQ,CAAC,OAAO,EAAE,2BAA2B,GAAG,OAAO;IAkBjD,SAAS,CACb,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC;IAIxC,OAAO,CACX,OAAO,EAAE,yBAAyB,CAAC,WAAW,CAAC,GAC9C,UAAU,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC;CAGnD"}
1
+ {"version":3,"file":"AcrossStrategy.d.cts","sourceRoot":"","sources":["../../../src/strategy/across/AcrossStrategy.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAgB;AAC3C,OAAO,KAAK,EACV,WAAW,EACX,yBAAyB,EACzB,2BAA2B,EAC3B,mBAAmB,EACpB,wBAAoB;AAGrB,qBAAa,cAAe,YAAW,WAAW,CAAC,WAAW,CAAC;IAC7D,QAAQ,CAAC,OAAO,EAAE,2BAA2B,GAAG,OAAO;IAuBjD,SAAS,CACb,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC;IAIxC,OAAO,CACX,OAAO,EAAE,yBAAyB,CAAC,WAAW,CAAC,GAC9C,UAAU,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC;CAGnD"}
@@ -1 +1 @@
1
- {"version":3,"file":"AcrossStrategy.d.mts","sourceRoot":"","sources":["../../../src/strategy/across/AcrossStrategy.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAgB;AAC3C,OAAO,KAAK,EACV,WAAW,EACX,yBAAyB,EACzB,2BAA2B,EAC3B,mBAAmB,EACpB,wBAAoB;AAGrB,qBAAa,cAAe,YAAW,WAAW,CAAC,WAAW,CAAC;IAC7D,QAAQ,CAAC,OAAO,EAAE,2BAA2B,GAAG,OAAO;IAkBjD,SAAS,CACb,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC;IAIxC,OAAO,CACX,OAAO,EAAE,yBAAyB,CAAC,WAAW,CAAC,GAC9C,UAAU,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC;CAGnD"}
1
+ {"version":3,"file":"AcrossStrategy.d.mts","sourceRoot":"","sources":["../../../src/strategy/across/AcrossStrategy.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAgB;AAC3C,OAAO,KAAK,EACV,WAAW,EACX,yBAAyB,EACzB,2BAA2B,EAC3B,mBAAmB,EACpB,wBAAoB;AAGrB,qBAAa,cAAe,YAAW,WAAW,CAAC,WAAW,CAAC;IAC7D,QAAQ,CAAC,OAAO,EAAE,2BAA2B,GAAG,OAAO;IAuBjD,SAAS,CACb,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC;IAIxC,OAAO,CACX,OAAO,EAAE,yBAAyB,CAAC,WAAW,CAAC,GAC9C,UAAU,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC;CAGnD"}
@@ -1,6 +1,7 @@
1
1
  import { TransactionType } from "@metamask/transaction-controller";
2
2
  import { getAcrossQuotes } from "./across-quotes.mjs";
3
3
  import { submitAcrossQuotes } from "./across-submit.mjs";
4
+ import { isSupportedAcrossPerpsDepositRequest } from "./perps.mjs";
4
5
  import { getPayStrategiesConfig } from "../../utils/feature-flags.mjs";
5
6
  export class AcrossStrategy {
6
7
  supports(request) {
@@ -8,8 +9,8 @@ export class AcrossStrategy {
8
9
  if (!config.across.enabled) {
9
10
  return false;
10
11
  }
11
- if (request.transaction?.type === TransactionType.perpsAcrossDeposit) {
12
- return false;
12
+ if (request.transaction?.type === TransactionType.perpsDeposit) {
13
+ return request.requests.every((singleRequest) => isSupportedAcrossPerpsDepositRequest(singleRequest, request.transaction?.type));
13
14
  }
14
15
  // Across doesn't support same-chain swaps (e.g. mUSD conversions).
15
16
  return request.requests.every((singleRequest) => singleRequest.sourceChainId !== singleRequest.targetChainId);
@@ -1 +1 @@
1
- {"version":3,"file":"AcrossStrategy.mjs","sourceRoot":"","sources":["../../../src/strategy/across/AcrossStrategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,yCAAyC;AAEnE,OAAO,EAAE,eAAe,EAAE,4BAAwB;AAClD,OAAO,EAAE,kBAAkB,EAAE,4BAAwB;AAQrD,OAAO,EAAE,sBAAsB,EAAE,sCAAkC;AAEnE,MAAM,OAAO,cAAc;IACzB,QAAQ,CAAC,OAAoC;QAC3C,MAAM,MAAM,GAAG,sBAAsB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAEzD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,OAAO,CAAC,WAAW,EAAE,IAAI,KAAK,eAAe,CAAC,kBAAkB,EAAE,CAAC;YACrE,OAAO,KAAK,CAAC;QACf,CAAC;QAED,mEAAmE;QACnE,OAAO,OAAO,CAAC,QAAQ,CAAC,KAAK,CAC3B,CAAC,aAAa,EAAE,EAAE,CAChB,aAAa,CAAC,aAAa,KAAK,aAAa,CAAC,aAAa,CAC9D,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,SAAS,CACb,OAAoC;QAEpC,OAAO,eAAe,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,OAAO,CACX,OAA+C;QAE/C,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;CACF","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\n\nimport { getAcrossQuotes } from './across-quotes';\nimport { submitAcrossQuotes } from './across-submit';\nimport type { AcrossQuote } from './types';\nimport type {\n PayStrategy,\n PayStrategyExecuteRequest,\n PayStrategyGetQuotesRequest,\n TransactionPayQuote,\n} from '../../types';\nimport { getPayStrategiesConfig } from '../../utils/feature-flags';\n\nexport class AcrossStrategy implements PayStrategy<AcrossQuote> {\n supports(request: PayStrategyGetQuotesRequest): boolean {\n const config = getPayStrategiesConfig(request.messenger);\n\n if (!config.across.enabled) {\n return false;\n }\n\n if (request.transaction?.type === TransactionType.perpsAcrossDeposit) {\n return false;\n }\n\n // Across doesn't support same-chain swaps (e.g. mUSD conversions).\n return request.requests.every(\n (singleRequest) =>\n singleRequest.sourceChainId !== singleRequest.targetChainId,\n );\n }\n\n async getQuotes(\n request: PayStrategyGetQuotesRequest,\n ): Promise<TransactionPayQuote<AcrossQuote>[]> {\n return getAcrossQuotes(request);\n }\n\n async execute(\n request: PayStrategyExecuteRequest<AcrossQuote>,\n ): ReturnType<PayStrategy<AcrossQuote>['execute']> {\n return submitAcrossQuotes(request);\n }\n}\n"]}
1
+ {"version":3,"file":"AcrossStrategy.mjs","sourceRoot":"","sources":["../../../src/strategy/across/AcrossStrategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,yCAAyC;AAEnE,OAAO,EAAE,eAAe,EAAE,4BAAwB;AAClD,OAAO,EAAE,kBAAkB,EAAE,4BAAwB;AACrD,OAAO,EAAE,oCAAoC,EAAE,oBAAgB;AAQ/D,OAAO,EAAE,sBAAsB,EAAE,sCAAkC;AAEnE,MAAM,OAAO,cAAc;IACzB,QAAQ,CAAC,OAAoC;QAC3C,MAAM,MAAM,GAAG,sBAAsB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAEzD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,OAAO,CAAC,WAAW,EAAE,IAAI,KAAK,eAAe,CAAC,YAAY,EAAE,CAAC;YAC/D,OAAO,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,aAAa,EAAE,EAAE,CAC9C,oCAAoC,CAClC,aAAa,EACb,OAAO,CAAC,WAAW,EAAE,IAAI,CAC1B,CACF,CAAC;QACJ,CAAC;QAED,mEAAmE;QACnE,OAAO,OAAO,CAAC,QAAQ,CAAC,KAAK,CAC3B,CAAC,aAAa,EAAE,EAAE,CAChB,aAAa,CAAC,aAAa,KAAK,aAAa,CAAC,aAAa,CAC9D,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,SAAS,CACb,OAAoC;QAEpC,OAAO,eAAe,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,OAAO,CACX,OAA+C;QAE/C,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;CACF","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\n\nimport { getAcrossQuotes } from './across-quotes';\nimport { submitAcrossQuotes } from './across-submit';\nimport { isSupportedAcrossPerpsDepositRequest } from './perps';\nimport type { AcrossQuote } from './types';\nimport type {\n PayStrategy,\n PayStrategyExecuteRequest,\n PayStrategyGetQuotesRequest,\n TransactionPayQuote,\n} from '../../types';\nimport { getPayStrategiesConfig } from '../../utils/feature-flags';\n\nexport class AcrossStrategy implements PayStrategy<AcrossQuote> {\n supports(request: PayStrategyGetQuotesRequest): boolean {\n const config = getPayStrategiesConfig(request.messenger);\n\n if (!config.across.enabled) {\n return false;\n }\n\n if (request.transaction?.type === TransactionType.perpsDeposit) {\n return request.requests.every((singleRequest) =>\n isSupportedAcrossPerpsDepositRequest(\n singleRequest,\n request.transaction?.type,\n ),\n );\n }\n\n // Across doesn't support same-chain swaps (e.g. mUSD conversions).\n return request.requests.every(\n (singleRequest) =>\n singleRequest.sourceChainId !== singleRequest.targetChainId,\n );\n }\n\n async getQuotes(\n request: PayStrategyGetQuotesRequest,\n ): Promise<TransactionPayQuote<AcrossQuote>[]> {\n return getAcrossQuotes(request);\n }\n\n async execute(\n request: PayStrategyExecuteRequest<AcrossQuote>,\n ): ReturnType<PayStrategy<AcrossQuote>['execute']> {\n return submitAcrossQuotes(request);\n }\n}\n"]}
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isExtractableOutputTokenTransferCall = exports.getAcrossDestination = exports.getTransferRecipient = exports.buildAcrossActionFromCall = exports.UNSUPPORTED_DESTINATION_ERROR = exports.SAFE_EXEC_TRANSACTION_SIGNATURE = exports.CREATE_PROXY_SIGNATURE = exports.TOKEN_TRANSFER_SIGNATURE = void 0;
4
4
  const abi_1 = require("@ethersproject/abi");
5
+ const perps_1 = require("./perps.cjs");
5
6
  exports.TOKEN_TRANSFER_SIGNATURE = 'function transfer(address to, uint256 value)';
6
7
  exports.CREATE_PROXY_SIGNATURE = 'function createProxy(address paymentToken, uint256 payment, address payable paymentReceiver, (uint8 v, bytes32 r, bytes32 s) createSig)';
7
8
  exports.SAFE_EXEC_TRANSACTION_SIGNATURE = 'function execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures)';
@@ -36,6 +37,12 @@ function getTransferRecipient(data) {
36
37
  }
37
38
  exports.getTransferRecipient = getTransferRecipient;
38
39
  function getAcrossDestination(transaction, request) {
40
+ if ((0, perps_1.isSupportedAcrossPerpsDepositRequest)(request, transaction.type)) {
41
+ return {
42
+ actions: [],
43
+ recipient: request.from,
44
+ };
45
+ }
39
46
  const { from } = request;
40
47
  const destinationCalls = getDestinationCalls(transaction);
41
48
  const swapRecipientTransferCallIndex = destinationCalls.findIndex((call) => isExtractableOutputTokenTransferCall(call, request));
@@ -1 +1 @@
1
- {"version":3,"file":"across-actions.cjs","sourceRoot":"","sources":["../../../src/strategy/across/across-actions.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport type { TransactionDescription } from '@ethersproject/abi';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport type { AcrossAction, AcrossActionArg } from './types';\nimport type { QuoteRequest } from '../../types';\n\nexport const TOKEN_TRANSFER_SIGNATURE =\n 'function transfer(address to, uint256 value)';\nexport const CREATE_PROXY_SIGNATURE =\n 'function createProxy(address paymentToken, uint256 payment, address payable paymentReceiver, (uint8 v, bytes32 r, bytes32 s) createSig)';\nexport const SAFE_EXEC_TRANSACTION_SIGNATURE =\n 'function execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures)';\n\nexport const UNSUPPORTED_DESTINATION_ERROR =\n 'Across only supports direct token transfers and a limited set of post-swap destination actions at the moment';\n\nexport type AcrossDestinationCall = {\n data: Hex;\n target?: Hex;\n};\n\nexport type AcrossDestination = {\n actions: AcrossAction[];\n recipient: Hex;\n};\n\ntype ParsedAcrossActionCall = {\n functionSignature: string;\n transaction: TransactionDescription;\n};\n\ntype BigNumberLike = {\n _isBigNumber: true;\n toString: () => string;\n};\n\nconst ACROSS_ACTION_SIGNATURES = [\n CREATE_PROXY_SIGNATURE,\n SAFE_EXEC_TRANSACTION_SIGNATURE,\n];\n\nexport function buildAcrossActionFromCall(\n call: AcrossDestinationCall,\n request: QuoteRequest,\n): AcrossAction {\n if (isTransferCall(call.data)) {\n return buildAcrossTransferAction(call, request);\n }\n\n const parsedCall = parseAcrossActionCall(call.data);\n\n return {\n args: Array.from(parsedCall.transaction.args).map((arg) => ({\n populateDynamically: false,\n value: serializeAcrossActionValue(arg),\n })),\n functionSignature: parsedCall.functionSignature,\n isNativeTransfer: false,\n target: getRequiredTarget(call),\n value: '0',\n };\n}\n\nexport function getTransferRecipient(data: Hex): Hex {\n const parsedCall = tryParseTransferCall(data);\n\n if (!parsedCall) {\n throw new Error(getUnsupportedDestinationErrorMessage(data));\n }\n\n return normalizeHexString(String(parsedCall.args[0])) as Hex;\n}\n\nexport function getAcrossDestination(\n transaction: TransactionMeta,\n request: QuoteRequest,\n): AcrossDestination {\n const { from } = request;\n const destinationCalls = getDestinationCalls(transaction);\n const swapRecipientTransferCallIndex = destinationCalls.findIndex((call) =>\n isExtractableOutputTokenTransferCall(call, request),\n );\n const callsForActions = [...destinationCalls];\n let recipient = from;\n\n if (swapRecipientTransferCallIndex !== -1) {\n const [swapRecipientTransferCall] = callsForActions.splice(\n swapRecipientTransferCallIndex,\n 1,\n );\n\n recipient = getTransferRecipient(swapRecipientTransferCall.data);\n }\n\n return {\n actions: callsForActions.map((call) =>\n buildAcrossActionFromCall(call, request),\n ),\n recipient,\n };\n}\n\nexport function isExtractableOutputTokenTransferCall(\n call: AcrossDestinationCall,\n request: QuoteRequest,\n): boolean {\n return (\n isTransferCall(call.data) &&\n (call.target === undefined ||\n normalizeHexString(call.target) ===\n normalizeHexString(request.targetTokenAddress))\n );\n}\n\nfunction getRequiredTarget(call: AcrossDestinationCall): Hex {\n if (!call.target) {\n throw new Error(UNSUPPORTED_DESTINATION_ERROR);\n }\n\n return call.target;\n}\n\nfunction normalizeHexString(value: string): string {\n /* istanbul ignore next: current supported Across action signatures only emit hex strings here. */\n if (!value.startsWith('0x')) {\n return value;\n }\n\n return value.toLowerCase();\n}\n\nfunction parseAcrossActionCall(data: Hex): ParsedAcrossActionCall {\n const parsedCall = tryParseAcrossActionCall(data);\n\n if (!parsedCall) {\n throw new Error(getUnsupportedDestinationErrorMessage(data));\n }\n\n return parsedCall;\n}\n\nfunction serializeAcrossActionValue(value: unknown): AcrossActionArg['value'] {\n if (Array.isArray(value)) {\n return value.map((entry) =>\n serializeAcrossActionScalar(entry),\n ) as AcrossActionArg['value'];\n }\n\n return serializeAcrossActionScalar(value);\n}\n\nfunction buildAcrossTransferAction(\n call: AcrossDestinationCall,\n request: QuoteRequest,\n): AcrossAction {\n return {\n args: [\n {\n populateDynamically: false,\n value: getTransferRecipient(call.data),\n },\n {\n balanceSourceToken: request.targetTokenAddress,\n populateDynamically: true,\n value: '0',\n },\n ],\n functionSignature: TOKEN_TRANSFER_SIGNATURE,\n isNativeTransfer: false,\n target: call.target ?? request.targetTokenAddress,\n value: '0',\n };\n}\n\nfunction getDestinationCalls(\n transaction: TransactionMeta,\n): AcrossDestinationCall[] {\n const nestedCalls = (\n transaction.nestedTransactions ?? []\n ).flatMap<AcrossDestinationCall>((nestedTx: { data?: Hex; to?: Hex }) =>\n nestedTx.data !== undefined && nestedTx.data !== '0x'\n ? [{ data: nestedTx.data, target: nestedTx.to }]\n : [],\n );\n\n if (nestedCalls.length > 0) {\n return nestedCalls;\n }\n\n const data = transaction.txParams?.data as Hex | undefined;\n\n if (data === undefined || data === '0x') {\n return [];\n }\n\n return [\n {\n data,\n target: transaction.txParams?.to as Hex | undefined,\n },\n ];\n}\n\nfunction getUnsupportedDestinationErrorMessage(data?: Hex): string {\n const selector = getDestinationSelector(data);\n\n return selector\n ? `${UNSUPPORTED_DESTINATION_ERROR}. Destination selector: ${selector}`\n : UNSUPPORTED_DESTINATION_ERROR;\n}\n\nfunction getDestinationSelector(data?: Hex): Hex | undefined {\n if (!data || data.length < 10) {\n return undefined;\n }\n\n return data.slice(0, 10).toLowerCase() as Hex;\n}\n\nfunction serializeAcrossActionScalar(value: unknown): string {\n if (typeof value === 'string') {\n return normalizeHexString(value);\n }\n\n if (\n typeof value === 'number' ||\n typeof value === 'bigint' ||\n typeof value === 'boolean'\n ) {\n return String(value);\n }\n\n if (isBigNumberLike(value)) {\n return value.toString();\n }\n\n /* istanbul ignore next: supported Across action ABIs only decode scalars and tuples of scalars. */\n throw new Error(UNSUPPORTED_DESTINATION_ERROR);\n}\n\nfunction isBigNumberLike(value: unknown): value is BigNumberLike {\n return (\n typeof value === 'object' &&\n value !== null &&\n '_isBigNumber' in value &&\n value._isBigNumber === true &&\n 'toString' in value &&\n typeof value.toString === 'function'\n );\n}\n\nfunction isTransferCall(data: Hex): boolean {\n return tryParseTransferCall(data) !== undefined;\n}\n\nfunction tryParseAcrossActionCall(\n data: Hex,\n): ParsedAcrossActionCall | undefined {\n for (const functionSignature of ACROSS_ACTION_SIGNATURES) {\n try {\n const actionInterface = new Interface([functionSignature]);\n\n return {\n functionSignature,\n transaction: actionInterface.parseTransaction({ data }),\n };\n } catch {\n // Intentionally empty.\n }\n }\n\n return undefined;\n}\n\nfunction tryParseTransferCall(data: Hex): TransactionDescription | undefined {\n try {\n return new Interface([TOKEN_TRANSFER_SIGNATURE]).parseTransaction({ data });\n } catch {\n return undefined;\n }\n}\n"]}
1
+ {"version":3,"file":"across-actions.cjs","sourceRoot":"","sources":["../../../src/strategy/across/across-actions.ts"],"names":[],"mappings":";;;AAAA,4CAA+C;AAK/C,uCAA+D;AAIlD,QAAA,wBAAwB,GACnC,8CAA8C,CAAC;AACpC,QAAA,sBAAsB,GACjC,yIAAyI,CAAC;AAC/H,QAAA,+BAA+B,GAC1C,oMAAoM,CAAC;AAE1L,QAAA,6BAA6B,GACxC,8GAA8G,CAAC;AAsBjH,MAAM,wBAAwB,GAAG;IAC/B,8BAAsB;IACtB,uCAA+B;CAChC,CAAC;AAEF,SAAgB,yBAAyB,CACvC,IAA2B,EAC3B,OAAqB;IAErB,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,OAAO,yBAAyB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,UAAU,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEpD,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAC1D,mBAAmB,EAAE,KAAK;YAC1B,KAAK,EAAE,0BAA0B,CAAC,GAAG,CAAC;SACvC,CAAC,CAAC;QACH,iBAAiB,EAAE,UAAU,CAAC,iBAAiB;QAC/C,gBAAgB,EAAE,KAAK;QACvB,MAAM,EAAE,iBAAiB,CAAC,IAAI,CAAC;QAC/B,KAAK,EAAE,GAAG;KACX,CAAC;AACJ,CAAC;AApBD,8DAoBC;AAED,SAAgB,oBAAoB,CAAC,IAAS;IAC5C,MAAM,UAAU,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAE9C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,kBAAkB,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAQ,CAAC;AAC/D,CAAC;AARD,oDAQC;AAED,SAAgB,oBAAoB,CAClC,WAA4B,EAC5B,OAAqB;IAErB,IAAI,IAAA,4CAAoC,EAAC,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QACpE,OAAO;YACL,OAAO,EAAE,EAAE;YACX,SAAS,EAAE,OAAO,CAAC,IAAI;SACxB,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IACzB,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC1D,MAAM,8BAA8B,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CACzE,oCAAoC,CAAC,IAAI,EAAE,OAAO,CAAC,CACpD,CAAC;IACF,MAAM,eAAe,GAAG,CAAC,GAAG,gBAAgB,CAAC,CAAC;IAC9C,IAAI,SAAS,GAAG,IAAI,CAAC;IAErB,IAAI,8BAA8B,KAAK,CAAC,CAAC,EAAE,CAAC;QAC1C,MAAM,CAAC,yBAAyB,CAAC,GAAG,eAAe,CAAC,MAAM,CACxD,8BAA8B,EAC9B,CAAC,CACF,CAAC;QAEF,SAAS,GAAG,oBAAoB,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC;IACnE,CAAC;IAED,OAAO;QACL,OAAO,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACpC,yBAAyB,CAAC,IAAI,EAAE,OAAO,CAAC,CACzC;QACD,SAAS;KACV,CAAC;AACJ,CAAC;AAlCD,oDAkCC;AAED,SAAgB,oCAAoC,CAClD,IAA2B,EAC3B,OAAqB;IAErB,OAAO,CACL,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;QACzB,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS;YACxB,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC7B,kBAAkB,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CACpD,CAAC;AACJ,CAAC;AAVD,oFAUC;AAED,SAAS,iBAAiB,CAAC,IAA2B;IACpD,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,qCAA6B,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,IAAI,CAAC,MAAM,CAAC;AACrB,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAa;IACvC,kGAAkG;IAClG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;AAC7B,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAS;IACtC,MAAM,UAAU,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC;IAElD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,0BAA0B,CAAC,KAAc;IAChD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACzB,2BAA2B,CAAC,KAAK,CAAC,CACP,CAAC;IAChC,CAAC;IAED,OAAO,2BAA2B,CAAC,KAAK,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,yBAAyB,CAChC,IAA2B,EAC3B,OAAqB;IAErB,OAAO;QACL,IAAI,EAAE;YACJ;gBACE,mBAAmB,EAAE,KAAK;gBAC1B,KAAK,EAAE,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC;aACvC;YACD;gBACE,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;gBAC9C,mBAAmB,EAAE,IAAI;gBACzB,KAAK,EAAE,GAAG;aACX;SACF;QACD,iBAAiB,EAAE,gCAAwB;QAC3C,gBAAgB,EAAE,KAAK;QACvB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,kBAAkB;QACjD,KAAK,EAAE,GAAG;KACX,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAC1B,WAA4B;IAE5B,MAAM,WAAW,GAAG,CAClB,WAAW,CAAC,kBAAkB,IAAI,EAAE,CACrC,CAAC,OAAO,CAAwB,CAAC,QAAkC,EAAE,EAAE,CACtE,QAAQ,CAAC,IAAI,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI;QACnD,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC;QAChD,CAAC,CAAC,EAAE,CACP,CAAC;IAEF,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,EAAE,IAAuB,CAAC;IAE3D,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QACxC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO;QACL;YACE,IAAI;YACJ,MAAM,EAAE,WAAW,CAAC,QAAQ,EAAE,EAAqB;SACpD;KACF,CAAC;AACJ,CAAC;AAED,SAAS,qCAAqC,CAAC,IAAU;IACvD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAE9C,OAAO,QAAQ;QACb,CAAC,CAAC,GAAG,qCAA6B,2BAA2B,QAAQ,EAAE;QACvE,CAAC,CAAC,qCAA6B,CAAC;AACpC,CAAC;AAED,SAAS,sBAAsB,CAAC,IAAU;IACxC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QAC9B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,EAAS,CAAC;AAChD,CAAC;AAED,SAAS,2BAA2B,CAAC,KAAc;IACjD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAED,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,OAAO,KAAK,KAAK,QAAQ;QACzB,OAAO,KAAK,KAAK,SAAS,EAC1B,CAAC;QACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAED,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC1B,CAAC;IAED,mGAAmG;IACnG,MAAM,IAAI,KAAK,CAAC,qCAA6B,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,cAAc,IAAI,KAAK;QACvB,KAAK,CAAC,YAAY,KAAK,IAAI;QAC3B,UAAU,IAAI,KAAK;QACnB,OAAO,KAAK,CAAC,QAAQ,KAAK,UAAU,CACrC,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,IAAS;IAC/B,OAAO,oBAAoB,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC;AAClD,CAAC;AAED,SAAS,wBAAwB,CAC/B,IAAS;IAET,KAAK,MAAM,iBAAiB,IAAI,wBAAwB,EAAE,CAAC;QACzD,IAAI,CAAC;YACH,MAAM,eAAe,GAAG,IAAI,eAAS,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC;YAE3D,OAAO;gBACL,iBAAiB;gBACjB,WAAW,EAAE,eAAe,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,CAAC;aACxD,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,uBAAuB;QACzB,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAS;IACrC,IAAI,CAAC;QACH,OAAO,IAAI,eAAS,CAAC,CAAC,gCAAwB,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport type { TransactionDescription } from '@ethersproject/abi';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport { isSupportedAcrossPerpsDepositRequest } from './perps';\nimport type { AcrossAction, AcrossActionArg } from './types';\nimport type { QuoteRequest } from '../../types';\n\nexport const TOKEN_TRANSFER_SIGNATURE =\n 'function transfer(address to, uint256 value)';\nexport const CREATE_PROXY_SIGNATURE =\n 'function createProxy(address paymentToken, uint256 payment, address payable paymentReceiver, (uint8 v, bytes32 r, bytes32 s) createSig)';\nexport const SAFE_EXEC_TRANSACTION_SIGNATURE =\n 'function execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures)';\n\nexport const UNSUPPORTED_DESTINATION_ERROR =\n 'Across only supports direct token transfers and a limited set of post-swap destination actions at the moment';\n\nexport type AcrossDestinationCall = {\n data: Hex;\n target?: Hex;\n};\n\nexport type AcrossDestination = {\n actions: AcrossAction[];\n recipient: Hex;\n};\n\ntype ParsedAcrossActionCall = {\n functionSignature: string;\n transaction: TransactionDescription;\n};\n\ntype BigNumberLike = {\n _isBigNumber: true;\n toString: () => string;\n};\n\nconst ACROSS_ACTION_SIGNATURES = [\n CREATE_PROXY_SIGNATURE,\n SAFE_EXEC_TRANSACTION_SIGNATURE,\n];\n\nexport function buildAcrossActionFromCall(\n call: AcrossDestinationCall,\n request: QuoteRequest,\n): AcrossAction {\n if (isTransferCall(call.data)) {\n return buildAcrossTransferAction(call, request);\n }\n\n const parsedCall = parseAcrossActionCall(call.data);\n\n return {\n args: Array.from(parsedCall.transaction.args).map((arg) => ({\n populateDynamically: false,\n value: serializeAcrossActionValue(arg),\n })),\n functionSignature: parsedCall.functionSignature,\n isNativeTransfer: false,\n target: getRequiredTarget(call),\n value: '0',\n };\n}\n\nexport function getTransferRecipient(data: Hex): Hex {\n const parsedCall = tryParseTransferCall(data);\n\n if (!parsedCall) {\n throw new Error(getUnsupportedDestinationErrorMessage(data));\n }\n\n return normalizeHexString(String(parsedCall.args[0])) as Hex;\n}\n\nexport function getAcrossDestination(\n transaction: TransactionMeta,\n request: QuoteRequest,\n): AcrossDestination {\n if (isSupportedAcrossPerpsDepositRequest(request, transaction.type)) {\n return {\n actions: [],\n recipient: request.from,\n };\n }\n\n const { from } = request;\n const destinationCalls = getDestinationCalls(transaction);\n const swapRecipientTransferCallIndex = destinationCalls.findIndex((call) =>\n isExtractableOutputTokenTransferCall(call, request),\n );\n const callsForActions = [...destinationCalls];\n let recipient = from;\n\n if (swapRecipientTransferCallIndex !== -1) {\n const [swapRecipientTransferCall] = callsForActions.splice(\n swapRecipientTransferCallIndex,\n 1,\n );\n\n recipient = getTransferRecipient(swapRecipientTransferCall.data);\n }\n\n return {\n actions: callsForActions.map((call) =>\n buildAcrossActionFromCall(call, request),\n ),\n recipient,\n };\n}\n\nexport function isExtractableOutputTokenTransferCall(\n call: AcrossDestinationCall,\n request: QuoteRequest,\n): boolean {\n return (\n isTransferCall(call.data) &&\n (call.target === undefined ||\n normalizeHexString(call.target) ===\n normalizeHexString(request.targetTokenAddress))\n );\n}\n\nfunction getRequiredTarget(call: AcrossDestinationCall): Hex {\n if (!call.target) {\n throw new Error(UNSUPPORTED_DESTINATION_ERROR);\n }\n\n return call.target;\n}\n\nfunction normalizeHexString(value: string): string {\n /* istanbul ignore next: current supported Across action signatures only emit hex strings here. */\n if (!value.startsWith('0x')) {\n return value;\n }\n\n return value.toLowerCase();\n}\n\nfunction parseAcrossActionCall(data: Hex): ParsedAcrossActionCall {\n const parsedCall = tryParseAcrossActionCall(data);\n\n if (!parsedCall) {\n throw new Error(getUnsupportedDestinationErrorMessage(data));\n }\n\n return parsedCall;\n}\n\nfunction serializeAcrossActionValue(value: unknown): AcrossActionArg['value'] {\n if (Array.isArray(value)) {\n return value.map((entry) =>\n serializeAcrossActionScalar(entry),\n ) as AcrossActionArg['value'];\n }\n\n return serializeAcrossActionScalar(value);\n}\n\nfunction buildAcrossTransferAction(\n call: AcrossDestinationCall,\n request: QuoteRequest,\n): AcrossAction {\n return {\n args: [\n {\n populateDynamically: false,\n value: getTransferRecipient(call.data),\n },\n {\n balanceSourceToken: request.targetTokenAddress,\n populateDynamically: true,\n value: '0',\n },\n ],\n functionSignature: TOKEN_TRANSFER_SIGNATURE,\n isNativeTransfer: false,\n target: call.target ?? request.targetTokenAddress,\n value: '0',\n };\n}\n\nfunction getDestinationCalls(\n transaction: TransactionMeta,\n): AcrossDestinationCall[] {\n const nestedCalls = (\n transaction.nestedTransactions ?? []\n ).flatMap<AcrossDestinationCall>((nestedTx: { data?: Hex; to?: Hex }) =>\n nestedTx.data !== undefined && nestedTx.data !== '0x'\n ? [{ data: nestedTx.data, target: nestedTx.to }]\n : [],\n );\n\n if (nestedCalls.length > 0) {\n return nestedCalls;\n }\n\n const data = transaction.txParams?.data as Hex | undefined;\n\n if (data === undefined || data === '0x') {\n return [];\n }\n\n return [\n {\n data,\n target: transaction.txParams?.to as Hex | undefined,\n },\n ];\n}\n\nfunction getUnsupportedDestinationErrorMessage(data?: Hex): string {\n const selector = getDestinationSelector(data);\n\n return selector\n ? `${UNSUPPORTED_DESTINATION_ERROR}. Destination selector: ${selector}`\n : UNSUPPORTED_DESTINATION_ERROR;\n}\n\nfunction getDestinationSelector(data?: Hex): Hex | undefined {\n if (!data || data.length < 10) {\n return undefined;\n }\n\n return data.slice(0, 10).toLowerCase() as Hex;\n}\n\nfunction serializeAcrossActionScalar(value: unknown): string {\n if (typeof value === 'string') {\n return normalizeHexString(value);\n }\n\n if (\n typeof value === 'number' ||\n typeof value === 'bigint' ||\n typeof value === 'boolean'\n ) {\n return String(value);\n }\n\n if (isBigNumberLike(value)) {\n return value.toString();\n }\n\n /* istanbul ignore next: supported Across action ABIs only decode scalars and tuples of scalars. */\n throw new Error(UNSUPPORTED_DESTINATION_ERROR);\n}\n\nfunction isBigNumberLike(value: unknown): value is BigNumberLike {\n return (\n typeof value === 'object' &&\n value !== null &&\n '_isBigNumber' in value &&\n value._isBigNumber === true &&\n 'toString' in value &&\n typeof value.toString === 'function'\n );\n}\n\nfunction isTransferCall(data: Hex): boolean {\n return tryParseTransferCall(data) !== undefined;\n}\n\nfunction tryParseAcrossActionCall(\n data: Hex,\n): ParsedAcrossActionCall | undefined {\n for (const functionSignature of ACROSS_ACTION_SIGNATURES) {\n try {\n const actionInterface = new Interface([functionSignature]);\n\n return {\n functionSignature,\n transaction: actionInterface.parseTransaction({ data }),\n };\n } catch {\n // Intentionally empty.\n }\n }\n\n return undefined;\n}\n\nfunction tryParseTransferCall(data: Hex): TransactionDescription | undefined {\n try {\n return new Interface([TOKEN_TRANSFER_SIGNATURE]).parseTransaction({ data });\n } catch {\n return undefined;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"across-actions.d.cts","sourceRoot":"","sources":["../../../src/strategy/across/across-actions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,KAAK,EAAE,YAAY,EAAmB,oBAAgB;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,wBAAoB;AAEhD,eAAO,MAAM,wBAAwB,iDACW,CAAC;AACjD,eAAO,MAAM,sBAAsB,4IACwG,CAAC;AAC5I,eAAO,MAAM,+BAA+B,uMAC0J,CAAC;AAEvM,eAAO,MAAM,6BAA6B,iHACsE,CAAC;AAEjH,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,GAAG,CAAC;IACV,MAAM,CAAC,EAAE,GAAG,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,SAAS,EAAE,GAAG,CAAC;CAChB,CAAC;AAiBF,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,qBAAqB,EAC3B,OAAO,EAAE,YAAY,GACpB,YAAY,CAiBd;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,GAAG,GAAG,GAAG,CAQnD;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,eAAe,EAC5B,OAAO,EAAE,YAAY,GACpB,iBAAiB,CAwBnB;AAED,wBAAgB,oCAAoC,CAClD,IAAI,EAAE,qBAAqB,EAC3B,OAAO,EAAE,YAAY,GACpB,OAAO,CAOT"}
1
+ {"version":3,"file":"across-actions.d.cts","sourceRoot":"","sources":["../../../src/strategy/across/across-actions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAG3C,OAAO,KAAK,EAAE,YAAY,EAAmB,oBAAgB;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,wBAAoB;AAEhD,eAAO,MAAM,wBAAwB,iDACW,CAAC;AACjD,eAAO,MAAM,sBAAsB,4IACwG,CAAC;AAC5I,eAAO,MAAM,+BAA+B,uMAC0J,CAAC;AAEvM,eAAO,MAAM,6BAA6B,iHACsE,CAAC;AAEjH,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,GAAG,CAAC;IACV,MAAM,CAAC,EAAE,GAAG,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,SAAS,EAAE,GAAG,CAAC;CAChB,CAAC;AAiBF,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,qBAAqB,EAC3B,OAAO,EAAE,YAAY,GACpB,YAAY,CAiBd;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,GAAG,GAAG,GAAG,CAQnD;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,eAAe,EAC5B,OAAO,EAAE,YAAY,GACpB,iBAAiB,CA+BnB;AAED,wBAAgB,oCAAoC,CAClD,IAAI,EAAE,qBAAqB,EAC3B,OAAO,EAAE,YAAY,GACpB,OAAO,CAOT"}
@@ -1 +1 @@
1
- {"version":3,"file":"across-actions.d.mts","sourceRoot":"","sources":["../../../src/strategy/across/across-actions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,KAAK,EAAE,YAAY,EAAmB,oBAAgB;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,wBAAoB;AAEhD,eAAO,MAAM,wBAAwB,iDACW,CAAC;AACjD,eAAO,MAAM,sBAAsB,4IACwG,CAAC;AAC5I,eAAO,MAAM,+BAA+B,uMAC0J,CAAC;AAEvM,eAAO,MAAM,6BAA6B,iHACsE,CAAC;AAEjH,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,GAAG,CAAC;IACV,MAAM,CAAC,EAAE,GAAG,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,SAAS,EAAE,GAAG,CAAC;CAChB,CAAC;AAiBF,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,qBAAqB,EAC3B,OAAO,EAAE,YAAY,GACpB,YAAY,CAiBd;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,GAAG,GAAG,GAAG,CAQnD;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,eAAe,EAC5B,OAAO,EAAE,YAAY,GACpB,iBAAiB,CAwBnB;AAED,wBAAgB,oCAAoC,CAClD,IAAI,EAAE,qBAAqB,EAC3B,OAAO,EAAE,YAAY,GACpB,OAAO,CAOT"}
1
+ {"version":3,"file":"across-actions.d.mts","sourceRoot":"","sources":["../../../src/strategy/across/across-actions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAG3C,OAAO,KAAK,EAAE,YAAY,EAAmB,oBAAgB;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,wBAAoB;AAEhD,eAAO,MAAM,wBAAwB,iDACW,CAAC;AACjD,eAAO,MAAM,sBAAsB,4IACwG,CAAC;AAC5I,eAAO,MAAM,+BAA+B,uMAC0J,CAAC;AAEvM,eAAO,MAAM,6BAA6B,iHACsE,CAAC;AAEjH,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,GAAG,CAAC;IACV,MAAM,CAAC,EAAE,GAAG,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,SAAS,EAAE,GAAG,CAAC;CAChB,CAAC;AAiBF,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,qBAAqB,EAC3B,OAAO,EAAE,YAAY,GACpB,YAAY,CAiBd;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,GAAG,GAAG,GAAG,CAQnD;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,eAAe,EAC5B,OAAO,EAAE,YAAY,GACpB,iBAAiB,CA+BnB;AAED,wBAAgB,oCAAoC,CAClD,IAAI,EAAE,qBAAqB,EAC3B,OAAO,EAAE,YAAY,GACpB,OAAO,CAOT"}
@@ -1,4 +1,5 @@
1
1
  import { Interface } from "@ethersproject/abi";
2
+ import { isSupportedAcrossPerpsDepositRequest } from "./perps.mjs";
2
3
  export const TOKEN_TRANSFER_SIGNATURE = 'function transfer(address to, uint256 value)';
3
4
  export const CREATE_PROXY_SIGNATURE = 'function createProxy(address paymentToken, uint256 payment, address payable paymentReceiver, (uint8 v, bytes32 r, bytes32 s) createSig)';
4
5
  export const SAFE_EXEC_TRANSACTION_SIGNATURE = 'function execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures)';
@@ -31,6 +32,12 @@ export function getTransferRecipient(data) {
31
32
  return normalizeHexString(String(parsedCall.args[0]));
32
33
  }
33
34
  export function getAcrossDestination(transaction, request) {
35
+ if (isSupportedAcrossPerpsDepositRequest(request, transaction.type)) {
36
+ return {
37
+ actions: [],
38
+ recipient: request.from,
39
+ };
40
+ }
34
41
  const { from } = request;
35
42
  const destinationCalls = getDestinationCalls(transaction);
36
43
  const swapRecipientTransferCallIndex = destinationCalls.findIndex((call) => isExtractableOutputTokenTransferCall(call, request));
@@ -1 +1 @@
1
- {"version":3,"file":"across-actions.mjs","sourceRoot":"","sources":["../../../src/strategy/across/across-actions.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport type { TransactionDescription } from '@ethersproject/abi';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport type { AcrossAction, AcrossActionArg } from './types';\nimport type { QuoteRequest } from '../../types';\n\nexport const TOKEN_TRANSFER_SIGNATURE =\n 'function transfer(address to, uint256 value)';\nexport const CREATE_PROXY_SIGNATURE =\n 'function createProxy(address paymentToken, uint256 payment, address payable paymentReceiver, (uint8 v, bytes32 r, bytes32 s) createSig)';\nexport const SAFE_EXEC_TRANSACTION_SIGNATURE =\n 'function execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures)';\n\nexport const UNSUPPORTED_DESTINATION_ERROR =\n 'Across only supports direct token transfers and a limited set of post-swap destination actions at the moment';\n\nexport type AcrossDestinationCall = {\n data: Hex;\n target?: Hex;\n};\n\nexport type AcrossDestination = {\n actions: AcrossAction[];\n recipient: Hex;\n};\n\ntype ParsedAcrossActionCall = {\n functionSignature: string;\n transaction: TransactionDescription;\n};\n\ntype BigNumberLike = {\n _isBigNumber: true;\n toString: () => string;\n};\n\nconst ACROSS_ACTION_SIGNATURES = [\n CREATE_PROXY_SIGNATURE,\n SAFE_EXEC_TRANSACTION_SIGNATURE,\n];\n\nexport function buildAcrossActionFromCall(\n call: AcrossDestinationCall,\n request: QuoteRequest,\n): AcrossAction {\n if (isTransferCall(call.data)) {\n return buildAcrossTransferAction(call, request);\n }\n\n const parsedCall = parseAcrossActionCall(call.data);\n\n return {\n args: Array.from(parsedCall.transaction.args).map((arg) => ({\n populateDynamically: false,\n value: serializeAcrossActionValue(arg),\n })),\n functionSignature: parsedCall.functionSignature,\n isNativeTransfer: false,\n target: getRequiredTarget(call),\n value: '0',\n };\n}\n\nexport function getTransferRecipient(data: Hex): Hex {\n const parsedCall = tryParseTransferCall(data);\n\n if (!parsedCall) {\n throw new Error(getUnsupportedDestinationErrorMessage(data));\n }\n\n return normalizeHexString(String(parsedCall.args[0])) as Hex;\n}\n\nexport function getAcrossDestination(\n transaction: TransactionMeta,\n request: QuoteRequest,\n): AcrossDestination {\n const { from } = request;\n const destinationCalls = getDestinationCalls(transaction);\n const swapRecipientTransferCallIndex = destinationCalls.findIndex((call) =>\n isExtractableOutputTokenTransferCall(call, request),\n );\n const callsForActions = [...destinationCalls];\n let recipient = from;\n\n if (swapRecipientTransferCallIndex !== -1) {\n const [swapRecipientTransferCall] = callsForActions.splice(\n swapRecipientTransferCallIndex,\n 1,\n );\n\n recipient = getTransferRecipient(swapRecipientTransferCall.data);\n }\n\n return {\n actions: callsForActions.map((call) =>\n buildAcrossActionFromCall(call, request),\n ),\n recipient,\n };\n}\n\nexport function isExtractableOutputTokenTransferCall(\n call: AcrossDestinationCall,\n request: QuoteRequest,\n): boolean {\n return (\n isTransferCall(call.data) &&\n (call.target === undefined ||\n normalizeHexString(call.target) ===\n normalizeHexString(request.targetTokenAddress))\n );\n}\n\nfunction getRequiredTarget(call: AcrossDestinationCall): Hex {\n if (!call.target) {\n throw new Error(UNSUPPORTED_DESTINATION_ERROR);\n }\n\n return call.target;\n}\n\nfunction normalizeHexString(value: string): string {\n /* istanbul ignore next: current supported Across action signatures only emit hex strings here. */\n if (!value.startsWith('0x')) {\n return value;\n }\n\n return value.toLowerCase();\n}\n\nfunction parseAcrossActionCall(data: Hex): ParsedAcrossActionCall {\n const parsedCall = tryParseAcrossActionCall(data);\n\n if (!parsedCall) {\n throw new Error(getUnsupportedDestinationErrorMessage(data));\n }\n\n return parsedCall;\n}\n\nfunction serializeAcrossActionValue(value: unknown): AcrossActionArg['value'] {\n if (Array.isArray(value)) {\n return value.map((entry) =>\n serializeAcrossActionScalar(entry),\n ) as AcrossActionArg['value'];\n }\n\n return serializeAcrossActionScalar(value);\n}\n\nfunction buildAcrossTransferAction(\n call: AcrossDestinationCall,\n request: QuoteRequest,\n): AcrossAction {\n return {\n args: [\n {\n populateDynamically: false,\n value: getTransferRecipient(call.data),\n },\n {\n balanceSourceToken: request.targetTokenAddress,\n populateDynamically: true,\n value: '0',\n },\n ],\n functionSignature: TOKEN_TRANSFER_SIGNATURE,\n isNativeTransfer: false,\n target: call.target ?? request.targetTokenAddress,\n value: '0',\n };\n}\n\nfunction getDestinationCalls(\n transaction: TransactionMeta,\n): AcrossDestinationCall[] {\n const nestedCalls = (\n transaction.nestedTransactions ?? []\n ).flatMap<AcrossDestinationCall>((nestedTx: { data?: Hex; to?: Hex }) =>\n nestedTx.data !== undefined && nestedTx.data !== '0x'\n ? [{ data: nestedTx.data, target: nestedTx.to }]\n : [],\n );\n\n if (nestedCalls.length > 0) {\n return nestedCalls;\n }\n\n const data = transaction.txParams?.data as Hex | undefined;\n\n if (data === undefined || data === '0x') {\n return [];\n }\n\n return [\n {\n data,\n target: transaction.txParams?.to as Hex | undefined,\n },\n ];\n}\n\nfunction getUnsupportedDestinationErrorMessage(data?: Hex): string {\n const selector = getDestinationSelector(data);\n\n return selector\n ? `${UNSUPPORTED_DESTINATION_ERROR}. Destination selector: ${selector}`\n : UNSUPPORTED_DESTINATION_ERROR;\n}\n\nfunction getDestinationSelector(data?: Hex): Hex | undefined {\n if (!data || data.length < 10) {\n return undefined;\n }\n\n return data.slice(0, 10).toLowerCase() as Hex;\n}\n\nfunction serializeAcrossActionScalar(value: unknown): string {\n if (typeof value === 'string') {\n return normalizeHexString(value);\n }\n\n if (\n typeof value === 'number' ||\n typeof value === 'bigint' ||\n typeof value === 'boolean'\n ) {\n return String(value);\n }\n\n if (isBigNumberLike(value)) {\n return value.toString();\n }\n\n /* istanbul ignore next: supported Across action ABIs only decode scalars and tuples of scalars. */\n throw new Error(UNSUPPORTED_DESTINATION_ERROR);\n}\n\nfunction isBigNumberLike(value: unknown): value is BigNumberLike {\n return (\n typeof value === 'object' &&\n value !== null &&\n '_isBigNumber' in value &&\n value._isBigNumber === true &&\n 'toString' in value &&\n typeof value.toString === 'function'\n );\n}\n\nfunction isTransferCall(data: Hex): boolean {\n return tryParseTransferCall(data) !== undefined;\n}\n\nfunction tryParseAcrossActionCall(\n data: Hex,\n): ParsedAcrossActionCall | undefined {\n for (const functionSignature of ACROSS_ACTION_SIGNATURES) {\n try {\n const actionInterface = new Interface([functionSignature]);\n\n return {\n functionSignature,\n transaction: actionInterface.parseTransaction({ data }),\n };\n } catch {\n // Intentionally empty.\n }\n }\n\n return undefined;\n}\n\nfunction tryParseTransferCall(data: Hex): TransactionDescription | undefined {\n try {\n return new Interface([TOKEN_TRANSFER_SIGNATURE]).parseTransaction({ data });\n } catch {\n return undefined;\n }\n}\n"]}
1
+ {"version":3,"file":"across-actions.mjs","sourceRoot":"","sources":["../../../src/strategy/across/across-actions.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport type { TransactionDescription } from '@ethersproject/abi';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport { isSupportedAcrossPerpsDepositRequest } from './perps';\nimport type { AcrossAction, AcrossActionArg } from './types';\nimport type { QuoteRequest } from '../../types';\n\nexport const TOKEN_TRANSFER_SIGNATURE =\n 'function transfer(address to, uint256 value)';\nexport const CREATE_PROXY_SIGNATURE =\n 'function createProxy(address paymentToken, uint256 payment, address payable paymentReceiver, (uint8 v, bytes32 r, bytes32 s) createSig)';\nexport const SAFE_EXEC_TRANSACTION_SIGNATURE =\n 'function execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures)';\n\nexport const UNSUPPORTED_DESTINATION_ERROR =\n 'Across only supports direct token transfers and a limited set of post-swap destination actions at the moment';\n\nexport type AcrossDestinationCall = {\n data: Hex;\n target?: Hex;\n};\n\nexport type AcrossDestination = {\n actions: AcrossAction[];\n recipient: Hex;\n};\n\ntype ParsedAcrossActionCall = {\n functionSignature: string;\n transaction: TransactionDescription;\n};\n\ntype BigNumberLike = {\n _isBigNumber: true;\n toString: () => string;\n};\n\nconst ACROSS_ACTION_SIGNATURES = [\n CREATE_PROXY_SIGNATURE,\n SAFE_EXEC_TRANSACTION_SIGNATURE,\n];\n\nexport function buildAcrossActionFromCall(\n call: AcrossDestinationCall,\n request: QuoteRequest,\n): AcrossAction {\n if (isTransferCall(call.data)) {\n return buildAcrossTransferAction(call, request);\n }\n\n const parsedCall = parseAcrossActionCall(call.data);\n\n return {\n args: Array.from(parsedCall.transaction.args).map((arg) => ({\n populateDynamically: false,\n value: serializeAcrossActionValue(arg),\n })),\n functionSignature: parsedCall.functionSignature,\n isNativeTransfer: false,\n target: getRequiredTarget(call),\n value: '0',\n };\n}\n\nexport function getTransferRecipient(data: Hex): Hex {\n const parsedCall = tryParseTransferCall(data);\n\n if (!parsedCall) {\n throw new Error(getUnsupportedDestinationErrorMessage(data));\n }\n\n return normalizeHexString(String(parsedCall.args[0])) as Hex;\n}\n\nexport function getAcrossDestination(\n transaction: TransactionMeta,\n request: QuoteRequest,\n): AcrossDestination {\n if (isSupportedAcrossPerpsDepositRequest(request, transaction.type)) {\n return {\n actions: [],\n recipient: request.from,\n };\n }\n\n const { from } = request;\n const destinationCalls = getDestinationCalls(transaction);\n const swapRecipientTransferCallIndex = destinationCalls.findIndex((call) =>\n isExtractableOutputTokenTransferCall(call, request),\n );\n const callsForActions = [...destinationCalls];\n let recipient = from;\n\n if (swapRecipientTransferCallIndex !== -1) {\n const [swapRecipientTransferCall] = callsForActions.splice(\n swapRecipientTransferCallIndex,\n 1,\n );\n\n recipient = getTransferRecipient(swapRecipientTransferCall.data);\n }\n\n return {\n actions: callsForActions.map((call) =>\n buildAcrossActionFromCall(call, request),\n ),\n recipient,\n };\n}\n\nexport function isExtractableOutputTokenTransferCall(\n call: AcrossDestinationCall,\n request: QuoteRequest,\n): boolean {\n return (\n isTransferCall(call.data) &&\n (call.target === undefined ||\n normalizeHexString(call.target) ===\n normalizeHexString(request.targetTokenAddress))\n );\n}\n\nfunction getRequiredTarget(call: AcrossDestinationCall): Hex {\n if (!call.target) {\n throw new Error(UNSUPPORTED_DESTINATION_ERROR);\n }\n\n return call.target;\n}\n\nfunction normalizeHexString(value: string): string {\n /* istanbul ignore next: current supported Across action signatures only emit hex strings here. */\n if (!value.startsWith('0x')) {\n return value;\n }\n\n return value.toLowerCase();\n}\n\nfunction parseAcrossActionCall(data: Hex): ParsedAcrossActionCall {\n const parsedCall = tryParseAcrossActionCall(data);\n\n if (!parsedCall) {\n throw new Error(getUnsupportedDestinationErrorMessage(data));\n }\n\n return parsedCall;\n}\n\nfunction serializeAcrossActionValue(value: unknown): AcrossActionArg['value'] {\n if (Array.isArray(value)) {\n return value.map((entry) =>\n serializeAcrossActionScalar(entry),\n ) as AcrossActionArg['value'];\n }\n\n return serializeAcrossActionScalar(value);\n}\n\nfunction buildAcrossTransferAction(\n call: AcrossDestinationCall,\n request: QuoteRequest,\n): AcrossAction {\n return {\n args: [\n {\n populateDynamically: false,\n value: getTransferRecipient(call.data),\n },\n {\n balanceSourceToken: request.targetTokenAddress,\n populateDynamically: true,\n value: '0',\n },\n ],\n functionSignature: TOKEN_TRANSFER_SIGNATURE,\n isNativeTransfer: false,\n target: call.target ?? request.targetTokenAddress,\n value: '0',\n };\n}\n\nfunction getDestinationCalls(\n transaction: TransactionMeta,\n): AcrossDestinationCall[] {\n const nestedCalls = (\n transaction.nestedTransactions ?? []\n ).flatMap<AcrossDestinationCall>((nestedTx: { data?: Hex; to?: Hex }) =>\n nestedTx.data !== undefined && nestedTx.data !== '0x'\n ? [{ data: nestedTx.data, target: nestedTx.to }]\n : [],\n );\n\n if (nestedCalls.length > 0) {\n return nestedCalls;\n }\n\n const data = transaction.txParams?.data as Hex | undefined;\n\n if (data === undefined || data === '0x') {\n return [];\n }\n\n return [\n {\n data,\n target: transaction.txParams?.to as Hex | undefined,\n },\n ];\n}\n\nfunction getUnsupportedDestinationErrorMessage(data?: Hex): string {\n const selector = getDestinationSelector(data);\n\n return selector\n ? `${UNSUPPORTED_DESTINATION_ERROR}. Destination selector: ${selector}`\n : UNSUPPORTED_DESTINATION_ERROR;\n}\n\nfunction getDestinationSelector(data?: Hex): Hex | undefined {\n if (!data || data.length < 10) {\n return undefined;\n }\n\n return data.slice(0, 10).toLowerCase() as Hex;\n}\n\nfunction serializeAcrossActionScalar(value: unknown): string {\n if (typeof value === 'string') {\n return normalizeHexString(value);\n }\n\n if (\n typeof value === 'number' ||\n typeof value === 'bigint' ||\n typeof value === 'boolean'\n ) {\n return String(value);\n }\n\n if (isBigNumberLike(value)) {\n return value.toString();\n }\n\n /* istanbul ignore next: supported Across action ABIs only decode scalars and tuples of scalars. */\n throw new Error(UNSUPPORTED_DESTINATION_ERROR);\n}\n\nfunction isBigNumberLike(value: unknown): value is BigNumberLike {\n return (\n typeof value === 'object' &&\n value !== null &&\n '_isBigNumber' in value &&\n value._isBigNumber === true &&\n 'toString' in value &&\n typeof value.toString === 'function'\n );\n}\n\nfunction isTransferCall(data: Hex): boolean {\n return tryParseTransferCall(data) !== undefined;\n}\n\nfunction tryParseAcrossActionCall(\n data: Hex,\n): ParsedAcrossActionCall | undefined {\n for (const functionSignature of ACROSS_ACTION_SIGNATURES) {\n try {\n const actionInterface = new Interface([functionSignature]);\n\n return {\n functionSignature,\n transaction: actionInterface.parseTransaction({ data }),\n };\n } catch {\n // Intentionally empty.\n }\n }\n\n return undefined;\n}\n\nfunction tryParseTransferCall(data: Hex): TransactionDescription | undefined {\n try {\n return new Interface([TOKEN_TRANSFER_SIGNATURE]).parseTransaction({ data });\n } catch {\n return undefined;\n }\n}\n"]}
@@ -5,6 +5,7 @@ const controller_utils_1 = require("@metamask/controller-utils");
5
5
  const utils_1 = require("@metamask/utils");
6
6
  const bignumber_js_1 = require("bignumber.js");
7
7
  const across_actions_1 = require("./across-actions.cjs");
8
+ const perps_1 = require("./perps.cjs");
8
9
  const transactions_1 = require("./transactions.cjs");
9
10
  const constants_1 = require("../../constants.cjs");
10
11
  const logger_1 = require("../../logger.cjs");
@@ -44,7 +45,8 @@ async function getAcrossQuotes(request) {
44
45
  exports.getAcrossQuotes = getAcrossQuotes;
45
46
  async function getSingleQuote(request, fullRequest) {
46
47
  const { messenger, transaction } = fullRequest;
47
- const { from, isMaxAmount, sourceChainId, sourceTokenAddress, sourceTokenAmount, targetAmountMinimum, targetChainId, targetTokenAddress, } = request;
48
+ const normalizedRequest = (0, perps_1.normalizeAcrossRequest)(request, transaction.type);
49
+ const { from, isMaxAmount, sourceChainId, sourceTokenAddress, sourceTokenAmount, targetAmountMinimum, targetChainId, targetTokenAddress, } = normalizedRequest;
48
50
  const config = (0, feature_flags_1.getPayStrategiesConfig)(messenger);
49
51
  const slippageDecimal = (0, feature_flags_1.getSlippage)(messenger, sourceChainId, sourceTokenAddress);
50
52
  const amount = isMaxAmount ? sourceTokenAmount : targetAmountMinimum;
@@ -70,7 +72,7 @@ async function getSingleQuote(request, fullRequest) {
70
72
  tradeType,
71
73
  },
72
74
  };
73
- return await normalizeQuote(originalQuote, request, fullRequest);
75
+ return await normalizeQuote(originalQuote, normalizedRequest, fullRequest);
74
76
  }
75
77
  async function requestAcrossApproval(request) {
76
78
  const { actions, amount, apiBase, depositor, destinationChainId, inputToken, originChainId, outputToken, recipient, slippage, tradeType, } = request;
@@ -1 +1 @@
1
- {"version":3,"file":"across-quotes.cjs","sourceRoot":"","sources":["../../../src/strategy/across/across-quotes.ts"],"names":[],"mappings":";;;AAAA,iEAAoE;AAEpE,2CAAqD;AACrD,+CAAyC;AAEzC,yDAAwD;AACxD,qDAA8D;AAQ9D,mDAAyD;AACzD,6CAA6C;AAS7C,qDAAsE;AACtE,iEAAgF;AAChF,6CAAmD;AACnD,yDAA+D;AAC/D,iDAAqD;AAErD,MAAM,GAAG,GAAG,IAAA,0BAAkB,EAAC,sBAAa,EAAE,iBAAiB,CAAC,CAAC;AAEjE,MAAM,oCAAoC,GACxC,iEAAiE,CAAC;AAIpE;;;;;GAKG;AACI,KAAK,UAAU,eAAe,CACnC,OAAoC;IAEpC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAE7B,GAAG,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;IAEjC,IAAI,CAAC;QACH,MAAM,kBAAkB,GAAG,QAAQ,CAAC,MAAM,CACxC,CAAC,aAAa,EAAE,EAAE,CAChB,aAAa,CAAC,WAAW,KAAK,IAAI;YAClC,CAAC,aAAa,CAAC,mBAAmB,KAAK,SAAS;gBAC9C,aAAa,CAAC,mBAAmB,KAAK,GAAG,CAAC,CAC/C,CAAC;QAEF,IAAI,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,IAAI,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,CAAC;YAC5D,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACxD,CAAC;QAED,OAAO,MAAM,OAAO,CAAC,GAAG,CACtB,kBAAkB,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,EAAE,CACvC,cAAc,CAAC,aAAa,EAAE,OAAO,CAAC,CACvC,CACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,uBAAuB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,kCAAkC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACrE,CAAC;AACH,CAAC;AAhCD,0CAgCC;AAED,KAAK,UAAU,cAAc,CAC3B,OAAqB,EACrB,WAAwC;IAExC,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,WAAW,CAAC;IAC/C,MAAM,EACJ,IAAI,EACJ,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,kBAAkB,GACnB,GAAG,OAAO,CAAC;IAEZ,MAAM,MAAM,GAAG,IAAA,sCAAsB,EAAC,SAAS,CAAC,CAAC;IACjD,MAAM,eAAe,GAAG,IAAA,2BAAW,EACjC,SAAS,EACT,aAAa,EACb,kBAAkB,CACnB,CAAC;IAEF,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,mBAAmB,CAAC;IACrE,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC;IAC7D,MAAM,WAAW,GAAG,IAAA,qCAAoB,EAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,MAAM,qBAAqB,CAAC;QACxC,OAAO,EAAE,WAAW,CAAC,OAAO;QAC5B,MAAM;QACN,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO;QAC9B,SAAS,EAAE,IAAI;QACf,kBAAkB,EAAE,aAAa;QACjC,UAAU,EAAE,kBAAkB;QAC9B,aAAa,EAAE,aAAa;QAC5B,WAAW,EAAE,kBAAkB;QAC/B,SAAS,EAAE,WAAW,CAAC,SAAS;QAChC,QAAQ,EAAE,eAAe;QACzB,SAAS;KACV,CAAC,CAAC;IAEH,MAAM,aAAa,GAA+B;QAChD,KAAK;QACL,OAAO,EAAE;YACP,MAAM;YACN,SAAS;SACV;KACF,CAAC;IAEF,OAAO,MAAM,cAAc,CAAC,aAAa,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;AACnE,CAAC;AAgBD,KAAK,UAAU,qBAAqB,CAClC,OAA8B;IAE9B,MAAM,EACJ,OAAO,EACP,MAAM,EACN,OAAO,EACP,SAAS,EACT,kBAAkB,EAClB,UAAU,EACV,aAAa,EACb,WAAW,EACX,SAAS,EACT,QAAQ,EACR,SAAS,GACV,GAAG,OAAO,CAAC;IAEZ,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;IACrC,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACnC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC7B,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IACrC,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;IACvC,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACjE,MAAM,CAAC,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,QAAQ,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3E,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACnC,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAEnC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,IAAI,GAA4B,EAAE,OAAO,EAAE,CAAC;IAClD,MAAM,GAAG,GAAG,GAAG,OAAO,kBAAkB,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC5D,MAAM,OAAO,GAAgB;QAC3B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;QAC1B,OAAO,EAAE;YACP,MAAM,EAAE,kBAAkB;YAC1B,cAAc,EAAE,kBAAkB;SACnC;QACD,MAAM,EAAE,MAAM;KACf,CAAC;IACF,MAAM,QAAQ,GAAG,MAAM,IAAA,kCAAe,EAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAErD,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA+B,CAAC;AAC/D,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,QAAoC,EACpC,OAAqB,EACrB,WAAwC;IAExC,MAAM,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC;IAClC,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC;IAE3B,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,GAAG,YAAY,CACpE,SAAS,EACT,KAAK,CACN,CAAC;IAEF,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;IACjE,MAAM,IAAI,GAAG,IAAA,6BAAmB,EAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAEzD,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,0BAA0B,CAC3E,KAAK,EACL,SAAS,EACT,OAAO,CACR,CAAC;IAEF,MAAM,aAAa,GAAG,IAAA,6BAAmB,EAAC,IAAI,wBAAS,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;IAE3E,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,IAAI,GAAG,CAAC;IAChD,MAAM,eAAe,GAAG,IAAI,wBAAS,CACnC,KAAK,CAAC,oBAAoB;QACxB,KAAK,CAAC,eAAe;QACrB,OAAO,CAAC,mBAAmB;QAC3B,GAAG,CACN,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAEf,MAAM,YAAY,GAAG,wBAAwB,CAAC;QAC5C,SAAS,EAAE,cAAc;QACzB,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,QAAQ;QACnC,QAAQ,EAAE,cAAc;KACzB,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,oBAAoB,CACtC,KAAK,EACL,cAAc,EACd,cAAc,EACd,cAAc,EACd,KAAK,CAAC,oBAAoB,CAC3B,CAAC;IACF,MAAM,QAAQ,GAAG,IAAA,6BAAmB,EAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IACjE,MAAM,WAAW,GAAG,IAAA,6BAAmB,EACrC,IAAI,wBAAS,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,EACtD,aAAa,CACd,CAAC;IAEF,MAAM,YAAY,GAAG,wBAAwB,CAAC;QAC5C,SAAS,EAAE,eAAe;QAC1B,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC,QAAQ;QACpC,QAAQ,EAAE,cAAc;KACzB,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG;QACf,SAAS;QACT,MAAM;KACP,CAAC;IAEF,OAAO;QACL,IAAI;QACJ,iBAAiB,EAAE,KAAK,CAAC,gBAAgB,IAAI,CAAC;QAC9C,IAAI,EAAE;YACJ,QAAQ,EAAE,WAAW;YACrB,QAAQ;YACR,aAAa;YACb,aAAa;SACd;QACD,QAAQ,EAAE;YACR,GAAG,QAAQ;YACX,QAAQ;SACT;QACD,OAAO;QACP,YAAY;QACZ,YAAY;QACZ,QAAQ,EAAE,kCAAsB,CAAC,MAAM;KACJ,CAAC;AACxC,CAAC;AAED,SAAS,YAAY,CACnB,SAA4C,EAC5C,KAAiC;IAMjC,MAAM,cAAc,GAAG,IAAA,wBAAgB,EACrC,SAAS,EACT,KAAK,CAAC,UAAU,CAAC,OAAO,EACxB,IAAA,wBAAK,EAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAChC,CAAC;IAEF,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,cAAc,GAClB,IAAA,wBAAgB,EACd,SAAS,EACT,KAAK,CAAC,WAAW,CAAC,OAAO,EACzB,IAAA,wBAAK,EAAC,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CACjC,IAAI,cAAc,CAAC;IAEtB,MAAM,aAAa,GAAG,IAAI,wBAAS,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,SAAS,CACpE,cAAc,CAAC,OAAO,CACvB,CAAC;IAEF,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC;AAC3D,CAAC;AAED,SAAS,gBAAgB,CACvB,KAAiC,EACjC,OAAqB,EACrB,cAAyB;IAEzB,MAAM,iBAAiB,GAAG,KAAK,CAAC,oBAAoB,CAAC;IAErD,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;QACpC,OAAO,IAAI,wBAAS,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,wBAAS,CAAC,iBAAiB,CAAC,CAAC;IACxD,MAAM,aAAa,GAAG,IAAI,wBAAS,CACjC,KAAK,CAAC,eAAe,IAAI,OAAO,CAAC,mBAAmB,IAAI,GAAG,CAC5D,CAAC;IAEF,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,UAAU,EAAE;QAC9D,CAAC,CAAC,IAAI,wBAAS,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAEjE,OAAO,SAAS,CAAC,YAAY,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,oBAAoB,CAC3B,KAAiC,EACjC,cAAsB,EACtB,cAAyB,EACzB,cAAyB,EACzB,iBAA0B;IAE1B,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC;IAEjD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,IAAI,wBAAS,CAAC,WAAW,CAAC,CAAC,GAAG,EAAE,CAAC;IAC1C,CAAC;IAED,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;QACpC,OAAO,IAAI,wBAAS,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,wBAAS,CAAC,iBAAiB,CAAC,CAAC;IAExD,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,wBAAS,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,wBAAS,CAAC,cAAc,CAAC;SACjD,SAAS,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC;SACrC,YAAY,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,iBAAiB,GAAG,cAAc;SACrC,SAAS,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC;SACtC,YAAY,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,cAAc,GAAG,cAAc,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAE/D,OAAO,cAAc,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,wBAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;AACzE,CAAC;AAED,SAAS,wBAAwB,CAAC,EAChC,SAAS,EACT,QAAQ,EACR,QAAQ,GAKT;IACC,MAAM,QAAQ,GAAG,IAAI,wBAAS,CAAC,SAAS,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAElC,MAAM,UAAU,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAEtC,MAAM,GAAG,GAAG,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACnE,MAAM,IAAI,GAAG,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAErE,OAAO;QACL,IAAI;QACJ,KAAK;QACL,GAAG;QACH,GAAG;KACJ,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,0BAA0B,CACvC,KAAiC,EACjC,SAA4C,EAC5C,OAAqB;IAMrB,MAAM,iBAAiB,GACrB,IAAA,sCAAsB,EAAC,SAAS,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;IACvD,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IACzB,MAAM,mBAAmB,GAAG,IAAA,2CAA4B,EAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACpE,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACzB,MAAM,WAAW,GAAG,IAAA,wBAAK,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,YAAY,GAAG,MAAM,IAAA,kCAAsB,EAAC;QAChD,WAAW,EAAE,iBAAiB;QAC9B,SAAS;QACT,YAAY,EAAE,mBAAmB,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YACtD,OAAO,EAAE,IAAA,wBAAK,EAAC,WAAW,CAAC,OAAO,CAAC;YACnC,IAAI,EAAE,WAAW,CAAC,IAAI;YACtB,IAAI;YACJ,GAAG,EAAE,WAAW,CAAC,GAAG;YACpB,EAAE,EAAE,WAAW,CAAC,EAAE;YAClB,KAAK,EAAE,WAAW,CAAC,KAAK,IAAI,KAAK;SAClC,CAAC,CAAC;KACJ,CAAC,CAAC;IACH,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC;IAE/C,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,QAAQ,GAAG,IAAA,sBAAgB,EAAC;YAChC,OAAO,EAAE,WAAW;YACpB,GAAG,EAAE,aAAa,CAAC,QAAQ;YAC3B,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,oBAAoB,EAAE,MAAM,CAAC,oBAAoB;YACjD,SAAS;SACV,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,IAAA,sBAAgB,EAAC;YAC3B,OAAO,EAAE,WAAW;YACpB,GAAG,EAAE,aAAa,CAAC,GAAG;YACtB,KAAK,EAAE,IAAI;YACX,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,oBAAoB,EAAE,MAAM,CAAC,oBAAoB;YACjD,SAAS;SACV,CAAC,CAAC;QAEH,OAAO;YACL,aAAa,EAAE;gBACb,QAAQ;gBACR,GAAG;aACJ;YACD,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE;gBACT;oBACE,QAAQ,EAAE,aAAa,CAAC,QAAQ;oBAChC,GAAG,EAAE,aAAa,CAAC,GAAG;iBACvB;aACF;SACF,CAAC;IACJ,CAAC;IAED,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,GAAG,CAClD,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QACvB,WAAW,EAAE,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC;QAC1C,WAAW;KACZ,CAAC,CACH,CAAC;IAEF,MAAM,QAAQ,GAAG,IAAA,oBAAU,EACzB,oBAAoB,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,EAAE,CACxD,IAAA,sBAAgB,EAAC;QACf,OAAO,EAAE,IAAA,wBAAK,EAAC,WAAW,CAAC,OAAO,CAAC;QACnC,GAAG,EAAE,WAAW,CAAC,QAAQ;QACzB,YAAY,EAAE,WAAW,CAAC,YAAY;QACtC,oBAAoB,EAAE,WAAW,CAAC,oBAAoB;QACtD,SAAS;KACV,CAAC,CACH,CACF,CAAC;IAEF,MAAM,GAAG,GAAG,IAAA,oBAAU,EACpB,oBAAoB,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,EAAE,CACxD,IAAA,sBAAgB,EAAC;QACf,OAAO,EAAE,IAAA,wBAAK,EAAC,WAAW,CAAC,OAAO,CAAC;QACnC,GAAG,EAAE,WAAW,CAAC,GAAG;QACpB,KAAK,EAAE,IAAI;QACX,YAAY,EAAE,WAAW,CAAC,YAAY;QACtC,oBAAoB,EAAE,WAAW,CAAC,oBAAoB;QACtD,SAAS;KACV,CAAC,CACH,CACF,CAAC;IAEF,OAAO;QACL,aAAa,EAAE;YACb,QAAQ;YACR,GAAG;SACJ;QACD,MAAM,EAAE,KAAK;QACb,SAAS,EAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC;YACxD,QAAQ,EAAE,WAAW,CAAC,QAAQ;YAC9B,GAAG,EAAE,WAAW,CAAC,GAAG;SACrB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC","sourcesContent":["import { successfulFetch, toHex } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { getAcrossDestination } from './across-actions';\nimport { getAcrossOrderedTransactions } from './transactions';\nimport type {\n AcrossAction,\n AcrossActionRequestBody,\n AcrossGasLimits,\n AcrossQuote,\n AcrossSwapApprovalResponse,\n} from './types';\nimport { TransactionPayStrategy } from '../../constants';\nimport { projectLogger } from '../../logger';\nimport type {\n Amount,\n FiatRates,\n PayStrategyGetQuotesRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types';\nimport { getFiatValueFromUsd, sumAmounts } from '../../utils/amounts';\nimport { getPayStrategiesConfig, getSlippage } from '../../utils/feature-flags';\nimport { calculateGasCost } from '../../utils/gas';\nimport { estimateQuoteGasLimits } from '../../utils/quote-gas';\nimport { getTokenFiatRate } from '../../utils/token';\n\nconst log = createModuleLogger(projectLogger, 'across-strategy');\n\nconst UNSUPPORTED_AUTHORIZATION_LIST_ERROR =\n 'Across does not support type-4/EIP-7702 authorization lists yet';\n\ntype AcrossQuoteWithoutMetaMask = Omit<AcrossQuote, 'metamask'>;\n\n/**\n * Fetch Across quotes.\n *\n * @param request - Request object.\n * @returns Array of quotes.\n */\nexport async function getAcrossQuotes(\n request: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<AcrossQuote>[]> {\n const { requests } = request;\n\n log('Fetching quotes', requests);\n\n try {\n const normalizedRequests = requests.filter(\n (singleRequest) =>\n singleRequest.isMaxAmount === true ||\n (singleRequest.targetAmountMinimum !== undefined &&\n singleRequest.targetAmountMinimum !== '0'),\n );\n\n if (normalizedRequests.length === 0) {\n return [];\n }\n\n if (request.transaction.txParams?.authorizationList?.length) {\n throw new Error(UNSUPPORTED_AUTHORIZATION_LIST_ERROR);\n }\n\n return await Promise.all(\n normalizedRequests.map((singleRequest) =>\n getSingleQuote(singleRequest, request),\n ),\n );\n } catch (error) {\n log('Error fetching quotes', { error });\n throw new Error(`Failed to fetch Across quotes: ${String(error)}`);\n }\n}\n\nasync function getSingleQuote(\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<AcrossQuote>> {\n const { messenger, transaction } = fullRequest;\n const {\n from,\n isMaxAmount,\n sourceChainId,\n sourceTokenAddress,\n sourceTokenAmount,\n targetAmountMinimum,\n targetChainId,\n targetTokenAddress,\n } = request;\n\n const config = getPayStrategiesConfig(messenger);\n const slippageDecimal = getSlippage(\n messenger,\n sourceChainId,\n sourceTokenAddress,\n );\n\n const amount = isMaxAmount ? sourceTokenAmount : targetAmountMinimum;\n const tradeType = isMaxAmount ? 'exactInput' : 'exactOutput';\n const destination = getAcrossDestination(transaction, request);\n const quote = await requestAcrossApproval({\n actions: destination.actions,\n amount,\n apiBase: config.across.apiBase,\n depositor: from,\n destinationChainId: targetChainId,\n inputToken: sourceTokenAddress,\n originChainId: sourceChainId,\n outputToken: targetTokenAddress,\n recipient: destination.recipient,\n slippage: slippageDecimal,\n tradeType,\n });\n\n const originalQuote: AcrossQuoteWithoutMetaMask = {\n quote,\n request: {\n amount,\n tradeType,\n },\n };\n\n return await normalizeQuote(originalQuote, request, fullRequest);\n}\n\ntype AcrossApprovalRequest = {\n actions: AcrossAction[];\n amount: string;\n apiBase: string;\n depositor: Hex;\n destinationChainId: Hex;\n inputToken: Hex;\n originChainId: Hex;\n outputToken: Hex;\n recipient: Hex;\n slippage?: number;\n tradeType: 'exactInput' | 'exactOutput';\n};\n\nasync function requestAcrossApproval(\n request: AcrossApprovalRequest,\n): Promise<AcrossSwapApprovalResponse> {\n const {\n actions,\n amount,\n apiBase,\n depositor,\n destinationChainId,\n inputToken,\n originChainId,\n outputToken,\n recipient,\n slippage,\n tradeType,\n } = request;\n\n const params = new URLSearchParams();\n params.set('tradeType', tradeType);\n params.set('amount', amount);\n params.set('inputToken', inputToken);\n params.set('outputToken', outputToken);\n params.set('originChainId', String(parseInt(originChainId, 16)));\n params.set('destinationChainId', String(parseInt(destinationChainId, 16)));\n params.set('depositor', depositor);\n params.set('recipient', recipient);\n\n if (slippage !== undefined) {\n params.set('slippage', String(slippage));\n }\n\n const body: AcrossActionRequestBody = { actions };\n const url = `${apiBase}/swap/approval?${params.toString()}`;\n const options: RequestInit = {\n body: JSON.stringify(body),\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n };\n const response = await successfulFetch(url, options);\n\n return (await response.json()) as AcrossSwapApprovalResponse;\n}\n\nasync function normalizeQuote(\n original: AcrossQuoteWithoutMetaMask,\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<AcrossQuote>> {\n const { messenger } = fullRequest;\n const { quote } = original;\n\n const { usdToFiatRate, sourceFiatRate, targetFiatRate } = getFiatRates(\n messenger,\n quote,\n );\n\n const dustUsd = calculateDustUsd(quote, request, targetFiatRate);\n const dust = getFiatValueFromUsd(dustUsd, usdToFiatRate);\n\n const { gasLimits, is7702, sourceNetwork } = await calculateSourceNetworkCost(\n quote,\n messenger,\n request,\n );\n\n const targetNetwork = getFiatValueFromUsd(new BigNumber(0), usdToFiatRate);\n\n const inputAmountRaw = quote.inputAmount ?? '0';\n const outputAmountRaw = new BigNumber(\n quote.expectedOutputAmount ??\n quote.minOutputAmount ??\n request.targetAmountMinimum ??\n '0',\n ).toString(10);\n\n const sourceAmount = getAmountFromTokenAmount({\n amountRaw: inputAmountRaw,\n decimals: quote.inputToken.decimals,\n fiatRate: sourceFiatRate,\n });\n\n const providerUsd = calculateProviderUsd(\n quote,\n inputAmountRaw,\n sourceFiatRate,\n targetFiatRate,\n quote.expectedOutputAmount,\n );\n const provider = getFiatValueFromUsd(providerUsd, usdToFiatRate);\n const metaMaskFee = getFiatValueFromUsd(\n new BigNumber(quote.fees?.app?.amountUsd ?? '0').abs(),\n usdToFiatRate,\n );\n\n const targetAmount = getAmountFromTokenAmount({\n amountRaw: outputAmountRaw,\n decimals: quote.outputToken.decimals,\n fiatRate: targetFiatRate,\n });\n\n const metamask = {\n gasLimits,\n is7702,\n };\n\n return {\n dust,\n estimatedDuration: quote.expectedFillTime ?? 0,\n fees: {\n metaMask: metaMaskFee,\n provider,\n sourceNetwork,\n targetNetwork,\n },\n original: {\n ...original,\n metamask,\n },\n request,\n sourceAmount,\n targetAmount,\n strategy: TransactionPayStrategy.Across,\n } as TransactionPayQuote<AcrossQuote>;\n}\n\nfunction getFiatRates(\n messenger: TransactionPayControllerMessenger,\n quote: AcrossSwapApprovalResponse,\n): {\n sourceFiatRate: FiatRates;\n targetFiatRate: FiatRates;\n usdToFiatRate: BigNumber;\n} {\n const sourceFiatRate = getTokenFiatRate(\n messenger,\n quote.inputToken.address,\n toHex(quote.inputToken.chainId),\n );\n\n if (!sourceFiatRate) {\n throw new Error('Source token fiat rate not found');\n }\n\n const targetFiatRate =\n getTokenFiatRate(\n messenger,\n quote.outputToken.address,\n toHex(quote.outputToken.chainId),\n ) ?? sourceFiatRate;\n\n const usdToFiatRate = new BigNumber(sourceFiatRate.fiatRate).dividedBy(\n sourceFiatRate.usdRate,\n );\n\n return { sourceFiatRate, targetFiatRate, usdToFiatRate };\n}\n\nfunction calculateDustUsd(\n quote: AcrossSwapApprovalResponse,\n request: QuoteRequest,\n targetFiatRate: FiatRates,\n): BigNumber {\n const expectedOutputRaw = quote.expectedOutputAmount;\n\n if (expectedOutputRaw === undefined) {\n return new BigNumber(0);\n }\n\n const expectedOutput = new BigNumber(expectedOutputRaw);\n const minimumOutput = new BigNumber(\n quote.minOutputAmount ?? request.targetAmountMinimum ?? '0',\n );\n\n const dustRaw = expectedOutput.minus(minimumOutput).isNegative()\n ? new BigNumber(0)\n : expectedOutput.minus(minimumOutput);\n const dustHuman = dustRaw.shiftedBy(-quote.outputToken.decimals);\n\n return dustHuman.multipliedBy(targetFiatRate.usdRate);\n}\n\nfunction calculateProviderUsd(\n quote: AcrossSwapApprovalResponse,\n inputAmountRaw: string,\n sourceFiatRate: FiatRates,\n targetFiatRate: FiatRates,\n expectedOutputRaw?: string,\n): BigNumber {\n const totalFeeUsd = quote.fees?.total?.amountUsd;\n\n if (totalFeeUsd !== undefined) {\n return new BigNumber(totalFeeUsd).abs();\n }\n\n if (expectedOutputRaw === undefined) {\n return new BigNumber(0);\n }\n\n const expectedOutput = new BigNumber(expectedOutputRaw);\n\n if (expectedOutput.lte(0)) {\n return new BigNumber(0);\n }\n\n const inputAmountUsd = new BigNumber(inputAmountRaw)\n .shiftedBy(-quote.inputToken.decimals)\n .multipliedBy(sourceFiatRate.usdRate);\n const expectedOutputUsd = expectedOutput\n .shiftedBy(-quote.outputToken.decimals)\n .multipliedBy(targetFiatRate.usdRate);\n const providerFeeUsd = inputAmountUsd.minus(expectedOutputUsd);\n\n return providerFeeUsd.isNegative() ? new BigNumber(0) : providerFeeUsd;\n}\n\nfunction getAmountFromTokenAmount({\n amountRaw,\n decimals,\n fiatRate,\n}: {\n amountRaw: string;\n decimals: number;\n fiatRate: FiatRates;\n}): Amount {\n const rawValue = new BigNumber(amountRaw);\n const raw = rawValue.toString(10);\n\n const humanValue = rawValue.shiftedBy(-decimals);\n const human = humanValue.toString(10);\n\n const usd = humanValue.multipliedBy(fiatRate.usdRate).toString(10);\n const fiat = humanValue.multipliedBy(fiatRate.fiatRate).toString(10);\n\n return {\n fiat,\n human,\n raw,\n usd,\n };\n}\n\nasync function calculateSourceNetworkCost(\n quote: AcrossSwapApprovalResponse,\n messenger: TransactionPayControllerMessenger,\n request: QuoteRequest,\n): Promise<{\n sourceNetwork: TransactionPayQuote<AcrossQuote>['fees']['sourceNetwork'];\n gasLimits: AcrossGasLimits;\n is7702: boolean;\n}> {\n const acrossFallbackGas =\n getPayStrategiesConfig(messenger).across.fallbackGas;\n const { from } = request;\n const orderedTransactions = getAcrossOrderedTransactions({ quote });\n const { swapTx } = quote;\n const swapChainId = toHex(swapTx.chainId);\n const gasEstimates = await estimateQuoteGasLimits({\n fallbackGas: acrossFallbackGas,\n messenger,\n transactions: orderedTransactions.map((transaction) => ({\n chainId: toHex(transaction.chainId),\n data: transaction.data,\n from,\n gas: transaction.gas,\n to: transaction.to,\n value: transaction.value ?? '0x0',\n })),\n });\n const { batchGasLimit, is7702 } = gasEstimates;\n\n if (is7702) {\n if (!batchGasLimit) {\n throw new Error('Across combined batch gas estimate missing');\n }\n\n const estimate = calculateGasCost({\n chainId: swapChainId,\n gas: batchGasLimit.estimate,\n maxFeePerGas: swapTx.maxFeePerGas,\n maxPriorityFeePerGas: swapTx.maxPriorityFeePerGas,\n messenger,\n });\n const max = calculateGasCost({\n chainId: swapChainId,\n gas: batchGasLimit.max,\n isMax: true,\n maxFeePerGas: swapTx.maxFeePerGas,\n maxPriorityFeePerGas: swapTx.maxPriorityFeePerGas,\n messenger,\n });\n\n return {\n sourceNetwork: {\n estimate,\n max,\n },\n is7702: true,\n gasLimits: [\n {\n estimate: batchGasLimit.estimate,\n max: batchGasLimit.max,\n },\n ],\n };\n }\n\n const transactionGasLimits = orderedTransactions.map(\n (transaction, index) => ({\n gasEstimate: gasEstimates.gasLimits[index],\n transaction,\n }),\n );\n\n const estimate = sumAmounts(\n transactionGasLimits.map(({ gasEstimate, transaction }) =>\n calculateGasCost({\n chainId: toHex(transaction.chainId),\n gas: gasEstimate.estimate,\n maxFeePerGas: transaction.maxFeePerGas,\n maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,\n messenger,\n }),\n ),\n );\n\n const max = sumAmounts(\n transactionGasLimits.map(({ gasEstimate, transaction }) =>\n calculateGasCost({\n chainId: toHex(transaction.chainId),\n gas: gasEstimate.max,\n isMax: true,\n maxFeePerGas: transaction.maxFeePerGas,\n maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,\n messenger,\n }),\n ),\n );\n\n return {\n sourceNetwork: {\n estimate,\n max,\n },\n is7702: false,\n gasLimits: transactionGasLimits.map(({ gasEstimate }) => ({\n estimate: gasEstimate.estimate,\n max: gasEstimate.max,\n })),\n };\n}\n"]}
1
+ {"version":3,"file":"across-quotes.cjs","sourceRoot":"","sources":["../../../src/strategy/across/across-quotes.ts"],"names":[],"mappings":"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","sourcesContent":["import { successfulFetch, toHex } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { getAcrossDestination } from './across-actions';\nimport { normalizeAcrossRequest } from './perps';\nimport { getAcrossOrderedTransactions } from './transactions';\nimport type {\n AcrossAction,\n AcrossActionRequestBody,\n AcrossGasLimits,\n AcrossQuote,\n AcrossSwapApprovalResponse,\n} from './types';\nimport { TransactionPayStrategy } from '../../constants';\nimport { projectLogger } from '../../logger';\nimport type {\n Amount,\n FiatRates,\n PayStrategyGetQuotesRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types';\nimport { getFiatValueFromUsd, sumAmounts } from '../../utils/amounts';\nimport { getPayStrategiesConfig, getSlippage } from '../../utils/feature-flags';\nimport { calculateGasCost } from '../../utils/gas';\nimport { estimateQuoteGasLimits } from '../../utils/quote-gas';\nimport { getTokenFiatRate } from '../../utils/token';\n\nconst log = createModuleLogger(projectLogger, 'across-strategy');\n\nconst UNSUPPORTED_AUTHORIZATION_LIST_ERROR =\n 'Across does not support type-4/EIP-7702 authorization lists yet';\n\ntype AcrossQuoteWithoutMetaMask = Omit<AcrossQuote, 'metamask'>;\n\n/**\n * Fetch Across quotes.\n *\n * @param request - Request object.\n * @returns Array of quotes.\n */\nexport async function getAcrossQuotes(\n request: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<AcrossQuote>[]> {\n const { requests } = request;\n\n log('Fetching quotes', requests);\n\n try {\n const normalizedRequests = requests.filter(\n (singleRequest) =>\n singleRequest.isMaxAmount === true ||\n (singleRequest.targetAmountMinimum !== undefined &&\n singleRequest.targetAmountMinimum !== '0'),\n );\n\n if (normalizedRequests.length === 0) {\n return [];\n }\n\n if (request.transaction.txParams?.authorizationList?.length) {\n throw new Error(UNSUPPORTED_AUTHORIZATION_LIST_ERROR);\n }\n\n return await Promise.all(\n normalizedRequests.map((singleRequest) =>\n getSingleQuote(singleRequest, request),\n ),\n );\n } catch (error) {\n log('Error fetching quotes', { error });\n throw new Error(`Failed to fetch Across quotes: ${String(error)}`);\n }\n}\n\nasync function getSingleQuote(\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<AcrossQuote>> {\n const { messenger, transaction } = fullRequest;\n const normalizedRequest = normalizeAcrossRequest(request, transaction.type);\n const {\n from,\n isMaxAmount,\n sourceChainId,\n sourceTokenAddress,\n sourceTokenAmount,\n targetAmountMinimum,\n targetChainId,\n targetTokenAddress,\n } = normalizedRequest;\n\n const config = getPayStrategiesConfig(messenger);\n const slippageDecimal = getSlippage(\n messenger,\n sourceChainId,\n sourceTokenAddress,\n );\n\n const amount = isMaxAmount ? sourceTokenAmount : targetAmountMinimum;\n const tradeType = isMaxAmount ? 'exactInput' : 'exactOutput';\n const destination = getAcrossDestination(transaction, request);\n const quote = await requestAcrossApproval({\n actions: destination.actions,\n amount,\n apiBase: config.across.apiBase,\n depositor: from,\n destinationChainId: targetChainId,\n inputToken: sourceTokenAddress,\n originChainId: sourceChainId,\n outputToken: targetTokenAddress,\n recipient: destination.recipient,\n slippage: slippageDecimal,\n tradeType,\n });\n\n const originalQuote: AcrossQuoteWithoutMetaMask = {\n quote,\n request: {\n amount,\n tradeType,\n },\n };\n\n return await normalizeQuote(originalQuote, normalizedRequest, fullRequest);\n}\n\ntype AcrossApprovalRequest = {\n actions: AcrossAction[];\n amount: string;\n apiBase: string;\n depositor: Hex;\n destinationChainId: Hex;\n inputToken: Hex;\n originChainId: Hex;\n outputToken: Hex;\n recipient: Hex;\n slippage?: number;\n tradeType: 'exactInput' | 'exactOutput';\n};\n\nasync function requestAcrossApproval(\n request: AcrossApprovalRequest,\n): Promise<AcrossSwapApprovalResponse> {\n const {\n actions,\n amount,\n apiBase,\n depositor,\n destinationChainId,\n inputToken,\n originChainId,\n outputToken,\n recipient,\n slippage,\n tradeType,\n } = request;\n\n const params = new URLSearchParams();\n params.set('tradeType', tradeType);\n params.set('amount', amount);\n params.set('inputToken', inputToken);\n params.set('outputToken', outputToken);\n params.set('originChainId', String(parseInt(originChainId, 16)));\n params.set('destinationChainId', String(parseInt(destinationChainId, 16)));\n params.set('depositor', depositor);\n params.set('recipient', recipient);\n\n if (slippage !== undefined) {\n params.set('slippage', String(slippage));\n }\n\n const body: AcrossActionRequestBody = { actions };\n const url = `${apiBase}/swap/approval?${params.toString()}`;\n const options: RequestInit = {\n body: JSON.stringify(body),\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n };\n const response = await successfulFetch(url, options);\n\n return (await response.json()) as AcrossSwapApprovalResponse;\n}\n\nasync function normalizeQuote(\n original: AcrossQuoteWithoutMetaMask,\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<AcrossQuote>> {\n const { messenger } = fullRequest;\n const { quote } = original;\n\n const { usdToFiatRate, sourceFiatRate, targetFiatRate } = getFiatRates(\n messenger,\n quote,\n );\n\n const dustUsd = calculateDustUsd(quote, request, targetFiatRate);\n const dust = getFiatValueFromUsd(dustUsd, usdToFiatRate);\n\n const { gasLimits, is7702, sourceNetwork } = await calculateSourceNetworkCost(\n quote,\n messenger,\n request,\n );\n\n const targetNetwork = getFiatValueFromUsd(new BigNumber(0), usdToFiatRate);\n\n const inputAmountRaw = quote.inputAmount ?? '0';\n const outputAmountRaw = new BigNumber(\n quote.expectedOutputAmount ??\n quote.minOutputAmount ??\n request.targetAmountMinimum ??\n '0',\n ).toString(10);\n\n const sourceAmount = getAmountFromTokenAmount({\n amountRaw: inputAmountRaw,\n decimals: quote.inputToken.decimals,\n fiatRate: sourceFiatRate,\n });\n\n const providerUsd = calculateProviderUsd(\n quote,\n inputAmountRaw,\n sourceFiatRate,\n targetFiatRate,\n quote.expectedOutputAmount,\n );\n const provider = getFiatValueFromUsd(providerUsd, usdToFiatRate);\n const metaMaskFee = getFiatValueFromUsd(\n new BigNumber(quote.fees?.app?.amountUsd ?? '0').abs(),\n usdToFiatRate,\n );\n\n const targetAmount = getAmountFromTokenAmount({\n amountRaw: outputAmountRaw,\n decimals: quote.outputToken.decimals,\n fiatRate: targetFiatRate,\n });\n\n const metamask = {\n gasLimits,\n is7702,\n };\n\n return {\n dust,\n estimatedDuration: quote.expectedFillTime ?? 0,\n fees: {\n metaMask: metaMaskFee,\n provider,\n sourceNetwork,\n targetNetwork,\n },\n original: {\n ...original,\n metamask,\n },\n request,\n sourceAmount,\n targetAmount,\n strategy: TransactionPayStrategy.Across,\n } as TransactionPayQuote<AcrossQuote>;\n}\n\nfunction getFiatRates(\n messenger: TransactionPayControllerMessenger,\n quote: AcrossSwapApprovalResponse,\n): {\n sourceFiatRate: FiatRates;\n targetFiatRate: FiatRates;\n usdToFiatRate: BigNumber;\n} {\n const sourceFiatRate = getTokenFiatRate(\n messenger,\n quote.inputToken.address,\n toHex(quote.inputToken.chainId),\n );\n\n if (!sourceFiatRate) {\n throw new Error('Source token fiat rate not found');\n }\n\n const targetFiatRate =\n getTokenFiatRate(\n messenger,\n quote.outputToken.address,\n toHex(quote.outputToken.chainId),\n ) ?? sourceFiatRate;\n\n const usdToFiatRate = new BigNumber(sourceFiatRate.fiatRate).dividedBy(\n sourceFiatRate.usdRate,\n );\n\n return { sourceFiatRate, targetFiatRate, usdToFiatRate };\n}\n\nfunction calculateDustUsd(\n quote: AcrossSwapApprovalResponse,\n request: QuoteRequest,\n targetFiatRate: FiatRates,\n): BigNumber {\n const expectedOutputRaw = quote.expectedOutputAmount;\n\n if (expectedOutputRaw === undefined) {\n return new BigNumber(0);\n }\n\n const expectedOutput = new BigNumber(expectedOutputRaw);\n const minimumOutput = new BigNumber(\n quote.minOutputAmount ?? request.targetAmountMinimum ?? '0',\n );\n\n const dustRaw = expectedOutput.minus(minimumOutput).isNegative()\n ? new BigNumber(0)\n : expectedOutput.minus(minimumOutput);\n const dustHuman = dustRaw.shiftedBy(-quote.outputToken.decimals);\n\n return dustHuman.multipliedBy(targetFiatRate.usdRate);\n}\n\nfunction calculateProviderUsd(\n quote: AcrossSwapApprovalResponse,\n inputAmountRaw: string,\n sourceFiatRate: FiatRates,\n targetFiatRate: FiatRates,\n expectedOutputRaw?: string,\n): BigNumber {\n const totalFeeUsd = quote.fees?.total?.amountUsd;\n\n if (totalFeeUsd !== undefined) {\n return new BigNumber(totalFeeUsd).abs();\n }\n\n if (expectedOutputRaw === undefined) {\n return new BigNumber(0);\n }\n\n const expectedOutput = new BigNumber(expectedOutputRaw);\n\n if (expectedOutput.lte(0)) {\n return new BigNumber(0);\n }\n\n const inputAmountUsd = new BigNumber(inputAmountRaw)\n .shiftedBy(-quote.inputToken.decimals)\n .multipliedBy(sourceFiatRate.usdRate);\n const expectedOutputUsd = expectedOutput\n .shiftedBy(-quote.outputToken.decimals)\n .multipliedBy(targetFiatRate.usdRate);\n const providerFeeUsd = inputAmountUsd.minus(expectedOutputUsd);\n\n return providerFeeUsd.isNegative() ? new BigNumber(0) : providerFeeUsd;\n}\n\nfunction getAmountFromTokenAmount({\n amountRaw,\n decimals,\n fiatRate,\n}: {\n amountRaw: string;\n decimals: number;\n fiatRate: FiatRates;\n}): Amount {\n const rawValue = new BigNumber(amountRaw);\n const raw = rawValue.toString(10);\n\n const humanValue = rawValue.shiftedBy(-decimals);\n const human = humanValue.toString(10);\n\n const usd = humanValue.multipliedBy(fiatRate.usdRate).toString(10);\n const fiat = humanValue.multipliedBy(fiatRate.fiatRate).toString(10);\n\n return {\n fiat,\n human,\n raw,\n usd,\n };\n}\n\nasync function calculateSourceNetworkCost(\n quote: AcrossSwapApprovalResponse,\n messenger: TransactionPayControllerMessenger,\n request: QuoteRequest,\n): Promise<{\n sourceNetwork: TransactionPayQuote<AcrossQuote>['fees']['sourceNetwork'];\n gasLimits: AcrossGasLimits;\n is7702: boolean;\n}> {\n const acrossFallbackGas =\n getPayStrategiesConfig(messenger).across.fallbackGas;\n const { from } = request;\n const orderedTransactions = getAcrossOrderedTransactions({ quote });\n const { swapTx } = quote;\n const swapChainId = toHex(swapTx.chainId);\n const gasEstimates = await estimateQuoteGasLimits({\n fallbackGas: acrossFallbackGas,\n messenger,\n transactions: orderedTransactions.map((transaction) => ({\n chainId: toHex(transaction.chainId),\n data: transaction.data,\n from,\n gas: transaction.gas,\n to: transaction.to,\n value: transaction.value ?? '0x0',\n })),\n });\n const { batchGasLimit, is7702 } = gasEstimates;\n\n if (is7702) {\n if (!batchGasLimit) {\n throw new Error('Across combined batch gas estimate missing');\n }\n\n const estimate = calculateGasCost({\n chainId: swapChainId,\n gas: batchGasLimit.estimate,\n maxFeePerGas: swapTx.maxFeePerGas,\n maxPriorityFeePerGas: swapTx.maxPriorityFeePerGas,\n messenger,\n });\n const max = calculateGasCost({\n chainId: swapChainId,\n gas: batchGasLimit.max,\n isMax: true,\n maxFeePerGas: swapTx.maxFeePerGas,\n maxPriorityFeePerGas: swapTx.maxPriorityFeePerGas,\n messenger,\n });\n\n return {\n sourceNetwork: {\n estimate,\n max,\n },\n is7702: true,\n gasLimits: [\n {\n estimate: batchGasLimit.estimate,\n max: batchGasLimit.max,\n },\n ],\n };\n }\n\n const transactionGasLimits = orderedTransactions.map(\n (transaction, index) => ({\n gasEstimate: gasEstimates.gasLimits[index],\n transaction,\n }),\n );\n\n const estimate = sumAmounts(\n transactionGasLimits.map(({ gasEstimate, transaction }) =>\n calculateGasCost({\n chainId: toHex(transaction.chainId),\n gas: gasEstimate.estimate,\n maxFeePerGas: transaction.maxFeePerGas,\n maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,\n messenger,\n }),\n ),\n );\n\n const max = sumAmounts(\n transactionGasLimits.map(({ gasEstimate, transaction }) =>\n calculateGasCost({\n chainId: toHex(transaction.chainId),\n gas: gasEstimate.max,\n isMax: true,\n maxFeePerGas: transaction.maxFeePerGas,\n maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,\n messenger,\n }),\n ),\n );\n\n return {\n sourceNetwork: {\n estimate,\n max,\n },\n is7702: false,\n gasLimits: transactionGasLimits.map(({ gasEstimate }) => ({\n estimate: gasEstimate.estimate,\n max: gasEstimate.max,\n })),\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"across-quotes.d.cts","sourceRoot":"","sources":["../../../src/strategy/across/across-quotes.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAIV,WAAW,EAEZ,oBAAgB;AAGjB,OAAO,KAAK,EAGV,2BAA2B,EAG3B,mBAAmB,EACpB,wBAAoB;AAcrB;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC,CA8B7C"}
1
+ {"version":3,"file":"across-quotes.d.cts","sourceRoot":"","sources":["../../../src/strategy/across/across-quotes.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAIV,WAAW,EAEZ,oBAAgB;AAGjB,OAAO,KAAK,EAGV,2BAA2B,EAG3B,mBAAmB,EACpB,wBAAoB;AAcrB;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC,CA8B7C"}
@@ -1 +1 @@
1
- {"version":3,"file":"across-quotes.d.mts","sourceRoot":"","sources":["../../../src/strategy/across/across-quotes.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAIV,WAAW,EAEZ,oBAAgB;AAGjB,OAAO,KAAK,EAGV,2BAA2B,EAG3B,mBAAmB,EACpB,wBAAoB;AAcrB;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC,CA8B7C"}
1
+ {"version":3,"file":"across-quotes.d.mts","sourceRoot":"","sources":["../../../src/strategy/across/across-quotes.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAIV,WAAW,EAEZ,oBAAgB;AAGjB,OAAO,KAAK,EAGV,2BAA2B,EAG3B,mBAAmB,EACpB,wBAAoB;AAcrB;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC,CA8B7C"}
@@ -2,6 +2,7 @@ import { successfulFetch, toHex } from "@metamask/controller-utils";
2
2
  import { createModuleLogger } from "@metamask/utils";
3
3
  import { BigNumber } from "bignumber.js";
4
4
  import { getAcrossDestination } from "./across-actions.mjs";
5
+ import { normalizeAcrossRequest } from "./perps.mjs";
5
6
  import { getAcrossOrderedTransactions } from "./transactions.mjs";
6
7
  import { TransactionPayStrategy } from "../../constants.mjs";
7
8
  import { projectLogger } from "../../logger.mjs";
@@ -40,7 +41,8 @@ export async function getAcrossQuotes(request) {
40
41
  }
41
42
  async function getSingleQuote(request, fullRequest) {
42
43
  const { messenger, transaction } = fullRequest;
43
- const { from, isMaxAmount, sourceChainId, sourceTokenAddress, sourceTokenAmount, targetAmountMinimum, targetChainId, targetTokenAddress, } = request;
44
+ const normalizedRequest = normalizeAcrossRequest(request, transaction.type);
45
+ const { from, isMaxAmount, sourceChainId, sourceTokenAddress, sourceTokenAmount, targetAmountMinimum, targetChainId, targetTokenAddress, } = normalizedRequest;
44
46
  const config = getPayStrategiesConfig(messenger);
45
47
  const slippageDecimal = getSlippage(messenger, sourceChainId, sourceTokenAddress);
46
48
  const amount = isMaxAmount ? sourceTokenAmount : targetAmountMinimum;
@@ -66,7 +68,7 @@ async function getSingleQuote(request, fullRequest) {
66
68
  tradeType,
67
69
  },
68
70
  };
69
- return await normalizeQuote(originalQuote, request, fullRequest);
71
+ return await normalizeQuote(originalQuote, normalizedRequest, fullRequest);
70
72
  }
71
73
  async function requestAcrossApproval(request) {
72
74
  const { actions, amount, apiBase, depositor, destinationChainId, inputToken, originChainId, outputToken, recipient, slippage, tradeType, } = request;
@@ -1 +1 @@
1
- {"version":3,"file":"across-quotes.mjs","sourceRoot":"","sources":["../../../src/strategy/across/across-quotes.ts"],"names":[],"mappings":"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","sourcesContent":["import { successfulFetch, toHex } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { getAcrossDestination } from './across-actions';\nimport { getAcrossOrderedTransactions } from './transactions';\nimport type {\n AcrossAction,\n AcrossActionRequestBody,\n AcrossGasLimits,\n AcrossQuote,\n AcrossSwapApprovalResponse,\n} from './types';\nimport { TransactionPayStrategy } from '../../constants';\nimport { projectLogger } from '../../logger';\nimport type {\n Amount,\n FiatRates,\n PayStrategyGetQuotesRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types';\nimport { getFiatValueFromUsd, sumAmounts } from '../../utils/amounts';\nimport { getPayStrategiesConfig, getSlippage } from '../../utils/feature-flags';\nimport { calculateGasCost } from '../../utils/gas';\nimport { estimateQuoteGasLimits } from '../../utils/quote-gas';\nimport { getTokenFiatRate } from '../../utils/token';\n\nconst log = createModuleLogger(projectLogger, 'across-strategy');\n\nconst UNSUPPORTED_AUTHORIZATION_LIST_ERROR =\n 'Across does not support type-4/EIP-7702 authorization lists yet';\n\ntype AcrossQuoteWithoutMetaMask = Omit<AcrossQuote, 'metamask'>;\n\n/**\n * Fetch Across quotes.\n *\n * @param request - Request object.\n * @returns Array of quotes.\n */\nexport async function getAcrossQuotes(\n request: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<AcrossQuote>[]> {\n const { requests } = request;\n\n log('Fetching quotes', requests);\n\n try {\n const normalizedRequests = requests.filter(\n (singleRequest) =>\n singleRequest.isMaxAmount === true ||\n (singleRequest.targetAmountMinimum !== undefined &&\n singleRequest.targetAmountMinimum !== '0'),\n );\n\n if (normalizedRequests.length === 0) {\n return [];\n }\n\n if (request.transaction.txParams?.authorizationList?.length) {\n throw new Error(UNSUPPORTED_AUTHORIZATION_LIST_ERROR);\n }\n\n return await Promise.all(\n normalizedRequests.map((singleRequest) =>\n getSingleQuote(singleRequest, request),\n ),\n );\n } catch (error) {\n log('Error fetching quotes', { error });\n throw new Error(`Failed to fetch Across quotes: ${String(error)}`);\n }\n}\n\nasync function getSingleQuote(\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<AcrossQuote>> {\n const { messenger, transaction } = fullRequest;\n const {\n from,\n isMaxAmount,\n sourceChainId,\n sourceTokenAddress,\n sourceTokenAmount,\n targetAmountMinimum,\n targetChainId,\n targetTokenAddress,\n } = request;\n\n const config = getPayStrategiesConfig(messenger);\n const slippageDecimal = getSlippage(\n messenger,\n sourceChainId,\n sourceTokenAddress,\n );\n\n const amount = isMaxAmount ? sourceTokenAmount : targetAmountMinimum;\n const tradeType = isMaxAmount ? 'exactInput' : 'exactOutput';\n const destination = getAcrossDestination(transaction, request);\n const quote = await requestAcrossApproval({\n actions: destination.actions,\n amount,\n apiBase: config.across.apiBase,\n depositor: from,\n destinationChainId: targetChainId,\n inputToken: sourceTokenAddress,\n originChainId: sourceChainId,\n outputToken: targetTokenAddress,\n recipient: destination.recipient,\n slippage: slippageDecimal,\n tradeType,\n });\n\n const originalQuote: AcrossQuoteWithoutMetaMask = {\n quote,\n request: {\n amount,\n tradeType,\n },\n };\n\n return await normalizeQuote(originalQuote, request, fullRequest);\n}\n\ntype AcrossApprovalRequest = {\n actions: AcrossAction[];\n amount: string;\n apiBase: string;\n depositor: Hex;\n destinationChainId: Hex;\n inputToken: Hex;\n originChainId: Hex;\n outputToken: Hex;\n recipient: Hex;\n slippage?: number;\n tradeType: 'exactInput' | 'exactOutput';\n};\n\nasync function requestAcrossApproval(\n request: AcrossApprovalRequest,\n): Promise<AcrossSwapApprovalResponse> {\n const {\n actions,\n amount,\n apiBase,\n depositor,\n destinationChainId,\n inputToken,\n originChainId,\n outputToken,\n recipient,\n slippage,\n tradeType,\n } = request;\n\n const params = new URLSearchParams();\n params.set('tradeType', tradeType);\n params.set('amount', amount);\n params.set('inputToken', inputToken);\n params.set('outputToken', outputToken);\n params.set('originChainId', String(parseInt(originChainId, 16)));\n params.set('destinationChainId', String(parseInt(destinationChainId, 16)));\n params.set('depositor', depositor);\n params.set('recipient', recipient);\n\n if (slippage !== undefined) {\n params.set('slippage', String(slippage));\n }\n\n const body: AcrossActionRequestBody = { actions };\n const url = `${apiBase}/swap/approval?${params.toString()}`;\n const options: RequestInit = {\n body: JSON.stringify(body),\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n };\n const response = await successfulFetch(url, options);\n\n return (await response.json()) as AcrossSwapApprovalResponse;\n}\n\nasync function normalizeQuote(\n original: AcrossQuoteWithoutMetaMask,\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<AcrossQuote>> {\n const { messenger } = fullRequest;\n const { quote } = original;\n\n const { usdToFiatRate, sourceFiatRate, targetFiatRate } = getFiatRates(\n messenger,\n quote,\n );\n\n const dustUsd = calculateDustUsd(quote, request, targetFiatRate);\n const dust = getFiatValueFromUsd(dustUsd, usdToFiatRate);\n\n const { gasLimits, is7702, sourceNetwork } = await calculateSourceNetworkCost(\n quote,\n messenger,\n request,\n );\n\n const targetNetwork = getFiatValueFromUsd(new BigNumber(0), usdToFiatRate);\n\n const inputAmountRaw = quote.inputAmount ?? '0';\n const outputAmountRaw = new BigNumber(\n quote.expectedOutputAmount ??\n quote.minOutputAmount ??\n request.targetAmountMinimum ??\n '0',\n ).toString(10);\n\n const sourceAmount = getAmountFromTokenAmount({\n amountRaw: inputAmountRaw,\n decimals: quote.inputToken.decimals,\n fiatRate: sourceFiatRate,\n });\n\n const providerUsd = calculateProviderUsd(\n quote,\n inputAmountRaw,\n sourceFiatRate,\n targetFiatRate,\n quote.expectedOutputAmount,\n );\n const provider = getFiatValueFromUsd(providerUsd, usdToFiatRate);\n const metaMaskFee = getFiatValueFromUsd(\n new BigNumber(quote.fees?.app?.amountUsd ?? '0').abs(),\n usdToFiatRate,\n );\n\n const targetAmount = getAmountFromTokenAmount({\n amountRaw: outputAmountRaw,\n decimals: quote.outputToken.decimals,\n fiatRate: targetFiatRate,\n });\n\n const metamask = {\n gasLimits,\n is7702,\n };\n\n return {\n dust,\n estimatedDuration: quote.expectedFillTime ?? 0,\n fees: {\n metaMask: metaMaskFee,\n provider,\n sourceNetwork,\n targetNetwork,\n },\n original: {\n ...original,\n metamask,\n },\n request,\n sourceAmount,\n targetAmount,\n strategy: TransactionPayStrategy.Across,\n } as TransactionPayQuote<AcrossQuote>;\n}\n\nfunction getFiatRates(\n messenger: TransactionPayControllerMessenger,\n quote: AcrossSwapApprovalResponse,\n): {\n sourceFiatRate: FiatRates;\n targetFiatRate: FiatRates;\n usdToFiatRate: BigNumber;\n} {\n const sourceFiatRate = getTokenFiatRate(\n messenger,\n quote.inputToken.address,\n toHex(quote.inputToken.chainId),\n );\n\n if (!sourceFiatRate) {\n throw new Error('Source token fiat rate not found');\n }\n\n const targetFiatRate =\n getTokenFiatRate(\n messenger,\n quote.outputToken.address,\n toHex(quote.outputToken.chainId),\n ) ?? sourceFiatRate;\n\n const usdToFiatRate = new BigNumber(sourceFiatRate.fiatRate).dividedBy(\n sourceFiatRate.usdRate,\n );\n\n return { sourceFiatRate, targetFiatRate, usdToFiatRate };\n}\n\nfunction calculateDustUsd(\n quote: AcrossSwapApprovalResponse,\n request: QuoteRequest,\n targetFiatRate: FiatRates,\n): BigNumber {\n const expectedOutputRaw = quote.expectedOutputAmount;\n\n if (expectedOutputRaw === undefined) {\n return new BigNumber(0);\n }\n\n const expectedOutput = new BigNumber(expectedOutputRaw);\n const minimumOutput = new BigNumber(\n quote.minOutputAmount ?? request.targetAmountMinimum ?? '0',\n );\n\n const dustRaw = expectedOutput.minus(minimumOutput).isNegative()\n ? new BigNumber(0)\n : expectedOutput.minus(minimumOutput);\n const dustHuman = dustRaw.shiftedBy(-quote.outputToken.decimals);\n\n return dustHuman.multipliedBy(targetFiatRate.usdRate);\n}\n\nfunction calculateProviderUsd(\n quote: AcrossSwapApprovalResponse,\n inputAmountRaw: string,\n sourceFiatRate: FiatRates,\n targetFiatRate: FiatRates,\n expectedOutputRaw?: string,\n): BigNumber {\n const totalFeeUsd = quote.fees?.total?.amountUsd;\n\n if (totalFeeUsd !== undefined) {\n return new BigNumber(totalFeeUsd).abs();\n }\n\n if (expectedOutputRaw === undefined) {\n return new BigNumber(0);\n }\n\n const expectedOutput = new BigNumber(expectedOutputRaw);\n\n if (expectedOutput.lte(0)) {\n return new BigNumber(0);\n }\n\n const inputAmountUsd = new BigNumber(inputAmountRaw)\n .shiftedBy(-quote.inputToken.decimals)\n .multipliedBy(sourceFiatRate.usdRate);\n const expectedOutputUsd = expectedOutput\n .shiftedBy(-quote.outputToken.decimals)\n .multipliedBy(targetFiatRate.usdRate);\n const providerFeeUsd = inputAmountUsd.minus(expectedOutputUsd);\n\n return providerFeeUsd.isNegative() ? new BigNumber(0) : providerFeeUsd;\n}\n\nfunction getAmountFromTokenAmount({\n amountRaw,\n decimals,\n fiatRate,\n}: {\n amountRaw: string;\n decimals: number;\n fiatRate: FiatRates;\n}): Amount {\n const rawValue = new BigNumber(amountRaw);\n const raw = rawValue.toString(10);\n\n const humanValue = rawValue.shiftedBy(-decimals);\n const human = humanValue.toString(10);\n\n const usd = humanValue.multipliedBy(fiatRate.usdRate).toString(10);\n const fiat = humanValue.multipliedBy(fiatRate.fiatRate).toString(10);\n\n return {\n fiat,\n human,\n raw,\n usd,\n };\n}\n\nasync function calculateSourceNetworkCost(\n quote: AcrossSwapApprovalResponse,\n messenger: TransactionPayControllerMessenger,\n request: QuoteRequest,\n): Promise<{\n sourceNetwork: TransactionPayQuote<AcrossQuote>['fees']['sourceNetwork'];\n gasLimits: AcrossGasLimits;\n is7702: boolean;\n}> {\n const acrossFallbackGas =\n getPayStrategiesConfig(messenger).across.fallbackGas;\n const { from } = request;\n const orderedTransactions = getAcrossOrderedTransactions({ quote });\n const { swapTx } = quote;\n const swapChainId = toHex(swapTx.chainId);\n const gasEstimates = await estimateQuoteGasLimits({\n fallbackGas: acrossFallbackGas,\n messenger,\n transactions: orderedTransactions.map((transaction) => ({\n chainId: toHex(transaction.chainId),\n data: transaction.data,\n from,\n gas: transaction.gas,\n to: transaction.to,\n value: transaction.value ?? '0x0',\n })),\n });\n const { batchGasLimit, is7702 } = gasEstimates;\n\n if (is7702) {\n if (!batchGasLimit) {\n throw new Error('Across combined batch gas estimate missing');\n }\n\n const estimate = calculateGasCost({\n chainId: swapChainId,\n gas: batchGasLimit.estimate,\n maxFeePerGas: swapTx.maxFeePerGas,\n maxPriorityFeePerGas: swapTx.maxPriorityFeePerGas,\n messenger,\n });\n const max = calculateGasCost({\n chainId: swapChainId,\n gas: batchGasLimit.max,\n isMax: true,\n maxFeePerGas: swapTx.maxFeePerGas,\n maxPriorityFeePerGas: swapTx.maxPriorityFeePerGas,\n messenger,\n });\n\n return {\n sourceNetwork: {\n estimate,\n max,\n },\n is7702: true,\n gasLimits: [\n {\n estimate: batchGasLimit.estimate,\n max: batchGasLimit.max,\n },\n ],\n };\n }\n\n const transactionGasLimits = orderedTransactions.map(\n (transaction, index) => ({\n gasEstimate: gasEstimates.gasLimits[index],\n transaction,\n }),\n );\n\n const estimate = sumAmounts(\n transactionGasLimits.map(({ gasEstimate, transaction }) =>\n calculateGasCost({\n chainId: toHex(transaction.chainId),\n gas: gasEstimate.estimate,\n maxFeePerGas: transaction.maxFeePerGas,\n maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,\n messenger,\n }),\n ),\n );\n\n const max = sumAmounts(\n transactionGasLimits.map(({ gasEstimate, transaction }) =>\n calculateGasCost({\n chainId: toHex(transaction.chainId),\n gas: gasEstimate.max,\n isMax: true,\n maxFeePerGas: transaction.maxFeePerGas,\n maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,\n messenger,\n }),\n ),\n );\n\n return {\n sourceNetwork: {\n estimate,\n max,\n },\n is7702: false,\n gasLimits: transactionGasLimits.map(({ gasEstimate }) => ({\n estimate: gasEstimate.estimate,\n max: gasEstimate.max,\n })),\n };\n}\n"]}
1
+ {"version":3,"file":"across-quotes.mjs","sourceRoot":"","sources":["../../../src/strategy/across/across-quotes.ts"],"names":[],"mappings":"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","sourcesContent":["import { successfulFetch, toHex } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { getAcrossDestination } from './across-actions';\nimport { normalizeAcrossRequest } from './perps';\nimport { getAcrossOrderedTransactions } from './transactions';\nimport type {\n AcrossAction,\n AcrossActionRequestBody,\n AcrossGasLimits,\n AcrossQuote,\n AcrossSwapApprovalResponse,\n} from './types';\nimport { TransactionPayStrategy } from '../../constants';\nimport { projectLogger } from '../../logger';\nimport type {\n Amount,\n FiatRates,\n PayStrategyGetQuotesRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types';\nimport { getFiatValueFromUsd, sumAmounts } from '../../utils/amounts';\nimport { getPayStrategiesConfig, getSlippage } from '../../utils/feature-flags';\nimport { calculateGasCost } from '../../utils/gas';\nimport { estimateQuoteGasLimits } from '../../utils/quote-gas';\nimport { getTokenFiatRate } from '../../utils/token';\n\nconst log = createModuleLogger(projectLogger, 'across-strategy');\n\nconst UNSUPPORTED_AUTHORIZATION_LIST_ERROR =\n 'Across does not support type-4/EIP-7702 authorization lists yet';\n\ntype AcrossQuoteWithoutMetaMask = Omit<AcrossQuote, 'metamask'>;\n\n/**\n * Fetch Across quotes.\n *\n * @param request - Request object.\n * @returns Array of quotes.\n */\nexport async function getAcrossQuotes(\n request: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<AcrossQuote>[]> {\n const { requests } = request;\n\n log('Fetching quotes', requests);\n\n try {\n const normalizedRequests = requests.filter(\n (singleRequest) =>\n singleRequest.isMaxAmount === true ||\n (singleRequest.targetAmountMinimum !== undefined &&\n singleRequest.targetAmountMinimum !== '0'),\n );\n\n if (normalizedRequests.length === 0) {\n return [];\n }\n\n if (request.transaction.txParams?.authorizationList?.length) {\n throw new Error(UNSUPPORTED_AUTHORIZATION_LIST_ERROR);\n }\n\n return await Promise.all(\n normalizedRequests.map((singleRequest) =>\n getSingleQuote(singleRequest, request),\n ),\n );\n } catch (error) {\n log('Error fetching quotes', { error });\n throw new Error(`Failed to fetch Across quotes: ${String(error)}`);\n }\n}\n\nasync function getSingleQuote(\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<AcrossQuote>> {\n const { messenger, transaction } = fullRequest;\n const normalizedRequest = normalizeAcrossRequest(request, transaction.type);\n const {\n from,\n isMaxAmount,\n sourceChainId,\n sourceTokenAddress,\n sourceTokenAmount,\n targetAmountMinimum,\n targetChainId,\n targetTokenAddress,\n } = normalizedRequest;\n\n const config = getPayStrategiesConfig(messenger);\n const slippageDecimal = getSlippage(\n messenger,\n sourceChainId,\n sourceTokenAddress,\n );\n\n const amount = isMaxAmount ? sourceTokenAmount : targetAmountMinimum;\n const tradeType = isMaxAmount ? 'exactInput' : 'exactOutput';\n const destination = getAcrossDestination(transaction, request);\n const quote = await requestAcrossApproval({\n actions: destination.actions,\n amount,\n apiBase: config.across.apiBase,\n depositor: from,\n destinationChainId: targetChainId,\n inputToken: sourceTokenAddress,\n originChainId: sourceChainId,\n outputToken: targetTokenAddress,\n recipient: destination.recipient,\n slippage: slippageDecimal,\n tradeType,\n });\n\n const originalQuote: AcrossQuoteWithoutMetaMask = {\n quote,\n request: {\n amount,\n tradeType,\n },\n };\n\n return await normalizeQuote(originalQuote, normalizedRequest, fullRequest);\n}\n\ntype AcrossApprovalRequest = {\n actions: AcrossAction[];\n amount: string;\n apiBase: string;\n depositor: Hex;\n destinationChainId: Hex;\n inputToken: Hex;\n originChainId: Hex;\n outputToken: Hex;\n recipient: Hex;\n slippage?: number;\n tradeType: 'exactInput' | 'exactOutput';\n};\n\nasync function requestAcrossApproval(\n request: AcrossApprovalRequest,\n): Promise<AcrossSwapApprovalResponse> {\n const {\n actions,\n amount,\n apiBase,\n depositor,\n destinationChainId,\n inputToken,\n originChainId,\n outputToken,\n recipient,\n slippage,\n tradeType,\n } = request;\n\n const params = new URLSearchParams();\n params.set('tradeType', tradeType);\n params.set('amount', amount);\n params.set('inputToken', inputToken);\n params.set('outputToken', outputToken);\n params.set('originChainId', String(parseInt(originChainId, 16)));\n params.set('destinationChainId', String(parseInt(destinationChainId, 16)));\n params.set('depositor', depositor);\n params.set('recipient', recipient);\n\n if (slippage !== undefined) {\n params.set('slippage', String(slippage));\n }\n\n const body: AcrossActionRequestBody = { actions };\n const url = `${apiBase}/swap/approval?${params.toString()}`;\n const options: RequestInit = {\n body: JSON.stringify(body),\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n };\n const response = await successfulFetch(url, options);\n\n return (await response.json()) as AcrossSwapApprovalResponse;\n}\n\nasync function normalizeQuote(\n original: AcrossQuoteWithoutMetaMask,\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<AcrossQuote>> {\n const { messenger } = fullRequest;\n const { quote } = original;\n\n const { usdToFiatRate, sourceFiatRate, targetFiatRate } = getFiatRates(\n messenger,\n quote,\n );\n\n const dustUsd = calculateDustUsd(quote, request, targetFiatRate);\n const dust = getFiatValueFromUsd(dustUsd, usdToFiatRate);\n\n const { gasLimits, is7702, sourceNetwork } = await calculateSourceNetworkCost(\n quote,\n messenger,\n request,\n );\n\n const targetNetwork = getFiatValueFromUsd(new BigNumber(0), usdToFiatRate);\n\n const inputAmountRaw = quote.inputAmount ?? '0';\n const outputAmountRaw = new BigNumber(\n quote.expectedOutputAmount ??\n quote.minOutputAmount ??\n request.targetAmountMinimum ??\n '0',\n ).toString(10);\n\n const sourceAmount = getAmountFromTokenAmount({\n amountRaw: inputAmountRaw,\n decimals: quote.inputToken.decimals,\n fiatRate: sourceFiatRate,\n });\n\n const providerUsd = calculateProviderUsd(\n quote,\n inputAmountRaw,\n sourceFiatRate,\n targetFiatRate,\n quote.expectedOutputAmount,\n );\n const provider = getFiatValueFromUsd(providerUsd, usdToFiatRate);\n const metaMaskFee = getFiatValueFromUsd(\n new BigNumber(quote.fees?.app?.amountUsd ?? '0').abs(),\n usdToFiatRate,\n );\n\n const targetAmount = getAmountFromTokenAmount({\n amountRaw: outputAmountRaw,\n decimals: quote.outputToken.decimals,\n fiatRate: targetFiatRate,\n });\n\n const metamask = {\n gasLimits,\n is7702,\n };\n\n return {\n dust,\n estimatedDuration: quote.expectedFillTime ?? 0,\n fees: {\n metaMask: metaMaskFee,\n provider,\n sourceNetwork,\n targetNetwork,\n },\n original: {\n ...original,\n metamask,\n },\n request,\n sourceAmount,\n targetAmount,\n strategy: TransactionPayStrategy.Across,\n } as TransactionPayQuote<AcrossQuote>;\n}\n\nfunction getFiatRates(\n messenger: TransactionPayControllerMessenger,\n quote: AcrossSwapApprovalResponse,\n): {\n sourceFiatRate: FiatRates;\n targetFiatRate: FiatRates;\n usdToFiatRate: BigNumber;\n} {\n const sourceFiatRate = getTokenFiatRate(\n messenger,\n quote.inputToken.address,\n toHex(quote.inputToken.chainId),\n );\n\n if (!sourceFiatRate) {\n throw new Error('Source token fiat rate not found');\n }\n\n const targetFiatRate =\n getTokenFiatRate(\n messenger,\n quote.outputToken.address,\n toHex(quote.outputToken.chainId),\n ) ?? sourceFiatRate;\n\n const usdToFiatRate = new BigNumber(sourceFiatRate.fiatRate).dividedBy(\n sourceFiatRate.usdRate,\n );\n\n return { sourceFiatRate, targetFiatRate, usdToFiatRate };\n}\n\nfunction calculateDustUsd(\n quote: AcrossSwapApprovalResponse,\n request: QuoteRequest,\n targetFiatRate: FiatRates,\n): BigNumber {\n const expectedOutputRaw = quote.expectedOutputAmount;\n\n if (expectedOutputRaw === undefined) {\n return new BigNumber(0);\n }\n\n const expectedOutput = new BigNumber(expectedOutputRaw);\n const minimumOutput = new BigNumber(\n quote.minOutputAmount ?? request.targetAmountMinimum ?? '0',\n );\n\n const dustRaw = expectedOutput.minus(minimumOutput).isNegative()\n ? new BigNumber(0)\n : expectedOutput.minus(minimumOutput);\n const dustHuman = dustRaw.shiftedBy(-quote.outputToken.decimals);\n\n return dustHuman.multipliedBy(targetFiatRate.usdRate);\n}\n\nfunction calculateProviderUsd(\n quote: AcrossSwapApprovalResponse,\n inputAmountRaw: string,\n sourceFiatRate: FiatRates,\n targetFiatRate: FiatRates,\n expectedOutputRaw?: string,\n): BigNumber {\n const totalFeeUsd = quote.fees?.total?.amountUsd;\n\n if (totalFeeUsd !== undefined) {\n return new BigNumber(totalFeeUsd).abs();\n }\n\n if (expectedOutputRaw === undefined) {\n return new BigNumber(0);\n }\n\n const expectedOutput = new BigNumber(expectedOutputRaw);\n\n if (expectedOutput.lte(0)) {\n return new BigNumber(0);\n }\n\n const inputAmountUsd = new BigNumber(inputAmountRaw)\n .shiftedBy(-quote.inputToken.decimals)\n .multipliedBy(sourceFiatRate.usdRate);\n const expectedOutputUsd = expectedOutput\n .shiftedBy(-quote.outputToken.decimals)\n .multipliedBy(targetFiatRate.usdRate);\n const providerFeeUsd = inputAmountUsd.minus(expectedOutputUsd);\n\n return providerFeeUsd.isNegative() ? new BigNumber(0) : providerFeeUsd;\n}\n\nfunction getAmountFromTokenAmount({\n amountRaw,\n decimals,\n fiatRate,\n}: {\n amountRaw: string;\n decimals: number;\n fiatRate: FiatRates;\n}): Amount {\n const rawValue = new BigNumber(amountRaw);\n const raw = rawValue.toString(10);\n\n const humanValue = rawValue.shiftedBy(-decimals);\n const human = humanValue.toString(10);\n\n const usd = humanValue.multipliedBy(fiatRate.usdRate).toString(10);\n const fiat = humanValue.multipliedBy(fiatRate.fiatRate).toString(10);\n\n return {\n fiat,\n human,\n raw,\n usd,\n };\n}\n\nasync function calculateSourceNetworkCost(\n quote: AcrossSwapApprovalResponse,\n messenger: TransactionPayControllerMessenger,\n request: QuoteRequest,\n): Promise<{\n sourceNetwork: TransactionPayQuote<AcrossQuote>['fees']['sourceNetwork'];\n gasLimits: AcrossGasLimits;\n is7702: boolean;\n}> {\n const acrossFallbackGas =\n getPayStrategiesConfig(messenger).across.fallbackGas;\n const { from } = request;\n const orderedTransactions = getAcrossOrderedTransactions({ quote });\n const { swapTx } = quote;\n const swapChainId = toHex(swapTx.chainId);\n const gasEstimates = await estimateQuoteGasLimits({\n fallbackGas: acrossFallbackGas,\n messenger,\n transactions: orderedTransactions.map((transaction) => ({\n chainId: toHex(transaction.chainId),\n data: transaction.data,\n from,\n gas: transaction.gas,\n to: transaction.to,\n value: transaction.value ?? '0x0',\n })),\n });\n const { batchGasLimit, is7702 } = gasEstimates;\n\n if (is7702) {\n if (!batchGasLimit) {\n throw new Error('Across combined batch gas estimate missing');\n }\n\n const estimate = calculateGasCost({\n chainId: swapChainId,\n gas: batchGasLimit.estimate,\n maxFeePerGas: swapTx.maxFeePerGas,\n maxPriorityFeePerGas: swapTx.maxPriorityFeePerGas,\n messenger,\n });\n const max = calculateGasCost({\n chainId: swapChainId,\n gas: batchGasLimit.max,\n isMax: true,\n maxFeePerGas: swapTx.maxFeePerGas,\n maxPriorityFeePerGas: swapTx.maxPriorityFeePerGas,\n messenger,\n });\n\n return {\n sourceNetwork: {\n estimate,\n max,\n },\n is7702: true,\n gasLimits: [\n {\n estimate: batchGasLimit.estimate,\n max: batchGasLimit.max,\n },\n ],\n };\n }\n\n const transactionGasLimits = orderedTransactions.map(\n (transaction, index) => ({\n gasEstimate: gasEstimates.gasLimits[index],\n transaction,\n }),\n );\n\n const estimate = sumAmounts(\n transactionGasLimits.map(({ gasEstimate, transaction }) =>\n calculateGasCost({\n chainId: toHex(transaction.chainId),\n gas: gasEstimate.estimate,\n maxFeePerGas: transaction.maxFeePerGas,\n maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,\n messenger,\n }),\n ),\n );\n\n const max = sumAmounts(\n transactionGasLimits.map(({ gasEstimate, transaction }) =>\n calculateGasCost({\n chainId: toHex(transaction.chainId),\n gas: gasEstimate.max,\n isMax: true,\n maxFeePerGas: transaction.maxFeePerGas,\n maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,\n messenger,\n }),\n ),\n );\n\n return {\n sourceNetwork: {\n estimate,\n max,\n },\n is7702: false,\n gasLimits: transactionGasLimits.map(({ gasEstimate }) => ({\n estimate: gasEstimate.estimate,\n max: gasEstimate.max,\n })),\n };\n}\n"]}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeAcrossRequest = exports.isSupportedAcrossPerpsDepositRequest = exports.ACROSS_HYPERCORE_USDC_PERPS_ADDRESS = void 0;
4
+ const transaction_controller_1 = require("@metamask/transaction-controller");
5
+ const bignumber_js_1 = require("bignumber.js");
6
+ const constants_1 = require("../../constants.cjs");
7
+ exports.ACROSS_HYPERCORE_USDC_PERPS_ADDRESS = '0x2100000000000000000000000000000000000000';
8
+ /**
9
+ * Detect the quote-time parent transaction shape that Across can map to the
10
+ * new HyperCore USDC-PERPS direct-deposit route.
11
+ *
12
+ * The parent transaction remains `perpsDeposit` while quotes are being
13
+ * selected. `perpsAcrossDeposit` is only assigned later to the generated
14
+ * Across submission transaction(s).
15
+ *
16
+ * @param request - Transaction pay quote request.
17
+ * @param parentTransactionType - Parent transaction type before Across
18
+ * execution.
19
+ * @returns Whether the request matches the supported direct-deposit path.
20
+ */
21
+ function isSupportedAcrossPerpsDepositRequest(request, parentTransactionType) {
22
+ return (parentTransactionType === transaction_controller_1.TransactionType.perpsDeposit &&
23
+ request.isPostQuote !== true &&
24
+ request.targetChainId === constants_1.CHAIN_ID_ARBITRUM &&
25
+ request.targetTokenAddress.toLowerCase() ===
26
+ constants_1.ARBITRUM_USDC_ADDRESS.toLowerCase());
27
+ }
28
+ exports.isSupportedAcrossPerpsDepositRequest = isSupportedAcrossPerpsDepositRequest;
29
+ /**
30
+ * Convert the transaction-pay request into the Across route shape required for
31
+ * direct perps deposits.
32
+ *
33
+ * Transaction pay starts from the required on-chain asset identity
34
+ * (Arbitrum USDC, 6 decimals), while Across now expects the HyperCore
35
+ * USDC-PERPS destination token (8 decimals).
36
+ *
37
+ * @param request - Transaction pay quote request.
38
+ * @param parentTransactionType - Parent transaction type before Across
39
+ * execution.
40
+ * @returns Normalized request for Across quoting.
41
+ */
42
+ function normalizeAcrossRequest(request, parentTransactionType) {
43
+ if (!isSupportedAcrossPerpsDepositRequest(request, parentTransactionType)) {
44
+ return request;
45
+ }
46
+ return {
47
+ ...request,
48
+ targetAmountMinimum: new bignumber_js_1.BigNumber(request.targetAmountMinimum)
49
+ .shiftedBy(constants_1.HYPERCORE_USDC_DECIMALS - constants_1.USDC_DECIMALS)
50
+ .toFixed(0),
51
+ targetChainId: constants_1.CHAIN_ID_HYPERCORE,
52
+ targetTokenAddress: exports.ACROSS_HYPERCORE_USDC_PERPS_ADDRESS,
53
+ };
54
+ }
55
+ exports.normalizeAcrossRequest = normalizeAcrossRequest;
56
+ //# sourceMappingURL=perps.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perps.cjs","sourceRoot":"","sources":["../../../src/strategy/across/perps.ts"],"names":[],"mappings":";;;AAAA,6EAAmE;AAEnE,+CAAyC;AAEzC,mDAMyB;AAGZ,QAAA,mCAAmC,GAC9C,4CAAmD,CAAC;AAEtD;;;;;;;;;;;;GAYG;AACH,SAAgB,oCAAoC,CAClD,OAGC,EACD,qBAAuC;IAEvC,OAAO,CACL,qBAAqB,KAAK,wCAAe,CAAC,YAAY;QACtD,OAAO,CAAC,WAAW,KAAK,IAAI;QAC5B,OAAO,CAAC,aAAa,KAAK,6BAAiB;QAC3C,OAAO,CAAC,kBAAkB,CAAC,WAAW,EAAE;YACtC,iCAAqB,CAAC,WAAW,EAAE,CACtC,CAAC;AACJ,CAAC;AAdD,oFAcC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,sBAAsB,CACpC,OAAqB,EACrB,qBAAuC;IAEvC,IAAI,CAAC,oCAAoC,CAAC,OAAO,EAAE,qBAAqB,CAAC,EAAE,CAAC;QAC1E,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO;QACL,GAAG,OAAO;QACV,mBAAmB,EAAE,IAAI,wBAAS,CAAC,OAAO,CAAC,mBAAmB,CAAC;aAC5D,SAAS,CAAC,mCAAuB,GAAG,yBAAa,CAAC;aAClD,OAAO,CAAC,CAAC,CAAC;QACb,aAAa,EAAE,8BAAkB;QACjC,kBAAkB,EAAE,2CAAmC;KACxD,CAAC;AACJ,CAAC;AAhBD,wDAgBC","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport {\n ARBITRUM_USDC_ADDRESS,\n CHAIN_ID_ARBITRUM,\n CHAIN_ID_HYPERCORE,\n HYPERCORE_USDC_DECIMALS,\n USDC_DECIMALS,\n} from '../../constants';\nimport type { QuoteRequest } from '../../types';\n\nexport const ACROSS_HYPERCORE_USDC_PERPS_ADDRESS =\n '0x2100000000000000000000000000000000000000' as Hex;\n\n/**\n * Detect the quote-time parent transaction shape that Across can map to the\n * new HyperCore USDC-PERPS direct-deposit route.\n *\n * The parent transaction remains `perpsDeposit` while quotes are being\n * selected. `perpsAcrossDeposit` is only assigned later to the generated\n * Across submission transaction(s).\n *\n * @param request - Transaction pay quote request.\n * @param parentTransactionType - Parent transaction type before Across\n * execution.\n * @returns Whether the request matches the supported direct-deposit path.\n */\nexport function isSupportedAcrossPerpsDepositRequest(\n request: Pick<\n QuoteRequest,\n 'isPostQuote' | 'targetChainId' | 'targetTokenAddress'\n >,\n parentTransactionType?: TransactionType,\n): boolean {\n return (\n parentTransactionType === TransactionType.perpsDeposit &&\n request.isPostQuote !== true &&\n request.targetChainId === CHAIN_ID_ARBITRUM &&\n request.targetTokenAddress.toLowerCase() ===\n ARBITRUM_USDC_ADDRESS.toLowerCase()\n );\n}\n\n/**\n * Convert the transaction-pay request into the Across route shape required for\n * direct perps deposits.\n *\n * Transaction pay starts from the required on-chain asset identity\n * (Arbitrum USDC, 6 decimals), while Across now expects the HyperCore\n * USDC-PERPS destination token (8 decimals).\n *\n * @param request - Transaction pay quote request.\n * @param parentTransactionType - Parent transaction type before Across\n * execution.\n * @returns Normalized request for Across quoting.\n */\nexport function normalizeAcrossRequest(\n request: QuoteRequest,\n parentTransactionType?: TransactionType,\n): QuoteRequest {\n if (!isSupportedAcrossPerpsDepositRequest(request, parentTransactionType)) {\n return request;\n }\n\n return {\n ...request,\n targetAmountMinimum: new BigNumber(request.targetAmountMinimum)\n .shiftedBy(HYPERCORE_USDC_DECIMALS - USDC_DECIMALS)\n .toFixed(0),\n targetChainId: CHAIN_ID_HYPERCORE,\n targetTokenAddress: ACROSS_HYPERCORE_USDC_PERPS_ADDRESS,\n };\n}\n"]}
@@ -0,0 +1,32 @@
1
+ import { TransactionType } from "@metamask/transaction-controller";
2
+ import type { QuoteRequest } from "../../types.cjs";
3
+ export declare const ACROSS_HYPERCORE_USDC_PERPS_ADDRESS: `0x${string}`;
4
+ /**
5
+ * Detect the quote-time parent transaction shape that Across can map to the
6
+ * new HyperCore USDC-PERPS direct-deposit route.
7
+ *
8
+ * The parent transaction remains `perpsDeposit` while quotes are being
9
+ * selected. `perpsAcrossDeposit` is only assigned later to the generated
10
+ * Across submission transaction(s).
11
+ *
12
+ * @param request - Transaction pay quote request.
13
+ * @param parentTransactionType - Parent transaction type before Across
14
+ * execution.
15
+ * @returns Whether the request matches the supported direct-deposit path.
16
+ */
17
+ export declare function isSupportedAcrossPerpsDepositRequest(request: Pick<QuoteRequest, 'isPostQuote' | 'targetChainId' | 'targetTokenAddress'>, parentTransactionType?: TransactionType): boolean;
18
+ /**
19
+ * Convert the transaction-pay request into the Across route shape required for
20
+ * direct perps deposits.
21
+ *
22
+ * Transaction pay starts from the required on-chain asset identity
23
+ * (Arbitrum USDC, 6 decimals), while Across now expects the HyperCore
24
+ * USDC-PERPS destination token (8 decimals).
25
+ *
26
+ * @param request - Transaction pay quote request.
27
+ * @param parentTransactionType - Parent transaction type before Across
28
+ * execution.
29
+ * @returns Normalized request for Across quoting.
30
+ */
31
+ export declare function normalizeAcrossRequest(request: QuoteRequest, parentTransactionType?: TransactionType): QuoteRequest;
32
+ //# sourceMappingURL=perps.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perps.d.cts","sourceRoot":"","sources":["../../../src/strategy/across/perps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,yCAAyC;AAWnE,OAAO,KAAK,EAAE,YAAY,EAAE,wBAAoB;AAEhD,eAAO,MAAM,mCAAmC,eACK,CAAC;AAEtD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,IAAI,CACX,YAAY,EACZ,aAAa,GAAG,eAAe,GAAG,oBAAoB,CACvD,EACD,qBAAqB,CAAC,EAAE,eAAe,GACtC,OAAO,CAQT;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,YAAY,EACrB,qBAAqB,CAAC,EAAE,eAAe,GACtC,YAAY,CAad"}
@@ -0,0 +1,32 @@
1
+ import { TransactionType } from "@metamask/transaction-controller";
2
+ import type { QuoteRequest } from "../../types.mjs";
3
+ export declare const ACROSS_HYPERCORE_USDC_PERPS_ADDRESS: `0x${string}`;
4
+ /**
5
+ * Detect the quote-time parent transaction shape that Across can map to the
6
+ * new HyperCore USDC-PERPS direct-deposit route.
7
+ *
8
+ * The parent transaction remains `perpsDeposit` while quotes are being
9
+ * selected. `perpsAcrossDeposit` is only assigned later to the generated
10
+ * Across submission transaction(s).
11
+ *
12
+ * @param request - Transaction pay quote request.
13
+ * @param parentTransactionType - Parent transaction type before Across
14
+ * execution.
15
+ * @returns Whether the request matches the supported direct-deposit path.
16
+ */
17
+ export declare function isSupportedAcrossPerpsDepositRequest(request: Pick<QuoteRequest, 'isPostQuote' | 'targetChainId' | 'targetTokenAddress'>, parentTransactionType?: TransactionType): boolean;
18
+ /**
19
+ * Convert the transaction-pay request into the Across route shape required for
20
+ * direct perps deposits.
21
+ *
22
+ * Transaction pay starts from the required on-chain asset identity
23
+ * (Arbitrum USDC, 6 decimals), while Across now expects the HyperCore
24
+ * USDC-PERPS destination token (8 decimals).
25
+ *
26
+ * @param request - Transaction pay quote request.
27
+ * @param parentTransactionType - Parent transaction type before Across
28
+ * execution.
29
+ * @returns Normalized request for Across quoting.
30
+ */
31
+ export declare function normalizeAcrossRequest(request: QuoteRequest, parentTransactionType?: TransactionType): QuoteRequest;
32
+ //# sourceMappingURL=perps.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perps.d.mts","sourceRoot":"","sources":["../../../src/strategy/across/perps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,yCAAyC;AAWnE,OAAO,KAAK,EAAE,YAAY,EAAE,wBAAoB;AAEhD,eAAO,MAAM,mCAAmC,eACK,CAAC;AAEtD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,IAAI,CACX,YAAY,EACZ,aAAa,GAAG,eAAe,GAAG,oBAAoB,CACvD,EACD,qBAAqB,CAAC,EAAE,eAAe,GACtC,OAAO,CAQT;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,YAAY,EACrB,qBAAqB,CAAC,EAAE,eAAe,GACtC,YAAY,CAad"}
@@ -0,0 +1,51 @@
1
+ import { TransactionType } from "@metamask/transaction-controller";
2
+ import { BigNumber } from "bignumber.js";
3
+ import { ARBITRUM_USDC_ADDRESS, CHAIN_ID_ARBITRUM, CHAIN_ID_HYPERCORE, HYPERCORE_USDC_DECIMALS, USDC_DECIMALS } from "../../constants.mjs";
4
+ export const ACROSS_HYPERCORE_USDC_PERPS_ADDRESS = '0x2100000000000000000000000000000000000000';
5
+ /**
6
+ * Detect the quote-time parent transaction shape that Across can map to the
7
+ * new HyperCore USDC-PERPS direct-deposit route.
8
+ *
9
+ * The parent transaction remains `perpsDeposit` while quotes are being
10
+ * selected. `perpsAcrossDeposit` is only assigned later to the generated
11
+ * Across submission transaction(s).
12
+ *
13
+ * @param request - Transaction pay quote request.
14
+ * @param parentTransactionType - Parent transaction type before Across
15
+ * execution.
16
+ * @returns Whether the request matches the supported direct-deposit path.
17
+ */
18
+ export function isSupportedAcrossPerpsDepositRequest(request, parentTransactionType) {
19
+ return (parentTransactionType === TransactionType.perpsDeposit &&
20
+ request.isPostQuote !== true &&
21
+ request.targetChainId === CHAIN_ID_ARBITRUM &&
22
+ request.targetTokenAddress.toLowerCase() ===
23
+ ARBITRUM_USDC_ADDRESS.toLowerCase());
24
+ }
25
+ /**
26
+ * Convert the transaction-pay request into the Across route shape required for
27
+ * direct perps deposits.
28
+ *
29
+ * Transaction pay starts from the required on-chain asset identity
30
+ * (Arbitrum USDC, 6 decimals), while Across now expects the HyperCore
31
+ * USDC-PERPS destination token (8 decimals).
32
+ *
33
+ * @param request - Transaction pay quote request.
34
+ * @param parentTransactionType - Parent transaction type before Across
35
+ * execution.
36
+ * @returns Normalized request for Across quoting.
37
+ */
38
+ export function normalizeAcrossRequest(request, parentTransactionType) {
39
+ if (!isSupportedAcrossPerpsDepositRequest(request, parentTransactionType)) {
40
+ return request;
41
+ }
42
+ return {
43
+ ...request,
44
+ targetAmountMinimum: new BigNumber(request.targetAmountMinimum)
45
+ .shiftedBy(HYPERCORE_USDC_DECIMALS - USDC_DECIMALS)
46
+ .toFixed(0),
47
+ targetChainId: CHAIN_ID_HYPERCORE,
48
+ targetTokenAddress: ACROSS_HYPERCORE_USDC_PERPS_ADDRESS,
49
+ };
50
+ }
51
+ //# sourceMappingURL=perps.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perps.mjs","sourceRoot":"","sources":["../../../src/strategy/across/perps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,yCAAyC;AAEnE,OAAO,EAAE,SAAS,EAAE,qBAAqB;AAEzC,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,aAAa,EACd,4BAAwB;AAGzB,MAAM,CAAC,MAAM,mCAAmC,GAC9C,4CAAmD,CAAC;AAEtD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,oCAAoC,CAClD,OAGC,EACD,qBAAuC;IAEvC,OAAO,CACL,qBAAqB,KAAK,eAAe,CAAC,YAAY;QACtD,OAAO,CAAC,WAAW,KAAK,IAAI;QAC5B,OAAO,CAAC,aAAa,KAAK,iBAAiB;QAC3C,OAAO,CAAC,kBAAkB,CAAC,WAAW,EAAE;YACtC,qBAAqB,CAAC,WAAW,EAAE,CACtC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAAqB,EACrB,qBAAuC;IAEvC,IAAI,CAAC,oCAAoC,CAAC,OAAO,EAAE,qBAAqB,CAAC,EAAE,CAAC;QAC1E,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO;QACL,GAAG,OAAO;QACV,mBAAmB,EAAE,IAAI,SAAS,CAAC,OAAO,CAAC,mBAAmB,CAAC;aAC5D,SAAS,CAAC,uBAAuB,GAAG,aAAa,CAAC;aAClD,OAAO,CAAC,CAAC,CAAC;QACb,aAAa,EAAE,kBAAkB;QACjC,kBAAkB,EAAE,mCAAmC;KACxD,CAAC;AACJ,CAAC","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport {\n ARBITRUM_USDC_ADDRESS,\n CHAIN_ID_ARBITRUM,\n CHAIN_ID_HYPERCORE,\n HYPERCORE_USDC_DECIMALS,\n USDC_DECIMALS,\n} from '../../constants';\nimport type { QuoteRequest } from '../../types';\n\nexport const ACROSS_HYPERCORE_USDC_PERPS_ADDRESS =\n '0x2100000000000000000000000000000000000000' as Hex;\n\n/**\n * Detect the quote-time parent transaction shape that Across can map to the\n * new HyperCore USDC-PERPS direct-deposit route.\n *\n * The parent transaction remains `perpsDeposit` while quotes are being\n * selected. `perpsAcrossDeposit` is only assigned later to the generated\n * Across submission transaction(s).\n *\n * @param request - Transaction pay quote request.\n * @param parentTransactionType - Parent transaction type before Across\n * execution.\n * @returns Whether the request matches the supported direct-deposit path.\n */\nexport function isSupportedAcrossPerpsDepositRequest(\n request: Pick<\n QuoteRequest,\n 'isPostQuote' | 'targetChainId' | 'targetTokenAddress'\n >,\n parentTransactionType?: TransactionType,\n): boolean {\n return (\n parentTransactionType === TransactionType.perpsDeposit &&\n request.isPostQuote !== true &&\n request.targetChainId === CHAIN_ID_ARBITRUM &&\n request.targetTokenAddress.toLowerCase() ===\n ARBITRUM_USDC_ADDRESS.toLowerCase()\n );\n}\n\n/**\n * Convert the transaction-pay request into the Across route shape required for\n * direct perps deposits.\n *\n * Transaction pay starts from the required on-chain asset identity\n * (Arbitrum USDC, 6 decimals), while Across now expects the HyperCore\n * USDC-PERPS destination token (8 decimals).\n *\n * @param request - Transaction pay quote request.\n * @param parentTransactionType - Parent transaction type before Across\n * execution.\n * @returns Normalized request for Across quoting.\n */\nexport function normalizeAcrossRequest(\n request: QuoteRequest,\n parentTransactionType?: TransactionType,\n): QuoteRequest {\n if (!isSupportedAcrossPerpsDepositRequest(request, parentTransactionType)) {\n return request;\n }\n\n return {\n ...request,\n targetAmountMinimum: new BigNumber(request.targetAmountMinimum)\n .shiftedBy(HYPERCORE_USDC_DECIMALS - USDC_DECIMALS)\n .toFixed(0),\n targetChainId: CHAIN_ID_HYPERCORE,\n targetTokenAddress: ACROSS_HYPERCORE_USDC_PERPS_ADDRESS,\n };\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.updateSourceAmounts = void 0;
4
+ const transaction_controller_1 = require("@metamask/transaction-controller");
4
5
  const utils_1 = require("@metamask/utils");
5
6
  const bignumber_js_1 = require("bignumber.js");
6
7
  const token_1 = require("./token.cjs");
@@ -27,7 +28,8 @@ function updateSourceAmounts(transactionId, transactionData, messenger) {
27
28
  // For post-quote flows, source amounts are calculated differently
28
29
  // The source is the transaction's required token, not the selected token
29
30
  if (isPostQuote) {
30
- const sourceAmounts = calculatePostQuoteSourceAmounts(tokens, paymentToken, isMaxAmount ?? false);
31
+ const { isHyperliquidSource } = transactionData;
32
+ const sourceAmounts = calculatePostQuoteSourceAmounts(tokens, paymentToken, isMaxAmount ?? false, isHyperliquidSource);
31
33
  log('Updated post-quote source amounts', { transactionId, sourceAmounts });
32
34
  transactionData.sourceAmounts = sourceAmounts;
33
35
  return;
@@ -47,9 +49,10 @@ exports.updateSourceAmounts = updateSourceAmounts;
47
49
  * @param tokens - Required tokens from the transaction.
48
50
  * @param paymentToken - Selected payment/destination token.
49
51
  * @param isMaxAmount - Whether the transaction is a maximum amount transaction.
52
+ * @param isHyperliquidSource - Whether the source is HyperLiquid (perps withdrawal).
50
53
  * @returns Array of source amounts.
51
54
  */
52
- function calculatePostQuoteSourceAmounts(tokens, paymentToken, isMaxAmount) {
55
+ function calculatePostQuoteSourceAmounts(tokens, paymentToken, isMaxAmount, isHyperliquidSource) {
53
56
  return tokens
54
57
  .filter((token) => {
55
58
  if (token.skipIfBalance) {
@@ -60,8 +63,11 @@ function calculatePostQuoteSourceAmounts(tokens, paymentToken, isMaxAmount) {
60
63
  log('Skipping token as zero amount', { tokenAddress: token.address });
61
64
  return false;
62
65
  }
63
- // Skip same token on same chain
64
- if ((0, token_1.isSameToken)(token, paymentToken)) {
66
+ // Skip same token on same chain, unless the source is HyperLiquid.
67
+ // For HyperLiquid withdrawals the relay strategy renormalizes the
68
+ // source from Arbitrum USDC to HyperCore USDC (a different chain),
69
+ // so the tokens are not actually the same after normalization.
70
+ if ((0, token_1.isSameToken)(token, paymentToken) && !isHyperliquidSource) {
65
71
  log('Skipping token as same as destination token');
66
72
  return false;
67
73
  }
@@ -98,8 +104,8 @@ function calculateSourceAmount(paymentToken, token, messenger, transactionId, is
98
104
  });
99
105
  return undefined;
100
106
  }
101
- const strategy = getStrategyType(transactionId, messenger);
102
- const isAlwaysRequired = isQuoteAlwaysRequired(token, strategy);
107
+ const { parentTransactionType, strategy } = getStrategyContext(transactionId, messenger);
108
+ const isAlwaysRequired = isQuoteAlwaysRequired(token, strategy, parentTransactionType);
103
109
  if ((0, token_1.isSameToken)(token, paymentToken) && !isAlwaysRequired) {
104
110
  log('Skipping token as same as payment token');
105
111
  return undefined;
@@ -131,22 +137,22 @@ function calculateSourceAmount(paymentToken, token, messenger, transactionId, is
131
137
  *
132
138
  * @param token - Target token.
133
139
  * @param strategy - Payment strategy.
140
+ * @param parentTransactionType - Parent transaction type, if available.
134
141
  * @returns True if a quote is always required, false otherwise.
135
142
  */
136
- function isQuoteAlwaysRequired(token, strategy) {
143
+ function isQuoteAlwaysRequired(token, strategy, parentTransactionType) {
137
144
  const isHyperliquidDeposit = token.chainId === constants_1.CHAIN_ID_ARBITRUM &&
138
145
  token.address.toLowerCase() === constants_1.ARBITRUM_USDC_ADDRESS.toLowerCase();
139
- return strategy === __1.TransactionPayStrategy.Relay && isHyperliquidDeposit;
146
+ return (isHyperliquidDeposit &&
147
+ (strategy === __1.TransactionPayStrategy.Relay ||
148
+ (strategy === __1.TransactionPayStrategy.Across &&
149
+ parentTransactionType === transaction_controller_1.TransactionType.perpsDeposit)));
140
150
  }
141
- /**
142
- * Get the strategy type for a transaction.
143
- *
144
- * @param transactionId - ID of the transaction.
145
- * @param messenger - Controller messenger.
146
- * @returns Payment strategy type.
147
- */
148
- function getStrategyType(transactionId, messenger) {
151
+ function getStrategyContext(transactionId, messenger) {
149
152
  const transaction = (0, transaction_1.getTransaction)(transactionId, messenger);
150
- return messenger.call('TransactionPayController:getStrategy', transaction);
153
+ return {
154
+ parentTransactionType: transaction.type,
155
+ strategy: messenger.call('TransactionPayController:getStrategy', transaction),
156
+ };
151
157
  }
152
158
  //# sourceMappingURL=source-amounts.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"source-amounts.cjs","sourceRoot":"","sources":["../../src/utils/source-amounts.ts"],"names":[],"mappings":"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","sourcesContent":["import { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { getTokenFiatRate, isSameToken } from './token';\nimport { getTransaction } from './transaction';\nimport type {\n TransactionPayControllerMessenger,\n TransactionPaymentToken,\n} from '..';\nimport { TransactionPayStrategy } from '..';\nimport type { TransactionMeta } from '../../../transaction-controller/src';\nimport { ARBITRUM_USDC_ADDRESS, CHAIN_ID_ARBITRUM } from '../constants';\nimport { projectLogger } from '../logger';\nimport type {\n TransactionPaySourceAmount,\n TransactionData,\n TransactionPayRequiredToken,\n} from '../types';\n\nconst log = createModuleLogger(projectLogger, 'source-amounts');\n\n/**\n * Update the source amounts for a transaction.\n *\n * @param transactionId - ID of the transaction to update.\n * @param transactionData - Existing transaction data.\n * @param messenger - Controller messenger.\n */\nexport function updateSourceAmounts(\n transactionId: string,\n transactionData: TransactionData | undefined,\n messenger: TransactionPayControllerMessenger,\n): void {\n if (!transactionData) {\n return;\n }\n\n const { isMaxAmount, isPostQuote, paymentToken, tokens } = transactionData;\n\n if (!tokens.length || !paymentToken) {\n return;\n }\n\n // For post-quote flows, source amounts are calculated differently\n // The source is the transaction's required token, not the selected token\n if (isPostQuote) {\n const sourceAmounts = calculatePostQuoteSourceAmounts(\n tokens,\n paymentToken,\n isMaxAmount ?? false,\n );\n log('Updated post-quote source amounts', { transactionId, sourceAmounts });\n transactionData.sourceAmounts = sourceAmounts;\n return;\n }\n\n const sourceAmounts = tokens\n .map((singleToken) =>\n calculateSourceAmount(\n paymentToken,\n singleToken,\n messenger,\n transactionId,\n isMaxAmount ?? false,\n ),\n )\n .filter(Boolean) as TransactionPaySourceAmount[];\n\n log('Updated source amounts', { transactionId, sourceAmounts });\n\n transactionData.sourceAmounts = sourceAmounts;\n}\n\n/**\n * Calculate source amounts for post-quote flows.\n * In this flow, the required tokens ARE the source tokens,\n * and the payment token is the target (destination).\n *\n * @param tokens - Required tokens from the transaction.\n * @param paymentToken - Selected payment/destination token.\n * @param isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @returns Array of source amounts.\n */\nfunction calculatePostQuoteSourceAmounts(\n tokens: TransactionPayRequiredToken[],\n paymentToken: TransactionPaymentToken,\n isMaxAmount: boolean,\n): TransactionPaySourceAmount[] {\n return tokens\n .filter((token) => {\n if (token.skipIfBalance) {\n return false;\n }\n\n // Skip zero amounts (unless max amount, where we use balance)\n if (token.amountRaw === '0' && !isMaxAmount) {\n log('Skipping token as zero amount', { tokenAddress: token.address });\n return false;\n }\n\n // Skip same token on same chain\n if (isSameToken(token, paymentToken)) {\n log('Skipping token as same as destination token');\n return false;\n }\n\n return true;\n })\n .map((token) => ({\n sourceAmountHuman: isMaxAmount ? token.balanceHuman : token.amountHuman,\n sourceAmountRaw: isMaxAmount ? token.balanceRaw : token.amountRaw,\n sourceBalanceRaw: token.balanceRaw,\n sourceChainId: token.chainId,\n sourceTokenAddress: token.address,\n targetTokenAddress: paymentToken.address,\n }));\n}\n\n/**\n * Calculate the required source amount for a payment token to cover a target token.\n *\n * @param paymentToken - Selected payment token.\n * @param token - Target token to cover.\n * @param messenger - Controller messenger.\n * @param transactionId - ID of the transaction.\n * @param isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @returns The source amount or undefined if calculation failed.\n */\nfunction calculateSourceAmount(\n paymentToken: TransactionPaymentToken,\n token: TransactionPayRequiredToken,\n messenger: TransactionPayControllerMessenger,\n transactionId: string,\n isMaxAmount: boolean,\n): TransactionPaySourceAmount | undefined {\n const paymentTokenFiatRate = getTokenFiatRate(\n messenger,\n paymentToken.address,\n paymentToken.chainId,\n );\n\n if (!paymentTokenFiatRate) {\n return undefined;\n }\n\n const hasBalance = new BigNumber(token.balanceRaw).gte(token.amountRaw);\n\n if (token.skipIfBalance && hasBalance) {\n log('Skipping token as sufficient balance', {\n tokenAddress: token.address,\n });\n return undefined;\n }\n\n const strategy = getStrategyType(transactionId, messenger);\n const isAlwaysRequired = isQuoteAlwaysRequired(token, strategy);\n\n if (isSameToken(token, paymentToken) && !isAlwaysRequired) {\n log('Skipping token as same as payment token');\n return undefined;\n }\n\n const sourceAmountHumanValue = new BigNumber(token.amountUsd).div(\n paymentTokenFiatRate.usdRate,\n );\n\n const sourceAmountHuman = sourceAmountHumanValue.toString(10);\n\n const sourceAmountRaw = sourceAmountHumanValue\n .shiftedBy(paymentToken.decimals)\n .toFixed(0);\n\n if (token.amountRaw === '0') {\n log('Skipping token as zero amount', { tokenAddress: token.address });\n return undefined;\n }\n\n if (isMaxAmount) {\n return {\n sourceAmountHuman: paymentToken.balanceHuman,\n sourceAmountRaw: paymentToken.balanceRaw,\n targetTokenAddress: token.address,\n };\n }\n\n return {\n sourceAmountHuman,\n sourceAmountRaw,\n targetTokenAddress: token.address,\n };\n}\n\n/**\n * Determine if a quote is always required for a token and strategy.\n *\n * @param token - Target token.\n * @param strategy - Payment strategy.\n * @returns True if a quote is always required, false otherwise.\n */\nfunction isQuoteAlwaysRequired(\n token: TransactionPayRequiredToken,\n strategy: TransactionPayStrategy,\n): boolean {\n const isHyperliquidDeposit =\n token.chainId === CHAIN_ID_ARBITRUM &&\n token.address.toLowerCase() === ARBITRUM_USDC_ADDRESS.toLowerCase();\n\n return strategy === TransactionPayStrategy.Relay && isHyperliquidDeposit;\n}\n\n/**\n * Get the strategy type for a transaction.\n *\n * @param transactionId - ID of the transaction.\n * @param messenger - Controller messenger.\n * @returns Payment strategy type.\n */\nfunction getStrategyType(\n transactionId: string,\n messenger: TransactionPayControllerMessenger,\n): TransactionPayStrategy {\n const transaction = getTransaction(\n transactionId,\n messenger,\n ) as TransactionMeta;\n\n return messenger.call('TransactionPayController:getStrategy', transaction);\n}\n"]}
1
+ {"version":3,"file":"source-amounts.cjs","sourceRoot":"","sources":["../../src/utils/source-amounts.ts"],"names":[],"mappings":"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","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { getTokenFiatRate, isSameToken } from './token';\nimport { getTransaction } from './transaction';\nimport type {\n TransactionPayControllerMessenger,\n TransactionPaymentToken,\n} from '..';\nimport { TransactionPayStrategy } from '..';\nimport type { TransactionMeta } from '../../../transaction-controller/src';\nimport { ARBITRUM_USDC_ADDRESS, CHAIN_ID_ARBITRUM } from '../constants';\nimport { projectLogger } from '../logger';\nimport type {\n TransactionPaySourceAmount,\n TransactionData,\n TransactionPayRequiredToken,\n} from '../types';\n\nconst log = createModuleLogger(projectLogger, 'source-amounts');\n\n/**\n * Update the source amounts for a transaction.\n *\n * @param transactionId - ID of the transaction to update.\n * @param transactionData - Existing transaction data.\n * @param messenger - Controller messenger.\n */\nexport function updateSourceAmounts(\n transactionId: string,\n transactionData: TransactionData | undefined,\n messenger: TransactionPayControllerMessenger,\n): void {\n if (!transactionData) {\n return;\n }\n\n const { isMaxAmount, isPostQuote, paymentToken, tokens } = transactionData;\n\n if (!tokens.length || !paymentToken) {\n return;\n }\n\n // For post-quote flows, source amounts are calculated differently\n // The source is the transaction's required token, not the selected token\n if (isPostQuote) {\n const { isHyperliquidSource } = transactionData;\n const sourceAmounts = calculatePostQuoteSourceAmounts(\n tokens,\n paymentToken,\n isMaxAmount ?? false,\n isHyperliquidSource,\n );\n log('Updated post-quote source amounts', { transactionId, sourceAmounts });\n transactionData.sourceAmounts = sourceAmounts;\n return;\n }\n\n const sourceAmounts = tokens\n .map((singleToken) =>\n calculateSourceAmount(\n paymentToken,\n singleToken,\n messenger,\n transactionId,\n isMaxAmount ?? false,\n ),\n )\n .filter(Boolean) as TransactionPaySourceAmount[];\n\n log('Updated source amounts', { transactionId, sourceAmounts });\n\n transactionData.sourceAmounts = sourceAmounts;\n}\n\n/**\n * Calculate source amounts for post-quote flows.\n * In this flow, the required tokens ARE the source tokens,\n * and the payment token is the target (destination).\n *\n * @param tokens - Required tokens from the transaction.\n * @param paymentToken - Selected payment/destination token.\n * @param isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @param isHyperliquidSource - Whether the source is HyperLiquid (perps withdrawal).\n * @returns Array of source amounts.\n */\nfunction calculatePostQuoteSourceAmounts(\n tokens: TransactionPayRequiredToken[],\n paymentToken: TransactionPaymentToken,\n isMaxAmount: boolean,\n isHyperliquidSource?: boolean,\n): TransactionPaySourceAmount[] {\n return tokens\n .filter((token) => {\n if (token.skipIfBalance) {\n return false;\n }\n\n // Skip zero amounts (unless max amount, where we use balance)\n if (token.amountRaw === '0' && !isMaxAmount) {\n log('Skipping token as zero amount', { tokenAddress: token.address });\n return false;\n }\n\n // Skip same token on same chain, unless the source is HyperLiquid.\n // For HyperLiquid withdrawals the relay strategy renormalizes the\n // source from Arbitrum USDC to HyperCore USDC (a different chain),\n // so the tokens are not actually the same after normalization.\n if (isSameToken(token, paymentToken) && !isHyperliquidSource) {\n log('Skipping token as same as destination token');\n return false;\n }\n\n return true;\n })\n .map((token) => ({\n sourceAmountHuman: isMaxAmount ? token.balanceHuman : token.amountHuman,\n sourceAmountRaw: isMaxAmount ? token.balanceRaw : token.amountRaw,\n sourceBalanceRaw: token.balanceRaw,\n sourceChainId: token.chainId,\n sourceTokenAddress: token.address,\n targetTokenAddress: paymentToken.address,\n }));\n}\n\n/**\n * Calculate the required source amount for a payment token to cover a target token.\n *\n * @param paymentToken - Selected payment token.\n * @param token - Target token to cover.\n * @param messenger - Controller messenger.\n * @param transactionId - ID of the transaction.\n * @param isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @returns The source amount or undefined if calculation failed.\n */\nfunction calculateSourceAmount(\n paymentToken: TransactionPaymentToken,\n token: TransactionPayRequiredToken,\n messenger: TransactionPayControllerMessenger,\n transactionId: string,\n isMaxAmount: boolean,\n): TransactionPaySourceAmount | undefined {\n const paymentTokenFiatRate = getTokenFiatRate(\n messenger,\n paymentToken.address,\n paymentToken.chainId,\n );\n\n if (!paymentTokenFiatRate) {\n return undefined;\n }\n\n const hasBalance = new BigNumber(token.balanceRaw).gte(token.amountRaw);\n\n if (token.skipIfBalance && hasBalance) {\n log('Skipping token as sufficient balance', {\n tokenAddress: token.address,\n });\n return undefined;\n }\n\n const { parentTransactionType, strategy } = getStrategyContext(\n transactionId,\n messenger,\n );\n const isAlwaysRequired = isQuoteAlwaysRequired(\n token,\n strategy,\n parentTransactionType,\n );\n\n if (isSameToken(token, paymentToken) && !isAlwaysRequired) {\n log('Skipping token as same as payment token');\n return undefined;\n }\n\n const sourceAmountHumanValue = new BigNumber(token.amountUsd).div(\n paymentTokenFiatRate.usdRate,\n );\n\n const sourceAmountHuman = sourceAmountHumanValue.toString(10);\n\n const sourceAmountRaw = sourceAmountHumanValue\n .shiftedBy(paymentToken.decimals)\n .toFixed(0);\n\n if (token.amountRaw === '0') {\n log('Skipping token as zero amount', { tokenAddress: token.address });\n return undefined;\n }\n\n if (isMaxAmount) {\n return {\n sourceAmountHuman: paymentToken.balanceHuman,\n sourceAmountRaw: paymentToken.balanceRaw,\n targetTokenAddress: token.address,\n };\n }\n\n return {\n sourceAmountHuman,\n sourceAmountRaw,\n targetTokenAddress: token.address,\n };\n}\n\n/**\n * Determine if a quote is always required for a token and strategy.\n *\n * @param token - Target token.\n * @param strategy - Payment strategy.\n * @param parentTransactionType - Parent transaction type, if available.\n * @returns True if a quote is always required, false otherwise.\n */\nfunction isQuoteAlwaysRequired(\n token: TransactionPayRequiredToken,\n strategy: TransactionPayStrategy,\n parentTransactionType?: TransactionType,\n): boolean {\n const isHyperliquidDeposit =\n token.chainId === CHAIN_ID_ARBITRUM &&\n token.address.toLowerCase() === ARBITRUM_USDC_ADDRESS.toLowerCase();\n\n return (\n isHyperliquidDeposit &&\n (strategy === TransactionPayStrategy.Relay ||\n (strategy === TransactionPayStrategy.Across &&\n parentTransactionType === TransactionType.perpsDeposit))\n );\n}\n\nfunction getStrategyContext(\n transactionId: string,\n messenger: TransactionPayControllerMessenger,\n): {\n parentTransactionType?: TransactionType;\n strategy: TransactionPayStrategy;\n} {\n const transaction = getTransaction(\n transactionId,\n messenger,\n ) as TransactionMeta;\n\n return {\n parentTransactionType: transaction.type,\n strategy: messenger.call(\n 'TransactionPayController:getStrategy',\n transaction,\n ),\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"source-amounts.d.cts","sourceRoot":"","sources":["../../src/utils/source-amounts.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,iCAAiC,EAElC,qBAAW;AAKZ,OAAO,KAAK,EAEV,eAAe,EAEhB,qBAAiB;AAIlB;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,eAAe,GAAG,SAAS,EAC5C,SAAS,EAAE,iCAAiC,GAC3C,IAAI,CAuCN"}
1
+ {"version":3,"file":"source-amounts.d.cts","sourceRoot":"","sources":["../../src/utils/source-amounts.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,iCAAiC,EAElC,qBAAW;AAKZ,OAAO,KAAK,EAEV,eAAe,EAEhB,qBAAiB;AAIlB;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,eAAe,GAAG,SAAS,EAC5C,SAAS,EAAE,iCAAiC,GAC3C,IAAI,CAyCN"}
@@ -1 +1 @@
1
- {"version":3,"file":"source-amounts.d.mts","sourceRoot":"","sources":["../../src/utils/source-amounts.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,iCAAiC,EAElC,qBAAW;AAKZ,OAAO,KAAK,EAEV,eAAe,EAEhB,qBAAiB;AAIlB;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,eAAe,GAAG,SAAS,EAC5C,SAAS,EAAE,iCAAiC,GAC3C,IAAI,CAuCN"}
1
+ {"version":3,"file":"source-amounts.d.mts","sourceRoot":"","sources":["../../src/utils/source-amounts.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,iCAAiC,EAElC,qBAAW;AAKZ,OAAO,KAAK,EAEV,eAAe,EAEhB,qBAAiB;AAIlB;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,eAAe,GAAG,SAAS,EAC5C,SAAS,EAAE,iCAAiC,GAC3C,IAAI,CAyCN"}
@@ -1,3 +1,4 @@
1
+ import { TransactionType } from "@metamask/transaction-controller";
1
2
  import { createModuleLogger } from "@metamask/utils";
2
3
  import { BigNumber } from "bignumber.js";
3
4
  import { getTokenFiatRate, isSameToken } from "./token.mjs";
@@ -24,7 +25,8 @@ export function updateSourceAmounts(transactionId, transactionData, messenger) {
24
25
  // For post-quote flows, source amounts are calculated differently
25
26
  // The source is the transaction's required token, not the selected token
26
27
  if (isPostQuote) {
27
- const sourceAmounts = calculatePostQuoteSourceAmounts(tokens, paymentToken, isMaxAmount ?? false);
28
+ const { isHyperliquidSource } = transactionData;
29
+ const sourceAmounts = calculatePostQuoteSourceAmounts(tokens, paymentToken, isMaxAmount ?? false, isHyperliquidSource);
28
30
  log('Updated post-quote source amounts', { transactionId, sourceAmounts });
29
31
  transactionData.sourceAmounts = sourceAmounts;
30
32
  return;
@@ -43,9 +45,10 @@ export function updateSourceAmounts(transactionId, transactionData, messenger) {
43
45
  * @param tokens - Required tokens from the transaction.
44
46
  * @param paymentToken - Selected payment/destination token.
45
47
  * @param isMaxAmount - Whether the transaction is a maximum amount transaction.
48
+ * @param isHyperliquidSource - Whether the source is HyperLiquid (perps withdrawal).
46
49
  * @returns Array of source amounts.
47
50
  */
48
- function calculatePostQuoteSourceAmounts(tokens, paymentToken, isMaxAmount) {
51
+ function calculatePostQuoteSourceAmounts(tokens, paymentToken, isMaxAmount, isHyperliquidSource) {
49
52
  return tokens
50
53
  .filter((token) => {
51
54
  if (token.skipIfBalance) {
@@ -56,8 +59,11 @@ function calculatePostQuoteSourceAmounts(tokens, paymentToken, isMaxAmount) {
56
59
  log('Skipping token as zero amount', { tokenAddress: token.address });
57
60
  return false;
58
61
  }
59
- // Skip same token on same chain
60
- if (isSameToken(token, paymentToken)) {
62
+ // Skip same token on same chain, unless the source is HyperLiquid.
63
+ // For HyperLiquid withdrawals the relay strategy renormalizes the
64
+ // source from Arbitrum USDC to HyperCore USDC (a different chain),
65
+ // so the tokens are not actually the same after normalization.
66
+ if (isSameToken(token, paymentToken) && !isHyperliquidSource) {
61
67
  log('Skipping token as same as destination token');
62
68
  return false;
63
69
  }
@@ -94,8 +100,8 @@ function calculateSourceAmount(paymentToken, token, messenger, transactionId, is
94
100
  });
95
101
  return undefined;
96
102
  }
97
- const strategy = getStrategyType(transactionId, messenger);
98
- const isAlwaysRequired = isQuoteAlwaysRequired(token, strategy);
103
+ const { parentTransactionType, strategy } = getStrategyContext(transactionId, messenger);
104
+ const isAlwaysRequired = isQuoteAlwaysRequired(token, strategy, parentTransactionType);
99
105
  if (isSameToken(token, paymentToken) && !isAlwaysRequired) {
100
106
  log('Skipping token as same as payment token');
101
107
  return undefined;
@@ -127,22 +133,22 @@ function calculateSourceAmount(paymentToken, token, messenger, transactionId, is
127
133
  *
128
134
  * @param token - Target token.
129
135
  * @param strategy - Payment strategy.
136
+ * @param parentTransactionType - Parent transaction type, if available.
130
137
  * @returns True if a quote is always required, false otherwise.
131
138
  */
132
- function isQuoteAlwaysRequired(token, strategy) {
139
+ function isQuoteAlwaysRequired(token, strategy, parentTransactionType) {
133
140
  const isHyperliquidDeposit = token.chainId === CHAIN_ID_ARBITRUM &&
134
141
  token.address.toLowerCase() === ARBITRUM_USDC_ADDRESS.toLowerCase();
135
- return strategy === TransactionPayStrategy.Relay && isHyperliquidDeposit;
142
+ return (isHyperliquidDeposit &&
143
+ (strategy === TransactionPayStrategy.Relay ||
144
+ (strategy === TransactionPayStrategy.Across &&
145
+ parentTransactionType === TransactionType.perpsDeposit)));
136
146
  }
137
- /**
138
- * Get the strategy type for a transaction.
139
- *
140
- * @param transactionId - ID of the transaction.
141
- * @param messenger - Controller messenger.
142
- * @returns Payment strategy type.
143
- */
144
- function getStrategyType(transactionId, messenger) {
147
+ function getStrategyContext(transactionId, messenger) {
145
148
  const transaction = getTransaction(transactionId, messenger);
146
- return messenger.call('TransactionPayController:getStrategy', transaction);
149
+ return {
150
+ parentTransactionType: transaction.type,
151
+ strategy: messenger.call('TransactionPayController:getStrategy', transaction),
152
+ };
147
153
  }
148
154
  //# sourceMappingURL=source-amounts.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"source-amounts.mjs","sourceRoot":"","sources":["../../src/utils/source-amounts.ts"],"names":[],"mappings":"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","sourcesContent":["import { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { getTokenFiatRate, isSameToken } from './token';\nimport { getTransaction } from './transaction';\nimport type {\n TransactionPayControllerMessenger,\n TransactionPaymentToken,\n} from '..';\nimport { TransactionPayStrategy } from '..';\nimport type { TransactionMeta } from '../../../transaction-controller/src';\nimport { ARBITRUM_USDC_ADDRESS, CHAIN_ID_ARBITRUM } from '../constants';\nimport { projectLogger } from '../logger';\nimport type {\n TransactionPaySourceAmount,\n TransactionData,\n TransactionPayRequiredToken,\n} from '../types';\n\nconst log = createModuleLogger(projectLogger, 'source-amounts');\n\n/**\n * Update the source amounts for a transaction.\n *\n * @param transactionId - ID of the transaction to update.\n * @param transactionData - Existing transaction data.\n * @param messenger - Controller messenger.\n */\nexport function updateSourceAmounts(\n transactionId: string,\n transactionData: TransactionData | undefined,\n messenger: TransactionPayControllerMessenger,\n): void {\n if (!transactionData) {\n return;\n }\n\n const { isMaxAmount, isPostQuote, paymentToken, tokens } = transactionData;\n\n if (!tokens.length || !paymentToken) {\n return;\n }\n\n // For post-quote flows, source amounts are calculated differently\n // The source is the transaction's required token, not the selected token\n if (isPostQuote) {\n const sourceAmounts = calculatePostQuoteSourceAmounts(\n tokens,\n paymentToken,\n isMaxAmount ?? false,\n );\n log('Updated post-quote source amounts', { transactionId, sourceAmounts });\n transactionData.sourceAmounts = sourceAmounts;\n return;\n }\n\n const sourceAmounts = tokens\n .map((singleToken) =>\n calculateSourceAmount(\n paymentToken,\n singleToken,\n messenger,\n transactionId,\n isMaxAmount ?? false,\n ),\n )\n .filter(Boolean) as TransactionPaySourceAmount[];\n\n log('Updated source amounts', { transactionId, sourceAmounts });\n\n transactionData.sourceAmounts = sourceAmounts;\n}\n\n/**\n * Calculate source amounts for post-quote flows.\n * In this flow, the required tokens ARE the source tokens,\n * and the payment token is the target (destination).\n *\n * @param tokens - Required tokens from the transaction.\n * @param paymentToken - Selected payment/destination token.\n * @param isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @returns Array of source amounts.\n */\nfunction calculatePostQuoteSourceAmounts(\n tokens: TransactionPayRequiredToken[],\n paymentToken: TransactionPaymentToken,\n isMaxAmount: boolean,\n): TransactionPaySourceAmount[] {\n return tokens\n .filter((token) => {\n if (token.skipIfBalance) {\n return false;\n }\n\n // Skip zero amounts (unless max amount, where we use balance)\n if (token.amountRaw === '0' && !isMaxAmount) {\n log('Skipping token as zero amount', { tokenAddress: token.address });\n return false;\n }\n\n // Skip same token on same chain\n if (isSameToken(token, paymentToken)) {\n log('Skipping token as same as destination token');\n return false;\n }\n\n return true;\n })\n .map((token) => ({\n sourceAmountHuman: isMaxAmount ? token.balanceHuman : token.amountHuman,\n sourceAmountRaw: isMaxAmount ? token.balanceRaw : token.amountRaw,\n sourceBalanceRaw: token.balanceRaw,\n sourceChainId: token.chainId,\n sourceTokenAddress: token.address,\n targetTokenAddress: paymentToken.address,\n }));\n}\n\n/**\n * Calculate the required source amount for a payment token to cover a target token.\n *\n * @param paymentToken - Selected payment token.\n * @param token - Target token to cover.\n * @param messenger - Controller messenger.\n * @param transactionId - ID of the transaction.\n * @param isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @returns The source amount or undefined if calculation failed.\n */\nfunction calculateSourceAmount(\n paymentToken: TransactionPaymentToken,\n token: TransactionPayRequiredToken,\n messenger: TransactionPayControllerMessenger,\n transactionId: string,\n isMaxAmount: boolean,\n): TransactionPaySourceAmount | undefined {\n const paymentTokenFiatRate = getTokenFiatRate(\n messenger,\n paymentToken.address,\n paymentToken.chainId,\n );\n\n if (!paymentTokenFiatRate) {\n return undefined;\n }\n\n const hasBalance = new BigNumber(token.balanceRaw).gte(token.amountRaw);\n\n if (token.skipIfBalance && hasBalance) {\n log('Skipping token as sufficient balance', {\n tokenAddress: token.address,\n });\n return undefined;\n }\n\n const strategy = getStrategyType(transactionId, messenger);\n const isAlwaysRequired = isQuoteAlwaysRequired(token, strategy);\n\n if (isSameToken(token, paymentToken) && !isAlwaysRequired) {\n log('Skipping token as same as payment token');\n return undefined;\n }\n\n const sourceAmountHumanValue = new BigNumber(token.amountUsd).div(\n paymentTokenFiatRate.usdRate,\n );\n\n const sourceAmountHuman = sourceAmountHumanValue.toString(10);\n\n const sourceAmountRaw = sourceAmountHumanValue\n .shiftedBy(paymentToken.decimals)\n .toFixed(0);\n\n if (token.amountRaw === '0') {\n log('Skipping token as zero amount', { tokenAddress: token.address });\n return undefined;\n }\n\n if (isMaxAmount) {\n return {\n sourceAmountHuman: paymentToken.balanceHuman,\n sourceAmountRaw: paymentToken.balanceRaw,\n targetTokenAddress: token.address,\n };\n }\n\n return {\n sourceAmountHuman,\n sourceAmountRaw,\n targetTokenAddress: token.address,\n };\n}\n\n/**\n * Determine if a quote is always required for a token and strategy.\n *\n * @param token - Target token.\n * @param strategy - Payment strategy.\n * @returns True if a quote is always required, false otherwise.\n */\nfunction isQuoteAlwaysRequired(\n token: TransactionPayRequiredToken,\n strategy: TransactionPayStrategy,\n): boolean {\n const isHyperliquidDeposit =\n token.chainId === CHAIN_ID_ARBITRUM &&\n token.address.toLowerCase() === ARBITRUM_USDC_ADDRESS.toLowerCase();\n\n return strategy === TransactionPayStrategy.Relay && isHyperliquidDeposit;\n}\n\n/**\n * Get the strategy type for a transaction.\n *\n * @param transactionId - ID of the transaction.\n * @param messenger - Controller messenger.\n * @returns Payment strategy type.\n */\nfunction getStrategyType(\n transactionId: string,\n messenger: TransactionPayControllerMessenger,\n): TransactionPayStrategy {\n const transaction = getTransaction(\n transactionId,\n messenger,\n ) as TransactionMeta;\n\n return messenger.call('TransactionPayController:getStrategy', transaction);\n}\n"]}
1
+ {"version":3,"file":"source-amounts.mjs","sourceRoot":"","sources":["../../src/utils/source-amounts.ts"],"names":[],"mappings":"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","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { getTokenFiatRate, isSameToken } from './token';\nimport { getTransaction } from './transaction';\nimport type {\n TransactionPayControllerMessenger,\n TransactionPaymentToken,\n} from '..';\nimport { TransactionPayStrategy } from '..';\nimport type { TransactionMeta } from '../../../transaction-controller/src';\nimport { ARBITRUM_USDC_ADDRESS, CHAIN_ID_ARBITRUM } from '../constants';\nimport { projectLogger } from '../logger';\nimport type {\n TransactionPaySourceAmount,\n TransactionData,\n TransactionPayRequiredToken,\n} from '../types';\n\nconst log = createModuleLogger(projectLogger, 'source-amounts');\n\n/**\n * Update the source amounts for a transaction.\n *\n * @param transactionId - ID of the transaction to update.\n * @param transactionData - Existing transaction data.\n * @param messenger - Controller messenger.\n */\nexport function updateSourceAmounts(\n transactionId: string,\n transactionData: TransactionData | undefined,\n messenger: TransactionPayControllerMessenger,\n): void {\n if (!transactionData) {\n return;\n }\n\n const { isMaxAmount, isPostQuote, paymentToken, tokens } = transactionData;\n\n if (!tokens.length || !paymentToken) {\n return;\n }\n\n // For post-quote flows, source amounts are calculated differently\n // The source is the transaction's required token, not the selected token\n if (isPostQuote) {\n const { isHyperliquidSource } = transactionData;\n const sourceAmounts = calculatePostQuoteSourceAmounts(\n tokens,\n paymentToken,\n isMaxAmount ?? false,\n isHyperliquidSource,\n );\n log('Updated post-quote source amounts', { transactionId, sourceAmounts });\n transactionData.sourceAmounts = sourceAmounts;\n return;\n }\n\n const sourceAmounts = tokens\n .map((singleToken) =>\n calculateSourceAmount(\n paymentToken,\n singleToken,\n messenger,\n transactionId,\n isMaxAmount ?? false,\n ),\n )\n .filter(Boolean) as TransactionPaySourceAmount[];\n\n log('Updated source amounts', { transactionId, sourceAmounts });\n\n transactionData.sourceAmounts = sourceAmounts;\n}\n\n/**\n * Calculate source amounts for post-quote flows.\n * In this flow, the required tokens ARE the source tokens,\n * and the payment token is the target (destination).\n *\n * @param tokens - Required tokens from the transaction.\n * @param paymentToken - Selected payment/destination token.\n * @param isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @param isHyperliquidSource - Whether the source is HyperLiquid (perps withdrawal).\n * @returns Array of source amounts.\n */\nfunction calculatePostQuoteSourceAmounts(\n tokens: TransactionPayRequiredToken[],\n paymentToken: TransactionPaymentToken,\n isMaxAmount: boolean,\n isHyperliquidSource?: boolean,\n): TransactionPaySourceAmount[] {\n return tokens\n .filter((token) => {\n if (token.skipIfBalance) {\n return false;\n }\n\n // Skip zero amounts (unless max amount, where we use balance)\n if (token.amountRaw === '0' && !isMaxAmount) {\n log('Skipping token as zero amount', { tokenAddress: token.address });\n return false;\n }\n\n // Skip same token on same chain, unless the source is HyperLiquid.\n // For HyperLiquid withdrawals the relay strategy renormalizes the\n // source from Arbitrum USDC to HyperCore USDC (a different chain),\n // so the tokens are not actually the same after normalization.\n if (isSameToken(token, paymentToken) && !isHyperliquidSource) {\n log('Skipping token as same as destination token');\n return false;\n }\n\n return true;\n })\n .map((token) => ({\n sourceAmountHuman: isMaxAmount ? token.balanceHuman : token.amountHuman,\n sourceAmountRaw: isMaxAmount ? token.balanceRaw : token.amountRaw,\n sourceBalanceRaw: token.balanceRaw,\n sourceChainId: token.chainId,\n sourceTokenAddress: token.address,\n targetTokenAddress: paymentToken.address,\n }));\n}\n\n/**\n * Calculate the required source amount for a payment token to cover a target token.\n *\n * @param paymentToken - Selected payment token.\n * @param token - Target token to cover.\n * @param messenger - Controller messenger.\n * @param transactionId - ID of the transaction.\n * @param isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @returns The source amount or undefined if calculation failed.\n */\nfunction calculateSourceAmount(\n paymentToken: TransactionPaymentToken,\n token: TransactionPayRequiredToken,\n messenger: TransactionPayControllerMessenger,\n transactionId: string,\n isMaxAmount: boolean,\n): TransactionPaySourceAmount | undefined {\n const paymentTokenFiatRate = getTokenFiatRate(\n messenger,\n paymentToken.address,\n paymentToken.chainId,\n );\n\n if (!paymentTokenFiatRate) {\n return undefined;\n }\n\n const hasBalance = new BigNumber(token.balanceRaw).gte(token.amountRaw);\n\n if (token.skipIfBalance && hasBalance) {\n log('Skipping token as sufficient balance', {\n tokenAddress: token.address,\n });\n return undefined;\n }\n\n const { parentTransactionType, strategy } = getStrategyContext(\n transactionId,\n messenger,\n );\n const isAlwaysRequired = isQuoteAlwaysRequired(\n token,\n strategy,\n parentTransactionType,\n );\n\n if (isSameToken(token, paymentToken) && !isAlwaysRequired) {\n log('Skipping token as same as payment token');\n return undefined;\n }\n\n const sourceAmountHumanValue = new BigNumber(token.amountUsd).div(\n paymentTokenFiatRate.usdRate,\n );\n\n const sourceAmountHuman = sourceAmountHumanValue.toString(10);\n\n const sourceAmountRaw = sourceAmountHumanValue\n .shiftedBy(paymentToken.decimals)\n .toFixed(0);\n\n if (token.amountRaw === '0') {\n log('Skipping token as zero amount', { tokenAddress: token.address });\n return undefined;\n }\n\n if (isMaxAmount) {\n return {\n sourceAmountHuman: paymentToken.balanceHuman,\n sourceAmountRaw: paymentToken.balanceRaw,\n targetTokenAddress: token.address,\n };\n }\n\n return {\n sourceAmountHuman,\n sourceAmountRaw,\n targetTokenAddress: token.address,\n };\n}\n\n/**\n * Determine if a quote is always required for a token and strategy.\n *\n * @param token - Target token.\n * @param strategy - Payment strategy.\n * @param parentTransactionType - Parent transaction type, if available.\n * @returns True if a quote is always required, false otherwise.\n */\nfunction isQuoteAlwaysRequired(\n token: TransactionPayRequiredToken,\n strategy: TransactionPayStrategy,\n parentTransactionType?: TransactionType,\n): boolean {\n const isHyperliquidDeposit =\n token.chainId === CHAIN_ID_ARBITRUM &&\n token.address.toLowerCase() === ARBITRUM_USDC_ADDRESS.toLowerCase();\n\n return (\n isHyperliquidDeposit &&\n (strategy === TransactionPayStrategy.Relay ||\n (strategy === TransactionPayStrategy.Across &&\n parentTransactionType === TransactionType.perpsDeposit))\n );\n}\n\nfunction getStrategyContext(\n transactionId: string,\n messenger: TransactionPayControllerMessenger,\n): {\n parentTransactionType?: TransactionType;\n strategy: TransactionPayStrategy;\n} {\n const transaction = getTransaction(\n transactionId,\n messenger,\n ) as TransactionMeta;\n\n return {\n parentTransactionType: transaction.type,\n strategy: messenger.call(\n 'TransactionPayController:getStrategy',\n transaction,\n ),\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/transaction-pay-controller",
3
- "version": "19.0.3-preview-b6a517f5e",
3
+ "version": "19.0.3-preview-119723bcd",
4
4
  "description": "Manages alternate payment strategies to provide required funds for transactions in MetaMask",
5
5
  "keywords": [
6
6
  "MetaMask",