@metamask/bridge-status-controller 71.2.1 → 72.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 +40 -1
- package/dist/bridge-status-controller-method-action-types.cjs.map +1 -1
- package/dist/bridge-status-controller-method-action-types.d.cts +5 -1
- package/dist/bridge-status-controller-method-action-types.d.cts.map +1 -1
- package/dist/bridge-status-controller-method-action-types.d.mts +5 -1
- package/dist/bridge-status-controller-method-action-types.d.mts.map +1 -1
- package/dist/bridge-status-controller-method-action-types.mjs.map +1 -1
- package/dist/bridge-status-controller.cjs +161 -366
- package/dist/bridge-status-controller.cjs.map +1 -1
- package/dist/bridge-status-controller.d.cts +27 -7
- package/dist/bridge-status-controller.d.cts.map +1 -1
- package/dist/bridge-status-controller.d.mts +27 -7
- package/dist/bridge-status-controller.d.mts.map +1 -1
- package/dist/bridge-status-controller.mjs +162 -370
- package/dist/bridge-status-controller.mjs.map +1 -1
- package/dist/index.cjs +4 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +1 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -1
- package/dist/strategy/batch-sell-strategy.cjs +103 -0
- package/dist/strategy/batch-sell-strategy.cjs.map +1 -0
- package/dist/strategy/batch-sell-strategy.d.cts +10 -0
- package/dist/strategy/batch-sell-strategy.d.cts.map +1 -0
- package/dist/strategy/batch-sell-strategy.d.mts +10 -0
- package/dist/strategy/batch-sell-strategy.d.mts.map +1 -0
- package/dist/strategy/batch-sell-strategy.mjs +99 -0
- package/dist/strategy/batch-sell-strategy.mjs.map +1 -0
- package/dist/strategy/batch-strategy.cjs +74 -0
- package/dist/strategy/batch-strategy.cjs.map +1 -0
- package/dist/strategy/batch-strategy.d.cts +10 -0
- package/dist/strategy/batch-strategy.d.cts.map +1 -0
- package/dist/strategy/batch-strategy.d.mts +10 -0
- package/dist/strategy/batch-strategy.d.mts.map +1 -0
- package/dist/strategy/batch-strategy.mjs +70 -0
- package/dist/strategy/batch-strategy.mjs.map +1 -0
- package/dist/strategy/evm-strategy.cjs +149 -0
- package/dist/strategy/evm-strategy.cjs.map +1 -0
- package/dist/strategy/evm-strategy.d.cts +38 -0
- package/dist/strategy/evm-strategy.d.cts.map +1 -0
- package/dist/strategy/evm-strategy.d.mts +38 -0
- package/dist/strategy/evm-strategy.d.mts.map +1 -0
- package/dist/strategy/evm-strategy.mjs +143 -0
- package/dist/strategy/evm-strategy.mjs.map +1 -0
- package/dist/strategy/index.cjs +70 -0
- package/dist/strategy/index.cjs.map +1 -0
- package/dist/strategy/index.d.cts +12 -0
- package/dist/strategy/index.d.cts.map +1 -0
- package/dist/strategy/index.d.mts +12 -0
- package/dist/strategy/index.d.mts.map +1 -0
- package/dist/strategy/index.mjs +68 -0
- package/dist/strategy/index.mjs.map +1 -0
- package/dist/strategy/intent-strategy.cjs +160 -0
- package/dist/strategy/intent-strategy.cjs.map +1 -0
- package/dist/strategy/intent-strategy.d.cts +17 -0
- package/dist/strategy/intent-strategy.d.cts.map +1 -0
- package/dist/strategy/intent-strategy.d.mts +17 -0
- package/dist/strategy/intent-strategy.d.mts.map +1 -0
- package/dist/strategy/intent-strategy.mjs +156 -0
- package/dist/strategy/intent-strategy.mjs.map +1 -0
- package/dist/strategy/non-evm-strategy.cjs +80 -0
- package/dist/strategy/non-evm-strategy.cjs.map +1 -0
- package/dist/strategy/non-evm-strategy.d.cts +15 -0
- package/dist/strategy/non-evm-strategy.d.cts.map +1 -0
- package/dist/strategy/non-evm-strategy.d.mts +15 -0
- package/dist/strategy/non-evm-strategy.d.mts.map +1 -0
- package/dist/strategy/non-evm-strategy.mjs +76 -0
- package/dist/strategy/non-evm-strategy.mjs.map +1 -0
- package/dist/strategy/types.cjs +13 -0
- package/dist/strategy/types.cjs.map +1 -0
- package/dist/strategy/types.d.cts +77 -0
- package/dist/strategy/types.d.cts.map +1 -0
- package/dist/strategy/types.d.mts +77 -0
- package/dist/strategy/types.d.mts.map +1 -0
- package/dist/strategy/types.mjs +10 -0
- package/dist/strategy/types.mjs.map +1 -0
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +41 -6
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +41 -6
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/bridge.cjs +5 -1
- package/dist/utils/bridge.cjs.map +1 -1
- package/dist/utils/bridge.d.cts +2 -2
- package/dist/utils/bridge.d.cts.map +1 -1
- package/dist/utils/bridge.d.mts +2 -2
- package/dist/utils/bridge.d.mts.map +1 -1
- package/dist/utils/bridge.mjs +3 -0
- package/dist/utils/bridge.mjs.map +1 -1
- package/dist/utils/history.cjs +72 -20
- package/dist/utils/history.cjs.map +1 -1
- package/dist/utils/history.d.cts +19 -5
- package/dist/utils/history.d.cts.map +1 -1
- package/dist/utils/history.d.mts +19 -5
- package/dist/utils/history.d.mts.map +1 -1
- package/dist/utils/history.mjs +69 -19
- package/dist/utils/history.mjs.map +1 -1
- package/dist/utils/metrics.cjs +10 -7
- package/dist/utils/metrics.cjs.map +1 -1
- package/dist/utils/metrics.d.cts +7 -6
- package/dist/utils/metrics.d.cts.map +1 -1
- package/dist/utils/metrics.d.mts +7 -6
- package/dist/utils/metrics.d.mts.map +1 -1
- package/dist/utils/metrics.mjs +10 -7
- package/dist/utils/metrics.mjs.map +1 -1
- package/dist/utils/trace.cjs +4 -4
- package/dist/utils/trace.cjs.map +1 -1
- package/dist/utils/trace.d.cts +2 -2
- package/dist/utils/trace.d.cts.map +1 -1
- package/dist/utils/trace.d.mts +2 -2
- package/dist/utils/trace.d.mts.map +1 -1
- package/dist/utils/trace.mjs +4 -4
- package/dist/utils/trace.mjs.map +1 -1
- package/dist/utils/transaction.cjs +222 -253
- package/dist/utils/transaction.cjs.map +1 -1
- package/dist/utils/transaction.d.cts +68 -147
- package/dist/utils/transaction.d.cts.map +1 -1
- package/dist/utils/transaction.d.mts +68 -147
- package/dist/utils/transaction.d.mts.map +1 -1
- package/dist/utils/transaction.mjs +213 -248
- package/dist/utils/transaction.mjs.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/* eslint-disable consistent-return */
|
|
2
|
+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
3
|
+
import { formatChainIdToHex, isEvmTxData } from "@metamask/bridge-controller";
|
|
4
|
+
import { TransactionType } from "@metamask/transaction-controller";
|
|
5
|
+
import { getAccountByAddress } from "../utils/accounts.mjs";
|
|
6
|
+
import { getNetworkClientIdByChainId } from "../utils/network.mjs";
|
|
7
|
+
import { getApprovalTraceParams } from "../utils/trace.mjs";
|
|
8
|
+
import { addTransaction, generateActionId, handleApprovalDelay, handleMobileHardwareWalletDelay, toTransactionParams, waitForTxConfirmation } from "../utils/transaction.mjs";
|
|
9
|
+
import { SubmitStep } from "./types.mjs";
|
|
10
|
+
/**
|
|
11
|
+
* Submits a single tx to the TransactionController and returns the txMetaId
|
|
12
|
+
*
|
|
13
|
+
* @param args - The parameters for the transaction
|
|
14
|
+
* @param args.transactionType - The type of transaction to submit
|
|
15
|
+
* @param args.trade - The trade data to confirm
|
|
16
|
+
* @param args.requireApproval - Whether to require approval for the transaction
|
|
17
|
+
* @param args.txFee - Optional gas fee parameters from the quote (used when gasIncluded is true)
|
|
18
|
+
* @param args.txFee.maxFeePerGas - The maximum fee per gas from the quote
|
|
19
|
+
* @param args.txFee.maxPriorityFeePerGas - The maximum priority fee per gas from the quote
|
|
20
|
+
* @param args.actionId - Optional actionId for pre-submission history (if not provided, one is generated)
|
|
21
|
+
* @param args.messenger - The messenger to use for the transaction
|
|
22
|
+
* @returns The transaction meta
|
|
23
|
+
*/
|
|
24
|
+
export const handleSingleTx = async ({ messenger, trade, transactionType, requireApproval = false, txFee,
|
|
25
|
+
// Use provided actionId (for pre-submission history) or generate one
|
|
26
|
+
actionId = generateActionId(), }) => {
|
|
27
|
+
const selectedAccount = getAccountByAddress(messenger, trade.from);
|
|
28
|
+
if (!selectedAccount) {
|
|
29
|
+
throw new Error('Failed to submit cross-chain swap transaction: unknown account in trade data');
|
|
30
|
+
}
|
|
31
|
+
const hexChainId = formatChainIdToHex(trade.chainId);
|
|
32
|
+
const networkClientId = getNetworkClientIdByChainId(messenger, hexChainId);
|
|
33
|
+
const requestOptions = {
|
|
34
|
+
actionId,
|
|
35
|
+
networkClientId,
|
|
36
|
+
requireApproval,
|
|
37
|
+
type: transactionType,
|
|
38
|
+
origin: 'metamask',
|
|
39
|
+
isInternal: true,
|
|
40
|
+
};
|
|
41
|
+
const transactionParamsWithMaxGas = await toTransactionParams(messenger, trade, networkClientId, hexChainId, txFee);
|
|
42
|
+
return await addTransaction(messenger, { ...transactionParamsWithMaxGas, from: trade.from }, requestOptions);
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Submits the approval and resetApproval transactions through the TransactionController.
|
|
46
|
+
* If there is a resetApproval, it will be submitted first.
|
|
47
|
+
* But only the approval's txMetaId will be returned.
|
|
48
|
+
*
|
|
49
|
+
* @param args - The parameters for the submission flow
|
|
50
|
+
*
|
|
51
|
+
* @returns The approvalTxId of the approval transaction
|
|
52
|
+
*/
|
|
53
|
+
const approve = async (args) => {
|
|
54
|
+
const { quoteResponses: [quoteResponse], isBridgeTx, } = args;
|
|
55
|
+
const { approval, resetApproval } = quoteResponse;
|
|
56
|
+
if (!approval || !isEvmTxData(approval)) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
const transactionType = isBridgeTx
|
|
60
|
+
? TransactionType.bridgeApproval
|
|
61
|
+
: TransactionType.swapApproval;
|
|
62
|
+
if (resetApproval) {
|
|
63
|
+
await handleSingleTx({
|
|
64
|
+
...args,
|
|
65
|
+
transactionType,
|
|
66
|
+
trade: resetApproval,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
if (approval) {
|
|
70
|
+
const approvalTxMeta = await handleSingleTx({
|
|
71
|
+
...args,
|
|
72
|
+
transactionType,
|
|
73
|
+
trade: approval,
|
|
74
|
+
});
|
|
75
|
+
return approvalTxMeta?.id;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
export const handleEvmApprovals = async (args) => await args.traceFn(getApprovalTraceParams(args.quoteResponses[0], args.isStxEnabled), async () => await approve(args));
|
|
79
|
+
/**
|
|
80
|
+
* Sequentially submits EVM resetApproval, approval and trade transactions through the TransactionController.
|
|
81
|
+
*
|
|
82
|
+
* @param args - The parameters for the transaction
|
|
83
|
+
* @yields Data for updating the BridgeStatusController
|
|
84
|
+
*/
|
|
85
|
+
export async function* submitEvmHandler(args) {
|
|
86
|
+
const { quoteResponses: [quoteResponse], requireApproval, isBridgeTx, } = args;
|
|
87
|
+
// Submit resetApproval and approval transactions if present
|
|
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
|
|
100
|
+
const actionId = generateActionId();
|
|
101
|
+
// Add pre-submission history keyed by actionId
|
|
102
|
+
// This ensures we have quote data available if transaction fails during submission
|
|
103
|
+
yield {
|
|
104
|
+
type: SubmitStep.AddHistoryItem,
|
|
105
|
+
payload: {
|
|
106
|
+
historyKey: actionId,
|
|
107
|
+
approvalTxId,
|
|
108
|
+
actionId,
|
|
109
|
+
quoteResponse,
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
const transactionType = isBridgeTx
|
|
113
|
+
? TransactionType.bridge
|
|
114
|
+
: TransactionType.swap;
|
|
115
|
+
const tradeMeta = await handleSingleTx({
|
|
116
|
+
...args,
|
|
117
|
+
transactionType,
|
|
118
|
+
trade: quoteResponse.trade,
|
|
119
|
+
// TODO figure out if this is needed
|
|
120
|
+
// Pass txFee when gasIncluded is true to use the quote's gas fees
|
|
121
|
+
// instead of re-estimating (which would fail for max native token swaps)
|
|
122
|
+
txFee: quoteResponse.quote.gasIncluded
|
|
123
|
+
? quoteResponse.quote.feeData.txFee
|
|
124
|
+
: undefined,
|
|
125
|
+
actionId,
|
|
126
|
+
});
|
|
127
|
+
// Use the tradeMeta's id as history key
|
|
128
|
+
yield {
|
|
129
|
+
type: SubmitStep.RekeyHistoryItem,
|
|
130
|
+
payload: {
|
|
131
|
+
oldHistoryKey: actionId,
|
|
132
|
+
newHistoryKey: tradeMeta.id,
|
|
133
|
+
tradeMeta,
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
yield {
|
|
137
|
+
type: SubmitStep.SetTradeMeta,
|
|
138
|
+
payload: {
|
|
139
|
+
tradeMeta,
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=evm-strategy.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evm-strategy.mjs","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';\nimport { getAccountByAddress } from '../utils/accounts';\nimport { getNetworkClientIdByChainId } from '../utils/network';\nimport { getApprovalTraceParams } from '../utils/trace';\nimport {\n addTransaction,\n generateActionId,\n handleApprovalDelay,\n handleMobileHardwareWalletDelay,\n toTransactionParams,\n waitForTxConfirmation,\n} from '../utils/transaction';\nimport { SubmitStep } from './types';\nimport type { SubmitStrategyParams, SubmitStepResult } from './types';\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 undefined;\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"]}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
|
|
4
|
+
const bridge_controller_1 = require("@metamask/bridge-controller");
|
|
5
|
+
const batch_sell_strategy_1 = require("./batch-sell-strategy.cjs");
|
|
6
|
+
const batch_strategy_1 = require("./batch-strategy.cjs");
|
|
7
|
+
const evm_strategy_1 = require("./evm-strategy.cjs");
|
|
8
|
+
const intent_strategy_1 = require("./intent-strategy.cjs");
|
|
9
|
+
const non_evm_strategy_1 = require("./non-evm-strategy.cjs");
|
|
10
|
+
const validateParams = (params) => {
|
|
11
|
+
const txs = params.quoteResponses
|
|
12
|
+
.flatMap((quoteResponse) => [
|
|
13
|
+
quoteResponse.trade,
|
|
14
|
+
quoteResponse.approval,
|
|
15
|
+
quoteResponse.resetApproval,
|
|
16
|
+
])
|
|
17
|
+
.filter((tx) => tx !== undefined);
|
|
18
|
+
// Assumes all quotes are for the same chain
|
|
19
|
+
switch (params.quoteResponses[0].quote.srcChainId) {
|
|
20
|
+
case bridge_controller_1.ChainId.SOLANA:
|
|
21
|
+
return txs.every((tx) => typeof tx === 'string');
|
|
22
|
+
case bridge_controller_1.ChainId.BTC:
|
|
23
|
+
return txs.every(bridge_controller_1.isBitcoinTrade);
|
|
24
|
+
case bridge_controller_1.ChainId.TRON:
|
|
25
|
+
return txs.every(bridge_controller_1.isTronTrade);
|
|
26
|
+
default:
|
|
27
|
+
return txs.every(bridge_controller_1.isEvmTxData);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const validateBatchSellParams = (params) =>
|
|
31
|
+
// A BatchSell payload containing at least 1 trade is considered valid
|
|
32
|
+
Boolean(params.batchSellTrades) && params.quoteResponses.length >= 1;
|
|
33
|
+
/**
|
|
34
|
+
* Selects the appropriate submit strategy based on the quote parameters then executes it
|
|
35
|
+
*
|
|
36
|
+
* @param params - The parameters for the transaction
|
|
37
|
+
* @returns An async generator that yields results from each step of the submit flow. The yielded
|
|
38
|
+
* results are used to update the BridgeStatusController state and emit events.
|
|
39
|
+
*/
|
|
40
|
+
const executeSubmitStrategy = (params) => {
|
|
41
|
+
const { quoteResponses: [quoteResponse], isStxEnabled, isDelegatedAccount, } = params;
|
|
42
|
+
// Non-EVM transactions
|
|
43
|
+
if ((0, bridge_controller_1.isNonEvmChainId)(quoteResponse.quote.srcChainId)) {
|
|
44
|
+
if (!validateParams(params)) {
|
|
45
|
+
throw new Error('Failed to submit cross-chain swap transaction: trade is not a non-EVM transaction');
|
|
46
|
+
}
|
|
47
|
+
return (0, non_evm_strategy_1.submitNonEvmHandler)(params);
|
|
48
|
+
}
|
|
49
|
+
// EVM transactions
|
|
50
|
+
if (!validateParams(params)) {
|
|
51
|
+
throw new Error('Failed to submit cross-chain swap transaction: trade is not an EVM transaction');
|
|
52
|
+
}
|
|
53
|
+
// Intent transactions
|
|
54
|
+
if (quoteResponse.quote.intent) {
|
|
55
|
+
return (0, intent_strategy_1.submitIntentHandler)(params);
|
|
56
|
+
}
|
|
57
|
+
// Batch sell transactions
|
|
58
|
+
if (validateBatchSellParams(params)) {
|
|
59
|
+
return (0, batch_sell_strategy_1.submitBatchSellHandler)(params);
|
|
60
|
+
}
|
|
61
|
+
// Batched transactions
|
|
62
|
+
const shouldBatchTxs = isStxEnabled || quoteResponse.quote.gasIncluded7702 || isDelegatedAccount;
|
|
63
|
+
if (shouldBatchTxs) {
|
|
64
|
+
return (0, batch_strategy_1.submitBatchHandler)(params);
|
|
65
|
+
}
|
|
66
|
+
// Non-stx/gasless EVM transactions
|
|
67
|
+
return (0, evm_strategy_1.submitEvmHandler)(params);
|
|
68
|
+
};
|
|
69
|
+
exports.default = executeSubmitStrategy;
|
|
70
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../../src/strategy/index.ts"],"names":[],"mappings":";;AAAA,iEAAiE;AACjE,mEAWqC;AAErC,mEAA+D;AAC/D,yDAAsD;AACtD,qDAA0E;AAC1E,2DAAwD;AACxD,6DAAyD;AAGzD,MAAM,cAAc,GAAG,CAGrB,MAAmC,EACS,EAAE;IAC9C,MAAM,GAAG,GAAG,MAAM,CAAC,cAAc;SAC9B,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC;QAC1B,aAAa,CAAC,KAAK;QACnB,aAAa,CAAC,QAAQ;QACtB,aAAa,CAAC,aAAa;KAC5B,CAAC;SACD,MAAM,CAAC,CAAC,EAAE,EAAoB,EAAE,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;IAEtD,4CAA4C;IAC5C,QAAQ,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;QAClD,KAAK,2BAAO,CAAC,MAAM;YACjB,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,KAAK,QAAQ,CAAC,CAAC;QACnD,KAAK,2BAAO,CAAC,GAAG;YACd,OAAO,GAAG,CAAC,KAAK,CAAC,kCAAc,CAAC,CAAC;QACnC,KAAK,2BAAO,CAAC,IAAI;YACf,OAAO,GAAG,CAAC,KAAK,CAAC,+BAAW,CAAC,CAAC;QAChC;YACE,OAAO,GAAG,CAAC,KAAK,CAAC,+BAAW,CAAC,CAAC;IAClC,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,uBAAuB,GAAG,CAC9B,MAA4B,EACqC,EAAE;AACnE,sEAAsE;AACtE,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,MAAM,CAAC,cAAc,CAAC,MAAM,IAAI,CAAC,CAAC;AAEvE;;;;;;GAMG;AACH,MAAM,qBAAqB,GAAG,CAC5B,MAAmC,EACW,EAAE;IAChD,MAAM,EACJ,cAAc,EAAE,CAAC,aAAa,CAAC,EAC/B,YAAY,EACZ,kBAAkB,GACnB,GAAG,MAAM,CAAC;IAEX,uBAAuB;IACvB,IAAI,IAAA,mCAAe,EAAC,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;QACpD,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CACb,mFAAmF,CACpF,CAAC;QACJ,CAAC;QACD,OAAO,IAAA,sCAAmB,EAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAED,mBAAmB;IACnB,IAAI,CAAC,cAAc,CAAS,MAAM,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CACb,gFAAgF,CACjF,CAAC;IACJ,CAAC;IAED,sBAAsB;IACtB,IAAI,aAAa,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAC/B,OAAO,IAAA,qCAAmB,EAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAED,0BAA0B;IAC1B,IAAI,uBAAuB,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,OAAO,IAAA,4CAAsB,EAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAED,uBAAuB;IACvB,MAAM,cAAc,GAClB,YAAY,IAAI,aAAa,CAAC,KAAK,CAAC,eAAe,IAAI,kBAAkB,CAAC;IAC5E,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO,IAAA,mCAAkB,EAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAED,mCAAmC;IACnC,OAAO,IAAA,+BAAoB,EAAC,MAAM,CAAC,CAAC;AACtC,CAAC,CAAC;AAEF,kBAAe,qBAAqB,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */\nimport {\n BatchSellTradesResponse,\n BitcoinTradeData,\n ChainId,\n isBitcoinTrade,\n isEvmTxData,\n isNonEvmChainId,\n isTronTrade,\n Trade,\n TronTradeData,\n TxData,\n} from '@metamask/bridge-controller';\n\nimport { submitBatchSellHandler } from './batch-sell-strategy';\nimport { submitBatchHandler } from './batch-strategy';\nimport { submitEvmHandler as defaultSubmitHandler } from './evm-strategy';\nimport { submitIntentHandler } from './intent-strategy';\nimport { submitNonEvmHandler } from './non-evm-strategy';\nimport type { SubmitStrategyParams, SubmitStepResult } from './types';\n\nconst validateParams = <\n TxDataType extends BitcoinTradeData | TronTradeData | string | TxData,\n>(\n params: SubmitStrategyParams<Trade>,\n): params is SubmitStrategyParams<TxDataType> => {\n const txs = params.quoteResponses\n .flatMap((quoteResponse) => [\n quoteResponse.trade,\n quoteResponse.approval,\n quoteResponse.resetApproval,\n ])\n .filter((tx): tx is TxDataType => tx !== undefined);\n\n // Assumes all quotes are for the same chain\n switch (params.quoteResponses[0].quote.srcChainId) {\n case ChainId.SOLANA:\n return txs.every((tx) => typeof tx === 'string');\n case ChainId.BTC:\n return txs.every(isBitcoinTrade);\n case ChainId.TRON:\n return txs.every(isTronTrade);\n default:\n return txs.every(isEvmTxData);\n }\n};\n\nconst validateBatchSellParams = (\n params: SubmitStrategyParams,\n): params is SubmitStrategyParams<TxData, BatchSellTradesResponse> =>\n // A BatchSell payload containing at least 1 trade is considered valid\n Boolean(params.batchSellTrades) && params.quoteResponses.length >= 1;\n\n/**\n * Selects the appropriate submit strategy based on the quote parameters then executes it\n *\n * @param params - The parameters for the transaction\n * @returns An async generator that yields results from each step of the submit flow. The yielded\n * results are used to update the BridgeStatusController state and emit events.\n */\nconst executeSubmitStrategy = (\n params: SubmitStrategyParams<Trade>,\n): AsyncGenerator<SubmitStepResult, void, void> => {\n const {\n quoteResponses: [quoteResponse],\n isStxEnabled,\n isDelegatedAccount,\n } = params;\n\n // Non-EVM transactions\n if (isNonEvmChainId(quoteResponse.quote.srcChainId)) {\n if (!validateParams(params)) {\n throw new Error(\n 'Failed to submit cross-chain swap transaction: trade is not a non-EVM transaction',\n );\n }\n return submitNonEvmHandler(params);\n }\n\n // EVM transactions\n if (!validateParams<TxData>(params)) {\n throw new Error(\n 'Failed to submit cross-chain swap transaction: trade is not an EVM transaction',\n );\n }\n\n // Intent transactions\n if (quoteResponse.quote.intent) {\n return submitIntentHandler(params);\n }\n\n // Batch sell transactions\n if (validateBatchSellParams(params)) {\n return submitBatchSellHandler(params);\n }\n\n // Batched transactions\n const shouldBatchTxs =\n isStxEnabled || quoteResponse.quote.gasIncluded7702 || isDelegatedAccount;\n if (shouldBatchTxs) {\n return submitBatchHandler(params);\n }\n\n // Non-stx/gasless EVM transactions\n return defaultSubmitHandler(params);\n};\n\nexport default executeSubmitStrategy;\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Trade } from "@metamask/bridge-controller";
|
|
2
|
+
import type { SubmitStrategyParams, SubmitStepResult } from "./types.cjs";
|
|
3
|
+
/**
|
|
4
|
+
* Selects the appropriate submit strategy based on the quote parameters then executes it
|
|
5
|
+
*
|
|
6
|
+
* @param params - The parameters for the transaction
|
|
7
|
+
* @returns An async generator that yields results from each step of the submit flow. The yielded
|
|
8
|
+
* results are used to update the BridgeStatusController state and emit events.
|
|
9
|
+
*/
|
|
10
|
+
declare const executeSubmitStrategy: (params: SubmitStrategyParams<Trade>) => AsyncGenerator<SubmitStepResult, void, void>;
|
|
11
|
+
export default executeSubmitStrategy;
|
|
12
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../src/strategy/index.ts"],"names":[],"mappings":"AACA,OAAO,EAQL,KAAK,EAGN,oCAAoC;AAOrC,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,oBAAgB;AAkCtE;;;;;;GAMG;AACH,QAAA,MAAM,qBAAqB,WACjB,qBAAqB,KAAK,CAAC,KAClC,eAAe,gBAAgB,EAAE,IAAI,EAAE,IAAI,CA2C7C,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Trade } from "@metamask/bridge-controller";
|
|
2
|
+
import type { SubmitStrategyParams, SubmitStepResult } from "./types.mjs";
|
|
3
|
+
/**
|
|
4
|
+
* Selects the appropriate submit strategy based on the quote parameters then executes it
|
|
5
|
+
*
|
|
6
|
+
* @param params - The parameters for the transaction
|
|
7
|
+
* @returns An async generator that yields results from each step of the submit flow. The yielded
|
|
8
|
+
* results are used to update the BridgeStatusController state and emit events.
|
|
9
|
+
*/
|
|
10
|
+
declare const executeSubmitStrategy: (params: SubmitStrategyParams<Trade>) => AsyncGenerator<SubmitStepResult, void, void>;
|
|
11
|
+
export default executeSubmitStrategy;
|
|
12
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../src/strategy/index.ts"],"names":[],"mappings":"AACA,OAAO,EAQL,KAAK,EAGN,oCAAoC;AAOrC,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,oBAAgB;AAkCtE;;;;;;GAMG;AACH,QAAA,MAAM,qBAAqB,WACjB,qBAAqB,KAAK,CAAC,KAClC,eAAe,gBAAgB,EAAE,IAAI,EAAE,IAAI,CA2C7C,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
|
|
2
|
+
import { ChainId, isBitcoinTrade, isEvmTxData, isNonEvmChainId, isTronTrade } from "@metamask/bridge-controller";
|
|
3
|
+
import { submitBatchSellHandler } from "./batch-sell-strategy.mjs";
|
|
4
|
+
import { submitBatchHandler } from "./batch-strategy.mjs";
|
|
5
|
+
import { submitEvmHandler as defaultSubmitHandler } from "./evm-strategy.mjs";
|
|
6
|
+
import { submitIntentHandler } from "./intent-strategy.mjs";
|
|
7
|
+
import { submitNonEvmHandler } from "./non-evm-strategy.mjs";
|
|
8
|
+
const validateParams = (params) => {
|
|
9
|
+
const txs = params.quoteResponses
|
|
10
|
+
.flatMap((quoteResponse) => [
|
|
11
|
+
quoteResponse.trade,
|
|
12
|
+
quoteResponse.approval,
|
|
13
|
+
quoteResponse.resetApproval,
|
|
14
|
+
])
|
|
15
|
+
.filter((tx) => tx !== undefined);
|
|
16
|
+
// Assumes all quotes are for the same chain
|
|
17
|
+
switch (params.quoteResponses[0].quote.srcChainId) {
|
|
18
|
+
case ChainId.SOLANA:
|
|
19
|
+
return txs.every((tx) => typeof tx === 'string');
|
|
20
|
+
case ChainId.BTC:
|
|
21
|
+
return txs.every(isBitcoinTrade);
|
|
22
|
+
case ChainId.TRON:
|
|
23
|
+
return txs.every(isTronTrade);
|
|
24
|
+
default:
|
|
25
|
+
return txs.every(isEvmTxData);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const validateBatchSellParams = (params) =>
|
|
29
|
+
// A BatchSell payload containing at least 1 trade is considered valid
|
|
30
|
+
Boolean(params.batchSellTrades) && params.quoteResponses.length >= 1;
|
|
31
|
+
/**
|
|
32
|
+
* Selects the appropriate submit strategy based on the quote parameters then executes it
|
|
33
|
+
*
|
|
34
|
+
* @param params - The parameters for the transaction
|
|
35
|
+
* @returns An async generator that yields results from each step of the submit flow. The yielded
|
|
36
|
+
* results are used to update the BridgeStatusController state and emit events.
|
|
37
|
+
*/
|
|
38
|
+
const executeSubmitStrategy = (params) => {
|
|
39
|
+
const { quoteResponses: [quoteResponse], isStxEnabled, isDelegatedAccount, } = params;
|
|
40
|
+
// Non-EVM transactions
|
|
41
|
+
if (isNonEvmChainId(quoteResponse.quote.srcChainId)) {
|
|
42
|
+
if (!validateParams(params)) {
|
|
43
|
+
throw new Error('Failed to submit cross-chain swap transaction: trade is not a non-EVM transaction');
|
|
44
|
+
}
|
|
45
|
+
return submitNonEvmHandler(params);
|
|
46
|
+
}
|
|
47
|
+
// EVM transactions
|
|
48
|
+
if (!validateParams(params)) {
|
|
49
|
+
throw new Error('Failed to submit cross-chain swap transaction: trade is not an EVM transaction');
|
|
50
|
+
}
|
|
51
|
+
// Intent transactions
|
|
52
|
+
if (quoteResponse.quote.intent) {
|
|
53
|
+
return submitIntentHandler(params);
|
|
54
|
+
}
|
|
55
|
+
// Batch sell transactions
|
|
56
|
+
if (validateBatchSellParams(params)) {
|
|
57
|
+
return submitBatchSellHandler(params);
|
|
58
|
+
}
|
|
59
|
+
// Batched transactions
|
|
60
|
+
const shouldBatchTxs = isStxEnabled || quoteResponse.quote.gasIncluded7702 || isDelegatedAccount;
|
|
61
|
+
if (shouldBatchTxs) {
|
|
62
|
+
return submitBatchHandler(params);
|
|
63
|
+
}
|
|
64
|
+
// Non-stx/gasless EVM transactions
|
|
65
|
+
return defaultSubmitHandler(params);
|
|
66
|
+
};
|
|
67
|
+
export default executeSubmitStrategy;
|
|
68
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/strategy/index.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */\nimport {\n BatchSellTradesResponse,\n BitcoinTradeData,\n ChainId,\n isBitcoinTrade,\n isEvmTxData,\n isNonEvmChainId,\n isTronTrade,\n Trade,\n TronTradeData,\n TxData,\n} from '@metamask/bridge-controller';\n\nimport { submitBatchSellHandler } from './batch-sell-strategy';\nimport { submitBatchHandler } from './batch-strategy';\nimport { submitEvmHandler as defaultSubmitHandler } from './evm-strategy';\nimport { submitIntentHandler } from './intent-strategy';\nimport { submitNonEvmHandler } from './non-evm-strategy';\nimport type { SubmitStrategyParams, SubmitStepResult } from './types';\n\nconst validateParams = <\n TxDataType extends BitcoinTradeData | TronTradeData | string | TxData,\n>(\n params: SubmitStrategyParams<Trade>,\n): params is SubmitStrategyParams<TxDataType> => {\n const txs = params.quoteResponses\n .flatMap((quoteResponse) => [\n quoteResponse.trade,\n quoteResponse.approval,\n quoteResponse.resetApproval,\n ])\n .filter((tx): tx is TxDataType => tx !== undefined);\n\n // Assumes all quotes are for the same chain\n switch (params.quoteResponses[0].quote.srcChainId) {\n case ChainId.SOLANA:\n return txs.every((tx) => typeof tx === 'string');\n case ChainId.BTC:\n return txs.every(isBitcoinTrade);\n case ChainId.TRON:\n return txs.every(isTronTrade);\n default:\n return txs.every(isEvmTxData);\n }\n};\n\nconst validateBatchSellParams = (\n params: SubmitStrategyParams,\n): params is SubmitStrategyParams<TxData, BatchSellTradesResponse> =>\n // A BatchSell payload containing at least 1 trade is considered valid\n Boolean(params.batchSellTrades) && params.quoteResponses.length >= 1;\n\n/**\n * Selects the appropriate submit strategy based on the quote parameters then executes it\n *\n * @param params - The parameters for the transaction\n * @returns An async generator that yields results from each step of the submit flow. The yielded\n * results are used to update the BridgeStatusController state and emit events.\n */\nconst executeSubmitStrategy = (\n params: SubmitStrategyParams<Trade>,\n): AsyncGenerator<SubmitStepResult, void, void> => {\n const {\n quoteResponses: [quoteResponse],\n isStxEnabled,\n isDelegatedAccount,\n } = params;\n\n // Non-EVM transactions\n if (isNonEvmChainId(quoteResponse.quote.srcChainId)) {\n if (!validateParams(params)) {\n throw new Error(\n 'Failed to submit cross-chain swap transaction: trade is not a non-EVM transaction',\n );\n }\n return submitNonEvmHandler(params);\n }\n\n // EVM transactions\n if (!validateParams<TxData>(params)) {\n throw new Error(\n 'Failed to submit cross-chain swap transaction: trade is not an EVM transaction',\n );\n }\n\n // Intent transactions\n if (quoteResponse.quote.intent) {\n return submitIntentHandler(params);\n }\n\n // Batch sell transactions\n if (validateBatchSellParams(params)) {\n return submitBatchSellHandler(params);\n }\n\n // Batched transactions\n const shouldBatchTxs =\n isStxEnabled || quoteResponse.quote.gasIncluded7702 || isDelegatedAccount;\n if (shouldBatchTxs) {\n return submitBatchHandler(params);\n }\n\n // Non-stx/gasless EVM transactions\n return defaultSubmitHandler(params);\n};\n\nexport default executeSubmitStrategy;\n"]}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.submitIntentHandler = void 0;
|
|
4
|
+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
5
|
+
const bridge_controller_1 = require("@metamask/bridge-controller");
|
|
6
|
+
const transaction_controller_1 = require("@metamask/transaction-controller");
|
|
7
|
+
const authentication_1 = require("../utils/authentication.cjs");
|
|
8
|
+
const intent_api_1 = require("../utils/intent-api.cjs");
|
|
9
|
+
const keyring_1 = require("../utils/keyring.cjs");
|
|
10
|
+
const network_1 = require("../utils/network.cjs");
|
|
11
|
+
const transaction_1 = require("../utils/transaction.cjs");
|
|
12
|
+
const evm_strategy_1 = require("./evm-strategy.cjs");
|
|
13
|
+
const types_1 = require("./types.cjs");
|
|
14
|
+
/**
|
|
15
|
+
* Submits a synthetic EVM transaction to the TransactionController in order to display the intent order's
|
|
16
|
+
* status in theclients, before the actual transaction is finalized on chain. The resulting transaction
|
|
17
|
+
* is only available locally and is not submitted to the chain.
|
|
18
|
+
*
|
|
19
|
+
* @param orderUid - The order uid of the intent transaction
|
|
20
|
+
* @param args - The parameters for the transaction
|
|
21
|
+
* @returns The tradeMeta for the synthetic transaction
|
|
22
|
+
*/
|
|
23
|
+
const handleSyntheticTx = async (orderUid, args) => {
|
|
24
|
+
const { quoteResponses: [quoteResponse], messenger, isBridgeTx, selectedAccount, } = args;
|
|
25
|
+
const { quote: { srcChainId }, } = quoteResponse;
|
|
26
|
+
// Determine transaction type: swap for same-chain, bridge for cross-chain
|
|
27
|
+
const transactionType = isBridgeTx
|
|
28
|
+
? /* c8 ignore start */
|
|
29
|
+
transaction_controller_1.TransactionType.bridge
|
|
30
|
+
: /* c8 ignore end */
|
|
31
|
+
transaction_controller_1.TransactionType.swap;
|
|
32
|
+
const networkClientId = (0, network_1.getNetworkClientIdByChainId)(messenger, srcChainId);
|
|
33
|
+
// This is a synthetic transaction whose purpose is to be able
|
|
34
|
+
// to track the order status via the history
|
|
35
|
+
if (!(0, bridge_controller_1.isEvmTxData)(quoteResponse.trade)) {
|
|
36
|
+
throw new Error('Failed to submit intent: trade is not an EVM transaction');
|
|
37
|
+
}
|
|
38
|
+
const intent = (0, intent_api_1.getIntentFromQuote)(quoteResponse);
|
|
39
|
+
// This is a synthetic transaction whose purpose is to be able
|
|
40
|
+
// to track the order status via the history
|
|
41
|
+
/**
|
|
42
|
+
* @deprecated use trade data from quote response instead
|
|
43
|
+
*/
|
|
44
|
+
const intentTransactionParams = {
|
|
45
|
+
chainId: (0, bridge_controller_1.formatChainIdToHex)(srcChainId),
|
|
46
|
+
from: selectedAccount.address,
|
|
47
|
+
to: intent.settlementContract ?? '0x9008D19f58AAbd9eD0D60971565AA8510560ab41', // Default settlement contract
|
|
48
|
+
data: `0x${orderUid?.slice(-8)}`, // Use last 8 chars of orderUid to make each transaction unique
|
|
49
|
+
value: '0x0',
|
|
50
|
+
gas: '0x5208', // Minimal gas for display purposes
|
|
51
|
+
gasPrice: '0x3b9aca00', // 1 Gwei - will be converted to EIP-1559 fees if network supports it
|
|
52
|
+
};
|
|
53
|
+
const initialTxMeta = await (0, transaction_1.addSyntheticTransaction)(messenger, intentTransactionParams, {
|
|
54
|
+
requireApproval: false,
|
|
55
|
+
networkClientId,
|
|
56
|
+
type: transactionType,
|
|
57
|
+
});
|
|
58
|
+
return initialTxMeta;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Submits batched EVM transactions to the TransactionController
|
|
62
|
+
*
|
|
63
|
+
* @param args - The parameters for the transaction
|
|
64
|
+
* @param args.quoteResponse - The quote response
|
|
65
|
+
* @param args.messenger - The messenger
|
|
66
|
+
* @param args.selectedAccount - The selected account
|
|
67
|
+
* @param args.traceFn - The trace function
|
|
68
|
+
* @param args.isBridgeTx - Whether the transaction is a bridge transaction
|
|
69
|
+
* @returns The approvalTxId and tradeMeta for the non-EVM transaction
|
|
70
|
+
*/
|
|
71
|
+
const handleSubmitIntent = async (args) => {
|
|
72
|
+
const { quoteResponses: [quoteResponse], messenger, selectedAccount, clientId, fetchFn, bridgeApiBaseUrl, } = args;
|
|
73
|
+
const { srcChainId, requestId } = quoteResponse.quote;
|
|
74
|
+
const intent = (0, intent_api_1.getIntentFromQuote)(quoteResponse);
|
|
75
|
+
const signature = await (0, keyring_1.signTypedMessage)({
|
|
76
|
+
messenger,
|
|
77
|
+
accountAddress: selectedAccount.address,
|
|
78
|
+
typedData: intent.typedData,
|
|
79
|
+
});
|
|
80
|
+
const { id: orderUid, status } = await (0, intent_api_1.postSubmitOrder)({
|
|
81
|
+
params: {
|
|
82
|
+
srcChainId,
|
|
83
|
+
quoteId: requestId,
|
|
84
|
+
signature,
|
|
85
|
+
order: intent.order,
|
|
86
|
+
userAddress: selectedAccount.address,
|
|
87
|
+
aggregatorId: intent.protocol,
|
|
88
|
+
},
|
|
89
|
+
clientId,
|
|
90
|
+
jwt: await (0, authentication_1.getJwt)(messenger),
|
|
91
|
+
fetchFn,
|
|
92
|
+
bridgeApiBaseUrl,
|
|
93
|
+
});
|
|
94
|
+
return {
|
|
95
|
+
orderUid,
|
|
96
|
+
orderStatus: status,
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Submits an approval tx to the TransactionController,
|
|
101
|
+
* posts an intent order to the bridge-api,
|
|
102
|
+
* and creates a synthetic transaction in the TransactionController
|
|
103
|
+
*
|
|
104
|
+
* @param args - The parameters for the transaction
|
|
105
|
+
* @param args.quoteResponse - The quote response
|
|
106
|
+
* @param args.messenger - The messenger
|
|
107
|
+
* @param args.selectedAccount - The selected account
|
|
108
|
+
* @param args.traceFn - The trace function
|
|
109
|
+
* @param args.isBridgeTx - Whether the transaction is a bridge transaction
|
|
110
|
+
* @yields The approvalTxId and tradeMeta for the intent transaction
|
|
111
|
+
*/
|
|
112
|
+
async function* submitIntentHandler(args) {
|
|
113
|
+
// TODO handle STX/batch approvals
|
|
114
|
+
const approvalTxId = await (0, evm_strategy_1.handleEvmApprovals)(args);
|
|
115
|
+
approvalTxId && (await (0, transaction_1.waitForTxConfirmation)(args.messenger, approvalTxId));
|
|
116
|
+
// TODO add to history after approval tx is confirmed
|
|
117
|
+
// Submit the intent order to the bridge-api
|
|
118
|
+
const { orderUid, orderStatus } = await handleSubmitIntent(args);
|
|
119
|
+
// Initialize a transaction in the TransactionController
|
|
120
|
+
const syntheticTxMeta = await handleSyntheticTx(orderUid, {
|
|
121
|
+
...args,
|
|
122
|
+
requireApproval: false,
|
|
123
|
+
isStxEnabled: false,
|
|
124
|
+
});
|
|
125
|
+
// Use synthetic transaction metadata + translated intent order status as the tradeMeta
|
|
126
|
+
yield {
|
|
127
|
+
type: types_1.SubmitStep.SetTradeMeta,
|
|
128
|
+
payload: {
|
|
129
|
+
tradeMeta: {
|
|
130
|
+
...syntheticTxMeta,
|
|
131
|
+
// Map intent order status to TransactionController status
|
|
132
|
+
status: (0, intent_api_1.mapIntentOrderStatusToTransactionStatus)(orderStatus),
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
// Update txHistory with synthetic txMeta and order id
|
|
137
|
+
yield {
|
|
138
|
+
type: types_1.SubmitStep.AddHistoryItem,
|
|
139
|
+
payload: {
|
|
140
|
+
// Use orderId as the history key for intent transactions
|
|
141
|
+
historyKey: orderUid,
|
|
142
|
+
bridgeTxMeta: {
|
|
143
|
+
id: syntheticTxMeta?.id,
|
|
144
|
+
},
|
|
145
|
+
approvalTxId,
|
|
146
|
+
// Keep original txId for TransactionController updates
|
|
147
|
+
originalTransactionId: syntheticTxMeta?.id,
|
|
148
|
+
quoteResponse: args.quoteResponses[0],
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
// Start polling using the orderId as the history key
|
|
152
|
+
yield {
|
|
153
|
+
type: types_1.SubmitStep.StartPolling,
|
|
154
|
+
payload: {
|
|
155
|
+
historyKey: orderUid,
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
exports.submitIntentHandler = submitIntentHandler;
|
|
160
|
+
//# sourceMappingURL=intent-strategy.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent-strategy.cjs","sourceRoot":"","sources":["../../src/strategy/intent-strategy.ts"],"names":[],"mappings":";;;AAAA,qEAAqE;AACrE,mEAIqC;AACrC,6EAAmE;AAEnE,gEAAiD;AACjD,wDAI6B;AAC7B,kDAAoD;AACpD,kDAA+D;AAC/D,0DAG8B;AAC9B,qDAAoD;AACpD,uCAA6E;AAE7E;;;;;;;;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,wCAAe,CAAC,MAAM;QACxB,CAAC,CAAC,mBAAmB;YACnB,wCAAe,CAAC,IAAI,CAAC;IAEzB,MAAM,eAAe,GAAG,IAAA,qCAA2B,EAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAE3E,8DAA8D;IAC9D,4CAA4C;IAC5C,IAAI,CAAC,IAAA,+BAAW,EAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IACD,MAAM,MAAM,GAAG,IAAA,+BAAkB,EAAC,aAAa,CAAC,CAAC;IACjD,8DAA8D;IAC9D,4CAA4C;IAC5C;;OAEG;IACH,MAAM,uBAAuB,GAAG;QAC9B,OAAO,EAAE,IAAA,sCAAkB,EAAC,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,IAAA,qCAAuB,EACjD,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,IAAA,+BAAkB,EAAC,aAAa,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,MAAM,IAAA,0BAAgB,EAAC;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,IAAA,4BAAe,EAAC;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,IAAA,uBAAM,EAAC,SAAS,CAAC;QAC5B,OAAO;QACP,gBAAgB;KACjB,CAAC,CAAC;IAEH,OAAO;QACL,QAAQ;QACR,WAAW,EAAE,MAAM;KACpB,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACI,KAAK,SAAS,CAAC,CAAC,mBAAmB,CACxC,IAAkC;IAElC,kCAAkC;IAClC,MAAM,YAAY,GAAG,MAAM,IAAA,iCAAkB,EAAC,IAAI,CAAC,CAAC;IACpD,YAAY,IAAI,CAAC,MAAM,IAAA,mCAAqB,EAAC,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,kBAAU,CAAC,YAAY;QAC7B,OAAO,EAAE;YACP,SAAS,EAAE;gBACT,GAAG,eAAe;gBAClB,0DAA0D;gBAC1D,MAAM,EAAE,IAAA,oDAAuC,EAAC,WAAW,CAAC;aAC7D;SACF;KACF,CAAC;IAEF,sDAAsD;IACtD,MAAM;QACJ,IAAI,EAAE,kBAAU,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,kBAAU,CAAC,YAAY;QAC7B,OAAO,EAAE;YACP,UAAU,EAAE,QAAQ;SACrB;KACF,CAAC;AACJ,CAAC;AAtDD,kDAsDC","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';\nimport {\n getIntentFromQuote,\n mapIntentOrderStatusToTransactionStatus,\n postSubmitOrder,\n} from '../utils/intent-api';\nimport { signTypedMessage } from '../utils/keyring';\nimport { getNetworkClientIdByChainId } from '../utils/network';\nimport {\n addSyntheticTransaction,\n waitForTxConfirmation,\n} from '../utils/transaction';\nimport { handleEvmApprovals } from './evm-strategy';\nimport { SubmitStrategyParams, SubmitStepResult, SubmitStep } from './types';\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"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { TxData } from "@metamask/bridge-controller";
|
|
2
|
+
import { SubmitStrategyParams, SubmitStepResult } from "./types.cjs";
|
|
3
|
+
/**
|
|
4
|
+
* Submits an approval tx to the TransactionController,
|
|
5
|
+
* posts an intent order to the bridge-api,
|
|
6
|
+
* and creates a synthetic transaction in the TransactionController
|
|
7
|
+
*
|
|
8
|
+
* @param args - The parameters for the transaction
|
|
9
|
+
* @param args.quoteResponse - The quote response
|
|
10
|
+
* @param args.messenger - The messenger
|
|
11
|
+
* @param args.selectedAccount - The selected account
|
|
12
|
+
* @param args.traceFn - The trace function
|
|
13
|
+
* @param args.isBridgeTx - Whether the transaction is a bridge transaction
|
|
14
|
+
* @yields The approvalTxId and tradeMeta for the intent transaction
|
|
15
|
+
*/
|
|
16
|
+
export declare function submitIntentHandler(args: SubmitStrategyParams<TxData>): AsyncGenerator<SubmitStepResult, void, void>;
|
|
17
|
+
//# sourceMappingURL=intent-strategy.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent-strategy.d.cts","sourceRoot":"","sources":["../../src/strategy/intent-strategy.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,MAAM,EACP,oCAAoC;AAgBrC,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAc,oBAAgB;AAsH7E;;;;;;;;;;;;GAYG;AACH,wBAAuB,mBAAmB,CACxC,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC,GACjC,cAAc,CAAC,gBAAgB,EAAE,IAAI,EAAE,IAAI,CAAC,CAoD9C"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { TxData } from "@metamask/bridge-controller";
|
|
2
|
+
import { SubmitStrategyParams, SubmitStepResult } from "./types.mjs";
|
|
3
|
+
/**
|
|
4
|
+
* Submits an approval tx to the TransactionController,
|
|
5
|
+
* posts an intent order to the bridge-api,
|
|
6
|
+
* and creates a synthetic transaction in the TransactionController
|
|
7
|
+
*
|
|
8
|
+
* @param args - The parameters for the transaction
|
|
9
|
+
* @param args.quoteResponse - The quote response
|
|
10
|
+
* @param args.messenger - The messenger
|
|
11
|
+
* @param args.selectedAccount - The selected account
|
|
12
|
+
* @param args.traceFn - The trace function
|
|
13
|
+
* @param args.isBridgeTx - Whether the transaction is a bridge transaction
|
|
14
|
+
* @yields The approvalTxId and tradeMeta for the intent transaction
|
|
15
|
+
*/
|
|
16
|
+
export declare function submitIntentHandler(args: SubmitStrategyParams<TxData>): AsyncGenerator<SubmitStepResult, void, void>;
|
|
17
|
+
//# sourceMappingURL=intent-strategy.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent-strategy.d.mts","sourceRoot":"","sources":["../../src/strategy/intent-strategy.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,MAAM,EACP,oCAAoC;AAgBrC,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAc,oBAAgB;AAsH7E;;;;;;;;;;;;GAYG;AACH,wBAAuB,mBAAmB,CACxC,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC,GACjC,cAAc,CAAC,gBAAgB,EAAE,IAAI,EAAE,IAAI,CAAC,CAoD9C"}
|