Skip to main content

How to integrate Ethereum Wallets to Near DApps?

In this article we will describe how to add EVM wallets support to your Near app, which is already uses the Near Wallet Selector.

info

AuroraLabs team has worked on this feature almost for a year now. You can learn more about it from NEP-518.

To integrate the Metatamask and other EVM wallets you will need:

  1. Update Wallet Selector libraries
  2. Add Web3Modal libraries (wagmi, web3wallet, eth-wallets-selector)
  3. Add Near chain config with our RPCs.
  4. Add Web3Modal.
  5. Call setupEthereumWallets.

We will add Ethereum Wallets support to the Hello Near Examples.

Let's go step-by-step with it!

Update Wallet Selector libraries

Go to your package.json and change versions of the @near-wallet-selector/core package and all of the wallets packages to be ^8.9.13:

package.json
  "dependencies": {
...
"@near-wallet-selector/core": "^8.9.13",
"@near-wallet-selector/here-wallet": "^8.9.13",
"@near-wallet-selector/modal-ui": "^8.9.13",
"@near-wallet-selector/my-near-wallet": "^8.9.13",
// add the Ethereum Wallets package here
"@near-wallet-selector/ethereum-wallets": "^8.9.13",
...
}

Add the Ethereum wallets package:

package.json
  "dependencies": {
...
"@near-wallet-selector/core": "^8.9.13",
...
// add the Ethereum Wallets package here
"@near-wallet-selector/ethereum-wallets": "^8.9.13",
...
}

Install the packages:

# Using Yarn
yarn install

# Using NPM
npm install

Add Web3Modal libraries

Web3Modal (also known as AppKit) is a standard way to integrate multiple wallets in Ethereum community.

It is based on [wagmi] hooks library for React. We will describe the React integration here, but if you are on another platform - just go here, and try using specific instructions suitable for you to install it.

# Using Yarn
yarn add @web3modal/wagmi wagmi viem @tanstack/react-query

# Using NPM.
npm install @web3modal/wagmi wagmi viem @tanstack/react-query

Add Near chain config with our RPCs

To your config files you will need to add RPCs data. One for the mainnet, and another for the testnet.

source/config.js
const evmWalletChains = {
testnet: {
nearEnv: "testnet",
chainId: 398,
walletExplorerUrl: "https://eth-explorer-testnet.near.org",
explorerUrl: "https://testnet.nearblocks.io",
ethRpcForNear: "https://eth-rpc.testnet.near.org",
nearNativeRpc: "https://rpc.testnet.near.org"
},
mainnet: {
chainId: 397,
nearEnv: "mainnet",
walletExplorerUrl: "https://eth-explorer.near.org",
explorerUrl: "https://nearblocks.io",
ethRpcForNear: "https://eth-rpc.mainnet.near.org",
nearNativeRpc: "https://rpc.mainnet.near.org"
}
}

export const NetworkId = 'testnet';
export const EVMWalletChain = evmWalletChains[NetworkId];

Add Web3Modal

Chain configuration

First, let's create a new file to store our Web3Modal there, import some libs and add nearChain config there formatted in wagmi style:

source/wallets/web3modal.js
import { NetworkId, EVMWalletChain } from '@/config';
import { reconnect, http, createConfig } from "@wagmi/core";
import { walletConnect, injected } from "@wagmi/connectors";

const onMainnet = NetworkId == "mainnet";
const nearChain = {
id: EVMWalletChain.chainId,
name: `NEAR Protocol${ onMainnet ? "" : " Testnet"}`,
nativeCurrency: {
decimals: 18,
name: "NEAR",
symbol: "NEAR",
},
rpcUrls: {
default: { http: [EVMWalletChain.ethRpcForNear] },
public: { http: [EVMWalletChain.ethRpcForNear] },
},
blockExplorers: {
default: {
name: "NEAR Explorer",
url: EVMWalletChain.walletExplorerUrl,
},
},
testnet: !onMainnet,
};

Get projectId

Let's get the Web3Modal projectId for your project. To do that you will need to:

  1. Go to Cloud Reown.
  2. Register there.
  3. Create a project on Cloud Reown.
  4. You can copy your projectId:

reown_projectid

You can read more about the projectId and how it works here.

Prepare metadata

Make sure to pass the correct hosting URL here of your project as url and create a metadata object:

source/wallets/web3modal.js
...

// get your host URL here
const url = "http://localhost:3000";

const metadata = {
name: "Onboard to NEAR Protocol with EVM Wallet",
description: "Discover NEAR Protocol with Ethereum and NEAR wallets.",
url: url,
icons: [`${url}/icon.svg`],
};

...

This tracks the app requesting the connection on the WalletConnect side. See more here. It is crucial to display the correct information inside the EVM wallets, like MetaMask.

Create wagmiConfig

Now, we can use that projectId and metadata to instantiate the wagmiConfig:

source/wallets/web3modal.js

...

const reownProjectId = '5bb0fe33763b3bea40b8d69e4269b4ae';

const metadata = { ... };

export const wagmiConfig = createConfig({
chains: [nearChain],
transports: {
[nearChain.id]: http(),
},
connectors: [
walletConnect({ projectId: reownProjectId, metadata, showQrModal: false }),
injected({ shimDisconnect: true }),
],
});

// Needed to be called to preserve the login state if your will reload the page
// Make sure you are calling it there in your file
reconnect(wagmiConfig);

note

Make sure you have reconnect(wagmiConfig); in your code.

Create Web3Modal

Let's create a Web3Modal now with a config we just prepared with createWeb3Modal function:

source/wallets/web3modal.js
import { createWeb3Modal } from "@web3modal/wagmi";

...

export const web3Modal = createWeb3Modal({
wagmiConfig: wagmiConfig,
// Get a project ID at https://cloud.walletconnect.com
projectId: reownProjectId,
});

Call setupEthereumWallets

The last step is to add the Ethereum Wallets selector to your Near Wallet Selector. Let's find your setupWalletSelector call and add setupEthereumWallets there:

wallets/near.js
import { setupWalletSelector } from '@near-wallet-selector/core';
import { wagmiConfig, web3Modal } from '@/wallets/web3modal';
import { setupEthereumWallets } from "@near-wallet-selector/ethereum-wallets";
...
// to start using EVM wallet with Near the user needs to do a free onboarding transaction
// `alwaysOnboardDuringSignIn` option ensures that it will happen right away after login
const alwaysOnboardDuringSignIn = true;
this.selector = setupWalletSelector({
network: this.networkId,
modules: [
setupMyNearWallet(),
setupHereWallet(),
// pass your wagmiConfig and web3Modal here as arguments
setupEthereumWallets({ wagmiConfig, web3Modal, alwaysOnboardDuringSignIn }),
]
});

And that is it! Just re-build your project and try connecting MetaMask to it!

You should see Ethereum Wallets option in your Near Selector:

ethwallets_popup1

And after click to be able to choose the EVM wallet of your taste:

ethwallets_popup2

Resources

  1. A fuller version of docs about integration

  2. Source code of the project above

  3. Example of the EVM account on the Near Testnet to see what happens in reality on-chain during the execution.

  4. Details about how does it work are in NEP-518

  5. Recording of the Near Devs call with the EthWallets presentation.