Typescript가 window.ethereum을 거부할때..

2022. 9. 8. 17:11React/NFT Airdropper

Typescript로 작업을 하게 되면 당연하지만,

window.ethereum을 올바르지 않은 객체 접근이라고 뜬다.

 

 

그간 Theme를 설정하느라 XXXX.d.ts에 대해서 배워왔다. 이번에도 똑같이 설정해주면 되지않을까?

근데 어디에서 선언을 해줘야하는걸까?

 

 

Trying to use window.ethereum.request in Typescript errors out with Property 'request' does not exist on type 'EthereumProvider'

Except for one unanswered question from last November, I cannot find anything . . . . I am revamping some typescript code (in Visual Studio) for the Metamask January change. Previously, I was using...

ethereum.stackexchange.com

 

정답은 react-app.env.d.ts

 

 

window.ethereum에 포함되어 있는 수많은 callback 함수들과 언제 어떻게 쓰일 지 모르는 변수들을 하나하나 정의해주기는 너무너무 귀찮고 힘들다.

 

맘편하게 any로 설정해보자!

 

 react-app.env.d.ts

/// <reference types="react-scripts" />

interface Window {
  ethereum: any;
}

 

자 어차피 connect metamask 해서 지갑 주소를 받아오는 과정은 hooks로 빼줘서 작업을 해줘야 하니 미리미리 훅을 만들어주자.

 

useMetaMask.ts

import {useState, useEffect, useCallback} from "react";

export const useMetaMask = (): void => {
  const [isMetaMaskInstalled, setIsMetaMaskInstalled] = useState(false);

  const checkMetaMaskInstall = useCallback(() => {
    if (window.ethereum.isMetaMask) {
      console.log("installed completed");
    }
  }, []);

  useEffect(() => {
    checkMetaMaskInstall();
  }, []);
};

 

Docs.tsx

import React from 'react';
import { DocsDivider } from "./styles";
import { ReactComponent as Logo } from "../../assets/svg/Logo.svg";
import Button from "../../component/button/button";
import {useMetaMask} from "../../utils/useMetaMask";

const Docs = () => {
  return (
    <DocsDivider>
      <div className={"nav"}>
        <Logo />
        <Button 
          content={"link with MetaMask"} 
          btnType={"default"} 
          animation 
          onClick={(e) => console.log(window.ethereum)} />
      </div>
    </DocsDivider>
  );
}

export default Docs;

 

자 한 번 결과를 본다면?

위엔 window.ethereum, 아래엔 window.ehtereum.isMetaMask

 

오 에러 없이 잘 되는 걸 확인할 수 있다.

다음에 한번 포스팅하긴 할거지만, window.ethereum 객체는 chrome의 MetaMask를 확장 프로그램으로 설치했다는 걸 가정하고 실행한다.

 

따라서 다양한 예외 케이스들을 다뤄줘야한다.

 

1. MetaMask 확장이 지원되지 않는 브라우저를 만났을 경우,
2. 모바일 브라우저를 만났을 경우
    (deep link로 메타마스크 앱에 요청을 쏴주거나, MetaMask 앱의 브라우저를 쓰거나)
3. 크롬 환경이지만 아직 MetaMask가 설치되지 않은경우,

 

각 조건들에 대한 return 값을 최상단에서 useState로 관리를 해주자.

그러면 각 상황에 대해 처리가 가능하다.

 

이 처리 과정은 조금 더 깔끔하게 다룬 뒤 공유하겠다.