MetaMaskは何千万ものユーザーにとってEthereumへの主要な入り口であり、dApp開発者にとってMetaMask APIはUIとユーザーの署名キーを繋ぐ重要なインターフェースです。MetaMask APIは、EIP-1193で定義されたwindow.ethereumプロバイダーと、同インターフェースをモバイルやNode.jsに拡張するMetaMask SDKの2つで構成されます。このプロバイダーを理解すれば、Web3ウォレット統合の大半に対応できます。
このガイドでは、プロバイダーの検出、アカウントリクエスト、チェーンの取得、personal_signやEIP-712を利用した署名、トランザクション送信、チェーン追加・切替、さらにMetaMask SDKをブラウザ外で使う手順を解説します。ethers.js v6・viemとの組み合わせや、JSON-RPC呼び出しのテスト方法としてApidogを活用する方法も紹介します。
ウォレット関連の開発を行う際は、このガイドと最高の暗号ウォレットAPI解説も一緒にブックマークしておくと便利です。
要点
- MetaMask APIはブラウザの
window.ethereum(EIP-1193プロバイダー)と、モバイル/Node向けMetaMask SDKで構成。 -
eth_requestAccountsでユーザー接続、accountsChangedとchainChangedで状態監視。 -
personal_signでメッセージ署名、eth_signTypedData_v4(EIP-712)で構造化データ署名。 -
wallet_switchEthereumChain(EIP-3326)でネットワーク切替、wallet_addEthereumChain(EIP-3085)で新規ネットワーク追加。 - ethers.js v6、viem、wagmiなどの高レベルライブラリはプロバイダーをラップ、SnapsでMetaMask拡張も可能。
- ApidogでJSON-RPCエンドポイントのテスト、トランザクション応答のモック、署名デバッグができる。
MetaMask APIとは?
MetaMask APIは、MetaMaskがWebページやアプリに提供するEVM互換チェーンと通信するための標準インターフェースです。ブラウザ拡張はwindow.ethereumを注入し、これはEIP-1193に準拠。EIP-1193対応dAppはMetaMask・Coinbase Wallet・Rabbyなど主要ウォレットすべてで動作します。
ブラウザ以外では、MetaMask SDKを使うことで、React NativeやNode.js、Electronアプリ、サーバーサイドスクリプトでも同じ方式で接続できます。SDKはディープリンクやQRコード経由でトランザクション署名をモバイルウォレットへ委譲可能。コードの共通化が容易です。
また、MetaMaskはSnapsというプラグインシステムも提供しており、サードパーティによる新チェーン追加・カスタムRPCメソッド・独自アカウントタイプの拡張が可能です(本記事では割愛)。
認証とセットアップ
MetaMaskプロバイダー自身にAPIキーは不要です。認証は、ユーザーが各リクエストごとにウォレットUIで承認ボタンを押す形になります。実装時のポイントは、プロバイダー検出とイベントリスナー追加です。
プロバイダーの検出
複数ウォレットが同時インストールされているケースもあるため、@metamask/detect-providerの利用が推奨されます。直接チェックも可能です。
// Vanilla JSでMetaMaskプロバイダーを検出
import detectEthereumProvider from '@metamask/detect-provider';
const provider = await detectEthereumProvider({ mustBeMetaMask: true });
if (!provider) {
alert('Please install MetaMask');
} else {
console.log('MetaMask detected');
}
イベントリスナーの追加
アカウントやチェーンの切替イベントを必ずハンドリングしましょう。accountsChangedを無視するとバグの原因になります。
window.ethereum.on('accountsChanged', (accounts) => {
if (accounts.length === 0) {
console.log('User disconnected');
} else {
console.log('Active account:', accounts[0]);
}
});
window.ethereum.on('chainChanged', (chainId) => {
// ベストプラクティス: チェーン変更時はリロード
window.location.reload();
});
React環境ではwagmi等のライブラリがコネクタとして自動検出・管理してくれます。
主要エンドポイント
全てのリクエストはwindow.ethereum.request({ method, params })で行います。メソッドはJSON-RPCの文字列名、paramsは配列またはオブジェクトです。以下、主要なメソッドとサンプル実装例です。
アカウントリクエストとチェーン情報取得
// ユーザーに接続を促す
const accounts = await window.ethereum.request({
method: 'eth_requestAccounts',
});
const account = accounts[0];
// 現在のチェーンIDを取得
const chainId = await window.ethereum.request({
method: 'eth_chainId',
});
console.log(account, chainId); // 例: '0x...' '0x1'
同じリクエストはcurlでも実行可能です。
curl https://mainnet.infura.io/v3/YOUR_KEY \
-X POST \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'
読み取りだけの場合はMetaMask不要で、AlchemyやInfura等のノードプロバイダー経由でもOKです。詳細はAlchemy APIガイドを参考に。
メッセージ署名(personal_sign)
const message = 'Sign in to Apidog at ' + new Date().toISOString();
const signature = await window.ethereum.request({
method: 'personal_sign',
params: [message, account],
});
構造化データ署名(EIP-712, eth_signTypedData_v4)
const typedData = {
domain: { name: 'Apidog Demo', version: '1', chainId: 1 },
types: {
EIP712Domain: [
{ name: 'name', type: 'string' },
{ name: 'version', type: 'string' },
{ name: 'chainId', type: 'uint256' },
],
Login: [
{ name: 'wallet', type: 'address' },
{ name: 'nonce', type: 'uint256' },
],
},
primaryType: 'Login',
message: { wallet: account, nonce: 42 },
};
const sig = await window.ethereum.request({
method: 'eth_signTypedData_v4',
params: [account, JSON.stringify(typedData)],
});
トランザクション送信
const txHash = await window.ethereum.request({
method: 'eth_sendTransaction',
params: [{
from: account,
to: '0xRecipientAddressHere',
value: '0x38d7ea4c68000', // 0.001 ETH (wei, hex)
}],
});
チェーン切り替え・新規追加
// Polygon(chainId 137 = 0x89)へ切り替え
try {
await window.ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: '0x89' }],
});
} catch (err) {
if (err.code === 4902) {
// 未追加の場合は新規追加
await window.ethereum.request({
method: 'wallet_addEthereumChain',
params: [{
chainId: '0x89',
chainName: 'Polygon',
rpcUrls: ['https://polygon-rpc.com'],
nativeCurrency: { name: 'MATIC', symbol: 'MATIC', decimals: 18 },
}],
});
}
}
MetaMask SDKをReactで使う
SDKはデスクトップ拡張・モバイルディープリンク・アプリ内ブラウザ全対応のシングルパス統合が可能です。
import { MetaMaskProvider, useSDK } from '@metamask/sdk-react';
function Connect() {
const { sdk, connected, account } = useSDK();
return (
<button onClick={() => sdk?.connect()}>
{connected ? account : 'Connect MetaMask'}
</button>
);
}
export default function App() {
return (
<MetaMaskProvider sdkOptions={{ dappMetadata: { name: 'My dApp' } }}>
<Connect />
</MetaMaskProvider>
);
}
本番アプリでは、ethers.js v6やviemなどでラップし、型付きコントラクト呼び出しやエラーハンドリングを強化しましょう。メールやソーシャルログインを組み合わせる場合はPrivy APIガイドも参考に。
一般的なエラーとレート制限
MetaMaskは標準JSON-RPCエラーコードを返します。よくあるエラーは次の通りです。
-
4001: ユーザーによるリクエスト拒否。再試行は避け、UIで「キャンセルされました」を表示。 -
4100: 権限なし。アカウント未接続。まずeth_requestAccountsを呼ぶ。 -
4200: 未サポートメソッド。ウォレット固有メソッド利用時はMetaMaskか確認。 -
4902: 未追加チェーン。wallet_addEthereumChainで追加。 -
-32002: リクエスト保留中。二重クリック防止のデバウンス推奨。
プロバイダー自体にはレート制限はありませんが、背後のRPCノード(InfuraやAlchemy)はプランごとに制限されます。法定通貨変換などのフィアット連携にはフィアットオンランプAPIガイドも参照ください。
MetaMask APIの料金
MetaMask拡張とSDKは完全無料です。接続・署名・送信ごとの課金はありません。MetaMaskの収益はユーザーのスワップ手数料とカード事業からで、dApp開発者は無料で使えます。
かかるコストは、RPCエンドポイント(例:Alchemy/Infura)の利用分です。無料枠で小規模用途は十分ですが、本番運用では月額49~299ドル程度の専用プラン利用が一般的です。
ApidogでMetaMask APIをテストする
ブラウザベースの署名フローは、拡張・ページ・モバイルディープリンクの連携もありデバッグが難しい場合があります。Apidogを使えば、dAppで利用するJSON-RPCエンドポイントへ直接リクエストし、eth_chainIdやeth_getBalanceの値確認、テストスイート化が容易です。
Ethereum JSON-RPC仕様をインポートし、ノードURLを環境変数で切替えれば、あらゆるEVMチェーンで再利用可能なコレクションを構築できます。Apidogは応答モック機能もあり、コントラクトが未監査でもフロント開発を進めたい場合に便利。CI環境では同コレクションをCLI実行してスキーマ変化検知も可能。Postmanの共有・同期に悩んでいるなら、PostmanなしのAPIテスト解説もおすすめです。
始めるには、Apidogをダウンロードしてください。
よくある質問
MetaMask APIはモバイルで使えますか?
はい、MetaMask SDKで対応可能です。ディープリンクでモバイルウォレット署名を実現できます。インターフェースはブラウザ拡張と同一、コード修正不要です。モバイル用SDK比較はこちら。eth_sign・personal_sign・eth_signTypedData_v4の違いは?
eth_signは生バイト署名で危険。personal_signは人間可読メッセージにプレフィックス、eth_signTypedData_v4(EIP-712)は構造化データ署名とUIでのフィールド表示。後者2つ推奨、eth_signは避けましょう。MetaMask利用にAPIキーは必要?
いいえ、MetaMaskプロバイダー自体は無料・キー不要。外部ノード利用時(Alchemy/Infura等)は別途APIキーが必要です。ethers.jsやviemはMetaMaskと併用できる?
どちらもwindow.ethereumをラップ。ethers v6はBrowserProvider(window.ethereum)、viemはcreateWalletClient({ transport: custom(window.ethereum) })で利用可能。多くのdAppがこれらを利用しています。複数ウォレットインストール時の挙動は?
MetaMaskはEIP-6963対応済み。dAppはwindow.ethereumを取り合わず、全ウォレットの検出が可能。wagmi・RainbowKitは自動対応。MetaMask Snapsは本番利用できる?
2024年に一般公開済み。主に非EVMチェーン対応、カスタムトランザクションインサイト、ハードウェアウォレット統合に用いられています。
Top comments (0)