@dupecom/botcha 0.13.1 → 0.15.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.
- package/README.md +48 -2
- package/dist/lib/client/index.d.ts +64 -2
- package/dist/lib/client/index.d.ts.map +1 -1
- package/dist/lib/client/index.js +136 -1
- package/dist/lib/client/types.d.ts +68 -0
- package/dist/lib/client/types.d.ts.map +1 -1
- package/dist/lib/index.js +2 -0
- package/dist/src/challenges/compute.d.ts +19 -0
- package/dist/src/challenges/compute.d.ts.map +1 -0
- package/dist/src/challenges/compute.js +88 -0
- package/dist/src/challenges/hybrid.d.ts +45 -0
- package/dist/src/challenges/hybrid.d.ts.map +1 -0
- package/dist/src/challenges/hybrid.js +94 -0
- package/dist/src/challenges/reasoning.d.ts +29 -0
- package/dist/src/challenges/reasoning.d.ts.map +1 -0
- package/dist/src/challenges/reasoning.js +414 -0
- package/dist/src/challenges/speed.d.ts +34 -0
- package/dist/src/challenges/speed.d.ts.map +1 -0
- package/dist/src/challenges/speed.js +115 -0
- package/dist/src/middleware/tap-enhanced-verify.d.ts +57 -0
- package/dist/src/middleware/tap-enhanced-verify.d.ts.map +1 -0
- package/dist/src/middleware/tap-enhanced-verify.js +368 -0
- package/dist/src/middleware/verify.d.ts +12 -0
- package/dist/src/middleware/verify.d.ts.map +1 -0
- package/dist/src/middleware/verify.js +141 -0
- package/dist/src/utils/badge-image.d.ts +15 -0
- package/dist/src/utils/badge-image.d.ts.map +1 -0
- package/dist/src/utils/badge-image.js +253 -0
- package/dist/src/utils/badge.d.ts +39 -0
- package/dist/src/utils/badge.d.ts.map +1 -0
- package/dist/src/utils/badge.js +125 -0
- package/dist/src/utils/signature.d.ts +23 -0
- package/dist/src/utils/signature.d.ts.map +1 -0
- package/dist/src/utils/signature.js +160 -0
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -36,7 +36,8 @@ Use cases:
|
|
|
36
36
|
- 📧 Email verification, account recovery, and secret rotation
|
|
37
37
|
- 🤖 Agent-first dashboard auth (challenge-based login + device code handoff)
|
|
38
38
|
- 🆔 Persistent agent identities with registry
|
|
39
|
-
- 🔏 Trusted Agent Protocol (TAP) — cryptographic agent auth with HTTP Message Signatures
|
|
39
|
+
- 🔏 Trusted Agent Protocol (TAP) — cryptographic agent auth with HTTP Message Signatures (SDK: `registerTAPAgent`, `createTAPSession`)
|
|
40
|
+
- 🌐 TAP showcase homepage at [botcha.ai](https://botcha.ai) — one of the first services to implement [Visa's Trusted Agent Protocol](https://github.com/visa/trusted-agent-protocol)
|
|
40
41
|
|
|
41
42
|
## Install
|
|
42
43
|
|
|
@@ -416,6 +417,51 @@ curl -X POST https://botcha.ai/v1/sessions/tap \
|
|
|
416
417
|
| `POST /v1/sessions/tap` | Create TAP session with intent validation |
|
|
417
418
|
| `GET /v1/sessions/:id/tap` | Get TAP session info |
|
|
418
419
|
|
|
420
|
+
### TAP SDK Methods
|
|
421
|
+
|
|
422
|
+
**TypeScript:**
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
import { BotchaClient } from '@dupecom/botcha/client';
|
|
426
|
+
|
|
427
|
+
const client = new BotchaClient({ appId: 'app_abc123' });
|
|
428
|
+
|
|
429
|
+
// Register a TAP agent
|
|
430
|
+
const agent = await client.registerTAPAgent({
|
|
431
|
+
name: 'my-agent',
|
|
432
|
+
operator: 'Acme Corp',
|
|
433
|
+
capabilities: [{ action: 'browse', scope: ['products'] }],
|
|
434
|
+
trust_level: 'verified',
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
// Create a TAP session
|
|
438
|
+
const session = await client.createTAPSession({
|
|
439
|
+
agent_id: agent.agent_id,
|
|
440
|
+
user_context: 'user-hash',
|
|
441
|
+
intent: { action: 'browse', resource: 'products', duration: 3600 },
|
|
442
|
+
});
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
**Python:**
|
|
446
|
+
|
|
447
|
+
```python
|
|
448
|
+
from botcha import BotchaClient
|
|
449
|
+
|
|
450
|
+
async with BotchaClient(app_id="app_abc123") as client:
|
|
451
|
+
agent = await client.register_tap_agent(
|
|
452
|
+
name="my-agent",
|
|
453
|
+
operator="Acme Corp",
|
|
454
|
+
capabilities=[{"action": "browse", "scope": ["products"]}],
|
|
455
|
+
trust_level="verified",
|
|
456
|
+
)
|
|
457
|
+
|
|
458
|
+
session = await client.create_tap_session(
|
|
459
|
+
agent_id=agent.agent_id,
|
|
460
|
+
user_context="user-hash",
|
|
461
|
+
intent={"action": "browse", "resource": "products", "duration": 3600},
|
|
462
|
+
)
|
|
463
|
+
```
|
|
464
|
+
|
|
419
465
|
### Express Middleware (Verification Modes)
|
|
420
466
|
|
|
421
467
|
```typescript
|
|
@@ -510,7 +556,7 @@ BOTCHA is designed to be auto-discoverable by AI agents through multiple standar
|
|
|
510
556
|
All responses include these headers for agent discovery:
|
|
511
557
|
|
|
512
558
|
```http
|
|
513
|
-
X-Botcha-Version: 0.
|
|
559
|
+
X-Botcha-Version: 0.15.0
|
|
514
560
|
X-Botcha-Enabled: true
|
|
515
561
|
X-Botcha-Methods: hybrid-challenge,speed-challenge,reasoning-challenge,standard-challenge
|
|
516
562
|
X-Botcha-Docs: https://botcha.ai/openapi.json
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export type { SpeedProblem, BotchaClientOptions, ChallengeResponse, StandardChallengeResponse, VerifyResponse, TokenResponse, StreamSession, StreamEvent, Problem, VerifyResult, StreamChallengeOptions, CreateAppResponse, VerifyEmailResponse, ResendVerificationResponse, RecoverAccountResponse, RotateSecretResponse, } from './types.js';
|
|
2
|
-
import type { BotchaClientOptions, VerifyResponse, CreateAppResponse, VerifyEmailResponse, ResendVerificationResponse, RecoverAccountResponse, RotateSecretResponse } from './types.js';
|
|
1
|
+
export type { SpeedProblem, BotchaClientOptions, ChallengeResponse, StandardChallengeResponse, VerifyResponse, TokenResponse, StreamSession, StreamEvent, Problem, VerifyResult, StreamChallengeOptions, CreateAppResponse, VerifyEmailResponse, ResendVerificationResponse, RecoverAccountResponse, RotateSecretResponse, TAPAction, TAPTrustLevel, TAPSignatureAlgorithm, TAPCapability, TAPIntent, RegisterTAPAgentOptions, TAPAgentResponse, TAPAgentListResponse, CreateTAPSessionOptions, TAPSessionResponse, } from './types.js';
|
|
2
|
+
import type { BotchaClientOptions, VerifyResponse, CreateAppResponse, VerifyEmailResponse, ResendVerificationResponse, RecoverAccountResponse, RotateSecretResponse, RegisterTAPAgentOptions, TAPAgentResponse, TAPAgentListResponse, CreateTAPSessionOptions, TAPSessionResponse } from './types.js';
|
|
3
3
|
export { BotchaStreamClient } from './stream.js';
|
|
4
4
|
/**
|
|
5
5
|
* BOTCHA Client SDK for AI Agents
|
|
@@ -154,6 +154,68 @@ export declare class BotchaClient {
|
|
|
154
154
|
* ```
|
|
155
155
|
*/
|
|
156
156
|
rotateSecret(appId?: string): Promise<RotateSecretResponse>;
|
|
157
|
+
/**
|
|
158
|
+
* Register an agent with TAP (Trusted Agent Protocol) capabilities.
|
|
159
|
+
* Enables cryptographic agent authentication with optional public key signing.
|
|
160
|
+
*
|
|
161
|
+
* @param options - Registration options including name, public key, capabilities
|
|
162
|
+
* @returns TAP agent details including agent_id
|
|
163
|
+
* @throws Error if registration fails
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```typescript
|
|
167
|
+
* const agent = await client.registerTAPAgent({
|
|
168
|
+
* name: 'my-shopping-agent',
|
|
169
|
+
* operator: 'acme-corp',
|
|
170
|
+
* capabilities: [{ action: 'browse', scope: ['products'] }],
|
|
171
|
+
* trust_level: 'verified',
|
|
172
|
+
* });
|
|
173
|
+
* console.log(agent.agent_id);
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
registerTAPAgent(options: RegisterTAPAgentOptions): Promise<TAPAgentResponse>;
|
|
177
|
+
/**
|
|
178
|
+
* Get a TAP agent by ID.
|
|
179
|
+
*
|
|
180
|
+
* @param agentId - The agent ID to retrieve
|
|
181
|
+
* @returns TAP agent details
|
|
182
|
+
* @throws Error if agent not found
|
|
183
|
+
*/
|
|
184
|
+
getTAPAgent(agentId: string): Promise<TAPAgentResponse>;
|
|
185
|
+
/**
|
|
186
|
+
* List TAP agents for the current app.
|
|
187
|
+
*
|
|
188
|
+
* @param tapOnly - If true, only return TAP-enabled agents (default: false)
|
|
189
|
+
* @returns List of TAP agents with counts
|
|
190
|
+
* @throws Error if listing fails
|
|
191
|
+
*/
|
|
192
|
+
listTAPAgents(tapOnly?: boolean): Promise<TAPAgentListResponse>;
|
|
193
|
+
/**
|
|
194
|
+
* Create a TAP session after agent verification.
|
|
195
|
+
*
|
|
196
|
+
* @param options - Session options including agent_id, user_context, and intent
|
|
197
|
+
* @returns TAP session details including session_id and expiry
|
|
198
|
+
* @throws Error if session creation fails
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* ```typescript
|
|
202
|
+
* const session = await client.createTAPSession({
|
|
203
|
+
* agent_id: 'agent_abc123',
|
|
204
|
+
* user_context: 'user-hash',
|
|
205
|
+
* intent: { action: 'browse', resource: 'products', duration: 3600 },
|
|
206
|
+
* });
|
|
207
|
+
* console.log(session.session_id, session.expires_at);
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
210
|
+
createTAPSession(options: CreateTAPSessionOptions): Promise<TAPSessionResponse>;
|
|
211
|
+
/**
|
|
212
|
+
* Get a TAP session by ID.
|
|
213
|
+
*
|
|
214
|
+
* @param sessionId - The session ID to retrieve
|
|
215
|
+
* @returns TAP session details including time_remaining
|
|
216
|
+
* @throws Error if session not found or expired
|
|
217
|
+
*/
|
|
218
|
+
getTAPSession(sessionId: string): Promise<TAPSessionResponse>;
|
|
157
219
|
}
|
|
158
220
|
/**
|
|
159
221
|
* Convenience function for one-off solves
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/client/index.ts"],"names":[],"mappings":"AAMA,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,yBAAyB,EACzB,cAAc,EACd,aAAa,EACb,aAAa,EACb,WAAW,EACX,OAAO,EACP,YAAY,EACZ,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,0BAA0B,EAC1B,sBAAsB,EACtB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/client/index.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/client/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import crypto from 'crypto';
|
|
2
2
|
// SDK version - hardcoded since npm_package_version is unreliable when used as a library
|
|
3
|
-
const SDK_VERSION = '0.
|
|
3
|
+
const SDK_VERSION = '0.13.1';
|
|
4
4
|
// Export stream client
|
|
5
5
|
export { BotchaStreamClient } from './stream.js';
|
|
6
6
|
/**
|
|
@@ -494,6 +494,141 @@ export class BotchaClient {
|
|
|
494
494
|
}
|
|
495
495
|
return await res.json();
|
|
496
496
|
}
|
|
497
|
+
// ============ TAP (TRUSTED AGENT PROTOCOL) ============
|
|
498
|
+
/**
|
|
499
|
+
* Register an agent with TAP (Trusted Agent Protocol) capabilities.
|
|
500
|
+
* Enables cryptographic agent authentication with optional public key signing.
|
|
501
|
+
*
|
|
502
|
+
* @param options - Registration options including name, public key, capabilities
|
|
503
|
+
* @returns TAP agent details including agent_id
|
|
504
|
+
* @throws Error if registration fails
|
|
505
|
+
*
|
|
506
|
+
* @example
|
|
507
|
+
* ```typescript
|
|
508
|
+
* const agent = await client.registerTAPAgent({
|
|
509
|
+
* name: 'my-shopping-agent',
|
|
510
|
+
* operator: 'acme-corp',
|
|
511
|
+
* capabilities: [{ action: 'browse', scope: ['products'] }],
|
|
512
|
+
* trust_level: 'verified',
|
|
513
|
+
* });
|
|
514
|
+
* console.log(agent.agent_id);
|
|
515
|
+
* ```
|
|
516
|
+
*/
|
|
517
|
+
async registerTAPAgent(options) {
|
|
518
|
+
const url = this.appId
|
|
519
|
+
? `${this.baseUrl}/v1/agents/register/tap?app_id=${encodeURIComponent(this.appId)}`
|
|
520
|
+
: `${this.baseUrl}/v1/agents/register/tap`;
|
|
521
|
+
const headers = {
|
|
522
|
+
'Content-Type': 'application/json',
|
|
523
|
+
'User-Agent': this.agentIdentity,
|
|
524
|
+
};
|
|
525
|
+
if (this.cachedToken) {
|
|
526
|
+
headers['Authorization'] = `Bearer ${this.cachedToken}`;
|
|
527
|
+
}
|
|
528
|
+
const res = await fetch(url, {
|
|
529
|
+
method: 'POST',
|
|
530
|
+
headers,
|
|
531
|
+
body: JSON.stringify(options),
|
|
532
|
+
});
|
|
533
|
+
if (!res.ok) {
|
|
534
|
+
const body = await res.json().catch(() => ({}));
|
|
535
|
+
throw new Error(body.message || `TAP agent registration failed with status ${res.status}`);
|
|
536
|
+
}
|
|
537
|
+
return await res.json();
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Get a TAP agent by ID.
|
|
541
|
+
*
|
|
542
|
+
* @param agentId - The agent ID to retrieve
|
|
543
|
+
* @returns TAP agent details
|
|
544
|
+
* @throws Error if agent not found
|
|
545
|
+
*/
|
|
546
|
+
async getTAPAgent(agentId) {
|
|
547
|
+
const res = await fetch(`${this.baseUrl}/v1/agents/${encodeURIComponent(agentId)}/tap`, {
|
|
548
|
+
headers: { 'User-Agent': this.agentIdentity },
|
|
549
|
+
});
|
|
550
|
+
if (!res.ok) {
|
|
551
|
+
const body = await res.json().catch(() => ({}));
|
|
552
|
+
throw new Error(body.message || `TAP agent retrieval failed with status ${res.status}`);
|
|
553
|
+
}
|
|
554
|
+
return await res.json();
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* List TAP agents for the current app.
|
|
558
|
+
*
|
|
559
|
+
* @param tapOnly - If true, only return TAP-enabled agents (default: false)
|
|
560
|
+
* @returns List of TAP agents with counts
|
|
561
|
+
* @throws Error if listing fails
|
|
562
|
+
*/
|
|
563
|
+
async listTAPAgents(tapOnly = false) {
|
|
564
|
+
let url = this.appId
|
|
565
|
+
? `${this.baseUrl}/v1/agents/tap?app_id=${encodeURIComponent(this.appId)}`
|
|
566
|
+
: `${this.baseUrl}/v1/agents/tap`;
|
|
567
|
+
if (tapOnly) {
|
|
568
|
+
url += url.includes('?') ? '&tap_only=true' : '?tap_only=true';
|
|
569
|
+
}
|
|
570
|
+
const headers = {
|
|
571
|
+
'User-Agent': this.agentIdentity,
|
|
572
|
+
};
|
|
573
|
+
if (this.cachedToken) {
|
|
574
|
+
headers['Authorization'] = `Bearer ${this.cachedToken}`;
|
|
575
|
+
}
|
|
576
|
+
const res = await fetch(url, { headers });
|
|
577
|
+
if (!res.ok) {
|
|
578
|
+
const body = await res.json().catch(() => ({}));
|
|
579
|
+
throw new Error(body.message || `TAP agent listing failed with status ${res.status}`);
|
|
580
|
+
}
|
|
581
|
+
return await res.json();
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Create a TAP session after agent verification.
|
|
585
|
+
*
|
|
586
|
+
* @param options - Session options including agent_id, user_context, and intent
|
|
587
|
+
* @returns TAP session details including session_id and expiry
|
|
588
|
+
* @throws Error if session creation fails
|
|
589
|
+
*
|
|
590
|
+
* @example
|
|
591
|
+
* ```typescript
|
|
592
|
+
* const session = await client.createTAPSession({
|
|
593
|
+
* agent_id: 'agent_abc123',
|
|
594
|
+
* user_context: 'user-hash',
|
|
595
|
+
* intent: { action: 'browse', resource: 'products', duration: 3600 },
|
|
596
|
+
* });
|
|
597
|
+
* console.log(session.session_id, session.expires_at);
|
|
598
|
+
* ```
|
|
599
|
+
*/
|
|
600
|
+
async createTAPSession(options) {
|
|
601
|
+
const res = await fetch(`${this.baseUrl}/v1/sessions/tap`, {
|
|
602
|
+
method: 'POST',
|
|
603
|
+
headers: {
|
|
604
|
+
'Content-Type': 'application/json',
|
|
605
|
+
'User-Agent': this.agentIdentity,
|
|
606
|
+
},
|
|
607
|
+
body: JSON.stringify(options),
|
|
608
|
+
});
|
|
609
|
+
if (!res.ok) {
|
|
610
|
+
const body = await res.json().catch(() => ({}));
|
|
611
|
+
throw new Error(body.message || `TAP session creation failed with status ${res.status}`);
|
|
612
|
+
}
|
|
613
|
+
return await res.json();
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* Get a TAP session by ID.
|
|
617
|
+
*
|
|
618
|
+
* @param sessionId - The session ID to retrieve
|
|
619
|
+
* @returns TAP session details including time_remaining
|
|
620
|
+
* @throws Error if session not found or expired
|
|
621
|
+
*/
|
|
622
|
+
async getTAPSession(sessionId) {
|
|
623
|
+
const res = await fetch(`${this.baseUrl}/v1/sessions/${encodeURIComponent(sessionId)}/tap`, {
|
|
624
|
+
headers: { 'User-Agent': this.agentIdentity },
|
|
625
|
+
});
|
|
626
|
+
if (!res.ok) {
|
|
627
|
+
const body = await res.json().catch(() => ({}));
|
|
628
|
+
throw new Error(body.message || `TAP session retrieval failed with status ${res.status}`);
|
|
629
|
+
}
|
|
630
|
+
return await res.json();
|
|
631
|
+
}
|
|
497
632
|
}
|
|
498
633
|
/**
|
|
499
634
|
* Convenience function for one-off solves
|
|
@@ -131,4 +131,72 @@ export interface RotateSecretResponse {
|
|
|
131
131
|
error?: string;
|
|
132
132
|
message?: string;
|
|
133
133
|
}
|
|
134
|
+
export type TAPAction = 'browse' | 'compare' | 'purchase' | 'audit' | 'search';
|
|
135
|
+
export type TAPTrustLevel = 'basic' | 'verified' | 'enterprise';
|
|
136
|
+
export type TAPSignatureAlgorithm = 'ecdsa-p256-sha256' | 'rsa-pss-sha256';
|
|
137
|
+
export interface TAPCapability {
|
|
138
|
+
action: TAPAction;
|
|
139
|
+
scope?: string[];
|
|
140
|
+
restrictions?: {
|
|
141
|
+
max_amount?: number;
|
|
142
|
+
rate_limit?: number;
|
|
143
|
+
[key: string]: any;
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
export interface TAPIntent {
|
|
147
|
+
action: TAPAction;
|
|
148
|
+
resource?: string;
|
|
149
|
+
scope?: string[];
|
|
150
|
+
duration?: number;
|
|
151
|
+
}
|
|
152
|
+
export interface RegisterTAPAgentOptions {
|
|
153
|
+
name: string;
|
|
154
|
+
operator?: string;
|
|
155
|
+
version?: string;
|
|
156
|
+
public_key?: string;
|
|
157
|
+
signature_algorithm?: TAPSignatureAlgorithm;
|
|
158
|
+
capabilities?: TAPCapability[];
|
|
159
|
+
trust_level?: TAPTrustLevel;
|
|
160
|
+
issuer?: string;
|
|
161
|
+
}
|
|
162
|
+
export interface TAPAgentResponse {
|
|
163
|
+
success: boolean;
|
|
164
|
+
agent_id: string;
|
|
165
|
+
app_id: string;
|
|
166
|
+
name: string;
|
|
167
|
+
operator?: string;
|
|
168
|
+
version?: string;
|
|
169
|
+
created_at: string;
|
|
170
|
+
tap_enabled: boolean;
|
|
171
|
+
trust_level?: TAPTrustLevel;
|
|
172
|
+
capabilities?: TAPCapability[];
|
|
173
|
+
signature_algorithm?: TAPSignatureAlgorithm;
|
|
174
|
+
issuer?: string;
|
|
175
|
+
has_public_key: boolean;
|
|
176
|
+
key_fingerprint?: string;
|
|
177
|
+
last_verified_at?: string | null;
|
|
178
|
+
public_key?: string;
|
|
179
|
+
}
|
|
180
|
+
export interface TAPAgentListResponse {
|
|
181
|
+
success: boolean;
|
|
182
|
+
agents: TAPAgentResponse[];
|
|
183
|
+
count: number;
|
|
184
|
+
tap_enabled_count: number;
|
|
185
|
+
}
|
|
186
|
+
export interface CreateTAPSessionOptions {
|
|
187
|
+
agent_id: string;
|
|
188
|
+
user_context: string;
|
|
189
|
+
intent: TAPIntent;
|
|
190
|
+
}
|
|
191
|
+
export interface TAPSessionResponse {
|
|
192
|
+
success: boolean;
|
|
193
|
+
session_id: string;
|
|
194
|
+
agent_id: string;
|
|
195
|
+
app_id?: string;
|
|
196
|
+
capabilities?: TAPCapability[];
|
|
197
|
+
intent: TAPIntent;
|
|
198
|
+
created_at?: string;
|
|
199
|
+
expires_at: string;
|
|
200
|
+
time_remaining?: number;
|
|
201
|
+
}
|
|
134
202
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../lib/client/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../lib/client/types.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/index.js
CHANGED
|
@@ -114,3 +114,5 @@ export function solve(problems) {
|
|
|
114
114
|
// ============ EXPORTS ============
|
|
115
115
|
export const botcha = { verify, solve };
|
|
116
116
|
export default botcha;
|
|
117
|
+
// TAP Enhanced Middleware available via:
|
|
118
|
+
// import { tapEnhancedVerify, createTAPVerifyMiddleware, tapVerifyModes } from '@dupecom/botcha/middleware'
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare function generateChallenge(difficulty?: 'easy' | 'medium' | 'hard'): {
|
|
2
|
+
id: string;
|
|
3
|
+
puzzle: string;
|
|
4
|
+
timeLimit: number;
|
|
5
|
+
hint: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function verifyChallenge(id: string, answer: string): {
|
|
8
|
+
valid: boolean;
|
|
9
|
+
reason?: string;
|
|
10
|
+
timeMs?: number;
|
|
11
|
+
};
|
|
12
|
+
export declare function generatePrimes(count: number): number[];
|
|
13
|
+
export declare function isPrime(n: number): boolean;
|
|
14
|
+
declare const _default: {
|
|
15
|
+
generateChallenge: typeof generateChallenge;
|
|
16
|
+
verifyChallenge: typeof verifyChallenge;
|
|
17
|
+
};
|
|
18
|
+
export default _default;
|
|
19
|
+
//# sourceMappingURL=compute.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compute.d.ts","sourceRoot":"","sources":["../../../src/challenges/compute.ts"],"names":[],"mappings":"AAuBA,wBAAgB,iBAAiB,CAAC,UAAU,GAAE,MAAM,GAAG,QAAQ,GAAG,MAAiB,GAAG;IACpF,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd,CAmCA;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG;IAC3D,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CA0BA;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAYtD;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAU1C;;;;;AAED,wBAAsD"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
// In-memory challenge store (use Redis in production)
|
|
3
|
+
const challenges = new Map();
|
|
4
|
+
// Clean up expired challenges periodically
|
|
5
|
+
setInterval(() => {
|
|
6
|
+
const now = Date.now();
|
|
7
|
+
for (const [id, challenge] of challenges) {
|
|
8
|
+
if (challenge.expiresAt < now) {
|
|
9
|
+
challenges.delete(id);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}, 60000);
|
|
13
|
+
export function generateChallenge(difficulty = 'medium') {
|
|
14
|
+
const id = crypto.randomUUID();
|
|
15
|
+
// Different difficulty levels
|
|
16
|
+
const config = {
|
|
17
|
+
easy: { primes: 100, timeLimit: 10000 },
|
|
18
|
+
medium: { primes: 500, timeLimit: 5000 },
|
|
19
|
+
hard: { primes: 1000, timeLimit: 3000 },
|
|
20
|
+
}[difficulty];
|
|
21
|
+
// Random salt makes each challenge unique — precomputed lookup tables won't work
|
|
22
|
+
const salt = crypto.randomUUID().replace(/-/g, '').substring(0, 16);
|
|
23
|
+
// Generate first N primes, concatenate with salt, hash
|
|
24
|
+
const primes = generatePrimes(config.primes);
|
|
25
|
+
const concatenated = primes.join('') + salt;
|
|
26
|
+
const hash = crypto.createHash('sha256').update(concatenated).digest('hex');
|
|
27
|
+
const answer = hash.substring(0, 16); // First 16 chars
|
|
28
|
+
const challenge = {
|
|
29
|
+
id,
|
|
30
|
+
puzzle: `Compute SHA256 of the first ${config.primes} prime numbers concatenated (no separators) followed by the salt "${salt}". Return the first 16 hex characters.`,
|
|
31
|
+
expectedAnswer: answer,
|
|
32
|
+
expiresAt: Date.now() + config.timeLimit + 1000, // Small grace period
|
|
33
|
+
difficulty,
|
|
34
|
+
};
|
|
35
|
+
challenges.set(id, challenge);
|
|
36
|
+
return {
|
|
37
|
+
id,
|
|
38
|
+
puzzle: challenge.puzzle,
|
|
39
|
+
timeLimit: config.timeLimit,
|
|
40
|
+
hint: `Example: First 5 primes + salt = "235711${salt}" → SHA256 → first 16 chars`,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export function verifyChallenge(id, answer) {
|
|
44
|
+
const challenge = challenges.get(id);
|
|
45
|
+
if (!challenge) {
|
|
46
|
+
return { valid: false, reason: 'Challenge not found or expired' };
|
|
47
|
+
}
|
|
48
|
+
const now = Date.now();
|
|
49
|
+
if (now > challenge.expiresAt) {
|
|
50
|
+
challenges.delete(id);
|
|
51
|
+
return { valid: false, reason: 'Challenge expired - too slow!' };
|
|
52
|
+
}
|
|
53
|
+
const isValid = answer.toLowerCase() === challenge.expectedAnswer.toLowerCase();
|
|
54
|
+
// Clean up used challenge
|
|
55
|
+
challenges.delete(id);
|
|
56
|
+
if (!isValid) {
|
|
57
|
+
return { valid: false, reason: 'Incorrect answer' };
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
valid: true,
|
|
61
|
+
timeMs: challenge.expiresAt - now - 1000, // Approximate solve time
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
export function generatePrimes(count) {
|
|
65
|
+
const primes = [];
|
|
66
|
+
let num = 2;
|
|
67
|
+
while (primes.length < count) {
|
|
68
|
+
if (isPrime(num)) {
|
|
69
|
+
primes.push(num);
|
|
70
|
+
}
|
|
71
|
+
num++;
|
|
72
|
+
}
|
|
73
|
+
return primes;
|
|
74
|
+
}
|
|
75
|
+
export function isPrime(n) {
|
|
76
|
+
if (n < 2)
|
|
77
|
+
return false;
|
|
78
|
+
if (n === 2)
|
|
79
|
+
return true;
|
|
80
|
+
if (n % 2 === 0)
|
|
81
|
+
return false;
|
|
82
|
+
for (let i = 3; i <= Math.sqrt(n); i += 2) {
|
|
83
|
+
if (n % i === 0)
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
export default { generateChallenge, verifyChallenge };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate a hybrid challenge: speed + reasoning combined
|
|
3
|
+
* Must solve SHA256 problems in <500ms AND answer reasoning questions
|
|
4
|
+
*/
|
|
5
|
+
export declare function generateHybridChallenge(): {
|
|
6
|
+
id: string;
|
|
7
|
+
speed: {
|
|
8
|
+
problems: {
|
|
9
|
+
num: number;
|
|
10
|
+
operation: string;
|
|
11
|
+
}[];
|
|
12
|
+
timeLimit: number;
|
|
13
|
+
};
|
|
14
|
+
reasoning: {
|
|
15
|
+
questions: {
|
|
16
|
+
id: string;
|
|
17
|
+
question: string;
|
|
18
|
+
category: string;
|
|
19
|
+
}[];
|
|
20
|
+
timeLimit: number;
|
|
21
|
+
};
|
|
22
|
+
instructions: string;
|
|
23
|
+
};
|
|
24
|
+
export declare function verifyHybridChallenge(id: string, speedAnswers: string[], reasoningAnswers: Record<string, string>): {
|
|
25
|
+
valid: boolean;
|
|
26
|
+
reason?: string;
|
|
27
|
+
speed: {
|
|
28
|
+
passed: boolean;
|
|
29
|
+
solveTimeMs?: number;
|
|
30
|
+
reason?: string;
|
|
31
|
+
};
|
|
32
|
+
reasoning: {
|
|
33
|
+
passed: boolean;
|
|
34
|
+
score?: string;
|
|
35
|
+
solveTimeMs?: number;
|
|
36
|
+
reason?: string;
|
|
37
|
+
};
|
|
38
|
+
totalTimeMs?: number;
|
|
39
|
+
};
|
|
40
|
+
declare const _default: {
|
|
41
|
+
generateHybridChallenge: typeof generateHybridChallenge;
|
|
42
|
+
verifyHybridChallenge: typeof verifyHybridChallenge;
|
|
43
|
+
};
|
|
44
|
+
export default _default;
|
|
45
|
+
//# sourceMappingURL=hybrid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hybrid.d.ts","sourceRoot":"","sources":["../../../src/challenges/hybrid.ts"],"names":[],"mappings":"AAsBA;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE;QACL,QAAQ,EAAE;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC/C,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,SAAS,EAAE;QACT,SAAS,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAChE,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,YAAY,EAAE,MAAM,CAAC;CACtB,CA4BA;AAED,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,MAAM,EACV,YAAY,EAAE,MAAM,EAAE,EACtB,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACvC;IACD,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE,SAAS,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACtF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CA2DA;;;;;AAED,wBAAkE"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
import { generateSpeedChallenge, verifySpeedChallenge } from './speed.js';
|
|
3
|
+
import { generateReasoningChallenge, verifyReasoningChallenge } from './reasoning.js';
|
|
4
|
+
const hybridChallenges = new Map();
|
|
5
|
+
// Cleanup expired
|
|
6
|
+
setInterval(() => {
|
|
7
|
+
const now = Date.now();
|
|
8
|
+
for (const [id, c] of hybridChallenges) {
|
|
9
|
+
if (c.expiresAt < now)
|
|
10
|
+
hybridChallenges.delete(id);
|
|
11
|
+
}
|
|
12
|
+
}, 60000);
|
|
13
|
+
/**
|
|
14
|
+
* Generate a hybrid challenge: speed + reasoning combined
|
|
15
|
+
* Must solve SHA256 problems in <500ms AND answer reasoning questions
|
|
16
|
+
*/
|
|
17
|
+
export function generateHybridChallenge() {
|
|
18
|
+
const id = crypto.randomUUID();
|
|
19
|
+
// Generate both sub-challenges
|
|
20
|
+
const speedChallenge = generateSpeedChallenge();
|
|
21
|
+
const reasoningChallenge = generateReasoningChallenge();
|
|
22
|
+
// Store the mapping
|
|
23
|
+
hybridChallenges.set(id, {
|
|
24
|
+
id,
|
|
25
|
+
speedChallengeId: speedChallenge.id,
|
|
26
|
+
reasoningChallengeId: reasoningChallenge.id,
|
|
27
|
+
issuedAt: Date.now(),
|
|
28
|
+
expiresAt: Date.now() + 35000, // 35 seconds total (500ms for speed + 30s for reasoning + buffer)
|
|
29
|
+
});
|
|
30
|
+
return {
|
|
31
|
+
id,
|
|
32
|
+
speed: {
|
|
33
|
+
problems: speedChallenge.challenges,
|
|
34
|
+
timeLimit: speedChallenge.timeLimit,
|
|
35
|
+
},
|
|
36
|
+
reasoning: {
|
|
37
|
+
questions: reasoningChallenge.questions,
|
|
38
|
+
timeLimit: reasoningChallenge.timeLimit,
|
|
39
|
+
},
|
|
40
|
+
instructions: 'Solve ALL speed problems (SHA256) in <500ms AND answer ALL reasoning questions. Submit both together.',
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export function verifyHybridChallenge(id, speedAnswers, reasoningAnswers) {
|
|
44
|
+
const hybrid = hybridChallenges.get(id);
|
|
45
|
+
if (!hybrid) {
|
|
46
|
+
return {
|
|
47
|
+
valid: false,
|
|
48
|
+
reason: 'Hybrid challenge not found or expired',
|
|
49
|
+
speed: { passed: false, reason: 'Challenge not found' },
|
|
50
|
+
reasoning: { passed: false, reason: 'Challenge not found' },
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const now = Date.now();
|
|
54
|
+
const totalTimeMs = now - hybrid.issuedAt;
|
|
55
|
+
// Don't delete yet - we need to verify both parts
|
|
56
|
+
if (now > hybrid.expiresAt) {
|
|
57
|
+
hybridChallenges.delete(id);
|
|
58
|
+
return {
|
|
59
|
+
valid: false,
|
|
60
|
+
reason: 'Hybrid challenge expired',
|
|
61
|
+
speed: { passed: false, reason: 'Expired' },
|
|
62
|
+
reasoning: { passed: false, reason: 'Expired' },
|
|
63
|
+
totalTimeMs,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// Verify speed challenge
|
|
67
|
+
const speedResult = verifySpeedChallenge(hybrid.speedChallengeId, speedAnswers);
|
|
68
|
+
// Verify reasoning challenge
|
|
69
|
+
const reasoningResult = verifyReasoningChallenge(hybrid.reasoningChallengeId, reasoningAnswers);
|
|
70
|
+
// Clean up
|
|
71
|
+
hybridChallenges.delete(id);
|
|
72
|
+
const speedPassed = speedResult.valid;
|
|
73
|
+
const reasoningPassed = reasoningResult.valid;
|
|
74
|
+
const bothPassed = speedPassed && reasoningPassed;
|
|
75
|
+
return {
|
|
76
|
+
valid: bothPassed,
|
|
77
|
+
reason: bothPassed
|
|
78
|
+
? undefined
|
|
79
|
+
: `Failed: ${!speedPassed ? 'speed' : ''}${!speedPassed && !reasoningPassed ? ' + ' : ''}${!reasoningPassed ? 'reasoning' : ''}`,
|
|
80
|
+
speed: {
|
|
81
|
+
passed: speedPassed,
|
|
82
|
+
solveTimeMs: speedResult.solveTimeMs,
|
|
83
|
+
reason: speedResult.reason,
|
|
84
|
+
},
|
|
85
|
+
reasoning: {
|
|
86
|
+
passed: reasoningPassed,
|
|
87
|
+
score: reasoningResult.valid ? `${reasoningResult.correctCount}/${reasoningResult.totalCount}` : undefined,
|
|
88
|
+
solveTimeMs: reasoningResult.solveTimeMs,
|
|
89
|
+
reason: reasoningResult.reason,
|
|
90
|
+
},
|
|
91
|
+
totalTimeMs,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
export default { generateHybridChallenge, verifyHybridChallenge };
|