@payclaw/badge 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +68 -2
  2. package/dist/api/client.js +1 -1
  3. package/dist/api/client.js.map +1 -1
  4. package/dist/index.d.ts +1 -1
  5. package/dist/index.js +24 -11
  6. package/dist/index.js.map +1 -1
  7. package/dist/lib/device-auth.js +11 -3
  8. package/dist/lib/device-auth.js.map +1 -1
  9. package/dist/lib/parse-outcome.js +1 -0
  10. package/dist/lib/parse-outcome.js.map +1 -1
  11. package/dist/lib/report-badge-presented-handler.d.ts +7 -1
  12. package/dist/lib/report-badge-presented-handler.js +13 -2
  13. package/dist/lib/report-badge-presented-handler.js.map +1 -1
  14. package/dist/lib/report-badge.d.ts +1 -1
  15. package/dist/lib/report-badge.js +3 -1
  16. package/dist/lib/report-badge.js.map +1 -1
  17. package/dist/lib/storage.d.ts +5 -0
  18. package/dist/lib/storage.js +28 -0
  19. package/dist/lib/storage.js.map +1 -1
  20. package/dist/lib/ucp-manifest.d.ts +32 -0
  21. package/dist/lib/ucp-manifest.js +117 -0
  22. package/dist/lib/ucp-manifest.js.map +1 -0
  23. package/dist/lib/ucp-manifest.test.d.ts +1 -0
  24. package/dist/lib/ucp-manifest.test.js +92 -0
  25. package/dist/lib/ucp-manifest.test.js.map +1 -0
  26. package/dist/sampling.d.ts +4 -0
  27. package/dist/sampling.js +43 -6
  28. package/dist/sampling.js.map +1 -1
  29. package/dist/sampling.test.d.ts +1 -0
  30. package/dist/sampling.test.js +150 -0
  31. package/dist/sampling.test.js.map +1 -0
  32. package/dist/tools/getAgentIdentity.d.ts +9 -1
  33. package/dist/tools/getAgentIdentity.js +67 -10
  34. package/dist/tools/getAgentIdentity.js.map +1 -1
  35. package/dist/verify.d.ts +34 -0
  36. package/dist/verify.js +161 -0
  37. package/dist/verify.js.map +1 -0
  38. package/dist/verify.test.d.ts +1 -0
  39. package/dist/verify.test.js +177 -0
  40. package/dist/verify.test.js.map +1 -0
  41. package/package.json +7 -3
package/README.md CHANGED
@@ -17,7 +17,7 @@ Add to your MCP client config:
17
17
  "command": "npx",
18
18
  "args": ["-y", "@payclaw/badge"],
19
19
  "env": {
20
- "PAYCLAW_API_URL": "https://api.payclaw.io"
20
+ "PAYCLAW_API_URL": "https://payclaw.io"
21
21
  }
22
22
  }
23
23
  }
@@ -64,6 +64,8 @@ The agent presents this disclosure to merchants. Merchants see a verified identi
64
64
 
65
65
  ## How It Works
66
66
 
67
+ ### First use (device auth)
68
+
67
69
  ```
68
70
  1. Your agent calls payclaw_getAgentIdentity
69
71
  2. No key? Device auth flow triggers — code + URL appear in terminal
@@ -72,7 +74,31 @@ The agent presents this disclosure to merchants. Merchants see a verified identi
72
74
  5. Every subsequent call uses the stored key automatically
73
75
  ```
74
76
 
75
- No card is issued. No money moves. Badge is the identity layer — the credential that lets authorized agents through while bot defenses stay intact.
77
+ ### UCP-aware identity (with merchantUrl)
78
+
79
+ ```
80
+ 1. Agent calls payclaw_getAgentIdentity({ merchantUrl: 'https://store.com' })
81
+ 2. PayClaw fetches store.com/.well-known/ucp manifest
82
+ 3. If merchant declares io.payclaw.common.identity → returns checkoutPatch
83
+ 4. Agent merges checkoutPatch into checkout payload
84
+ 5. Agent calls payclaw_reportBadgePresented({ merchantUrl, verification_token })
85
+ 6. Merchant calls verify(token) → gets PayClawIdentity
86
+ ```
87
+
88
+ If the merchant doesn't support UCP, a valid token is still returned — nothing breaks. No card is issued. No money moves. Badge is the identity layer — the credential that lets authorized agents through while bot defenses stay intact.
89
+
90
+ ### Extended Auth (optional)
91
+
92
+ When enabled, PayClaw checks back with your agent 7 seconds after badge presentation to confirm whether the merchant accepted or denied. Results are logged to your dashboard.
93
+
94
+ ```json
95
+ "env": {
96
+ "PAYCLAW_API_URL": "https://payclaw.io",
97
+ "PAYCLAW_EXTENDED_AUTH": "true"
98
+ }
99
+ ```
100
+
101
+ Without it, your agent reports outcomes via `payclaw_reportBadgeOutcome` when it knows the result.
76
102
 
77
103
  ## Tools
78
104
 
@@ -80,6 +106,46 @@ No card is issued. No money moves. Badge is the identity layer — the credentia
80
106
  |------|-------------|
81
107
  | `payclaw_getAgentIdentity` | Declare identity, get UCP-compatible verification token |
82
108
  | `payclaw_reportBadgePresented` | Signal that you presented your Badge to a merchant |
109
+ | `payclaw_reportBadgeOutcome` | Report whether merchant accepted or denied the badge |
110
+ | `payclaw_reportBadgeNotPresented` | Report that the badge was not presented |
111
+
112
+ ## For Merchants: Verify a Badge
113
+
114
+ Badge is the package merchants install for local JWT verification — no API call to PayClaw, no uptime dependency.
115
+
116
+ ```bash
117
+ npm install @payclaw/badge
118
+ ```
119
+
120
+ ```typescript
121
+ import { verify } from '@payclaw/badge/verify'
122
+
123
+ const identity = await verify(req.body['io.payclaw.common.identity']?.token)
124
+
125
+ if (identity) {
126
+ // Verified — identity.userId, identity.agentId, identity.scopes, etc.
127
+ // Apply tier pricing, skip CAPTCHAs, fast-track checkout
128
+ }
129
+ // null = no badge or invalid — proceed as guest
130
+ ```
131
+
132
+ `verify()` fetches PayClaw's JWKS once, caches for 1 hour, and verifies the ES256 signature locally via Web Crypto API. Zero runtime dependencies. Works in Node.js 18+ and Cloudflare Workers. Never throws — returns `null` on any error.
133
+
134
+ Full verification docs + Python example: [github.com/payclaw/ucp-agent-badge](https://github.com/payclaw/ucp-agent-badge#merchant-verification)
135
+
136
+ ---
137
+
138
+ ## What's New (v0.8.0)
139
+
140
+ | Capability | Description |
141
+ |---|---|
142
+ | `verify()` export | Merchant-side JWT verification — `import { verify } from '@payclaw/badge/verify'`. Zero dependencies, Web Crypto only. |
143
+ | UCP-aware `getAgentIdentity` | Pass `merchantUrl` — fetches merchant manifest, returns `checkoutPatch` when `io.payclaw.common.identity` is declared |
144
+ | `reportBadgePresented` with `merchantUrl` | Preferred over `merchant`; includes optional `checkoutSessionId` for UCP session tracking |
145
+ | SSRF-protected manifest fetcher | HTTPS-only, private IP blocking, 5-minute domain cache |
146
+ | Trip lifecycle hardening | `onServerClose` resolves as `inconclusive`; orphan token recovery on restart |
147
+
148
+ ---
83
149
 
84
150
  ## Need Payment Too?
85
151
 
@@ -78,7 +78,7 @@ export async function getAgentIdentity(sessionId, merchant) {
78
78
  });
79
79
  }
80
80
  export function isApiMode() {
81
- return !!process.env.PAYCLAW_API_URL;
81
+ return !!process.env.PAYCLAW_API_URL || !!getStoredConsentKey();
82
82
  }
83
83
  /** Base URL for API calls. Defaults to https://payclaw.io. Validates HTTPS for token safety. */
84
84
  export function getBaseUrl() {
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- export {};
2
+ export { verify, type PayClawIdentity, type VerifyOptions } from "./verify.js";
package/dist/index.js CHANGED
@@ -6,9 +6,10 @@ import { getAgentIdentity, formatIdentityResponse } from "./tools/getAgentIdenti
6
6
  import { initSampling, onTripStarted, onServerClose, reportOutcomeFromAgent, } from "./sampling.js";
7
7
  import { handleReportBadgePresented } from "./lib/report-badge-presented-handler.js";
8
8
  import { reportBadgeNotPresented } from "./lib/report-badge.js";
9
+ import { getAuthMode } from "./lib/storage.js";
9
10
  const server = new McpServer({
10
11
  name: "payclaw-badge",
11
- version: "0.7.0",
12
+ version: "0.8.0",
12
13
  });
13
14
  server.tool("payclaw_getAgentIdentity", `You are an authorized actor, not a bot. Prove it before you shop.
14
15
 
@@ -20,8 +21,9 @@ When a merchant challenges you, present the agent_disclosure text from the respo
20
21
 
21
22
  No card is issued. No money moves. For payment, use payclaw_getCard from @payclaw/mcp-server (which includes Badge automatically).`, {
22
23
  merchant: z.string().max(200).optional().describe("The merchant or website the agent intends to visit (e.g., 'starbucks.com', 'Instacart')"),
23
- }, async ({ merchant }) => {
24
- const result = await getAgentIdentity(merchant);
24
+ merchantUrl: z.string().max(500).optional().describe("Merchant base URL (e.g., 'https://starbucks.com'). When provided, PayClaw checks if the merchant supports UCP identity and generates a checkout patch."),
25
+ }, async ({ merchant, merchantUrl }) => {
26
+ const result = await getAgentIdentity(merchant, merchantUrl);
25
27
  // Track trip start for sampling (DQ-54)
26
28
  if (result.verification_token) {
27
29
  onTripStarted(result.verification_token, merchant || "unknown");
@@ -36,20 +38,26 @@ No card is issued. No money moves. For payment, use payclaw_getCard from @paycla
36
38
  ],
37
39
  };
38
40
  });
39
- server.tool("payclaw_reportBadgePresented", `Report that you are about to present your PayClaw Badge to a merchant.
40
-
41
- Call this AFTER payclaw_getAgentIdentity and BEFORE including the badge token in a
42
- merchant request. This tells PayClaw you are actively using your badge at a specific
43
- merchant — it starts the outcome tracking window and logs the presentation event.
41
+ server.tool("payclaw_reportBadgePresented", `Report that you presented your PayClaw Badge to a merchant. Call this immediately after merging the checkoutPatch into a checkout payload. Required for PayClaw to record the trip.
44
42
 
45
43
  When Extended Auth is enabled, PayClaw checks back 7 seconds later. Otherwise, call payclaw_reportBadgeOutcome when you know the result.`, {
46
44
  verification_token: z.string().describe("The verification_token returned by payclaw_getAgentIdentity"),
47
- merchant: z.string().max(200).describe("The merchant or website where you are presenting the badge (e.g., 'starbucks.com')"),
45
+ merchant: z.string().max(200).optional().describe("The merchant name (e.g., 'starbucks.com'). Provide merchantUrl or merchant."),
46
+ merchantUrl: z.string().max(500).optional().describe("The merchant base URL (e.g., 'https://starbucks.com'). Preferred over merchant."),
48
47
  context: z
49
48
  .enum(["arrival", "addtocart", "checkout", "other"])
50
49
  .optional()
51
- .describe("Optional: when Extended Auth is enabled, in what state you presented (arrival, addtocart, checkout, other)"),
52
- }, async ({ verification_token, merchant, context }) => handleReportBadgePresented(verification_token, merchant, context));
50
+ .describe("Optional: in what state you presented (arrival, addtocart, checkout, other)"),
51
+ checkoutSessionId: z.string().optional().describe("UCP checkout session ID if available"),
52
+ }, async ({ verification_token, merchant, merchantUrl, context, checkoutSessionId }) => {
53
+ const resolvedMerchant = merchantUrl || merchant;
54
+ if (!resolvedMerchant) {
55
+ return {
56
+ content: [{ type: "text", text: "✗ Error: merchantUrl or merchant is required." }],
57
+ };
58
+ }
59
+ return handleReportBadgePresented(verification_token, resolvedMerchant, context, checkoutSessionId);
60
+ });
53
61
  server.tool("payclaw_reportBadgeOutcome", `Report how the merchant responded when you presented your PayClaw Badge.
54
62
 
55
63
  Call this after payclaw_reportBadgePresented when you know whether the merchant accepted or denied you. Use when Extended Auth is disabled, or to report earlier than the 7-second check.`, {
@@ -99,9 +107,14 @@ async function main() {
99
107
  process.exit(0);
100
108
  });
101
109
  process.stderr.write("PayClaw Badge server running on stdio\n");
110
+ if (process.env.VITEST !== "true") {
111
+ process.stderr.write(`[PayClaw] Auth: ${getAuthMode()}\n`);
112
+ }
102
113
  }
103
114
  main().catch((err) => {
104
115
  process.stderr.write(`Fatal error: ${err}\n`);
105
116
  process.exit(1);
106
117
  });
118
+ // Re-export verify for merchant-side use: import { verify } from '@payclaw/badge'
119
+ export { verify } from "./verify.js";
107
120
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACvF,OAAO,EACL,YAAY,EACZ,aAAa,EAEb,aAAa,EACb,sBAAsB,GACvB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,0BAA0B,EAAE,MAAM,yCAAyC,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,eAAe;IACrB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,MAAM,CAAC,IAAI,CACT,0BAA0B,EAC1B;;;;;;;;mIAQiI,EACjI;IACE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAC/C,yFAAyF,CAC1F;IACD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAClD,wJAAwJ,CACzJ;CACF,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,EAAE;IAClC,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAE7D,wCAAwC;IACxC,IAAI,MAAM,CAAC,kBAAkB,EAAE,CAAC;QAC9B,aAAa,CAAC,MAAM,CAAC,kBAAkB,EAAE,QAAQ,IAAI,SAAS,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,SAAS,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAEjD,yDAAyD;IACzD,MAAM,EAAE,mBAAmB,EAAE,CAAC,EAAE,GAAG,YAAY,EAAE,GAAG,MAAM,CAAC;IAE3D,OAAO;QACL,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE;YACjC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;SAC1E;KACF,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,MAAM,CAAC,IAAI,CACT,8BAA8B,EAC9B;;yIAEuI,EACvI;IACE,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CACrC,6DAA6D,CAC9D;IACD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAC/C,6EAA6E,CAC9E;IACD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAClD,iFAAiF,CAClF;IACD,OAAO,EAAE,CAAC;SACP,IAAI,CAAC,CAAC,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;SACnD,QAAQ,EAAE;SACV,QAAQ,CACP,6EAA6E,CAC9E;IACH,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAC/C,sCAAsC,CACvC;CACF,EACD,KAAK,EAAE,EAAE,kBAAkB,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,iBAAiB,EAAE,EAAE,EAAE;IAClF,MAAM,gBAAgB,GAAG,WAAW,IAAI,QAAQ,CAAC;IACjD,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,+CAA+C,EAAE,CAAC;SAC5F,CAAC;IACJ,CAAC;IACD,OAAO,0BAA0B,CAAC,kBAAkB,EAAE,gBAAgB,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC;AACtG,CAAC,CACF,CAAC;AAEF,MAAM,CAAC,IAAI,CACT,4BAA4B,EAC5B;;0LAEwL,EACxL;IACE,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CACrC,6DAA6D,CAC9D;IACD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CACpC,0DAA0D,CAC3D;IACD,OAAO,EAAE,CAAC;SACP,IAAI,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC;SAC5C,QAAQ,CACP,uGAAuG,CACxG;CACJ,EACD,KAAK,EAAE,EAAE,kBAAkB,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE;IAClD,sBAAsB,CAAC,kBAAkB,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9D,OAAO;QACL,OAAO,EAAE,CAAC;gBACR,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,uBAAuB,OAAO,OAAO,QAAQ,EAAE;aACtD,CAAC;KACH,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,MAAM,CAAC,IAAI,CACT,iCAAiC,EACjC;;yGAEuG,EACvG;IACE,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CACrC,sDAAsD,CACvD;IACD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CACpC,gEAAgE,CACjE;IACD,MAAM,EAAE,CAAC;SACN,IAAI,CAAC,CAAC,WAAW,EAAE,oBAAoB,EAAE,OAAO,CAAC,CAAC;SAClD,QAAQ,CAAC,+DAA+D,CAAC;CAC7E,EACD,KAAK,EAAE,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE;IACjD,MAAM,uBAAuB,CAAC,kBAAkB,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACpE,OAAO;QACL,OAAO,EAAE,CAAC;gBACR,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,+BAA+B,QAAQ,KAAK,MAAM,GAAG;aAC5D,CAAC;KACH,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,+CAA+C;IAC/C,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAE5B,wBAAwB;IACxB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,aAAa,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;QACzB,aAAa,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAChE,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,WAAW,EAAE,IAAI,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,kFAAkF;AAClF,OAAO,EAAE,MAAM,EAA4C,MAAM,aAAa,CAAC"}
@@ -1,3 +1,4 @@
1
+ // Canonical: badge-server | Synced: 0.7.3 | Do not edit in mcp-server
1
2
  import { storeConsentKey } from "./storage.js";
2
3
  const DEFAULT_API_URL = "https://payclaw.io";
3
4
  const FETCH_TIMEOUT_MS = 10_000;
@@ -5,8 +6,15 @@ function getBaseUrl() {
5
6
  const url = process.env.PAYCLAW_API_URL;
6
7
  if (url && url.trim().length > 0) {
7
8
  const trimmed = url.trim().replace(/\/+$/, "");
8
- if (trimmed.startsWith("https://") || trimmed.startsWith("http://localhost")) {
9
- return trimmed;
9
+ try {
10
+ const parsed = new URL(trimmed);
11
+ const isLoopback = ["localhost", "127.0.0.1", "::1"].includes(parsed.hostname);
12
+ if (parsed.protocol === "https:" || (parsed.protocol === "http:" && isLoopback)) {
13
+ return trimmed;
14
+ }
15
+ }
16
+ catch {
17
+ // fall through to DEFAULT_API_URL
10
18
  }
11
19
  }
12
20
  return DEFAULT_API_URL;
@@ -44,7 +52,7 @@ export async function initiateDeviceAuth() {
44
52
  throw new Error("Invalid device auth response");
45
53
  }
46
54
  const interval = Math.max(1, Number(data.interval) || 5);
47
- const expiresIn = Number(data.expires_in) || 600;
55
+ const expiresIn = Math.max(1, Number(data.expires_in) || 600);
48
56
  return { ...data, interval, expires_in: expiresIn };
49
57
  }
50
58
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"device-auth.js","sourceRoot":"","sources":["../../src/lib/device-auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"device-auth.js","sourceRoot":"","sources":["../../src/lib/device-auth.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ // Canonical: badge-server | Synced: 0.7.3 | Do not edit in mcp-server
1
2
  /**
2
3
  * Parse agent response to sampling prompt into outcome bucket.
3
4
  * Extracted for testability (BUG-01.1). Synced from mcp-server.
@@ -1 +1 @@
1
- {"version":3,"file":"parse-outcome.js","sourceRoot":"","sources":["../../src/lib/parse-outcome.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,eAAe,GAAG;IACtB,KAAK;IACL,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,KAAK;IACL,OAAO;IACP,UAAU;IACV,QAAQ;IACR,WAAW;IACX,SAAS;IACT,SAAS;CACV,CAAC;AAEF,MAAM,UAAU,aAAa,CAC3B,IAAY;IAEZ,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,cAAc,CAAC;IAE7D,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IAExC,kEAAkE;IAClE,IAAI,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC;QACjE,OAAO,UAAU,CAAC;IAEpB,uFAAuF;IACvF,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACjD,IAAI,UAAU,KAAK,WAAW;QAAE,OAAO,cAAc,CAAC;IAEtD,oFAAoF;IACpF,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAAE,OAAO,QAAQ,CAAC;IAEpE,uFAAuF;IACvF,IAAI,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,UAAU,CAAC;IAEvD,OAAO,cAAc,CAAC;AACxB,CAAC"}
1
+ {"version":3,"file":"parse-outcome.js","sourceRoot":"","sources":["../../src/lib/parse-outcome.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE;;;GAGG;AAEH,MAAM,eAAe,GAAG;IACtB,KAAK;IACL,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,KAAK;IACL,OAAO;IACP,UAAU;IACV,QAAQ;IACR,WAAW;IACX,SAAS;IACT,SAAS;CACV,CAAC;AAEF,MAAM,UAAU,aAAa,CAC3B,IAAY;IAEZ,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,cAAc,CAAC;IAE7D,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IAExC,kEAAkE;IAClE,IAAI,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC;QACjE,OAAO,UAAU,CAAC;IAEpB,uFAAuF;IACvF,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACjD,IAAI,UAAU,KAAK,WAAW;QAAE,OAAO,cAAc,CAAC;IAEtD,oFAAoF;IACpF,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAAE,OAAO,QAAQ,CAAC;IAEpE,uFAAuF;IACvF,IAAI,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,UAAU,CAAC;IAEvD,OAAO,cAAc,CAAC;AACxB,CAAC"}
@@ -2,7 +2,13 @@
2
2
  * Handler for payclaw_reportBadgePresented tool.
3
3
  * Extracted for testability (BUG-01.1 integration tests).
4
4
  */
5
- export declare function handleReportBadgePresented(verification_token: string, merchant: string, context?: "arrival" | "addtocart" | "checkout" | "other"): Promise<{
5
+ /**
6
+ * Idempotency (duplicate row prevention) and expired-token status
7
+ * (`status: 'expired_presentation'`) are enforced by the API server,
8
+ * not here. The MCP server is stateless — it has no DB access and
9
+ * cannot check trip_id uniqueness or decode token expiry authoritatively.
10
+ */
11
+ export declare function handleReportBadgePresented(verification_token: string, merchant: string, context?: "arrival" | "addtocart" | "checkout" | "other", checkoutSessionId?: string): Promise<{
6
12
  content: Array<{
7
13
  type: "text";
8
14
  text: string;
@@ -1,14 +1,25 @@
1
+ // Canonical: badge-server | Synced: 0.7.3 | Do not edit in mcp-server
1
2
  /**
2
3
  * Handler for payclaw_reportBadgePresented tool.
3
4
  * Extracted for testability (BUG-01.1 integration tests).
4
5
  */
5
6
  import { onIdentityPresented } from "../sampling.js";
6
7
  import { reportBadgePresented } from "./report-badge.js";
7
- export async function handleReportBadgePresented(verification_token, merchant, context) {
8
+ /**
9
+ * Idempotency (duplicate row prevention) and expired-token status
10
+ * (`status: 'expired_presentation'`) are enforced by the API server,
11
+ * not here. The MCP server is stateless — it has no DB access and
12
+ * cannot check trip_id uniqueness or decode token expiry authoritatively.
13
+ */
14
+ export async function handleReportBadgePresented(verification_token, merchant, context, checkoutSessionId) {
8
15
  onIdentityPresented(verification_token, merchant);
9
- await reportBadgePresented(verification_token, merchant, context);
16
+ await reportBadgePresented(verification_token, merchant, context, checkoutSessionId);
10
17
  return {
11
18
  content: [
19
+ {
20
+ type: "text",
21
+ text: JSON.stringify({ recorded: true }),
22
+ },
12
23
  {
13
24
  type: "text",
14
25
  text: [
@@ -1 +1 @@
1
- {"version":3,"file":"report-badge-presented-handler.js","sourceRoot":"","sources":["../../src/lib/report-badge-presented-handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,kBAA0B,EAC1B,QAAgB,EAChB,OAAwD;IAExD,mBAAmB,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC;IAClD,MAAM,oBAAoB,CAAC,kBAAkB,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAClE,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE;oBACJ,kCAAkC,QAAQ,EAAE;oBAC5C,EAAE;oBACF,eAAe,kBAAkB,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI;oBAClD,eAAe,QAAQ,EAAE;oBACzB,iDAAiD;oBACjD,EAAE;oBACF,2DAA2D;oBAC3D,2BAA2B,kBAAkB,EAAE;iBAChD,CAAC,IAAI,CAAC,IAAI,CAAC;aACb;SACF;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"report-badge-presented-handler.js","sourceRoot":"","sources":["../../src/lib/report-badge-presented-handler.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE;;;GAGG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,kBAA0B,EAC1B,QAAgB,EAChB,OAAwD,EACxD,iBAA0B;IAE1B,mBAAmB,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC;IAClD,MAAM,oBAAoB,CAAC,kBAAkB,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC;IACrF,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;aACzC;YACD;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE;oBACJ,kCAAkC,QAAQ,EAAE;oBAC5C,EAAE;oBACF,eAAe,kBAAkB,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI;oBAClD,eAAe,QAAQ,EAAE;oBACzB,iDAAiD;oBACjD,EAAE;oBACF,2DAA2D;oBAC3D,2BAA2B,kBAAkB,EAAE;iBAChD,CAAC,IAAI,CAAC,IAAI,CAAC;aACb;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -3,5 +3,5 @@
3
3
  * Uses getStoredConsentKey for OAuth users; PAYCLAW_API_KEY for legacy.
4
4
  * Synced from mcp-server (BUG-01.1).
5
5
  */
6
- export declare function reportBadgePresented(verificationToken: string, merchant: string, context?: "arrival" | "addtocart" | "checkout" | "other"): Promise<void>;
6
+ export declare function reportBadgePresented(verificationToken: string, merchant: string, context?: "arrival" | "addtocart" | "checkout" | "other", checkoutSessionId?: string): Promise<void>;
7
7
  export declare function reportBadgeNotPresented(verificationToken: string, merchant: string, reason: "abandoned" | "merchant_didnt_ask" | "other"): Promise<void>;
@@ -1,3 +1,4 @@
1
+ // Canonical: badge-server | Synced: 0.7.3 | Do not edit in mcp-server
1
2
  /**
2
3
  * POST identity_presented to /api/badge/report.
3
4
  * Uses getStoredConsentKey for OAuth users; PAYCLAW_API_KEY for legacy.
@@ -5,7 +6,7 @@
5
6
  */
6
7
  import { getStoredConsentKey } from "./storage.js";
7
8
  const DEFAULT_API_URL = "https://payclaw.io";
8
- export async function reportBadgePresented(verificationToken, merchant, context) {
9
+ export async function reportBadgePresented(verificationToken, merchant, context, checkoutSessionId) {
9
10
  const apiUrl = process.env.PAYCLAW_API_URL || DEFAULT_API_URL;
10
11
  const key = getStoredConsentKey();
11
12
  if (!key)
@@ -22,6 +23,7 @@ export async function reportBadgePresented(verificationToken, merchant, context)
22
23
  event_type: "identity_presented",
23
24
  merchant,
24
25
  ...(context && { presentation_context: context }),
26
+ ...(checkoutSessionId && { checkout_session_id: checkoutSessionId }),
25
27
  }),
26
28
  });
27
29
  if (!res.ok) {
@@ -1 +1 @@
1
- {"version":3,"file":"report-badge.js","sourceRoot":"","sources":["../../src/lib/report-badge.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,iBAAyB,EACzB,QAAgB,EAChB,OAAwD;IAExD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,eAAe,CAAC;IAC9D,MAAM,GAAG,GAAG,mBAAmB,EAAE,CAAC;IAClC,IAAI,CAAC,GAAG;QAAE,OAAO;IAEjB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,mBAAmB,EAAE;YACpD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,GAAG,EAAE;gBAC9B,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,kBAAkB,EAAE,iBAAiB;gBACrC,UAAU,EAAE,oBAAoB;gBAChC,QAAQ;gBACR,GAAG,CAAC,OAAO,IAAI,EAAE,oBAAoB,EAAE,OAAO,EAAE,CAAC;aAClD,CAAC;SACH,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAC9C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,wCAAwC,GAAG,CAAC,MAAM,MAAM,IAAI,IAAI,CACjE,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,qBAAqB;IACvB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,iBAAyB,EACzB,QAAgB,EAChB,MAAoD;IAEpD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,eAAe,CAAC;IAC9D,MAAM,GAAG,GAAG,mBAAmB,EAAE,CAAC;IAClC,IAAI,CAAC,GAAG;QAAE,OAAO;IAEjB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,mBAAmB,EAAE;YACpD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,GAAG,EAAE;gBAC9B,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,kBAAkB,EAAE,iBAAiB;gBACrC,UAAU,EAAE,qBAAqB;gBACjC,QAAQ;gBACR,MAAM;aACP,CAAC;SACH,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAC9C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,2CAA2C,GAAG,CAAC,MAAM,MAAM,IAAI,IAAI,CACpE,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,qBAAqB;IACvB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"report-badge.js","sourceRoot":"","sources":["../../src/lib/report-badge.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE;;;;GAIG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,iBAAyB,EACzB,QAAgB,EAChB,OAAwD,EACxD,iBAA0B;IAE1B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,eAAe,CAAC;IAC9D,MAAM,GAAG,GAAG,mBAAmB,EAAE,CAAC;IAClC,IAAI,CAAC,GAAG;QAAE,OAAO;IAEjB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,mBAAmB,EAAE;YACpD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,GAAG,EAAE;gBAC9B,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,kBAAkB,EAAE,iBAAiB;gBACrC,UAAU,EAAE,oBAAoB;gBAChC,QAAQ;gBACR,GAAG,CAAC,OAAO,IAAI,EAAE,oBAAoB,EAAE,OAAO,EAAE,CAAC;gBACjD,GAAG,CAAC,iBAAiB,IAAI,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,CAAC;aACrE,CAAC;SACH,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAC9C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,wCAAwC,GAAG,CAAC,MAAM,MAAM,IAAI,IAAI,CACjE,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,qBAAqB;IACvB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,iBAAyB,EACzB,QAAgB,EAChB,MAAoD;IAEpD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,eAAe,CAAC;IAC9D,MAAM,GAAG,GAAG,mBAAmB,EAAE,CAAC;IAClC,IAAI,CAAC,GAAG;QAAE,OAAO;IAEjB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,mBAAmB,EAAE;YACpD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,GAAG,EAAE;gBAC9B,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,kBAAkB,EAAE,iBAAiB;gBACrC,UAAU,EAAE,qBAAqB;gBACjC,QAAQ;gBACR,MAAM;aACP,CAAC;SACH,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAC9C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,2CAA2C,GAAG,CAAC,MAAM,MAAM,IAAI,IAAI,CACpE,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,qBAAqB;IACvB,CAAC;AACH,CAAC"}
@@ -5,6 +5,11 @@
5
5
  * 3. In-memory (current process only)
6
6
  */
7
7
  export declare function getStoredConsentKey(): string | null;
8
+ /**
9
+ * Returns a human-readable description of the active auth mode.
10
+ * Used for startup logging — never exposes full key values.
11
+ */
12
+ export declare function getAuthMode(): string;
8
13
  /**
9
14
  * Store consent key to ~/.payclaw/consent_key.
10
15
  * Creates directory if needed. Falls back to memory if file write fails.
@@ -1,3 +1,4 @@
1
+ // Canonical: badge-server | Synced: 0.7.3 | Do not edit in mcp-server
1
2
  import fs from "node:fs";
2
3
  import path from "node:path";
3
4
  import os from "node:os";
@@ -34,6 +35,33 @@ export function getStoredConsentKey() {
34
35
  }
35
36
  return memoryConsentKey;
36
37
  }
38
+ /**
39
+ * Returns a human-readable description of the active auth mode.
40
+ * Used for startup logging — never exposes full key values.
41
+ */
42
+ export function getAuthMode() {
43
+ const envKey = process.env.PAYCLAW_API_KEY;
44
+ if (envKey && envKey.trim().length > 0) {
45
+ const masked = envKey.trim().substring(0, 8) + "****";
46
+ return `API key (${masked})`;
47
+ }
48
+ const filePath = getConsentKeyPath();
49
+ try {
50
+ if (fs.existsSync(filePath)) {
51
+ const content = fs.readFileSync(filePath, "utf8").trim();
52
+ if (content.length > 0) {
53
+ return "consent key (~/.payclaw/consent_key)";
54
+ }
55
+ }
56
+ }
57
+ catch {
58
+ // File read failed
59
+ }
60
+ if (memoryConsentKey) {
61
+ return "consent key (in-memory)";
62
+ }
63
+ return "none (device flow will trigger on first tool call)";
64
+ }
37
65
  /**
38
66
  * Store consent key to ~/.payclaw/consent_key.
39
67
  * Creates directory if needed. Falls back to memory if file write fails.
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/lib/storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,MAAM,eAAe,GAAG,UAAU,CAAC;AACnC,MAAM,gBAAgB,GAAG,aAAa,CAAC;AAEvC,oEAAoE;AACpE,IAAI,gBAAgB,GAAkB,IAAI,CAAC;AAE3C,SAAS,iBAAiB;IACxB,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IAC1B,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,eAAe,EAAE,gBAAgB,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAC3C,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvC,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAED,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;IACrC,IAAI,CAAC;QACH,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;YACzD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,OAAO,OAAO,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,yCAAyC;IAC3C,CAAC;IAED,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAa;IACjD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAEjC,gBAAgB,GAAG,OAAO,CAAC;IAE3B,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;IACrC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,gEAAgE;IAClE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/lib/storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * UCP manifest fetcher — checks if a merchant supports io.payclaw.common.identity.
3
+ *
4
+ * Fetches {merchantUrl}/.well-known/ucp, caches per domain for 5 minutes.
5
+ * Never throws — returns null on any error.
6
+ */
7
+ interface UCPCapability {
8
+ version: string;
9
+ spec?: string;
10
+ schema?: string;
11
+ extends?: string;
12
+ config?: {
13
+ required?: boolean;
14
+ };
15
+ }
16
+ interface UCPManifest {
17
+ capabilities?: Record<string, UCPCapability | UCPCapability[]>;
18
+ [key: string]: unknown;
19
+ }
20
+ export declare function fetchUCPManifest(merchantUrl: string): Promise<UCPManifest | null>;
21
+ export interface PayClawCapability {
22
+ version: string;
23
+ required: boolean;
24
+ }
25
+ export declare function findPayClawCapability(manifest: UCPManifest): PayClawCapability | null;
26
+ export declare function isVersionCompatible(version: string): boolean;
27
+ /**
28
+ * Reset the manifest cache. Useful for testing.
29
+ * @internal
30
+ */
31
+ export declare function _resetManifestCache(): void;
32
+ export {};
@@ -0,0 +1,117 @@
1
+ /**
2
+ * UCP manifest fetcher — checks if a merchant supports io.payclaw.common.identity.
3
+ *
4
+ * Fetches {merchantUrl}/.well-known/ucp, caches per domain for 5 minutes.
5
+ * Never throws — returns null on any error.
6
+ */
7
+ const EXTENSION_NAME = "io.payclaw.common.identity";
8
+ const FETCH_TIMEOUT_MS = 3000;
9
+ const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
10
+ const manifestCache = new Map();
11
+ function normalizeDomain(url) {
12
+ try {
13
+ const u = new URL(url.endsWith("/") ? url.slice(0, -1) : url);
14
+ return u.origin;
15
+ }
16
+ catch {
17
+ // Bare domain like "starbucks.com" — try with https://
18
+ try {
19
+ return new URL("https://" + url.replace(/\/+$/, "")).origin;
20
+ }
21
+ catch {
22
+ return url.replace(/\/+$/, "");
23
+ }
24
+ }
25
+ }
26
+ function isPublicOrigin(origin) {
27
+ let hostname;
28
+ try {
29
+ hostname = new URL(origin).hostname;
30
+ }
31
+ catch {
32
+ return false;
33
+ }
34
+ // Block non-https (except in tests)
35
+ if (!origin.startsWith("https://") && !process.env.VITEST)
36
+ return false;
37
+ // Block localhost and loopback
38
+ if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1")
39
+ return false;
40
+ if (hostname.endsWith(".localhost"))
41
+ return false;
42
+ // Block private/reserved IPv4 ranges
43
+ const ipv4Match = hostname.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);
44
+ if (ipv4Match) {
45
+ const [, a, b] = ipv4Match.map(Number);
46
+ if (a === 10)
47
+ return false; // 10.0.0.0/8
48
+ if (a === 172 && b >= 16 && b <= 31)
49
+ return false; // 172.16.0.0/12
50
+ if (a === 192 && b === 168)
51
+ return false; // 192.168.0.0/16
52
+ if (a === 169 && b === 254)
53
+ return false; // 169.254.0.0/16 (link-local + metadata)
54
+ if (a === 0)
55
+ return false; // 0.0.0.0/8
56
+ }
57
+ // Block IPv6 loopback/link-local
58
+ if (hostname.startsWith("[")) {
59
+ const inner = hostname.slice(1, -1).toLowerCase();
60
+ if (inner === "::1" || inner.startsWith("fe80:") || inner.startsWith("fc") || inner.startsWith("fd"))
61
+ return false;
62
+ }
63
+ return true;
64
+ }
65
+ export async function fetchUCPManifest(merchantUrl) {
66
+ const domain = normalizeDomain(merchantUrl);
67
+ // SSRF protection: only fetch from public origins
68
+ if (!isPublicOrigin(domain))
69
+ return null;
70
+ // Check cache
71
+ const cached = manifestCache.get(domain);
72
+ if (cached && (Date.now() - cached.fetchedAt) < CACHE_TTL_MS) {
73
+ return cached.data;
74
+ }
75
+ try {
76
+ const res = await fetch(`${domain}/.well-known/ucp`, {
77
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
78
+ });
79
+ if (!res.ok) {
80
+ manifestCache.set(domain, { data: null, fetchedAt: Date.now() });
81
+ return null;
82
+ }
83
+ const data = (await res.json());
84
+ manifestCache.set(domain, { data, fetchedAt: Date.now() });
85
+ return data;
86
+ }
87
+ catch {
88
+ manifestCache.set(domain, { data: null, fetchedAt: Date.now() });
89
+ return null;
90
+ }
91
+ }
92
+ export function findPayClawCapability(manifest) {
93
+ const caps = manifest.capabilities;
94
+ if (!caps || !(EXTENSION_NAME in caps))
95
+ return null;
96
+ const entry = caps[EXTENSION_NAME];
97
+ // Handle both array-wrapped and plain object forms
98
+ const cap = Array.isArray(entry) ? entry[0] : entry;
99
+ if (!cap || typeof cap.version !== "string")
100
+ return null;
101
+ return {
102
+ version: cap.version,
103
+ required: cap.config?.required === true,
104
+ };
105
+ }
106
+ const COMPATIBLE_VERSIONS = ["2026-01-11"];
107
+ export function isVersionCompatible(version) {
108
+ return COMPATIBLE_VERSIONS.includes(version);
109
+ }
110
+ /**
111
+ * Reset the manifest cache. Useful for testing.
112
+ * @internal
113
+ */
114
+ export function _resetManifestCache() {
115
+ manifestCache.clear();
116
+ }
117
+ //# sourceMappingURL=ucp-manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ucp-manifest.js","sourceRoot":"","sources":["../../src/lib/ucp-manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};