Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e20047c
docs: plan connect evm integration
wenfix May 28, 2026
fcd8f3d
docs: add connect evm implementation plan
wenfix May 28, 2026
66e4394
chore: ignore local worktrees
wenfix May 28, 2026
eb73c47
chore: fix connect evm plan baseline lint
wenfix May 28, 2026
420d1d2
feat: add connect evm dependency
wenfix May 28, 2026
e32cae2
chore: require node 20
wenfix May 28, 2026
7aab376
chore: update node version file
wenfix May 28, 2026
846fda3
feat: add connect evm client helper
wenfix May 28, 2026
f61acc6
fix: harden connect evm helper
wenfix May 28, 2026
885eb5e
fix: allow connect evm init retry
wenfix May 28, 2026
a2b6a36
feat: add connect evm button
wenfix May 28, 2026
cd8ef9a
fix: tighten connect evm button text
wenfix May 28, 2026
6b894f6
feat: wire connect evm button
wenfix May 28, 2026
aa5e91c
feat: support eip1193 provider initialization
wenfix May 28, 2026
6d3360d
fix: clean up active provider listeners
wenfix May 28, 2026
a02ed65
fix: keep walletconnect disconnect state cleared
wenfix May 28, 2026
261d329
fix: clear active provider teardown state
wenfix May 28, 2026
03faa76
fix: resolve process browser shim
wenfix May 28, 2026
0bd2df0
fix: tighten provider disconnect lifecycle
wenfix May 28, 2026
42e5f95
chore: remove plan docs
wenfix May 28, 2026
06c2818
fix: rename connect evm button label
wenfix May 28, 2026
9ee1850
fix: drop unused connect evm provider tracking
wenfix Jun 25, 2026
cd66c91
fix: tidy connect evm icon and install event dispatch
wenfix Jun 25, 2026
004f076
ci: drop node 18 from build-lint-test matrix
wenfix Jun 25, 2026
1f3fb25
chore: allowlist install scripts for connect evm deps
wenfix Jun 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module.exports = {
{
files: ['src/**/*.js'],
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module',
},
},
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-lint-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x, 20.x]
node-version: [20.x]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mm-connect requires node version >=20.19.0

steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ node_modules
dist
.eslintcache
.DS_Store
.worktrees
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v18
v20.19.1
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ It can be used by navigating to `/request.html?method=${METHOD}&params=${PARAMS}

### Setup

- Install [Node.js](https://nodejs.org) version 16
- Install [Node.js](https://nodejs.org) version 20.19.0 or later
- If you are using [nvm](https://github.com/creationix/nvm#installation) (recommended) running `nvm use` will automatically choose the right node version for you.
- Install [Yarn v1](https://yarnpkg.com/en/docs/install)
- Run `yarn setup` to install dependencies and run any required post-install scripts
Expand Down
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "9.9.0",
"description": "A simple dapp used in MetaMask e2e tests.",
"engines": {
"node": ">= 18.0.0"
"node": ">=20.19.0"
},
"scripts": {
"setup": "yarn install && yarn allow-scripts",
Expand Down Expand Up @@ -42,6 +42,7 @@
"@lavamoat/allow-scripts": "^2.5.1",
"@lavamoat/preinstall-always-fail": "^2.0.0",
"@metamask/auto-changelog": "^2.5.0",
"@metamask/connect-evm": "^1.4.0",
"@metamask/eslint-config": "^6.0.0",
"@metamask/eslint-config-nodejs": "^6.0.0",
"@metamask/eth-sig-util": "^7.0.1",
Expand Down Expand Up @@ -82,7 +83,10 @@
"@metamask/sdk>@metamask/sdk-communication-layer>bufferutil": false,
"@metamask/sdk>@metamask/sdk-communication-layer>utf-8-validate": false,
"@metamask/sdk>eciesjs>secp256k1": false,
"@web3modal/ethers5>@coinbase/wallet-sdk>@solana/web3.js>rpc-websockets>utf-8-validate": false
"@web3modal/ethers5>@coinbase/wallet-sdk>@solana/web3.js>rpc-websockets>utf-8-validate": false,
"@metamask/connect-evm>@metamask/connect-multichain>@metamask/mobile-wallet-protocol-core>centrifuge>protobufjs": false,
"ethereumjs-util>ethereum-cryptography>keccak": false,
"ethereumjs-util>ethereum-cryptography>secp256k1": false
}
},
"packageManager": "yarn@1.22.22"
Expand Down
5 changes: 5 additions & 0 deletions src/components/connections/connections.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ export function connectionsComponent(parentContainer) {
>
SDK Connect
</button>
<button
class="btn btn-primary btn-lg btn-block mb-3"
id="connectEvm"
>MetaMask Connect</button>
<hr />
<button
class="btn btn-primary btn-lg btn-block mb-3"
Expand All @@ -51,6 +55,7 @@ export function connectionsComponent(parentContainer) {
const onboardButton = document.getElementById('connectButton');
const walletConnectBtn = document.getElementById('walletConnect');
const sdkConnectBtn = document.getElementById('sdkConnect');
const connectEvmBtn = document.getElementById('connectEvm');
*/
const getAccounts = document.getElementById('getAccounts');
const getAccountsResult = document.getElementById('getAccountsResult');
Expand Down
121 changes: 121 additions & 0 deletions src/connect-evm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { createEVMClient } from '@metamask/connect-evm';
import dappMetadata from './dapp-metadata';
import globalContext, {
handleNewAccounts,
handleNewProviderDetail,
removeProviderDetail,
setActiveProviderDetail,
updateFormElements,
} from '.';

export const CONNECT_EVM_PROVIDER_UUID = 'connect-evm';

export const CONNECT_EVM_SUPPORTED_NETWORKS = {
'0x1': 'https://ethereum.publicnode.com',
'0xaa36a7': 'https://ethereum-sepolia.publicnode.com',
'0xa': 'https://optimism.publicnode.com',
'0x89': 'https://polygon-bor-rpc.publicnode.com',
'0x2105': 'https://base.publicnode.com',
'0xa4b1': 'https://arbitrum-one.publicnode.com',
'0xa86a': 'https://avalanche-c-chain-rpc.publicnode.com',
'0x38': 'https://bsc-dataseed.binance.org',
'0x539': 'http://127.0.0.1:8545',
'0x53a': 'http://127.0.0.1:8546',
};

export const CONNECT_EVM_CHAIN_IDS = Object.keys(
CONNECT_EVM_SUPPORTED_NETWORKS,
);

let connectEvmClientPromise;

const noop = () => undefined;

async function getConnectEvmClient() {
if (!connectEvmClientPromise) {
connectEvmClientPromise = createEVMClient({
dapp: dappMetadata,
api: {
supportedNetworks: CONNECT_EVM_SUPPORTED_NETWORKS,
},
});
}

try {
return await connectEvmClientPromise;
} catch (err) {
connectEvmClientPromise = undefined;
throw err;
}
}

function getConnectEvmProviderDetail(provider, name) {
return {
info: {
uuid: CONNECT_EVM_PROVIDER_UUID,
name,
icon: './metamask-fox.svg',
rdns: 'io.metamask',
},
provider,
};
}

function setConnectedButtonState(button) {
button.innerText = 'MetaMask Connect - Disconnect';
button.classList.remove('btn-primary');
button.classList.add('btn-danger');
}

function setDisconnectedButtonState(button) {
button.innerText = 'MetaMask Connect';
button.classList.add('btn-primary');
button.classList.remove('btn-danger');
}

export async function handleConnectEvm(
name,
button,
isConnected,
updateConnectionState = noop,
) {
button.disabled = true;

try {
const client = await getConnectEvmClient();

if (isConnected) {
await client.disconnect();
updateConnectionState(false);
const activeProviderRemoved = removeProviderDetail(name);
setDisconnectedButtonState(button);
if (activeProviderRemoved) {
updateFormElements();
}
return;
}

const { accounts } = await client.connect({
chainIds: CONNECT_EVM_CHAIN_IDS,
});
const provider = client.getProvider();

const providerDetail = getConnectEvmProviderDetail(provider, name);
await setActiveProviderDetail(providerDetail);
handleNewProviderDetail(providerDetail);
updateConnectionState(true);
setConnectedButtonState(button);
updateFormElements();
handleNewAccounts(accounts);
globalContext.connected = true;
} catch (err) {
console.error('Error connecting with MetaMask Connect EVM', err);
if (isConnected) {
setConnectedButtonState(button);
} else {
setDisconnectedButtonState(button);
}
} finally {
button.disabled = false;
}
}
24 changes: 10 additions & 14 deletions src/connections.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { MetaMaskSDK } from '@metamask/sdk';
import dappMetadata from './dapp-metadata';
import globalContext, {
handleNewAccounts,
handleNewProviderDetail,
Expand All @@ -9,12 +10,6 @@ import globalContext, {
updateWalletConnectState,
} from '.';

const dappMetadata = {
name: 'E2e Test Dapp',
description: 'This is the E2e Test Dapp',
url: 'https://metamask.github.io/test-dapp/',
};

const sdk = new MetaMaskSDK({ dappMetadata });

export const initializeWeb3Modal = () => {
Expand Down Expand Up @@ -52,14 +47,15 @@ function _setProviderDetail(provider, name, uuid) {

export async function handleSdkConnect(name, button, isConnected) {
if (isConnected) {
handleNewAccounts([]);
updateFormElements();
updateSdkConnectionState(false);
removeProviderDetail(name);
const activeProviderRemoved = removeProviderDetail(name);
await sdk.terminate();
button.innerText = 'Sdk Connect';
button.classList.add('btn-primary');
button.classList.remove('btn-danger');
if (activeProviderRemoved) {
updateFormElements();
}
} else {
await sdk.connect();
const provider = sdk.getProvider();
Expand Down Expand Up @@ -87,14 +83,14 @@ export async function handleSdkConnect(name, button, isConnected) {

export async function handleWalletConnect(name, button, isConnected) {
if (isConnected) {
handleNewAccounts([]);
updateFormElements();
updateWalletConnectState(false);
removeProviderDetail(name);
const activeProviderRemoved = removeProviderDetail(name);
button.innerText = 'Wallet Connect';
button.classList.add('btn-primary');
button.classList.remove('btn-danger');
globalContext.connected = false;
if (activeProviderRemoved) {
updateFormElements();
}
} else {
const { provider } = walletConnect.getWalletProvider();
const uuid = provider.signer.uri;
Expand All @@ -116,6 +112,6 @@ export async function handleWalletConnect(name, button, isConnected) {
} catch (err) {
console.error('Error on init when getting accounts', err);
}
globalContext.connected = true;
}
globalContext.connected = true;
}
7 changes: 7 additions & 0 deletions src/dapp-metadata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const dappMetadata = {
name: 'E2e Test Dapp',
description: 'This is the E2e Test Dapp',
url: 'https://metamask.github.io/test-dapp/',
};

export default dappMetadata;
Loading
Loading