@private.me/xbind 3.0.3 → 3.1.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.backup DELETED
@@ -1,2121 +0,0 @@
1
- # @private.me/xbind
2
-
3
- ![npm version](https://img.shields.io/npm/v/@private.me/xbind)
4
- ![version](https://img.shields.io/badge/version-3.0.3-blue)
5
- ![tests](https://img.shields.io/badge/tests-2762%20passing-brightgreen)
6
- ![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue)
7
- ![license](https://img.shields.io/badge/license-Proprietary-blue)
8
-
9
- **Authenticated agent-to-agent messaging with post-quantum cryptographic identity.**
10
-
11
- Build AI agents that communicate securely using ML-DSA-65 DID identity, ML-KEM-768 + AES-256-GCM encryption, and information-theoretic split-channel delivery (XorIDA). Every message is signed and encrypted. No API keys, no rotation, no sprawl.
12
-
13
- Part of the **Private.Me** platform—where APIs have keys, but ACIs have identity.
14
-
15
- **Version 3.0.3** — **Major Features:** LoopbackTransport export for testing (GAP-CORE-2), describeSecurityModeStructured export (GAP-API-3), Agent.quickstart() signature fixes. Full Control IP Protection (PLAN-13) - Vault Store architecture with payment-gated algorithm delivery. Store Front (npm) contains Share 1 only, Vault Store (EC2) contains Share 2 (payment-gated). Runtime crypto loading, 4-layer security (DID auth + usage quotas + rate limiting + audit logging). Usage-based model: Free tier 100K ops/month (includes vault access), Pro tier unlimited. Previous v3.0.2: Full Control IP Protection launch. Previous v1.4.2: Runtime compatibility, API enhancements.
16
-
17
- ## Install
18
-
19
- ```bash
20
- # Node.js / TypeScript
21
- npm install @private.me/xbind
22
-
23
- # Python
24
- pip install private-me-xbind
25
- ```
26
-
27
- **Distribution Model:** xBind uses Full Control IP protection (2-share XorIDA). Share 1 (Store Front) is distributed via npm registry. Share 2 (Vault Store) is served via `/api/full-control/share2/:package/:version` and requires payment verification and xBind authentication.
28
-
29
- [Python SDK documentation](./python/README.md) • [Complete docs](./docs/README.md) • [White paper](https://private.me/docs/xbind.html)
30
-
31
- ## Security Notice
32
-
33
- **Post-Quantum Cryptography:** xBind uses `mldsa-wasm@0.0.4` for post-quantum digital signatures (ML-DSA-65/FIPS 204). This package is pre-1.0 beta software. While based on audited upstream cryptography ([PQCA mldsa](https://github.com/dajiaji/mldsa)), it has not been independently audited.
34
-
35
- **Risk Acceptance:** We have accepted this risk for the following reasons:
36
- - Based on NIST FIPS 204 standardized algorithm
37
- - Zero production dependencies (minimal supply chain risk)
38
- - No known CVEs
39
- - Version pinned (not using semver range) for stability
40
-
41
- **Migration Plan:** We plan to migrate to [@noble/post-quantum](https://www.npmjs.com/package/@noble/post-quantum) in Q4 2026 (xBind v2.0.0), which offers broader ecosystem support and maturity.
42
-
43
- For production deployments requiring formal cryptographic assurance, please contact contact@private.me for enterprise options.
44
-
45
- ## Secure Key Storage
46
-
47
- **⚠️ CRITICAL SECURITY WARNING:** All post-quantum cryptography in xBind is undermined if seeds/keys are stored in plaintext.
48
-
49
- ### ❌ NEVER Store Keys in Plaintext
50
-
51
- **Dangerous practices that expose your identity:**
52
-
53
- <!-- ANTI-PATTERN -->
54
- ```typescript
55
- // ❌ WRONG: Plaintext file storage
56
- const seed = agent.exportSeeds();
57
- fs.writeFileSync('seed.txt', seed); // Readable by any process
58
- fs.writeFileSync('.env', `XBIND_SEED=${seed}`); // Committed to git by accident
59
- localStorage.setItem('seed', seed); // Accessible to XSS attacks
60
-
61
- // ❌ WRONG: Hardcoded in source code
62
- const agent = await Agent.fromSeed('0123456789abcdef...'); // Visible in repository
63
-
64
- // ❌ WRONG: Unencrypted database
65
- await db.run('INSERT INTO config VALUES (?, ?)', ['seed', seed]); // SQL injection risk
66
- ```
67
- <!-- /ANTI-PATTERN -->
68
-
69
- **Why this is critical:**
70
- - **Identity Theft**: Attacker gains your DID and can impersonate your agent
71
- - **Message Decryption**: All past and future messages can be decrypted
72
- - **Billing Fraud**: Attacker can exhaust your quota or make unauthorized charges
73
- - **Post-Quantum Broken**: ML-KEM and ML-DSA offer no protection if seed is leaked
74
-
75
- ### ✅ Use OS-Level Keystore APIs
76
-
77
- **Recommended secure storage by platform:**
78
-
79
- #### macOS: Keychain Services
80
-
81
- <!-- SNIPPET -->
82
- ```typescript
83
- import { exec } from 'node:child_process';
84
- import { promisify } from 'node:util';
85
- const execAsync = promisify(exec);
86
-
87
- // Store seed in macOS Keychain
88
- async function storeSeed(seed: string): Promise<void> {
89
- await execAsync(
90
- `security add-generic-password -a xbind -s "xBind Agent Seed" -w "${seed}" -U`
91
- );
92
- }
93
-
94
- // Retrieve seed from macOS Keychain
95
- async function getSeed(): Promise<string> {
96
- const { stdout } = await execAsync(
97
- 'security find-generic-password -a xbind -s "xBind Agent Seed" -w'
98
- );
99
- return stdout.trim();
100
- }
101
-
102
- // Create agent from keychain
103
- import { Agent, HttpTrustRegistry, HttpsTransportAdapter } from '@private.me/xbind';
104
-
105
- const seed = await getSeed();
106
- const result = await Agent.fromSeed(Buffer.from(seed, 'hex'), {
107
- registry: new HttpTrustRegistry({ baseUrl: 'https://private.me/registry' }),
108
- transport: new HttpsTransportAdapter({ baseUrl: 'https://private.me/relay' }),
109
- postQuantumSig: false
110
- });
111
-
112
- if (!result.ok) {
113
- throw new Error(`Failed to create agent: ${result.error.message}`);
114
- }
115
-
116
- const agent = result.value;
117
- ```
118
- <!-- /SNIPPET -->
119
-
120
- #### Windows: Credential Manager (DPAPI)
121
-
122
- <!-- SNIPPET -->
123
- ```typescript
124
- // Using keytar package for cross-platform keychain access
125
- import keytar from 'keytar';
126
-
127
- // Store seed in Windows Credential Manager
128
- await keytar.setPassword('xbind', 'agent-seed', seed);
129
-
130
- // Retrieve seed from Windows Credential Manager
131
- import { Agent, HttpTrustRegistry, HttpsTransportAdapter } from '@private.me/xbind';
132
-
133
- const seed = await keytar.getPassword('xbind', 'agent-seed');
134
- if (!seed) throw new Error('Seed not found in credential store');
135
-
136
- const result = await Agent.fromSeed(Buffer.from(seed, 'hex'), {
137
- registry: new HttpTrustRegistry({ baseUrl: 'https://private.me/registry' }),
138
- transport: new HttpsTransportAdapter({ baseUrl: 'https://private.me/relay' }),
139
- postQuantumSig: false
140
- });
141
-
142
- if (!result.ok) {
143
- throw new Error(`Failed to create agent: ${result.error.message}`);
144
- }
145
-
146
- const agent = result.value;
147
- ```
148
- <!-- /SNIPPET -->
149
-
150
- #### Linux: Secret Service API (gnome-keyring, KWallet)
151
-
152
- <!-- SNIPPET -->
153
- ```typescript
154
- import keytar from 'keytar';
155
-
156
- // Store seed in Secret Service (libsecret)
157
- await keytar.setPassword('xbind', 'agent-seed', seed);
158
-
159
- // Retrieve seed from Secret Service
160
- import { Agent, HttpTrustRegistry, HttpsTransportAdapter } from '@private.me/xbind';
161
-
162
- const seed = await keytar.getPassword('xbind', 'agent-seed');
163
- if (!seed) throw new Error('Seed not found in Secret Service');
164
-
165
- const result = await Agent.fromSeed(Buffer.from(seed, 'hex'), {
166
- registry: new HttpTrustRegistry({ baseUrl: 'https://private.me/registry' }),
167
- transport: new HttpsTransportAdapter({ baseUrl: 'https://private.me/relay' }),
168
- postQuantumSig: false
169
- });
170
-
171
- if (!result.ok) {
172
- throw new Error(`Failed to create agent: ${result.error.message}`);
173
- }
174
-
175
- const agent = result.value;
176
- ```
177
- <!-- /SNIPPET -->
178
-
179
- **Cross-platform library:**
180
- ```bash
181
- npm install keytar # Unified API for macOS/Windows/Linux keystores
182
- ```
183
-
184
- ### 🏢 Production: Hardware Security Modules (HSM)
185
-
186
- For production deployments with compliance requirements (PCI-DSS, HIPAA, SOC 2):
187
-
188
- <!-- SNIPPET -->
189
- ```typescript
190
- // Using AWS CloudHSM or Azure Key Vault
191
- import { KMSClient, DecryptCommand } from '@aws-sdk/client-kms';
192
-
193
- const kms = new KMSClient({ region: 'us-west-2' });
194
-
195
- // Encrypt seed with KMS (one-time setup)
196
- const encryptedSeed = await kms.send(new EncryptCommand({
197
- KeyId: 'arn:aws:kms:us-west-2:...',
198
- Plaintext: Buffer.from(seed)
199
- }));
200
-
201
- // Store encrypted seed in database (safe)
202
- await db.run('INSERT INTO config VALUES (?, ?)', ['seed', encryptedSeed.CiphertextBlob]);
203
-
204
- // Decrypt seed with KMS at runtime
205
- import { Agent, HttpTrustRegistry, HttpsTransportAdapter } from '@private.me/xbind';
206
-
207
- const decryptedSeed = await kms.send(new DecryptCommand({
208
- CiphertextBlob: encryptedSeedFromDB
209
- }));
210
-
211
- const result = await Agent.fromSeed(Buffer.from(decryptedSeed.Plaintext), {
212
- registry: new HttpTrustRegistry({ baseUrl: 'https://private.me/registry' }),
213
- transport: new HttpsTransportAdapter({ baseUrl: 'https://private.me/relay' }),
214
- postQuantumSig: false
215
- });
216
-
217
- if (!result.ok) {
218
- throw new Error(`Failed to create agent: ${result.error.message}`);
219
- }
220
-
221
- const agent = result.value;
222
- ```
223
- <!-- /SNIPPET -->
224
-
225
- **HSM Benefits:**
226
- - **FIPS 140-2 Level 3** certified hardware
227
- - **Tamper-evident**: Keys destroyed if physical breach detected
228
- - **Audit logging**: All key access operations logged
229
- - **Access control**: IAM policies restrict who can decrypt
230
-
231
- ### 📋 Key Storage Best Practices
232
-
233
- 1. **Encrypt at Rest**: If storing in database/filesystem, use AES-256-GCM with a separate encryption key
234
- 2. **Least Privilege**: Only the agent process should have access to the seed
235
- 3. **Rotation**: Plan for key rotation (see Succession API section)
236
- 4. **Backup**: Encrypted backups to separate storage (3-2-1 rule)
237
- 5. **Monitoring**: Alert on unauthorized seed access attempts
238
- 6. **Destruction**: Securely wipe seeds when decommissioning agents
239
-
240
- ### 🔒 Environment Variable Security
241
-
242
- If you MUST use environment variables (not recommended):
243
-
244
- ```bash
245
- # ✅ Better: Encrypted environment variable (AWS Secrets Manager)
246
- export XBIND_SEED=$(aws secretsmanager get-secret-value --secret-id xbind-seed --query SecretString --output text)
247
-
248
- # ❌ Avoid: Plaintext in shell history
249
- export XBIND_SEED="0123456789abcdef..." # Visible in ~/.bash_history
250
- ```
251
-
252
- **Limitations of environment variables:**
253
- - Visible to all processes (ps, /proc/PID/environ)
254
- - Logged by process managers (systemd, Docker logs)
255
- - Inherited by child processes
256
- - Difficult to rotate without restart
257
-
258
- ### 🚨 Incident Response
259
-
260
- **If your seed is compromised:**
261
-
262
- 1. **Revoke immediately**: Use the Succession API to rotate to a new identity
263
- 2. **Audit access**: Check all messages sent/received during exposure window
264
- 3. **Notify recipients**: Inform peers to distrust the old DID
265
- 4. **Update registry**: Register new DID, revoke old DID
266
- 5. **Forensics**: Determine how seed was leaked to prevent recurrence
267
-
268
- **Contact contact@private.me for incident assistance** (24-hour SLA for Pro/VIP tiers).
269
-
270
- ---
271
-
272
- ## Dependencies
273
-
274
- xBind requires the following runtime dependencies for cryptographic operations and network communication:
275
-
276
- ### Post-Quantum Cryptography
277
-
278
- - **mlkem** — Post-quantum key encapsulation mechanism (ML-KEM-768, FIPS 203)
279
- - Purpose: Quantum-resistant key agreement for message encryption
280
- - Security: NIST-approved lattice-based cryptography, 192-bit security level
281
- - Usage: Establishes shared secrets between agents resistant to quantum attacks
282
-
283
- - **mldsa-wasm@0.0.4** — Post-quantum digital signatures (ML-DSA-65, FIPS 204)
284
- - Purpose: Quantum-resistant DID identity and message signing
285
- - Security: NIST-approved lattice-based signatures, 192-bit security level
286
- - Usage: Signs all agent messages and verifies peer identity
287
-
288
- ### Network Communication
289
-
290
- - **bonjour-service** — mDNS service discovery (Peer Discovery model)
291
- - Purpose: Zero-configuration local network device pairing
292
- - Security: LAN-only discovery with user confirmation and cryptographic verification
293
- - Usage: Enables IoT devices and offline pairing without internet connectivity
294
-
295
- - **nodemailer@8.0.7** — Email transport for invitation delivery
296
- - Purpose: Delivers single-use invite codes for customer onboarding
297
- - Security: 6-character codes with 24-hour TTL, rate-limited generation
298
- - Usage: Supports Invite Code connection model for remote agent pairing
299
-
300
- ### Internal Dependencies (Bundled)
301
-
302
- The following @private.me/* packages are bundled into xBind's distribution and do not require separate installation:
303
-
304
- - **@private.me/shared** — Core types and Result<T,E> error handling primitives
305
- - **@private.me/crypto** — XorIDA threshold sharing, HMAC verification, cryptographic primitives
306
- - **@private.me/xchange** — Transport envelope formatting and message serialization
307
- - **@private.me/ux-helpers** — Abuse prevention and rate limiting utilities
308
- - **@private.me/xregistry** — Trust registry interface and DID resolution
309
-
310
- These dependencies are compiled into `dist-standalone/` with relative import paths. Users install xBind as a single package - no separate installation of building blocks required.
311
-
312
- All cryptographic dependencies are production-grade implementations. No test or mock crypto is used in production builds.
313
-
314
- ## Setup & Configuration
315
-
316
- ### Environment Variables
317
-
318
- #### FULL_CONTROL_MASTER_KEY (Required)
319
-
320
- **Critical for Production:** This key is required for Share 2 decryption in the Full Control vault store. Without it, the package cannot access proprietary XorIDA algorithms.
321
-
322
- ```bash
323
- # Generate a new key (one-time setup)
324
- openssl rand -base64 32
325
-
326
- # Set in your environment
327
- export FULL_CONTROL_MASTER_KEY="<generated-key-here>"
328
-
329
- # Verify length (should be 44 characters)
330
- echo ${#FULL_CONTROL_MASTER_KEY}
331
- ```
332
-
333
- **Key Details:**
334
- - **Purpose:** Master key for Share 2 decryption in Full Control vault store
335
- - **Format:** 32-byte random value, base64-encoded (44 characters)
336
- - **When Required:**
337
- - ✅ Required in production for Full Control operations
338
- - ✅ Required for server health checks to pass
339
- - ⚠️ Optional for basic testing (package will use fallback behavior)
340
- - **Security:** Store in `.env` file with `chmod 600` permissions
341
- - **Validation:** Server health check at `/aci/billing/health` validates this key
342
-
343
- **Troubleshooting:**
344
-
345
- If you see errors like `FULL_CONTROL_MASTER_KEY not configured` or `Share 2 decryption failed`:
346
- 1. Verify the key is set: `echo $FULL_CONTROL_MASTER_KEY`
347
- 2. Check the length is exactly 44 characters
348
- 3. Ensure `.env` file is loaded (if using dotenv)
349
- 4. Verify file permissions: `chmod 600 .env`
350
- 5. For production deployments, confirm the key is set in your deployment configuration
351
-
352
- See [Configuration Guide](./docs/configuration.md) for complete setup instructions and advanced configuration options.
353
-
354
- ## Pricing
355
-
356
- **Free tier available** — No credit card required.
357
-
358
- See [pricing details](../../docs/pricing-reference.md) for current rates and tier comparison.
359
-
360
- [Subscribe now](https://private.me/subscribe?product=xbind)
361
-
362
- ## Quick Start
363
-
364
- **Complete setup in under 2 minutes:**
365
-
366
- ### Step 1: Email Verification (Required)
367
-
368
- **ALL API calls are blocked until you verify your email address.** This links your usage to a verified contact for security notifications and billing.
369
-
370
- ```bash
371
- npx xbind setup --email user@example.com
372
- ```
373
-
374
- **What happens:**
375
- 1. **DID Generation**: Creates Ed25519 cryptographic identity (did:key:z6Mk...)
376
- 2. **DeploymentID Creation**: Generates persistent economic identity (DEP-202605-XXXXXXXXXX)
377
- 3. **Email Code Delivery**: Sends 6-digit verification code to your email
378
- 4. **Code Verification**: Enter code to link email to DeploymentID
379
- 5. **Identity Storage**: Saves to `~/.xbind/identity.json` (chmod 600)
380
- 6. **Ready to Use**: No additional configuration needed
381
-
382
- **Dual-Mode Verification:**
383
- - **CLI/Programmatic**: 6-digit code (this method)
384
- - **Web/Browser**: Magic link (auto-verifies on click)
385
-
386
- **Command Options:**
387
- ```bash
388
- npx xbind setup --email user@example.com # Standard setup
389
- npx xbind setup --email user@example.com --force # Overwrite existing identity
390
- npx xbind setup --dev # Development mode (mock email provider)
391
- ```
392
-
393
- **Security Notes:**
394
- - Disposable email services blocked (Mailinator, Guerrilla Mail, etc.)
395
- - Device fingerprinting active (100+ signals for abuse prevention)
396
- - DID ≠ DeploymentID (see Identity Model section below)
397
-
398
- ---
399
-
400
- ### Identity Model: DID vs DeploymentID
401
-
402
- **Two complementary identities for different purposes:**
403
-
404
- #### DID (Decentralized Identifier)
405
- - **Format**: `did:key:z6Mk...` (Ed25519 public key)
406
- - **Purpose**: Cryptographic authentication (message signing)
407
- - **Lifespan**: Ephemeral - can be rotated for security
408
- - **Use case**: Proving "I sent this message"
409
- - **Storage**: `~/.xbind/identity.json` (local only)
410
-
411
- #### DeploymentID (Persistent Economic Identity)
412
- - **Format**: `DEP-YYYYMM-XXXXXXXXXX` (month prefix + 10 hex digits)
413
- - **Purpose**: Billing and usage tracking (persistent across DIDs)
414
- - **Lifespan**: Permanent - never changes for your account
415
- - **Use case**: "This deployment used 50K operations this month"
416
- - **Prevents**: Economic state reset attacks (DID rotation to bypass usage limits)
417
-
418
- **Why Both?**
419
- - **Security**: Rotate DID without losing billing history
420
- - **Privacy**: DID is pseudonymous, DeploymentID links to verified email
421
- - **Billing**: Usage tracked by DeploymentID, even if DID changes
422
- - **Attack Prevention**: Cannot reset free tier quota by generating new DID
423
-
424
- **Example:**
425
- ```
426
- User creates account:
427
- - DID: did:key:z6MkABC123... (for signing messages)
428
- - DeploymentID: DEP-202605-7F3A2B1C (for billing)
429
-
430
- User rotates DID for security:
431
- - DID: did:key:z6MkXYZ789... (NEW cryptographic identity)
432
- - DeploymentID: DEP-202605-7F3A2B1C (SAME billing identity)
433
- - Usage history: Preserved ✅
434
- - Free tier quota: Cannot reset ✅
435
- ```
436
-
437
- ---
438
-
439
- ### Device Fingerprinting & Privacy
440
-
441
- **xBind collects device fingerprints for abuse prevention:**
442
-
443
- **What We Collect (100+ Signals):**
444
- 1. **Browser**: User agent, language, timezone, screen resolution
445
- 2. **OS**: Platform, CPU cores, memory (approximate)
446
- 3. **Hardware**: GPU vendor, audio context, canvas fingerprint
447
- 4. **Network**: IP address (hashed), connection type
448
- 5. **Behavior**: Timing patterns, interaction signals
449
- 6. **Fonts**: Installed font list (system fingerprint)
450
-
451
- **Why We Collect:**
452
- - Detect multi-accounting (creating unlimited free accounts)
453
- - Identify coordinated abuse patterns
454
- - Link DeploymentIDs across devices (same user, different machines)
455
- - Risk scoring (0-100 scale, manual review ≥70)
456
-
457
- **Privacy Protections:**
458
- - **SHA-256 hashed**: Fingerprints stored as hashes, not raw data
459
- - **No PII**: Individual signals don't identify you personally
460
- - **GDPR compliant**: Right to access, deletion, opt-out
461
- - **Minimization**: Only signals necessary for abuse detection
462
- - **Retention**: 90 days for fingerprints, 30 days for raw signals
463
-
464
- **Opt-Out:**
465
- Email contact@private.me with subject "Fingerprint Opt-Out" and your DeploymentID. Note: Opting out may trigger manual review for new accounts.
466
-
467
- **Transparency:**
468
- Full fingerprinting source code available at `apps/server/src/device-fingerprinting.ts`
469
-
470
- **Note:** Disposable email services (Mailinator, Guerrilla Mail, etc.) are blocked. Use a real email address.
471
-
472
- ### Step 2: Create Agent & Send Messages
473
-
474
- ```typescript
475
- import { Agent } from '@private.me/xbind';
476
-
477
- // Create agent (auto-generates cryptographic identity, throws on error)
478
- const agent = await Agent.quickstart({ name: 'my-service' });
479
-
480
- // Send authenticated message
481
- const sendResult = await agent.send({
482
- to: 'did:key:z6Mk...', // recipient DID
483
- payload: { action: 'createCharge', amount: 100 },
484
- scope: 'billing'
485
- });
486
-
487
- if (!sendResult.ok) {
488
- console.error(`Failed: ${sendResult.error}`);
489
- return;
490
- }
491
-
492
- console.log('Message sent with cryptographic identity');
493
- console.log('Agent DID:', agent.did);
494
- ```
495
-
496
- ### Step 3: Understand Your Free Tier
497
-
498
- - **100,000 operations/month** (free tier)
499
- - **120,000 hard cap** (20% grace buffer)
500
- - **Monthly reset:** 1st of each month at 00:00 UTC
501
- - **Milestone emails:** Sent at 50%, 80%, 100%, 120% usage
502
-
503
- **At 100K operations:** Email verification enforced (if not already verified)
504
- **At 120K operations:** Hard cap reached. Upgrade to Pro for unlimited operations.
505
-
506
- **Prerequisites:** The `FULL_CONTROL_MASTER_KEY` environment variable is required for Share 2 operations in production but optional for basic testing. See [Environment Variables](#environment-variables) for setup.
507
-
508
- **JITR (Just-in-Time Registration):** Agents created with `Agent.fromSeed()` automatically register with the trust registry on first use. No manual registration scripts required. Includes all encryption keys (Ed25519, X25519, ML-KEM, ML-DSA) for zero-config encrypted messaging.
509
-
510
- [More examples](./docs/examples.md) • [Python examples](./python/README.md)
511
-
512
- ## Programmatic Quickstart
513
-
514
- **Complete, copy-paste ready examples** tested in clean environments:
515
-
516
- ### Example 1: Create Agent & Get DID
517
-
518
- <!-- RUNNABLE-EXAMPLE -->
519
- ```typescript
520
- import { Agent } from '@private.me/xbind';
521
-
522
- // Create agent with automatic identity generation
523
- const agent = await Agent.quickstart({ name: 'test-agent' });
524
-
525
- console.log('Agent DID:', agent.did);
526
- console.log('Agent name:', agent.name);
527
- ```
528
- <!-- /RUNNABLE-EXAMPLE -->
529
-
530
- **Expected output:**
531
- ```
532
- Agent DID: did:key:z6Mk...
533
- Agent name: test-agent
534
- ```
535
-
536
- ### Example 2: Agent Identity Details
537
-
538
- <!-- RUNNABLE-EXAMPLE -->
539
- ```typescript
540
- import { Agent } from '@private.me/xbind';
541
-
542
- // Create agent
543
- const agent = await Agent.quickstart({ name: 'identity-test' });
544
-
545
- // Access identity information
546
- console.log('DID:', agent.did);
547
- console.log('Has Ed25519 keys:', !!agent.identity.publicKey);
548
- console.log('Has X25519 keys:', !!agent.identity.x25519PublicKey);
549
- console.log('Has ML-KEM keys:', !!agent.identity.mlKemPublicKey);
550
- ```
551
- <!-- /RUNNABLE-EXAMPLE -->
552
-
553
- **Expected output:**
554
- ```
555
- DID: did:key:z6Mk...
556
- Has Ed25519 keys: true
557
- Has X25519 keys: true
558
- Has ML-KEM keys: true
559
- ```
560
-
561
- ### Example 3: Registry & Transport Configuration
562
-
563
- <!-- RUNNABLE-EXAMPLE -->
564
- ```typescript
565
- import { Agent } from '@private.me/xbind';
566
-
567
- // Quickstart uses defaults: MemoryRegistry + HttpsTransport
568
- const agent = await Agent.quickstart({ name: 'config-test' });
569
-
570
- // Check configuration
571
- console.log('Registry type:', agent.registry.constructor.name);
572
- console.log('Transports count:', agent.transports.length);
573
- console.log('Transport type:', agent.transports[0].constructor.name);
574
- ```
575
- <!-- /RUNNABLE-EXAMPLE -->
576
-
577
- **Expected output:**
578
- ```
579
- Registry type: MemoryTrustRegistry
580
- Transports count: 1
581
- Transport type: HttpsTransportAdapter
582
- ```
583
-
584
- **Note:** These examples work immediately after `npm install @private.me/xbind`. Email verification is NOT required for basic agent creation and local operations. Verification is enforced when:
585
- - Sending messages to other agents
586
- - Exceeding 100K operations/month
587
- - Accessing production features
588
-
589
- [More examples](./docs/examples.md) • [Python examples](./python/README.md)
590
-
591
- ## Post-Quantum Cryptography & Envelopes
592
-
593
- **Complete examples for ML-DSA signatures, key export, and envelope operations:**
594
-
595
- ### Example 4: ML-DSA-65 Signing and Verification
596
-
597
- <!-- RUNNABLE-EXAMPLE -->
598
- ```typescript
599
- import { Agent, signMlDsa65, verifyMlDsa65 } from '@private.me/xbind';
600
-
601
- // Create agent with post-quantum signatures enabled
602
- const agent = await Agent.quickstart({
603
- name: 'pq-test',
604
- postQuantumSig: true
605
- });
606
-
607
- // Sign data with ML-DSA-65
608
- const data = new TextEncoder().encode('Critical transaction data');
609
- const mlDsaSecretKey = agent.identity.mlDsaSecretKey;
610
-
611
- if (!mlDsaSecretKey) {
612
- throw new Error('ML-DSA keys not available');
613
- }
614
-
615
- const signResult = await signMlDsa65(mlDsaSecretKey, data);
616
- if (!signResult.ok) {
617
- throw new Error(`Signing failed: ${signResult.error}`);
618
- }
619
-
620
- console.log('ML-DSA-65 signature length:', signResult.value.length); // 3309 bytes
621
-
622
- // Verify signature
623
- const mlDsaPublicKey = agent.identity.mlDsaPublicKey!;
624
- const verifyResult = await verifyMlDsa65(mlDsaPublicKey, signResult.value, data);
625
-
626
- if (verifyResult.ok && verifyResult.value) {
627
- console.log('Post-quantum signature verified successfully');
628
- } else {
629
- console.error('Signature verification failed');
630
- }
631
- ```
632
- <!-- /RUNNABLE-EXAMPLE -->
633
-
634
- **Expected output:**
635
- ```
636
- ML-DSA-65 signature length: 3309
637
- Post-quantum signature verified successfully
638
- ```
639
-
640
- ### Example 5: Export Post-Quantum Keys
641
-
642
- <!-- RUNNABLE-EXAMPLE -->
643
- ```typescript
644
- import {
645
- Agent,
646
- exportMlDsaSecretKey,
647
- exportMlDsaPublicKey,
648
- exportMlKemSecretKey,
649
- exportMlKemPublicKey
650
- } from '@private.me/xbind';
651
-
652
- // Create agent with post-quantum cryptography
653
- const agent = await Agent.quickstart({
654
- name: 'export-test',
655
- postQuantumSig: true
656
- });
657
-
658
- // Export ML-DSA keys (signatures)
659
- const mlDsaSecret = exportMlDsaSecretKey(agent.identity);
660
- const mlDsaPublic = exportMlDsaPublicKey(agent.identity);
661
-
662
- console.log('ML-DSA-65 secret key:', mlDsaSecret ? `${mlDsaSecret.length} bytes` : 'N/A');
663
- console.log('ML-DSA-65 public key:', mlDsaPublic ? `${mlDsaPublic.length} bytes` : 'N/A');
664
-
665
- // Export ML-KEM keys (encryption)
666
- const mlKemSecret = exportMlKemSecretKey(agent.identity);
667
- const mlKemPublic = exportMlKemPublicKey(agent.identity);
668
-
669
- console.log('ML-KEM-768 secret key:', mlKemSecret ? `${mlKemSecret.length} bytes` : 'N/A');
670
- console.log('ML-KEM-768 public key:', mlKemPublic ? `${mlKemPublic.length} bytes` : 'N/A');
671
- ```
672
- <!-- /RUNNABLE-EXAMPLE -->
673
-
674
- **Expected output:**
675
- ```
676
- ML-DSA-65 secret key: 32 bytes
677
- ML-DSA-65 public key: 1952 bytes
678
- ML-KEM-768 secret key: 2400 bytes
679
- ML-KEM-768 public key: 1184 bytes
680
- ```
681
-
682
- ### Example 6: Key Rotation with Backward Compatibility
683
-
684
- <!-- RUNNABLE-EXAMPLE -->
685
- ```typescript
686
- import { Agent, rotateKeys } from '@private.me/xbind';
687
-
688
- // Create agent
689
- const agent = await Agent.quickstart({ name: 'rotation-test' });
690
-
691
- // Store original X25519 public key
692
- const originalX25519 = Buffer.from(agent.identity.rawX25519PublicKey).toString('hex');
693
-
694
- // Rotate encryption keys (X25519 + ML-KEM)
695
- const rotatedResult = await rotateKeys(agent.identity);
696
-
697
- if (!rotatedResult.ok) {
698
- throw new Error(`Key rotation failed: ${rotatedResult.error}`);
699
- }
700
-
701
- const rotatedIdentity = rotatedResult.value;
702
-
703
- // New keys are active
704
- const newX25519 = Buffer.from(rotatedIdentity.rawX25519PublicKey).toString('hex');
705
- console.log('Keys rotated successfully');
706
- console.log('Original X25519:', originalX25519.substring(0, 16) + '...');
707
- console.log('New X25519:', newX25519.substring(0, 16) + '...');
708
-
709
- // Old keys preserved for decryption
710
- console.log('Rotation history:', rotatedIdentity.rotatedKeys?.length ?? 0);
711
- console.log('DID unchanged:', agent.identity.did === rotatedIdentity.did);
712
- ```
713
- <!-- /RUNNABLE-EXAMPLE -->
714
-
715
- **Expected output:**
716
- ```
717
- Keys rotated successfully
718
- Original X25519: a1b2c3d4e5f6g7h8...
719
- New X25519: 9i0j1k2l3m4n5o6p...
720
- Rotation history: 1
721
- DID unchanged: true
722
- ```
723
-
724
- ### Example 7: Create V1 Envelope (Classical Crypto)
725
-
726
- <!-- RUNNABLE-EXAMPLE -->
727
- ```typescript
728
- import { Agent, createEnvelope, generateSharedKey } from '@private.me/xbind';
729
-
730
- // Generate shared AES-256-GCM key
731
- const sharedKey = await generateSharedKey();
732
-
733
- // Create agent
734
- const agent = await Agent.quickstart({ name: 'envelope-test' });
735
-
736
- // Create encrypted envelope
737
- const plaintext = new TextEncoder().encode(JSON.stringify({
738
- action: 'transfer',
739
- amount: 1000
740
- }));
741
-
742
- const envelopeResult = await createEnvelope({
743
- senderDid: agent.did,
744
- recipientDid: 'did:key:z6MkRecipient...',
745
- scope: 'billing:write',
746
- plaintext,
747
- privateKey: agent.identity.privateKey,
748
- sharedKey
749
- });
750
-
751
- if (!envelopeResult.ok) {
752
- throw new Error(`Envelope creation failed: ${envelopeResult.error}`);
753
- }
754
-
755
- const envelope = envelopeResult.value;
756
- console.log('Envelope version:', envelope.v);
757
- console.log('Algorithm:', envelope.alg);
758
- console.log('Signature length:', envelope.signature.length);
759
- console.log('Encrypted payload:', envelope.payload.substring(0, 32) + '...');
760
- ```
761
- <!-- /RUNNABLE-EXAMPLE -->
762
-
763
- **Expected output:**
764
- ```
765
- Envelope version: 1
766
- Algorithm: Ed25519
767
- Signature length: 88
768
- Encrypted payload: aGVsbG8gd29ybGQgdGhpcyBpcyBhIHRl...
769
- ```
770
-
771
- ### Example 8: Create V2 Envelope (Hybrid KEM)
772
-
773
- <!-- RUNNABLE-EXAMPLE -->
774
- ```typescript
775
- import { Agent, createEnvelopeV2, generateSharedKey } from '@private.me/xbind';
776
- import { createMlKem768 } from 'mlkem';
777
-
778
- // Generate shared AES-256-GCM key
779
- const sharedKey = await generateSharedKey();
780
-
781
- // Generate ephemeral X25519 keypair
782
- const x25519Pair = await crypto.subtle.generateKey(
783
- { name: 'X25519' },
784
- true,
785
- ['deriveBits']
786
- );
787
- const ephemeralPub = new Uint8Array(
788
- await crypto.subtle.exportKey('raw', x25519Pair.publicKey)
789
- );
790
-
791
- // Generate ML-KEM-768 ciphertext (mocked for example)
792
- const mlkem = await createMlKem768();
793
- const recipientMlKemPub = mlkem.generateKeyPair()[0]; // Mock recipient public key
794
- const [kemCiphertext] = mlkem.encap(recipientMlKemPub);
795
-
796
- const agent = await Agent.quickstart({ name: 'v2-envelope-test' });
797
-
798
- const envelope = await createEnvelopeV2({
799
- senderDid: agent.did,
800
- recipientDid: 'did:key:z6MkRecipient...',
801
- scope: 'messaging',
802
- plaintext: new TextEncoder().encode('Hybrid KEM message'),
803
- privateKey: agent.identity.privateKey,
804
- sharedKey,
805
- ephemeralPublicKey: ephemeralPub,
806
- kemCiphertext
807
- });
808
-
809
- if (envelope.ok) {
810
- console.log('Envelope version:', envelope.value.v);
811
- console.log('KEM mode:', envelope.value.kem);
812
- console.log('ML-KEM ciphertext length:', envelope.value.kemCiphertext.length);
813
- }
814
- ```
815
- <!-- /RUNNABLE-EXAMPLE -->
816
-
817
- **Expected output:**
818
- ```
819
- Envelope version: 2
820
- KEM mode: X25519-MLKEM768
821
- ML-KEM ciphertext length: 1452
822
- ```
823
-
824
- ### Example 9: Create V3 Envelope (Dual Signatures)
825
-
826
- <!-- RUNNABLE-EXAMPLE -->
827
- ```typescript
828
- import { Agent, createEnvelopeV3, generateSharedKey } from '@private.me/xbind';
829
- import { createMlKem768 } from 'mlkem';
830
-
831
- // Create agent with ML-DSA enabled
832
- const agent = await Agent.quickstart({
833
- name: 'v3-envelope-test',
834
- postQuantumSig: true
835
- });
836
-
837
- if (!agent.identity.mlDsaSecretKey) {
838
- throw new Error('ML-DSA keys required for V3 envelopes');
839
- }
840
-
841
- // Generate shared key and KEM materials
842
- const sharedKey = await generateSharedKey();
843
- const x25519Pair = await crypto.subtle.generateKey(
844
- { name: 'X25519' },
845
- true,
846
- ['deriveBits']
847
- );
848
- const ephemeralPub = new Uint8Array(
849
- await crypto.subtle.exportKey('raw', x25519Pair.publicKey)
850
- );
851
-
852
- const mlkem = await createMlKem768();
853
- const recipientMlKemPub = mlkem.generateKeyPair()[0];
854
- const [kemCiphertext] = mlkem.encap(recipientMlKemPub);
855
-
856
- const envelope = await createEnvelopeV3({
857
- senderDid: agent.did,
858
- recipientDid: 'did:key:z6MkRecipient...',
859
- scope: 'high-security',
860
- plaintext: new TextEncoder().encode('Dual-signature message'),
861
- privateKey: agent.identity.privateKey,
862
- sharedKey,
863
- ephemeralPublicKey: ephemeralPub,
864
- kemCiphertext,
865
- mlDsaSecretKey: agent.identity.mlDsaSecretKey
866
- });
867
-
868
- if (envelope.ok) {
869
- console.log('Envelope version:', envelope.value.v);
870
- console.log('Signature scheme:', envelope.value.sig);
871
- console.log('Ed25519 signature:', envelope.value.signature.substring(0, 16) + '...');
872
- console.log('ML-DSA signature:', envelope.value.pqSignature.substring(0, 16) + '...');
873
- }
874
- ```
875
- <!-- /RUNNABLE-EXAMPLE -->
876
-
877
- **Expected output:**
878
- ```
879
- Envelope version: 3
880
- Signature scheme: Ed25519+MLDSA65
881
- Ed25519 signature: SGVsbG8gd29ybGQ...
882
- ML-DSA signature: cG9zdC1xdWFudHV...
883
- ```
884
-
885
- ### Example 10: Create V4 Envelope (Xchange Mode)
886
-
887
- <!-- RUNNABLE-EXAMPLE -->
888
- ```typescript
889
- import { Agent, createEnvelopeV4 } from '@private.me/xbind';
890
-
891
- const agent = await Agent.quickstart({ name: 'xchange-test' });
892
-
893
- // Xchange mode: Share data is the payload (no encryption layer)
894
- const shareData = new TextEncoder().encode('XorIDA share data');
895
-
896
- const envelope = await createEnvelopeV4({
897
- senderDid: agent.did,
898
- recipientDid: 'did:key:z6MkRecipient...',
899
- scope: 'xchange',
900
- shareData,
901
- privateKey: agent.identity.privateKey,
902
- shareIndex: 0,
903
- shareTotal: 3,
904
- shareThreshold: 2,
905
- shareGroupId: 'group-uuid-1234',
906
- shareHmacKey: 'base64-hmac-key',
907
- shareHmacSig: 'base64-hmac-sig'
908
- });
909
-
910
- if (envelope.ok) {
911
- console.log('Envelope version:', envelope.value.v);
912
- console.log('KEM mode:', envelope.value.kem);
913
- console.log('Share index:', envelope.value.shareIndex);
914
- console.log('Threshold:', `${envelope.value.shareThreshold}-of-${envelope.value.shareTotal}`);
915
- }
916
- ```
917
- <!-- /RUNNABLE-EXAMPLE -->
918
-
919
- **Expected output:**
920
- ```
921
- Envelope version: 4
922
- KEM mode: Xchange
923
- Share index: 0
924
- Threshold: 2-of-3
925
- ```
926
-
927
- ### Example 11: Decrypt Envelope Payload
928
-
929
- <!-- RUNNABLE-EXAMPLE -->
930
- ```typescript
931
- import {
932
- Agent,
933
- createEnvelope,
934
- decryptPayload,
935
- generateSharedKey
936
- } from '@private.me/xbind';
937
-
938
- // Create and encrypt envelope
939
- const sharedKey = await generateSharedKey();
940
- const agent = await Agent.quickstart({ name: 'decrypt-test' });
941
-
942
- const originalMessage = 'Secret payment details';
943
- const plaintext = new TextEncoder().encode(originalMessage);
944
-
945
- const envelopeResult = await createEnvelope({
946
- senderDid: agent.did,
947
- recipientDid: 'did:key:z6MkRecipient...',
948
- scope: 'payments',
949
- plaintext,
950
- privateKey: agent.identity.privateKey,
951
- sharedKey
952
- });
953
-
954
- if (!envelopeResult.ok) {
955
- throw new Error('Envelope creation failed');
956
- }
957
-
958
- // Decrypt the payload
959
- const decryptResult = await decryptPayload(envelopeResult.value, sharedKey);
960
-
961
- if (!decryptResult.ok) {
962
- throw new Error(`Decryption failed: ${decryptResult.error}`);
963
- }
964
-
965
- const decryptedMessage = new TextDecoder().decode(decryptResult.value);
966
- console.log('Decrypted:', decryptedMessage);
967
- console.log('Match:', decryptedMessage === originalMessage);
968
- ```
969
- <!-- /RUNNABLE-EXAMPLE -->
970
-
971
- **Expected output:**
972
- ```
973
- Decrypted: Secret payment details
974
- Match: true
975
- ```
976
-
977
- ### Example 12: Serialize and Deserialize Envelope
978
-
979
- <!-- RUNNABLE-EXAMPLE -->
980
- ```typescript
981
- import {
982
- Agent,
983
- createEnvelope,
984
- serializeEnvelope,
985
- deserializeEnvelope,
986
- generateSharedKey
987
- } from '@private.me/xbind';
988
-
989
- // Create envelope
990
- const sharedKey = await generateSharedKey();
991
- const agent = await Agent.quickstart({ name: 'serialize-test' });
992
-
993
- const envelope = await createEnvelope({
994
- senderDid: agent.did,
995
- recipientDid: 'did:key:z6MkRecipient...',
996
- scope: 'test',
997
- plaintext: new TextEncoder().encode('Test message'),
998
- privateKey: agent.identity.privateKey,
999
- sharedKey
1000
- });
1001
-
1002
- if (!envelope.ok) {
1003
- throw new Error('Envelope creation failed');
1004
- }
1005
-
1006
- // Serialize to bytes
1007
- const serialized = serializeEnvelope(envelope.value);
1008
- console.log('Serialized length:', serialized.length, 'bytes');
1009
-
1010
- // Deserialize back to envelope
1011
- const deserialized = deserializeEnvelope(serialized);
1012
-
1013
- if (deserialized.ok) {
1014
- console.log('Deserialized version:', deserialized.value.v);
1015
- console.log('Sender DID:', deserialized.value.sender.substring(0, 20) + '...');
1016
- console.log('Round-trip successful');
1017
- }
1018
- ```
1019
- <!-- /RUNNABLE-EXAMPLE -->
1020
-
1021
- **Expected output:**
1022
- ```
1023
- Serialized length: 512 bytes
1024
- Deserialized version: 1
1025
- Sender DID: did:key:z6Mk...
1026
- Round-trip successful
1027
- ```
1028
-
1029
- ### Example 13: Validate Envelope Structure
1030
-
1031
- <!-- RUNNABLE-EXAMPLE -->
1032
- ```typescript
1033
- import { validateEnvelope } from '@private.me/xbind';
1034
-
1035
- // Valid envelope structure
1036
- const validEnvelope = {
1037
- v: 1,
1038
- alg: 'Ed25519',
1039
- sender: 'did:key:z6MkSender...',
1040
- recipient: 'did:key:z6MkRecipient...',
1041
- timestamp: Date.now(),
1042
- nonce: 'YmFzZTY0LW5vbmNl',
1043
- scope: 'test',
1044
- payload: 'ZW5jcnlwdGVkLXBheWxvYWQ=',
1045
- signature: 'c2lnbmF0dXJlLWRhdGE='
1046
- };
1047
-
1048
- const validation = validateEnvelope(validEnvelope);
1049
-
1050
- if (validation.ok) {
1051
- console.log('Envelope valid');
1052
- console.log('Version:', validation.value.v);
1053
- console.log('Algorithm:', validation.value.alg);
1054
- } else {
1055
- console.error('Validation error:', validation.error);
1056
- }
1057
-
1058
- // Invalid envelope (missing required field)
1059
- const invalidEnvelope = {
1060
- v: 1,
1061
- alg: 'Ed25519',
1062
- sender: 'did:key:z6MkSender...'
1063
- // Missing recipient, timestamp, nonce, etc.
1064
- };
1065
-
1066
- const invalidValidation = validateEnvelope(invalidEnvelope);
1067
- console.log('Invalid envelope error:', invalidValidation.ok ? 'N/A' : invalidValidation.error);
1068
- ```
1069
- <!-- /RUNNABLE-EXAMPLE -->
1070
-
1071
- **Expected output:**
1072
- ```
1073
- Envelope valid
1074
- Version: 1
1075
- Algorithm: Ed25519
1076
- Invalid envelope error: INVALID_FIELDS
1077
- ```
1078
-
1079
-
1080
- ## Identity & CLI Operations
1081
-
1082
- ### CLI Initialization
1083
-
1084
- <!-- RUNNABLE-EXAMPLE -->
1085
- ```typescript
1086
- import { initCommand } from '@private.me/xbind';
1087
-
1088
- // Initialize xBind project with invite code
1089
- await initCommand({
1090
- invite: 'https://xbind.to/invite/XBD-abc123',
1091
- name: 'my-xbind-app',
1092
- runtime: 'node-typescript',
1093
- yes: true // Skip interactive prompts
1094
- });
1095
-
1096
- // Or use CLI directly:
1097
- // npx xbind-init --invite XBD-abc123 --name my-app --runtime node-typescript --yes
1098
- ```
1099
- <!-- /RUNNABLE-EXAMPLE -->
1100
-
1101
- ### DID Conversions
1102
-
1103
- <!-- RUNNABLE-EXAMPLE -->
1104
- ```typescript
1105
- import { generateIdentity, publicKeyToDid, didToPublicKeyBytes } from '@private.me/xbind';
1106
-
1107
- // Generate identity and extract DID
1108
- const result = await generateIdentity();
1109
- if (!result.ok) throw new Error(result.error);
1110
-
1111
- const identity = result.value;
1112
- console.log('DID:', identity.did); // did:key:z6Mk...
1113
-
1114
- // Convert public key to DID
1115
- const did = publicKeyToDid(identity.rawPublicKey);
1116
- console.log('Derived DID:', did);
1117
-
1118
- // Convert DID back to public key bytes
1119
- const keyResult = didToPublicKeyBytes(did);
1120
- if (!keyResult.ok) throw new Error(keyResult.error);
1121
-
1122
- console.log('Public key bytes:', keyResult.value); // Uint8Array(32)
1123
- ```
1124
- <!-- /RUNNABLE-EXAMPLE -->
1125
-
1126
- ### PKCS8 Key Export
1127
-
1128
- <!-- RUNNABLE-EXAMPLE -->
1129
- ```typescript
1130
- import { generateIdentity, exportPKCS8, exportX25519PKCS8 } from '@private.me/xbind';
1131
-
1132
- const result = await generateIdentity();
1133
- if (!result.ok) throw new Error(result.error);
1134
-
1135
- const identity = result.value;
1136
-
1137
- // Export Ed25519 private key as PKCS8 (for persistent storage)
1138
- const ed25519Result = await exportPKCS8(identity.privateKey);
1139
- if (!ed25519Result.ok) throw new Error(ed25519Result.error);
1140
-
1141
- console.log('Ed25519 PKCS8:', ed25519Result.value); // Uint8Array(48)
1142
-
1143
- // Export X25519 private key as PKCS8
1144
- const x25519Result = await exportX25519PKCS8(identity.x25519PrivateKey);
1145
- if (!x25519Result.ok) throw new Error(x25519Result.error);
1146
-
1147
- console.log('X25519 PKCS8:', x25519Result.value); // Uint8Array(48)
1148
- ```
1149
- <!-- /RUNNABLE-EXAMPLE -->
1150
-
1151
- ### PKCS8 Key Import
1152
-
1153
- <!-- RUNNABLE-EXAMPLE -->
1154
- ```typescript
1155
- import { exportPKCS8, exportX25519PKCS8, importFromPKCS8, importIdentity } from '@private.me/xbind';
1156
-
1157
- // Assume we have PKCS8 bytes from previous export
1158
- const ed25519Pkcs8 = new Uint8Array(48); // From exportPKCS8()
1159
- const x25519Pkcs8 = new Uint8Array(48); // From exportX25519PKCS8()
1160
-
1161
- // Import Ed25519 identity (generates new X25519 keypair)
1162
- const simpleResult = await importFromPKCS8(ed25519Pkcs8);
1163
- if (!simpleResult.ok) throw new Error(simpleResult.error);
1164
-
1165
- console.log('Restored DID:', simpleResult.value.did);
1166
-
1167
- // Import full identity (preserves both Ed25519 + X25519 keys)
1168
- const fullResult = await importIdentity(ed25519Pkcs8, x25519Pkcs8);
1169
- if (!fullResult.ok) throw new Error(fullResult.error);
1170
-
1171
- console.log('Full identity restored:', fullResult.value.did);
1172
- console.log('Has X25519 keys:', !!fullResult.value.x25519PublicKey);
1173
- ```
1174
- <!-- /RUNNABLE-EXAMPLE -->
1175
-
1176
- ### Deterministic Identity from Seed
1177
-
1178
- <!-- RUNNABLE-EXAMPLE -->
1179
- ```typescript
1180
- import { identityFromSeed } from '@private.me/xbind';
1181
-
1182
- // Generate 32-byte seed (high-entropy random bytes)
1183
- const seed = crypto.getRandomValues(new Uint8Array(32));
1184
-
1185
- // Derive deterministic identity (same seed = same DID)
1186
- const result = await identityFromSeed(seed);
1187
- if (!result.ok) throw new Error(result.error);
1188
-
1189
- console.log('DID:', result.value.did);
1190
- console.log('Has Ed25519 keys:', !!result.value.publicKey);
1191
- console.log('Has X25519 keys:', !!result.value.x25519PublicKey);
1192
- console.log('Has ML-KEM keys:', !!result.value.mlKemPublicKey);
1193
-
1194
- // Same seed produces identical DID
1195
- const result2 = await identityFromSeed(seed);
1196
- if (!result2.ok) throw new Error(result2.error);
1197
-
1198
- console.log('DIDs match:', result.value.did === result2.value.did); // true
1199
- ```
1200
- <!-- /RUNNABLE-EXAMPLE -->
1201
-
1202
- ### Raw Key Extraction
1203
-
1204
- <!-- RUNNABLE-EXAMPLE -->
1205
- ```typescript
1206
- import { exportPKCS8, exportX25519PKCS8, extractRawEd25519, extractRawX25519 } from '@private.me/xbind';
1207
- import { generateIdentity } from '@private.me/xbind';
1208
-
1209
- const identity = (await generateIdentity()).value!;
1210
-
1211
- // Export PKCS8 format
1212
- const ed25519Pkcs8 = (await exportPKCS8(identity.privateKey)).value!;
1213
- const x25519Pkcs8 = (await exportX25519PKCS8(identity.x25519PrivateKey)).value!;
1214
-
1215
- // Extract raw 32-byte private keys
1216
- const ed25519Raw = extractRawEd25519(ed25519Pkcs8);
1217
- if (!ed25519Raw.ok) throw new Error(ed25519Raw.error);
1218
-
1219
- console.log('Ed25519 raw key:', ed25519Raw.value); // Uint8Array(32)
1220
-
1221
- const x25519Raw = extractRawX25519(x25519Pkcs8);
1222
- if (!x25519Raw.ok) throw new Error(x25519Raw.error);
1223
-
1224
- console.log('X25519 raw key:', x25519Raw.value); // Uint8Array(32)
1225
- ```
1226
- <!-- /RUNNABLE-EXAMPLE -->
1227
-
1228
- ### ML-KEM Key Export
1229
-
1230
- <!-- RUNNABLE-EXAMPLE -->
1231
- ```typescript
1232
- import { generateIdentity, exportMlKemSecretKey, exportMlKemPublicKey } from '@private.me/xbind';
1233
-
1234
- const result = await generateIdentity();
1235
- if (!result.ok) throw new Error(result.error);
1236
-
1237
- const identity = result.value;
1238
-
1239
- // Export ML-KEM-768 secret key (2400 bytes)
1240
- const secretKey = exportMlKemSecretKey(identity);
1241
- if (secretKey) {
1242
- console.log('ML-KEM secret key size:', secretKey.length); // 2400
1243
- }
1244
-
1245
- // Export ML-KEM-768 public key (1184 bytes)
1246
- const publicKey = exportMlKemPublicKey(identity);
1247
- if (publicKey) {
1248
- console.log('ML-KEM public key size:', publicKey.length); // 1184
1249
- }
1250
- ```
1251
- <!-- /RUNNABLE-EXAMPLE -->
1252
-
1253
- ## Advanced Networking & Resilience
1254
-
1255
- xBind provides production-grade retry strategies, replay prevention, and circuit breakers for fault-tolerant distributed systems.
1256
-
1257
- ### Replay Prevention with MemoryNonceStore
1258
-
1259
- <!-- RUNNABLE-EXAMPLE -->
1260
- ```typescript
1261
- import { MemoryNonceStore } from '@private.me/xbind';
1262
-
1263
- // Create in-memory nonce store (10-minute TTL, 60-second cleanup)
1264
- const nonceStore = new MemoryNonceStore({
1265
- ttlMs: 10 * 60 * 1000,
1266
- cleanupIntervalMs: 60 * 1000,
1267
- });
1268
-
1269
- // Check nonce freshness (returns true if new, false if duplicate)
1270
- const nonce1 = 'unique-nonce-abc123';
1271
- const senderDid = 'did:key:z6Mk...';
1272
-
1273
- const isNewNonce = await nonceStore.check(nonce1, senderDid);
1274
- console.log('Nonce accepted:', isNewNonce); // true (first use)
1275
-
1276
- const isDuplicate = await nonceStore.check(nonce1, senderDid);
1277
- console.log('Nonce rejected:', !isDuplicate); // false (replay attack)
1278
-
1279
- // Clean up
1280
- nonceStore.dispose();
1281
- ```
1282
- <!-- /RUNNABLE-EXAMPLE -->
1283
-
1284
- ### Redis Nonce Store (Multi-Node)
1285
-
1286
- <!-- RUNNABLE-EXAMPLE -->
1287
- ```typescript
1288
- import { RedisNonceStore } from '@private.me/xbind';
1289
- import Redis from 'ioredis';
1290
-
1291
- // Create Redis client
1292
- const redis = new Redis({ host: 'localhost', port: 6379 });
1293
-
1294
- // Create Redis nonce store (distributed across all nodes)
1295
- const nonceStore = new RedisNonceStore({
1296
- client: {
1297
- setNX: async (key, value, ttl) => {
1298
- const result = await redis.set(key, value, 'EX', ttl, 'NX');
1299
- return result === 'OK' ? 'OK' : null;
1300
- },
1301
- del: (key) => redis.del(key),
1302
- quit: () => redis.quit(),
1303
- },
1304
- ttlSeconds: 600, // 10 minutes
1305
- keyPrefix: 'xbind:nonce:',
1306
- });
1307
-
1308
- // Use nonce store (same API as MemoryNonceStore)
1309
- const isNewNonce = await nonceStore.check('nonce-xyz', 'did:key:z6Mk...');
1310
- console.log('Distributed nonce check:', isNewNonce);
1311
-
1312
- // Clean up
1313
- await nonceStore.dispose();
1314
- ```
1315
- <!-- /RUNNABLE-EXAMPLE -->
1316
-
1317
- ### Exponential Backoff Retry
1318
-
1319
- <!-- RUNNABLE-EXAMPLE -->
1320
- ```typescript
1321
- import { ExponentialBackoffStrategy, executeWithRetry } from '@private.me/xbind';
1322
- import { err, ok } from '@private.me/shared';
1323
-
1324
- // Create exponential backoff strategy (3 attempts, 1s → 2s → 4s)
1325
- const retryStrategy = new ExponentialBackoffStrategy({
1326
- maxAttempts: 3,
1327
- initialDelayMs: 1000,
1328
- maxDelayMs: 30000,
1329
- multiplier: 2,
1330
- jitter: true,
1331
- });
1332
-
1333
- // Simulate flaky operation
1334
- let attemptCount = 0;
1335
- async function flakyOperation() {
1336
- attemptCount++;
1337
- console.log(`Attempt ${attemptCount}`);
1338
-
1339
- if (attemptCount < 3) {
1340
- return err('NETWORK_ERROR' as const);
1341
- }
1342
- return ok({ data: 'Success after retries' });
1343
- }
1344
-
1345
- // Execute with retry
1346
- const result = await executeWithRetry(flakyOperation, retryStrategy);
1347
-
1348
- if (result.ok) {
1349
- console.log('Operation succeeded:', result.value.data);
1350
- } else {
1351
- console.error('Operation failed:', result.error);
1352
- }
1353
- ```
1354
- <!-- /RUNNABLE-EXAMPLE -->
1355
-
1356
- ### Linear Backoff Strategy
1357
-
1358
- <!-- RUNNABLE-EXAMPLE -->
1359
- ```typescript
1360
- import { LinearBackoffStrategy, executeWithRetry } from '@private.me/xbind';
1361
- import { err, ok } from '@private.me/shared';
1362
-
1363
- // Create linear backoff strategy (delays: 1s, 2s, 3s, 4s)
1364
- const retryStrategy = new LinearBackoffStrategy({
1365
- maxAttempts: 4,
1366
- initialDelayMs: 1000,
1367
- delayIncrementMs: 1000,
1368
- maxDelayMs: 10000,
1369
- jitter: true,
1370
- });
1371
-
1372
- // Simulate operation
1373
- async function operation() {
1374
- return ok({ message: 'Linear backoff demo' });
1375
- }
1376
-
1377
- const result = await executeWithRetry(operation, retryStrategy);
1378
- console.log('Result:', result.ok ? result.value.message : result.error);
1379
- ```
1380
- <!-- /RUNNABLE-EXAMPLE -->
1381
-
1382
- ### Fixed Delay Strategy
1383
-
1384
- <!-- RUNNABLE-EXAMPLE -->
1385
- ```typescript
1386
- import { FixedDelayStrategy, executeWithRetry } from '@private.me/xbind';
1387
- import { err, ok } from '@private.me/shared';
1388
-
1389
- // Create fixed delay strategy (constant 2s delay between retries)
1390
- const retryStrategy = new FixedDelayStrategy({
1391
- maxAttempts: 3,
1392
- delayMs: 2000,
1393
- jitter: false,
1394
- });
1395
-
1396
- // Simulate operation
1397
- async function operation() {
1398
- return ok({ message: 'Fixed delay demo' });
1399
- }
1400
-
1401
- const result = await executeWithRetry(operation, retryStrategy);
1402
- console.log('Result:', result.ok ? result.value.message : result.error);
1403
- ```
1404
- <!-- /RUNNABLE-EXAMPLE -->
1405
-
1406
- ### No Retry Strategy
1407
-
1408
- <!-- RUNNABLE-EXAMPLE -->
1409
- ```typescript
1410
- import { NoRetryStrategy, executeWithRetry } from '@private.me/xbind';
1411
- import { err } from '@private.me/shared';
1412
-
1413
- // Create no-retry strategy (fail immediately)
1414
- const retryStrategy = new NoRetryStrategy();
1415
-
1416
- // Simulate failing operation
1417
- async function operation() {
1418
- return err('NETWORK_ERROR' as const);
1419
- }
1420
-
1421
- const result = await executeWithRetry(operation, retryStrategy);
1422
- console.log('Failed immediately:', !result.ok);
1423
- console.log('Error:', result.ok ? null : result.error);
1424
- ```
1425
- <!-- /RUNNABLE-EXAMPLE -->
1426
-
1427
- ### Circuit Breaker Pattern
1428
-
1429
- <!-- RUNNABLE-EXAMPLE -->
1430
- ```typescript
1431
- import { CircuitBreaker } from '@private.me/xbind';
1432
-
1433
- // Create circuit breaker (5 failures → open, 60s reset, 2 successes → close)
1434
- const breaker = new CircuitBreaker({
1435
- failureThreshold: 5,
1436
- resetTimeoutMs: 60000,
1437
- successThreshold: 2,
1438
- windowMs: 60000,
1439
- });
1440
-
1441
- // Simulate failures to trip circuit
1442
- for (let i = 0; i < 5; i++) {
1443
- breaker.recordFailure();
1444
- }
1445
-
1446
- console.log('Circuit state after 5 failures:', breaker.getStats().state); // OPEN
1447
-
1448
- // Attempt request while circuit is open
1449
- const canProceed = breaker.allowRequest();
1450
- console.log('Request allowed:', canProceed); // false
1451
-
1452
- // Get circuit statistics
1453
- const stats = breaker.getStats();
1454
- console.log('Stats:', {
1455
- state: stats.state,
1456
- totalFailures: stats.totalFailures,
1457
- consecutiveFailures: stats.consecutiveFailures,
1458
- });
1459
- ```
1460
- <!-- /RUNNABLE-EXAMPLE -->
1461
-
1462
- ### Retry with Circuit Breaker
1463
-
1464
- <!-- RUNNABLE-EXAMPLE -->
1465
- ```typescript
1466
- import {
1467
- ExponentialBackoffStrategy,
1468
- CircuitBreaker,
1469
- executeWithRetry,
1470
- } from '@private.me/xbind';
1471
- import { err, ok } from '@private.me/shared';
1472
-
1473
- // Create retry strategy and circuit breaker
1474
- const retryStrategy = new ExponentialBackoffStrategy({
1475
- maxAttempts: 3,
1476
- initialDelayMs: 1000,
1477
- });
1478
-
1479
- const circuitBreaker = new CircuitBreaker({
1480
- failureThreshold: 2,
1481
- resetTimeoutMs: 5000,
1482
- });
1483
-
1484
- // Simulate operation that succeeds after circuit recovery
1485
- let callCount = 0;
1486
- async function operation() {
1487
- callCount++;
1488
- if (callCount === 1) {
1489
- return err('NETWORK_ERROR' as const);
1490
- }
1491
- return ok({ data: `Success on attempt ${callCount}` });
1492
- }
1493
-
1494
- // Execute with retry + circuit breaker
1495
- const result = await executeWithRetry(operation, retryStrategy, circuitBreaker);
1496
-
1497
- console.log('Operation result:', result.ok ? result.value.data : result.error);
1498
- console.log('Circuit state:', circuitBreaker.getStats().state);
1499
- ```
1500
- <!-- /RUNNABLE-EXAMPLE -->
1501
-
1502
- ### RetryTransportAdapter (Automatic Retry)
1503
-
1504
- <!-- RUNNABLE-EXAMPLE -->
1505
- ```typescript
1506
- import { RetryTransportAdapter, HttpsTransportAdapter, Agent } from '@private.me/xbind';
1507
-
1508
- // Create base transport
1509
- const baseTransport = new HttpsTransportAdapter({
1510
- baseUrl: 'https://gateway.private.me',
1511
- });
1512
-
1513
- // Wrap with retry decorator (exponential backoff, 3 attempts)
1514
- const retryTransport = new RetryTransportAdapter(baseTransport, {
1515
- maxAttempts: 3,
1516
- initialDelayMs: 1000,
1517
- maxDelayMs: 10000,
1518
- strategy: 'exponential',
1519
- });
1520
-
1521
- // Create agent with retry transport
1522
- const agent = await Agent.quickstart({
1523
- name: 'retry-demo',
1524
- transports: [retryTransport],
1525
- });
1526
-
1527
- console.log('Agent created with retry transport');
1528
- console.log('Transport type:', agent.transports[0].constructor.name);
1529
- ```
1530
- <!-- /RUNNABLE-EXAMPLE -->
1531
-
1532
- ### Shared Key Generation
1533
-
1534
- <!-- RUNNABLE-EXAMPLE -->
1535
- ```typescript
1536
- import { generateSharedKey } from '@private.me/xbind';
1537
-
1538
- // Generate random AES-256-GCM shared key
1539
- const sharedKeyResult = await generateSharedKey();
1540
-
1541
- if (!sharedKeyResult.ok) {
1542
- throw new Error(`Failed to generate key: ${sharedKeyResult.error}`);
1543
- }
1544
-
1545
- const sharedKey = sharedKeyResult.value;
1546
-
1547
- // Export key material for inspection
1548
- const keyMaterial = await crypto.subtle.exportKey('raw', sharedKey);
1549
- console.log('Shared key generated (256 bits):', keyMaterial.byteLength * 8);
1550
- console.log('Key algorithm:', sharedKey.algorithm.name);
1551
- console.log('Key usages:', sharedKey.usages);
1552
- ```
1553
- <!-- /RUNNABLE-EXAMPLE -->
1554
-
1555
- ### Signed Envelopes
1556
-
1557
- <!-- RUNNABLE-EXAMPLE -->
1558
- ```typescript
1559
- import { createSignedEnvelope, openSignedEnvelope, Agent } from '@private.me/xbind';
1560
-
1561
- // Create agents
1562
- const sender = await Agent.quickstart({ name: 'sender' });
1563
- const recipient = await Agent.quickstart({ name: 'recipient' });
1564
-
1565
- // Create signed envelope
1566
- const payload = { action: 'transfer', amount: 100 };
1567
- const envelopeResult = await createSignedEnvelope(
1568
- sender.identity,
1569
- recipient.did,
1570
- payload,
1571
- 'billing'
1572
- );
1573
-
1574
- if (!envelopeResult.ok) {
1575
- throw new Error(`Failed to create envelope: ${envelopeResult.error}`);
1576
- }
1577
-
1578
- const envelope = envelopeResult.value;
1579
- console.log('Envelope created with signature');
1580
- console.log('Sender DID:', envelope.sender);
1581
- console.log('Recipient DID:', envelope.recipient);
1582
- console.log('Signature length:', envelope.signature.length);
1583
-
1584
- // Verify and open envelope
1585
- const openResult = await openSignedEnvelope(envelope, sender.identity.publicKey);
1586
-
1587
- if (!openResult.ok) {
1588
- throw new Error(`Failed to open envelope: ${openResult.error}`);
1589
- }
1590
-
1591
- console.log('Envelope verified and opened');
1592
- console.log('Payload:', openResult.value);
1593
- ```
1594
- <!-- /RUNNABLE-EXAMPLE -->
1595
-
1596
- ## Python SDK
1597
-
1598
- Complete Python bindings for agent identity and messaging:
1599
-
1600
- ```python
1601
- from private_me.xbind import Agent
1602
-
1603
- # Create agent from private key
1604
- agent = Agent.from_private_key(private_key_bytes)
1605
-
1606
- # Make authenticated call
1607
- result = agent.call('stripe:createCharge', {
1608
- 'amount': 100,
1609
- 'currency': 'usd',
1610
- 'description': 'AI agent purchase'
1611
- })
1612
-
1613
- if result['ok']:
1614
- print(f"Charge ID: {result['data']['id']}")
1615
- print(f"Agent DID: {result['audit']['agent']}")
1616
- else:
1617
- print(f"Error: {result['error']['message']}")
1618
- ```
1619
-
1620
- See [Python SDK documentation](./python/README.md) for complete API reference and examples.
1621
-
1622
- ## Why xBind?
1623
-
1624
- Zero key management, zero cascade failures, zero bearer credentials. Cryptographic identity replaces API keys. See [white paper](https://private.me/docs/xbind.html) for architecture details and benchmarks.
1625
-
1626
- ## Getting Started
1627
-
1628
- **[Guide](../../docs/xbind-integrations/getting-started/index.md)** — Concepts, migration
1629
- **[Quickstart](../../docs/xbind-integrations/getting-started/quickstart.md)** — 15-second setup
1630
-
1631
- ## Features
1632
-
1633
- **Zero-config JITR:** Just-in-Time Registration auto-registers agents with trust registry on first use (AWS IoT JITR, OAuth DCR, MCP 2025 standards).
1634
-
1635
- ### Core Security
1636
- - **Post-quantum cryptography:** ML-KEM-768 key encapsulation, ML-DSA-65 digital signatures (FIPS 203/204)
1637
- - **Hybrid key agreement:** X-Wing combiner (IETF draft-10) with 6-parameter domain separation
1638
- - **XorIDA split-channel delivery:** Information-theoretic threshold sharing (2-of-2, 2-of-3, 3-of-5)
1639
- - **Cryptographic request signing:** Ed25519 signatures prevent DID header forgery
1640
- - **Key rotation:** ML-KEM + X25519 rotation with fallback decryption (10 rotation history)
1641
- - **Proof-of-Possession:** Ed25519 signature verification prevents DID spoofing
1642
- - **Share-aware nonce deduplication:** Prevents replay attacks with composite keys
1643
-
1644
- ### Runtime Compatibility (4 Platforms)
1645
- - **Browser:** WebCrypto API, IndexedDB/localStorage adapters, WASM support, service workers
1646
- - **React Native:** AsyncStorage, Buffer polyfills, crypto detection, iOS/Android platform support
1647
- - **Edge Runtime:** Cloudflare Workers, Vercel Edge, Deno Deploy, KV storage, <1MB optimization
1648
- - **Node.js:** Native crypto module, filesystem storage, full feature set
1649
-
1650
- ### Operations Patterns
1651
- - **Health checks:** Startup/liveness/readiness probes, Kubernetes-compatible, Express/Fastify middleware
1652
- - **Circuit breakers:** 3-state machine (closed/open/half-open), registry/gateway/S3 presets, automatic recovery
1653
- - **Graceful degradation:** QoS tiers, intelligent caching, service health tracking, fallback strategies
1654
- - **Performance benchmarks:** Latency histograms with baselines for key ops (ML-KEM, ML-DSA, encryption)
1655
- - **Structured logging:** 4 levels (DEBUG/INFO/WARN/ERROR), automatic sensitive data redaction, correlation IDs
1656
- - **Telemetry:** Prometheus-compatible metrics (counters, histograms, gauges), operation latency tracking
1657
-
1658
- ### Security Audit Preparation
1659
- - **STRIDE threat modeling:** 66 threats analyzed across 6 categories
1660
- - **Crypto claims documentation:** 41 cryptographic claims documented with evidence
1661
- - **Known limitations disclosure:** 24 limitations disclosed for auditor transparency
1662
- - **Audit-ready:** NCC Group / Trail of Bits preparation ($100K-$150K, 12-week timeline)
1663
-
1664
- ### API Enhancements
1665
- - **Batch operations:** 6-8x speedup for parallel operations with single network round-trip
1666
- - **Async iterators:** `for await...of` syntax support for streaming message processing
1667
- - **Plugin/middleware system:** 6-phase lifecycle hooks with 3 built-in plugins
1668
- - **Event emitters:** Type-safe events with 5 event types, priority execution, bubbling
1669
- - **Cancellation tokens:** AbortController integration with timeout support
1670
- - **Progress callbacks:** 4 specialized trackers (operation, transfer, share, encryption)
1671
- - **Retry strategies:** 4 strategies (exponential, linear, immediate, jittered) + circuit breaker integration
1672
- - **Request timeouts:** Per-operation config with inheritance and cancellation
1673
- - **Connection pooling:** 60-70% latency reduction with keep-alive and metrics
1674
- - **Serialization formats:** JSON/MessagePack/CBOR support with auto-detection and negotiation
1675
- - **Configuration validation:** Comprehensive validation with clear error messages
1676
- - **Debug mode:** Performance profiling, network/crypto tracing, state inspection
1677
- - **SDK version info:** Capability detection, deprecation warnings, compatibility checking
1678
-
1679
- ### Developer Experience
1680
- - **Type safety:** `Result<T, E>` error handling with 96+ error codes
1681
- - **TypeScript strict mode:** Zero type errors, complete type coverage
1682
- - **Python SDK:** Complete bindings for identity, messaging, and encryption
1683
- - **User-friendly errors:** 75+ errors with actionable recovery hints
1684
- - **Complete API docs:** 2,587 lines with 50+ usage examples
1685
- - **CHANGELOG generation:** Automated Keep a Changelog format with semver discipline
1686
- - **Dependency audit:** Weekly Dependabot scans, 5-layer vulnerability scanning
1687
- - **Crypto license compliance:** Automated MIT/MIT-0 validation with GPL/AGPL detection
1688
-
1689
- ### Enterprise Features
1690
- - **Version negotiation:** Explicit SDK version fields prevent "404 Route not found" in mixed fleets
1691
- - **Multi-device session resume:** AES-256-GCM encrypted session state sync with PBKDF2 (100k iterations)
1692
- - **Encrypted backup/restore:** Password-protected identity export with PBKDF2-SHA256 (310k iterations)
1693
- - **Offline sync:** Message queueing for offline devices (max 1000 messages, 24-hour TTL)
1694
- - **Registry expiration:** TTL support with cleanup (default 7 days)
1695
- - **Server-side spending limits:** Redis-backed enforcement with deployment-level aggregation
1696
- - **Rate limiting:** Three-tier protection (per-DID, per-IP, global)
1697
- - **Full Control IP protection:** Store Front (npm) + Vault Store (EC2) with payment verification
1698
-
1699
- ### Testing & Quality
1700
- - **2,762 tests:** Comprehensive coverage (96.6% passing)
1701
- - **End-to-end integration:** Full message flow tests (Agent A → Gateway → Agent B)
1702
- - **Gateway concurrency:** 100 concurrent sends, race condition detection
1703
- - **Network partition recovery:** Disconnect/reconnect cycles with retry logic
1704
- - **PLAN-3 hybrid signatures:** Bilateral authorization with composite verification
1705
-
1706
- ## Bundle Size Optimization (Tree-Shaking)
1707
-
1708
- **New in v3.0.3:** LoopbackTransport export (testing workflow), describeSecurityModeStructured export (white paper examples), Agent.quickstart() signature fixes (README correctness). Full Control IP Protection (v3.0.2) - cryptographic algorithms delivered via payment-gated Vault Store. Share 1 in npm (useless alone), Share 2 in EC2 (completes algorithm). Information-theoretic security for proprietary IP.
1709
-
1710
- ### Full Import (Convenience)
1711
-
1712
- ```typescript
1713
- import { Agent, generateIdentity } from '@private.me/xbind';
1714
-
1715
- // Bundle size: ~450 KB
1716
- ```
1717
-
1718
- ### Granular Import (Optimized)
1719
-
1720
- ```typescript
1721
- import { Agent } from '@private.me/xbind/agent';
1722
- import { generateIdentity } from '@private.me/xbind/identity';
1723
-
1724
- // Bundle size: ~180 KB (60% reduction)
1725
- ```
1726
-
1727
- ### Available Entry Points
1728
-
1729
- | Entry Point | Exports | Bundle Impact |
1730
- |-------------|---------|---------------|
1731
- | `@private.me/xbind` | All exports | Full package (~450 KB) |
1732
- | `@private.me/xbind/agent` | `Agent`, `AgentOptions` | ~180 KB |
1733
- | `@private.me/xbind/identity` | `generateIdentity`, `Identity` | ~120 KB |
1734
- | `@private.me/xbind/trust-registry` | Registry classes | ~200 KB |
1735
- | `@private.me/xbind/key-agreement` | Key exchange functions | ~90 KB |
1736
- | `@private.me/xbind/errors` | Error types | 0 KB (types only) |
1737
-
1738
- **Bundler Support:** Works with webpack 5+, Rollup, esbuild, and Vite. Tree-shaking is automatic in production mode.
1739
-
1740
- **See:** [Tree-Shaking Guide](./docs/packaging/tree-shaking.md) for detailed usage and configuration.
1741
-
1742
- ## Automatic XorIDA Split-Channel Protection
1743
-
1744
- xBind automatically activates information-theoretic XorIDA threshold sharing for high-risk operations. No code changes required—security is transparent.
1745
-
1746
- ### Risk Tags (Recommended for Crypto)
1747
-
1748
- For cryptocurrency transactions (BTC, ETH, etc.), use explicit risk tags in your payload:
1749
-
1750
- ```typescript
1751
- // Low risk: 2-of-2 threshold
1752
- await agent.send({
1753
- to: recipientDid,
1754
- payload: { amount: 0.5, currency: 'BTC', risk: 'low' }
1755
- });
1756
-
1757
- // Medium risk: 2-of-3 threshold
1758
- await agent.send({
1759
- to: recipientDid,
1760
- payload: { amount: 5.0, currency: 'ETH', risk: 'medium' }
1761
- });
1762
-
1763
- // High risk: 3-of-5 threshold
1764
- await agent.send({
1765
- to: recipientDid,
1766
- payload: { amount: 50, currency: 'BTC', risk: 'high' }
1767
- });
1768
-
1769
- // Critical risk: 3-of-5 threshold
1770
- await agent.send({
1771
- to: recipientDid,
1772
- payload: { amount: 100, currency: 'BTC', risk: 'critical' }
1773
- });
1774
- ```
1775
-
1776
- ### Fiat Currency Auto-Detection
1777
-
1778
- For fiat currencies (USD, EUR, GBP), xBind uses numeric thresholds:
1779
-
1780
- ```typescript
1781
- // Automatically triggers 2-of-3 (amount >= $100,000)
1782
- await agent.send({
1783
- to: recipientDid,
1784
- payload: { amount: 500000, currency: 'USD', action: 'transfer' }
1785
- });
1786
-
1787
- // Automatically triggers 3-of-5 (amount >= $1,000,000)
1788
- await agent.send({
1789
- to: recipientDid,
1790
- payload: { amount: 2500000, currency: 'USD', action: 'transfer' }
1791
- });
1792
- ```
1793
-
1794
- ### Manual Security Override
1795
-
1796
- Override automatic detection with explicit security levels:
1797
-
1798
- ```typescript
1799
- // Force 2-of-3 regardless of amount/risk
1800
- await agent.send({
1801
- to: recipientDid,
1802
- payload: data,
1803
- security: 'high'
1804
- });
1805
-
1806
- // Force 3-of-5 for maximum security
1807
- await agent.send({
1808
- to: recipientDid,
1809
- payload: data,
1810
- security: 'critical'
1811
- });
1812
-
1813
- // Disable XorIDA (standard encrypted transport)
1814
- await agent.send({
1815
- to: recipientDid,
1816
- payload: data,
1817
- security: 'standard'
1818
- });
1819
- ```
1820
-
1821
- ### Threshold Schemes
1822
-
1823
- | Risk Tag / Threshold | Shares | Required | Security Level |
1824
- |---------------------|--------|----------|----------------|
1825
- | `low` | 2 | 2 | 2-of-2 threshold |
1826
- | `medium` / $100k-$1M | 3 | 2 | 2-of-3 threshold |
1827
- | `high` / `critical` / >$1M | 5 | 3 | 3-of-5 threshold |
1828
- | No tag / <$100k | — | — | Standard encrypted transport |
1829
-
1830
- **Key Insight:** XorIDA is information-theoretically secure. Any K-1 shares reveal zero information about the secret, even with unlimited computing power. Quantum computers cannot break XorIDA.
1831
-
1832
- ## Billing & Metering
1833
-
1834
- xBind includes usage-based billing with automated milestone notifications:
1835
-
1836
- - **Free Tier:** Generous monthly limits (no email verification required upfront)
1837
- - **Grace Buffer:** Additional operations available after email verification
1838
- - **Pro Tier:** Usage-based billing with unlimited operations
1839
- - **Monthly Reset:** 1st of each month at 00:00 UTC
1840
-
1841
- See [pricing](../../docs/pricing-reference.md) for current rates and tier details.
1842
-
1843
- ### Milestone Notifications
1844
-
1845
- Automated email notifications at usage thresholds with progress bars and CTAs for upgrades.
1846
-
1847
- **Email verification:** Required at free tier limit to access grace buffer.
1848
-
1849
- **Implementation:**
1850
- - Metering logic: `apps/server/src/customer-metering.ts`
1851
- - Milestone system: `apps/server/src/usage-milestone-notifications.ts`
1852
- - Tier pattern: See `docs/gold-package.md` section 7.6.5
1853
-
1854
- ## Gateway
1855
-
1856
- Non-authoritative coordination for discovery, relay, push notifications, and state checkpoints. Cannot forge identity or decide trust. See [Gateway Architecture](./docs/gateway-architecture.md).
1857
-
1858
- ## Connection Models
1859
-
1860
- xBind provides four connection models for entity-to-entity authentication: Invite Code (email-based onboarding), QR Code (physical proximity pairing), Trust Registry (pre-authorized enterprise), and Peer Discovery (mDNS local network). All use cryptographic DIDs.
1861
-
1862
- | Model | Security | UX | Best For |
1863
- |-------|----------|-----|----------|
1864
- | Invite Code | Single-use, 24h TTL | 6-char code | Customer onboarding |
1865
- | QR Code | Physical proximity, 60s TTL | Scan & tap | Mobile/desktop pairing |
1866
- | Trust Registry | Admin pre-auth, scoped | Zero (automated) | Enterprise/CI/CD |
1867
- | Peer Discovery | LAN proximity, user confirm | Scan & confirm | IoT devices, offline |
1868
-
1869
- See [Entity-to-Entity Connection UX Guide](../../docs/ENTITY-TO-ENTITY-CONNECTION-UX.md) for implementation patterns and code examples.
1870
-
1871
- ## Configuration
1872
-
1873
- ### Basic Setup
1874
-
1875
- ```typescript
1876
- import { HttpTrustRegistry } from '@private.me/xbind';
1877
-
1878
- // Documentation example - use your actual gateway URL
1879
- const registry = new HttpTrustRegistry({
1880
- baseUrl: 'https://gateway.private.me'
1881
- });
1882
- ```
1883
-
1884
- ### Advanced Features
1885
-
1886
- Checkpoints, sequence numbers, subscription proofs, XorIDA configuration, key backup (2-of-3 default), DID succession. See [Configuration Guide](./docs/configuration.md) and [Examples](./docs/examples.md).
1887
-
1888
- ## Type Safety
1889
-
1890
- xbind returns `Result<T, E>` types for type-safe error handling.
1891
-
1892
- <!-- SNIPPET -->
1893
- ```typescript
1894
- import { call, type CallResult } from '@private.me/xbind';
1895
-
1896
- interface User { id: number; name: string; email: string; }
1897
-
1898
- const result: CallResult<User> = await call('getUser', { id: 123 });
1899
- if (result.ok) {
1900
- console.log(result.value.data.name);
1901
- console.log(result.value.audit.signature);
1902
- } else {
1903
- console.error(result.error.message);
1904
- }
1905
- ```
1906
- <!-- /SNIPPET -->
1907
-
1908
- Error types: `ConnectionError`, `AuthenticationError`, `ValidationError`, `RateLimitError`, `ServerError`
1909
-
1910
- ## Documentation
1911
-
1912
- - **[API Reference](./docs/api-reference.md)** — Complete API documentation
1913
- - **[Configuration Guide](./docs/configuration.md)** — All configuration options
1914
- - **[Examples](./docs/examples.md)** — Common usage patterns
1915
- - **[Troubleshooting](./docs/troubleshooting.md)** — Common issues and solutions
1916
- - **[Advanced Guide](./docs/advanced.md)** — Multi-backend failover, retry strategies
1917
- - **[White Paper](https://private.me/docs/xbind.html)** — Architecture and design
1918
- - **[AGENTS.md](./AGENTS.md)** — AI agent patterns
1919
- - **[SECURITY.md](./SECURITY.md)** — Threat model
1920
-
1921
- ## Testing
1922
-
1923
- **1,245/1,245 tests passing** — Comprehensive coverage including post-quantum cryptography (ML-KEM-768, ML-DSA-65), hybrid signature verification, DID generation, message encryption, transport layer, multi-agent coordination, error handling, Python SDK bindings, and Full Control protection.
1924
-
1925
- ```bash
1926
- pnpm test # All tests
1927
- pnpm test:coverage # Coverage report
1928
- pnpm test:watch # Watch mode
1929
- ```
1930
-
1931
- ## Full Control IP Protection
1932
-
1933
- xBind uses **Full Control** (2-share XorIDA) to protect proprietary cryptographic algorithms while maintaining a seamless developer experience.
1934
-
1935
- ### Architecture: Store Front + Vault Store
1936
-
1937
- **Store Front (npm registry):**
1938
- - Contains wrapper code, types, and non-proprietary utilities
1939
- - Includes Share 1 (`share1.dat`) — useless alone, safe to distribute publicly
1940
- - Installed via standard `npm install @private.me/xbind`
1941
-
1942
- **Vault Store (private.me gateway):**
1943
- - Contains Share 2 (encrypted, payment-gated)
1944
- - Delivered via `/api/vault-store/crypto` endpoint
1945
- - Requires xBind DID authentication + usage quota verification
1946
- - AES-256-GCM encrypted with `FULL_CONTROL_MASTER_KEY`
1947
-
1948
- When combined, Share 1 + Share 2 reconstruct the complete XorIDA algorithm at runtime.
1949
-
1950
- ### Usage-Based Access Model
1951
-
1952
- **IMPORTANT:** Full Control uses **usage-based metering**, NOT feature-gating.
1953
-
1954
- **All tiers** can access the Vault Store (crypto algorithms + Share 2) **within their usage quota**:
1955
-
1956
- - **Free Tier:** 100,000 operations/month
1957
- - Grace buffer: 120,000 hard cap (includes 20% overage)
1958
- - Email verification required
1959
- - Vault access included (no additional payment needed)
1960
- - At 120K ops: 402 Quota Exceeded → Upgrade prompt
1961
-
1962
- - **Pro Tier:** Unlimited operations
1963
- - $5 per 100,000 operations (after first 100K free)
1964
- - No quota checks
1965
- - Vault access unlimited
1966
- - Example: 400K ops = $15/month (100K free + 300K @ $5/100K)
1967
-
1968
- - **VIP Tier:** Custom limits per account
1969
- - Bronze: 200K, Silver: 500K, Gold: 1M, Platinum: Unlimited
1970
- - Vault access within custom quota
1971
-
1972
- ### Upgrade to Pro
1973
-
1974
- If you exceed the free tier quota, upgrade to Pro for unlimited operations:
1975
-
1976
- ```bash
1977
- # Visit the upgrade page
1978
- https://private.me/subscribe?product=xbind&tier=pro
1979
-
1980
- # Or upgrade programmatically via xBind API
1981
- const result = await agent.send({
1982
- to: 'did:key:z6MkBillingService...',
1983
- payload: { action: 'upgradeTier', tier: 'pro' }
1984
- });
1985
- ```
1986
-
1987
- ### 4-Layer Security
1988
-
1989
- 1. **DID Authentication:** Ed25519 signature verification (cryptographic proof of identity)
1990
- 2. **Usage Quota Verification:** Monthly operation count checked against tier limits
1991
- 3. **Rate Limiting:** Free: 100 req/hour, Pro: 1000 req/hour, VIP: 5000 req/hour
1992
- 4. **Audit Logging:** Every vault access logged with DID, timestamp, IP, and success status
1993
-
1994
- ### Runtime Flow
1995
-
1996
- ```typescript
1997
- // 1. Install package (includes Share 1)
1998
- // npm install @private.me/xbind
1999
-
2000
- // 2. Create agent (auto-fetches Share 2 on first use)
2001
- const agent = await Agent.create(seed);
2002
-
2003
- // 3. Vault Store loader detects missing crypto
2004
- // 4. POST /api/vault-store/crypto
2005
- // - Auth: DID signature
2006
- // - Verify: Usage quota (Free: <120K, Pro: unlimited)
2007
- // - Response: { cryptoBundle, share2, version }
2008
-
2009
- // 5. Load crypto dynamically (Share 1 + Share 2 = complete algorithm)
2010
- // 6. Cache in memory (session-only, 7-day expiration)
2011
- // 7. Use reconstructed XorIDA algorithm
2012
-
2013
- await agent.send({
2014
- to: recipientDid,
2015
- payload: { amount: 100, currency: 'BTC' },
2016
- security: 'high' // Uses XorIDA (2-of-3 threshold)
2017
- });
2018
- ```
2019
-
2020
- ### Why This Matters
2021
-
2022
- **Without Full Control:**
2023
- - Complete XorIDA algorithm exposed in npm tarball
2024
- - Anyone can download and use without payment
2025
- - Patent protection (US 11,972,000) defeated
2026
- - Revenue model bypassed
2027
-
2028
- **With Full Control:**
2029
- - Share 1 alone is mathematically useless (information-theoretic security)
2030
- - Share 2 requires usage-based quota verification
2031
- - Patent-protected algorithms delivered only to paying users (or within free tier quota)
2032
- - Reverse engineering requires breaking AES-256-GCM encryption
2033
-
2034
- **Revenue Protection:**
2035
- - Free tier: 100K ops/month (generous for experimentation)
2036
- - Pro tier: Usage-based billing scales with value delivered
2037
- - DeploymentID tracking prevents quota reset attacks (DID rotation doesn't bypass limits)
2038
-
2039
- See [IP Protection Documentation](./docs/ip-protection.md) for complete technical details.
2040
-
2041
- ## Data Collection
2042
-
2043
- xBind makes network connections for three purposes, each with different security and privacy characteristics:
2044
-
2045
- ### 1. Local Network Discovery (Peer Discovery Model Only)
2046
-
2047
- **When:** Only when using the Peer Discovery connection model for IoT devices and offline pairing.
2048
-
2049
- **What:** Sends mDNS (multicast DNS) broadcast messages on your local network to discover nearby xBind-compatible devices.
2050
-
2051
- **Data transmitted:**
2052
- - Device DID (cryptographic identity, public key)
2053
- - Device type identifier
2054
- - Service announcement (port, protocol version)
2055
-
2056
- **Security:** Broadcast messages are visible to all devices on the local network. Does NOT transmit private keys, message content, or personal data. Recipients cannot impersonate your device without the private key.
2057
-
2058
- **Privacy:** Other connection models (Invite Code, QR Code, Trust Registry) do NOT use local network discovery.
2059
-
2060
- ### 2. Gateway Communication (gateway.private.me)
2061
-
2062
- **When:** During message delivery, Share 2 retrieval, and connection establishment.
2063
-
2064
- **What:** Encrypted communication with gateway.private.me for coordination and IP protection.
2065
-
2066
- **Data transmitted:**
2067
- - **Share 2 delivery:** Encrypted share required for Full Control vault store reconstruction (payment-gated)
2068
- - **Usage metrics:** Operation counts, error codes, latency (anonymized, no message content)
2069
- - **Connection metadata:** DID identifiers, sequence numbers, checkpoints (for message ordering)
2070
- - **Push notifications:** Delivery receipts, presence signals (encrypted, no content)
2071
-
2072
- **Security:** All communication uses TLS 1.3. Gateway is non-authoritative and cannot forge identity or decrypt messages. See [Gateway Architecture](./docs/gateway-architecture.md).
2073
-
2074
- **Privacy:** No message content, API credentials, or plaintext data transmitted. DIDs are pseudonymous identifiers.
2075
-
2076
- ### 3. Full Control Share Retrieval
2077
-
2078
- **When:** During initial setup and algorithm reconstruction.
2079
-
2080
- **What:** Downloads Share 2 (Vault Store) from gateway.private.me after payment verification.
2081
-
2082
- **Data transmitted:**
2083
- - Payment proof (Stripe subscription ID)
2084
- - xBind authentication token (cryptographic proof of identity)
2085
- - Package identifier and version
2086
-
2087
- **Security:** Share 2 is AES-256-GCM encrypted with FULL_CONTROL_MASTER_KEY. Without both Share 1 (npm) and Share 2 (gateway), the algorithm cannot execute.
2088
-
2089
- **Privacy:** Payment verification uses Stripe (see [Stripe Privacy](https://stripe.com/privacy)). xBind does not store credit card data.
2090
-
2091
- ### Data Retention
2092
-
2093
- - **Usage metrics:** 90 days (aggregated, anonymized)
2094
- - **Connection metadata:** 30 days (sequence numbers, checkpoints)
2095
- - **Share 2 downloads:** Access logs retained per payment verification requirements
2096
-
2097
- ### Opt-Out
2098
-
2099
- **Local network discovery:** Disable by not using Peer Discovery connection model.
2100
-
2101
- **Gateway communication:** Required for message delivery. Self-hosted gateway option available for enterprise (contact contact@private.me).
2102
-
2103
- **Usage metrics:** Cannot be disabled (required for billing and abuse prevention).
2104
-
2105
- For complete privacy details, see [Privacy Policy](https://private.me/privacy).
2106
-
2107
- ## Legal
2108
-
2109
- [Terms of Service](https://private.me/terms) • [Privacy Policy](https://private.me/privacy) • [License](./LICENSE.md)
2110
-
2111
- ## Export Control Notice
2112
-
2113
- This package contains cryptographic software. Export restrictions may apply. Users are responsible for compliance with U.S. Export Administration Regulations (EAR) and jurisdiction-specific export control requirements.
2114
-
2115
- ---
2116
-
2117
- **License:** Proprietary
2118
-
2119
- ---
2120
-
2121
- **Questions?** [Documentation](./docs/README.md) • [White paper](https://private.me/docs/xbind.html) • [Issues](https://github.com/xail-io/xail/issues)