diff --git a/core/src/server/ws-handler.ts b/core/src/server/ws-handler.ts index bef1d94c..96d8638d 100644 --- a/core/src/server/ws-handler.ts +++ b/core/src/server/ws-handler.ts @@ -103,6 +103,7 @@ const WATCH_METHODS = new Set([ "watchOrderBook", "watchOrderBooks", "watchTrades", + "watchAddress", ]); /** Data-feed methods that produce streaming data. */ @@ -113,6 +114,7 @@ const FEED_WATCH_METHODS = new Set([ /** Methods for unsubscribing. */ const UNWATCH_METHODS: Record = { unwatchOrderBook: "watchOrderBook", + unwatchAddress: "watchAddress", }; function send(ws: WebSocket, msg: ServerEvent): void { diff --git a/core/test/pipeline/ws-handler-streaming-methods.test.ts b/core/test/pipeline/ws-handler-streaming-methods.test.ts new file mode 100644 index 00000000..0c2b7586 --- /dev/null +++ b/core/test/pipeline/ws-handler-streaming-methods.test.ts @@ -0,0 +1,26 @@ +import fs from 'fs'; +import path from 'path'; + +const repoRoot = path.resolve(__dirname, '../../..'); + +function read(relativePath: string): string { + return fs.readFileSync(path.join(repoRoot, relativePath), 'utf8'); +} + +describe('WebSocket streaming method registry', () => { + it('accepts every exchange method declared with the ws verb', () => { + const methodVerbConfig = JSON.parse(read('core/src/server/method-verbs.json')) as Record; + const wsHandler = read('core/src/server/ws-handler.ts'); + + const registeredMethodNames = new Set( + Array.from(wsHandler.matchAll(/(?:["'])(watch[A-Za-z]+|unwatch[A-Za-z]+)(?:["'])|\b(unwatch[A-Za-z]+)\s*:/g)) + .map((match) => match[1] || match[2]) + .filter(Boolean), + ); + const wsMethods = Object.entries(methodVerbConfig) + .filter(([, config]) => config.verb === 'ws') + .map(([method]) => method); + + expect(wsMethods.filter((method) => !registeredMethodNames.has(method))).toEqual([]); + }); +});