@teneo-protocol/sdk 2.2.2 → 3.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 (228) hide show
  1. package/.github/ISSUE_TEMPLATE/config.yml +1 -1
  2. package/CHANGELOG.md +366 -15
  3. package/CONCEPTS.md +182 -44
  4. package/README.md +524 -94
  5. package/dist/constants.d.ts +3 -1
  6. package/dist/constants.d.ts.map +1 -1
  7. package/dist/constants.js +5 -3
  8. package/dist/constants.js.map +1 -1
  9. package/dist/core/websocket-client.d.ts.map +1 -1
  10. package/dist/core/websocket-client.js +9 -5
  11. package/dist/core/websocket-client.js.map +1 -1
  12. package/dist/formatters/response-formatter.d.ts +6 -6
  13. package/dist/handlers/message-handlers/agent-details-response-handler.d.ts +756 -756
  14. package/dist/handlers/message-handlers/agent-details-response-handler.js +2 -2
  15. package/dist/handlers/message-handlers/agent-details-response-handler.js.map +1 -1
  16. package/dist/handlers/message-handlers/agent-error-handler.d.ts +91 -0
  17. package/dist/handlers/message-handlers/agent-error-handler.d.ts.map +1 -0
  18. package/dist/handlers/message-handlers/agent-error-handler.js +44 -0
  19. package/dist/handlers/message-handlers/agent-error-handler.js.map +1 -0
  20. package/dist/handlers/message-handlers/agent-selected-handler.d.ts +6 -0
  21. package/dist/handlers/message-handlers/agent-selected-handler.d.ts.map +1 -1
  22. package/dist/handlers/message-handlers/agent-status-update-handler.d.ts +756 -756
  23. package/dist/handlers/message-handlers/agent-status-update-handler.d.ts.map +1 -1
  24. package/dist/handlers/message-handlers/agent-status-update-handler.js +2 -7
  25. package/dist/handlers/message-handlers/agent-status-update-handler.js.map +1 -1
  26. package/dist/handlers/message-handlers/all-agents-response-handler.js +2 -2
  27. package/dist/handlers/message-handlers/all-agents-response-handler.js.map +1 -1
  28. package/dist/handlers/message-handlers/auth-error-handler.d.ts +6 -0
  29. package/dist/handlers/message-handlers/auth-error-handler.d.ts.map +1 -1
  30. package/dist/handlers/message-handlers/auth-message-handler.d.ts.map +1 -1
  31. package/dist/handlers/message-handlers/auth-message-handler.js +6 -1
  32. package/dist/handlers/message-handlers/auth-message-handler.js.map +1 -1
  33. package/dist/handlers/message-handlers/auth-required-handler.d.ts +6 -0
  34. package/dist/handlers/message-handlers/auth-required-handler.d.ts.map +1 -1
  35. package/dist/handlers/message-handlers/auth-success-handler.d.ts.map +1 -1
  36. package/dist/handlers/message-handlers/auth-success-handler.js +6 -1
  37. package/dist/handlers/message-handlers/auth-success-handler.js.map +1 -1
  38. package/dist/handlers/message-handlers/base-handler.d.ts +2 -1
  39. package/dist/handlers/message-handlers/base-handler.d.ts.map +1 -1
  40. package/dist/handlers/message-handlers/base-handler.js +24 -4
  41. package/dist/handlers/message-handlers/base-handler.js.map +1 -1
  42. package/dist/handlers/message-handlers/challenge-handler.d.ts +6 -0
  43. package/dist/handlers/message-handlers/challenge-handler.d.ts.map +1 -1
  44. package/dist/handlers/message-handlers/error-message-handler.d.ts +6 -0
  45. package/dist/handlers/message-handlers/error-message-handler.d.ts.map +1 -1
  46. package/dist/handlers/message-handlers/index.d.ts +4 -0
  47. package/dist/handlers/message-handlers/index.d.ts.map +1 -1
  48. package/dist/handlers/message-handlers/index.js +23 -1
  49. package/dist/handlers/message-handlers/index.js.map +1 -1
  50. package/dist/handlers/message-handlers/list-available-agents-handler.d.ts +792 -756
  51. package/dist/handlers/message-handlers/list-available-agents-handler.d.ts.map +1 -1
  52. package/dist/handlers/message-handlers/list-available-agents-handler.js +23 -10
  53. package/dist/handlers/message-handlers/list-available-agents-handler.js.map +1 -1
  54. package/dist/handlers/message-handlers/list-room-agents-handler.d.ts +756 -756
  55. package/dist/handlers/message-handlers/list-room-agents-handler.d.ts.map +1 -1
  56. package/dist/handlers/message-handlers/list-room-agents-handler.js +2 -6
  57. package/dist/handlers/message-handlers/list-room-agents-handler.js.map +1 -1
  58. package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts.map +1 -1
  59. package/dist/handlers/message-handlers/list-rooms-response-handler.js +2 -5
  60. package/dist/handlers/message-handlers/list-rooms-response-handler.js.map +1 -1
  61. package/dist/handlers/message-handlers/ping-pong-handler.d.ts +52 -4
  62. package/dist/handlers/message-handlers/ping-pong-handler.d.ts.map +1 -1
  63. package/dist/handlers/message-handlers/ping-pong-handler.js +23 -4
  64. package/dist/handlers/message-handlers/ping-pong-handler.js.map +1 -1
  65. package/dist/handlers/message-handlers/rate-limit-notification-handler.d.ts.map +1 -1
  66. package/dist/handlers/message-handlers/rate-limit-notification-handler.js +3 -2
  67. package/dist/handlers/message-handlers/rate-limit-notification-handler.js.map +1 -1
  68. package/dist/handlers/message-handlers/regular-message-handler.d.ts +6 -0
  69. package/dist/handlers/message-handlers/regular-message-handler.d.ts.map +1 -1
  70. package/dist/handlers/message-handlers/subscribe-response-handler.d.ts +12 -6
  71. package/dist/handlers/message-handlers/subscribe-response-handler.d.ts.map +1 -1
  72. package/dist/handlers/message-handlers/success-handler.d.ts +82 -0
  73. package/dist/handlers/message-handlers/success-handler.d.ts.map +1 -0
  74. package/dist/handlers/message-handlers/success-handler.js +24 -0
  75. package/dist/handlers/message-handlers/success-handler.js.map +1 -0
  76. package/dist/handlers/message-handlers/task-confirmed-handler.d.ts +110 -0
  77. package/dist/handlers/message-handlers/task-confirmed-handler.d.ts.map +1 -0
  78. package/dist/handlers/message-handlers/task-confirmed-handler.js +46 -0
  79. package/dist/handlers/message-handlers/task-confirmed-handler.js.map +1 -0
  80. package/dist/handlers/message-handlers/trigger-wallet-tx-handler.d.ts +244 -0
  81. package/dist/handlers/message-handlers/trigger-wallet-tx-handler.d.ts.map +1 -0
  82. package/dist/handlers/message-handlers/trigger-wallet-tx-handler.js +58 -0
  83. package/dist/handlers/message-handlers/trigger-wallet-tx-handler.js.map +1 -0
  84. package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts +12 -6
  85. package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts.map +1 -1
  86. package/dist/handlers/message-handlers/user-authenticated-handler.js +2 -2
  87. package/dist/handlers/message-handlers/user-authenticated-handler.js.map +1 -1
  88. package/dist/handlers/message-handlers/user-count-handler.js +2 -2
  89. package/dist/handlers/message-handlers/user-count-handler.js.map +1 -1
  90. package/dist/index.d.ts +3 -3
  91. package/dist/index.d.ts.map +1 -1
  92. package/dist/index.js +11 -4
  93. package/dist/index.js.map +1 -1
  94. package/dist/managers/admin-manager.d.ts +2 -0
  95. package/dist/managers/admin-manager.d.ts.map +1 -1
  96. package/dist/managers/admin-manager.js +3 -2
  97. package/dist/managers/admin-manager.js.map +1 -1
  98. package/dist/managers/agent-room-manager.d.ts +89 -11
  99. package/dist/managers/agent-room-manager.d.ts.map +1 -1
  100. package/dist/managers/agent-room-manager.js +99 -35
  101. package/dist/managers/agent-room-manager.js.map +1 -1
  102. package/dist/managers/index.d.ts +1 -1
  103. package/dist/managers/index.d.ts.map +1 -1
  104. package/dist/managers/index.js.map +1 -1
  105. package/dist/managers/message-router.d.ts +45 -5
  106. package/dist/managers/message-router.d.ts.map +1 -1
  107. package/dist/managers/message-router.js +96 -24
  108. package/dist/managers/message-router.js.map +1 -1
  109. package/dist/managers/room-manager.d.ts +29 -7
  110. package/dist/managers/room-manager.d.ts.map +1 -1
  111. package/dist/managers/room-manager.js +37 -11
  112. package/dist/managers/room-manager.js.map +1 -1
  113. package/dist/payments/index.d.ts +3 -1
  114. package/dist/payments/index.d.ts.map +1 -1
  115. package/dist/payments/index.js +17 -3
  116. package/dist/payments/index.js.map +1 -1
  117. package/dist/payments/networks.d.ts +59 -0
  118. package/dist/payments/networks.d.ts.map +1 -0
  119. package/dist/payments/networks.js +192 -0
  120. package/dist/payments/networks.js.map +1 -0
  121. package/dist/payments/payment-client.d.ts +55 -10
  122. package/dist/payments/payment-client.d.ts.map +1 -1
  123. package/dist/payments/payment-client.js +172 -51
  124. package/dist/payments/payment-client.js.map +1 -1
  125. package/dist/teneo-sdk.d.ts +214 -40
  126. package/dist/teneo-sdk.d.ts.map +1 -1
  127. package/dist/teneo-sdk.js +360 -83
  128. package/dist/teneo-sdk.js.map +1 -1
  129. package/dist/types/config.d.ts +334 -25
  130. package/dist/types/config.d.ts.map +1 -1
  131. package/dist/types/config.js +114 -22
  132. package/dist/types/config.js.map +1 -1
  133. package/dist/types/events.d.ts +60 -14
  134. package/dist/types/events.d.ts.map +1 -1
  135. package/dist/types/events.js.map +1 -1
  136. package/dist/types/index.d.ts +1 -1
  137. package/dist/types/index.d.ts.map +1 -1
  138. package/dist/types/index.js +11 -4
  139. package/dist/types/index.js.map +1 -1
  140. package/dist/types/messages.d.ts +9801 -7222
  141. package/dist/types/messages.d.ts.map +1 -1
  142. package/dist/types/messages.js +180 -40
  143. package/dist/types/messages.js.map +1 -1
  144. package/dist/utils/pricing-resolver.d.ts +1 -1
  145. package/dist/utils/pricing-resolver.d.ts.map +1 -1
  146. package/dist/utils/pricing-resolver.js +9 -1
  147. package/dist/utils/pricing-resolver.js.map +1 -1
  148. package/examples/agent-room-management-example.ts +5 -5
  149. package/examples/basic-usage.ts +26 -6
  150. package/examples/claude-agent-x-follower/index.ts +1 -1
  151. package/examples/minimal-chat.ts +4 -3
  152. package/examples/n8n-teneo/index.ts +2 -2
  153. package/examples/nestjs-dashboard/README.md +1 -1
  154. package/examples/nestjs-dashboard/src/teneo/agents.controller.ts +3 -3
  155. package/examples/nestjs-dashboard/src/teneo/rooms.controller.ts +5 -5
  156. package/examples/nestjs-dashboard/src/teneo/teneo.service.ts +8 -8
  157. package/examples/openai-teneo/index.ts +1 -1
  158. package/examples/payment-flow.ts +143 -0
  159. package/examples/production-dashboard/README.md +6 -8
  160. package/examples/production-dashboard/server.ts +22 -10
  161. package/examples/room-management-example.ts +2 -2
  162. package/examples/usage/01-connect.ts +0 -3
  163. package/examples/usage/02-list-agents.ts +0 -2
  164. package/examples/usage/03-pick-agent.ts +3 -4
  165. package/examples/usage/04-find-by-capability.ts +10 -12
  166. package/examples/usage/05-webhook-example.ts +2 -4
  167. package/examples/usage/06-simple-api-server.ts +13 -9
  168. package/examples/usage/07-event-listener.ts +1 -13
  169. package/examples/usage/README.md +33 -7
  170. package/examples/webhook-integration.ts +9 -9
  171. package/examples/x-influencer-battle-server.ts +1 -1
  172. package/package.json +1 -1
  173. package/scripts/diagnose-connection.ts +86 -0
  174. package/scripts/investigate-payload.ts +163 -0
  175. package/scripts/list-agents.ts +58 -0
  176. package/scripts/live-multi-network-test.ts +230 -0
  177. package/src/constants.ts +5 -3
  178. package/src/core/websocket-client.ts +10 -9
  179. package/src/handlers/message-handlers/agent-details-response-handler.ts +2 -2
  180. package/src/handlers/message-handlers/agent-error-handler.ts +47 -0
  181. package/src/handlers/message-handlers/agent-status-update-handler.ts +2 -7
  182. package/src/handlers/message-handlers/all-agents-response-handler.ts +2 -2
  183. package/src/handlers/message-handlers/auth-message-handler.ts +7 -1
  184. package/src/handlers/message-handlers/auth-success-handler.ts +7 -1
  185. package/src/handlers/message-handlers/base-handler.ts +24 -4
  186. package/src/handlers/message-handlers/index.ts +24 -0
  187. package/src/handlers/message-handlers/list-available-agents-handler.ts +24 -11
  188. package/src/handlers/message-handlers/list-room-agents-handler.ts +2 -6
  189. package/src/handlers/message-handlers/list-rooms-response-handler.ts +2 -5
  190. package/src/handlers/message-handlers/ping-pong-handler.ts +29 -4
  191. package/src/handlers/message-handlers/rate-limit-notification-handler.ts +3 -2
  192. package/src/handlers/message-handlers/success-handler.ts +26 -0
  193. package/src/handlers/message-handlers/task-confirmed-handler.ts +49 -0
  194. package/src/handlers/message-handlers/trigger-wallet-tx-handler.ts +62 -0
  195. package/src/handlers/message-handlers/user-authenticated-handler.ts +2 -2
  196. package/src/handlers/message-handlers/user-count-handler.ts +2 -2
  197. package/src/index.ts +12 -4
  198. package/src/managers/admin-manager.ts +5 -2
  199. package/src/managers/agent-room-manager.ts +155 -26
  200. package/src/managers/index.ts +6 -1
  201. package/src/managers/message-router.ts +122 -27
  202. package/src/managers/room-manager.ts +39 -11
  203. package/src/payments/index.ts +20 -5
  204. package/src/payments/networks.ts +208 -0
  205. package/src/payments/payment-client.ts +211 -56
  206. package/src/teneo-sdk.ts +401 -70
  207. package/src/types/config.test.ts +24 -4
  208. package/src/types/config.ts +123 -25
  209. package/src/types/events.ts +36 -2
  210. package/src/types/index.ts +16 -3
  211. package/src/types/messages.ts +221 -57
  212. package/src/utils/pricing-resolver.ts +10 -2
  213. package/tests/direct-agent-test.ts +1 -1
  214. package/tests/integration/real-server.test.ts +1 -1
  215. package/tests/integration/websocket.test.ts +3 -3
  216. package/tests/multi-network-payment.test.ts +309 -0
  217. package/tests/multi-network.test.ts +296 -0
  218. package/tests/payment-flow-test.ts +6 -4
  219. package/tests/unit/handlers/agent-error-handler.test.ts +388 -0
  220. package/tests/unit/handlers/agent-room-operation-response-handler.test.ts +9 -6
  221. package/tests/unit/handlers/agent-status-update-handler.test.ts +11 -16
  222. package/tests/unit/handlers/list-available-agents-handler.test.ts +11 -14
  223. package/tests/unit/handlers/list-room-agents-handler.test.ts +11 -15
  224. package/tests/unit/handlers/room-operation-response-handler.test.ts +9 -6
  225. package/tests/unit/handlers/trigger-wallet-tx-handler.test.ts +431 -0
  226. package/tests/unit/managers/admin-manager.test.ts +183 -0
  227. package/tests/unit/managers/agent-room-manager.test.ts +189 -33
  228. package/tests/unit/sdk-new-methods.test.ts +221 -0
@@ -27,18 +27,20 @@ export class RoomManager extends EventEmitter<SDKEvents> {
27
27
  * Validates room ID and sends subscribe message to the server.
28
28
  * The actual subscription state is updated when the server confirms via room:subscribed event.
29
29
  *
30
- * @param roomId - The ID of the room to subscribe to
31
- * @returns Promise that resolves when subscribed
30
+ * Note: This only applies to public rooms. Private rooms are automatically available after authentication.
31
+ *
32
+ * @param roomId - The ID of the public room to subscribe to
33
+ * @returns Promise that resolves when subscription request is sent
32
34
  * @throws {SDKError} If not connected to the network
33
35
  * @throws {ValidationError} If roomId is empty or invalid
34
36
  *
35
37
  * @example
36
38
  * ```typescript
37
- * await roomManager.subscribeToRoom('general');
38
- * console.log('Subscription request sent to general room');
39
+ * await roomManager.subscribeToPublicRoom('room-id');
40
+ * console.log('Subscription request sent');
39
41
  * ```
40
42
  */
41
- public async subscribeToRoom(roomId: string): Promise<void> {
43
+ public async subscribeToPublicRoom(roomId: string): Promise<void> {
42
44
  if (!this.wsClient.isConnected) {
43
45
  throw new SDKError("Not connected to Teneo Protocol", ErrorCode.NOT_CONNECTED);
44
46
  }
@@ -46,12 +48,25 @@ export class RoomManager extends EventEmitter<SDKEvents> {
46
48
  // Validate room ID
47
49
  const validatedRoomId = RoomIdSchema.parse(roomId);
48
50
 
49
- this.logger.info("RoomManager: Subscribing to room", { roomId: validatedRoomId });
51
+ this.logger.info("RoomManager: Subscribing to public room", { roomId: validatedRoomId });
50
52
 
51
53
  const message = createSubscribe(validatedRoomId);
52
54
  await this.wsClient.sendMessage(message);
53
55
  }
54
56
 
57
+ /**
58
+ * @deprecated Use subscribeToPublicRoom() instead. This method only affects public rooms.
59
+ * Private rooms are automatically available after authentication without subscription.
60
+ *
61
+ * Subscribes to a public room in the Teneo Protocol.
62
+ *
63
+ * @param roomId - The ID of the public room to subscribe to
64
+ * @returns Promise that resolves when subscription request is sent
65
+ */
66
+ public async subscribeToRoom(roomId: string): Promise<void> {
67
+ return this.subscribeToPublicRoom(roomId);
68
+ }
69
+
55
70
  /**
56
71
  * Unsubscribes from a public room in the Teneo Protocol.
57
72
  * Validates room ID and sends unsubscribe message to the server.
@@ -66,11 +81,11 @@ export class RoomManager extends EventEmitter<SDKEvents> {
66
81
  *
67
82
  * @example
68
83
  * ```typescript
69
- * await roomManager.unsubscribeFromRoom('public-announcements');
84
+ * await roomManager.unsubscribeFromPublicRoom('public-room-id');
70
85
  * console.log('Unsubscription request sent for public room');
71
86
  * ```
72
87
  */
73
- public async unsubscribeFromRoom(roomId: string): Promise<void> {
88
+ public async unsubscribeFromPublicRoom(roomId: string): Promise<void> {
74
89
  if (!this.wsClient.isConnected) {
75
90
  throw new SDKError("Not connected to Teneo Protocol", ErrorCode.NOT_CONNECTED);
76
91
  }
@@ -78,12 +93,25 @@ export class RoomManager extends EventEmitter<SDKEvents> {
78
93
  // Validate room ID
79
94
  const validatedRoomId = RoomIdSchema.parse(roomId);
80
95
 
81
- this.logger.info("RoomManager: Unsubscribing from room", { roomId: validatedRoomId });
96
+ this.logger.info("RoomManager: Unsubscribing from public room", { roomId: validatedRoomId });
82
97
 
83
98
  const message = createUnsubscribe(validatedRoomId);
84
99
  await this.wsClient.sendMessage(message);
85
100
  }
86
101
 
102
+ /**
103
+ * @deprecated Use unsubscribeFromPublicRoom() instead. This method only affects public rooms.
104
+ * Private rooms cannot be unsubscribed from.
105
+ *
106
+ * Unsubscribes from a public room in the Teneo Protocol.
107
+ *
108
+ * @param roomId - The ID of the public room to unsubscribe from
109
+ * @returns Promise that resolves when unsubscribed
110
+ */
111
+ public async unsubscribeFromRoom(roomId: string): Promise<void> {
112
+ return this.unsubscribeFromPublicRoom(roomId);
113
+ }
114
+
87
115
  /**
88
116
  * Updates the subscription state from server response.
89
117
  * This is the authoritative source of which rooms you're subscribed to.
@@ -95,7 +123,7 @@ export class RoomManager extends EventEmitter<SDKEvents> {
95
123
  * @example
96
124
  * ```typescript
97
125
  * // Internal SDK usage
98
- * roomManager.updateSubscriptions(['general', 'support', 'trading']);
126
+ * roomManager.updateSubscriptions(['room-id-1', 'room-id-2', 'room-id-3']);
99
127
  * ```
100
128
  */
101
129
  public updateSubscriptions(subscriptions: string[]): void {
@@ -150,7 +178,7 @@ export class RoomManager extends EventEmitter<SDKEvents> {
150
178
  *
151
179
  * @example
152
180
  * ```typescript
153
- * const room = roomManager.getRoom('general');
181
+ * const room = roomManager.getRoom('room-id');
154
182
  * if (room) {
155
183
  * console.log(`Room: ${room.name}`);
156
184
  * console.log(`Members: ${room.members?.length ?? 0}`);
@@ -1,22 +1,37 @@
1
1
  /**
2
2
  * Payment module exports for quote-approve flow (v2.2.0)
3
+ * Multi-network support added in v2.3.0
3
4
  */
4
5
 
5
6
  export {
6
7
  PaymentClient,
7
8
  type PaymentClientConfig,
8
- // Constants
9
+ // Constants (legacy, for backwards compatibility)
9
10
  USDC_CONTRACT,
10
11
  PEAQ_CHAIN_ID,
11
12
  USDC_DECIMALS,
12
13
  X402_VERSION,
13
14
  DEFAULT_PAYMENT_TIMEOUT_SECONDS,
14
15
  DEFAULT_PAY_TO_ADDRESS,
15
- DEFAULT_RPC_URL,
16
16
  // Utilities
17
17
  buildX402ResourceUrl,
18
18
  usdcToUnits,
19
- unitsToUsdc,
20
- // Types
21
- type SupportedChain
19
+ unitsToUsdc
22
20
  } from "./payment-client";
21
+
22
+ // Multi-network support (v2.3.0)
23
+ export {
24
+ type NetworkConfig,
25
+ NETWORKS,
26
+ CHAIN_ID_TO_NETWORK,
27
+ CAIP2_TO_NETWORK,
28
+ getNetwork,
29
+ getDefaultNetwork,
30
+ createChainDefinition,
31
+ isNetworkSupported,
32
+ getSupportedNetworks,
33
+ // Network config fetching (v2.4.0)
34
+ setNetworkConfigUrl,
35
+ fetchNetworkConfigs,
36
+ initializeNetworks
37
+ } from "./networks";
@@ -0,0 +1,208 @@
1
+ import { defineChain, type Chain } from "viem";
2
+ import { z } from "zod";
3
+
4
+ // Zod schema for runtime validation
5
+ const NetworkConfigSchema = z.object({
6
+ chainId: z.number(),
7
+ name: z.string(),
8
+ caip2: z.string(),
9
+ rpcUrl: z.string().url(),
10
+ usdcContract: z.string(),
11
+ settlementRouter: z.string(),
12
+ transferHook: z.string(),
13
+ eip712: z.object({
14
+ name: z.string(),
15
+ version: z.string()
16
+ })
17
+ });
18
+
19
+ export type NetworkConfig = z.infer<typeof NetworkConfigSchema>;
20
+
21
+ let cachedNetworks: Record<string, NetworkConfig> | null = null;
22
+ let networksFetchPromise: Promise<Record<string, NetworkConfig>> | null = null;
23
+ let lastFetchTime = 0;
24
+ const CACHE_TTL_MS = 60 * 60 * 1000;
25
+
26
+ export let NETWORKS: Record<string, NetworkConfig> = {};
27
+
28
+ // Dynamic lookup mappings - populated from backend response in fetchNetworkConfigs()
29
+ export let CHAIN_ID_TO_NETWORK: Record<number, string> = {};
30
+ export let CAIP2_TO_NETWORK: Record<string, string> = {};
31
+
32
+ let backendUrl: string | null = null;
33
+
34
+ export function setNetworkConfigUrl(url: string): void {
35
+ backendUrl = url
36
+ .replace(/^wss:/, "https:")
37
+ .replace(/^ws:/, "http:")
38
+ .replace(/\/ws\/?$/, "");
39
+ }
40
+
41
+ export async function fetchNetworkConfigs(): Promise<Record<string, NetworkConfig>> {
42
+ if (cachedNetworks && Date.now() - lastFetchTime < CACHE_TTL_MS) {
43
+ return cachedNetworks;
44
+ }
45
+
46
+ if (networksFetchPromise) {
47
+ return networksFetchPromise;
48
+ }
49
+
50
+ if (!backendUrl) {
51
+ throw new Error("Backend URL not set. Call setNetworkConfigUrl() before initializing networks.");
52
+ }
53
+
54
+ networksFetchPromise = (async () => {
55
+ try {
56
+ const response = await fetch(`${backendUrl}/api/networks`, {
57
+ method: "GET",
58
+ headers: { "Accept": "application/json" }
59
+ });
60
+
61
+ if (!response.ok) {
62
+ throw new Error(`HTTP ${response.status} ${response.statusText}`);
63
+ }
64
+
65
+ const data = await response.json();
66
+ if (!data.networks || typeof data.networks !== "object" || Object.keys(data.networks).length === 0) {
67
+ throw new Error("Invalid or empty network config response");
68
+ }
69
+
70
+ // Validate each network config gracefully - skip invalid ones
71
+ const validatedNetworks: Record<string, NetworkConfig> = {};
72
+ const invalidNetworks: string[] = [];
73
+
74
+ for (const [name, config] of Object.entries(data.networks)) {
75
+ const result = NetworkConfigSchema.safeParse(config);
76
+ if (result.success) {
77
+ validatedNetworks[name] = result.data;
78
+ } else {
79
+ invalidNetworks.push(name);
80
+ console.warn(`[Networks] Skipping invalid network "${name}":`, result.error.issues.map(i => i.message).join(", "));
81
+ }
82
+ }
83
+
84
+ // If no valid networks, fall back to cache or throw
85
+ if (Object.keys(validatedNetworks).length === 0) {
86
+ if (cachedNetworks) {
87
+ console.warn("[Networks] All networks invalid, using cached config");
88
+ return cachedNetworks;
89
+ }
90
+ throw new Error(`All network configs failed validation. Invalid: ${invalidNetworks.join(", ")}`);
91
+ }
92
+
93
+ // Log warnings if some networks were invalid
94
+ if (invalidNetworks.length > 0) {
95
+ console.warn(`[Networks] ${invalidNetworks.length} network(s) failed validation and were skipped: ${invalidNetworks.join(", ")}`);
96
+ }
97
+
98
+ cachedNetworks = validatedNetworks;
99
+ lastFetchTime = Date.now();
100
+ NETWORKS = { ...validatedNetworks };
101
+
102
+ // Build dynamic lookup mappings from validated networks
103
+ CHAIN_ID_TO_NETWORK = {};
104
+ CAIP2_TO_NETWORK = {};
105
+ for (const [name, config] of Object.entries(validatedNetworks)) {
106
+ CHAIN_ID_TO_NETWORK[config.chainId] = name;
107
+ CAIP2_TO_NETWORK[config.caip2] = name;
108
+ }
109
+
110
+ console.log("[Networks] Fetched from backend:", Object.keys(validatedNetworks).join(", "));
111
+ return validatedNetworks;
112
+ } catch (error) {
113
+ if (cachedNetworks) {
114
+ console.warn("[Networks] Backend unavailable, using cached config");
115
+ return cachedNetworks;
116
+ }
117
+ throw new Error(`Failed to fetch network configs and no cache available: ${error}`);
118
+ } finally {
119
+ networksFetchPromise = null;
120
+ }
121
+ })();
122
+
123
+ return networksFetchPromise;
124
+ }
125
+
126
+ export async function initializeNetworks(): Promise<void> {
127
+ await fetchNetworkConfigs();
128
+ }
129
+
130
+ export function getNetwork(nameOrChainId: string | number): NetworkConfig {
131
+ if (Object.keys(NETWORKS).length === 0) {
132
+ throw new Error("Networks not initialized. Call initializeNetworks() first.");
133
+ }
134
+
135
+ if (typeof nameOrChainId === "number") {
136
+ const name = CHAIN_ID_TO_NETWORK[nameOrChainId];
137
+ if (!name) {
138
+ throw new Error(`Unknown chain ID: ${nameOrChainId}. Supported: ${Object.keys(CHAIN_ID_TO_NETWORK).join(", ")}`);
139
+ }
140
+ return NETWORKS[name];
141
+ }
142
+
143
+ if (nameOrChainId.startsWith("eip155:")) {
144
+ const name = CAIP2_TO_NETWORK[nameOrChainId];
145
+ if (!name) {
146
+ throw new Error(`Unknown CAIP-2 network: ${nameOrChainId}. Supported: ${Object.keys(CAIP2_TO_NETWORK).join(", ")}`);
147
+ }
148
+ return NETWORKS[name];
149
+ }
150
+
151
+ const network = NETWORKS[nameOrChainId.toLowerCase()];
152
+ if (!network) {
153
+ throw new Error(`Unknown network: ${nameOrChainId}. Supported: ${Object.keys(NETWORKS).join(", ")}`);
154
+ }
155
+ return network;
156
+ }
157
+
158
+ export function getDefaultNetwork(): NetworkConfig {
159
+ const networkKeys = Object.keys(NETWORKS);
160
+ if (networkKeys.length === 0) {
161
+ throw new Error("Networks not initialized. Call initializeNetworks() first.");
162
+ }
163
+
164
+ const envNetwork = process.env.TENEO_NETWORK;
165
+ if (envNetwork) {
166
+ try {
167
+ return getNetwork(envNetwork);
168
+ } catch {
169
+ console.warn(`Invalid TENEO_NETWORK: ${envNetwork}, using default`);
170
+ }
171
+ }
172
+
173
+ // Prefer "peaq" if available, otherwise use first available network
174
+ if (NETWORKS["peaq"]) {
175
+ return NETWORKS["peaq"];
176
+ }
177
+ return NETWORKS[networkKeys[0]];
178
+ }
179
+
180
+ export function createChainDefinition(network: NetworkConfig): Chain {
181
+ return defineChain({
182
+ id: network.chainId,
183
+ name: network.name,
184
+ network: network.name.toLowerCase().replace(/\s+/g, "-"),
185
+ nativeCurrency: {
186
+ decimals: 18,
187
+ name: network.name.split(" ")[0],
188
+ symbol: network.name === "PEAQ Mainnet" ? "PEAQ" : network.name === "Avalanche Mainnet" ? "AVAX" : "ETH"
189
+ },
190
+ rpcUrls: {
191
+ default: { http: [network.rpcUrl] },
192
+ public: { http: [network.rpcUrl] }
193
+ }
194
+ });
195
+ }
196
+
197
+ export function isNetworkSupported(nameOrChainId: string | number): boolean {
198
+ try {
199
+ getNetwork(nameOrChainId);
200
+ return true;
201
+ } catch {
202
+ return false;
203
+ }
204
+ }
205
+
206
+ export function getSupportedNetworks(): string[] {
207
+ return Object.keys(NETWORKS);
208
+ }