@metamask/bridge-status-controller 70.0.0 → 70.0.1

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 (72) hide show
  1. package/CHANGELOG.md +14 -1
  2. package/dist/bridge-status-controller.cjs +48 -172
  3. package/dist/bridge-status-controller.cjs.map +1 -1
  4. package/dist/bridge-status-controller.d.cts +2 -1
  5. package/dist/bridge-status-controller.d.cts.map +1 -1
  6. package/dist/bridge-status-controller.d.mts +2 -1
  7. package/dist/bridge-status-controller.d.mts.map +1 -1
  8. package/dist/bridge-status-controller.intent.cjs +7 -19
  9. package/dist/bridge-status-controller.intent.cjs.map +1 -1
  10. package/dist/bridge-status-controller.intent.d.cts +2 -10
  11. package/dist/bridge-status-controller.intent.d.cts.map +1 -1
  12. package/dist/bridge-status-controller.intent.d.mts +2 -10
  13. package/dist/bridge-status-controller.intent.d.mts.map +1 -1
  14. package/dist/bridge-status-controller.intent.mjs +7 -19
  15. package/dist/bridge-status-controller.intent.mjs.map +1 -1
  16. package/dist/bridge-status-controller.mjs +51 -175
  17. package/dist/bridge-status-controller.mjs.map +1 -1
  18. package/dist/types.cjs.map +1 -1
  19. package/dist/types.d.cts +10 -4
  20. package/dist/types.d.cts.map +1 -1
  21. package/dist/types.d.mts +10 -4
  22. package/dist/types.d.mts.map +1 -1
  23. package/dist/types.mjs.map +1 -1
  24. package/dist/utils/bridge-status.cjs +17 -1
  25. package/dist/utils/bridge-status.cjs.map +1 -1
  26. package/dist/utils/bridge-status.d.cts +8 -2
  27. package/dist/utils/bridge-status.d.cts.map +1 -1
  28. package/dist/utils/bridge-status.d.mts +8 -2
  29. package/dist/utils/bridge-status.d.mts.map +1 -1
  30. package/dist/utils/bridge-status.mjs +15 -0
  31. package/dist/utils/bridge-status.mjs.map +1 -1
  32. package/dist/utils/gas.cjs +1 -58
  33. package/dist/utils/gas.cjs.map +1 -1
  34. package/dist/utils/gas.d.cts +3 -26
  35. package/dist/utils/gas.d.cts.map +1 -1
  36. package/dist/utils/gas.d.mts +3 -26
  37. package/dist/utils/gas.d.mts.map +1 -1
  38. package/dist/utils/gas.mjs +0 -55
  39. package/dist/utils/gas.mjs.map +1 -1
  40. package/dist/utils/history.cjs +9 -8
  41. package/dist/utils/history.cjs.map +1 -1
  42. package/dist/utils/history.d.cts +3 -2
  43. package/dist/utils/history.d.cts.map +1 -1
  44. package/dist/utils/history.d.mts +3 -2
  45. package/dist/utils/history.d.mts.map +1 -1
  46. package/dist/utils/history.mjs +9 -8
  47. package/dist/utils/history.mjs.map +1 -1
  48. package/dist/utils/intent-api.cjs +26 -26
  49. package/dist/utils/intent-api.cjs.map +1 -1
  50. package/dist/utils/intent-api.d.cts +7 -2
  51. package/dist/utils/intent-api.d.cts.map +1 -1
  52. package/dist/utils/intent-api.d.mts +7 -2
  53. package/dist/utils/intent-api.d.mts.map +1 -1
  54. package/dist/utils/intent-api.mjs +24 -25
  55. package/dist/utils/intent-api.mjs.map +1 -1
  56. package/dist/utils/snaps.cjs +5 -5
  57. package/dist/utils/snaps.cjs.map +1 -1
  58. package/dist/utils/snaps.d.cts +3 -17
  59. package/dist/utils/snaps.d.cts.map +1 -1
  60. package/dist/utils/snaps.d.mts +3 -17
  61. package/dist/utils/snaps.d.mts.map +1 -1
  62. package/dist/utils/snaps.mjs +6 -6
  63. package/dist/utils/snaps.mjs.map +1 -1
  64. package/dist/utils/transaction.cjs +250 -24
  65. package/dist/utils/transaction.cjs.map +1 -1
  66. package/dist/utils/transaction.d.cts +91 -169
  67. package/dist/utils/transaction.d.cts.map +1 -1
  68. package/dist/utils/transaction.d.mts +91 -169
  69. package/dist/utils/transaction.d.mts.map +1 -1
  70. package/dist/utils/transaction.mjs +234 -19
  71. package/dist/utils/transaction.mjs.map +1 -1
  72. package/package.json +3 -3
@@ -1,176 +1,57 @@
1
1
  import type { QuoteMetadata, QuoteResponse, TxData } from "@metamask/bridge-controller";
2
2
  import { TransactionType } from "@metamask/transaction-controller";
3
- import type { BatchTransactionParams, TransactionMeta } from "@metamask/transaction-controller";
3
+ import type { BatchTransactionParams, TransactionController, TransactionMeta, TransactionParams } from "@metamask/transaction-controller";
4
+ import { Hex } from "@metamask/utils";
5
+ import { BigNumber } from "bignumber.js";
4
6
  import type { BridgeStatusControllerMessenger } from "../types.mjs";
7
+ export declare const getGasFeeEstimates: (messenger: BridgeStatusControllerMessenger, args: Parameters<TransactionController['estimateGasFee']>[0]) => Promise<{
8
+ maxFeePerGas?: string;
9
+ maxPriorityFeePerGas?: string;
10
+ }>;
11
+ /**
12
+ * Get the gas fee estimates for a transaction
13
+ *
14
+ * @param messenger - The messenger for the gas fee estimates
15
+ * @param estimateGasFeeParams - The parameters for the {@link TransactionController.estimateGasFee} method
16
+
17
+ * @returns The gas fee estimates for the transaction
18
+ */
19
+ export declare const getTxGasEstimates: (messenger: BridgeStatusControllerMessenger, estimateGasFeeParams: Parameters<TransactionController['estimateGasFee']>[0]) => Promise<{
20
+ baseAndPriorityFeePerGas: BigNumber | undefined;
21
+ maxFeePerGas: string | undefined;
22
+ maxPriorityFeePerGas: string | undefined;
23
+ }>;
24
+ export declare const calculateGasFees: (skipGasFields: boolean, messenger: BridgeStatusControllerMessenger, { chainId: _, gasLimit, ...trade }: TxData, networkClientId: string, chainId: Hex, txFee?: {
25
+ maxFeePerGas: string;
26
+ maxPriorityFeePerGas: string;
27
+ }) => Promise<{
28
+ maxFeePerGas?: undefined;
29
+ maxPriorityFeePerGas?: undefined;
30
+ gas?: undefined;
31
+ } | {
32
+ gas: string | undefined;
33
+ maxFeePerGas: string;
34
+ maxPriorityFeePerGas: string;
35
+ } | {
36
+ maxFeePerGas: string | undefined;
37
+ maxPriorityFeePerGas: string | undefined;
38
+ gas: `0x${string}`;
39
+ }>;
40
+ export declare const getTransactions: (messenger: BridgeStatusControllerMessenger) => TransactionMeta[];
41
+ export declare const getTransactionMetaById: (messenger: BridgeStatusControllerMessenger, txId?: string) => TransactionMeta | undefined;
42
+ export declare const getTransactionMetaByHash: (messenger: BridgeStatusControllerMessenger, txHash?: string) => TransactionMeta | undefined;
43
+ export declare const updateTransaction: (messenger: BridgeStatusControllerMessenger, txMeta: TransactionMeta, txMetaUpdates: Partial<TransactionMeta>, note: string) => void;
44
+ export declare const checkIsDelegatedAccount: (messenger: BridgeStatusControllerMessenger, fromAddress: Hex, chainIds: Hex[]) => Promise<boolean>;
45
+ export declare const addTransaction: (messenger: BridgeStatusControllerMessenger, txParams: TransactionParams, options: import("@metamask/transaction-controller").AddTransactionOptions) => Promise<TransactionMeta>;
5
46
  export declare const generateActionId: () => string;
6
- export declare const getStatusRequestParams: (quoteResponse: QuoteResponse) => {
7
- bridgeId: string;
8
- bridge: string;
9
- srcChainId: number;
10
- destChainId: number;
11
- quote: {
12
- srcChainId: number;
13
- destChainId: number;
14
- srcAsset: {
15
- symbol: string;
16
- chainId: number;
17
- address: string;
18
- assetId: `${string}:${string}/${string}:${string}`;
19
- name: string;
20
- decimals: number;
21
- icon?: string | null | undefined;
22
- iconUrl?: string | null | undefined;
23
- };
24
- destAsset: {
25
- symbol: string;
26
- chainId: number;
27
- address: string;
28
- assetId: `${string}:${string}/${string}:${string}`;
29
- name: string;
30
- decimals: number;
31
- icon?: string | null | undefined;
32
- iconUrl?: string | null | undefined;
33
- };
34
- requestId: string;
35
- srcTokenAmount: string;
36
- destTokenAmount: string;
37
- minDestTokenAmount: string;
38
- feeData: {
39
- metabridge: {
40
- amount: string;
41
- asset: {
42
- symbol: string;
43
- chainId: number;
44
- address: string;
45
- assetId: `${string}:${string}/${string}:${string}`;
46
- name: string;
47
- decimals: number;
48
- icon?: string | null | undefined;
49
- iconUrl?: string | null | undefined;
50
- };
51
- };
52
- txFee?: ({
53
- amount: string;
54
- asset: {
55
- symbol: string;
56
- chainId: number;
57
- address: string;
58
- assetId: `${string}:${string}/${string}:${string}`;
59
- name: string;
60
- decimals: number;
61
- icon?: string | null | undefined;
62
- iconUrl?: string | null | undefined;
63
- };
64
- } & {
65
- maxFeePerGas: string;
66
- maxPriorityFeePerGas: string;
67
- }) | undefined;
68
- };
69
- bridgeId: string;
70
- bridges: string[];
71
- steps: {
72
- action: import("@metamask/bridge-controller").ActionTypes;
73
- srcChainId: number;
74
- srcAsset: {
75
- symbol: string;
76
- chainId: number;
77
- address: string;
78
- assetId: `${string}:${string}/${string}:${string}`;
79
- name: string;
80
- decimals: number;
81
- icon?: string | null | undefined;
82
- iconUrl?: string | null | undefined;
83
- };
84
- destAsset: {
85
- symbol: string;
86
- chainId: number;
87
- address: string;
88
- assetId: `${string}:${string}/${string}:${string}`;
89
- name: string;
90
- decimals: number;
91
- icon?: string | null | undefined;
92
- iconUrl?: string | null | undefined;
93
- };
94
- srcAmount: string;
95
- destAmount: string;
96
- protocol: {
97
- name: string;
98
- icon?: string | undefined;
99
- displayName?: string | undefined;
100
- };
101
- destChainId?: number | undefined;
102
- }[];
103
- refuel?: {
104
- action: import("@metamask/bridge-controller").ActionTypes;
105
- srcChainId: number;
106
- srcAsset: {
107
- symbol: string;
108
- chainId: number;
109
- address: string;
110
- assetId: `${string}:${string}/${string}:${string}`;
111
- name: string;
112
- decimals: number;
113
- icon?: string | null | undefined;
114
- iconUrl?: string | null | undefined;
115
- };
116
- destAsset: {
117
- symbol: string;
118
- chainId: number;
119
- address: string;
120
- assetId: `${string}:${string}/${string}:${string}`;
121
- name: string;
122
- decimals: number;
123
- icon?: string | null | undefined;
124
- iconUrl?: string | null | undefined;
125
- };
126
- srcAmount: string;
127
- destAmount: string;
128
- protocol: {
129
- name: string;
130
- icon?: string | undefined;
131
- displayName?: string | undefined;
132
- };
133
- destChainId?: number | undefined;
134
- } | undefined;
135
- gasIncluded?: boolean | undefined;
136
- gasIncluded7702?: boolean | undefined;
137
- priceData?: {
138
- totalFromAmountUsd?: string | undefined;
139
- totalToAmountUsd?: string | undefined;
140
- priceImpact?: string | undefined;
141
- totalFeeAmountUsd?: string | undefined;
142
- } | undefined;
143
- intent?: {
144
- protocol: string;
145
- order: {
146
- sellToken: string;
147
- buyToken: string;
148
- validTo: string | number;
149
- appData: string;
150
- appDataHash: string;
151
- feeAmount: string;
152
- kind: "sell" | "buy";
153
- partiallyFillable: boolean;
154
- receiver?: string | undefined;
155
- sellAmount?: string | undefined;
156
- buyAmount?: string | undefined;
157
- from?: string | undefined;
158
- };
159
- typedData: {
160
- types: Record<string, {
161
- name: string;
162
- type: string;
163
- }[]>;
164
- primaryType: string;
165
- domain: Record<string, any>;
166
- message: Record<string, any>;
167
- };
168
- settlementContract?: string | undefined;
169
- } | undefined;
170
- gasSponsored?: boolean | undefined;
171
- };
172
- refuel: boolean;
173
- };
47
+ /**
48
+ * Adds a synthetic transaction to the TransactionController to display pending intent orders in the UI
49
+ *
50
+ * @param messenger - The messenger to use for the transaction
51
+ * @param args - The arguments for the transaction
52
+ * @returns The transaction meta
53
+ */
54
+ export declare const addSyntheticTransaction: (messenger: BridgeStatusControllerMessenger, txParams: TransactionParams, options: import("@metamask/transaction-controller").AddTransactionOptions) => Promise<TransactionMeta>;
174
55
  export declare const handleApprovalDelay: (srcChainId: QuoteResponse['quote']['srcChainId']) => Promise<void>;
175
56
  /**
176
57
  * Adds a delay for hardware wallet transactions on mobile to fix an issue
@@ -180,6 +61,17 @@ export declare const handleApprovalDelay: (srcChainId: QuoteResponse['quote']['s
180
61
  * @param requireApproval - Whether the delay should be applied
181
62
  */
182
63
  export declare const handleMobileHardwareWalletDelay: (requireApproval: boolean) => Promise<void>;
64
+ /**
65
+ * Waits until a given transaction (by id) reaches confirmed/finalized status or fails/times out.
66
+ *
67
+ * @deprecated use addTransaction util
68
+ * @param messenger - the BridgeStatusControllerMessenger
69
+ * @param txId - the transaction ID
70
+ * @param options - the options for the timeout and poll
71
+ * @param options.timeoutMs - the timeout in milliseconds
72
+ * @param options.pollMs - the poll interval in milliseconds
73
+ * @returns the transaction meta
74
+ */
183
75
  export declare const waitForTxConfirmation: (messenger: BridgeStatusControllerMessenger, txId: string, { timeoutMs, pollMs, }?: {
184
76
  timeoutMs?: number | undefined;
185
77
  pollMs?: number | undefined;
@@ -237,6 +129,7 @@ export declare const findAndUpdateTransactionsInBatch: ({ messenger, batchId, tx
237
129
  perpsDeposit?: string | undefined;
238
130
  perpsDepositAndOrder?: string | undefined;
239
131
  perpsRelayDeposit?: string | undefined;
132
+ perpsWithdraw?: string | undefined;
240
133
  personal_sign?: string | undefined;
241
134
  predictAcrossDeposit?: string | undefined;
242
135
  predictBuy?: string | undefined;
@@ -270,4 +163,33 @@ export declare const findAndUpdateTransactionsInBatch: ({ messenger, batchId, tx
270
163
  approvalMeta?: TransactionMeta | undefined;
271
164
  tradeMeta?: TransactionMeta | undefined;
272
165
  };
166
+ export declare const addTransactionBatch: (messenger: BridgeStatusControllerMessenger, addTransactionBatchFn: TransactionController['addTransactionBatch'], request: import("@metamask/transaction-controller").TransactionBatchRequest) => Promise<{
167
+ approvalMeta: TransactionMeta | undefined;
168
+ tradeMeta: TransactionMeta;
169
+ }>;
170
+ /**
171
+ * Submits an EVM transaction to the TransactionController
172
+ *
173
+ * @param params - The parameters for the transaction
174
+ * @param params.transactionType - The type of transaction to submit
175
+ * @param params.trade - The trade data to confirm
176
+ * @param params.requireApproval - Whether to require approval for the transaction
177
+ * @param params.txFee - Optional gas fee parameters from the quote (used when gasIncluded is true)
178
+ * @param params.txFee.maxFeePerGas - The maximum fee per gas from the quote
179
+ * @param params.txFee.maxPriorityFeePerGas - The maximum priority fee per gas from the quote
180
+ * @param params.actionId - Optional actionId for pre-submission history (if not provided, one is generated)
181
+ * @param params.messenger - The messenger to use for the transaction
182
+ * @returns The transaction meta
183
+ */
184
+ export declare const submitEvmTransaction: ({ messenger, trade, transactionType, requireApproval, txFee, actionId, }: {
185
+ messenger: BridgeStatusControllerMessenger;
186
+ transactionType: TransactionType;
187
+ trade: TxData;
188
+ requireApproval?: boolean | undefined;
189
+ txFee?: {
190
+ maxFeePerGas: string;
191
+ maxPriorityFeePerGas: string;
192
+ } | undefined;
193
+ actionId?: string | undefined;
194
+ }) => Promise<TransactionMeta>;
273
195
  //# sourceMappingURL=transaction.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"transaction.d.mts","sourceRoot":"","sources":["../../src/utils/transaction.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,MAAM,EACP,oCAAoC;AAErC,OAAO,EAEL,eAAe,EAChB,yCAAyC;AAC1C,OAAO,KAAK,EACV,sBAAsB,EAEtB,eAAe,EAChB,yCAAyC;AAQ1C,OAAO,KAAK,EAAE,+BAA+B,EAAE,qBAAiB;AAEhE,eAAO,MAAM,gBAAgB,cAAgD,CAAC;AAE9E,eAAO,MAAM,sBAAsB,kBAAmB,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CASlE,CAAC;AAEF,eAAO,MAAM,mBAAmB,eAClB,aAAa,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,kBAYjD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,oBACzB,OAAO,kBAQzB,CAAC;AAEF,eAAO,MAAM,qBAAqB,qDAE1B,MAAM;;;MAKX,QAAQ,eAAe,CAyBzB,CAAC;AAEF,eAAO,MAAM,eAAe,kBACX,OAAO,mCACW,MAAM;;;;MAMtC,sBAiBF,CAAC;AAEF,eAAO,MAAM,4BAA4B;;gBAoB3B,OAAO;WACZ,MAAM;mBACE,KAAK,aAAa,EAAE,UAAU,GAAG,OAAO,CAAC,GACtD,QAAQ,aAAa,CAAC;;;;;;;;;;;;;;;;;;;;;iFAqFzB,CAAC;AAEF,eAAO,MAAM,gCAAgC;;aAMlC,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2EhB,CAAC"}
1
+ {"version":3,"file":"transaction.d.mts","sourceRoot":"","sources":["../../src/utils/transaction.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,MAAM,EACP,oCAAoC;AAErC,OAAO,EAEL,eAAe,EAChB,yCAAyC;AAC1C,OAAO,KAAK,EACV,sBAAsB,EAEtB,qBAAqB,EACrB,eAAe,EAEf,iBAAiB,EAClB,yCAAyC;AAC1C,OAAO,EAAuB,GAAG,EAAE,wBAAwB;AAC3D,OAAO,EAAE,SAAS,EAAE,qBAAqB;AAKzC,OAAO,KAAK,EAAE,+BAA+B,EAAE,qBAAiB;AAEhE,eAAO,MAAM,kBAAkB,qDAEvB,WAAW,qBAAqB,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,KAC3D,QAAQ;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,oBAAoB,CAAC,EAAE,MAAM,CAAA;CAAE,CAclE,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,qEAEN,WAAW,qBAAqB,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;;;;EA4B7E,CAAC;AAEF,eAAO,MAAM,gBAAgB,kBACZ,OAAO,kFAEc,MAAM,mBACzB,MAAM,WACd,GAAG,UACJ;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,oBAAoB,EAAE,MAAM,CAAA;CAAE;;;;;;kBAAtC,MAAM;0BAAwB,MAAM;;;;;EA8B7D,CAAC;AAEF,eAAO,MAAM,eAAe,mEAE3B,CAAC;AAEF,eAAO,MAAM,sBAAsB,sDAE1B,MAAM,gCAKd,CAAC;AAEF,eAAO,MAAM,wBAAwB,wDAE1B,MAAM,gCAKhB,CAAC;AAEF,eAAO,MAAM,iBAAiB,uDAEpB,eAAe,iBACR,QAAQ,eAAe,CAAC,QACjC,MAAM,SAOb,CAAC;AAEF,eAAO,MAAM,uBAAuB,4DAErB,GAAG,YACN,GAAG,EAAE,KACd,QAAQ,OAAO,CAgBjB,CAAC;AAkBF,eAAO,MAAM,cAAc,kLAS1B,CAAC;AAEF,eAAO,MAAM,gBAAgB,cAAgD,CAAC;AAE9E;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,kLAenC,CAAC;AAEF,eAAO,MAAM,mBAAmB,eAClB,aAAa,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,kBAYjD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,oBACzB,OAAO,kBAQzB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,qDAE1B,MAAM;;;MAKX,QAAQ,eAAe,CAwBzB,CAAC;AAEF,eAAO,MAAM,eAAe,kBACX,OAAO,mCACW,MAAM;;;;MAMtC,sBAiBF,CAAC;AAEF,eAAO,MAAM,4BAA4B;;gBAoB3B,OAAO;WACZ,MAAM;mBACE,KAAK,aAAa,EAAE,UAAU,GAAG,OAAO,CAAC,GACtD,QAAQ,aAAa,CAAC;;;;;;;;;;;;;;;;;;;;;iFA4FzB,CAAC;AAEF,eAAO,MAAM,gCAAgC;;aAMlC,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4EhB,CAAC;AAEF,eAAO,MAAM,mBAAmB,sEAEP,qBAAqB,CAAC,qBAAqB,CAAC;;;EAiCpE,CAAC;AAyCF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB;;qBAUd,eAAe;WACzB,MAAM;;;sBAEW,MAAM;8BAAwB,MAAM;;;MAE1D,QAAQ,eAAe,CAgD1B,CAAC"}
@@ -1,23 +1,130 @@
1
1
  /* eslint-disable @typescript-eslint/explicit-function-return-type */
2
- import { ChainId, formatChainIdToHex } from "@metamask/bridge-controller";
2
+ import { ChainId, formatChainIdToHex, BRIDGE_PREFERRED_GAS_ESTIMATE } from "@metamask/bridge-controller";
3
3
  import { toHex } from "@metamask/controller-utils";
4
4
  import { TransactionStatus, TransactionType } from "@metamask/transaction-controller";
5
5
  import { createProjectLogger } from "@metamask/utils";
6
+ import { BigNumber } from "bignumber.js";
6
7
  import { getAccountByAddress } from "./accounts.mjs";
7
- import { calculateGasFees } from "./gas.mjs";
8
8
  import { getNetworkClientIdByChainId } from "./network.mjs";
9
9
  import { APPROVAL_DELAY_MS } from "../constants.mjs";
10
- export const generateActionId = () => (Date.now() + Math.random()).toString();
11
- export const getStatusRequestParams = (quoteResponse) => {
10
+ export const getGasFeeEstimates = async (messenger, args) => {
11
+ const { estimates } = await messenger.call('TransactionController:estimateGasFee', args);
12
+ if (BRIDGE_PREFERRED_GAS_ESTIMATE in estimates &&
13
+ typeof estimates[BRIDGE_PREFERRED_GAS_ESTIMATE] === 'object' &&
14
+ 'maxFeePerGas' in estimates[BRIDGE_PREFERRED_GAS_ESTIMATE] &&
15
+ 'maxPriorityFeePerGas' in estimates[BRIDGE_PREFERRED_GAS_ESTIMATE]) {
16
+ return estimates[BRIDGE_PREFERRED_GAS_ESTIMATE];
17
+ }
18
+ return {};
19
+ };
20
+ /**
21
+ * Get the gas fee estimates for a transaction
22
+ *
23
+ * @param messenger - The messenger for the gas fee estimates
24
+ * @param estimateGasFeeParams - The parameters for the {@link TransactionController.estimateGasFee} method
25
+
26
+ * @returns The gas fee estimates for the transaction
27
+ */
28
+ export const getTxGasEstimates = async (messenger, estimateGasFeeParams) => {
29
+ const { gasFeeEstimates } = messenger.call('GasFeeController:getState');
30
+ const estimatedBaseFee = 'estimatedBaseFee' in gasFeeEstimates
31
+ ? gasFeeEstimates.estimatedBaseFee
32
+ : '0';
33
+ // Get transaction's 1559 gas fee estimates
34
+ const { maxFeePerGas, maxPriorityFeePerGas } = await getGasFeeEstimates(messenger, estimateGasFeeParams);
35
+ /**
36
+ * @deprecated this is unused
37
+ */
38
+ const baseAndPriorityFeePerGas = maxPriorityFeePerGas
39
+ ? new BigNumber(estimatedBaseFee, 10)
40
+ .times(10 ** 9)
41
+ .plus(maxPriorityFeePerGas, 16)
42
+ : undefined;
43
+ return {
44
+ baseAndPriorityFeePerGas,
45
+ maxFeePerGas,
46
+ maxPriorityFeePerGas,
47
+ };
48
+ };
49
+ export const calculateGasFees = async (skipGasFields, messenger, { chainId: _, gasLimit, ...trade }, networkClientId, chainId, txFee) => {
50
+ if (skipGasFields) {
51
+ return {};
52
+ }
53
+ if (txFee) {
54
+ return { ...txFee, gas: gasLimit?.toString() };
55
+ }
56
+ const transactionParams = {
57
+ ...trade,
58
+ gas: gasLimit?.toString(),
59
+ data: trade.data,
60
+ to: trade.to,
61
+ value: trade.value,
62
+ };
63
+ const { maxFeePerGas, maxPriorityFeePerGas } = await getTxGasEstimates(messenger, {
64
+ transactionParams,
65
+ networkClientId,
66
+ chainId,
67
+ });
68
+ const maxGasLimit = toHex(transactionParams.gas ?? 0);
12
69
  return {
13
- bridgeId: quoteResponse.quote.bridgeId,
14
- bridge: quoteResponse.quote.bridges[0],
15
- srcChainId: quoteResponse.quote.srcChainId,
16
- destChainId: quoteResponse.quote.destChainId,
17
- quote: quoteResponse.quote,
18
- refuel: Boolean(quoteResponse.quote.refuel),
70
+ maxFeePerGas,
71
+ maxPriorityFeePerGas,
72
+ gas: maxGasLimit,
19
73
  };
20
74
  };
75
+ export const getTransactions = (messenger) => {
76
+ return messenger.call('TransactionController:getState').transactions ?? [];
77
+ };
78
+ export const getTransactionMetaById = (messenger, txId) => {
79
+ return getTransactions(messenger).find((tx) => tx.id === txId);
80
+ };
81
+ export const getTransactionMetaByHash = (messenger, txHash) => {
82
+ return getTransactions(messenger).find((tx) => tx.hash === txHash);
83
+ };
84
+ export const updateTransaction = (messenger, txMeta, txMetaUpdates, note) => {
85
+ return messenger.call('TransactionController:updateTransaction', { ...txMeta, ...txMetaUpdates }, note);
86
+ };
87
+ export const checkIsDelegatedAccount = async (messenger, fromAddress, chainIds) => {
88
+ try {
89
+ const atomicBatchSupport = await messenger.call('TransactionController:isAtomicBatchSupported', {
90
+ address: fromAddress,
91
+ chainIds,
92
+ });
93
+ return atomicBatchSupport.some((entry) => entry.isSupported && entry.delegationAddress);
94
+ }
95
+ catch {
96
+ return false;
97
+ }
98
+ };
99
+ const waitForHashAndReturnFinalTxMeta = async (messenger, hashPromise) => {
100
+ const txHash = await hashPromise;
101
+ const finalTransactionMeta = getTransactionMetaByHash(messenger, txHash);
102
+ if (!finalTransactionMeta) {
103
+ throw new Error('Failed to submit cross-chain swap tx: txMeta for txHash was not found');
104
+ }
105
+ return finalTransactionMeta;
106
+ };
107
+ export const addTransaction = async (messenger, ...args) => {
108
+ const { result } = await messenger.call('TransactionController:addTransaction', ...args);
109
+ return await waitForHashAndReturnFinalTxMeta(messenger, result);
110
+ };
111
+ export const generateActionId = () => (Date.now() + Math.random()).toString();
112
+ /**
113
+ * Adds a synthetic transaction to the TransactionController to display pending intent orders in the UI
114
+ *
115
+ * @param messenger - The messenger to use for the transaction
116
+ * @param args - The arguments for the transaction
117
+ * @returns The transaction meta
118
+ */
119
+ export const addSyntheticTransaction = async (messenger, ...args) => {
120
+ const { transactionMeta } = await messenger.call('TransactionController:addTransaction', args[0], {
121
+ origin: 'metamask',
122
+ actionId: generateActionId(),
123
+ isStateOnly: true,
124
+ ...args[1],
125
+ });
126
+ return transactionMeta;
127
+ };
21
128
  export const handleApprovalDelay = async (srcChainId) => {
22
129
  if ([ChainId.LINEA, ChainId.BASE].includes(srcChainId)) {
23
130
  const debugLog = createProjectLogger('bridge');
@@ -39,11 +146,21 @@ export const handleMobileHardwareWalletDelay = async (requireApproval) => {
39
146
  await mobileHardwareWalletDelay;
40
147
  }
41
148
  };
149
+ /**
150
+ * Waits until a given transaction (by id) reaches confirmed/finalized status or fails/times out.
151
+ *
152
+ * @deprecated use addTransaction util
153
+ * @param messenger - the BridgeStatusControllerMessenger
154
+ * @param txId - the transaction ID
155
+ * @param options - the options for the timeout and poll
156
+ * @param options.timeoutMs - the timeout in milliseconds
157
+ * @param options.pollMs - the poll interval in milliseconds
158
+ * @returns the transaction meta
159
+ */
42
160
  export const waitForTxConfirmation = async (messenger, txId, { timeoutMs = 5 * 60000, pollMs = 3000, } = {}) => {
43
161
  const start = Date.now();
44
162
  while (true) {
45
- const { transactions } = messenger.call('TransactionController:getState');
46
- const meta = transactions.find((tx) => tx.id === txId);
163
+ const meta = getTransactionMetaById(messenger, txId);
47
164
  if (meta) {
48
165
  if (meta.status === TransactionStatus.confirmed) {
49
166
  return meta;
@@ -78,6 +195,7 @@ export const toBatchTxParams = (skipGasFields, { chainId, gasLimit, ...trade },
78
195
  };
79
196
  };
80
197
  export const getAddTransactionBatchParams = async ({ messenger, isBridgeTx, approval, resetApproval, trade, quoteResponse: { quote: { feeData: { txFee }, gasIncluded, gasIncluded7702, gasSponsored, }, sentAmount, toTokenAmount, }, requireApproval = false, isDelegatedAccount = false, }) => {
198
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
81
199
  const isGasless = gasIncluded || gasIncluded7702;
82
200
  const selectedAccount = getAccountByAddress(messenger, trade.from);
83
201
  if (!selectedAccount) {
@@ -90,7 +208,11 @@ export const getAddTransactionBatchParams = async ({ messenger, isBridgeTx, appr
90
208
  // Enable 7702 batching when the quote includes gasless 7702 support,
91
209
  // or when the account is already delegated (to avoid the in-flight
92
210
  // transaction limit for delegated accounts)
93
- const disable7702 = !skipGasFields && !isDelegatedAccount;
211
+ let disable7702 = !skipGasFields && !isDelegatedAccount;
212
+ // For gasless transactions with STX/sendBundle we keep disabling 7702.
213
+ if (gasIncluded && !gasIncluded7702) {
214
+ disable7702 = true;
215
+ }
94
216
  const transactions = [];
95
217
  if (resetApproval) {
96
218
  const gasFees = await calculateGasFees(skipGasFields, messenger, resetApproval, networkClientId, hexChainId, isGasless ? txFee : undefined);
@@ -132,14 +254,15 @@ export const getAddTransactionBatchParams = async ({ messenger, isBridgeTx, appr
132
254
  return transactionParams;
133
255
  };
134
256
  export const findAndUpdateTransactionsInBatch = ({ messenger, batchId, txDataByType, }) => {
135
- const txs = messenger.call('TransactionController:getState').transactions;
257
+ const txs = getTransactions(messenger);
136
258
  const txBatch = {
137
259
  approvalMeta: undefined,
138
260
  tradeMeta: undefined,
139
261
  };
140
262
  // This is a workaround to update the tx type after the tx is signed
141
263
  // TODO: remove this once the tx type for batch txs is preserved in the tx controller
142
- Object.entries(txDataByType).forEach(([txType, txData]) => {
264
+ const txEntries = Object.entries(txDataByType);
265
+ txEntries.forEach(([txType, txData]) => {
143
266
  // Skip types not present in the batch (e.g. swap entry is undefined for bridge txs)
144
267
  if (txData === undefined) {
145
268
  return;
@@ -174,12 +297,104 @@ export const findAndUpdateTransactionsInBatch = ({ messenger, batchId, txDataByT
174
297
  });
175
298
  if (txMeta) {
176
299
  const updatedTx = { ...txMeta, type: txType };
177
- messenger.call('TransactionController:updateTransaction', updatedTx, `Update tx type to ${txType}`);
178
- txBatch[[TransactionType.bridgeApproval, TransactionType.swapApproval].includes(txType)
179
- ? 'approvalMeta'
180
- : 'tradeMeta'] = updatedTx;
300
+ updateTransaction(messenger, txMeta, { type: txType }, `Update tx type to ${txType}`);
301
+ const txTypes = [
302
+ TransactionType.bridgeApproval,
303
+ TransactionType.swapApproval,
304
+ ];
305
+ txBatch[txTypes.includes(txType) ? 'approvalMeta' : 'tradeMeta'] =
306
+ updatedTx;
181
307
  }
182
308
  });
183
309
  return txBatch;
184
310
  };
311
+ export const addTransactionBatch = async (messenger, addTransactionBatchFn, ...args) => {
312
+ const txDataByType = {
313
+ [TransactionType.bridgeApproval]: args[0].transactions.find(({ type }) => type === TransactionType.bridgeApproval)?.params.data,
314
+ [TransactionType.swapApproval]: args[0].transactions.find(({ type }) => type === TransactionType.swapApproval)?.params.data,
315
+ [TransactionType.bridge]: args[0].transactions.find(({ type }) => type === TransactionType.bridge)?.params.data,
316
+ [TransactionType.swap]: args[0].transactions.find(({ type }) => type === TransactionType.swap)?.params.data,
317
+ };
318
+ const { batchId } = await addTransactionBatchFn(...args);
319
+ const { approvalMeta, tradeMeta } = findAndUpdateTransactionsInBatch({
320
+ messenger,
321
+ batchId,
322
+ txDataByType,
323
+ });
324
+ if (!tradeMeta) {
325
+ throw new Error('Failed to update cross-chain swap transaction batch: tradeMeta not found');
326
+ }
327
+ return { approvalMeta, tradeMeta };
328
+ };
329
+ // TODO rename
330
+ const getGasFeesForSubmission = async (messenger, transactionParams, networkClientId, chainId, txFee) => {
331
+ const { gas } = transactionParams;
332
+ // If txFee is provided (gasIncluded case), use the quote's gas fees
333
+ // Convert to hex since txFee values from the quote are decimal strings
334
+ if (txFee) {
335
+ return {
336
+ maxFeePerGas: toHex(txFee.maxFeePerGas),
337
+ maxPriorityFeePerGas: toHex(txFee.maxPriorityFeePerGas),
338
+ gas: gas ? toHex(gas) : undefined,
339
+ };
340
+ }
341
+ const { maxFeePerGas, maxPriorityFeePerGas } = await getTxGasEstimates(messenger, {
342
+ transactionParams,
343
+ chainId,
344
+ networkClientId,
345
+ });
346
+ return {
347
+ maxFeePerGas,
348
+ maxPriorityFeePerGas,
349
+ gas: gas ? toHex(gas) : undefined,
350
+ };
351
+ };
352
+ /**
353
+ * Submits an EVM transaction to the TransactionController
354
+ *
355
+ * @param params - The parameters for the transaction
356
+ * @param params.transactionType - The type of transaction to submit
357
+ * @param params.trade - The trade data to confirm
358
+ * @param params.requireApproval - Whether to require approval for the transaction
359
+ * @param params.txFee - Optional gas fee parameters from the quote (used when gasIncluded is true)
360
+ * @param params.txFee.maxFeePerGas - The maximum fee per gas from the quote
361
+ * @param params.txFee.maxPriorityFeePerGas - The maximum priority fee per gas from the quote
362
+ * @param params.actionId - Optional actionId for pre-submission history (if not provided, one is generated)
363
+ * @param params.messenger - The messenger to use for the transaction
364
+ * @returns The transaction meta
365
+ */
366
+ export const submitEvmTransaction = async ({ messenger, trade, transactionType, requireApproval = false, txFee,
367
+ // Use provided actionId (for pre-submission history) or generate one
368
+ actionId = generateActionId(), }) => {
369
+ const selectedAccount = getAccountByAddress(messenger, trade.from);
370
+ if (!selectedAccount) {
371
+ throw new Error('Failed to submit cross-chain swap transaction: unknown account in trade data');
372
+ }
373
+ const hexChainId = formatChainIdToHex(trade.chainId);
374
+ const networkClientId = getNetworkClientIdByChainId(messenger, hexChainId);
375
+ const requestOptions = {
376
+ actionId,
377
+ networkClientId,
378
+ requireApproval,
379
+ type: transactionType,
380
+ origin: 'metamask',
381
+ };
382
+ // Exclude gasLimit from trade to avoid type issues (it can be null)
383
+ const { gasLimit: tradeGasLimit, ...tradeWithoutGasLimit } = trade;
384
+ const transactionParams = {
385
+ ...tradeWithoutGasLimit,
386
+ chainId: hexChainId,
387
+ // Only add gasLimit and gas if they're valid (not undefined/null/zero)
388
+ ...(tradeGasLimit &&
389
+ tradeGasLimit !== 0 && {
390
+ gasLimit: tradeGasLimit.toString(),
391
+ gas: tradeGasLimit.toString(),
392
+ }),
393
+ };
394
+ const transactionParamsWithMaxGas = {
395
+ ...transactionParams,
396
+ ...(await getGasFeesForSubmission(messenger, transactionParams, networkClientId, hexChainId, txFee)),
397
+ };
398
+ return await addTransaction(messenger, transactionParamsWithMaxGas, requestOptions);
399
+ };
185
400
  //# sourceMappingURL=transaction.mjs.map