← JPYC Pay に戻る |

作り方ガイド

🥷

AIで作るJPYCウォレット
完全ガイド

このページは Claude Code (AI) を使って実際に作られたウォレットの解説です。
同じものをあなたも作れます。

Polygon EIP-3009 ガスレス Cloudflare Pages 無料で構築可能

目次

  1. これは何か
  2. 仕組み(ガスレスの仕組み)
  3. 作り方(AIへの頼み方)
  4. 費用とランニングコスト
  5. 注意点・セキュリティ
  6. AIへのプロンプト(コピペ用)

これは何か

このウォレットは Polygon チェーン上の JPYC(日本円ステーブルコイン)専用 の決済ウォレットです。 QRコードをスキャンするだけで送金できます。

できること

  • 📷 QRコードをスキャンして JPYC を送金
  • 📥 受取用 QR コード表示
  • 💰 金額指定の請求 QR 生成
  • ガスレス(POL 残高ゼロでも送金可)
  • 📲 PWA対応(ホーム画面にアプリとして追加可)

仕組み(ガスレスの仕組み)

通常の送金はユーザーがガス代(POL)を払う必要があります。このウォレットは EIP-3009 という仕組みで「署名だけ」で送金できます。

送金フロー

① ユーザーが MetaMask で署名だけする(無料)
↓ 署名データを送信
リレイヤー(Cloudflare Worker)が受け取る
↓ 運営ウォレットの POL でガスを払って送信
③ Polygon チェーンで JPYC が着金

使用技術

フロントエンド
Vanilla HTML/CSS/JS
ethers.js v6(ESM CDN)
qrcodejs(QR生成)
jsQR(QRスキャン)
WalletConnect v2
バックエンド
Cloudflare Pages Functions
ethers.js v6(リレイヤー)
Polygon RPC
JPYC v2 コントラクト
EIP-3009 transferWithAuthorization

作り方(AIへの頼み方)

Claude Code などの AI コーディングアシスタントに以下の手順で頼むと作れます。

  1. Cloudflare Pages のプロジェクトを用意
    無料プランで OK。静的サイトをデプロイできる環境があれば何でも可。
  2. AI に「JPYC ガスレスウォレットを作って」と頼む
    下の「AIへのプロンプト」セクションをコピペして使えます。
  3. リレイヤーウォレットを用意して POL を入金
    送金を中継するウォレットに少量の POL(数百円分)を入れておく。1送金あたり約0.07円。
  4. Cloudflare の環境変数に秘密鍵を設定
    RELAYER_PRIVATE_KEY にリレイヤーウォレットの秘密鍵を登録。
  5. デプロイして完成
    wrangler pages deploy public --project-name YOUR_PROJECT --branch main

費用とランニングコスト

無料
Cloudflare Pages
ホスティング
無料
WalletConnect
Project ID
〜0.07円/件
Polygon ガス代
(リレイヤー負担)

月1,000回送金しても 約70円。リレイヤーウォレットへの POL 補充は不定期で OK。


注意点・セキュリティ

⚠️ 秘密鍵の管理

リレイヤーウォレットの秘密鍵は Cloudflare の環境変数(シークレット)に保管します。 絶対にコードや Git にコミットしないこと。リレイヤーウォレットには必要最小限の POL だけ入れておくこと。

⚠️ JPYC コントラクトアドレスの確認

このウォレットで使用している JPYC アドレスは 0xE7C3D8C9a439feDe00D2600032D5dB0Be71C3c29(Polygon PoS)です。 公式サイト jpyc.co.jp で必ず確認してください。

⚠️ EIP-3009 の domain 名

署名時の EIP-712 domain name は "JPY Coin"、version は "1" です。 コントラクトアドレスが変わると domain も変わる可能性があるため、変更時は必ず確認してください。

スパム・悪用対策

  • リレイヤーに送金上限を設ける(デフォルト: 1億 JPYC)
  • nonce の使用済みチェック(二重送金防止)
  • validBefore による有効期限チェック(デフォルト: 30分)
  • リレイヤー残高監視(不足時は 503 を返す)

AIへのプロンプト(コピペ用)

Claude Code や ChatGPT に以下をコピペすると同様のものを作れます。

基本プロンプト

Polygon チェーンの JPYC (0xE7C3D8C9a439feDe00D2600032D5dB0Be71C3c29) に特化した
ガスレス決済ウォレットをHTML/JS で作ってください。

要件:
- スマホ QR スキャンで送金(メイン機能)
- EIP-3009 transferWithAuthorization でオフチェーン署名
- Cloudflare Pages Functions でリレイヤー(/api/relay)
- MetaMask + WalletConnect v2 対応
- PWA 対応(ホーム画面に追加可能)
- ガスレス(ユーザーは POL 不要)
- リレイヤーウォレット: 0xYOUR_WALLET_ADDRESS
- WalletConnect Project ID: YOUR_PROJECT_ID

JPYC の EIP-712 domain:
  name: "JPY Coin", version: "1", chainId: 137

リレイヤー Worker のポイント

// functions/api/relay.js (Cloudflare Pages Functions)
import { ethers } from 'ethers';

export async function onRequestPost(context) {
  const { env, request } = context;
  const privKey = env.RELAYER_PRIVATE_KEY; // Cloudflare環境変数
  const body = await request.json();
  const { from, to, value, validAfter, validBefore, nonce, v, r, s } = body;

  const provider = new ethers.JsonRpcProvider('https://polygon-rpc.com');
  const relayer  = new ethers.Wallet(privKey, provider);
  const contract = new ethers.Contract(JPYC_ADDRESS, JPYC_ABI, relayer);

  const tx = await contract.transferWithAuthorization(
    from, to, value, validAfter, validBefore, nonce, v, r, s
  );
  return Response.json({ txHash: tx.hash });
}

フロントエンドの署名ロジック(EIP-3009)

// EIP-3009 署名(ethers.js v6)
const domain = {
  name: 'JPY Coin', version: '1',
  chainId: 137,
  verifyingContract: '0xE7C3D8C9a439feDe00D2600032D5dB0Be71C3c29'
};
const types = {
  TransferWithAuthorization: [
    { name: 'from',        type: 'address' },
    { name: 'to',          type: 'address' },
    { name: 'value',       type: 'uint256' },
    { name: 'validAfter',  type: 'uint256' },
    { name: 'validBefore', type: 'uint256' },
    { name: 'nonce',       type: 'bytes32'  },
  ]
};
const message = {
  from: account, to: recipientAddress,
  value: ethers.parseUnits(amount, 18),
  validAfter: 0,
  validBefore: Math.floor(Date.now() / 1000) + 1800, // 30分
  nonce: ethers.hexlify(ethers.randomBytes(32))
};
const sig = await signer.signTypedData(domain, types, message);
const { v, r, s } = ethers.Signature.from(sig);

QRコード形式

# 送金先アドレスのみ
0xE7C3D8C9a439feDe00D2600032D5dB0Be71C3c29

# 金額付き請求QR(jpyc: スキーム)
jpyc:0xE7C3D8C9a439feDe00D2600032D5dB0Be71C3c29?amount=1000

# URL パラメータでの受け渡し
https://cryptoninjaswap.com/wallettools/jpyc-wallet?to=0xADDR&amount=1000

🥷 JPYC Pay を使ってみる →