@teneo-protocol/sdk 1.0.1 → 2.2.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.
- package/.eslintrc.json +11 -2
- package/.github/CODEOWNERS +2 -0
- package/.github/ISSUE_TEMPLATE/01-bug.yml +85 -0
- package/.github/ISSUE_TEMPLATE/config.yml +8 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
- package/.github/workflows/claude-code-review.yml +8 -3
- package/.github/workflows/claude-reviewer.yml +6 -4
- package/.github/workflows/publish-npm.yml +9 -6
- package/.github/workflows/push-to-main.yml +1 -1
- package/.github/workflows/top-issue.yml +102 -0
- package/CHANGELOG.md +334 -0
- package/CONCEPTS.md +747 -0
- package/README.md +577 -54
- package/dist/constants.js +8 -8
- package/dist/constants.js.map +1 -1
- package/dist/core/websocket-client.d.ts +25 -1
- package/dist/core/websocket-client.d.ts.map +1 -1
- package/dist/core/websocket-client.js +74 -15
- package/dist/core/websocket-client.js.map +1 -1
- package/dist/formatters/response-formatter.js +4 -0
- package/dist/formatters/response-formatter.js.map +1 -1
- package/dist/handlers/message-handler-registry.js +2 -1
- package/dist/handlers/message-handler-registry.js.map +1 -1
- package/dist/handlers/message-handlers/agent-details-response-handler.d.ts +1666 -0
- package/dist/handlers/message-handlers/agent-details-response-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/agent-details-response-handler.js +38 -0
- package/dist/handlers/message-handlers/agent-details-response-handler.js.map +1 -0
- package/dist/handlers/message-handlers/agent-room-operation-response-handler.d.ts +76 -0
- package/dist/handlers/message-handlers/agent-room-operation-response-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/agent-room-operation-response-handler.js +67 -0
- package/dist/handlers/message-handlers/agent-room-operation-response-handler.js.map +1 -0
- package/dist/handlers/message-handlers/agent-selected-handler.d.ts +92 -38
- package/dist/handlers/message-handlers/agent-selected-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/agent-selected-handler.js +2 -5
- package/dist/handlers/message-handlers/agent-selected-handler.js.map +1 -1
- package/dist/handlers/message-handlers/agent-status-update-handler.d.ts +1687 -0
- package/dist/handlers/message-handlers/agent-status-update-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/agent-status-update-handler.js +48 -0
- package/dist/handlers/message-handlers/agent-status-update-handler.js.map +1 -0
- package/dist/handlers/message-handlers/agents-list-handler.js +2 -5
- package/dist/handlers/message-handlers/agents-list-handler.js.map +1 -1
- package/dist/handlers/message-handlers/all-agents-response-handler.d.ts +439 -0
- package/dist/handlers/message-handlers/all-agents-response-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/all-agents-response-handler.js +36 -0
- package/dist/handlers/message-handlers/all-agents-response-handler.js.map +1 -0
- package/dist/handlers/message-handlers/auth-error-handler.d.ts +45 -31
- package/dist/handlers/message-handlers/auth-error-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-error-handler.js +2 -5
- package/dist/handlers/message-handlers/auth-error-handler.js.map +1 -1
- package/dist/handlers/message-handlers/auth-message-handler.d.ts +6 -0
- package/dist/handlers/message-handlers/auth-message-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-message-handler.js +71 -10
- package/dist/handlers/message-handlers/auth-message-handler.js.map +1 -1
- package/dist/handlers/message-handlers/auth-required-handler.d.ts +49 -31
- package/dist/handlers/message-handlers/auth-required-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-required-handler.js +2 -5
- package/dist/handlers/message-handlers/auth-required-handler.js.map +1 -1
- package/dist/handlers/message-handlers/auth-success-handler.d.ts +6 -0
- package/dist/handlers/message-handlers/auth-success-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-success-handler.js +52 -9
- package/dist/handlers/message-handlers/auth-success-handler.js.map +1 -1
- package/dist/handlers/message-handlers/base-handler.d.ts +4 -4
- package/dist/handlers/message-handlers/base-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/base-handler.js +3 -1
- package/dist/handlers/message-handlers/base-handler.js.map +1 -1
- package/dist/handlers/message-handlers/challenge-handler.d.ts +45 -31
- package/dist/handlers/message-handlers/challenge-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/challenge-handler.js +3 -2
- package/dist/handlers/message-handlers/challenge-handler.js.map +1 -1
- package/dist/handlers/message-handlers/error-message-handler.d.ts +49 -31
- package/dist/handlers/message-handlers/error-message-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/error-message-handler.js +2 -5
- package/dist/handlers/message-handlers/error-message-handler.js.map +1 -1
- package/dist/handlers/message-handlers/index.d.ts +11 -0
- package/dist/handlers/message-handlers/index.d.ts.map +1 -1
- package/dist/handlers/message-handlers/index.js +55 -1
- package/dist/handlers/message-handlers/index.js.map +1 -1
- package/dist/handlers/message-handlers/list-available-agents-handler.d.ts +1660 -0
- package/dist/handlers/message-handlers/list-available-agents-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/list-available-agents-handler.js +35 -0
- package/dist/handlers/message-handlers/list-available-agents-handler.js.map +1 -0
- package/dist/handlers/message-handlers/list-room-agents-handler.d.ts +1669 -0
- package/dist/handlers/message-handlers/list-room-agents-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/list-room-agents-handler.js +48 -0
- package/dist/handlers/message-handlers/list-room-agents-handler.js.map +1 -0
- package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts +2 -110
- package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/list-rooms-response-handler.js +4 -6
- package/dist/handlers/message-handlers/list-rooms-response-handler.js.map +1 -1
- package/dist/handlers/message-handlers/ping-pong-handler.d.ts +62 -58
- package/dist/handlers/message-handlers/ping-pong-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/ping-pong-handler.js +4 -10
- package/dist/handlers/message-handlers/ping-pong-handler.js.map +1 -1
- package/dist/handlers/message-handlers/rate-limit-notification-handler.d.ts +94 -0
- package/dist/handlers/message-handlers/rate-limit-notification-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/rate-limit-notification-handler.js +35 -0
- package/dist/handlers/message-handlers/rate-limit-notification-handler.js.map +1 -0
- package/dist/handlers/message-handlers/regular-message-handler.d.ts +31 -29
- package/dist/handlers/message-handlers/regular-message-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/regular-message-handler.js +4 -6
- package/dist/handlers/message-handlers/regular-message-handler.js.map +1 -1
- package/dist/handlers/message-handlers/room-operation-response-handler.d.ts +328 -0
- package/dist/handlers/message-handlers/room-operation-response-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/room-operation-response-handler.js +89 -0
- package/dist/handlers/message-handlers/room-operation-response-handler.js.map +1 -0
- package/dist/handlers/message-handlers/subscribe-response-handler.d.ts +53 -31
- package/dist/handlers/message-handlers/subscribe-response-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/subscribe-response-handler.js +4 -6
- package/dist/handlers/message-handlers/subscribe-response-handler.js.map +1 -1
- package/dist/handlers/message-handlers/task-quote-handler.d.ts +14 -0
- package/dist/handlers/message-handlers/task-quote-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/task-quote-handler.js +29 -0
- package/dist/handlers/message-handlers/task-quote-handler.js.map +1 -0
- package/dist/handlers/message-handlers/task-response-handler.js +2 -5
- package/dist/handlers/message-handlers/task-response-handler.js.map +1 -1
- package/dist/handlers/message-handlers/types.d.ts +21 -7
- package/dist/handlers/message-handlers/types.d.ts.map +1 -1
- package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts +53 -31
- package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/unsubscribe-response-handler.js +4 -6
- package/dist/handlers/message-handlers/unsubscribe-response-handler.js.map +1 -1
- package/dist/handlers/message-handlers/user-authenticated-handler.d.ts +40 -0
- package/dist/handlers/message-handlers/user-authenticated-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/user-authenticated-handler.js +28 -0
- package/dist/handlers/message-handlers/user-authenticated-handler.js.map +1 -0
- package/dist/handlers/message-handlers/user-count-handler.d.ts +49 -0
- package/dist/handlers/message-handlers/user-count-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/user-count-handler.js +31 -0
- package/dist/handlers/message-handlers/user-count-handler.js.map +1 -0
- package/dist/handlers/webhook-handler.d.ts +1 -1
- package/dist/handlers/webhook-handler.d.ts.map +1 -1
- package/dist/handlers/webhook-handler.js +14 -5
- package/dist/handlers/webhook-handler.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -2
- package/dist/index.js.map +1 -1
- package/dist/managers/admin-manager.d.ts +116 -0
- package/dist/managers/admin-manager.d.ts.map +1 -0
- package/dist/managers/admin-manager.js +169 -0
- package/dist/managers/admin-manager.js.map +1 -0
- package/dist/managers/agent-registry.d.ts +52 -1
- package/dist/managers/agent-registry.d.ts.map +1 -1
- package/dist/managers/agent-registry.js +145 -6
- package/dist/managers/agent-registry.js.map +1 -1
- package/dist/managers/agent-room-manager.d.ts +216 -0
- package/dist/managers/agent-room-manager.d.ts.map +1 -0
- package/dist/managers/agent-room-manager.js +555 -0
- package/dist/managers/agent-room-manager.js.map +1 -0
- package/dist/managers/connection-manager.js +2 -0
- package/dist/managers/connection-manager.js.map +1 -1
- package/dist/managers/index.d.ts +4 -1
- package/dist/managers/index.d.ts.map +1 -1
- package/dist/managers/index.js +7 -1
- package/dist/managers/index.js.map +1 -1
- package/dist/managers/message-router.d.ts +56 -5
- package/dist/managers/message-router.d.ts.map +1 -1
- package/dist/managers/message-router.js +155 -8
- package/dist/managers/message-router.js.map +1 -1
- package/dist/managers/room-management-manager.d.ts +213 -0
- package/dist/managers/room-management-manager.d.ts.map +1 -0
- package/dist/managers/room-management-manager.js +442 -0
- package/dist/managers/room-management-manager.js.map +1 -0
- package/dist/managers/room-manager.d.ts +11 -9
- package/dist/managers/room-manager.d.ts.map +1 -1
- package/dist/managers/room-manager.js +14 -10
- package/dist/managers/room-manager.js.map +1 -1
- package/dist/payments/index.d.ts +5 -0
- package/dist/payments/index.d.ts.map +1 -0
- package/dist/payments/index.js +21 -0
- package/dist/payments/index.js.map +1 -0
- package/dist/payments/payment-client.d.ts +74 -0
- package/dist/payments/payment-client.d.ts.map +1 -0
- package/dist/payments/payment-client.js +207 -0
- package/dist/payments/payment-client.js.map +1 -0
- package/dist/teneo-sdk.d.ts +467 -33
- package/dist/teneo-sdk.d.ts.map +1 -1
- package/dist/teneo-sdk.js +735 -26
- package/dist/teneo-sdk.js.map +1 -1
- package/dist/types/categories.d.ts +22 -0
- package/dist/types/categories.d.ts.map +1 -0
- package/dist/types/categories.js +40 -0
- package/dist/types/categories.js.map +1 -0
- package/dist/types/config.d.ts +134 -54
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +70 -9
- package/dist/types/config.js.map +1 -1
- package/dist/types/error-codes.d.ts +10 -0
- package/dist/types/error-codes.d.ts.map +1 -1
- package/dist/types/error-codes.js +12 -0
- package/dist/types/error-codes.js.map +1 -1
- package/dist/types/events.d.ts +176 -68
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/events.js +19 -1
- package/dist/types/events.js.map +1 -1
- package/dist/types/index.d.ts +3 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +57 -2
- package/dist/types/index.js.map +1 -1
- package/dist/types/messages.d.ts +22225 -2592
- package/dist/types/messages.d.ts.map +1 -1
- package/dist/types/messages.js +537 -28
- package/dist/types/messages.js.map +1 -1
- package/dist/utils/bounded-queue.d.ts.map +1 -1
- package/dist/utils/bounded-queue.js +5 -2
- package/dist/utils/bounded-queue.js.map +1 -1
- package/dist/utils/circuit-breaker.js +11 -4
- package/dist/utils/circuit-breaker.js.map +1 -1
- package/dist/utils/deduplication-cache.js +3 -1
- package/dist/utils/deduplication-cache.js.map +1 -1
- package/dist/utils/event-waiter.d.ts +3 -3
- package/dist/utils/event-waiter.d.ts.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +4 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/pricing-resolver.d.ts +26 -0
- package/dist/utils/pricing-resolver.d.ts.map +1 -0
- package/dist/utils/pricing-resolver.js +85 -0
- package/dist/utils/pricing-resolver.js.map +1 -0
- package/dist/utils/rate-limiter.d.ts.map +1 -1
- package/dist/utils/rate-limiter.js +6 -0
- package/dist/utils/rate-limiter.js.map +1 -1
- package/dist/utils/retry-policy.js +1 -0
- package/dist/utils/retry-policy.js.map +1 -1
- package/dist/utils/secure-private-key.js +3 -1
- package/dist/utils/secure-private-key.js.map +1 -1
- package/dist/utils/signature-verifier.d.ts.map +1 -1
- package/dist/utils/signature-verifier.js +3 -1
- package/dist/utils/signature-verifier.js.map +1 -1
- package/examples/.env.example +2 -2
- package/examples/agent-room-management-example.ts +335 -0
- package/examples/basic-usage.ts +3 -4
- package/examples/claude-agent-x-follower/.env.example +3 -3
- package/examples/claude-agent-x-follower/QUICKSTART.md +3 -3
- package/examples/claude-agent-x-follower/README.md +3 -3
- package/examples/claude-agent-x-follower/index.ts +120 -96
- package/examples/n8n-teneo/.env.example +3 -3
- package/examples/n8n-teneo/README.md +2 -2
- package/examples/n8n-teneo/index.ts +54 -44
- package/examples/nestjs-dashboard/.env.example +11 -0
- package/examples/nestjs-dashboard/README.md +297 -0
- package/examples/nestjs-dashboard/nest-cli.json +10 -0
- package/examples/nestjs-dashboard/package.json +44 -0
- package/examples/nestjs-dashboard/pnpm-lock.yaml +3079 -0
- package/examples/nestjs-dashboard/src/app.controller.ts +24 -0
- package/examples/nestjs-dashboard/src/app.module.ts +15 -0
- package/examples/nestjs-dashboard/src/main.ts +32 -0
- package/examples/nestjs-dashboard/src/public/dashboard.html +1144 -0
- package/examples/nestjs-dashboard/src/teneo/agents.controller.ts +54 -0
- package/examples/nestjs-dashboard/src/teneo/events.controller.ts +65 -0
- package/examples/nestjs-dashboard/src/teneo/messages.controller.ts +47 -0
- package/examples/nestjs-dashboard/src/teneo/rooms.controller.ts +258 -0
- package/examples/nestjs-dashboard/src/teneo/teneo.module.ts +13 -0
- package/examples/nestjs-dashboard/src/teneo/teneo.service.ts +484 -0
- package/examples/nestjs-dashboard/tsconfig.json +22 -0
- package/examples/openai-teneo/.env.example +3 -3
- package/examples/openai-teneo/README.md +3 -3
- package/examples/openai-teneo/index.ts +82 -71
- package/examples/production-dashboard/.env.example +3 -3
- package/examples/production-dashboard/README.md +90 -13
- package/examples/production-dashboard/public/dashboard.html +1173 -601
- package/examples/production-dashboard/server.ts +349 -7
- package/examples/room-management-example.ts +282 -0
- package/examples/usage/.env.example +2 -2
- package/examples/usage/01-connect.ts +3 -4
- package/examples/usage/02-list-agents.ts +2 -3
- package/examples/usage/03-pick-agent.ts +2 -3
- package/examples/usage/04-find-by-capability.ts +2 -3
- package/examples/usage/05-webhook-example.ts +2 -3
- package/examples/usage/06-simple-api-server.ts +2 -3
- package/examples/usage/07-event-listener.ts +2 -3
- package/examples/usage/README.md +1 -1
- package/examples/webhook-integration.ts +1 -1
- package/examples/x-influencer-battle-server.ts +2 -2
- package/package.json +12 -1
- package/src/core/websocket-client.test.ts +8 -3
- package/src/core/websocket-client.ts +58 -4
- package/src/formatters/response-formatter.test.ts +2 -0
- package/src/formatters/response-formatter.ts +3 -3
- package/src/handlers/message-handlers/agent-details-response-handler.ts +42 -0
- package/src/handlers/message-handlers/agent-room-operation-response-handler.ts +77 -0
- package/src/handlers/message-handlers/agent-status-update-handler.ts +52 -0
- package/src/handlers/message-handlers/all-agents-response-handler.ts +39 -0
- package/src/handlers/message-handlers/auth-message-handler.ts +78 -5
- package/src/handlers/message-handlers/auth-success-handler.ts +63 -6
- package/src/handlers/message-handlers/base-handler.ts +20 -7
- package/src/handlers/message-handlers/index.ts +53 -0
- package/src/handlers/message-handlers/list-available-agents-handler.ts +41 -0
- package/src/handlers/message-handlers/list-room-agents-handler.ts +58 -0
- package/src/handlers/message-handlers/list-rooms-response-handler.ts +4 -2
- package/src/handlers/message-handlers/rate-limit-notification-handler.ts +45 -0
- package/src/handlers/message-handlers/regular-message-handler.ts +3 -2
- package/src/handlers/message-handlers/room-operation-response-handler.ts +102 -0
- package/src/handlers/message-handlers/subscribe-response-handler.ts +12 -2
- package/src/handlers/message-handlers/task-quote-handler.ts +31 -0
- package/src/handlers/message-handlers/types.ts +41 -7
- package/src/handlers/message-handlers/unsubscribe-response-handler.ts +12 -2
- package/src/handlers/message-handlers/user-authenticated-handler.ts +31 -0
- package/src/handlers/message-handlers/user-count-handler.ts +34 -0
- package/src/handlers/webhook-handler.test.ts +3 -2
- package/src/handlers/webhook-handler.ts +13 -7
- package/src/index.ts +21 -0
- package/src/managers/admin-manager.ts +249 -0
- package/src/managers/agent-registry.test.ts +2 -1
- package/src/managers/agent-registry.ts +170 -2
- package/src/managers/agent-room-manager.ts +665 -0
- package/src/managers/index.ts +15 -1
- package/src/managers/message-router.ts +215 -17
- package/src/managers/room-management-manager.ts +520 -0
- package/src/managers/room-manager.ts +15 -20
- package/src/payments/index.ts +22 -0
- package/src/payments/payment-client.ts +240 -0
- package/src/teneo-sdk.ts +806 -30
- package/src/types/categories.ts +45 -0
- package/src/types/config.ts +80 -7
- package/src/types/error-codes.ts +14 -0
- package/src/types/events.test.ts +1 -0
- package/src/types/events.ts +67 -0
- package/src/types/index.ts +111 -0
- package/src/types/messages.test.ts +2 -1
- package/src/types/messages.ts +677 -42
- package/src/utils/bounded-queue.test.ts +1 -1
- package/src/utils/bounded-queue.ts +2 -1
- package/src/utils/circuit-breaker.test.ts +1 -1
- package/src/utils/deduplication-cache.test.ts +1 -1
- package/src/utils/event-waiter.test.ts +1 -1
- package/src/utils/event-waiter.ts +3 -3
- package/src/utils/index.ts +7 -0
- package/src/utils/logger.ts +8 -8
- package/src/utils/pricing-resolver.ts +128 -0
- package/src/utils/rate-limiter.test.ts +1 -1
- package/src/utils/rate-limiter.ts +1 -0
- package/src/utils/signature-verifier.test.ts +2 -2
- package/src/utils/signature-verifier.ts +3 -2
- package/tests/.env.example +7 -0
- package/tests/direct-agent-test.ts +151 -0
- package/tests/integration/real-server.test.ts +2 -0
- package/tests/integration/room-management.test.ts +516 -0
- package/tests/integration/websocket.test.ts +5 -2
- package/tests/payment-flow-test.ts +147 -0
- package/tests/unit/handlers/agent-room-operation-response-handler.test.ts +382 -0
- package/tests/unit/handlers/agent-status-update-handler.test.ts +403 -0
- package/tests/unit/handlers/auth-success-handler-rooms.test.ts +697 -0
- package/tests/unit/handlers/list-available-agents-handler.test.ts +248 -0
- package/tests/unit/handlers/list-room-agents-handler.test.ts +290 -0
- package/tests/unit/handlers/room-operation-response-handler.test.ts +500 -0
- package/tests/unit/managers/agent-room-manager.test.ts +527 -0
- package/tests/unit/managers/room-management-manager.test.ts +420 -0
- package/tsconfig.json +2 -2
- package/vitest.config.ts +1 -0
|
@@ -0,0 +1,516 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration tests for Room Management (v2.0.0)
|
|
3
|
+
* Tests complete room CRUD flow with mock WebSocket server
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach } from "vitest";
|
|
7
|
+
import { WebSocketServer } from "ws";
|
|
8
|
+
import { TeneoSDK } from "../../src";
|
|
9
|
+
import { SDKConfigBuilder } from "../../src/types";
|
|
10
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
11
|
+
import { generatePrivateKey } from "viem/accounts";
|
|
12
|
+
import { RoomInfo } from "../../src/types";
|
|
13
|
+
|
|
14
|
+
// TODO: Fix integration test setup - mock server needs proper event handling
|
|
15
|
+
describe.skip("Room Management Integration Tests", () => {
|
|
16
|
+
let server: WebSocketServer;
|
|
17
|
+
let sdk: TeneoSDK;
|
|
18
|
+
let serverPort: number;
|
|
19
|
+
let privateKey: string;
|
|
20
|
+
let walletAddress: string;
|
|
21
|
+
|
|
22
|
+
// Mock server to simulate Teneo WebSocket server
|
|
23
|
+
beforeAll(() => {
|
|
24
|
+
serverPort = 8082;
|
|
25
|
+
privateKey = generatePrivateKey();
|
|
26
|
+
const account = privateKeyToAccount(privateKey);
|
|
27
|
+
walletAddress = account.address;
|
|
28
|
+
|
|
29
|
+
// Create WebSocket server
|
|
30
|
+
server = new WebSocketServer({ port: serverPort });
|
|
31
|
+
|
|
32
|
+
// Room storage for testing
|
|
33
|
+
const rooms = new Map<string, RoomInfo>();
|
|
34
|
+
let roomCounter = 1;
|
|
35
|
+
|
|
36
|
+
server.on("connection", (ws) => {
|
|
37
|
+
ws.on("message", (data) => {
|
|
38
|
+
const message = JSON.parse(data.toString());
|
|
39
|
+
|
|
40
|
+
// Handle different message types
|
|
41
|
+
switch (message.type) {
|
|
42
|
+
case "request_challenge":
|
|
43
|
+
ws.send(
|
|
44
|
+
JSON.stringify({
|
|
45
|
+
type: "challenge",
|
|
46
|
+
data: {
|
|
47
|
+
challenge: "test-challenge-" + Date.now(),
|
|
48
|
+
timestamp: Date.now()
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
);
|
|
52
|
+
break;
|
|
53
|
+
|
|
54
|
+
case "auth":
|
|
55
|
+
// Send auth success with room management info
|
|
56
|
+
ws.send(
|
|
57
|
+
JSON.stringify({
|
|
58
|
+
type: "auth_success",
|
|
59
|
+
data: {
|
|
60
|
+
id: "client-123",
|
|
61
|
+
type: "user",
|
|
62
|
+
address: message.data.address,
|
|
63
|
+
nft_verified: false,
|
|
64
|
+
is_whitelisted: true,
|
|
65
|
+
rooms: Array.from(rooms.values()),
|
|
66
|
+
max_private_rooms: 5 // v2.0: Room limit
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
);
|
|
70
|
+
break;
|
|
71
|
+
|
|
72
|
+
case "create_room": {
|
|
73
|
+
// Create new room
|
|
74
|
+
const newRoomId = `room-${roomCounter++}`;
|
|
75
|
+
const newRoom: RoomInfo = {
|
|
76
|
+
id: newRoomId,
|
|
77
|
+
name: message.name,
|
|
78
|
+
description: message.description,
|
|
79
|
+
is_public: message.is_public || false,
|
|
80
|
+
created_by: walletAddress,
|
|
81
|
+
created_at: new Date().toISOString(),
|
|
82
|
+
updated_at: new Date().toISOString(),
|
|
83
|
+
is_owner: true
|
|
84
|
+
};
|
|
85
|
+
rooms.set(newRoomId, newRoom);
|
|
86
|
+
|
|
87
|
+
// Send success response
|
|
88
|
+
ws.send(
|
|
89
|
+
JSON.stringify({
|
|
90
|
+
type: "room_operation_response",
|
|
91
|
+
data: {
|
|
92
|
+
success: true,
|
|
93
|
+
room: newRoom,
|
|
94
|
+
message: "Room created successfully"
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
);
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
case "update_room": {
|
|
102
|
+
// Update existing room
|
|
103
|
+
const roomId = message.room_id;
|
|
104
|
+
const existingRoom = rooms.get(roomId);
|
|
105
|
+
|
|
106
|
+
if (!existingRoom) {
|
|
107
|
+
ws.send(
|
|
108
|
+
JSON.stringify({
|
|
109
|
+
type: "room_operation_response",
|
|
110
|
+
data: {
|
|
111
|
+
success: false,
|
|
112
|
+
message: "Room not found",
|
|
113
|
+
room_id: roomId
|
|
114
|
+
}
|
|
115
|
+
})
|
|
116
|
+
);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Update room
|
|
121
|
+
const updatedRoom: RoomInfo = {
|
|
122
|
+
...existingRoom,
|
|
123
|
+
name: message.name ?? existingRoom.name,
|
|
124
|
+
description: message.description ?? existingRoom.description,
|
|
125
|
+
updated_at: new Date().toISOString()
|
|
126
|
+
};
|
|
127
|
+
rooms.set(roomId, updatedRoom);
|
|
128
|
+
|
|
129
|
+
// Send success response
|
|
130
|
+
ws.send(
|
|
131
|
+
JSON.stringify({
|
|
132
|
+
type: "room_operation_response",
|
|
133
|
+
data: {
|
|
134
|
+
success: true,
|
|
135
|
+
room: updatedRoom,
|
|
136
|
+
message: "Room updated successfully"
|
|
137
|
+
}
|
|
138
|
+
})
|
|
139
|
+
);
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
case "delete_room": {
|
|
144
|
+
// Delete room
|
|
145
|
+
const deleteRoomId = message.room_id;
|
|
146
|
+
const roomToDelete = rooms.get(deleteRoomId);
|
|
147
|
+
|
|
148
|
+
if (!roomToDelete) {
|
|
149
|
+
ws.send(
|
|
150
|
+
JSON.stringify({
|
|
151
|
+
type: "room_operation_response",
|
|
152
|
+
data: {
|
|
153
|
+
success: false,
|
|
154
|
+
message: "Room not found",
|
|
155
|
+
room_id: deleteRoomId
|
|
156
|
+
}
|
|
157
|
+
})
|
|
158
|
+
);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
rooms.delete(deleteRoomId);
|
|
163
|
+
|
|
164
|
+
// Send success response
|
|
165
|
+
ws.send(
|
|
166
|
+
JSON.stringify({
|
|
167
|
+
type: "room_operation_response",
|
|
168
|
+
data: {
|
|
169
|
+
success: true,
|
|
170
|
+
room_id: deleteRoomId,
|
|
171
|
+
message: "Room deleted successfully"
|
|
172
|
+
}
|
|
173
|
+
})
|
|
174
|
+
);
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
case "ping":
|
|
179
|
+
ws.send(JSON.stringify({ type: "pong" }));
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
afterAll(() => {
|
|
187
|
+
server.close();
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
beforeEach(async () => {
|
|
191
|
+
// Create SDK instance
|
|
192
|
+
const config = new SDKConfigBuilder()
|
|
193
|
+
.withWebSocketUrl(`ws://localhost:${serverPort}`)
|
|
194
|
+
.withAuthentication(privateKey)
|
|
195
|
+
.withReconnection(false) // Disable for tests
|
|
196
|
+
.build();
|
|
197
|
+
|
|
198
|
+
sdk = new TeneoSDK(config);
|
|
199
|
+
|
|
200
|
+
// Wait for connection and auth
|
|
201
|
+
await new Promise<void>((resolve, reject) => {
|
|
202
|
+
const timeout = setTimeout(() => {
|
|
203
|
+
reject(new Error("Connection timeout"));
|
|
204
|
+
}, 5000);
|
|
205
|
+
|
|
206
|
+
sdk.once("ready", () => {
|
|
207
|
+
clearTimeout(timeout);
|
|
208
|
+
resolve();
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
sdk.once("error", (error) => {
|
|
212
|
+
clearTimeout(timeout);
|
|
213
|
+
reject(error);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// Connect to server
|
|
217
|
+
sdk.connect().catch(reject);
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
afterEach(async () => {
|
|
222
|
+
if (sdk) {
|
|
223
|
+
await sdk.destroy();
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
describe("Room Creation", () => {
|
|
228
|
+
it("should create a private room", async () => {
|
|
229
|
+
const roomOptions = {
|
|
230
|
+
name: "Test Private Room",
|
|
231
|
+
description: "A test private room"
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
const room = await sdk.createRoom(roomOptions);
|
|
235
|
+
|
|
236
|
+
expect(room).toBeDefined();
|
|
237
|
+
expect(room.id).toBeDefined();
|
|
238
|
+
expect(room.name).toBe(roomOptions.name);
|
|
239
|
+
expect(room.description).toBe(roomOptions.description);
|
|
240
|
+
expect(room.is_public).toBe(false);
|
|
241
|
+
expect(room.is_owner).toBe(true);
|
|
242
|
+
expect(room.created_by).toBeDefined();
|
|
243
|
+
expect(room.created_at).toBeDefined();
|
|
244
|
+
|
|
245
|
+
// Should be in owned rooms
|
|
246
|
+
const ownedRooms = sdk.getOwnedRooms();
|
|
247
|
+
expect(ownedRooms).toHaveLength(1);
|
|
248
|
+
expect(ownedRooms[0].id).toBe(room.id);
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
it("should emit room:created event", async () => {
|
|
252
|
+
const roomOptions = {
|
|
253
|
+
name: "Event Test Room"
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
const eventPromise = new Promise<RoomInfo>((resolve) => {
|
|
257
|
+
sdk.once("room:created", (room) => {
|
|
258
|
+
resolve(room);
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
const room = await sdk.createRoom(roomOptions);
|
|
263
|
+
const emittedRoom = await eventPromise;
|
|
264
|
+
|
|
265
|
+
expect(emittedRoom.id).toBe(room.id);
|
|
266
|
+
expect(emittedRoom.name).toBe(room.name);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it("should validate room name", async () => {
|
|
270
|
+
await expect(sdk.createRoom({ name: "" })).rejects.toThrow("Room name cannot be empty");
|
|
271
|
+
|
|
272
|
+
await expect(sdk.createRoom({ name: "a".repeat(101) })).rejects.toThrow("Room name too long");
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
it("should validate room description", async () => {
|
|
276
|
+
await expect(
|
|
277
|
+
sdk.createRoom({
|
|
278
|
+
name: "Test",
|
|
279
|
+
description: "a".repeat(501)
|
|
280
|
+
})
|
|
281
|
+
).rejects.toThrow("Room description too long");
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
describe("Room Updates", () => {
|
|
286
|
+
it("should update room name", async () => {
|
|
287
|
+
// Create room first
|
|
288
|
+
const room = await sdk.createRoom({ name: "Original Name" });
|
|
289
|
+
|
|
290
|
+
// Update name
|
|
291
|
+
const updatedRoom = await sdk.updateRoom(room.id, { name: "Updated Name" });
|
|
292
|
+
|
|
293
|
+
expect(updatedRoom.id).toBe(room.id);
|
|
294
|
+
expect(updatedRoom.name).toBe("Updated Name");
|
|
295
|
+
|
|
296
|
+
// Should be updated in cache
|
|
297
|
+
const cachedRoom = sdk.getRoomById(room.id);
|
|
298
|
+
expect(cachedRoom?.name).toBe("Updated Name");
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
it("should update room description", async () => {
|
|
302
|
+
const room = await sdk.createRoom({ name: "Test Room" });
|
|
303
|
+
|
|
304
|
+
const updatedRoom = await sdk.updateRoom(room.id, {
|
|
305
|
+
description: "New description"
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
expect(updatedRoom.description).toBe("New description");
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
it("should update both name and description", async () => {
|
|
312
|
+
const room = await sdk.createRoom({ name: "Test Room" });
|
|
313
|
+
|
|
314
|
+
const updatedRoom = await sdk.updateRoom(room.id, {
|
|
315
|
+
name: "New Name",
|
|
316
|
+
description: "New description"
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
expect(updatedRoom.name).toBe("New Name");
|
|
320
|
+
expect(updatedRoom.description).toBe("New description");
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
it("should emit room:updated event", async () => {
|
|
324
|
+
const room = await sdk.createRoom({ name: "Test Room" });
|
|
325
|
+
|
|
326
|
+
const eventPromise = new Promise<RoomInfo>((resolve) => {
|
|
327
|
+
sdk.once("room:updated", (updatedRoom) => {
|
|
328
|
+
resolve(updatedRoom);
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
await sdk.updateRoom(room.id, { name: "Updated" });
|
|
333
|
+
const emittedRoom = await eventPromise;
|
|
334
|
+
|
|
335
|
+
expect(emittedRoom.id).toBe(room.id);
|
|
336
|
+
expect(emittedRoom.name).toBe("Updated");
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
it("should validate update parameters", async () => {
|
|
340
|
+
const room = await sdk.createRoom({ name: "Test Room" });
|
|
341
|
+
|
|
342
|
+
await expect(sdk.updateRoom(room.id, {})).rejects.toThrow("At least one field");
|
|
343
|
+
|
|
344
|
+
await expect(sdk.updateRoom(room.id, { name: "" })).rejects.toThrow(
|
|
345
|
+
"Room name cannot be empty"
|
|
346
|
+
);
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
describe("Room Deletion", () => {
|
|
351
|
+
it("should delete a room", async () => {
|
|
352
|
+
// Create room first
|
|
353
|
+
const room = await sdk.createRoom({ name: "Room to Delete" });
|
|
354
|
+
|
|
355
|
+
expect(sdk.getOwnedRoomCount()).toBe(1);
|
|
356
|
+
|
|
357
|
+
// Delete room
|
|
358
|
+
await sdk.deleteRoom(room.id);
|
|
359
|
+
|
|
360
|
+
// Should be removed from cache
|
|
361
|
+
expect(sdk.getOwnedRoomCount()).toBe(0);
|
|
362
|
+
expect(sdk.getRoomById(room.id)).toBeUndefined();
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
it("should emit room:deleted event", async () => {
|
|
366
|
+
const room = await sdk.createRoom({ name: "Test Room" });
|
|
367
|
+
|
|
368
|
+
const eventPromise = new Promise<string>((resolve) => {
|
|
369
|
+
sdk.once("room:deleted", (roomId) => {
|
|
370
|
+
resolve(roomId);
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
await sdk.deleteRoom(room.id);
|
|
375
|
+
const deletedRoomId = await eventPromise;
|
|
376
|
+
|
|
377
|
+
expect(deletedRoomId).toBe(room.id);
|
|
378
|
+
});
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
describe("Complete Room Lifecycle", () => {
|
|
382
|
+
it("should create, update, and delete a room", async () => {
|
|
383
|
+
// Create
|
|
384
|
+
const room = await sdk.createRoom({
|
|
385
|
+
name: "Lifecycle Test Room",
|
|
386
|
+
description: "Initial description"
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
expect(room.name).toBe("Lifecycle Test Room");
|
|
390
|
+
expect(sdk.getOwnedRoomCount()).toBe(1);
|
|
391
|
+
|
|
392
|
+
// Update
|
|
393
|
+
const updatedRoom = await sdk.updateRoom(room.id, {
|
|
394
|
+
name: "Updated Lifecycle Room",
|
|
395
|
+
description: "Updated description"
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
expect(updatedRoom.name).toBe("Updated Lifecycle Room");
|
|
399
|
+
expect(updatedRoom.description).toBe("Updated description");
|
|
400
|
+
expect(sdk.getOwnedRoomCount()).toBe(1);
|
|
401
|
+
|
|
402
|
+
// Delete
|
|
403
|
+
await sdk.deleteRoom(room.id);
|
|
404
|
+
|
|
405
|
+
expect(sdk.getOwnedRoomCount()).toBe(0);
|
|
406
|
+
expect(sdk.getRoomById(room.id)).toBeUndefined();
|
|
407
|
+
});
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
describe("Room Query Methods", () => {
|
|
411
|
+
it("should get owned rooms", async () => {
|
|
412
|
+
await sdk.createRoom({ name: "Room 1" });
|
|
413
|
+
await sdk.createRoom({ name: "Room 2" });
|
|
414
|
+
|
|
415
|
+
const ownedRooms = sdk.getOwnedRooms();
|
|
416
|
+
expect(ownedRooms).toHaveLength(2);
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
it("should get room by ID", async () => {
|
|
420
|
+
const room = await sdk.createRoom({ name: "Test Room" });
|
|
421
|
+
|
|
422
|
+
const found = sdk.getRoomById(room.id);
|
|
423
|
+
expect(found).toBeDefined();
|
|
424
|
+
expect(found?.name).toBe("Test Room");
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
it("should return undefined for non-existent room", () => {
|
|
428
|
+
const room = sdk.getRoomById("non-existent-id");
|
|
429
|
+
expect(room).toBeUndefined();
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
it("should get owned room count", async () => {
|
|
433
|
+
expect(sdk.getOwnedRoomCount()).toBe(0);
|
|
434
|
+
|
|
435
|
+
await sdk.createRoom({ name: "Room 1" });
|
|
436
|
+
expect(sdk.getOwnedRoomCount()).toBe(1);
|
|
437
|
+
|
|
438
|
+
await sdk.createRoom({ name: "Room 2" });
|
|
439
|
+
expect(sdk.getOwnedRoomCount()).toBe(2);
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
it("should get room limit", () => {
|
|
443
|
+
const limit = sdk.getRoomLimit();
|
|
444
|
+
expect(limit).toBe(5); // Set in mock server
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
it("should check if can create room", () => {
|
|
448
|
+
expect(sdk.canCreateRoom()).toBe(true);
|
|
449
|
+
});
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
describe("Return Value Immutability", () => {
|
|
453
|
+
it("should return defensive copies", async () => {
|
|
454
|
+
await sdk.createRoom({ name: "Test Room" });
|
|
455
|
+
|
|
456
|
+
const rooms1 = sdk.getOwnedRooms();
|
|
457
|
+
const rooms2 = sdk.getOwnedRooms();
|
|
458
|
+
|
|
459
|
+
// Should be different array instances
|
|
460
|
+
expect(rooms1).not.toBe(rooms2);
|
|
461
|
+
// But have same content
|
|
462
|
+
expect(rooms1[0].id).toBe(rooms2[0].id);
|
|
463
|
+
|
|
464
|
+
// Modifying returned array shouldn't affect internal state
|
|
465
|
+
rooms1[0].name = "Modified";
|
|
466
|
+
const rooms3 = sdk.getOwnedRooms();
|
|
467
|
+
expect(rooms3[0].name).not.toBe("Modified");
|
|
468
|
+
});
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
describe("Multiple Rooms", () => {
|
|
472
|
+
it("should handle creating multiple rooms", async () => {
|
|
473
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
474
|
+
const room1 = await sdk.createRoom({ name: "Room 1" });
|
|
475
|
+
const room2 = await sdk.createRoom({ name: "Room 2" });
|
|
476
|
+
const room3 = await sdk.createRoom({ name: "Room 3" });
|
|
477
|
+
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
478
|
+
|
|
479
|
+
expect(sdk.getOwnedRoomCount()).toBe(3);
|
|
480
|
+
|
|
481
|
+
const rooms = sdk.getOwnedRooms();
|
|
482
|
+
expect(rooms.map((r) => r.name)).toContain("Room 1");
|
|
483
|
+
expect(rooms.map((r) => r.name)).toContain("Room 2");
|
|
484
|
+
expect(rooms.map((r) => r.name)).toContain("Room 3");
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
it("should handle updating multiple rooms", async () => {
|
|
488
|
+
const room1 = await sdk.createRoom({ name: "Room 1" });
|
|
489
|
+
const room2 = await sdk.createRoom({ name: "Room 2" });
|
|
490
|
+
|
|
491
|
+
await sdk.updateRoom(room1.id, { name: "Updated Room 1" });
|
|
492
|
+
await sdk.updateRoom(room2.id, { name: "Updated Room 2" });
|
|
493
|
+
|
|
494
|
+
const rooms = sdk.getOwnedRooms();
|
|
495
|
+
expect(rooms.find((r) => r.id === room1.id)?.name).toBe("Updated Room 1");
|
|
496
|
+
expect(rooms.find((r) => r.id === room2.id)?.name).toBe("Updated Room 2");
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
it("should handle deleting multiple rooms", async () => {
|
|
500
|
+
const room1 = await sdk.createRoom({ name: "Room 1" });
|
|
501
|
+
const room2 = await sdk.createRoom({ name: "Room 2" });
|
|
502
|
+
const room3 = await sdk.createRoom({ name: "Room 3" });
|
|
503
|
+
|
|
504
|
+
expect(sdk.getOwnedRoomCount()).toBe(3);
|
|
505
|
+
|
|
506
|
+
await sdk.deleteRoom(room1.id);
|
|
507
|
+
expect(sdk.getOwnedRoomCount()).toBe(2);
|
|
508
|
+
|
|
509
|
+
await sdk.deleteRoom(room2.id);
|
|
510
|
+
expect(sdk.getOwnedRoomCount()).toBe(1);
|
|
511
|
+
|
|
512
|
+
await sdk.deleteRoom(room3.id);
|
|
513
|
+
expect(sdk.getOwnedRoomCount()).toBe(0);
|
|
514
|
+
});
|
|
515
|
+
});
|
|
516
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach } from "vitest";
|
|
2
|
-
import
|
|
2
|
+
import { WebSocketServer } from "ws";
|
|
3
3
|
import { TeneoSDK } from "../../src";
|
|
4
4
|
import { SDKConfigBuilder } from "../../src/types";
|
|
5
5
|
import { privateKeyToAccount } from "viem/accounts";
|
|
@@ -10,6 +10,7 @@ describe("WebSocket Integration Tests", () => {
|
|
|
10
10
|
let sdk: TeneoSDK;
|
|
11
11
|
let serverPort: number;
|
|
12
12
|
let privateKey: string;
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
13
14
|
let walletAddress: string;
|
|
14
15
|
|
|
15
16
|
// Mock server to simulate Teneo WebSocket server
|
|
@@ -150,6 +151,7 @@ describe("WebSocket Integration Tests", () => {
|
|
|
150
151
|
.withAuthentication(privateKey)
|
|
151
152
|
.withReconnection(false) // Disable for tests
|
|
152
153
|
.withAutoJoinRooms(["test-room"]) // Auto-join test room
|
|
154
|
+
.withPayments({ autoApprove: false }) // Use legacy flow for mock server
|
|
153
155
|
.build();
|
|
154
156
|
|
|
155
157
|
sdk = new TeneoSDK(config);
|
|
@@ -290,6 +292,7 @@ describe("WebSocket Integration Tests", () => {
|
|
|
290
292
|
.withAuthentication(privateKey)
|
|
291
293
|
.withWebhook("http://localhost:3001/webhook")
|
|
292
294
|
.withReconnection(false)
|
|
295
|
+
.withPayments({ autoApprove: false }) // Use legacy flow for mock server
|
|
293
296
|
.build()
|
|
294
297
|
);
|
|
295
298
|
|
|
@@ -310,7 +313,7 @@ describe("WebSocket Integration Tests", () => {
|
|
|
310
313
|
});
|
|
311
314
|
|
|
312
315
|
describe("Integration with Real Server", () => {
|
|
313
|
-
const REAL_SERVER_URL = "wss://
|
|
316
|
+
const REAL_SERVER_URL = "wss://your-teneo-server.com/ws";
|
|
314
317
|
let sdk: TeneoSDK;
|
|
315
318
|
let privateKey: string;
|
|
316
319
|
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payment Flow Test - Tests the quote-approve payment flow
|
|
3
|
+
*
|
|
4
|
+
* Setup:
|
|
5
|
+
* Create a .env file in the teneo-sdk root with:
|
|
6
|
+
* PRIVATE_KEY=your_private_key_here
|
|
7
|
+
* WS_URL=wss://backend.developer.chatroom.teneo-protocol.ai/ws # optional
|
|
8
|
+
*
|
|
9
|
+
* Run:
|
|
10
|
+
* npx tsx tests/payment-flow-test.ts
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import "dotenv/config";
|
|
14
|
+
import { TeneoSDK } from "../src/teneo-sdk";
|
|
15
|
+
|
|
16
|
+
// Configuration from environment variables (loaded from .env)
|
|
17
|
+
const WS_URL = process.env.WS_URL || "wss://backend.developer.chatroom.teneo-protocol.ai/ws";
|
|
18
|
+
const PRIVATE_KEY = process.env.PRIVATE_KEY;
|
|
19
|
+
|
|
20
|
+
if (!PRIVATE_KEY) {
|
|
21
|
+
console.error("❌ Missing PRIVATE_KEY");
|
|
22
|
+
console.error("");
|
|
23
|
+
console.error("Setup: Create a .env file in the teneo-sdk root with:");
|
|
24
|
+
console.error(" PRIVATE_KEY=your_private_key_here");
|
|
25
|
+
console.error("");
|
|
26
|
+
console.error("Then run:");
|
|
27
|
+
console.error(" npx tsx tests/payment-flow-test.ts");
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Type assertion after validation
|
|
32
|
+
const privateKey: string = PRIVATE_KEY;
|
|
33
|
+
|
|
34
|
+
let TEST_ROOM = ""; // Will be set after auth to use user's private room
|
|
35
|
+
|
|
36
|
+
async function testPaymentFlow() {
|
|
37
|
+
console.log("=== Payment Flow Test ===\n");
|
|
38
|
+
console.log("WebSocket URL:", WS_URL);
|
|
39
|
+
|
|
40
|
+
// Create SDK with quote-approve enabled
|
|
41
|
+
const config = TeneoSDK.builder()
|
|
42
|
+
.withWebSocketUrl(WS_URL)
|
|
43
|
+
.withAuthentication(privateKey)
|
|
44
|
+
.withPayments({
|
|
45
|
+
autoApprove: true,
|
|
46
|
+
maxPricePerRequest: 10_000_000 // Max 10 USDC
|
|
47
|
+
})
|
|
48
|
+
.withLogging("info")
|
|
49
|
+
.build();
|
|
50
|
+
|
|
51
|
+
const sdk = new TeneoSDK(config);
|
|
52
|
+
|
|
53
|
+
// Set up event listeners
|
|
54
|
+
sdk.on("connection:open", () => console.log("✓ Connected"));
|
|
55
|
+
sdk.on("auth:success", (state) => {
|
|
56
|
+
console.log("✓ Authenticated as:", state.walletAddress);
|
|
57
|
+
// Get user's first private room
|
|
58
|
+
if (state.privateRoomIds && state.privateRoomIds.length > 0) {
|
|
59
|
+
TEST_ROOM = state.privateRoomIds[0];
|
|
60
|
+
console.log("✓ Using room:", TEST_ROOM);
|
|
61
|
+
} else if (state.rooms && state.rooms.length > 0) {
|
|
62
|
+
TEST_ROOM = state.rooms[0];
|
|
63
|
+
console.log("✓ Using room:", TEST_ROOM);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
sdk.on("quote:received", (quote) => {
|
|
67
|
+
console.log("\n📋 Quote Received:");
|
|
68
|
+
console.log(" Task ID:", quote.data.task_id);
|
|
69
|
+
console.log(" Agent:", quote.data.agent_name);
|
|
70
|
+
console.log(" Price:", quote.data.pricing.pricePerUnit, "USDC");
|
|
71
|
+
console.log(" Expires:", quote.data.expires_at);
|
|
72
|
+
});
|
|
73
|
+
sdk.on("payment:attached", (data) => {
|
|
74
|
+
console.log("\n💰 Payment Attached:");
|
|
75
|
+
console.log(" Agent:", data.agentId);
|
|
76
|
+
console.log(" Amount:", data.amount / 1_000_000, "USDC");
|
|
77
|
+
console.log(" Command:", data.command);
|
|
78
|
+
});
|
|
79
|
+
sdk.on("agent:response", (response) => {
|
|
80
|
+
console.log("\n📥 Agent Response:");
|
|
81
|
+
console.log(" Success:", response.success);
|
|
82
|
+
console.log(" Content:", response.content.substring(0, 200) + "...");
|
|
83
|
+
});
|
|
84
|
+
sdk.on("error", (error) => console.error("❌ Error:", error.message));
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
// Connect
|
|
88
|
+
console.log("\nConnecting to", WS_URL);
|
|
89
|
+
await sdk.connect();
|
|
90
|
+
console.log("Connected!\n");
|
|
91
|
+
|
|
92
|
+
// Wait for auth to complete and room to be set
|
|
93
|
+
await sleep(500);
|
|
94
|
+
|
|
95
|
+
if (!TEST_ROOM) {
|
|
96
|
+
throw new Error("No room available - auth may have failed");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Subscribe to test room
|
|
100
|
+
console.log("Subscribing to room:", TEST_ROOM);
|
|
101
|
+
try {
|
|
102
|
+
await sdk.subscribeToRoom(TEST_ROOM);
|
|
103
|
+
console.log("Subscribed!\n");
|
|
104
|
+
} catch {
|
|
105
|
+
console.log("Room subscription skipped (private room)\n");
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Wait a bit for connection to stabilize
|
|
109
|
+
await sleep(1000);
|
|
110
|
+
|
|
111
|
+
// Send test message - this will trigger quote-approve flow
|
|
112
|
+
console.log("\n=== Sending Test Request ===");
|
|
113
|
+
console.log('Request: "get me 1 post from @elonmusk from x"\n');
|
|
114
|
+
|
|
115
|
+
const response = await sdk.sendMessage("get me 1 post from @elonmusk from x", {
|
|
116
|
+
room: TEST_ROOM,
|
|
117
|
+
waitForResponse: true,
|
|
118
|
+
timeout: 120000 // 2 minutes
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
if (response) {
|
|
122
|
+
console.log("\n=== Test Complete ===");
|
|
123
|
+
console.log("Response received successfully!");
|
|
124
|
+
console.log(
|
|
125
|
+
"Humanized:",
|
|
126
|
+
typeof response.humanized === "string" ? response.humanized.substring(0, 500) : response
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
} catch (error: unknown) {
|
|
130
|
+
const err = error as Error & { details?: unknown };
|
|
131
|
+
console.error("\n❌ Test failed:", err.message);
|
|
132
|
+
if (err.details) {
|
|
133
|
+
console.error("Details:", err.details);
|
|
134
|
+
}
|
|
135
|
+
} finally {
|
|
136
|
+
console.log("\nDisconnecting...");
|
|
137
|
+
sdk.destroy();
|
|
138
|
+
console.log("Done!");
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function sleep(ms: number): Promise<void> {
|
|
143
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Run the test
|
|
147
|
+
testPaymentFlow().catch(console.error);
|