What you need to know: Add the EVM extension from the Chains table on Adding extensions. You need at least one EVM extension to support Ethereum-compatible chains. There are only two kinds of wallet: embedded and external. Each extension below lets you support one or both for EVM.
window.ethereum, or Dynamic embedded wallets). Enable the EVM chain in the Dynamic dashboard as well.
Installation
Default EVM extension
If you wish to support the standard EVM wallets and Dynamic embedded wallets, you can add the default EVM extension to your client using theaddEvmExtension method.
Standalone EVM extensions
If you want to be more granular, you can add the standalone EVM extensions individually to your client.EIP-6963 extension
Window-injected extension
When users open your app inside a wallet’s built-in browser (e.g. MetaMask Mobile, Trust Wallet, Coinbase Wallet), the wallet injects its provider intowindow.ethereum rather than announcing via EIP-6963. Use this
extension as a fallback to support those environments:
addEIP6963Extension, EIP-6963 providers take priority automatically — so if a
wallet supports both, the EIP-6963 version is used.
WAAS EVM extension
Base Account extension
Adds support for Base Account — Coinbase’s popup / QR flow that surfaces both Coinbase Smart Wallet (passkey-backed ERC-4337 contract wallet atkeys.coinbase.com) and Coinbase Wallet (EOA). It complements, rather than replaces, the EIP-6963 and window-injected paths, which continue to handle the Coinbase Wallet browser extension.
preference.options to control which Base Account flavor(s) appear in the popup:
Combining extensions
You can combine as many extensions as you want to support all the wallets you want to support.React
In React, register extensions at module level in the same file where you create the client — not inside components. This runs once when the module is first imported.React Native
Complete Setup on Bare React Native or Setup on Expo before adding an EVM extension — this section only covers a Metro-specific issue those guides don’t.Resolve Metro bundling errors
@dynamic-labs-sdk/evm uses viem internally, and viem depends on isows for its WebSocket transport. isows imports the Node-only ws package unconditionally, even though it only uses ws on Node — on React Native it picks the platform’s native WebSocket at runtime instead. Metro still has to resolve ws at bundle time, and ws isn’t Node-compatible: ws/lib/stream.js requires Node’s stream module (and transitively net/tls/zlib), none of which exist under Hermes, so the bundle fails with an error like Unable to resolve module stream.
This applies whenever
@dynamic-labs-sdk/evm is in your dependency tree on React Native — regardless of which extension you use, and whether you use viem directly yourself. If you also use @dynamic-labs-sdk/solana, you may separately need rpc-websockets version overrides — that’s an unrelated resolution issue in a different package.ws to a shim in metro.config.js. The only difference between Expo and bare React Native is which package provides getDefaultConfig:
- Bare React Native
- Expo
metro.config.js
isows calls — a WebSocket constructor — so subclass React Native’s built-in global rather than reimplementing it:
shims/ws.js