mcpField
F
frontend-apps

frontend-apps

github.com/mystenlabs開発19431 回インストール今日更新
リポジトリ

frontend-apps について

現行の dApp Kit API を使った Sui フロントエンド dApp 開発向けのスキルです。React、Vue などの実装を案内し、非推奨 API からの移行やトランザクションでの注意点も扱います。

主な機能

  1. 01dApp Kit のセットアップと初期化
  2. 02React のウォレット接続と状態管理
  3. 03Vue、Svelte、Vanilla JS の実装パターン
  4. 04TanStack Query によるオンチェーン照会
  5. 05トランザクションの署名・実行・状態確認
  6. 06旧 API からの移行とコードレビュー

活用シーン

  1. 01新しい Sui React dApp の構築
  2. 02Vue や Svelte でのウォレット UI 実装
  3. 03残高の照会とトランザクションの送信
  4. 04古いチュートリアルの API を点検

MCP 対応

利用可能な場合、最新情報の検証や参考ファイルにない詳細の確認に Sui ドキュメント MCP サーバーを使います。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mystenlabs/skills --skill frontend-apps

インストール後、Claude Code で/frontend-appsを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

limitations.md
non-react.md
queries.md
react.md
setup.md
transactions.md
evals/
code-evals.json
evals.json

詳細

Sui フロントエンド/dApp Kit

MCP ツール: 環境で利用できる場合は、最新の情報を得るために Sui ドキュメント MCP サーバー(https://sui.mcp.kapa.ai)にも問い合わせてください。検証や、これらのリファレンスファイルに記載されていない詳細の確認に利用してください。

ブラウザー上の Sui アプリで問題が発生する原因は、次のようなものに集約されます。

  1. パッケージが間違っています。 @mysten/dapp-kit(サフィックスなし)は、JSON-RPC のみをサポートするレガシーパッケージで、非推奨です。新しいコードでは @mysten/dapp-kit-react または @mysten/dapp-kit-core を使用します。
  2. クライアントが間違っています。 dApp Kit では、createDAppKit の createClient に SuiGrpcClient(推奨)を指定します。SuiJsonRpcClient は渡さないでください。JSON-RPC は非推奨です。
  3. プロバイダースタックが古いです。 コードで v1 のパターン、つまり QueryClientProvider → SuiClientProvider → WalletProvider が使われていることがよくあります。この方式は廃止されています。新しいパターンは、createDAppKit ファクトリーと DAppKitProvider(または React を使わない同等の方式)です。
  4. フックが廃止されています。 useSuiClientQuery、useSuiClientInfiniteQuery、useSignAndExecuteTransaction(ミューテーションフック)、useConnectWallet、useDisconnectWallet、useSuiClient、useSuiClientContext は削除されました。これらは useCurrentClient/useCurrentNetwork/useDAppKit()(命令型メソッド)と、独自の TanStack Query ラッパーに置き換えられています。
  5. 実行後、再取得の前に waitForTransaction を呼び出していません。 フルノードはトランザクションを非同期でインデックス化するため、signAndExecuteTransaction の直後に TanStack のキャッシュを無効化すると、古いデータが再取得されます。
  6. ウォレットに渡す前に、アプリのコードで tx.build() を使って PTB を構築しています。 これではウォレットによるガス選択が機能しなくなります。必ず Transaction インスタンスをウォレットに渡してください。

このスキルのパターンはすべて、次の情報をもとにしています。

API に不明な点があれば、該当するページから情報を取得してください。レガシーの @mysten/dapp-kit や v2 より前のフック API から推測してはいけません。古いチュートリアルが多数存在します。


リファレンスファイル

setup — インストール、ファクトリー、プロバイダー

パス: setup.md 読み込むタイミング: 新しい dApp プロジェクトを始めるとき、React/Next.js/Vue のセットアップを構成するとき、または従来の 3 つのプロバイダーを使うパターンから移行するとき。パッケージの選択、createDAppKit({ networks, createClient })、DAppKitProvider(React)、declare module による TypeScript の拡張を扱います。

react — React フックとパターン

パス: react.md 読み込むタイミング: React コンポーネントを作成するとき。現在のすべてのフック(useCurrentAccount、useCurrentWallet、useCurrentNetwork、useCurrentClient、useDAppKit、useWallets、useWalletConnection)、標準コンポーネント(ConnectButton)、ウォレット接続を条件とする UI の定型パターンを扱います。

non-react — Vue、バニラ JS、Web Components

パス: non-react.md 読み込むタイミング: Vue/Svelte/バニラ JS の dApp を構築するとき。@mysten/dapp-kit-core、nanostores のリアクティブな状態(dAppKit.stores.$connection など)、Web Components の登録、@nanostores/vue による Vue バインディングを扱います。

queries — TanStack Query のパターン

パス: queries.md 読み込むタイミング: dApp でオンチェーンデータ(残高、所有オブジェクト、コイン、動的フィールド、トランザクション)を取得するとき。useQuery と useCurrentClient の組み合わせ、ページ分割された結果に使う useInfiniteQuery、enabled によるガード、書き込み後のキャッシュ無効化を扱います。

transactions — 署名と実行

パス: transactions.md 読み込むタイミング: dApp からトランザクションを送信するとき。dAppKit.signAndExecuteTransaction、$kind に基づく結果の判別、signTransaction(ウォレットで署名するが実行はしないため、スポンサー付きフローに使用)、signPersonalMessage、waitForTransaction と invalidateQueries の手順、ウォレットの UX でよくある問題を扱います。

limitations — フロントエンドでできないこと、すべきでないこと

パス: limitations.md 読み込むタイミング: ブラウザー環境の境界を越えるような設計を検討している場合です。対象:バックエンド専用機能(ガスステーションの内部処理、バリデーターキー)、ブラウザー/SSR の注意点、自動接続の信頼性、「シークレットをブラウザーに置かない」というルール。

ルーティングガイド

タスク読み込むファイル
React dApp をゼロから作成するsetup + react + queries + transactions
Vue/vanilla/Svelte dApp を新規作成するsetup + non-react
「ウォレットを接続するには?」react(または non-react)
「残高/所有オブジェクトをクエリするには?」queries
「トランザクションを送信するには?」transactions +(PTB の構築には sui-sdks)
スポンサー付き tx のフローtransactions(フロントエンド側)+ ptbs(PTB 側)
@mysten/dapp-kit(サフィックスなし)からの移行setup + limitations + 必要に応じてすべて
tx の後に UI が古いままなのはなぜ?transactions + queries
SSR/Next.js への対応setup + limitations
dApp のコードレビュー全般すべてのリファレンスファイル + 以下のコードレビュー用チェックリスト
「このコードをレビューして」/「このスニペットの問題点は?」以下のコードレビュー用チェックリスト + 関連するリファレンスファイル

スキルの内容

主な概念
  • 2 つのパッケージ、1 つの API。 @mysten/dapp-kit-react は @mysten/dapp-kit-core をラップしています。createDAppKit は両方にあります。アクション(signAndExecuteTransaction、signTransaction、switchNetwork、connectWallet、disconnectWallet)は同一です。異なるのはリアクティブな状態の読み取り方法です。React ではフックを使い、non-React では nanostores のストアを読み取ります。
  • 1 つのインスタンスで複数のネットワークに対応。 createDAppKit({ networks: [...], createClient }) は、複数のネットワークに対応する dApp Kit インスタンスを 1 つ作成します。dAppKit.switchNetwork(name) でアクティブなネットワークを切り替えます。createClient ファクトリーはネットワークごとに遅延呼び出しされます。
  • デフォルトは gRPC。 新しい dApp Kit は SuiGrpcClient 向けに構築されています。JSON-RPC は非推奨です。createClient では SuiGrpcClient を使用してください。
  • ウォレットはブラウザー専用です。 ウォレットの検出には window.navigator.wallets と CustomEvents を使用します。ウォレットの状態を扱うコンポーネントは、クライアント側でレンダリングする必要があります。Next.js/SSR フレームワークでは、ウォレットを扱うコンポーネントに 'use client' を指定します。
  • ガスはウォレットが管理します。 アプリは Transaction を構築し、ウォレットに渡します。ウォレットがガスコインを選択し(ドライランを通じて)予算を設定して、署名します。スポンサー付きフローの場合を除き、tx.build() を呼び出してバイト列を渡してはいけません。詳しくは transactions.md を参照してください。
  • フルノードのデータ反映には時間がかかります。 signAndExecuteTransaction は、データをクエリできるようになる前にダイジェストを返します。再取得する前に、必ず waitForTransaction を実行してください。
ルール
  1. 新しいコードでは @mysten/dapp-kit-react または @mysten/dapp-kit-core を使用してください — 以前の @mysten/dapp-kit は使用しないでください。このパッケージは JSON-RPC 専用であり、非推奨です。
  2. createClient では SuiGrpcClient を使用してください。 SuiClient は使用しないでください — SuiClient は v2 で削除されています。@mysten/sui/grpc の SuiGrpcClient を使用してください。
  3. createDAppKit + DAppKitProvider を使用してください。 3 つのプロバイダーを組み合わせる構成(QueryClientProvider + SuiClientProvider + WalletProvider)は使用しないでください。データ取得に TanStack Query を使用する場合は、引き続き QueryClientProvider でラップしますが、dApp Kit 自体には必要ありません。
  4. declare module の TypeScript 拡張を含めてください。 これにより、インスタンスを手動で渡さなくてもフックで適切な型が使用されます。
  5. 削除されたフックは使用しないでください。 useSuiClientQuery / useSuiClientInfiniteQuery / useSuiClientContext / useSuiClient / useSignAndExecuteTransaction(ミューテーションフック) / useConnectWallet / useDisconnectWallet は削除されています。代わりに、useCurrentClient + useQuery / useInfiniteQuery + useDAppKit() の命令型メソッドを使用してください。
  6. 現在のアカウントが null かどうか確認してください。 useCurrentAccount() は接続前に null を返します。常に if (!account) return を使用するか、クエリで enabled: !!account を指定してください。
  7. キャッシュを無効化する前に waitForTransaction を実行してください。 await client.waitForTransaction({ digest: result.Transaction.digest }) を実行してから queryClient.invalidateQueries(...) を呼び出してください。順序を逆にすると、古いデータが取得されます。
  8. await tx.build(...) のバイト列ではなく、Transaction インスタンスをウォレットに渡してください。 ガスの選択はウォレットに任せる必要があります。例外は、tx.build({ client, onlyTransactionKind: true }) を使用するスポンサー付きフローです — ptbs スキルを参照してください。
  9. result.$kind === 'FailedTransaction'(または result.FailedTransaction)を確認してください。 成功を前提にしないでください。v1 の result.effects?.status?.status は使用しないでください。
  10. ウォレットで制御する UI はクライアント側でレンダリングしてください。 クライアント側のガードなしで SSR を行うと、ウォレットを検出できる前にウォレットボタンがレンダリングされます。'use client' / 動的インポート / effect ベースのハイドレーションを使用してください。
  11. Vue:useStore は Vue の ref を返します — スクリプト内のコードでは .value を使用してください。 const connection = useStore(dAppKit.stores.$connection) は ref を返します。<script setup> では connection.value.account として状態にアクセスしてください。Vue はテンプレート内の ref を自動的にアンラップしますが、スクリプトの例では常に .value のパターンを示してください。
コードレビューのチェックリスト

ユーザーからコードスニペットのレビューを依頼されたら、最初に見つけた2~3件の問題だけで終わらせないでください。このチェックリストを明示的に確認し、該当する項目をすべて指摘してください。Browser Sui のコードは、v1 のチュートリアルからコピーされたものが多く、1つのコンポーネントに通常5~10件の問題が重なっています。

インポート/パッケージ

  • @mysten/sui.js(どこで使われていても)— 凍結された v1 パッケージです。@mysten/sui に置き換えてください。
  • @mysten/dapp-kit(サフィックスなし)— 非推奨の JSON-RPC 専用パッケージです。@mysten/dapp-kit-react(React)または @mysten/dapp-kit-core(その他のフレームワーク)に置き換えてください。
  • import { ConnectButton } from '@mysten/dapp-kit-react' — パスが間違っています。ConnectButton と ConnectModal は @mysten/dapp-kit-react/ui からエクスポートされています。間違ったパスを使うと、何も表示されない白い画面になります。
  • import { SuiClient } — SuiClient は v2 で削除されました。@mysten/sui/grpc の SuiGrpcClient(またはコンポーネント内の useCurrentClient())を使ってください。
  • import { TransactionBlock } — v2 では Transaction に改名されました。

削除されたフック(いずれかがあればバグ)

  • useSuiClientQuery、useSuiClientInfiniteQuery、useSuiClientContext、useSuiClient — useCurrentClient() と TanStack の useQuery/useInfiniteQuery に置き換えてください。
  • useSignAndExecuteTransaction(ミューテーションフック)— イベントハンドラー内で命令的に呼び出す useDAppKit().signAndExecuteTransaction(...) に置き換えてください。
  • useConnectWallet、useDisconnectWallet — useDAppKit().connectWallet()/disconnectWallet() に置き換えてください。

プロバイダースタック

  • SuiClientProvider + WalletProvider(v1 の3プロバイダースタック)— createDAppKit(...) + <DAppKitProvider> に置き換えてください。TanStack の QueryClientProvider は引き続き使用できます。

コンポーネント内でのクライアント構築

  • コンポーネント本体内の new SuiClient(...)/new SuiGrpcClient(...) — ネットワークの切り替えに対応できず、レンダーのたびにクライアントを作り直します。useCurrentClient() を使ってください。
  • 接続済みウォレットが必要なクエリで enabled: !!account が指定されていない — owner が未定義のまま実行され、エラーになります。

トランザクションの構築

  • tx.pure(value)(型指定なし)— Move の型に合った型付きヘルパーに置き換えてください:tx.pure.u64(n)、tx.pure.address(addr)、tx.pure.string(s) など。
  • ウォレットに渡す前の tx.build() — ウォレットによるガス選択を無効にしてしまいます。Transaction インスタンスをそのまま渡してください。

実行/待機/ステータス

  • signAndExecuteTransactionBlock(...)(v1 のメソッド)— signAndExecuteTransaction(...) に置き換えてください。
  • { transactionBlock: tx } というパラメーター形式 — { transaction: tx } に置き換えてください。
  • result.effects?.status?.status === 'success' — v1 の形式です。result.$kind !== 'FailedTransaction' に置き換えるか、result.FailedTransaction を確認してください。
  • result.digest への直接アクセス — 成功時のダイジェストは result.Transaction.digest にあります。失敗時にはダイジェストはありません。
  • 実行直後のキャッシュ無効化 — まず await client.waitForTransaction({ digest }) を実行してから、queryClient.invalidateQueries(...) を実行する必要があります。

SSR/Next.js

  • 'use client' のない、ウォレット対応コンポーネント — ウォレットの検出にはブラウザー専用 API が使われます。

チェックリストを確認したら、見つかった個別の問題の数を数えてください。古いチュートリアルから取得した一般的な複数行のスニペットで5件未満の場合は、スニペットをもう一度確認してください。見落としがある可能性が非常に高いです。

よくある間違い
  • 接続済みのウォレットが必要なクエリで、enabled: !!account を指定せずに @tanstack/react-query の useQuery を使うことです。owner が未定義の状態でクエリが実行され、エラーになります。
  • React-Query の queryFn から Transaction を返すことです。トランザクションはクエリではありません。useDAppKit() を使って、ミューテーションまたはイベントハンドラー内で使用してください。
  • dAppKit.signAndExecuteTransaction({ transactionBlock: tx }) とすることです。新しい API では { transaction: tx } です。
  • result.digest を直接読み取ることです。成功時の digest は result.Transaction.digest にあります。失敗時は digest がないため、まず result.FailedTransaction を確認してください。
  • waitForTransaction の前にクエリを無効化することです。これは典型的な UI の古い状態を引き起こすバグです。必ず先に待機してください。
  • コンポーネント内で new SuiGrpcClient(...) を呼び出すことです。ネットワーク切り替えが機能しなくなります。useCurrentClient() を使用してください。
  • SuinsClient/DeepBookClient を直接インスタンス化することです。createClient から返されたクライアントで、client.$extend(suins(), deepbook({ address })) を使用してください。
  • わかりにくい UX のまま autoConnect: true にしておくことです。自動再接続は、読み込み時に最後に使用したウォレットを復元します。アプリで権限や nonce を扱う場合は、この復元が非同期であることを考慮してください(保留中/再接続中の状態)。
  • testnet/mainnet の URL を複数箇所にハードコードすることです。ネットワーク名をキーとする単一の GRPC_URLS マップにまとめ、createClient から参照してください。
  • wallet-standard API を直接使用することです。dApp Kit は wallet standard をラップしています。自分で window.navigator.wallets を呼び出さず、useWallets()/dAppKit.stores.$wallets を使用してください。
  • 秘密鍵やシークレットをブラウザーに保存することです。絶対にしないでください。dApp はウォレット経由で署名し、バックエンドで鍵を保持します。

コメント