# Monobundle — Full documentation (llms-full.txt) > Single-file version of MBSC API and React SDK docs. Source: https://www.monobundle.com/service/mbsc/docs --- ## Document: /service/mbsc/docs/intro # MBSC API / MBSC React SDK Doc **MBSC** は、日本円(銀行振込)とステーブルコイン(ERC-20)の**双方向ブリッジ**を提供する API です。 - **Fiat → SC(Intent)**: 円を入金すると、指定チェーン上のウォレットへ SC を送付 - **SC → Fiat(Redemption)**: SC を送付すると、銀行振込で円を払い戻し **Fiat → SC(日本円→SC)の画面例** ![Fiat→SC(Intent)フロントエンドの画面例](/assets/mbsc-react-sdk-intent-frontend.png) **SC → Fiat(SC→日本円)の画面例** ![SC→日本円(Redemption)フロントエンドの画面例](/assets/redemption-frontend.png) このドキュメントでは、REST API の仕様・エンドポイント・リクエスト/レスポンス例、およびフロントエンド(React)からの統合方法を説明します。React SDK は npm で公開しています([@mbsc-core/checkout](https://www.npmjs.com/package/@mbsc-core/checkout)、[@mbsc-core/types](https://www.npmjs.com/package/@mbsc-core/types))。 ## ドキュメント構成 | セクション | 内容 | |-----------|------| | [API 概要](/service/mbsc/docs/mbsc-api/overview) | ベース URL・バージョニング・サービス概要・役割 | | [認証](/service/mbsc/docs/mbsc-api/authentication) | エンドユーザー(Cookie セッション)、2FA、Admin API Key | | [Intent(Fiat→SC)](/service/mbsc/docs/mbsc-api/intent) | Intent 作成・取得・Payout・状態遷移 | | [Redemption(SC→Fiat)](/service/mbsc/docs/mbsc-api/redemption) | Redemption 作成・取得・払い戻し・状態遷移 | | [Webhook](/service/mbsc/docs/mbsc-api/webhooks) | 内向き(入金通知・オンチェーン)・署名検証・外向き通知 | | [Admin API](/service/mbsc/docs/mbsc-api/admin) | ユーザー一覧・Tx 履歴・検索・SC 情報 | | [Sandbox](/service/mbsc/docs/mbsc-api/sandbox) | 入金シミュレーション(開発用) | | [リソース定義](/service/mbsc/docs/mbsc-api/resources) | User / Intent / Redemption の JSON スキーマ | | [エラー・対応チェーン](/service/mbsc/docs/mbsc-api/errors-and-chains) | エラー形式・対応チェーン一覧 | ## クイックスタート(認証〜Intent 作成) ```bash # 1. 会員登録 curl -X POST https://api.mbsc.example.com/api/auth/register \ -H "Content-Type: application/json" \ -d '{"name":"Taro","email":"user@example.com","password":"password1234"}' # 2. ログイン(Cookie が Set-Cookie で返る) curl -X POST https://api.mbsc.example.com/api/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"user@example.com","password":"password1234"}' -c cookies.txt # 3. KYC スキップ(開発用) curl -X POST https://api.mbsc.example.com/api/v1/kyc/skip \ -b cookies.txt -H "Content-Type: application/json" # 4. Intent 作成(Fiat→SC) curl -X POST https://api.mbsc.example.com/api/v1/intents \ -b cookies.txt -H "Content-Type: application/json" \ -d '{ "amountJpy": 10000, "issueChain": "polygon", "walletAddress": "0x...", "bankAccount": { "bankName": "みずほ銀行", "bankAccountNumber": "1234567", "bankAccountHolder": "ヤマダ タロウ" } }' ``` ブラウザや React から利用する場合は、同一オリジンまたは CORS 許可のうえ `credentials: "include"` で Cookie を送信してください。詳細は [認証](/service/mbsc/docs/mbsc-api/authentication) を参照してください。 --- ## Document: /service/mbsc/docs/mbsc-api/overview # MBSC API MBSC のバックエンド API です。**Fiat → SC(Intent)** と **SC → Fiat(Redemption)** の両方に対応し、日本円(銀行振込)と自社 SC を相互に行き来させるためのエンドポイントを提供します。 ## ベース URL・バージョニング | 項目 | 説明 | |------|------| | **ベース URL** | `https://api.mbsc.monobundle.com` | | **v1 API** | `/api/v1/...`(Intent / Redemption / Webhook / Sandbox / KYC skip) | | **その他** | `/api/...`(認証・Me・2FA など) | | **Content-Type** | `application/json` | OpenAPI ドキュメントは API サーバー `GET https://api.mbsc.monobundle.com/api/openapi.json` のほか、コーポレートサイト(LLM 向け)からも同一仕様を `GET /api/openapi.json` で取得できます。 > **試し方**: 前提なしで curl できるのは `GET /api/health` と `GET /api/openapi.json` のみ。それ以外は Cookie セッション・Admin API Key または実在する Intent/Redemption ID が必要です。 ## サービス概要(何を提供しているか) MBSC は、**日本円(銀行振込)と自社 SC(ERC-20 / 18 decimals)を相互に行き来**させるためのバックエンドです。 ### 提供フロー - **Fiat → SC(Intent)**: ユーザーが JPY 入金すると、入金検知後に SC をユーザーウォレットへ送付 - 銀行側: バーチャル口座(GMOあおぞら等)を発行し、入金 Webhook を受けて処理 - チェーン側: mint/transfer で送付 - **SC → Fiat(Redemption)**: ユーザーが SC を指定アドレスへ送付すると、オンチェーン検知後に銀行振込で払い戻し - 申請ごとに**専用入金アドレス**を生成(ERC-20 はメモがないため紐付け簡易化) - 外部インデクサ/監視が ERC-20 Transfer を検知して内向き Webhook(`/api/v1/webhooks/crypto-payin`)を呼ぶ想定 ### 前提・換算 - **JPY**: 整数(円) - **SC**: 18 decimals(内部は `amountWei`) - **換算**: 現行実装は **1 SC = 1 JPY** を前提(`amountScWei` が整数 SC のときのみ JPY に変換) ## 役割(誰が何をするか) | 役割 | 説明 | |------|------| | **エンドユーザー(End user)** | 事業者フロントから、Intent/Redemption の作成・ステータス確認を行う | | **事業者サーバー(Merchant server)** | 運用上の連携(Webhook 受領、管理画面操作の自動化) | | **管理者ダッシュボード(Admin)** | 管理権限で Payout を手動承認/実行する | | **外部銀行API(deposit 等)** | 入金 Webhook を MBSC に通知する(内向き Webhook) | | **外部インデクサ・RPC(Crypto pay-in)** | オンチェーンの Transfer を監視し、MBSC に通知する(内向き Webhook) | ## エンドポイント一覧 ### 動作確認 | Method | Path | 説明 | |--------|------|------| | GET | `/api/health` | 稼働確認 | | GET | `/api/openapi.json` | OpenAPI 仕様 | ### 認証・オンボーディング | Method | Path | 説明 | |--------|------|------| | POST | `/api/auth/register` | 会員登録 | | POST | `/api/auth/login` | ログイン | | POST | `/api/auth/2fa-verify` | 2FA コード検証 | | POST | `/api/auth/logout` | ログアウト | | GET | `/api/me` | 自分・オンボーディング状態 | | GET | `/api/me/applications` | 自分の申請一覧 | | GET | `/api/2fa/setup` | 2FA セットアップ(secret / otpauth URL) | | POST | `/api/2fa/verify-setup` | 2FA 有効化 | | POST | `/api/2fa/skip` | 2FA スキップ | | POST | `/api/v1/kyc/skip` | KYC スキップ(開発用) | ### Intent(Fiat → SC) | Method | Path | 説明 | 認証 | |--------|------|------|------| | POST | `/api/v1/intents` | Intent 作成 | Cookie | | GET | `/api/v1/intents/:id` | Intent 取得 | Cookie | | POST | `/api/v1/intents/:id/payout` | 入金済み Intent の SC 送金実行 | Admin API Key | | POST | `/api/v1/payments/payout` | body: `{ intentId }` で Payout 実行 | Admin API Key | ### Redemption(SC → Fiat) | Method | Path | 説明 | 認証 | |--------|------|------|------| | POST | `/api/v1/redemptions` | Redemption 作成 | Cookie | | GET | `/api/v1/redemptions/:id` | Redemption 取得 | Cookie | | POST | `/api/v1/redemptions/:id/payout` | JPY 払い戻し実行 | Admin API Key | ### Webhook・Sandbox・Admin Webhook(内向き)、Sandbox、Admin の一覧は [Webhook](/service/mbsc/docs/mbsc-api/webhooks)、[Sandbox](/service/mbsc/docs/mbsc-api/sandbox)、[Admin API](/service/mbsc/docs/mbsc-api/admin) を参照してください。 ## 関連ドキュメント - [MBSC Core React SDK 概要](/service/mbsc/docs/mbsc-react-sdk/intro) — フロント用 SDK の概要・クイックスタート - [Intent(Fiat→SC)](/service/mbsc/docs/mbsc-api/intent) — Intent API 仕様 - [Redemption(SC→Fiat)](/service/mbsc/docs/mbsc-api/redemption) — Redemption API 仕様 --- ## Document: /service/mbsc/docs/mbsc-api/authentication # 認証 ## エンドユーザー(Cookie セッション) - ログイン成功時に `Set-Cookie: session=` が返る - 以降は同一オリジン、または CORS 許可+`credentials: "include"` で Cookie 送信 - 2FA 有効時は `POST /api/auth/login` が `requires2fa: true` と `tempToken` を返し、`POST /api/auth/2fa-verify` でコード検証後にセッション発行 ## Admin / Payout(API Key) - **Payout**(`POST /api/v1/intents/:id/payout`、`POST /api/v1/payments/payout`、`POST /api/v1/redemptions/:id/payout`)と **Admin API**(`GET /api/admin/*`)は、`Authorization: Bearer ` で保護 - 環境変数 `ADMIN_API_KEY` が未設定の場合は認可チェックをスキップ(開発用)。本番では必ず設定すること --- ## 会員登録・ログイン ### POST /api/auth/register **Request** ```json { "name": "Taro", "email": "user@example.com", "password": "password1234" } ``` **Response** ```json { "user": { "id": "usr_123", "name": "Taro", "email": "user@example.com" } } ``` `Set-Cookie: session=...` が返ります。 **サンプル(curl)** ```bash curl -X POST https://api.mbsc.example.com/api/auth/register \ -H "Content-Type: application/json" \ -d '{"name":"Taro","email":"user@example.com","password":"password1234"}' -c cookies.txt ``` **サンプル(TypeScript / fetch)** ```typescript const res = await fetch('https://api.mbsc.example.com/api/auth/register', { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify({ name: 'Taro', email: 'user@example.com', password: 'password1234', }), }); const data = await res.json(); // Cookie は credentials: 'include' で自動で保存される console.log(data.user); ``` ### POST /api/auth/login **Response(2FA なし)** ```json { "user": { "id": "usr_123", "name": "Taro", "email": "user@example.com" } } ``` **Response(2FA あり)** ```json { "requires2fa": true, "tempToken": "..." } ``` **サンプル(React)** ```tsx async function login(email: string, password: string) { const res = await fetch('https://api.mbsc.example.com/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify({ email, password }), }); const data = await res.json(); if (data.requires2fa) { return { requires2fa: true, tempToken: data.tempToken }; } return { user: data.user }; } ``` ### POST /api/auth/2fa-verify **Request** ```json { "tempToken": "...", "code": "123456" } ``` **サンプル(fetch)** ```typescript const res = await fetch('https://api.mbsc.example.com/api/auth/2fa-verify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify({ tempToken, code: '123456' }), }); // 成功時は Set-Cookie でセッションが発行される ``` ### POST /api/auth/logout **Response** ```json { "ok": true } ``` --- ## Me(オンボーディング状態) ### GET /api/me **Response** ```json { "user": { "id": "usr_123", "email": "user@example.com", "name": "Taro", "kycStatus": "approved" }, "onboarding": { "auth": true, "kycDone": true, "twoFaDone": false } } ``` **サンプル(React)** ```tsx useEffect(() => { fetch('https://api.mbsc.example.com/api/me', { credentials: 'include' }) .then((r) => r.json()) .then((data) => { setUser(data.user); setOnboarding(data.onboarding); }); }, []); ``` ### GET /api/me/applications **Response** ```json { "applications": [ { "id": "int_123", "amountJpy": 10000, "status": "Applied" } ] } ``` --- ## 2FA(TOTP) - `GET /api/2fa/setup` — 2FA セットアップ(secret / otpauth URL 取得) - `POST /api/2fa/verify-setup` — body: `{ "secret", "code" }` で 2FA 有効化 - `POST /api/2fa/skip` — 2FA スキップ --- ## KYC スキップ(開発用) ### POST /api/v1/kyc/skip **Response** ```json { "ok": true, "kycStatus": "approved" } ``` **サンプル(curl)** ```bash curl -X POST https://api.mbsc.example.com/api/v1/kyc/skip \ -b cookies.txt -H "Content-Type: application/json" ``` **サンプル(fetch)** ```typescript await fetch('https://api.mbsc.example.com/api/v1/kyc/skip', { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json' }, }); ``` --- ## Document: /service/mbsc/docs/mbsc-api/intent # Intent(Fiat → SC) 「ユーザーが JPY を入金し、SC を受け取る」という**意思(予約)**を表すリソースです。Stripe の `PaymentIntent` と同種です。 ## 状態遷移 1. `POST /api/v1/intents` → **PENDING_DEPOSIT**(DB: Applied) 2. `POST /api/v1/webhooks/deposit`(入金検知)→ **DEPOSITED**(DB: Deposited) 3. 自動、または `POST /api/v1/intents/:id/payout` → **COMPLETED**(DB: Completed) 4. 金額不一致/送金失敗 → **FAILED**(DB: Failed) --- ## Intent 作成 ### POST /api/v1/intents 認証: **Cookie セッション必須**。KYC が `approved` である必要があります。 **Request** ```json { "amountJpy": 10000, "issueChain": "polygon", "walletAddress": "0x...", "bankAccount": { "bankName": "みずほ銀行", "bankAccountNumber": "1234567", "bankAccountHolder": "ヤマダ タロウ" } } ``` - `issueChain`: `ethereum` \| `polygon` \| `avalanche` \| `arbitrum` \| `optimism` \| `arc`(省略時は `polygon`) - `bankAccount` は任意(ユーザー情報に保存される) **Response** ```json { "intent": { "id": "int_123", "status": "PENDING_DEPOSIT", "amountJpy": 10000, "issueChain": "polygon", "transferDetails": { "bankCode": "0001", "branchCode": "001", "accountNumber": "1234567", "accountHolder": "MBSC ...", "ref": "MBSC-..." }, "expiresAt": "2026-02-12T10:00:00.000Z" } } ``` > `transferDetails` は現行実装では DB に保存していないため、**このレスポンスでのみ返ります**(`GET` では返らない想定)。 **サンプル(curl)** ```bash curl -X POST https://api.mbsc.example.com/api/v1/intents \ -b cookies.txt -H "Content-Type: application/json" \ -d '{ "amountJpy": 10000, "issueChain": "polygon", "walletAddress": "0x1234567890abcdef1234567890abcdef12345678", "bankAccount": { "bankName": "みずほ銀行", "bankAccountNumber": "1234567", "bankAccountHolder": "ヤマダ タロウ" } }' ``` **サンプル(TypeScript / React)** ```typescript interface CreateIntentParams { amountJpy: number; issueChain?: string; walletAddress: string; bankAccount?: { bankName: string; bankAccountNumber: string; bankAccountHolder: string; }; } async function createIntent(params: CreateIntentParams) { const res = await fetch('https://api.mbsc.example.com/api/v1/intents', { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify({ amountJpy: params.amountJpy, issueChain: params.issueChain ?? 'polygon', walletAddress: params.walletAddress, bankAccount: params.bankAccount, }), }); if (!res.ok) throw new Error(await res.text()); const { intent } = await res.json(); return intent; } // 使用例 const intent = await createIntent({ amountJpy: 10000, walletAddress: '0x1234567890abcdef1234567890abcdef12345678', bankAccount: { bankName: 'みずほ銀行', bankAccountNumber: '1234567', bankAccountHolder: 'ヤマダ タロウ', }, }); console.log('振込先:', intent.transferDetails); console.log('有効期限:', intent.expiresAt); ``` --- ## Intent 取得 ### GET /api/v1/intents/:id 認証: 現行実装では intentId を知っていれば取得可能。`transferDetails` は返却されません。 **サンプル(fetch)** ```typescript const res = await fetch( `https://api.mbsc.example.com/api/v1/intents/${intentId}`, { credentials: 'include' } ); const { intent } = await res.json(); console.log(intent.status, intent.amountJpy); ``` --- ## Payout(Admin API Key) 入金検知後、SC をユーザーに送金する処理です。**Admin API Key**(`Authorization: Bearer `)必須です。 ### POST /api/v1/intents/:id/payout ### POST /api/v1/payments/payout body に `intentId` を指定して Payout を実行。 **Request** ```json { "intentId": "int_123" } ``` **サンプル(curl)** ```bash curl -X POST https://api.mbsc.example.com/api/v1/payments/payout \ -H "Authorization: Bearer $ADMIN_API_KEY" \ -H "Content-Type: application/json" \ -d '{"intentId":"int_123"}' ``` **サンプル(Node.js)** ```typescript const ADMIN_API_KEY = process.env.ADMIN_API_KEY; await fetch('https://api.mbsc.example.com/api/v1/payments/payout', { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${ADMIN_API_KEY}`, }, body: JSON.stringify({ intentId: 'int_123' }), }); ``` --- ## 冪等キー(推奨) 重複送信に耐えるため、書き込み系では **Idempotency-Key** ヘッダーの利用を推奨します。 - **ヘッダー**: `Idempotency-Key: ` - 対象: `POST /api/v1/intents`、`POST /api/v1/payments/payout` など > 現行実装では `Idempotency-Key` の保存/強制は行っていません(将来対応の方針として記載)。 **サンプル** ```typescript import { randomUUID } from 'crypto'; await fetch('https://api.mbsc.example.com/api/v1/intents', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Idempotency-Key': randomUUID(), }, credentials: 'include', body: JSON.stringify({ amountJpy: 10000, walletAddress: '0x...' }), }); ``` --- ## Document: /service/mbsc/docs/mbsc-api/redemption # Redemption(SC → Fiat) ユーザーが SC を指定アドレスへ送付し、銀行振込で JPY を受け取るフローです。申請ごとに**専用入金アドレス**が発行されます。 ## 状態遷移 1. `POST /api/v1/redemptions` → **Requested** 2. `POST /api/v1/webhooks/crypto-payin` → **CryptoDetected** → **CryptoConfirmed**(confirmations 条件) 3. `POST /api/v1/redemptions/:id/payout` → **FiatPayoutProcessing** → **Completed** 4. 期限切れ/過少/過多/遅延入金 → **OnHold** / **Expired** / **Failed** --- ## Redemption 作成 ### POST /api/v1/redemptions 認証: **Cookie セッション必須**。KYC `approved` および銀行口座情報(bankName, bankAccountNumber, bankAccountHolder)がユーザーに設定されている必要があります。 **Request** ```json { "amountSc": 5000, "chain": "polygon" } ``` - `amountSc`: 整数(SC 数量)。1 以上 - `chain`: `ethereum` \| `polygon` \| `avalanche` \| `arbitrum` \| `optimism` \| `arc`(省略時は `polygon`) **Response(201)** ```json { "redemption": { "redemptionId": "uuid", "status": "Requested", "chain": "polygon", "tokenAddress": "0x...", "depositAddress": "0x...", "amountSc": 5000, "expiresAt": "2026-02-12T10:00:00.000Z" } } ``` API によっては `id` や `amountScWei` で返る場合があります。 **サンプル(curl)** ```bash curl -X POST https://api.mbsc.example.com/api/v1/redemptions \ -b cookies.txt -H "Content-Type: application/json" \ -d '{"amountSc": 5000, "chain": "polygon"}' ``` **サンプル(TypeScript / React)** ```typescript interface CreateRedemptionParams { amountSc: number; chain?: string; } async function createRedemption(params: CreateRedemptionParams) { const res = await fetch('https://api.mbsc.example.com/api/v1/redemptions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify({ amountSc: params.amountSc, chain: params.chain ?? 'polygon', }), }); if (!res.ok) { const err = await res.json(); throw new Error(err.error?.message ?? 'Redemption failed'); } const { redemption } = await res.json(); return redemption; } // 使用例: ユーザーに送金先アドレスを表示 const redemption = await createRedemption({ amountSc: 5000 }); console.log('このアドレスへ送金:', redemption.depositAddress); console.log('数量:', redemption.amountSc, 'SC'); console.log('有効期限:', redemption.expiresAt); ``` --- ## Redemption 取得 ### GET /api/v1/redemptions/:id 認証: **Cookie セッション必須**。自分が作成した Redemption のみ取得可能。 **Response** `redemption` オブジェクトに `id`, `userId`, `chain`, `tokenAddress`, `depositAddress`, `amountScWei`, `status`, `cryptoTxHash`, `cryptoConfirmations`, `payoutRef`, `failureReason`, `expiresAt`, `createdAt`, `updatedAt` などが含まれます。詳細は [リソース定義 - Redemption](/service/mbsc/docs/mbsc-api/resources#63-redemptioncryptofiat) を参照してください。 **サンプル(fetch)** ```typescript const res = await fetch( `https://api.mbsc.example.com/api/v1/redemptions/${redemptionId}`, { credentials: 'include' } ); const { redemption } = await res.json(); console.log(redemption.status, redemption.depositAddress); ``` --- ## Payout(Admin API Key) Redemption が **CryptoConfirmed** のときのみ実行可能。未満の場合は `400 Redemption is not in CRYPTO_CONFIRMED state`。 ### POST /api/v1/redemptions/:id/payout 認証: **Admin API Key** 必須。 **サンプル(curl)** ```bash curl -X POST https://api.mbsc.example.com/api/v1/redemptions/red_123/payout \ -H "Authorization: Bearer $ADMIN_API_KEY" \ -H "Content-Type: application/json" ``` **サンプル(Node.js)** ```typescript const ADMIN_API_KEY = process.env.ADMIN_API_KEY; async function triggerRedemptionPayout(redemptionId: string) { const res = await fetch( `https://api.mbsc.example.com/api/v1/redemptions/${redemptionId}/payout`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${ADMIN_API_KEY}`, }, } ); if (!res.ok) throw new Error(await res.text()); return res.json(); } ``` --- ## Document: /service/mbsc/docs/mbsc-api/webhooks # Webhook ## 内向き Webhook(MBSC が受信) 以下の環境変数が設定されている場合、対応する Webhook で署名検証を行います。 - **銀行入金**: `WEBHOOK_DEPOSIT_SECRET` - **Crypto pay-in**: `WEBHOOK_CRYPTO_PAYIN_SECRET` **方式**: ヘッダー `x-signature` に `hex(HMAC-SHA256(rawBody, secret))` を載せる。送信側はリクエスト body の**生文字列**を UTF-8 で HMAC-SHA256 し、hex でヘッダーに設定すること。 シークレット未設定時は検証をスキップ(開発用)。 --- ## 銀行入金 Webhook ### POST /api/v1/webhooks/deposit GMO 等の入金通知を受けるエンドポイントです。Payload は GMO 入金通知に準拠(`transactionRef` が冪等キー)。`WEBHOOK_DEPOSIT_SECRET` 設定時は `x-signature`(HMAC-SHA256 hex)で署名検証を行います。 **署名検証サンプル(Node.js)** ```typescript import crypto from 'crypto'; function verifyDepositSignature(rawBody: string, signature: string, secret: string): boolean { const expected = crypto .createHmac('sha256', secret) .update(rawBody, 'utf8') .digest('hex'); return crypto.timingSafeEqual( Buffer.from(signature, 'hex'), Buffer.from(expected, 'hex') ); } // ミドルウェア例(Express) app.post('/api/v1/webhooks/deposit', express.raw({ type: 'application/json' }), (req, res) => { const sig = req.headers['x-signature'] as string; const rawBody = (req as any).body?.toString?.() ?? ''; if (!verifyDepositSignature(rawBody, sig, process.env.WEBHOOK_DEPOSIT_SECRET!)) { return res.status(401).json({ error: 'Invalid signature' }); } const payload = JSON.parse(rawBody); // 入金処理... res.status(200).send('OK'); }); ``` --- ## Crypto pay-in Webhook ### POST /api/v1/webhooks/crypto-payin オンチェーン入金を検知したインデクサ等が呼び出すエンドポイントです。 **Request 例** ```json { "chain": "polygon", "tokenAddress": "0x...", "txHash": "0x...", "logIndex": 12, "to": "0x...", "amountWei": "1000000000000000000", "status": "detected | confirmed | on_hold", "confirmations": 10 } ``` - `confirmed` / `on_hold`: オンチェーンの Transfer を検証(改ざん耐性) - `detected`: pending の可能性があるため、receipt が取れれば検証 **署名検証サンプル(送信側・擬似)** ```typescript import crypto from 'crypto'; function signCryptoPayinBody(body: object, secret: string): string { const raw = JSON.stringify(body); return crypto.createHmac('sha256', secret).update(raw, 'utf8').digest('hex'); } const payload = { chain: 'polygon', tokenAddress: '0x...', txHash: '0x...', logIndex: 12, to: '0x...', amountWei: '1000000000000000000', status: 'confirmed', confirmations: 10, }; const signature = signCryptoPayinBody(payload, process.env.WEBHOOK_CRYPTO_PAYIN_SECRET!); await fetch('https://api.mbsc.example.com/api/v1/webhooks/crypto-payin', { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-signature': signature, }, body: JSON.stringify(payload), }); ``` --- ## 外向き Webhook(状態変更通知) 環境変数 `OUTBOUND_WEBHOOK_URL` が設定されている場合、Intent / Redemption の状態変更時にその URL へ POST します。 **Body 例** ```json { "event": "intent.completed", "intentId": "uuid", "status": "COMPLETED", "amountJpy": 10000, "txId": "0x...", "timestamp": "2026-02-13T12:00:00.000Z" } ``` **イベント種別** - `intent.deposited` / `intent.completed` / `intent.failed` - `redemption.status_changed` / `redemption.completed` / `redemption.failed` 受信側は **200 を速やかに返し**、処理は非同期で行うことを推奨します。冪等に設計してください。 **受信側サンプル(Node.js / Express)** ```typescript app.post('/webhooks/mbsc', express.json(), async (req, res) => { // 速やかに 200 を返す res.status(200).send('OK'); const { event, intentId, status, amountJpy, txId, timestamp } = req.body; // 非同期で処理(DB 更新、通知など) await processMbscEvent({ event, intentId, status, amountJpy, txId, timestamp }); }); ``` --- ## Document: /service/mbsc/docs/mbsc-api/admin # Admin API 運営向けの管理 API です。**Admin API Key**(`Authorization: Bearer `)が必須です。環境変数 `ADMIN_API_KEY` が未設定の場合は認可をスキップ(開発用)。本番では必ず設定してください。 ## エンドポイント一覧 | Method | Path | 説明 | |--------|------|------| | GET | `/api/admin/users` | ユーザー一覧 | | GET | `/api/admin/tx-history` | Tx 履歴 | | GET | `/api/admin/users/:userId/tx-history` | ユーザー別 Tx 履歴 | | GET | `/api/admin/tx-search?userId=&txId=` | Tx 検索 | | GET | `/api/admin/sc-info` | SC 情報マスタ | --- ## 共通ヘッダー すべての Admin リクエストで次のヘッダーを付与します。 ``` Authorization: Bearer ``` **サンプル(curl)** ```bash export ADMIN_API_KEY="your-admin-api-key" curl -H "Authorization: Bearer $ADMIN_API_KEY" \ "https://api.mbsc.example.com/api/admin/users" ``` **サンプル(TypeScript)** ```typescript const ADMIN_API_KEY = process.env.ADMIN_API_KEY; async function adminFetch(path: string, options: RequestInit = {}) { const res = await fetch(`https://api.mbsc.example.com${path}`, { ...options, headers: { ...options.headers, Authorization: `Bearer ${ADMIN_API_KEY}`, }, }); if (!res.ok) throw new Error(await res.text()); return res.json(); } // ユーザー一覧 const users = await adminFetch('/api/admin/users'); // Tx 履歴 const txHistory = await adminFetch('/api/admin/tx-history'); // ユーザー別 Tx 履歴 const userTx = await adminFetch('/api/admin/users/usr_123/tx-history'); // Tx 検索 const search = await adminFetch('/api/admin/tx-search?userId=usr_123&txId=int_456'); // SC 情報マスタ const scInfo = await adminFetch('/api/admin/sc-info'); ``` --- ## GET /api/admin/users ユーザー一覧を取得します。レスポンス形式は実装に依存します。 --- ## GET /api/admin/tx-history トランザクション履歴を取得します。Intent / Redemption 等の一覧が返ります。 --- ## GET /api/admin/users/:userId/tx-history 指定ユーザーのトランザクション履歴を取得します。 --- ## GET /api/admin/tx-search クエリパラメータで検索します。 | パラメータ | 説明 | |-----------|------| | `userId` | ユーザー ID で絞り込み | | `txId` | トランザクション ID で絞り込み | --- ## GET /api/admin/sc-info SC(ステーブルコイン)の情報マスタを取得します。チェーン別のコントラクトアドレスなどが含まれます。 --- ## Document: /service/mbsc/docs/mbsc-api/sandbox # Sandbox(開発・テスト用) `SANDBOX_ENABLED=true` または `NODE_ENV=development` のときのみ有効です。本番環境では無効にしてください。 ## 入金シミュレーション ### POST /api/v1/sandbox/simulate-deposit Intent に対する「入金」をシミュレートし、状態を **DEPOSITED** にします。実際の銀行入金は発生しません。 **Request** ```json { "intentId": "int_123", "amountJpy": 10000 } ``` **サンプル(curl)** ```bash curl -X POST https://api.mbsc.example.com/api/v1/sandbox/simulate-deposit \ -H "Content-Type: application/json" \ -d '{"intentId":"int_123","amountJpy":10000}' ``` **サンプル(TypeScript)** ```typescript async function simulateDeposit(intentId: string, amountJpy: number) { const res = await fetch( 'https://api.mbsc.example.com/api/v1/sandbox/simulate-deposit', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ intentId, amountJpy }), } ); if (!res.ok) throw new Error(await res.text()); return res.json(); } // 使用例: Intent 作成後に即シミュレート const intent = await createIntent({ amountJpy: 10000, walletAddress: '0x...' }); await simulateDeposit(intent.id, intent.amountJpy); // 以降、Payout を実行すると COMPLETED になる ``` **E2E テスト例(Intent フロー)** ```typescript describe('Intent flow (sandbox)', () => { it('should complete intent after simulated deposit', async () => { const intent = await createIntent({ amountJpy: 10000, walletAddress: testWallet, }); expect(intent.status).toBe('PENDING_DEPOSIT'); await simulateDeposit(intent.id, intent.amountJpy); const updated = await getIntent(intent.id); expect(updated.status).toBe('DEPOSITED'); await payoutIntent(intent.id); // Admin API const completed = await getIntent(intent.id); expect(completed.status).toBe('COMPLETED'); }); }); ``` --- ## Document: /service/mbsc/docs/mbsc-api/resources # リソース定義 API で扱う主要リソースの JSON スキーマです。現行バックエンド(2026-02 時点)に準拠しています。 --- ## 6.1 User ユーザー(エンドユーザー)を表すリソース。KYC / 2FA の状態を持ちます。 ```json { "id": "usr_123", "email": "user@example.com", "name": "Taro Yamada", "kycStatus": "none | pending | approved | rejected", "twoFaEnabledAt": "2026-02-11T10:00:00.000Z", "twoFaSkippedAt": null, "walletAddress": "0x...", "bankName": null, "bankAccountNumber": null, "bankAccountHolder": null } ``` - `GET /api/me` の `user` は上記の形で返ります。 - `twoFaEnabledAt` / `twoFaSkippedAt` で 2FA 状態を表現します。 - 現行では eKYC ベンダー連携(KycSession)は未実装で、開発用に `POST /api/v1/kyc/skip` が存在します。 --- ## 6.2 Intent(Fiat→SC) 「ユーザーが JPY を入金し、SC を受け取る」という**意思(予約)**を表すリソースです。 ```json { "id": "int_123", "userId": "usr_123", "amountJpy": 10000, "issueChain": "polygon", "status": "PENDING_DEPOSIT | DEPOSITED | COMPLETED | FAILED", "transferDetails": { "bankCode": "0001", "branchCode": "001", "accountNumber": "1234567", "accountHolder": "MBSC ...", "ref": "MBSC-..." }, "depositRef": "deposit_tx_...", "payoutTxId": "0x...", "failureReason": "Amount mismatch ...", "expiresAt": "2026-02-12T10:00:00.000Z", "createdAt": "2026-02-11T10:00:00.000Z", "updatedAt": "2026-02-11T10:10:00.000Z" } ``` - `transferDetails` は現行実装では DB に保存していないため、**`POST /api/v1/intents` のレスポンスでのみ返り得ます**(`GET` では返らない想定)。 - `expiresAt` は「作成から 24 時間」を返しますが、Intent を `EXPIRED` に自動更新する処理は現行未実装です。 --- ## 6.3 Redemption(Crypto→Fiat) ユーザーが SC を送付して JPY 払い戻しを受けるためのリソースです。 ```json { "id": "red_123", "userId": "usr_123", "chain": "polygon", "tokenAddress": "0x...", "depositAddress": "0x...", "amountScWei": "5000000000000000000", "status": "Requested | CryptoDetected | CryptoConfirmed | FiatPayoutProcessing | Completed | Failed | OnHold | Expired", "cryptoTxHash": "0x...", "cryptoConfirmations": 12, "payoutRef": "payout_...", "failureReason": "Underpaid: ...", "expiresAt": "2026-02-12T10:00:00.000Z", "createdAt": "2026-02-11T10:00:00.000Z", "updatedAt": "2026-02-11T10:10:00.000Z" } ``` - `depositAddress`: この Redemption 専用の入金アドレス。ここへ SC を送付すると紐付けられます。 - `amountScWei`: 18 decimals の Wei 表記。整数 SC の場合は `amountSc` で 5000 のように返る API もあります。 --- ## Document: /service/mbsc/docs/mbsc-api/errors-and-chains # エラー形式・対応チェーン ## エラー形式(v1) `4xx` / `5xx` 時は次の形式です。`requestId` は省略されることがあります。 ```json { "error": { "code": "UNAUTHORIZED", "message": "ログインしてください", "requestId": "req_..." } } ``` 認証系(`/api/auth/*`, `/api/me`, `/api/2fa/*`)や Redemption の一部エラーでは、`{ "error": "..." }` の簡易形式を返すことがあります。 **サンプル(エラーハンドリング)** ```typescript const res = await fetch('https://api.mbsc.example.com/api/v1/intents', { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ amountJpy: 10000, walletAddress: '0x...' }), }); if (!res.ok) { const data = await res.json().catch(() => ({})); const message = data.error?.message ?? data.error ?? res.statusText; throw new Error(message); } const { intent } = await res.json(); ``` **よくあるエラーコード例** | code | 説明 | |------|------| | `UNAUTHORIZED` | 未ログインまたはセッション無効 | | `FORBIDDEN` | 権限不足(例: Admin API Key 不足) | | `BAD_REQUEST` | リクエスト body 不正・バリデーションエラー | | `NOT_FOUND` | リソースが存在しない | | `CONFLICT` | 状態が不正(例: Redemption が CryptoConfirmed でないのに Payout) | --- ## 共通ルール(日時・金額) - **日時**: ISO 8601(例: `2026-02-11T10:00:00.000Z`) - **JPY**: **整数(円)**(例: `amountJpy: 10000`) - **SC**: **18 decimals**(オンチェーン送金時は `amountWei` 相当で扱う) --- ## 対応チェーン Intent の `issueChain` および Redemption の `chain` で指定可能な値です。 | 値 | チェーン | ブロックエクスプローラ例 | |----|----------|--------------------------| | `ethereum` | Ethereum Mainnet | etherscan.io | | `polygon` | Polygon | polygonscan.com | | `avalanche` | Avalanche | snowtrace.io | | `arbitrum` | Arbitrum One | arbiscan.io | | `optimism` | Optimism | optimistic.etherscan.io | | `arc` | Q Mainnet | explorer.q.org | RPC は環境変数 `INFURA_ETHEREUM_RPC` / `INFURA_POLYGON_RPC` 等(または `INFURA_RPC_URL`)で指定。SC コントラクトは `SC_CONTRACT_ADDRESS` または `SC_CONTRACT_POLYGON` 等で指定します。 **チェーン指定サンプル** ```typescript // Intent: Polygon で SC を受け取る(省略時も polygon) await createIntent({ amountJpy: 10000, issueChain: 'polygon', walletAddress: '0x...', }); // Redemption: Arbitrum 上の SC を送って円で受け取る await createRedemption({ amountSc: 5000, chain: 'arbitrum' }); ``` --- ## Document: /service/mbsc/docs/mbsc-react-sdk/intro # MBSC Core React SDK MBSC の申請フローを React アプリに埋め込むための SDK です。**Fiat → SC(Checkout)** と **SC → Fiat(Redemption)** の両方に対応し、次の npm パッケージを提供しています。 - **[@mbsc-core/checkout](https://www.npmjs.com/package/@mbsc-core/checkout)** — React コンポーネント(申請フォーム・アカウントカードなど) - **[@mbsc-core/types](https://www.npmjs.com/package/@mbsc-core/types)** — API / SDK 用の型定義(checkout の依存として同梱、型のみ必要な場合に単体利用可) ![MBSC React SDK フロントエンドの画面例](/assets/mbsc-react-sdk-intent-frontend.png) ## インストール ```bash bun add @mbsc-core/checkout # or npm install @mbsc-core/checkout ``` 型のみ使う場合(任意): ```bash bun add @mbsc-core/types ``` **Peer dependencies**: React 18 以上(`react`, `react-dom`) ## クイックスタート ### Checkout(Fiat → SC)最小例 ルート(または申請画面の親)を `MBSCCheckoutProvider` でラップし、`ApplyForm`(申請フォーム)と `AccountCard`(アカウント・2FA 状態)を子に配置します。認証は Cookie セッション(`credentials: "include"`)を想定しています。 ```tsx import { MBSCCheckoutProvider, ApplyForm, AccountCard, } from "@mbsc-core/checkout"; export default function ApplyPage() { const apiBaseUrl = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3000"; return (
); } ``` | コンポーネント / Prop | 説明 | |-----------------------|------| | **MBSCCheckoutProvider** | `apiBaseUrl`: MBSC API のベース URL。`credentials`: `"include"`(Cookie)または `{ getHeaders: () => ({ Authorization: "Bearer ..." }) }`(トークン) | | **ApplyForm** | 申請フォーム。`copy` / `applyCardCopy` でラベルなどを上書き可能 | | **AccountCard** | アカウント・2FA 状態表示。`copy`、`linkComponent`(例: Next.js `Link`)、`setup2FaPath` などでカスタム可能 | ### オールインワン: MBSCRedemption(SC → Fiat・換金) 換金数量・チェーンを props で渡し、申請完了時に専用入金アドレスとステータスを表示する最小構成です。 ![Redemption(SC→日本円)フロントエンドの画面例](/assets/redemption-frontend.png) ```tsx import { MBSCRedemption } from "@mbsc-core/checkout"; export default function RedeemPage() { return ( { console.log("Redemption ID:", result.redemptionId); console.log("Deposit address:", result.depositAddress); }} /> ); } ``` | Prop | 説明 | |------|------| | **apiBaseUrl** | MBSC API のベース URL | | **initialAmountSc** | 換金する SC 数量(整数)の初期値 | | **initialChain** | チェーン。省略時は `polygon` | | **pollIntervalMs** | ステータスをポーリングする間隔(ms)。0 でポーリングしない | | **onComplete** | 申請送信成功時に呼ばれるコールバック。KYC 承認・銀行口座設定済みである必要あり | ## 関連ドキュメント - [MBSC API 概要](/service/mbsc/docs/mbsc-api/overview) — バックエンド API の概要 - [Intent(Fiat→SC)](/service/mbsc/docs/mbsc-api/intent) — Intent API 仕様 - [Redemption(SC→Fiat)](/service/mbsc/docs/mbsc-api/redemption) — Redemption API 仕様 --- ## Document: /service/mbsc/docs/mbsc-react-sdk/authentication # 認証 SDK から MBSC API を呼び出す際の認証方法です。 ## Cookie セッション(デフォルト) 同一オリジン、または CORS 許可+Cookie 送信でログイン済みの場合、そのまま利用できます。 ```tsx ``` ## Token 認証 `Authorization` ヘッダーで Bearer トークンを渡す場合: ```tsx ({ Authorization: `Bearer ${yourToken}` }), }} amountJpy={10000} walletAddress="0x..." /> ``` `credentials` は `MBSCCheckoutProvider` / `MBSCRedemptionProvider` にも同じ形式で渡せます。省略時は `"include"` になります。 --- ## Document: /service/mbsc/docs/mbsc-react-sdk/client # クライアントを直接使う Provider を使わず、`createCheckoutClient` だけ使う場合の型とメソッドです。 ```tsx import { createCheckoutClient } from "@mbsc-core/checkout"; const client = createCheckoutClient(apiBaseUrl, "include"); // or credentials オブジェクト // 認証状態の取得(未認証時は null) const me = await client.getMe(); // { user: MeUser | null, onboarding: Onboarding | null } | null // Fiat → SC 申請 const intent = await client.postApply({ walletAddress: "0x...", amountJpy: 10000, issueChain: "polygon" }); // SC → Fiat 申請 const redemption = await client.postCreateRedemption({ amountSc: 5000, chain: "polygon" }); // 換金ステータス取得 const latest = await client.getRedemption(redemption.redemptionId); ``` ## メソッド一覧 | メソッド | 対応 API | 説明 | |----------|----------|------| | **getMe()** | `GET /api/me` | 認証状態を取得。失敗・未認証時は `null` を返す実装です。 | | **postApply(body)** | `POST /api/v1/intents` | Fiat→SC 申請。body は `PostApplyBody`。 | | **postCreateRedemption(body)** | `POST /api/v1/redemptions` | SC→Fiat 申請。body は `PostRedemptionBody`(`amountSc`, `chain?`)。 | | **getRedemption(redemptionId)** | `GET /api/v1/redemptions/:id` | 換金ステータス取得。戻り値は `Redemption`。 | ## エラー時 - `postApply` / `postCreateRedemption` / `getRedemption` は、レスポンスが 2xx でない場合に `Error` を throw します。メッセージは API の `error.message` または `error` 文字列です。 - `getMe` は失敗時も `null` を返し、throw しません。 --- ## Document: /service/mbsc/docs/mbsc-react-sdk/checkout # Checkout(Fiat → SC)の構成 オールインワンではなく、レイアウトを細かく組みたい場合は **Provider + 部品** で構成します。 ## Provider + 部品の例 `MBSCCheckoutProvider` でラップし、その中で `ApplyForm` や `AccountCard` を配置します。 ```tsx import { MBSCCheckoutProvider, useMBSCCheckout, ApplyForm, AccountCard, } from "@mbsc-core/checkout"; export default function ApplyPage() { const apiBaseUrl = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3000"; return (
console.log(result)} />
); } ``` ## MBSCCheckoutProvider | Prop | 型 | 説明 | |------|-----|------| | apiBaseUrl | string | MBSC API のベース URL | | credentials | `"include" \| { getHeaders: () => Record }` | 認証方法。省略時は `"include"` | | children | ReactNode | 子要素 | ## ApplyForm | Prop | 型 | 説明 | |------|-----|------| | copy | Partial\ | フォームの表示文言 | | applyCardCopy | Partial\ | 申請結果カードの表示文言 | | initialAmountJpy | number | 金額の初期値 | | initialWalletAddress | string | ウォレットアドレスの初期値 | | initialIssueChain | IssueChain | 発行チェーン(POST 時に body に含める) | | onComplete | (result: ApplyResult) => void | 申請完了時のコールバック | | sandboxConfig | SandboxConfig | 開発用: 入金シミュレートの表示・実行 | ## AccountCard KYC と 2FA の状態を表示し、未設定時は設定ページへのリンクを出します。`useMBSCCheckout` の `user` を参照するため、Checkout または Redemption のいずれかの Provider の子で配置してください。 | Prop | 型 | 説明 | |------|-----|------| | copy | Partial\ | 表示文言 | | linkComponent | `ComponentType<{ href, children }>` | リンク用コンポーネント(例: Next.js の `Link`)。未指定時は `` | | setupKycPath | string | KYC 設定ページのパス。デフォルト `"/onboarding/kyc"` | | setup2FaPath | string | 2FA 設定ページのパス。デフォルト `"/settings/2fa"` | ## ApplyCard 申請送信後に表示するカード。振込先(transferDetails)・申請ID・ステータス・金額を表示します。`ApplyForm` 内で自動的に使われます。単体で使う場合は `result` と `copy` を渡します。 | Prop | 型 | 説明 | |------|-----|------| | result | ApplyResult | 申請 API の戻り値 | | copy | Partial\ | 表示文言 | | sandbox | `{ enabled, simulateLabel?, onSimulate }` | 開発用: 入金シミュレートボタン。`result.status` が `Applied` または `PENDING_DEPOSIT` のとき表示 | ## useMBSCCheckout Provider の子コンポーネント内で、現在のユーザー・オンボーディング状態・`postApply` を取得します。 ```tsx const { user, onboarding, loading, postApply } = useMBSCCheckout(); ``` --- ## MBSCCheckout の Props 一覧 オールインワンコンポーネント `MBSCCheckout` の全 Props です。 | Prop | 型 | 必須 | 説明 | |------|-----|------|------| | apiBaseUrl | string | ○ | MBSC API のベース URL | | credentials | CheckoutCredentials | - | 認証。省略時は `"include"` | | amountJpy | number | ○ | 申請金額(初期値) | | issueChain | IssueChain | - | 発行チェーン。省略時は `polygon` | | walletAddress | string | ○ | 受取ウォレット(初期値) | | onComplete | (intent: ApplyResult) => void | - | 申請完了コールバック | | copy | Partial\ | - | フォーム文言 | | applyCardCopy | Partial\ | - | 申請結果カード文言 | | sandboxConfig | SandboxConfig | - | Sandbox 入金シミュレート | | children | ReactNode | - | 指定時は ApplyForm の代わりにこれを表示 | --- ## Document: /service/mbsc/docs/mbsc-react-sdk/redemption # Redemption(SC → Fiat)の構成 換金フローを細かく組みたい場合は、**MBSCRedemptionProvider** でラップし、`ApplyRedemptionForm` と `RedemptionCard` を配置します。 ## Provider + 部品の例 ```tsx import { MBSCRedemptionProvider, useMBSCRedemption, ApplyRedemptionForm, AccountCard, } from "@mbsc-core/checkout"; export default function RedeemPage() { const apiBaseUrl = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3000"; return ( console.log(result)} /> ); } ``` ## MBSCRedemptionProvider | Prop | 型 | 説明 | |------|-----|------| | apiBaseUrl | string | MBSC API のベース URL | | credentials | `"include"` \| `{ getHeaders: () => Record }` | 認証方法。省略時は `"include"` | | children | ReactNode | 子要素 | ## ApplyRedemptionForm フォームでは**送金元ウォレットアドレス**(入金元アドレス)の入力を必須としています。申請後、結果カードに「このアドレスから送金先へ SC を送金してください」と表示されます。API には送信せず、表示用として保持します。 | Prop | 型 | 説明 | |------|-----|------| | copy | Partial\ | フォームの表示文言(送金元アドレス・数量・チェーンなど) | | redemptionCardCopy | Partial\ | 換金結果カードの表示文言 | | initialAmountSc | number | 換金数量の初期値 | | initialChain | IssueChain | チェーン。省略時は `polygon` | | onComplete | (result: CreateRedemptionResponse) => void | 申請完了時のコールバック | | pollIntervalMs | number | ステータスをポーリングする間隔(ms)。0 でポーリングしない | ## RedemptionCard 申請完了後に表示するカード。**送金元アドレス**(フォームで入力したもの)・専用入金アドレス(コピーボタン付き)・金額・ステータス・チェーン・有効期限などを表示します。`pollIntervalMs` と `getRedemption` を渡すとステータスを自動更新します。 | Prop | 型 | 説明 | |------|-----|------| | result | RedemptionResult | POST 直後のレスポンスまたは GET で取得した Redemption | | sourceWalletAddress | string | フォームで入力した送金元ウォレットアドレス。指定時はカードに表示 | | copy | Partial\ | 表示文言 | | pollIntervalMs | number | ポーリング間隔(ms)。0 でポーリングしない | | getRedemption | (redemptionId: string) => Promise\ | ポーリング時に呼ぶ取得関数(通常は `useMBSCRedemption().getRedemption`) | ## useMBSCRedemption Provider の子コンポーネント内で、現在のユーザー・`postRedemption`・`getRedemption` を取得します。 ```tsx const { user, onboarding, loading, postRedemption, getRedemption } = useMBSCRedemption(); ``` **注意**: `ApplyForm` と `ApplyRedemptionForm` は、`user` が `null`(未ログインなど)のとき何も描画しません(`return null`)。認証済みであることを前提にしています。 --- ## MBSCRedemption の Props 一覧 オールインワンコンポーネント `MBSCRedemption` の全 Props です。 | Prop | 型 | 必須 | 説明 | |------|-----|------|------| | apiBaseUrl | string | ○ | MBSC API のベース URL | | credentials | CheckoutCredentials | - | 認証。省略時は `"include"` | | initialAmountSc | number | - | 換金数量の初期値 | | initialChain | IssueChain | - | チェーン。省略時は `polygon` | | onComplete | (result: CreateRedemptionResponse) => void | - | 申請完了コールバック | | pollIntervalMs | number | - | ステータスポーリング間隔(ms) | | copy | Partial\ | - | フォーム文言 | | redemptionCardCopy | Partial\ | - | 換金結果カード文言 | | children | ReactNode | - | 指定時は ApplyRedemptionForm の代わりにこれを表示 | --- ## Document: /service/mbsc/docs/mbsc-react-sdk/reference # UI 部品(Button / Input) フォーム内で使われている共通部品です。スタイルを揃えたい場合に単体で import できます。 - **Button**: `