Web3.js와 MetaMask(메타마스크) 연동하기 Connect Web3.js to MetaMask
아무말
오랜만의 dApp 개발에 기분이 좋아진 인피덕
블로그에도 관련 내용을 남기고 싶어 메타마스크 연동 방법을 포스팅하려고 한다.
본론
Web3.js 와 MetaMask가 설치되어 있다는 가정 하에, 간단한 예제 코드로 설명하고자 한다.
import Web3 from 'web3'
...
return new Promise((resolve, reject) => {
// 1
window.addEventListener('load', async () => {
let web3, account;
// 2
if (window.ethereum) {
web3 = new Web3(window.ethereum);
// 3
} else if (typeof window.web3 !== 'undefined') {
web3 = new Web3(window.web3.currentProvider);
} else {
// 4
reject(new Error('No web3 instance injected, using local web3.'))
}
if (web3) {
// 5
account = await web3.eth.requestAccounts();
}
})
})
-
페이지가 load 됐을 때 감지할 수 있도록 event listener를 설정한다.
-
window.ethereum
이 있다(MetaMask가 설치된 상태)면 web3 객체를 주입한다. (MetaMask가window.ethereum
을 제공하고 있다.) window.web3
가 있다(MetaMask가 설치된 상태)면 해당 객체에 속한 currentProvider로 web3 객체를 주입한다.- 현재
window.web3
는 레거시 코드이고 사용을 지양하고 있지만, 이 내용을 모르는 프로젝트에 경고 메시지를 발생시키기 위해 더미 코드로 남겨둔 상태이다. 즉,window.ethereum
으로 연동하는 게 좋다.
- 현재
-
window.ethereum
과window.web3
가 모두 없는 경우 에러를 발생시킨다. - web3 객체가 있으면 계정 정보를 가져온다.
- 동일한 의미의 코드들:
window.ethereum.enable()
(레거시 코드),window.ethereum.request({ method: 'eth_requestAccounts' })
(web3만 사용하는 코드에서는 동작하지 않을 수 있음)
- 동일한 의미의 코드들:
위 코드를 실행시키면 아래와 같은 팝업이 뜨고, 연결을 누르면 web3.js와 MetaMask의 연동이 완료된다.
발생할 수 있는 에러
이미 연동 팝업이 뜬 상태에서 다시 연동하려고 할 때
inpage.js:1 MetaMask - RPC Error: Request of type 'wallet_requestPermissions' already pending for origin https://.com. Please wait. {code: -32002, message: "Request of type 'wallet_requestPermissions' alread…origin https://x.com. Please wait."}
이미 띄워진 팝업을 찾아 연동해주면 해결된다.
연동 중인 상태에서 연동을 해제할 때
이 경우는 MetaMask에서 지원하고 있는 이벤트 accountsChanged
를 사용하면 된다.
이 이벤트는 계정이 연동됐거나 연동 해제 됐을 때 캐치할 수 있는 이벤트이다.
ethereum.on('accountsChanged', handler: (accounts: Array<string>) => void);
이외에도, MetaMask 연결 성공 및 실패 등의 이벤트가 있으니 필요 시 사용하면 된다.