react-wallet-connector について
DApp Connector APIを通じてMidnightウォレット拡張機能に接続する、ReactとTypeScriptの実行可能なアプリを生成するスキルです。ウォレットの検出、認証、アドレス表示、任意のウォレット選択を備えたフロントエンドの接続基盤を提供します。
主な機能
- 01ViteによるReact・TypeScriptアプリのひな形
- 02注入されたMidnightウォレットの検出
- 03DApp Connector API経由の接続
- 04接続状態と非シールドアドレスの表示
- 05任意の複数ウォレット選択機能
- 06ネットワーク選択のガイダンス
活用シーン
- 01ウォレット接続対応のReactアプリ作成
- 02インストール済みウォレットからの選択
- 03ネットワーク接続に必要なウォレット認証
- 04ウォレットの接続状態とアドレスの表示
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ kali-decoder/ midnight-skills --skill react-wallet-connectorインストール後、Claude Code で/react-wallet-connectorを入力して読み込まれたか確認します。
詳細
React ウォレットコネクターのスキル
このスキルは、DApp Connector API を使って Midnight ウォレット拡張機能に接続する、完全で実行可能な React アプリケーションを生成します。必要なすべてのファイルを網羅しています。Vite + React + TypeScript のひな形、ウォレットの選択、接続ロジック、WalletCard UI コンポーネントが含まれます。
主な参照資料:
docs.midnight.network— React ウォレットコネクターガイド(DApp Connector API)llms.txt— Midnight のドキュメント全体のインデックス@midnight-ntwrk/[email protected]— 最新の安定版コネクターパッケージ(2026年2月)
主なアーキテクチャ上の注意点:
- ウォレットは
window.midnightにInitialAPIインスタンスを注入し、それぞれに UUID が割り当てられます。window.midnight.mnLaceのようなハードコードされたキーは使用しないでください Object.values(window.midnight)でウォレットを列挙します。ウォレットが複数ある場合は、ユーザーに選択してもらいます@midnight-ntwrk/dapp-connector-apiを副作用インポートして、グローバルのwindow.midnight型を拡張します- シールド済みアドレスは、アプリで実際に必要になったときにのみ要求します。このテンプレートでは
getUnshieldedAddress()を使用します - ネットワーク ID:
'undeployed'(ローカル)、'preview'、'preprod'、'mainnet'。ウォレットで設定されているネットワークと一致させる必要があります - コード例では意図的に CSS スタイルを省略しています。ひな形の作成後、お好みのスタイル設定ソリューションを追加してください
他のスキルとの関係:
- 1AM ウォレットを使ったコントラクトのデプロイと回路呼び出し全般については →
1am-wallet/を使用 - ヘッドレス Node.js ウォレットとテストについては →
example-hello-world/またはmidnight-js/を使用 - このスキルは フロントエンドのウォレット接続の基盤 のみを対象とします
1) プロジェクト構成
my-wallet-app/
├── index.html
├── package.json
├── tsconfig.json
├── tsconfig.app.json
├── tsconfig.node.json
├── vite.config.ts
└── src/
├── main.tsx
├── App.tsx
├── WalletCard.tsx
├── types.ts
├── selectWallet.ts
└── vite-env.d.ts
2) 前提条件
- Node.js 18 以降および npm
- React + TypeScript の基本的な知識
- Midnight ウォレットのブラウザー拡張機能がインストールされていること(1AM、Lace、または DApp Connector 対応ウォレット)
3) ひな形の作成とインストール
npm create vite@latest my-wallet-app -- --template react-ts
cd my-wallet-app
npm install @midnight-ntwrk/[email protected]
4) package.json
Vite の react-ts テンプレートの出力を使い、@midnight-ntwrk/dapp-connector-api が含まれていることを確認してください:
{
"name": "my-wallet-app",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"preview": "vite preview"
},
"dependencies": {
"@midnight-ntwrk/dapp-connector-api": "4.0.1",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@vitejs/plugin-react": "^4.3.0",
"typescript": "~5.7.0",
"vite": "^6.0.0"
}
}
ユーザーから別途指定がない限り、
@midnight-ntwrk/dapp-connector-apiのバージョンは4.0.1に固定してください。インストール時にETARGETエラーが発生した場合は、npm view @midnight-ntwrk/dapp-connector-api versionを確認してください。
5) vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
});
6) tsconfig.json
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
]
}
7) tsconfig.app.json
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["src"]
}
8) tsconfig.node.json
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "ES2022",
"lib": ["ES2023"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["vite.config.ts"]
}
9) src/vite-env.d.ts
/// <reference types="vite/client" />
App.tsx で @midnight-ntwrk/dapp-connector-api を副作用インポートすると、window.midnight が拡張されるため、手動で宣言する必要はありません。
10) src/types.ts
export interface WalletCardProps {
isConnected: boolean;
walletAddress: string | null;
onConnect: () => void;
onDisconnect: () => void;
}
11) src/selectWallet.ts
ウォレットは UUID キーを使って window.midnight の下に注入されます。必ず列挙し、ウォレット名をハードコードしないでください。
import type { InitialAPI } from '@midnight-ntwrk/dapp-connector-api';
export const listWallets = (): InitialAPI[] => {
const injected = window.midnight;
return injected ? Object.values(injected) : [];
};
export const selectWallet = (): InitialAPI => {
const wallets = listWallets();
if (wallets.length === 0) {
throw new Error(
'No Midnight wallet found. Please install a Midnight wallet extension.',
);
}
return wallets[0];
};
利用可能なウォレットが複数ある場合は、listWallets() を使って選択画面を表示し、ユーザーに選んでもらいます。XSS を防ぐため、各ウォレットの名前とアイコンは安全に表示してください。
12) src/WalletCard.tsx
表示レイヤーです。接続状態、アドレス表示、接続/切断ボタンを扱います。CSS は含まれていないため、必要に応じてスタイルを追加してください。
import React from 'react';
import type { WalletCardProps } from './types';
const WalletCard: React.FC<WalletCardProps> = ({
isConnected,
walletAddress,
onConnect,
onDisconnect,
}) => {
return (
<div>
<div>
<h2>Connection Status</h2>
<div>{isConnected ? 'Connected' : 'Disconnected'}</div>
</div>
<div>
{isConnected && walletAddress ? (
<>
<p>Wallet Address:</p>
<p title={walletAddress}>{walletAddress}</p>
</>
) : (
<p>Please connect your wallet to proceed.</p>
)}
</div>
<div>
{isConnected ? (
<button onClick={onDisconnect}>Disconnect Wallet</button>
) : (
<button onClick={onConnect}>Connect Wallet</button>
)}
</div>
</div>
);
};
export default WalletCard;
13) src/App.tsx
DApp Connector API を使った接続ロジックです。
import React, { useState } from 'react';
import WalletCard from './WalletCard';
import '@midnight-ntwrk/dapp-connector-api';
import { selectWallet } from './selectWallet';
const App: React.FC = () => {
const [isConnected, setIsConnected] = useState<boolean>(false);
const [walletAddress, setWalletAddress] = useState<string | null>(null);
const handleConnect = async () => {
console.log('Connect button clicked');
let connected = false;
let address: string | null = null;
try {
const wallet = selectWallet();
// 'undeployed' for local dev; 'preprod' | 'preview' | 'mainnet' for live networks
const connectedApi = await wallet.connect('preprod');
const { unshieldedAddress } = await connectedApi.getUnshieldedAddress();
address = unshieldedAddress;
const serviceUriConfig = await connectedApi.getConfiguration();
console.log('Service URI Config:', serviceUriConfig);
const connectionStatus = await connectedApi.getConnectionStatus();
if (connectionStatus.status === 'connected') {
connected = true;
console.log('Connected to the wallet:', address);
}
} catch (error) {
console.log('An error occurred:', error);
}
setIsConnected(connected);
setWalletAddress(address);
};
const handleDisconnect = () => {
setWalletAddress(null);
setIsConnected(false);
};
return (
<div>
<header>
<h1>Midnight Wallet Connector</h1>
</header>
<main>
<WalletCard
isConnected={isConnected}
walletAddress={walletAddress}
onConnect={handleConnect}
onDisconnect={handleDisconnect}
/>
</main>
</div>
);
};
export default App;
接続フローの内訳
- ウォレットを選択 —
selectWallet()はwindow.midnightのエントリーを読み取ります。見つからない場合は例外をスローし(try/catchで捕捉されます) - ネットワークに接続 —
wallet.connect(networkId)によって、ユーザーに認証を求めます - アドレスを取得 —
getUnshieldedAddress()は公開された非シールドアドレスを返します - 状態を確認 —
getConnectionStatus()は{ status: 'connected' | 'disconnected' }に解決されます - 任意の設定を取得 —
getConfiguration()は、後続の SDK 接続に使うサービス URI(インデクサー、ノードなど)を返します
14) src/main.tsx
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.tsx';
createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
</StrictMode>,
);
15) index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Midnight Wallet Connector</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
16) 実行
npm install
npm run dev
http://localhost:5173 を開きます。Connect Wallet をクリックすると、拡張機能が認証を求めます。承認後、アプリに接続状態と非シールドアドレスが表示されます。
17) 複数ウォレットの選択(オプションの拡張)
listWallets() が複数のエントリを返す場合は、selectWallet() で自動選択する代わりに、ユーザー向けのセレクターを表示します。
// src/WalletPicker.tsx
import type { InitialAPI } from '@midnight-ntwrk/dapp-connector-api';
import { listWallets } from './selectWallet';
type Props = {
onSelect: (wallet: InitialAPI) => void;
};
export function WalletPicker({ onSelect }: Props) {
const wallets = listWallets();
if (wallets.length === 0) {
return <p>No Midnight wallet found. Install a wallet extension and refresh.</p>;
}
return (
<ul>
{wallets.map((wallet) => (
<li key={wallet.name}>
<button type="button" onClick={() => onSelect(wallet)}>
{wallet.name}
</button>
</li>
))}
</ul>
);
}
HTML をサニタイズしない場合は、ウォレットの name と icon をテキストとしてのみ表示してください。ウォレットから提供されたアイコン URL に dangerouslySetInnerHTML を決して使用しないでください。
18) トラブルシューティング
| エラー | 原因 | 対処方法 |
|---|---|---|
window.midnight が undefined | 拡張機能がインストールされていないか、インジェクション前にページが読み込まれた | Midnight ウォレットをインストールし、インストール後にページを更新します |
No Midnight wallet found | 拡張機能が無効になっているか、検出パターンが正しくない | window.midnight.mnLace などのハードコードされたキーではなく、Object.values(window.midnight) を使用します |
| 接続が拒否される/失敗する | ネットワークが一致していない | connect('preprod') がウォレットのアクティブなネットワークと一致していることを確認します |
| 接続が完了しない | ウォレットがロックされているか、同期されていない | ウォレットのロックを解除し、同期が完了するまで待ちます |
インストール時に ETARGET が発生する | パッケージのバージョンが古い | npm view @midnight-ntwrk/dapp-connector-api version を実行し、最新バージョンを指定します |
window.midnight の型エラー | 副作用インポートがない | App.tsx に import '@midnight-ntwrk/dapp-connector-api' を追加します |
19) 次のステップ
コネクターが動作したら、アプリを拡張します。
| 機能 | スキル/API |
|---|---|
| Compact コントラクトのデプロイと呼び出し | 1am-wallet/ |
| トークンの送金 | token-transfers/ |
| 残高とトランザクション履歴の照会 | indexer/ |
| 任意のメッセージへの署名 | connectedApi の署名メソッド(DApp Connector API のドキュメントを参照) |
| 複数ネットワークのセレクター | wallet.connect(selectedNetwork) を呼び出すネットワークのドロップダウン |
| SDK プロバイダーの完全な配線 | midnight-js/ |
20) エージェントのチェックリスト
ユーザー向けにこのテンプレートを生成する際は、次の項目を確認します。
- Vite の
react-tsでスキャフォールディングするか、このスキルに含まれるすべてのファイルを作成する -
@midnight-ntwrk/[email protected]をインストールする -
types.ts、selectWallet.ts、WalletCard.tsx、App.tsx、main.tsxを作成する -
App.tsxに副作用インポート@midnight-ntwrk/dapp-connector-apiを含める - ウォレットの検出には
Object.values(window.midnight)を使用し、ウォレットのキーを決してハードコードしない - ユーザーがローカル(
'undeployed')または別のネットワークを指定しない限り、デフォルトのネットワークを'preprod'にする - ユーザーがスタイル設定を求めない限り、CSS は省略する
- テスト前にウォレット拡張機能をインストールする必要があることを伝える