@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,145 @@
1
+ /**
2
+ * @module approval
3
+ * OAuth-style approval flow for agents
4
+ *
5
+ * Enterprise agents require explicit user consent before performing
6
+ * sensitive operations. This module implements OAuth-style consent
7
+ * screens and approval tokens.
8
+ */
9
+ import type { Result } from '@private.me/shared';
10
+ import type { PolicyConstraints } from './agent-call.js';
11
+ /**
12
+ * Approval request options
13
+ */
14
+ export interface ApprovalOptions {
15
+ /** Agent DID requesting approval */
16
+ readonly agentDid: string;
17
+ /** Scopes being requested (e.g., ["payments:createCharge", "invoices:create"]) */
18
+ readonly scopes: string[];
19
+ /** Policy limits to enforce */
20
+ readonly limits: PolicyConstraints['limits'];
21
+ /** Duration of approval (ISO 8601 duration or ms) */
22
+ readonly duration: string | number;
23
+ /** Human-readable description of what the agent will do */
24
+ readonly description?: string;
25
+ /** Metadata for audit logging */
26
+ readonly metadata?: Record<string, unknown>;
27
+ }
28
+ /**
29
+ * Approval token (returned after user consent)
30
+ */
31
+ export interface ApprovalToken {
32
+ /** Unique approval ID */
33
+ readonly id: string;
34
+ /** Agent DID this approval is for */
35
+ readonly agentDid: string;
36
+ /** Granted scopes */
37
+ readonly scopes: string[];
38
+ /** Granted limits */
39
+ readonly limits: PolicyConstraints['limits'];
40
+ /** Expiration timestamp (ms since epoch) */
41
+ readonly expiresAt: number;
42
+ /** When this approval was created */
43
+ readonly createdAt: number;
44
+ /** Whether this approval is still valid */
45
+ readonly valid: boolean;
46
+ /** JWT-style signature (Ed25519) */
47
+ readonly signature: string;
48
+ }
49
+ /**
50
+ * Approval result
51
+ */
52
+ export interface ApprovalResult {
53
+ /** Whether user approved */
54
+ readonly approved: boolean;
55
+ /** Approval token (if approved) */
56
+ readonly token?: ApprovalToken;
57
+ /** Reason for denial (if not approved) */
58
+ readonly reason?: string;
59
+ }
60
+ /**
61
+ * Approval error codes
62
+ */
63
+ export declare enum ApprovalErrorCode {
64
+ USER_DENIED = "APPROVAL_USER_DENIED",
65
+ TIMEOUT = "APPROVAL_TIMEOUT",
66
+ INVALID_DURATION = "APPROVAL_INVALID_DURATION",
67
+ SIGNATURE_FAILED = "APPROVAL_SIGNATURE_FAILED",
68
+ TOKEN_EXPIRED = "APPROVAL_TOKEN_EXPIRED",
69
+ TOKEN_REVOKED = "APPROVAL_TOKEN_REVOKED",
70
+ INVALID_TOKEN = "APPROVAL_INVALID_TOKEN"
71
+ }
72
+ /**
73
+ * Approval error
74
+ */
75
+ export declare class ApprovalError extends Error {
76
+ readonly code: ApprovalErrorCode;
77
+ readonly details?: Record<string, unknown> | undefined;
78
+ constructor(code: ApprovalErrorCode, message: string, details?: Record<string, unknown> | undefined);
79
+ }
80
+ /**
81
+ * Approval presenter (UI abstraction)
82
+ *
83
+ * Implementations display consent screen to user and return their decision.
84
+ * This allows different UIs (CLI, web, mobile) to plug in.
85
+ */
86
+ export interface ApprovalPresenter {
87
+ /**
88
+ * Present approval request to user
89
+ *
90
+ * @param options - Approval options
91
+ * @returns User's decision
92
+ */
93
+ present(options: ApprovalOptions): Promise<Result<ApprovalResult, ApprovalError>>;
94
+ }
95
+ /**
96
+ * CLI approval presenter (prints to console, reads stdin)
97
+ * This is a legitimate CLI interface - console output is intentional
98
+ */
99
+ export declare class CLIApprovalPresenter implements ApprovalPresenter {
100
+ present(options: ApprovalOptions): Promise<Result<ApprovalResult, ApprovalError>>;
101
+ }
102
+ /**
103
+ * Approval flow coordinator
104
+ *
105
+ * Orchestrates the consent flow: present to user → sign token → track expiry
106
+ */
107
+ export declare class ApprovalFlow {
108
+ private readonly presenter;
109
+ private readonly tokens;
110
+ constructor(options?: {
111
+ readonly presenter?: ApprovalPresenter;
112
+ });
113
+ /**
114
+ * Request approval from user
115
+ *
116
+ * @param options - Approval request options
117
+ * @returns Approval result with token (if approved)
118
+ */
119
+ requestApproval(options: ApprovalOptions): Promise<Result<ApprovalResult, ApprovalError>>;
120
+ /**
121
+ * Verify an approval token
122
+ *
123
+ * @param tokenId - Token ID to verify
124
+ * @returns Token if valid, error otherwise
125
+ */
126
+ verifyToken(tokenId: string): Result<ApprovalToken, ApprovalError>;
127
+ /**
128
+ * Revoke an approval token
129
+ *
130
+ * @param tokenId - Token ID to revoke
131
+ */
132
+ revokeToken(tokenId: string): void;
133
+ /**
134
+ * Parse duration string to milliseconds
135
+ */
136
+ private parseDuration;
137
+ /**
138
+ * Generate a unique token ID
139
+ */
140
+ private generateTokenId;
141
+ /**
142
+ * Sign an approval token (stub - production would use Ed25519)
143
+ */
144
+ private signToken;
145
+ }
@@ -0,0 +1,193 @@
1
+ /**
2
+ * @module approval
3
+ * OAuth-style approval flow for agents
4
+ *
5
+ * Enterprise agents require explicit user consent before performing
6
+ * sensitive operations. This module implements OAuth-style consent
7
+ * screens and approval tokens.
8
+ */
9
+ import { ok, err } from"./_deps/shared/index.js";
10
+ /**
11
+ * Approval error codes
12
+ */
13
+ export var ApprovalErrorCode;
14
+ (function (ApprovalErrorCode) {
15
+ ApprovalErrorCode["USER_DENIED"] = "APPROVAL_USER_DENIED";
16
+ ApprovalErrorCode["TIMEOUT"] = "APPROVAL_TIMEOUT";
17
+ ApprovalErrorCode["INVALID_DURATION"] = "APPROVAL_INVALID_DURATION";
18
+ ApprovalErrorCode["SIGNATURE_FAILED"] = "APPROVAL_SIGNATURE_FAILED";
19
+ ApprovalErrorCode["TOKEN_EXPIRED"] = "APPROVAL_TOKEN_EXPIRED";
20
+ ApprovalErrorCode["TOKEN_REVOKED"] = "APPROVAL_TOKEN_REVOKED";
21
+ ApprovalErrorCode["INVALID_TOKEN"] = "APPROVAL_INVALID_TOKEN";
22
+ })(ApprovalErrorCode || (ApprovalErrorCode = {}));
23
+ /**
24
+ * Approval error
25
+ */
26
+ export class ApprovalError extends Error {
27
+ code;
28
+ details;
29
+ constructor(code, message, details) {
30
+ super(message);
31
+ this.code = code;
32
+ this.details = details;
33
+ this.name = 'ApprovalError';
34
+ }
35
+ }
36
+ /**
37
+ * CLI approval presenter (prints to console, reads stdin)
38
+ * This is a legitimate CLI interface - console output is intentional
39
+ */
40
+ export class CLIApprovalPresenter {
41
+ /* eslint-disable no-console */
42
+ async present(options) {
43
+ console.log('\n=== AGENT APPROVAL REQUEST ===');
44
+ console.log(`Agent: ${options.agentDid}`);
45
+ console.log(`Duration: ${options.duration}`);
46
+ console.log('\nRequested Scopes:');
47
+ for (const scope of options.scopes) {
48
+ console.log(` - ${scope}`);
49
+ }
50
+ if (options.limits) {
51
+ console.log('\nPolicy Limits:');
52
+ if (options.limits.amountPerTxn) {
53
+ console.log(` - Max per transaction: $${options.limits.amountPerTxn.toLocaleString()}`);
54
+ }
55
+ if (options.limits.dailyAmount) {
56
+ console.log(` - Daily limit: $${options.limits.dailyAmount.toLocaleString()}`);
57
+ }
58
+ if (options.limits.callsPerMinute) {
59
+ console.log(` - Rate limit: ${options.limits.callsPerMinute} calls/minute`);
60
+ }
61
+ }
62
+ if (options.description) {
63
+ console.log(`\nDescription: ${options.description}`);
64
+ }
65
+ console.log('\n[This is a mock presenter - auto-approving for development]');
66
+ console.log('In production, this would prompt for user input.\n');
67
+ // Auto-approve for development (production would prompt for y/n)
68
+ return ok({
69
+ approved: true,
70
+ });
71
+ }
72
+ }
73
+ /**
74
+ * Approval flow coordinator
75
+ *
76
+ * Orchestrates the consent flow: present to user → sign token → track expiry
77
+ */
78
+ export class ApprovalFlow {
79
+ presenter;
80
+ tokens = new Map();
81
+ constructor(options = {}) {
82
+ this.presenter = options.presenter ?? new CLIApprovalPresenter();
83
+ }
84
+ /**
85
+ * Request approval from user
86
+ *
87
+ * @param options - Approval request options
88
+ * @returns Approval result with token (if approved)
89
+ */
90
+ async requestApproval(options) {
91
+ // Validate duration
92
+ const durationMs = this.parseDuration(options.duration);
93
+ if (durationMs <= 0) {
94
+ return err(new ApprovalError(ApprovalErrorCode.INVALID_DURATION, `Invalid duration: ${options.duration}`));
95
+ }
96
+ // Present to user
97
+ const result = await this.presenter.present(options);
98
+ if (!result.ok)
99
+ return result;
100
+ if (!result.value.approved) {
101
+ return ok({
102
+ approved: false,
103
+ reason: result.value.reason ?? 'User denied approval',
104
+ });
105
+ }
106
+ // Generate approval token
107
+ const now = Date.now();
108
+ const token = {
109
+ id: this.generateTokenId(),
110
+ agentDid: options.agentDid,
111
+ scopes: options.scopes,
112
+ limits: options.limits,
113
+ expiresAt: now + durationMs,
114
+ createdAt: now,
115
+ valid: true,
116
+ signature: await this.signToken(options.agentDid, options.scopes, now + durationMs),
117
+ };
118
+ // Store token
119
+ this.tokens.set(token.id, token);
120
+ return ok({
121
+ approved: true,
122
+ token,
123
+ });
124
+ }
125
+ /**
126
+ * Verify an approval token
127
+ *
128
+ * @param tokenId - Token ID to verify
129
+ * @returns Token if valid, error otherwise
130
+ */
131
+ verifyToken(tokenId) {
132
+ const token = this.tokens.get(tokenId);
133
+ if (!token) {
134
+ return err(new ApprovalError(ApprovalErrorCode.INVALID_TOKEN, `Token ${tokenId} not found`));
135
+ }
136
+ if (!token.valid) {
137
+ return err(new ApprovalError(ApprovalErrorCode.TOKEN_REVOKED, `Token ${tokenId} has been revoked`));
138
+ }
139
+ if (Date.now() > token.expiresAt) {
140
+ return err(new ApprovalError(ApprovalErrorCode.TOKEN_EXPIRED, `Token ${tokenId} expired at ${new Date(token.expiresAt).toISOString()}`));
141
+ }
142
+ return ok(token);
143
+ }
144
+ /**
145
+ * Revoke an approval token
146
+ *
147
+ * @param tokenId - Token ID to revoke
148
+ */
149
+ revokeToken(tokenId) {
150
+ const token = this.tokens.get(tokenId);
151
+ if (token) {
152
+ this.tokens.set(tokenId, { ...token, valid: false });
153
+ }
154
+ }
155
+ /**
156
+ * Parse duration string to milliseconds
157
+ */
158
+ parseDuration(duration) {
159
+ if (typeof duration === 'number')
160
+ return duration;
161
+ // Parse ISO 8601 duration or simple format
162
+ const matches = duration.match(/^(\d+)([smhd])$/);
163
+ if (!matches)
164
+ return -1;
165
+ const value = parseInt(matches[1] ?? '0', 10);
166
+ const unit = matches[2];
167
+ switch (unit) {
168
+ case 's': return value * 1000;
169
+ case 'm': return value * 60 * 1000;
170
+ case 'h': return value * 60 * 60 * 1000;
171
+ case 'd': return value * 24 * 60 * 60 * 1000;
172
+ default: return -1;
173
+ }
174
+ }
175
+ /**
176
+ * Generate a unique token ID
177
+ */
178
+ generateTokenId() {
179
+ const randomBytes = new Uint8Array(12);
180
+ crypto.getRandomValues(randomBytes);
181
+ const randomString = Array.from(randomBytes, b => b.toString(16).padStart(2, '0')).join('');
182
+ return `appr_${Date.now()}_${randomString}`;
183
+ }
184
+ /**
185
+ * Sign an approval token (stub - production would use Ed25519)
186
+ */
187
+ async signToken(agentDid, scopes, expiresAt) {
188
+ // Production would use Ed25519 signature over JSON.stringify({ agentDid, scopes, expiresAt })
189
+ // For now, return a mock signature
190
+ const payload = JSON.stringify({ agentDid, scopes, expiresAt });
191
+ return btoa(payload).substring(0, 32);
192
+ }
193
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Xlock auth challenge module for Agent SDK.
3
+ *
4
+ * Provides requestAuth(), respondToChallenge(), and onChallenge()
5
+ * functions that work with an Agent instance and the XBind gateway.
6
+ *
7
+ * These functions are also re-exported as thin methods on the Agent class.
8
+ */
9
+ import type { Result, AuthRequest, AuthResult, IncomingAuthChallenge, AuthChallengeErrorCode } from '@private.me/shared';
10
+ import type { Agent } from './agent.js';
11
+ /** Options for the gateway connection used by auth functions. */
12
+ export interface AuthGatewayOptions {
13
+ /** Gateway base URL (e.g. 'https://api.xail.io'). */
14
+ readonly gatewayUrl: string;
15
+ /** Bearer token for status polling (HMAC-SHA256 of sender DID). */
16
+ readonly accessToken: string;
17
+ }
18
+ /**
19
+ * Create an auth challenge and poll until the user responds.
20
+ *
21
+ * Sends a challenge via the XBind gateway, then polls the status
22
+ * endpoint until the challenge is approved, denied, or expires.
23
+ *
24
+ * @param agent - The Agent requesting authorization.
25
+ * @param request - Auth request details (recipient DID, action, metadata).
26
+ * @param gateway - Gateway connection options.
27
+ * @returns Auth result (approved/denied) or error.
28
+ */
29
+ export declare function requestAuth(agent: Agent, request: AuthRequest, gateway: AuthGatewayOptions): Promise<Result<AuthResult, AuthChallengeErrorCode>>;
30
+ /**
31
+ * Respond to an incoming auth challenge (approve or deny).
32
+ *
33
+ * Sends a signed response envelope to the gateway.
34
+ *
35
+ * @param agent - The Agent responding to the challenge.
36
+ * @param challengeId - The challenge ID to respond to.
37
+ * @param approved - Whether the user approved the challenge.
38
+ * @param gateway - Gateway connection options.
39
+ * @returns Success or error.
40
+ */
41
+ export declare function respondToChallenge(agent: Agent, challengeId: string, approved: boolean, gateway: AuthGatewayOptions): Promise<Result<void, AuthChallengeErrorCode>>;
42
+ /**
43
+ * Register a callback for incoming auth challenges via WebSocket.
44
+ *
45
+ * The callback fires when an `auth:challenge` message arrives
46
+ * over the gateway WebSocket connection.
47
+ *
48
+ * @param ws - The WebSocket connection to the gateway.
49
+ * @param callback - Handler for incoming challenges.
50
+ * @returns Cleanup function to unregister the listener.
51
+ */
52
+ export declare function onChallenge(ws: {
53
+ addEventListener: (type: string, handler: (event: {
54
+ data: string;
55
+ }) => void) => void;
56
+ removeEventListener: (type: string, handler: (event: {
57
+ data: string;
58
+ }) => void) => void;
59
+ }, callback: (challenge: IncomingAuthChallenge) => void): () => void;
60
+ /**
61
+ * Generate a registration QR code URI for TOTP migration.
62
+ *
63
+ * Creates a `xlock://register` URI that replaces `otpauth://` for
64
+ * asymmetric DID-based registration.
65
+ *
66
+ * @param options - Registration options.
67
+ * @returns The registration URI string.
68
+ */
69
+ export declare function generateRegistrationQR(options: {
70
+ readonly appName: string;
71
+ readonly appDid: string;
72
+ readonly registryUrl: string;
73
+ readonly callbackUrl: string;
74
+ readonly appIcon?: string;
75
+ }): string;
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Xlock auth challenge module for Agent SDK.
3
+ *
4
+ * Provides requestAuth(), respondToChallenge(), and onChallenge()
5
+ * functions that work with an Agent instance and the XBind gateway.
6
+ *
7
+ * These functions are also re-exported as thin methods on the Agent class.
8
+ */
9
+ import { ok, err } from"./_deps/shared/index.js";
10
+ import { createSignedEnvelope } from './envelope.js';
11
+ /** Default poll interval for challenge status. */
12
+ const DEFAULT_POLL_INTERVAL_MS = 2_000;
13
+ /** Default TTL for challenges (5 minutes). */
14
+ const DEFAULT_TTL_MS = 5 * 60 * 1000;
15
+ /** Max poll iterations (TTL / pollInterval + safety margin). */
16
+ const MAX_POLL_ITERATIONS = 200;
17
+ /**
18
+ * Create an auth challenge and poll until the user responds.
19
+ *
20
+ * Sends a challenge via the XBind gateway, then polls the status
21
+ * endpoint until the challenge is approved, denied, or expires.
22
+ *
23
+ * @param agent - The Agent requesting authorization.
24
+ * @param request - Auth request details (recipient DID, action, metadata).
25
+ * @param gateway - Gateway connection options.
26
+ * @returns Auth result (approved/denied) or error.
27
+ */
28
+ export async function requestAuth(agent, request, gateway) {
29
+ const ttlMs = request.ttlMs ?? DEFAULT_TTL_MS;
30
+ const pollIntervalMs = request.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
31
+ // Build the challenge payload
32
+ const payload = {
33
+ recipientDid: request.to,
34
+ action: request.action,
35
+ metadata: request.metadata ?? {},
36
+ ttlMs,
37
+ };
38
+ // Create a signed envelope wrapping the challenge request
39
+ const envelopeResult = await createSignedEnvelope({
40
+ senderDid: agent.did,
41
+ recipientDid: request.to,
42
+ scope: 'xlock:challenge',
43
+ plaintext: new TextEncoder().encode(JSON.stringify(payload)),
44
+ privateKey: agent.identity.privateKey,
45
+ });
46
+ if (!envelopeResult.ok) {
47
+ return err('INVALID_REQUEST');
48
+ }
49
+ // POST to gateway
50
+ let challengeId;
51
+ let expiresAt;
52
+ try {
53
+ const response = await fetch(`${gateway.gatewayUrl}/gateway/auth/challenge`, {
54
+ method: 'POST',
55
+ headers: { 'Content-Type': 'application/json' },
56
+ body: JSON.stringify(envelopeResult.value),
57
+ });
58
+ if (response.status === 429)
59
+ return err('RATE_LIMITED');
60
+ if (!response.ok) {
61
+ const body = await response.json().catch(() => null);
62
+ const code = body
63
+ ?.error?.code;
64
+ return err(code ?? 'INVALID_REQUEST');
65
+ }
66
+ const data = await response.json();
67
+ challengeId = data.challengeId;
68
+ expiresAt = data.expiresAt;
69
+ }
70
+ catch {
71
+ return err('INVALID_REQUEST');
72
+ }
73
+ // Poll for status
74
+ return pollChallengeStatus(challengeId, expiresAt, pollIntervalMs, gateway);
75
+ }
76
+ /**
77
+ * Respond to an incoming auth challenge (approve or deny).
78
+ *
79
+ * Sends a signed response envelope to the gateway.
80
+ *
81
+ * @param agent - The Agent responding to the challenge.
82
+ * @param challengeId - The challenge ID to respond to.
83
+ * @param approved - Whether the user approved the challenge.
84
+ * @param gateway - Gateway connection options.
85
+ * @returns Success or error.
86
+ */
87
+ export async function respondToChallenge(agent, challengeId, approved, gateway) {
88
+ const payload = {
89
+ challengeId,
90
+ approved,
91
+ timestamp: Date.now(),
92
+ };
93
+ // Create a signed envelope for the response
94
+ const envelopeResult = await createSignedEnvelope({
95
+ senderDid: agent.did,
96
+ recipientDid: agent.did, // Self-addressed (gateway verifies recipient match)
97
+ scope: 'xlock:respond',
98
+ plaintext: new TextEncoder().encode(JSON.stringify(payload)),
99
+ privateKey: agent.identity.privateKey,
100
+ });
101
+ if (!envelopeResult.ok) {
102
+ return err('INVALID_REQUEST');
103
+ }
104
+ try {
105
+ const response = await fetch(`${gateway.gatewayUrl}/gateway/auth/respond`, {
106
+ method: 'POST',
107
+ headers: { 'Content-Type': 'application/json' },
108
+ body: JSON.stringify({
109
+ ...envelopeResult.value,
110
+ // Include response fields at top level for the server
111
+ challengeId,
112
+ approved,
113
+ responseEnvelope: envelopeResult.value,
114
+ }),
115
+ });
116
+ if (!response.ok) {
117
+ const body = await response.json().catch(() => null);
118
+ const code = body
119
+ ?.error?.code;
120
+ return err(code ?? 'INVALID_REQUEST');
121
+ }
122
+ return ok(undefined);
123
+ }
124
+ catch {
125
+ return err('INVALID_REQUEST');
126
+ }
127
+ }
128
+ /**
129
+ * Register a callback for incoming auth challenges via WebSocket.
130
+ *
131
+ * The callback fires when an `auth:challenge` message arrives
132
+ * over the gateway WebSocket connection.
133
+ *
134
+ * @param ws - The WebSocket connection to the gateway.
135
+ * @param callback - Handler for incoming challenges.
136
+ * @returns Cleanup function to unregister the listener.
137
+ */
138
+ export function onChallenge(ws, callback) {
139
+ const handler = (event) => {
140
+ try {
141
+ const msg = JSON.parse(event.data);
142
+ if (msg.type === 'auth:challenge' && msg.data) {
143
+ callback(msg.data);
144
+ }
145
+ }
146
+ catch {
147
+ // Skip non-JSON messages
148
+ }
149
+ };
150
+ ws.addEventListener('message', handler);
151
+ return () => ws.removeEventListener('message', handler);
152
+ }
153
+ /**
154
+ * Generate a registration QR code URI for TOTP migration.
155
+ *
156
+ * Creates a `xlock://register` URI that replaces `otpauth://` for
157
+ * asymmetric DID-based registration.
158
+ *
159
+ * @param options - Registration options.
160
+ * @returns The registration URI string.
161
+ */
162
+ export function generateRegistrationQR(options) {
163
+ const params = new URLSearchParams({
164
+ app: options.appName,
165
+ did: options.appDid,
166
+ registry: options.registryUrl,
167
+ callback: options.callbackUrl,
168
+ });
169
+ if (options.appIcon)
170
+ params.set('icon', options.appIcon);
171
+ return `xlock://register?${params.toString()}`;
172
+ }
173
+ /** Poll the gateway for challenge status until resolved or expired. */
174
+ async function pollChallengeStatus(challengeId, expiresAt, pollIntervalMs, gateway) {
175
+ for (let i = 0; i < MAX_POLL_ITERATIONS; i++) {
176
+ if (Date.now() > expiresAt) {
177
+ return err('CHALLENGE_EXPIRED');
178
+ }
179
+ await sleep(pollIntervalMs);
180
+ try {
181
+ const response = await fetch(`${gateway.gatewayUrl}/gateway/auth/status/${challengeId}`, {
182
+ headers: { Authorization: `Bearer ${gateway.accessToken}` },
183
+ });
184
+ if (!response.ok) {
185
+ if (response.status === 404)
186
+ return err('CHALLENGE_NOT_FOUND');
187
+ continue; // Retry on transient errors
188
+ }
189
+ const data = await response.json();
190
+ if (data.status === 'approved') {
191
+ return ok({
192
+ challengeId: data.challengeId,
193
+ approved: true,
194
+ respondedAt: data.respondedAt,
195
+ envelope: data.envelope,
196
+ });
197
+ }
198
+ if (data.status === 'denied') {
199
+ return ok({
200
+ challengeId: data.challengeId,
201
+ approved: false,
202
+ respondedAt: data.respondedAt,
203
+ });
204
+ }
205
+ if (data.status === 'expired') {
206
+ return err('CHALLENGE_EXPIRED');
207
+ }
208
+ // Still pending — continue polling
209
+ }
210
+ catch {
211
+ // Network error — continue polling
212
+ }
213
+ }
214
+ return err('CHALLENGE_TIMEOUT');
215
+ }
216
+ /** Promise-based sleep. */
217
+ function sleep(ms) {
218
+ return new Promise((resolve) => setTimeout(resolve, ms));
219
+ }