@metamask/bridge-status-controller 69.0.0 → 70.0.0
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 +9 -1
- package/dist/bridge-status-controller.cjs +77 -192
- package/dist/bridge-status-controller.cjs.map +1 -1
- package/dist/bridge-status-controller.d.cts +1 -4
- package/dist/bridge-status-controller.d.cts.map +1 -1
- package/dist/bridge-status-controller.d.mts +1 -4
- package/dist/bridge-status-controller.d.mts.map +1 -1
- package/dist/bridge-status-controller.intent.cjs +6 -7
- package/dist/bridge-status-controller.intent.cjs.map +1 -1
- package/dist/bridge-status-controller.intent.d.cts +2 -5
- package/dist/bridge-status-controller.intent.d.cts.map +1 -1
- package/dist/bridge-status-controller.intent.d.mts +2 -5
- package/dist/bridge-status-controller.intent.d.mts.map +1 -1
- package/dist/bridge-status-controller.intent.mjs +6 -7
- package/dist/bridge-status-controller.intent.mjs.map +1 -1
- package/dist/bridge-status-controller.mjs +79 -194
- package/dist/bridge-status-controller.mjs.map +1 -1
- package/dist/index.cjs +1 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +0 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +0 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +0 -1
- package/dist/index.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +2 -2
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +2 -2
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/accounts.cjs +8 -0
- package/dist/utils/accounts.cjs.map +1 -0
- package/dist/utils/accounts.d.cts +36 -0
- package/dist/utils/accounts.d.cts.map +1 -0
- package/dist/utils/accounts.d.mts +36 -0
- package/dist/utils/accounts.d.mts.map +1 -0
- package/dist/utils/accounts.mjs +4 -0
- package/dist/utils/accounts.mjs.map +1 -0
- package/dist/utils/authentication.cjs +15 -0
- package/dist/utils/authentication.cjs.map +1 -0
- package/dist/utils/authentication.d.cts +3 -0
- package/dist/utils/authentication.d.cts.map +1 -0
- package/dist/utils/authentication.d.mts +3 -0
- package/dist/utils/authentication.d.mts.map +1 -0
- package/dist/utils/authentication.mjs +11 -0
- package/dist/utils/authentication.mjs.map +1 -0
- package/dist/utils/bridge.cjs +16 -0
- package/dist/utils/bridge.cjs.map +1 -0
- package/dist/utils/bridge.d.cts +10 -0
- package/dist/utils/bridge.d.cts.map +1 -0
- package/dist/utils/bridge.d.mts +10 -0
- package/dist/utils/bridge.d.mts.map +1 -0
- package/dist/utils/bridge.mjs +11 -0
- package/dist/utils/bridge.mjs.map +1 -0
- package/dist/utils/gas.cjs +3 -6
- package/dist/utils/gas.cjs.map +1 -1
- package/dist/utils/gas.d.cts +1 -1
- package/dist/utils/gas.d.cts.map +1 -1
- package/dist/utils/gas.d.mts +1 -1
- package/dist/utils/gas.d.mts.map +1 -1
- package/dist/utils/gas.mjs +3 -6
- package/dist/utils/gas.mjs.map +1 -1
- package/dist/utils/history.cjs +97 -0
- package/dist/utils/history.cjs.map +1 -0
- package/dist/utils/history.d.cts +21 -0
- package/dist/utils/history.d.cts.map +1 -0
- package/dist/utils/history.d.mts +21 -0
- package/dist/utils/history.d.mts.map +1 -0
- package/dist/utils/history.mjs +90 -0
- package/dist/utils/history.mjs.map +1 -0
- package/dist/utils/intent-api.cjs +16 -1
- package/dist/utils/intent-api.cjs.map +1 -1
- package/dist/utils/intent-api.d.cts +9 -1
- package/dist/utils/intent-api.d.cts.map +1 -1
- package/dist/utils/intent-api.d.mts +9 -1
- package/dist/utils/intent-api.d.mts.map +1 -1
- package/dist/utils/intent-api.mjs +14 -0
- package/dist/utils/intent-api.mjs.map +1 -1
- package/dist/utils/keyring.cjs +12 -0
- package/dist/utils/keyring.cjs.map +1 -0
- package/dist/utils/keyring.d.cts +8 -0
- package/dist/utils/keyring.d.cts.map +1 -0
- package/dist/utils/keyring.d.mts +8 -0
- package/dist/utils/keyring.d.mts.map +1 -0
- package/dist/utils/keyring.mjs +8 -0
- package/dist/utils/keyring.mjs.map +1 -0
- package/dist/utils/network.cjs +17 -0
- package/dist/utils/network.cjs.map +1 -0
- package/dist/utils/network.d.cts +5 -0
- package/dist/utils/network.d.cts.map +1 -0
- package/dist/utils/network.d.mts +5 -0
- package/dist/utils/network.d.mts.map +1 -0
- package/dist/utils/network.mjs +12 -0
- package/dist/utils/network.mjs.map +1 -0
- package/dist/utils/snaps.cjs +146 -1
- package/dist/utils/snaps.cjs.map +1 -1
- package/dist/utils/snaps.d.cts +62 -0
- package/dist/utils/snaps.d.cts.map +1 -1
- package/dist/utils/snaps.d.mts +62 -0
- package/dist/utils/snaps.d.mts.map +1 -1
- package/dist/utils/snaps.mjs +141 -0
- package/dist/utils/snaps.mjs.map +1 -1
- package/dist/utils/trace.cjs +31 -0
- package/dist/utils/trace.cjs.map +1 -0
- package/dist/utils/trace.d.cts +17 -0
- package/dist/utils/trace.d.cts.map +1 -0
- package/dist/utils/trace.d.mts +17 -0
- package/dist/utils/trace.d.mts.map +1 -0
- package/dist/utils/trace.mjs +26 -0
- package/dist/utils/trace.mjs.map +1 -0
- package/dist/utils/transaction.cjs +12 -183
- package/dist/utils/transaction.cjs.map +1 -1
- package/dist/utils/transaction.d.cts +5 -78
- package/dist/utils/transaction.d.cts.map +1 -1
- package/dist/utils/transaction.d.mts +5 -78
- package/dist/utils/transaction.d.mts.map +1 -1
- package/dist/utils/transaction.mjs +12 -177
- package/dist/utils/transaction.mjs.map +1 -1
- package/dist/utils/validators.d.cts +2 -2
- package/dist/utils/validators.d.mts +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getNetworkClientIdByChainId = exports.getSelectedChainId = void 0;
|
|
4
|
+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
5
|
+
const bridge_controller_1 = require("@metamask/bridge-controller");
|
|
6
|
+
const getSelectedChainId = (messenger) => {
|
|
7
|
+
const { selectedNetworkClientId } = messenger.call('NetworkController:getState');
|
|
8
|
+
const networkClient = messenger.call('NetworkController:getNetworkClientById', selectedNetworkClientId);
|
|
9
|
+
return networkClient.configuration.chainId;
|
|
10
|
+
};
|
|
11
|
+
exports.getSelectedChainId = getSelectedChainId;
|
|
12
|
+
const getNetworkClientIdByChainId = (messenger, chainId) => {
|
|
13
|
+
const hexChainId = (0, bridge_controller_1.formatChainIdToHex)(chainId);
|
|
14
|
+
return messenger.call('NetworkController:findNetworkClientIdByChainId', hexChainId);
|
|
15
|
+
};
|
|
16
|
+
exports.getNetworkClientIdByChainId = getNetworkClientIdByChainId;
|
|
17
|
+
//# sourceMappingURL=network.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network.cjs","sourceRoot":"","sources":["../../src/utils/network.ts"],"names":[],"mappings":";;;AAAA,qEAAqE;AACrE,mEAGqC;AAI9B,MAAM,kBAAkB,GAAG,CAChC,SAA0C,EAC1C,EAAE;IACF,MAAM,EAAE,uBAAuB,EAAE,GAAG,SAAS,CAAC,IAAI,CAChD,4BAA4B,CAC7B,CAAC;IACF,MAAM,aAAa,GAAG,SAAS,CAAC,IAAI,CAClC,wCAAwC,EACxC,uBAAuB,CACxB,CAAC;IACF,OAAO,aAAa,CAAC,aAAa,CAAC,OAAO,CAAC;AAC7C,CAAC,CAAC;AAXW,QAAA,kBAAkB,sBAW7B;AAEK,MAAM,2BAA2B,GAAG,CACzC,SAA0C,EAC1C,OAA0C,EAC1C,EAAE;IACF,MAAM,UAAU,GAAG,IAAA,sCAAkB,EAAC,OAAO,CAAC,CAAC;IAC/C,OAAO,SAAS,CAAC,IAAI,CACnB,gDAAgD,EAChD,UAAU,CACX,CAAC;AACJ,CAAC,CAAC;AATW,QAAA,2BAA2B,+BAStC","sourcesContent":["/* eslint-disable @typescript-eslint/explicit-function-return-type */\nimport {\n formatChainIdToHex,\n GenericQuoteRequest,\n} from '@metamask/bridge-controller';\n\nimport { BridgeStatusControllerMessenger } from '../types';\n\nexport const getSelectedChainId = (\n messenger: BridgeStatusControllerMessenger,\n) => {\n const { selectedNetworkClientId } = messenger.call(\n 'NetworkController:getState',\n );\n const networkClient = messenger.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n return networkClient.configuration.chainId;\n};\n\nexport const getNetworkClientIdByChainId = (\n messenger: BridgeStatusControllerMessenger,\n chainId: GenericQuoteRequest['srcChainId'],\n) => {\n const hexChainId = formatChainIdToHex(chainId);\n return messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n hexChainId,\n );\n};\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { GenericQuoteRequest } from "@metamask/bridge-controller";
|
|
2
|
+
import { BridgeStatusControllerMessenger } from "../types.cjs";
|
|
3
|
+
export declare const getSelectedChainId: (messenger: BridgeStatusControllerMessenger) => `0x${string}`;
|
|
4
|
+
export declare const getNetworkClientIdByChainId: (messenger: BridgeStatusControllerMessenger, chainId: GenericQuoteRequest['srcChainId']) => string;
|
|
5
|
+
//# sourceMappingURL=network.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network.d.cts","sourceRoot":"","sources":["../../src/utils/network.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,mBAAmB,EACpB,oCAAoC;AAErC,OAAO,EAAE,+BAA+B,EAAE,qBAAiB;AAE3D,eAAO,MAAM,kBAAkB,+DAW9B,CAAC;AAEF,eAAO,MAAM,2BAA2B,wDAE7B,mBAAmB,CAAC,YAAY,CAAC,WAO3C,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { GenericQuoteRequest } from "@metamask/bridge-controller";
|
|
2
|
+
import { BridgeStatusControllerMessenger } from "../types.mjs";
|
|
3
|
+
export declare const getSelectedChainId: (messenger: BridgeStatusControllerMessenger) => `0x${string}`;
|
|
4
|
+
export declare const getNetworkClientIdByChainId: (messenger: BridgeStatusControllerMessenger, chainId: GenericQuoteRequest['srcChainId']) => string;
|
|
5
|
+
//# sourceMappingURL=network.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network.d.mts","sourceRoot":"","sources":["../../src/utils/network.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,mBAAmB,EACpB,oCAAoC;AAErC,OAAO,EAAE,+BAA+B,EAAE,qBAAiB;AAE3D,eAAO,MAAM,kBAAkB,+DAW9B,CAAC;AAEF,eAAO,MAAM,2BAA2B,wDAE7B,mBAAmB,CAAC,YAAY,CAAC,WAO3C,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
2
|
+
import { formatChainIdToHex } from "@metamask/bridge-controller";
|
|
3
|
+
export const getSelectedChainId = (messenger) => {
|
|
4
|
+
const { selectedNetworkClientId } = messenger.call('NetworkController:getState');
|
|
5
|
+
const networkClient = messenger.call('NetworkController:getNetworkClientById', selectedNetworkClientId);
|
|
6
|
+
return networkClient.configuration.chainId;
|
|
7
|
+
};
|
|
8
|
+
export const getNetworkClientIdByChainId = (messenger, chainId) => {
|
|
9
|
+
const hexChainId = formatChainIdToHex(chainId);
|
|
10
|
+
return messenger.call('NetworkController:findNetworkClientIdByChainId', hexChainId);
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=network.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network.mjs","sourceRoot":"","sources":["../../src/utils/network.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,OAAO,EACL,kBAAkB,EAEnB,oCAAoC;AAIrC,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,SAA0C,EAC1C,EAAE;IACF,MAAM,EAAE,uBAAuB,EAAE,GAAG,SAAS,CAAC,IAAI,CAChD,4BAA4B,CAC7B,CAAC;IACF,MAAM,aAAa,GAAG,SAAS,CAAC,IAAI,CAClC,wCAAwC,EACxC,uBAAuB,CACxB,CAAC;IACF,OAAO,aAAa,CAAC,aAAa,CAAC,OAAO,CAAC;AAC7C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAG,CACzC,SAA0C,EAC1C,OAA0C,EAC1C,EAAE;IACF,MAAM,UAAU,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC/C,OAAO,SAAS,CAAC,IAAI,CACnB,gDAAgD,EAChD,UAAU,CACX,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/explicit-function-return-type */\nimport {\n formatChainIdToHex,\n GenericQuoteRequest,\n} from '@metamask/bridge-controller';\n\nimport { BridgeStatusControllerMessenger } from '../types';\n\nexport const getSelectedChainId = (\n messenger: BridgeStatusControllerMessenger,\n) => {\n const { selectedNetworkClientId } = messenger.call(\n 'NetworkController:getState',\n );\n const networkClient = messenger.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n return networkClient.configuration.chainId;\n};\n\nexport const getNetworkClientIdByChainId = (\n messenger: BridgeStatusControllerMessenger,\n chainId: GenericQuoteRequest['srcChainId'],\n) => {\n const hexChainId = formatChainIdToHex(chainId);\n return messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n hexChainId,\n );\n};\n"]}
|
package/dist/utils/snaps.cjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createClientTransactionRequest = void 0;
|
|
3
|
+
exports.handleNonEvmTx = exports.handleNonEvmTxResponse = exports.getTxMetaFields = exports.getClientRequest = exports.createClientTransactionRequest = void 0;
|
|
4
|
+
const bridge_controller_1 = require("@metamask/bridge-controller");
|
|
5
|
+
const transaction_controller_1 = require("@metamask/transaction-controller");
|
|
4
6
|
const uuid_1 = require("uuid");
|
|
5
7
|
/**
|
|
6
8
|
* Creates a client request object for signing and sending a transaction
|
|
@@ -33,4 +35,147 @@ const createClientTransactionRequest = (snapId, transaction, scope, accountId, o
|
|
|
33
35
|
};
|
|
34
36
|
};
|
|
35
37
|
exports.createClientTransactionRequest = createClientTransactionRequest;
|
|
38
|
+
/**
|
|
39
|
+
* Creates a request to sign and send a transaction for non-EVM chains
|
|
40
|
+
* Uses the new unified ClientRequest:signAndSendTransaction interface
|
|
41
|
+
*
|
|
42
|
+
* @param trade - The trade data
|
|
43
|
+
* @param srcChainId - The source chain ID
|
|
44
|
+
* @param accountId - The selected account ID
|
|
45
|
+
* @param snapId - The snap ID
|
|
46
|
+
* @returns The snap request object for signing and sending transaction
|
|
47
|
+
*/
|
|
48
|
+
const getClientRequest = (trade, srcChainId, accountId, snapId) => {
|
|
49
|
+
const scope = (0, bridge_controller_1.formatChainIdToCaip)(srcChainId);
|
|
50
|
+
const transactionData = (0, bridge_controller_1.extractTradeData)(trade);
|
|
51
|
+
// Tron trades need the visible flag and contract type to be included in the request options
|
|
52
|
+
const options = (0, bridge_controller_1.isTronTrade)(trade)
|
|
53
|
+
? {
|
|
54
|
+
visible: trade.visible,
|
|
55
|
+
type: trade.raw_data?.contract?.[0]?.type,
|
|
56
|
+
}
|
|
57
|
+
: undefined;
|
|
58
|
+
// Use the new unified interface
|
|
59
|
+
return (0, exports.createClientTransactionRequest)(snapId, transactionData, scope, accountId, options);
|
|
60
|
+
};
|
|
61
|
+
exports.getClientRequest = getClientRequest;
|
|
62
|
+
const getTxMetaFields = (quoteResponse, approvalTxId) => {
|
|
63
|
+
// Handle destination chain ID - should always be convertible for EVM destinations
|
|
64
|
+
let destinationChainId;
|
|
65
|
+
try {
|
|
66
|
+
destinationChainId = (0, bridge_controller_1.formatChainIdToHex)(quoteResponse.quote.destChainId);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// Fallback for non-EVM destination (shouldn't happen for BTC->EVM)
|
|
70
|
+
destinationChainId = '0x1'; // Default to mainnet
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
destinationChainId,
|
|
74
|
+
sourceTokenAmount: quoteResponse.quote.srcTokenAmount,
|
|
75
|
+
sourceTokenSymbol: quoteResponse.quote.srcAsset.symbol,
|
|
76
|
+
sourceTokenDecimals: quoteResponse.quote.srcAsset.decimals,
|
|
77
|
+
sourceTokenAddress: quoteResponse.quote.srcAsset.address,
|
|
78
|
+
destinationTokenAmount: quoteResponse.quote.destTokenAmount,
|
|
79
|
+
destinationTokenSymbol: quoteResponse.quote.destAsset.symbol,
|
|
80
|
+
destinationTokenDecimals: quoteResponse.quote.destAsset.decimals,
|
|
81
|
+
destinationTokenAddress: quoteResponse.quote.destAsset.address,
|
|
82
|
+
// chainId is now excluded from this function and handled by the caller
|
|
83
|
+
approvalTxId,
|
|
84
|
+
// this is the decimal (non atomic) amount (not USD value) of source token to swap
|
|
85
|
+
swapTokenValue: quoteResponse.sentAmount.amount,
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
exports.getTxMetaFields = getTxMetaFields;
|
|
89
|
+
/**
|
|
90
|
+
* Handles the response from non-EVM transaction submission
|
|
91
|
+
* Works with the new unified ClientRequest:signAndSendTransaction interface
|
|
92
|
+
* Supports Solana, Bitcoin, and other non-EVM chains
|
|
93
|
+
*
|
|
94
|
+
* @param snapResponse - The response from the snap after transaction submission
|
|
95
|
+
* @param trade - The non-evm trade or approval data
|
|
96
|
+
* @param quoteResponse - The quote response containing trade details and metadata
|
|
97
|
+
* @param selectedAccount - The selected account information
|
|
98
|
+
* @returns The transaction metadata including non-EVM specific fields
|
|
99
|
+
*/
|
|
100
|
+
const handleNonEvmTxResponse = (snapResponse, trade, quoteResponse, selectedAccount) => {
|
|
101
|
+
const selectedAccountAddress = selectedAccount.address;
|
|
102
|
+
const snapId = selectedAccount.metadata.snap?.id;
|
|
103
|
+
let hash;
|
|
104
|
+
// Handle different response formats
|
|
105
|
+
if (typeof snapResponse === 'string') {
|
|
106
|
+
hash = snapResponse;
|
|
107
|
+
}
|
|
108
|
+
else if (snapResponse && typeof snapResponse === 'object') {
|
|
109
|
+
// Check for new unified interface response format first
|
|
110
|
+
if ('transactionId' in snapResponse && snapResponse.transactionId) {
|
|
111
|
+
hash = snapResponse.transactionId;
|
|
112
|
+
}
|
|
113
|
+
else if ('result' in snapResponse &&
|
|
114
|
+
snapResponse.result &&
|
|
115
|
+
typeof snapResponse.result === 'object') {
|
|
116
|
+
// Try to extract signature from common locations in response object
|
|
117
|
+
hash =
|
|
118
|
+
snapResponse.result.signature ||
|
|
119
|
+
snapResponse.result.txid ||
|
|
120
|
+
snapResponse.result.hash ||
|
|
121
|
+
snapResponse.result.txHash;
|
|
122
|
+
}
|
|
123
|
+
else if ('signature' in snapResponse &&
|
|
124
|
+
snapResponse.signature &&
|
|
125
|
+
typeof snapResponse.signature === 'string') {
|
|
126
|
+
hash = snapResponse.signature;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const isBridgeTx = (0, bridge_controller_1.isCrossChain)(quoteResponse.quote.srcChainId, quoteResponse.quote.destChainId);
|
|
130
|
+
let hexChainId;
|
|
131
|
+
try {
|
|
132
|
+
hexChainId = (0, bridge_controller_1.formatChainIdToHex)(quoteResponse.quote.srcChainId);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
hexChainId = '0x1';
|
|
136
|
+
}
|
|
137
|
+
// Extract the transaction data for storage
|
|
138
|
+
const tradeData = (0, bridge_controller_1.extractTradeData)(trade);
|
|
139
|
+
// Create a transaction meta object with bridge-specific fields
|
|
140
|
+
return {
|
|
141
|
+
...(0, exports.getTxMetaFields)(quoteResponse),
|
|
142
|
+
time: Date.now(),
|
|
143
|
+
id: hash ?? (0, uuid_1.v4)(),
|
|
144
|
+
chainId: hexChainId,
|
|
145
|
+
networkClientId: snapId ?? 'mainnet',
|
|
146
|
+
txParams: { from: selectedAccountAddress, data: tradeData },
|
|
147
|
+
type: isBridgeTx ? transaction_controller_1.TransactionType.bridge : transaction_controller_1.TransactionType.swap,
|
|
148
|
+
status: transaction_controller_1.TransactionStatus.submitted,
|
|
149
|
+
hash, // Add the transaction signature as hash
|
|
150
|
+
origin: snapId,
|
|
151
|
+
// Add an explicit flag to mark this as a non-EVM transaction
|
|
152
|
+
isSolana: true, // TODO deprecate this and use chainId to detect non-EVM chains
|
|
153
|
+
isBridgeTx,
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
exports.handleNonEvmTxResponse = handleNonEvmTxResponse;
|
|
157
|
+
/**
|
|
158
|
+
* Submits the transaction to the snap using the new unified ClientRequest interface
|
|
159
|
+
* Works for all non-EVM chains (Solana, BTC, Tron)
|
|
160
|
+
* This adds an approval tx to the ApprovalsController in the background
|
|
161
|
+
* The client needs to handle the approval tx by redirecting to the confirmation page with the approvalTxId in the URL
|
|
162
|
+
*
|
|
163
|
+
* @param messenger - The BridgeStatusControllerMessenger instance
|
|
164
|
+
* @param trade - The trade data (can be approval or main trade)
|
|
165
|
+
* @param quoteResponse - The quote response containing metadata
|
|
166
|
+
* @param selectedAccount - The account to submit the transaction for
|
|
167
|
+
* @returns The transaction meta
|
|
168
|
+
*/
|
|
169
|
+
const handleNonEvmTx = async (messenger, trade, quoteResponse, selectedAccount) => {
|
|
170
|
+
if (!selectedAccount.metadata?.snap?.id) {
|
|
171
|
+
throw new Error('Failed to submit cross-chain swap transaction: undefined snap id');
|
|
172
|
+
}
|
|
173
|
+
const request = (0, exports.getClientRequest)(trade, quoteResponse.quote.srcChainId, selectedAccount.id, selectedAccount.metadata?.snap?.id);
|
|
174
|
+
const requestResponse = (await messenger.call('SnapController:handleRequest', request));
|
|
175
|
+
const txMeta = (0, exports.handleNonEvmTxResponse)(requestResponse, trade, quoteResponse, selectedAccount);
|
|
176
|
+
// TODO remove this eventually, just returning it now to match extension behavior
|
|
177
|
+
// OR if the snap can propagate the snapRequestId or keyringReqId to the ApprovalsController, this can return the approvalTxId instead and clients won't need to subscribe to the ApprovalsController state to redirect
|
|
178
|
+
return txMeta;
|
|
179
|
+
};
|
|
180
|
+
exports.handleNonEvmTx = handleNonEvmTx;
|
|
36
181
|
//# sourceMappingURL=snaps.cjs.map
|
package/dist/utils/snaps.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snaps.cjs","sourceRoot":"","sources":["../../src/utils/snaps.ts"],"names":[],"mappings":";;;AACA,+BAAkC;AAElC;;;;;;;;;;GAUG;AACI,MAAM,8BAA8B,GAAG,CAC5C,MAAc,EACd,WAAmB,EACnB,KAAkB,EAClB,SAAiB,EACjB,OAAiC,EACjC,EAAE;IACF,OAAO;QACL,kCAAkC;QAClC,MAAM,EAAE,MAAe;QACvB,MAAM,EAAE,UAAU;QAClB,OAAO,EAAE,iBAA0B;QACnC,OAAO,EAAE;YACP,EAAE,EAAE,IAAA,SAAI,GAAE;YACV,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,wBAAwB;YAChC,MAAM,EAAE;gBACN,WAAW;gBACX,KAAK;gBACL,SAAS;gBACT,GAAG,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,CAAC;aAC5B;SACF;KACF,CAAC;AACJ,CAAC,CAAC;AAxBW,QAAA,8BAA8B,kCAwBzC","sourcesContent":["import type { CaipChainId } from '@metamask/utils';\nimport { v4 as uuid } from 'uuid';\n\n/**\n * Creates a client request object for signing and sending a transaction\n * Works for Solana, BTC, Tron, and other non-EVM networks\n *\n * @param snapId - The snap ID to send the request to\n * @param transaction - The base64 encoded transaction string\n * @param scope - The CAIP-2 chain scope\n * @param accountId - The account ID\n * @param options - Optional network-specific options\n * @returns The snap request object\n */\nexport const createClientTransactionRequest = (\n snapId: string,\n transaction: string,\n scope: CaipChainId,\n accountId: string,\n options?: Record<string, unknown>,\n) => {\n return {\n // TODO: remove 'as never' typing.\n snapId: snapId as never,\n origin: 'metamask',\n handler: 'onClientRequest' as never,\n request: {\n id: uuid(),\n jsonrpc: '2.0',\n method: 'signAndSendTransaction',\n params: {\n transaction,\n scope,\n accountId,\n ...(options && { options }),\n },\n },\n };\n};\n"]}
|
|
1
|
+
{"version":3,"file":"snaps.cjs","sourceRoot":"","sources":["../../src/utils/snaps.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/explicit-function-return-type */\nimport type { AccountsControllerState } from '@metamask/accounts-controller';\nimport type {\n QuoteMetadata,\n QuoteResponse,\n Trade,\n} from '@metamask/bridge-controller';\nimport {\n extractTradeData,\n formatChainIdToCaip,\n formatChainIdToHex,\n isCrossChain,\n isTronTrade,\n} from '@metamask/bridge-controller';\nimport {\n TransactionStatus,\n TransactionType,\n} from '@metamask/transaction-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { CaipChainId, Hex } from '@metamask/utils';\nimport { v4 as uuid } from 'uuid';\n\nimport type {\n BridgeStatusControllerMessenger,\n SolanaTransactionMeta,\n} from '../types';\n\n/**\n * Creates a client request object for signing and sending a transaction\n * Works for Solana, BTC, Tron, and other non-EVM networks\n *\n * @param snapId - The snap ID to send the request to\n * @param transaction - The base64 encoded transaction string\n * @param scope - The CAIP-2 chain scope\n * @param accountId - The account ID\n * @param options - Optional network-specific options\n * @returns The snap request object\n */\nexport const createClientTransactionRequest = (\n snapId: string,\n transaction: string,\n scope: CaipChainId,\n accountId: string,\n options?: Record<string, unknown>,\n) => {\n return {\n // TODO: remove 'as never' typing.\n snapId: snapId as never,\n origin: 'metamask',\n handler: 'onClientRequest' as never,\n request: {\n id: uuid(),\n jsonrpc: '2.0',\n method: 'signAndSendTransaction',\n params: {\n transaction,\n scope,\n accountId,\n ...(options && { options }),\n },\n },\n };\n};\n\n/**\n * Creates a request to sign and send a transaction for non-EVM chains\n * Uses the new unified ClientRequest:signAndSendTransaction interface\n *\n * @param trade - The trade data\n * @param srcChainId - The source chain ID\n * @param accountId - The selected account ID\n * @param snapId - The snap ID\n * @returns The snap request object for signing and sending transaction\n */\nexport const getClientRequest = (\n trade: Trade,\n srcChainId: number,\n accountId: string,\n snapId: string,\n) => {\n const scope = formatChainIdToCaip(srcChainId);\n\n const transactionData = extractTradeData(trade);\n\n // Tron trades need the visible flag and contract type to be included in the request options\n const options = isTronTrade(trade)\n ? {\n visible: trade.visible,\n type: trade.raw_data?.contract?.[0]?.type,\n }\n : undefined;\n\n // Use the new unified interface\n return createClientTransactionRequest(\n snapId,\n transactionData,\n scope,\n accountId,\n options,\n );\n};\n\nexport const getTxMetaFields = (\n quoteResponse: Omit<QuoteResponse<Trade, Trade>, 'approval' | 'trade'> &\n QuoteMetadata,\n approvalTxId?: string,\n): Omit<\n TransactionMeta,\n 'networkClientId' | 'status' | 'time' | 'txParams' | 'id' | 'chainId'\n> => {\n // Handle destination chain ID - should always be convertible for EVM destinations\n let destinationChainId;\n try {\n destinationChainId = formatChainIdToHex(quoteResponse.quote.destChainId);\n } catch {\n // Fallback for non-EVM destination (shouldn't happen for BTC->EVM)\n destinationChainId = '0x1' as `0x${string}`; // Default to mainnet\n }\n\n return {\n destinationChainId,\n sourceTokenAmount: quoteResponse.quote.srcTokenAmount,\n sourceTokenSymbol: quoteResponse.quote.srcAsset.symbol,\n sourceTokenDecimals: quoteResponse.quote.srcAsset.decimals,\n sourceTokenAddress: quoteResponse.quote.srcAsset.address,\n\n destinationTokenAmount: quoteResponse.quote.destTokenAmount,\n destinationTokenSymbol: quoteResponse.quote.destAsset.symbol,\n destinationTokenDecimals: quoteResponse.quote.destAsset.decimals,\n destinationTokenAddress: quoteResponse.quote.destAsset.address,\n\n // chainId is now excluded from this function and handled by the caller\n approvalTxId,\n // this is the decimal (non atomic) amount (not USD value) of source token to swap\n swapTokenValue: quoteResponse.sentAmount.amount,\n };\n};\n\n/**\n * Handles the response from non-EVM transaction submission\n * Works with the new unified ClientRequest:signAndSendTransaction interface\n * Supports Solana, Bitcoin, and other non-EVM chains\n *\n * @param snapResponse - The response from the snap after transaction submission\n * @param trade - The non-evm trade or approval data\n * @param quoteResponse - The quote response containing trade details and metadata\n * @param selectedAccount - The selected account information\n * @returns The transaction metadata including non-EVM specific fields\n */\nexport const handleNonEvmTxResponse = (\n snapResponse:\n | string\n | { transactionId: string } // New unified interface response\n | { result: Record<string, string> }\n | { signature: string },\n trade: Trade,\n quoteResponse: Omit<QuoteResponse<Trade>, 'trade' | 'approval'> &\n QuoteMetadata,\n selectedAccount: AccountsControllerState['internalAccounts']['accounts'][string],\n): TransactionMeta & SolanaTransactionMeta => {\n const selectedAccountAddress = selectedAccount.address;\n const snapId = selectedAccount.metadata.snap?.id;\n let hash;\n // Handle different response formats\n if (typeof snapResponse === 'string') {\n hash = snapResponse;\n } else if (snapResponse && typeof snapResponse === 'object') {\n // Check for new unified interface response format first\n if ('transactionId' in snapResponse && snapResponse.transactionId) {\n hash = snapResponse.transactionId;\n } else if (\n 'result' in snapResponse &&\n snapResponse.result &&\n typeof snapResponse.result === 'object'\n ) {\n // Try to extract signature from common locations in response object\n hash =\n snapResponse.result.signature ||\n snapResponse.result.txid ||\n snapResponse.result.hash ||\n snapResponse.result.txHash;\n } else if (\n 'signature' in snapResponse &&\n snapResponse.signature &&\n typeof snapResponse.signature === 'string'\n ) {\n hash = snapResponse.signature;\n }\n }\n\n const isBridgeTx = isCrossChain(\n quoteResponse.quote.srcChainId,\n quoteResponse.quote.destChainId,\n );\n\n let hexChainId: Hex;\n try {\n hexChainId = formatChainIdToHex(quoteResponse.quote.srcChainId);\n } catch {\n hexChainId = '0x1';\n }\n // Extract the transaction data for storage\n const tradeData = extractTradeData(trade);\n\n // Create a transaction meta object with bridge-specific fields\n return {\n ...getTxMetaFields(quoteResponse),\n time: Date.now(),\n id: hash ?? uuid(),\n chainId: hexChainId,\n networkClientId: snapId ?? 'mainnet',\n txParams: { from: selectedAccountAddress, data: tradeData },\n type: isBridgeTx ? TransactionType.bridge : TransactionType.swap,\n status: TransactionStatus.submitted,\n hash, // Add the transaction signature as hash\n origin: snapId,\n // Add an explicit flag to mark this as a non-EVM transaction\n isSolana: true, // TODO deprecate this and use chainId to detect non-EVM chains\n isBridgeTx,\n };\n};\n\n/**\n * Submits the transaction to the snap using the new unified ClientRequest interface\n * Works for all non-EVM chains (Solana, BTC, Tron)\n * This adds an approval tx to the ApprovalsController in the background\n * The client needs to handle the approval tx by redirecting to the confirmation page with the approvalTxId in the URL\n *\n * @param messenger - The BridgeStatusControllerMessenger instance\n * @param trade - The trade data (can be approval or main trade)\n * @param quoteResponse - The quote response containing metadata\n * @param selectedAccount - The account to submit the transaction for\n * @returns The transaction meta\n */\nexport const handleNonEvmTx = async (\n messenger: BridgeStatusControllerMessenger,\n trade: Trade,\n quoteResponse: QuoteResponse<Trade, Trade> & QuoteMetadata,\n selectedAccount: AccountsControllerState['internalAccounts']['accounts'][string],\n): Promise<TransactionMeta> => {\n if (!selectedAccount.metadata?.snap?.id) {\n throw new Error(\n 'Failed to submit cross-chain swap transaction: undefined snap id',\n );\n }\n\n const request = getClientRequest(\n trade,\n quoteResponse.quote.srcChainId,\n selectedAccount.id,\n selectedAccount.metadata?.snap?.id,\n );\n const requestResponse = (await messenger.call(\n 'SnapController:handleRequest',\n request,\n )) as\n | string\n | { transactionId: string }\n | { result: Record<string, string> }\n | { signature: string };\n\n const txMeta = handleNonEvmTxResponse(\n requestResponse,\n trade,\n quoteResponse,\n selectedAccount,\n );\n\n // TODO remove this eventually, just returning it now to match extension behavior\n // OR if the snap can propagate the snapRequestId or keyringReqId to the ApprovalsController, this can return the approvalTxId instead and clients won't need to subscribe to the ApprovalsController state to redirect\n return txMeta;\n};\n"]}
|
package/dist/utils/snaps.d.cts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import type { AccountsControllerState } from "@metamask/accounts-controller";
|
|
2
|
+
import type { QuoteMetadata, QuoteResponse, Trade } from "@metamask/bridge-controller";
|
|
3
|
+
import type { TransactionMeta } from "@metamask/transaction-controller";
|
|
1
4
|
import type { CaipChainId } from "@metamask/utils";
|
|
5
|
+
import type { BridgeStatusControllerMessenger, SolanaTransactionMeta } from "../types.cjs";
|
|
2
6
|
/**
|
|
3
7
|
* Creates a client request object for signing and sending a transaction
|
|
4
8
|
* Works for Solana, BTC, Tron, and other non-EVM networks
|
|
@@ -26,4 +30,62 @@ export declare const createClientTransactionRequest: (snapId: string, transactio
|
|
|
26
30
|
};
|
|
27
31
|
};
|
|
28
32
|
};
|
|
33
|
+
/**
|
|
34
|
+
* Creates a request to sign and send a transaction for non-EVM chains
|
|
35
|
+
* Uses the new unified ClientRequest:signAndSendTransaction interface
|
|
36
|
+
*
|
|
37
|
+
* @param trade - The trade data
|
|
38
|
+
* @param srcChainId - The source chain ID
|
|
39
|
+
* @param accountId - The selected account ID
|
|
40
|
+
* @param snapId - The snap ID
|
|
41
|
+
* @returns The snap request object for signing and sending transaction
|
|
42
|
+
*/
|
|
43
|
+
export declare const getClientRequest: (trade: Trade, srcChainId: number, accountId: string, snapId: string) => {
|
|
44
|
+
snapId: never;
|
|
45
|
+
origin: string;
|
|
46
|
+
handler: never;
|
|
47
|
+
request: {
|
|
48
|
+
id: string;
|
|
49
|
+
jsonrpc: string;
|
|
50
|
+
method: string;
|
|
51
|
+
params: {
|
|
52
|
+
options?: Record<string, unknown> | undefined;
|
|
53
|
+
transaction: string;
|
|
54
|
+
scope: `${string}:${string}`;
|
|
55
|
+
accountId: string;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
export declare const getTxMetaFields: (quoteResponse: Omit<QuoteResponse<Trade, Trade>, 'approval' | 'trade'> & QuoteMetadata, approvalTxId?: string) => Omit<TransactionMeta, 'networkClientId' | 'status' | 'time' | 'txParams' | 'id' | 'chainId'>;
|
|
60
|
+
/**
|
|
61
|
+
* Handles the response from non-EVM transaction submission
|
|
62
|
+
* Works with the new unified ClientRequest:signAndSendTransaction interface
|
|
63
|
+
* Supports Solana, Bitcoin, and other non-EVM chains
|
|
64
|
+
*
|
|
65
|
+
* @param snapResponse - The response from the snap after transaction submission
|
|
66
|
+
* @param trade - The non-evm trade or approval data
|
|
67
|
+
* @param quoteResponse - The quote response containing trade details and metadata
|
|
68
|
+
* @param selectedAccount - The selected account information
|
|
69
|
+
* @returns The transaction metadata including non-EVM specific fields
|
|
70
|
+
*/
|
|
71
|
+
export declare const handleNonEvmTxResponse: (snapResponse: string | {
|
|
72
|
+
transactionId: string;
|
|
73
|
+
} | {
|
|
74
|
+
result: Record<string, string>;
|
|
75
|
+
} | {
|
|
76
|
+
signature: string;
|
|
77
|
+
}, trade: Trade, quoteResponse: Omit<QuoteResponse<Trade>, 'trade' | 'approval'> & QuoteMetadata, selectedAccount: AccountsControllerState['internalAccounts']['accounts'][string]) => TransactionMeta & SolanaTransactionMeta;
|
|
78
|
+
/**
|
|
79
|
+
* Submits the transaction to the snap using the new unified ClientRequest interface
|
|
80
|
+
* Works for all non-EVM chains (Solana, BTC, Tron)
|
|
81
|
+
* This adds an approval tx to the ApprovalsController in the background
|
|
82
|
+
* The client needs to handle the approval tx by redirecting to the confirmation page with the approvalTxId in the URL
|
|
83
|
+
*
|
|
84
|
+
* @param messenger - The BridgeStatusControllerMessenger instance
|
|
85
|
+
* @param trade - The trade data (can be approval or main trade)
|
|
86
|
+
* @param quoteResponse - The quote response containing metadata
|
|
87
|
+
* @param selectedAccount - The account to submit the transaction for
|
|
88
|
+
* @returns The transaction meta
|
|
89
|
+
*/
|
|
90
|
+
export declare const handleNonEvmTx: (messenger: BridgeStatusControllerMessenger, trade: Trade, quoteResponse: QuoteResponse<Trade, Trade> & QuoteMetadata, selectedAccount: AccountsControllerState['internalAccounts']['accounts'][string]) => Promise<TransactionMeta>;
|
|
29
91
|
//# sourceMappingURL=snaps.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snaps.d.cts","sourceRoot":"","sources":["../../src/utils/snaps.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"snaps.d.cts","sourceRoot":"","sources":["../../src/utils/snaps.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,sCAAsC;AAC7E,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,KAAK,EACN,oCAAoC;AAYrC,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAO,wBAAwB;AAGxD,OAAO,KAAK,EACV,+BAA+B,EAC/B,qBAAqB,EACtB,qBAAiB;AAElB;;;;;;;;;;GAUG;AACH,eAAO,MAAM,8BAA8B,WACjC,MAAM,eACD,MAAM,SACZ,WAAW,aACP,MAAM,YACP,OAAO,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;;;;CAmBlC,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,UACpB,KAAK,cACA,MAAM,aACP,MAAM,UACT,MAAM;;;;;;;;;;;;;;;CAsBf,CAAC;AAEF,eAAO,MAAM,eAAe,kBACX,KAAK,cAAc,KAAK,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,GACpE,aAAa,iBACA,MAAM,KACpB,KACD,eAAe,EACf,iBAAiB,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,IAAI,GAAG,SAAS,CA4BtE,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,iBAE7B,MAAM,GACN;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,MAAM,EAAE,OAAO,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAClC;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,SAClB,KAAK,iBACG,KAAK,cAAc,KAAK,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC,GAC7D,aAAa,mBACE,uBAAuB,CAAC,kBAAkB,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAC/E,eAAe,GAAG,qBA6DpB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,sDAElB,KAAK,iBACG,cAAc,KAAK,EAAE,KAAK,CAAC,GAAG,aAAa,mBACzC,uBAAuB,CAAC,kBAAkB,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAC/E,QAAQ,eAAe,CAgCzB,CAAC"}
|
package/dist/utils/snaps.d.mts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import type { AccountsControllerState } from "@metamask/accounts-controller";
|
|
2
|
+
import type { QuoteMetadata, QuoteResponse, Trade } from "@metamask/bridge-controller";
|
|
3
|
+
import type { TransactionMeta } from "@metamask/transaction-controller";
|
|
1
4
|
import type { CaipChainId } from "@metamask/utils";
|
|
5
|
+
import type { BridgeStatusControllerMessenger, SolanaTransactionMeta } from "../types.mjs";
|
|
2
6
|
/**
|
|
3
7
|
* Creates a client request object for signing and sending a transaction
|
|
4
8
|
* Works for Solana, BTC, Tron, and other non-EVM networks
|
|
@@ -26,4 +30,62 @@ export declare const createClientTransactionRequest: (snapId: string, transactio
|
|
|
26
30
|
};
|
|
27
31
|
};
|
|
28
32
|
};
|
|
33
|
+
/**
|
|
34
|
+
* Creates a request to sign and send a transaction for non-EVM chains
|
|
35
|
+
* Uses the new unified ClientRequest:signAndSendTransaction interface
|
|
36
|
+
*
|
|
37
|
+
* @param trade - The trade data
|
|
38
|
+
* @param srcChainId - The source chain ID
|
|
39
|
+
* @param accountId - The selected account ID
|
|
40
|
+
* @param snapId - The snap ID
|
|
41
|
+
* @returns The snap request object for signing and sending transaction
|
|
42
|
+
*/
|
|
43
|
+
export declare const getClientRequest: (trade: Trade, srcChainId: number, accountId: string, snapId: string) => {
|
|
44
|
+
snapId: never;
|
|
45
|
+
origin: string;
|
|
46
|
+
handler: never;
|
|
47
|
+
request: {
|
|
48
|
+
id: string;
|
|
49
|
+
jsonrpc: string;
|
|
50
|
+
method: string;
|
|
51
|
+
params: {
|
|
52
|
+
options?: Record<string, unknown> | undefined;
|
|
53
|
+
transaction: string;
|
|
54
|
+
scope: `${string}:${string}`;
|
|
55
|
+
accountId: string;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
export declare const getTxMetaFields: (quoteResponse: Omit<QuoteResponse<Trade, Trade>, 'approval' | 'trade'> & QuoteMetadata, approvalTxId?: string) => Omit<TransactionMeta, 'networkClientId' | 'status' | 'time' | 'txParams' | 'id' | 'chainId'>;
|
|
60
|
+
/**
|
|
61
|
+
* Handles the response from non-EVM transaction submission
|
|
62
|
+
* Works with the new unified ClientRequest:signAndSendTransaction interface
|
|
63
|
+
* Supports Solana, Bitcoin, and other non-EVM chains
|
|
64
|
+
*
|
|
65
|
+
* @param snapResponse - The response from the snap after transaction submission
|
|
66
|
+
* @param trade - The non-evm trade or approval data
|
|
67
|
+
* @param quoteResponse - The quote response containing trade details and metadata
|
|
68
|
+
* @param selectedAccount - The selected account information
|
|
69
|
+
* @returns The transaction metadata including non-EVM specific fields
|
|
70
|
+
*/
|
|
71
|
+
export declare const handleNonEvmTxResponse: (snapResponse: string | {
|
|
72
|
+
transactionId: string;
|
|
73
|
+
} | {
|
|
74
|
+
result: Record<string, string>;
|
|
75
|
+
} | {
|
|
76
|
+
signature: string;
|
|
77
|
+
}, trade: Trade, quoteResponse: Omit<QuoteResponse<Trade>, 'trade' | 'approval'> & QuoteMetadata, selectedAccount: AccountsControllerState['internalAccounts']['accounts'][string]) => TransactionMeta & SolanaTransactionMeta;
|
|
78
|
+
/**
|
|
79
|
+
* Submits the transaction to the snap using the new unified ClientRequest interface
|
|
80
|
+
* Works for all non-EVM chains (Solana, BTC, Tron)
|
|
81
|
+
* This adds an approval tx to the ApprovalsController in the background
|
|
82
|
+
* The client needs to handle the approval tx by redirecting to the confirmation page with the approvalTxId in the URL
|
|
83
|
+
*
|
|
84
|
+
* @param messenger - The BridgeStatusControllerMessenger instance
|
|
85
|
+
* @param trade - The trade data (can be approval or main trade)
|
|
86
|
+
* @param quoteResponse - The quote response containing metadata
|
|
87
|
+
* @param selectedAccount - The account to submit the transaction for
|
|
88
|
+
* @returns The transaction meta
|
|
89
|
+
*/
|
|
90
|
+
export declare const handleNonEvmTx: (messenger: BridgeStatusControllerMessenger, trade: Trade, quoteResponse: QuoteResponse<Trade, Trade> & QuoteMetadata, selectedAccount: AccountsControllerState['internalAccounts']['accounts'][string]) => Promise<TransactionMeta>;
|
|
29
91
|
//# sourceMappingURL=snaps.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snaps.d.mts","sourceRoot":"","sources":["../../src/utils/snaps.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"snaps.d.mts","sourceRoot":"","sources":["../../src/utils/snaps.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,sCAAsC;AAC7E,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,KAAK,EACN,oCAAoC;AAYrC,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAO,wBAAwB;AAGxD,OAAO,KAAK,EACV,+BAA+B,EAC/B,qBAAqB,EACtB,qBAAiB;AAElB;;;;;;;;;;GAUG;AACH,eAAO,MAAM,8BAA8B,WACjC,MAAM,eACD,MAAM,SACZ,WAAW,aACP,MAAM,YACP,OAAO,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;;;;CAmBlC,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,UACpB,KAAK,cACA,MAAM,aACP,MAAM,UACT,MAAM;;;;;;;;;;;;;;;CAsBf,CAAC;AAEF,eAAO,MAAM,eAAe,kBACX,KAAK,cAAc,KAAK,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,GACpE,aAAa,iBACA,MAAM,KACpB,KACD,eAAe,EACf,iBAAiB,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,IAAI,GAAG,SAAS,CA4BtE,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,iBAE7B,MAAM,GACN;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,MAAM,EAAE,OAAO,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAClC;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,SAClB,KAAK,iBACG,KAAK,cAAc,KAAK,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC,GAC7D,aAAa,mBACE,uBAAuB,CAAC,kBAAkB,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAC/E,eAAe,GAAG,qBA6DpB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,sDAElB,KAAK,iBACG,cAAc,KAAK,EAAE,KAAK,CAAC,GAAG,aAAa,mBACzC,uBAAuB,CAAC,kBAAkB,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAC/E,QAAQ,eAAe,CAgCzB,CAAC"}
|
package/dist/utils/snaps.mjs
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { extractTradeData, formatChainIdToCaip, formatChainIdToHex, isCrossChain, isTronTrade } from "@metamask/bridge-controller";
|
|
2
|
+
import { TransactionStatus, TransactionType } from "@metamask/transaction-controller";
|
|
1
3
|
import { v4 as uuid } from "uuid";
|
|
2
4
|
/**
|
|
3
5
|
* Creates a client request object for signing and sending a transaction
|
|
@@ -29,4 +31,143 @@ export const createClientTransactionRequest = (snapId, transaction, scope, accou
|
|
|
29
31
|
},
|
|
30
32
|
};
|
|
31
33
|
};
|
|
34
|
+
/**
|
|
35
|
+
* Creates a request to sign and send a transaction for non-EVM chains
|
|
36
|
+
* Uses the new unified ClientRequest:signAndSendTransaction interface
|
|
37
|
+
*
|
|
38
|
+
* @param trade - The trade data
|
|
39
|
+
* @param srcChainId - The source chain ID
|
|
40
|
+
* @param accountId - The selected account ID
|
|
41
|
+
* @param snapId - The snap ID
|
|
42
|
+
* @returns The snap request object for signing and sending transaction
|
|
43
|
+
*/
|
|
44
|
+
export const getClientRequest = (trade, srcChainId, accountId, snapId) => {
|
|
45
|
+
const scope = formatChainIdToCaip(srcChainId);
|
|
46
|
+
const transactionData = extractTradeData(trade);
|
|
47
|
+
// Tron trades need the visible flag and contract type to be included in the request options
|
|
48
|
+
const options = isTronTrade(trade)
|
|
49
|
+
? {
|
|
50
|
+
visible: trade.visible,
|
|
51
|
+
type: trade.raw_data?.contract?.[0]?.type,
|
|
52
|
+
}
|
|
53
|
+
: undefined;
|
|
54
|
+
// Use the new unified interface
|
|
55
|
+
return createClientTransactionRequest(snapId, transactionData, scope, accountId, options);
|
|
56
|
+
};
|
|
57
|
+
export const getTxMetaFields = (quoteResponse, approvalTxId) => {
|
|
58
|
+
// Handle destination chain ID - should always be convertible for EVM destinations
|
|
59
|
+
let destinationChainId;
|
|
60
|
+
try {
|
|
61
|
+
destinationChainId = formatChainIdToHex(quoteResponse.quote.destChainId);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// Fallback for non-EVM destination (shouldn't happen for BTC->EVM)
|
|
65
|
+
destinationChainId = '0x1'; // Default to mainnet
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
destinationChainId,
|
|
69
|
+
sourceTokenAmount: quoteResponse.quote.srcTokenAmount,
|
|
70
|
+
sourceTokenSymbol: quoteResponse.quote.srcAsset.symbol,
|
|
71
|
+
sourceTokenDecimals: quoteResponse.quote.srcAsset.decimals,
|
|
72
|
+
sourceTokenAddress: quoteResponse.quote.srcAsset.address,
|
|
73
|
+
destinationTokenAmount: quoteResponse.quote.destTokenAmount,
|
|
74
|
+
destinationTokenSymbol: quoteResponse.quote.destAsset.symbol,
|
|
75
|
+
destinationTokenDecimals: quoteResponse.quote.destAsset.decimals,
|
|
76
|
+
destinationTokenAddress: quoteResponse.quote.destAsset.address,
|
|
77
|
+
// chainId is now excluded from this function and handled by the caller
|
|
78
|
+
approvalTxId,
|
|
79
|
+
// this is the decimal (non atomic) amount (not USD value) of source token to swap
|
|
80
|
+
swapTokenValue: quoteResponse.sentAmount.amount,
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Handles the response from non-EVM transaction submission
|
|
85
|
+
* Works with the new unified ClientRequest:signAndSendTransaction interface
|
|
86
|
+
* Supports Solana, Bitcoin, and other non-EVM chains
|
|
87
|
+
*
|
|
88
|
+
* @param snapResponse - The response from the snap after transaction submission
|
|
89
|
+
* @param trade - The non-evm trade or approval data
|
|
90
|
+
* @param quoteResponse - The quote response containing trade details and metadata
|
|
91
|
+
* @param selectedAccount - The selected account information
|
|
92
|
+
* @returns The transaction metadata including non-EVM specific fields
|
|
93
|
+
*/
|
|
94
|
+
export const handleNonEvmTxResponse = (snapResponse, trade, quoteResponse, selectedAccount) => {
|
|
95
|
+
const selectedAccountAddress = selectedAccount.address;
|
|
96
|
+
const snapId = selectedAccount.metadata.snap?.id;
|
|
97
|
+
let hash;
|
|
98
|
+
// Handle different response formats
|
|
99
|
+
if (typeof snapResponse === 'string') {
|
|
100
|
+
hash = snapResponse;
|
|
101
|
+
}
|
|
102
|
+
else if (snapResponse && typeof snapResponse === 'object') {
|
|
103
|
+
// Check for new unified interface response format first
|
|
104
|
+
if ('transactionId' in snapResponse && snapResponse.transactionId) {
|
|
105
|
+
hash = snapResponse.transactionId;
|
|
106
|
+
}
|
|
107
|
+
else if ('result' in snapResponse &&
|
|
108
|
+
snapResponse.result &&
|
|
109
|
+
typeof snapResponse.result === 'object') {
|
|
110
|
+
// Try to extract signature from common locations in response object
|
|
111
|
+
hash =
|
|
112
|
+
snapResponse.result.signature ||
|
|
113
|
+
snapResponse.result.txid ||
|
|
114
|
+
snapResponse.result.hash ||
|
|
115
|
+
snapResponse.result.txHash;
|
|
116
|
+
}
|
|
117
|
+
else if ('signature' in snapResponse &&
|
|
118
|
+
snapResponse.signature &&
|
|
119
|
+
typeof snapResponse.signature === 'string') {
|
|
120
|
+
hash = snapResponse.signature;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const isBridgeTx = isCrossChain(quoteResponse.quote.srcChainId, quoteResponse.quote.destChainId);
|
|
124
|
+
let hexChainId;
|
|
125
|
+
try {
|
|
126
|
+
hexChainId = formatChainIdToHex(quoteResponse.quote.srcChainId);
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
hexChainId = '0x1';
|
|
130
|
+
}
|
|
131
|
+
// Extract the transaction data for storage
|
|
132
|
+
const tradeData = extractTradeData(trade);
|
|
133
|
+
// Create a transaction meta object with bridge-specific fields
|
|
134
|
+
return {
|
|
135
|
+
...getTxMetaFields(quoteResponse),
|
|
136
|
+
time: Date.now(),
|
|
137
|
+
id: hash ?? uuid(),
|
|
138
|
+
chainId: hexChainId,
|
|
139
|
+
networkClientId: snapId ?? 'mainnet',
|
|
140
|
+
txParams: { from: selectedAccountAddress, data: tradeData },
|
|
141
|
+
type: isBridgeTx ? TransactionType.bridge : TransactionType.swap,
|
|
142
|
+
status: TransactionStatus.submitted,
|
|
143
|
+
hash, // Add the transaction signature as hash
|
|
144
|
+
origin: snapId,
|
|
145
|
+
// Add an explicit flag to mark this as a non-EVM transaction
|
|
146
|
+
isSolana: true, // TODO deprecate this and use chainId to detect non-EVM chains
|
|
147
|
+
isBridgeTx,
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* Submits the transaction to the snap using the new unified ClientRequest interface
|
|
152
|
+
* Works for all non-EVM chains (Solana, BTC, Tron)
|
|
153
|
+
* This adds an approval tx to the ApprovalsController in the background
|
|
154
|
+
* The client needs to handle the approval tx by redirecting to the confirmation page with the approvalTxId in the URL
|
|
155
|
+
*
|
|
156
|
+
* @param messenger - The BridgeStatusControllerMessenger instance
|
|
157
|
+
* @param trade - The trade data (can be approval or main trade)
|
|
158
|
+
* @param quoteResponse - The quote response containing metadata
|
|
159
|
+
* @param selectedAccount - The account to submit the transaction for
|
|
160
|
+
* @returns The transaction meta
|
|
161
|
+
*/
|
|
162
|
+
export const handleNonEvmTx = async (messenger, trade, quoteResponse, selectedAccount) => {
|
|
163
|
+
if (!selectedAccount.metadata?.snap?.id) {
|
|
164
|
+
throw new Error('Failed to submit cross-chain swap transaction: undefined snap id');
|
|
165
|
+
}
|
|
166
|
+
const request = getClientRequest(trade, quoteResponse.quote.srcChainId, selectedAccount.id, selectedAccount.metadata?.snap?.id);
|
|
167
|
+
const requestResponse = (await messenger.call('SnapController:handleRequest', request));
|
|
168
|
+
const txMeta = handleNonEvmTxResponse(requestResponse, trade, quoteResponse, selectedAccount);
|
|
169
|
+
// TODO remove this eventually, just returning it now to match extension behavior
|
|
170
|
+
// OR if the snap can propagate the snapRequestId or keyringReqId to the ApprovalsController, this can return the approvalTxId instead and clients won't need to subscribe to the ApprovalsController state to redirect
|
|
171
|
+
return txMeta;
|
|
172
|
+
};
|
|
32
173
|
//# sourceMappingURL=snaps.mjs.map
|
package/dist/utils/snaps.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snaps.mjs","sourceRoot":"","sources":["../../src/utils/snaps.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE,aAAa;AAElC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAC5C,MAAc,EACd,WAAmB,EACnB,KAAkB,EAClB,SAAiB,EACjB,OAAiC,EACjC,EAAE;IACF,OAAO;QACL,kCAAkC;QAClC,MAAM,EAAE,MAAe;QACvB,MAAM,EAAE,UAAU;QAClB,OAAO,EAAE,iBAA0B;QACnC,OAAO,EAAE;YACP,EAAE,EAAE,IAAI,EAAE;YACV,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,wBAAwB;YAChC,MAAM,EAAE;gBACN,WAAW;gBACX,KAAK;gBACL,SAAS;gBACT,GAAG,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,CAAC;aAC5B;SACF;KACF,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import type { CaipChainId } from '@metamask/utils';\nimport { v4 as uuid } from 'uuid';\n\n/**\n * Creates a client request object for signing and sending a transaction\n * Works for Solana, BTC, Tron, and other non-EVM networks\n *\n * @param snapId - The snap ID to send the request to\n * @param transaction - The base64 encoded transaction string\n * @param scope - The CAIP-2 chain scope\n * @param accountId - The account ID\n * @param options - Optional network-specific options\n * @returns The snap request object\n */\nexport const createClientTransactionRequest = (\n snapId: string,\n transaction: string,\n scope: CaipChainId,\n accountId: string,\n options?: Record<string, unknown>,\n) => {\n return {\n // TODO: remove 'as never' typing.\n snapId: snapId as never,\n origin: 'metamask',\n handler: 'onClientRequest' as never,\n request: {\n id: uuid(),\n jsonrpc: '2.0',\n method: 'signAndSendTransaction',\n params: {\n transaction,\n scope,\n accountId,\n ...(options && { options }),\n },\n },\n };\n};\n"]}
|
|
1
|
+
{"version":3,"file":"snaps.mjs","sourceRoot":"","sources":["../../src/utils/snaps.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/explicit-function-return-type */\nimport type { AccountsControllerState } from '@metamask/accounts-controller';\nimport type {\n QuoteMetadata,\n QuoteResponse,\n Trade,\n} from '@metamask/bridge-controller';\nimport {\n extractTradeData,\n formatChainIdToCaip,\n formatChainIdToHex,\n isCrossChain,\n isTronTrade,\n} from '@metamask/bridge-controller';\nimport {\n TransactionStatus,\n TransactionType,\n} from '@metamask/transaction-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { CaipChainId, Hex } from '@metamask/utils';\nimport { v4 as uuid } from 'uuid';\n\nimport type {\n BridgeStatusControllerMessenger,\n SolanaTransactionMeta,\n} from '../types';\n\n/**\n * Creates a client request object for signing and sending a transaction\n * Works for Solana, BTC, Tron, and other non-EVM networks\n *\n * @param snapId - The snap ID to send the request to\n * @param transaction - The base64 encoded transaction string\n * @param scope - The CAIP-2 chain scope\n * @param accountId - The account ID\n * @param options - Optional network-specific options\n * @returns The snap request object\n */\nexport const createClientTransactionRequest = (\n snapId: string,\n transaction: string,\n scope: CaipChainId,\n accountId: string,\n options?: Record<string, unknown>,\n) => {\n return {\n // TODO: remove 'as never' typing.\n snapId: snapId as never,\n origin: 'metamask',\n handler: 'onClientRequest' as never,\n request: {\n id: uuid(),\n jsonrpc: '2.0',\n method: 'signAndSendTransaction',\n params: {\n transaction,\n scope,\n accountId,\n ...(options && { options }),\n },\n },\n };\n};\n\n/**\n * Creates a request to sign and send a transaction for non-EVM chains\n * Uses the new unified ClientRequest:signAndSendTransaction interface\n *\n * @param trade - The trade data\n * @param srcChainId - The source chain ID\n * @param accountId - The selected account ID\n * @param snapId - The snap ID\n * @returns The snap request object for signing and sending transaction\n */\nexport const getClientRequest = (\n trade: Trade,\n srcChainId: number,\n accountId: string,\n snapId: string,\n) => {\n const scope = formatChainIdToCaip(srcChainId);\n\n const transactionData = extractTradeData(trade);\n\n // Tron trades need the visible flag and contract type to be included in the request options\n const options = isTronTrade(trade)\n ? {\n visible: trade.visible,\n type: trade.raw_data?.contract?.[0]?.type,\n }\n : undefined;\n\n // Use the new unified interface\n return createClientTransactionRequest(\n snapId,\n transactionData,\n scope,\n accountId,\n options,\n );\n};\n\nexport const getTxMetaFields = (\n quoteResponse: Omit<QuoteResponse<Trade, Trade>, 'approval' | 'trade'> &\n QuoteMetadata,\n approvalTxId?: string,\n): Omit<\n TransactionMeta,\n 'networkClientId' | 'status' | 'time' | 'txParams' | 'id' | 'chainId'\n> => {\n // Handle destination chain ID - should always be convertible for EVM destinations\n let destinationChainId;\n try {\n destinationChainId = formatChainIdToHex(quoteResponse.quote.destChainId);\n } catch {\n // Fallback for non-EVM destination (shouldn't happen for BTC->EVM)\n destinationChainId = '0x1' as `0x${string}`; // Default to mainnet\n }\n\n return {\n destinationChainId,\n sourceTokenAmount: quoteResponse.quote.srcTokenAmount,\n sourceTokenSymbol: quoteResponse.quote.srcAsset.symbol,\n sourceTokenDecimals: quoteResponse.quote.srcAsset.decimals,\n sourceTokenAddress: quoteResponse.quote.srcAsset.address,\n\n destinationTokenAmount: quoteResponse.quote.destTokenAmount,\n destinationTokenSymbol: quoteResponse.quote.destAsset.symbol,\n destinationTokenDecimals: quoteResponse.quote.destAsset.decimals,\n destinationTokenAddress: quoteResponse.quote.destAsset.address,\n\n // chainId is now excluded from this function and handled by the caller\n approvalTxId,\n // this is the decimal (non atomic) amount (not USD value) of source token to swap\n swapTokenValue: quoteResponse.sentAmount.amount,\n };\n};\n\n/**\n * Handles the response from non-EVM transaction submission\n * Works with the new unified ClientRequest:signAndSendTransaction interface\n * Supports Solana, Bitcoin, and other non-EVM chains\n *\n * @param snapResponse - The response from the snap after transaction submission\n * @param trade - The non-evm trade or approval data\n * @param quoteResponse - The quote response containing trade details and metadata\n * @param selectedAccount - The selected account information\n * @returns The transaction metadata including non-EVM specific fields\n */\nexport const handleNonEvmTxResponse = (\n snapResponse:\n | string\n | { transactionId: string } // New unified interface response\n | { result: Record<string, string> }\n | { signature: string },\n trade: Trade,\n quoteResponse: Omit<QuoteResponse<Trade>, 'trade' | 'approval'> &\n QuoteMetadata,\n selectedAccount: AccountsControllerState['internalAccounts']['accounts'][string],\n): TransactionMeta & SolanaTransactionMeta => {\n const selectedAccountAddress = selectedAccount.address;\n const snapId = selectedAccount.metadata.snap?.id;\n let hash;\n // Handle different response formats\n if (typeof snapResponse === 'string') {\n hash = snapResponse;\n } else if (snapResponse && typeof snapResponse === 'object') {\n // Check for new unified interface response format first\n if ('transactionId' in snapResponse && snapResponse.transactionId) {\n hash = snapResponse.transactionId;\n } else if (\n 'result' in snapResponse &&\n snapResponse.result &&\n typeof snapResponse.result === 'object'\n ) {\n // Try to extract signature from common locations in response object\n hash =\n snapResponse.result.signature ||\n snapResponse.result.txid ||\n snapResponse.result.hash ||\n snapResponse.result.txHash;\n } else if (\n 'signature' in snapResponse &&\n snapResponse.signature &&\n typeof snapResponse.signature === 'string'\n ) {\n hash = snapResponse.signature;\n }\n }\n\n const isBridgeTx = isCrossChain(\n quoteResponse.quote.srcChainId,\n quoteResponse.quote.destChainId,\n );\n\n let hexChainId: Hex;\n try {\n hexChainId = formatChainIdToHex(quoteResponse.quote.srcChainId);\n } catch {\n hexChainId = '0x1';\n }\n // Extract the transaction data for storage\n const tradeData = extractTradeData(trade);\n\n // Create a transaction meta object with bridge-specific fields\n return {\n ...getTxMetaFields(quoteResponse),\n time: Date.now(),\n id: hash ?? uuid(),\n chainId: hexChainId,\n networkClientId: snapId ?? 'mainnet',\n txParams: { from: selectedAccountAddress, data: tradeData },\n type: isBridgeTx ? TransactionType.bridge : TransactionType.swap,\n status: TransactionStatus.submitted,\n hash, // Add the transaction signature as hash\n origin: snapId,\n // Add an explicit flag to mark this as a non-EVM transaction\n isSolana: true, // TODO deprecate this and use chainId to detect non-EVM chains\n isBridgeTx,\n };\n};\n\n/**\n * Submits the transaction to the snap using the new unified ClientRequest interface\n * Works for all non-EVM chains (Solana, BTC, Tron)\n * This adds an approval tx to the ApprovalsController in the background\n * The client needs to handle the approval tx by redirecting to the confirmation page with the approvalTxId in the URL\n *\n * @param messenger - The BridgeStatusControllerMessenger instance\n * @param trade - The trade data (can be approval or main trade)\n * @param quoteResponse - The quote response containing metadata\n * @param selectedAccount - The account to submit the transaction for\n * @returns The transaction meta\n */\nexport const handleNonEvmTx = async (\n messenger: BridgeStatusControllerMessenger,\n trade: Trade,\n quoteResponse: QuoteResponse<Trade, Trade> & QuoteMetadata,\n selectedAccount: AccountsControllerState['internalAccounts']['accounts'][string],\n): Promise<TransactionMeta> => {\n if (!selectedAccount.metadata?.snap?.id) {\n throw new Error(\n 'Failed to submit cross-chain swap transaction: undefined snap id',\n );\n }\n\n const request = getClientRequest(\n trade,\n quoteResponse.quote.srcChainId,\n selectedAccount.id,\n selectedAccount.metadata?.snap?.id,\n );\n const requestResponse = (await messenger.call(\n 'SnapController:handleRequest',\n request,\n )) as\n | string\n | { transactionId: string }\n | { result: Record<string, string> }\n | { signature: string };\n\n const txMeta = handleNonEvmTxResponse(\n requestResponse,\n trade,\n quoteResponse,\n selectedAccount,\n );\n\n // TODO remove this eventually, just returning it now to match extension behavior\n // OR if the snap can propagate the snapRequestId or keyringReqId to the ApprovalsController, this can return the approvalTxId instead and clients won't need to subscribe to the ApprovalsController state to redirect\n return txMeta;\n};\n"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getApprovalTraceParams = exports.getTraceParams = void 0;
|
|
4
|
+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
5
|
+
const bridge_controller_1 = require("@metamask/bridge-controller");
|
|
6
|
+
const constants_1 = require("../constants.cjs");
|
|
7
|
+
const getTraceParams = (quoteResponse, isStxEnabledOnClient) => {
|
|
8
|
+
return {
|
|
9
|
+
name: (0, bridge_controller_1.isCrossChain)(quoteResponse.quote.srcChainId, quoteResponse.quote.destChainId)
|
|
10
|
+
? constants_1.TraceName.BridgeTransactionCompleted
|
|
11
|
+
: constants_1.TraceName.SwapTransactionCompleted,
|
|
12
|
+
data: {
|
|
13
|
+
srcChainId: (0, bridge_controller_1.formatChainIdToCaip)(quoteResponse.quote.srcChainId),
|
|
14
|
+
stxEnabled: isStxEnabledOnClient,
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
exports.getTraceParams = getTraceParams;
|
|
19
|
+
const getApprovalTraceParams = (quoteResponse, isStxEnabledOnClient) => {
|
|
20
|
+
return {
|
|
21
|
+
name: (0, bridge_controller_1.isCrossChain)(quoteResponse.quote.srcChainId, quoteResponse.quote.destChainId)
|
|
22
|
+
? constants_1.TraceName.BridgeTransactionApprovalCompleted
|
|
23
|
+
: constants_1.TraceName.SwapTransactionApprovalCompleted,
|
|
24
|
+
data: {
|
|
25
|
+
srcChainId: (0, bridge_controller_1.formatChainIdToCaip)(quoteResponse.quote.srcChainId),
|
|
26
|
+
stxEnabled: isStxEnabledOnClient,
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
exports.getApprovalTraceParams = getApprovalTraceParams;
|
|
31
|
+
//# sourceMappingURL=trace.cjs.map
|