Web3アプリへのユーザーオンボーディングは、依然としてほとんどのユーザーを最初の段階で遠ざけています。シードフレーズ、ブラウザ拡張機能、ガス料金は、2タップで完了するはずのサインアップを10分間の奮闘に変えてしまいます。Privy APIは、このギャップを解消します。すべての新規ユーザーに、メール、SMS、Google、Apple、またはMetaMaskのような既存のウォレットといった使い慣れたログイン方法の裏側で、埋め込みウォレットを提供します。これにより、ブラウザ拡張機能をインストールするよう誰かに頼むことなく、暗号ネイティブなユーザーを獲得できます。
Privyは現在、Blackbird、Friend.tech、OpenSea、その他数千ものアプリのウォレットをサポートしており、その製品はEthereum、Solana、および任意のEVMチェーンに及びます。このガイドでは、Privyアプリの作成、React SDKの組み込み、サーバー上でのトークン検証、埋め込みウォレットでのトランザクション署名、およびWebhookのデプロイといった開発者ワークフロー全体を説明します。MetaMaskの開発者ツールキットのような他のオプションと比較したい場合は、このページを開いたまま、必要に応じて参照してください。
要点
- Privyは、埋め込みウォレットと、メール、SMS、ソーシャル、外部ウォレットによるログインを1つのSDKで統合します。
- React SDKは、`PrivyProvider`、`useLogin`、`useWallets`、`usePrivy`フックを提供し、認証と署名のフロー全体をカバーします。
- `@privy-io/server-auth`は、バックエンドでアクセストークンを検証し、すべてのリクエストでユーザーIDを信頼できるようにします。
- ウォレットはEthereum、Solana、その他のEVMチェーンをサポートしており、主要な操作にはオプションでエクスポート機能と認証署名が利用可能です。
- Webhookは、ユーザー作成、ログイン、ウォレットイベント時に発火し、ポーリングなしでデータベースを同期させます。
- Privyのポリシーエンジンは、アプリコードを変更することなく、MFA、許可リスト、トランザクションルールを追加します。
Privy APIとは?
Privyは認証およびウォレットインフラプラットフォームです。あなたのアプリに、ログインUI、ユーザーごとにプロビジョニングされる埋め込みウォレット、そしてサーバーサイドチェック用のRESTエンドポイント群の3つを提供します。埋め込みウォレットはセキュアエンクレーブ内に存在するため、Privyもあなたのバックエンドも秘密鍵を見ることはありません。ユーザーは後で自己管理型ウォレットに移行したい場合、自分の鍵をエクスポートできます。このオプション性は、Privyの大きな魅力の一部です。
このプラットフォームは月間アクティブウォレット数に応じて課金されるため、無料でプロトタイプをリリースし、利用状況に応じて料金を拡大できます。無料ティアでは1,000人の月間アクティブユーザーをカバーし、Proは月額149ドルから、EnterpriseはカスタムSLAに対応します。
認証とセットアップ
privy.ioから始め、ダッシュボードで新しいアプリを作成します。あなたにとって重要な2つの値が得られます。
- App ID (`clxxxxx...`) はクライアントSDK用
- App secret はサーバーSDK用
許可されたログイン方法(メール、SMS、Google、Apple、Farcaster、ウォレット)を設定し、デフォルトのチェーンを選択し、あなたのドメインを許可されたオリジンリストに追加します。Reactの場合、SDKをインストールします。
npm install @privy-io/react-auth
あなたのアプリを`PrivyProvider`でラップします。
import { PrivyProvider } from '@privy-io/react-auth';
export default function App({ Component, pageProps }) {
return (
<PrivyProvider
appId={process.env.NEXT_PUBLIC_PRIVY_APP_ID}
config={{
loginMethods: ['email', 'wallet', 'google'],
embeddedWallets: { createOnLogin: 'users-without-wallets' },
defaultChain: { id: 8453 }, // Base
supportedChains: [{ id: 1 }, { id: 8453 }, { id: 137 }],
}}
>
<Component {...pageProps} />
</PrivyProvider>
);
}
`createOnLogin`フラグは、ユーザーがウォレットなしで初めてログインしたときに埋め込みウォレットをプロビジョニングします。サポートされるチェーンはあなたが制御します。Solanaは別の`solanaClusters`設定の下にあります。
主要なエンドポイントとSDK呼び出し
PrivyのReact SDKはほとんどのフローを処理するため、生のRESTを直接叩くことはほとんどありません。しかし、サーバーSDKとWebhookのペイロードは同じトークン形式を使用するため、状況が悪化した際には基盤となるAPIを知っていることが役立ちます。
ログインのトリガーとユーザーの読み取り
import { usePrivy, useWallets } from '@privy-io/react-auth';
function LoginButton() {
const { ready, authenticated, login, logout, user } = usePrivy();
const { wallets } = useWallets();
if (!ready) return <p>Loading...</p>;
if (!authenticated) return <button onClick={login}>Sign in</button>;
const embedded = wallets.find((w) => w.walletClientType === 'privy');
return (
<div>
<p>Hi {user.email?.address ?? user.id}</p>
<p>Wallet: {embedded?.address}</p>
<button onClick={logout}>Log out</button>
</div>
);
}
`useWallets`は、ユーザーがリンクしたすべてのウォレットを返し、`walletClientType`フィールドはPrivyが作成したウォレットを識別します。これは、Privyの埋め込みウォレットで採用するパターンです。
トランザクションへの署名
const { wallets } = useWallets();
const wallet = wallets.find((w) => w.walletClientType === 'privy');
async function sendTx() {
const provider = await wallet.getEthereumProvider();
const hash = await provider.request({
method: 'eth_sendTransaction',
params: [{
to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb2',
value: '0x38d7ea4c68000', // 0.001 ETH
}],
});
console.log('tx hash', hash);
}
Solanaの場合、`getEthereumProvider`を`getSolanaProvider`に置き換え、シリアライズされたトランザクションを渡します。Alchemyのようなプロバイダーからのデータアクセスパターンを模倣したい場合、Privyはそれらとうまく連携します。Privyが鍵を処理し、AlchemyがRPCを処理します。
サーバー上でのトークン検証
サーバーSDKをインストールします。
npm install @privy-io/server-auth
フロントエンドからのすべての認証済みリクエストには、Privyのアクセストークン(JWT)が含まれています。ユーザーIDを信頼する前に、サーバーでこれを検証してください。
import { PrivyClient } from '@privy-io/server-auth';
const privy = new PrivyClient(
process.env.PRIVY_APP_ID,
process.env.PRIVY_APP_SECRET
);
export async function GET(req) {
const auth = req.headers.get('authorization')?.replace('Bearer ', '');
try {
const claims = await privy.verifyAuthToken(auth);
// claims.userId is the Privy user DID
return Response.json({ userId: claims.userId });
} catch (err) {
return new Response('Unauthorized', { status: 401 });
}
}
リンクされたアカウント、ウォレットアドレス、カスタムメタデータをチェックするために、完全なユーザーオブジェクト(`privy.getUser(userId)`)を取得することもできます。
埋め込みウォレットのエクスポート
Privyは、ユーザーがいつでも秘密鍵をエクスポートできるようにします。UXは単一のフックです。
import { useExportWallet } from '@privy-io/react-auth';
const { exportWallet } = useExportWallet();
<button onClick={() => exportWallet()}>Export private key</button>;
Privyはセキュアなiframeモーダルを表示します。あなたのアプリが鍵の素材に触れることはありません。
認証署名とポリシーエンジン
機密性の高い操作(大規模な送金、新しいデバイスからのログインなど)のために、Privyは**認証署名**をサポートしています。ダッシュボードでポリシーを定義し、それをアプリに紐付けることで、トランザクションが実行される前にPrivyがMFA、許可リスト、またはサーバー署名による承認を強制します。詳細はPrivyの認証鍵ガイドに記載されています。MFAオプション(TOTP、SMS、パスキー)と組み合わせることで、通常のウォレットが残すほとんどのアカウント乗っ取りのリスクを解消します。
Webhook
Privyは、ユーザーとウォレットのライフサイクル変更時に、あなたのエンドポイントにJSONイベントを投稿します。
curl -X POST https://yourapp.com/webhooks/privy \
-H "Content-Type: application/json" \
-H "svix-id: msg_..." \
-H "svix-signature: v1,..." \
-d '{
"type": "user.created",
"user": { "id": "did:privy:...", "email": { "address": "a@b.com" } }
}'
データベースに何かを書き込む前に、ダッシュボードから取得したWebhookシークレットで`svix-signature`ヘッダーを検証してください。
よくあるエラーとレート制限
いくつかのエラーが繰り返し発生します。
- **`invalid_token`**: フロントエンドのJWTが期限切れです。フェッチする直前に`usePrivy`から`getAccessToken()`を呼び出してください。トークンは1時間有効です。
- **`403 origin_not_allowed`**: デプロイURLがPrivyダッシュボードの許可リストにありません。`https://yourapp.com`とプレビュードメインを追加してください。
- **`wallet_not_ready`**: `ready`がtrueになる前に`useWallets`を読み取りました。すべてのウォレット呼び出しは`ready`フラグで保護してください。
- **レート制限**: 無料ティアでは、RESTエンドポイントはアプリごとに1秒あたり100リクエストを許可します。ほとんどのアプリはこれに到達しませんが、もし到達した場合は、`getUser`呼び出しをバッチ処理するか、ユーザーIDでキャッシュしてください。
失敗したWebhookをローカルでリプレイするには、Apidogを使用してください。生のペイロードをリクエストに貼り付け、署名ヘッダーを編集し、ハンドラーがパスするまで開発サーバーに繰り返しリクエストを送信します。
Privyの料金
- Free: 月間アクティブウォレット数1,000まで、コアログイン方法、EVM + Solana上の埋め込みウォレット。
- Pro: 月額149ドル、より高いMAW制限、フルWebhookスイート、ステージングアプリ。
- Enterprise: カスタムSLA、専用サポート、オンコールエンジニアリング、カスタムポリシーエンジンルール。
現在の料金はprivy.io/pricingで確認してください。製品の成長に伴い、ティアは変更される可能性があります。
Apidogを使ったPrivy APIのテスト
PrivyのクライアントSDKはHTTPS呼び出しを隠蔽しますが、あなたのバックエンドが処理するすべてのトークン検証、ユーザー検索、およびWebhookは通常のRESTリクエストです。ここでApidogが真価を発揮します。ApidogでPrivyコレクションを作成し、アプリIDとシークレットを環境変数として設定し、ツールから離れることなく`GET /api/v1/users/{userId}`や`POST /api/v1/users/{userId}/wallets`のようなエンドポイントを叩くことができます。
ダッシュボードからWebhookペイロードを記録し、Apidogリクエストとして保存し、ローカルトンネルに対してそれらをリプレイすることもできます。有効なJWTがユーザーオブジェクトを返し、期限切れのJWTが401を返すことを検証する自動テストを設定し、デプロイごとに実行してください。Apidogを無料でダウンロードして、cURLでの複雑な操作は不要になります。Postmanからすでに移行した場合は、サイドバイサイドワークフローガイドで完全な移行について説明しています。
よくある質問
PrivyはWeb3AuthやMagicとどう違うのですか?3つとも埋め込みウォレットを提供しますが、Privyは複合認証(メール+ウォレット+ソーシャル)と、大規模アプリが必要とするポリシーエンジンに重点を置いています。Web3AuthはMPC鍵分割に焦点を当てており、Magicはより広範なマジックリンク製品を提供しています。クリーンなオンボーディングUIとウォレットの機能に対するきめ細かな制御の両方が必要な場合は、Privyを選択してください。
PrivyはSolanaをサポートしていますか?はい。埋め込みウォレットはSolanaのメインネットと開発者ネットで機能し、React SDKはトランザクションの署名と送信のために`getSolanaProvider()`を公開しています。同じアプリ内でEVMとSolanaの両方を設定できます。
ユーザーは自分のウォレットを持ち込めますか?はい。MetaMask、Coinbase Wallet、WalletConnect、Phantom、その他多数のウォレットがすぐに使えます。Privyは外部ウォレットをリンクされたアカウントとして扱い、同じユーザーDIDが埋め込み鍵と外部鍵の両方を所有します。
Privyがダウンした場合どうなりますか?鍵はユーザーのブラウザエンクレーブに存在するため、ユーザーはエクスポートされたウォレットにアクセスできます。本番アプリの場合、ウォレットのエクスポート機能を有効にし、フォールバックパスを文書化してください。ベンダーリスクパターンについては、IDプロバイダー比較ガイドを参照してください。
PrivyはMFAをサポートしていますか?はい。TOTP、SMS、パスキーはすべて組み込まれており、ポリシーエンジンを通じて特定の操作(トークンの送信、ウォレットのエクスポートなど)にMFAを要求できます。
私のアプリのコードはサーバーサイドで実行されますか、それともクライアントサイドで実行されますか?両方です。クライアントSDKはログインUIと署名を処理し、サーバーSDKはトークンを検証しユーザーデータをフェッチします。アプリシークレットをブラウザに公開しないでください。
