메타마스크 테스트 네트워크의 지갑주소, 잔고를 화면에 뿌려보자.
리액트에서 web3의 Dapp과 관련된 특정 데이터를 최신상태로 유지해주는 state machine으로 기본 블록체인 API가 ethers.js인 react 라이브러리이다.
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를 제공하는 역할을 한다.
context 값에 접근할 수 있도록 해주는 hook
const {connector, library, chainId, account, active, error, activate, deactivate} = useWeb3React();
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>
);
}
연결 버튼을 누르면 메타마스크 지갑과 연동되고, 관련된 데이터들이 렌더링된다.
기존에 메타마스크 익스텐션이 설치되어 있지 않은 경우, 에러 처리도 추가해 주었다.
위에서 언급한 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>
)
}