@metamask/bridge-status-controller 69.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.
- package/CHANGELOG.md +22 -1
- package/dist/bridge-status-controller.cjs +115 -354
- package/dist/bridge-status-controller.cjs.map +1 -1
- package/dist/bridge-status-controller.d.cts +3 -5
- package/dist/bridge-status-controller.d.cts.map +1 -1
- package/dist/bridge-status-controller.d.mts +3 -5
- package/dist/bridge-status-controller.d.mts.map +1 -1
- package/dist/bridge-status-controller.intent.cjs +12 -25
- package/dist/bridge-status-controller.intent.cjs.map +1 -1
- package/dist/bridge-status-controller.intent.d.cts +3 -14
- package/dist/bridge-status-controller.intent.d.cts.map +1 -1
- package/dist/bridge-status-controller.intent.d.mts +3 -14
- package/dist/bridge-status-controller.intent.d.mts.map +1 -1
- package/dist/bridge-status-controller.intent.mjs +12 -25
- package/dist/bridge-status-controller.intent.mjs.map +1 -1
- package/dist/bridge-status-controller.mjs +118 -357
- package/dist/bridge-status-controller.mjs.map +1 -1
- package/dist/index.cjs +1 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +0 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +0 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +0 -1
- package/dist/index.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +11 -5
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +11 -5
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/accounts.cjs +8 -0
- package/dist/utils/accounts.cjs.map +1 -0
- package/dist/utils/accounts.d.cts +36 -0
- package/dist/utils/accounts.d.cts.map +1 -0
- package/dist/utils/accounts.d.mts +36 -0
- package/dist/utils/accounts.d.mts.map +1 -0
- package/dist/utils/accounts.mjs +4 -0
- package/dist/utils/accounts.mjs.map +1 -0
- package/dist/utils/authentication.cjs +15 -0
- package/dist/utils/authentication.cjs.map +1 -0
- package/dist/utils/authentication.d.cts +3 -0
- package/dist/utils/authentication.d.cts.map +1 -0
- package/dist/utils/authentication.d.mts +3 -0
- package/dist/utils/authentication.d.mts.map +1 -0
- package/dist/utils/authentication.mjs +11 -0
- package/dist/utils/authentication.mjs.map +1 -0
- package/dist/utils/bridge-status.cjs +17 -1
- package/dist/utils/bridge-status.cjs.map +1 -1
- package/dist/utils/bridge-status.d.cts +8 -2
- package/dist/utils/bridge-status.d.cts.map +1 -1
- package/dist/utils/bridge-status.d.mts +8 -2
- package/dist/utils/bridge-status.d.mts.map +1 -1
- package/dist/utils/bridge-status.mjs +15 -0
- package/dist/utils/bridge-status.mjs.map +1 -1
- package/dist/utils/bridge.cjs +16 -0
- package/dist/utils/bridge.cjs.map +1 -0
- package/dist/utils/bridge.d.cts +10 -0
- package/dist/utils/bridge.d.cts.map +1 -0
- package/dist/utils/bridge.d.mts +10 -0
- package/dist/utils/bridge.d.mts.map +1 -0
- package/dist/utils/bridge.mjs +11 -0
- package/dist/utils/bridge.mjs.map +1 -0
- package/dist/utils/gas.cjs +1 -61
- package/dist/utils/gas.cjs.map +1 -1
- package/dist/utils/gas.d.cts +3 -26
- package/dist/utils/gas.d.cts.map +1 -1
- package/dist/utils/gas.d.mts +3 -26
- package/dist/utils/gas.d.mts.map +1 -1
- package/dist/utils/gas.mjs +0 -58
- package/dist/utils/gas.mjs.map +1 -1
- package/dist/utils/history.cjs +98 -0
- package/dist/utils/history.cjs.map +1 -0
- package/dist/utils/history.d.cts +22 -0
- package/dist/utils/history.d.cts.map +1 -0
- package/dist/utils/history.d.mts +22 -0
- package/dist/utils/history.d.mts.map +1 -0
- package/dist/utils/history.mjs +91 -0
- package/dist/utils/history.mjs.map +1 -0
- package/dist/utils/intent-api.cjs +41 -26
- package/dist/utils/intent-api.cjs.map +1 -1
- package/dist/utils/intent-api.d.cts +16 -3
- package/dist/utils/intent-api.d.cts.map +1 -1
- package/dist/utils/intent-api.d.mts +16 -3
- package/dist/utils/intent-api.d.mts.map +1 -1
- package/dist/utils/intent-api.mjs +38 -25
- package/dist/utils/intent-api.mjs.map +1 -1
- package/dist/utils/keyring.cjs +12 -0
- package/dist/utils/keyring.cjs.map +1 -0
- package/dist/utils/keyring.d.cts +8 -0
- package/dist/utils/keyring.d.cts.map +1 -0
- package/dist/utils/keyring.d.mts +8 -0
- package/dist/utils/keyring.d.mts.map +1 -0
- package/dist/utils/keyring.mjs +8 -0
- package/dist/utils/keyring.mjs.map +1 -0
- package/dist/utils/network.cjs +17 -0
- package/dist/utils/network.cjs.map +1 -0
- package/dist/utils/network.d.cts +5 -0
- package/dist/utils/network.d.cts.map +1 -0
- package/dist/utils/network.d.mts +5 -0
- package/dist/utils/network.d.mts.map +1 -0
- package/dist/utils/network.mjs +12 -0
- package/dist/utils/network.mjs.map +1 -0
- package/dist/utils/snaps.cjs +146 -1
- package/dist/utils/snaps.cjs.map +1 -1
- package/dist/utils/snaps.d.cts +48 -0
- package/dist/utils/snaps.d.cts.map +1 -1
- package/dist/utils/snaps.d.mts +48 -0
- package/dist/utils/snaps.d.mts.map +1 -1
- package/dist/utils/snaps.mjs +141 -0
- package/dist/utils/snaps.mjs.map +1 -1
- package/dist/utils/trace.cjs +31 -0
- package/dist/utils/trace.cjs.map +1 -0
- package/dist/utils/trace.d.cts +17 -0
- package/dist/utils/trace.d.cts.map +1 -0
- package/dist/utils/trace.d.mts +17 -0
- package/dist/utils/trace.d.mts.map +1 -0
- package/dist/utils/trace.mjs +26 -0
- package/dist/utils/trace.mjs.map +1 -0
- package/dist/utils/transaction.cjs +239 -184
- package/dist/utils/transaction.cjs.map +1 -1
- package/dist/utils/transaction.d.cts +85 -236
- package/dist/utils/transaction.d.cts.map +1 -1
- package/dist/utils/transaction.d.mts +85 -236
- package/dist/utils/transaction.d.mts.map +1 -1
- package/dist/utils/transaction.mjs +226 -176
- package/dist/utils/transaction.mjs.map +1 -1
- package/dist/utils/validators.d.cts +2 -2
- package/dist/utils/validators.d.mts +2 -2
- package/package.json +3 -3
|
@@ -1,123 +1,144 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.submitEvmTransaction = exports.addTransactionBatch = exports.findAndUpdateTransactionsInBatch = exports.getAddTransactionBatchParams = exports.toBatchTxParams = exports.waitForTxConfirmation = exports.handleMobileHardwareWalletDelay = exports.handleApprovalDelay = exports.addSyntheticTransaction = exports.generateActionId = exports.addTransaction = exports.checkIsDelegatedAccount = exports.updateTransaction = exports.getTransactionMetaByHash = exports.getTransactionMetaById = exports.getTransactions = exports.calculateGasFees = exports.getTxGasEstimates = exports.getGasFeeEstimates = void 0;
|
|
4
|
+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
4
5
|
const bridge_controller_1 = require("@metamask/bridge-controller");
|
|
5
6
|
const controller_utils_1 = require("@metamask/controller-utils");
|
|
6
7
|
const transaction_controller_1 = require("@metamask/transaction-controller");
|
|
7
8
|
const utils_1 = require("@metamask/utils");
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
9
|
+
const bignumber_js_1 = require("bignumber.js");
|
|
10
|
+
const accounts_1 = require("./accounts.cjs");
|
|
11
|
+
const network_1 = require("./network.cjs");
|
|
11
12
|
const constants_1 = require("../constants.cjs");
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const getGasFeeEstimates = async (messenger, args) => {
|
|
14
|
+
const { estimates } = await messenger.call('TransactionController:estimateGasFee', args);
|
|
15
|
+
if (bridge_controller_1.BRIDGE_PREFERRED_GAS_ESTIMATE in estimates &&
|
|
16
|
+
typeof estimates[bridge_controller_1.BRIDGE_PREFERRED_GAS_ESTIMATE] === 'object' &&
|
|
17
|
+
'maxFeePerGas' in estimates[bridge_controller_1.BRIDGE_PREFERRED_GAS_ESTIMATE] &&
|
|
18
|
+
'maxPriorityFeePerGas' in estimates[bridge_controller_1.BRIDGE_PREFERRED_GAS_ESTIMATE]) {
|
|
19
|
+
return estimates[bridge_controller_1.BRIDGE_PREFERRED_GAS_ESTIMATE];
|
|
20
|
+
}
|
|
21
|
+
return {};
|
|
22
|
+
};
|
|
23
|
+
exports.getGasFeeEstimates = getGasFeeEstimates;
|
|
24
|
+
/**
|
|
25
|
+
* Get the gas fee estimates for a transaction
|
|
26
|
+
*
|
|
27
|
+
* @param messenger - The messenger for the gas fee estimates
|
|
28
|
+
* @param estimateGasFeeParams - The parameters for the {@link TransactionController.estimateGasFee} method
|
|
29
|
+
|
|
30
|
+
* @returns The gas fee estimates for the transaction
|
|
31
|
+
*/
|
|
32
|
+
const getTxGasEstimates = async (messenger, estimateGasFeeParams) => {
|
|
33
|
+
const { gasFeeEstimates } = messenger.call('GasFeeController:getState');
|
|
34
|
+
const estimatedBaseFee = 'estimatedBaseFee' in gasFeeEstimates
|
|
35
|
+
? gasFeeEstimates.estimatedBaseFee
|
|
36
|
+
: '0';
|
|
37
|
+
// Get transaction's 1559 gas fee estimates
|
|
38
|
+
const { maxFeePerGas, maxPriorityFeePerGas } = await (0, exports.getGasFeeEstimates)(messenger, estimateGasFeeParams);
|
|
39
|
+
/**
|
|
40
|
+
* @deprecated this is unused
|
|
41
|
+
*/
|
|
42
|
+
const baseAndPriorityFeePerGas = maxPriorityFeePerGas
|
|
43
|
+
? new bignumber_js_1.BigNumber(estimatedBaseFee, 10)
|
|
44
|
+
.times(10 ** 9)
|
|
45
|
+
.plus(maxPriorityFeePerGas, 16)
|
|
46
|
+
: undefined;
|
|
15
47
|
return {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
destChainId: quoteResponse.quote.destChainId,
|
|
20
|
-
quote: quoteResponse.quote,
|
|
21
|
-
refuel: Boolean(quoteResponse.quote.refuel),
|
|
48
|
+
baseAndPriorityFeePerGas,
|
|
49
|
+
maxFeePerGas,
|
|
50
|
+
maxPriorityFeePerGas,
|
|
22
51
|
};
|
|
23
52
|
};
|
|
24
|
-
exports.
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
try {
|
|
29
|
-
destinationChainId = (0, bridge_controller_1.formatChainIdToHex)(quoteResponse.quote.destChainId);
|
|
53
|
+
exports.getTxGasEstimates = getTxGasEstimates;
|
|
54
|
+
const calculateGasFees = async (skipGasFields, messenger, { chainId: _, gasLimit, ...trade }, networkClientId, chainId, txFee) => {
|
|
55
|
+
if (skipGasFields) {
|
|
56
|
+
return {};
|
|
30
57
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
destinationChainId = '0x1'; // Default to mainnet
|
|
58
|
+
if (txFee) {
|
|
59
|
+
return { ...txFee, gas: gasLimit?.toString() };
|
|
34
60
|
}
|
|
61
|
+
const transactionParams = {
|
|
62
|
+
...trade,
|
|
63
|
+
gas: gasLimit?.toString(),
|
|
64
|
+
data: trade.data,
|
|
65
|
+
to: trade.to,
|
|
66
|
+
value: trade.value,
|
|
67
|
+
};
|
|
68
|
+
const { maxFeePerGas, maxPriorityFeePerGas } = await (0, exports.getTxGasEstimates)(messenger, {
|
|
69
|
+
transactionParams,
|
|
70
|
+
networkClientId,
|
|
71
|
+
chainId,
|
|
72
|
+
});
|
|
73
|
+
const maxGasLimit = (0, controller_utils_1.toHex)(transactionParams.gas ?? 0);
|
|
35
74
|
return {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
sourceTokenDecimals: quoteResponse.quote.srcAsset.decimals,
|
|
40
|
-
sourceTokenAddress: quoteResponse.quote.srcAsset.address,
|
|
41
|
-
destinationTokenAmount: quoteResponse.quote.destTokenAmount,
|
|
42
|
-
destinationTokenSymbol: quoteResponse.quote.destAsset.symbol,
|
|
43
|
-
destinationTokenDecimals: quoteResponse.quote.destAsset.decimals,
|
|
44
|
-
destinationTokenAddress: quoteResponse.quote.destAsset.address,
|
|
45
|
-
// chainId is now excluded from this function and handled by the caller
|
|
46
|
-
approvalTxId,
|
|
47
|
-
// this is the decimal (non atomic) amount (not USD value) of source token to swap
|
|
48
|
-
swapTokenValue: quoteResponse.sentAmount.amount,
|
|
75
|
+
maxFeePerGas,
|
|
76
|
+
maxPriorityFeePerGas,
|
|
77
|
+
gas: maxGasLimit,
|
|
49
78
|
};
|
|
50
79
|
};
|
|
51
|
-
exports.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
else if (snapResponse && typeof snapResponse === 'object') {
|
|
71
|
-
// Check for new unified interface response format first
|
|
72
|
-
if ('transactionId' in snapResponse && snapResponse.transactionId) {
|
|
73
|
-
hash = snapResponse.transactionId;
|
|
74
|
-
}
|
|
75
|
-
else if ('result' in snapResponse &&
|
|
76
|
-
snapResponse.result &&
|
|
77
|
-
typeof snapResponse.result === 'object') {
|
|
78
|
-
// Try to extract signature from common locations in response object
|
|
79
|
-
hash =
|
|
80
|
-
snapResponse.result.signature ||
|
|
81
|
-
snapResponse.result.txid ||
|
|
82
|
-
snapResponse.result.hash ||
|
|
83
|
-
snapResponse.result.txHash;
|
|
84
|
-
}
|
|
85
|
-
else if ('signature' in snapResponse &&
|
|
86
|
-
snapResponse.signature &&
|
|
87
|
-
typeof snapResponse.signature === 'string') {
|
|
88
|
-
hash = snapResponse.signature;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
const isBridgeTx = (0, bridge_controller_1.isCrossChain)(quoteResponse.quote.srcChainId, quoteResponse.quote.destChainId);
|
|
92
|
-
let hexChainId;
|
|
80
|
+
exports.calculateGasFees = calculateGasFees;
|
|
81
|
+
const getTransactions = (messenger) => {
|
|
82
|
+
return messenger.call('TransactionController:getState').transactions ?? [];
|
|
83
|
+
};
|
|
84
|
+
exports.getTransactions = getTransactions;
|
|
85
|
+
const getTransactionMetaById = (messenger, txId) => {
|
|
86
|
+
return (0, exports.getTransactions)(messenger).find((tx) => tx.id === txId);
|
|
87
|
+
};
|
|
88
|
+
exports.getTransactionMetaById = getTransactionMetaById;
|
|
89
|
+
const getTransactionMetaByHash = (messenger, txHash) => {
|
|
90
|
+
return (0, exports.getTransactions)(messenger).find((tx) => tx.hash === txHash);
|
|
91
|
+
};
|
|
92
|
+
exports.getTransactionMetaByHash = getTransactionMetaByHash;
|
|
93
|
+
const updateTransaction = (messenger, txMeta, txMetaUpdates, note) => {
|
|
94
|
+
return messenger.call('TransactionController:updateTransaction', { ...txMeta, ...txMetaUpdates }, note);
|
|
95
|
+
};
|
|
96
|
+
exports.updateTransaction = updateTransaction;
|
|
97
|
+
const checkIsDelegatedAccount = async (messenger, fromAddress, chainIds) => {
|
|
93
98
|
try {
|
|
94
|
-
|
|
99
|
+
const atomicBatchSupport = await messenger.call('TransactionController:isAtomicBatchSupported', {
|
|
100
|
+
address: fromAddress,
|
|
101
|
+
chainIds,
|
|
102
|
+
});
|
|
103
|
+
return atomicBatchSupport.some((entry) => entry.isSupported && entry.delegationAddress);
|
|
95
104
|
}
|
|
96
105
|
catch {
|
|
97
|
-
|
|
98
|
-
// Fallback to Ethereum mainnet for now
|
|
99
|
-
hexChainId = '0x1';
|
|
106
|
+
return false;
|
|
100
107
|
}
|
|
101
|
-
// Extract the transaction data for storage
|
|
102
|
-
const tradeData = (0, bridge_controller_1.extractTradeData)(quoteResponse.trade);
|
|
103
|
-
// Create a transaction meta object with bridge-specific fields
|
|
104
|
-
return {
|
|
105
|
-
...(0, exports.getTxMetaFields)(quoteResponse),
|
|
106
|
-
time: Date.now(),
|
|
107
|
-
id: hash ?? (0, uuid_1.v4)(),
|
|
108
|
-
chainId: hexChainId,
|
|
109
|
-
networkClientId: snapId ?? hexChainId,
|
|
110
|
-
txParams: { from: selectedAccountAddress, data: tradeData },
|
|
111
|
-
type: isBridgeTx ? transaction_controller_1.TransactionType.bridge : transaction_controller_1.TransactionType.swap,
|
|
112
|
-
status: transaction_controller_1.TransactionStatus.submitted,
|
|
113
|
-
hash, // Add the transaction signature as hash
|
|
114
|
-
origin: snapId,
|
|
115
|
-
// Add an explicit flag to mark this as a non-EVM transaction
|
|
116
|
-
isSolana: true, // TODO deprecate this and use chainId to detect non-EVM chains
|
|
117
|
-
isBridgeTx,
|
|
118
|
-
};
|
|
119
108
|
};
|
|
120
|
-
exports.
|
|
109
|
+
exports.checkIsDelegatedAccount = checkIsDelegatedAccount;
|
|
110
|
+
const waitForHashAndReturnFinalTxMeta = async (messenger, hashPromise) => {
|
|
111
|
+
const txHash = await hashPromise;
|
|
112
|
+
const finalTransactionMeta = (0, exports.getTransactionMetaByHash)(messenger, txHash);
|
|
113
|
+
if (!finalTransactionMeta) {
|
|
114
|
+
throw new Error('Failed to submit cross-chain swap tx: txMeta for txHash was not found');
|
|
115
|
+
}
|
|
116
|
+
return finalTransactionMeta;
|
|
117
|
+
};
|
|
118
|
+
const addTransaction = async (messenger, ...args) => {
|
|
119
|
+
const { result } = await messenger.call('TransactionController:addTransaction', ...args);
|
|
120
|
+
return await waitForHashAndReturnFinalTxMeta(messenger, result);
|
|
121
|
+
};
|
|
122
|
+
exports.addTransaction = addTransaction;
|
|
123
|
+
const generateActionId = () => (Date.now() + Math.random()).toString();
|
|
124
|
+
exports.generateActionId = generateActionId;
|
|
125
|
+
/**
|
|
126
|
+
* Adds a synthetic transaction to the TransactionController to display pending intent orders in the UI
|
|
127
|
+
*
|
|
128
|
+
* @param messenger - The messenger to use for the transaction
|
|
129
|
+
* @param args - The arguments for the transaction
|
|
130
|
+
* @returns The transaction meta
|
|
131
|
+
*/
|
|
132
|
+
const addSyntheticTransaction = async (messenger, ...args) => {
|
|
133
|
+
const { transactionMeta } = await messenger.call('TransactionController:addTransaction', args[0], {
|
|
134
|
+
origin: 'metamask',
|
|
135
|
+
actionId: (0, exports.generateActionId)(),
|
|
136
|
+
isStateOnly: true,
|
|
137
|
+
...args[1],
|
|
138
|
+
});
|
|
139
|
+
return transactionMeta;
|
|
140
|
+
};
|
|
141
|
+
exports.addSyntheticTransaction = addSyntheticTransaction;
|
|
121
142
|
const handleApprovalDelay = async (srcChainId) => {
|
|
122
143
|
if ([bridge_controller_1.ChainId.LINEA, bridge_controller_1.ChainId.BASE].includes(srcChainId)) {
|
|
123
144
|
const debugLog = (0, utils_1.createProjectLogger)('bridge');
|
|
@@ -142,33 +163,20 @@ const handleMobileHardwareWalletDelay = async (requireApproval) => {
|
|
|
142
163
|
};
|
|
143
164
|
exports.handleMobileHardwareWalletDelay = handleMobileHardwareWalletDelay;
|
|
144
165
|
/**
|
|
145
|
-
*
|
|
146
|
-
* Uses the new unified ClientRequest:signAndSendTransaction interface
|
|
166
|
+
* Waits until a given transaction (by id) reaches confirmed/finalized status or fails/times out.
|
|
147
167
|
*
|
|
148
|
-
* @
|
|
149
|
-
* @param
|
|
150
|
-
* @param
|
|
151
|
-
* @
|
|
168
|
+
* @deprecated use addTransaction util
|
|
169
|
+
* @param messenger - the BridgeStatusControllerMessenger
|
|
170
|
+
* @param txId - the transaction ID
|
|
171
|
+
* @param options - the options for the timeout and poll
|
|
172
|
+
* @param options.timeoutMs - the timeout in milliseconds
|
|
173
|
+
* @param options.pollMs - the poll interval in milliseconds
|
|
174
|
+
* @returns the transaction meta
|
|
152
175
|
*/
|
|
153
|
-
const getClientRequest = (trade, srcChainId, selectedAccount) => {
|
|
154
|
-
const scope = (0, bridge_controller_1.formatChainIdToCaip)(srcChainId);
|
|
155
|
-
const transactionData = (0, bridge_controller_1.extractTradeData)(trade);
|
|
156
|
-
// Tron trades need the visible flag and contract type to be included in the request options
|
|
157
|
-
const options = (0, bridge_controller_1.isTronTrade)(trade)
|
|
158
|
-
? {
|
|
159
|
-
visible: trade.visible,
|
|
160
|
-
type: trade.raw_data?.contract?.[0]?.type,
|
|
161
|
-
}
|
|
162
|
-
: undefined;
|
|
163
|
-
// Use the new unified interface
|
|
164
|
-
return (0, snaps_1.createClientTransactionRequest)(selectedAccount.metadata.snap?.id, transactionData, scope, selectedAccount.id, options);
|
|
165
|
-
};
|
|
166
|
-
exports.getClientRequest = getClientRequest;
|
|
167
176
|
const waitForTxConfirmation = async (messenger, txId, { timeoutMs = 5 * 60000, pollMs = 3000, } = {}) => {
|
|
168
177
|
const start = Date.now();
|
|
169
178
|
while (true) {
|
|
170
|
-
const
|
|
171
|
-
const meta = transactions.find((tx) => tx.id === txId);
|
|
179
|
+
const meta = (0, exports.getTransactionMetaById)(messenger, txId);
|
|
172
180
|
if (meta) {
|
|
173
181
|
if (meta.status === transaction_controller_1.TransactionStatus.confirmed) {
|
|
174
182
|
return meta;
|
|
@@ -186,27 +194,6 @@ const waitForTxConfirmation = async (messenger, txId, { timeoutMs = 5 * 60000, p
|
|
|
186
194
|
}
|
|
187
195
|
};
|
|
188
196
|
exports.waitForTxConfirmation = waitForTxConfirmation;
|
|
189
|
-
const rekeyHistoryItemInState = (state, actionId, txMeta) => {
|
|
190
|
-
const historyItem = state.txHistory[actionId];
|
|
191
|
-
if (!historyItem) {
|
|
192
|
-
return false;
|
|
193
|
-
}
|
|
194
|
-
state.txHistory[txMeta.id] = {
|
|
195
|
-
...historyItem,
|
|
196
|
-
txMetaId: txMeta.id,
|
|
197
|
-
originalTransactionId: historyItem.originalTransactionId ?? txMeta.id,
|
|
198
|
-
status: {
|
|
199
|
-
...historyItem.status,
|
|
200
|
-
srcChain: {
|
|
201
|
-
...historyItem.status.srcChain,
|
|
202
|
-
txHash: txMeta.hash ?? historyItem.status.srcChain?.txHash,
|
|
203
|
-
},
|
|
204
|
-
},
|
|
205
|
-
};
|
|
206
|
-
delete state.txHistory[actionId];
|
|
207
|
-
return true;
|
|
208
|
-
};
|
|
209
|
-
exports.rekeyHistoryItemInState = rekeyHistoryItemInState;
|
|
210
197
|
const toBatchTxParams = (skipGasFields, { chainId, gasLimit, ...trade }, { maxFeePerGas, maxPriorityFeePerGas, gas, }) => {
|
|
211
198
|
const params = {
|
|
212
199
|
...trade,
|
|
@@ -225,23 +212,28 @@ const toBatchTxParams = (skipGasFields, { chainId, gasLimit, ...trade }, { maxFe
|
|
|
225
212
|
};
|
|
226
213
|
};
|
|
227
214
|
exports.toBatchTxParams = toBatchTxParams;
|
|
228
|
-
const getAddTransactionBatchParams = async ({ messenger, isBridgeTx, approval, resetApproval, trade, quoteResponse: { quote: { feeData: { txFee }, gasIncluded, gasIncluded7702, gasSponsored, }, sentAmount, toTokenAmount, }, requireApproval = false, isDelegatedAccount = false,
|
|
215
|
+
const getAddTransactionBatchParams = async ({ messenger, isBridgeTx, approval, resetApproval, trade, quoteResponse: { quote: { feeData: { txFee }, gasIncluded, gasIncluded7702, gasSponsored, }, sentAmount, toTokenAmount, }, requireApproval = false, isDelegatedAccount = false, }) => {
|
|
216
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
229
217
|
const isGasless = gasIncluded || gasIncluded7702;
|
|
230
|
-
const selectedAccount =
|
|
218
|
+
const selectedAccount = (0, accounts_1.getAccountByAddress)(messenger, trade.from);
|
|
231
219
|
if (!selectedAccount) {
|
|
232
220
|
throw new Error('Failed to submit cross-chain swap batch transaction: unknown account in trade data');
|
|
233
221
|
}
|
|
234
222
|
const hexChainId = (0, bridge_controller_1.formatChainIdToHex)(trade.chainId);
|
|
235
|
-
const networkClientId =
|
|
223
|
+
const networkClientId = (0, network_1.getNetworkClientIdByChainId)(messenger, hexChainId);
|
|
236
224
|
// Gas fields should be omitted only when gas is sponsored via 7702
|
|
237
225
|
const skipGasFields = gasIncluded7702 === true;
|
|
238
226
|
// Enable 7702 batching when the quote includes gasless 7702 support,
|
|
239
227
|
// or when the account is already delegated (to avoid the in-flight
|
|
240
228
|
// transaction limit for delegated accounts)
|
|
241
|
-
|
|
229
|
+
let disable7702 = !skipGasFields && !isDelegatedAccount;
|
|
230
|
+
// For gasless transactions with STX/sendBundle we keep disabling 7702.
|
|
231
|
+
if (gasIncluded && !gasIncluded7702) {
|
|
232
|
+
disable7702 = true;
|
|
233
|
+
}
|
|
242
234
|
const transactions = [];
|
|
243
235
|
if (resetApproval) {
|
|
244
|
-
const gasFees = await (0,
|
|
236
|
+
const gasFees = await (0, exports.calculateGasFees)(skipGasFields, messenger, resetApproval, networkClientId, hexChainId, isGasless ? txFee : undefined);
|
|
245
237
|
transactions.push({
|
|
246
238
|
type: isBridgeTx
|
|
247
239
|
? transaction_controller_1.TransactionType.bridgeApproval
|
|
@@ -250,7 +242,7 @@ const getAddTransactionBatchParams = async ({ messenger, isBridgeTx, approval, r
|
|
|
250
242
|
});
|
|
251
243
|
}
|
|
252
244
|
if (approval) {
|
|
253
|
-
const gasFees = await (0,
|
|
245
|
+
const gasFees = await (0, exports.calculateGasFees)(skipGasFields, messenger, approval, networkClientId, hexChainId, isGasless ? txFee : undefined);
|
|
254
246
|
transactions.push({
|
|
255
247
|
type: isBridgeTx
|
|
256
248
|
? transaction_controller_1.TransactionType.bridgeApproval
|
|
@@ -258,7 +250,7 @@ const getAddTransactionBatchParams = async ({ messenger, isBridgeTx, approval, r
|
|
|
258
250
|
params: (0, exports.toBatchTxParams)(skipGasFields, approval, gasFees),
|
|
259
251
|
});
|
|
260
252
|
}
|
|
261
|
-
const gasFees = await (0,
|
|
253
|
+
const gasFees = await (0, exports.calculateGasFees)(skipGasFields, messenger, trade, networkClientId, hexChainId, isGasless ? txFee : undefined);
|
|
262
254
|
transactions.push({
|
|
263
255
|
type: isBridgeTx ? transaction_controller_1.TransactionType.bridge : transaction_controller_1.TransactionType.swap,
|
|
264
256
|
params: (0, exports.toBatchTxParams)(skipGasFields, trade, gasFees),
|
|
@@ -280,15 +272,16 @@ const getAddTransactionBatchParams = async ({ messenger, isBridgeTx, approval, r
|
|
|
280
272
|
return transactionParams;
|
|
281
273
|
};
|
|
282
274
|
exports.getAddTransactionBatchParams = getAddTransactionBatchParams;
|
|
283
|
-
const findAndUpdateTransactionsInBatch = ({ messenger,
|
|
284
|
-
const txs =
|
|
275
|
+
const findAndUpdateTransactionsInBatch = ({ messenger, batchId, txDataByType, }) => {
|
|
276
|
+
const txs = (0, exports.getTransactions)(messenger);
|
|
285
277
|
const txBatch = {
|
|
286
278
|
approvalMeta: undefined,
|
|
287
279
|
tradeMeta: undefined,
|
|
288
280
|
};
|
|
289
281
|
// This is a workaround to update the tx type after the tx is signed
|
|
290
282
|
// TODO: remove this once the tx type for batch txs is preserved in the tx controller
|
|
291
|
-
Object.entries(txDataByType)
|
|
283
|
+
const txEntries = Object.entries(txDataByType);
|
|
284
|
+
txEntries.forEach(([txType, txData]) => {
|
|
292
285
|
// Skip types not present in the batch (e.g. swap entry is undefined for bridge txs)
|
|
293
286
|
if (txData === undefined) {
|
|
294
287
|
return;
|
|
@@ -323,45 +316,107 @@ const findAndUpdateTransactionsInBatch = ({ messenger, updateTransactionFn, batc
|
|
|
323
316
|
});
|
|
324
317
|
if (txMeta) {
|
|
325
318
|
const updatedTx = { ...txMeta, type: txType };
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
319
|
+
(0, exports.updateTransaction)(messenger, txMeta, { type: txType }, `Update tx type to ${txType}`);
|
|
320
|
+
const txTypes = [
|
|
321
|
+
transaction_controller_1.TransactionType.bridgeApproval,
|
|
322
|
+
transaction_controller_1.TransactionType.swapApproval,
|
|
323
|
+
];
|
|
324
|
+
txBatch[txTypes.includes(txType) ? 'approvalMeta' : 'tradeMeta'] =
|
|
325
|
+
updatedTx;
|
|
330
326
|
}
|
|
331
327
|
});
|
|
332
328
|
return txBatch;
|
|
333
329
|
};
|
|
334
330
|
exports.findAndUpdateTransactionsInBatch = findAndUpdateTransactionsInBatch;
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
331
|
+
const addTransactionBatch = async (messenger, addTransactionBatchFn, ...args) => {
|
|
332
|
+
const txDataByType = {
|
|
333
|
+
[transaction_controller_1.TransactionType.bridgeApproval]: args[0].transactions.find(({ type }) => type === transaction_controller_1.TransactionType.bridgeApproval)?.params.data,
|
|
334
|
+
[transaction_controller_1.TransactionType.swapApproval]: args[0].transactions.find(({ type }) => type === transaction_controller_1.TransactionType.swapApproval)?.params.data,
|
|
335
|
+
[transaction_controller_1.TransactionType.bridge]: args[0].transactions.find(({ type }) => type === transaction_controller_1.TransactionType.bridge)?.params.data,
|
|
336
|
+
[transaction_controller_1.TransactionType.swap]: args[0].transactions.find(({ type }) => type === transaction_controller_1.TransactionType.swap)?.params.data,
|
|
337
|
+
};
|
|
338
|
+
const { batchId } = await addTransactionBatchFn(...args);
|
|
339
|
+
const { approvalMeta, tradeMeta } = (0, exports.findAndUpdateTransactionsInBatch)({
|
|
340
|
+
messenger,
|
|
341
|
+
batchId,
|
|
342
|
+
txDataByType,
|
|
343
|
+
});
|
|
344
|
+
if (!tradeMeta) {
|
|
345
|
+
throw new Error('Failed to update cross-chain swap transaction batch: tradeMeta not found');
|
|
348
346
|
}
|
|
349
|
-
return
|
|
350
|
-
}
|
|
351
|
-
exports.
|
|
347
|
+
return { approvalMeta, tradeMeta };
|
|
348
|
+
};
|
|
349
|
+
exports.addTransactionBatch = addTransactionBatch;
|
|
350
|
+
// TODO rename
|
|
351
|
+
const getGasFeesForSubmission = async (messenger, transactionParams, networkClientId, chainId, txFee) => {
|
|
352
|
+
const { gas } = transactionParams;
|
|
353
|
+
// If txFee is provided (gasIncluded case), use the quote's gas fees
|
|
354
|
+
// Convert to hex since txFee values from the quote are decimal strings
|
|
355
|
+
if (txFee) {
|
|
356
|
+
return {
|
|
357
|
+
maxFeePerGas: (0, controller_utils_1.toHex)(txFee.maxFeePerGas),
|
|
358
|
+
maxPriorityFeePerGas: (0, controller_utils_1.toHex)(txFee.maxPriorityFeePerGas),
|
|
359
|
+
gas: gas ? (0, controller_utils_1.toHex)(gas) : undefined,
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
const { maxFeePerGas, maxPriorityFeePerGas } = await (0, exports.getTxGasEstimates)(messenger, {
|
|
363
|
+
transactionParams,
|
|
364
|
+
chainId,
|
|
365
|
+
networkClientId,
|
|
366
|
+
});
|
|
367
|
+
return {
|
|
368
|
+
maxFeePerGas,
|
|
369
|
+
maxPriorityFeePerGas,
|
|
370
|
+
gas: gas ? (0, controller_utils_1.toHex)(gas) : undefined,
|
|
371
|
+
};
|
|
372
|
+
};
|
|
352
373
|
/**
|
|
353
|
-
*
|
|
374
|
+
* Submits an EVM transaction to the TransactionController
|
|
354
375
|
*
|
|
355
|
-
* @param
|
|
356
|
-
* @
|
|
357
|
-
* @
|
|
376
|
+
* @param params - The parameters for the transaction
|
|
377
|
+
* @param params.transactionType - The type of transaction to submit
|
|
378
|
+
* @param params.trade - The trade data to confirm
|
|
379
|
+
* @param params.requireApproval - Whether to require approval for the transaction
|
|
380
|
+
* @param params.txFee - Optional gas fee parameters from the quote (used when gasIncluded is true)
|
|
381
|
+
* @param params.txFee.maxFeePerGas - The maximum fee per gas from the quote
|
|
382
|
+
* @param params.txFee.maxPriorityFeePerGas - The maximum priority fee per gas from the quote
|
|
383
|
+
* @param params.actionId - Optional actionId for pre-submission history (if not provided, one is generated)
|
|
384
|
+
* @param params.messenger - The messenger to use for the transaction
|
|
385
|
+
* @returns The transaction meta
|
|
358
386
|
*/
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
387
|
+
const submitEvmTransaction = async ({ messenger, trade, transactionType, requireApproval = false, txFee,
|
|
388
|
+
// Use provided actionId (for pre-submission history) or generate one
|
|
389
|
+
actionId = (0, exports.generateActionId)(), }) => {
|
|
390
|
+
const selectedAccount = (0, accounts_1.getAccountByAddress)(messenger, trade.from);
|
|
391
|
+
if (!selectedAccount) {
|
|
392
|
+
throw new Error('Failed to submit cross-chain swap transaction: unknown account in trade data');
|
|
363
393
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
394
|
+
const hexChainId = (0, bridge_controller_1.formatChainIdToHex)(trade.chainId);
|
|
395
|
+
const networkClientId = (0, network_1.getNetworkClientIdByChainId)(messenger, hexChainId);
|
|
396
|
+
const requestOptions = {
|
|
397
|
+
actionId,
|
|
398
|
+
networkClientId,
|
|
399
|
+
requireApproval,
|
|
400
|
+
type: transactionType,
|
|
401
|
+
origin: 'metamask',
|
|
402
|
+
};
|
|
403
|
+
// Exclude gasLimit from trade to avoid type issues (it can be null)
|
|
404
|
+
const { gasLimit: tradeGasLimit, ...tradeWithoutGasLimit } = trade;
|
|
405
|
+
const transactionParams = {
|
|
406
|
+
...tradeWithoutGasLimit,
|
|
407
|
+
chainId: hexChainId,
|
|
408
|
+
// Only add gasLimit and gas if they're valid (not undefined/null/zero)
|
|
409
|
+
...(tradeGasLimit &&
|
|
410
|
+
tradeGasLimit !== 0 && {
|
|
411
|
+
gasLimit: tradeGasLimit.toString(),
|
|
412
|
+
gas: tradeGasLimit.toString(),
|
|
413
|
+
}),
|
|
414
|
+
};
|
|
415
|
+
const transactionParamsWithMaxGas = {
|
|
416
|
+
...transactionParams,
|
|
417
|
+
...(await getGasFeesForSubmission(messenger, transactionParams, networkClientId, hexChainId, txFee)),
|
|
418
|
+
};
|
|
419
|
+
return await (0, exports.addTransaction)(messenger, transactionParamsWithMaxGas, requestOptions);
|
|
420
|
+
};
|
|
421
|
+
exports.submitEvmTransaction = submitEvmTransaction;
|
|
367
422
|
//# sourceMappingURL=transaction.cjs.map
|