@zofai/zo-sdk 0.2.17 → 0.2.18

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.
@@ -1,11 +1,13 @@
1
1
  import { describe, expect, it, vi } from 'vitest'
2
2
 
3
3
  import {
4
+ apiBaseUrlToStorkWsUrl,
4
5
  buildStorkUpdateDataFromSignedPrice,
5
6
  fetchStorkUpdateDataFromKronos,
6
7
  getLatestStorkPrices,
7
8
  hexToBytes,
8
9
  parseStorkUpdateDataRaw,
10
+ StorkStreamClient,
9
11
  } from '../src/storkClient'
10
12
  import { appendStorkUpdatesToTransaction, estimateStorkUpdateFeeMist } from '../src/storkOracle'
11
13
  import { Transaction } from '@mysten/sui/transactions'
@@ -314,3 +316,89 @@ describe('storkOracle', () => {
314
316
  expect(tx.getData().commands.length).toBe(3)
315
317
  })
316
318
  })
319
+
320
+ describe('StorkStreamClient', () => {
321
+ class MockWebSocket {
322
+ static OPEN = 1
323
+ readyState = MockWebSocket.OPEN
324
+ sent: string[] = []
325
+ private listeners: Record<string, Array<(event: { data?: string }) => void>> = {}
326
+
327
+ constructor(public url: string) {
328
+ queueMicrotask(() => {
329
+ this.listeners.open?.forEach(cb => cb({}))
330
+ this.emit({ data: JSON.stringify({ type: 'connected' }) })
331
+ })
332
+ }
333
+
334
+ addEventListener(event: string, cb: (event: { data?: string }) => void, opts?: { once?: boolean }) {
335
+ if (!this.listeners[event]) {
336
+ this.listeners[event] = []
337
+ }
338
+ if (opts?.once) {
339
+ const onceWrapper = (ev: { data?: string }) => {
340
+ this.listeners[event] = this.listeners[event].filter(h => h !== onceWrapper)
341
+ cb(ev)
342
+ }
343
+ this.listeners[event].push(onceWrapper)
344
+ return
345
+ }
346
+ this.listeners[event].push(cb)
347
+ }
348
+
349
+ send(data: string) {
350
+ this.sent.push(data)
351
+ }
352
+
353
+ close() {
354
+ this.readyState = 3
355
+ this.listeners.close?.forEach(cb => cb({}))
356
+ }
357
+
358
+ emit(event: { data?: string }) {
359
+ this.listeners.message?.forEach(cb => cb(event))
360
+ }
361
+ }
362
+
363
+ it('derives evm and stark ws urls from kronos base url', () => {
364
+ expect(apiBaseUrlToStorkWsUrl('https://api.zofinance.io')).toBe('wss://api.zofinance.io/stork/stream/evm')
365
+ expect(apiBaseUrlToStorkWsUrl('http://localhost:8080', 'stark')).toBe('ws://localhost:8080/stork/stream/stark')
366
+ })
367
+
368
+ it('subscribes and forwards oracle_prices', async () => {
369
+ vi.stubGlobal('WebSocket', MockWebSocket)
370
+
371
+ const client = new StorkStreamClient('http://localhost:8080', {
372
+ WebSocketImpl: MockWebSocket as unknown as typeof WebSocket,
373
+ pingIntervalMs: 0,
374
+ })
375
+
376
+ const updates: string[] = []
377
+ client.subscribe(['BTCUSD'], (update) => {
378
+ updates.push(update.prices.BTCUSD?.asset_id ?? '')
379
+ })
380
+
381
+ await client.connect()
382
+ await new Promise<void>(resolve => setTimeout(resolve, 0))
383
+
384
+ expect(JSON.parse((client as any).ws.sent[0]).type).toBe('subscribe')
385
+ expect(JSON.parse((client as any).ws.sent[0]).data).toEqual(['BTCUSD'])
386
+
387
+ ;(client as any).ws.emit({
388
+ data: JSON.stringify({
389
+ type: 'oracle_prices',
390
+ trace_id: 'trace-1',
391
+ data: {
392
+ BTCUSD: {
393
+ asset_id: 'BTCUSD',
394
+ price: '100000000000000000000',
395
+ stork_signed_price: { price: '100000000000000000000' },
396
+ },
397
+ },
398
+ }),
399
+ })
400
+
401
+ expect(updates).toEqual(['BTCUSD'])
402
+ client.disconnect()
403
+ })
404
+ })