@metamask-previews/bridge-status-controller 74.0.1-preview-9e722dac3 → 74.0.1-preview-8f30863fb

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 CHANGED
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Fixed
11
+
12
+ - Only include `sourceAssetId` and `destAssetId` in the snap request options for Stellar trades
13
+ - Previously these options were passed for all non-EVM trades, which broke Bitcoin bridging/swapping because the Bitcoin snap strictly validates the request and rejects unexpected fields.
14
+
10
15
  ## [74.0.1]
11
16
 
12
17
  ### Changed
@@ -52,15 +52,20 @@ const getClientRequest = (trade, srcChainId, accountId, snapId, sourceAssetId, d
52
52
  const scope = (0, bridge_controller_1.formatChainIdToCaip)(srcChainId);
53
53
  const transaction = (0, bridge_controller_1.extractTradeData)(trade);
54
54
  let options;
55
- if (sourceAssetId !== undefined || destAssetId !== undefined) {
56
- options = {
57
- ...(sourceAssetId !== undefined && {
58
- sourceAssetId,
59
- }),
60
- ...(destAssetId !== undefined && {
61
- destAssetId,
62
- }),
63
- };
55
+ // Only Stellar trades expect asset IDs in the request options. Passing them
56
+ // for other non-EVM chains (e.g. Bitcoin) breaks strict snap request
57
+ // validation and prevents the transaction from being broadcast.
58
+ if ((0, bridge_controller_1.isStellarTrade)(trade)) {
59
+ if (sourceAssetId !== undefined || destAssetId !== undefined) {
60
+ options = {
61
+ ...(sourceAssetId !== undefined && {
62
+ sourceAssetId,
63
+ }),
64
+ ...(destAssetId !== undefined && {
65
+ destAssetId,
66
+ }),
67
+ };
68
+ }
64
69
  }
65
70
  if ((0, bridge_controller_1.isTronTrade)(trade)) {
66
71
  // Tron trades need the visible flag and contract type to be included in the request options
@@ -1 +1 @@
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 { SnapController } from '@metamask/snaps-controllers';\nimport {\n CHAIN_IDS,\n TransactionStatus,\n TransactionType,\n} from '@metamask/transaction-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { CaipAssetType, 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 account ID\n * @param snapId - The snap ID\n * @param sourceAssetId - The source asset ID\n * @param destAssetId - The destination asset ID\n * @returns The snap request object for signing and sending transaction\n */\nexport const getClientRequest = (\n trade: Trade,\n srcChainId: number,\n accountId: AccountsControllerState['internalAccounts']['accounts'][string]['id'],\n snapId: string,\n sourceAssetId?: CaipAssetType,\n destAssetId?: CaipAssetType,\n): Parameters<SnapController['handleRequest']>[0] => {\n const scope = formatChainIdToCaip(srcChainId);\n\n const transaction = extractTradeData(trade);\n\n let options: Record<string, unknown> | undefined;\n\n if (sourceAssetId !== undefined || destAssetId !== undefined) {\n options = {\n ...(sourceAssetId !== undefined && {\n sourceAssetId,\n }),\n ...(destAssetId !== undefined && {\n destAssetId,\n }),\n };\n }\n\n if (isTronTrade(trade)) {\n // Tron trades need the visible flag and contract type to be included in the request options\n options = {\n visible: trade.visible,\n type: trade.raw_data?.contract?.[0]?.type,\n };\n }\n\n return createClientTransactionRequest(\n snapId,\n transaction,\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 = CHAIN_IDS.MAINNET; // 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 quoteResponse.quote.srcAsset.assetId,\n quoteResponse.quote.destAsset.assetId,\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"]}
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 isStellarTrade,\n isTronTrade,\n} from '@metamask/bridge-controller';\nimport { SnapController } from '@metamask/snaps-controllers';\nimport {\n CHAIN_IDS,\n TransactionStatus,\n TransactionType,\n} from '@metamask/transaction-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { CaipAssetType, 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 account ID\n * @param snapId - The snap ID\n * @param sourceAssetId - The source asset ID\n * @param destAssetId - The destination asset ID\n * @returns The snap request object for signing and sending transaction\n */\nexport const getClientRequest = (\n trade: Trade,\n srcChainId: number,\n accountId: AccountsControllerState['internalAccounts']['accounts'][string]['id'],\n snapId: string,\n sourceAssetId?: CaipAssetType,\n destAssetId?: CaipAssetType,\n): Parameters<SnapController['handleRequest']>[0] => {\n const scope = formatChainIdToCaip(srcChainId);\n\n const transaction = extractTradeData(trade);\n\n let options: Record<string, unknown> | undefined;\n\n // Only Stellar trades expect asset IDs in the request options. Passing them\n // for other non-EVM chains (e.g. Bitcoin) breaks strict snap request\n // validation and prevents the transaction from being broadcast.\n if (isStellarTrade(trade)) {\n if (sourceAssetId !== undefined || destAssetId !== undefined) {\n options = {\n ...(sourceAssetId !== undefined && {\n sourceAssetId,\n }),\n ...(destAssetId !== undefined && {\n destAssetId,\n }),\n };\n }\n }\n\n if (isTronTrade(trade)) {\n // Tron trades need the visible flag and contract type to be included in the request options\n options = {\n visible: trade.visible,\n type: trade.raw_data?.contract?.[0]?.type,\n };\n }\n\n return createClientTransactionRequest(\n snapId,\n transaction,\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 = CHAIN_IDS.MAINNET; // 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 quoteResponse.quote.srcAsset.assetId,\n quoteResponse.quote.destAsset.assetId,\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"]}
@@ -1 +1 @@
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;AAQrC,OAAO,EAAE,cAAc,EAAE,oCAAoC;AAM7D,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAO,wBAAwB;AAGvE,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;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gBAAgB,UACpB,KAAK,cACA,MAAM,aACP,uBAAuB,CAAC,kBAAkB,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,UACxE,MAAM,kBACE,aAAa,gBACf,aAAa,KAC1B,WAAW,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAiC/C,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,CAkCzB,CAAC"}
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;AASrC,OAAO,EAAE,cAAc,EAAE,oCAAoC;AAM7D,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAO,wBAAwB;AAGvE,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;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gBAAgB,UACpB,KAAK,cACA,MAAM,aACP,uBAAuB,CAAC,kBAAkB,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,UACxE,MAAM,kBACE,aAAa,gBACf,aAAa,KAC1B,WAAW,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAsC/C,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,CAkCzB,CAAC"}
@@ -1 +1 @@
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;AAQrC,OAAO,EAAE,cAAc,EAAE,oCAAoC;AAM7D,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAO,wBAAwB;AAGvE,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;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gBAAgB,UACpB,KAAK,cACA,MAAM,aACP,uBAAuB,CAAC,kBAAkB,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,UACxE,MAAM,kBACE,aAAa,gBACf,aAAa,KAC1B,WAAW,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAiC/C,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,CAkCzB,CAAC"}
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;AASrC,OAAO,EAAE,cAAc,EAAE,oCAAoC;AAM7D,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAO,wBAAwB;AAGvE,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;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gBAAgB,UACpB,KAAK,cACA,MAAM,aACP,uBAAuB,CAAC,kBAAkB,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,UACxE,MAAM,kBACE,aAAa,gBACf,aAAa,KAC1B,WAAW,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAsC/C,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,CAkCzB,CAAC"}
@@ -1,4 +1,4 @@
1
- import { extractTradeData, formatChainIdToCaip, formatChainIdToHex, isCrossChain, isTronTrade } from "@metamask/bridge-controller";
1
+ import { extractTradeData, formatChainIdToCaip, formatChainIdToHex, isCrossChain, isStellarTrade, isTronTrade } from "@metamask/bridge-controller";
2
2
  import { SnapController } from "@metamask/snaps-controllers";
3
3
  import { CHAIN_IDS, TransactionStatus, TransactionType } from "@metamask/transaction-controller";
4
4
  import { v4 as uuid } from "uuid";
@@ -48,15 +48,20 @@ export const getClientRequest = (trade, srcChainId, accountId, snapId, sourceAss
48
48
  const scope = formatChainIdToCaip(srcChainId);
49
49
  const transaction = extractTradeData(trade);
50
50
  let options;
51
- if (sourceAssetId !== undefined || destAssetId !== undefined) {
52
- options = {
53
- ...(sourceAssetId !== undefined && {
54
- sourceAssetId,
55
- }),
56
- ...(destAssetId !== undefined && {
57
- destAssetId,
58
- }),
59
- };
51
+ // Only Stellar trades expect asset IDs in the request options. Passing them
52
+ // for other non-EVM chains (e.g. Bitcoin) breaks strict snap request
53
+ // validation and prevents the transaction from being broadcast.
54
+ if (isStellarTrade(trade)) {
55
+ if (sourceAssetId !== undefined || destAssetId !== undefined) {
56
+ options = {
57
+ ...(sourceAssetId !== undefined && {
58
+ sourceAssetId,
59
+ }),
60
+ ...(destAssetId !== undefined && {
61
+ destAssetId,
62
+ }),
63
+ };
64
+ }
60
65
  }
61
66
  if (isTronTrade(trade)) {
62
67
  // Tron trades need the visible flag and contract type to be included in the request options
@@ -1 +1 @@
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 { SnapController } from '@metamask/snaps-controllers';\nimport {\n CHAIN_IDS,\n TransactionStatus,\n TransactionType,\n} from '@metamask/transaction-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { CaipAssetType, 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 account ID\n * @param snapId - The snap ID\n * @param sourceAssetId - The source asset ID\n * @param destAssetId - The destination asset ID\n * @returns The snap request object for signing and sending transaction\n */\nexport const getClientRequest = (\n trade: Trade,\n srcChainId: number,\n accountId: AccountsControllerState['internalAccounts']['accounts'][string]['id'],\n snapId: string,\n sourceAssetId?: CaipAssetType,\n destAssetId?: CaipAssetType,\n): Parameters<SnapController['handleRequest']>[0] => {\n const scope = formatChainIdToCaip(srcChainId);\n\n const transaction = extractTradeData(trade);\n\n let options: Record<string, unknown> | undefined;\n\n if (sourceAssetId !== undefined || destAssetId !== undefined) {\n options = {\n ...(sourceAssetId !== undefined && {\n sourceAssetId,\n }),\n ...(destAssetId !== undefined && {\n destAssetId,\n }),\n };\n }\n\n if (isTronTrade(trade)) {\n // Tron trades need the visible flag and contract type to be included in the request options\n options = {\n visible: trade.visible,\n type: trade.raw_data?.contract?.[0]?.type,\n };\n }\n\n return createClientTransactionRequest(\n snapId,\n transaction,\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 = CHAIN_IDS.MAINNET; // 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 quoteResponse.quote.srcAsset.assetId,\n quoteResponse.quote.destAsset.assetId,\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"]}
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 isStellarTrade,\n isTronTrade,\n} from '@metamask/bridge-controller';\nimport { SnapController } from '@metamask/snaps-controllers';\nimport {\n CHAIN_IDS,\n TransactionStatus,\n TransactionType,\n} from '@metamask/transaction-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { CaipAssetType, 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 account ID\n * @param snapId - The snap ID\n * @param sourceAssetId - The source asset ID\n * @param destAssetId - The destination asset ID\n * @returns The snap request object for signing and sending transaction\n */\nexport const getClientRequest = (\n trade: Trade,\n srcChainId: number,\n accountId: AccountsControllerState['internalAccounts']['accounts'][string]['id'],\n snapId: string,\n sourceAssetId?: CaipAssetType,\n destAssetId?: CaipAssetType,\n): Parameters<SnapController['handleRequest']>[0] => {\n const scope = formatChainIdToCaip(srcChainId);\n\n const transaction = extractTradeData(trade);\n\n let options: Record<string, unknown> | undefined;\n\n // Only Stellar trades expect asset IDs in the request options. Passing them\n // for other non-EVM chains (e.g. Bitcoin) breaks strict snap request\n // validation and prevents the transaction from being broadcast.\n if (isStellarTrade(trade)) {\n if (sourceAssetId !== undefined || destAssetId !== undefined) {\n options = {\n ...(sourceAssetId !== undefined && {\n sourceAssetId,\n }),\n ...(destAssetId !== undefined && {\n destAssetId,\n }),\n };\n }\n }\n\n if (isTronTrade(trade)) {\n // Tron trades need the visible flag and contract type to be included in the request options\n options = {\n visible: trade.visible,\n type: trade.raw_data?.contract?.[0]?.type,\n };\n }\n\n return createClientTransactionRequest(\n snapId,\n transaction,\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 = CHAIN_IDS.MAINNET; // 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 quoteResponse.quote.srcAsset.assetId,\n quoteResponse.quote.destAsset.assetId,\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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/bridge-status-controller",
3
- "version": "74.0.1-preview-9e722dac3",
3
+ "version": "74.0.1-preview-8f30863fb",
4
4
  "description": "Manages bridge-related status fetching functionality for MetaMask",
5
5
  "keywords": [
6
6
  "Ethereum",