@metamask-previews/bridge-status-controller 76.4.0-preview-686aaf7 → 76.4.0-preview-51ecba2
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 +14 -0
- package/dist/bridge-status-controller.d.ts.map +1 -1
- package/dist/bridge-status-controller.js +78 -40
- package/dist/bridge-status-controller.js.map +1 -1
- package/dist/strategy/batch-sell-strategy.d.ts.map +1 -1
- package/dist/strategy/batch-sell-strategy.js +62 -34
- package/dist/strategy/batch-sell-strategy.js.map +1 -1
- package/dist/strategy/batch-strategy.d.ts.map +1 -1
- package/dist/strategy/batch-strategy.js +38 -13
- package/dist/strategy/batch-strategy.js.map +1 -1
- package/dist/strategy/evm-strategy.d.ts +2 -28
- package/dist/strategy/evm-strategy.d.ts.map +1 -1
- package/dist/strategy/evm-strategy.js +62 -39
- package/dist/strategy/evm-strategy.js.map +1 -1
- package/dist/strategy/intent-strategy.d.ts.map +1 -1
- package/dist/strategy/intent-strategy.js +2 -1
- package/dist/strategy/intent-strategy.js.map +1 -1
- package/dist/strategy/types.d.ts +3 -2
- package/dist/strategy/types.d.ts.map +1 -1
- package/dist/strategy/types.js.map +1 -1
- package/dist/types.d.ts +1 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/history.d.ts +2 -2
- package/dist/utils/history.d.ts.map +1 -1
- package/dist/utils/history.js +64 -25
- package/dist/utils/history.js.map +1 -1
- package/dist/utils/metrics.d.ts +2 -33
- package/dist/utils/metrics.d.ts.map +1 -1
- package/dist/utils/metrics.js.map +1 -1
- package/dist/utils/transaction.d.ts +2 -0
- package/dist/utils/transaction.d.ts.map +1 -1
- package/dist/utils/transaction.js +16 -4
- package/dist/utils/transaction.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TransactionType, } from '@metamask/transaction-controller';
|
|
1
|
+
import { generateBatchId, TransactionType, } from '@metamask/transaction-controller';
|
|
2
2
|
import { findAllTransactionsInBatch, getAddTransactionBatchParams, hasNestedSwapTransactions, is7702Tx, isTradeTx, shouldDisable7702, toQuoteAndTxMetadataBatch, } from '../utils/transaction.js';
|
|
3
3
|
import { SubmitStep } from './types.js';
|
|
4
4
|
const getHistoryKeyForQuote = ({ quoteResponse: { quoteId, quote }, }) => quoteId ?? quote.requestId;
|
|
@@ -16,6 +16,19 @@ export async function* submitBatchSellHandler(args) {
|
|
|
16
16
|
});
|
|
17
17
|
const { gasIncluded7702, gasIncluded, gasSponsored } = batchSellTrades;
|
|
18
18
|
const gasFeeToken = tradeData.find(({ type }) => type === TransactionType.tokenMethodTransfer)?.tx.to;
|
|
19
|
+
const batchId = batchIdParam ?? generateBatchId();
|
|
20
|
+
// Create 1 history item for the parent tx or first quote, keyed by the batchId
|
|
21
|
+
yield {
|
|
22
|
+
type: SubmitStep.AddHistoryItem,
|
|
23
|
+
payload: {
|
|
24
|
+
historyKey: batchId,
|
|
25
|
+
quoteResponse: tradeData[0].quoteResponse,
|
|
26
|
+
batchSellData: batchSellTrades,
|
|
27
|
+
bridgeTxMeta: {
|
|
28
|
+
batchId,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
};
|
|
19
32
|
const transactionParams = await getAddTransactionBatchParams({
|
|
20
33
|
messenger,
|
|
21
34
|
tradeData,
|
|
@@ -26,14 +39,27 @@ export async function* submitBatchSellHandler(args) {
|
|
|
26
39
|
disable7702: shouldDisable7702(gasIncluded7702, gasIncluded, isDelegatedAccount),
|
|
27
40
|
isGasFeeSponsored: gasSponsored,
|
|
28
41
|
isGasFeeIncluded: Boolean(gasIncluded7702),
|
|
29
|
-
batchId
|
|
42
|
+
batchId,
|
|
30
43
|
skipInitialGasEstimate: gasIncluded7702
|
|
31
44
|
? isDelegatedAccount
|
|
32
45
|
: Boolean(gasFeeToken),
|
|
33
46
|
excludeNativeTokenForFee: !gasFeeToken,
|
|
34
47
|
});
|
|
35
48
|
// Submit the batch to the TransactionController
|
|
36
|
-
|
|
49
|
+
try {
|
|
50
|
+
await addTransactionBatchFn(transactionParams);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
const allTradesInBatch = findAllTransactionsInBatch({
|
|
54
|
+
messenger,
|
|
55
|
+
batchId,
|
|
56
|
+
tradeData,
|
|
57
|
+
});
|
|
58
|
+
// Propagate the error if tx has not been added to the TransactionController
|
|
59
|
+
if (!allTradesInBatch.some(({ txMeta }) => txMeta)) {
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
37
63
|
// Find all batch transaction metas and add them to history
|
|
38
64
|
const allTradesInBatch = findAllTransactionsInBatch({
|
|
39
65
|
messenger,
|
|
@@ -61,46 +87,48 @@ export async function* submitBatchSellHandler(args) {
|
|
|
61
87
|
// `is7702Tx` only means the account is delegated (true even for many-tx
|
|
62
88
|
// batches), so count the unique txs instead.
|
|
63
89
|
const isSingleBatchTx = new Set(allTradesInBatch.map(({ txMeta }) => txMeta.id)).size === 1;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
};
|
|
79
|
-
// Then create a new history item for each nested trade, keyed by quoteId/requestId
|
|
80
|
-
for (const tradeWithMetadata of allTradesInBatch) {
|
|
81
|
-
const { quoteResponse } = tradeWithMetadata;
|
|
90
|
+
const isNested7702BatchTx = isSingleBatchTx &&
|
|
91
|
+
(is7702Tx(firstTradeMeta) || hasNestedSwapTransactions(firstTradeMeta));
|
|
92
|
+
// Each trade has its own txMeta if not submitted via 7702
|
|
93
|
+
// Create a new history item for each one, keyed by txMeta.id
|
|
94
|
+
// Note that the approvalTxId is not tracked in history
|
|
95
|
+
for (const [index, tradeWithMetadata] of allTradesInBatch.entries()) {
|
|
96
|
+
// Rekey the initial trade
|
|
97
|
+
if (index === 0) {
|
|
98
|
+
const quoteIds = isNested7702BatchTx
|
|
99
|
+
? Array.from(new Set(allTradesInBatch.map(getHistoryKeyForQuote)))
|
|
100
|
+
: undefined;
|
|
101
|
+
const initialTrade = isNested7702BatchTx
|
|
102
|
+
? firstTradeWithMetadata
|
|
103
|
+
: tradeWithMetadata;
|
|
82
104
|
yield {
|
|
83
|
-
type: SubmitStep.
|
|
105
|
+
type: SubmitStep.RekeyHistoryItem,
|
|
84
106
|
payload: {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
107
|
+
oldHistoryKey: batchId,
|
|
108
|
+
newHistoryKey: initialTrade.txMeta.id,
|
|
109
|
+
historyItemOverrides: {
|
|
110
|
+
quote: initialTrade.quoteResponse.quote,
|
|
111
|
+
quoteIds,
|
|
112
|
+
},
|
|
113
|
+
tradeMeta: initialTrade.txMeta,
|
|
88
114
|
},
|
|
89
115
|
};
|
|
90
116
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
117
|
+
// Create a new history item for each trade, keyed by quoteId or txMetaId
|
|
118
|
+
if (index > 0 || isNested7702BatchTx) {
|
|
119
|
+
const historyKey = isNested7702BatchTx
|
|
120
|
+
? getHistoryKeyForQuote(tradeWithMetadata)
|
|
121
|
+
: tradeWithMetadata.txMeta.id;
|
|
122
|
+
const bridgeTxMeta = isNested7702BatchTx
|
|
123
|
+
? undefined
|
|
124
|
+
: tradeWithMetadata.txMeta;
|
|
97
125
|
yield {
|
|
98
126
|
type: SubmitStep.AddHistoryItem,
|
|
99
127
|
payload: {
|
|
100
|
-
historyKey
|
|
101
|
-
quoteResponse,
|
|
128
|
+
historyKey,
|
|
129
|
+
quoteResponse: tradeWithMetadata.quoteResponse,
|
|
102
130
|
batchSellData: batchSellTrades,
|
|
103
|
-
bridgeTxMeta
|
|
131
|
+
bridgeTxMeta,
|
|
104
132
|
},
|
|
105
133
|
};
|
|
106
134
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batch-sell-strategy.js","sourceRoot":"","sources":["../../src/strategy/batch-sell-strategy.ts"],"names":[],"mappings":"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","sourcesContent":["import { BatchSellTradesResponse, TxData } from '@metamask/bridge-controller';\nimport {\n TransactionMeta,\n TransactionType,\n} from '@metamask/transaction-controller';\n\nimport { QuoteAndTxMetadata } from '../types.js';\nimport {\n findAllTransactionsInBatch,\n getAddTransactionBatchParams,\n hasNestedSwapTransactions,\n is7702Tx,\n isTradeTx,\n shouldDisable7702,\n toQuoteAndTxMetadataBatch,\n} from '../utils/transaction.js';\nimport { SubmitStep } from './types.js';\nimport type { SubmitStrategyParams, SubmitStepResult } from './types.js';\n\nconst getHistoryKeyForQuote = ({\n quoteResponse: { quoteId, quote },\n}: QuoteAndTxMetadata): string => quoteId ?? quote.requestId;\n\n/**\n * Submits batch-sell transactions to the TransactionController\n *\n * @param args - The parameters for the transaction\n * @yields The approvalMeta and tradeMeta for the first batch sell transaction\n */\nexport async function* submitBatchSellHandler(\n args: SubmitStrategyParams<TxData, BatchSellTradesResponse>,\n): AsyncGenerator<SubmitStepResult, void, void> {\n const {\n requireApproval,\n quoteResponses,\n messenger,\n addTransactionBatchFn,\n isDelegatedAccount,\n batchSellTrades,\n batchId: batchIdParam,\n } = args;\n\n const tradeData = toQuoteAndTxMetadataBatch({\n quoteResponses,\n batchSellTrades,\n });\n\n const { gasIncluded7702, gasIncluded, gasSponsored } = batchSellTrades;\n\n const gasFeeToken = tradeData.find(\n ({ type }) => type === TransactionType.tokenMethodTransfer,\n )?.tx.to;\n\n const transactionParams = await getAddTransactionBatchParams({\n messenger,\n tradeData,\n requireApproval,\n isDelegatedAccount,\n // Tx success/failure is independent of other txs in the batch\n atomic: false,\n disable7702: shouldDisable7702(\n gasIncluded7702,\n gasIncluded,\n isDelegatedAccount,\n ),\n isGasFeeSponsored: gasSponsored,\n isGasFeeIncluded: Boolean(gasIncluded7702),\n batchId: batchIdParam,\n skipInitialGasEstimate: gasIncluded7702\n ? isDelegatedAccount\n : Boolean(gasFeeToken),\n excludeNativeTokenForFee: !gasFeeToken,\n });\n\n // Submit the batch to the TransactionController\n const { batchId } = await addTransactionBatchFn(transactionParams);\n\n // Find all batch transaction metas and add them to history\n const allTradesInBatch = findAllTransactionsInBatch({\n messenger,\n batchId,\n tradeData,\n }).filter(\n (metadata): metadata is QuoteAndTxMetadata & { txMeta: TransactionMeta } =>\n isTradeTx(metadata.type) && metadata.txMeta !== undefined,\n );\n\n // This is either the delegation tx or the first STX swap in the batch\n const firstTradeWithMetadata = allTradesInBatch.find(\n ({ txMeta }) =>\n txMeta?.type &&\n (isTradeTx(txMeta.type) || hasNestedSwapTransactions(txMeta)),\n );\n const firstTradeMeta = firstTradeWithMetadata?.txMeta;\n if (!firstTradeMeta) {\n throw new Error(\n 'Failed to add BatchSell trade to history: txMeta not found',\n );\n }\n\n yield {\n type: SubmitStep.SetTradeMeta,\n payload: {\n tradeMeta: firstTradeMeta,\n },\n };\n\n // Each quote must be reported to the reconsiler service (through QuoteStatusManager) with the hash of the tx that\n // actually executed it. So the number of distinct txs the batch produced\n // decides how quotes are tracked:\n // - one tx (atomic 7702 batch): all quotes share the single hash.\n // - many txs (e.g. STX/sendBundle): each quote has its own hash.\n // `is7702Tx` only means the account is delegated (true even for many-tx\n // batches), so count the unique txs instead.\n const isSingleBatchTx =\n new Set(allTradesInBatch.map(({ txMeta }) => txMeta.id)).size === 1;\n\n // Nested/7702 batch\n if (\n isSingleBatchTx &&\n (is7702Tx(firstTradeMeta) || hasNestedSwapTransactions(firstTradeMeta))\n ) {\n const quoteIds = Array.from(\n new Set(allTradesInBatch.map(getHistoryKeyForQuote)),\n );\n\n // Create 1 history item for the parent tx, keyed by the txMeta.id\n yield {\n type: SubmitStep.AddHistoryItem,\n payload: {\n historyKey: firstTradeMeta.id,\n quoteResponse: firstTradeWithMetadata.quoteResponse,\n batchSellData: batchSellTrades,\n quoteIds,\n bridgeTxMeta: firstTradeMeta,\n },\n };\n // Then create a new history item for each nested trade, keyed by quoteId/requestId\n for (const tradeWithMetadata of allTradesInBatch) {\n const { quoteResponse } = tradeWithMetadata;\n\n yield {\n type: SubmitStep.AddHistoryItem,\n payload: {\n historyKey: getHistoryKeyForQuote(tradeWithMetadata),\n quoteResponse,\n batchSellData: batchSellTrades,\n },\n };\n }\n } else {\n // Each trade has its own txMeta if not submitted via 7702\n // Create a new history item for each one, keyed by txMeta.id\n // Note that the approvalTxId is not tracked in history\n for (const { txMeta, quoteResponse } of allTradesInBatch) {\n yield {\n type: SubmitStep.AddHistoryItem,\n payload: {\n historyKey: txMeta.id,\n quoteResponse,\n batchSellData: batchSellTrades,\n bridgeTxMeta: txMeta,\n },\n };\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"batch-sell-strategy.js","sourceRoot":"","sources":["../../src/strategy/batch-sell-strategy.ts"],"names":[],"mappings":"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","sourcesContent":["import { BatchSellTradesResponse, TxData } from '@metamask/bridge-controller';\nimport {\n generateBatchId,\n TransactionMeta,\n TransactionType,\n} from '@metamask/transaction-controller';\n\nimport { QuoteAndTxMetadata } from '../types.js';\nimport {\n findAllTransactionsInBatch,\n getAddTransactionBatchParams,\n hasNestedSwapTransactions,\n is7702Tx,\n isTradeTx,\n shouldDisable7702,\n toQuoteAndTxMetadataBatch,\n} from '../utils/transaction.js';\nimport { SubmitStep } from './types.js';\nimport type { SubmitStrategyParams, SubmitStepResult } from './types.js';\n\nconst getHistoryKeyForQuote = ({\n quoteResponse: { quoteId, quote },\n}: QuoteAndTxMetadata): string => quoteId ?? quote.requestId;\n\n/**\n * Submits batch-sell transactions to the TransactionController\n *\n * @param args - The parameters for the transaction\n * @yields The approvalMeta and tradeMeta for the first batch sell transaction\n */\nexport async function* submitBatchSellHandler(\n args: SubmitStrategyParams<TxData, BatchSellTradesResponse>,\n): AsyncGenerator<SubmitStepResult, void, void> {\n const {\n requireApproval,\n quoteResponses,\n messenger,\n addTransactionBatchFn,\n isDelegatedAccount,\n batchSellTrades,\n batchId: batchIdParam,\n } = args;\n\n const tradeData = toQuoteAndTxMetadataBatch({\n quoteResponses,\n batchSellTrades,\n });\n\n const { gasIncluded7702, gasIncluded, gasSponsored } = batchSellTrades;\n\n const gasFeeToken = tradeData.find(\n ({ type }) => type === TransactionType.tokenMethodTransfer,\n )?.tx.to;\n\n const batchId = batchIdParam ?? generateBatchId();\n\n // Create 1 history item for the parent tx or first quote, keyed by the batchId\n yield {\n type: SubmitStep.AddHistoryItem,\n payload: {\n historyKey: batchId,\n quoteResponse: tradeData[0].quoteResponse,\n batchSellData: batchSellTrades,\n bridgeTxMeta: {\n batchId,\n },\n },\n };\n\n const transactionParams = await getAddTransactionBatchParams({\n messenger,\n tradeData,\n requireApproval,\n isDelegatedAccount,\n // Tx success/failure is independent of other txs in the batch\n atomic: false,\n disable7702: shouldDisable7702(\n gasIncluded7702,\n gasIncluded,\n isDelegatedAccount,\n ),\n isGasFeeSponsored: gasSponsored,\n isGasFeeIncluded: Boolean(gasIncluded7702),\n batchId,\n skipInitialGasEstimate: gasIncluded7702\n ? isDelegatedAccount\n : Boolean(gasFeeToken),\n excludeNativeTokenForFee: !gasFeeToken,\n });\n\n // Submit the batch to the TransactionController\n try {\n await addTransactionBatchFn(transactionParams);\n } catch (error) {\n const allTradesInBatch = findAllTransactionsInBatch({\n messenger,\n batchId,\n tradeData,\n });\n // Propagate the error if tx has not been added to the TransactionController\n if (!allTradesInBatch.some(({ txMeta }) => txMeta)) {\n throw error;\n }\n }\n\n // Find all batch transaction metas and add them to history\n const allTradesInBatch = findAllTransactionsInBatch({\n messenger,\n batchId,\n tradeData,\n }).filter(\n (metadata): metadata is QuoteAndTxMetadata & { txMeta: TransactionMeta } =>\n isTradeTx(metadata.type) && metadata.txMeta !== undefined,\n );\n\n // This is either the delegation tx or the first STX swap in the batch\n const firstTradeWithMetadata = allTradesInBatch.find(\n ({ txMeta }) =>\n txMeta?.type &&\n (isTradeTx(txMeta.type) || hasNestedSwapTransactions(txMeta)),\n );\n const firstTradeMeta = firstTradeWithMetadata?.txMeta;\n if (!firstTradeMeta) {\n throw new Error(\n 'Failed to add BatchSell trade to history: txMeta not found',\n );\n }\n\n yield {\n type: SubmitStep.SetTradeMeta,\n payload: {\n tradeMeta: firstTradeMeta,\n },\n };\n\n // Each quote must be reported to the reconsiler service (through QuoteStatusManager) with the hash of the tx that\n // actually executed it. So the number of distinct txs the batch produced\n // decides how quotes are tracked:\n // - one tx (atomic 7702 batch): all quotes share the single hash.\n // - many txs (e.g. STX/sendBundle): each quote has its own hash.\n // `is7702Tx` only means the account is delegated (true even for many-tx\n // batches), so count the unique txs instead.\n const isSingleBatchTx =\n new Set(allTradesInBatch.map(({ txMeta }) => txMeta.id)).size === 1;\n const isNested7702BatchTx =\n isSingleBatchTx &&\n (is7702Tx(firstTradeMeta) || hasNestedSwapTransactions(firstTradeMeta));\n\n // Each trade has its own txMeta if not submitted via 7702\n // Create a new history item for each one, keyed by txMeta.id\n // Note that the approvalTxId is not tracked in history\n for (const [index, tradeWithMetadata] of allTradesInBatch.entries()) {\n // Rekey the initial trade\n if (index === 0) {\n const quoteIds = isNested7702BatchTx\n ? Array.from(new Set(allTradesInBatch.map(getHistoryKeyForQuote)))\n : undefined;\n const initialTrade = isNested7702BatchTx\n ? firstTradeWithMetadata\n : tradeWithMetadata;\n yield {\n type: SubmitStep.RekeyHistoryItem,\n payload: {\n oldHistoryKey: batchId,\n newHistoryKey: initialTrade.txMeta.id,\n historyItemOverrides: {\n quote: initialTrade.quoteResponse.quote,\n quoteIds,\n },\n tradeMeta: initialTrade.txMeta,\n },\n };\n }\n // Create a new history item for each trade, keyed by quoteId or txMetaId\n if (index > 0 || isNested7702BatchTx) {\n const historyKey = isNested7702BatchTx\n ? getHistoryKeyForQuote(tradeWithMetadata)\n : tradeWithMetadata.txMeta.id;\n const bridgeTxMeta = isNested7702BatchTx\n ? undefined\n : tradeWithMetadata.txMeta;\n yield {\n type: SubmitStep.AddHistoryItem,\n payload: {\n historyKey,\n quoteResponse: tradeWithMetadata.quoteResponse,\n batchSellData: batchSellTrades,\n bridgeTxMeta,\n },\n };\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batch-strategy.d.ts","sourceRoot":"","sources":["../../src/strategy/batch-strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"batch-strategy.d.ts","sourceRoot":"","sources":["../../src/strategy/batch-strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAa1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEzE;;;;;GAKG;AACH,wBAAuB,kBAAkB,CACvC,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC,GACjC,cAAc,CAAC,gBAAgB,EAAE,IAAI,EAAE,IAAI,CAAC,CAqG9C"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { generateBatchId } from '@metamask/transaction-controller';
|
|
1
2
|
import { findAllTransactionsInBatch, getAddTransactionBatchParams, isApprovalTx, isTradeTx, shouldDisable7702, toQuoteAndTxMetadata, } from '../utils/transaction.js';
|
|
2
3
|
import { SubmitStep } from './types.js';
|
|
3
4
|
/**
|
|
@@ -12,6 +13,17 @@ export async function* submitBatchHandler(args) {
|
|
|
12
13
|
quoteResponse,
|
|
13
14
|
isBridgeTx,
|
|
14
15
|
});
|
|
16
|
+
const batchId = generateBatchId();
|
|
17
|
+
yield {
|
|
18
|
+
type: SubmitStep.AddHistoryItem,
|
|
19
|
+
payload: {
|
|
20
|
+
historyKey: batchId,
|
|
21
|
+
quoteResponse,
|
|
22
|
+
bridgeTxMeta: {
|
|
23
|
+
batchId,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
};
|
|
15
27
|
const transactionParams = await getAddTransactionBatchParams({
|
|
16
28
|
tradeData,
|
|
17
29
|
requireApproval,
|
|
@@ -21,13 +33,28 @@ export async function* submitBatchHandler(args) {
|
|
|
21
33
|
disable7702: shouldDisable7702(quoteResponse.quote.gasIncluded7702, quoteResponse.quote.gasIncluded, isDelegatedAccount),
|
|
22
34
|
isGasFeeSponsored: Boolean(quoteResponse.quote.gasSponsored),
|
|
23
35
|
isGasFeeIncluded: Boolean(quoteResponse.quote.gasIncluded7702),
|
|
24
|
-
});
|
|
25
|
-
const { batchId } = await addTransactionBatchFn(transactionParams);
|
|
26
|
-
const quoteAndTxMetas = findAllTransactionsInBatch({
|
|
27
|
-
messenger,
|
|
28
36
|
batchId,
|
|
29
|
-
tradeData,
|
|
30
37
|
});
|
|
38
|
+
let quoteAndTxMetas = [];
|
|
39
|
+
try {
|
|
40
|
+
await addTransactionBatchFn(transactionParams);
|
|
41
|
+
quoteAndTxMetas = findAllTransactionsInBatch({
|
|
42
|
+
messenger,
|
|
43
|
+
batchId,
|
|
44
|
+
tradeData,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
quoteAndTxMetas = findAllTransactionsInBatch({
|
|
49
|
+
messenger,
|
|
50
|
+
batchId,
|
|
51
|
+
tradeData,
|
|
52
|
+
});
|
|
53
|
+
// If txMeta has not been added to the TransactionController, propagate the error
|
|
54
|
+
if (!quoteAndTxMetas.some(({ txMeta }) => txMeta)) {
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
31
58
|
yield {
|
|
32
59
|
type: SubmitStep.UpdateBatchTransactions,
|
|
33
60
|
payload: {
|
|
@@ -44,16 +71,14 @@ export async function* submitBatchHandler(args) {
|
|
|
44
71
|
payload: { tradeMeta },
|
|
45
72
|
};
|
|
46
73
|
yield {
|
|
47
|
-
type: SubmitStep.
|
|
74
|
+
type: SubmitStep.RekeyHistoryItem,
|
|
48
75
|
payload: {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
hash: tradeMeta.hash,
|
|
54
|
-
batchId: tradeMeta.batchId,
|
|
76
|
+
oldHistoryKey: batchId,
|
|
77
|
+
newHistoryKey: tradeMeta.id,
|
|
78
|
+
historyItemOverrides: {
|
|
79
|
+
approvalTxId: approvalMeta?.id,
|
|
55
80
|
},
|
|
56
|
-
|
|
81
|
+
tradeMeta,
|
|
57
82
|
},
|
|
58
83
|
};
|
|
59
84
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batch-strategy.js","sourceRoot":"","sources":["../../src/strategy/batch-strategy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"batch-strategy.js","sourceRoot":"","sources":["../../src/strategy/batch-strategy.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TxData } from '@metamask/bridge-controller';\nimport { generateBatchId } from '@metamask/transaction-controller';\n\nimport type { QuoteAndTxMetadata } from '../types.js';\nimport {\n findAllTransactionsInBatch,\n getAddTransactionBatchParams,\n isApprovalTx,\n isTradeTx,\n shouldDisable7702,\n toQuoteAndTxMetadata,\n} from '../utils/transaction.js';\nimport { SubmitStep } from './types.js';\nimport type { SubmitStrategyParams, SubmitStepResult } from './types.js';\n\n/**\n * Submits batched EVM transactions to the TransactionController\n *\n * @param args - The parameters for the transaction\n * @yields The approvalMeta and tradeMeta for the batched transaction\n */\nexport async function* submitBatchHandler(\n args: SubmitStrategyParams<TxData>,\n): AsyncGenerator<SubmitStepResult, void, void> {\n const {\n requireApproval,\n quoteResponses: [quoteResponse],\n messenger,\n isBridgeTx,\n addTransactionBatchFn,\n isDelegatedAccount,\n } = args;\n\n const tradeData = toQuoteAndTxMetadata({\n quoteResponse,\n isBridgeTx,\n });\n\n const batchId = generateBatchId();\n\n yield {\n type: SubmitStep.AddHistoryItem,\n payload: {\n historyKey: batchId,\n quoteResponse,\n bridgeTxMeta: {\n batchId,\n },\n },\n };\n\n const transactionParams = await getAddTransactionBatchParams({\n tradeData,\n requireApproval,\n isDelegatedAccount,\n messenger,\n atomic: true,\n disable7702: shouldDisable7702(\n quoteResponse.quote.gasIncluded7702,\n quoteResponse.quote.gasIncluded,\n isDelegatedAccount,\n ),\n isGasFeeSponsored: Boolean(quoteResponse.quote.gasSponsored),\n isGasFeeIncluded: Boolean(quoteResponse.quote.gasIncluded7702),\n batchId,\n });\n\n let quoteAndTxMetas: QuoteAndTxMetadata[] = [];\n try {\n await addTransactionBatchFn(transactionParams);\n quoteAndTxMetas = findAllTransactionsInBatch({\n messenger,\n batchId,\n tradeData,\n });\n } catch (error) {\n quoteAndTxMetas = findAllTransactionsInBatch({\n messenger,\n batchId,\n tradeData,\n });\n // If txMeta has not been added to the TransactionController, propagate the error\n if (!quoteAndTxMetas.some(({ txMeta }) => txMeta)) {\n throw error;\n }\n }\n\n yield {\n type: SubmitStep.UpdateBatchTransactions,\n payload: {\n quoteAndTxMetas,\n },\n };\n\n const tradeMeta = quoteAndTxMetas.find(\n ({ type, txMeta }) => isTradeTx(type) && txMeta,\n )?.txMeta;\n\n const approvalMeta = quoteAndTxMetas.find(\n ({ type, txMeta }) => isApprovalTx(type) && txMeta,\n )?.txMeta;\n\n if (!tradeMeta) {\n throw new Error(\n 'Failed to update cross-chain swap transaction batch: tradeMeta not found',\n );\n }\n\n yield {\n type: SubmitStep.SetTradeMeta,\n payload: { tradeMeta },\n };\n\n yield {\n type: SubmitStep.RekeyHistoryItem,\n payload: {\n oldHistoryKey: batchId,\n newHistoryKey: tradeMeta.id,\n historyItemOverrides: {\n approvalTxId: approvalMeta?.id,\n },\n tradeMeta,\n },\n };\n}\n"]}
|
|
@@ -1,33 +1,7 @@
|
|
|
1
1
|
import type { TxData } from '@metamask/bridge-controller';
|
|
2
|
-
import { TransactionMeta
|
|
3
|
-
import { BridgeStatusControllerMessenger } from '../types.js';
|
|
2
|
+
import { TransactionMeta } from '@metamask/transaction-controller';
|
|
4
3
|
import type { SubmitStrategyParams, SubmitStepResult } from './types.js';
|
|
5
|
-
|
|
6
|
-
* Submits a single tx to the TransactionController and returns the txMetaId
|
|
7
|
-
*
|
|
8
|
-
* @param args - The parameters for the transaction
|
|
9
|
-
* @param args.transactionType - The type of transaction to submit
|
|
10
|
-
* @param args.trade - The trade data to confirm
|
|
11
|
-
* @param args.requireApproval - Whether to require approval for the transaction
|
|
12
|
-
* @param args.txFee - Optional gas fee parameters from the quote (used when gasIncluded is true)
|
|
13
|
-
* @param args.txFee.maxFeePerGas - The maximum fee per gas from the quote
|
|
14
|
-
* @param args.txFee.maxPriorityFeePerGas - The maximum priority fee per gas from the quote
|
|
15
|
-
* @param args.actionId - Optional actionId for pre-submission history (if not provided, one is generated)
|
|
16
|
-
* @param args.messenger - The messenger to use for the transaction
|
|
17
|
-
* @returns The transaction meta
|
|
18
|
-
*/
|
|
19
|
-
export declare const handleSingleTx: ({ messenger, trade, transactionType, requireApproval, txFee, actionId, }: {
|
|
20
|
-
messenger: BridgeStatusControllerMessenger;
|
|
21
|
-
transactionType: TransactionType;
|
|
22
|
-
trade: TxData;
|
|
23
|
-
requireApproval?: boolean;
|
|
24
|
-
txFee?: {
|
|
25
|
-
maxFeePerGas: string;
|
|
26
|
-
maxPriorityFeePerGas: string;
|
|
27
|
-
};
|
|
28
|
-
actionId?: string;
|
|
29
|
-
}) => Promise<TransactionMeta>;
|
|
30
|
-
export declare const handleEvmApprovals: (args: SubmitStrategyParams) => Promise<string | undefined>;
|
|
4
|
+
export declare const handleEvmApprovals: (args: SubmitStrategyParams, actionId?: string) => Promise<TransactionMeta | undefined>;
|
|
31
5
|
/**
|
|
32
6
|
* Sequentially submits EVM resetApproval, approval and trade transactions through the TransactionController.
|
|
33
7
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evm-strategy.d.ts","sourceRoot":"","sources":["../../src/strategy/evm-strategy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EACL,eAAe,
|
|
1
|
+
{"version":3,"file":"evm-strategy.d.ts","sourceRoot":"","sources":["../../src/strategy/evm-strategy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EACL,eAAe,EAEhB,MAAM,kCAAkC,CAAC;AAgB1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AA4GzE,eAAO,MAAM,kBAAkB,SACvB,oBAAoB,aACf,MAAM,yCAKhB,CAAC;AAEJ;;;;;GAKG;AACH,wBAAuB,gBAAgB,CACrC,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC,GACjC,cAAc,CAAC,gBAAgB,EAAE,IAAI,EAAE,IAAI,CAAC,CA0F9C"}
|
|
@@ -5,7 +5,7 @@ import { TransactionType, } from '@metamask/transaction-controller';
|
|
|
5
5
|
import { getAccountByAddress } from '../utils/accounts.js';
|
|
6
6
|
import { getNetworkClientIdByChainId } from '../utils/network.js';
|
|
7
7
|
import { getApprovalTraceParams } from '../utils/trace.js';
|
|
8
|
-
import { addTransaction, generateActionId, handleApprovalDelay, handleMobileHardwareWalletDelay, toTransactionParams, waitForTxConfirmation, } from '../utils/transaction.js';
|
|
8
|
+
import { addTransaction, generateActionId, getTransactionMetaByActionId, handleApprovalDelay, handleMobileHardwareWalletDelay, toTransactionParams, waitForTxConfirmation, } from '../utils/transaction.js';
|
|
9
9
|
import { SubmitStep } from './types.js';
|
|
10
10
|
/**
|
|
11
11
|
* Submits a single tx to the TransactionController and returns the txMetaId
|
|
@@ -21,7 +21,7 @@ import { SubmitStep } from './types.js';
|
|
|
21
21
|
* @param args.messenger - The messenger to use for the transaction
|
|
22
22
|
* @returns The transaction meta
|
|
23
23
|
*/
|
|
24
|
-
|
|
24
|
+
const handleSingleTx = async ({ messenger, trade, transactionType, requireApproval = false, txFee,
|
|
25
25
|
// Use provided actionId (for pre-submission history) or generate one
|
|
26
26
|
actionId = generateActionId(), }) => {
|
|
27
27
|
const selectedAccount = getAccountByAddress(messenger, trade.from);
|
|
@@ -47,10 +47,11 @@ actionId = generateActionId(), }) => {
|
|
|
47
47
|
* But only the approval's txMetaId will be returned.
|
|
48
48
|
*
|
|
49
49
|
* @param args - The parameters for the submission flow
|
|
50
|
+
* @param actionId - The actionId for the approval transaction
|
|
50
51
|
*
|
|
51
|
-
* @returns The
|
|
52
|
+
* @returns The approval txMeta of the approval transaction
|
|
52
53
|
*/
|
|
53
|
-
const approve = async (args) => {
|
|
54
|
+
const approve = async (args, actionId) => {
|
|
54
55
|
const { quoteResponses: [quoteResponse], isBridgeTx, } = args;
|
|
55
56
|
const { approval, resetApproval } = quoteResponse;
|
|
56
57
|
if (!approval || !isEvmTxData(approval)) {
|
|
@@ -71,11 +72,12 @@ const approve = async (args) => {
|
|
|
71
72
|
...args,
|
|
72
73
|
transactionType,
|
|
73
74
|
trade: approval,
|
|
75
|
+
actionId,
|
|
74
76
|
});
|
|
75
|
-
return approvalTxMeta
|
|
77
|
+
return approvalTxMeta;
|
|
76
78
|
}
|
|
77
79
|
};
|
|
78
|
-
export const handleEvmApprovals = async (args) => await args.traceFn(getApprovalTraceParams(args.quoteResponses[0], args.isStxEnabled), async () => await approve(args));
|
|
80
|
+
export const handleEvmApprovals = async (args, actionId) => await args.traceFn(getApprovalTraceParams(args.quoteResponses[0], args.isStxEnabled), async () => await approve(args, actionId));
|
|
79
81
|
/**
|
|
80
82
|
* Sequentially submits EVM resetApproval, approval and trade transactions through the TransactionController.
|
|
81
83
|
*
|
|
@@ -84,19 +86,7 @@ export const handleEvmApprovals = async (args) => await args.traceFn(getApproval
|
|
|
84
86
|
*/
|
|
85
87
|
export async function* submitEvmHandler(args) {
|
|
86
88
|
const { quoteResponses: [quoteResponse], requireApproval, isBridgeTx, } = args;
|
|
87
|
-
//
|
|
88
|
-
const approvalTxId = await handleEvmApprovals(args);
|
|
89
|
-
// Delay after approval
|
|
90
|
-
if (approvalTxId) {
|
|
91
|
-
await handleApprovalDelay(quoteResponse.quote.srcChainId);
|
|
92
|
-
}
|
|
93
|
-
// Hardware-wallet delay first (Ledger second-prompt spacing), then wait for
|
|
94
|
-
// on-chain approval confirmation so swap gas estimation runs after allowance is set.
|
|
95
|
-
await handleMobileHardwareWalletDelay(requireApproval);
|
|
96
|
-
if (requireApproval && approvalTxId) {
|
|
97
|
-
await waitForTxConfirmation(args.messenger, approvalTxId);
|
|
98
|
-
}
|
|
99
|
-
// Generate trade actionId for pre-submission history
|
|
89
|
+
// Generate actionId for pre-submission history
|
|
100
90
|
const actionId = generateActionId();
|
|
101
91
|
// Add pre-submission history keyed by actionId
|
|
102
92
|
// This ensures we have quote data available if transaction fails during submission
|
|
@@ -104,40 +94,73 @@ export async function* submitEvmHandler(args) {
|
|
|
104
94
|
type: SubmitStep.AddHistoryItem,
|
|
105
95
|
payload: {
|
|
106
96
|
historyKey: actionId,
|
|
107
|
-
approvalTxId,
|
|
108
97
|
actionId,
|
|
109
98
|
quoteResponse,
|
|
110
99
|
},
|
|
111
100
|
};
|
|
101
|
+
// Submit resetApproval and approval transactions if present
|
|
102
|
+
const approvalTxMeta = await handleEvmApprovals(args, actionId);
|
|
103
|
+
const approvalTxId = approvalTxMeta?.id;
|
|
104
|
+
let tradeActionId = actionId;
|
|
105
|
+
// Delay after approval
|
|
106
|
+
if (approvalTxId) {
|
|
107
|
+
// Generate a new actionId for the trade transaction since approval used the first one
|
|
108
|
+
tradeActionId = generateActionId();
|
|
109
|
+
yield {
|
|
110
|
+
type: SubmitStep.RekeyHistoryItem,
|
|
111
|
+
payload: {
|
|
112
|
+
oldHistoryKey: actionId,
|
|
113
|
+
newHistoryKey: tradeActionId,
|
|
114
|
+
historyItemOverrides: {
|
|
115
|
+
approvalTxId,
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
await handleApprovalDelay(quoteResponse.quote.srcChainId);
|
|
120
|
+
}
|
|
121
|
+
// Hardware-wallet delay first (Ledger second-prompt spacing), then wait for
|
|
122
|
+
// on-chain approval confirmation so swap gas estimation runs after allowance is set.
|
|
123
|
+
await handleMobileHardwareWalletDelay(requireApproval);
|
|
124
|
+
if (requireApproval && approvalTxId) {
|
|
125
|
+
await waitForTxConfirmation(args.messenger, approvalTxId);
|
|
126
|
+
}
|
|
112
127
|
const transactionType = isBridgeTx
|
|
113
128
|
? TransactionType.bridge
|
|
114
129
|
: TransactionType.swap;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
:
|
|
125
|
-
|
|
126
|
-
|
|
130
|
+
let tradeMeta;
|
|
131
|
+
try {
|
|
132
|
+
tradeMeta = await handleSingleTx({
|
|
133
|
+
...args,
|
|
134
|
+
transactionType,
|
|
135
|
+
trade: quoteResponse.trade,
|
|
136
|
+
// TODO figure out if this is needed
|
|
137
|
+
// Pass txFee when gasIncluded is true to use the quote's gas fees
|
|
138
|
+
// instead of re-estimating (which would fail for max native token swaps)
|
|
139
|
+
txFee: quoteResponse.quote.gasIncluded
|
|
140
|
+
? quoteResponse.quote.feeData.txFee
|
|
141
|
+
: undefined,
|
|
142
|
+
actionId: tradeActionId,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
// Silence the error if tx has been added to the TransactionController to prevent duplicate Failed events
|
|
147
|
+
tradeMeta = getTransactionMetaByActionId(args.messenger, tradeActionId);
|
|
148
|
+
if (!tradeMeta) {
|
|
149
|
+
throw error;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
yield {
|
|
153
|
+
type: SubmitStep.SetTradeMeta,
|
|
154
|
+
payload: { tradeMeta },
|
|
155
|
+
};
|
|
127
156
|
// Use the tradeMeta's id as history key
|
|
128
157
|
yield {
|
|
129
158
|
type: SubmitStep.RekeyHistoryItem,
|
|
130
159
|
payload: {
|
|
131
|
-
oldHistoryKey:
|
|
160
|
+
oldHistoryKey: tradeActionId,
|
|
132
161
|
newHistoryKey: tradeMeta.id,
|
|
133
162
|
tradeMeta,
|
|
134
163
|
},
|
|
135
164
|
};
|
|
136
|
-
yield {
|
|
137
|
-
type: SubmitStep.SetTradeMeta,
|
|
138
|
-
payload: {
|
|
139
|
-
tradeMeta,
|
|
140
|
-
},
|
|
141
|
-
};
|
|
142
165
|
}
|
|
143
166
|
//# sourceMappingURL=evm-strategy.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evm-strategy.js","sourceRoot":"","sources":["../../src/strategy/evm-strategy.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable consistent-return */\n/* eslint-disable @typescript-eslint/explicit-function-return-type */\nimport { formatChainIdToHex, isEvmTxData } from '@metamask/bridge-controller';\nimport type { TxData } from '@metamask/bridge-controller';\nimport {\n TransactionMeta,\n TransactionType,\n} from '@metamask/transaction-controller';\n\nimport { BridgeStatusControllerMessenger } from '../types.js';\nimport { getAccountByAddress } from '../utils/accounts.js';\nimport { getNetworkClientIdByChainId } from '../utils/network.js';\nimport { getApprovalTraceParams } from '../utils/trace.js';\nimport {\n addTransaction,\n generateActionId,\n handleApprovalDelay,\n handleMobileHardwareWalletDelay,\n toTransactionParams,\n waitForTxConfirmation,\n} from '../utils/transaction.js';\nimport { SubmitStep } from './types.js';\nimport type { SubmitStrategyParams, SubmitStepResult } from './types.js';\n\n/**\n * Submits a single tx to the TransactionController and returns the txMetaId\n *\n * @param args - The parameters for the transaction\n * @param args.transactionType - The type of transaction to submit\n * @param args.trade - The trade data to confirm\n * @param args.requireApproval - Whether to require approval for the transaction\n * @param args.txFee - Optional gas fee parameters from the quote (used when gasIncluded is true)\n * @param args.txFee.maxFeePerGas - The maximum fee per gas from the quote\n * @param args.txFee.maxPriorityFeePerGas - The maximum priority fee per gas from the quote\n * @param args.actionId - Optional actionId for pre-submission history (if not provided, one is generated)\n * @param args.messenger - The messenger to use for the transaction\n * @returns The transaction meta\n */\nexport const handleSingleTx = async ({\n messenger,\n trade,\n transactionType,\n requireApproval = false,\n txFee,\n // Use provided actionId (for pre-submission history) or generate one\n actionId = generateActionId(),\n}: {\n messenger: BridgeStatusControllerMessenger;\n transactionType: TransactionType;\n trade: TxData;\n requireApproval?: boolean;\n txFee?: { maxFeePerGas: string; maxPriorityFeePerGas: string };\n actionId?: string;\n}): Promise<TransactionMeta> => {\n const selectedAccount = getAccountByAddress(messenger, trade.from);\n if (!selectedAccount) {\n throw new Error(\n 'Failed to submit cross-chain swap transaction: unknown account in trade data',\n );\n }\n const hexChainId = formatChainIdToHex(trade.chainId);\n const networkClientId = getNetworkClientIdByChainId(messenger, hexChainId);\n\n const requestOptions = {\n actionId,\n networkClientId,\n requireApproval,\n type: transactionType,\n origin: 'metamask',\n isInternal: true,\n };\n\n const transactionParamsWithMaxGas = await toTransactionParams(\n messenger,\n trade,\n networkClientId,\n hexChainId,\n txFee,\n );\n\n return await addTransaction(\n messenger,\n { ...transactionParamsWithMaxGas, from: trade.from },\n requestOptions,\n );\n};\n\n/**\n * Submits the approval and resetApproval transactions through the TransactionController.\n * If there is a resetApproval, it will be submitted first.\n * But only the approval's txMetaId will be returned.\n *\n * @param args - The parameters for the submission flow\n *\n * @returns The approvalTxId of the approval transaction\n */\nconst approve = async (args: SubmitStrategyParams) => {\n const {\n quoteResponses: [quoteResponse],\n isBridgeTx,\n } = args;\n const { approval, resetApproval } = quoteResponse;\n if (!approval || !isEvmTxData(approval)) {\n return;\n }\n\n const transactionType = isBridgeTx\n ? TransactionType.bridgeApproval\n : TransactionType.swapApproval;\n\n if (resetApproval) {\n await handleSingleTx({\n ...args,\n transactionType,\n trade: resetApproval,\n });\n }\n\n if (approval) {\n const approvalTxMeta = await handleSingleTx({\n ...args,\n transactionType,\n trade: approval,\n });\n return approvalTxMeta?.id;\n }\n};\n\nexport const handleEvmApprovals = async (args: SubmitStrategyParams) =>\n await args.traceFn(\n getApprovalTraceParams(args.quoteResponses[0], args.isStxEnabled),\n async () => await approve(args),\n );\n\n/**\n * Sequentially submits EVM resetApproval, approval and trade transactions through the TransactionController.\n *\n * @param args - The parameters for the transaction\n * @yields Data for updating the BridgeStatusController\n */\nexport async function* submitEvmHandler(\n args: SubmitStrategyParams<TxData>,\n): AsyncGenerator<SubmitStepResult, void, void> {\n const {\n quoteResponses: [quoteResponse],\n requireApproval,\n isBridgeTx,\n } = args;\n\n // Submit resetApproval and approval transactions if present\n const approvalTxId = await handleEvmApprovals(args);\n\n // Delay after approval\n if (approvalTxId) {\n await handleApprovalDelay(quoteResponse.quote.srcChainId);\n }\n // Hardware-wallet delay first (Ledger second-prompt spacing), then wait for\n // on-chain approval confirmation so swap gas estimation runs after allowance is set.\n await handleMobileHardwareWalletDelay(requireApproval);\n if (requireApproval && approvalTxId) {\n await waitForTxConfirmation(args.messenger, approvalTxId);\n }\n\n // Generate trade actionId for pre-submission history\n const actionId = generateActionId();\n\n // Add pre-submission history keyed by actionId\n // This ensures we have quote data available if transaction fails during submission\n yield {\n type: SubmitStep.AddHistoryItem,\n payload: {\n historyKey: actionId,\n approvalTxId,\n actionId,\n quoteResponse,\n },\n };\n\n const transactionType = isBridgeTx\n ? TransactionType.bridge\n : TransactionType.swap;\n\n const tradeMeta = await handleSingleTx({\n ...args,\n transactionType,\n trade: quoteResponse.trade,\n // TODO figure out if this is needed\n // Pass txFee when gasIncluded is true to use the quote's gas fees\n // instead of re-estimating (which would fail for max native token swaps)\n txFee: quoteResponse.quote.gasIncluded\n ? quoteResponse.quote.feeData.txFee\n : undefined,\n actionId,\n });\n\n // Use the tradeMeta's id as history key\n yield {\n type: SubmitStep.RekeyHistoryItem,\n payload: {\n oldHistoryKey: actionId,\n newHistoryKey: tradeMeta.id,\n tradeMeta,\n },\n };\n\n yield {\n type: SubmitStep.SetTradeMeta,\n payload: {\n tradeMeta,\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"evm-strategy.js","sourceRoot":"","sources":["../../src/strategy/evm-strategy.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable consistent-return */\n/* eslint-disable @typescript-eslint/explicit-function-return-type */\nimport { formatChainIdToHex, isEvmTxData } from '@metamask/bridge-controller';\nimport type { TxData } from '@metamask/bridge-controller';\nimport {\n TransactionMeta,\n TransactionType,\n} from '@metamask/transaction-controller';\n\nimport { BridgeStatusControllerMessenger } from '../types.js';\nimport { getAccountByAddress } from '../utils/accounts.js';\nimport { getNetworkClientIdByChainId } from '../utils/network.js';\nimport { getApprovalTraceParams } from '../utils/trace.js';\nimport {\n addTransaction,\n generateActionId,\n getTransactionMetaByActionId,\n handleApprovalDelay,\n handleMobileHardwareWalletDelay,\n toTransactionParams,\n waitForTxConfirmation,\n} from '../utils/transaction.js';\nimport { SubmitStep } from './types.js';\nimport type { SubmitStrategyParams, SubmitStepResult } from './types.js';\n\n/**\n * Submits a single tx to the TransactionController and returns the txMetaId\n *\n * @param args - The parameters for the transaction\n * @param args.transactionType - The type of transaction to submit\n * @param args.trade - The trade data to confirm\n * @param args.requireApproval - Whether to require approval for the transaction\n * @param args.txFee - Optional gas fee parameters from the quote (used when gasIncluded is true)\n * @param args.txFee.maxFeePerGas - The maximum fee per gas from the quote\n * @param args.txFee.maxPriorityFeePerGas - The maximum priority fee per gas from the quote\n * @param args.actionId - Optional actionId for pre-submission history (if not provided, one is generated)\n * @param args.messenger - The messenger to use for the transaction\n * @returns The transaction meta\n */\nconst handleSingleTx = async ({\n messenger,\n trade,\n transactionType,\n requireApproval = false,\n txFee,\n // Use provided actionId (for pre-submission history) or generate one\n actionId = generateActionId(),\n}: {\n messenger: BridgeStatusControllerMessenger;\n transactionType: TransactionType;\n trade: TxData;\n requireApproval?: boolean;\n txFee?: { maxFeePerGas: string; maxPriorityFeePerGas: string };\n actionId?: string;\n}): Promise<TransactionMeta> => {\n const selectedAccount = getAccountByAddress(messenger, trade.from);\n if (!selectedAccount) {\n throw new Error(\n 'Failed to submit cross-chain swap transaction: unknown account in trade data',\n );\n }\n const hexChainId = formatChainIdToHex(trade.chainId);\n const networkClientId = getNetworkClientIdByChainId(messenger, hexChainId);\n\n const requestOptions = {\n actionId,\n networkClientId,\n requireApproval,\n type: transactionType,\n origin: 'metamask',\n isInternal: true,\n };\n\n const transactionParamsWithMaxGas = await toTransactionParams(\n messenger,\n trade,\n networkClientId,\n hexChainId,\n txFee,\n );\n\n return await addTransaction(\n messenger,\n { ...transactionParamsWithMaxGas, from: trade.from },\n requestOptions,\n );\n};\n\n/**\n * Submits the approval and resetApproval transactions through the TransactionController.\n * If there is a resetApproval, it will be submitted first.\n * But only the approval's txMetaId will be returned.\n *\n * @param args - The parameters for the submission flow\n * @param actionId - The actionId for the approval transaction\n *\n * @returns The approval txMeta of the approval transaction\n */\nconst approve = async (args: SubmitStrategyParams, actionId?: string) => {\n const {\n quoteResponses: [quoteResponse],\n isBridgeTx,\n } = args;\n const { approval, resetApproval } = quoteResponse;\n if (!approval || !isEvmTxData(approval)) {\n return;\n }\n\n const transactionType = isBridgeTx\n ? TransactionType.bridgeApproval\n : TransactionType.swapApproval;\n\n if (resetApproval) {\n await handleSingleTx({\n ...args,\n transactionType,\n trade: resetApproval,\n });\n }\n\n if (approval) {\n const approvalTxMeta = await handleSingleTx({\n ...args,\n transactionType,\n trade: approval,\n actionId,\n });\n return approvalTxMeta;\n }\n};\n\nexport const handleEvmApprovals = async (\n args: SubmitStrategyParams,\n actionId?: string,\n) =>\n await args.traceFn(\n getApprovalTraceParams(args.quoteResponses[0], args.isStxEnabled),\n async () => await approve(args, actionId),\n );\n\n/**\n * Sequentially submits EVM resetApproval, approval and trade transactions through the TransactionController.\n *\n * @param args - The parameters for the transaction\n * @yields Data for updating the BridgeStatusController\n */\nexport async function* submitEvmHandler(\n args: SubmitStrategyParams<TxData>,\n): AsyncGenerator<SubmitStepResult, void, void> {\n const {\n quoteResponses: [quoteResponse],\n requireApproval,\n isBridgeTx,\n } = args;\n\n // Generate actionId for pre-submission history\n const actionId = generateActionId();\n\n // Add pre-submission history keyed by actionId\n // This ensures we have quote data available if transaction fails during submission\n yield {\n type: SubmitStep.AddHistoryItem,\n payload: {\n historyKey: actionId,\n actionId,\n quoteResponse,\n },\n };\n\n // Submit resetApproval and approval transactions if present\n const approvalTxMeta = await handleEvmApprovals(args, actionId);\n const approvalTxId = approvalTxMeta?.id;\n\n let tradeActionId = actionId;\n\n // Delay after approval\n if (approvalTxId) {\n // Generate a new actionId for the trade transaction since approval used the first one\n tradeActionId = generateActionId();\n yield {\n type: SubmitStep.RekeyHistoryItem,\n payload: {\n oldHistoryKey: actionId,\n newHistoryKey: tradeActionId,\n historyItemOverrides: {\n approvalTxId,\n },\n },\n };\n await handleApprovalDelay(quoteResponse.quote.srcChainId);\n }\n // Hardware-wallet delay first (Ledger second-prompt spacing), then wait for\n // on-chain approval confirmation so swap gas estimation runs after allowance is set.\n await handleMobileHardwareWalletDelay(requireApproval);\n if (requireApproval && approvalTxId) {\n await waitForTxConfirmation(args.messenger, approvalTxId);\n }\n\n const transactionType = isBridgeTx\n ? TransactionType.bridge\n : TransactionType.swap;\n\n let tradeMeta: TransactionMeta | undefined;\n try {\n tradeMeta = await handleSingleTx({\n ...args,\n transactionType,\n trade: quoteResponse.trade,\n // TODO figure out if this is needed\n // Pass txFee when gasIncluded is true to use the quote's gas fees\n // instead of re-estimating (which would fail for max native token swaps)\n txFee: quoteResponse.quote.gasIncluded\n ? quoteResponse.quote.feeData.txFee\n : undefined,\n actionId: tradeActionId,\n });\n } catch (error) {\n // Silence the error if tx has been added to the TransactionController to prevent duplicate Failed events\n tradeMeta = getTransactionMetaByActionId(args.messenger, tradeActionId);\n if (!tradeMeta) {\n throw error;\n }\n }\n\n yield {\n type: SubmitStep.SetTradeMeta,\n payload: { tradeMeta },\n };\n\n // Use the tradeMeta's id as history key\n yield {\n type: SubmitStep.RekeyHistoryItem,\n payload: {\n oldHistoryKey: tradeActionId,\n newHistoryKey: tradeMeta.id,\n tradeMeta,\n },\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intent-strategy.d.ts","sourceRoot":"","sources":["../../src/strategy/intent-strategy.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,MAAM,EACP,MAAM,6BAA6B,CAAC;AAgBrC,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAc,MAAM,YAAY,CAAC;AAsHhF;;;;;;;;;;;;GAYG;AACH,wBAAuB,mBAAmB,CACxC,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC,GACjC,cAAc,CAAC,gBAAgB,EAAE,IAAI,EAAE,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"intent-strategy.d.ts","sourceRoot":"","sources":["../../src/strategy/intent-strategy.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,MAAM,EACP,MAAM,6BAA6B,CAAC;AAgBrC,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAc,MAAM,YAAY,CAAC;AAsHhF;;;;;;;;;;;;GAYG;AACH,wBAAuB,mBAAmB,CACxC,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC,GACjC,cAAc,CAAC,gBAAgB,EAAE,IAAI,EAAE,IAAI,CAAC,CAqD9C"}
|
|
@@ -108,7 +108,8 @@ const handleSubmitIntent = async (args) => {
|
|
|
108
108
|
*/
|
|
109
109
|
export async function* submitIntentHandler(args) {
|
|
110
110
|
// TODO handle STX/batch approvals
|
|
111
|
-
const
|
|
111
|
+
const approvalTxMeta = await handleEvmApprovals(args);
|
|
112
|
+
const approvalTxId = approvalTxMeta?.id;
|
|
112
113
|
approvalTxId && (await waitForTxConfirmation(args.messenger, approvalTxId));
|
|
113
114
|
// TODO add to history after approval tx is confirmed
|
|
114
115
|
// Submit the intent order to the bridge-api
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intent-strategy.js","sourceRoot":"","sources":["../../src/strategy/intent-strategy.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/explicit-function-return-type */\nimport {\n formatChainIdToHex,\n isEvmTxData,\n TxData,\n} from '@metamask/bridge-controller';\nimport { TransactionType } from '@metamask/transaction-controller';\n\nimport { getJwt } from '../utils/authentication.js';\nimport {\n getIntentFromQuote,\n mapIntentOrderStatusToTransactionStatus,\n postSubmitOrder,\n} from '../utils/intent-api.js';\nimport { signTypedMessage } from '../utils/keyring.js';\nimport { getNetworkClientIdByChainId } from '../utils/network.js';\nimport {\n addSyntheticTransaction,\n waitForTxConfirmation,\n} from '../utils/transaction.js';\nimport { handleEvmApprovals } from './evm-strategy.js';\nimport { SubmitStrategyParams, SubmitStepResult, SubmitStep } from './types.js';\n\n/**\n * Submits a synthetic EVM transaction to the TransactionController in order to display the intent order's\n * status in theclients, before the actual transaction is finalized on chain. The resulting transaction\n * is only available locally and is not submitted to the chain.\n *\n * @param orderUid - The order uid of the intent transaction\n * @param args - The parameters for the transaction\n * @returns The tradeMeta for the synthetic transaction\n */\nconst handleSyntheticTx = async (\n orderUid: string,\n args: SubmitStrategyParams,\n) => {\n const {\n quoteResponses: [quoteResponse],\n messenger,\n isBridgeTx,\n selectedAccount,\n } = args;\n const {\n quote: { srcChainId },\n } = quoteResponse;\n\n // Determine transaction type: swap for same-chain, bridge for cross-chain\n const transactionType = isBridgeTx\n ? /* c8 ignore start */\n TransactionType.bridge\n : /* c8 ignore end */\n TransactionType.swap;\n\n const networkClientId = getNetworkClientIdByChainId(messenger, srcChainId);\n\n // This is a synthetic transaction whose purpose is to be able\n // to track the order status via the history\n if (!isEvmTxData(quoteResponse.trade)) {\n throw new Error('Failed to submit intent: trade is not an EVM transaction');\n }\n const intent = getIntentFromQuote(quoteResponse);\n // This is a synthetic transaction whose purpose is to be able\n // to track the order status via the history\n /**\n * @deprecated use trade data from quote response instead\n */\n const intentTransactionParams = {\n chainId: formatChainIdToHex(srcChainId),\n from: selectedAccount.address,\n to:\n intent.settlementContract ?? '0x9008D19f58AAbd9eD0D60971565AA8510560ab41', // Default settlement contract\n data: `0x${orderUid?.slice(-8)}`, // Use last 8 chars of orderUid to make each transaction unique\n value: '0x0',\n gas: '0x5208', // Minimal gas for display purposes\n gasPrice: '0x3b9aca00', // 1 Gwei - will be converted to EIP-1559 fees if network supports it\n };\n\n const initialTxMeta = await addSyntheticTransaction(\n messenger,\n intentTransactionParams,\n {\n requireApproval: false,\n networkClientId,\n type: transactionType,\n },\n );\n return initialTxMeta;\n};\n\n/**\n * Submits batched EVM transactions to the TransactionController\n *\n * @param args - The parameters for the transaction\n * @param args.quoteResponse - The quote response\n * @param args.messenger - The messenger\n * @param args.selectedAccount - The selected account\n * @param args.traceFn - The trace function\n * @param args.isBridgeTx - Whether the transaction is a bridge transaction\n * @returns The approvalTxId and tradeMeta for the non-EVM transaction\n */\nconst handleSubmitIntent = async (args: SubmitStrategyParams<TxData>) => {\n const {\n quoteResponses: [quoteResponse],\n messenger,\n selectedAccount,\n clientId,\n fetchFn,\n bridgeApiBaseUrl,\n } = args;\n const { srcChainId, requestId } = quoteResponse.quote;\n\n const intent = getIntentFromQuote(quoteResponse);\n const signature = await signTypedMessage({\n messenger,\n accountAddress: selectedAccount.address,\n typedData: intent.typedData,\n });\n\n const { id: orderUid, status } = await postSubmitOrder({\n params: {\n srcChainId,\n quoteId: requestId,\n signature,\n order: intent.order,\n userAddress: selectedAccount.address,\n aggregatorId: intent.protocol,\n },\n clientId,\n jwt: await getJwt(messenger),\n fetchFn,\n bridgeApiBaseUrl,\n });\n\n return {\n orderUid,\n orderStatus: status,\n };\n};\n\n/**\n * Submits an approval tx to the TransactionController,\n * posts an intent order to the bridge-api,\n * and creates a synthetic transaction in the TransactionController\n *\n * @param args - The parameters for the transaction\n * @param args.quoteResponse - The quote response\n * @param args.messenger - The messenger\n * @param args.selectedAccount - The selected account\n * @param args.traceFn - The trace function\n * @param args.isBridgeTx - Whether the transaction is a bridge transaction\n * @yields The approvalTxId and tradeMeta for the intent transaction\n */\nexport async function* submitIntentHandler(\n args: SubmitStrategyParams<TxData>,\n): AsyncGenerator<SubmitStepResult, void, void> {\n // TODO handle STX/batch approvals\n const approvalTxId = await handleEvmApprovals(args);\n approvalTxId && (await waitForTxConfirmation(args.messenger, approvalTxId));\n\n // TODO add to history after approval tx is confirmed\n\n // Submit the intent order to the bridge-api\n const { orderUid, orderStatus } = await handleSubmitIntent(args);\n\n // Initialize a transaction in the TransactionController\n const syntheticTxMeta = await handleSyntheticTx(orderUid, {\n ...args,\n requireApproval: false,\n isStxEnabled: false,\n });\n\n // Use synthetic transaction metadata + translated intent order status as the tradeMeta\n yield {\n type: SubmitStep.SetTradeMeta,\n payload: {\n tradeMeta: {\n ...syntheticTxMeta,\n // Map intent order status to TransactionController status\n status: mapIntentOrderStatusToTransactionStatus(orderStatus),\n },\n },\n };\n\n // Update txHistory with synthetic txMeta and order id\n yield {\n type: SubmitStep.AddHistoryItem,\n payload: {\n // Use orderId as the history key for intent transactions\n historyKey: orderUid,\n bridgeTxMeta: {\n id: syntheticTxMeta?.id,\n },\n approvalTxId,\n // Keep original txId for TransactionController updates\n originalTransactionId: syntheticTxMeta?.id,\n quoteResponse: args.quoteResponses[0],\n },\n };\n\n // Start polling using the orderId as the history key\n yield {\n type: SubmitStep.StartPolling,\n payload: {\n historyKey: orderUid,\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"intent-strategy.js","sourceRoot":"","sources":["../../src/strategy/intent-strategy.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,OAAO,EACL,kBAAkB,EAClB,WAAW,GAEZ,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAEnE,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EACL,kBAAkB,EAClB,uCAAuC,EACvC,eAAe,GAChB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EACL,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAA0C,UAAU,EAAE,MAAM,YAAY,CAAC;AAEhF;;;;;;;;GAQG;AACH,MAAM,iBAAiB,GAAG,KAAK,EAC7B,QAAgB,EAChB,IAA0B,EAC1B,EAAE;IACF,MAAM,EACJ,cAAc,EAAE,CAAC,aAAa,CAAC,EAC/B,SAAS,EACT,UAAU,EACV,eAAe,GAChB,GAAG,IAAI,CAAC;IACT,MAAM,EACJ,KAAK,EAAE,EAAE,UAAU,EAAE,GACtB,GAAG,aAAa,CAAC;IAElB,0EAA0E;IAC1E,MAAM,eAAe,GAAG,UAAU;QAChC,CAAC,CAAC,qBAAqB;YACrB,eAAe,CAAC,MAAM;QACxB,CAAC,CAAC,mBAAmB;YACnB,eAAe,CAAC,IAAI,CAAC;IAEzB,MAAM,eAAe,GAAG,2BAA2B,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAE3E,8DAA8D;IAC9D,4CAA4C;IAC5C,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IACD,MAAM,MAAM,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAC;IACjD,8DAA8D;IAC9D,4CAA4C;IAC5C;;OAEG;IACH,MAAM,uBAAuB,GAAG;QAC9B,OAAO,EAAE,kBAAkB,CAAC,UAAU,CAAC;QACvC,IAAI,EAAE,eAAe,CAAC,OAAO;QAC7B,EAAE,EACA,MAAM,CAAC,kBAAkB,IAAI,4CAA4C,EAAE,8BAA8B;QAC3G,IAAI,EAAE,KAAK,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,+DAA+D;QACjG,KAAK,EAAE,KAAK;QACZ,GAAG,EAAE,QAAQ,EAAE,mCAAmC;QAClD,QAAQ,EAAE,YAAY,EAAE,qEAAqE;KAC9F,CAAC;IAEF,MAAM,aAAa,GAAG,MAAM,uBAAuB,CACjD,SAAS,EACT,uBAAuB,EACvB;QACE,eAAe,EAAE,KAAK;QACtB,eAAe;QACf,IAAI,EAAE,eAAe;KACtB,CACF,CAAC;IACF,OAAO,aAAa,CAAC;AACvB,CAAC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,kBAAkB,GAAG,KAAK,EAAE,IAAkC,EAAE,EAAE;IACtE,MAAM,EACJ,cAAc,EAAE,CAAC,aAAa,CAAC,EAC/B,SAAS,EACT,eAAe,EACf,QAAQ,EACR,OAAO,EACP,gBAAgB,GACjB,GAAG,IAAI,CAAC;IACT,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,aAAa,CAAC,KAAK,CAAC;IAEtD,MAAM,MAAM,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC;QACvC,SAAS;QACT,cAAc,EAAE,eAAe,CAAC,OAAO;QACvC,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC,CAAC;IAEH,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,eAAe,CAAC;QACrD,MAAM,EAAE;YACN,UAAU;YACV,OAAO,EAAE,SAAS;YAClB,SAAS;YACT,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,WAAW,EAAE,eAAe,CAAC,OAAO;YACpC,YAAY,EAAE,MAAM,CAAC,QAAQ;SAC9B;QACD,QAAQ;QACR,GAAG,EAAE,MAAM,MAAM,CAAC,SAAS,CAAC;QAC5B,OAAO;QACP,gBAAgB;KACjB,CAAC,CAAC;IAEH,OAAO;QACL,QAAQ;QACR,WAAW,EAAE,MAAM;KACpB,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,mBAAmB,CACxC,IAAkC;IAElC,kCAAkC;IAClC,MAAM,cAAc,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACtD,MAAM,YAAY,GAAG,cAAc,EAAE,EAAE,CAAC;IACxC,YAAY,IAAI,CAAC,MAAM,qBAAqB,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC;IAE5E,qDAAqD;IAErD,4CAA4C;IAC5C,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAEjE,wDAAwD;IACxD,MAAM,eAAe,GAAG,MAAM,iBAAiB,CAAC,QAAQ,EAAE;QACxD,GAAG,IAAI;QACP,eAAe,EAAE,KAAK;QACtB,YAAY,EAAE,KAAK;KACpB,CAAC,CAAC;IAEH,uFAAuF;IACvF,MAAM;QACJ,IAAI,EAAE,UAAU,CAAC,YAAY;QAC7B,OAAO,EAAE;YACP,SAAS,EAAE;gBACT,GAAG,eAAe;gBAClB,0DAA0D;gBAC1D,MAAM,EAAE,uCAAuC,CAAC,WAAW,CAAC;aAC7D;SACF;KACF,CAAC;IAEF,sDAAsD;IACtD,MAAM;QACJ,IAAI,EAAE,UAAU,CAAC,cAAc;QAC/B,OAAO,EAAE;YACP,yDAAyD;YACzD,UAAU,EAAE,QAAQ;YACpB,YAAY,EAAE;gBACZ,EAAE,EAAE,eAAe,EAAE,EAAE;aACxB;YACD,YAAY;YACZ,uDAAuD;YACvD,qBAAqB,EAAE,eAAe,EAAE,EAAE;YAC1C,aAAa,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;SACtC;KACF,CAAC;IAEF,qDAAqD;IACrD,MAAM;QACJ,IAAI,EAAE,UAAU,CAAC,YAAY;QAC7B,OAAO,EAAE;YACP,UAAU,EAAE,QAAQ;SACrB;KACF,CAAC;AACJ,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/explicit-function-return-type */\nimport {\n formatChainIdToHex,\n isEvmTxData,\n TxData,\n} from '@metamask/bridge-controller';\nimport { TransactionType } from '@metamask/transaction-controller';\n\nimport { getJwt } from '../utils/authentication.js';\nimport {\n getIntentFromQuote,\n mapIntentOrderStatusToTransactionStatus,\n postSubmitOrder,\n} from '../utils/intent-api.js';\nimport { signTypedMessage } from '../utils/keyring.js';\nimport { getNetworkClientIdByChainId } from '../utils/network.js';\nimport {\n addSyntheticTransaction,\n waitForTxConfirmation,\n} from '../utils/transaction.js';\nimport { handleEvmApprovals } from './evm-strategy.js';\nimport { SubmitStrategyParams, SubmitStepResult, SubmitStep } from './types.js';\n\n/**\n * Submits a synthetic EVM transaction to the TransactionController in order to display the intent order's\n * status in theclients, before the actual transaction is finalized on chain. The resulting transaction\n * is only available locally and is not submitted to the chain.\n *\n * @param orderUid - The order uid of the intent transaction\n * @param args - The parameters for the transaction\n * @returns The tradeMeta for the synthetic transaction\n */\nconst handleSyntheticTx = async (\n orderUid: string,\n args: SubmitStrategyParams,\n) => {\n const {\n quoteResponses: [quoteResponse],\n messenger,\n isBridgeTx,\n selectedAccount,\n } = args;\n const {\n quote: { srcChainId },\n } = quoteResponse;\n\n // Determine transaction type: swap for same-chain, bridge for cross-chain\n const transactionType = isBridgeTx\n ? /* c8 ignore start */\n TransactionType.bridge\n : /* c8 ignore end */\n TransactionType.swap;\n\n const networkClientId = getNetworkClientIdByChainId(messenger, srcChainId);\n\n // This is a synthetic transaction whose purpose is to be able\n // to track the order status via the history\n if (!isEvmTxData(quoteResponse.trade)) {\n throw new Error('Failed to submit intent: trade is not an EVM transaction');\n }\n const intent = getIntentFromQuote(quoteResponse);\n // This is a synthetic transaction whose purpose is to be able\n // to track the order status via the history\n /**\n * @deprecated use trade data from quote response instead\n */\n const intentTransactionParams = {\n chainId: formatChainIdToHex(srcChainId),\n from: selectedAccount.address,\n to:\n intent.settlementContract ?? '0x9008D19f58AAbd9eD0D60971565AA8510560ab41', // Default settlement contract\n data: `0x${orderUid?.slice(-8)}`, // Use last 8 chars of orderUid to make each transaction unique\n value: '0x0',\n gas: '0x5208', // Minimal gas for display purposes\n gasPrice: '0x3b9aca00', // 1 Gwei - will be converted to EIP-1559 fees if network supports it\n };\n\n const initialTxMeta = await addSyntheticTransaction(\n messenger,\n intentTransactionParams,\n {\n requireApproval: false,\n networkClientId,\n type: transactionType,\n },\n );\n return initialTxMeta;\n};\n\n/**\n * Submits batched EVM transactions to the TransactionController\n *\n * @param args - The parameters for the transaction\n * @param args.quoteResponse - The quote response\n * @param args.messenger - The messenger\n * @param args.selectedAccount - The selected account\n * @param args.traceFn - The trace function\n * @param args.isBridgeTx - Whether the transaction is a bridge transaction\n * @returns The approvalTxId and tradeMeta for the non-EVM transaction\n */\nconst handleSubmitIntent = async (args: SubmitStrategyParams<TxData>) => {\n const {\n quoteResponses: [quoteResponse],\n messenger,\n selectedAccount,\n clientId,\n fetchFn,\n bridgeApiBaseUrl,\n } = args;\n const { srcChainId, requestId } = quoteResponse.quote;\n\n const intent = getIntentFromQuote(quoteResponse);\n const signature = await signTypedMessage({\n messenger,\n accountAddress: selectedAccount.address,\n typedData: intent.typedData,\n });\n\n const { id: orderUid, status } = await postSubmitOrder({\n params: {\n srcChainId,\n quoteId: requestId,\n signature,\n order: intent.order,\n userAddress: selectedAccount.address,\n aggregatorId: intent.protocol,\n },\n clientId,\n jwt: await getJwt(messenger),\n fetchFn,\n bridgeApiBaseUrl,\n });\n\n return {\n orderUid,\n orderStatus: status,\n };\n};\n\n/**\n * Submits an approval tx to the TransactionController,\n * posts an intent order to the bridge-api,\n * and creates a synthetic transaction in the TransactionController\n *\n * @param args - The parameters for the transaction\n * @param args.quoteResponse - The quote response\n * @param args.messenger - The messenger\n * @param args.selectedAccount - The selected account\n * @param args.traceFn - The trace function\n * @param args.isBridgeTx - Whether the transaction is a bridge transaction\n * @yields The approvalTxId and tradeMeta for the intent transaction\n */\nexport async function* submitIntentHandler(\n args: SubmitStrategyParams<TxData>,\n): AsyncGenerator<SubmitStepResult, void, void> {\n // TODO handle STX/batch approvals\n const approvalTxMeta = await handleEvmApprovals(args);\n const approvalTxId = approvalTxMeta?.id;\n approvalTxId && (await waitForTxConfirmation(args.messenger, approvalTxId));\n\n // TODO add to history after approval tx is confirmed\n\n // Submit the intent order to the bridge-api\n const { orderUid, orderStatus } = await handleSubmitIntent(args);\n\n // Initialize a transaction in the TransactionController\n const syntheticTxMeta = await handleSyntheticTx(orderUid, {\n ...args,\n requireApproval: false,\n isStxEnabled: false,\n });\n\n // Use synthetic transaction metadata + translated intent order status as the tradeMeta\n yield {\n type: SubmitStep.SetTradeMeta,\n payload: {\n tradeMeta: {\n ...syntheticTxMeta,\n // Map intent order status to TransactionController status\n status: mapIntentOrderStatusToTransactionStatus(orderStatus),\n },\n },\n };\n\n // Update txHistory with synthetic txMeta and order id\n yield {\n type: SubmitStep.AddHistoryItem,\n payload: {\n // Use orderId as the history key for intent transactions\n historyKey: orderUid,\n bridgeTxMeta: {\n id: syntheticTxMeta?.id,\n },\n approvalTxId,\n // Keep original txId for TransactionController updates\n originalTransactionId: syntheticTxMeta?.id,\n quoteResponse: args.quoteResponses[0],\n },\n };\n\n // Start polling using the orderId as the history key\n yield {\n type: SubmitStep.StartPolling,\n payload: {\n historyKey: orderUid,\n },\n };\n}\n"]}
|