-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuyer.ts
More file actions
105 lines (86 loc) · 4.32 KB
/
buyer.ts
File metadata and controls
105 lines (86 loc) · 4.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/**
* 渡(Watari) — Buyer (has fiat, wants BTC)
*
* Watari is the trustless fiat ↔ BTC crossing. The buyer:
* 1. Discovers open 渡(Watari) orders on the Anchr network
* 2. Pays via the seller's Square Payment Link
* 3. Receives the Square access token + Payment ID from the seller
* (via NIP-44 encrypted_context in the Nostr selection event)
* 4. Fetches the Payment status from Square API
* 5. Generates a TLSNotary proof of the JSON response
* 6. Submits the proof to Anchr to redeem escrowed BTC
*
* Square uses ECDSA TLS certificates, so MPC-TLS completes in ~2 seconds
* (unlike Stripe which uses RSA and hangs).
*
* Usage:
* bun run example/tlsn-fiat-swap-square/buyer.ts
*/
// Published package: import { Anchr } from "anchr-sdk";
import { Anchr } from "anchr-sdk";
import process from "node:process";
const SERVER_URL = process.env.ANCHR_SERVER_URL ?? "http://localhost:3000";
const anchr = new Anchr({ serverUrl: SERVER_URL });
console.log("=== 渡(Watari) — Buyer ===\n");
console.log(`Server: ${SERVER_URL}\n`);
// --- Step 1: Discover open 渡(Watari) orders ---
console.log("Step 1: Finding open 渡(Watari) orders...\n");
const orders = await anchr.listOpenQueries();
const watari = orders.find((o) => o.description.includes("Square payment"));
if (!watari) {
console.log("No open 渡(Watari) orders found.");
console.log("Run seller.ts first to create one.");
process.exit(0);
}
console.log(`Found order: ${watari.id}`);
console.log(` Description: ${watari.description}`);
console.log(` Bounty: ${watari.bounty?.amount_sats ?? 0} sats`);
if (watari.tlsn_requirements) {
const domain = watari.tlsn_requirements.domain_hint ?? watari.tlsn_requirements.target_url;
console.log(` Domain: ${domain}`);
if (watari.tlsn_requirements.conditions) {
console.log(" Conditions:");
for (const cond of watari.tlsn_requirements.conditions) {
console.log(` - [${cond.type}] "${cond.expression}" — ${cond.description ?? ""}`);
}
}
}
// --- Step 2: Pay via Square ---
console.log("\n--- Step 2: Pay via Square ---\n");
console.log("Open the seller's Square Payment Link and complete the payment.\n");
// --- Step 3: TLSNotary proof of Square API ---
console.log("--- Step 3: Generate TLSNotary Proof ---\n");
console.log("After the seller shares the Square access token and Payment ID");
console.log("(via NIP-44 encrypted_context), prove the Payment status:\n");
console.log(" Target URL: https://connect.squareupsandbox.com/v2/payments/{payment_id}");
console.log(" Header: Authorization: Bearer {access_token}");
console.log();
console.log("The TLSNotary proof captures the JSON response from connect.squareupsandbox.com:");
console.log(' { "payment": { "status": "COMPLETED", "amount_money": { ... } } }');
console.log();
console.log("The proof cryptographically verifies:");
console.log(" 1. Domain: connect.squareupsandbox.com (from TLS certificate, ECDSA)");
console.log(' 2. Body contains: "status":"COMPLETED"');
console.log(" 3. Attestation is fresh (< max_attestation_age_seconds)");
// --- Step 4: Submit proof ---
console.log("\n--- Step 4: Submit Proof ---\n");
// Square uses ECDSA → both CLI and Extension work in ~2s
console.log("=== Method A: CLI (tlsn-prove) ===\n");
console.log(" tlsn-prove \\");
console.log(' --verifier localhost:7046 \\');
console.log(' -H "Authorization: Bearer $SQUARE_ACCESS_TOKEN" \\');
console.log(' "https://connect.squareupsandbox.com/v2/payments/$PAYMENT_ID" \\');
console.log(" -o proof.presentation.tlsn\n");
console.log("=== Method B: TLSNotary Extension (DevConsole) ===\n");
console.log(" 1. bun run scripts/launch-chrome-tlsn.ts");
console.log(" 2. Open DevConsole → paste plugin code from RUNBOOK Step 6b");
console.log(" 3. Run Code → Allow → proof copied to clipboard\n");
console.log("=== Submit to Anchr ===\n");
console.log(` curl -X POST ${SERVER_URL}/queries/${watari.id}/result \\`);
console.log(' -H "Content-Type: application/json" \\');
console.log(' -d \'{"worker_pubkey": "<your-pubkey>", "tlsn_presentation": "<base64-of-proof>"}\'');
console.log();
console.log("After successful verification:");
console.log(" - Oracle releases HTLC preimage");
console.log(" - Buyer redeems Cashu HTLC token with preimage + signature");
console.log(` - ${watari.bounty?.amount_sats ?? "100,000"} sats transferred trustlessly`);