@private.me/xbind 3.0.1 → 3.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/README.md +2419 -216
  2. package/README.md.backup +2121 -0
  3. package/dist-standalone/_deps/shared/cjs/errors.js +1 -1
  4. package/dist-standalone/_deps/shared/cjs/index.js +1 -1
  5. package/dist-standalone/_deps/shared/cjs/types.js +1 -1
  6. package/dist-standalone/_deps/shared/errors.js +1 -1
  7. package/dist-standalone/_deps/shared/index.js +1 -1
  8. package/dist-standalone/_deps/shared/types.js +1 -1
  9. package/dist-standalone/_deps/xchange/auto-accept.js +1 -1
  10. package/dist-standalone/_deps/xchange/cjs/auto-accept.js +1 -1
  11. package/dist-standalone/_deps/xchange/cjs/errors.js +1 -1
  12. package/dist-standalone/_deps/xchange/cjs/index.js +1 -1
  13. package/dist-standalone/_deps/xchange/cjs/invite-client.js +1 -1
  14. package/dist-standalone/_deps/xchange/cjs/lazy-init.js +1 -1
  15. package/dist-standalone/_deps/xchange/cjs/trust-integration.js +1 -1
  16. package/dist-standalone/_deps/xchange/cjs/xchange.js +1 -1
  17. package/dist-standalone/_deps/xchange/errors.js +1 -1
  18. package/dist-standalone/_deps/xchange/index.js +1 -1
  19. package/dist-standalone/_deps/xchange/invite-client.js +1 -1
  20. package/dist-standalone/_deps/xchange/lazy-init.js +1 -1
  21. package/dist-standalone/_deps/xchange/trust-integration.js +1 -1
  22. package/dist-standalone/_deps/xchange/xchange.js +1 -1
  23. package/dist-standalone/_deps/xregistry/cjs/discovery.js +1 -1
  24. package/dist-standalone/_deps/xregistry/cjs/errors.js +1 -1
  25. package/dist-standalone/_deps/xregistry/cjs/index.js +1 -1
  26. package/dist-standalone/_deps/xregistry/cjs/registry.js +1 -1
  27. package/dist-standalone/_deps/xregistry/cjs/schema.js +1 -1
  28. package/dist-standalone/_deps/xregistry/cjs/types.js +1 -1
  29. package/dist-standalone/_deps/xregistry/discovery.js +1 -1
  30. package/dist-standalone/_deps/xregistry/errors.js +1 -1
  31. package/dist-standalone/_deps/xregistry/index.js +1 -1
  32. package/dist-standalone/_deps/xregistry/registry.js +1 -1
  33. package/dist-standalone/_deps/xregistry/schema.js +1 -1
  34. package/dist-standalone/_deps/xregistry/types.js +1 -1
  35. package/dist-standalone/agent-call.d.ts +2 -2
  36. package/dist-standalone/agent-call.js +1 -1
  37. package/dist-standalone/agent.d.ts +2 -0
  38. package/dist-standalone/agent.js +1 -1
  39. package/dist-standalone/async-iterators.d.ts +3 -3
  40. package/dist-standalone/backup.js +1 -1
  41. package/dist-standalone/cjs/agent-call.js +1 -1
  42. package/dist-standalone/cjs/agent.js +1 -1
  43. package/dist-standalone/cjs/backup.js +1 -1
  44. package/dist-standalone/cjs/cli/init.js +1 -1
  45. package/dist-standalone/cjs/connection-pool.js +1 -1
  46. package/dist-standalone/cjs/crypto-utils.js +1 -1
  47. package/dist-standalone/cjs/debug-mode.js +1 -1
  48. package/dist-standalone/cjs/email-transport.js +1 -1
  49. package/dist-standalone/cjs/errors.js +1 -1
  50. package/dist-standalone/cjs/http-compat.js +1 -1
  51. package/dist-standalone/cjs/index.js +1 -1
  52. package/dist-standalone/cjs/lazy-init.js +1 -1
  53. package/dist-standalone/cjs/loopback-transport.js +1 -0
  54. package/dist-standalone/cjs/mdns-discovery.js +1 -1
  55. package/dist-standalone/cjs/plugins/logging.js +1 -1
  56. package/dist-standalone/cjs/runtime/edge.js +1 -1
  57. package/dist-standalone/cjs/security-policy.js +1 -1
  58. package/dist-standalone/cjs/serialization.js +1 -1
  59. package/dist-standalone/cjs/transport.js +1 -1
  60. package/dist-standalone/cjs/trust-registry.js +1 -1
  61. package/dist-standalone/cjs/vault-store-loader.js +1 -1
  62. package/dist-standalone/cjs/version-info.js +1 -1
  63. package/dist-standalone/cjs/xfetch.js +1 -1
  64. package/dist-standalone/cli/init.js +1 -1
  65. package/dist-standalone/cli/setup.js +1 -1
  66. package/dist-standalone/cli/xbind.js +1 -1
  67. package/dist-standalone/connection-pool.js +1 -1
  68. package/dist-standalone/crypto-utils.d.ts +2 -7
  69. package/dist-standalone/crypto-utils.js +1 -1
  70. package/dist-standalone/debug-mode.js +1 -1
  71. package/dist-standalone/email-transport.d.ts +2 -2
  72. package/dist-standalone/email-transport.js +1 -1
  73. package/dist-standalone/errors.d.ts +13 -3
  74. package/dist-standalone/errors.js +1 -1
  75. package/dist-standalone/gateway-state.d.ts +1 -1
  76. package/dist-standalone/health-check.d.ts +5 -1
  77. package/dist-standalone/http-compat.d.ts +1 -1
  78. package/dist-standalone/http-compat.js +1 -1
  79. package/dist-standalone/index.d.ts +15 -4
  80. package/dist-standalone/index.js +1 -1
  81. package/dist-standalone/lazy-init.d.ts +11 -6
  82. package/dist-standalone/lazy-init.js +1 -1
  83. package/dist-standalone/loopback-transport.d.ts +87 -0
  84. package/dist-standalone/loopback-transport.js +1 -0
  85. package/dist-standalone/mdns-discovery.js +1 -1
  86. package/dist-standalone/plugins/logging.js +1 -1
  87. package/dist-standalone/plugins/metrics.d.ts +4 -4
  88. package/dist-standalone/runtime/edge.js +1 -1
  89. package/dist-standalone/runtime/react-native.d.ts +1 -1
  90. package/dist-standalone/security-policy.js +1 -1
  91. package/dist-standalone/serialization.js +1 -1
  92. package/dist-standalone/transport.js +1 -1
  93. package/dist-standalone/trust-registry.d.ts +3 -3
  94. package/dist-standalone/trust-registry.js +1 -1
  95. package/dist-standalone/vault-store-loader.d.ts +9 -0
  96. package/dist-standalone/vault-store-loader.js +1 -1
  97. package/dist-standalone/version-info.js +1 -1
  98. package/dist-standalone/xfetch.js +1 -1
  99. package/package.json +4 -13
  100. package/share1.dat +0 -0
  101. package/dist-standalone/_deps/mldsa-wasm/LICENSE +0 -24
  102. package/dist-standalone/_deps/mldsa-wasm/package.json +0 -46
  103. package/dist-standalone/_deps/shared/cjs/package.json +0 -1
  104. package/dist-standalone/_deps/ux-helpers/cjs/package.json +0 -1
  105. package/dist-standalone/_deps/xchange/cjs/package.json +0 -1
  106. package/dist-standalone/_deps/xregistry/cjs/package.json +0 -1
  107. package/dist-standalone/cjs/package.json +0 -3
  108. package/dist-standalone/package.json +0 -10
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # @private.me/xbind
2
2
 
3
3
  ![npm version](https://img.shields.io/npm/v/@private.me/xbind)
4
- ![version](https://img.shields.io/badge/version-3.0.1-blue)
5
- ![tests](https://img.shields.io/badge/tests-2762%20passing-brightgreen)
4
+ ![version](https://img.shields.io/badge/version-3.0.3-blue)
5
+ ![tests](https://img.shields.io/badge/tests-2951%20passing-brightgreen)
6
6
  ![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue)
7
7
  ![license](https://img.shields.io/badge/license-Proprietary-blue)
8
8
 
@@ -12,14 +12,7 @@ Build AI agents that communicate securely using ML-DSA-65 DID identity, ML-KEM-7
12
12
 
13
13
  Part of the **Private.Me** platform—where APIs have keys, but ACIs have identity.
14
14
 
15
- **Version 3.0.1** — **Major Features:** 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 v1.4.2: Runtime compatibility, API enhancements. Previous v1.3.5: ML-KEM deterministic key generation fix.
16
-
17
- ## Pricing
18
-
19
- **Free tier:** 100,000 operations/month (includes Vault Store access)
20
- **Pro tier:** Unlimited operations
21
-
22
- See [pricing](https://private.me/pricing) for current rates and purchase flow.
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.
23
16
 
24
17
  ## Install
25
18
 
@@ -57,6 +50,7 @@ For production deployments requiring formal cryptographic assurance, please cont
57
50
 
58
51
  **Dangerous practices that expose your identity:**
59
52
 
53
+ <!-- ANTI-PATTERN -->
60
54
  ```typescript
61
55
  // ❌ WRONG: Plaintext file storage
62
56
  const seed = agent.exportSeeds();
@@ -70,6 +64,7 @@ const agent = await Agent.fromSeed('0123456789abcdef...'); // Visible in reposi
70
64
  // ❌ WRONG: Unencrypted database
71
65
  await db.run('INSERT INTO config VALUES (?, ?)', ['seed', seed]); // SQL injection risk
72
66
  ```
67
+ <!-- /ANTI-PATTERN -->
73
68
 
74
69
  **Why this is critical:**
75
70
  - **Identity Theft**: Attacker gains your DID and can impersonate your agent
@@ -83,6 +78,7 @@ await db.run('INSERT INTO config VALUES (?, ?)', ['seed', seed]); // SQL inject
83
78
 
84
79
  #### macOS: Keychain Services
85
80
 
81
+ <!-- SNIPPET -->
86
82
  ```typescript
87
83
  import { exec } from 'node:child_process';
88
84
  import { promisify } from 'node:util';
@@ -104,12 +100,26 @@ async function getSeed(): Promise<string> {
104
100
  }
105
101
 
106
102
  // Create agent from keychain
103
+ import { Agent, HttpTrustRegistry, HttpsTransportAdapter } from '@private.me/xbind';
104
+
107
105
  const seed = await getSeed();
108
- const agent = await Agent.fromSeed(seed);
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;
109
117
  ```
118
+ <!-- /SNIPPET -->
110
119
 
111
120
  #### Windows: Credential Manager (DPAPI)
112
121
 
122
+ <!-- SNIPPET -->
113
123
  ```typescript
114
124
  // Using keytar package for cross-platform keychain access
115
125
  import keytar from 'keytar';
@@ -118,14 +128,28 @@ import keytar from 'keytar';
118
128
  await keytar.setPassword('xbind', 'agent-seed', seed);
119
129
 
120
130
  // Retrieve seed from Windows Credential Manager
131
+ import { Agent, HttpTrustRegistry, HttpsTransportAdapter } from '@private.me/xbind';
132
+
121
133
  const seed = await keytar.getPassword('xbind', 'agent-seed');
122
134
  if (!seed) throw new Error('Seed not found in credential store');
123
135
 
124
- const agent = await Agent.fromSeed(seed);
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;
125
147
  ```
148
+ <!-- /SNIPPET -->
126
149
 
127
150
  #### Linux: Secret Service API (gnome-keyring, KWallet)
128
151
 
152
+ <!-- SNIPPET -->
129
153
  ```typescript
130
154
  import keytar from 'keytar';
131
155
 
@@ -133,11 +157,24 @@ import keytar from 'keytar';
133
157
  await keytar.setPassword('xbind', 'agent-seed', seed);
134
158
 
135
159
  // Retrieve seed from Secret Service
160
+ import { Agent, HttpTrustRegistry, HttpsTransportAdapter } from '@private.me/xbind';
161
+
136
162
  const seed = await keytar.getPassword('xbind', 'agent-seed');
137
163
  if (!seed) throw new Error('Seed not found in Secret Service');
138
164
 
139
- const agent = await Agent.fromSeed(seed);
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;
140
176
  ```
177
+ <!-- /SNIPPET -->
141
178
 
142
179
  **Cross-platform library:**
143
180
  ```bash
@@ -148,6 +185,7 @@ npm install keytar # Unified API for macOS/Windows/Linux keystores
148
185
 
149
186
  For production deployments with compliance requirements (PCI-DSS, HIPAA, SOC 2):
150
187
 
188
+ <!-- SNIPPET -->
151
189
  ```typescript
152
190
  // Using AWS CloudHSM or Azure Key Vault
153
191
  import { KMSClient, DecryptCommand } from '@aws-sdk/client-kms';
@@ -164,12 +202,25 @@ const encryptedSeed = await kms.send(new EncryptCommand({
164
202
  await db.run('INSERT INTO config VALUES (?, ?)', ['seed', encryptedSeed.CiphertextBlob]);
165
203
 
166
204
  // Decrypt seed with KMS at runtime
205
+ import { Agent, HttpTrustRegistry, HttpsTransportAdapter } from '@private.me/xbind';
206
+
167
207
  const decryptedSeed = await kms.send(new DecryptCommand({
168
208
  CiphertextBlob: encryptedSeedFromDB
169
209
  }));
170
210
 
171
- const agent = await Agent.fromSeed(decryptedSeed.Plaintext.toString());
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;
172
222
  ```
223
+ <!-- /SNIPPET -->
173
224
 
174
225
  **HSM Benefits:**
175
226
  - **FIPS 140-2 Level 3** certified hardware
@@ -302,9 +353,15 @@ See [Configuration Guide](./docs/configuration.md) for complete setup instructio
302
353
 
303
354
  ## Pricing
304
355
 
305
- **Free tier available** No credit card required.
356
+ xBind offers three tiers to fit your needs:
306
357
 
307
- See [pricing details](../../docs/pricing-reference.md) for current rates and tier comparison.
358
+ - **Free Tier** Generous monthly operations, no credit card required
359
+ - **Pro Tier** — Unlimited operations for production use
360
+ - **VIP Tier** — Custom limits with priority support
361
+
362
+ **See [pricing details](https://private.me/docs/xbind.html#pricing) for current rates, quotas, and purchase options.**
363
+
364
+ All tiers include full Vault Store access for proprietary algorithms. Billing is usage-based with monthly cycles. No upfront commitment required.
308
365
 
309
366
  [Subscribe now](https://private.me/subscribe?product=xbind)
310
367
 
@@ -423,8 +480,8 @@ Full fingerprinting source code available at `apps/server/src/device-fingerprint
423
480
  ```typescript
424
481
  import { Agent } from '@private.me/xbind';
425
482
 
426
- // Create agent (auto-generates cryptographic identity)
427
- const agent = await Agent.lazy({ name: 'my-service' });
483
+ // Create agent (auto-generates cryptographic identity, throws on error)
484
+ const agent = await Agent.quickstart({ name: 'my-service' });
428
485
 
429
486
  // Send authenticated message
430
487
  const result = await agent.send({
@@ -434,7 +491,8 @@ const result = await agent.send({
434
491
  });
435
492
 
436
493
  if (!result.ok) {
437
- console.error(`Failed: ${result.error}`);
494
+ console.error('Send failed:', result.error.code);
495
+ console.error('Details:', result.error.message);
438
496
  return;
439
497
  }
440
498
 
@@ -442,6 +500,29 @@ console.log('Message sent with cryptographic identity');
442
500
  console.log('Agent DID:', agent.did);
443
501
  ```
444
502
 
503
+ ### Receiving Messages
504
+
505
+ ```typescript
506
+ import { Agent } from '@private.me/xbind';
507
+
508
+ // Assume you received an envelope from your transport layer
509
+ const envelope = // ... from transport
510
+
511
+ // Receive and decrypt the message
512
+ const result = await agent.receive(envelope);
513
+
514
+ if (!result.ok) {
515
+ console.error('Receive failed:', result.error.code);
516
+ console.error('Details:', result.error.message);
517
+ return;
518
+ }
519
+
520
+ const message = result.value;
521
+ console.log('From:', message.sender);
522
+ console.log('Payload:', message.payload);
523
+ console.log('Scope:', message.scope);
524
+ ```
525
+
445
526
  ### Step 3: Understand Your Free Tier
446
527
 
447
528
  - **100,000 operations/month** (free tier)
@@ -452,300 +533,2332 @@ console.log('Agent DID:', agent.did);
452
533
  **At 100K operations:** Email verification enforced (if not already verified)
453
534
  **At 120K operations:** Hard cap reached. Upgrade to Pro for unlimited operations.
454
535
 
536
+ **Purchase & Billing:**
537
+ - Free tier: 100,000 operations/month (includes Vault Store access)
538
+ - Pro tier: Unlimited operations (usage-based billing)
539
+ - See [pricing](../../docs/pricing-reference.md) for details
540
+ - Purchase endpoint: `/api/full-control/share2` (authenticated)
541
+
455
542
  **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.
456
543
 
457
544
  **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.
458
545
 
459
546
  [More examples](./docs/examples.md) • [Python examples](./python/README.md)
460
547
 
461
- ## Python SDK
548
+ ## Programmatic Quickstart
462
549
 
463
- Complete Python bindings for agent identity and messaging:
550
+ **Complete, copy-paste ready examples** tested in clean environments:
464
551
 
465
- ```python
466
- from private_me.xbind import Agent
552
+ ### Example 1: Create Agent & Get DID
467
553
 
468
- # Create agent from private key
469
- agent = Agent.from_private_key(private_key_bytes)
554
+ <!-- RUNNABLE-EXAMPLE -->
555
+ ```typescript
556
+ import { Agent } from '@private.me/xbind';
470
557
 
471
- # Make authenticated call
472
- result = agent.call('stripe:createCharge', {
473
- 'amount': 100,
474
- 'currency': 'usd',
475
- 'description': 'AI agent purchase'
476
- })
558
+ // Create agent with automatic identity generation
559
+ const agent = await Agent.quickstart({ name: 'test-agent' });
477
560
 
478
- if result['ok']:
479
- print(f"Charge ID: {result['data']['id']}")
480
- print(f"Agent DID: {result['audit']['agent']}")
481
- else:
482
- print(f"Error: {result['error']['message']}")
561
+ console.log('Agent DID:', agent.did);
562
+ console.log('Agent name:', agent.name);
483
563
  ```
564
+ <!-- /RUNNABLE-EXAMPLE -->
484
565
 
485
- See [Python SDK documentation](./python/README.md) for complete API reference and examples.
566
+ **Expected output:**
567
+ ```
568
+ Agent DID: did:key:z6Mk...
569
+ Agent name: test-agent
570
+ ```
486
571
 
487
- ## Why xBind?
572
+ ### Example 2: Agent Identity Details
488
573
 
489
- 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.
574
+ <!-- RUNNABLE-EXAMPLE -->
575
+ ```typescript
576
+ import { Agent } from '@private.me/xbind';
490
577
 
491
- ## Getting Started
578
+ // Create agent
579
+ const agent = await Agent.quickstart({ name: 'identity-test' });
492
580
 
493
- **[Guide](../../docs/xbind-integrations/getting-started/index.md)** Concepts, migration
494
- **[Quickstart](../../docs/xbind-integrations/getting-started/quickstart.md)** — 15-second setup
581
+ // Access identity information
582
+ console.log('DID:', agent.did);
583
+ console.log('Has Ed25519 keys:', !!agent.identity.publicKey);
584
+ console.log('Has X25519 keys:', !!agent.identity.x25519PublicKey);
585
+ console.log('Has ML-KEM keys:', !!agent.identity.mlKemPublicKey);
586
+ ```
587
+ <!-- /RUNNABLE-EXAMPLE -->
495
588
 
496
- ## Features
589
+ **Expected output:**
590
+ ```
591
+ DID: did:key:z6Mk...
592
+ Has Ed25519 keys: true
593
+ Has X25519 keys: true
594
+ Has ML-KEM keys: true
595
+ ```
497
596
 
498
- **Zero-config JITR:** Just-in-Time Registration auto-registers agents with trust registry on first use (AWS IoT JITR, OAuth DCR, MCP 2025 standards).
597
+ ### Example 3: Registry & Transport Configuration
499
598
 
500
- ### Core Security
501
- - **Post-quantum cryptography:** ML-KEM-768 key encapsulation, ML-DSA-65 digital signatures (FIPS 203/204)
502
- - **Hybrid key agreement:** X-Wing combiner (IETF draft-10) with 6-parameter domain separation
503
- - **XorIDA split-channel delivery:** Information-theoretic threshold sharing (2-of-2, 2-of-3, 3-of-5)
504
- - **Cryptographic request signing:** Ed25519 signatures prevent DID header forgery
505
- - **Key rotation:** ML-KEM + X25519 rotation with fallback decryption (10 rotation history)
506
- - **Proof-of-Possession:** Ed25519 signature verification prevents DID spoofing
507
- - **Share-aware nonce deduplication:** Prevents replay attacks with composite keys
599
+ <!-- RUNNABLE-EXAMPLE -->
600
+ ```typescript
601
+ import { Agent } from '@private.me/xbind';
508
602
 
509
- ### Runtime Compatibility (4 Platforms)
510
- - **Browser:** WebCrypto API, IndexedDB/localStorage adapters, WASM support, service workers
511
- - **React Native:** AsyncStorage, Buffer polyfills, crypto detection, iOS/Android platform support
512
- - **Edge Runtime:** Cloudflare Workers, Vercel Edge, Deno Deploy, KV storage, <1MB optimization
513
- - **Node.js:** Native crypto module, filesystem storage, full feature set
603
+ // Quickstart uses defaults: MemoryRegistry + HttpsTransport
604
+ const agent = await Agent.quickstart({ name: 'config-test' });
514
605
 
515
- ### Operations Patterns
516
- - **Health checks:** Startup/liveness/readiness probes, Kubernetes-compatible, Express/Fastify middleware
517
- - **Circuit breakers:** 3-state machine (closed/open/half-open), registry/gateway/S3 presets, automatic recovery
518
- - **Graceful degradation:** QoS tiers, intelligent caching, service health tracking, fallback strategies
519
- - **Performance benchmarks:** Latency histograms with baselines for key ops (ML-KEM, ML-DSA, encryption)
520
- - **Structured logging:** 4 levels (DEBUG/INFO/WARN/ERROR), automatic sensitive data redaction, correlation IDs
521
- - **Telemetry:** Prometheus-compatible metrics (counters, histograms, gauges), operation latency tracking
606
+ // Check configuration
607
+ console.log('Registry type:', agent.registry.constructor.name);
608
+ console.log('Transports count:', agent.transports.length);
609
+ console.log('Transport type:', agent.transports[0].constructor.name);
610
+ ```
611
+ <!-- /RUNNABLE-EXAMPLE -->
522
612
 
523
- ### Security Audit Preparation
524
- - **STRIDE threat modeling:** 66 threats analyzed across 6 categories
525
- - **Crypto claims documentation:** 41 cryptographic claims documented with evidence
526
- - **Known limitations disclosure:** 24 limitations disclosed for auditor transparency
527
- - **Audit-ready:** NCC Group / Trail of Bits preparation ($100K-$150K, 12-week timeline)
613
+ **Expected output:**
614
+ ```
615
+ Registry type: MemoryTrustRegistry
616
+ Transports count: 1
617
+ Transport type: HttpsTransportAdapter
618
+ ```
528
619
 
529
- ### API Enhancements
530
- - **Batch operations:** 6-8x speedup for parallel operations with single network round-trip
531
- - **Async iterators:** `for await...of` syntax support for streaming message processing
532
- - **Plugin/middleware system:** 6-phase lifecycle hooks with 3 built-in plugins
533
- - **Event emitters:** Type-safe events with 5 event types, priority execution, bubbling
534
- - **Cancellation tokens:** AbortController integration with timeout support
535
- - **Progress callbacks:** 4 specialized trackers (operation, transfer, share, encryption)
536
- - **Retry strategies:** 4 strategies (exponential, linear, immediate, jittered) + circuit breaker integration
537
- - **Request timeouts:** Per-operation config with inheritance and cancellation
538
- - **Connection pooling:** 60-70% latency reduction with keep-alive and metrics
539
- - **Serialization formats:** JSON/MessagePack/CBOR support with auto-detection and negotiation
540
- - **Configuration validation:** Comprehensive validation with clear error messages
541
- - **Debug mode:** Performance profiling, network/crypto tracing, state inspection
542
- - **SDK version info:** Capability detection, deprecation warnings, compatibility checking
620
+ **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:
621
+ - Sending messages to other agents
622
+ - Exceeding 100K operations/month
623
+ - Accessing production features
543
624
 
544
- ### Developer Experience
545
- - **Type safety:** `Result<T, E>` error handling with 96+ error codes
546
- - **TypeScript strict mode:** Zero type errors, complete type coverage
547
- - **Python SDK:** Complete bindings for identity, messaging, and encryption
548
- - **User-friendly errors:** 75+ errors with actionable recovery hints
549
- - **Complete API docs:** 2,587 lines with 50+ usage examples
550
- - **CHANGELOG generation:** Automated Keep a Changelog format with semver discipline
551
- - **Dependency audit:** Weekly Dependabot scans, 5-layer vulnerability scanning
552
- - **Crypto license compliance:** Automated MIT/MIT-0 validation with GPL/AGPL detection
625
+ [More examples](./docs/examples.md) • [Python examples](./python/README.md)
553
626
 
554
- ### Enterprise Features
555
- - **Version negotiation:** Explicit SDK version fields prevent "404 Route not found" in mixed fleets
556
- - **Multi-device session resume:** AES-256-GCM encrypted session state sync with PBKDF2 (100k iterations)
557
- - **Encrypted backup/restore:** Password-protected identity export with PBKDF2-SHA256 (310k iterations)
558
- - **Offline sync:** Message queueing for offline devices (max 1000 messages, 24-hour TTL)
559
- - **Registry expiration:** TTL support with cleanup (default 7 days)
560
- - **Server-side spending limits:** Redis-backed enforcement with deployment-level aggregation
561
- - **Rate limiting:** Three-tier protection (per-DID, per-IP, global)
562
- - **Full Control IP protection:** Store Front (npm) + Vault Store (EC2) with payment verification
627
+ ## Post-Quantum Cryptography & Envelopes
563
628
 
564
- ### Testing & Quality
565
- - **2,762 tests:** Comprehensive coverage (96.6% passing)
566
- - **End-to-end integration:** Full message flow tests (Agent A → Gateway → Agent B)
567
- - **Gateway concurrency:** 100 concurrent sends, race condition detection
568
- - **Network partition recovery:** Disconnect/reconnect cycles with retry logic
569
- - **PLAN-3 hybrid signatures:** Bilateral authorization with composite verification
629
+ **Complete examples for ML-DSA signatures, key export, and envelope operations:**
570
630
 
571
- ## Bundle Size Optimization (Tree-Shaking)
631
+ ### Example 4: ML-DSA-65 Signing and Verification
632
+
633
+ <!-- RUNNABLE-EXAMPLE -->
634
+ ```typescript
635
+ import { Agent, signMlDsa65, verifyMlDsa65 } from '@private.me/xbind';
636
+
637
+ // Create agent with post-quantum signatures enabled
638
+ const agent = await Agent.quickstart({
639
+ name: 'pq-test',
640
+ postQuantumSig: true
641
+ });
572
642
 
573
- **New in v3.0.0:** Full Control IP Protection - 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.
643
+ // Sign data with ML-DSA-65
644
+ const data = new TextEncoder().encode('Critical transaction data');
645
+ const mlDsaSecretKey = agent.identity.mlDsaSecretKey;
574
646
 
575
- ### Full Import (Convenience)
647
+ if (!mlDsaSecretKey) {
648
+ throw new Error('ML-DSA keys not available');
649
+ }
650
+
651
+ const signResult = await signMlDsa65(mlDsaSecretKey, data);
652
+ if (!signResult.ok) {
653
+ throw new Error(`Signing failed: ${signResult.error}`);
654
+ }
655
+
656
+ console.log('ML-DSA-65 signature length:', signResult.value.length); // 3309 bytes
657
+
658
+ // Verify signature
659
+ const mlDsaPublicKey = agent.identity.mlDsaPublicKey!;
660
+ const verifyResult = await verifyMlDsa65(mlDsaPublicKey, signResult.value, data);
661
+
662
+ if (verifyResult.ok && verifyResult.value) {
663
+ console.log('Post-quantum signature verified successfully');
664
+ } else {
665
+ console.error('Signature verification failed');
666
+ }
667
+ ```
668
+ <!-- /RUNNABLE-EXAMPLE -->
669
+
670
+ **ML-DSA-65 size constants:**
576
671
 
672
+ <!-- RUNNABLE-EXAMPLE -->
577
673
  ```typescript
578
- import { Agent, generateIdentity } from '@private.me/xbind';
674
+ import { ML_DSA65_SIG_BYTES, ML_DSA65_PK_BYTES, ML_DSA65_SK_BYTES } from '@private.me/xbind';
579
675
 
580
- // Bundle size: ~450 KB
676
+ console.log('ML-DSA-65 signature size:', ML_DSA65_SIG_BYTES); // 3309 bytes
677
+ console.log('ML-DSA-65 public key size:', ML_DSA65_PK_BYTES); // 1952 bytes
678
+ console.log('ML-DSA-65 secret key size:', ML_DSA65_SK_BYTES); // 4032 bytes
581
679
  ```
680
+ <!-- /RUNNABLE-EXAMPLE -->
582
681
 
583
- ### Granular Import (Optimized)
682
+ **Expected output:**
683
+ ```
684
+ ML-DSA-65 signature length: 3309
685
+ Post-quantum signature verified successfully
686
+ ```
687
+
688
+ ### Example 5: Export Post-Quantum Keys
584
689
 
690
+ <!-- RUNNABLE-EXAMPLE -->
585
691
  ```typescript
586
- import { Agent } from '@private.me/xbind/agent';
587
- import { generateIdentity } from '@private.me/xbind/identity';
692
+ import {
693
+ Agent,
694
+ exportMlDsaSecretKey,
695
+ exportMlDsaPublicKey,
696
+ exportMlKemSecretKey,
697
+ exportMlKemPublicKey
698
+ } from '@private.me/xbind';
699
+
700
+ // Create agent with post-quantum cryptography
701
+ const agent = await Agent.quickstart({
702
+ name: 'export-test',
703
+ postQuantumSig: true
704
+ });
588
705
 
589
- // Bundle size: ~180 KB (60% reduction)
706
+ // Export ML-DSA keys (signatures)
707
+ const mlDsaSecret = exportMlDsaSecretKey(agent.identity);
708
+ const mlDsaPublic = exportMlDsaPublicKey(agent.identity);
709
+
710
+ console.log('ML-DSA-65 secret key:', mlDsaSecret ? `${mlDsaSecret.length} bytes` : 'N/A');
711
+ console.log('ML-DSA-65 public key:', mlDsaPublic ? `${mlDsaPublic.length} bytes` : 'N/A');
712
+
713
+ // Export ML-KEM keys (encryption)
714
+ const mlKemSecret = exportMlKemSecretKey(agent.identity);
715
+ const mlKemPublic = exportMlKemPublicKey(agent.identity);
716
+
717
+ console.log('ML-KEM-768 secret key:', mlKemSecret ? `${mlKemSecret.length} bytes` : 'N/A');
718
+ console.log('ML-KEM-768 public key:', mlKemPublic ? `${mlKemPublic.length} bytes` : 'N/A');
590
719
  ```
720
+ <!-- /RUNNABLE-EXAMPLE -->
591
721
 
592
- ### Available Entry Points
722
+ **Expected output:**
723
+ ```
724
+ ML-DSA-65 secret key: 32 bytes
725
+ ML-DSA-65 public key: 1952 bytes
726
+ ML-KEM-768 secret key: 2400 bytes
727
+ ML-KEM-768 public key: 1184 bytes
728
+ ```
593
729
 
594
- | Entry Point | Exports | Bundle Impact |
595
- |-------------|---------|---------------|
596
- | `@private.me/xbind` | All exports | Full package (~450 KB) |
597
- | `@private.me/xbind/agent` | `Agent`, `AgentOptions` | ~180 KB |
598
- | `@private.me/xbind/identity` | `generateIdentity`, `Identity` | ~120 KB |
599
- | `@private.me/xbind/trust-registry` | Registry classes | ~200 KB |
600
- | `@private.me/xbind/key-agreement` | Key exchange functions | ~90 KB |
601
- | `@private.me/xbind/errors` | Error types | 0 KB (types only) |
730
+ ### Example 6: Key Rotation with Backward Compatibility
602
731
 
603
- **Bundler Support:** Works with webpack 5+, Rollup, esbuild, and Vite. Tree-shaking is automatic in production mode.
732
+ <!-- RUNNABLE-EXAMPLE -->
733
+ ```typescript
734
+ import { Agent, rotateKeys } from '@private.me/xbind';
604
735
 
605
- **See:** [Tree-Shaking Guide](./docs/packaging/tree-shaking.md) for detailed usage and configuration.
736
+ // Create agent
737
+ const agent = await Agent.quickstart({ name: 'rotation-test' });
606
738
 
607
- ## Automatic XorIDA Split-Channel Protection
739
+ // Store original X25519 public key
740
+ const originalX25519 = Buffer.from(agent.identity.rawX25519PublicKey).toString('hex');
608
741
 
609
- xBind automatically activates information-theoretic XorIDA threshold sharing for high-risk operations. No code changes required—security is transparent.
742
+ // Rotate encryption keys (X25519 + ML-KEM)
743
+ const rotatedResult = await rotateKeys(agent.identity);
610
744
 
611
- ### Risk Tags (Recommended for Crypto)
745
+ if (!rotatedResult.ok) {
746
+ throw new Error(`Key rotation failed: ${rotatedResult.error}`);
747
+ }
612
748
 
613
- For cryptocurrency transactions (BTC, ETH, etc.), use explicit risk tags in your payload:
749
+ const rotatedIdentity = rotatedResult.value;
750
+
751
+ // New keys are active
752
+ const newX25519 = Buffer.from(rotatedIdentity.rawX25519PublicKey).toString('hex');
753
+ console.log('Keys rotated successfully');
754
+ console.log('Original X25519:', originalX25519.substring(0, 16) + '...');
755
+ console.log('New X25519:', newX25519.substring(0, 16) + '...');
756
+
757
+ // Old keys preserved for decryption
758
+ console.log('Rotation history:', rotatedIdentity.rotatedKeys?.length ?? 0);
759
+ console.log('DID unchanged:', agent.identity.did === rotatedIdentity.did);
760
+ ```
761
+ <!-- /RUNNABLE-EXAMPLE -->
762
+
763
+ **Expected output:**
764
+ ```
765
+ Keys rotated successfully
766
+ Original X25519: a1b2c3d4e5f6g7h8...
767
+ New X25519: 9i0j1k2l3m4n5o6p...
768
+ Rotation history: 1
769
+ DID unchanged: true
770
+ ```
614
771
 
772
+ ### Example 7: Create V1 Envelope (Classical Crypto)
773
+
774
+ <!-- RUNNABLE-EXAMPLE -->
615
775
  ```typescript
616
- // Low risk: 2-of-2 threshold
617
- await agent.send({
618
- to: recipientDid,
619
- payload: { amount: 0.5, currency: 'BTC', risk: 'low' }
620
- });
776
+ import { Agent, createEnvelope, generateSharedKey } from '@private.me/xbind';
621
777
 
622
- // Medium risk: 2-of-3 threshold
623
- await agent.send({
624
- to: recipientDid,
625
- payload: { amount: 5.0, currency: 'ETH', risk: 'medium' }
626
- });
778
+ // Generate shared AES-256-GCM key
779
+ const sharedKey = await generateSharedKey();
627
780
 
628
- // High risk: 3-of-5 threshold
629
- await agent.send({
630
- to: recipientDid,
631
- payload: { amount: 50, currency: 'BTC', risk: 'high' }
632
- });
781
+ // Create agent
782
+ const agent = await Agent.quickstart({ name: 'envelope-test' });
633
783
 
634
- // Critical risk: 3-of-5 threshold
635
- await agent.send({
636
- to: recipientDid,
637
- payload: { amount: 100, currency: 'BTC', risk: 'critical' }
784
+ // Create encrypted envelope
785
+ const plaintext = new TextEncoder().encode(JSON.stringify({
786
+ action: 'transfer',
787
+ amount: 1000
788
+ }));
789
+
790
+ const envelopeResult = await createEnvelope({
791
+ senderDid: agent.did,
792
+ recipientDid: 'did:key:z6MkRecipient...',
793
+ scope: 'billing:write',
794
+ plaintext,
795
+ privateKey: agent.identity.privateKey,
796
+ sharedKey
638
797
  });
798
+
799
+ if (!envelopeResult.ok) {
800
+ throw new Error(`Envelope creation failed: ${envelopeResult.error}`);
801
+ }
802
+
803
+ const envelope = envelopeResult.value;
804
+ console.log('Envelope version:', envelope.v);
805
+ console.log('Algorithm:', envelope.alg);
806
+ console.log('Signature length:', envelope.signature.length);
807
+ console.log('Encrypted payload:', envelope.payload.substring(0, 32) + '...');
639
808
  ```
809
+ <!-- /RUNNABLE-EXAMPLE -->
640
810
 
641
- ### Fiat Currency Auto-Detection
811
+ **Expected output:**
812
+ ```
813
+ Envelope version: 1
814
+ Algorithm: Ed25519
815
+ Signature length: 88
816
+ Encrypted payload: aGVsbG8gd29ybGQgdGhpcyBpcyBhIHRl...
817
+ ```
642
818
 
643
- For fiat currencies (USD, EUR, GBP), xBind uses numeric thresholds:
819
+ ### Example 8: Create V2 Envelope (Hybrid KEM)
644
820
 
821
+ <!-- RUNNABLE-EXAMPLE -->
645
822
  ```typescript
646
- // Automatically triggers 2-of-3 (amount >= $100,000)
647
- await agent.send({
648
- to: recipientDid,
649
- payload: { amount: 500000, currency: 'USD', action: 'transfer' }
823
+ import { Agent, createEnvelopeV2, generateSharedKey } from '@private.me/xbind';
824
+ import { createMlKem768 } from 'mlkem';
825
+
826
+ // Generate shared AES-256-GCM key
827
+ const sharedKey = await generateSharedKey();
828
+
829
+ // Generate ephemeral X25519 keypair
830
+ const x25519Pair = await crypto.subtle.generateKey(
831
+ { name: 'X25519' },
832
+ true,
833
+ ['deriveBits']
834
+ );
835
+ const ephemeralPub = new Uint8Array(
836
+ await crypto.subtle.exportKey('raw', x25519Pair.publicKey)
837
+ );
838
+
839
+ // Generate ML-KEM-768 ciphertext (mocked for example)
840
+ const mlkem = await createMlKem768();
841
+ const recipientMlKemPub = mlkem.generateKeyPair()[0]; // Mock recipient public key
842
+ const [kemCiphertext] = mlkem.encap(recipientMlKemPub);
843
+
844
+ const agent = await Agent.quickstart({ name: 'v2-envelope-test' });
845
+
846
+ const envelope = await createEnvelopeV2({
847
+ senderDid: agent.did,
848
+ recipientDid: 'did:key:z6MkRecipient...',
849
+ scope: 'messaging',
850
+ plaintext: new TextEncoder().encode('Hybrid KEM message'),
851
+ privateKey: agent.identity.privateKey,
852
+ sharedKey,
853
+ ephemeralPublicKey: ephemeralPub,
854
+ kemCiphertext
650
855
  });
651
856
 
652
- // Automatically triggers 3-of-5 (amount >= $1,000,000)
653
- await agent.send({
654
- to: recipientDid,
655
- payload: { amount: 2500000, currency: 'USD', action: 'transfer' }
656
- });
857
+ if (envelope.ok) {
858
+ console.log('Envelope version:', envelope.value.v);
859
+ console.log('KEM mode:', envelope.value.kem);
860
+ console.log('ML-KEM ciphertext length:', envelope.value.kemCiphertext.length);
861
+ }
657
862
  ```
863
+ <!-- /RUNNABLE-EXAMPLE -->
658
864
 
659
- ### Manual Security Override
865
+ **Expected output:**
866
+ ```
867
+ Envelope version: 2
868
+ KEM mode: X25519-MLKEM768
869
+ ML-KEM ciphertext length: 1452
870
+ ```
660
871
 
661
- Override automatic detection with explicit security levels:
872
+ ### Example 9: Create V3 Envelope (Dual Signatures)
662
873
 
874
+ <!-- RUNNABLE-EXAMPLE -->
663
875
  ```typescript
664
- // Force 2-of-3 regardless of amount/risk
665
- await agent.send({
666
- to: recipientDid,
667
- payload: data,
668
- security: 'high'
876
+ import { Agent, createEnvelopeV3, generateSharedKey } from '@private.me/xbind';
877
+ import { createMlKem768 } from 'mlkem';
878
+
879
+ // Create agent with ML-DSA enabled
880
+ const agent = await Agent.quickstart({
881
+ name: 'v3-envelope-test',
882
+ postQuantumSig: true
669
883
  });
670
884
 
671
- // Force 3-of-5 for maximum security
672
- await agent.send({
673
- to: recipientDid,
674
- payload: data,
675
- security: 'critical'
885
+ if (!agent.identity.mlDsaSecretKey) {
886
+ throw new Error('ML-DSA keys required for V3 envelopes');
887
+ }
888
+
889
+ // Generate shared key and KEM materials
890
+ const sharedKey = await generateSharedKey();
891
+ const x25519Pair = await crypto.subtle.generateKey(
892
+ { name: 'X25519' },
893
+ true,
894
+ ['deriveBits']
895
+ );
896
+ const ephemeralPub = new Uint8Array(
897
+ await crypto.subtle.exportKey('raw', x25519Pair.publicKey)
898
+ );
899
+
900
+ const mlkem = await createMlKem768();
901
+ const recipientMlKemPub = mlkem.generateKeyPair()[0];
902
+ const [kemCiphertext] = mlkem.encap(recipientMlKemPub);
903
+
904
+ const envelope = await createEnvelopeV3({
905
+ senderDid: agent.did,
906
+ recipientDid: 'did:key:z6MkRecipient...',
907
+ scope: 'high-security',
908
+ plaintext: new TextEncoder().encode('Dual-signature message'),
909
+ privateKey: agent.identity.privateKey,
910
+ sharedKey,
911
+ ephemeralPublicKey: ephemeralPub,
912
+ kemCiphertext,
913
+ mlDsaSecretKey: agent.identity.mlDsaSecretKey
914
+ });
915
+
916
+ if (envelope.ok) {
917
+ console.log('Envelope version:', envelope.value.v);
918
+ console.log('Signature scheme:', envelope.value.sig);
919
+ console.log('Ed25519 signature:', envelope.value.signature.substring(0, 16) + '...');
920
+ console.log('ML-DSA signature:', envelope.value.pqSignature.substring(0, 16) + '...');
921
+ }
922
+ ```
923
+ <!-- /RUNNABLE-EXAMPLE -->
924
+
925
+ **Expected output:**
926
+ ```
927
+ Envelope version: 3
928
+ Signature scheme: Ed25519+MLDSA65
929
+ Ed25519 signature: SGVsbG8gd29ybGQ...
930
+ ML-DSA signature: cG9zdC1xdWFudHV...
931
+ ```
932
+
933
+ ### Example 10: Create V4 Envelope (Xchange Mode)
934
+
935
+ <!-- RUNNABLE-EXAMPLE -->
936
+ ```typescript
937
+ import { Agent, createEnvelopeV4 } from '@private.me/xbind';
938
+
939
+ const agent = await Agent.quickstart({ name: 'xchange-test' });
940
+
941
+ // Xchange mode: Share data is the payload (no encryption layer)
942
+ const shareData = new TextEncoder().encode('XorIDA share data');
943
+
944
+ const envelope = await createEnvelopeV4({
945
+ senderDid: agent.did,
946
+ recipientDid: 'did:key:z6MkRecipient...',
947
+ scope: 'xchange',
948
+ shareData,
949
+ privateKey: agent.identity.privateKey,
950
+ shareIndex: 0,
951
+ shareTotal: 3,
952
+ shareThreshold: 2,
953
+ shareGroupId: 'group-uuid-1234',
954
+ shareHmacKey: 'base64-hmac-key',
955
+ shareHmacSig: 'base64-hmac-sig'
956
+ });
957
+
958
+ if (envelope.ok) {
959
+ console.log('Envelope version:', envelope.value.v);
960
+ console.log('KEM mode:', envelope.value.kem);
961
+ console.log('Share index:', envelope.value.shareIndex);
962
+ console.log('Threshold:', `${envelope.value.shareThreshold}-of-${envelope.value.shareTotal}`);
963
+ }
964
+ ```
965
+ <!-- /RUNNABLE-EXAMPLE -->
966
+
967
+ **Expected output:**
968
+ ```
969
+ Envelope version: 4
970
+ KEM mode: Xchange
971
+ Share index: 0
972
+ Threshold: 2-of-3
973
+ ```
974
+
975
+ ### Example 11: Decrypt Envelope Payload
976
+
977
+ <!-- RUNNABLE-EXAMPLE -->
978
+ ```typescript
979
+ import {
980
+ Agent,
981
+ createEnvelope,
982
+ decryptPayload,
983
+ generateSharedKey
984
+ } from '@private.me/xbind';
985
+
986
+ // Create and encrypt envelope
987
+ const sharedKey = await generateSharedKey();
988
+ const agent = await Agent.quickstart({ name: 'decrypt-test' });
989
+
990
+ const originalMessage = 'Secret payment details';
991
+ const plaintext = new TextEncoder().encode(originalMessage);
992
+
993
+ const envelopeResult = await createEnvelope({
994
+ senderDid: agent.did,
995
+ recipientDid: 'did:key:z6MkRecipient...',
996
+ scope: 'payments',
997
+ plaintext,
998
+ privateKey: agent.identity.privateKey,
999
+ sharedKey
1000
+ });
1001
+
1002
+ if (!envelopeResult.ok) {
1003
+ throw new Error('Envelope creation failed');
1004
+ }
1005
+
1006
+ // Decrypt the payload
1007
+ const decryptResult = await decryptPayload(envelopeResult.value, sharedKey);
1008
+
1009
+ if (!decryptResult.ok) {
1010
+ throw new Error(`Decryption failed: ${decryptResult.error}`);
1011
+ }
1012
+
1013
+ const decryptedMessage = new TextDecoder().decode(decryptResult.value);
1014
+ console.log('Decrypted:', decryptedMessage);
1015
+ console.log('Match:', decryptedMessage === originalMessage);
1016
+ ```
1017
+ <!-- /RUNNABLE-EXAMPLE -->
1018
+
1019
+ **Expected output:**
1020
+ ```
1021
+ Decrypted: Secret payment details
1022
+ Match: true
1023
+ ```
1024
+
1025
+ ### Example 12: Serialize and Deserialize Envelope
1026
+
1027
+ <!-- RUNNABLE-EXAMPLE -->
1028
+ ```typescript
1029
+ import {
1030
+ Agent,
1031
+ createEnvelope,
1032
+ serializeEnvelope,
1033
+ deserializeEnvelope,
1034
+ generateSharedKey
1035
+ } from '@private.me/xbind';
1036
+
1037
+ // Create envelope
1038
+ const sharedKey = await generateSharedKey();
1039
+ const agent = await Agent.quickstart({ name: 'serialize-test' });
1040
+
1041
+ const envelope = await createEnvelope({
1042
+ senderDid: agent.did,
1043
+ recipientDid: 'did:key:z6MkRecipient...',
1044
+ scope: 'test',
1045
+ plaintext: new TextEncoder().encode('Test message'),
1046
+ privateKey: agent.identity.privateKey,
1047
+ sharedKey
1048
+ });
1049
+
1050
+ if (!envelope.ok) {
1051
+ throw new Error('Envelope creation failed');
1052
+ }
1053
+
1054
+ // Serialize to bytes
1055
+ const serialized = serializeEnvelope(envelope.value);
1056
+ console.log('Serialized length:', serialized.length, 'bytes');
1057
+
1058
+ // Deserialize back to envelope
1059
+ const deserialized = deserializeEnvelope(serialized);
1060
+
1061
+ if (deserialized.ok) {
1062
+ console.log('Deserialized version:', deserialized.value.v);
1063
+ console.log('Sender DID:', deserialized.value.sender.substring(0, 20) + '...');
1064
+ console.log('Round-trip successful');
1065
+ }
1066
+ ```
1067
+ <!-- /RUNNABLE-EXAMPLE -->
1068
+
1069
+ **Expected output:**
1070
+ ```
1071
+ Serialized length: 512 bytes
1072
+ Deserialized version: 1
1073
+ Sender DID: did:key:z6Mk...
1074
+ Round-trip successful
1075
+ ```
1076
+
1077
+ ### Example 13: Validate Envelope Structure
1078
+
1079
+ <!-- RUNNABLE-EXAMPLE -->
1080
+ ```typescript
1081
+ import { validateEnvelope } from '@private.me/xbind';
1082
+
1083
+ // Valid envelope structure
1084
+ const validEnvelope = {
1085
+ v: 1,
1086
+ alg: 'Ed25519',
1087
+ sender: 'did:key:z6MkSender...',
1088
+ recipient: 'did:key:z6MkRecipient...',
1089
+ timestamp: Date.now(),
1090
+ nonce: 'YmFzZTY0LW5vbmNl',
1091
+ scope: 'test',
1092
+ payload: 'ZW5jcnlwdGVkLXBheWxvYWQ=',
1093
+ signature: 'c2lnbmF0dXJlLWRhdGE='
1094
+ };
1095
+
1096
+ const validation = validateEnvelope(validEnvelope);
1097
+
1098
+ if (validation.ok) {
1099
+ console.log('Envelope valid');
1100
+ console.log('Version:', validation.value.v);
1101
+ console.log('Algorithm:', validation.value.alg);
1102
+ } else {
1103
+ console.error('Validation error:', validation.error);
1104
+ }
1105
+
1106
+ // Invalid envelope (missing required field)
1107
+ const invalidEnvelope = {
1108
+ v: 1,
1109
+ alg: 'Ed25519',
1110
+ sender: 'did:key:z6MkSender...'
1111
+ // Missing recipient, timestamp, nonce, etc.
1112
+ };
1113
+
1114
+ const invalidValidation = validateEnvelope(invalidEnvelope);
1115
+ console.log('Invalid envelope error:', invalidValidation.ok ? 'N/A' : invalidValidation.error);
1116
+ ```
1117
+ <!-- /RUNNABLE-EXAMPLE -->
1118
+
1119
+ **Expected output:**
1120
+ ```
1121
+ Envelope valid
1122
+ Version: 1
1123
+ Algorithm: Ed25519
1124
+ Invalid envelope error: INVALID_FIELDS
1125
+ ```
1126
+
1127
+
1128
+ ## Identity & CLI Operations
1129
+
1130
+ ### CLI Initialization
1131
+
1132
+ <!-- RUNNABLE-EXAMPLE -->
1133
+ ```typescript
1134
+ import { initCommand } from '@private.me/xbind';
1135
+
1136
+ // Initialize xBind project with invite code
1137
+ await initCommand({
1138
+ invite: 'https://xbind.to/invite/XBD-abc123',
1139
+ name: 'my-xbind-app',
1140
+ runtime: 'node-typescript',
1141
+ yes: true // Skip interactive prompts
1142
+ });
1143
+
1144
+ // Or use CLI directly:
1145
+ // npx xbind-init --invite XBD-abc123 --name my-app --runtime node-typescript --yes
1146
+ ```
1147
+ <!-- /RUNNABLE-EXAMPLE -->
1148
+
1149
+ ### Programmatic CLI Entry
1150
+
1151
+ <!-- RUNNABLE-EXAMPLE -->
1152
+ ```typescript
1153
+ import { cliMain } from '@private.me/xbind';
1154
+
1155
+ // Run xBind CLI programmatically (useful for testing or automation)
1156
+ const exitCode = await cliMain(['setup', '--email', 'agent@example.com', '--yes']);
1157
+
1158
+ if (exitCode === 0) {
1159
+ console.log('CLI setup completed successfully');
1160
+ } else {
1161
+ console.error(`CLI exited with code ${exitCode}`);
1162
+ }
1163
+
1164
+ // Can also be used to test CLI commands without spawning a child process
1165
+ ```
1166
+ <!-- /RUNNABLE-EXAMPLE -->
1167
+
1168
+ ### DID Conversions
1169
+
1170
+ <!-- RUNNABLE-EXAMPLE -->
1171
+ ```typescript
1172
+ import { generateIdentity, publicKeyToDid, didToPublicKeyBytes } from '@private.me/xbind';
1173
+
1174
+ // Generate identity and extract DID
1175
+ const result = await generateIdentity();
1176
+ if (!result.ok) throw new Error(result.error);
1177
+
1178
+ const identity = result.value;
1179
+ console.log('DID:', identity.did); // did:key:z6Mk...
1180
+
1181
+ // Convert public key to DID
1182
+ const did = publicKeyToDid(identity.rawPublicKey);
1183
+ console.log('Derived DID:', did);
1184
+
1185
+ // Convert DID back to public key bytes
1186
+ const keyResult = didToPublicKeyBytes(did);
1187
+ if (!keyResult.ok) throw new Error(keyResult.error);
1188
+
1189
+ console.log('Public key bytes:', keyResult.value); // Uint8Array(32)
1190
+ ```
1191
+ <!-- /RUNNABLE-EXAMPLE -->
1192
+
1193
+ ### PKCS8 Key Export
1194
+
1195
+ <!-- RUNNABLE-EXAMPLE -->
1196
+ ```typescript
1197
+ import { generateIdentity, exportPKCS8, exportX25519PKCS8 } from '@private.me/xbind';
1198
+
1199
+ const result = await generateIdentity();
1200
+ if (!result.ok) throw new Error(result.error);
1201
+
1202
+ const identity = result.value;
1203
+
1204
+ // Export Ed25519 private key as PKCS8 (for persistent storage)
1205
+ const ed25519Result = await exportPKCS8(identity.privateKey);
1206
+ if (!ed25519Result.ok) throw new Error(ed25519Result.error);
1207
+
1208
+ console.log('Ed25519 PKCS8:', ed25519Result.value); // Uint8Array(48)
1209
+
1210
+ // Export X25519 private key as PKCS8
1211
+ const x25519Result = await exportX25519PKCS8(identity.x25519PrivateKey);
1212
+ if (!x25519Result.ok) throw new Error(x25519Result.error);
1213
+
1214
+ console.log('X25519 PKCS8:', x25519Result.value); // Uint8Array(48)
1215
+ ```
1216
+ <!-- /RUNNABLE-EXAMPLE -->
1217
+
1218
+ ### PKCS8 Key Import
1219
+
1220
+ <!-- RUNNABLE-EXAMPLE -->
1221
+ ```typescript
1222
+ import { exportPKCS8, exportX25519PKCS8, importFromPKCS8, importIdentity } from '@private.me/xbind';
1223
+
1224
+ // Assume we have PKCS8 bytes from previous export
1225
+ const ed25519Pkcs8 = new Uint8Array(48); // From exportPKCS8()
1226
+ const x25519Pkcs8 = new Uint8Array(48); // From exportX25519PKCS8()
1227
+
1228
+ // Import Ed25519 identity (generates new X25519 keypair)
1229
+ const simpleResult = await importFromPKCS8(ed25519Pkcs8);
1230
+ if (!simpleResult.ok) throw new Error(simpleResult.error);
1231
+
1232
+ console.log('Restored DID:', simpleResult.value.did);
1233
+
1234
+ // Import full identity (preserves both Ed25519 + X25519 keys)
1235
+ const fullResult = await importIdentity(ed25519Pkcs8, x25519Pkcs8);
1236
+ if (!fullResult.ok) throw new Error(fullResult.error);
1237
+
1238
+ console.log('Full identity restored:', fullResult.value.did);
1239
+ console.log('Has X25519 keys:', !!fullResult.value.x25519PublicKey);
1240
+ ```
1241
+ <!-- /RUNNABLE-EXAMPLE -->
1242
+
1243
+ ### Deterministic Identity from Seed
1244
+
1245
+ <!-- RUNNABLE-EXAMPLE -->
1246
+ ```typescript
1247
+ import { identityFromSeed } from '@private.me/xbind';
1248
+
1249
+ // Generate 32-byte seed (high-entropy random bytes)
1250
+ const seed = crypto.getRandomValues(new Uint8Array(32));
1251
+
1252
+ // Derive deterministic identity (same seed = same DID)
1253
+ const result = await identityFromSeed(seed);
1254
+ if (!result.ok) throw new Error(result.error);
1255
+
1256
+ console.log('DID:', result.value.did);
1257
+ console.log('Has Ed25519 keys:', !!result.value.publicKey);
1258
+ console.log('Has X25519 keys:', !!result.value.x25519PublicKey);
1259
+ console.log('Has ML-KEM keys:', !!result.value.mlKemPublicKey);
1260
+
1261
+ // Same seed produces identical DID
1262
+ const result2 = await identityFromSeed(seed);
1263
+ if (!result2.ok) throw new Error(result2.error);
1264
+
1265
+ console.log('DIDs match:', result.value.did === result2.value.did); // true
1266
+ ```
1267
+ <!-- /RUNNABLE-EXAMPLE -->
1268
+
1269
+ ### Raw Key Extraction
1270
+
1271
+ <!-- RUNNABLE-EXAMPLE -->
1272
+ ```typescript
1273
+ import { exportPKCS8, exportX25519PKCS8, extractRawEd25519, extractRawX25519 } from '@private.me/xbind';
1274
+ import { generateIdentity } from '@private.me/xbind';
1275
+
1276
+ const identity = (await generateIdentity()).value!;
1277
+
1278
+ // Export PKCS8 format
1279
+ const ed25519Pkcs8 = (await exportPKCS8(identity.privateKey)).value!;
1280
+ const x25519Pkcs8 = (await exportX25519PKCS8(identity.x25519PrivateKey)).value!;
1281
+
1282
+ // Extract raw 32-byte private keys
1283
+ const ed25519Raw = extractRawEd25519(ed25519Pkcs8);
1284
+ if (!ed25519Raw.ok) throw new Error(ed25519Raw.error);
1285
+
1286
+ console.log('Ed25519 raw key:', ed25519Raw.value); // Uint8Array(32)
1287
+
1288
+ const x25519Raw = extractRawX25519(x25519Pkcs8);
1289
+ if (!x25519Raw.ok) throw new Error(x25519Raw.error);
1290
+
1291
+ console.log('X25519 raw key:', x25519Raw.value); // Uint8Array(32)
1292
+ ```
1293
+ <!-- /RUNNABLE-EXAMPLE -->
1294
+
1295
+ ### ML-KEM Key Export
1296
+
1297
+ <!-- RUNNABLE-EXAMPLE -->
1298
+ ```typescript
1299
+ import { generateIdentity, exportMlKemSecretKey, exportMlKemPublicKey } from '@private.me/xbind';
1300
+
1301
+ const result = await generateIdentity();
1302
+ if (!result.ok) throw new Error(result.error);
1303
+
1304
+ const identity = result.value;
1305
+
1306
+ // Export ML-KEM-768 secret key (2400 bytes)
1307
+ const secretKey = exportMlKemSecretKey(identity);
1308
+ if (secretKey) {
1309
+ console.log('ML-KEM secret key size:', secretKey.length); // 2400
1310
+ }
1311
+
1312
+ // Export ML-KEM-768 public key (1184 bytes)
1313
+ const publicKey = exportMlKemPublicKey(identity);
1314
+ if (publicKey) {
1315
+ console.log('ML-KEM public key size:', publicKey.length); // 1184
1316
+ }
1317
+ ```
1318
+ <!-- /RUNNABLE-EXAMPLE -->
1319
+
1320
+ ## Advanced Networking & Resilience
1321
+
1322
+ xBind provides production-grade retry strategies, replay prevention, and circuit breakers for fault-tolerant distributed systems.
1323
+
1324
+ ### Replay Prevention with MemoryNonceStore
1325
+
1326
+ <!-- RUNNABLE-EXAMPLE -->
1327
+ ```typescript
1328
+ import { MemoryNonceStore } from '@private.me/xbind';
1329
+
1330
+ // Create in-memory nonce store (10-minute TTL, 60-second cleanup)
1331
+ const nonceStore = new MemoryNonceStore({
1332
+ ttlMs: 10 * 60 * 1000,
1333
+ cleanupIntervalMs: 60 * 1000,
1334
+ });
1335
+
1336
+ // Check nonce freshness (returns true if new, false if duplicate)
1337
+ const nonce1 = 'unique-nonce-abc123';
1338
+ const senderDid = 'did:key:z6Mk...';
1339
+
1340
+ const isNewNonce = await nonceStore.check(nonce1, senderDid);
1341
+ console.log('Nonce accepted:', isNewNonce); // true (first use)
1342
+
1343
+ const isDuplicate = await nonceStore.check(nonce1, senderDid);
1344
+ console.log('Nonce rejected:', !isDuplicate); // false (replay attack)
1345
+
1346
+ // Clean up
1347
+ nonceStore.dispose();
1348
+ ```
1349
+ <!-- /RUNNABLE-EXAMPLE -->
1350
+
1351
+ ### Redis Nonce Store (Multi-Node)
1352
+
1353
+ <!-- RUNNABLE-EXAMPLE -->
1354
+ ```typescript
1355
+ import { RedisNonceStore } from '@private.me/xbind';
1356
+ import Redis from 'ioredis';
1357
+
1358
+ // Create Redis client
1359
+ const redis = new Redis({ host: 'localhost', port: 6379 });
1360
+
1361
+ // Create Redis nonce store (distributed across all nodes)
1362
+ const nonceStore = new RedisNonceStore({
1363
+ client: {
1364
+ setNX: async (key, value, ttl) => {
1365
+ const result = await redis.set(key, value, 'EX', ttl, 'NX');
1366
+ return result === 'OK' ? 'OK' : null;
1367
+ },
1368
+ del: (key) => redis.del(key),
1369
+ quit: () => redis.quit(),
1370
+ },
1371
+ ttlSeconds: 600, // 10 minutes
1372
+ keyPrefix: 'xbind:nonce:',
1373
+ });
1374
+
1375
+ // Use nonce store (same API as MemoryNonceStore)
1376
+ const isNewNonce = await nonceStore.check('nonce-xyz', 'did:key:z6Mk...');
1377
+ console.log('Distributed nonce check:', isNewNonce);
1378
+
1379
+ // Clean up
1380
+ await nonceStore.dispose();
1381
+ ```
1382
+ <!-- /RUNNABLE-EXAMPLE -->
1383
+
1384
+ ### Exponential Backoff Retry
1385
+
1386
+ <!-- RUNNABLE-EXAMPLE -->
1387
+ ```typescript
1388
+ import { ExponentialBackoffStrategy, executeWithRetry } from '@private.me/xbind';
1389
+ import { err, ok } from '@private.me/shared';
1390
+
1391
+ // Create exponential backoff strategy (3 attempts, 1s → 2s → 4s)
1392
+ const retryStrategy = new ExponentialBackoffStrategy({
1393
+ maxAttempts: 3,
1394
+ initialDelayMs: 1000,
1395
+ maxDelayMs: 30000,
1396
+ multiplier: 2,
1397
+ jitter: true,
1398
+ });
1399
+
1400
+ // Simulate flaky operation
1401
+ let attemptCount = 0;
1402
+ async function flakyOperation() {
1403
+ attemptCount++;
1404
+ console.log(`Attempt ${attemptCount}`);
1405
+
1406
+ if (attemptCount < 3) {
1407
+ return err('NETWORK_ERROR' as const);
1408
+ }
1409
+ return ok({ data: 'Success after retries' });
1410
+ }
1411
+
1412
+ // Execute with retry
1413
+ const result = await executeWithRetry(flakyOperation, retryStrategy);
1414
+
1415
+ if (result.ok) {
1416
+ console.log('Operation succeeded:', result.value.data);
1417
+ } else {
1418
+ console.error('Operation failed:', result.error);
1419
+ }
1420
+ ```
1421
+ <!-- /RUNNABLE-EXAMPLE -->
1422
+
1423
+ ### Linear Backoff Strategy
1424
+
1425
+ <!-- RUNNABLE-EXAMPLE -->
1426
+ ```typescript
1427
+ import { LinearBackoffStrategy, executeWithRetry } from '@private.me/xbind';
1428
+ import { err, ok } from '@private.me/shared';
1429
+
1430
+ // Create linear backoff strategy (delays: 1s, 2s, 3s, 4s)
1431
+ const retryStrategy = new LinearBackoffStrategy({
1432
+ maxAttempts: 4,
1433
+ initialDelayMs: 1000,
1434
+ delayIncrementMs: 1000,
1435
+ maxDelayMs: 10000,
1436
+ jitter: true,
1437
+ });
1438
+
1439
+ // Simulate operation
1440
+ async function operation() {
1441
+ return ok({ message: 'Linear backoff demo' });
1442
+ }
1443
+
1444
+ const result = await executeWithRetry(operation, retryStrategy);
1445
+ console.log('Result:', result.ok ? result.value.message : result.error);
1446
+ ```
1447
+ <!-- /RUNNABLE-EXAMPLE -->
1448
+
1449
+ ### Fixed Delay Strategy
1450
+
1451
+ <!-- RUNNABLE-EXAMPLE -->
1452
+ ```typescript
1453
+ import { FixedDelayStrategy, executeWithRetry } from '@private.me/xbind';
1454
+ import { err, ok } from '@private.me/shared';
1455
+
1456
+ // Create fixed delay strategy (constant 2s delay between retries)
1457
+ const retryStrategy = new FixedDelayStrategy({
1458
+ maxAttempts: 3,
1459
+ delayMs: 2000,
1460
+ jitter: false,
1461
+ });
1462
+
1463
+ // Simulate operation
1464
+ async function operation() {
1465
+ return ok({ message: 'Fixed delay demo' });
1466
+ }
1467
+
1468
+ const result = await executeWithRetry(operation, retryStrategy);
1469
+ console.log('Result:', result.ok ? result.value.message : result.error);
1470
+ ```
1471
+ <!-- /RUNNABLE-EXAMPLE -->
1472
+
1473
+ ### No Retry Strategy
1474
+
1475
+ <!-- RUNNABLE-EXAMPLE -->
1476
+ ```typescript
1477
+ import { NoRetryStrategy, executeWithRetry } from '@private.me/xbind';
1478
+ import { err } from '@private.me/shared';
1479
+
1480
+ // Create no-retry strategy (fail immediately)
1481
+ const retryStrategy = new NoRetryStrategy();
1482
+
1483
+ // Simulate failing operation
1484
+ async function operation() {
1485
+ return err('NETWORK_ERROR' as const);
1486
+ }
1487
+
1488
+ const result = await executeWithRetry(operation, retryStrategy);
1489
+ console.log('Failed immediately:', !result.ok);
1490
+ console.log('Error:', result.ok ? null : result.error);
1491
+ ```
1492
+ <!-- /RUNNABLE-EXAMPLE -->
1493
+
1494
+ ### Circuit Breaker Pattern
1495
+
1496
+ <!-- RUNNABLE-EXAMPLE -->
1497
+ ```typescript
1498
+ import { CircuitBreaker } from '@private.me/xbind';
1499
+
1500
+ // Create circuit breaker (5 failures → open, 60s reset, 2 successes → close)
1501
+ const breaker = new CircuitBreaker({
1502
+ failureThreshold: 5,
1503
+ resetTimeoutMs: 60000,
1504
+ successThreshold: 2,
1505
+ windowMs: 60000,
1506
+ });
1507
+
1508
+ // Simulate failures to trip circuit
1509
+ for (let i = 0; i < 5; i++) {
1510
+ breaker.recordFailure();
1511
+ }
1512
+
1513
+ console.log('Circuit state after 5 failures:', breaker.getStats().state); // OPEN
1514
+
1515
+ // Attempt request while circuit is open
1516
+ const canProceed = breaker.allowRequest();
1517
+ console.log('Request allowed:', canProceed); // false
1518
+
1519
+ // Get circuit statistics
1520
+ const stats = breaker.getStats();
1521
+ console.log('Stats:', {
1522
+ state: stats.state,
1523
+ totalFailures: stats.totalFailures,
1524
+ consecutiveFailures: stats.consecutiveFailures,
1525
+ });
1526
+ ```
1527
+ <!-- /RUNNABLE-EXAMPLE -->
1528
+
1529
+ ### Retry with Circuit Breaker
1530
+
1531
+ <!-- RUNNABLE-EXAMPLE -->
1532
+ ```typescript
1533
+ import {
1534
+ ExponentialBackoffStrategy,
1535
+ CircuitBreaker,
1536
+ executeWithRetry,
1537
+ } from '@private.me/xbind';
1538
+ import { err, ok } from '@private.me/shared';
1539
+
1540
+ // Create retry strategy and circuit breaker
1541
+ const retryStrategy = new ExponentialBackoffStrategy({
1542
+ maxAttempts: 3,
1543
+ initialDelayMs: 1000,
1544
+ });
1545
+
1546
+ const circuitBreaker = new CircuitBreaker({
1547
+ failureThreshold: 2,
1548
+ resetTimeoutMs: 5000,
1549
+ });
1550
+
1551
+ // Simulate operation that succeeds after circuit recovery
1552
+ let callCount = 0;
1553
+ async function operation() {
1554
+ callCount++;
1555
+ if (callCount === 1) {
1556
+ return err('NETWORK_ERROR' as const);
1557
+ }
1558
+ return ok({ data: `Success on attempt ${callCount}` });
1559
+ }
1560
+
1561
+ // Execute with retry + circuit breaker
1562
+ const result = await executeWithRetry(operation, retryStrategy, circuitBreaker);
1563
+
1564
+ console.log('Operation result:', result.ok ? result.value.data : result.error);
1565
+ console.log('Circuit state:', circuitBreaker.getStats().state);
1566
+ ```
1567
+ <!-- /RUNNABLE-EXAMPLE -->
1568
+
1569
+ ### RetryTransportAdapter (Automatic Retry)
1570
+
1571
+ <!-- RUNNABLE-EXAMPLE -->
1572
+ ```typescript
1573
+ import { RetryTransportAdapter, HttpsTransportAdapter, Agent } from '@private.me/xbind';
1574
+
1575
+ // Create base transport
1576
+ const baseTransport = new HttpsTransportAdapter({
1577
+ baseUrl: 'https://gateway.private.me',
1578
+ });
1579
+
1580
+ // Wrap with retry decorator (exponential backoff, 3 attempts)
1581
+ const retryTransport = new RetryTransportAdapter(baseTransport, {
1582
+ maxAttempts: 3,
1583
+ initialDelayMs: 1000,
1584
+ maxDelayMs: 10000,
1585
+ strategy: 'exponential',
1586
+ });
1587
+
1588
+ // Create agent with retry transport
1589
+ const agent = await Agent.quickstart({
1590
+ name: 'retry-demo',
1591
+ transports: [retryTransport],
1592
+ });
1593
+
1594
+ console.log('Agent created with retry transport');
1595
+ console.log('Transport type:', agent.transports[0].constructor.name);
1596
+ ```
1597
+ <!-- /RUNNABLE-EXAMPLE -->
1598
+
1599
+ ### Shared Key Generation
1600
+
1601
+ <!-- RUNNABLE-EXAMPLE -->
1602
+ ```typescript
1603
+ import { generateSharedKey } from '@private.me/xbind';
1604
+
1605
+ // Generate random AES-256-GCM shared key
1606
+ const sharedKeyResult = await generateSharedKey();
1607
+
1608
+ if (!sharedKeyResult.ok) {
1609
+ throw new Error(`Failed to generate key: ${sharedKeyResult.error}`);
1610
+ }
1611
+
1612
+ const sharedKey = sharedKeyResult.value;
1613
+
1614
+ // Export key material for inspection
1615
+ const keyMaterial = await crypto.subtle.exportKey('raw', sharedKey);
1616
+ console.log('Shared key generated (256 bits):', keyMaterial.byteLength * 8);
1617
+ console.log('Key algorithm:', sharedKey.algorithm.name);
1618
+ console.log('Key usages:', sharedKey.usages);
1619
+ ```
1620
+ <!-- /RUNNABLE-EXAMPLE -->
1621
+
1622
+ ### Signed Envelopes
1623
+
1624
+ <!-- RUNNABLE-EXAMPLE -->
1625
+ ```typescript
1626
+ import { createSignedEnvelope, openSignedEnvelope, Agent } from '@private.me/xbind';
1627
+
1628
+ // Create agents
1629
+ const sender = await Agent.quickstart({ name: 'sender' });
1630
+ const recipient = await Agent.quickstart({ name: 'recipient' });
1631
+
1632
+ // Create signed envelope
1633
+ const payload = { action: 'transfer', amount: 100 };
1634
+ const envelopeResult = await createSignedEnvelope(
1635
+ sender.identity,
1636
+ recipient.did,
1637
+ payload,
1638
+ 'billing'
1639
+ );
1640
+
1641
+ if (!envelopeResult.ok) {
1642
+ throw new Error(`Failed to create envelope: ${envelopeResult.error}`);
1643
+ }
1644
+
1645
+ const envelope = envelopeResult.value;
1646
+ console.log('Envelope created with signature');
1647
+ console.log('Sender DID:', envelope.sender);
1648
+ console.log('Recipient DID:', envelope.recipient);
1649
+ console.log('Signature length:', envelope.signature.length);
1650
+
1651
+ // Verify and open envelope
1652
+ const openResult = await openSignedEnvelope(envelope, sender.identity.publicKey);
1653
+
1654
+ if (!openResult.ok) {
1655
+ throw new Error(`Failed to open envelope: ${openResult.error}`);
1656
+ }
1657
+
1658
+ console.log('Envelope verified and opened');
1659
+ console.log('Payload:', openResult.value);
1660
+ ```
1661
+ <!-- /RUNNABLE-EXAMPLE -->
1662
+
1663
+ ## Python SDK
1664
+
1665
+ Complete Python bindings for agent identity and messaging:
1666
+
1667
+ ```python
1668
+ from private_me.xbind import Agent
1669
+
1670
+ # Create agent from private key
1671
+ agent = Agent.from_private_key(private_key_bytes)
1672
+
1673
+ # Make authenticated call
1674
+ result = agent.call('stripe:createCharge', {
1675
+ 'amount': 100,
1676
+ 'currency': 'usd',
1677
+ 'description': 'AI agent purchase'
1678
+ })
1679
+
1680
+ if result['ok']:
1681
+ print(f"Charge ID: {result['data']['id']}")
1682
+ print(f"Agent DID: {result['audit']['agent']}")
1683
+ else:
1684
+ print(f"Error: {result['error']['message']}")
1685
+ ```
1686
+
1687
+ See [Python SDK documentation](./python/README.md) for complete API reference and examples.
1688
+
1689
+ ## Why xBind?
1690
+
1691
+ 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.
1692
+
1693
+ ## Getting Started
1694
+
1695
+ **[Guide](../../docs/xbind-integrations/getting-started/index.md)** — Concepts, migration
1696
+ **[Quickstart](../../docs/xbind-integrations/getting-started/quickstart.md)** — 15-second setup
1697
+
1698
+ ## Features
1699
+
1700
+ **Zero-config JITR:** Just-in-Time Registration auto-registers agents with trust registry on first use (AWS IoT JITR, OAuth DCR, MCP 2025 standards).
1701
+
1702
+ ### Core Security
1703
+ - **Post-quantum cryptography:** ML-KEM-768 key encapsulation, ML-DSA-65 digital signatures (FIPS 203/204)
1704
+ - **Hybrid key agreement:** X-Wing combiner (IETF draft-10) with 6-parameter domain separation
1705
+ - **XorIDA split-channel delivery:** Information-theoretic threshold sharing (2-of-2, 2-of-3, 3-of-5)
1706
+ - **Cryptographic request signing:** Ed25519 signatures prevent DID header forgery
1707
+ - **Key rotation:** ML-KEM + X25519 rotation with fallback decryption (10 rotation history)
1708
+ - **Proof-of-Possession:** Ed25519 signature verification prevents DID spoofing
1709
+ - **Share-aware nonce deduplication:** Prevents replay attacks with composite keys
1710
+
1711
+ ### Runtime Compatibility (4 Platforms)
1712
+ - **Browser:** WebCrypto API, IndexedDB/localStorage adapters, WASM support, service workers
1713
+ - **React Native:** AsyncStorage, Buffer polyfills, crypto detection, iOS/Android platform support
1714
+ - **Edge Runtime:** Cloudflare Workers, Vercel Edge, Deno Deploy, KV storage, <1MB optimization
1715
+ - **Node.js:** Native crypto module, filesystem storage, full feature set
1716
+
1717
+ ### Operations Patterns
1718
+ - **Health checks:** Startup/liveness/readiness probes, Kubernetes-compatible, Express/Fastify middleware
1719
+ - **Circuit breakers:** 3-state machine (closed/open/half-open), registry/gateway/S3 presets, automatic recovery
1720
+ - **Graceful degradation:** QoS tiers, intelligent caching, service health tracking, fallback strategies
1721
+ - **Performance benchmarks:** Latency histograms with baselines for key ops (ML-KEM, ML-DSA, encryption)
1722
+ - **Structured logging:** 4 levels (DEBUG/INFO/WARN/ERROR), automatic sensitive data redaction, correlation IDs
1723
+ - **Telemetry:** Prometheus-compatible metrics (counters, histograms, gauges), operation latency tracking
1724
+
1725
+ ### Security Audit Preparation
1726
+ - **STRIDE threat modeling:** 66 threats analyzed across 6 categories
1727
+ - **Crypto claims documentation:** 41 cryptographic claims documented with evidence
1728
+ - **Known limitations disclosure:** 24 limitations disclosed for auditor transparency
1729
+ - **Audit-ready:** NCC Group / Trail of Bits preparation ($100K-$150K, 12-week timeline)
1730
+
1731
+ ### API Enhancements
1732
+ - **Batch operations:** 6-8x speedup for parallel operations with single network round-trip
1733
+ - **Async iterators:** `for await...of` syntax support for streaming message processing
1734
+ - **Plugin/middleware system:** 6-phase lifecycle hooks with 3 built-in plugins
1735
+ - **Event emitters:** Type-safe events with 5 event types, priority execution, bubbling
1736
+ - **Cancellation tokens:** AbortController integration with timeout support
1737
+ - **Progress callbacks:** 4 specialized trackers (operation, transfer, share, encryption)
1738
+ - **Retry strategies:** 4 strategies (exponential, linear, immediate, jittered) + circuit breaker integration
1739
+ - **Request timeouts:** Per-operation config with inheritance and cancellation
1740
+ - **Connection pooling:** 60-70% latency reduction with keep-alive and metrics
1741
+ - **Serialization formats:** JSON/MessagePack/CBOR support with auto-detection and negotiation
1742
+ - **Configuration validation:** Comprehensive validation with clear error messages
1743
+ - **Debug mode:** Performance profiling, network/crypto tracing, state inspection
1744
+ - **SDK version info:** Capability detection, deprecation warnings, compatibility checking
1745
+
1746
+ ### Developer Experience
1747
+ - **Type safety:** `Result<T, E>` error handling with 96+ error codes
1748
+ - **TypeScript strict mode:** Zero type errors, complete type coverage
1749
+ - **Python SDK:** Complete bindings for identity, messaging, and encryption
1750
+ - **User-friendly errors:** 75+ errors with actionable recovery hints
1751
+ - **Complete API docs:** 2,587 lines with 50+ usage examples
1752
+ - **CHANGELOG generation:** Automated Keep a Changelog format with semver discipline
1753
+ - **Dependency audit:** Weekly Dependabot scans, 5-layer vulnerability scanning
1754
+ - **Crypto license compliance:** Automated MIT/MIT-0 validation with GPL/AGPL detection
1755
+
1756
+ ### Enterprise Features
1757
+ - **Version negotiation:** Explicit SDK version fields prevent "404 Route not found" in mixed fleets
1758
+ - **Multi-device session resume:** AES-256-GCM encrypted session state sync with PBKDF2 (100k iterations)
1759
+ - **Encrypted backup/restore:** Password-protected identity export with PBKDF2-SHA256 (310k iterations)
1760
+ - **Offline sync:** Message queueing for offline devices (max 1000 messages, 24-hour TTL)
1761
+ - **Registry expiration:** TTL support with cleanup (default 7 days)
1762
+ - **Server-side spending limits:** Redis-backed enforcement with deployment-level aggregation
1763
+ - **Rate limiting:** Three-tier protection (per-DID, per-IP, global)
1764
+ - **Full Control IP protection:** Store Front (npm) + Vault Store (EC2) with payment verification
1765
+
1766
+ ### Testing & Quality
1767
+ - **2,951 tests:** Comprehensive coverage (100% passing)
1768
+ - **End-to-end integration:** Full message flow tests (Agent A → Gateway → Agent B)
1769
+ - **Gateway concurrency:** 100 concurrent sends, race condition detection
1770
+ - **Network partition recovery:** Disconnect/reconnect cycles with retry logic
1771
+ - **PLAN-3 hybrid signatures:** Bilateral authorization with composite verification
1772
+
1773
+ ## Bundle Size Optimization (Tree-Shaking)
1774
+
1775
+ **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.
1776
+
1777
+ ### Full Import (Convenience)
1778
+
1779
+ ```typescript
1780
+ import { Agent, generateIdentity } from '@private.me/xbind';
1781
+
1782
+ // Bundle size: ~450 KB
1783
+ ```
1784
+
1785
+ ### Granular Import (Optimized)
1786
+
1787
+ ```typescript
1788
+ import { Agent } from '@private.me/xbind/agent';
1789
+ import { generateIdentity } from '@private.me/xbind/identity';
1790
+
1791
+ // Bundle size: ~180 KB (60% reduction)
1792
+ ```
1793
+
1794
+ ### Available Entry Points
1795
+
1796
+ | Entry Point | Exports | Bundle Impact |
1797
+ |-------------|---------|---------------|
1798
+ | `@private.me/xbind` | All exports | Full package (~450 KB) |
1799
+ | `@private.me/xbind/agent` | `Agent`, `AgentOptions` | ~180 KB |
1800
+ | `@private.me/xbind/identity` | `generateIdentity`, `Identity` | ~120 KB |
1801
+ | `@private.me/xbind/trust-registry` | Registry classes | ~200 KB |
1802
+ | `@private.me/xbind/key-agreement` | Key exchange functions | ~90 KB |
1803
+ | `@private.me/xbind/errors` | Error types | 0 KB (types only) |
1804
+
1805
+ **Bundler Support:** Works with webpack 5+, Rollup, esbuild, and Vite. Tree-shaking is automatic in production mode.
1806
+
1807
+ **See:** [Tree-Shaking Guide](./docs/packaging/tree-shaking.md) for detailed usage and configuration.
1808
+
1809
+ ## Automatic XorIDA Split-Channel Protection
1810
+
1811
+ xBind automatically activates information-theoretic XorIDA threshold sharing for high-risk operations. No code changes required—security is transparent.
1812
+
1813
+ ### Risk Tags (Recommended for Crypto)
1814
+
1815
+ For cryptocurrency transactions (BTC, ETH, etc.), use explicit risk tags in your payload:
1816
+
1817
+ ```typescript
1818
+ // Low risk: 2-of-2 threshold
1819
+ await agent.send({
1820
+ to: recipientDid,
1821
+ payload: { amount: 0.5, currency: 'BTC', risk: 'low' }
1822
+ });
1823
+
1824
+ // Medium risk: 2-of-3 threshold
1825
+ await agent.send({
1826
+ to: recipientDid,
1827
+ payload: { amount: 5.0, currency: 'ETH', risk: 'medium' }
1828
+ });
1829
+
1830
+ // High risk: 3-of-5 threshold
1831
+ await agent.send({
1832
+ to: recipientDid,
1833
+ payload: { amount: 50, currency: 'BTC', risk: 'high' }
1834
+ });
1835
+
1836
+ // Critical risk: 3-of-5 threshold
1837
+ await agent.send({
1838
+ to: recipientDid,
1839
+ payload: { amount: 100, currency: 'BTC', risk: 'critical' }
1840
+ });
1841
+ ```
1842
+
1843
+ ### Fiat Currency Auto-Detection
1844
+
1845
+ For fiat currencies (USD, EUR, GBP), xBind uses numeric thresholds:
1846
+
1847
+ ```typescript
1848
+ // Automatically triggers 2-of-3 (amount >= $100,000)
1849
+ await agent.send({
1850
+ to: recipientDid,
1851
+ payload: { amount: 500000, currency: 'USD', action: 'transfer' }
1852
+ });
1853
+
1854
+ // Automatically triggers 3-of-5 (amount >= $1,000,000)
1855
+ await agent.send({
1856
+ to: recipientDid,
1857
+ payload: { amount: 2500000, currency: 'USD', action: 'transfer' }
1858
+ });
1859
+ ```
1860
+
1861
+ ### Manual Security Override
1862
+
1863
+ Override automatic detection with explicit security levels:
1864
+
1865
+ ```typescript
1866
+ // Force 2-of-3 regardless of amount/risk
1867
+ await agent.send({
1868
+ to: recipientDid,
1869
+ payload: data,
1870
+ security: 'high'
1871
+ });
1872
+
1873
+ // Force 3-of-5 for maximum security
1874
+ await agent.send({
1875
+ to: recipientDid,
1876
+ payload: data,
1877
+ security: 'critical'
676
1878
  });
677
1879
 
678
1880
  // Disable XorIDA (standard encrypted transport)
679
1881
  await agent.send({
680
1882
  to: recipientDid,
681
- payload: data,
682
- security: 'standard'
1883
+ payload: data,
1884
+ security: 'standard'
1885
+ });
1886
+ ```
1887
+
1888
+ ### Threshold Schemes
1889
+
1890
+ | Risk Tag / Threshold | Shares | Required | Security Level |
1891
+ |---------------------|--------|----------|----------------|
1892
+ | `low` | 2 | 2 | 2-of-2 threshold |
1893
+ | `medium` / $100k-$1M | 3 | 2 | 2-of-3 threshold |
1894
+ | `high` / `critical` / >$1M | 5 | 3 | 3-of-5 threshold |
1895
+ | No tag / <$100k | — | — | Standard encrypted transport |
1896
+
1897
+ **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.
1898
+
1899
+ ### Security Mode Description (Structured)
1900
+
1901
+ Get human-readable descriptions of security modes in multiple formats:
1902
+
1903
+ ```typescript
1904
+ import { describeSecurityModeStructured } from '@private.me/xbind';
1905
+
1906
+ // Describe a split-channel security mode
1907
+ const mode = { type: 'split', shares: 3, threshold: 2 };
1908
+ const description = describeSecurityModeStructured(mode);
1909
+
1910
+ // Single-line format (for UI labels)
1911
+ console.log(description.formats.singleline); // "2-of-3 XorIDA"
1912
+
1913
+ // Multi-line format (for detailed explanations)
1914
+ console.log(description.formats.multiline);
1915
+ // Output:
1916
+ // Security Mode: 2-of-3 XorIDA Split-Channel
1917
+ // Shares: 3 total, 2 required to reconstruct
1918
+ // Information-theoretic security (quantum-resistant)
1919
+
1920
+ // Markdown format (for documentation)
1921
+ console.log(description.formats.markdown);
1922
+ // Output:
1923
+ // **Security Mode:** 2-of-3 XorIDA Split-Channel
1924
+ // - **Shares:** 3 total, 2 required to reconstruct
1925
+ // - **Security:** Information-theoretic (quantum-resistant)
1926
+ ```
1927
+
1928
+ ## Billing & Metering
1929
+
1930
+ xBind includes usage-based billing with automated milestone notifications:
1931
+
1932
+ - **Free Tier:** Generous monthly limits (no email verification required upfront)
1933
+ - **Grace Buffer:** Additional operations available after email verification
1934
+ - **Pro Tier:** Usage-based billing with unlimited operations
1935
+ - **Monthly Reset:** 1st of each month at 00:00 UTC
1936
+
1937
+ See [pricing](../../docs/pricing-reference.md) for current rates and tier details.
1938
+
1939
+ ### Milestone Notifications
1940
+
1941
+ Automated email notifications at usage thresholds with progress bars and CTAs for upgrades.
1942
+
1943
+ **Email verification:** Required at free tier limit to access grace buffer.
1944
+
1945
+ **Implementation:**
1946
+ - Metering logic: `apps/server/src/customer-metering.ts`
1947
+ - Milestone system: `apps/server/src/usage-milestone-notifications.ts`
1948
+ - Tier pattern: See `docs/gold-package.md` section 7.6.5
1949
+
1950
+ ## Gateway
1951
+
1952
+ Non-authoritative coordination for discovery, relay, push notifications, and state checkpoints. Cannot forge identity or decide trust. See [Gateway Architecture](./docs/gateway-architecture.md).
1953
+
1954
+ ## Connection Models
1955
+
1956
+ 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.
1957
+
1958
+ | Model | Security | UX | Best For |
1959
+ |-------|----------|-----|----------|
1960
+ | Invite Code | Single-use, 24h TTL | 6-char code | Customer onboarding |
1961
+ | QR Code | Physical proximity, 60s TTL | Scan & tap | Mobile/desktop pairing |
1962
+ | Trust Registry | Admin pre-auth, scoped | Zero (automated) | Enterprise/CI/CD |
1963
+ | Peer Discovery | LAN proximity, user confirm | Scan & confirm | IoT devices, offline |
1964
+
1965
+ See [Entity-to-Entity Connection UX Guide](../../docs/ENTITY-TO-ENTITY-CONNECTION-UX.md) for implementation patterns and code examples.
1966
+
1967
+ ## Configuration
1968
+
1969
+ ### Basic Setup
1970
+
1971
+ ```typescript
1972
+ import { HttpTrustRegistry } from '@private.me/xbind';
1973
+
1974
+ // Documentation example - use your actual gateway URL
1975
+ const registry = new HttpTrustRegistry({
1976
+ baseUrl: 'https://gateway.private.me'
1977
+ });
1978
+ ```
1979
+
1980
+ ### Operational Excellence (Timeouts & Degradation)
1981
+
1982
+ **Timeouts with configurable per-operation controls:**
1983
+
1984
+ <!-- RUNNABLE-EXAMPLE -->
1985
+ ```typescript
1986
+ import { TimeoutConfig, withTimeout, createTimeoutController, isTimeoutError } from '@private.me/xbind';
1987
+
1988
+ // Create timeout configuration
1989
+ const config = new TimeoutConfig({
1990
+ registry: 10000, // 10 seconds for registry lookups
1991
+ gateway: 15000, // 15 seconds for gateway operations
1992
+ transport: 30000, // 30 seconds for transport/HTTP
1993
+ default: 30000 // 30 seconds fallback
1994
+ });
1995
+
1996
+ // Wrap async operation with timeout (using mock operation that completes quickly)
1997
+ const result = await withTimeout(
1998
+ async () => new Promise(resolve => setTimeout(() => resolve('Done'), 100)),
1999
+ 5000,
2000
+ 'API request'
2001
+ );
2002
+
2003
+ console.log('Request completed within timeout:', result);
2004
+ ```
2005
+ <!-- /RUNNABLE-EXAMPLE -->
2006
+
2007
+ **Timeout controller with AbortSignal:**
2008
+
2009
+ <!-- RUNNABLE-EXAMPLE -->
2010
+ ```typescript
2011
+ import { createTimeoutController, TimeoutError } from '@private.me/xbind';
2012
+
2013
+ const controller = createTimeoutController(5000, 'registry lookup');
2014
+
2015
+ try {
2016
+ const response = await fetch(url, { signal: controller.signal });
2017
+ controller.clear(); // Clear timeout on success
2018
+ console.log('Fetch succeeded');
2019
+ } catch (error) {
2020
+ if (controller.didTimeout()) {
2021
+ console.error('Operation timed out after 5000ms');
2022
+ }
2023
+ }
2024
+ ```
2025
+ <!-- /RUNNABLE-EXAMPLE -->
2026
+
2027
+ **Result-based timeout handling (no exceptions):**
2028
+
2029
+ <!-- RUNNABLE-EXAMPLE -->
2030
+ ```typescript
2031
+ import { withTimeoutResult, isTimeoutError } from '@private.me/xbind';
2032
+
2033
+ const result = await withTimeoutResult(
2034
+ async () => performOperation(),
2035
+ 5000,
2036
+ 'database query'
2037
+ );
2038
+
2039
+ if (result.ok) {
2040
+ console.log('Success:', result.value);
2041
+ } else {
2042
+ console.error('Timeout error:', result.error);
2043
+ }
2044
+ ```
2045
+ <!-- /RUNNABLE-EXAMPLE -->
2046
+
2047
+ **Operation timeout with category-based config:**
2048
+
2049
+ <!-- RUNNABLE-EXAMPLE -->
2050
+ ```typescript
2051
+ import { TimeoutConfig, createOperationTimeout } from '@private.me/xbind';
2052
+
2053
+ const config = new TimeoutConfig({ registry: 10000 });
2054
+ const controller = createOperationTimeout(config, 'registry', 'lookup DID');
2055
+
2056
+ const response = await fetch(url, { signal: controller.signal });
2057
+ controller.clear();
2058
+ ```
2059
+ <!-- /RUNNABLE-EXAMPLE -->
2060
+
2061
+ **Environment-based timeout configuration:**
2062
+
2063
+ <!-- RUNNABLE-EXAMPLE -->
2064
+ ```typescript
2065
+ import { createTimeoutConfigFromEnv, globalTimeoutConfig } from '@private.me/xbind';
2066
+
2067
+ // Reads from environment variables:
2068
+ // - XBIND_TIMEOUT_REGISTRY
2069
+ // - XBIND_TIMEOUT_GATEWAY
2070
+ // - XBIND_TIMEOUT_TRANSPORT
2071
+ // - XBIND_TIMEOUT_DEFAULT
2072
+
2073
+ const config = createTimeoutConfigFromEnv();
2074
+ console.log('Registry timeout:', config.getRegistry());
2075
+ console.log('Gateway timeout:', config.getGateway());
2076
+
2077
+ // Use global default config
2078
+ const defaultTimeout = globalTimeoutConfig.getDefault();
2079
+ ```
2080
+ <!-- /RUNNABLE-EXAMPLE -->
2081
+
2082
+ **Graceful degradation with cache fallback:**
2083
+
2084
+ <!-- RUNNABLE-EXAMPLE -->
2085
+ ```typescript
2086
+ import { GracefulDegradationManager, registryLookupWithFallback } from '@private.me/xbind';
2087
+
2088
+ const manager = new GracefulDegradationManager({
2089
+ defaultTTL: 300000, // 5 minutes cache TTL
2090
+ maxSize: 1000, // Max 1000 cached entries
2091
+ allowStale: true, // Use stale cache on failures
2092
+ maxStaleMs: 3600000 // 1 hour max staleness
2093
+ });
2094
+
2095
+ // Lookup with cache fallback
2096
+ const result = await registryLookupWithFallback(
2097
+ registry,
2098
+ 'did:key:z6Mk...',
2099
+ { operationId: '123', qos: 'HIGH', type: 'registry:lookup' },
2100
+ manager
2101
+ );
2102
+
2103
+ if (result.ok) {
2104
+ console.log('Public key:', result.value.publicKey);
2105
+ }
2106
+ ```
2107
+ <!-- /RUNNABLE-EXAMPLE -->
2108
+
2109
+ **Service health tracking:**
2110
+
2111
+ <!-- RUNNABLE-EXAMPLE -->
2112
+ ```typescript
2113
+ import { GracefulDegradationManager } from '@private.me/xbind';
2114
+
2115
+ const manager = new GracefulDegradationManager();
2116
+
2117
+ // Record success
2118
+ manager.recordSuccess('registry');
2119
+
2120
+ // Record failure
2121
+ manager.recordFailure('registry', 'NETWORK_ERROR');
2122
+
2123
+ // Check health
2124
+ const health = manager.getServiceHealth('registry');
2125
+ console.log('Registry health:', health); // 'HEALTHY' | 'DEGRADED' | 'UNAVAILABLE'
2126
+
2127
+ // Get detailed status
2128
+ const status = manager.getServiceStatus('registry');
2129
+ console.log('Failure count:', status?.failureCount);
2130
+ console.log('Last error:', status?.lastError);
2131
+ ```
2132
+ <!-- /RUNNABLE-EXAMPLE -->
2133
+
2134
+ **Cache management:**
2135
+
2136
+ <!-- RUNNABLE-EXAMPLE -->
2137
+ ```typescript
2138
+ import { GracefulDegradationManager } from '@private.me/xbind';
2139
+
2140
+ const manager = new GracefulDegradationManager();
2141
+
2142
+ // Store in cache
2143
+ manager.setCached('registry:did:key:z6Mk...', { publicKey: '...' }, 300000);
2144
+
2145
+ // Get from cache (QoS-aware)
2146
+ const cached = manager.getCached('registry:did:key:z6Mk...', 'HIGH');
2147
+
2148
+ // Invalidate cache
2149
+ manager.invalidate('registry:did:key:z6Mk...');
2150
+
2151
+ // Get cache statistics
2152
+ const stats = manager.getCacheStats();
2153
+ console.log('Cache size:', stats.size);
2154
+ console.log('Max size:', stats.maxSize);
2155
+ ```
2156
+ <!-- /RUNNABLE-EXAMPLE -->
2157
+
2158
+ **Transport fallback with retry:**
2159
+
2160
+ <!-- RUNNABLE-EXAMPLE -->
2161
+ ```typescript
2162
+ import { sendWithTransportFallback, GracefulDegradationManager } from '@private.me/xbind';
2163
+
2164
+ const manager = new GracefulDegradationManager();
2165
+
2166
+ const result = await sendWithTransportFallback(
2167
+ [primaryTransport, fallbackTransport],
2168
+ envelope,
2169
+ 'did:key:recipient',
2170
+ { operationId: '456', qos: 'NORMAL', type: 'transport:send' },
2171
+ manager
2172
+ );
2173
+
2174
+ if (!result.ok) {
2175
+ console.error('All transports failed:', result.error);
2176
+ }
2177
+ ```
2178
+ <!-- /RUNNABLE-EXAMPLE -->
2179
+
2180
+ ### Advanced Configuration Options
2181
+
2182
+ #### Identity Management
2183
+
2184
+ **`identity` - Pre-existing Identity (Persistent Agents)**
2185
+
2186
+ Provide an existing AgentIdentity for persistent agents that survive restarts.
2187
+
2188
+ ```typescript
2189
+ import { Agent, identityFromSeed } from '@private.me/xbind';
2190
+
2191
+ // Generate identity once, save seed
2192
+ const identityResult = await generateIdentity();
2193
+ if (!identityResult.ok) throw new Error(identityResult.error.message);
2194
+
2195
+ const seed = identityResult.value.seed;
2196
+ // Store seed securely (keychain, HSM, etc.)
2197
+
2198
+ // Later: Restore agent from seed
2199
+ const identityRestoreResult = await identityFromSeed(Buffer.from(seed, 'hex'));
2200
+ if (!identityRestoreResult.ok) throw new Error(identityRestoreResult.error.message);
2201
+
2202
+ const agent = await Agent.create({
2203
+ name: 'persistent-agent',
2204
+ identity: identityRestoreResult.value // Reuse same DID across restarts
2205
+ });
2206
+ ```
2207
+
2208
+ **`identityTTL` - Auto-Cleanup for Ephemeral Agents**
2209
+
2210
+ Set automatic cleanup time for short-lived agents (milliseconds).
2211
+
2212
+ ```typescript
2213
+ const agent = await Agent.create({
2214
+ name: 'temp-agent',
2215
+ identityTTL: 3600000 // Auto-cleanup after 1 hour
2216
+ });
2217
+ ```
2218
+
2219
+ #### Security Options
2220
+
2221
+ **`nonceStore` - Replay Attack Prevention**
2222
+
2223
+ Configure custom nonce storage for distributed deployments.
2224
+
2225
+ ```typescript
2226
+ import { Agent, RedisNonceStore } from '@private.me/xbind';
2227
+
2228
+ const agent = await Agent.create({
2229
+ name: 'distributed-agent',
2230
+ nonceStore: new RedisNonceStore({
2231
+ client: redisClient,
2232
+ ttl: 300000 // 5 minute nonce validity
2233
+ })
2234
+ });
2235
+ ```
2236
+
2237
+ **`scopes` - Authorization Scopes**
2238
+
2239
+ Restrict which message scopes this agent can receive.
2240
+
2241
+ ```typescript
2242
+ const agent = await Agent.create({
2243
+ name: 'scoped-receiver',
2244
+ scopes: ['messages', 'notifications'] // Only accept these scopes
2245
+ });
2246
+ ```
2247
+
2248
+ **`timestampWindowMs` - Timestamp Validation**
2249
+
2250
+ Configure acceptable clock skew between sender and receiver.
2251
+
2252
+ ```typescript
2253
+ const agent = await Agent.create({
2254
+ name: 'strict-timing',
2255
+ timestampWindowMs: 60000 // Accept messages within ±1 minute
2256
+ });
2257
+ ```
2258
+
2259
+ **`securityPolicy` - Enterprise Security Rules**
2260
+
2261
+ Apply custom security policies for enterprise deployments.
2262
+
2263
+ ```typescript
2264
+ import { Agent, DefaultSecurityPolicy } from '@private.me/xbind';
2265
+
2266
+ const customPolicy = new DefaultSecurityPolicy({
2267
+ requireEncryption: true,
2268
+ allowedDomains: ['*.private.me', '*.company.com']
2269
+ });
2270
+
2271
+ const agent = await Agent.create({
2272
+ name: 'enterprise-agent',
2273
+ securityPolicy: customPolicy
2274
+ });
2275
+ ```
2276
+
2277
+ **Security Mode Types**
2278
+
2279
+ Security policies use structured types to describe security modes (input) and their descriptions (output).
2280
+
2281
+ **`SecurityMode` (Input Type)**
2282
+
2283
+ Represents the security mode selected by the policy for a given action.
2284
+
2285
+ ```typescript
2286
+ type SecurityMode =
2287
+ | { readonly type: 'standard' }
2288
+ | { readonly type: 'split'; readonly shares: number; readonly threshold: number }
2289
+ | { readonly type: 'xchange' };
2290
+ ```
2291
+
2292
+ **`SecurityModeDescription` (Output Type)**
2293
+
2294
+ Structured description with multiple format representations for display, logging, APIs, and documentation.
2295
+
2296
+ ```typescript
2297
+ interface SecurityModeDescription {
2298
+ /** Security mode type. */
2299
+ readonly type: 'standard' | 'split' | 'xchange';
2300
+ /** Security level classification. */
2301
+ readonly level: 'standard' | 'high' | 'critical' | 'performance';
2302
+ /** Share configuration (only for split mode). */
2303
+ readonly shares?: { readonly total: number; readonly threshold: number };
2304
+ /** Multiple format representations. */
2305
+ readonly formats: {
2306
+ readonly multiline: string;
2307
+ readonly singleline: string;
2308
+ readonly json: string;
2309
+ readonly markdown: string;
2310
+ };
2311
+ }
2312
+ ```
2313
+
2314
+ **Usage Example**
2315
+
2316
+ ```typescript
2317
+ import { describeSecurityModeStructured, type SecurityMode } from '@private.me/xbind';
2318
+
2319
+ // Input: Security mode
2320
+ const mode: SecurityMode = { type: 'split', shares: 3, threshold: 2 };
2321
+
2322
+ // Output: Structured description
2323
+ const description = describeSecurityModeStructured(mode);
2324
+
2325
+ console.log(description.type); // 'split'
2326
+ console.log(description.level); // 'high'
2327
+ console.log(description.shares); // { total: 3, threshold: 2 }
2328
+
2329
+ // Format representations
2330
+ console.log(description.formats.singleline);
2331
+ // "high | split | 2-of-3"
2332
+
2333
+ console.log(description.formats.multiline);
2334
+ // "Security Level: High
2335
+ // Mode: Split-channel (XorIDA)
2336
+ // Shares: 3 total, 2 required"
2337
+
2338
+ console.log(description.formats.json);
2339
+ // '{"type":"split","level":"high","shares":{"total":3,"threshold":2}}'
2340
+
2341
+ console.log(description.formats.markdown);
2342
+ // "**Security Level:** High
2343
+ //
2344
+ // **Mode:** Split-channel (XorIDA)
2345
+ //
2346
+ // **Shares:** 3 total, 2 required"
2347
+ ```
2348
+
2349
+ **`registry` - Trust Registry Configuration**
2350
+
2351
+ Configure how agents discover and verify peer identities. Three implementations available.
2352
+
2353
+ ```typescript
2354
+ import { Agent, HttpTrustRegistry, FileTrustRegistry, MemoryTrustRegistry } from '@private.me/xbind';
2355
+
2356
+ // Production: HTTP-backed registry (default)
2357
+ const httpAgent = await Agent.create({
2358
+ name: 'production-agent',
2359
+ registry: new HttpTrustRegistry('https://private.me/registry')
2360
+ // Or shorthand: registry: 'https://private.me/registry'
2361
+ });
2362
+
2363
+ // Development: In-memory registry (ephemeral)
2364
+ const devAgent = await Agent.create({
2365
+ name: 'dev-agent',
2366
+ registry: new MemoryTrustRegistry() // No persistence, auto-cleanup
2367
+ });
2368
+
2369
+ // Enterprise: File-backed registry (local persistence)
2370
+ const fileAgent = await Agent.create({
2371
+ name: 'enterprise-agent',
2372
+ registry: new FileTrustRegistry('./registry.jsonl') // Append-only log
2373
+ });
2374
+ ```
2375
+
2376
+ **When to use each:**
2377
+ - `HttpTrustRegistry`: Production deployments, multi-agent coordination, DID resolution across networks
2378
+ - `MemoryTrustRegistry`: Testing, development, short-lived agents that don't need persistence
2379
+ - `FileTrustRegistry`: Enterprise deployments, local persistence, offline-capable systems
2380
+
2381
+ **`transport` - Multi-Transport Setup**
2382
+
2383
+ Configure message delivery channels. Single transport for simple deployments, multiple transports for redundancy or split-channel security.
2384
+
2385
+ ```typescript
2386
+ import { Agent, HttpsTransportAdapter, RetryTransportAdapter } from '@private.me/xbind';
2387
+
2388
+ // Single transport (default)
2389
+ const simpleAgent = await Agent.create({
2390
+ name: 'simple-agent',
2391
+ transport: new HttpsTransportAdapter('https://private.me/relay')
2392
+ });
2393
+
2394
+ // Retry wrapper for unreliable networks
2395
+ const reliableTransport = new RetryTransportAdapter(
2396
+ new HttpsTransportAdapter('https://private.me/relay'),
2397
+ {
2398
+ maxRetries: 3, // 3 retry attempts
2399
+ baseDelayMs: 1000, // 1s base delay
2400
+ maxJitterMs: 200 // ±200ms jitter
2401
+ }
2402
+ );
2403
+
2404
+ const reliableAgent = await Agent.create({
2405
+ name: 'reliable-agent',
2406
+ transport: reliableTransport
2407
+ });
2408
+
2409
+ // Multi-transport for split-channel (advanced)
2410
+ const multiAgent = await Agent.create({
2411
+ name: 'split-channel-agent',
2412
+ transport: [
2413
+ new HttpsTransportAdapter('https://relay1.private.me'),
2414
+ new HttpsTransportAdapter('https://relay2.private.me'),
2415
+ new HttpsTransportAdapter('https://relay3.private.me')
2416
+ ]
2417
+ });
2418
+ // Each XorIDA share routes to transport[shareIndex % transports.length]
2419
+ // Share 0 → relay1, Share 1 → relay2, Share 2 → relay3
2420
+ ```
2421
+
2422
+ **When to use:**
2423
+ - Single transport: Most use cases, simple deployments
2424
+ - `RetryTransportAdapter`: Mobile networks, unreliable connections, push notification delivery
2425
+ - Multi-transport: Critical security scenarios requiring channel separation (prevents correlation attacks)
2426
+
2427
+ **`postQuantumSig` - Post-Quantum Signatures**
2428
+
2429
+ Enable ML-DSA-65 (FIPS 204) post-quantum signatures for future-proof authentication.
2430
+
2431
+ ```typescript
2432
+ const quantumAgent = await Agent.create({
2433
+ name: 'quantum-safe-agent',
2434
+ postQuantumSig: true // Default: false
2435
+ });
2436
+
2437
+ // Sends v3 envelopes with hybrid signatures:
2438
+ // - Ed25519 (classical, 128-bit security)
2439
+ // - ML-DSA-65 (post-quantum, NIST Level 3)
2440
+ ```
2441
+
2442
+ **When to enable:**
2443
+ - Long-term data protection (10+ year confidentiality requirements)
2444
+ - Compliance with post-quantum cryptography mandates
2445
+ - High-security government/defense applications
2446
+ - Preparing for quantum computing threats
2447
+
2448
+ **Trade-offs:**
2449
+ - Signature size: +2.5KB per message (Ed25519: 64 bytes → ML-DSA-65: 2,701 bytes)
2450
+ - Performance: ~10% slower signing/verification
2451
+ - Compatibility: Requires peers to support v3 envelopes (xBind v0.2.0+)
2452
+
2453
+ **Default: `false`** (most applications don't need post-quantum signatures yet)
2454
+
2455
+ **`backupConfig` - Key Backup Configuration**
2456
+
2457
+ Configure XorIDA threshold sharing for key backup and recovery.
2458
+
2459
+ ```typescript
2460
+ import { Agent, DEFAULT_BACKUP_CONFIG } from '@private.me/xbind';
2461
+
2462
+ // Default: 2-of-3 (any 2 shares recover key)
2463
+ const defaultAgent = await Agent.create({
2464
+ name: 'default-backup',
2465
+ backupConfig: DEFAULT_BACKUP_CONFIG // threshold: 2, totalShares: 3
2466
+ });
2467
+
2468
+ // High security: 3-of-5 (lose 2 shares, still recover)
2469
+ const secureAgent = await Agent.create({
2470
+ name: 'secure-backup',
2471
+ backupConfig: {
2472
+ threshold: 3, // Need 3 shares to reconstruct
2473
+ totalShares: 5 // Generate 5 shares (can lose 2)
2474
+ }
2475
+ });
2476
+
2477
+ // Minimal: 2-of-2 (both shares required)
2478
+ const minimalAgent = await Agent.create({
2479
+ name: 'minimal-backup',
2480
+ backupConfig: {
2481
+ threshold: 2,
2482
+ totalShares: 2 // No fault tolerance (both required)
2483
+ }
2484
+ });
2485
+ ```
2486
+
2487
+ **When to use each:**
2488
+ - `2-of-3` (default): Balance security and convenience, tolerate 1 lost share
2489
+ - `3-of-5`: High-security scenarios, tolerate 2 lost shares, enterprise deployments
2490
+ - `2-of-2`: Minimal overhead, no fault tolerance, testing only
2491
+
2492
+ **Information-theoretic security:** Each share reveals zero information about the key. Even with `threshold - 1` shares, an attacker gains no information.
2493
+
2494
+ **`name` - Agent Naming Best Practices**
2495
+
2496
+ Agent names are human-readable identifiers used in logs, debugging, and trust registry lookups.
2497
+
2498
+ ```typescript
2499
+ // Good: Descriptive, kebab-case, unique per role
2500
+ const agent1 = await Agent.create({ name: 'email-service-agent' });
2501
+ const agent2 = await Agent.create({ name: 'payment-processor' });
2502
+ const agent3 = await Agent.create({ name: 'backup-validator' });
2503
+
2504
+ // Avoid: Generic names that don't identify purpose
2505
+ const bad1 = await Agent.create({ name: 'agent1' }); // Not descriptive
2506
+ const bad2 = await Agent.create({ name: 'test' }); // Too generic
2507
+ ```
2508
+
2509
+ **Conventions:**
2510
+ - Use kebab-case for consistency (`email-service`, not `EmailService` or `email_service`)
2511
+ - Include role/purpose (`payment-processor`, not `agent42`)
2512
+ - Keep under 50 characters for logging compatibility
2513
+ - Avoid PII or sensitive data in names (logged in plaintext)
2514
+
2515
+ **Name vs DID:**
2516
+ - **Name**: Human-readable, mutable, used for debugging/logs
2517
+ - **DID**: Cryptographic identifier, immutable, used for authentication
2518
+
2519
+ **`xchange` - Performance Mode**
2520
+
2521
+ Enable Xchange mode for 180× faster message delivery with single-layer information-theoretic security.
2522
+
2523
+ ```typescript
2524
+ const performanceAgent = await Agent.create({
2525
+ name: 'performance-agent',
2526
+ xchange: true // Default: false
2527
+ });
2528
+
2529
+ // Sending with Xchange mode
2530
+ await performanceAgent.send({
2531
+ to: recipientDid,
2532
+ payload: { action: 'transfer', amount: 100 },
2533
+ scope: 'payments'
2534
+ // Automatically uses v4 envelopes (XorIDA split + Ed25519, no KEM)
683
2535
  });
684
2536
  ```
685
2537
 
686
- ### Threshold Schemes
2538
+ **When to enable:**
2539
+ - High-throughput systems (>1000 messages/second)
2540
+ - Latency-sensitive applications (real-time chat, gaming)
2541
+ - Bandwidth-constrained networks (mobile, IoT)
2542
+ - Internal microservice communication (trusted network)
687
2543
 
688
- | Risk Tag / Threshold | Shares | Required | Security Level |
689
- |---------------------|--------|----------|----------------|
690
- | `low` | 2 | 2 | 2-of-2 threshold |
691
- | `medium` / $100k-$1M | 3 | 2 | 2-of-3 threshold |
692
- | `high` / `critical` / >$1M | 5 | 3 | 3-of-5 threshold |
693
- | No tag / <$100k | — | — | Standard encrypted transport |
2544
+ **Security model:**
2545
+ - Single layer: Information-theoretic XorIDA split (provably secure)
2546
+ - Authentication: Ed25519 signatures (128-bit security)
2547
+ - No KEM: Skips hybrid key encapsulation (saves ~180× overhead)
694
2548
 
695
- **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.
2549
+ **Trade-offs:**
2550
+ - Performance: ~180× faster than v3 split-channel
2551
+ - Security: Single IT layer vs triple-layer (IT + classical + post-quantum)
2552
+ - Use case: Trusted networks where triple-layer is overkill
696
2553
 
697
- ## Billing & Metering
2554
+ **Default: `false`** (prioritize maximum security over performance)
698
2555
 
699
- xBind includes usage-based billing with automated milestone notifications:
2556
+ ## Section 2: Trust & Key Agreement
700
2557
 
701
- - **Free Tier:** Generous monthly limits (no email verification required upfront)
702
- - **Grace Buffer:** Additional operations available after email verification
703
- - **Pro Tier:** Usage-based billing with unlimited operations
704
- - **Monthly Reset:** 1st of each month at 00:00 UTC
2558
+ ### Trust & Key Agreement
705
2559
 
706
- See [pricing](../../docs/pricing-reference.md) for current rates and tier details.
2560
+ **Generate ephemeral X25519 key pair:**
707
2561
 
708
- ### Milestone Notifications
2562
+ <!-- RUNNABLE-EXAMPLE -->
2563
+ ```typescript
2564
+ import { generateEphemeralKeyPair } from '@private.me/xbind';
709
2565
 
710
- Automated email notifications at usage thresholds with progress bars and CTAs for upgrades.
2566
+ const ephemeral = await generateEphemeralKeyPair();
2567
+ if (!ephemeral.ok) {
2568
+ throw new Error(`Key generation failed: ${ephemeral.error}`);
2569
+ }
711
2570
 
712
- **Email verification:** Required at free tier limit to access grace buffer.
2571
+ console.log('Ephemeral public key (32 bytes):', ephemeral.value.rawPublicKey);
2572
+ // Use ephemeral.value.privateKey for ECDH, then discard
2573
+ ```
2574
+ <!-- /RUNNABLE-EXAMPLE -->
713
2575
 
714
- **Implementation:**
715
- - Metering logic: `apps/server/src/customer-metering.ts`
716
- - Milestone system: `apps/server/src/usage-milestone-notifications.ts`
717
- - Tier pattern: See `docs/gold-package.md` section 7.6.5
2576
+ **Import X25519 public key:**
718
2577
 
719
- ## Gateway
2578
+ <!-- RUNNABLE-EXAMPLE -->
2579
+ ```typescript
2580
+ import { importX25519PublicKey } from '@private.me/xbind';
720
2581
 
721
- Non-authoritative coordination for discovery, relay, push notifications, and state checkpoints. Cannot forge identity or decide trust. See [Gateway Architecture](./docs/gateway-architecture.md).
2582
+ const rawPublicKey = new Uint8Array(32); // From recipient's identity
2583
+ const result = await importX25519PublicKey(rawPublicKey);
722
2584
 
723
- ## Connection Models
2585
+ if (!result.ok) {
2586
+ throw new Error(`Import failed: ${result.error}`);
2587
+ }
724
2588
 
725
- 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.
2589
+ const publicKey = result.value; // CryptoKey for ECDH
2590
+ ```
2591
+ <!-- /RUNNABLE-EXAMPLE -->
726
2592
 
727
- | Model | Security | UX | Best For |
728
- |-------|----------|-----|----------|
729
- | Invite Code | Single-use, 24h TTL | 6-char code | Customer onboarding |
730
- | QR Code | Physical proximity, 60s TTL | Scan & tap | Mobile/desktop pairing |
731
- | Trust Registry | Admin pre-auth, scoped | Zero (automated) | Enterprise/CI/CD |
732
- | Peer Discovery | LAN proximity, user confirm | Scan & confirm | IoT devices, offline |
2593
+ **Derive shared key via ECDH:**
733
2594
 
734
- See [Entity-to-Entity Connection UX Guide](../../docs/ENTITY-TO-ENTITY-CONNECTION-UX.md) for implementation patterns and code examples.
2595
+ <!-- RUNNABLE-EXAMPLE -->
2596
+ ```typescript
2597
+ import { deriveSharedKeyECDH, generateEphemeralKeyPair, importX25519PublicKey } from '@private.me/xbind';
735
2598
 
736
- ## Configuration
2599
+ // Generate ephemeral key
2600
+ const ephemeral = await generateEphemeralKeyPair();
2601
+ if (!ephemeral.ok) throw new Error(ephemeral.error);
737
2602
 
738
- ### Basic Setup
2603
+ // Import recipient's public key
2604
+ const recipientKey = await importX25519PublicKey(recipientPubKeyBytes);
2605
+ if (!recipientKey.ok) throw new Error(recipientKey.error);
2606
+
2607
+ // Derive shared AES-256-GCM key
2608
+ const shared = await deriveSharedKeyECDH(
2609
+ ephemeral.value.privateKey,
2610
+ recipientKey.value
2611
+ );
739
2612
 
2613
+ if (shared.ok) {
2614
+ console.log('Shared key derived for AES-256-GCM');
2615
+ }
2616
+ ```
2617
+ <!-- /RUNNABLE-EXAMPLE -->
2618
+
2619
+ **Sender-side key agreement:**
2620
+
2621
+ <!-- RUNNABLE-EXAMPLE -->
740
2622
  ```typescript
741
- import { HttpTrustRegistry } from '@private.me/xbind';
2623
+ import { senderKeyAgreement, importX25519PublicKey, generateIdentity } from '@private.me/xbind';
742
2624
 
743
- // Documentation example - use your actual gateway URL
744
- const registry = new HttpTrustRegistry({
745
- baseUrl: 'https://gateway.private.me'
2625
+ // Generate recipient identity for testing (in production, get from registry)
2626
+ const recipientResult = await generateIdentity();
2627
+ if (!recipientResult.ok) throw new Error(recipientResult.error);
2628
+ const recipientPubKeyRaw = recipientResult.value.rawX25519PublicKey;
2629
+
2630
+ // Import recipient's X25519 public key
2631
+ const recipientPubKey = await importX25519PublicKey(recipientPubKeyRaw);
2632
+ if (!recipientPubKey.ok) throw new Error(recipientPubKey.error);
2633
+
2634
+ // Perform key agreement
2635
+ const agreement = await senderKeyAgreement(recipientPubKey.value);
2636
+ if (!agreement.ok) throw new Error(agreement.error);
2637
+
2638
+ // Use shared key for encryption
2639
+ const { sharedKey, ephemeralPublicKey } = agreement.value;
2640
+ console.log('Ephemeral public key to include in envelope:', ephemeralPublicKey);
2641
+ ```
2642
+ <!-- /RUNNABLE-EXAMPLE -->
2643
+
2644
+ **Receiver-side key agreement:**
2645
+
2646
+ <!-- RUNNABLE-EXAMPLE -->
2647
+ ```typescript
2648
+ import { receiverKeyAgreement } from '@private.me/xbind';
2649
+
2650
+ // Extract ephemeral public key from envelope
2651
+ const senderEphemeralPubRaw = envelope.ephemeralPublicKey;
2652
+
2653
+ // Derive shared key using receiver's static private key
2654
+ const shared = await receiverKeyAgreement(
2655
+ receiverPrivateKey,
2656
+ senderEphemeralPubRaw
2657
+ );
2658
+
2659
+ if (shared.ok) {
2660
+ const sharedKey = shared.value;
2661
+ // Use sharedKey for decryption
2662
+ }
2663
+ ```
2664
+ <!-- /RUNNABLE-EXAMPLE -->
2665
+
2666
+ **Hybrid key agreement (X25519 + ML-KEM-768) - Sender:**
2667
+
2668
+ <!-- RUNNABLE-EXAMPLE -->
2669
+ ```typescript
2670
+ import { senderHybridKeyAgreement } from '@private.me/xbind';
2671
+
2672
+ // Recipient's keys from registry
2673
+ const recipientX25519Pub = recipientEntry.x25519PublicKey; // CryptoKey
2674
+ const recipientMlKemPub = recipientEntry.mlKemPublicKey; // 1184 bytes
2675
+
2676
+ const result = await senderHybridKeyAgreement(
2677
+ recipientX25519Pub,
2678
+ recipientMlKemPub
2679
+ );
2680
+
2681
+ if (!result.ok) {
2682
+ throw new Error(`Hybrid key agreement failed: ${result.error}`);
2683
+ }
2684
+
2685
+ const { sharedKey, ephemeralPublicKey, kemCiphertext } = result.value;
2686
+ // Include ephemeralPublicKey (32B) and kemCiphertext (1088B) in envelope
2687
+ ```
2688
+ <!-- /RUNNABLE-EXAMPLE -->
2689
+
2690
+ **Hybrid key agreement (X25519 + ML-KEM-768) - Receiver:**
2691
+
2692
+ <!-- RUNNABLE-EXAMPLE -->
2693
+ ```typescript
2694
+ import { receiverHybridKeyAgreement } from '@private.me/xbind';
2695
+
2696
+ // Receiver's keys
2697
+ const x25519PrivateKey = identity.x25519PrivateKey; // CryptoKey
2698
+ const x25519PublicKeyRaw = identity.x25519PublicKey; // 32 bytes
2699
+ const mlKemSecretKey = identity.mlKemSecretKey; // 2400 bytes
2700
+ const mlKemPublicKey = identity.mlKemPublicKey; // 1184 bytes
2701
+
2702
+ // Envelope data
2703
+ const ephPubRaw = envelope.ephemeralPublicKey; // 32 bytes
2704
+ const kemCiphertext = envelope.kemCiphertext; // 1088 bytes
2705
+
2706
+ const result = await receiverHybridKeyAgreement(
2707
+ x25519PrivateKey,
2708
+ x25519PublicKeyRaw,
2709
+ ephPubRaw,
2710
+ kemCiphertext,
2711
+ mlKemSecretKey,
2712
+ mlKemPublicKey
2713
+ );
2714
+
2715
+ if (result.ok) {
2716
+ const sharedKey = result.value; // Same AES-256-GCM key as sender
2717
+ }
2718
+ ```
2719
+ <!-- /RUNNABLE-EXAMPLE -->
2720
+
2721
+ **File-based trust registry:**
2722
+
2723
+ <!-- RUNNABLE-EXAMPLE -->
2724
+ ```typescript
2725
+ import { FileTrustRegistry } from '@private.me/xbind';
2726
+
2727
+ const registry = new FileTrustRegistry({
2728
+ path: '/opt/corp/trust.jsonl'
2729
+ });
2730
+
2731
+ // Register agent
2732
+ await registry.register(
2733
+ 'did:key:z6Mk...',
2734
+ publicKeyBytes,
2735
+ 'Corporate Gateway',
2736
+ ['billing', 'auth'],
2737
+ x25519PublicKey,
2738
+ mlKemPublicKey,
2739
+ mlDsaPublicKey,
2740
+ true, // xchange enabled
2741
+ ['billing', 'auth'], // receive scopes
2742
+ '3.0.3', // SDK version
2743
+ 1, // minEnvelopeVersion
2744
+ 4 // maxEnvelopeVersion
2745
+ );
2746
+
2747
+ // Resolve DID
2748
+ const result = await registry.resolve('did:key:z6Mk...');
2749
+ if (result.ok) {
2750
+ console.log('Public key:', result.value);
2751
+ }
2752
+
2753
+ // Cleanup expired entries
2754
+ const removed = await registry.cleanup();
2755
+ console.log('Removed entries:', removed);
2756
+ ```
2757
+ <!-- /RUNNABLE-EXAMPLE -->
2758
+
2759
+ **Enterprise trust registry factory:**
2760
+
2761
+ <!-- RUNNABLE-EXAMPLE -->
2762
+ ```typescript
2763
+ import { createEnterpriseTrustRegistry } from '@private.me/xbind';
2764
+
2765
+ const registry = await createEnterpriseTrustRegistry({
2766
+ storage: 'file',
2767
+ path: '/opt/corp/trust.jsonl',
2768
+ preload: [
2769
+ {
2770
+ did: 'did:web:corp.example.com',
2771
+ publicKey: corporateGatewayPubKey,
2772
+ name: 'Corporate Gateway',
2773
+ scopes: ['billing', 'auth', 'payments'],
2774
+ x25519PublicKey: corporateX25519Key,
2775
+ mlKemPublicKey: corporateMlKemKey
2776
+ }
2777
+ ]
2778
+ });
2779
+
2780
+ console.log('Enterprise registry initialized with pre-loaded entries');
2781
+ ```
2782
+ <!-- /RUNNABLE-EXAMPLE -->
2783
+
2784
+ **Message stream with async iteration:**
2785
+
2786
+ <!-- RUNNABLE-EXAMPLE -->
2787
+ ```typescript
2788
+ import { MessageStream, collectMessages } from '@private.me/xbind';
2789
+
2790
+ // Subscribe to all messages from Alice
2791
+ for await (const message of agent.subscribe({ from: 'did:key:alice' })) {
2792
+ console.log('Received:', message.payload);
2793
+ if (message.scope === 'urgent') break; // Early termination
2794
+ }
2795
+
2796
+ // Collect batch of messages with timeout
2797
+ const messages = await collectMessages(agent, {
2798
+ from: 'did:key:alice',
2799
+ limit: 10,
2800
+ timeout: 5000
746
2801
  });
2802
+
2803
+ console.log('Collected messages:', messages.length);
2804
+ ```
2805
+ <!-- /RUNNABLE-EXAMPLE -->
2806
+
2807
+ **Parse agent errors:**
2808
+
2809
+ <!-- RUNNABLE-EXAMPLE -->
2810
+ ```typescript
2811
+ import { parseAgentError, isXBindError } from '@private.me/xbind';
2812
+
2813
+ try {
2814
+ await agent.send({ to: recipientDid, payload: data });
2815
+ } catch (error) {
2816
+ if (isXBindError(error)) {
2817
+ console.error('Code:', error.code);
2818
+ console.error('Sub-code:', error.subCode);
2819
+ console.error('Docs:', error.docUrl);
2820
+ }
2821
+ }
747
2822
  ```
2823
+ <!-- /RUNNABLE-EXAMPLE -->
2824
+
2825
+ ---
748
2826
 
2827
+ ## Summary
2828
+
2829
+ **Batch 4 Examples (13 exports - Operational Excellence):**
2830
+ 1. TimeoutConfig - Timeout configuration manager
2831
+ 2. OperationTimeoutController - Per-operation timeout control
2832
+ 3. createTimeoutController - Create timeout controller
2833
+ 4. withTimeout - Wrap function with timeout
2834
+ 5. withTimeoutResult - Wrap with Result timeout
2835
+ 6. createOperationTimeoutSignal - Create AbortSignal
2836
+ 7. createOperationTimeout - Create timeout config
2837
+ 8. isTimeoutError - Check timeout error
2838
+ 9. getTimeoutFromError - Extract timeout
2839
+ 10. createTimeoutConfigFromEnv - Create from env
2840
+ 11. globalTimeoutConfig - Global config
2841
+ 12. GracefulDegradationManager - Graceful degradation
2842
+ 13. registryLookupWithFallback - Registry with fallback
2843
+
2844
+ **Batch 5 Examples (15 exports - Trust & Discovery):**
2845
+ 1. sendWithTransportFallback - Transport fallback
2846
+ 2. enhanceError - Error enhancement (not shown - internal)
2847
+ 3. FileTrustRegistry - File-based registry
2848
+ 4. createEnterpriseTrustRegistry - Enterprise factory
2849
+ 5. generateEphemeralKeyPair - Generate X25519 pair
2850
+ 6. importX25519PublicKey - Import X25519 key
2851
+ 7. deriveSharedKeyECDH - ECDH derivation
2852
+ 8. senderKeyAgreement - Sender key agreement
2853
+ 9. receiverKeyAgreement - Receiver key agreement
2854
+ 10. combineSharedSecrets - Combine secrets (not shown - internal)
2855
+ 11. senderHybridKeyAgreement - Hybrid sender
2856
+ 12. receiverHybridKeyAgreement - Hybrid receiver
2857
+ 13. parseAgentError - Parse errors
2858
+ 14. MessageStream - Async iteration
2859
+ 15. collectMessages - Batch collect
2860
+
2861
+ **Total: 28 new code examples for Batch 4 & 5 exports**
749
2862
  ### Advanced Features
750
2863
 
751
2864
  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).
@@ -754,6 +2867,7 @@ Checkpoints, sequence numbers, subscription proofs, XorIDA configuration, key ba
754
2867
 
755
2868
  xbind returns `Result<T, E>` types for type-safe error handling.
756
2869
 
2870
+ <!-- SNIPPET -->
757
2871
  ```typescript
758
2872
  import { call, type CallResult } from '@private.me/xbind';
759
2873
 
@@ -767,6 +2881,7 @@ if (result.ok) {
767
2881
  console.error(result.error.message);
768
2882
  }
769
2883
  ```
2884
+ <!-- /SNIPPET -->
770
2885
 
771
2886
  Error types: `ConnectionError`, `AuthenticationError`, `ValidationError`, `RateLimitError`, `ServerError`
772
2887
 
@@ -791,6 +2906,48 @@ pnpm test:coverage # Coverage report
791
2906
  pnpm test:watch # Watch mode
792
2907
  ```
793
2908
 
2909
+ ### Testing with LoopbackTransport
2910
+
2911
+ For unit testing and local development, use `LoopbackTransport` to simulate agent communication without network calls:
2912
+
2913
+ ```typescript
2914
+ import { Agent, LoopbackTransport } from '@private.me/xbind';
2915
+
2916
+ // Create a shared in-memory transport
2917
+ const transport = new LoopbackTransport();
2918
+
2919
+ // Create two agents using the same transport
2920
+ const alice = await Agent.create({
2921
+ name: 'alice',
2922
+ transport
2923
+ });
2924
+
2925
+ const bob = await Agent.create({
2926
+ name: 'bob',
2927
+ transport
2928
+ });
2929
+
2930
+ // Messages are delivered instantly in-memory
2931
+ const result = await alice.send({
2932
+ to: bob.did,
2933
+ payload: { test: true }
2934
+ });
2935
+
2936
+ if (result.ok) {
2937
+ console.log('Message delivered via loopback transport');
2938
+ }
2939
+
2940
+ // Bob can receive messages from Alice
2941
+ const envelope = // ... received via transport callback
2942
+ const received = await bob.receive(envelope);
2943
+ ```
2944
+
2945
+ **Use cases:**
2946
+ - Unit testing agent communication without external services
2947
+ - Local development without network dependencies
2948
+ - CI/CD pipelines that need fast, deterministic tests
2949
+ - Integration testing of multi-agent workflows
2950
+
794
2951
  ## Full Control IP Protection
795
2952
 
796
2953
  xBind uses **Full Control** (2-share XorIDA) to protect proprietary cryptographic algorithms while maintaining a seamless developer experience.
@@ -823,10 +2980,10 @@ When combined, Share 1 + Share 2 reconstruct the complete XorIDA algorithm at ru
823
2980
  - At 120K ops: 402 Quota Exceeded → Upgrade prompt
824
2981
 
825
2982
  - **Pro Tier:** Unlimited operations
826
- - $5 per 100,000 operations (after first 100K free)
2983
+ - Usage-based billing (after first 100K free)
827
2984
  - No quota checks
828
2985
  - Vault access unlimited
829
- - Example: 400K ops = $15/month (100K free + 300K @ $5/100K)
2986
+ - Example: 400K ops calculated based on current rates (see pricing link)
830
2987
 
831
2988
  - **VIP Tier:** Custom limits per account
832
2989
  - Bronze: 200K, Silver: 500K, Gold: 1M, Platinum: Unlimited
@@ -982,3 +3139,49 @@ This package contains cryptographic software. Export restrictions may apply. Use
982
3139
  ---
983
3140
 
984
3141
  **Questions?** [Documentation](./docs/README.md) • [White paper](https://private.me/docs/xbind.html) • [Issues](https://github.com/xail-io/xail/issues)
3142
+
3143
+ ### Stream Processing Utilities
3144
+
3145
+ **Transform message streams with map/filter/take:**
3146
+
3147
+ <!-- RUNNABLE-EXAMPLE -->
3148
+ ```typescript
3149
+ import { mapStream, filterStream, takeStream, mergeStreams } from '@private.me/xbind';
3150
+
3151
+ // Map transform
3152
+ const doubled = mapStream(messageStream, (msg) => ({
3153
+ ...msg,
3154
+ payload: msg.payload * 2
3155
+ }));
3156
+
3157
+ // Filter messages
3158
+ const urgent = filterStream(messageStream, (msg) => msg.scope === 'urgent');
3159
+
3160
+ // Take first N messages
3161
+ const first10 = takeStream(messageStream, 10);
3162
+
3163
+ // Merge multiple streams
3164
+ const combined = mergeStreams([streamA, streamB, streamC]);
3165
+
3166
+ for await (const message of combined) {
3167
+ console.log('Received from merged streams:', message);
3168
+ }
3169
+ ```
3170
+ <!-- /RUNNABLE-EXAMPLE -->
3171
+
3172
+ **Install async iterator support:**
3173
+
3174
+ <!-- RUNNABLE-EXAMPLE -->
3175
+ ```typescript
3176
+ import { installAsyncIterators } from '@private.me/xbind';
3177
+
3178
+ // Enable async iterator methods on Agent
3179
+ installAsyncIterators();
3180
+
3181
+ // Now you can use async iteration
3182
+ for await (const message of agent.messages()) {
3183
+ console.log('Message received:', message.payload);
3184
+ }
3185
+ ```
3186
+ <!-- /RUNNABLE-EXAMPLE -->
3187
+