Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add Wallet Connect support #284

Merged
merged 7 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
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
10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@
"eslint-plugin-prettier": "^3.4.0",
"eth-sig-util": "^2.5.3",
"ethereumjs-util": "^5.1.1",
"ethers": "^5.0.32",
"@web3modal/ethers5": "^3.2.0",
"@walletconnect/modal": "^2.6.2",
"ethers": "5.7.2",
"gh-pages": "^3.1.0",
"prettier": "^2.3.1",
"process": "^0.11.10",
Expand All @@ -68,7 +70,11 @@
"@lavamoat/preinstall-always-fail": false,
"eth-sig-util>ethereumjs-abi>ethereumjs-util>keccakjs>sha3": false,
"ethereumjs-util>keccak": false,
"ethereumjs-util>secp256k1": false
"ethereumjs-util>secp256k1": false,
"@web3modal/ethers5>@coinbase/wallet-sdk>@solana/web3.js>bigint-buffer": false,
"@web3modal/ethers5>@coinbase/wallet-sdk>keccak": false,
"webpack-dev-server>ws>bufferutil": false,
"webpack-dev-server>ws>utf-8-validate": false
}
},
"packageManager": "yarn@1.22.19"
Expand Down
6 changes: 6 additions & 0 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ <h4 class="card-title">
Connect
</button>

<button
class="btn btn-primary btn-lg btn-block mb-3"
id="open-connect-modal"
>
Wallet Connect
</button>
<button
class="btn btn-primary btn-lg btn-block mb-3"
id="getAccounts"
Expand Down
132 changes: 122 additions & 10 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import MetaMaskOnboarding from '@metamask/onboarding';
import { createWeb3Modal, defaultConfig } from '@web3modal/ethers5';
// eslint-disable-next-line camelcase
import {
encrypt,
Expand Down Expand Up @@ -72,6 +73,7 @@ const warningDiv = document.getElementById('warning');
const onboardButton = document.getElementById('connectButton');
const getAccountsButton = document.getElementById('getAccounts');
const getAccountsResult = document.getElementById('getAccountsResult');
const openConnectModalBtn = document.getElementById('open-connect-modal');

// Permissions Actions Section
const requestPermissionsButton = document.getElementById('requestPermissions');
Expand Down Expand Up @@ -364,6 +366,32 @@ const initialConnectedButtons = [
maliciousSeaport,
];

// Buttons that are available after connecting via Wallet Connect
Copy link
Contributor Author

Choose a reason for hiding this comment

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

not the same as the ones with Extension, as we don't allow to deploy contracts for now (more logic might be needed for getting deployed contract address)

const walletConnectButtons = [
sendButton,
personalSign,
signTypedData,
ethSign,
personalSign,
signTypedData,
signTypedDataV3,
signTypedDataV4,
signPermit,
siwe,
siweResources,
siweBadDomain,
siweBadAccount,
siweMalformed,
eip747WatchButton,
maliciousApprovalButton,
maliciousSetApprovalForAll,
maliciousERC20TransferButton,
maliciousRawEthButton,
maliciousPermit,
maliciousTradeOrder,
maliciousSeaport,
];

/**
* Provider
*/
Expand All @@ -374,10 +402,63 @@ let accounts = [];
let scrollToHandled = false;

const isMetaMaskConnected = () => accounts && accounts.length > 0;
let isWalletConnectConnected = false;

// TODO: Need to align with @metamask/onboarding
const isMetaMaskInstalled = () => provider && provider.isMetaMask;

// test id
const projectId = 'e6360eaee594162688065f1c70c863b7';

const metadata = {
name: 'E2e Test Dapp',
description: 'This is the E2e Test Dapp',
url: 'https://metamask.github.io/test-dapp/',
icons: ['https://avatars.mywebsite.com/'],
};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

metadata that will be seen on the Mobile device, once connected

image


const modal = createWeb3Modal({
ethersConfig: defaultConfig({ metadata }),
projectId,
});

async function handleWalletConnectChange({ isConnected }) {
if (isConnected) {
provider = modal.getWalletProvider().provider;
const providerDetail = {
info: {
uuid: provider.signer.uri,
name: 'wallet-connect',
icon: './wallet-connect.svg',
rdns: 'io.metamask',
},
provider,
};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

provider info that will be displayed on top of the test dapp

Screenshot from 2023-12-12 12-39-35

setActiveProviderDetail(providerDetail);
handleNewProviderDetail(providerDetail);

isWalletConnectConnected = true;
try {
const newAccounts = await provider.request({
method: 'eth_accounts',
});
handleNewAccounts(newAccounts);
} catch (err) {
console.error('Error on init when getting accounts', err);
}
} else {
isWalletConnectConnected = false;
openConnectModalBtn.innerText = 'Wallet Connect';
handleNewAccounts([]);
updateFormElements();
}
}

openConnectModalBtn.onclick = () => {
modal.open();
modal.subscribeProvider(handleWalletConnectChange);
};

const detectEip6963 = () => {
window.addEventListener('eip6963:announceProvider', (event) => {
if (event.detail.info.uuid) {
Expand All @@ -391,11 +472,20 @@ const detectEip6963 = () => {
window.dispatchEvent(new Event('eip6963:requestProvider'));
};

const setActiveProviderDetail = (providerDetail) => {
const setActiveProviderDetail = async (providerDetail) => {
closeProvider();
provider = providerDetail.provider;
initializeProvider();

try {
const newAccounts = await provider.request({
method: 'eth_accounts',
});
handleNewAccounts(newAccounts);
} catch (err) {
console.error('Error on init when getting accounts', err);
}

const { uuid, name, icon } = providerDetail.info;
activeProviderUUIDResult.innerText = uuid;
activeProviderNameResult.innerText = name;
Expand Down Expand Up @@ -737,6 +827,12 @@ const updateFormElements = () => {
}
}

for (const button of walletConnectButtons) {
isWalletConnectConnected
? (button.disabled = false)
: (button.disabled = true);
}

updateOnboardElements();
updateContractElements();
};
Expand Down Expand Up @@ -793,6 +889,22 @@ const updateOnboardElements = () => {
};
onboardButton.disabled = false;
}

if (isWalletConnectConnected) {
openConnectModalBtn.innerText = 'Wallet Connect - Connected';

if (onboarding) {
onboarding.stopOnboarding();
}
provider.autoRefreshOnNetworkChange = false;
getNetworkAndChainId();

provider.on('chainChanged', handleNewChain);
provider.on('chainChanged', handleEIP1559Support);
provider.on('chainChanged', handleNewNetwork);
provider.on('accountsChanged', handleNewAccounts);
provider.on('accountsChanged', handleEIP1559Support);
}
};

const updateContractElements = () => {
Expand Down Expand Up @@ -1075,7 +1187,7 @@ const initializeFormElements = () => {
watchNFTButton.onclick = async () => {
let watchNftsResult;
try {
watchNftsResult = await ethereum.request({
Copy link
Contributor Author

Choose a reason for hiding this comment

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

in some places, we were using ethereum.request instead of provider. We need to make sure that we are using the provider (whichever is selected)

watchNftsResult = await provider.request({
method: 'wallet_watchAsset',
params: {
type: 'ERC721',
Expand Down Expand Up @@ -1316,7 +1428,7 @@ const initializeFormElements = () => {
} else {
erc20Contract = '0x4fabb145d64652a948d72533023f6e7a623c7c53';
}
const result = await ethereum.request({
const result = await provider.request({
method: 'eth_sendTransaction',
params: [
{
Expand All @@ -1339,7 +1451,7 @@ const initializeFormElements = () => {
erc20Contract = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
}

const result = await ethereum.request({
const result = await provider.request({
method: 'eth_sendTransaction',
params: [
{
Expand All @@ -1354,7 +1466,7 @@ const initializeFormElements = () => {

// Malicious raw ETH transfer
maliciousRawEthButton.onclick = async () => {
const result = await ethereum.request({
const result = await provider.request({
method: 'eth_sendTransaction',
params: [
{
Expand All @@ -1369,7 +1481,7 @@ const initializeFormElements = () => {

// Malicious permit
maliciousPermit.onclick = async () => {
const result = await ethereum.request({
const result = await provider.request({
method: 'eth_signTypedData_v4',
params: [
accounts[0],
Expand All @@ -1381,7 +1493,7 @@ const initializeFormElements = () => {

// Malicious trade order
maliciousTradeOrder.onclick = async () => {
const result = await ethereum.request({
const result = await provider.request({
method: 'eth_signTypedData_v4',
params: [
accounts[0],
Expand All @@ -1393,7 +1505,7 @@ const initializeFormElements = () => {

// Malicious Seaport
maliciousSeaport.onclick = async () => {
const result = await ethereum.request({
const result = await provider.request({
method: 'eth_signTypedData_v4',
params: [
accounts[0],
Expand All @@ -1413,7 +1525,7 @@ const initializeFormElements = () => {
erc721Contract = '0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d';
}

const result = await ethereum.request({
const result = await provider.request({
method: 'eth_sendTransaction',
params: [
{
Expand Down Expand Up @@ -1512,7 +1624,7 @@ const initializeFormElements = () => {
const contractAddresses = tokenAddresses.innerHTML.split(', ');

const promises = contractAddresses.map((erc20Address) => {
return ethereum.request({
return provider.request({
method: 'wallet_watchAsset',
params: {
type: 'ERC20',
Expand Down
23 changes: 23 additions & 0 deletions src/wallet-connect.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading