-
-
Notifications
You must be signed in to change notification settings - Fork 351
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
Changes from 6 commits
170e1fc
130a3a3
d6527d3
c3ee877
8818e74
7e739da
7352fe8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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, | ||
|
@@ -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'); | ||
|
@@ -364,6 +366,32 @@ const initialConnectedButtons = [ | |
maliciousSeaport, | ||
]; | ||
|
||
// Buttons that are available after connecting via Wallet Connect | ||
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 | ||
*/ | ||
|
@@ -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/'], | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
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, | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
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) { | ||
|
@@ -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; | ||
|
@@ -737,6 +827,12 @@ const updateFormElements = () => { | |
} | ||
} | ||
|
||
for (const button of walletConnectButtons) { | ||
isWalletConnectConnected | ||
? (button.disabled = false) | ||
: (button.disabled = true); | ||
} | ||
|
||
updateOnboardElements(); | ||
updateContractElements(); | ||
}; | ||
|
@@ -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 = () => { | ||
|
@@ -1075,7 +1187,7 @@ const initializeFormElements = () => { | |
watchNFTButton.onclick = async () => { | ||
let watchNftsResult; | ||
try { | ||
watchNftsResult = await ethereum.request({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in some places, we were using |
||
watchNftsResult = await provider.request({ | ||
method: 'wallet_watchAsset', | ||
params: { | ||
type: 'ERC721', | ||
|
@@ -1316,7 +1428,7 @@ const initializeFormElements = () => { | |
} else { | ||
erc20Contract = '0x4fabb145d64652a948d72533023f6e7a623c7c53'; | ||
} | ||
const result = await ethereum.request({ | ||
const result = await provider.request({ | ||
method: 'eth_sendTransaction', | ||
params: [ | ||
{ | ||
|
@@ -1339,7 +1451,7 @@ const initializeFormElements = () => { | |
erc20Contract = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; | ||
} | ||
|
||
const result = await ethereum.request({ | ||
const result = await provider.request({ | ||
method: 'eth_sendTransaction', | ||
params: [ | ||
{ | ||
|
@@ -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: [ | ||
{ | ||
|
@@ -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], | ||
|
@@ -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], | ||
|
@@ -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], | ||
|
@@ -1413,7 +1525,7 @@ const initializeFormElements = () => { | |
erc721Contract = '0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d'; | ||
} | ||
|
||
const result = await ethereum.request({ | ||
const result = await provider.request({ | ||
method: 'eth_sendTransaction', | ||
params: [ | ||
{ | ||
|
@@ -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', | ||
|
There was a problem hiding this comment.
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)