@teneo-protocol/sdk 1.0.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 (281) hide show
  1. package/.dockerignore +14 -0
  2. package/.env.test.example +14 -0
  3. package/.eslintrc.json +26 -0
  4. package/.github/workflows/claude-code-review.yml +78 -0
  5. package/.github/workflows/claude-reviewer.yml +64 -0
  6. package/.github/workflows/publish-npm.yml +38 -0
  7. package/.github/workflows/push-to-main.yml +23 -0
  8. package/.node-version +1 -0
  9. package/.prettierrc +11 -0
  10. package/Dockerfile +25 -0
  11. package/LICENCE +661 -0
  12. package/README.md +709 -0
  13. package/dist/constants.d.ts +42 -0
  14. package/dist/constants.d.ts.map +1 -0
  15. package/dist/constants.js +45 -0
  16. package/dist/constants.js.map +1 -0
  17. package/dist/core/websocket-client.d.ts +261 -0
  18. package/dist/core/websocket-client.d.ts.map +1 -0
  19. package/dist/core/websocket-client.js +875 -0
  20. package/dist/core/websocket-client.js.map +1 -0
  21. package/dist/formatters/response-formatter.d.ts +354 -0
  22. package/dist/formatters/response-formatter.d.ts.map +1 -0
  23. package/dist/formatters/response-formatter.js +575 -0
  24. package/dist/formatters/response-formatter.js.map +1 -0
  25. package/dist/handlers/message-handler-registry.d.ts +155 -0
  26. package/dist/handlers/message-handler-registry.d.ts.map +1 -0
  27. package/dist/handlers/message-handler-registry.js +216 -0
  28. package/dist/handlers/message-handler-registry.js.map +1 -0
  29. package/dist/handlers/message-handlers/agent-selected-handler.d.ts +112 -0
  30. package/dist/handlers/message-handlers/agent-selected-handler.d.ts.map +1 -0
  31. package/dist/handlers/message-handlers/agent-selected-handler.js +40 -0
  32. package/dist/handlers/message-handlers/agent-selected-handler.js.map +1 -0
  33. package/dist/handlers/message-handlers/agents-list-handler.d.ts +14 -0
  34. package/dist/handlers/message-handlers/agents-list-handler.d.ts.map +1 -0
  35. package/dist/handlers/message-handlers/agents-list-handler.js +25 -0
  36. package/dist/handlers/message-handlers/agents-list-handler.js.map +1 -0
  37. package/dist/handlers/message-handlers/auth-error-handler.d.ts +71 -0
  38. package/dist/handlers/message-handlers/auth-error-handler.d.ts.map +1 -0
  39. package/dist/handlers/message-handlers/auth-error-handler.js +30 -0
  40. package/dist/handlers/message-handlers/auth-error-handler.js.map +1 -0
  41. package/dist/handlers/message-handlers/auth-message-handler.d.ts +18 -0
  42. package/dist/handlers/message-handlers/auth-message-handler.d.ts.map +1 -0
  43. package/dist/handlers/message-handlers/auth-message-handler.js +60 -0
  44. package/dist/handlers/message-handlers/auth-message-handler.js.map +1 -0
  45. package/dist/handlers/message-handlers/auth-required-handler.d.ts +76 -0
  46. package/dist/handlers/message-handlers/auth-required-handler.d.ts.map +1 -0
  47. package/dist/handlers/message-handlers/auth-required-handler.js +23 -0
  48. package/dist/handlers/message-handlers/auth-required-handler.js.map +1 -0
  49. package/dist/handlers/message-handlers/auth-success-handler.d.ts +18 -0
  50. package/dist/handlers/message-handlers/auth-success-handler.d.ts.map +1 -0
  51. package/dist/handlers/message-handlers/auth-success-handler.js +51 -0
  52. package/dist/handlers/message-handlers/auth-success-handler.js.map +1 -0
  53. package/dist/handlers/message-handlers/base-handler.d.ts +55 -0
  54. package/dist/handlers/message-handlers/base-handler.d.ts.map +1 -0
  55. package/dist/handlers/message-handlers/base-handler.js +83 -0
  56. package/dist/handlers/message-handlers/base-handler.js.map +1 -0
  57. package/dist/handlers/message-handlers/challenge-handler.d.ts +73 -0
  58. package/dist/handlers/message-handlers/challenge-handler.d.ts.map +1 -0
  59. package/dist/handlers/message-handlers/challenge-handler.js +47 -0
  60. package/dist/handlers/message-handlers/challenge-handler.js.map +1 -0
  61. package/dist/handlers/message-handlers/error-message-handler.d.ts +76 -0
  62. package/dist/handlers/message-handlers/error-message-handler.d.ts.map +1 -0
  63. package/dist/handlers/message-handlers/error-message-handler.js +29 -0
  64. package/dist/handlers/message-handlers/error-message-handler.js.map +1 -0
  65. package/dist/handlers/message-handlers/index.d.ts +28 -0
  66. package/dist/handlers/message-handlers/index.d.ts.map +1 -0
  67. package/dist/handlers/message-handlers/index.js +100 -0
  68. package/dist/handlers/message-handlers/index.js.map +1 -0
  69. package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts +122 -0
  70. package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts.map +1 -0
  71. package/dist/handlers/message-handlers/list-rooms-response-handler.js +30 -0
  72. package/dist/handlers/message-handlers/list-rooms-response-handler.js.map +1 -0
  73. package/dist/handlers/message-handlers/ping-pong-handler.d.ts +104 -0
  74. package/dist/handlers/message-handlers/ping-pong-handler.d.ts.map +1 -0
  75. package/dist/handlers/message-handlers/ping-pong-handler.js +36 -0
  76. package/dist/handlers/message-handlers/ping-pong-handler.js.map +1 -0
  77. package/dist/handlers/message-handlers/regular-message-handler.d.ts +56 -0
  78. package/dist/handlers/message-handlers/regular-message-handler.d.ts.map +1 -0
  79. package/dist/handlers/message-handlers/regular-message-handler.js +59 -0
  80. package/dist/handlers/message-handlers/regular-message-handler.js.map +1 -0
  81. package/dist/handlers/message-handlers/subscribe-response-handler.d.ts +81 -0
  82. package/dist/handlers/message-handlers/subscribe-response-handler.d.ts.map +1 -0
  83. package/dist/handlers/message-handlers/subscribe-response-handler.js +48 -0
  84. package/dist/handlers/message-handlers/subscribe-response-handler.js.map +1 -0
  85. package/dist/handlers/message-handlers/task-response-handler.d.ts +14 -0
  86. package/dist/handlers/message-handlers/task-response-handler.d.ts.map +1 -0
  87. package/dist/handlers/message-handlers/task-response-handler.js +44 -0
  88. package/dist/handlers/message-handlers/task-response-handler.js.map +1 -0
  89. package/dist/handlers/message-handlers/types.d.ts +51 -0
  90. package/dist/handlers/message-handlers/types.d.ts.map +1 -0
  91. package/dist/handlers/message-handlers/types.js +7 -0
  92. package/dist/handlers/message-handlers/types.js.map +1 -0
  93. package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts +81 -0
  94. package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts.map +1 -0
  95. package/dist/handlers/message-handlers/unsubscribe-response-handler.js +48 -0
  96. package/dist/handlers/message-handlers/unsubscribe-response-handler.js.map +1 -0
  97. package/dist/handlers/webhook-handler.d.ts +202 -0
  98. package/dist/handlers/webhook-handler.d.ts.map +1 -0
  99. package/dist/handlers/webhook-handler.js +511 -0
  100. package/dist/handlers/webhook-handler.js.map +1 -0
  101. package/dist/index.d.ts +71 -0
  102. package/dist/index.d.ts.map +1 -0
  103. package/dist/index.js +217 -0
  104. package/dist/index.js.map +1 -0
  105. package/dist/managers/agent-registry.d.ts +173 -0
  106. package/dist/managers/agent-registry.d.ts.map +1 -0
  107. package/dist/managers/agent-registry.js +310 -0
  108. package/dist/managers/agent-registry.js.map +1 -0
  109. package/dist/managers/connection-manager.d.ts +134 -0
  110. package/dist/managers/connection-manager.d.ts.map +1 -0
  111. package/dist/managers/connection-manager.js +176 -0
  112. package/dist/managers/connection-manager.js.map +1 -0
  113. package/dist/managers/index.d.ts +9 -0
  114. package/dist/managers/index.d.ts.map +1 -0
  115. package/dist/managers/index.js +16 -0
  116. package/dist/managers/index.js.map +1 -0
  117. package/dist/managers/message-router.d.ts +112 -0
  118. package/dist/managers/message-router.d.ts.map +1 -0
  119. package/dist/managers/message-router.js +260 -0
  120. package/dist/managers/message-router.js.map +1 -0
  121. package/dist/managers/room-manager.d.ts +165 -0
  122. package/dist/managers/room-manager.d.ts.map +1 -0
  123. package/dist/managers/room-manager.js +227 -0
  124. package/dist/managers/room-manager.js.map +1 -0
  125. package/dist/teneo-sdk.d.ts +703 -0
  126. package/dist/teneo-sdk.d.ts.map +1 -0
  127. package/dist/teneo-sdk.js +907 -0
  128. package/dist/teneo-sdk.js.map +1 -0
  129. package/dist/types/config.d.ts +1047 -0
  130. package/dist/types/config.d.ts.map +1 -0
  131. package/dist/types/config.js +720 -0
  132. package/dist/types/config.js.map +1 -0
  133. package/dist/types/error-codes.d.ts +29 -0
  134. package/dist/types/error-codes.d.ts.map +1 -0
  135. package/dist/types/error-codes.js +41 -0
  136. package/dist/types/error-codes.js.map +1 -0
  137. package/dist/types/events.d.ts +616 -0
  138. package/dist/types/events.d.ts.map +1 -0
  139. package/dist/types/events.js +261 -0
  140. package/dist/types/events.js.map +1 -0
  141. package/dist/types/health.d.ts +40 -0
  142. package/dist/types/health.d.ts.map +1 -0
  143. package/dist/types/health.js +6 -0
  144. package/dist/types/health.js.map +1 -0
  145. package/dist/types/index.d.ts +10 -0
  146. package/dist/types/index.d.ts.map +1 -0
  147. package/dist/types/index.js +123 -0
  148. package/dist/types/index.js.map +1 -0
  149. package/dist/types/messages.d.ts +3734 -0
  150. package/dist/types/messages.d.ts.map +1 -0
  151. package/dist/types/messages.js +482 -0
  152. package/dist/types/messages.js.map +1 -0
  153. package/dist/types/validation.d.ts +81 -0
  154. package/dist/types/validation.d.ts.map +1 -0
  155. package/dist/types/validation.js +115 -0
  156. package/dist/types/validation.js.map +1 -0
  157. package/dist/utils/bounded-queue.d.ts +127 -0
  158. package/dist/utils/bounded-queue.d.ts.map +1 -0
  159. package/dist/utils/bounded-queue.js +181 -0
  160. package/dist/utils/bounded-queue.js.map +1 -0
  161. package/dist/utils/circuit-breaker.d.ts +141 -0
  162. package/dist/utils/circuit-breaker.d.ts.map +1 -0
  163. package/dist/utils/circuit-breaker.js +215 -0
  164. package/dist/utils/circuit-breaker.js.map +1 -0
  165. package/dist/utils/deduplication-cache.d.ts +110 -0
  166. package/dist/utils/deduplication-cache.d.ts.map +1 -0
  167. package/dist/utils/deduplication-cache.js +177 -0
  168. package/dist/utils/deduplication-cache.js.map +1 -0
  169. package/dist/utils/event-waiter.d.ts +101 -0
  170. package/dist/utils/event-waiter.d.ts.map +1 -0
  171. package/dist/utils/event-waiter.js +118 -0
  172. package/dist/utils/event-waiter.js.map +1 -0
  173. package/dist/utils/index.d.ts +51 -0
  174. package/dist/utils/index.d.ts.map +1 -0
  175. package/dist/utils/index.js +72 -0
  176. package/dist/utils/index.js.map +1 -0
  177. package/dist/utils/logger.d.ts +22 -0
  178. package/dist/utils/logger.d.ts.map +1 -0
  179. package/dist/utils/logger.js +91 -0
  180. package/dist/utils/logger.js.map +1 -0
  181. package/dist/utils/rate-limiter.d.ts +122 -0
  182. package/dist/utils/rate-limiter.d.ts.map +1 -0
  183. package/dist/utils/rate-limiter.js +190 -0
  184. package/dist/utils/rate-limiter.js.map +1 -0
  185. package/dist/utils/retry-policy.d.ts +191 -0
  186. package/dist/utils/retry-policy.d.ts.map +1 -0
  187. package/dist/utils/retry-policy.js +225 -0
  188. package/dist/utils/retry-policy.js.map +1 -0
  189. package/dist/utils/secure-private-key.d.ts +113 -0
  190. package/dist/utils/secure-private-key.d.ts.map +1 -0
  191. package/dist/utils/secure-private-key.js +188 -0
  192. package/dist/utils/secure-private-key.js.map +1 -0
  193. package/dist/utils/signature-verifier.d.ts +143 -0
  194. package/dist/utils/signature-verifier.d.ts.map +1 -0
  195. package/dist/utils/signature-verifier.js +238 -0
  196. package/dist/utils/signature-verifier.js.map +1 -0
  197. package/dist/utils/ssrf-validator.d.ts +36 -0
  198. package/dist/utils/ssrf-validator.d.ts.map +1 -0
  199. package/dist/utils/ssrf-validator.js +195 -0
  200. package/dist/utils/ssrf-validator.js.map +1 -0
  201. package/examples/.env.example +17 -0
  202. package/examples/basic-usage.ts +211 -0
  203. package/examples/production-dashboard/.env.example +153 -0
  204. package/examples/production-dashboard/package.json +39 -0
  205. package/examples/production-dashboard/public/dashboard.html +642 -0
  206. package/examples/production-dashboard/server.ts +753 -0
  207. package/examples/webhook-integration.ts +239 -0
  208. package/examples/x-influencer-battle-redesign.html +1065 -0
  209. package/examples/x-influencer-battle-server.ts +217 -0
  210. package/examples/x-influencer-battle.html +787 -0
  211. package/package.json +65 -0
  212. package/src/constants.ts +43 -0
  213. package/src/core/websocket-client.test.ts +512 -0
  214. package/src/core/websocket-client.ts +1056 -0
  215. package/src/formatters/response-formatter.test.ts +571 -0
  216. package/src/formatters/response-formatter.ts +677 -0
  217. package/src/handlers/message-handler-registry.ts +239 -0
  218. package/src/handlers/message-handlers/agent-selected-handler.ts +40 -0
  219. package/src/handlers/message-handlers/agents-list-handler.ts +26 -0
  220. package/src/handlers/message-handlers/auth-error-handler.ts +31 -0
  221. package/src/handlers/message-handlers/auth-message-handler.ts +66 -0
  222. package/src/handlers/message-handlers/auth-required-handler.ts +23 -0
  223. package/src/handlers/message-handlers/auth-success-handler.ts +57 -0
  224. package/src/handlers/message-handlers/base-handler.ts +101 -0
  225. package/src/handlers/message-handlers/challenge-handler.ts +57 -0
  226. package/src/handlers/message-handlers/error-message-handler.ts +27 -0
  227. package/src/handlers/message-handlers/index.ts +77 -0
  228. package/src/handlers/message-handlers/list-rooms-response-handler.ts +28 -0
  229. package/src/handlers/message-handlers/ping-pong-handler.ts +30 -0
  230. package/src/handlers/message-handlers/regular-message-handler.ts +65 -0
  231. package/src/handlers/message-handlers/subscribe-response-handler.ts +47 -0
  232. package/src/handlers/message-handlers/task-response-handler.ts +45 -0
  233. package/src/handlers/message-handlers/types.ts +77 -0
  234. package/src/handlers/message-handlers/unsubscribe-response-handler.ts +47 -0
  235. package/src/handlers/webhook-handler.test.ts +789 -0
  236. package/src/handlers/webhook-handler.ts +576 -0
  237. package/src/index.ts +269 -0
  238. package/src/managers/agent-registry.test.ts +466 -0
  239. package/src/managers/agent-registry.ts +347 -0
  240. package/src/managers/connection-manager.ts +195 -0
  241. package/src/managers/index.ts +9 -0
  242. package/src/managers/message-router.ts +349 -0
  243. package/src/managers/room-manager.ts +248 -0
  244. package/src/teneo-sdk.ts +1022 -0
  245. package/src/types/config.test.ts +325 -0
  246. package/src/types/config.ts +799 -0
  247. package/src/types/error-codes.ts +44 -0
  248. package/src/types/events.test.ts +302 -0
  249. package/src/types/events.ts +382 -0
  250. package/src/types/health.ts +46 -0
  251. package/src/types/index.ts +199 -0
  252. package/src/types/messages.test.ts +660 -0
  253. package/src/types/messages.ts +570 -0
  254. package/src/types/validation.ts +123 -0
  255. package/src/utils/bounded-queue.test.ts +356 -0
  256. package/src/utils/bounded-queue.ts +205 -0
  257. package/src/utils/circuit-breaker.test.ts +394 -0
  258. package/src/utils/circuit-breaker.ts +262 -0
  259. package/src/utils/deduplication-cache.test.ts +380 -0
  260. package/src/utils/deduplication-cache.ts +198 -0
  261. package/src/utils/event-waiter.test.ts +381 -0
  262. package/src/utils/event-waiter.ts +172 -0
  263. package/src/utils/index.ts +74 -0
  264. package/src/utils/logger.ts +87 -0
  265. package/src/utils/rate-limiter.test.ts +341 -0
  266. package/src/utils/rate-limiter.ts +211 -0
  267. package/src/utils/retry-policy.test.ts +558 -0
  268. package/src/utils/retry-policy.ts +272 -0
  269. package/src/utils/secure-private-key.test.ts +356 -0
  270. package/src/utils/secure-private-key.ts +205 -0
  271. package/src/utils/signature-verifier.test.ts +464 -0
  272. package/src/utils/signature-verifier.ts +298 -0
  273. package/src/utils/ssrf-validator.test.ts +372 -0
  274. package/src/utils/ssrf-validator.ts +224 -0
  275. package/tests/integration/real-server.test.ts +740 -0
  276. package/tests/integration/websocket.test.ts +381 -0
  277. package/tests/integration-setup.ts +16 -0
  278. package/tests/setup.ts +34 -0
  279. package/tsconfig.json +32 -0
  280. package/vitest.config.ts +42 -0
  281. package/vitest.integration.config.ts +23 -0
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Secure private key storage with in-memory encryption
3
+ * Addresses SEC-3: Private Key Exposure Risk
4
+ *
5
+ * This class encrypts private keys in memory using AES-256-GCM to prevent
6
+ * exposure through memory dumps, heap snapshots, or accidental logging.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const secureKey = new SecurePrivateKey(privateKey);
11
+ *
12
+ * // Use the key temporarily for signing
13
+ * const signature = secureKey.use((key) => {
14
+ * return signMessage(key);
15
+ * });
16
+ *
17
+ * // Clean up when done
18
+ * secureKey.destroy();
19
+ * ```
20
+ */
21
+ /**
22
+ * Securely stores and manages an encrypted private key in memory.
23
+ *
24
+ * The key is encrypted immediately upon construction and only decrypted
25
+ * temporarily when needed for operations like signing. Decrypted keys
26
+ * are zeroed out immediately after use.
27
+ */
28
+ export declare class SecurePrivateKey {
29
+ private encrypted;
30
+ private encryptionKey;
31
+ private destroyed;
32
+ /**
33
+ * Creates a new secure private key storage.
34
+ * The provided private key is encrypted immediately and the original
35
+ * string becomes eligible for garbage collection.
36
+ *
37
+ * @param privateKey - The private key to encrypt and store securely
38
+ * @throws {Error} If private key is empty or invalid
39
+ */
40
+ constructor(privateKey: string);
41
+ /**
42
+ * Temporarily decrypts the private key and passes it to the provided function.
43
+ * The decrypted key is automatically zeroed out after the function completes,
44
+ * whether it succeeds or throws an error.
45
+ *
46
+ * This is the only way to access the decrypted private key, ensuring minimal
47
+ * exposure time in plaintext.
48
+ *
49
+ * @template T - The return type of the function
50
+ * @param fn - Function that uses the decrypted private key
51
+ * @returns The result of the function
52
+ * @throws {Error} If the key has been destroyed
53
+ * @throws Any error thrown by the provided function
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * const account = secureKey.use((key) => privateKeyToAccount(key));
58
+ * const signature = secureKey.use((key) => account.signMessage(key));
59
+ * ```
60
+ */
61
+ use<T>(fn: (key: string) => T): T;
62
+ /**
63
+ * Destroys this secure key by zeroing out all sensitive buffers.
64
+ * After calling destroy(), this instance can no longer be used.
65
+ *
66
+ * This should be called when the SDK is disconnected or the key
67
+ * is no longer needed to prevent memory exposure.
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * secureKey.destroy();
72
+ * // secureKey.use(...) will now throw an error
73
+ * ```
74
+ */
75
+ destroy(): void;
76
+ /**
77
+ * Checks if this secure key has been destroyed.
78
+ *
79
+ * @returns True if destroyed, false otherwise
80
+ */
81
+ isDestroyed(): boolean;
82
+ /**
83
+ * Encrypts the private key using AES-256-GCM.
84
+ *
85
+ * The encrypted buffer format is: [IV (16 bytes) | Auth Tag (16 bytes) | Ciphertext]
86
+ *
87
+ * @param data - The private key to encrypt
88
+ * @returns Buffer containing IV + auth tag + encrypted data
89
+ */
90
+ private encrypt;
91
+ /**
92
+ * Decrypts the stored private key.
93
+ *
94
+ * @returns The decrypted private key as a string
95
+ * @throws {Error} If decryption fails (tampered data or wrong key)
96
+ */
97
+ private decrypt;
98
+ /**
99
+ * Best-effort attempt to zero out a string in memory.
100
+ * JavaScript strings are immutable, but we can try to overwrite
101
+ * the backing buffer if it exists.
102
+ *
103
+ * @param str - The string to zero out
104
+ */
105
+ private zeroOutString;
106
+ /**
107
+ * Checks if this instance has been destroyed and throws if so.
108
+ *
109
+ * @throws {Error} If the key has been destroyed
110
+ */
111
+ private checkNotDestroyed;
112
+ }
113
+ //# sourceMappingURL=secure-private-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secure-private-key.d.ts","sourceRoot":"","sources":["../../src/utils/secure-private-key.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH;;;;;;GAMG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,SAAS,CAAS;IAE1B;;;;;;;OAOG;gBACS,UAAU,EAAE,MAAM;IAc9B;;;;;;;;;;;;;;;;;;;OAmBG;IACI,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC;IAcxC;;;;;;;;;;;;OAYG;IACI,OAAO,IAAI,IAAI;IAYtB;;;;OAIG;IACI,WAAW,IAAI,OAAO;IAI7B;;;;;;;OAOG;IACH,OAAO,CAAC,OAAO;IAoBf;;;;;OAKG;IACH,OAAO,CAAC,OAAO;IAmBf;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IASrB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;CAK1B"}
@@ -0,0 +1,188 @@
1
+ "use strict";
2
+ /**
3
+ * Secure private key storage with in-memory encryption
4
+ * Addresses SEC-3: Private Key Exposure Risk
5
+ *
6
+ * This class encrypts private keys in memory using AES-256-GCM to prevent
7
+ * exposure through memory dumps, heap snapshots, or accidental logging.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const secureKey = new SecurePrivateKey(privateKey);
12
+ *
13
+ * // Use the key temporarily for signing
14
+ * const signature = secureKey.use((key) => {
15
+ * return signMessage(key);
16
+ * });
17
+ *
18
+ * // Clean up when done
19
+ * secureKey.destroy();
20
+ * ```
21
+ */
22
+ var __importDefault = (this && this.__importDefault) || function (mod) {
23
+ return (mod && mod.__esModule) ? mod : { "default": mod };
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.SecurePrivateKey = void 0;
27
+ const crypto_1 = __importDefault(require("crypto"));
28
+ /**
29
+ * Securely stores and manages an encrypted private key in memory.
30
+ *
31
+ * The key is encrypted immediately upon construction and only decrypted
32
+ * temporarily when needed for operations like signing. Decrypted keys
33
+ * are zeroed out immediately after use.
34
+ */
35
+ class SecurePrivateKey {
36
+ /**
37
+ * Creates a new secure private key storage.
38
+ * The provided private key is encrypted immediately and the original
39
+ * string becomes eligible for garbage collection.
40
+ *
41
+ * @param privateKey - The private key to encrypt and store securely
42
+ * @throws {Error} If private key is empty or invalid
43
+ */
44
+ constructor(privateKey) {
45
+ this.destroyed = false;
46
+ if (!privateKey || typeof privateKey !== 'string') {
47
+ throw new Error('Private key must be a non-empty string');
48
+ }
49
+ // Generate a random encryption key for AES-256
50
+ this.encryptionKey = crypto_1.default.randomBytes(32);
51
+ // Encrypt the private key immediately
52
+ this.encrypted = this.encrypt(privateKey);
53
+ // Original privateKey string will be garbage collected
54
+ }
55
+ /**
56
+ * Temporarily decrypts the private key and passes it to the provided function.
57
+ * The decrypted key is automatically zeroed out after the function completes,
58
+ * whether it succeeds or throws an error.
59
+ *
60
+ * This is the only way to access the decrypted private key, ensuring minimal
61
+ * exposure time in plaintext.
62
+ *
63
+ * @template T - The return type of the function
64
+ * @param fn - Function that uses the decrypted private key
65
+ * @returns The result of the function
66
+ * @throws {Error} If the key has been destroyed
67
+ * @throws Any error thrown by the provided function
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * const account = secureKey.use((key) => privateKeyToAccount(key));
72
+ * const signature = secureKey.use((key) => account.signMessage(key));
73
+ * ```
74
+ */
75
+ use(fn) {
76
+ this.checkNotDestroyed();
77
+ const decrypted = this.decrypt();
78
+ try {
79
+ return fn(decrypted);
80
+ }
81
+ finally {
82
+ // Zero out the decrypted string in memory
83
+ // Note: This is best-effort as JavaScript strings are immutable
84
+ // but we overwrite the backing buffer
85
+ this.zeroOutString(decrypted);
86
+ }
87
+ }
88
+ /**
89
+ * Destroys this secure key by zeroing out all sensitive buffers.
90
+ * After calling destroy(), this instance can no longer be used.
91
+ *
92
+ * This should be called when the SDK is disconnected or the key
93
+ * is no longer needed to prevent memory exposure.
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * secureKey.destroy();
98
+ * // secureKey.use(...) will now throw an error
99
+ * ```
100
+ */
101
+ destroy() {
102
+ if (this.destroyed) {
103
+ return;
104
+ }
105
+ // Zero out all sensitive buffers
106
+ this.encryptionKey.fill(0);
107
+ this.encrypted.fill(0);
108
+ this.destroyed = true;
109
+ }
110
+ /**
111
+ * Checks if this secure key has been destroyed.
112
+ *
113
+ * @returns True if destroyed, false otherwise
114
+ */
115
+ isDestroyed() {
116
+ return this.destroyed;
117
+ }
118
+ /**
119
+ * Encrypts the private key using AES-256-GCM.
120
+ *
121
+ * The encrypted buffer format is: [IV (16 bytes) | Auth Tag (16 bytes) | Ciphertext]
122
+ *
123
+ * @param data - The private key to encrypt
124
+ * @returns Buffer containing IV + auth tag + encrypted data
125
+ */
126
+ encrypt(data) {
127
+ // Generate random initialization vector
128
+ const iv = crypto_1.default.randomBytes(16);
129
+ // Create cipher
130
+ const cipher = crypto_1.default.createCipheriv('aes-256-gcm', this.encryptionKey, iv);
131
+ // Encrypt the data
132
+ const encrypted = Buffer.concat([
133
+ cipher.update(data, 'utf8'),
134
+ cipher.final()
135
+ ]);
136
+ // Get authentication tag for integrity verification
137
+ const authTag = cipher.getAuthTag();
138
+ // Combine IV + authTag + encrypted data
139
+ return Buffer.concat([iv, authTag, encrypted]);
140
+ }
141
+ /**
142
+ * Decrypts the stored private key.
143
+ *
144
+ * @returns The decrypted private key as a string
145
+ * @throws {Error} If decryption fails (tampered data or wrong key)
146
+ */
147
+ decrypt() {
148
+ // Extract components from encrypted buffer
149
+ const iv = this.encrypted.subarray(0, 16);
150
+ const authTag = this.encrypted.subarray(16, 32);
151
+ const ciphertext = this.encrypted.subarray(32);
152
+ // Create decipher
153
+ const decipher = crypto_1.default.createDecipheriv('aes-256-gcm', this.encryptionKey, iv);
154
+ decipher.setAuthTag(authTag);
155
+ // Decrypt the data
156
+ const decrypted = Buffer.concat([
157
+ decipher.update(ciphertext),
158
+ decipher.final()
159
+ ]);
160
+ return decrypted.toString('utf8');
161
+ }
162
+ /**
163
+ * Best-effort attempt to zero out a string in memory.
164
+ * JavaScript strings are immutable, but we can try to overwrite
165
+ * the backing buffer if it exists.
166
+ *
167
+ * @param str - The string to zero out
168
+ */
169
+ zeroOutString(str) {
170
+ // Convert to buffer and zero it out
171
+ const buffer = Buffer.from(str, 'utf8');
172
+ buffer.fill(0);
173
+ // Note: The original string object may still exist in memory
174
+ // until garbage collected, but this reduces the attack surface
175
+ }
176
+ /**
177
+ * Checks if this instance has been destroyed and throws if so.
178
+ *
179
+ * @throws {Error} If the key has been destroyed
180
+ */
181
+ checkNotDestroyed() {
182
+ if (this.destroyed) {
183
+ throw new Error('SecurePrivateKey has been destroyed and can no longer be used');
184
+ }
185
+ }
186
+ }
187
+ exports.SecurePrivateKey = SecurePrivateKey;
188
+ //# sourceMappingURL=secure-private-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secure-private-key.js","sourceRoot":"","sources":["../../src/utils/secure-private-key.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Signature Verifier for Message Authentication
3
+ * Provides cryptographic verification of message signatures using Ethereum ECDSA
4
+ */
5
+ import { type Address } from 'viem';
6
+ import { BaseMessage, MessageType } from '../types';
7
+ /**
8
+ * Options for signature verification
9
+ */
10
+ export interface SignatureVerificationOptions {
11
+ /** Whitelist of trusted agent addresses (empty = allow all) */
12
+ trustedAddresses?: Address[];
13
+ /** Message types that require signatures */
14
+ requireSignaturesFor?: MessageType[];
15
+ /** Reject messages with missing signatures (vs just warn) */
16
+ strictMode?: boolean;
17
+ }
18
+ /**
19
+ * Result of signature verification
20
+ */
21
+ export interface VerificationResult {
22
+ /** Whether the signature is valid */
23
+ valid: boolean;
24
+ /** Recovered address from signature (if signature present) */
25
+ recoveredAddress?: Address;
26
+ /** Reason for failure (if not valid) */
27
+ reason?: string;
28
+ /** Whether signature was missing */
29
+ signatureMissing: boolean;
30
+ /** Whether address is in trusted whitelist (if whitelist configured) */
31
+ isTrusted?: boolean;
32
+ }
33
+ /**
34
+ * Signature verifier for authenticating message origins
35
+ * Prevents spoofing attacks by verifying Ethereum signatures on messages
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * const verifier = new SignatureVerifier({
40
+ * trustedAddresses: ['0x123...', '0x456...'],
41
+ * requireSignaturesFor: ['task_response', 'agent_selected'],
42
+ * strictMode: true
43
+ * });
44
+ *
45
+ * const result = await verifier.verify(message);
46
+ * if (!result.valid) {
47
+ * console.log(`Verification failed: ${result.reason}`);
48
+ * }
49
+ * ```
50
+ */
51
+ export declare class SignatureVerifier {
52
+ private readonly options;
53
+ /**
54
+ * Creates a new signature verifier
55
+ *
56
+ * @param options - Verification options
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * const verifier = new SignatureVerifier({
61
+ * trustedAddresses: ['0x123...'],
62
+ * requireSignaturesFor: ['task_response'],
63
+ * strictMode: false
64
+ * });
65
+ * ```
66
+ */
67
+ constructor(options?: SignatureVerificationOptions);
68
+ /**
69
+ * Verify a message's signature
70
+ *
71
+ * @param message - The message to verify
72
+ * @returns Verification result with validity and recovered address
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * const result = await verifier.verify(message);
77
+ * if (result.valid) {
78
+ * console.log(`Valid signature from ${result.recoveredAddress}`);
79
+ * } else {
80
+ * console.log(`Invalid: ${result.reason}`);
81
+ * }
82
+ * ```
83
+ */
84
+ verify(message: BaseMessage): Promise<VerificationResult>;
85
+ /**
86
+ * Create a canonical hash of message content for signing
87
+ *
88
+ * @param content - The signable content object
89
+ * @returns Message hash string
90
+ */
91
+ createMessageHash(content: object): string;
92
+ /**
93
+ * Extract signable content from message
94
+ * Excludes signature and publicKey fields to prevent circular dependency
95
+ *
96
+ * @param message - The message to extract content from
97
+ * @returns Object containing signable fields
98
+ */
99
+ getSignableContent(message: BaseMessage): object;
100
+ /**
101
+ * Check if signature is required for a message type
102
+ *
103
+ * @param messageType - The type of message
104
+ * @returns True if signature is required
105
+ */
106
+ isSignatureRequired(messageType: MessageType): boolean;
107
+ /**
108
+ * Check if an address is in the trusted whitelist
109
+ *
110
+ * @param address - The address to check
111
+ * @returns True if address is trusted (or no whitelist configured)
112
+ */
113
+ isTrustedAddress(address: Address): boolean;
114
+ /**
115
+ * Get the address to verify against
116
+ * Tries publicKey first, falls back to 'from' field
117
+ *
118
+ * @param message - The message to get address from
119
+ * @returns Address to verify, or undefined if none available
120
+ */
121
+ private getVerificationAddress;
122
+ /**
123
+ * Update verification options
124
+ *
125
+ * @param options - New options (merged with existing)
126
+ *
127
+ * @example
128
+ * ```typescript
129
+ * verifier.updateOptions({
130
+ * trustedAddresses: ['0x789...'],
131
+ * strictMode: true
132
+ * });
133
+ * ```
134
+ */
135
+ updateOptions(options: Partial<SignatureVerificationOptions>): void;
136
+ /**
137
+ * Get current verification options
138
+ *
139
+ * @returns Copy of current options
140
+ */
141
+ getOptions(): SignatureVerificationOptions;
142
+ }
143
+ //# sourceMappingURL=signature-verifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signature-verifier.d.ts","sourceRoot":"","sources":["../../src/utils/signature-verifier.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAA8B,KAAK,OAAO,EAAE,MAAM,MAAM,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,+DAA+D;IAC/D,gBAAgB,CAAC,EAAE,OAAO,EAAE,CAAC;IAE7B,4CAA4C;IAC5C,oBAAoB,CAAC,EAAE,WAAW,EAAE,CAAC;IAErC,6DAA6D;IAC7D,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,qCAAqC;IACrC,KAAK,EAAE,OAAO,CAAC;IAEf,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,oCAAoC;IACpC,gBAAgB,EAAE,OAAO,CAAC;IAE1B,wEAAwE;IACxE,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyC;IAEjE;;;;;;;;;;;;;OAaG;gBACS,OAAO,GAAE,4BAAiC;IAQtD;;;;;;;;;;;;;;;OAeG;IACU,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA8EtE;;;;;OAKG;IACI,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAQjD;;;;;;OAMG;IACI,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM;IAcvD;;;;;OAKG;IACI,mBAAmB,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO;IAI7D;;;;;OAKG;IACI,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAUlD;;;;;;OAMG;YACW,sBAAsB;IAiBpC;;;;;;;;;;;;OAYG;IACI,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,4BAA4B,CAAC,GAAG,IAAI;IAY1E;;;;OAIG;IACI,UAAU,IAAI,4BAA4B;CAGlD"}
@@ -0,0 +1,238 @@
1
+ "use strict";
2
+ /**
3
+ * Signature Verifier for Message Authentication
4
+ * Provides cryptographic verification of message signatures using Ethereum ECDSA
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.SignatureVerifier = void 0;
8
+ const viem_1 = require("viem");
9
+ /**
10
+ * Signature verifier for authenticating message origins
11
+ * Prevents spoofing attacks by verifying Ethereum signatures on messages
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const verifier = new SignatureVerifier({
16
+ * trustedAddresses: ['0x123...', '0x456...'],
17
+ * requireSignaturesFor: ['task_response', 'agent_selected'],
18
+ * strictMode: true
19
+ * });
20
+ *
21
+ * const result = await verifier.verify(message);
22
+ * if (!result.valid) {
23
+ * console.log(`Verification failed: ${result.reason}`);
24
+ * }
25
+ * ```
26
+ */
27
+ class SignatureVerifier {
28
+ /**
29
+ * Creates a new signature verifier
30
+ *
31
+ * @param options - Verification options
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const verifier = new SignatureVerifier({
36
+ * trustedAddresses: ['0x123...'],
37
+ * requireSignaturesFor: ['task_response'],
38
+ * strictMode: false
39
+ * });
40
+ * ```
41
+ */
42
+ constructor(options = {}) {
43
+ this.options = {
44
+ trustedAddresses: options.trustedAddresses || [],
45
+ requireSignaturesFor: options.requireSignaturesFor || [],
46
+ strictMode: options.strictMode !== undefined ? options.strictMode : false
47
+ };
48
+ }
49
+ /**
50
+ * Verify a message's signature
51
+ *
52
+ * @param message - The message to verify
53
+ * @returns Verification result with validity and recovered address
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * const result = await verifier.verify(message);
58
+ * if (result.valid) {
59
+ * console.log(`Valid signature from ${result.recoveredAddress}`);
60
+ * } else {
61
+ * console.log(`Invalid: ${result.reason}`);
62
+ * }
63
+ * ```
64
+ */
65
+ async verify(message) {
66
+ // Check if signature is present
67
+ if (!message.signature) {
68
+ const isRequired = this.isSignatureRequired(message.type);
69
+ return {
70
+ valid: !isRequired && !this.options.strictMode,
71
+ signatureMissing: true,
72
+ reason: isRequired
73
+ ? `Signature required for message type '${message.type}'`
74
+ : 'Signature missing but not required'
75
+ };
76
+ }
77
+ // Extract signable content (excludes signature and publicKey fields)
78
+ const signableContent = this.getSignableContent(message);
79
+ // Create canonical message hash
80
+ const messageHash = this.createMessageHash(signableContent);
81
+ try {
82
+ // Determine which address to verify against
83
+ const addressToVerify = await this.getVerificationAddress(message);
84
+ if (!addressToVerify) {
85
+ return {
86
+ valid: false,
87
+ signatureMissing: false,
88
+ reason: 'No address available for verification (missing publicKey and from fields)'
89
+ };
90
+ }
91
+ // Verify signature using viem
92
+ const isValid = await (0, viem_1.verifyMessage)({
93
+ address: addressToVerify,
94
+ message: messageHash,
95
+ signature: message.signature
96
+ });
97
+ if (!isValid) {
98
+ return {
99
+ valid: false,
100
+ recoveredAddress: addressToVerify,
101
+ signatureMissing: false,
102
+ reason: 'Signature verification failed - signature does not match message content'
103
+ };
104
+ }
105
+ // Check if address is trusted (if whitelist configured)
106
+ const isTrusted = this.isTrustedAddress(addressToVerify);
107
+ // If whitelist is configured and address is not trusted, reject
108
+ if (this.options.trustedAddresses.length > 0 && !isTrusted) {
109
+ return {
110
+ valid: false,
111
+ recoveredAddress: addressToVerify,
112
+ signatureMissing: false,
113
+ isTrusted: false,
114
+ reason: `Address ${addressToVerify} is not in trusted whitelist`
115
+ };
116
+ }
117
+ return {
118
+ valid: true,
119
+ recoveredAddress: addressToVerify,
120
+ signatureMissing: false,
121
+ isTrusted
122
+ };
123
+ }
124
+ catch (error) {
125
+ return {
126
+ valid: false,
127
+ signatureMissing: false,
128
+ reason: `Signature verification error: ${error instanceof Error ? error.message : String(error)}`
129
+ };
130
+ }
131
+ }
132
+ /**
133
+ * Create a canonical hash of message content for signing
134
+ *
135
+ * @param content - The signable content object
136
+ * @returns Message hash string
137
+ */
138
+ createMessageHash(content) {
139
+ // Create canonical JSON string (sorted keys for consistency)
140
+ const canonical = JSON.stringify(content, Object.keys(content).sort());
141
+ // Use viem's hashMessage for Ethereum-compatible hashing
142
+ return (0, viem_1.hashMessage)(canonical);
143
+ }
144
+ /**
145
+ * Extract signable content from message
146
+ * Excludes signature and publicKey fields to prevent circular dependency
147
+ *
148
+ * @param message - The message to extract content from
149
+ * @returns Object containing signable fields
150
+ */
151
+ getSignableContent(message) {
152
+ const { signature, publicKey, id, ...signableContent } = message;
153
+ // Include only defined fields for consistent hashing
154
+ const filtered = {};
155
+ for (const [key, value] of Object.entries(signableContent)) {
156
+ if (value !== undefined) {
157
+ filtered[key] = value;
158
+ }
159
+ }
160
+ return filtered;
161
+ }
162
+ /**
163
+ * Check if signature is required for a message type
164
+ *
165
+ * @param messageType - The type of message
166
+ * @returns True if signature is required
167
+ */
168
+ isSignatureRequired(messageType) {
169
+ return this.options.requireSignaturesFor.includes(messageType);
170
+ }
171
+ /**
172
+ * Check if an address is in the trusted whitelist
173
+ *
174
+ * @param address - The address to check
175
+ * @returns True if address is trusted (or no whitelist configured)
176
+ */
177
+ isTrustedAddress(address) {
178
+ if (this.options.trustedAddresses.length === 0) {
179
+ return true; // No whitelist = trust all
180
+ }
181
+ return this.options.trustedAddresses.some(trusted => trusted.toLowerCase() === address.toLowerCase());
182
+ }
183
+ /**
184
+ * Get the address to verify against
185
+ * Tries publicKey first, falls back to 'from' field
186
+ *
187
+ * @param message - The message to get address from
188
+ * @returns Address to verify, or undefined if none available
189
+ */
190
+ async getVerificationAddress(message) {
191
+ // If message includes publicKey, derive address from it
192
+ if (message.publicKey) {
193
+ // publicKey should be an Ethereum address already
194
+ // If it's actually a public key, we'd need to derive the address
195
+ // For now, assume publicKey field contains the address
196
+ return message.publicKey;
197
+ }
198
+ // Fall back to 'from' field if it looks like an address
199
+ if (message.from && message.from.startsWith('0x') && message.from.length === 42) {
200
+ return message.from;
201
+ }
202
+ return undefined;
203
+ }
204
+ /**
205
+ * Update verification options
206
+ *
207
+ * @param options - New options (merged with existing)
208
+ *
209
+ * @example
210
+ * ```typescript
211
+ * verifier.updateOptions({
212
+ * trustedAddresses: ['0x789...'],
213
+ * strictMode: true
214
+ * });
215
+ * ```
216
+ */
217
+ updateOptions(options) {
218
+ if (options.trustedAddresses !== undefined) {
219
+ this.options.trustedAddresses = options.trustedAddresses;
220
+ }
221
+ if (options.requireSignaturesFor !== undefined) {
222
+ this.options.requireSignaturesFor = options.requireSignaturesFor;
223
+ }
224
+ if (options.strictMode !== undefined) {
225
+ this.options.strictMode = options.strictMode;
226
+ }
227
+ }
228
+ /**
229
+ * Get current verification options
230
+ *
231
+ * @returns Copy of current options
232
+ */
233
+ getOptions() {
234
+ return { ...this.options };
235
+ }
236
+ }
237
+ exports.SignatureVerifier = SignatureVerifier;
238
+ //# sourceMappingURL=signature-verifier.js.map