@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 @@
1
+ {"version":3,"file":"signature-verifier.js","sourceRoot":"","sources":["../../src/utils/signature-verifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * SSRF (Server-Side Request Forgery) Validator
3
+ * Prevents webhook URLs from pointing to internal/private network resources
4
+ *
5
+ * This utility blocks:
6
+ * - Private IP ranges (RFC1918: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
7
+ * - Loopback addresses (127.0.0.0/8, ::1)
8
+ * - Link-local addresses (169.254.0.0/16, fe80::/10)
9
+ * - Cloud metadata endpoints (AWS, GCP, Azure, DigitalOcean)
10
+ * - IPv6 private ranges (fc00::/7, fd00::/8)
11
+ * - Multicast and broadcast addresses
12
+ */
13
+ /**
14
+ * Check if an IP address is in a private range
15
+ * Supports both IPv4 and IPv6
16
+ */
17
+ export declare function isPrivateIP(hostname: string): boolean;
18
+ /**
19
+ * Check if a hostname is a blocked cloud metadata endpoint
20
+ */
21
+ export declare function isCloudMetadataEndpoint(hostname: string): boolean;
22
+ /**
23
+ * Check if a hostname is an allowed localhost exception
24
+ * Only true localhost addresses, not bind-all addresses
25
+ */
26
+ export declare function isLocalhostException(hostname: string): boolean;
27
+ /**
28
+ * Validate a webhook URL for SSRF vulnerabilities
29
+ * Throws an error if the URL is unsafe
30
+ *
31
+ * @param url - The webhook URL to validate
32
+ * @param allowLocalhost - Whether to allow localhost URLs (for development)
33
+ * @throws Error if URL is unsafe or invalid
34
+ */
35
+ export declare function validateWebhookUrl(url: string, allowLocalhost?: boolean): void;
36
+ //# sourceMappingURL=ssrf-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssrf-validator.d.ts","sourceRoot":"","sources":["../../src/utils/ssrf-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAyCH;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAqCrD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAOjE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAI9D;AAkBD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,GAAE,OAAe,GAAG,IAAI,CAkFrF"}
@@ -0,0 +1,195 @@
1
+ "use strict";
2
+ /**
3
+ * SSRF (Server-Side Request Forgery) Validator
4
+ * Prevents webhook URLs from pointing to internal/private network resources
5
+ *
6
+ * This utility blocks:
7
+ * - Private IP ranges (RFC1918: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
8
+ * - Loopback addresses (127.0.0.0/8, ::1)
9
+ * - Link-local addresses (169.254.0.0/16, fe80::/10)
10
+ * - Cloud metadata endpoints (AWS, GCP, Azure, DigitalOcean)
11
+ * - IPv6 private ranges (fc00::/7, fd00::/8)
12
+ * - Multicast and broadcast addresses
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.isPrivateIP = isPrivateIP;
16
+ exports.isCloudMetadataEndpoint = isCloudMetadataEndpoint;
17
+ exports.isLocalhostException = isLocalhostException;
18
+ exports.validateWebhookUrl = validateWebhookUrl;
19
+ const url_1 = require("url");
20
+ /**
21
+ * Blocked hostnames that should never be accessible via webhooks
22
+ * Includes cloud provider metadata endpoints and localhost variations
23
+ */
24
+ const BLOCKED_HOSTNAMES = [
25
+ // AWS metadata endpoints
26
+ "169.254.169.254",
27
+ "fd00:ec2::254",
28
+ "instance-data",
29
+ "instance-data.ec2.internal",
30
+ // Google Cloud metadata
31
+ "metadata.google.internal",
32
+ "metadata.google.com",
33
+ // Azure metadata
34
+ "169.254.169.254", // Same as AWS
35
+ // DigitalOcean metadata
36
+ "169.254.169.254", // Same as AWS/Azure
37
+ // Kubernetes metadata
38
+ "kubernetes.default",
39
+ "kubernetes.default.svc",
40
+ "kubernetes.default.svc.cluster.local",
41
+ // Localhost bind-all (not safe for webhooks)
42
+ "0.0.0.0",
43
+ "[::]",
44
+ "::"
45
+ ];
46
+ /**
47
+ * Localhost hostnames that are allowed for development
48
+ */
49
+ const LOCALHOST_HOSTNAMES = ["localhost", "127.0.0.1", "::1", "[::1]"];
50
+ /**
51
+ * Check if an IP address is in a private range
52
+ * Supports both IPv4 and IPv6
53
+ */
54
+ function isPrivateIP(hostname) {
55
+ // Remove IPv6 brackets if present
56
+ const cleanHostname = hostname.replace(/^\[|\]$/g, "");
57
+ // IPv4 private ranges (RFC1918)
58
+ if (/^10\./.test(cleanHostname))
59
+ return true;
60
+ if (/^192\.168\./.test(cleanHostname))
61
+ return true;
62
+ if (/^172\.(1[6-9]|2[0-9]|3[0-1])\./.test(cleanHostname))
63
+ return true; // 172.16-31
64
+ // IPv4 loopback (127.0.0.0/8)
65
+ if (/^127\./.test(cleanHostname))
66
+ return true;
67
+ // IPv4 link-local (169.254.0.0/16)
68
+ if (/^169\.254\./.test(cleanHostname))
69
+ return true;
70
+ // IPv4 multicast (224.0.0.0/4)
71
+ if (/^2(2[4-9]|3[0-9])\./.test(cleanHostname))
72
+ return true;
73
+ // IPv4 broadcast
74
+ if (cleanHostname === "255.255.255.255")
75
+ return true;
76
+ // IPv6 private ranges
77
+ // Link-local (fe80::/10)
78
+ if (/^fe[89ab][0-9a-f]:/i.test(cleanHostname))
79
+ return true;
80
+ // Unique local addresses (fc00::/7)
81
+ if (/^f[cd][0-9a-f]{2}:/i.test(cleanHostname))
82
+ return true;
83
+ // IPv6 loopback (::1)
84
+ if (cleanHostname === "::1")
85
+ return true;
86
+ if (cleanHostname === "0:0:0:0:0:0:0:1")
87
+ return true;
88
+ // IPv6 unspecified (::)
89
+ if (cleanHostname === "::")
90
+ return true;
91
+ if (cleanHostname === "0:0:0:0:0:0:0:0")
92
+ return true;
93
+ return false;
94
+ }
95
+ /**
96
+ * Check if a hostname is a blocked cloud metadata endpoint
97
+ */
98
+ function isCloudMetadataEndpoint(hostname) {
99
+ const cleanHostname = hostname.toLowerCase().replace(/^\[|\]$/g, "");
100
+ return BLOCKED_HOSTNAMES.some((blocked) => cleanHostname === blocked.toLowerCase() || cleanHostname.endsWith(`.${blocked.toLowerCase()}`));
101
+ }
102
+ /**
103
+ * Check if a hostname is an allowed localhost exception
104
+ * Only true localhost addresses, not bind-all addresses
105
+ */
106
+ function isLocalhostException(hostname) {
107
+ const cleanHostname = hostname.toLowerCase().replace(/^\[|\]$/g, "");
108
+ return LOCALHOST_HOSTNAMES.some((allowed) => cleanHostname === allowed.toLowerCase());
109
+ }
110
+ /**
111
+ * Check if hostname resolves to a Kubernetes service
112
+ * Blocks internal k8s service discovery
113
+ */
114
+ function isKubernetesService(hostname) {
115
+ const cleanHostname = hostname.toLowerCase();
116
+ // Block .svc, .svc.cluster, .svc.cluster.local
117
+ if (cleanHostname.includes(".svc"))
118
+ return true;
119
+ // Block direct kubernetes service names
120
+ if (cleanHostname.startsWith("kubernetes"))
121
+ return true;
122
+ return false;
123
+ }
124
+ /**
125
+ * Validate a webhook URL for SSRF vulnerabilities
126
+ * Throws an error if the URL is unsafe
127
+ *
128
+ * @param url - The webhook URL to validate
129
+ * @param allowLocalhost - Whether to allow localhost URLs (for development)
130
+ * @throws Error if URL is unsafe or invalid
131
+ */
132
+ function validateWebhookUrl(url, allowLocalhost = false) {
133
+ let parsed;
134
+ try {
135
+ parsed = new url_1.URL(url);
136
+ }
137
+ catch (error) {
138
+ throw new Error(`Invalid webhook URL: ${error.message}`);
139
+ }
140
+ const hostname = parsed.hostname;
141
+ // Check protocol first (basic validation)
142
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
143
+ throw new Error(`Webhook URL must use HTTP or HTTPS protocol (got: ${parsed.protocol})`);
144
+ }
145
+ // Block cloud metadata endpoints FIRST (before any other checks)
146
+ if (isCloudMetadataEndpoint(hostname)) {
147
+ throw new Error(`Webhook URL blocked for security: ${hostname} is a cloud metadata endpoint. ` +
148
+ "This could expose sensitive credentials and secrets.");
149
+ }
150
+ // Block Kubernetes services
151
+ if (isKubernetesService(hostname)) {
152
+ throw new Error(`Webhook URL blocked for security: ${hostname} appears to be a Kubernetes service. ` +
153
+ "Internal service discovery is not allowed for webhooks.");
154
+ }
155
+ // Check localhost BEFORE private IP check (localhost is specific case of private IP)
156
+ if (isLocalhostException(hostname)) {
157
+ if (allowLocalhost) {
158
+ return; // Localhost is allowed for development
159
+ }
160
+ else {
161
+ throw new Error(`Webhook URL blocked: ${hostname} is a localhost address. ` +
162
+ "Set allowInsecureWebhooks=true to allow localhost webhooks for testing.");
163
+ }
164
+ }
165
+ // Block private IP ranges
166
+ if (isPrivateIP(hostname)) {
167
+ throw new Error(`Webhook URL blocked for security: ${hostname} is a private IP address. ` +
168
+ "Webhooks cannot point to internal network resources. " +
169
+ "Use a publicly accessible endpoint or set allowInsecureWebhooks=true for testing.");
170
+ }
171
+ // For non-HTTPS, only allow localhost (which already passed checks above)
172
+ if (parsed.protocol === "http:") {
173
+ throw new Error("Webhook URL must use HTTPS for non-localhost endpoints. " +
174
+ "Use HTTPS or set allowInsecureWebhooks=true for testing with localhost.");
175
+ }
176
+ // Additional safety: block ports that are commonly internal
177
+ if (parsed.port) {
178
+ const port = parseInt(parsed.port, 10);
179
+ const dangerousPorts = [
180
+ 22, // SSH
181
+ 23, // Telnet
182
+ 25, // SMTP
183
+ 3306, // MySQL
184
+ 5432, // PostgreSQL
185
+ 6379, // Redis
186
+ 9200, // Elasticsearch
187
+ 27017 // MongoDB
188
+ ];
189
+ if (dangerousPorts.includes(port)) {
190
+ throw new Error(`Webhook URL blocked for security: Port ${port} is commonly used for internal services. ` +
191
+ "Use a different port or set allowInsecureWebhooks=true for testing.");
192
+ }
193
+ }
194
+ }
195
+ //# sourceMappingURL=ssrf-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssrf-validator.js","sourceRoot":"","sources":["../../src/utils/ssrf-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ # Teneo SDK Examples - Environment Configuration
2
+ # Copy this file to .env and fill in your actual values
3
+
4
+ # Required: WebSocket URL for Teneo network
5
+ WS_URL=wss://developer.chatroom.teneo-protocol.ai/ws
6
+
7
+ # Required: Your Ethereum private key (keep this secret!)
8
+ PRIVATE_KEY=your-private-key-here
9
+
10
+ # Optional: Your wallet address (auto-derived from private key if not provided)
11
+ WALLET_ADDRESS=0x...
12
+
13
+ # Optional: Default room to join on connection
14
+ DEFAULT_ROOM=general
15
+
16
+ # Optional: Additional room ID (for multi-room examples)
17
+ ROOM_ID=your-room-id-here
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Basic usage example for Teneo Protocol SDK
3
+ * Demonstrates connection, authentication, and sending messages to agents
4
+ */
5
+
6
+ import { TeneoSDK, SDKConfigBuilder, SecurePrivateKey } from "../src";
7
+
8
+ // Load configuration from environment variables
9
+ const WS_URL =
10
+ process.env.WS_URL;
11
+ const PRIVATE_KEY = process.env.PRIVATE_KEY || "";
12
+ const WALLET_ADDRESS = process.env.WALLET_ADDRESS;
13
+ const DEFAULT_ROOM = process.env.DEFAULT_ROOM || "general";
14
+
15
+ async function main() {
16
+ // Validate required configuration
17
+ if (!PRIVATE_KEY) {
18
+ console.error("ERROR: PRIVATE_KEY environment variable is required");
19
+ console.error("Set it with: export PRIVATE_KEY='your-private-key'");
20
+ process.exit(1);
21
+ }
22
+
23
+ // SEC-3: Encrypt private key in memory for enhanced security
24
+ const secureKey = new SecurePrivateKey(PRIVATE_KEY);
25
+ console.log("✓ Private key encrypted in memory (SEC-3)");
26
+
27
+ // Build configuration using fluent API
28
+ const config = new SDKConfigBuilder()
29
+ .withWebSocketUrl(WS_URL)
30
+ .withAuthentication(secureKey, WALLET_ADDRESS) // Use encrypted key
31
+ .withAutoJoinRooms([DEFAULT_ROOM]) // Auto-join default room on connect
32
+ .withReconnection({ enabled: true, delay: 5000, maxAttempts: 10 }) // Enable reconnection
33
+ .withResponseFormat({ format: "both", includeMetadata: true }) // Get both raw and humanized responses with metadata
34
+ .withLogging("debug") // Enable debug logging
35
+ .build();
36
+
37
+ // Create SDK instance
38
+ const sdk = new TeneoSDK(config);
39
+
40
+ // Set up event listeners
41
+ setupEventListeners(sdk);
42
+
43
+ try {
44
+ // Connect to Teneo network
45
+ console.log("\n→ Connecting to Teneo network...");
46
+ await sdk.connect();
47
+ console.log("✓ SDK is connected and authenticated!");
48
+
49
+ // Show current subscriptions
50
+ const subscribed = sdk.getSubscribedRooms();
51
+ console.log(
52
+ `\n→ Currently subscribed to ${subscribed.length} room(s): ${subscribed.join(", ")}`
53
+ );
54
+
55
+ // Subscribe to additional room if available
56
+ const rooms = sdk.getRooms();
57
+ if (rooms.length > 1) {
58
+ const additionalRoom = rooms.find((r) => r.id !== DEFAULT_ROOM);
59
+ if (additionalRoom) {
60
+ console.log(
61
+ `\n→ Subscribing to additional room: ${additionalRoom.name || additionalRoom.id}`
62
+ );
63
+ await sdk.subscribeToRoom(additionalRoom.id);
64
+
65
+ // Show updated subscriptions
66
+ const updatedSubscriptions = sdk.getSubscribedRooms();
67
+ console.log(`✓ Now subscribed to: ${updatedSubscriptions.join(", ")}`);
68
+ }
69
+ }
70
+
71
+ // Get list of available agents
72
+ const agents = sdk.getAgents();
73
+ console.log(`\n→ Available agents: ${agents.length}`);
74
+ agents.forEach((agent) => {
75
+ console.log(` • ${agent.name}: ${agent.description || "No description"}`);
76
+ });
77
+
78
+ // PERF-3: Demonstrate indexed agent lookups (O(1) complexity)
79
+ console.log("\n→ Testing indexed agent lookups (PERF-3):");
80
+
81
+ // Search by capability (O(1))
82
+ const weatherAgents = sdk.findAgentsByCapability("weather-forecast");
83
+ if (weatherAgents.length > 0) {
84
+ console.log(` ✓ Found ${weatherAgents.length} agent(s) with weather capability`);
85
+ }
86
+
87
+ // Search by name (O(k) where k = tokens)
88
+ const searchResults = sdk.findAgentsByName("agent");
89
+ if (searchResults.length > 0) {
90
+ console.log(` ✓ Found ${searchResults.length} agent(s) matching name search`);
91
+ }
92
+
93
+ // Search by status (O(1))
94
+ const onlineAgents = sdk.findAgentsByStatus("online");
95
+ console.log(` ✓ ${onlineAgents.length} agent(s) currently online`);
96
+
97
+ // Send message to the room
98
+ console.log("\n→ Sending message to room...");
99
+ const response = await sdk.sendMessage("Hello from the Teneo SDK!", {
100
+ room: DEFAULT_ROOM,
101
+ waitForResponse: true,
102
+ timeout: 30000
103
+ });
104
+
105
+ if (response && response.humanized) {
106
+ console.log("✓ Response received:", response.humanized.substring(0, 200));
107
+ } else if (response) {
108
+ console.log("✓ Response received (no humanized content)");
109
+ }
110
+
111
+ // Wait for some messages
112
+ console.log("\n→ Listening for messages (press Ctrl+C to exit)...");
113
+ console.log(" Watch the event logs above for real-time updates");
114
+ await new Promise((resolve) => setTimeout(resolve, 60000));
115
+ } catch (error) {
116
+ console.error("\n✗ Error:", error);
117
+ } finally {
118
+ // Clean up
119
+ console.log("\n→ Disconnecting...");
120
+ sdk.disconnect();
121
+ sdk.destroy();
122
+ console.log("✓ Cleanup complete");
123
+ }
124
+ }
125
+
126
+ function setupEventListeners(sdk: TeneoSDK) {
127
+ // Connection events
128
+ sdk.on("connection:open", () => {
129
+ console.log("[CONNECTION] Connected to WebSocket");
130
+ });
131
+
132
+ sdk.on("connection:close", (code, reason) => {
133
+ console.log(`[CONNECTION] Disconnected: ${code} - ${reason}`);
134
+ });
135
+
136
+ sdk.on("connection:reconnecting", (attempt) => {
137
+ console.log(`[CONNECTION] Reconnecting... (attempt ${attempt})`);
138
+ });
139
+
140
+ sdk.on("connection:reconnected", () => {
141
+ console.log("[CONNECTION] Reconnected successfully");
142
+ });
143
+
144
+ // Authentication events
145
+ sdk.on("auth:challenge", (challenge) => {
146
+ console.log(`[AUTH] Authentication challenge received: ${challenge.substring(0, 10)}...`);
147
+ });
148
+
149
+ sdk.on("auth:success", (state) => {
150
+ console.log(`[AUTH] Authenticated as: ${state.walletAddress}`);
151
+ console.log(`[AUTH] Whitelisted: ${state.isWhitelisted}`);
152
+ console.log(`[AUTH] Rooms: ${state.rooms?.join(", ") || "None"}`);
153
+ });
154
+
155
+ sdk.on("auth:error", (error) => {
156
+ console.log(`[AUTH] Authentication failed: ${error}`);
157
+ });
158
+
159
+ // Agent events
160
+ sdk.on("agent:selected", (data) => {
161
+ console.log(`\n[AGENT] Coordinator selected: ${data.agentName}`);
162
+ console.log(`[AGENT] Reasoning: ${data.reasoning}`);
163
+ if (data.command) {
164
+ console.log(`[AGENT] Command: ${data.command}`);
165
+ }
166
+ });
167
+
168
+ sdk.on("agent:response", (response) => {
169
+ console.log(`\n[AGENT] Response from ${response.agentName || response.agentId}:`);
170
+ console.log(`[AGENT] Content: ${response.humanized || response.content}`);
171
+ if (response.error) {
172
+ console.log(`[AGENT] Error: ${response.error}`);
173
+ }
174
+ });
175
+
176
+ sdk.on("agent:list", (agents) => {
177
+ console.log(`\n[AGENT] Agent list updated: ${agents.length} agents`);
178
+ });
179
+
180
+ // Room events
181
+ sdk.on("room:subscribed", (data) => {
182
+ console.log(`[ROOM] Subscribed to room: ${data.roomId}`);
183
+ });
184
+
185
+ sdk.on("room:unsubscribed", (data) => {
186
+ console.log(`[ROOM] Unsubscribed from room: ${data.roomId}`);
187
+ });
188
+
189
+ // Webhook events
190
+ sdk.on("webhook:sent", (_payload, url) => {
191
+ console.log(`[WEBHOOK] Webhook sent to ${url}`);
192
+ });
193
+
194
+ sdk.on("webhook:error", (error, url) => {
195
+ console.log(`[WEBHOOK] Webhook error for ${url}: ${error.message}`);
196
+ });
197
+
198
+ // Error events
199
+ sdk.on("error", (error) => {
200
+ console.error(`[ERROR] SDK Error: ${error.message}`);
201
+ });
202
+
203
+ sdk.on("warning", (warning) => {
204
+ console.warn(`[WARNING] ${warning}`);
205
+ });
206
+ }
207
+
208
+ // Run the example
209
+ if (require.main === module) {
210
+ main().catch(console.error);
211
+ }
@@ -0,0 +1,153 @@
1
+ # Teneo Production Dashboard - Environment Configuration
2
+ # Copy this file to .env and fill in your values
3
+
4
+ # ============================================================================
5
+ # REQUIRED: Teneo Network Connection
6
+ # ============================================================================
7
+
8
+ # WebSocket URL for Teneo AI Network
9
+ WS_URL=wss://developer.chatroom.teneo-protocol.ai/ws
10
+
11
+ # Ethereum Private Key (with 0x prefix)
12
+ # IMPORTANT: Never commit your actual private key to version control!
13
+ PRIVATE_KEY=0x
14
+
15
+ # Ethereum Wallet Address (with 0x prefix)
16
+ # If not provided, will be derived from the private key
17
+ WALLET_ADDRESS=0x
18
+
19
+ # ============================================================================
20
+ # OPTIONAL: Room Configuration
21
+ # ============================================================================
22
+
23
+ # Default room to join on connection
24
+ # Leave empty to not auto-join any room
25
+ DEFAULT_ROOM=general
26
+
27
+ # Comma-separated list of rooms to auto-join
28
+ # Example: general,support,tech-help
29
+ # AUTO_JOIN_ROOMS=general,support
30
+
31
+ # ============================================================================
32
+ # OPTIONAL: Server Configuration
33
+ # ============================================================================
34
+
35
+ # Port for the dashboard server (default: 3000)
36
+ PORT=3000
37
+
38
+ # Node environment (development | production)
39
+ NODE_ENV=development
40
+
41
+ # ============================================================================
42
+ # OPTIONAL: Security Features
43
+ # ============================================================================
44
+
45
+ # Enable message signature verification (true | false)
46
+ # Verifies Ethereum signatures on incoming messages from agents
47
+ # Recommended: true for production
48
+ ENABLE_SIGNATURE_VERIFICATION=false
49
+
50
+ # Comma-separated list of trusted agent Ethereum addresses
51
+ # Only messages signed by these addresses will be accepted (if verification enabled)
52
+ # Leave empty to allow all signed messages
53
+ # Example: 0xAgent1...,0xAgent2...,0xAgent3...
54
+ TRUSTED_ADDRESSES=
55
+
56
+ # Require signatures for specific message types (comma-separated)
57
+ # Options: task_response,agent_selected,message,error
58
+ # Default: task_response,agent_selected
59
+ # REQUIRE_SIGNATURES_FOR=task_response,agent_selected
60
+
61
+ # Strict signature mode (true | false)
62
+ # true: Reject ALL unsigned messages
63
+ # false: Warn about unsigned messages but allow them
64
+ # STRICT_SIGNATURE_MODE=false
65
+
66
+ # ============================================================================
67
+ # OPTIONAL: Webhook Configuration
68
+ # ============================================================================
69
+
70
+ # Webhook URL to receive SDK events
71
+ # Auto-configured to localhost for development
72
+ # For production, use your publicly accessible webhook endpoint
73
+ # Example: https://api.example.com/webhooks/teneo
74
+ WEBHOOK_URL=http://localhost:3000/webhook
75
+
76
+ # Webhook authentication header (optional)
77
+ # WEBHOOK_AUTH_TOKEN=your-secret-token
78
+
79
+ # Max webhook retries on failure (0-10)
80
+ WEBHOOK_RETRIES=3
81
+
82
+ # Webhook timeout in milliseconds (1000-60000)
83
+ WEBHOOK_TIMEOUT=10000
84
+
85
+ # ============================================================================
86
+ # OPTIONAL: SDK Performance Tuning
87
+ # ============================================================================
88
+
89
+ # Enable agent caching (true | false)
90
+ ENABLE_CACHE=true
91
+
92
+ # Cache timeout in milliseconds (default: 300000 = 5 minutes)
93
+ CACHE_TIMEOUT=300000
94
+
95
+ # Maximum cache size (default: 100)
96
+ MAX_CACHE_SIZE=100
97
+
98
+ # ============================================================================
99
+ # OPTIONAL: Connection Settings
100
+ # ============================================================================
101
+
102
+ # Enable automatic reconnection (true | false)
103
+ ENABLE_RECONNECTION=true
104
+
105
+ # Reconnection delay in milliseconds (100-60000)
106
+ RECONNECT_DELAY=5000
107
+
108
+ # Maximum reconnection attempts (0-100, 0 = infinite)
109
+ MAX_RECONNECT_ATTEMPTS=10
110
+
111
+ # Connection timeout in milliseconds (1000-120000)
112
+ CONNECTION_TIMEOUT=30000
113
+
114
+ # ============================================================================
115
+ # OPTIONAL: Logging
116
+ # ============================================================================
117
+
118
+ # Log level (debug | info | warn | error | silent)
119
+ # debug: Very verbose, shows all SDK operations
120
+ # info: Normal operations and important events
121
+ # warn: Warnings and potential issues
122
+ # error: Errors only
123
+ # silent: No logging
124
+ LOG_LEVEL=info
125
+
126
+ # ============================================================================
127
+ # NOTES
128
+ # ============================================================================
129
+
130
+ # 1. Environment Precedence:
131
+ # - Environment variables override .env file values
132
+ # - .env file overrides default SDK values
133
+ #
134
+ # 2. Security Best Practices:
135
+ # - Never commit .env file to git (already in .gitignore)
136
+ # - Use different private keys for dev/prod
137
+ # - Enable signature verification in production
138
+ # - Use HTTPS webhooks in production
139
+ #
140
+ # 3. Development Tips:
141
+ # - Set LOG_LEVEL=debug for troubleshooting
142
+ # - Disable signature verification for local testing
143
+ # - Use localhost webhooks for development
144
+ #
145
+ # 4. Production Checklist:
146
+ # ✓ Use production WebSocket URL
147
+ # ✓ Use secure private key (from secrets manager)
148
+ # ✓ Enable signature verification
149
+ # ✓ Set trusted agent addresses
150
+ # ✓ Use HTTPS webhook URLs
151
+ # ✓ Set LOG_LEVEL=info or warn
152
+ # ✓ Enable all security features
153
+ # ✓ Use environment variables (not .env file)
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@teneo/production-dashboard-example",
3
+ "version": "1.0.0",
4
+ "description": "Production-ready dashboard example for Teneo Protocol SDK using Hono and Bun",
5
+ "private": true,
6
+ "type": "module",
7
+ "scripts": {
8
+ "dev": "bun --watch server.ts",
9
+ "start": "bun run server.ts",
10
+ "build": "bun build server.ts --outdir dist --target bun",
11
+ "serve": "bun run dist/server.js"
12
+ },
13
+ "dependencies": {
14
+ "hono": "^4.0.0",
15
+ "@hono/node-server": "^1.8.0",
16
+ "dotenv": "^16.4.0"
17
+ },
18
+ "devDependencies": {
19
+ "@types/bun": "latest"
20
+ },
21
+ "engines": {
22
+ "bun": ">=1.0.0",
23
+ "node": ">=18.0.0"
24
+ },
25
+ "keywords": [
26
+ "teneo",
27
+ "sdk",
28
+ "dashboard",
29
+ "hono",
30
+ "bun",
31
+ "websocket",
32
+ "ai",
33
+ "agents",
34
+ "example",
35
+ "production"
36
+ ],
37
+ "author": "Teneo",
38
+ "license": "MIT"
39
+ }