如何使用 Gas API 和 Next.js 建立簡易 Gas 追蹤應用程式

了解如何利用 MetaMask gas API、Next.js 和 ShadcnUI 建立一個簡單的 gas 追蹤應用程式。

8 分鐘閱讀
如何使用 Gas API 和 Next.js 建立簡易 Gas 追蹤應用程式

「Gas」是指衡量執行操作所需計算工作量的單位,例如進行交易或執行智能合約。這類似於汽車的燃料——網路處理和驗證操作時不可或缺。以太坊上的每筆交易都需要特定數量的 gas,由其複雜程度決定。使用者以 Gwei 設定 gas 價格(1 Gwei = 十億分之一個以太幣),代表他們願意為每單位 gas 支付的以太幣金額。

了解 gas 價格對於區塊鏈網路至關重要,因為它能幫助使用者管理交易成本。掌握當前 gas 價格,使用者可以選擇最經濟實惠的時機發起交易,並決定交易速度。了解 gas 價格對於防止交易失敗、規劃預算、理解網路擁塞狀況,以及做出明智的投資決策同樣不可或缺。

MetaMask Gas API

MetaMask Gas API 可透過 Infura 取得,是一款專為以太坊虛擬機器(EVM)相容網路提供即時 gas 價格資訊的專業工具。它作為預言機運作,提供在這些網路上執行操作或交易所需計算成本的最新資料。此 API 賦予開發者建立進階 gas 估算功能的能力,有助於節省後端交易操作的成本,或提升使用者的操作介面體驗。

在本教學中,我們將學習如何使用 Gas API、Next.js 和 ShadcnUI 建立一個 Gas Tracker 應用程式。此應用程式將讓 dapp 使用者能夠根據其交易優先順序取得建議的 gas 價格,協助確保這些交易能有效率地被納入區塊鏈區塊中。

前置條件

設定 Next.js + ShadcnUI

首先,確認您的機器已安裝 Node.js。設定好 Node.js 後,開啟終端機並執行以下指令,建立一個新的 Next.js 應用程式:

npx create-next-app@latest

執行指令後,不僅會出現多個提示,還會在您指定的專案名稱下建立一個新目錄——我使用的是 gastracker-app,從而建立 Next.js 的基礎架構並安裝必要的相依套件。接著,切換至您的專案目錄:

npx create-next-app@latest
✔ What is your project named? … gastracker-app
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias (@/*)? … No / Yes
複製

進入新的專案目錄後,使用以下指令以開發模式啟動 Next.js 應用程式。接著,您可以在瀏覽器中前往 http://localhost:3000 探索您的應用程式。

cd gastracker-app
npm run dev
複製

設計使用者介面

我們的應用程式將使用元件庫。讓我們先安裝 ShadcnUI:

npx shadcn-ui@latest init

安裝過程中,系統將引導您透過以下提示設定 components.json 檔案:

Would you like to use TypeScript (recommended)? no / yes
Which style would you like to use? › Default
Which color would you like to use as base color? › Slate
Where is your global CSS file? › › app/globals.css
Do you want to use CSS variables for colors? › no / yes
Where is your tailwind.config.js located? › tailwind.config.js
Configure the import alias for components: › @/components
Configure the import alias for utils: › @/lib/utils
Are you using React Server Components? › no / yes
複製

完成後,讓我們也安裝 Shadcn UI 的 Card 元件:

npx shadcn-ui@latest add card

在本教學中,我們將專注於使用 Shadcn UI 的 Card 元件。若要深入了解這些元件,請造訪 Shadcn UI 網站。前端設定完成後,我們就可以開始使用 Gas API 了。

在根目錄中,建立一個名為 .env 的檔案,用於儲存以下憑證:

INFURA_API_KEY=
INFURA_API_KEY_SECRET=
複製

請務必從您的 Infura 儀表板取得 API_KEY 和 API_KEY_SECRET。切記不要將 API 金鑰推送至 GitHub。在根目錄中,檢查 .gitignore 檔案,確認已包含必要的設定行。

# Ignore environment variables
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
複製

我們還需要 axios 和 dotenv 套件:

npm install axios
npm install dotenv
複製

現在,在 gastracker-app 的根目錄建立一個名為 'index.js' 的檔案,並將以下程式碼複製進去:

const axios = require("axios");
require("dotenv").config();

const Auth = Buffer.from(
  process.env.INFURA_API_KEY + ":" + process.env.INFURA_API_KEY_SECRET,
).toString("base64");

// The chain ID of the supported network
const chainId = 1;

(async () => {
  try {
    const { data } = await axios.get(
      `https://gas.api.infura.io/networks/${chainId}/suggestedGasFees`,
      {
        headers: {
          Authorization: `Basic ${Auth}`,
        },
      },
    );
    console.log("Suggested gas fees:", data);
  } catch (error) {
    console.log("Server responded with:", error);
  }
})();
複製

在另一個終端機視窗中,執行以下指令。

node index.js

您應該會看到以下內容:

Suggested gas fees: {
  low: {
    suggestedMaxPriorityFeePerGas: '0.05',
    suggestedMaxFeePerGas: '28.501086221',
    minWaitTimeEstimate: 15000,
    maxWaitTimeEstimate: 30000
  },
  medium: {
    suggestedMaxPriorityFeePerGas: '0.1',
    suggestedMaxFeePerGas: '38.508966399',
    minWaitTimeEstimate: 15000,
    maxWaitTimeEstimate: 45000
  },
  high: {
    suggestedMaxPriorityFeePerGas: '0.3',
    suggestedMaxFeePerGas: '48.666846576',
    minWaitTimeEstimate: 15000,
    maxWaitTimeEstimate: 60000
  },
  estimatedBaseFee: '28.451086221',
  networkCongestion: 0.7718,
  latestPriorityFeeRange: [ '0.05', '9.249760902' ],
  historicalPriorityFeeRange: [ '0.023435712', '56.009283908' ],
  historicalBaseFeeRange: [ '19.277073248', '31.361941035' ],
  priorityFeeTrend: 'down',
  baseFeeTrend: 'up'
}
複製

若您觀察到終端機中顯示的資料,表示我們已成功從 API 接收到回應。下一步是將此資料呈現在前端介面上。您現在可以刪除 index.js 檔案。

在前端顯示 gas 資料

若要為整個專案建立自訂型別,請在根目錄建立一個名為 'index.d.ts' 的檔案,並加入以下內容:

interface GasFeeEstimate {
    suggestedMaxPriorityFeePerGas: string;
    suggestedMaxFeePerGas: string;
    minWaitTimeEstimate: number;
    maxWaitTimeEstimate: number;
  }

  interface GasFeesApiResponse {
    low: GasFeeEstimate;
    medium: GasFeeEstimate;
    high: GasFeeEstimate;
    estimatedBaseFee: string;
    networkCongestion: number;
    latestPriorityFeeRange: string[];
    historicalPriorityFeeRange: string[];
    historicalBaseFeeRange: string[];
    priorityFeeTrend: 'up' | 'down';
    baseFeeTrend: 'up' | 'down';
  }
複製

全域檔案中的這些 TypeScript 介面宣告定義了 gas 費用估算與 API 回應的資料結構,涵蓋費用建議、等待時間、網路擁塞狀況,以及區塊鏈網路上不同交易優先等級的費用趨勢等詳細資訊。

在 'lib' 資料夾中,建立一個名為 'getData.ts' 的檔案,並加入以下程式碼:

const Auth = Buffer.from(
  process.env["INFURA_API_KEY"] + ":" + process.env["INFURA_API_KEY_SECRET"]
).toString("base64");

// The chain ID of the supported network
const chainId = 1;

export const getData = async () => {
  try {
    const res = await fetch(
      `https://gas.api.infura.io/networks/${chainId}/suggestedGasFees`,
      {
        headers: {
          Authorization: `Basic ${Auth}`,
        },
      }
    );

    const data = await res.json();

    return data as GasFeesApiResponse;
  } catch (error) {
    console.log("Server responded with:", error);
  }
};
複製

這些程式碼從 Gas API 取得 gas 費用資料:

  1. 驗證設定:從 INFURA_API_KEY 和 INFURA_API_KEY_SECRET 建立 Buffer,這兩者均設定為環境變數。此 Buffer 接著被轉換為 base64 字串(命名為 'Auth'),用於 API 請求中的基本驗證。

  2. Chain ID 設定:將變數 chainId 設為 1,在區塊鏈情境中通常代表以太坊主網。

  3. getData 函式:一個用於取得 gas 費用資料的非同步函式:

  • 使用 fetch 向 Infura API 端點發出 GET 請求,取得指定 chainId 的建議 gas 費用。

  • 在請求中使用先前建立的 Auth token 設定 Authorization 標頭。

  • 若成功,將回應解析為 JSON 並以 GasFeesApiResponse 形式回傳,與先前定義的介面相符。

  • 將任何錯誤(例如網路問題或伺服器錯誤)記錄至主控台。

Chain ID 的可變性:chainId 可根據應用程式所建構的網路進行調整。Infura 上的 Gas API 支援大多數主要的 EVM 網路。有關支援網路的更多資訊,請造訪說明文件。

處理使用者介面

我們現在進入令人興奮的部分,將專注於建立顯示資料的 UI。讓我們前往 components 資料夾,建立一個名為 'GasCard.tsx' 的元件。

import { getData } from "@/lib/getData";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";

export const GasCard = async () => {
  const data = await getData();

  const renderGasFeeEstimateCard = (
    estimate: GasFeeEstimate,
    title: string
  ) => (
    <Card>
      <CardHeader>
        <CardTitle>{title}</CardTitle>
      </CardHeader>
      <CardContent>
        <p>Max Priority Fee: {estimate.suggestedMaxPriorityFeePerGas}</p>
        <p>Max Fee Per Gas: {estimate.suggestedMaxFeePerGas}</p>
        <p>Min Wait Time: {estimate.minWaitTimeEstimate} seconds</p>
        <p>Max Wait Time: {estimate.maxWaitTimeEstimate} seconds</p>
      </CardContent>
    </Card>
  );

  return (
    <div className="space-y-4">
      <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
        {data?.low &&
          renderGasFeeEstimateCard(data.low, "Low Gas Fee Estimate")}
        {data?.medium &&
          renderGasFeeEstimateCard(data.medium, "Medium Gas Fee Estimate")}
        {data?.high &&
          renderGasFeeEstimateCard(data.high, "High Gas Fee Estimate")}
      </div>
      <Card>
        <CardContent>
          <h2 className="font-semibold">Estimated Base Fee</h2>
          <p>Gas Price: {data?.estimatedBaseFee}</p>
          <h2 className="font-semibold">Network Congestion</h2>
          <p>{data?.networkCongestion}</p>
          <h2 className="font-semibold">Latest Priority Fee Range</h2>
          <p>{data?.latestPriorityFeeRange.join(" - ")}</p>
          <h2 className="font-semibold">Historical Priority Fee Range</h2>
          <p>{data?.historicalPriorityFeeRange.join(" - ")}</p>
          <h2 className="font-semibold">Historical Base Fee Range</h2>
          <p>{data?.historicalBaseFeeRange.join(" - ")}</p>
          <h2 className="font-semibold">Priority Fee Trend</h2>
          <p>{data?.priorityFeeTrend}</p>
          <h2 className="font-semibold">Base Fee Trend</h2>
          <p>{data?.baseFeeTrend}</p>
        </CardContent>
      </Card>
    </div>
  );
};
複製

讓我們來看看這裡發生了什麼:

  1. 匯入與資料取得:

  • 此元件匯入用於取得 gas 費用資料的 getData 函式,以及各種 UI 元件,例如 Card、CardContent、CardHeader 和 CardTitle,這些都是我們先前安裝的 Shadcn UI 的一部分。

  • 在 GasCard 元件內部,呼叫 getData 函式以取得 gas 費用資料。

  1. 渲染 Gas 費用估算:

  • 定義一個名為 renderGasFeeEstimateCard 的函式,用於渲染特定 gas 費用估算(GasFeeEstimate)和標題(title)的卡片 UI。

  • 此函式建構一個 Card 元件,顯示最高優先費用、每單位 gas 的最高費用以及預估等待時間等詳細資訊。

  1. 元件結構:

  • GasCard 元件的 JSX 結構在 return 陳述式中呈現。它採用網格排版來展示低、中、高 gas 費用估算的卡片,這些卡片會根據資料可用性條件式顯示。

  • 另一張卡片顯示更多資訊,例如預估基礎費用、網路擁塞狀況、優先費用範圍(最新與歷史資料),以及優先費用和基礎費用的趨勢。

現在,唯一剩下的步驟是將 GasCard.tsx 匯入 page.tsx 檔案。完成後,所有資料應該都能在前端介面上顯示。

開始使用 Gas API

使用 Infura 上的 Gas API 為與 EVM 相容網路互動的開發者提供顯著優勢。它提供對波動 gas 市場的即時洞察,讓使用者能夠針對交易費用做出明智的決策。這對於同時優化交易速度和成本效益特別有益。

本教學涵蓋如何開始使用 GasAPI 並建立一個簡單的 Gas Tracker 應用程式。您可以在此找到程式碼:GitHub 上的 GasAPI-Template。

但我們還可以做更多有趣的事情;我們可以加入在特定時間搭配倒數計時器刷新 GasData 的功能,也可以將 GasAPI 整合到任何現有的應用程式中。我建議參考以下資源:

Gas API 文件:Infura Gas API 說明文件

EventSea:一個創意運用 GasAPI 的全端 Events Dapp:GitHub 上的 EventSea

祝開發愉快!🚀

AI 翻譯。可能包含錯誤。請務必核實資訊。

評價此翻譯