USDC(Base Sepolia)とJPYC(Sepolia)を使ったガスレス決済のサンプルアプリケーションです。
- ガチャマシン風UI: CSSアニメーションでガチャマシンを再現
- x402決済フロー: HTTP 402 + ERC-3009による決済
- Chainlink価格フィード: JPY/USD為替レートをリアルタイム取得
- Fortune Cookie API: 外部APIからフォーチュンメッセージを取得
- マルチトークン対応: USDC ($0.50) / JPYC (約75円) で支払い可能
- Passkeyモード: ERC-4337 + Paymaster でガスレス送金
- EOAモード: ERC-3009 + Facilitator でガスレス送金
- QR決済: スキャン払い対応
┌─────────────────┐
│ / (ガチャ) │ メインページ
└────────┬────────┘
│
▼
┌─────────────────┐
│ ウォレット接続 │ WalletConnect
└────────┬────────┘
│
▼
┌─────────────────┐
│ トークン選択 │ USDC / JPYC
│ (残高表示) │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Play ボタン │ 残高不足時は無効化
└────────┬────────┘
│
▼
┌─────────────────┐
│ EIP-712署名 │ transferWithAuthorization
└────────┬────────┘
│
▼
┌─────────────────┐
│ Facilitator │ ガス代負担で実行
└────────┬────────┘
│
▼
┌─────────────────┐
│ Fortune表示 │ ボールが落ちて結果表示
└─────────────────┘
| トークン | チェーン | Decimals | EIP-712 Domain |
|---|---|---|---|
| USDC | Base Sepolia | 6 | name: "USDC", version: "2" |
| JPYC | Sepolia | 18 | name: "JPY Coin", version: "1" |
| モード | 対象ユーザー | 技術 | ガス負担 |
|---|---|---|---|
| Passkey | 新規ユーザー | ERC-4337 + Paymaster | Pimlico |
| EOA | 既存ウォレットユーザー | ERC-3009 + Facilitator | サーバー |
| 技術 | 用途 |
|---|---|
| Next.js 16 | フロントエンドフレームワーク |
| viem | Ethereumライブラリ |
| wagmi | React Hooks for Ethereum |
| Reown AppKit | WalletConnect対応 |
| Pimlico | Bundler & Paymaster |
| Coinbase Smart Wallet | ERC-4337 Smart Account |
| Chainlink | JPY/USD 価格フィード (Mainnet) |
| Fortune Cookie API | フォーチュンメッセージ取得 |
- Passkey認証: Touch ID / Face ID / セキュリティキーでウォレット作成
- Smart Account: Coinbase Smart Wallet (ERC-4337)
- Paymaster: Pimlico Paymasterによるガスレス送金
- 対応トークン: USDC (Base Sepolia)
- WalletConnect対応: MetaMask, Rainbow, Coinbase Wallet等
- マルチチェーン: USDC (Base Sepolia) / JPYC (Sepolia) 切り替え
- ERC-3009:
transferWithAuthorizationによる署名ベース送金 - Facilitator: サーバーがガス代を負担
- QR決済: スキャン払い対応
┌─────────────────┐
│ Passkey │ WebAuthn P256署名
│ (Touch ID等) │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Coinbase Smart │ ERC-4337 Smart Account
│ Account │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Pimlico │ Bundler + Paymaster
│ (Gasless) │ ガス代スポンサー
└────────┬────────┘
│
▼
┌─────────────────┐
│ Base Sepolia │
│ USDC │
└─────────────────┘
┌─────────────────┐
│ MetaMask等 │ WalletConnect接続
│ (EOA Wallet) │
└────────┬────────┘
│
▼
┌─────────────────┐
│ トークン選択 │ USDC / JPYC
│ チェーン切替 │ Base Sepolia / Sepolia
└────────┬────────┘
│
▼
┌─────────────────┐
│ EIP-712 │ transferWithAuthorization
│ 署名生成 │ (ERC-3009)
└────────┬────────┘
│
▼
┌─────────────────┐
│ Facilitator │ 署名を受け取り
│ (Server) │ ガス代を負担して実行
└────────┬────────┘
│
▼
┌─────────────────────────────────────┐
│ Base Sepolia │ Sepolia │
│ USDC │ JPYC │
└─────────────────────────────────────┘
npm install --legacy-peer-deps.env.localファイルを作成:
# Pimlico (Passkeyモード用)
PAYMASTER_PIMLICO_API_KEY=pim_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Facilitator (EOAモード/ガチャ用) - ガス代を負担するウォレットの秘密鍵
# 注意: Base SepoliaとSepoliaの両方にETHが必要
FACILITATOR_PRIVATE_KEY=0x...
# Reown/WalletConnect (NEXT_PUBLIC_ prefix required for client-side)
NEXT_PUBLIC_WALLET_REOWN_PROJECT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Fortune Cookie API (ガチャ用)
FORTUNE_API_KEY=your_api_key_here
# ガチャ受取先アドレス (オプション)
GACHA_RECIPIENT_ADDRESS=0x...取得先:
- Pimlico Dashboard - Pimlico API Key
- Reown Cloud - Reown Project ID
- APIVerve - Fortune Cookie API Key
EOAモードを使用する場合、Facilitatorウォレットに両チェーンのETHが必要です:
# Base Sepolia Faucet
https://www.coinbase.com/faucets/base-ethereum-goerli-faucet
# Sepolia Faucet
https://sepoliafaucet.com/npm run devhttp://localhost:3000 にアクセス
- 「Passkey (Smart Wallet)」を選択
- 「Passkeyでウォレット作成」をクリック
- デバイスのPasskey(Touch ID / Face ID等)で認証
- 固定の送金先・金額で「Passkeyで署名して送金」
- 「EOA (MetaMask)」を選択
- トークン選択: USDC / JPYC ボタンで切り替え
- 「ウォレットを接続」をクリック
- WalletConnectでMetaMask等を接続
- チェーン切り替えを承認(自動で要求されます)
- 直接送金: 「送金する」ボタン
- QR決済: 「スキャン払い」→ QRスキャン → 「支払う」
店舗側 顧客側
─────── ───────
QRコード表示 → スマホでWebアプリ開く
(店舗の識別用) ↓
WalletConnect接続
↓
トークン選択(USDC/JPYC)
↓
「スキャン払い」タップ
↓
店舗QRをスキャン
↓
「支払う」タップ
↓
MetaMaskで署名
↓
完了! ← Facilitatorが送金実行
├── src/
│ ├── app/
│ │ ├── page.tsx # /gacha へリダイレクト
│ │ ├── gacha/
│ │ │ └── page.tsx # ガチャページ
│ │ ├── wallet/
│ │ │ └── page.tsx # ウォレットページ (Passkey/EOA)
│ │ └── api/
│ │ ├── gacha/
│ │ │ └── route.ts # ガチャAPI (x402決済)
│ │ └── facilitator/
│ │ └── erc3009/
│ │ └── route.ts # ERC-3009 Facilitator API
│ ├── components/
│ │ ├── GachaContent.tsx # ガチャUI + アニメーション
│ │ ├── PasskeyWallet.tsx # Passkeyモード (USDC)
│ │ ├── EOAWallet.tsx # EOAモード (USDC/JPYC)
│ │ ├── QRReceive.tsx # QRコード表示
│ │ ├── QRScanner.tsx # QRスキャナー
│ │ └── providers/
│ │ └── ReownProvider.tsx # WalletConnect Provider
│ └── lib/
│ ├── config.ts # トークン・チェーン設定
│ ├── chainlink.ts # Chainlink価格フィード
│ ├── passkey.ts # Passkey + Smart Account
│ ├── erc3009.ts # ERC-3009ユーティリティ
│ ├── wagmi.ts # wagmi設定
│ └── qrPayment.ts # QR決済データ形式
| トークン | アドレス | チェーン |
|---|---|---|
| USDC | 0x036CbD53842c5426634e7929541eC2318f3dCF7e |
Base Sepolia |
| JPYC | 0x431D5dfF03120AFA4bDf332c61A6e1766eF37BDB |
Sepolia |
USDCとJPYCが実装している規格。署名のみでトークン転送を承認でき、
Facilitatorがガス代を負担してtransferWithAuthorization()を実行します。
function transferWithAuthorization(
address from,
address to,
uint256 value,
uint256 validAfter,
uint256 validBefore,
bytes32 nonce,
uint8 v, bytes32 r, bytes32 s
) external;トークンごとに異なるEIP-712ドメインを使用:
| トークン | name | version |
|---|---|---|
| USDC | "USDC" | "2" |
| JPYC | "JPY Coin" | "1" |
Coinbase Smart WalletはP256(secp256r1)署名をネイティブにサポート。 Passkeyで署名したUserOperationを直接検証・実行できます。
モバイルウォレットとの接続を可能にするプロトコル。 ユーザーはブラウザ拡張なしでMetaMaskアプリ等を使用できます。
JPY/USD為替レートをEthereum Mainnetから取得。 JPYC支払い時の価格計算に使用します。
Feed Address: 0xBcE206caE7f0ec07b545EddE332A47C2F75bbeb3
Chain: Ethereum Mainnet
- 1分間キャッシュで高速化
- フォールバック価格: 150 JPY/USD
- HTTPS必須: WebAuthn APIはlocalhost以外ではHTTPS環境が必要
- ブラウザ対応: Chrome, Safari, Firefox等のモダンブラウザが必要
- Testnet: Base SepoliaとSepoliaテストネット用のデモです
- Facilitator残高: EOAモードではFacilitatorウォレットに両チェーンのETHが必要
MIT