Local EIP-1193 bridge
The Rust process binds only to 127.0.0.1 (default ws://127.0.0.1:21337/ws). Clients must supply the random/operator-provided token as the token query parameter or a bearer header. Browser origins can be restricted with repeatable/comma-delimited --allowed-origin values.
At startup the bridge resolves the configured RPC chain ID and fixes that as the active chain context. It does not switch RPCs at a dapp's request.
Supported methods
Wallet methods:
eth_accounts— returns the account only after account access was approved.eth_requestAccounts— deny-by-default CLI approval; emitsaccountsChangedafter approval.eth_chainId— the configured RPC's startup chain ID.personal_sign— validates the unlocked account and shows message format, byte length, and a bounded preview.eth_signTypedData_v4— validates the account and, when present, the EIP-712 domain chain ID; shows domain and message details.eth_sendTransaction— requiresfrom, validates account and optional chain ID, shows destination/value/calldata/fee fields, then signs and broadcasts through the configured RPC.wallet_switchEthereumChain— succeeds only when the requested chain already equals the fixed active chain; otherwise returns4901.
Read-only RPC forwarding allowlist:
eth_blockNumber,eth_call,eth_estimateGas,eth_feeHistory,eth_gasPriceeth_getBalance,eth_getBlockByHash,eth_getBlockByNumber,eth_getCode,eth_getLogs,eth_getStorageAteth_getTransactionByHash,eth_getTransactionCount,eth_getTransactionReceipteth_maxPriorityFeePerGas,eth_syncing,net_version,web3_clientVersion
Everything else returns -32601; malformed parameters return -32602; unauthorized account operations return 4100; unsupported chains return 4901; user rejection returns 4001. Upstream RPC failures preserve their JSON-RPC code/message when possible.
Approval and security model
Signatures and transactions always take the serialized prompt lock and require an interactive CLI confirmation defaulting to No. --auto-approve applies only to the account-access prompt and cannot bypass a signature or transaction prompt. The TypeScript bridge exposes only EIP-1193 requests; no method returns key material or accepts a raw digest for signing.
For the demo, use an explicit browser origin:
cargo run -- --serve --wallet 0xYourAccount \
--rpc-url https://your-sepolia-rpc.example \
--allowed-origin http://127.0.0.1:5173
The token travels in the WebSocket URL because browser WebSocket APIs cannot set an authorization header. Treat it as an ephemeral local capability: do not reuse it, paste it into dapps, or expose browser history/debug output.