Wallet Connect가 v1.0을 2월 말 이후로 지원 종료하며, v2.0을 사용한다 발표했다.
2.0은 1.0을 지원하지 않는다고 공식적으로 공지 했기에 기존 Wallet Connect 1.0을 사용하던 프로젝트의 migration이 필요한 상황이었다.
Wallet Connect 2.0 문서를 살펴보면.. 문서가 정말 진짜로 불친절 하게 되어 있는 것을 볼 수 있다. 특히 2.0 버전은 Web3Modal을 전적으로 활용하는 듯 보이는데, 기존에 WalletConnectProvider를 활용해 customizing 하던 프로젝트는 Web3Modal로 전면 변경을 해야 하는지 고민하게 될 것이다. (기존에도 modal을 지원했지만, 이 부분은 차치하고)
그러던 중 2.0 버전의 Provider 예제를 찾아 이를 토대로 Test & Migration을 진행하며 알게 된 내용들을 공유하고자 한다.
1. provider 찾기
기존의 walletconnect/web3-provider 의 WalletConnectProvider를 사용하던 프로젝트를 2.0으로 migration 하기 위해서는, 2.0에서 사용하는 Provider의 정보가 필요했다. 문서를 뒤지던 중 provider를 활용한 demo github 페이지를 찾을 수 있었다.
https://docs.walletconnect.com/2.0/javascript/guides/examples-and-resources 해당 링크로 들어가면 하단 부근에 아래 이미지와 같은 항목이 있다.
여기에서 세 번째 줄 (with EthereumProvider + web3.js) 링크로 들어가면 provider를 활용한 demo project를 확인할 수 있다.
(github 다이렉트 링크: https://github.com/WalletConnect/web-examples/tree/main/dapps/react-dapp-v2-with-web3js)
github을 보다보면 2.0은
import UniversalProvider from "@walletconnect/universal-provider";
와 같이 UniversalProvider를 사용하는 것을 확인할 수 있다.
2. provider 파헤치기
WalletConnect 2.0이 UniversalProvider를 사용한다는 것을 알았으니, 해당 모듈의 사용법을 알아야겠다. 아래는 참고할 수 있는 문서 링크이다.
[UniversalProvider npm 문서] https://www.npmjs.com/package/@walletconnect/universal-provider
[WalletConnect 2.0 Api문서] https://docs.walletconnect.com/2.0/javascript/sign/wallet-usage
해당 문서들을 보면 기존에 WalletConnect에서 등록했던 event listener 에서 대체된 listener들을 볼 수 있다.
각각 disconnect -> session_delete, chainChanged/accountChanged -> session_event 등으로 대체된 것을 볼 수 있다. npm문서에는 각 listener들만 정의되어있으나, WalletConnect 문서에는 parameter 등 각 listener에 대한 주석이 달려있어 참고에 더 용이할 것으로 보인다.
3. Listener 살펴보기
예제와 같이 Listener를 설정하고 테스팅을 진행하다 보면 session_event나 session_update 등의 listener가 정상적으로 동작하지 않는 듯 보일 수 있다. 필자의 경우, app wallet을 활용해 테스팅을 진행했는데 session_delete나 session_ping에 대한 감지는 일어나지만 session_event나 session_update의 케이스는 확인이 안 되었다.
이에 대한 테스팅을 진행해 본 결과, session_event의 경우 문서에는 기존의 accountChanged나 chainChanged를 대응한다고 작성되어 있었으나, 실제 wallet마다 처리하는 방식이 달라 발생하는 현상인 듯 했다.
일례로 session_event의 케이스를 살펴보면 아래와 같다.
async function onSessionEmit() {
await signClient.emit({
topic,
event: { name: 'chainChanged', data: 'Hello World' },
chainId: 'eip155:[yourChainId]'
})
}
위의 코드는 wallet에서 event를 발생시키는 코드로, SignClient 객체 (walletconnect/sign-client)의 emit함수를 사용하는 것을 볼 수 있다. 여기에서 우리가 주목해야 할 것은, emit함수 내에 event 객체이다.
코드와 같이 chainChanged라는 event를 호출하는게 아닌, name 값에 직접 타이핑해서 사용하는 것을 볼 수 있다. 1.0 버전과 다르게 각 event에 대한 함수와 parameter 규격이 정해지지 않고 직접 정의해서 사용하는 듯 보인다. (해당 케이스의 경우 예제이기 때문에 이런 양상을 보이는 것 일 수 있으나, 별도의 공식 메뉴얼이 없는 관계로 이 예제에 의존하는 부분은 감안하길 바람)
참고로, Wallet에 대한 테스트를 하고 싶다면 (ping 등..) 위에 링크한 demo github의 wallet 예제를 사용하는 것도 좋은 방법인 듯 하다. (필자는 2.0을 지원하는 wallet을 여러개 깔아서 테스트를 진행했는데, 결과적으로 event listening 테스팅은 demo를 사용해 종결지었다.)
혹시 찾지 못할 수 있으니 demo 사이트 링크를 남겨둔다.
(해당 프로젝트 경로는 위에 링크된 github 프로젝트의 web-examples/wallets/react-wallet-v2)
[wallet connect 2.0 wallet demo] https://react-wallet.walletconnect.com/
아무튼, 이렇게 사혼의 구슬 마냥 흩어져있는 문서와 예제를 모아모아 테스트 한 결과, 구조적으로 1.0과 2.0의 사용법이 크게 달라지지는 않을 것으로 보인다.
글을 전체적으로 두서없이 작성했는데, wallet 쪽 예제도 간단히 분석할 겸 섹션을 나눠 글을 정리해볼까 생각중이다.