bluvo
ユーザーのウォレットを取引所(Binance、Kraken、Coinbase)に安全に接続し、出金実行や認証情報管理を行うための暗号資産取引所接続APIです。取引所連携機能、2FAやSMS・KYC認証を含む出金UIの構築、またはマルチテナント型の暗号資産アプリケーション開発に活用できます。TypeScriptのステートマシンおよびReactフックのSDKを提供します。
description の原文を見る
Crypto exchange connectivity API for securely connecting user wallets to exchanges (Binance, Kraken, Coinbase), executing withdrawals, and managing credentials. Use when building exchange integrations, withdrawal UIs with 2FA/SMS/KYC, or multi-tenant crypto applications. SDKs: TypeScript state machine and React hooks.
SKILL.md 本文
Bluvo スキルリファレンス
製品概要
Bluvo は、暗号資産取引所の API 認証情報を安全に管理し、秘密鍵を公開することなくウォレット接続を実現する暗号資産取引所接続 API です。REST ラッパーではありません。ステートマシンが OAuth 認証からウォレットの読み込み、見積の生成、出金実行、2FA チャレンジ処理まで、フロー全体を統制します。
セキュリティ: AES-256-CBC 暗号化、テナント固有の暗号化キー、組織ごとの専用データベース。
| リソース | 場所 |
|---|---|
| REST API (OpenAPI) | https://api-bluvo.com/api/v0/openapi |
| TypeScript SDK | npm の @bluvo/sdk-ts |
| React SDK | npm の @bluvo/react |
| ポータル (API キー) | https://portal.bluvo.dev |
| ドキュメント | https://docs.bluvo.dev |
| GitHub (SDK) | https://github.com/bluvoinc/sdk |
プログラミングモデル
3 つのクライアントレイヤー
| クライアント | サイド | API キー? | 用途 |
|---|---|---|---|
BluvoClient | サーバー | あり | ウォレット、出金、OAuth 操作への直接 REST アクセス |
BluvoWebClient | ブラウザー | なし | OAuth ポップアップ、WebSocket リアルタイム更新 |
BluvoFlowClient | ブラウザー | なし (サーバーコールバックを使用) | 完全な出金フロー用のステートマシンオーケストレーター |
SDK はステートマシンパラダイムを使用します。イベントを送信するとマシンが状態遷移します。REST API を直接呼び出しません。BluvoFlowClient がすべての API 呼び出しを内部で統制し、購読する状態変化を発行します。
React SDK (@bluvo/react) はステートマシンをフック内にラップします。useBluvoFlow はほとんどのユースケースで主要なフックです。コンテキストプロバイダーは不要です。
状態図
idle ──→ exchanges:loading ──→ exchanges:ready ──→ oauth:waiting / qrcode:waiting
│ │
exchanges:error oauth:processing / qrcode:displaying
│
oauth:completed ←─ qrcode:scanning
│
wallet:loading
│
wallet:ready
│
quote:requesting
│
quote:ready ←─ (auto-refresh)
│
withdraw:processing
│ │ │
error2FA │ errorSMS errorKYC
error2FAMultiStep │ errorBalance
│
readyToConfirm │ retrying
│
withdraw:completed / fatal / blocked
CANCEL_FLOW → flow:cancelled (from ANY state)
ビルド可能なもの
- 取引所ウォレット接続フロー (OAuth ポップアップまたは Binance Web の QR コード)
- リアルタイム見積更新と手数料表示を備えた出金 UI
- マルチステップ 2FA 検証 (TOTP、メール、SMS、顔認識、セキュリティキー/FIDO)
- 残高プレビュー付きウォレットダッシュボード
- サーバー側の認証情報管理とバルク ウォレット操作
- 顧客ごとに独立した暗号資産操作を備えたマルチテナント SaaS
統合パスを選択
| アプローチ | 工数 | 最適な用途 | トレードオフ |
|---|---|---|---|
| REST API | 3~4 週間 | 完全な制御、カスタムフロー | フロー全体を自分で実装 |
| サーバー SDK | 3 週間 | 言語固有の統合 | 依然としてフロー ロジックの構築が必要 |
| ステートマシン SDK + サーバー SDK | 5 日 | 抽象化されたフロー、カスタム UI | ウィジェット UI のみ構築 |
React ステートマシン (@bluvo/react) | 24 時間 | 最小限のコードで React アプリ | React フレームワークに限定 |
| Vanilla JS ウィジェット | 24 時間 | クイック埋め込み可能 UI | カスタマイズが少ない |
| フレームワークウィジェット | 24 時間 | React/Vue/Angular 用のプリセット UI | 最小限のカスタマイズ |
決定ツリー:
- React または Next.js? →
@bluvo/react(~24 時間) - カスタム UI フレームワーク? →
@bluvo/sdk-tsのBluvoFlowClient(~5 日) - サーバーのみ / バックエンド? →
@bluvo/sdk-tsのBluvoClient - プリセット ウィジェット? →
@bluvo/widget-react、@bluvo/widget-vanjs、@bluvo/widget-svelte
# React + Next.js
pnpm add @bluvo/react
# TypeScript のみ
pnpm add @bluvo/sdk-ts
クイックスタート — React + Next.js
サーバーアクション
// app/actions/flowActions.ts
'use server'
import { createClient, createSandboxClient, createDevClient } from "@bluvo/sdk-ts";
function loadBluvoClient() {
const env = process.env.NEXT_PUBLIC_BLUVO_ENV;
if (env === 'production') {
return createClient({
orgId: process.env.BLUVO_ORG_ID!,
projectId: process.env.BLUVO_PROJECT_ID!,
apiKey: process.env.BLUVO_API_KEY!,
});
} else if (env === 'staging') {
return createSandboxClient({
orgId: process.env.BLUVO_ORG_ID!,
projectId: process.env.BLUVO_PROJECT_ID!,
apiKey: process.env.BLUVO_API_KEY!,
});
} else {
return createDevClient({
orgId: process.env.BLUVO_ORG_ID!,
projectId: process.env.BLUVO_PROJECT_ID!,
apiKey: process.env.BLUVO_API_KEY!,
});
}
}
// 重要: Next.js サーバーアクション シリアル化に toPlain() が必須
function toPlain<T extends object>(o: T): T {
return JSON.parse(JSON.stringify(o)) as T;
}
export async function listExchanges(status?: string) {
return toPlain(await loadBluvoClient().oauth2.listExchanges(status as any));
}
export async function fetchWithdrawableBalances(walletId: string) {
return toPlain(await loadBluvoClient().wallet.withdrawals.getWithdrawableBalance(walletId));
}
export async function executeWithdrawal(
walletId: string, idem: string, quoteId: string,
params?: { twofa?: string | null; emailCode?: string | null; smsCode?: string | null;
bizNo?: string | null; tag?: string | null; params?: { dryRun?: boolean } | null; }
) {
return toPlain(await loadBluvoClient().wallet.withdrawals.executeWithdrawal(walletId, idem, quoteId, params ?? {}));
}
サーバーアクション ファイル全体 (
requestQuotation、getWalletById、pingWalletByIdを含む) については、以下の SDK スキルファイルセクションで参照されているnextjs-patterns.mdサブスキルを読み込んでください。
ページコンポーネント
// app/home/page.tsx
"use client"; // 必須 — フックはブラウザーのみ
import { useBluvoFlow } from "@bluvo/react";
import {
fetchWithdrawableBalances, listExchanges, executeWithdrawal,
requestQuotation, getWalletById, pingWalletById
} from '../actions/flowActions';
export default function Home() {
const flow = useBluvoFlow({
orgId: process.env.NEXT_PUBLIC_BLUVO_ORG_ID!,
projectId: process.env.NEXT_PUBLIC_BLUVO_PROJECT_ID!,
listExchangesFn: listExchanges,
fetchWithdrawableBalanceFn: fetchWithdrawableBalances,
requestQuotationFn: requestQuotation,
executeWithdrawalFn: executeWithdrawal,
getWalletByIdFn: getWalletById,
pingWalletByIdFn: pingWalletById,
options: {
sandbox: process.env.NEXT_PUBLIC_BLUVO_ENV === 'staging',
dev: process.env.NEXT_PUBLIC_BLUVO_ENV === 'development',
},
});
// 状態ブール値: flow.isOAuthPending、flow.isWalletReady、flow.isQuoteReady など
// アクション: flow.startWithdrawalFlow()、flow.requestQuote()、flow.executeWithdrawal()
// チャレンジ: flow.requires2FA、flow.requires2FAMultiStep、flow.requiresSMS
// 終了状態: flow.isWithdrawalComplete、flow.isFlowCancelled、flow.hasFatalError
}
必要なセットアップ
環境変数
| 変数 | サイド | 必須 | 説明 |
|---|---|---|---|
BLUVO_ORG_ID | サーバー | はい | サーバーアクション用の組織 ID |
BLUVO_PROJECT_ID | サーバー | はい | サーバーアクション用のプロジェクト ID |
BLUVO_API_KEY | サーバー | はい | API キー (クライアントに公開しないこと) |
NEXT_PUBLIC_BLUVO_ORG_ID | クライアント | はい | フック用の組織 ID |
NEXT_PUBLIC_BLUVO_PROJECT_ID | クライアント | はい | フック用のプロジェクト ID |
NEXT_PUBLIC_BLUVO_ENV | クライアント | いいえ | production / staging / development |
認証
Bluvo ポータルの API キーセクションから orgId、projectId、および apiKey を取得します。
| スコープ | 用途 |
|---|---|
read | ウォレット、残高、アカウント情報の表示 |
quote | 出金見積の生成 |
withdrawal | 出金実行 |
delete | 接続ウォレットの削除 |
API キー スコープは、サーバーアクションが実行する操作と一致する必要があります。
制約
- 対応取引所: Binance、Kraken、Coinbase など。API または help@bluvo.co への問い合わせで現在のリストを確認してください
- React フックはブラウザーのみ — SSR サポートはありません。
useState、useEffect、WebSocket、localStorageを使用します useBluvoFlowはマウント時にオプションをキャプチャ — クライアントはuseState初期化子で作成されます。マウント後のオプション変更は効果がありません。コンポーネントを再マウントして再初期化します- API キー スコープは操作と一致する必要があります — 例:
executeWithdrawalにはwithdrawalスコープが必須 - 出金見積は有効期限切れになります — 実行前に常に新しい見積を取得します。
autoRefreshQuotationはデフォルトでtrueです
一般的なワークフロー
1. OAuth → 出金 (成功ケース)
idle → exchanges:ready → oauth:completed → wallet:ready → quote:ready → withdraw:completed
listExchanges() を呼び出す → ユーザーが取引所を選択 → startWithdrawalFlow({ exchange, walletId }) → OAuth ポップアップ → ウォレット読み込み → requestQuote({...}) → executeWithdrawal(quoteId) → 完了。
2. QR コード (binance-web)
exchange === 'binance-web' の場合、startWithdrawalFlow() により自動検出されます。手動ルーティングは不要です。
qrcode:waiting → qrcode:displaying → qrcode:scanning → oauth:completed → wallet:ready → ...
flow.qrCodeUrl を QR 画像として表示します。flow.isQRCodeScanning と flow.isOAuthComplete を監視します。
3. ウォレット再開
ウォレットが既に接続されている場合、OAuth をスキップします:
resumeWithdrawalFlow({ exchange, walletId })— OAuth をスキップ、ウォレット残高を読み込みsilentResumeWithdrawalFlow({ walletId, exchange, preloadedBalances? })— 直接wallet:readyにジャンプ
startWithdrawalFlow は getWalletByIdFn を介して既存ウォレットを自動検出し、再開にルーティングします。
4. 2FA 処理
シングルステップ: flow.requires2FA → flow.submit2FA(code) → withdraw:completed
マルチステップ (例: Binance GOOGLE + EMAIL + FACE + SMS + ROAMING_FIDO):
flow.requires2FAMultiStep— 必須ステップはflow.multiStep2FAStepsで確認flow.submit2FAMultiStep('GOOGLE', code)— 各コードベースのステップをサブミットflow.pollFaceVerification()— FACE ステップ用 (10 秒遅延、その後 5 秒ポーリング)flow.pollRoamingFidoVerification()— ROAMING_FIDO ステップ用 (即座に 5 秒ポーリング)flow.isReadyToConfirmの場合 →flow.confirmWithdrawal()→withdraw:completed
検証状態の信頼できる情報源として flow.mfaVerified を使用します (step.status ではなく)。
問題が発生した場合
- すべての Next.js サーバーアクション戻り値に
toPlain()が必須 — なければ:"Classes or null prototypes are not supported"シリアル化エラー - 無効な状態遷移はサイレント no-op —
getState().typeで遷移が発生したかを確認 WITHDRAWAL_DRY_RUN_COMPLETEは成功シグナル、エラーではありません — すべてのマルチステップ 2FA ステップが検証済みを意味します。SDK はwithdraw:readyToConfirmに遷移します- マルチステップ 2FA は
mfa.verifiedが信頼できる情報源 —step.statusではありません。バックエンドがmfa.verifiedを更新します - フックを使用するすべてのコンポーネントに
"use client"が必須 — Next.js App Router 要件 binance-webは QR コードフロー自動検出 — 手動でルーティングしないでください。startWithdrawalFlowが処理しますautoRefreshQuotationはデフォルトでtrue— 手動の「期限切れ」UI でflow.isQuoteExpiredが必要な場合はfalseに設定- API キーをログしないこと — Bluvo はキーマテリアルをログしません。コードも同様に確認してください
- OAuth ウィンドウ閉鎖検出には ~500ms のポーリング遅延がある — ポップアップ閉鎖と
oauth:window_closed_by_userの間に若干のラグ
SDK スキルファイル — 条件付き読み込みトリガー
SDK には詳細な実装ガイダンス用のスキルファイルがあります。構築内容に基づいてオンデマンドでこれらを読み込みます。
@bluvo/react (React フック)
読み込むタイミング: React または Next.js 出金 UI を構築する場合。
メインスキル: https://raw.githubusercontent.com/bluvoinc/sdk/main/packages/react/skill/SKILL.md
| リファレンス | 読み込むタイミング... | URL |
|---|---|---|
hooks-complete.md | 完全な useBluvoFlow 戻り値シグネチャ (~80+ フィールド) が必要 | https://raw.githubusercontent.com/bluvoinc/sdk/main/packages/react/skill/references/hooks-complete.md |
nextjs-patterns.md | Next.js App Router とサーバーアクションを構築 | https://raw.githubusercontent.com/bluvoinc/sdk/main/packages/react/skill/references/nextjs-patterns.md |
components.md | エクスポート済み React コンポーネントを探索 | https://raw.githubusercontent.com/bluvoinc/sdk/main/packages/react/skill/references/components.md |
qrcode-binance-web.md | binance-web の QR コード認証を実装 | https://raw.githubusercontent.com/bluvoinc/sdk/main/packages/react/skill/references/qrcode-binance-web.md |
multistep-2fa.md | マルチステップ 2FA (Binance GOOGLE+EMAIL+FACE+SMS+ROAMING_FIDO) を処理 | https://raw.githubusercontent.com/bluvoinc/sdk/main/packages/react/skill/references/multistep-2fa.md |
@bluvo/sdk-ts (コア TypeScript)
読み込むタイミング: React 以外のフロントエンド、サーバー側統合を構築、またはステートマシンの内部機構が必要な場合。
メインスキル: https://raw.githubusercontent.com/bluvoinc/sdk/main/packages/ts/skill/SKILL.md
| リファレンス | 読み込むタイミング... | URL |
|---|---|---|
api-client.md | REST 呼び出しの詳細、認証ヘッダー、ファクトリ関数、エラーコードが必要 | https://raw.githubusercontent.com/bluvoinc/sdk/main/packages/ts/skill/references/api-client.md |
types.md | 状態、コンテキスト、イベントの TypeScript 型定義が必要 | https://raw.githubusercontent.com/bluvoinc/sdk/main/packages/ts/skill/references/types.md |
state-transitions.md | 完全な遷移マップ、ガード条件、シーケンス図が必要 | https://raw.githubusercontent.com/bluvoinc/sdk/main/packages/ts/skill/references/state-transitions.md |
ドキュメント インデックス
| 知りたいこと | 移動先 |
|---|---|
| すべての API エンドポイント | https://docs.bluvo.dev/api-reference |
| API キーの取得方法 | https://docs.bluvo.dev/api-keys |
| OAuth2 統合レベル | https://docs.bluvo.dev/learn/oauth2-integration |
| セキュリティアーキテクチャ | https://docs.bluvo.dev/learn/security |
| マルチテナント設定 | https://docs.bluvo.dev/learn/multi-tenancy |
| 対応取引所 | https://docs.bluvo.dev/exchanges |
| LLM 用の完全なナビゲーション | https://docs.bluvo.dev/llms.txt |
| コードサンプル | https://github.com/bluvoinc/awesome |
検証チェックリスト
Bluvo での作業をサブミットする前に:
-
useBluvoFlowまたはBluvoFlowClientが 6 つのコールバック関数すべてで初期化済み - サーバーアクションが
toPlain()でラップ済み - クライアントコンポーネントが
"use client"でマーク済み - エラー/チャレンジ状態が処理済み (
oauth:error、withdraw:error2FA、withdraw:fatalなど) - 終了状態が処理済み (
withdraw:completed、flow:cancelled、withdraw:blocked) - API キーが操作に対して正しいスコープを持っている
- センシティブ認証情報がログされていない、公開されていない
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- bluvoinc
- リポジトリ
- bluvoinc/sdk
- ライセンス
- MIT
- 最終更新
- 2026/5/4
Source: https://github.com/bluvoinc/sdk / ライセンス: MIT