MetaMask / MetaMask/connect-monorepo
@metamask/connect-evm v0.9.0 uses browser transport (window.postMessage) on React Native instead of WebSocket relay
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 12
- Forks
- 11
- PR merge metrics
- No merged PRs in 30d
Description
## Bug Description
`@metamask/connect-evm` v0.9.0 does not work on React Native because it resolves to the browser transport (`windowPostMessageTransport`) instead of the React Native WebSocket transport.
## Root Cause
The package resolution chain breaks on React Native:
1. `@metamask/connect-evm` has **no `react-native` export** in `package.json`:
```json
// connect-evm/package.json exports
".": {
"import": "...",
"require": "...",
"default": "..."
// ❌ No "react-native" condition
}
```
2. `@metamask/multichain-api-client` also has **no `react-native` export**:
```json
// multichain-api-client/package.json exports
".": {
"import": "...",
"require": "..."
// ❌ No "react-native" condition
}
```
3. `@metamask/connect-multichain` **does** have a `react-native` export with `WebSocketTransport` (using `wss://mm-sdk-relay.api.cx.metamask.io`), but it's never reached because:
4. The `DefaultTransport` class in `connect-multichain` imports `getDefaultTransport()` from `@metamask/multichain-api-client`, which always returns `windowPostMessageTransport` — a browser-only transport using `window.postMessage()`.
## Result
On React Native:
- `client.connect()` hangs indefinitely — `window.postMessage()` is a no-op
- `window.addEventListener('message', ...)` never receives responses
- MetaMask deep link is never triggered (the SDK never reaches that code path)
- No error is thrown — the connection just silently hangs
## Expected Behavior
`createEVMClient()` should use the `WebSocketTransport` (Centrifuge relay at `wss://mm-sdk-relay.api.cx.metamask.io`) when running on React Native, as shown in the [React Native quickstart docs](https://docs.metamask.io/metamask-connect/evm/quickstart/react-native/).
## Environment
- `@metamask/connect-evm`: 0.9.0
- `@metamask/connect-multichain`: 0.11.0 (bundled)
- `@metamask/multichain-api-client`: 0.3.0
- `@metamask/mobile-wallet-protocol-core`: 0.4.0
- React Native: 0.81.5
- Expo: 54
- Metro bundler
- Android (Samsung Galaxy)
## Suggested Fix
Add `"react-native"` condition to the `exports` field in both:
1. `@metamask/connect-evm/package.json`
2. `@metamask/multichain-api-client/package.json`
Or ensure `DefaultTransport` in `connect-multichain` checks the platform and uses `WebSocketTransport` when `window.postMessage` is not available (i.e., React Native environment).
## Reproduction
```bash
npx expo init test-app
cd test-app
npm install @metamask/connect-evm react-native-get-random-values readable-stream
npx expo prebuild
```
```typescript
import { createEVMClient } from '@metamask/connect-evm';
const client = await createEVMClient({
dapp: { name: 'Test', url: 'https://test.com' },
api: { supportedNetworks: { '0x1': 'https://eth.llamarpc.com' } },
mobile: { preferredOpenLink: (url) => Linking.openURL(url) },
});
// This hangs forever — never opens MetaMask
await client.connect({ chainIds: ['0x1'] });
```
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Inspect the package.json exports for @metamask/connect-evm and @metamask/multichain-api-client, then trace DefaultTransport in connect-multichain and its getDefaultTransport import. Reproduce the Expo/React Native example and verify that createEVMClient().connect() uses the WebSocket relay, opens the MetaMask deep link, and no longer hangs.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react-native, typescript
- Domain
- mobile-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100