@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,44 @@
1
+ /**
2
+ * Error code enum for Teneo Protocol SDK
3
+ * Provides type-safe error codes to prevent typos and enable autocomplete
4
+ */
5
+
6
+ export enum ErrorCode {
7
+ // SDK errors
8
+ SDK_DESTROYED = "SDK_DESTROYED",
9
+ NOT_CONNECTED = "NOT_CONNECTED",
10
+ INVALID_CONFIG = "INVALID_CONFIG",
11
+ CONFIG_ERROR = "CONFIG_ERROR",
12
+
13
+ // Connection errors
14
+ CONNECTION_ERROR = "CONNECTION_ERROR",
15
+ CONNECTION_TIMEOUT = "CONNECTION_TIMEOUT",
16
+ CONNECTION_CLOSED = "CONNECTION_CLOSED",
17
+
18
+ // Auth errors
19
+ AUTH_ERROR = "AUTH_ERROR",
20
+ AUTH_TIMEOUT = "AUTH_TIMEOUT",
21
+ AUTH_INVALID_SIGNATURE = "AUTH_INVALID_SIGNATURE",
22
+
23
+ // Message errors
24
+ MESSAGE_ERROR = "MESSAGE_ERROR",
25
+ MESSAGE_TIMEOUT = "MESSAGE_TIMEOUT",
26
+ MESSAGE_TOO_LARGE = "MESSAGE_TOO_LARGE",
27
+
28
+ // Validation errors
29
+ VALIDATION_ERROR = "VALIDATION_ERROR",
30
+ INVALID_MESSAGE = "INVALID_MESSAGE",
31
+ SIGNATURE_VERIFICATION_ERROR = "SIGNATURE_VERIFICATION_ERROR",
32
+
33
+ // Webhook errors
34
+ WEBHOOK_ERROR = "WEBHOOK_ERROR",
35
+ WEBHOOK_TIMEOUT = "WEBHOOK_TIMEOUT",
36
+ WEBHOOK_INVALID_URL = "WEBHOOK_INVALID_URL",
37
+
38
+ // Rate limit
39
+ RATE_LIMIT = "RATE_LIMIT",
40
+
41
+ // Generic timeout (for backward compatibility)
42
+ TIMEOUT_ERROR = "TIMEOUT_ERROR",
43
+ TIMEOUT = "TIMEOUT"
44
+ }
@@ -0,0 +1,302 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import {
3
+ SDKError,
4
+ ConnectionError,
5
+ AuthenticationError,
6
+ MessageError,
7
+ WebhookError,
8
+ ConfigurationError,
9
+ TimeoutError,
10
+ isRecoverableError
11
+ } from "./events";
12
+
13
+ describe("Error Classes", () => {
14
+ describe("SDKError", () => {
15
+ it("should create base SDK error", () => {
16
+ const error = new SDKError("Test error", "TEST_ERROR");
17
+ expect(error).toBeInstanceOf(Error);
18
+ expect(error).toBeInstanceOf(SDKError);
19
+ expect(error.message).toBe("Test error");
20
+ expect(error.code).toBe("TEST_ERROR");
21
+ expect(error.name).toBe("SDKError");
22
+ expect(error.recoverable).toBe(false);
23
+ });
24
+
25
+ it("should include details in error", () => {
26
+ const details = { field: "value", count: 42 };
27
+ const error = new SDKError("Test error", "TEST_ERROR", details);
28
+ expect(error.details).toEqual(details);
29
+ });
30
+
31
+ it("should serialize to JSON", () => {
32
+ const error = new SDKError("Test error", "TEST_ERROR", { key: "value" });
33
+ const json = error.toJSON();
34
+
35
+ expect(json).toEqual({
36
+ name: "SDKError",
37
+ message: "Test error",
38
+ code: "TEST_ERROR",
39
+ recoverable: false,
40
+ details: { key: "value" }
41
+ });
42
+ });
43
+
44
+ it("should have stack trace", () => {
45
+ const error = new SDKError("Test error", "TEST_ERROR");
46
+ expect(error.stack).toBeDefined();
47
+ expect(error.stack).toContain("SDKError");
48
+ });
49
+ });
50
+
51
+ describe("ConnectionError", () => {
52
+ it("should create connection error", () => {
53
+ const error = new ConnectionError("Connection failed");
54
+ expect(error).toBeInstanceOf(ConnectionError);
55
+ expect(error).toBeInstanceOf(SDKError);
56
+ expect(error.name).toBe("ConnectionError");
57
+ expect(error.code).toBe("CONNECTION_ERROR");
58
+ expect(error.recoverable).toBe(true); // Connection errors are recoverable
59
+ });
60
+
61
+ it("should be recoverable by default", () => {
62
+ const error = new ConnectionError("Connection lost");
63
+ expect(error.recoverable).toBe(true);
64
+ expect(isRecoverableError(error)).toBe(true);
65
+ });
66
+
67
+ it("should include connection details", () => {
68
+ const error = new ConnectionError("Connection failed", {
69
+ url: "wss://example.com",
70
+ attempt: 3
71
+ });
72
+ expect(error.details).toEqual({
73
+ url: "wss://example.com",
74
+ attempt: 3
75
+ });
76
+ });
77
+ });
78
+
79
+ describe("AuthenticationError", () => {
80
+ it("should create authentication error", () => {
81
+ const error = new AuthenticationError("Invalid credentials");
82
+ expect(error).toBeInstanceOf(AuthenticationError);
83
+ expect(error.name).toBe("AuthenticationError");
84
+ expect(error.code).toBe("AUTH_ERROR");
85
+ expect(error.recoverable).toBe(false); // Auth errors are not recoverable
86
+ });
87
+
88
+ it("should not be recoverable", () => {
89
+ const error = new AuthenticationError("Invalid token");
90
+ expect(error.recoverable).toBe(false);
91
+ expect(isRecoverableError(error)).toBe(false);
92
+ });
93
+
94
+ it("should include auth details", () => {
95
+ const error = new AuthenticationError("Auth failed", {
96
+ walletAddress: "0x123",
97
+ reason: "Invalid signature"
98
+ });
99
+ expect(error.details?.walletAddress).toBe("0x123");
100
+ expect(error.details?.reason).toBe("Invalid signature");
101
+ });
102
+ });
103
+
104
+ describe("MessageError", () => {
105
+ it("should create message error", () => {
106
+ const error = new MessageError("Invalid message format");
107
+ expect(error).toBeInstanceOf(MessageError);
108
+ expect(error.name).toBe("MessageError");
109
+ expect(error.code).toBe("MESSAGE_ERROR");
110
+ expect(error.recoverable).toBe(false);
111
+ });
112
+
113
+ it("should include message details", () => {
114
+ const error = new MessageError("Parse failed", {
115
+ messageType: "agent_response",
116
+ validationErrors: ["Missing field: content"]
117
+ });
118
+ expect(error.details?.messageType).toBe("agent_response");
119
+ expect(error.details?.validationErrors).toContain("Missing field: content");
120
+ });
121
+ });
122
+
123
+ describe("WebhookError", () => {
124
+ it("should create webhook error", () => {
125
+ const error = new WebhookError("Webhook delivery failed");
126
+ expect(error).toBeInstanceOf(WebhookError);
127
+ expect(error.name).toBe("WebhookError");
128
+ expect(error.code).toBe("WEBHOOK_ERROR");
129
+ expect(error.recoverable).toBe(true); // Webhook errors are recoverable
130
+ });
131
+
132
+ it("should be recoverable", () => {
133
+ const error = new WebhookError("Network error");
134
+ expect(error.recoverable).toBe(true);
135
+ expect(isRecoverableError(error)).toBe(true);
136
+ });
137
+
138
+ it("should include webhook details", () => {
139
+ const error = new WebhookError("Delivery failed", {
140
+ url: "https://webhook.example.com",
141
+ statusCode: 500,
142
+ attempt: 2
143
+ });
144
+ expect(error.details?.url).toBe("https://webhook.example.com");
145
+ expect(error.details?.statusCode).toBe(500);
146
+ expect(error.details?.attempt).toBe(2);
147
+ });
148
+ });
149
+
150
+ describe("ConfigurationError", () => {
151
+ it("should create configuration error", () => {
152
+ const error = new ConfigurationError("Invalid configuration");
153
+ expect(error).toBeInstanceOf(ConfigurationError);
154
+ expect(error.name).toBe("ConfigurationError");
155
+ expect(error.code).toBe("CONFIG_ERROR");
156
+ expect(error.recoverable).toBe(false);
157
+ });
158
+
159
+ it("should not be recoverable", () => {
160
+ const error = new ConfigurationError("Missing required field");
161
+ expect(error.recoverable).toBe(false);
162
+ expect(isRecoverableError(error)).toBe(false);
163
+ });
164
+
165
+ it("should include config details", () => {
166
+ const error = new ConfigurationError("Invalid config", {
167
+ field: "websocketUrl",
168
+ value: "http://invalid",
169
+ reason: "Must use wss:// protocol"
170
+ });
171
+ expect(error.details?.field).toBe("websocketUrl");
172
+ expect(error.details?.reason).toBe("Must use wss:// protocol");
173
+ });
174
+ });
175
+
176
+ describe("TimeoutError", () => {
177
+ it("should create timeout error", () => {
178
+ const error = new TimeoutError("Request timed out");
179
+ expect(error).toBeInstanceOf(TimeoutError);
180
+ expect(error.name).toBe("TimeoutError");
181
+ expect(error.code).toBe("TIMEOUT_ERROR");
182
+ expect(error.recoverable).toBe(true); // Timeout errors are recoverable
183
+ });
184
+
185
+ it("should be recoverable", () => {
186
+ const error = new TimeoutError("Operation timed out");
187
+ expect(error.recoverable).toBe(true);
188
+ expect(isRecoverableError(error)).toBe(true);
189
+ });
190
+
191
+ it("should include timeout details", () => {
192
+ const error = new TimeoutError("Request timeout", {
193
+ operation: "auth_request",
194
+ timeout: 5000,
195
+ elapsed: 5100
196
+ });
197
+ expect(error.details?.operation).toBe("auth_request");
198
+ expect(error.details?.timeout).toBe(5000);
199
+ expect(error.details?.elapsed).toBe(5100);
200
+ });
201
+ });
202
+
203
+ describe("isRecoverableError", () => {
204
+ it("should identify recoverable errors", () => {
205
+ const recoverableErrors = [
206
+ new ConnectionError("Connection lost"),
207
+ new WebhookError("Delivery failed"),
208
+ new TimeoutError("Request timeout")
209
+ ];
210
+
211
+ recoverableErrors.forEach((error) => {
212
+ expect(isRecoverableError(error)).toBe(true);
213
+ });
214
+ });
215
+
216
+ it("should identify non-recoverable errors", () => {
217
+ const nonRecoverableErrors = [
218
+ new AuthenticationError("Invalid credentials"),
219
+ new MessageError("Invalid format"),
220
+ new ConfigurationError("Invalid config"),
221
+ new SDKError("Generic error", "GENERIC")
222
+ ];
223
+
224
+ nonRecoverableErrors.forEach((error) => {
225
+ expect(isRecoverableError(error)).toBe(false);
226
+ });
227
+ });
228
+
229
+ it("should handle non-SDKError instances", () => {
230
+ const regularError = new Error("Regular error");
231
+ expect(isRecoverableError(regularError)).toBe(false);
232
+
233
+ const customError = { message: "Not an error object" };
234
+ expect(isRecoverableError(customError as any)).toBe(false);
235
+ });
236
+ });
237
+
238
+ describe("Error Inheritance", () => {
239
+ it("should maintain proper prototype chain", () => {
240
+ const connectionError = new ConnectionError("Test");
241
+ expect(connectionError).toBeInstanceOf(Error);
242
+ expect(connectionError).toBeInstanceOf(SDKError);
243
+ expect(connectionError).toBeInstanceOf(ConnectionError);
244
+
245
+ const authError = new AuthenticationError("Test");
246
+ expect(authError).toBeInstanceOf(Error);
247
+ expect(authError).toBeInstanceOf(SDKError);
248
+ expect(authError).toBeInstanceOf(AuthenticationError);
249
+ });
250
+
251
+ it("should have correct constructor name", () => {
252
+ const errors = [
253
+ new SDKError("Test", "TEST"),
254
+ new ConnectionError("Test"),
255
+ new AuthenticationError("Test"),
256
+ new MessageError("Test"),
257
+ new WebhookError("Test"),
258
+ new ConfigurationError("Test"),
259
+ new TimeoutError("Test")
260
+ ];
261
+
262
+ expect(errors[0].constructor.name).toBe("SDKError");
263
+ expect(errors[1].constructor.name).toBe("ConnectionError");
264
+ expect(errors[2].constructor.name).toBe("AuthenticationError");
265
+ expect(errors[3].constructor.name).toBe("MessageError");
266
+ expect(errors[4].constructor.name).toBe("WebhookError");
267
+ expect(errors[5].constructor.name).toBe("ConfigurationError");
268
+ expect(errors[6].constructor.name).toBe("TimeoutError");
269
+ });
270
+ });
271
+
272
+ describe("Error Serialization", () => {
273
+ it("should serialize all error types to JSON", () => {
274
+ const errors = [
275
+ new ConnectionError("Connection failed", { url: "wss://example.com" }),
276
+ new AuthenticationError("Auth failed", { wallet: "0x123" }),
277
+ new MessageError("Parse failed", { type: "unknown" }),
278
+ new WebhookError("Delivery failed", { status: 500 }),
279
+ new ConfigurationError("Invalid config", { field: "url" }),
280
+ new TimeoutError("Timeout", { ms: 5000 })
281
+ ];
282
+
283
+ errors.forEach((error) => {
284
+ const json = error.toJSON();
285
+ expect(json).toHaveProperty("name");
286
+ expect(json).toHaveProperty("message");
287
+ expect(json).toHaveProperty("code");
288
+ expect(json).toHaveProperty("recoverable");
289
+ expect(json).toHaveProperty("details");
290
+
291
+ // Ensure JSON is serializable
292
+ const stringified = JSON.stringify(json);
293
+ expect(stringified).toBeDefined();
294
+
295
+ // Can parse back
296
+ const parsed = JSON.parse(stringified);
297
+ expect(parsed.message).toBe(error.message);
298
+ expect(parsed.code).toBe(error.code);
299
+ });
300
+ });
301
+ });
302
+ });