ethers-i18n GitHub リポジトリ

はじめに

ethers.jsを使ったdApp開発で、こんな経験はありませんか?

Error: insufficient funds for intrinsic transaction cost

エラーの意味は分かるけれど、このメッセージをそのままエンドユーザーに見せるわけにはいきません。特に日本語圏のユーザー向けサービスでは、エラーメッセージの日本語化は避けて通れない課題です。

そこで、ethers.jsのエラーメッセージを多言語化するライブラリ ethers-i18n を作りました。

https://github.com/nakamura196/ethers-i18n

ethers-i18nとは

ethers-i18nは、ethers.js v6のエラーコードに対応した翻訳メッセージを提供するi18nプラグインです。

主な特徴:

  • シンプルなAPIsetLocale("ja")t("ERROR_CODE") だけで使える
  • 非破壊的 — 既存のethers.jsコードに影響を与えない
  • 型安全 — TypeScriptの型定義を完備
  • 4言語対応 — 英語・日本語・韓国語・中国語をサポート
  • 軽量 — 依存関係はethers.jsのみ(peerDependency)

インストール

npm install @nakamura196/ethers-i18n

ethers.js v6がpeerDependencyとして必要です。

基本的な使い方

ロケールの設定と翻訳

import { setLocale, t, getLocale, getSupportedLocales } from "@nakamura196/ethers-i18n";

// サポートされているロケール一覧
console.log(getSupportedLocales()); // ["en", "ja", "ko", "zh"]

// 日本語に設定
setLocale("ja");
console.log(getLocale()); // "ja"

// エラーコードを翻訳
console.log(t("INVALID_ARGUMENT"));    // "無効な引数です"
console.log(t("INSUFFICIENT_FUNDS"));  // "トランザクションに必要な残高が不足しています"
console.log(t("NETWORK_ERROR"));       // "ネットワークエラーが発生しました"

エラーオブジェクトの翻訳

ethers.jsが投げるエラーオブジェクトをそのまま翻訳できます。

import { setLocale } from "@nakamura196/ethers-i18n";
import { translateError } from "@nakamura196/ethers-i18n/wrapper";

setLocale("ja");

try {
  // ethers.jsの操作(例:不正なアドレスでの送金)
  await provider.getBalance("invalid-address");
} catch (error) {
  // ethers.jsのエラーコードを自動検出して翻訳
  const message = translateError(error);
  console.log(message); // "無効な引数です"
}

withI18nラッパー

非同期関数をラップして、エラーメッセージを自動的に翻訳することもできます。

import { setLocale } from "@nakamura196/ethers-i18n";
import { withI18n } from "@nakamura196/ethers-i18n/wrapper";

setLocale("ja");

try {
  const balance = await withI18n(() => provider.getBalance("invalid-address"));
} catch (error) {
  // error.message は翻訳済み
  console.log(error.message); // "無効な引数です"

  // 元のメッセージも保持されている
  console.log(error.originalMessage); // "invalid argument"
}

withI18nの利点は、翻訳されたエラーをthrowしてくれるため、上位のエラーハンドリングでそのまま多言語メッセージを利用できることです。

対応エラーコード一覧

ethers.js v6の主要なエラーコード17種に対応しています。

エラーコード英語日本語
INVALID_ARGUMENTinvalid argument無効な引数です
MISSING_ARGUMENTmissing argument引数が不足しています
UNEXPECTED_ARGUMENTunexpected argument予期しない引数です
CALL_EXCEPTIONcall exceptionコントラクト呼び出しに失敗しました
INSUFFICIENT_FUNDSinsufficient fundsトランザクションに必要な残高が不足しています
NETWORK_ERRORnetwork errorネットワークエラーが発生しました
SERVER_ERRORserver errorサーバーエラーが発生しました
TIMEOUTtimeoutタイムアウトしました
BUFFER_OVERRUNbuffer overrunバッファオーバーランが発生しました
NUMERIC_FAULTnumeric fault数値演算エラーが発生しました
ACTION_REJECTEDaction rejectedユーザーによって操作が拒否されました
NONCE_EXPIREDnonce expiredノンスは既に使用されています
REPLACEMENT_UNDERPRICEDreplacement fee too low置換手数料が低すぎます
TRANSACTION_REPLACEDtransaction replacedトランザクションが置換されました
UNPREDICTABLE_GAS_LIMITcannot estimate gasガスリミットを推定できません
UNSUPPORTED_OPERATIONunsupported operationサポートされていない操作です
UNKNOWN_ERRORunknown error不明なエラーが発生しました

設計思想

なぜライブラリとして切り出したのか

dApp開発ではエラーメッセージの翻訳は各プロジェクトで個別に対応しがちです。しかし、ethers.jsのエラーコードは仕様として固定されているため、翻訳を共通化できます。

ライブラリとして提供することで:

  1. 車輪の再発明を防ぐ — 各プロジェクトで同じ翻訳を書く必要がない
  2. 翻訳品質の向上 — コミュニティで翻訳をレビュー・改善できる
  3. 型安全性 — エラーコードのtypoをコンパイル時に検出できる

シンプルなAPI設計

// 設定は1行
setLocale("ja");

// 翻訳も1行
const msg = t("INVALID_ARGUMENT");

i18nライブラリにありがちな複雑な設定は不要です。ethers.jsのエラーコードという限定されたスコープに特化することで、APIをシンプルに保っています。

フォールバック機構

翻訳が見つからない場合は、フォールバックロケール(デフォルト: 英語)が使われます。

import { configure } from "@nakamura196/ethers-i18n";

configure({
  locale: "ja",
  fallback: "en", // 日本語訳がない場合は英語にフォールバック
});

新しい言語を追加する

新しい言語の追加は非常に簡単です。ロケールファイルを1つ作成するだけです。

// src/locales/fr.ts
import { LocaleMessages } from "../types";

export const fr: LocaleMessages = {
  INVALID_ARGUMENT: "argument invalide",
  MISSING_ARGUMENT: "argument manquant",
  UNEXPECTED_ARGUMENT: "argument inattendu",
  CALL_EXCEPTION: "exception d'appel de contrat",
  INSUFFICIENT_FUNDS: "fonds insuffisants pour la transaction",
  // ... 残りのエラーコードも定義
};

LocaleMessages型により、すべてのエラーコードを漏れなく定義する必要があるため、翻訳の抜け漏れを防げます。

ユースケース

1. dAppのエラー表示

// React での使用例
import { setLocale } from "@nakamura196/ethers-i18n";
import { translateError } from "@nakamura196/ethers-i18n/wrapper";

function App() {
  // ブラウザの言語設定に応じてロケールを切り替え
  useEffect(() => {
    const lang = navigator.language.startsWith("ja") ? "ja" : "en";
    setLocale(lang);
  }, []);

  const handleTransaction = async () => {
    try {
      await contract.transfer(to, amount);
    } catch (error) {
      // ユーザーに分かりやすいメッセージを表示
      toast.error(translateError(error));
    }
  };
}

2. CLIツールのエラーメッセージ

import { setLocale } from "@nakamura196/ethers-i18n";
import { withI18n } from "@nakamura196/ethers-i18n/wrapper";

// 環境変数でロケールを制御
setLocale(process.env.LANG?.startsWith("ja") ? "ja" : "en");

const balance = await withI18n(() => provider.getBalance(address));

今後の展望

  • 対応言語の拡充 — フランス語、スペイン語、ドイツ語などの追加
  • エラーメッセージのカスタマイズ — プロジェクト固有のメッセージで上書きする機能
  • viem対応 — ethers.jsだけでなくviemのエラーメッセージにも対応

コントリビューションは大歓迎です!特に各言語の翻訳についてPRをお待ちしています。

まとめ

ethers-i18nは、ethers.jsのエラーメッセージを多言語化するための軽量なプラグインです。シンプルなAPIで既存のコードに簡単に組み込め、TypeScriptの型安全性により翻訳の抜け漏れも防げます。

dAppのUX向上に、ぜひお試しください。

https://github.com/nakamura196/ethers-i18n