Skip to content

Conversation

rplusq
Copy link
Contributor

@rplusq rplusq commented Jun 21, 2025

Summary

  • Refactors browser wallet support into a dedicated crate for better modularity
  • Implements browser wallet integration (MetaMask, etc.) for Foundry tools
  • Addresses issue feat(periphery): support to invoke metamask #6556
  • Adds support for transaction sending, contract deployment, and message signing

Motivation

Browser wallets like MetaMask are widely used in the Ethereum ecosystem. This PR adds native support for browser wallets in Foundry, making it more accessible to developers who prefer using their browser wallets for signing transactions.

Solution

This implementation follows the Moccasin pattern with a local HTTP server that bridges between the CLI and browser wallet:

  1. HTTP Server Bridge: When --browser flag is used, Foundry starts a local server and opens a browser window
  2. Queue-based Communication: Transactions and signing requests are queued and processed asynchronously
  3. Web Interface: Clean, minimal interface that handles wallet connections and transaction approvals

What's Implemented

Commands with Full Support

  • cast send --browser - Send transactions via browser wallet
  • forge create --browser - Deploy contracts via browser wallet
  • cast wallet sign --browser - Message signing with both personal_sign and eth_signTypedData_v4

Commands with Limited/No Support

  • cast mktx --browser - Shows clear error (browser wallets can't create offline transactions)
  • forge script --browser - Not implemented (architectural incompatibility explained below)

Architectural Decisions

New Dedicated Crate

Browser wallet functionality has been extracted into a dedicated foundry-browser-wallet crate for:

  • Better separation of concerns
  • Easier maintenance and testing
  • Clear API boundaries

Why forge script is not supported

Forge script's execution model is fundamentally incompatible with browser wallets:

  • Forge script uses separate sign/broadcast steps for transaction management
  • Browser wallets only support atomic eth_sendTransaction (sign+send together)
  • This mismatch makes it impossible to integrate without major architectural changes

Users who need browser wallet deployments should use forge create instead.

Implementation Details

  • Uses axum for the HTTP server
  • Follows EIP-1193 standard for wallet interaction
  • Includes retry logic for wallet detection
  • Comprehensive error handling and timeouts
  • Full test suite with integration tests

API Documentation

The browser wallet HTTP API and message types are fully documented in crates/browser-wallet/README.md. The API includes:

  • HTTP Endpoints: RESTful API for communication between CLI and browser

    • /api/heartbeat - Health check and connection status
    • /api/transaction/pending - Retrieve pending transactions
    • /api/transaction/response - Submit transaction results
    • /api/sign/pending - Retrieve pending signing requests
    • /api/sign/response - Submit signing results
    • /api/network - Get network configuration
    • /api/account - Update wallet connection status
  • Message Types: Strongly-typed request/response formats

    • BrowserTransaction - Transaction request wrapper
    • SignRequest - Message signing requests
    • TransactionResponse - Transaction execution results
    • SignResponse - Signing operation results
  • Standards Compliance:

    • EIP-1193 for Ethereum Provider JavaScript API
    • EIP-712 for typed data signing
    • JSON-RPC 2.0 for communication protocol

See the full API reference in the browser-wallet README.

Testing

  • Run cargo test -p foundry-browser-wallet to run browser wallet tests
  • Comprehensive integration test suite covering:
    • Connection management
    • Transaction handling
    • Message signing
    • Security features
    • State persistence
  • Manual testing done with MetaMask and Rabby

Breaking Changes

None - this is a new feature that doesn't affect existing functionality.

Closes #6556

Files Changed

Refactoring (Browser Wallet Extraction)

  • crates/browser-wallet/ - New dedicated crate for browser wallet functionality
    • Cargo.toml - Crate configuration
    • README.md - API documentation and usage guide
    • src/lib.rs - Public API and message types
    • src/server.rs - HTTP server implementation
    • src/signer.rs - Alloy signer trait implementation
    • src/state.rs - Shared state management
    • src/error.rs - Error types
    • src/assets.rs - Embedded web assets
    • src/assets/web/ - Enhanced web interface (HTML, CSS, JS)
    • src/tests.rs - Unit tests
    • tests/integration/ - Comprehensive integration tests

Updates to Existing Files

  • Cargo.lock - Updated dependencies
  • Cargo.toml - Added browser-wallet crate to workspace
  • crates/cast/src/cmd/send.rs - Updated to use new browser wallet crate
  • crates/wallets/Cargo.toml - Removed browser wallet dependencies
  • crates/wallets/src/ - Removed browser wallet code (moved to dedicated crate)

Testing Instructions

# Test cast send
cast send 0x... --value 0.1ether --browser

# Test forge create
forge create MyContract --browser

# Test message signing
cast wallet sign "Hello World" --browser

# Run tests
cargo test -p foundry-browser-wallet

Video Demo

cast wallet sign --browser

demo.on.cast.wallet.sign.--browser.mp4

@rplusq rplusq changed the title feat(cast): add browser wallet support feat: add browser wallet support Jun 21, 2025
Copy link
Member

@mattsse mattsse left a comment

Choose a reason for hiding this comment

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

this looks decent,

not opposed to this but what I'm missing from this is some API specs or references.

@rplusq
Copy link
Contributor Author

rplusq commented Jun 23, 2025

Thanks for the feedback, @mattsse. Applied.

@rplusq rplusq requested a review from mattsse June 23, 2025 14:05
@rplusq rplusq force-pushed the feat/browser-wallet-support branch from a53dda8 to 1f5bcf6 Compare June 27, 2025 10:25
rplusq and others added 7 commits June 27, 2025 13:59
Implements browser wallet integration (MetaMask, etc.) for Foundry tools,
addressing issue foundry-rs#6556.

- New `browser` wallet type with HTTP server bridge
- Web interface for wallet interaction following Moccasin pattern
- Queue-based communication between CLI and browser
- Support for multiple wallet types (MetaMask, Rabby, etc.)

- `cast send --browser`: Full support for sending transactions
- `cast mktx --browser`: Clear error message explaining architectural limitation
- `forge create --browser`: Full support for contract deployment
- Message signing: Support for personal_sign and eth_signTypedData_v4

- Automatic browser opening when --browser flag is used
- Connection state management with proper initialization
- Transaction approval flow with user confirmation
- Message signing for both personal messages and typed data
- Hardware wallet security reminder in UI
- Comprehensive error handling and timeout management

Browser wallets are architecturally incompatible with forge script's execution model.
Forge script requires separate sign/broadcast steps, while browser wallets only
support atomic eth_sendTransaction. Users should use forge create for deployments
or consider alternative wallet options for scripting.

This command creates offline transactions, which browser wallets cannot do.
The implementation provides a clear error message directing users to use
`cast send` instead.

- Uses axum for HTTP server
- Follows EIP-1193 standard for wallet interaction
- Implements proper async/await patterns for transaction handling
- Includes comprehensive test suite for browser wallet functionality

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Changed reqwest in foundry-wallets dev-dependencies to use workspace = true
- This ensures it inherits the rustls-tls feature instead of default-tls
- Fixes cargo deny error about banned openssl dependency

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
@rplusq rplusq force-pushed the feat/browser-wallet-support branch from 92e3a3f to f12f07e Compare June 27, 2025 12:59
@onbjerg
Copy link
Collaborator

onbjerg commented Aug 21, 2025

Hi @rplusq, this is very cool and we really appreciate you for writing up this PR, however we have decided not to merge this.

This is solely due to the fact that we do not think encouraging people to use their web browser wallets to deploy is a good idea from a security standpoint. Instead, people should opt to use KMS or hardware wallets for real deployments, as these are generally more secure and less likely to be compromised, and in turn less likely to compromise the deployments people make using Foundry.

We think of web extension wallets as end-user wallets to interact with apps, not to deploy and secure protocols.

Thank you for putting this together, we appreciate the time you spent on this.

@PatrickAlphaC
Copy link

PatrickAlphaC commented Aug 21, 2025

Hi @onbjerg, the advantage of Metamask/Web Wallet is the most wallets will have compatibility with a software wallet, and a user can connect almost any hardware wallet to the software wallet to deploy.

The disadvantage of not implementing this, is now foundry is a bit of a "king maker" in the sense that only the following are currently supported:

  • trezor
  • ledger
  • aws

This means that:

  • GCP, Digital Ocean, etc are not compatible with foundry
  • All other hardware wallets like OneKey, BitBox, Keystone, Lattice1, etc cannot be used as hardware wallets to deploy/script.

This essentially forces developers to buy either trezor or ledger... Which doesn't seem correct.

Or you actually encourage people to export their private keys from unsupported hardware wallets, which I would argue is much worse from a security standpoint.

The reason I am advocating for this feature, is that at Cyfrin, we still get private keys sent to us by mistake, and it seems that if you just have "the wrong" hardware wallet, you're forced to export your private key if you use foundry.

We could have foundry just "support all hardware wallets" but that doesn't scale great...

@duncancmt
Copy link

Chiming in here to emphasize @PatrickAlphaC 's point about hardware wallet compatibility. Foundry has support for only Ledger and Trezor. Other hardware wallets (i.e. BitBox, Tangem, Keystone, GridPlus Lattice1) are not possible to connect to Foundry without going through some kind of extension wallet software. So this is cutting off a lot of options for key custody. And for wallets like Keystone and GridPlus Lattice1, the ability to inspect the transaction on a screen that is part of the wallet's secure enclave is a killer feature that neither Ledger nor Trezor support.

@onbjerg
Copy link
Collaborator

onbjerg commented Aug 21, 2025

I think a better solution for that would IMO to offer up some sort of extensible protocol for people to ship their own extensions/wrappers around the hardware wallets. I don't think we want to maintain a web server + API + frontend to enable browser wallets, given the above still.

We can't realistically ship support for every hardware wallet, given there is no standardized API. But we can provide a standard way to use hardware wallets that are not supported by Foundry natively by making an API ourselves, and have others maintain the integrations.

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

Successfully merging this pull request may close these issues.

feat(periphery): support to invoke metamask
5 participants