フロントエンドのベースを作成しよう
🚅 フロントエンドのベースを実装しましょう
コード量が多く貼り付ける作業が大変になってしまうのを防ぐため、本プロジェクトのpackages/clientディレクトリからファイルやディレクトリごとコピーしてフロントエンドを構築していきます。
本レポジトリ自体をローカルにクローンしてからコピーしたほうが作業が楽かもしれません。
📁 stylesディレクトリ
stylesディレクトリにはcssのコードが入っています。
全てのページに適用されるよう用意されたglobal.cssと、ホームページ用のHome.module.cssがあります。
今回はtailwindを使用するので、Home.module.cssを削除してください。
client
└── styles
└── globals.css
📁 publicディレクトリ
Next.jsはルートディレクトリ直下のpublicディレクトリを静的なリソース(画像やテキストデータなど)の配置場所と認識します。
そのためソースコード内で画像のURLを/image.pngと指定した場合、
Next.jsは自動的にpublicディレクトリをルートとしたプロジェクトルート/image.pngを参照してくれます。
このディレクトリを本プロジェクトのpackages/client/publicディレクトリと置き換えてください。
favicon.ico: ファビコンになります。お好きな画像で設定したい場合は同じファイル名で保存するとファビコンに設定できます。
あなたのアプリのファビコンをお好きな画像で設定したい場合は、favicon.icoという名前でpublic/favicon.icoと置き換えてください。
background.png: ホームページの背景画像になります。
tailwindで画像を扱えるようにtailwind.config.jsを以下の内容に書き換えてください。
vscodeがエラーを出す可能性もありますが、気にせず進めて問題ありません。
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./pages/**/*.{js,ts,jsx,tsx}",
"./components/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {
backgroundImage: {
home: "url('../background.png')",
},
},
},
plugins: [],
};
client
└── public
├── background.png
└── favicon.ico
📁 typesディレクトリ
typesディレクトリを本プロジェクトのpackages/clientディレクトリからコピーして貼り付けてください。
中身に関しては次のセクションで触れます。
client
└── types
└── ...
📁 artifactsディレクトリ
artifactsディレクトリを本プロジェクトのpackages/clientディレクトリからコピーして貼り付けてください。
中身に関しては次のセクションで触れます。
client
└── artifacts
├── Bank.json
└── IAllowList.json
📁 utilsディレクトリ
utilsディレクトリを本プロジェクトのpackages/clientディレクトリからコピーして貼り付けてください。
🐬 ethereum.ts
型定義に厳格なtypescriptでwindow.ethereumを使用するためには、windowにethereumオブジェクトがあるということを明示する必要があります。
MetaMaskInpageProviderは環境設定時にインストールした@metamask/providersから取得したethereumの型定義です。
📓
window.ethereumとは Web アプリケーション上でユーザーがブロックチェーンネットワークと通信するためには、Web アプリケーションはユーザーのウォレット情報を取得する必要があります。
window.ethereumは MetaMask がwindow(JavaScript にデフォルトで存在するグローバル変数)の直下に用意するオブジェクトであり API です 。 この API を使用して、ウェブサイトはユーザーのイーサリアムアカウントを要求し、ユーザーが接続しているブロックチェーンからデータを読み取り、ユーザーがメッセージや取引に署名するよう求めることができます。
また、getEthereum関数を呼び出すとwindowから取り出したethereumオブジェクトを取得できるようにしています。
🐬 formatter.ts
weiToAvax(or avaxToWei)はweiとAVAXの単位変換を行なっています。
※ APIでは「1 AVAX = 10^18 wei」で単位変換がされているため、formatEther(or parseEther)を使用できます。
また、blockTimeStampToDateはsolidity内のblock.timestampから、フロントエンドで使用するDateへの変換を行なっています。
block.timestampは単位がミリ秒で、Dateは秒単位の時間を元に作成するので* 1000を行なっています。
🐬 compare.ts
ここでは2つのアドレスを比較する関数を用意しています。
client
└── utils
├── compare.ts
├── ethereum.ts
└── formatter.ts
📁 hooksディレクトリ
hooksディレクトリを本プロジェクトのpackages/clientディレクトリからコピーして貼り付けてください。
ウォレットやコントラクトの状態を扱うようなカスタムフック(独自で作ったフック)を実装したファイルを保存します。
🐬 useWallet.ts
ここでは、ユーザがMetamaskを持っていることの確認とウォレットへの接続機能を実装します。
connectWalletはWebアプリがユーザのウォレットにアクセスすることを求める関数です。
この後の実装でUIにユーザのウォレット接続ボタンを用意し、そのボタンとこの関数を連携します。
そのため外部で使用できるように返り値の中に含めています。
checkIfWalletIsConnectedは既にユーザのウォレットとWebアプリが接続しているかを確認する関数です。
また、それぞれの関数内で使用しているeth_requestAccountsとeth_accountsは,空の配列または単一のアカウントアドレスを含む配列を返す特別なメソッドです。
ユーザーがウォレットに複数のアカウントを持っている場合を考慮して、プログラ ムはユーザーの1つ目のアカウントアドレスを取得することにしています。
🐬 useWallet.ts
ユーザがMetamaskを持っていることの確認とウォレットへの接続機能を実装しています。
connectWalletはWebアプリがユーザのウォレットにアクセスすることを求める関数です。
この後の実装でUIにユーザのウォレット接続ボタンを用意し、そのボタンとこの関数を連携します。
そのため外部で使用できるように返り値の中に含めています。
checkIfWalletIsConnectedは既にユーザのウォレットとWebアプリが接続しているかを確認する関数です。
また、それぞれの関数内で使用しているeth_requestAccountsとeth_accountsは,空の配列または単一のアカウントアドレスを含む配列を返す特別なメソッドです。
ユーザーがウォレットに複数のアカウントを持っている場合を考慮して、プログラムはユーザーの1つ目のアカウントアドレスを取得することにしています。
🐬 useContract.ts
コントラクトとの接続を行います。
ファイル冒頭には、今回フロントエンドから接続する2つのコントラクトのアドレスBankAddressとTxAllowListAddressが記載されています。
BankAddressはBankコントラクトのアドレスに後ほど変更します。
TxAllowListAddressは(section-1のLesson_3で設定したPreCompileの)TransactionAllowListのアドレスになります。
このアドレス値は固定です。
その下には型の定義があり、その下にuseContractが定義されています。
主な関数はgetContractで、接続しているcurrentAccount