Skip to content

feat: add browser wallet support #10823

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

feat(periphery): support to invoke metamask
2 participants