@teneo-protocol/sdk 2.2.2 → 3.0.1
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.
- package/.github/ISSUE_TEMPLATE/config.yml +1 -1
- package/CHANGELOG.md +366 -15
- package/CONCEPTS.md +182 -44
- package/README.md +524 -94
- package/dist/constants.d.ts +3 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +5 -3
- package/dist/constants.js.map +1 -1
- package/dist/core/websocket-client.d.ts.map +1 -1
- package/dist/core/websocket-client.js +9 -5
- package/dist/core/websocket-client.js.map +1 -1
- package/dist/formatters/response-formatter.d.ts +6 -6
- package/dist/handlers/message-handlers/agent-details-response-handler.d.ts +1080 -756
- package/dist/handlers/message-handlers/agent-details-response-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/agent-details-response-handler.js +2 -2
- package/dist/handlers/message-handlers/agent-details-response-handler.js.map +1 -1
- package/dist/handlers/message-handlers/agent-error-handler.d.ts +91 -0
- package/dist/handlers/message-handlers/agent-error-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/agent-error-handler.js +44 -0
- package/dist/handlers/message-handlers/agent-error-handler.js.map +1 -0
- package/dist/handlers/message-handlers/agent-selected-handler.d.ts +6 -0
- package/dist/handlers/message-handlers/agent-selected-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/agent-status-update-handler.d.ts +1080 -756
- package/dist/handlers/message-handlers/agent-status-update-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/agent-status-update-handler.js +2 -7
- package/dist/handlers/message-handlers/agent-status-update-handler.js.map +1 -1
- package/dist/handlers/message-handlers/all-agents-response-handler.d.ts +135 -54
- package/dist/handlers/message-handlers/all-agents-response-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/all-agents-response-handler.js +2 -2
- package/dist/handlers/message-handlers/all-agents-response-handler.js.map +1 -1
- package/dist/handlers/message-handlers/auth-error-handler.d.ts +6 -0
- package/dist/handlers/message-handlers/auth-error-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-message-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-message-handler.js +6 -1
- package/dist/handlers/message-handlers/auth-message-handler.js.map +1 -1
- package/dist/handlers/message-handlers/auth-required-handler.d.ts +6 -0
- package/dist/handlers/message-handlers/auth-required-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-success-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-success-handler.js +6 -1
- package/dist/handlers/message-handlers/auth-success-handler.js.map +1 -1
- package/dist/handlers/message-handlers/base-handler.d.ts +2 -1
- package/dist/handlers/message-handlers/base-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/base-handler.js +24 -4
- package/dist/handlers/message-handlers/base-handler.js.map +1 -1
- package/dist/handlers/message-handlers/challenge-handler.d.ts +6 -0
- package/dist/handlers/message-handlers/challenge-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/error-message-handler.d.ts +6 -0
- package/dist/handlers/message-handlers/error-message-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/index.d.ts +4 -0
- package/dist/handlers/message-handlers/index.d.ts.map +1 -1
- package/dist/handlers/message-handlers/index.js +23 -1
- package/dist/handlers/message-handlers/index.js.map +1 -1
- package/dist/handlers/message-handlers/list-available-agents-handler.d.ts +1116 -756
- package/dist/handlers/message-handlers/list-available-agents-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/list-available-agents-handler.js +23 -10
- package/dist/handlers/message-handlers/list-available-agents-handler.js.map +1 -1
- package/dist/handlers/message-handlers/list-room-agents-handler.d.ts +1080 -756
- package/dist/handlers/message-handlers/list-room-agents-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/list-room-agents-handler.js +2 -6
- package/dist/handlers/message-handlers/list-room-agents-handler.js.map +1 -1
- package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/list-rooms-response-handler.js +2 -5
- package/dist/handlers/message-handlers/list-rooms-response-handler.js.map +1 -1
- package/dist/handlers/message-handlers/ping-pong-handler.d.ts +52 -4
- package/dist/handlers/message-handlers/ping-pong-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/ping-pong-handler.js +23 -4
- package/dist/handlers/message-handlers/ping-pong-handler.js.map +1 -1
- package/dist/handlers/message-handlers/rate-limit-notification-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/rate-limit-notification-handler.js +3 -2
- package/dist/handlers/message-handlers/rate-limit-notification-handler.js.map +1 -1
- package/dist/handlers/message-handlers/regular-message-handler.d.ts +6 -0
- package/dist/handlers/message-handlers/regular-message-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/subscribe-response-handler.d.ts +12 -6
- package/dist/handlers/message-handlers/subscribe-response-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/success-handler.d.ts +82 -0
- package/dist/handlers/message-handlers/success-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/success-handler.js +24 -0
- package/dist/handlers/message-handlers/success-handler.js.map +1 -0
- package/dist/handlers/message-handlers/task-confirmed-handler.d.ts +110 -0
- package/dist/handlers/message-handlers/task-confirmed-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/task-confirmed-handler.js +46 -0
- package/dist/handlers/message-handlers/task-confirmed-handler.js.map +1 -0
- package/dist/handlers/message-handlers/trigger-wallet-tx-handler.d.ts +244 -0
- package/dist/handlers/message-handlers/trigger-wallet-tx-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/trigger-wallet-tx-handler.js +58 -0
- package/dist/handlers/message-handlers/trigger-wallet-tx-handler.js.map +1 -0
- package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts +12 -6
- package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/user-authenticated-handler.js +2 -2
- package/dist/handlers/message-handlers/user-authenticated-handler.js.map +1 -1
- package/dist/handlers/message-handlers/user-count-handler.js +2 -2
- package/dist/handlers/message-handlers/user-count-handler.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -4
- package/dist/index.js.map +1 -1
- package/dist/managers/admin-manager.d.ts +3 -1
- package/dist/managers/admin-manager.d.ts.map +1 -1
- package/dist/managers/admin-manager.js +4 -3
- package/dist/managers/admin-manager.js.map +1 -1
- package/dist/managers/agent-room-manager.d.ts +89 -11
- package/dist/managers/agent-room-manager.d.ts.map +1 -1
- package/dist/managers/agent-room-manager.js +99 -35
- package/dist/managers/agent-room-manager.js.map +1 -1
- package/dist/managers/index.d.ts +1 -1
- package/dist/managers/index.d.ts.map +1 -1
- package/dist/managers/index.js.map +1 -1
- package/dist/managers/message-router.d.ts +45 -5
- package/dist/managers/message-router.d.ts.map +1 -1
- package/dist/managers/message-router.js +96 -24
- package/dist/managers/message-router.js.map +1 -1
- package/dist/managers/room-manager.d.ts +29 -7
- package/dist/managers/room-manager.d.ts.map +1 -1
- package/dist/managers/room-manager.js +37 -11
- package/dist/managers/room-manager.js.map +1 -1
- package/dist/payments/index.d.ts +3 -1
- package/dist/payments/index.d.ts.map +1 -1
- package/dist/payments/index.js +17 -3
- package/dist/payments/index.js.map +1 -1
- package/dist/payments/networks.d.ts +59 -0
- package/dist/payments/networks.d.ts.map +1 -0
- package/dist/payments/networks.js +192 -0
- package/dist/payments/networks.js.map +1 -0
- package/dist/payments/payment-client.d.ts +55 -10
- package/dist/payments/payment-client.d.ts.map +1 -1
- package/dist/payments/payment-client.js +172 -51
- package/dist/payments/payment-client.js.map +1 -1
- package/dist/teneo-sdk.d.ts +215 -41
- package/dist/teneo-sdk.d.ts.map +1 -1
- package/dist/teneo-sdk.js +361 -84
- package/dist/teneo-sdk.js.map +1 -1
- package/dist/types/config.d.ts +334 -25
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +114 -22
- package/dist/types/config.js.map +1 -1
- package/dist/types/events.d.ts +60 -14
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/events.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +11 -4
- package/dist/types/index.js.map +1 -1
- package/dist/types/messages.d.ts +13110 -7451
- package/dist/types/messages.d.ts.map +1 -1
- package/dist/types/messages.js +195 -44
- package/dist/types/messages.js.map +1 -1
- package/dist/utils/pricing-resolver.d.ts +1 -1
- package/dist/utils/pricing-resolver.d.ts.map +1 -1
- package/dist/utils/pricing-resolver.js +9 -1
- package/dist/utils/pricing-resolver.js.map +1 -1
- package/examples/agent-room-management-example.ts +5 -5
- package/examples/basic-usage.ts +26 -6
- package/examples/claude-agent-x-follower/index.ts +1 -1
- package/examples/minimal-chat.ts +4 -3
- package/examples/n8n-teneo/index.ts +2 -2
- package/examples/nestjs-dashboard/README.md +1 -1
- package/examples/nestjs-dashboard/src/teneo/agents.controller.ts +3 -3
- package/examples/nestjs-dashboard/src/teneo/rooms.controller.ts +5 -5
- package/examples/nestjs-dashboard/src/teneo/teneo.service.ts +8 -8
- package/examples/openai-teneo/index.ts +1 -1
- package/examples/payment-flow.ts +143 -0
- package/examples/production-dashboard/README.md +6 -8
- package/examples/production-dashboard/server.ts +22 -10
- package/examples/room-management-example.ts +2 -2
- package/examples/usage/01-connect.ts +0 -3
- package/examples/usage/02-list-agents.ts +0 -2
- package/examples/usage/03-pick-agent.ts +3 -4
- package/examples/usage/04-find-by-capability.ts +10 -12
- package/examples/usage/05-webhook-example.ts +2 -4
- package/examples/usage/06-simple-api-server.ts +13 -9
- package/examples/usage/07-event-listener.ts +1 -13
- package/examples/usage/README.md +33 -7
- package/examples/webhook-integration.ts +9 -9
- package/examples/x-influencer-battle-server.ts +1 -1
- package/package.json +1 -1
- package/scripts/diagnose-connection.ts +86 -0
- package/scripts/investigate-payload.ts +163 -0
- package/scripts/list-agents.ts +58 -0
- package/scripts/live-multi-network-test.ts +230 -0
- package/src/constants.ts +5 -3
- package/src/core/websocket-client.ts +10 -9
- package/src/handlers/message-handlers/agent-details-response-handler.ts +2 -2
- package/src/handlers/message-handlers/agent-error-handler.ts +47 -0
- package/src/handlers/message-handlers/agent-status-update-handler.ts +2 -7
- package/src/handlers/message-handlers/all-agents-response-handler.ts +2 -2
- package/src/handlers/message-handlers/auth-message-handler.ts +7 -1
- package/src/handlers/message-handlers/auth-success-handler.ts +7 -1
- package/src/handlers/message-handlers/base-handler.ts +24 -4
- package/src/handlers/message-handlers/index.ts +24 -0
- package/src/handlers/message-handlers/list-available-agents-handler.ts +24 -11
- package/src/handlers/message-handlers/list-room-agents-handler.ts +2 -6
- package/src/handlers/message-handlers/list-rooms-response-handler.ts +2 -5
- package/src/handlers/message-handlers/ping-pong-handler.ts +29 -4
- package/src/handlers/message-handlers/rate-limit-notification-handler.ts +3 -2
- package/src/handlers/message-handlers/success-handler.ts +26 -0
- package/src/handlers/message-handlers/task-confirmed-handler.ts +49 -0
- package/src/handlers/message-handlers/trigger-wallet-tx-handler.ts +62 -0
- package/src/handlers/message-handlers/user-authenticated-handler.ts +2 -2
- package/src/handlers/message-handlers/user-count-handler.ts +2 -2
- package/src/index.ts +12 -4
- package/src/managers/admin-manager.ts +6 -3
- package/src/managers/agent-room-manager.ts +155 -26
- package/src/managers/index.ts +6 -1
- package/src/managers/message-router.ts +122 -27
- package/src/managers/room-manager.ts +39 -11
- package/src/payments/index.ts +20 -5
- package/src/payments/networks.ts +208 -0
- package/src/payments/payment-client.ts +211 -56
- package/src/teneo-sdk.ts +402 -71
- package/src/types/config.test.ts +24 -4
- package/src/types/config.ts +123 -25
- package/src/types/events.ts +36 -2
- package/src/types/index.ts +16 -3
- package/src/types/messages.ts +235 -60
- package/src/utils/pricing-resolver.ts +10 -2
- package/tests/direct-agent-test.ts +1 -1
- package/tests/integration/real-server.test.ts +1 -1
- package/tests/integration/websocket.test.ts +3 -3
- package/tests/multi-network-payment.test.ts +309 -0
- package/tests/multi-network.test.ts +296 -0
- package/tests/payment-flow-test.ts +6 -4
- package/tests/unit/handlers/agent-error-handler.test.ts +388 -0
- package/tests/unit/handlers/agent-room-operation-response-handler.test.ts +9 -6
- package/tests/unit/handlers/agent-status-update-handler.test.ts +11 -16
- package/tests/unit/handlers/list-available-agents-handler.test.ts +11 -14
- package/tests/unit/handlers/list-room-agents-handler.test.ts +11 -15
- package/tests/unit/handlers/room-operation-response-handler.test.ts +9 -6
- package/tests/unit/handlers/trigger-wallet-tx-handler.test.ts +431 -0
- package/tests/unit/managers/admin-manager.test.ts +183 -0
- package/tests/unit/managers/agent-room-manager.test.ts +189 -33
- 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
|
-
*
|
|
31
|
-
*
|
|
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.
|
|
38
|
-
* console.log('Subscription request sent
|
|
39
|
+
* await roomManager.subscribeToPublicRoom('room-id');
|
|
40
|
+
* console.log('Subscription request sent');
|
|
39
41
|
* ```
|
|
40
42
|
*/
|
|
41
|
-
public async
|
|
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.
|
|
84
|
+
* await roomManager.unsubscribeFromPublicRoom('public-room-id');
|
|
70
85
|
* console.log('Unsubscription request sent for public room');
|
|
71
86
|
* ```
|
|
72
87
|
*/
|
|
73
|
-
public async
|
|
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(['
|
|
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('
|
|
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}`);
|
package/src/payments/index.ts
CHANGED
|
@@ -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
|
+
}
|