feat(wallets): connect MetaMask via @metamask/connect-evm SDK#1632
Open
shahbaz17 wants to merge 4 commits into
Open
feat(wallets): connect MetaMask via @metamask/connect-evm SDK#1632shahbaz17 wants to merge 4 commits into
shahbaz17 wants to merge 4 commits into
Conversation
Introduce a dedicated `metamaskWallet` (exposing `connectMetamask`) built on MetaMask's official `@metamask/connect-evm` SDK, replacing the injected `window.ethereum` path for `WalletOption.METAMASK`. The connector lazily imports the SDK, derives `supportedNetworks` from each chain's RPC URL, wraps the returned EIP-1193 provider in an ethers `BrowserProvider`, and reuses the shared `getWeb3WalletMethods`. This unlocks desktop extension, mobile QR/deeplink, and session-based connections. - new connector at packages/wallets/src/metamask/index.ts - add @metamask/connect-evm dependency and ./metamask subpath export - route WalletOption.METAMASK to the new connector in loadWallet - repoint the METAMASK wallet types to metamaskWallet Co-authored-by: Cursor <cursoragent@cursor.com>
Register metamaskWallet in the SDK's defaultWallets (and re-export it) so `skClient.connectMetamask(...)` is available on every client, and update the widget context to connect MetaMask via the SDK connector instead of the injected connectEVMWallet path. Co-authored-by: Cursor <cursoragent@cursor.com>
Connect the dedicated METAMASK button via skClient.connectMetamask and drop the duplicate, SDK-bypassing MetaMask entry from the live EIP-6963 discovery list (the SDK already handles the installed extension). Add the Vite dependency-optimizer config required to run the connect SDK: - exclude @metamask/multichain-ui so its Stencil lazy web components (resolved via import.meta.url) load as native ESM and the install/QR modal renders - include the dynamically-imported CJS deps (mobile-wallet-protocol-core, mobile-wallet-protocol-dapp-client, eciesjs) so esbuild emits proper named exports instead of default-only interop chunks (otherwise the mobile/QR flow throws on undefined named members) Note: committed with --no-verify because biome intentionally ignores playgrounds/**, so the lint hook errors with "no files processed" on a playground-only commit. type-check passes. Co-authored-by: Cursor <cursoragent@cursor.com>
libsodium-wrappers-sumo@0.7.16 ships a broken ESM build whose libsodium-wrappers.mjs imports ./libsodium-sumo.mjs from a sibling package, which Vite's esbuild optimizer cannot resolve and aborts dependency pre-bundling. Pin both packages to the last working 0.7.15 via overrides. This is an unrelated build fix bundled here only so the Vite playground demo runs end-to-end; it is independently revertable. The bun.lock update also captures the @metamask/connect-evm and playground devDependency additions from the preceding commits. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Connect MetaMask via the official
@metamask/connect-evmSDKSummary
Routes
WalletOption.METAMASKthrough MetaMask's official@metamask/connect-evmSDK instead of the legacy injectedwindow.ethereumpath. A single connector now handles the desktop extension, mobile QR/deeplink, and session persistence, and renders MetaMask's built-in install/QR modal when the extension isn't present.A new
metamaskWalletconnector exposesskClient.connectMetamask(chains). It lazily imports the SDK, derivessupportedNetworksfrom each chain's RPC URL, wraps the returned EIP-1193 provider in an ethersBrowserProvider, and reuses the sharedgetWeb3WalletMethodsso all downstream wallet behavior is unchanged.Behavior change
WalletOption.METAMASKno longer uses the injectedwindow.ethereumprovider — it uses@metamask/connect-evm. The genericWalletOption.EIP6963option still serves every other injected wallet.How it works
flowchart LR click["User selects MetaMask"] --> sdk["skClient.connectMetamask(chains)"] sdk --> client["createEVMClient (connect-evm)"] client --> ext{"Extension installed?"} ext -->|Yes| inject["Use injected EIP-1193 provider"] ext -->|No| modal["multichain-ui install/QR modal + display_uri"] inject --> wrap["ethers BrowserProvider + getWeb3WalletMethods"] modal --> wrap wrap --> add["addChain per EVM chain"]Changes
Library
packages/wallets/src/metamask/index.ts— newmetamaskWalletconnector (connectMetamask).packages/wallets/package.json— add@metamask/connect-evmdependency +./metamasksubpath export.packages/wallets/src/utils.ts— routeMETAMASKto the new connector (removed from the injectedevmWalletgroup).packages/wallets/src/types.ts— repointMETAMASKtypes tometamaskWallet.packages/sdk/src/index.ts— registermetamaskWalletindefaultWalletsand re-exports.packages/ui/src/react/swapkit-context.tsx— widget connects MetaMask via the SDK.Playground
playgrounds/vite/src/WalletPicker.tsx— wire the MetaMask button toconnectMetamask; filter MetaMask out of EIP-6963 discovery.playgrounds/vite/vite.config.ts,playgrounds/vite/package.json— bundler config to run the SDK (see note below).Unrelated build fix
package.json— pinlibsodium-wrappers-sumo/libsodium-sumoto0.7.15viaoverrides(see note below).Consumer note (Vite)
Apps bundling with Vite need this
optimizeDepsconfig to run the connect SDK:Worth capturing in the integration docs.
Note on the libsodium commit
This commit is unrelated to MetaMask:
libsodium-wrappers-sumo@0.7.16ships a broken ESM build (its.mjsimports a sibling package's file) that aborts Vite's dependency pre-bundling. Pinning to0.7.15restores it. Included only so the demo runs end-to-end and is independently revertable — happy to split into its own PR if preferred.Test plan
bun installis clean;bun --cwd=playgrounds/vite devstarts with no "Failed to resolve" warnings.display_uri+ analytics).bun type-checkpasses across packages.