@dupecom/botcha-cloudflare 0.20.2 → 0.23.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 (88) hide show
  1. package/README.md +74 -9
  2. package/dist/agent-auth.d.ts +129 -0
  3. package/dist/agent-auth.d.ts.map +1 -0
  4. package/dist/agent-auth.js +210 -0
  5. package/dist/agents.d.ts +10 -0
  6. package/dist/agents.d.ts.map +1 -1
  7. package/dist/agents.js +51 -1
  8. package/dist/app-gate.d.ts +6 -0
  9. package/dist/app-gate.d.ts.map +1 -0
  10. package/dist/app-gate.js +69 -0
  11. package/dist/apps.d.ts +13 -4
  12. package/dist/apps.d.ts.map +1 -1
  13. package/dist/apps.js +30 -4
  14. package/dist/dashboard/account.d.ts +63 -0
  15. package/dist/dashboard/account.d.ts.map +1 -0
  16. package/dist/dashboard/account.js +488 -0
  17. package/dist/dashboard/api.js +15 -68
  18. package/dist/dashboard/auth.d.ts.map +1 -1
  19. package/dist/dashboard/auth.js +14 -14
  20. package/dist/dashboard/docs.d.ts.map +1 -1
  21. package/dist/dashboard/docs.js +146 -3
  22. package/dist/dashboard/layout.d.ts.map +1 -1
  23. package/dist/dashboard/layout.js +2 -2
  24. package/dist/dashboard/mcp-setup.d.ts +15 -0
  25. package/dist/dashboard/mcp-setup.d.ts.map +1 -0
  26. package/dist/dashboard/mcp-setup.js +391 -0
  27. package/dist/dashboard/showcase.d.ts +6 -10
  28. package/dist/dashboard/showcase.d.ts.map +1 -1
  29. package/dist/dashboard/showcase.js +67 -991
  30. package/dist/dashboard/whitepaper.d.ts.map +1 -1
  31. package/dist/dashboard/whitepaper.js +42 -4
  32. package/dist/index.d.ts +5 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +660 -83
  35. package/dist/mcp.d.ts +20 -0
  36. package/dist/mcp.d.ts.map +1 -0
  37. package/dist/mcp.js +1290 -0
  38. package/dist/oauth-agent.d.ts +130 -0
  39. package/dist/oauth-agent.d.ts.map +1 -0
  40. package/dist/oauth-agent.js +194 -0
  41. package/dist/static.d.ts +781 -5
  42. package/dist/static.d.ts.map +1 -1
  43. package/dist/static.js +790 -111
  44. package/dist/tap-a2a-routes.d.ts +355 -0
  45. package/dist/tap-a2a-routes.d.ts.map +1 -0
  46. package/dist/tap-a2a-routes.js +475 -0
  47. package/dist/tap-a2a.d.ts +199 -0
  48. package/dist/tap-a2a.d.ts.map +1 -0
  49. package/dist/tap-a2a.js +502 -0
  50. package/dist/tap-agents.d.ts +15 -0
  51. package/dist/tap-agents.d.ts.map +1 -1
  52. package/dist/tap-agents.js +31 -1
  53. package/dist/tap-ans-routes.d.ts +302 -0
  54. package/dist/tap-ans-routes.d.ts.map +1 -0
  55. package/dist/tap-ans-routes.js +535 -0
  56. package/dist/tap-ans.d.ts +241 -0
  57. package/dist/tap-ans.d.ts.map +1 -0
  58. package/dist/tap-ans.js +481 -0
  59. package/dist/tap-delegation-routes.d.ts.map +1 -1
  60. package/dist/tap-delegation-routes.js +11 -0
  61. package/dist/tap-did.d.ts +140 -0
  62. package/dist/tap-did.d.ts.map +1 -0
  63. package/dist/tap-did.js +262 -0
  64. package/dist/tap-oidca-routes.d.ts +383 -0
  65. package/dist/tap-oidca-routes.d.ts.map +1 -0
  66. package/dist/tap-oidca-routes.js +597 -0
  67. package/dist/tap-oidca.d.ts +288 -0
  68. package/dist/tap-oidca.d.ts.map +1 -0
  69. package/dist/tap-oidca.js +461 -0
  70. package/dist/tap-routes.d.ts +24 -8
  71. package/dist/tap-routes.d.ts.map +1 -1
  72. package/dist/tap-routes.js +169 -23
  73. package/dist/tap-vc-routes.d.ts +358 -0
  74. package/dist/tap-vc-routes.d.ts.map +1 -0
  75. package/dist/tap-vc-routes.js +367 -0
  76. package/dist/tap-vc.d.ts +125 -0
  77. package/dist/tap-vc.d.ts.map +1 -0
  78. package/dist/tap-vc.js +245 -0
  79. package/dist/tap-x402-routes.d.ts +89 -0
  80. package/dist/tap-x402-routes.d.ts.map +1 -0
  81. package/dist/tap-x402-routes.js +579 -0
  82. package/dist/tap-x402.d.ts +222 -0
  83. package/dist/tap-x402.d.ts.map +1 -0
  84. package/dist/tap-x402.js +546 -0
  85. package/dist/webhooks.d.ts +99 -0
  86. package/dist/webhooks.d.ts.map +1 -0
  87. package/dist/webhooks.js +642 -0
  88. package/package.json +3 -1
@@ -0,0 +1,241 @@
1
+ /**
2
+ * BOTCHA ANS Integration — tap-ans.ts
3
+ *
4
+ * Agent Name Service (ANS) is the emerging "DNS for AI agents" led by GoDaddy.
5
+ * ANS names like `ans://v1.0.myagent.example.com` resolve via DNS TXT records
6
+ * to structured agent metadata. This module makes BOTCHA the verification badge
7
+ * on top of ANS's domain-level trust.
8
+ *
9
+ * ANS gives you DV-level trust (domain exists). BOTCHA adds:
10
+ * "this agent actually behaves like an AI."
11
+ *
12
+ * Together: ANS names the agent, BOTCHA verifies it.
13
+ *
14
+ * Key ANS spec: https://agentnameregistry.org
15
+ * ANS format: ans://v1.0.<label>.<domain>
16
+ * e.g. ans://v1.0.myagent.example.com
17
+ * DNS lookup: TXT record at _ans.<domain>
18
+ * e.g. _ans.example.com TXT "v=ANS1 ..."
19
+ *
20
+ * References:
21
+ * - https://agentnameregistry.org
22
+ * - GoDaddy ANS Marketplace (Dec 2025)
23
+ * - IETF ANS draft (Nov 2025)
24
+ */
25
+ export interface KVNamespace {
26
+ get(key: string, encoding?: string): Promise<string | null>;
27
+ put(key: string, value: string, options?: {
28
+ expirationTtl?: number;
29
+ }): Promise<void>;
30
+ delete(key: string): Promise<void>;
31
+ list(options?: {
32
+ prefix?: string;
33
+ limit?: number;
34
+ cursor?: string;
35
+ }): Promise<{
36
+ keys: Array<{
37
+ name: string;
38
+ expiration?: number;
39
+ }>;
40
+ list_complete: boolean;
41
+ cursor?: string;
42
+ }>;
43
+ }
44
+ /**
45
+ * Parsed ANS name components
46
+ * ans://v1.0.myagent.example.com
47
+ * version: "v1.0"
48
+ * label: "myagent"
49
+ * domain: "example.com"
50
+ */
51
+ export interface ANSNameComponents {
52
+ raw: string;
53
+ version: string;
54
+ label: string;
55
+ domain: string;
56
+ fqdn: string;
57
+ dnsLookupName: string;
58
+ }
59
+ /**
60
+ * Raw ANS TXT record content (after parsing)
61
+ * ANS spec v1: v=ANS1 name=<label> pub=<base64-pubkey> cap=<csv> url=<agentcard-url>
62
+ */
63
+ export interface ANSTXTRecord {
64
+ version: string;
65
+ name?: string;
66
+ pub?: string;
67
+ cap?: string[];
68
+ url?: string;
69
+ did?: string;
70
+ raw: string;
71
+ }
72
+ /**
73
+ * Result of resolving an ANS name
74
+ */
75
+ export interface ANSResolutionResult {
76
+ success: boolean;
77
+ name?: ANSNameComponents;
78
+ record?: ANSTXTRecord;
79
+ agentCard?: Record<string, unknown>;
80
+ error?: string;
81
+ resolvedAt?: number;
82
+ }
83
+ /**
84
+ * BOTCHA verification badge linked to an ANS name
85
+ */
86
+ export interface ANSVerificationBadge {
87
+ badge_id: string;
88
+ ans_name: string;
89
+ domain: string;
90
+ agent_id?: string;
91
+ verified: boolean;
92
+ verification_type: 'dns-ownership' | 'key-ownership' | 'challenge-verified';
93
+ trust_level: 'domain-validated' | 'key-validated' | 'behavior-validated';
94
+ credential_token: string;
95
+ issued_at: number;
96
+ expires_at: number;
97
+ issuer: 'botcha.ai';
98
+ }
99
+ /**
100
+ * ANS-verified agent in the BOTCHA discovery registry
101
+ */
102
+ export interface ANSRegistryEntry {
103
+ ans_name: string;
104
+ domain: string;
105
+ label: string;
106
+ agent_id?: string;
107
+ app_id?: string;
108
+ badge_id: string;
109
+ trust_level: 'domain-validated' | 'key-validated' | 'behavior-validated';
110
+ capabilities?: string[];
111
+ agent_card_url?: string;
112
+ verified_at: number;
113
+ expires_at: number;
114
+ }
115
+ /**
116
+ * Parse an ANS name into its components.
117
+ *
118
+ * Accepts:
119
+ * - ans://v1.0.myagent.example.com
120
+ * - v1.0.myagent.example.com (without scheme)
121
+ * - myagent.example.com (bare domain, defaults to v1.0)
122
+ * - example.com (root domain, label = domain apex)
123
+ */
124
+ export declare function parseANSName(input: string): {
125
+ success: boolean;
126
+ components?: ANSNameComponents;
127
+ error?: string;
128
+ };
129
+ /**
130
+ * Resolve an ANS name to agent metadata.
131
+ *
132
+ * Steps:
133
+ * 1. Parse the ANS name
134
+ * 2. Look up DNS TXT at _ans.<domain>
135
+ * 3. Parse ANS TXT record
136
+ * 4. Optionally fetch Agent Card from record.url
137
+ */
138
+ export declare function resolveANSName(ansName: string): Promise<ANSResolutionResult>;
139
+ /**
140
+ * Verify that the caller owns the ANS name.
141
+ *
142
+ * Ownership proof options (in order of strength):
143
+ *
144
+ * 1. Key ownership: caller provides a signature over a BOTCHA nonce using the
145
+ * public key embedded in the ANS TXT record. This proves the holder of the
146
+ * private key is the registrant.
147
+ *
148
+ * 2. DNS challenge: BOTCHA issues a nonce, caller must place it in a DNS TXT
149
+ * record at _botcha-verify.<domain>. This proves DNS control.
150
+ *
151
+ * For Phase 1 we implement key-ownership verification using SubtleCrypto.
152
+ */
153
+ export interface ANSOwnershipProof {
154
+ ans_name: string;
155
+ nonce: string;
156
+ signature: string;
157
+ algorithm?: string;
158
+ public_key?: string;
159
+ }
160
+ export interface ANSOwnershipResult {
161
+ verified: boolean;
162
+ method: 'key-ownership' | 'dns-challenge';
163
+ error?: string;
164
+ }
165
+ /**
166
+ * Verify ANS name ownership via key signature.
167
+ * The ANS TXT record must contain `pub=<base64-pubkey>`.
168
+ */
169
+ export declare function verifyANSOwnership(proof: ANSOwnershipProof, resolvedRecord: ANSTXTRecord): Promise<ANSOwnershipResult>;
170
+ /**
171
+ * Issue a BOTCHA-ANS linked verification badge.
172
+ *
173
+ * The badge is a signed JWT (HS256) containing:
174
+ * - ans_name: canonical ANS identifier
175
+ * - domain: verified domain
176
+ * - trust_level: what was verified
177
+ * - botcha: "verified" — the stamp
178
+ *
179
+ * This badge can be embedded in ANS Marketplace listings and verified
180
+ * by anyone who knows the BOTCHA JWT secret (or JWKS public key).
181
+ */
182
+ export declare function issueANSBadge(components: ANSNameComponents, trustLevel: ANSVerificationBadge['trust_level'], jwtSecret: string, options?: {
183
+ agentId?: string;
184
+ capabilities?: string[];
185
+ agentCardUrl?: string;
186
+ expiresInSeconds?: number;
187
+ }): Promise<ANSVerificationBadge>;
188
+ /**
189
+ * Save a verified ANS agent to the BOTCHA discovery registry.
190
+ * Stored in KV under `ans_registry:<domain>:<label>`
191
+ */
192
+ export declare function saveANSRegistryEntry(kv: KVNamespace, entry: ANSRegistryEntry): Promise<void>;
193
+ /**
194
+ * Get a single ANS registry entry.
195
+ */
196
+ export declare function getANSRegistryEntry(kv: KVNamespace, domain: string, label: string): Promise<ANSRegistryEntry | null>;
197
+ /**
198
+ * List all BOTCHA-verified ANS agents in the discovery registry.
199
+ * Optionally filter by domain.
200
+ */
201
+ export declare function listANSRegistry(kv: KVNamespace, options?: {
202
+ domain?: string;
203
+ limit?: number;
204
+ }): Promise<ANSRegistryEntry[]>;
205
+ /**
206
+ * Generate and store a fresh nonce for ANS ownership verification.
207
+ * TTL: 10 minutes — caller must sign and return within this window.
208
+ */
209
+ export declare function generateANSNonce(kv: KVNamespace, ansName: string): Promise<string>;
210
+ /**
211
+ * Consume (verify + delete) a stored ANS nonce.
212
+ * Returns true if nonce matches. Nonces are single-use.
213
+ */
214
+ export declare function consumeANSNonce(kv: KVNamespace, ansName: string, providedNonce: string): Promise<boolean>;
215
+ /**
216
+ * Returns the metadata for BOTCHA's own ANS registration.
217
+ * ans://v1.0.botcha.ai
218
+ *
219
+ * This would be placed as a TXT record at _ans.botcha.ai:
220
+ * v=ANS1 name=botcha cap=verify,issue,discover url=https://botcha.ai/.well-known/agent.json
221
+ */
222
+ export declare function getBotchaANSRecord(): {
223
+ ans_name: string;
224
+ dns_name: string;
225
+ txt_record: string;
226
+ agent_card: Record<string, unknown>;
227
+ };
228
+ declare const _default: {
229
+ parseANSName: typeof parseANSName;
230
+ resolveANSName: typeof resolveANSName;
231
+ verifyANSOwnership: typeof verifyANSOwnership;
232
+ issueANSBadge: typeof issueANSBadge;
233
+ saveANSRegistryEntry: typeof saveANSRegistryEntry;
234
+ getANSRegistryEntry: typeof getANSRegistryEntry;
235
+ listANSRegistry: typeof listANSRegistry;
236
+ generateANSNonce: typeof generateANSNonce;
237
+ consumeANSNonce: typeof consumeANSNonce;
238
+ getBotchaANSRecord: typeof getBotchaANSRecord;
239
+ };
240
+ export default _default;
241
+ //# sourceMappingURL=tap-ans.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tap-ans.d.ts","sourceRoot":"","sources":["../src/tap-ans.ts"],"names":[],"mappings":"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"}