ts-sdk-wallet-adapter について
React 製 Aptos dapp にブラウザーウォレットを組み込むためのスキルガイドです。アダプターの Provider とフック、ユーザー承認による取引送信、確定確認を扱います。
主な機能
- 01AptosWalletAdapterProvider の設定
- 02useWallet() によるウォレット機能の利用
- 03ウォレットアダプター経由の取引送信
- 04取引の確定待ち
- 05拒否処理とウォレット一覧の動的取得
活用シーン
- 01React dapp でのブラウザーウォレット接続
- 02ユーザー承認済み取引の送信
- 03フロントエンドでのウォレット拒否への対応
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ aptos-labs/ aptos-agent-skills --skill ts-sdk-wallet-adapterインストール後、Claude Code で/ts-sdk-wallet-adapterを入力して読み込まれたか確認します。
詳細
TypeScript SDK:ウォレットアダプター(React)
目的
React で @aptos-labs/wallet-adapter-react を使用し、ウォレット接続とフロントエンドからのトランザクション送信を行います。エンドユーザーはブラウザーウォレット(Petra、Nightly など)でトランザクションに署名します。生の秘密鍵は使用しません。
必ず行うこと
- フロントエンドのウォレット統合には
@aptos-labs/wallet-adapter-reactを使用します — これが標準の React アダプターです。 - アプリのルートを
AptosWalletAdapterProviderでラップします — すべてのuseWallet()呼び出しでこのコンテキストが必要です。 - React コンポーネントでウォレット機能にアクセスするには
useWallet()フックを使用します。 - フロントエンドではウォレットアダプターの
signAndSubmitTransaction(useWallet()から取得)を使用します — SDK のaptos.signAndSubmitTransactionは使用しません。 - 送信後は必ず
aptos.waitForTransaction({ transactionHash })を呼び出します — ウォレットから返されるのはトランザクションが受理された時点であり、コミットされた時点ではありません。
絶対に行わないこと
- ブラウザー/フロントエンドで
Account.generate()や生の秘密鍵を使用しないでください — エンドユーザーにはウォレットアダプターを使用します。 - React コンポーネントで SDK の
aptos.signAndSubmitTransactionを使用しないでください —useWallet()から取得したウォレットアダプター版を使用します。 - ウォレット名をハードコードしないでください — 動的な一覧には
useWallet()のwallets配列を使用します。
インストール
npm install @aptos-labs/wallet-adapter-react
最新の AIP-62 標準ウォレット(Petra、Nightly など)は自動検出され、追加パッケージは不要です。レガシーウォレットでは、プラグインパッケージを別途インストールする必要があります。
プロバイダーの設定
アプリのルートを AptosWalletAdapterProvider でラップします。
// main.tsx or App.tsx
import { AptosWalletAdapterProvider } from "@aptos-labs/wallet-adapter-react";
import { Network } from "@aptos-labs/ts-sdk";
function App() {
return (
<AptosWalletAdapterProvider
autoConnect={true}
dappConfig={{
network: Network.TESTNET
}}
onError={(error) => console.error("Wallet error:", error)}
>
<YourApp />
</AptosWalletAdapterProvider>
);
}
useWallet() フック
import { useWallet } from "@aptos-labs/wallet-adapter-react";
function MyComponent() {
const {
account, // Current connected account { address, publicKey }
connected, // Boolean: is wallet connected?
wallet, // Current wallet info { name, icon, url }
wallets, // Array of available wallets
connect, // (walletName) => Promise<void>
disconnect, // () => Promise<void>
signAndSubmitTransaction, // Submit entry function calls (use THIS in frontend)
signTransaction, // Sign without submitting
submitTransaction, // Submit a signed transaction
signMessage, // Sign an arbitrary message
signMessageAndVerify, // Sign and verify a message
changeNetwork, // Switch networks (not all wallets support this)
network // Current network info
} = useWallet();
}
フロントエンドのトランザクションパターン
InputTransactionData を使用した型付きペイロードを使用します。
// entry-functions/increment.ts
import { InputTransactionData } from "@aptos-labs/wallet-adapter-react";
import { MODULE_ADDRESS } from "../lib/aptos";
export function buildIncrementPayload(): InputTransactionData {
return {
data: {
function: `${MODULE_ADDRESS}::counter::increment`,
functionArguments: []
}
};
}
// components/IncrementButton.tsx
import { useWallet } from "@aptos-labs/wallet-adapter-react";
import { aptos } from "../lib/aptos";
import { buildIncrementPayload } from "../entry-functions/increment";
function IncrementButton() {
const { signAndSubmitTransaction } = useWallet();
const handleClick = async () => {
try {
const response = await signAndSubmitTransaction(buildIncrementPayload());
await aptos.waitForTransaction({
transactionHash: response.hash
});
} catch (error) {
console.error("Transaction failed:", error);
}
};
return <button onClick={handleClick}>Increment</button>;
}
ウォレット接続 UI
import { useWallet } from "@aptos-labs/wallet-adapter-react";
function WalletInfo() {
const { account, connected, connect, disconnect, wallet, wallets } = useWallet();
if (!connected) {
return (
<div>
{wallets.map((w) => (
<button key={w.name} onClick={() => connect(w.name)}>
Connect {w.name}
</button>
))}
</div>
);
}
return (
<div>
<p>Connected: {account?.address}</p>
<p>Wallet: {wallet?.name}</p>
<button onClick={disconnect}>Disconnect</button>
</div>
);
}
よくある間違い
| 間違い | 正しい方法 |
|---|---|
AptosWalletAdapterProvider のラッパーがない | アプリのルートをプロバイダーでラップします |
| 送信後にトランザクションの完了を待たない | 必ず aptos.waitForTransaction() を呼び出します |
React で SDK の aptos.signAndSubmitTransaction を使用する | useWallet() から取得したウォレットアダプターの signAndSubmitTransaction を使用します |
フロントエンドで Account.generate() を使用する | ウォレットアダプターを使用します。生成するのはサーバー/スクリプト内に限ります |
| ユーザーによる拒否を処理しない | 拒否に関連するエラーメッセージを捕捉して確認します |
| ウォレット名をハードコードする | 動的な一覧には useWallet() の wallets 配列を使用します |
参考資料
コメント
Markdown 対応