@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,328 @@
1
+ "use strict";
2
+ /**
3
+ * @module invite
4
+ * Viral invite system for XBind connections.
5
+ *
6
+ * Enables one-click invites:
7
+ * - Generate: `xbind invite payments-service`
8
+ * - Accept: Click link or `xbind accept https://xbind.to/invite/abc123`
9
+ *
10
+ * The viral loop:
11
+ * 1. Service A invites Service B
12
+ * 2. Service B clicks link (< 60 sec setup)
13
+ * 3. Connection established
14
+ * 4. Service B invites Service C
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.InviteService = exports.InviteErrorCode = void 0;
18
+ const shared_1 = require("../_deps/shared/index.js");
19
+ /**
20
+ * Invite error codes.
21
+ */
22
+ var InviteErrorCode;
23
+ (function (InviteErrorCode) {
24
+ InviteErrorCode["INVALID_INVITE"] = "INVITE_INVALID";
25
+ InviteErrorCode["EXPIRED_INVITE"] = "INVITE_EXPIRED";
26
+ InviteErrorCode["INVITE_NOT_FOUND"] = "INVITE_NOT_FOUND";
27
+ InviteErrorCode["NETWORK_ERROR"] = "INVITE_NETWORK_ERROR";
28
+ InviteErrorCode["ALREADY_CONNECTED"] = "INVITE_ALREADY_CONNECTED";
29
+ })(InviteErrorCode || (exports.InviteErrorCode = InviteErrorCode = {}));
30
+ /**
31
+ * Invite service for creating and accepting invites.
32
+ */
33
+ class InviteService {
34
+ inviteApiUrl;
35
+ /**
36
+ * Create invite service.
37
+ *
38
+ * @param options - Configuration
39
+ * @param options.inviteApiUrl - Invite API URL (default: https://xbind.to)
40
+ */
41
+ constructor(options = {}) {
42
+ this.inviteApiUrl = options.inviteApiUrl || 'https://xbind.to';
43
+ }
44
+ /**
45
+ * Create an invite.
46
+ *
47
+ * @param options - Invite options
48
+ * @param options.from - Sender service info
49
+ * @param options.target - Target service (optional)
50
+ * @param options.template - Suggested template (e.g., "payment-processing")
51
+ * @param options.permissions - Custom permissions
52
+ * @param options.expiresIn - Expiration in seconds (default: 7 days)
53
+ * @returns Invite or error
54
+ *
55
+ * @example
56
+ * ```ts
57
+ * const inviteService = new InviteService();
58
+ * const invite = await inviteService.create({
59
+ * from: {
60
+ * name: 'billing-service',
61
+ * did: 'did:key:z6Mk...',
62
+ * endpoint: 'https://billing.example.com',
63
+ * publicKey: '...',
64
+ * },
65
+ * target: {
66
+ * name: 'payments-service',
67
+ * },
68
+ * template: 'payment-processing',
69
+ * });
70
+ *
71
+ * // Share invite.value.url or invite.value.qr
72
+ * ```
73
+ */
74
+ async create(options) {
75
+ const expiresIn = options.expiresIn || 7 * 24 * 60 * 60; // 7 days
76
+ const expires = new Date(Date.now() + expiresIn * 1000).toISOString();
77
+ try {
78
+ const response = await fetch(`${this.inviteApiUrl}/invites/create`, {
79
+ method: 'POST',
80
+ headers: {
81
+ 'Content-Type': 'application/json',
82
+ },
83
+ body: JSON.stringify({
84
+ from: {
85
+ name: options.from.name,
86
+ did: options.from.did,
87
+ endpoint: options.from.endpoint,
88
+ publicKey: options.from.publicKey,
89
+ x25519PublicKey: options.from.x25519PublicKey,
90
+ mlKemPublicKey: options.from.mlKemPublicKey,
91
+ },
92
+ to: options.target,
93
+ template: options.template,
94
+ permissions: options.permissions,
95
+ expires,
96
+ }),
97
+ });
98
+ if (!response.ok) {
99
+ return (0, shared_1.err)({
100
+ code: InviteErrorCode.NETWORK_ERROR,
101
+ message: `Failed to create invite: ${response.status}`,
102
+ });
103
+ }
104
+ const data = await response.json();
105
+ return (0, shared_1.ok)(data);
106
+ }
107
+ catch (error) {
108
+ return (0, shared_1.err)({
109
+ code: InviteErrorCode.NETWORK_ERROR,
110
+ message: error instanceof Error ? error.message : 'Network error',
111
+ });
112
+ }
113
+ }
114
+ /**
115
+ * Accept an invite.
116
+ *
117
+ * @param options - Accept options
118
+ * @param options.inviteUrl - Invite URL (e.g., https://xbind.to/invite/abc123)
119
+ * @param options.acceptor - Acceptor service info
120
+ * @returns Connection info or error
121
+ *
122
+ * @example
123
+ * ```ts
124
+ * const inviteService = new InviteService();
125
+ * const result = await inviteService.accept({
126
+ * inviteUrl: 'https://xbind.to/invite/abc123',
127
+ * acceptor: {
128
+ * name: 'payments-service',
129
+ * did: 'did:key:z6Mk...',
130
+ * endpoint: 'https://payments.example.com',
131
+ * publicKey: '...',
132
+ * }
133
+ * });
134
+ *
135
+ * if (result.ok) {
136
+ * console.log('Connected!');
137
+ * }
138
+ * ```
139
+ */
140
+ async accept(options) {
141
+ try {
142
+ // Extract invite ID from URL
143
+ const inviteId = this.extractInviteId(options.inviteUrl);
144
+ if (!inviteId) {
145
+ return (0, shared_1.err)({
146
+ code: InviteErrorCode.INVALID_INVITE,
147
+ message: 'Invalid invite URL',
148
+ hint: 'URL should be like: https://xbind.to/invite/abc123',
149
+ });
150
+ }
151
+ // Accept invite
152
+ const response = await fetch(`${this.inviteApiUrl}/invites/${inviteId}/accept`, {
153
+ method: 'POST',
154
+ headers: {
155
+ 'Content-Type': 'application/json',
156
+ },
157
+ body: JSON.stringify({
158
+ acceptor: {
159
+ name: options.acceptor.name,
160
+ did: options.acceptor.did,
161
+ endpoint: options.acceptor.endpoint,
162
+ publicKey: options.acceptor.publicKey,
163
+ x25519PublicKey: options.acceptor.x25519PublicKey,
164
+ mlKemPublicKey: options.acceptor.mlKemPublicKey,
165
+ },
166
+ }),
167
+ });
168
+ if (response.status === 404) {
169
+ return (0, shared_1.err)({
170
+ code: InviteErrorCode.INVITE_NOT_FOUND,
171
+ message: 'Invite not found or expired',
172
+ hint: 'The invite may have been revoked or expired',
173
+ });
174
+ }
175
+ if (response.status === 410) {
176
+ const errorData = await response.json().catch(() => ({}));
177
+ return (0, shared_1.err)({
178
+ code: InviteErrorCode.EXPIRED_INVITE,
179
+ message: errorData.message || 'Invite has expired',
180
+ hint: errorData.hint || 'Ask the sender to create a new invite',
181
+ });
182
+ }
183
+ if (response.status === 409) {
184
+ return (0, shared_1.err)({
185
+ code: InviteErrorCode.ALREADY_CONNECTED,
186
+ message: 'Services are already connected',
187
+ hint: 'You are already connected to this service',
188
+ });
189
+ }
190
+ if (!response.ok) {
191
+ return (0, shared_1.err)({
192
+ code: InviteErrorCode.NETWORK_ERROR,
193
+ message: `Failed to accept invite: ${response.status}`,
194
+ });
195
+ }
196
+ const data = await response.json();
197
+ return (0, shared_1.ok)(data);
198
+ }
199
+ catch (error) {
200
+ return (0, shared_1.err)({
201
+ code: InviteErrorCode.NETWORK_ERROR,
202
+ message: error instanceof Error ? error.message : 'Network error',
203
+ hint: 'Check your network connection and try again',
204
+ });
205
+ }
206
+ }
207
+ /**
208
+ * Get invite details without accepting.
209
+ *
210
+ * @param inviteUrl - Invite URL
211
+ * @returns Invite details or error
212
+ */
213
+ async get(inviteUrl) {
214
+ try {
215
+ const inviteId = this.extractInviteId(inviteUrl);
216
+ if (!inviteId) {
217
+ return (0, shared_1.err)({
218
+ code: InviteErrorCode.INVALID_INVITE,
219
+ message: 'Invalid invite URL',
220
+ });
221
+ }
222
+ const response = await fetch(`${this.inviteApiUrl}/invites/${inviteId}`, {
223
+ headers: {
224
+ 'Accept': 'application/json',
225
+ },
226
+ });
227
+ if (response.status === 404) {
228
+ return (0, shared_1.err)({
229
+ code: InviteErrorCode.INVITE_NOT_FOUND,
230
+ message: 'Invite not found',
231
+ });
232
+ }
233
+ if (!response.ok) {
234
+ return (0, shared_1.err)({
235
+ code: InviteErrorCode.NETWORK_ERROR,
236
+ message: `Failed to get invite: ${response.status}`,
237
+ });
238
+ }
239
+ const data = await response.json();
240
+ return (0, shared_1.ok)(data);
241
+ }
242
+ catch (error) {
243
+ return (0, shared_1.err)({
244
+ code: InviteErrorCode.NETWORK_ERROR,
245
+ message: error instanceof Error ? error.message : 'Network error',
246
+ });
247
+ }
248
+ }
249
+ /**
250
+ * Revoke an invite.
251
+ *
252
+ * @param inviteId - Invite ID to revoke
253
+ * @returns Success or error
254
+ *
255
+ * @example
256
+ * ```ts
257
+ * const inviteService = new InviteService();
258
+ * const result = await inviteService.revoke('inv_abc123');
259
+ *
260
+ * if (result.ok) {
261
+ * console.log('Invite revoked');
262
+ * }
263
+ * ```
264
+ */
265
+ async revoke(inviteId) {
266
+ try {
267
+ const response = await fetch(`${this.inviteApiUrl}/invites/${inviteId}/revoke`, {
268
+ method: 'POST',
269
+ headers: {
270
+ 'Content-Type': 'application/json',
271
+ },
272
+ });
273
+ if (response.status === 404) {
274
+ return (0, shared_1.err)({
275
+ code: InviteErrorCode.INVITE_NOT_FOUND,
276
+ message: 'Invite not found',
277
+ hint: 'The invite may have already been revoked or expired',
278
+ });
279
+ }
280
+ if (!response.ok) {
281
+ return (0, shared_1.err)({
282
+ code: InviteErrorCode.NETWORK_ERROR,
283
+ message: `Failed to revoke invite: ${response.status}`,
284
+ });
285
+ }
286
+ const data = await response.json();
287
+ return (0, shared_1.ok)(data);
288
+ }
289
+ catch (error) {
290
+ return (0, shared_1.err)({
291
+ code: InviteErrorCode.NETWORK_ERROR,
292
+ message: error instanceof Error ? error.message : 'Network error',
293
+ });
294
+ }
295
+ }
296
+ /**
297
+ * Extract invite ID from URL.
298
+ *
299
+ * @param url - Invite URL
300
+ * @returns Invite ID or null
301
+ *
302
+ * @example
303
+ * ```ts
304
+ * extractInviteId('https://xbind.to/invite/abc123') // 'abc123'
305
+ * extractInviteId('https://xbind.to/billing/invite/xyz') // 'xyz'
306
+ * ```
307
+ */
308
+ extractInviteId(url) {
309
+ try {
310
+ const parsed = new URL(url);
311
+ const segments = parsed.pathname.split('/').filter(s => s.length > 0);
312
+ // Look for 'invite' segment followed by ID
313
+ const inviteIndex = segments.indexOf('invite');
314
+ if (inviteIndex !== -1 && segments[inviteIndex + 1]) {
315
+ return segments[inviteIndex + 1] ?? null;
316
+ }
317
+ // Fallback: last segment
318
+ if (segments.length > 0) {
319
+ return segments[segments.length - 1] ?? null;
320
+ }
321
+ return null;
322
+ }
323
+ catch {
324
+ return null;
325
+ }
326
+ }
327
+ }
328
+ exports.InviteService = InviteService;
@@ -0,0 +1,246 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateEphemeralKeyPair = generateEphemeralKeyPair;
4
+ exports.importX25519PublicKey = importX25519PublicKey;
5
+ exports.deriveSharedKeyECDH = deriveSharedKeyECDH;
6
+ exports.senderKeyAgreement = senderKeyAgreement;
7
+ exports.receiverKeyAgreement = receiverKeyAgreement;
8
+ exports.combineSharedSecrets = combineSharedSecrets;
9
+ exports.senderHybridKeyAgreement = senderHybridKeyAgreement;
10
+ exports.receiverHybridKeyAgreement = receiverHybridKeyAgreement;
11
+ const shared_1 = require("../_deps/shared/index.js");
12
+ const mlkem_1 = require("mlkem");
13
+ /* -- Constants -- */
14
+ const X25519_RAW_KEY_BYTES = 32;
15
+ const AES_KEY_BITS = 256;
16
+ /* -- Helpers -- */
17
+ /** Copy Uint8Array to fresh ArrayBuffer. */
18
+ function toArrayBuffer(data) {
19
+ const buf = new ArrayBuffer(data.byteLength);
20
+ new Uint8Array(buf).set(data);
21
+ return buf;
22
+ }
23
+ /* -- Key Generation -- */
24
+ /**
25
+ * Generate an ephemeral X25519 key pair for ECDH key agreement.
26
+ *
27
+ * Uses Web Crypto API to generate a fresh X25519 key pair.
28
+ * The key pair is ephemeral -- it should be used for a single
29
+ * key agreement and then discarded.
30
+ *
31
+ * @returns Result containing the ephemeral key pair or error.
32
+ */
33
+ async function generateEphemeralKeyPair() {
34
+ try {
35
+ // SAFETY: X25519 generateKey always returns CryptoKeyPair
36
+ const keyPair = await crypto.subtle.generateKey({ name: 'X25519' }, true, ['deriveBits']);
37
+ const rawPub = new Uint8Array(await crypto.subtle.exportKey('raw', keyPair.publicKey));
38
+ return (0, shared_1.ok)({
39
+ privateKey: keyPair.privateKey,
40
+ publicKey: keyPair.publicKey,
41
+ rawPublicKey: rawPub,
42
+ });
43
+ }
44
+ catch {
45
+ return (0, shared_1.err)('KEYGEN_FAILED');
46
+ }
47
+ }
48
+ /* -- Key Import -- */
49
+ /**
50
+ * Import a raw 32-byte X25519 public key into a CryptoKey.
51
+ *
52
+ * Used by the receiver to import the sender's ephemeral public
53
+ * key from the envelope for ECDH derivation.
54
+ *
55
+ * @param rawPublicKey - Raw 32-byte X25519 public key.
56
+ * @returns Result containing the imported CryptoKey or error.
57
+ */
58
+ async function importX25519PublicKey(rawPublicKey) {
59
+ if (rawPublicKey.length !== X25519_RAW_KEY_BYTES) {
60
+ return (0, shared_1.err)('INVALID_KEY_LENGTH:EXPECTED_32');
61
+ }
62
+ try {
63
+ const key = await crypto.subtle.importKey('raw', toArrayBuffer(rawPublicKey), { name: 'X25519' }, true, []);
64
+ return (0, shared_1.ok)(key);
65
+ }
66
+ catch {
67
+ return (0, shared_1.err)('IMPORT_FAILED');
68
+ }
69
+ }
70
+ /* -- ECDH Key Derivation -- */
71
+ /**
72
+ * Derive a shared AES-256-GCM key via X25519 ECDH.
73
+ *
74
+ * Performs ECDH key agreement between a local private key and a
75
+ * remote public key, producing 256 bits of shared secret that
76
+ * are imported as an AES-256-GCM key.
77
+ *
78
+ * @param localPrivateKey - Local X25519 private key.
79
+ * @param remotePublicKey - Remote X25519 public key (CryptoKey).
80
+ * @returns Result containing the derived AES-256-GCM key or error.
81
+ */
82
+ async function deriveSharedKeyECDH(localPrivateKey, remotePublicKey) {
83
+ try {
84
+ const sharedBits = await crypto.subtle.deriveBits({ name: 'X25519', public: remotePublicKey }, localPrivateKey, AES_KEY_BITS);
85
+ const aesKey = await crypto.subtle.importKey('raw', sharedBits, { name: 'AES-GCM', length: AES_KEY_BITS }, false, ['encrypt', 'decrypt']);
86
+ return (0, shared_1.ok)(aesKey);
87
+ }
88
+ catch {
89
+ return (0, shared_1.err)('DERIVE_FAILED');
90
+ }
91
+ }
92
+ /* -- High-Level API -- */
93
+ /**
94
+ * Perform sender-side ECDH key agreement.
95
+ *
96
+ * Generates an ephemeral X25519 key pair, derives a shared key
97
+ * with the recipient's static X25519 public key, and returns
98
+ * both the shared key and the ephemeral public key to include
99
+ * in the envelope.
100
+ *
101
+ * @param recipientX25519PubKey - Recipient's static X25519 public key.
102
+ * @returns Result containing the key agreement result or error.
103
+ */
104
+ async function senderKeyAgreement(recipientX25519PubKey) {
105
+ const ephemeral = await generateEphemeralKeyPair();
106
+ if (!ephemeral.ok)
107
+ return ephemeral;
108
+ const shared = await deriveSharedKeyECDH(ephemeral.value.privateKey, recipientX25519PubKey);
109
+ if (!shared.ok)
110
+ return shared;
111
+ return (0, shared_1.ok)({
112
+ sharedKey: shared.value,
113
+ ephemeralPublicKey: ephemeral.value.rawPublicKey,
114
+ });
115
+ }
116
+ /**
117
+ * Perform receiver-side ECDH key agreement.
118
+ *
119
+ * Imports the sender's ephemeral public key from the envelope
120
+ * and derives the shared key using the receiver's static X25519
121
+ * private key.
122
+ *
123
+ * @param receiverPrivateKey - Receiver's static X25519 private key.
124
+ * @param senderEphemeralPubRaw - Sender's ephemeral public key (raw bytes).
125
+ * @returns Result containing the derived AES-256-GCM key or error.
126
+ */
127
+ async function receiverKeyAgreement(receiverPrivateKey, senderEphemeralPubRaw) {
128
+ const imported = await importX25519PublicKey(senderEphemeralPubRaw);
129
+ if (!imported.ok)
130
+ return imported;
131
+ return deriveSharedKeyECDH(receiverPrivateKey, imported.value);
132
+ }
133
+ /* -- Hybrid Key Agreement (X25519 + ML-KEM-768) -- */
134
+ const HYBRID_HKDF_INFO = 'xail-hybrid-kem-v2';
135
+ /**
136
+ * Combine X25519 and ML-KEM shared secrets via HKDF-SHA256.
137
+ *
138
+ * Concatenates 32B X25519 + 32B ML-KEM shared secrets, runs HKDF
139
+ * with zero salt and 'xail-hybrid-kem-v2' info, outputs 256-bit AES key.
140
+ * Secure as long as either X25519 OR ML-KEM remains unbroken.
141
+ *
142
+ * @param x25519Shared - 32-byte raw X25519 ECDH shared bits.
143
+ * @param mlKemShared - 32-byte ML-KEM-768 shared secret.
144
+ * @returns AES-256-GCM CryptoKey derived from both secrets.
145
+ */
146
+ async function combineSharedSecrets(x25519Shared, mlKemShared) {
147
+ try {
148
+ const combined = new Uint8Array(x25519Shared.length + mlKemShared.length);
149
+ combined.set(x25519Shared);
150
+ combined.set(mlKemShared, x25519Shared.length);
151
+ const baseKey = await crypto.subtle.importKey('raw', toArrayBuffer(combined), 'HKDF', false, ['deriveBits']);
152
+ const derived = await crypto.subtle.deriveBits({
153
+ name: 'HKDF',
154
+ hash: 'SHA-256',
155
+ salt: new Uint8Array(32),
156
+ info: new TextEncoder().encode(HYBRID_HKDF_INFO),
157
+ }, baseKey, AES_KEY_BITS);
158
+ const aesKey = await crypto.subtle.importKey('raw', derived, { name: 'AES-GCM', length: AES_KEY_BITS }, false, ['encrypt', 'decrypt']);
159
+ return (0, shared_1.ok)(aesKey);
160
+ }
161
+ catch {
162
+ return (0, shared_1.err)('HKDF_FAILED');
163
+ }
164
+ }
165
+ /**
166
+ * Perform sender-side hybrid key agreement (X25519 + ML-KEM-768).
167
+ *
168
+ * 1. Generate ephemeral X25519, ECDH → x25519SharedBits
169
+ * 2. ML-KEM-768 encapsulate → kemCiphertext + mlKemShared
170
+ * 3. HKDF(x25519Shared || mlKemShared) → AES-256-GCM key
171
+ *
172
+ * @param recipientX25519Pub - Recipient's static X25519 public key.
173
+ * @param recipientMlKemPub - Recipient's ML-KEM-768 public key (1184B).
174
+ * @returns Hybrid key agreement result with shared key, ephemeral pub, and KEM ciphertext.
175
+ */
176
+ async function senderHybridKeyAgreement(recipientX25519Pub, recipientMlKemPub) {
177
+ // Step 1: Ephemeral X25519 ECDH
178
+ const ephemeral = await generateEphemeralKeyPair();
179
+ if (!ephemeral.ok)
180
+ return ephemeral;
181
+ let x25519Shared;
182
+ try {
183
+ x25519Shared = new Uint8Array(await crypto.subtle.deriveBits({ name: 'X25519', public: recipientX25519Pub }, ephemeral.value.privateKey, AES_KEY_BITS));
184
+ }
185
+ catch {
186
+ return (0, shared_1.err)('DERIVE_FAILED');
187
+ }
188
+ // Step 2: ML-KEM-768 encapsulate
189
+ let kemCipherText;
190
+ let kemSharedSecret;
191
+ try {
192
+ const mlkem = new mlkem_1.MlKem768();
193
+ const [cipherText, sharedSecret] = await mlkem.encap(recipientMlKemPub);
194
+ kemCipherText = cipherText;
195
+ kemSharedSecret = sharedSecret;
196
+ }
197
+ catch {
198
+ return (0, shared_1.err)('KEM_ENCAPSULATE_FAILED');
199
+ }
200
+ // Step 3: Combine via HKDF
201
+ const combined = await combineSharedSecrets(x25519Shared, kemSharedSecret);
202
+ if (!combined.ok)
203
+ return combined;
204
+ return (0, shared_1.ok)({
205
+ sharedKey: combined.value,
206
+ ephemeralPublicKey: ephemeral.value.rawPublicKey,
207
+ kemCiphertext: kemCipherText,
208
+ });
209
+ }
210
+ /**
211
+ * Perform receiver-side hybrid key agreement (X25519 + ML-KEM-768).
212
+ *
213
+ * 1. Import ephemeral X25519, ECDH → x25519SharedBits
214
+ * 2. ML-KEM-768 decapsulate → mlKemShared
215
+ * 3. HKDF(x25519Shared || mlKemShared) → same AES-256-GCM key
216
+ *
217
+ * @param x25519PrivateKey - Receiver's static X25519 private key.
218
+ * @param ephPubRaw - Sender's ephemeral X25519 public key (32B).
219
+ * @param kemCiphertext - ML-KEM-768 ciphertext from sender (1088B).
220
+ * @param mlKemSecretKey - Receiver's ML-KEM-768 secret key (2400B).
221
+ * @returns AES-256-GCM shared key or error.
222
+ */
223
+ async function receiverHybridKeyAgreement(x25519PrivateKey, ephPubRaw, kemCiphertext, mlKemSecretKey) {
224
+ // Step 1: X25519 ECDH
225
+ const imported = await importX25519PublicKey(ephPubRaw);
226
+ if (!imported.ok)
227
+ return imported;
228
+ let x25519Shared;
229
+ try {
230
+ x25519Shared = new Uint8Array(await crypto.subtle.deriveBits({ name: 'X25519', public: imported.value }, x25519PrivateKey, AES_KEY_BITS));
231
+ }
232
+ catch {
233
+ return (0, shared_1.err)('DERIVE_FAILED');
234
+ }
235
+ // Step 2: ML-KEM-768 decapsulate
236
+ let mlKemShared;
237
+ try {
238
+ const mlkem = new mlkem_1.MlKem768();
239
+ mlKemShared = await mlkem.decap(kemCiphertext, mlKemSecretKey);
240
+ }
241
+ catch {
242
+ return (0, shared_1.err)('KEM_DECAPSULATE_FAILED');
243
+ }
244
+ // Step 3: Combine via HKDF
245
+ return combineSharedSecrets(x25519Shared, mlKemShared);
246
+ }