mcpField
R
react-wallet-connector

react-wallet-connector

github.com/kali-decoder開発18127 回インストール1 日前に更新
リポジトリ

react-wallet-connector について

DApp Connector APIを通じてMidnightウォレット拡張機能に接続する、ReactとTypeScriptの実行可能なアプリを生成するスキルです。ウォレットの検出、認証、アドレス表示、任意のウォレット選択を備えたフロントエンドの接続基盤を提供します。

主な機能

  1. 01ViteによるReact・TypeScriptアプリのひな形
  2. 02注入されたMidnightウォレットの検出
  3. 03DApp Connector API経由の接続
  4. 04接続状態と非シールドアドレスの表示
  5. 05任意の複数ウォレット選択機能
  6. 06ネットワーク選択のガイダンス

活用シーン

  1. 01ウォレット接続対応のReactアプリ作成
  2. 02インストール済みウォレットからの選択
  3. 03ネットワーク接続に必要なウォレット認証
  4. 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;
接続フローの内訳
  1. ウォレットを選択 — selectWallet() は window.midnight のエントリーを読み取ります。見つからない場合は例外をスローし(try/catch で捕捉されます)
  2. ネットワークに接続 — wallet.connect(networkId) によって、ユーザーに認証を求めます
  3. アドレスを取得 — getUnshieldedAddress() は公開された非シールドアドレスを返します
  4. 状態を確認 — getConnectionStatus() は { status: 'connected' | 'disconnected' } に解決されます
  5. 任意の設定を取得 — 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 は省略する
  • テスト前にウォレット拡張機能をインストールする必要があることを伝える

コメント