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 と同程度の速度で証明が完了する。
- https://developer.squareup.com/apps でアカウント作成
- アプリケーションを作成(または既存のものを使用)
- Sandbox タブから:
- Sandbox Access Token (
EAAAl...) をコピー - Sandbox Application ID をメモ
- Sandbox Access Token (
Sandbox Dashboard でテスト Payment Link を作成:
- https://squareupsandbox.com/dashboard → Payment Links
または 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'docker compose up -d
docker compose restart cashu-mint # 必要に応じて
docker compose psBLOSSOM_SERVERS=http://localhost:3333 \
NOSTR_RELAYS=ws://localhost:7777 \
CASHU_MINT_URL=http://localhost:3338 \
bun run devSQUARE_ACCESS_TOKEN=EAAAl... \
bun example/tlsn-fiat-swap-square/seller.tsこのターミナルは開いたままにする。
Payment Link を開いて支払いを完了する。
Sandbox テストカード:
- カード番号:
4532 7597 3454 5858 - 有効期限: 任意の未来の日付
- CVC:
111 - 郵便番号:
94103
# 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}'支払い後、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" }
}Square は ECDSA 証明書のため、CLI / Extension どちらでも ~2秒で完了する。
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
Chrome for Testing を起動:
bun run scripts/launch-chrome-tlsn.tsDevConsole (chrome-extension://<id>/devConsole.html) に以下を貼り付けて Run Code:
PAYMENT_ID と SQUARE_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を増やす。
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)\"}"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
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 |
| 項目 | 値 |
|---|---|
| ドメイン | 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 | Stripe | |
|---|---|---|
| ドメイン | connect.squareupsandbox.com | api.stripe.com |
| 証明書の鍵 | ECDSA (P-256) | RSA |
| MPC-TLS 時間 | 2.1秒 | ハング (>3分) |
| 推奨方式 | CLI (tlsn-prove) |
非推奨 (RSA ボトルネック) |