TIL96. 메타마스크 지갑 연동(feat.web3-react)

조연정·2022년 4월 27일
3
post-thumbnail

메타마스크 테스트 네트워크의 지갑주소, 잔고를 화면에 뿌려보자.

Web3-react란?

리액트에서 web3의 Dapp과 관련된 특정 데이터를 최신상태로 유지해주는 state machine으로 기본 블록체인 API가 ethers.js인 react 라이브러리이다.

*web3js

web3.js는 내부적으로 HTTP나 IPC(프로세스 사이에서 통신을 가능하게 하는 기술)를 통해 JSON-RPC API를 호출하도록 되어있다. 이더리움 네트워크는 노드로 구성되어 있고, 각 노드는 블록체인의 복사본을 가지고 있다. 이더리움 노드들은 JSON-RPC로만 소통할 수 있기 때문에 web3.js로 개발자들이 쉽게 개발할 수 있도록 자바스크립트 인터페이스로 상호작용할 수 있도록 도와주는 역할을 한다.

설치 및 기본설정

npm i @web3-react/core @ethersproject/providers
// index.js
import ReactDOM from "react-dom";
import { Web3ReactProvider } from "@web3-react/core";
import { Web3Provider } from "@ethersproject/providers";
import App from "./App";

const getLibrary = (provider: any) => new Web3Provider(provider);

const rootElement = document.getElementById("root");
ReactDOM.render(
  <StrictMode>
    <Web3ReactProvider getLibrary={getLibrary}>
      <App />
    </Web3ReactProvider>
  </StrictMode>,
  rootElement
);

web3를 사용하려면 리액트 앱 루트에 Web3ReactProvider컴포넌트로 감싸줘야한다. 이 컴포넌트에 getLibrary함수를 props로 전달하는데 web3-react가 사용할 web3 provider를 제공하는 역할을 한다.

useWeb3React()

context 값에 접근할 수 있도록 해주는 hook

const {connector, library, chainId, account, active, error, activate, deactivate} = useWeb3React();
  • connector: 현재 dapp에 연결된 지갑의 connector 값
  • *library: web3 provider 제공
  • chainId: dapp에 연결된 account의 chainId
  • account: dapp에 연결된 지갑 주소
  • active: dapp 유저가 로그인 상태
  • activate: dapp 월렛 연결 기능 함수
  • deactivate: dapp 월렛 연결 해제 함수
function Wallet() {
  	const {account, library, active, activate, deactivate} = useWeb3React();

  const connectWallet = async () => {
		try {
			await activate(injected);
		} catch (err) {
			console.log(err);
		}
	};
}

지갑 연동

지갑을 dapp에 연결하기 위해서는 해당 지갑과 맞는 connector를 activate 함수에 인자로 전달해야 한다.(metamask-injectedConnector)

//설치
npm i @web3-react/injected-connector
// connectors.js
import {InjectedConnector} from '@web3-react/injected-connector';

export const injected = new InjectedConnector();

구현코드

function Wallet() {
  const connectWallet = async () => {
		try {
			await activate(injected, (error) => {
				// 크롬 익스텐션 없을 경우 오류 핸들링
				if ('/No Ethereum provider was found on window.ethereum/')
					throw new Error('Metamask 익스텐션을 설치해주세요');
			});
		} catch (err) {
			alert(err);
			window.open('https://metamask.io/download.html');
		}
	};
  return (
		<div>
			{active ? (
				<>
					<WalletINfo>
						<h2>My Wallets</h2>
						<span>
							{account?.substr(0, 8)}...{account?.substr(0, 8)}
						</span>
					</WalletINfo>
				</>
			) : (
				<ConnectButton connectWallet={connectWallet} />
			)}
		</div>
	);
}

연결 버튼을 누르면 메타마스크 지갑과 연동되고, 관련된 데이터들이 렌더링된다.
기존에 메타마스크 익스텐션이 설치되어 있지 않은 경우, 에러 처리도 추가해 주었다.

⭐️library

위에서 언급한 context 값
'library'에서 getbalance에 접근할 수 있다.
getbalance 속성 {
_hex:string;
_isBigNumber:boolean;
}
_hex 16진수이기 때문에 formatEther 라이브러리를 사용해서 10진수로 변환

	function Wallet () {
  	const {account, library, active} = useWeb3React();
    	const [balance, setBalance] = useState('');

    useEffect(() => {
		if (account) {
			library
				?.getBalance(account)
				.then((result: IResult) => setBalance(result._hex));
		}
	}, [account, library]);
    
    return(
    <h1>
		 {balance && Number(formatEther(balance)).toFixed(4)}
							ETH
	 </h1>
    )
  }
profile
Lv.1🌷

0개의 댓글