Feat/metamask multichain#101
Open
GiMa-SwapKit wants to merge 4 commits into
Open
Conversation
… + Solana)
Route WalletOption.METAMASK through MetaMask's multichain CAIP-25 SDK so a single
session/approval covers EVM and Solana (and future ecosystems). A dedicated
metamaskWallet connector opens one session over all requested scopes, then adapts
invokeMethod into each existing SwapKit toolbox:
- EVM: an EIP-1193 shim over invokeMethod -> ethers BrowserProvider ->
getWeb3WalletMethods (reused unchanged).
- Solana: a SolanaProvider-style signer whose signTransaction calls
solana_signTransaction (sign-only; SwapKit broadcasts) -> getSolanaToolbox.
Also registers metamaskWallet in the SDK defaultWallets + re-exports, repoints the
METAMASK types, adds @metamask/connect-multichain and @solana/web3.js deps plus the
./metamask subpath export, and adds the Vite optimizeDeps config the connect SDK needs.
Import Chain as a value, drop the readonly->mutable EVMChains cast, use the Chain.Solana enum in chainToScope, and pass supportedChains as a plain Chain[] ([...EVMChains, Chain.Solana]) with directSigningSupport — mirroring the phantom and evmWallet connectors. Removing the 'as EVMChain[]' cast restores createWallet's generic inference, which also clears the cascaded 'name is missing' (index.ts) and 'possibly undefined' (types.ts) errors.
getWeb3WalletMethods always wraps the toolbox in prepareNetworkSwitch, which is built for injected wallets that switch an active chain before signing. In a CAIP-25 multichain session the scope already pins the chain, so answer wallet_switchEthereumChain / wallet_addEthereumChain locally as no-ops instead of forwarding them into invokeMethod (where they're meaningless and may throw).
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.
feat(wallets): connect MetaMask via
@metamask/connect-multichain(EVM + Solana)Summary
Routes
WalletOption.METAMASKthrough MetaMask's official multichain SDK(
[@metamask/connect-multichain](https://docs.metamask.io/metamask-connect/multichain/))instead of the legacy injected
window.ethereumpath. A single[CAIP-25](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-25.md)
session — and a single approval prompt — now covers EVM and Solana (and any
future ecosystem MetaMask adds), rather than a per-chain injected provider.
A new
metamaskWalletconnector exposesskClient.connectMetamask(chains, options?).It lazily imports the SDK, derives
supportedNetworksfrom each requested chain'sRPC URL, opens one session over all the requested CAIP-2 scopes, then adapts the
session into each toolbox SwapKit already has.
This is the multichain counterpart to the upstream
@metamask/connect-evmwork in[swapkit/SwapKit#1632](swapkit/SwapKit#1632), chosen here
because the goal is EVM and Solana from one connection.
connect-evmcannot doSolana; the multichain client can, and per MetaMask's own guidance the two share
session infrastructure so this is the right long-term target.
Behavior change
WalletOption.METAMASKno longer uses the injectedwindow.ethereumprovider.It is split out of the injected
evmWalletgroup and routed to the new connector.The generic
WalletOption.EIP6963option still serves every other injected wallet.How it works
The multichain client has no per-chain EIP-1193 provider — all interaction goes
through
invokeMethod({ scope, request }). The connector reshapes that into whateach existing SwapKit toolbox already consumes:
invokeMethod(it answerseth_accounts/eth_chainIdfrom the session and forwards everything else to the wallet/RPC) →wrapped in an ethers
BrowserProvider→ fed to the existinggetWeb3WalletMethods,unchanged.
SolanaProvider-style signer whosesignTransactioncallssolana_signTransaction(serialize → base64 → invoke → deserialize). It signs andreturns; SwapKit broadcasts via its own
sendRawTransaction, matchinggetSolanaToolbox({ signer }).Account resolution scans every
sessionScopesbucket and matches accounts by theirCAIP-10
namespace:reference, so it is robust whethergetSessionreturns fullCAIP-2 keys (
eip155:1) or the namespace-collapsed form (eip155+references).Changes
Library
packages/wallets/src/metamask/index.ts— newmetamaskWalletconnector (connectMetamask).packages/wallets/package.json— add@metamask/connect-multichainand@solana/web3.js; add./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-export it.Playground
playgrounds/vite-lite/vite.config.ts—optimizeDepsconfig required to run the connect SDK (exclude@metamask/multichain-ui; include the dynamically-imported CJS deps).Test plan
bun run build:cibuilds all packages and generates d.ts files cleanly.bun run type-checkpasses for every package,@swapkit/walletsand@swapkit/sdkincluded.directly and resolves both an EVM and a Solana address from one prompt.
solana_signTransactionround-trip(serialize → invoke → deserialize → SwapKit broadcast) and the EIP-1193 shim
under a real
BrowserProvider.The runtime items need a UI to exercise them;
vite-litehas no MetaMask button yet.Happy to add one in a follow-up (or here) for an end-to-end smoke test.
Open questions / follow-ups
@metamask/connect-multichainis at1.1.0; confirm thesolana_signTransactionreturn shape against the installed version if it bumps.
wallet_sessionChanged) is intentionallyleft to SwapKit's reconnect layer rather than the connector.
headless/onDisplayUripassthrough so the widget can render itsown QR instead of MetaMask's built-in modal.