서론
메타마스크 지갑 연결 부분은 아래 포스팅에 설명되어 있습니다. 본 글은 전 글에 이어 서명 부분만 추가한 프로세스를 정리하였습니다.
https://3d-yeju.tistory.com/90
React | web3-react를 사용하여 메타마스크(Metamask) 지갑연결하기
서론 web3.js란? web3.js 는 내부적으로 HTTP 나 IPC를 통해 JSON RPC API를 호출하도록 되어있습니다. 만약, 스마트 컨트렉트의 함수를 실행하고자 한다면 1.스마트 컨트렉트의 주소 2. 실행할 함수 3. 함수
3d-yeju.tistory.com
라이브러리 설치
ethers 라이브러리는 web3.js와 같이 이더리움 네트워크를 조회하고 조작할 수 있는 인터페이스를 제공합니다.
npm i ethers
지갑 연결 후 서명 요청하여 서명값 받아오기
// src > components > MetamaskTracker.tsx
import React, { useEffect } from 'react';
import { useWeb3React } from '@web3-react/core';
import { providers } from 'ethers';
import { useSetRecoilState } from 'recoil';
import { walletAddressAtom } from '../states/atom';
import useAuth from '../hooks/useAuth';
export default function MetaTracker() {
const { account, deactivate } = useWeb3React();
const { login, logout } = useAuth();
const localAccount = window.localStorage.getItem('account');
const setWalletAddress = useSetRecoilState(walletAddressAtom);
const getLoginInfo = async () => {
const message = JSON.stringify({ method: 'LOGIN' });
const sig = await signMessage({ message, account });
if (account && sig) {
// login api 연결 및 login process 진행.
setWalletAddress(account);
window.localStorage.setItem('account', account);
}
};
const signMessage = async ({ message, account }: any) => {
try {
const provider = new providers.Web3Provider(window.ethereum); // provider 생성
const signer = provider.getSigner(account); // 메타마스크에 선택된 지갑으로 서명을 함.
const signature = await signer.signMessage(message);
const address = await signer.getAddress();
return {
signature,
address,
};
} catch (err: any) {
console.log('signMessage-err', err);
deactivate();
}
};
useEffect(() => {
if (account && account !== '') {
if (!localAccount) {
// 로그인 되어있지 않을 때만 서명값 요청
getLoginInfo();
} else {
if (localAccount !== account) {
// 로그인된 지갑주소와 현재 연결되어있는 지갑주소가 다를 때.
window.alert(
'Your wallet account has been changed. Please login again.'
);
logout();
} else {
// 새로고침시 로그인 풀림 방지
setWalletAddress(account);
}
}
}
}, [account]);
useEffect(() => {
if (localAccount !== null) {
// Web3 account 현재계정 업데이트
login();
}
}, []);
return <div />;
}
1. 새로고침 했을 때에는 로컬스토리지로 저장한 로그인 정보 값을 확인하여, 로그인이 되어있는 상태라면 web3-react를 사용하여 메타마스크에 연결된 현재 계정을 업데이트해줍니다.
2. web3-react에 지갑이 연결되어 있다면 연결된 지갑주소와 로컬스토리지의 지갑주소를 확인하여 분기를 타줍니다.
1) 로컬 지갑 주소 없을 때 (= 로그인이 안되어있을 때) , 서명 요청
2) 로컬 지갑 주소가 있을 때는 연결된 지갑주소와 로컬스토리지 지갑주소가 같은지 확인.
같다면 전역 state값 업데이트, 다르다면 로그아웃 처리.
3. 서명을 요청하기 위해서는 연결된 지갑 주소와 서명에 표시될 message값을 정의하여 넘겨주어야 합니다.
4. 서명하기
const provider = new providers.Web3Provider(window.ethereum); // provider 생성
const signer = provider.getSigner(account); // 메타마스크에 선택된 지갑으로 서명을 함.
const signature = await signer.signMessage(message);
const address = await signer.getAddress();
provider를 설정하고 해당 privider로 서명을 요청한 후 서명값과 지갑주소 값을 확인해 로그인 처리를 해줍니다. 이때, 서명에 사용된 메시지 값은 서버 쪽에서 서명값으로 로그인정보를 확인할 때 같아야 하므로 함께 보내주면 됩니다.
* 서명을 취소했을 때 try catch 문에 걸려 나는 에러.
이 때는, 로그인 처리가 완전히 되어있지 않은 상태이기 때문에 deactivate 함수를 사용하여 지갑 연결도 끊어버립니다.
https://meongae.tistory.com/89https://dantechblog.gatsbyjs.io/posts/web3-react/
'Web > React & Next.js' 카테고리의 다른 글
React | web3를 사용하여 메타마스크(Metamask) BSC 네트워크 변경 및 추가하기 (0) | 2023.01.25 |
---|---|
React | axios interceptors header에 token값 설정&추가하기, 삭제하기 (0) | 2023.01.17 |
React | web3-react를 사용하여 메타마스크(Metamask) 지갑연결하기 (0) | 2023.01.16 |
TypeScript 환경에서 React Query 사용하기 (0) | 2022.11.28 |
React | Swiper.js를 사용하여 카드 슬라이드 구현하기 (Slides per view) (0) | 2022.11.25 |