@private.me/xbind 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (295) hide show
  1. package/AGENTS.md +778 -0
  2. package/LICENSE.md +27 -0
  3. package/README.md +400 -0
  4. package/dist-standalone/_deps/crypto/base64.d.ts +29 -0
  5. package/dist-standalone/_deps/crypto/base64.js +97 -0
  6. package/dist-standalone/_deps/crypto/cjs/base64.js +103 -0
  7. package/dist-standalone/_deps/crypto/cjs/errors.js +119 -0
  8. package/dist-standalone/_deps/crypto/cjs/hmac.js +71 -0
  9. package/dist-standalone/_deps/crypto/cjs/index.js +86 -0
  10. package/dist-standalone/_deps/crypto/cjs/padding.js +57 -0
  11. package/dist-standalone/_deps/crypto/cjs/share-header.js +68 -0
  12. package/dist-standalone/_deps/crypto/cjs/shares.js +152 -0
  13. package/dist-standalone/_deps/crypto/cjs/tlv.js +199 -0
  14. package/dist-standalone/_deps/crypto/cjs/uuid.js +61 -0
  15. package/dist-standalone/_deps/crypto/cjs/verify.js +24 -0
  16. package/dist-standalone/_deps/crypto/cjs/xorida.js +221 -0
  17. package/dist-standalone/_deps/crypto/errors.d.ts +51 -0
  18. package/dist-standalone/_deps/crypto/errors.js +109 -0
  19. package/dist-standalone/_deps/crypto/hmac.d.ts +39 -0
  20. package/dist-standalone/_deps/crypto/hmac.js +66 -0
  21. package/dist-standalone/_deps/crypto/index.d.ts +20 -0
  22. package/dist-standalone/_deps/crypto/index.js +45 -0
  23. package/dist-standalone/_deps/crypto/padding.d.ts +19 -0
  24. package/dist-standalone/_deps/crypto/padding.js +53 -0
  25. package/dist-standalone/_deps/crypto/share-header.d.ts +44 -0
  26. package/dist-standalone/_deps/crypto/share-header.js +63 -0
  27. package/dist-standalone/_deps/crypto/shares.d.ts +27 -0
  28. package/dist-standalone/_deps/crypto/shares.js +148 -0
  29. package/dist-standalone/_deps/crypto/tlv.d.ts +26 -0
  30. package/dist-standalone/_deps/crypto/tlv.js +195 -0
  31. package/dist-standalone/_deps/crypto/uuid.d.ts +22 -0
  32. package/dist-standalone/_deps/crypto/uuid.js +56 -0
  33. package/dist-standalone/_deps/crypto/verify.d.ts +15 -0
  34. package/dist-standalone/_deps/crypto/verify.js +15 -0
  35. package/dist-standalone/_deps/crypto/xorida.d.ts +44 -0
  36. package/dist-standalone/_deps/crypto/xorida.js +215 -0
  37. package/dist-standalone/_deps/mldsa-wasm/LICENSE +24 -0
  38. package/dist-standalone/_deps/mldsa-wasm/dist/mldsa.js +1920 -0
  39. package/dist-standalone/_deps/mldsa-wasm/package.json +46 -0
  40. package/dist-standalone/_deps/mldsa-wasm/types/mldsa.d.ts +30 -0
  41. package/dist-standalone/_deps/shared/cjs/errors.js +582 -0
  42. package/dist-standalone/_deps/shared/cjs/index.js +492 -0
  43. package/dist-standalone/_deps/shared/cjs/package.json +1 -0
  44. package/dist-standalone/_deps/shared/cjs/types.js +403 -0
  45. package/dist-standalone/_deps/shared/errors.d.ts +48 -0
  46. package/dist-standalone/_deps/shared/errors.d.ts.map +1 -0
  47. package/dist-standalone/_deps/shared/errors.js +192 -0
  48. package/dist-standalone/_deps/shared/errors.js.map +1 -0
  49. package/dist-standalone/_deps/shared/index.d.ts +4 -0
  50. package/dist-standalone/_deps/shared/index.d.ts.map +1 -0
  51. package/dist-standalone/_deps/shared/index.js +78 -0
  52. package/dist-standalone/_deps/shared/index.js.map +1 -0
  53. package/dist-standalone/_deps/shared/types.d.ts +1097 -0
  54. package/dist-standalone/_deps/shared/types.d.ts.map +1 -0
  55. package/dist-standalone/_deps/shared/types.js +89 -0
  56. package/dist-standalone/_deps/shared/types.js.map +1 -0
  57. package/dist-standalone/_deps/ux-helpers/cjs/errors.d.ts +115 -0
  58. package/dist-standalone/_deps/ux-helpers/cjs/errors.d.ts.map +1 -0
  59. package/dist-standalone/_deps/ux-helpers/cjs/errors.js +1 -0
  60. package/dist-standalone/_deps/ux-helpers/cjs/errors.js.map +1 -0
  61. package/dist-standalone/_deps/ux-helpers/cjs/index.d.ts +13 -0
  62. package/dist-standalone/_deps/ux-helpers/cjs/index.d.ts.map +1 -0
  63. package/dist-standalone/_deps/ux-helpers/cjs/index.js +1 -0
  64. package/dist-standalone/_deps/ux-helpers/cjs/index.js.map +1 -0
  65. package/dist-standalone/_deps/ux-helpers/cjs/package.json +1 -0
  66. package/dist-standalone/_deps/ux-helpers/cjs/pagination.d.ts +39 -0
  67. package/dist-standalone/_deps/ux-helpers/cjs/pagination.d.ts.map +1 -0
  68. package/dist-standalone/_deps/ux-helpers/cjs/pagination.js +83 -0
  69. package/dist-standalone/_deps/ux-helpers/cjs/pagination.js.map +1 -0
  70. package/dist-standalone/_deps/ux-helpers/cjs/progress.d.ts +99 -0
  71. package/dist-standalone/_deps/ux-helpers/cjs/progress.d.ts.map +1 -0
  72. package/dist-standalone/_deps/ux-helpers/cjs/progress.js +143 -0
  73. package/dist-standalone/_deps/ux-helpers/cjs/progress.js.map +1 -0
  74. package/dist-standalone/_deps/ux-helpers/cjs/search.d.ts +32 -0
  75. package/dist-standalone/_deps/ux-helpers/cjs/search.d.ts.map +1 -0
  76. package/dist-standalone/_deps/ux-helpers/cjs/search.js +119 -0
  77. package/dist-standalone/_deps/ux-helpers/cjs/search.js.map +1 -0
  78. package/dist-standalone/_deps/ux-helpers/cjs/types.d.ts +109 -0
  79. package/dist-standalone/_deps/ux-helpers/cjs/types.d.ts.map +1 -0
  80. package/dist-standalone/_deps/ux-helpers/cjs/types.js +8 -0
  81. package/dist-standalone/_deps/ux-helpers/cjs/types.js.map +1 -0
  82. package/dist-standalone/_deps/ux-helpers/errors.d.ts +115 -0
  83. package/dist-standalone/_deps/ux-helpers/errors.d.ts.map +1 -0
  84. package/dist-standalone/_deps/ux-helpers/errors.js +253 -0
  85. package/dist-standalone/_deps/ux-helpers/errors.js.map +1 -0
  86. package/dist-standalone/_deps/ux-helpers/index.d.ts +13 -0
  87. package/dist-standalone/_deps/ux-helpers/index.d.ts.map +1 -0
  88. package/dist-standalone/_deps/ux-helpers/index.js +16 -0
  89. package/dist-standalone/_deps/ux-helpers/index.js.map +1 -0
  90. package/dist-standalone/_deps/ux-helpers/pagination.d.ts +39 -0
  91. package/dist-standalone/_deps/ux-helpers/pagination.d.ts.map +1 -0
  92. package/dist-standalone/_deps/ux-helpers/pagination.js +79 -0
  93. package/dist-standalone/_deps/ux-helpers/pagination.js.map +1 -0
  94. package/dist-standalone/_deps/ux-helpers/progress.d.ts +99 -0
  95. package/dist-standalone/_deps/ux-helpers/progress.d.ts.map +1 -0
  96. package/dist-standalone/_deps/ux-helpers/progress.js +138 -0
  97. package/dist-standalone/_deps/ux-helpers/progress.js.map +1 -0
  98. package/dist-standalone/_deps/ux-helpers/search.d.ts +32 -0
  99. package/dist-standalone/_deps/ux-helpers/search.d.ts.map +1 -0
  100. package/dist-standalone/_deps/ux-helpers/search.js +116 -0
  101. package/dist-standalone/_deps/ux-helpers/search.js.map +1 -0
  102. package/dist-standalone/_deps/ux-helpers/types.d.ts +109 -0
  103. package/dist-standalone/_deps/ux-helpers/types.d.ts.map +1 -0
  104. package/dist-standalone/_deps/ux-helpers/types.js +7 -0
  105. package/dist-standalone/_deps/ux-helpers/types.js.map +1 -0
  106. package/dist-standalone/_deps/xchange/auto-accept.d.ts +127 -0
  107. package/dist-standalone/_deps/xchange/auto-accept.js +1 -0
  108. package/dist-standalone/_deps/xchange/cjs/auto-accept.js +1 -0
  109. package/dist-standalone/_deps/xchange/cjs/errors.js +1 -0
  110. package/dist-standalone/_deps/xchange/cjs/index.js +1 -0
  111. package/dist-standalone/_deps/xchange/cjs/invite-client.js +1 -0
  112. package/dist-standalone/_deps/xchange/cjs/lazy-init.js +1 -0
  113. package/dist-standalone/_deps/xchange/cjs/package.json +1 -0
  114. package/dist-standalone/_deps/xchange/cjs/trust-integration.js +1 -0
  115. package/dist-standalone/_deps/xchange/cjs/xchange.js +1 -0
  116. package/dist-standalone/_deps/xchange/errors.d.ts +69 -0
  117. package/dist-standalone/_deps/xchange/errors.js +1 -0
  118. package/dist-standalone/_deps/xchange/index.d.ts +15 -0
  119. package/dist-standalone/_deps/xchange/index.js +1 -0
  120. package/dist-standalone/_deps/xchange/invite-client.d.ts +178 -0
  121. package/dist-standalone/_deps/xchange/invite-client.js +1 -0
  122. package/dist-standalone/_deps/xchange/lazy-init.d.ts +176 -0
  123. package/dist-standalone/_deps/xchange/lazy-init.js +1 -0
  124. package/dist-standalone/_deps/xchange/trust-integration.d.ts +102 -0
  125. package/dist-standalone/_deps/xchange/trust-integration.js +1 -0
  126. package/dist-standalone/_deps/xchange/xchange.d.ts +60 -0
  127. package/dist-standalone/_deps/xchange/xchange.js +1 -0
  128. package/dist-standalone/_deps/xregistry/cjs/discovery.js +1 -0
  129. package/dist-standalone/_deps/xregistry/cjs/errors.js +1 -0
  130. package/dist-standalone/_deps/xregistry/cjs/index.js +1 -0
  131. package/dist-standalone/_deps/xregistry/cjs/package.json +1 -0
  132. package/dist-standalone/_deps/xregistry/cjs/registry.js +1 -0
  133. package/dist-standalone/_deps/xregistry/cjs/schema.js +1 -0
  134. package/dist-standalone/_deps/xregistry/cjs/types.js +1 -0
  135. package/dist-standalone/_deps/xregistry/discovery.d.ts +126 -0
  136. package/dist-standalone/_deps/xregistry/discovery.d.ts.map +1 -0
  137. package/dist-standalone/_deps/xregistry/discovery.js +1 -0
  138. package/dist-standalone/_deps/xregistry/discovery.js.map +1 -0
  139. package/dist-standalone/_deps/xregistry/errors.d.ts +41 -0
  140. package/dist-standalone/_deps/xregistry/errors.d.ts.map +1 -0
  141. package/dist-standalone/_deps/xregistry/errors.js +1 -0
  142. package/dist-standalone/_deps/xregistry/errors.js.map +1 -0
  143. package/dist-standalone/_deps/xregistry/index.d.ts +8 -0
  144. package/dist-standalone/_deps/xregistry/index.d.ts.map +1 -0
  145. package/dist-standalone/_deps/xregistry/index.js +1 -0
  146. package/dist-standalone/_deps/xregistry/index.js.map +1 -0
  147. package/dist-standalone/_deps/xregistry/registry.d.ts +85 -0
  148. package/dist-standalone/_deps/xregistry/registry.d.ts.map +1 -0
  149. package/dist-standalone/_deps/xregistry/registry.js +1 -0
  150. package/dist-standalone/_deps/xregistry/registry.js.map +1 -0
  151. package/dist-standalone/_deps/xregistry/schema.d.ts +81 -0
  152. package/dist-standalone/_deps/xregistry/schema.d.ts.map +1 -0
  153. package/dist-standalone/_deps/xregistry/schema.js +1 -0
  154. package/dist-standalone/_deps/xregistry/schema.js.map +1 -0
  155. package/dist-standalone/_deps/xregistry/types.d.ts +95 -0
  156. package/dist-standalone/_deps/xregistry/types.d.ts.map +1 -0
  157. package/dist-standalone/_deps/xregistry/types.js +1 -0
  158. package/dist-standalone/_deps/xregistry/types.js.map +1 -0
  159. package/dist-standalone/agent-call.d.ts +286 -0
  160. package/dist-standalone/agent-call.js +642 -0
  161. package/dist-standalone/agent-sdk.d.ts +207 -0
  162. package/dist-standalone/agent-sdk.js +328 -0
  163. package/dist-standalone/agent.d.ts +670 -0
  164. package/dist-standalone/agent.js +1529 -0
  165. package/dist-standalone/approval.d.ts +145 -0
  166. package/dist-standalone/approval.js +193 -0
  167. package/dist-standalone/auth.d.ts +75 -0
  168. package/dist-standalone/auth.js +219 -0
  169. package/dist-standalone/auto-accept.d.ts +102 -0
  170. package/dist-standalone/auto-accept.js +229 -0
  171. package/dist-standalone/backup-config.d.ts +150 -0
  172. package/dist-standalone/backup-config.js +201 -0
  173. package/dist-standalone/checkpoint.d.ts +125 -0
  174. package/dist-standalone/checkpoint.js +186 -0
  175. package/dist-standalone/cjs/agent-call.js +651 -0
  176. package/dist-standalone/cjs/agent-sdk.js +332 -0
  177. package/dist-standalone/cjs/agent.js +1566 -0
  178. package/dist-standalone/cjs/approval.js +199 -0
  179. package/dist-standalone/cjs/auth.js +225 -0
  180. package/dist-standalone/cjs/auto-accept.js +233 -0
  181. package/dist-standalone/cjs/backup-config.js +207 -0
  182. package/dist-standalone/cjs/checkpoint.js +193 -0
  183. package/dist-standalone/cjs/cli/init.js +487 -0
  184. package/dist-standalone/cjs/connect.js +312 -0
  185. package/dist-standalone/cjs/did-document.js +101 -0
  186. package/dist-standalone/cjs/did-privateme.js +130 -0
  187. package/dist-standalone/cjs/did-web.js +201 -0
  188. package/dist-standalone/cjs/discovery.js +462 -0
  189. package/dist-standalone/cjs/dual-mode.js +251 -0
  190. package/dist-standalone/cjs/email-templates.js +313 -0
  191. package/dist-standalone/cjs/email-transport.js +239 -0
  192. package/dist-standalone/cjs/envelope.js +510 -0
  193. package/dist-standalone/cjs/errors.js +562 -0
  194. package/dist-standalone/cjs/gateway-state.js +55 -0
  195. package/dist-standalone/cjs/gateway-transport.js +120 -0
  196. package/dist-standalone/cjs/guardrails.js +223 -0
  197. package/dist-standalone/cjs/http-compat.js +272 -0
  198. package/dist-standalone/cjs/identity.js +541 -0
  199. package/dist-standalone/cjs/index.js +224 -0
  200. package/dist-standalone/cjs/invitation.js +421 -0
  201. package/dist-standalone/cjs/invite.js +328 -0
  202. package/dist-standalone/cjs/key-agreement.js +246 -0
  203. package/dist-standalone/cjs/lazy-init.js +300 -0
  204. package/dist-standalone/cjs/mdns-discovery.js +202 -0
  205. package/dist-standalone/cjs/nonce-store.js +66 -0
  206. package/dist-standalone/cjs/package.json +3 -0
  207. package/dist-standalone/cjs/pairing-manager.js +223 -0
  208. package/dist-standalone/cjs/policy.js +320 -0
  209. package/dist-standalone/cjs/redis-nonce-store.js +76 -0
  210. package/dist-standalone/cjs/registry-middleware.js +50 -0
  211. package/dist-standalone/cjs/retry-transport.js +102 -0
  212. package/dist-standalone/cjs/security-policy.js +204 -0
  213. package/dist-standalone/cjs/split-channel.js +177 -0
  214. package/dist-standalone/cjs/subscription-proof.js +230 -0
  215. package/dist-standalone/cjs/succession.js +148 -0
  216. package/dist-standalone/cjs/transport.js +63 -0
  217. package/dist-standalone/cjs/trust-registry.js +742 -0
  218. package/dist-standalone/cjs/verify.js +25 -0
  219. package/dist-standalone/cjs/xfetch.js +252 -0
  220. package/dist-standalone/cli/init.d.ts +63 -0
  221. package/dist-standalone/cli/init.js +450 -0
  222. package/dist-standalone/connect.d.ts +143 -0
  223. package/dist-standalone/connect.js +274 -0
  224. package/dist-standalone/did-document.d.ts +65 -0
  225. package/dist-standalone/did-document.js +96 -0
  226. package/dist-standalone/did-privateme.d.ts +70 -0
  227. package/dist-standalone/did-privateme.js +121 -0
  228. package/dist-standalone/did-web.d.ts +73 -0
  229. package/dist-standalone/did-web.js +196 -0
  230. package/dist-standalone/discovery.d.ts +176 -0
  231. package/dist-standalone/discovery.js +458 -0
  232. package/dist-standalone/dual-mode.d.ts +145 -0
  233. package/dist-standalone/dual-mode.js +247 -0
  234. package/dist-standalone/email-templates.d.ts +41 -0
  235. package/dist-standalone/email-templates.js +309 -0
  236. package/dist-standalone/email-transport.d.ts +139 -0
  237. package/dist-standalone/email-transport.js +232 -0
  238. package/dist-standalone/envelope.d.ts +288 -0
  239. package/dist-standalone/envelope.js +497 -0
  240. package/dist-standalone/errors.d.ts +74 -0
  241. package/dist-standalone/errors.js +548 -0
  242. package/dist-standalone/gateway-state.d.ts +32 -0
  243. package/dist-standalone/gateway-state.js +51 -0
  244. package/dist-standalone/gateway-transport.d.ts +59 -0
  245. package/dist-standalone/gateway-transport.js +116 -0
  246. package/dist-standalone/guardrails.d.ts +136 -0
  247. package/dist-standalone/guardrails.js +216 -0
  248. package/dist-standalone/http-compat.d.ts +150 -0
  249. package/dist-standalone/http-compat.js +267 -0
  250. package/dist-standalone/identity.d.ts +176 -0
  251. package/dist-standalone/identity.js +516 -0
  252. package/dist-standalone/index.d.ts +83 -0
  253. package/dist-standalone/index.js +51 -0
  254. package/dist-standalone/invitation.d.ts +211 -0
  255. package/dist-standalone/invitation.js +415 -0
  256. package/dist-standalone/invite.d.ts +192 -0
  257. package/dist-standalone/invite.js +324 -0
  258. package/dist-standalone/key-agreement.d.ts +122 -0
  259. package/dist-standalone/key-agreement.js +236 -0
  260. package/dist-standalone/lazy-init.d.ts +167 -0
  261. package/dist-standalone/lazy-init.js +295 -0
  262. package/dist-standalone/mdns-discovery.d.ts +117 -0
  263. package/dist-standalone/mdns-discovery.js +195 -0
  264. package/dist-standalone/nonce-store.d.ts +39 -0
  265. package/dist-standalone/nonce-store.js +62 -0
  266. package/dist-standalone/package.json +11 -0
  267. package/dist-standalone/pairing-manager.d.ts +147 -0
  268. package/dist-standalone/pairing-manager.js +219 -0
  269. package/dist-standalone/policy.d.ts +150 -0
  270. package/dist-standalone/policy.js +315 -0
  271. package/dist-standalone/redis-nonce-store.d.ts +93 -0
  272. package/dist-standalone/redis-nonce-store.js +72 -0
  273. package/dist-standalone/registry-middleware.d.ts +38 -0
  274. package/dist-standalone/registry-middleware.js +47 -0
  275. package/dist-standalone/retry-transport.d.ts +76 -0
  276. package/dist-standalone/retry-transport.js +98 -0
  277. package/dist-standalone/security-policy.d.ts +146 -0
  278. package/dist-standalone/security-policy.js +198 -0
  279. package/dist-standalone/split-channel.d.ts +69 -0
  280. package/dist-standalone/split-channel.js +171 -0
  281. package/dist-standalone/subscription-proof.d.ts +103 -0
  282. package/dist-standalone/subscription-proof.js +224 -0
  283. package/dist-standalone/succession.d.ts +57 -0
  284. package/dist-standalone/succession.js +142 -0
  285. package/dist-standalone/transport.d.ts +50 -0
  286. package/dist-standalone/transport.js +59 -0
  287. package/dist-standalone/trust-registry.d.ts +286 -0
  288. package/dist-standalone/trust-registry.js +702 -0
  289. package/dist-standalone/verify.d.ts +16 -0
  290. package/dist-standalone/verify.js +16 -0
  291. package/dist-standalone/xfetch.d.ts +129 -0
  292. package/dist-standalone/xfetch.js +247 -0
  293. package/llms.txt +800 -0
  294. package/package.json +79 -0
  295. package/share1.dat +0 -0
@@ -0,0 +1,224 @@
1
+ import { ok, err } from"./_deps/shared/index.js";
2
+ import { signMlDsa65, verifyMlDsa65, ML_DSA65_SIG_BYTES } from './identity.js';
3
+ /* ── Internal Helpers ── */
4
+ /**
5
+ * Compute SHA-256 hash of a Uint8Array.
6
+ *
7
+ * @param data - Data to hash.
8
+ * @returns Hex-encoded SHA-256 hash.
9
+ */
10
+ async function sha256Hash(data) {
11
+ try {
12
+ // SAFETY: Creating fresh copy ensures proper ArrayBuffer type (not SharedArrayBuffer)
13
+ const buffer = new Uint8Array(data);
14
+ const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
15
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
16
+ const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
17
+ return ok(hashHex);
18
+ }
19
+ catch {
20
+ return err('HASH_FAILED');
21
+ }
22
+ }
23
+ /**
24
+ * Serialize subscription proof data for signing (canonical format).
25
+ *
26
+ * Format: type|version|peer_did|bloom_filter_hash|asserted_at|expires_at
27
+ *
28
+ * @param proof - Subscription proof (without signature).
29
+ * @returns Canonical byte representation.
30
+ */
31
+ function serializeForSigning(proof) {
32
+ const canonical = `${proof.type}|${proof.version}|${proof.peer_did}|${proof.bloom_filter_hash}|${proof.asserted_at}|${proof.expires_at}`;
33
+ return new TextEncoder().encode(canonical);
34
+ }
35
+ /**
36
+ * Base64 encode (standard, not URL-safe).
37
+ */
38
+ function toBase64(data) {
39
+ // Use Buffer in Node.js, btoa in browser
40
+ if (typeof Buffer !== 'undefined') {
41
+ return Buffer.from(data).toString('base64');
42
+ }
43
+ // SAFETY: btoa is standard in browsers
44
+ return globalThis.btoa(String.fromCharCode(...data));
45
+ }
46
+ /**
47
+ * Base64 decode (standard, not URL-safe).
48
+ */
49
+ function fromBase64(data) {
50
+ // Use Buffer in Node.js, atob in browser
51
+ if (typeof Buffer !== 'undefined') {
52
+ return new Uint8Array(Buffer.from(data, 'base64'));
53
+ }
54
+ // SAFETY: atob is standard in browsers
55
+ const binary = globalThis.atob(data);
56
+ const bytes = new Uint8Array(binary.length);
57
+ for (let i = 0; i < binary.length; i++) {
58
+ bytes[i] = binary.charCodeAt(i);
59
+ }
60
+ return bytes;
61
+ }
62
+ /* ── Public API ── */
63
+ /**
64
+ * Create a subscription proof (client-side).
65
+ *
66
+ * Signs a bloom filter hash with the peer's ML-DSA-65 private key, creating
67
+ * a portable proof that can be used to resume subscriptions on a new gateway.
68
+ *
69
+ * @param peerDid - Subscriber's DID (must match the private key).
70
+ * @param bloomFilterHash - SHA-256 hash of the bloom filter (hex string).
71
+ * @param privateKey - 32-byte ML-DSA-65 secret key seed.
72
+ * @param expiresAt - Optional expiration timestamp (ms). Default: 30 days from now.
73
+ * @returns Subscription proof with ML-DSA-65 signature.
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * const proof = await createSubscriptionProof(
78
+ * 'did:key:z6Mk...',
79
+ * 'a1b2c3...',
80
+ * mlDsaPrivateKey,
81
+ * Date.now() + 30 * 24 * 60 * 60 * 1000
82
+ * );
83
+ * ```
84
+ */
85
+ export async function createSubscriptionProof(peerDid, bloomFilterHash, privateKey, expiresAt) {
86
+ const assertedAt = Date.now();
87
+ const expiresAtFinal = expiresAt ?? (assertedAt + 30 * 24 * 60 * 60 * 1000); // 30 days default
88
+ // Build proof without signature
89
+ const proofWithoutSig = {
90
+ type: 'SubscriptionProof',
91
+ version: '1.0',
92
+ peer_did: peerDid,
93
+ bloom_filter_hash: bloomFilterHash,
94
+ asserted_at: assertedAt,
95
+ expires_at: expiresAtFinal,
96
+ };
97
+ // Serialize and sign
98
+ const dataToSign = serializeForSigning(proofWithoutSig);
99
+ const signatureResult = await signMlDsa65(privateKey, dataToSign);
100
+ if (!signatureResult.ok) {
101
+ return err('SIGNATURE_VERIFICATION_FAILED');
102
+ }
103
+ const signature = signatureResult.value;
104
+ if (signature.length !== ML_DSA65_SIG_BYTES) {
105
+ return err('SIGNATURE_VERIFICATION_FAILED');
106
+ }
107
+ // Build final proof
108
+ const proof = {
109
+ ...proofWithoutSig,
110
+ peer_signature_algorithm: 'ML-DSA-65',
111
+ peer_signature: toBase64(signature),
112
+ };
113
+ return ok(proof);
114
+ }
115
+ /**
116
+ * Verify a subscription proof (gateway-side).
117
+ *
118
+ * Validates the ML-DSA-65 signature and checks expiration.
119
+ *
120
+ * @param proof - Subscription proof to verify.
121
+ * @param peerPublicKey - 1952-byte ML-DSA-65 public key of the subscriber.
122
+ * @returns true if valid, false if invalid or expired.
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * const isValid = await verifySubscriptionProof(proof, mlDsaPublicKey);
127
+ * if (isValid.ok && isValid.value) {
128
+ * // Resume subscription
129
+ * }
130
+ * ```
131
+ */
132
+ export async function verifySubscriptionProof(proof, peerPublicKey) {
133
+ // Check proof version
134
+ if (proof.version !== '1.0' || proof.type !== 'SubscriptionProof') {
135
+ return ok(false);
136
+ }
137
+ // Check expiration
138
+ if (Date.now() > proof.expires_at) {
139
+ return err('EXPIRED');
140
+ }
141
+ // Check signature algorithm
142
+ if (proof.peer_signature_algorithm !== 'ML-DSA-65') {
143
+ return ok(false);
144
+ }
145
+ // Decode signature
146
+ let signature;
147
+ try {
148
+ signature = fromBase64(proof.peer_signature);
149
+ }
150
+ catch {
151
+ return ok(false);
152
+ }
153
+ if (signature.length !== ML_DSA65_SIG_BYTES) {
154
+ return ok(false);
155
+ }
156
+ // Reconstruct signed data
157
+ const proofWithoutSig = {
158
+ type: proof.type,
159
+ version: proof.version,
160
+ peer_did: proof.peer_did,
161
+ bloom_filter_hash: proof.bloom_filter_hash,
162
+ asserted_at: proof.asserted_at,
163
+ expires_at: proof.expires_at,
164
+ };
165
+ const dataToVerify = serializeForSigning(proofWithoutSig);
166
+ // Verify signature
167
+ const verifyResult = await verifyMlDsa65(peerPublicKey, signature, dataToVerify);
168
+ if (!verifyResult.ok) {
169
+ return err('SIGNATURE_VERIFICATION_FAILED');
170
+ }
171
+ return ok(verifyResult.value);
172
+ }
173
+ /**
174
+ * Resume subscription on a new gateway using a proof.
175
+ *
176
+ * Presents the subscription proof to the new gateway, allowing the client
177
+ * to resume receiving trust events without re-subscribing.
178
+ *
179
+ * @param proof - Valid subscription proof.
180
+ * @param newGatewayUrl - Base URL of the new gateway (e.g., https://atelier2.xail.io).
181
+ * @returns Success or network error.
182
+ *
183
+ * @example
184
+ * ```typescript
185
+ * const result = await resumeSubscription(proof, 'https://atelier2.xail.io');
186
+ * if (result.ok) {
187
+ * console.log('Subscription resumed on new gateway');
188
+ * }
189
+ * ```
190
+ */
191
+ export async function resumeSubscription(proof, newGatewayUrl) {
192
+ try {
193
+ const baseUrl = newGatewayUrl.replace(/\/$/, '');
194
+ const response = await fetch(`${baseUrl}/trust/resume`, {
195
+ method: 'POST',
196
+ headers: { 'Content-Type': 'application/json' },
197
+ body: JSON.stringify(proof),
198
+ });
199
+ if (!response.ok) {
200
+ return err('NETWORK_ERROR');
201
+ }
202
+ return ok(undefined);
203
+ }
204
+ catch {
205
+ return err('NETWORK_ERROR');
206
+ }
207
+ }
208
+ /**
209
+ * Compute SHA-256 hash of a bloom filter for proof creation.
210
+ *
211
+ * @param bloomFilter - Bloom filter bytes.
212
+ * @returns Hex-encoded SHA-256 hash.
213
+ *
214
+ * @example
215
+ * ```typescript
216
+ * const hash = await hashBloomFilter(bloomFilterBytes);
217
+ * if (hash.ok) {
218
+ * const proof = await createSubscriptionProof(did, hash.value, privateKey);
219
+ * }
220
+ * ```
221
+ */
222
+ export async function hashBloomFilter(bloomFilter) {
223
+ return sha256Hash(bloomFilter);
224
+ }
@@ -0,0 +1,57 @@
1
+ import type { Result } from '@private.me/shared';
2
+ /** Error codes for succession operations. */
3
+ export type SuccessionError = 'SIGN_FAILED' | 'VERIFY_FAILED' | 'INVALID_FORMAT' | 'INVALID_TIMESTAMP' | 'SEQUENCE_ROLLBACK' | 'FORK_DETECTED';
4
+ export interface SuccessionAnnouncement {
5
+ oldDid: string;
6
+ newDid: string;
7
+ rotation_sequence: number;
8
+ effective_at: number;
9
+ expires_at: number;
10
+ grace_period_ms: number;
11
+ timestamp: number;
12
+ oldSignature: Uint8Array;
13
+ newSignature: Uint8Array;
14
+ }
15
+ /**
16
+ * Create DID succession announcement with dual signatures.
17
+ *
18
+ * Format: did:key:OLD||did:key:NEW||sequence||effective_at||expires_at||grace_period||timestamp||sig_OLD||sig_NEW
19
+ * Both old and new keys must sign to prove possession.
20
+ *
21
+ * @param oldDid - DID being rotated (old key)
22
+ * @param oldPrivateKey - ML-DSA-65 secret key (32-byte seed) for old DID
23
+ * @param newDid - DID replacing old DID
24
+ * @param newPrivateKey - ML-DSA-65 secret key (32-byte seed) for new DID
25
+ * @param rotationSequence - Monotonically increasing sequence number
26
+ * @param gracePeriodMs - Overlap window in milliseconds (default: 7 days)
27
+ * @returns Succession announcement with dual signatures or error
28
+ */
29
+ export declare function createSuccession(oldDid: string, oldPrivateKey: Uint8Array, newDid: string, newPrivateKey: Uint8Array, rotationSequence: number, gracePeriodMs?: number): Promise<Result<SuccessionAnnouncement, SuccessionError>>;
30
+ /**
31
+ * Verify succession announcement dual signatures.
32
+ *
33
+ * Both old and new keys must have valid signatures.
34
+ * Also checks sequence monotonicity (new sequence must be greater than current).
35
+ *
36
+ * @param announcement - Succession announcement to verify
37
+ * @param oldPublicKey - ML-DSA-65 public key (1952 bytes) for old DID
38
+ * @param newPublicKey - ML-DSA-65 public key (1952 bytes) for new DID
39
+ * @returns true if both signatures valid, false otherwise
40
+ */
41
+ export declare function verifySuccession(announcement: SuccessionAnnouncement, oldPublicKey: Uint8Array, newPublicKey: Uint8Array): Promise<Result<boolean, SuccessionError>>;
42
+ /**
43
+ * Encode succession announcement to wire format.
44
+ *
45
+ * Format: did:key:OLD||did:key:NEW||sequence||effective_at||expires_at||grace_period||timestamp||sig_OLD||sig_NEW
46
+ *
47
+ * @param announcement - Succession announcement to encode
48
+ * @returns Wire format string (base64-encoded signatures)
49
+ */
50
+ export declare function encodeSuccession(announcement: SuccessionAnnouncement): string;
51
+ /**
52
+ * Decode succession announcement from wire format.
53
+ *
54
+ * @param encoded - Wire format string
55
+ * @returns Parsed succession announcement or error
56
+ */
57
+ export declare function decodeSuccession(encoded: string): Result<SuccessionAnnouncement, SuccessionError>;
@@ -0,0 +1,142 @@
1
+ import { signMlDsa65, verifyMlDsa65 } from './identity.js';
2
+ import { ok, err } from"./_deps/shared/index.js";
3
+ /**
4
+ * Create DID succession announcement with dual signatures.
5
+ *
6
+ * Format: did:key:OLD||did:key:NEW||sequence||effective_at||expires_at||grace_period||timestamp||sig_OLD||sig_NEW
7
+ * Both old and new keys must sign to prove possession.
8
+ *
9
+ * @param oldDid - DID being rotated (old key)
10
+ * @param oldPrivateKey - ML-DSA-65 secret key (32-byte seed) for old DID
11
+ * @param newDid - DID replacing old DID
12
+ * @param newPrivateKey - ML-DSA-65 secret key (32-byte seed) for new DID
13
+ * @param rotationSequence - Monotonically increasing sequence number
14
+ * @param gracePeriodMs - Overlap window in milliseconds (default: 7 days)
15
+ * @returns Succession announcement with dual signatures or error
16
+ */
17
+ export async function createSuccession(oldDid, oldPrivateKey, newDid, newPrivateKey, rotationSequence, gracePeriodMs = 7 * 24 * 60 * 60 * 1000 // 7 days default
18
+ ) {
19
+ const timestamp = Date.now();
20
+ const effective_at = timestamp;
21
+ const expires_at = timestamp + 30 * 24 * 60 * 60 * 1000; // 30 days proof validity
22
+ const message = `${oldDid}||${newDid}||${rotationSequence}||${effective_at}||${expires_at}||${gracePeriodMs}||${timestamp}`;
23
+ const messageBytes = new TextEncoder().encode(message);
24
+ const oldSigResult = await signMlDsa65(oldPrivateKey, messageBytes);
25
+ if (!oldSigResult.ok) {
26
+ return err('SIGN_FAILED');
27
+ }
28
+ const newSigResult = await signMlDsa65(newPrivateKey, messageBytes);
29
+ if (!newSigResult.ok) {
30
+ return err('SIGN_FAILED');
31
+ }
32
+ return ok({
33
+ oldDid,
34
+ newDid,
35
+ rotation_sequence: rotationSequence,
36
+ effective_at,
37
+ expires_at,
38
+ grace_period_ms: gracePeriodMs,
39
+ timestamp,
40
+ oldSignature: oldSigResult.value,
41
+ newSignature: newSigResult.value
42
+ });
43
+ }
44
+ /**
45
+ * Verify succession announcement dual signatures.
46
+ *
47
+ * Both old and new keys must have valid signatures.
48
+ * Also checks sequence monotonicity (new sequence must be greater than current).
49
+ *
50
+ * @param announcement - Succession announcement to verify
51
+ * @param oldPublicKey - ML-DSA-65 public key (1952 bytes) for old DID
52
+ * @param newPublicKey - ML-DSA-65 public key (1952 bytes) for new DID
53
+ * @returns true if both signatures valid, false otherwise
54
+ */
55
+ export async function verifySuccession(announcement, oldPublicKey, newPublicKey) {
56
+ const message = `${announcement.oldDid}||${announcement.newDid}||${announcement.rotation_sequence}||${announcement.effective_at}||${announcement.expires_at}||${announcement.grace_period_ms}||${announcement.timestamp}`;
57
+ const messageBytes = new TextEncoder().encode(message);
58
+ const oldValidResult = await verifyMlDsa65(oldPublicKey, announcement.oldSignature, messageBytes);
59
+ if (!oldValidResult.ok) {
60
+ return err('VERIFY_FAILED');
61
+ }
62
+ const newValidResult = await verifyMlDsa65(newPublicKey, announcement.newSignature, messageBytes);
63
+ if (!newValidResult.ok) {
64
+ return err('VERIFY_FAILED');
65
+ }
66
+ const bothValid = oldValidResult.value && newValidResult.value;
67
+ return ok(bothValid);
68
+ }
69
+ /**
70
+ * Encode succession announcement to wire format.
71
+ *
72
+ * Format: did:key:OLD||did:key:NEW||sequence||effective_at||expires_at||grace_period||timestamp||sig_OLD||sig_NEW
73
+ *
74
+ * @param announcement - Succession announcement to encode
75
+ * @returns Wire format string (base64-encoded signatures)
76
+ */
77
+ export function encodeSuccession(announcement) {
78
+ const parts = [
79
+ announcement.oldDid,
80
+ announcement.newDid,
81
+ announcement.rotation_sequence.toString(),
82
+ announcement.effective_at.toString(),
83
+ announcement.expires_at.toString(),
84
+ announcement.grace_period_ms.toString(),
85
+ announcement.timestamp.toString(),
86
+ Buffer.from(announcement.oldSignature).toString('base64'),
87
+ Buffer.from(announcement.newSignature).toString('base64')
88
+ ];
89
+ return parts.join('||');
90
+ }
91
+ /**
92
+ * Decode succession announcement from wire format.
93
+ *
94
+ * @param encoded - Wire format string
95
+ * @returns Parsed succession announcement or error
96
+ */
97
+ export function decodeSuccession(encoded) {
98
+ const parts = encoded.split('||');
99
+ if (parts.length !== 9) {
100
+ return err('INVALID_FORMAT');
101
+ }
102
+ const oldDid = parts[0];
103
+ const newDid = parts[1];
104
+ const sequenceStr = parts[2];
105
+ const effectiveAtStr = parts[3];
106
+ const expiresAtStr = parts[4];
107
+ const gracePeriodStr = parts[5];
108
+ const timestampStr = parts[6];
109
+ const oldSigB64 = parts[7];
110
+ const newSigB64 = parts[8];
111
+ if (!oldDid || !newDid || !sequenceStr || !effectiveAtStr || !expiresAtStr || !gracePeriodStr || !timestampStr || !oldSigB64 || !newSigB64) {
112
+ return err('INVALID_FORMAT');
113
+ }
114
+ const rotation_sequence = parseInt(sequenceStr, 10);
115
+ const effective_at = parseInt(effectiveAtStr, 10);
116
+ const expires_at = parseInt(expiresAtStr, 10);
117
+ const grace_period_ms = parseInt(gracePeriodStr, 10);
118
+ const timestamp = parseInt(timestampStr, 10);
119
+ if (isNaN(rotation_sequence) || rotation_sequence < 0 ||
120
+ isNaN(effective_at) || effective_at < 0 ||
121
+ isNaN(expires_at) || expires_at < 0 ||
122
+ isNaN(grace_period_ms) || grace_period_ms < 0 ||
123
+ isNaN(timestamp) || timestamp < 0) {
124
+ return err('INVALID_TIMESTAMP');
125
+ }
126
+ try {
127
+ return ok({
128
+ oldDid,
129
+ newDid,
130
+ rotation_sequence,
131
+ effective_at,
132
+ expires_at,
133
+ grace_period_ms,
134
+ timestamp,
135
+ oldSignature: new Uint8Array(Buffer.from(oldSigB64, 'base64')),
136
+ newSignature: new Uint8Array(Buffer.from(newSigB64, 'base64'))
137
+ });
138
+ }
139
+ catch {
140
+ return err('INVALID_FORMAT');
141
+ }
142
+ }
@@ -0,0 +1,50 @@
1
+ import type { Result } from '@private.me/shared';
2
+ import type { AnyTransportEnvelope } from './envelope.js';
3
+ /** Transport-level error codes. */
4
+ export type TransportError = 'SEND_FAILED' | 'NETWORK_ERROR' | 'RECIPIENT_UNREACHABLE' | 'TIMEOUT';
5
+ /** Handler invoked when an envelope is received. */
6
+ export type EnvelopeHandler = (envelope: AnyTransportEnvelope) => void;
7
+ /**
8
+ * Transport adapter interface for delivering signed envelopes.
9
+ *
10
+ * Both HTTPS (SDK default) and WebRTC (P2P, Phase 2) implement this contract.
11
+ * Accepts v1 and v2 envelopes.
12
+ */
13
+ export interface XailTransportAdapter {
14
+ /** Send a signed envelope to a recipient. */
15
+ send(envelope: AnyTransportEnvelope, recipientDid: string): Promise<Result<void, TransportError>>;
16
+ /** Register a handler for incoming envelopes. */
17
+ onReceive(handler: EnvelopeHandler): void;
18
+ /** Shut down the transport (close connections, clear handlers). */
19
+ dispose(): void;
20
+ }
21
+ /** Options for HttpsTransportAdapter. */
22
+ export interface HttpsTransportOptions {
23
+ /** Base URL for envelope delivery endpoint. */
24
+ readonly baseUrl: string;
25
+ /** Request timeout in milliseconds. Default: 10000. */
26
+ readonly timeoutMs?: number;
27
+ /** Custom fetch implementation (for testing). */
28
+ readonly fetch?: typeof globalThis.fetch;
29
+ }
30
+ /**
31
+ * HTTPS transport adapter — sends envelopes as JSON POST requests.
32
+ *
33
+ * Recipient URL resolved as: baseUrl/deliver/{recipientDid}
34
+ * This is the SDK's default transport for server-to-server delivery.
35
+ */
36
+ export declare class HttpsTransportAdapter implements XailTransportAdapter {
37
+ private readonly baseUrl;
38
+ private readonly timeoutMs;
39
+ private readonly fetchFn;
40
+ private handlers;
41
+ constructor(opts: HttpsTransportOptions);
42
+ send(envelope: AnyTransportEnvelope, recipientDid: string): Promise<Result<void, TransportError>>;
43
+ onReceive(handler: EnvelopeHandler): void;
44
+ /**
45
+ * Dispatch a received envelope to all handlers.
46
+ * Called by the server when an incoming POST is received.
47
+ */
48
+ dispatch(envelope: AnyTransportEnvelope): void;
49
+ dispose(): void;
50
+ }
@@ -0,0 +1,59 @@
1
+ import { ok, err } from"./_deps/shared/index.js";
2
+ /**
3
+ * HTTPS transport adapter — sends envelopes as JSON POST requests.
4
+ *
5
+ * Recipient URL resolved as: baseUrl/deliver/{recipientDid}
6
+ * This is the SDK's default transport for server-to-server delivery.
7
+ */
8
+ export class HttpsTransportAdapter {
9
+ baseUrl;
10
+ timeoutMs;
11
+ fetchFn;
12
+ handlers = [];
13
+ constructor(opts) {
14
+ this.baseUrl = opts.baseUrl.replace(/\/$/, '');
15
+ this.timeoutMs = opts.timeoutMs ?? 10_000;
16
+ this.fetchFn = opts.fetch ?? globalThis.fetch.bind(globalThis);
17
+ }
18
+ async send(envelope, recipientDid) {
19
+ const url = `${this.baseUrl}/deliver/${encodeURIComponent(recipientDid)}`;
20
+ try {
21
+ const controller = new AbortController();
22
+ const timer = setTimeout(() => controller.abort(), this.timeoutMs);
23
+ const response = await this.fetchFn(url, {
24
+ method: 'POST',
25
+ headers: { 'Content-Type': 'application/json' },
26
+ body: JSON.stringify(envelope),
27
+ signal: controller.signal,
28
+ });
29
+ clearTimeout(timer);
30
+ if (!response.ok) {
31
+ return err(response.status === 404
32
+ ? 'RECIPIENT_UNREACHABLE'
33
+ : 'SEND_FAILED');
34
+ }
35
+ return ok(undefined);
36
+ }
37
+ catch (e) {
38
+ if (e instanceof DOMException && e.name === 'AbortError') {
39
+ return err('TIMEOUT');
40
+ }
41
+ return err('NETWORK_ERROR');
42
+ }
43
+ }
44
+ onReceive(handler) {
45
+ this.handlers.push(handler);
46
+ }
47
+ /**
48
+ * Dispatch a received envelope to all handlers.
49
+ * Called by the server when an incoming POST is received.
50
+ */
51
+ dispatch(envelope) {
52
+ for (const handler of this.handlers) {
53
+ handler(envelope);
54
+ }
55
+ }
56
+ dispose() {
57
+ this.handlers = [];
58
+ }
59
+ }