Skip to content

Conversation

ghgoodreau
Copy link
Contributor

@ghgoodreau ghgoodreau commented Sep 3, 2025

Explanation

This PR extends the bridge controller to support Bitcoin transactions, building on the existing Solana support to create a more generic non-EVM chain handling system.

Current state: The bridge controller currently only supports EVM chains and Solana for cross-chain transactions.

Solution: This PR:

  • Renames Solana-specific functions and types to be generic for all non-EVM chains (NonEvmFees
    instead of SolanaFees, handleNonEvmTx instead of handleSolanaTx)
  • Adds support for Bitcoin transactions using PSBT (Partially Signed Bitcoin Transaction) format
  • Updates the Snap interface to use the new unified computeFee and signAndSendTransaction methods
    that work across all non-EVM chains
  • Maintains backward compatibility while deprecating Solana-specific naming

Key changes:

  • The nonEvmFeesInNative field now stores fees in the smallest units for each chain
  • Transaction handling now detects Bitcoin PSBT format alongside string trade data

References

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed, highlighting breaking changes as necessary
  • I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes

@ghgoodreau ghgoodreau requested a review from a team as a code owner September 3, 2025 20:31
@ghgoodreau ghgoodreau marked this pull request as draft September 3, 2025 20:31
cursor[bot]

This comment was marked as outdated.

@ghgoodreau ghgoodreau changed the title DRAFT: SWAPS-2839 updates snap methods to new interface in bridge controller SWAPS-2839 updates snap methods to new interface in bridge controller Sep 8, 2025
@ghgoodreau ghgoodreau marked this pull request as ready for review September 8, 2025 18:42
@ghgoodreau ghgoodreau requested a review from a team as a code owner September 8, 2025 18:42
@ghgoodreau ghgoodreau marked this pull request as draft September 9, 2025 15:27
Copy link

@aganglada aganglada left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the confusion on the spec. The ClientRequest: bit was only to outline it it's an onClientRequest

Comment on lines 13 to 14
import { toHex } from '@metamask/controller-utils';
import { SolScope } from '@metamask/keyring-api';
import type {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice! I believe you can remove keyring-api from the package.json as well

{ exchangeRate, usdExchangeRate }: ExchangeRate,
chainId: string | number,
) => {
const { nonEvmFeesInNative } = bridgeQuote;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For 1 SOL, is nonEvmFeesInNative equal to 1000000000 or 1?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For 1 SOL, nonEvmFeesInNative equals 1000000000, and the calcNonEvmTotalNetworkFee function converts this to 1 SOL by dividing by 10^9

@ghgoodreau ghgoodreau marked this pull request as ready for review September 11, 2025 20:25
cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

@ghgoodreau ghgoodreau changed the title SWAPS-2839 updates snap methods to new interface in bridge controller SWAPS-2839 update bridge controllers for bitcoin Sep 17, 2025
export type SolanaFees = {
solanaFeesInLamports?: string; // solana fees in lamports, appended by BridgeController.#appendSolanaFees
export type NonEvmFees = {
nonEvmFeesInNative?: string; // Non-EVM chain fees in smallest units (lamports for Solana, satoshis for BTC, sun for Tron)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I've been calling them atomic units

* @param chainId - The chain ID to check
* @returns True if the chain is a supported non-EVM chain, false otherwise
*/
export const isNonEvmChainId = (
Copy link
Contributor

@infiniteflower infiniteflower Sep 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if there's an easier way, otherwise we need to keep updating this for every single new non EVM network

How about:

  1. Convert chainId to CAIP
  2. Check CAIP namespace for eip155
  3. If eip155, then it's EVM

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that idea! It does add some testing scope whereas the current functionality is already tested and working. Is this blocking? If not, I'd prefer to get these changes released to unblock the client PR, and then can update the function next week. Let me know what you think and I can add a // TODO comment @infiniteflower

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

if (isSolanaChainId(chainId)) {
// Solana fees are stored in lamports (smallest units), need to convert to SOL
const decimals = 9;
feeInNative = calcTokenAmount(nonEvmFeesInNative ?? '0', decimals);
Copy link
Member

@micaelae micaelae Sep 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we convert the SOL amount to lamports in bridge-controller.ts if we need to convert it back to SOL here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants