WalletConnect 공식 블로그인 것 같은 곳에 v2.0 코드에 대한 설명을 잘 해줘서 이 글을 참고하여 walletconnect v2.0을 이해해보려한다. - 참고 블로그
~~
~~
const web3Modal = new Web3Modal({
projectId: process.env.REACT_APP_PROJECT_ID,
standaloneChains: ["eip155:5"]
})
handleConnect라는 새 비동기 함수를 만듭니다. 먼저 signClient가 존재하는지 확인하고 존재하지 않으면 오류가 발생합니다. try/catch 블록으로 계속 진행합니다.
블록체인에 연결하기 위해 SignClient에서 제공하는 연결 방법을 사용합니다.
이 메서드는 uri 속성을 포함하는 개체로 확인되는 약속을 반환합니다.
메서드에서 requiredNamespaces가 포함된 개체를 전달합니다.
필수 네임스페이스는 클라이언트의 기능과 수행할 수 있는 작업을 정의합니다.
그런 다음 uri는 반환된 객체에서 해체됩니다. URI는 WalletConnect 세션의 고유 식별자입니다. 세션에 대한 정보가 포함된 문자열입니다. 존재하는지 확인하고, 존재한다면 모달을 엽니다.
모달을 열려면 openModal을 호출하고 uri를 전달합니다.
async function handleConnect() { <- ※본문에서는 여기에 오타있으니 주의※
if (!signClient) throw Error("SignClient does not exist");
const proposalNamespace = {
eip155: {
methods: ["eth_sendTransaction"],
chains: ["eip155:5"],
events: ["connect", "disconnect"]
}
}
const { uri } = await signClient.connect({
requiredNamespaces: proposalNamespace
});
if (uri){
web3Modal.openModal({ uri });
}
try {
} catch(e){
console.log(e);
}
}
기능을 테스트하려면 헤더 텍스트 뒤에 새 버튼을 추가하십시오. 요소에 disabled 속성을 추가하고 !signClient로 설정하면 signClient가 없으면 버튼이 비활성화됩니다.
<button onClick={handleConnect} disbaled={!signClient}>Connect</button>
이 단계 후 App.js는 어떻게 보여야 할까요?
이 단계에서는 세션 및 계정 정보를 상태 변수에 저장합니다. 그런 다음 사용자의 계정 정보를 표시합니다.
dApp을 지갑에 연결하려면 Sign v2가 통합된 지갑을 사용해야 합니다. 이 예에서는 WalletConnect의 데모 지갑을 사용할 것입니다. 이것은 테스트 지갑이므로 실제 자금을 저장하지 마십시오. 테스트넷에 액세스하려면 설정 기어를 클릭하고 테스트넷을 활성화하십시오.
두 개의 새 상태 변수를 추가하여 시작합니다.
const [session, setSession] = useState([]);
const [account, setAccount] = useState([]);
다음으로 반환된 객체의 approval인 다른 속성을 파괴할 것입니다.
const { uri, approval } = await signClient.connect({
// ...
})
approval
속성은 사용자가 연결에 대해 승인한 세션 네임스페이스를 지정합니다. 모달을 연 후 approval
호출을 기다리면 세션 네임스페이스를 저장할 수 있습니다. 그런 다음 해당 세션을 onSessionConnected
에 전달합니다(다음에 이 함수를 생성할 것임). 마지막으로 QR 코드를 스캔하면 모달이 계속 열려 있음을 눈치채셨을 것입니다. closeModal
을 호출하여 해결할 수 있습니다.
const sessionNamespace = await approval();
onSessionConnected(sessionNamespace);
web3Modal.closeModal();
onSessionConnected
라는 새 비동기 함수를 만들고 session
을 매개 변수로 전달합니다. try/catch
블록으로 시작합니다. 여기에서 세션을 세션 매개변수로 설정하고 계정을 계정 번호로 설정합니다.
async function onSessionConnected(session<- 이거 본문에는 안들어있음 ※주의※){
try {
setSession(session);
setAccount(session.namespaces.eip155.accounts[0].slice(9));
} catch(e){
console.log(e)
}
}
계정 정보를 렌더링해 보겠습니다. 반품 명세서에서 제목 뒤에 삼항 표현식을 작성하십시오. 계정 배열이 비어 있으면 연결 버튼을 렌더링합니다. 계정 배열이 비어 있지 않으면 계정 값을 렌더링합니다.
{account.length ? (
<p>{account}</p>
) : (
<button onClick={handleConnect} disabled={!signClient}>
Connect
</button>
)}
이 단계 후 App.js는 어떻게 보여야 할까요?
handleDisconnect
라는 새 비동기 함수를 만듭니다. try/catch
블록에서 signClient
의 disconnect
메서드를 호출합니다. 주제, 메시지 및 코드를 포함하는 개체를 전달합니다. 사용 가능한 모든 오류 코드를 보려면 문서를 살펴보세요.
disconnect
호출을 기다린 후 reset
이라는 새 함수를 호출합니다.
await signClient.disconnect({
topic: session.topic,
message: "User disconnected",
code: 6000,
});
reset();
} catch (e) {
console.log(e);
}
}
이제 새 함수를 만들어 보겠습니다. reset
은 accounts
와 session
을 빈 배열로 설정합니다.
const reset = () => {
setAccount([]);
setSession([]);
};
연결 해제 버튼을 포함하도록 return statement를 업데이트하십시오.
<>
<p>{account}</p>
<button onClick={handleDisconnect}>Disconnect</button>
</>
계속해서 버튼을 테스트하십시오.
이 단계 후 App.js는 어떻게 보여야 할까요?
자 여기까지 하고나면
웹 페이지를 실행했을때 나온 버튼을 누르면 QR코드가 생성되고
블록체인 지갑으로 해당 QR코드를 스캔하면
연결되면서 웹페이지의 다음 화면으로 이동해야하는데
3번이 안되더랍니다.
그래서 해당 예제 프로젝트의 완성본 깃헙에 issue 부분에 들어갔더니
만든 개발자는 잘되는 영상을 올리고 여러 사람들은 저와 같은 문제를 2022.04.01 부터 겪고 있었더라구요 - 월렛커넥트 깃헙의 해당 이슈 관련 질의응답 공간
ㅠㅠㅠㅠㅠㅠ
이 곳에 답이 없는 것 같았다고 생각하고 다른 자료를 찾아보던 찰나!
갑자기 머릿속을 스치는 생각에 그대로 해봤더니
맞았습니다.
이 '설마'가 글쓴이의 2주를 잡아먹었습니다.
현재 메타마스크, 다른 월렛들이 v2.0 월렛커넥트를 지원하지 않았던 것이었어요
물론 앱 내에 정확한 버전이 명시되어있는 건 아니었지만 (깃헙을 보고 추측해보면 "@walletconnect/client": "^1.7.1", "@walletconnect/utils": "^1.7.1"
를 쓰고있는 것 같더라고요)
깃헙 issue 란에 개발자가 보여준 시연 동영상에서는 월렛커넥트 2.0을 사용한 dapp(월렛커넥트가 데모로 만든 월렛커넥트 2.0 사용 dapp) 으로 시연을 했거든요
깨달은 점
1. 많이 접해보지 못한 API를 사용할 때는 무조건 공식 문서부터 다 읽고 이슈도 모두 읽으며 개발하자(근본성!)
2. 공식 문서라고 해서 오류가 없는 건 아니니 문제를 다양한 관점으로 생각해보고 그래도 안되면 공식 개발자에게 질문하기(능동성!)
여기까지 잠깐 쉬어가는 곳이었습니다.ㅎㅎ
사용자가 지갑에서 세션 연결을 끊으면 어떻게 됩니까? 앱이 해당 이벤트를 어떻게 수신할 수 있나요? 방법은 다음과 같습니다. subscribeToEvents
라는 또 다른 비동기 함수를 만들고 client
를 매개 변수로 전달합니다. client
가 존재하는지 확인하고 없으면 오류를 발생시킵니다. try
블록 내에서 on
메서드를 호출하고 듣고 있는 이벤트를 전달합니다. 테스트를 위해 사용자가 지갑에서 세션 연결을 끊을 때 dApp에서 기록된 메시지를 볼 수 있도록 메시지를 기록할 것입니다. 로깅 후 reset
을 호출하세요.
async function subscribeToEvents(client) {
if (!client)
throw Error("Unable to subscribe to events. Client does not exist.");
try {
client.on("session_delete", () => {
console.log("The user has disconnected the session from their wallet.");
reset();
});
} catch (e) {
console.log(e);
}
}
이제 방금 만든 이 새 함수를 호출해야 합니다. createClient
에서 signClient
를 설정한 후 subscribeToEvents
를 대기하고 signClient
를 인수로 전달합니다.
이 단계 후 App.js는 어떻게 보여야 할까요?
다음으로 우리는 마침내 트랜잭션을 보낼 것입니다. handleSend
라는 새로운 비동기 함수를 만들어 보겠습니다. 이 기능은 전송 요청을 처리합니다.
account
에 항목이 있는지 확인하고 없으면 오류를 발생시킵니다.
try/catch
블록으로 계속 진행합니다. 거래 params
설정부터 시작하겠습니다. 샘플 개체를 보려면 문서를 확인하세요.
tx
는 트랜잭션의 세부 정보를 제공할 것입니다.
우리는 연결된 어떤 계정에서든 보내기를 원하기 때문에 from
to account
를 설정합니다. to
주소를 자유롭게 변경하십시오. data
, gasPrice
, gasLimit
및 value
는 모두 16진수로 인코딩되어야 합니다. 그렇지 않으면 트랜잭션이 실패하게 됩니다.
const tx = {
from: account,
to: "0xBDE1EAE59cE082505bB73fedBa56252b1b9C60Ce",
data: "0x",
gasPrice: "0x029104e28c",
gasLimit: "0x5208",
value: "0x00",
};
다음으로 결과를 저장하고 기록하겠습니다.
const result = await signClient.request({
topic: session.topic,
chainId: "eip155:5",
request: {
method: "eth_sendTransaction",
params: [tx],
},
})
console.log(result);
return statement 에서 계정 세부 정보 뒤에 거래를 보내기 위한 새 버튼을 추가해 보겠습니다.
<button onClick={handleSend}>Send Transaction</button>
버튼을 테스트합니다. 지갑에서 트랜잭션을 수락하고 기록된 결과를 기다립니다.
로깅된 응답은 트랜잭션 해시이므로 https://goerli.etherscan.io/tx/${result}
로 이동하면 새 트랜잭션을 볼 수 있습니다.
이 단계 후 App.js는 어떻게 보여야 할까요?
오류 사진
오류를 해석해보면
insufficient funds for intrinsic transaction cost
본질적인 거래 비용에 대한 자금이 부족하다고 나오네요.
그래서 이더리움 goerli faucet에 가서 자금을 얻었습니다.
그 후에 Tx를 보내보니
이렇게 result가 콘솔에 출력되었고
그 result값을 위에 나온 https://goerli.etherscan.io/tx/${result}
의 url에 넣어 들어갔더니
짜잔~ 재대로된 Tx값이 보이네요!
단순히 로그만 콘솔로 띄우는 대신 페이지에서 결과를 볼 수 있도록 UI를 업데이트할 예정입니다. 새 상태 변수를 만드는 것으로 시작합니다. 그것을 txnURL
이라고 부를 수 있습니다.
const [txnUrl, setTxnUrl] = useState();
마지막 단계에서 만든 로그를 이것으로 교체하십시오. 결과를 저장하고 txnUrl
로 설정하겠습니다.
setTxnUrl(result);
반품 명세서에서 연결 해제 버튼 다음에 다음을 추가합니다. txnUrl
이 존재하는 경우 Etherscan 트랜잭션 정보로 일부 헤더 텍스트를 렌더링합니다.
이 단계 후 App.js는 어떻게 보여야 할까요?
프로토콜에 대해 자세히 알아보려면 GitHub 및 설명서를 확인하는 것이 좋습니다. 보다 강력한 예제를 원하시면 샘플 dapp을 확인하십시오. Solana를 포함하여 9개의 체인이 있습니다. 다른 JavaScript 웹 예제는 문서를 참조하십시오.
Twitter에서 WalletConnect를 팔로우하여 향후 발표 및 업데이트에 대한 최신 정보를 얻으십시오. 질문이 있으시면 Discord 서버에서 자유롭게 질문해 주십시오.