Skip to content

Latest commit

 

History

History
304 lines (238 loc) · 9.12 KB

File metadata and controls

304 lines (238 loc) · 9.12 KB

渡(Watari) — Runbook

Watari — a crossing or ferry. Here: trustless fiat ↔ BTC crossing via Square.

Square テスト決済を TLSNotary で証明し、Anchr 経由で BTC と trustless に交換する E2E 手順。

検証対象: Square Payments API (connect.squareupsandbox.com / connect.squareup.com) の JSON レスポンス 証明方式: CLI (tlsn-prove) — Square は ECDSA 証明書のため MPC-TLS が ~2秒で完了 (実測 2.1秒)

なぜ Square か: Stripe は RSA 証明書を使用しており、MPC-TLS の RSA 署名検証が非常に遅い(数分以上ハング)。Square は ECDSA (P-256) 証明書のため、CoinGecko と同程度の速度で証明が完了する。


0. 準備

0-1. Square Developer アカウント

  1. https://developer.squareup.com/apps でアカウント作成
  2. アプリケーションを作成(または既存のものを使用)
  3. Sandbox タブから:
    • Sandbox Access Token (EAAAl...) をコピー
    • Sandbox Application ID をメモ

0-2. Square Sandbox で Payment Link を作成

Sandbox Dashboard でテスト Payment Link を作成:

または API で作成:

curl -X POST https://connect.squareup.com/v2/online-checkout/payment-links \
  -H "Authorization: Bearer $SQUARE_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "quick_pay": {
      "name": "Test Payment",
      "price_money": { "amount": 100, "currency": "JPY" },
      "location_id": "'$SQUARE_LOCATION_ID'"
    }
  }' | jq '.payment_link.url'

1. インフラ起動

docker compose up -d
docker compose restart cashu-mint  # 必要に応じて
docker compose ps

2. Anchr サーバー起動

BLOSSOM_SERVERS=http://localhost:3333 \
NOSTR_RELAYS=ws://localhost:7777 \
CASHU_MINT_URL=http://localhost:3338 \
bun run dev

3. Seller: オーダー作成

SQUARE_ACCESS_TOKEN=EAAAl... \
bun example/tlsn-fiat-swap-square/seller.ts

このターミナルは開いたままにする。


4. Buyer: Square で支払い

方法 A: Payment Link で支払い

Payment Link を開いて支払いを完了する。

Sandbox テストカード:

  • カード番号: 4532 7597 3454 5858
  • 有効期限: 任意の未来の日付
  • CVC: 111
  • 郵便番号: 94103

方法 B: API でテスト決済を作成 (Sandbox)

# Location ID を取得
LOCATION_ID=$(curl -s https://connect.squareupsandbox.com/v2/locations \
  -H "Authorization: Bearer $SQUARE_ACCESS_TOKEN" | jq -r '.locations[0].id')

# テスト決済を作成 (card-nonce-ok = 成功するテストノンス)
curl -s -X POST https://connect.squareupsandbox.com/v2/payments \
  -H "Authorization: Bearer $SQUARE_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "source_id": "cnon:card-nonce-ok",
    "idempotency_key": "'$(uuidgen)'",
    "amount_money": { "amount": 100, "currency": "JPY" },
    "location_id": "'$LOCATION_ID'"
  }' | jq '{id: .payment.id, status: .payment.status, amount: .payment.amount_money}'

5. Payment ID を取得

支払い後、Square Dashboard または API から Payment ID を取得:

curl -s https://connect.squareupsandbox.com/v2/payments \
  -H "Authorization: Bearer $SQUARE_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"sort_order": "DESC", "limit": 1}' | jq '.payments[0] | {id, status, amount_money}'

期待される出力:

{
  "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "amount_money": { "amount": 100, "currency": "JPY" }
}

6. Buyer: TLSNotary proof 生成

Square は ECDSA 証明書のため、CLI / Extension どちらでも ~2秒で完了する。

6a. CLI (tlsn-prove)

PAYMENT_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"  # Step 5 で取得

./crates/tlsn-prover/target/release/tlsn-prove \
  --verifier localhost:7046 \
  --max-recv-data 4096 \
  --max-sent-data 4096 \
  -H "Authorization: Bearer $SQUARE_ACCESS_TOKEN" \
  "https://connect.squareupsandbox.com/v2/payments/$PAYMENT_ID" \
  -o proof.presentation.tlsn

期待される出力:

[tlsn-prove] Target: connect.squareupsandbox.com:443/v2/payments/...
[tlsn-prove] MPC limits: max_sent=4096, max_recv=4096
[tlsn-prove] MPC connection established
[tlsn-prove] Connected to connect.squareupsandbox.com:443
[tlsn-prove] Sending HTTP request...
[tlsn-prove] Response status: 200 OK
[tlsn-prove] MPC complete, requesting attestation...
[tlsn-prove] Presentation saved to proof.presentation.tlsn

6b. TLSNotary Extension (DevConsole)

Chrome for Testing を起動:

bun run scripts/launch-chrome-tlsn.ts

DevConsole (chrome-extension://<id>/devConsole.html) に以下を貼り付けて Run Code:

PAYMENT_IDSQUARE_KEY を実際の値に置き換える:

// Anchr: prove Square Payment status via API
const PAYMENT_ID = 'JYQNlEG29vRfsVibEeOiNMr25lbZY';  // ← Step 5 で取得した Payment ID
const SQUARE_KEY = 'EAAAl...';  // ← Seller から受け取った Square Access Token
const VERIFIER_URL = 'ws://localhost:7047';
const PROXY_URL = 'ws://localhost:7047/proxy?token=connect.squareupsandbox.com';

export default {
  config: {
    name: 'Anchr: Square API',
    description: 'Prove Square Payment status',
    requests: [{
      method: 'GET',
      host: 'connect.squareupsandbox.com',
      pathname: '/**',
      verifierUrl: VERIFIER_URL,
    }],
  },
  main: async () => {
    const proof = await prove(
      {
        url: `https://connect.squareupsandbox.com/v2/payments/${PAYMENT_ID}`,
        method: 'GET',
        headers: {
          'Host': 'connect.squareupsandbox.com',
          'Authorization': `Bearer ${SQUARE_KEY}`,
          'Accept': 'application/json',
          'Accept-Encoding': 'identity',
          'Connection': 'close',
        },
      },
      {
        verifierUrl: VERIFIER_URL,
        proxyUrl: PROXY_URL,
        maxRecvData: 4096,
        maxSentData: 4096,
        handlers: [
          { type: 'SENT', part: 'START_LINE', action: 'REVEAL' },
          { type: 'RECV', part: 'STATUS_CODE', action: 'REVEAL' },
          { type: 'RECV', part: 'BODY', action: 'REVEAL' },
          // Authorization ヘッダーは REVEAL しない → proof に API Key が含まれない
        ],
      }
    );

    try {
      await navigator.clipboard.writeText(JSON.stringify(proof));
      console.log('[Anchr] Proof copied to clipboard');
    } catch (e) {
      console.log('[Anchr] Proof:', JSON.stringify(proof).slice(0, 200));
    }

    done(proof);
  },
};

確認ポップアップ が表示されたら Allow をクリック。~2秒で完了。

レスポンスサイズの確認:

curl -s --http1.1 -o /dev/null -w 'headers: %{size_header}\nbody: %{size_download}\n' \
  -H "Authorization: Bearer $SQUARE_ACCESS_TOKEN" \
  -H "Accept: application/json" \
  -H "Accept-Encoding: identity" \
  -H "Connection: close" \
  "https://connect.squareupsandbox.com/v2/payments/$PAYMENT_ID"

headers + body の合計が 4096 を超える場合は --max-recv-data を増やす。


7. Buyer: proof を Anchr に提出

QUERY_ID="query_xxxxx"  # seller.ts の出力から

curl -X POST http://localhost:3000/queries/${QUERY_ID}/result \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${HTTP_API_KEY:-test}" \
  -d "{\"worker_pubkey\":\"buyer\",\"tlsn_presentation\":\"$(base64 < proof.presentation.tlsn)\"}"

8. 検証結果の確認

Seller 側 (Terminal):

Order completed!
  Status: approved
  Payment verified — BTC released to buyer
  Verification checks:
    ✓ cryptographically verified from connect.squareup.com
    ✓ server name matches target_url
    ✓ "status":"COMPLETED" condition satisfied

9. クリーンアップ

docker compose down

トラブルシューティング

問題 対処
Square API で 401 SQUARE_ACCESS_TOKEN が正しいか確認。Sandbox トークン (EAAAl...) を使う。Sandbox は connect.squareupsandbox.com (本番は connect.squareup.com)
Payment ID が分からない Step 5 の API コマンドで最新の payment を取得
レスポンスが 4096 を超える --max-recv-data 8192 に増やす (ECDSA なので 8192 でも数秒で完了)
MPC-TLS がハングする Square は ECDSA なので通常ハングしない。verifier を restart: docker compose restart tlsn-verifier

実測データ (2026-03-29)

項目
ドメイン connect.squareupsandbox.com
TLS 証明書 ECDSA (P-256)
レスポンスサイズ headers: 899, body: 1406, 合計: 2,305 bytes
max_recv_data 4096 (余裕: 1,791 bytes)
MPC-TLS 時間 2.1秒 (release ビルド)
Proof サイズ 6,289 bytes

Square vs Stripe: TLS 証明書の比較

Square Stripe
ドメイン connect.squareupsandbox.com api.stripe.com
証明書の鍵 ECDSA (P-256) RSA
MPC-TLS 時間 2.1秒 ハング (>3分)
推奨方式 CLI (tlsn-prove) 非推奨 (RSA ボトルネック)