@private.me/xbind 3.0.2 → 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 (221) hide show
  1. package/README.md +2366 -204
  2. package/README.md.backup +2121 -0
  3. package/dist-standalone/_deps/mldsa-wasm/dist/mldsa.js +1 -1920
  4. package/dist-standalone/_deps/shared/cjs/errors.js +1 -729
  5. package/dist-standalone/_deps/shared/cjs/index.js +1 -463
  6. package/dist-standalone/_deps/shared/cjs/types.js +1 -315
  7. package/dist-standalone/_deps/shared/errors.js +1 -244
  8. package/dist-standalone/_deps/shared/index.js +1 -72
  9. package/dist-standalone/_deps/shared/types.js +1 -86
  10. package/dist-standalone/_deps/ux-helpers/cjs/errors.js +1 -1
  11. package/dist-standalone/_deps/ux-helpers/cjs/index.js +1 -1
  12. package/dist-standalone/_deps/ux-helpers/cjs/pagination.js +1 -1
  13. package/dist-standalone/_deps/ux-helpers/cjs/progress.js +1 -1
  14. package/dist-standalone/_deps/ux-helpers/cjs/search.js +1 -1
  15. package/dist-standalone/_deps/ux-helpers/cjs/types.js +1 -1
  16. package/dist-standalone/_deps/ux-helpers/errors.js +1 -1
  17. package/dist-standalone/_deps/ux-helpers/index.js +1 -1
  18. package/dist-standalone/_deps/ux-helpers/pagination.js +1 -1
  19. package/dist-standalone/_deps/ux-helpers/progress.js +1 -1
  20. package/dist-standalone/_deps/ux-helpers/search.js +1 -1
  21. package/dist-standalone/_deps/xchange/auto-accept.js +1 -1
  22. package/dist-standalone/_deps/xchange/cjs/auto-accept.js +1 -1
  23. package/dist-standalone/_deps/xchange/cjs/errors.js +1 -1
  24. package/dist-standalone/_deps/xchange/cjs/index.js +1 -1
  25. package/dist-standalone/_deps/xchange/cjs/invite-client.js +1 -1
  26. package/dist-standalone/_deps/xchange/cjs/lazy-init.js +1 -1
  27. package/dist-standalone/_deps/xchange/cjs/trust-integration.js +1 -1
  28. package/dist-standalone/_deps/xchange/cjs/xchange.js +1 -1
  29. package/dist-standalone/_deps/xchange/errors.js +1 -1
  30. package/dist-standalone/_deps/xchange/index.js +1 -1
  31. package/dist-standalone/_deps/xchange/invite-client.js +1 -1
  32. package/dist-standalone/_deps/xchange/lazy-init.js +1 -1
  33. package/dist-standalone/_deps/xchange/trust-integration.js +1 -1
  34. package/dist-standalone/_deps/xchange/xchange.js +1 -1
  35. package/dist-standalone/_deps/xregistry/cjs/discovery.js +1 -1
  36. package/dist-standalone/_deps/xregistry/cjs/errors.js +1 -1
  37. package/dist-standalone/_deps/xregistry/cjs/index.js +1 -1
  38. package/dist-standalone/_deps/xregistry/cjs/registry.js +1 -1
  39. package/dist-standalone/_deps/xregistry/cjs/schema.js +1 -1
  40. package/dist-standalone/_deps/xregistry/cjs/types.js +1 -1
  41. package/dist-standalone/_deps/xregistry/discovery.js +1 -1
  42. package/dist-standalone/_deps/xregistry/errors.js +1 -1
  43. package/dist-standalone/_deps/xregistry/index.js +1 -1
  44. package/dist-standalone/_deps/xregistry/registry.js +1 -1
  45. package/dist-standalone/_deps/xregistry/schema.js +1 -1
  46. package/dist-standalone/_deps/xregistry/types.js +1 -1
  47. package/dist-standalone/agent-call.d.ts +2 -2
  48. package/dist-standalone/agent-call.js +1 -659
  49. package/dist-standalone/agent-sdk.js +1 -328
  50. package/dist-standalone/agent.d.ts +2 -0
  51. package/dist-standalone/agent.js +1 -1800
  52. package/dist-standalone/approval.js +1 -193
  53. package/dist-standalone/async-iterators.d.ts +3 -3
  54. package/dist-standalone/async-iterators.js +1 -382
  55. package/dist-standalone/auth.js +1 -219
  56. package/dist-standalone/auto-accept.js +1 -229
  57. package/dist-standalone/backup-config.js +1 -201
  58. package/dist-standalone/backup.js +1 -326
  59. package/dist-standalone/batch-operations.js +1 -388
  60. package/dist-standalone/cancellation.js +1 -477
  61. package/dist-standalone/checkpoint.js +1 -186
  62. package/dist-standalone/circuit-breaker.js +1 -468
  63. package/dist-standalone/cjs/agent-call.js +1 -701
  64. package/dist-standalone/cjs/agent-sdk.js +1 -332
  65. package/dist-standalone/cjs/agent.js +1 -1837
  66. package/dist-standalone/cjs/approval.js +1 -199
  67. package/dist-standalone/cjs/async-iterators.js +1 -392
  68. package/dist-standalone/cjs/auth.js +1 -225
  69. package/dist-standalone/cjs/auto-accept.js +1 -233
  70. package/dist-standalone/cjs/backup-config.js +1 -207
  71. package/dist-standalone/cjs/backup.js +1 -330
  72. package/dist-standalone/cjs/batch-operations.js +1 -397
  73. package/dist-standalone/cjs/cancellation.js +1 -490
  74. package/dist-standalone/cjs/checkpoint.js +1 -193
  75. package/dist-standalone/cjs/circuit-breaker.js +1 -476
  76. package/dist-standalone/cjs/cli/init.js +1 -492
  77. package/dist-standalone/cjs/config-validation.js +1 -522
  78. package/dist-standalone/cjs/connect.js +1 -312
  79. package/dist-standalone/cjs/connection-pool.js +1 -506
  80. package/dist-standalone/cjs/correlation-id.js +1 -339
  81. package/dist-standalone/cjs/crypto-utils.js +1 -176
  82. package/dist-standalone/cjs/debug-mode.js +1 -534
  83. package/dist-standalone/cjs/did-document.js +1 -101
  84. package/dist-standalone/cjs/did-privateme.js +1 -130
  85. package/dist-standalone/cjs/did-web.js +1 -201
  86. package/dist-standalone/cjs/discovery.js +1 -462
  87. package/dist-standalone/cjs/dual-mode.js +1 -251
  88. package/dist-standalone/cjs/email-templates.js +1 -313
  89. package/dist-standalone/cjs/email-transport.js +1 -239
  90. package/dist-standalone/cjs/envelope.js +1 -538
  91. package/dist-standalone/cjs/errors.js +1 -913
  92. package/dist-standalone/cjs/event-emitter.js +1 -461
  93. package/dist-standalone/cjs/gateway-state.js +1 -55
  94. package/dist-standalone/cjs/gateway-transport.js +1 -120
  95. package/dist-standalone/cjs/graceful-degradation.js +1 -403
  96. package/dist-standalone/cjs/guardrails.js +1 -223
  97. package/dist-standalone/cjs/health-check.js +1 -336
  98. package/dist-standalone/cjs/http-compat.js +1 -272
  99. package/dist-standalone/cjs/http-status-map.js +1 -571
  100. package/dist-standalone/cjs/identity.js +1 -645
  101. package/dist-standalone/cjs/index.js +1 -406
  102. package/dist-standalone/cjs/invitation.js +1 -421
  103. package/dist-standalone/cjs/invite.js +1 -328
  104. package/dist-standalone/cjs/key-agreement.js +1 -335
  105. package/dist-standalone/cjs/lazy-init.js +1 -300
  106. package/dist-standalone/cjs/logger.js +1 -291
  107. package/dist-standalone/cjs/loopback-transport.js +1 -0
  108. package/dist-standalone/cjs/mdns-discovery.js +1 -202
  109. package/dist-standalone/cjs/nonce-store.js +1 -80
  110. package/dist-standalone/cjs/pairing-manager.js +1 -223
  111. package/dist-standalone/cjs/plugin-system.js +1 -264
  112. package/dist-standalone/cjs/plugins/logging.js +1 -168
  113. package/dist-standalone/cjs/plugins/metrics.js +1 -181
  114. package/dist-standalone/cjs/plugins/validation.js +1 -302
  115. package/dist-standalone/cjs/policy.js +1 -320
  116. package/dist-standalone/cjs/progress-callbacks.js +1 -583
  117. package/dist-standalone/cjs/redis-nonce-store.js +1 -76
  118. package/dist-standalone/cjs/registry-middleware.js +1 -50
  119. package/dist-standalone/cjs/retry-strategies.js +1 -544
  120. package/dist-standalone/cjs/retry-transport.js +1 -102
  121. package/dist-standalone/cjs/runtime/browser.js +1 -533
  122. package/dist-standalone/cjs/runtime/edge.js +1 -526
  123. package/dist-standalone/cjs/runtime/react-native.js +1 -394
  124. package/dist-standalone/cjs/security-policy.js +1 -245
  125. package/dist-standalone/cjs/serialization.js +1 -1040
  126. package/dist-standalone/cjs/split-channel.js +1 -225
  127. package/dist-standalone/cjs/subscription-proof.js +1 -230
  128. package/dist-standalone/cjs/succession.js +1 -148
  129. package/dist-standalone/cjs/timeouts.js +1 -412
  130. package/dist-standalone/cjs/trace-context.js +1 -424
  131. package/dist-standalone/cjs/trace-spans.js +1 -495
  132. package/dist-standalone/cjs/transport.js +1 -63
  133. package/dist-standalone/cjs/trust-registry.js +1 -991
  134. package/dist-standalone/cjs/types/error-response.js +1 -56
  135. package/dist-standalone/cjs/vault-auth.js +1 -178
  136. package/dist-standalone/cjs/vault-store-loader.js +1 -194
  137. package/dist-standalone/cjs/verify.js +1 -25
  138. package/dist-standalone/cjs/version-info.js +1 -543
  139. package/dist-standalone/cjs/xfetch.js +1 -340
  140. package/dist-standalone/cli/init.js +1 -455
  141. package/dist-standalone/cli/setup.js +1 -514
  142. package/dist-standalone/cli/types.js +1 -27
  143. package/dist-standalone/cli/xbind.js +1 -148
  144. package/dist-standalone/config-validation.js +1 -513
  145. package/dist-standalone/connect.js +1 -274
  146. package/dist-standalone/connection-pool.js +1 -500
  147. package/dist-standalone/correlation-id.js +1 -326
  148. package/dist-standalone/crypto-utils.d.ts +2 -7
  149. package/dist-standalone/crypto-utils.js +1 -157
  150. package/dist-standalone/debug-mode.js +1 -510
  151. package/dist-standalone/did-document.js +1 -96
  152. package/dist-standalone/did-privateme.js +1 -121
  153. package/dist-standalone/did-web.js +1 -196
  154. package/dist-standalone/discovery.js +1 -458
  155. package/dist-standalone/dual-mode.js +1 -247
  156. package/dist-standalone/email-templates.js +1 -309
  157. package/dist-standalone/email-transport.d.ts +2 -2
  158. package/dist-standalone/email-transport.js +1 -232
  159. package/dist-standalone/envelope.js +1 -525
  160. package/dist-standalone/errors.d.ts +13 -3
  161. package/dist-standalone/errors.js +1 -896
  162. package/dist-standalone/event-emitter.js +1 -456
  163. package/dist-standalone/gateway-state.d.ts +1 -1
  164. package/dist-standalone/gateway-state.js +1 -51
  165. package/dist-standalone/gateway-transport.js +1 -116
  166. package/dist-standalone/graceful-degradation.js +1 -396
  167. package/dist-standalone/guardrails.js +1 -216
  168. package/dist-standalone/health-check.d.ts +5 -1
  169. package/dist-standalone/health-check.js +1 -332
  170. package/dist-standalone/http-compat.d.ts +1 -1
  171. package/dist-standalone/http-compat.js +1 -267
  172. package/dist-standalone/http-status-map.js +1 -561
  173. package/dist-standalone/identity.js +1 -619
  174. package/dist-standalone/index.d.ts +15 -4
  175. package/dist-standalone/index.js +1 -78
  176. package/dist-standalone/invitation.js +1 -415
  177. package/dist-standalone/invite.js +1 -324
  178. package/dist-standalone/key-agreement.js +1 -325
  179. package/dist-standalone/lazy-init.d.ts +11 -6
  180. package/dist-standalone/lazy-init.js +1 -295
  181. package/dist-standalone/logger.js +1 -285
  182. package/dist-standalone/loopback-transport.d.ts +87 -0
  183. package/dist-standalone/loopback-transport.js +1 -0
  184. package/dist-standalone/mdns-discovery.js +1 -195
  185. package/dist-standalone/nonce-store.js +1 -76
  186. package/dist-standalone/pairing-manager.js +1 -219
  187. package/dist-standalone/plugin-system.js +1 -257
  188. package/dist-standalone/plugins/logging.js +1 -163
  189. package/dist-standalone/plugins/metrics.d.ts +4 -4
  190. package/dist-standalone/plugins/metrics.js +1 -176
  191. package/dist-standalone/plugins/validation.js +1 -297
  192. package/dist-standalone/policy.js +1 -315
  193. package/dist-standalone/progress-callbacks.js +1 -576
  194. package/dist-standalone/redis-nonce-store.js +1 -72
  195. package/dist-standalone/registry-middleware.js +1 -47
  196. package/dist-standalone/retry-strategies.js +1 -534
  197. package/dist-standalone/retry-transport.js +1 -98
  198. package/dist-standalone/runtime/browser.js +1 -516
  199. package/dist-standalone/runtime/edge.js +1 -511
  200. package/dist-standalone/runtime/react-native.d.ts +1 -1
  201. package/dist-standalone/runtime/react-native.js +1 -383
  202. package/dist-standalone/security-policy.js +1 -239
  203. package/dist-standalone/serialization.js +1 -1031
  204. package/dist-standalone/split-channel.js +1 -219
  205. package/dist-standalone/subscription-proof.js +1 -224
  206. package/dist-standalone/succession.js +1 -142
  207. package/dist-standalone/timeouts.js +1 -398
  208. package/dist-standalone/trace-context.js +1 -414
  209. package/dist-standalone/trace-spans.js +1 -488
  210. package/dist-standalone/transport.js +1 -59
  211. package/dist-standalone/trust-registry.d.ts +3 -3
  212. package/dist-standalone/trust-registry.js +1 -950
  213. package/dist-standalone/types/error-response.js +1 -52
  214. package/dist-standalone/vault-auth.js +1 -174
  215. package/dist-standalone/vault-store-loader.d.ts +9 -0
  216. package/dist-standalone/vault-store-loader.js +1 -187
  217. package/dist-standalone/verify.js +1 -16
  218. package/dist-standalone/version-info.js +1 -530
  219. package/dist-standalone/xfetch.js +1 -335
  220. package/package.json +1 -1
  221. package/share1.dat +0 -0
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.2-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,7 +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.2** — **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.
15
+ **Version 3.0.3** — **Major Features:** LoopbackTransport export for testing (GAP-CORE-2), describeSecurityModeStructured export (GAP-API-3), Agent.quickstart() signature fixes. Full Control IP Protection (PLAN-13) - Vault Store architecture with payment-gated algorithm delivery. Store Front (npm) contains Share 1 only, Vault Store (EC2) contains Share 2 (payment-gated). Runtime crypto loading, 4-layer security (DID auth + usage quotas + rate limiting + audit logging). Usage-based model: Free tier 100K ops/month (includes vault access), Pro tier unlimited. Previous v3.0.2: Full Control IP Protection launch. Previous v1.4.2: Runtime compatibility, API enhancements.
16
16
 
17
17
  ## Install
18
18
 
@@ -50,6 +50,7 @@ For production deployments requiring formal cryptographic assurance, please cont
50
50
 
51
51
  **Dangerous practices that expose your identity:**
52
52
 
53
+ <!-- ANTI-PATTERN -->
53
54
  ```typescript
54
55
  // ❌ WRONG: Plaintext file storage
55
56
  const seed = agent.exportSeeds();
@@ -63,6 +64,7 @@ const agent = await Agent.fromSeed('0123456789abcdef...'); // Visible in reposi
63
64
  // ❌ WRONG: Unencrypted database
64
65
  await db.run('INSERT INTO config VALUES (?, ?)', ['seed', seed]); // SQL injection risk
65
66
  ```
67
+ <!-- /ANTI-PATTERN -->
66
68
 
67
69
  **Why this is critical:**
68
70
  - **Identity Theft**: Attacker gains your DID and can impersonate your agent
@@ -76,6 +78,7 @@ await db.run('INSERT INTO config VALUES (?, ?)', ['seed', seed]); // SQL inject
76
78
 
77
79
  #### macOS: Keychain Services
78
80
 
81
+ <!-- SNIPPET -->
79
82
  ```typescript
80
83
  import { exec } from 'node:child_process';
81
84
  import { promisify } from 'node:util';
@@ -112,9 +115,11 @@ if (!result.ok) {
112
115
 
113
116
  const agent = result.value;
114
117
  ```
118
+ <!-- /SNIPPET -->
115
119
 
116
120
  #### Windows: Credential Manager (DPAPI)
117
121
 
122
+ <!-- SNIPPET -->
118
123
  ```typescript
119
124
  // Using keytar package for cross-platform keychain access
120
125
  import keytar from 'keytar';
@@ -140,9 +145,11 @@ if (!result.ok) {
140
145
 
141
146
  const agent = result.value;
142
147
  ```
148
+ <!-- /SNIPPET -->
143
149
 
144
150
  #### Linux: Secret Service API (gnome-keyring, KWallet)
145
151
 
152
+ <!-- SNIPPET -->
146
153
  ```typescript
147
154
  import keytar from 'keytar';
148
155
 
@@ -167,6 +174,7 @@ if (!result.ok) {
167
174
 
168
175
  const agent = result.value;
169
176
  ```
177
+ <!-- /SNIPPET -->
170
178
 
171
179
  **Cross-platform library:**
172
180
  ```bash
@@ -177,6 +185,7 @@ npm install keytar # Unified API for macOS/Windows/Linux keystores
177
185
 
178
186
  For production deployments with compliance requirements (PCI-DSS, HIPAA, SOC 2):
179
187
 
188
+ <!-- SNIPPET -->
180
189
  ```typescript
181
190
  // Using AWS CloudHSM or Azure Key Vault
182
191
  import { KMSClient, DecryptCommand } from '@aws-sdk/client-kms';
@@ -211,6 +220,7 @@ if (!result.ok) {
211
220
 
212
221
  const agent = result.value;
213
222
  ```
223
+ <!-- /SNIPPET -->
214
224
 
215
225
  **HSM Benefits:**
216
226
  - **FIPS 140-2 Level 3** certified hardware
@@ -343,9 +353,15 @@ See [Configuration Guide](./docs/configuration.md) for complete setup instructio
343
353
 
344
354
  ## Pricing
345
355
 
346
- **Free tier available** No credit card required.
356
+ xBind offers three tiers to fit your needs:
347
357
 
348
- 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.
349
365
 
350
366
  [Subscribe now](https://private.me/subscribe?product=xbind)
351
367
 
@@ -464,8 +480,8 @@ Full fingerprinting source code available at `apps/server/src/device-fingerprint
464
480
  ```typescript
465
481
  import { Agent } from '@private.me/xbind';
466
482
 
467
- // Create agent (auto-generates cryptographic identity)
468
- 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' });
469
485
 
470
486
  // Send authenticated message
471
487
  const result = await agent.send({
@@ -475,7 +491,8 @@ const result = await agent.send({
475
491
  });
476
492
 
477
493
  if (!result.ok) {
478
- console.error(`Failed: ${result.error}`);
494
+ console.error('Send failed:', result.error.code);
495
+ console.error('Details:', result.error.message);
479
496
  return;
480
497
  }
481
498
 
@@ -483,6 +500,29 @@ console.log('Message sent with cryptographic identity');
483
500
  console.log('Agent DID:', agent.did);
484
501
  ```
485
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
+
486
526
  ### Step 3: Understand Your Free Tier
487
527
 
488
528
  - **100,000 operations/month** (free tier)
@@ -493,300 +533,2332 @@ console.log('Agent DID:', agent.did);
493
533
  **At 100K operations:** Email verification enforced (if not already verified)
494
534
  **At 120K operations:** Hard cap reached. Upgrade to Pro for unlimited operations.
495
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
+
496
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.
497
543
 
498
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.
499
545
 
500
546
  [More examples](./docs/examples.md) • [Python examples](./python/README.md)
501
547
 
502
- ## Python SDK
548
+ ## Programmatic Quickstart
503
549
 
504
- Complete Python bindings for agent identity and messaging:
550
+ **Complete, copy-paste ready examples** tested in clean environments:
505
551
 
506
- ```python
507
- from private_me.xbind import Agent
552
+ ### Example 1: Create Agent & Get DID
508
553
 
509
- # Create agent from private key
510
- agent = Agent.from_private_key(private_key_bytes)
554
+ <!-- RUNNABLE-EXAMPLE -->
555
+ ```typescript
556
+ import { Agent } from '@private.me/xbind';
511
557
 
512
- # Make authenticated call
513
- result = agent.call('stripe:createCharge', {
514
- 'amount': 100,
515
- 'currency': 'usd',
516
- 'description': 'AI agent purchase'
517
- })
558
+ // Create agent with automatic identity generation
559
+ const agent = await Agent.quickstart({ name: 'test-agent' });
518
560
 
519
- if result['ok']:
520
- print(f"Charge ID: {result['data']['id']}")
521
- print(f"Agent DID: {result['audit']['agent']}")
522
- else:
523
- print(f"Error: {result['error']['message']}")
561
+ console.log('Agent DID:', agent.did);
562
+ console.log('Agent name:', agent.name);
524
563
  ```
564
+ <!-- /RUNNABLE-EXAMPLE -->
525
565
 
526
- 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
+ ```
527
571
 
528
- ## Why xBind?
572
+ ### Example 2: Agent Identity Details
529
573
 
530
- 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';
531
577
 
532
- ## Getting Started
578
+ // Create agent
579
+ const agent = await Agent.quickstart({ name: 'identity-test' });
533
580
 
534
- **[Guide](../../docs/xbind-integrations/getting-started/index.md)** Concepts, migration
535
- **[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 -->
536
588
 
537
- ## 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
+ ```
538
596
 
539
- **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
540
598
 
541
- ### Core Security
542
- - **Post-quantum cryptography:** ML-KEM-768 key encapsulation, ML-DSA-65 digital signatures (FIPS 203/204)
543
- - **Hybrid key agreement:** X-Wing combiner (IETF draft-10) with 6-parameter domain separation
544
- - **XorIDA split-channel delivery:** Information-theoretic threshold sharing (2-of-2, 2-of-3, 3-of-5)
545
- - **Cryptographic request signing:** Ed25519 signatures prevent DID header forgery
546
- - **Key rotation:** ML-KEM + X25519 rotation with fallback decryption (10 rotation history)
547
- - **Proof-of-Possession:** Ed25519 signature verification prevents DID spoofing
548
- - **Share-aware nonce deduplication:** Prevents replay attacks with composite keys
599
+ <!-- RUNNABLE-EXAMPLE -->
600
+ ```typescript
601
+ import { Agent } from '@private.me/xbind';
549
602
 
550
- ### Runtime Compatibility (4 Platforms)
551
- - **Browser:** WebCrypto API, IndexedDB/localStorage adapters, WASM support, service workers
552
- - **React Native:** AsyncStorage, Buffer polyfills, crypto detection, iOS/Android platform support
553
- - **Edge Runtime:** Cloudflare Workers, Vercel Edge, Deno Deploy, KV storage, <1MB optimization
554
- - **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' });
555
605
 
556
- ### Operations Patterns
557
- - **Health checks:** Startup/liveness/readiness probes, Kubernetes-compatible, Express/Fastify middleware
558
- - **Circuit breakers:** 3-state machine (closed/open/half-open), registry/gateway/S3 presets, automatic recovery
559
- - **Graceful degradation:** QoS tiers, intelligent caching, service health tracking, fallback strategies
560
- - **Performance benchmarks:** Latency histograms with baselines for key ops (ML-KEM, ML-DSA, encryption)
561
- - **Structured logging:** 4 levels (DEBUG/INFO/WARN/ERROR), automatic sensitive data redaction, correlation IDs
562
- - **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 -->
563
612
 
564
- ### Security Audit Preparation
565
- - **STRIDE threat modeling:** 66 threats analyzed across 6 categories
566
- - **Crypto claims documentation:** 41 cryptographic claims documented with evidence
567
- - **Known limitations disclosure:** 24 limitations disclosed for auditor transparency
568
- - **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
+ ```
569
619
 
570
- ### API Enhancements
571
- - **Batch operations:** 6-8x speedup for parallel operations with single network round-trip
572
- - **Async iterators:** `for await...of` syntax support for streaming message processing
573
- - **Plugin/middleware system:** 6-phase lifecycle hooks with 3 built-in plugins
574
- - **Event emitters:** Type-safe events with 5 event types, priority execution, bubbling
575
- - **Cancellation tokens:** AbortController integration with timeout support
576
- - **Progress callbacks:** 4 specialized trackers (operation, transfer, share, encryption)
577
- - **Retry strategies:** 4 strategies (exponential, linear, immediate, jittered) + circuit breaker integration
578
- - **Request timeouts:** Per-operation config with inheritance and cancellation
579
- - **Connection pooling:** 60-70% latency reduction with keep-alive and metrics
580
- - **Serialization formats:** JSON/MessagePack/CBOR support with auto-detection and negotiation
581
- - **Configuration validation:** Comprehensive validation with clear error messages
582
- - **Debug mode:** Performance profiling, network/crypto tracing, state inspection
583
- - **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
584
624
 
585
- ### Developer Experience
586
- - **Type safety:** `Result<T, E>` error handling with 96+ error codes
587
- - **TypeScript strict mode:** Zero type errors, complete type coverage
588
- - **Python SDK:** Complete bindings for identity, messaging, and encryption
589
- - **User-friendly errors:** 75+ errors with actionable recovery hints
590
- - **Complete API docs:** 2,587 lines with 50+ usage examples
591
- - **CHANGELOG generation:** Automated Keep a Changelog format with semver discipline
592
- - **Dependency audit:** Weekly Dependabot scans, 5-layer vulnerability scanning
593
- - **Crypto license compliance:** Automated MIT/MIT-0 validation with GPL/AGPL detection
625
+ [More examples](./docs/examples.md) • [Python examples](./python/README.md)
594
626
 
595
- ### Enterprise Features
596
- - **Version negotiation:** Explicit SDK version fields prevent "404 Route not found" in mixed fleets
597
- - **Multi-device session resume:** AES-256-GCM encrypted session state sync with PBKDF2 (100k iterations)
598
- - **Encrypted backup/restore:** Password-protected identity export with PBKDF2-SHA256 (310k iterations)
599
- - **Offline sync:** Message queueing for offline devices (max 1000 messages, 24-hour TTL)
600
- - **Registry expiration:** TTL support with cleanup (default 7 days)
601
- - **Server-side spending limits:** Redis-backed enforcement with deployment-level aggregation
602
- - **Rate limiting:** Three-tier protection (per-DID, per-IP, global)
603
- - **Full Control IP protection:** Store Front (npm) + Vault Store (EC2) with payment verification
627
+ ## Post-Quantum Cryptography & Envelopes
604
628
 
605
- ### Testing & Quality
606
- - **2,762 tests:** Comprehensive coverage (96.6% passing)
607
- - **End-to-end integration:** Full message flow tests (Agent A → Gateway → Agent B)
608
- - **Gateway concurrency:** 100 concurrent sends, race condition detection
609
- - **Network partition recovery:** Disconnect/reconnect cycles with retry logic
610
- - **PLAN-3 hybrid signatures:** Bilateral authorization with composite verification
629
+ **Complete examples for ML-DSA signatures, key export, and envelope operations:**
630
+
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
+ });
642
+
643
+ // Sign data with ML-DSA-65
644
+ const data = new TextEncoder().encode('Critical transaction data');
645
+ const mlDsaSecretKey = agent.identity.mlDsaSecretKey;
646
+
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:**
671
+
672
+ <!-- RUNNABLE-EXAMPLE -->
673
+ ```typescript
674
+ import { ML_DSA65_SIG_BYTES, ML_DSA65_PK_BYTES, ML_DSA65_SK_BYTES } from '@private.me/xbind';
675
+
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
679
+ ```
680
+ <!-- /RUNNABLE-EXAMPLE -->
681
+
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
689
+
690
+ <!-- RUNNABLE-EXAMPLE -->
691
+ ```typescript
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
+ });
705
+
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');
719
+ ```
720
+ <!-- /RUNNABLE-EXAMPLE -->
721
+
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
+ ```
729
+
730
+ ### Example 6: Key Rotation with Backward Compatibility
731
+
732
+ <!-- RUNNABLE-EXAMPLE -->
733
+ ```typescript
734
+ import { Agent, rotateKeys } from '@private.me/xbind';
735
+
736
+ // Create agent
737
+ const agent = await Agent.quickstart({ name: 'rotation-test' });
738
+
739
+ // Store original X25519 public key
740
+ const originalX25519 = Buffer.from(agent.identity.rawX25519PublicKey).toString('hex');
741
+
742
+ // Rotate encryption keys (X25519 + ML-KEM)
743
+ const rotatedResult = await rotateKeys(agent.identity);
744
+
745
+ if (!rotatedResult.ok) {
746
+ throw new Error(`Key rotation failed: ${rotatedResult.error}`);
747
+ }
748
+
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
+ ```
771
+
772
+ ### Example 7: Create V1 Envelope (Classical Crypto)
773
+
774
+ <!-- RUNNABLE-EXAMPLE -->
775
+ ```typescript
776
+ import { Agent, createEnvelope, generateSharedKey } from '@private.me/xbind';
777
+
778
+ // Generate shared AES-256-GCM key
779
+ const sharedKey = await generateSharedKey();
780
+
781
+ // Create agent
782
+ const agent = await Agent.quickstart({ name: 'envelope-test' });
783
+
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
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) + '...');
808
+ ```
809
+ <!-- /RUNNABLE-EXAMPLE -->
810
+
811
+ **Expected output:**
812
+ ```
813
+ Envelope version: 1
814
+ Algorithm: Ed25519
815
+ Signature length: 88
816
+ Encrypted payload: aGVsbG8gd29ybGQgdGhpcyBpcyBhIHRl...
817
+ ```
818
+
819
+ ### Example 8: Create V2 Envelope (Hybrid KEM)
820
+
821
+ <!-- RUNNABLE-EXAMPLE -->
822
+ ```typescript
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
855
+ });
856
+
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
+ }
862
+ ```
863
+ <!-- /RUNNABLE-EXAMPLE -->
864
+
865
+ **Expected output:**
866
+ ```
867
+ Envelope version: 2
868
+ KEM mode: X25519-MLKEM768
869
+ ML-KEM ciphertext length: 1452
870
+ ```
871
+
872
+ ### Example 9: Create V3 Envelope (Dual Signatures)
873
+
874
+ <!-- RUNNABLE-EXAMPLE -->
875
+ ```typescript
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
883
+ });
884
+
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'
1878
+ });
1879
+
1880
+ // Disable XorIDA (standard encrypted transport)
1881
+ await agent.send({
1882
+ to: recipientDid,
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
+ });
611
2270
 
612
- ## Bundle Size Optimization (Tree-Shaking)
2271
+ const agent = await Agent.create({
2272
+ name: 'enterprise-agent',
2273
+ securityPolicy: customPolicy
2274
+ });
2275
+ ```
613
2276
 
614
- **New in v3.0.2:** 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.
2277
+ **Security Mode Types**
615
2278
 
616
- ### Full Import (Convenience)
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.
617
2284
 
618
2285
  ```typescript
619
- import { Agent, generateIdentity } from '@private.me/xbind';
2286
+ type SecurityMode =
2287
+ | { readonly type: 'standard' }
2288
+ | { readonly type: 'split'; readonly shares: number; readonly threshold: number }
2289
+ | { readonly type: 'xchange' };
2290
+ ```
620
2291
 
621
- // Bundle size: ~450 KB
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
+ }
622
2312
  ```
623
2313
 
624
- ### Granular Import (Optimized)
2314
+ **Usage Example**
625
2315
 
626
2316
  ```typescript
627
- import { Agent } from '@private.me/xbind/agent';
628
- import { generateIdentity } from '@private.me/xbind/identity';
2317
+ import { describeSecurityModeStructured, type SecurityMode } from '@private.me/xbind';
629
2318
 
630
- // Bundle size: ~180 KB (60% reduction)
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"
631
2347
  ```
632
2348
 
633
- ### Available Entry Points
2349
+ **`registry` - Trust Registry Configuration**
634
2350
 
635
- | Entry Point | Exports | Bundle Impact |
636
- |-------------|---------|---------------|
637
- | `@private.me/xbind` | All exports | Full package (~450 KB) |
638
- | `@private.me/xbind/agent` | `Agent`, `AgentOptions` | ~180 KB |
639
- | `@private.me/xbind/identity` | `generateIdentity`, `Identity` | ~120 KB |
640
- | `@private.me/xbind/trust-registry` | Registry classes | ~200 KB |
641
- | `@private.me/xbind/key-agreement` | Key exchange functions | ~90 KB |
642
- | `@private.me/xbind/errors` | Error types | 0 KB (types only) |
2351
+ Configure how agents discover and verify peer identities. Three implementations available.
643
2352
 
644
- **Bundler Support:** Works with webpack 5+, Rollup, esbuild, and Vite. Tree-shaking is automatic in production mode.
2353
+ ```typescript
2354
+ import { Agent, HttpTrustRegistry, FileTrustRegistry, MemoryTrustRegistry } from '@private.me/xbind';
645
2355
 
646
- **See:** [Tree-Shaking Guide](./docs/packaging/tree-shaking.md) for detailed usage and configuration.
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
+ });
647
2362
 
648
- ## Automatic XorIDA Split-Channel Protection
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
+ });
649
2368
 
650
- xBind automatically activates information-theoretic XorIDA threshold sharing for high-risk operations. No code changes required—security is transparent.
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
+ ```
651
2375
 
652
- ### Risk Tags (Recommended for Crypto)
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
653
2380
 
654
- For cryptocurrency transactions (BTC, ETH, etc.), use explicit risk tags in your payload:
2381
+ **`transport` - Multi-Transport Setup**
2382
+
2383
+ Configure message delivery channels. Single transport for simple deployments, multiple transports for redundancy or split-channel security.
655
2384
 
656
2385
  ```typescript
657
- // Low risk: 2-of-2 threshold
658
- await agent.send({
659
- to: recipientDid,
660
- payload: { amount: 0.5, currency: 'BTC', risk: 'low' }
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')
661
2392
  });
662
2393
 
663
- // Medium risk: 2-of-3 threshold
664
- await agent.send({
665
- to: recipientDid,
666
- payload: { amount: 5.0, currency: 'ETH', risk: 'medium' }
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
667
2407
  });
668
2408
 
669
- // High risk: 3-of-5 threshold
670
- await agent.send({
671
- to: recipientDid,
672
- payload: { amount: 50, currency: 'BTC', risk: 'high' }
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
+ ]
673
2417
  });
2418
+ // Each XorIDA share routes to transport[shareIndex % transports.length]
2419
+ // Share 0 → relay1, Share 1 → relay2, Share 2 → relay3
2420
+ ```
674
2421
 
675
- // Critical risk: 3-of-5 threshold
676
- await agent.send({
677
- to: recipientDid,
678
- payload: { amount: 100, currency: 'BTC', risk: 'critical' }
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
679
2435
  });
2436
+
2437
+ // Sends v3 envelopes with hybrid signatures:
2438
+ // - Ed25519 (classical, 128-bit security)
2439
+ // - ML-DSA-65 (post-quantum, NIST Level 3)
680
2440
  ```
681
2441
 
682
- ### Fiat Currency Auto-Detection
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
683
2447
 
684
- For fiat currencies (USD, EUR, GBP), xBind uses numeric thresholds:
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.
685
2458
 
686
2459
  ```typescript
687
- // Automatically triggers 2-of-3 (amount >= $100,000)
688
- await agent.send({
689
- to: recipientDid,
690
- payload: { amount: 500000, currency: 'USD', action: 'transfer' }
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
691
2466
  });
692
2467
 
693
- // Automatically triggers 3-of-5 (amount >= $1,000,000)
694
- await agent.send({
695
- to: recipientDid,
696
- payload: { amount: 2500000, currency: 'USD', action: 'transfer' }
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
+ }
697
2484
  });
698
2485
  ```
699
2486
 
700
- ### Manual Security Override
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
701
2491
 
702
- Override automatic detection with explicit security levels:
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.
703
2497
 
704
2498
  ```typescript
705
- // Force 2-of-3 regardless of amount/risk
706
- await agent.send({
707
- to: recipientDid,
708
- payload: data,
709
- security: 'high'
710
- });
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
+ ```
711
2508
 
712
- // Force 3-of-5 for maximum security
713
- await agent.send({
714
- to: recipientDid,
715
- payload: data,
716
- security: 'critical'
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
717
2527
  });
718
2528
 
719
- // Disable XorIDA (standard encrypted transport)
720
- await agent.send({
2529
+ // Sending with Xchange mode
2530
+ await performanceAgent.send({
721
2531
  to: recipientDid,
722
- payload: data,
723
- security: 'standard'
2532
+ payload: { action: 'transfer', amount: 100 },
2533
+ scope: 'payments'
2534
+ // Automatically uses v4 envelopes (XorIDA split + Ed25519, no KEM)
724
2535
  });
725
2536
  ```
726
2537
 
727
- ### 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)
728
2543
 
729
- | Risk Tag / Threshold | Shares | Required | Security Level |
730
- |---------------------|--------|----------|----------------|
731
- | `low` | 2 | 2 | 2-of-2 threshold |
732
- | `medium` / $100k-$1M | 3 | 2 | 2-of-3 threshold |
733
- | `high` / `critical` / >$1M | 5 | 3 | 3-of-5 threshold |
734
- | 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)
735
2548
 
736
- **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
737
2553
 
738
- ## Billing & Metering
2554
+ **Default: `false`** (prioritize maximum security over performance)
739
2555
 
740
- xBind includes usage-based billing with automated milestone notifications:
2556
+ ## Section 2: Trust & Key Agreement
741
2557
 
742
- - **Free Tier:** Generous monthly limits (no email verification required upfront)
743
- - **Grace Buffer:** Additional operations available after email verification
744
- - **Pro Tier:** Usage-based billing with unlimited operations
745
- - **Monthly Reset:** 1st of each month at 00:00 UTC
2558
+ ### Trust & Key Agreement
746
2559
 
747
- See [pricing](../../docs/pricing-reference.md) for current rates and tier details.
2560
+ **Generate ephemeral X25519 key pair:**
748
2561
 
749
- ### Milestone Notifications
2562
+ <!-- RUNNABLE-EXAMPLE -->
2563
+ ```typescript
2564
+ import { generateEphemeralKeyPair } from '@private.me/xbind';
750
2565
 
751
- 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
+ }
752
2570
 
753
- **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 -->
754
2575
 
755
- **Implementation:**
756
- - Metering logic: `apps/server/src/customer-metering.ts`
757
- - Milestone system: `apps/server/src/usage-milestone-notifications.ts`
758
- - Tier pattern: See `docs/gold-package.md` section 7.6.5
2576
+ **Import X25519 public key:**
759
2577
 
760
- ## Gateway
2578
+ <!-- RUNNABLE-EXAMPLE -->
2579
+ ```typescript
2580
+ import { importX25519PublicKey } from '@private.me/xbind';
761
2581
 
762
- 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);
763
2584
 
764
- ## Connection Models
2585
+ if (!result.ok) {
2586
+ throw new Error(`Import failed: ${result.error}`);
2587
+ }
765
2588
 
766
- 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 -->
767
2592
 
768
- | Model | Security | UX | Best For |
769
- |-------|----------|-----|----------|
770
- | Invite Code | Single-use, 24h TTL | 6-char code | Customer onboarding |
771
- | QR Code | Physical proximity, 60s TTL | Scan & tap | Mobile/desktop pairing |
772
- | Trust Registry | Admin pre-auth, scoped | Zero (automated) | Enterprise/CI/CD |
773
- | Peer Discovery | LAN proximity, user confirm | Scan & confirm | IoT devices, offline |
2593
+ **Derive shared key via ECDH:**
774
2594
 
775
- 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';
776
2598
 
777
- ## Configuration
2599
+ // Generate ephemeral key
2600
+ const ephemeral = await generateEphemeralKeyPair();
2601
+ if (!ephemeral.ok) throw new Error(ephemeral.error);
778
2602
 
779
- ### 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
+ );
780
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 -->
781
2622
  ```typescript
782
- import { HttpTrustRegistry } from '@private.me/xbind';
2623
+ import { senderKeyAgreement, importX25519PublicKey, generateIdentity } from '@private.me/xbind';
783
2624
 
784
- // Documentation example - use your actual gateway URL
785
- const registry = new HttpTrustRegistry({
786
- 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
787
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
+ }
788
2822
  ```
2823
+ <!-- /RUNNABLE-EXAMPLE -->
2824
+
2825
+ ---
789
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**
790
2862
  ### Advanced Features
791
2863
 
792
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).
@@ -795,6 +2867,7 @@ Checkpoints, sequence numbers, subscription proofs, XorIDA configuration, key ba
795
2867
 
796
2868
  xbind returns `Result<T, E>` types for type-safe error handling.
797
2869
 
2870
+ <!-- SNIPPET -->
798
2871
  ```typescript
799
2872
  import { call, type CallResult } from '@private.me/xbind';
800
2873
 
@@ -808,6 +2881,7 @@ if (result.ok) {
808
2881
  console.error(result.error.message);
809
2882
  }
810
2883
  ```
2884
+ <!-- /SNIPPET -->
811
2885
 
812
2886
  Error types: `ConnectionError`, `AuthenticationError`, `ValidationError`, `RateLimitError`, `ServerError`
813
2887
 
@@ -832,6 +2906,48 @@ pnpm test:coverage # Coverage report
832
2906
  pnpm test:watch # Watch mode
833
2907
  ```
834
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
+
835
2951
  ## Full Control IP Protection
836
2952
 
837
2953
  xBind uses **Full Control** (2-share XorIDA) to protect proprietary cryptographic algorithms while maintaining a seamless developer experience.
@@ -864,10 +2980,10 @@ When combined, Share 1 + Share 2 reconstruct the complete XorIDA algorithm at ru
864
2980
  - At 120K ops: 402 Quota Exceeded → Upgrade prompt
865
2981
 
866
2982
  - **Pro Tier:** Unlimited operations
867
- - $5 per 100,000 operations (after first 100K free)
2983
+ - Usage-based billing (after first 100K free)
868
2984
  - No quota checks
869
2985
  - Vault access unlimited
870
- - Example: 400K ops = $15/month (100K free + 300K @ $5/100K)
2986
+ - Example: 400K ops calculated based on current rates (see pricing link)
871
2987
 
872
2988
  - **VIP Tier:** Custom limits per account
873
2989
  - Bronze: 200K, Silver: 500K, Gold: 1M, Platinum: Unlimited
@@ -1023,3 +3139,49 @@ This package contains cryptographic software. Export restrictions may apply. Use
1023
3139
  ---
1024
3140
 
1025
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
+