-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
1,557 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,6 @@ | |
.DS_Store | ||
.idea/ | ||
*.pem | ||
|
||
node_modules | ||
dist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
{ | ||
"name": "@blockworks-foundation/mango-feeds", | ||
"version": "0.9.12", | ||
"description": "Typescript Client for mango-feeds.", | ||
"repository": "https://github.com/blockworks-foundation/mango-feeds", | ||
"author": { | ||
"name": "Blockworks Foundation", | ||
"email": "[email protected]", | ||
"url": "https://blockworks.foundation" | ||
}, | ||
"sideEffects": false, | ||
"main": "./dist/cjs/src/index.js", | ||
"module": "./dist/esm/src/index.js", | ||
"types": "./dist/types/src/index.d.ts", | ||
"files": [ | ||
"dist" | ||
], | ||
"scripts": { | ||
"build": "rimraf dist && yarn build:browser && yarn build:node && yarn build:types", | ||
"build:node": " tsc -p tsconfig.cjs.json --noEmit false", | ||
"build:browser": "tsc -p tsconfig.esm.json --noEmit false", | ||
"build:types": "tsc -p tsconfig.types.json --noEmit false", | ||
"test": "ts-mocha ts/client/**/*.spec.ts --timeout 300000", | ||
"lint": "eslint ./ts/client/src --ext ts --ext tsx --ext js --quiet", | ||
"typecheck": "tsc --noEmit --pretty", | ||
"prepublishOnly": "yarn validate && yarn build", | ||
"validate": "yarn lint && yarn format" | ||
}, | ||
"devDependencies": { | ||
"@tsconfig/recommended": "^1.0.1", | ||
"@types/node": "^18.11.18", | ||
"@typescript-eslint/eslint-plugin": "^5.32.0", | ||
"@typescript-eslint/parser": "^5.32.0", | ||
"eslint": "^7.28.0", | ||
"eslint-config-prettier": "^7.2.0", | ||
"prettier": "^2.0.5", | ||
"ts-node": "^10.9.1", | ||
"typedoc": "^0.22.5", | ||
"typescript": "^4.8.4" | ||
}, | ||
"prettier": { | ||
"singleQuote": true, | ||
"trailingComma": "all" | ||
}, | ||
"dependencies": { | ||
"ws": "^8.13.0" | ||
}, | ||
"license": "AGPL-3.0-only" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { FillsFeed } from '../src'; | ||
|
||
const RECONNECT_INTERVAL_MS = 1000; | ||
const RECONNECT_ATTEMPTS_MAX = -1; | ||
|
||
// Subscribe on connection | ||
const fillsFeed = new FillsFeed('ws://localhost:8080', { | ||
reconnectIntervalMs: RECONNECT_INTERVAL_MS, | ||
reconnectionMaxAttempts: RECONNECT_ATTEMPTS_MAX, | ||
subscriptions: { | ||
accountIds: ['9XJt2tvSZghsMAhWto1VuPBrwXsiimPtsTR8XwGgDxK2'], | ||
}, | ||
}); | ||
|
||
// Subscribe after connection | ||
fillsFeed.onConnect(() => { | ||
console.log('connected'); | ||
fillsFeed.subscribe({ | ||
marketIds: ['ESdnpnNLgTkBCZRuTJkZLi5wKEZ2z47SG3PJrhundSQ2'], | ||
headUpdates: true, | ||
}); | ||
}); | ||
|
||
fillsFeed.onDisconnect(() => { | ||
console.log(`disconnected, reconnecting in ${RECONNECT_INTERVAL_MS}...`); | ||
}); | ||
|
||
fillsFeed.onFill((update) => { | ||
console.log('fill', update); | ||
}); | ||
|
||
fillsFeed.onHead((update) => { | ||
console.log('head', update); | ||
}); | ||
|
||
fillsFeed.onStatus((update) => { | ||
console.log('status', update); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
import WebSocket from 'ws'; | ||
|
||
interface FillsFeedOptions { | ||
subscriptions?: FillsFeedSubscriptionParams; | ||
reconnectIntervalMs?: number; | ||
reconnectionMaxAttempts?: number; | ||
} | ||
|
||
interface FillsFeedSubscriptionParams { | ||
marketId?: string; | ||
marketIds?: string[]; | ||
accountIds?: string[]; | ||
headUpdates?: boolean; | ||
} | ||
|
||
interface FillEventUpdate { | ||
status: 'new' | 'revoke'; | ||
marketKey: 'string'; | ||
marketName: 'string'; | ||
slot: number; | ||
writeVersion: number; | ||
event: { | ||
eventType: 'spot' | 'perp'; | ||
maker: 'string'; | ||
taker: 'string'; | ||
takerSide: 'bid' | 'ask'; | ||
timestamp: 'string'; // DateTime | ||
seqNum: number; | ||
makerClientOrderId: number; | ||
takerClientOrderId: number; | ||
makerFee: number; | ||
takerFee: number; | ||
price: number; | ||
quantity: number; | ||
}; | ||
} | ||
|
||
function isFillEventUpdate(obj: any): obj is FillEventUpdate { | ||
return obj.event !== undefined; | ||
} | ||
|
||
interface HeadUpdate { | ||
head: number; | ||
previousHead: number; | ||
headSeqNum: number; | ||
previousHeadSeqNum: number; | ||
status: 'new' | 'revoke'; | ||
marketKey: 'string'; | ||
marketName: 'string'; | ||
slot: number; | ||
writeVersion: number; | ||
} | ||
|
||
function isHeadUpdate(obj: any): obj is HeadUpdate { | ||
return obj.head !== undefined; | ||
} | ||
|
||
interface StatusMessage { | ||
success: boolean; | ||
message: string; | ||
} | ||
|
||
function isStatusMessage(obj: any): obj is StatusMessage { | ||
return obj.success !== undefined; | ||
} | ||
|
||
export class FillsFeed { | ||
private _url: string; | ||
private _socket: WebSocket; | ||
private _subscriptions?: FillsFeedSubscriptionParams; | ||
private _connected: boolean; | ||
private _reconnectionIntervalMs; | ||
private _reconnectionAttempts; | ||
private _reconnectionMaxAttempts; | ||
|
||
private _onConnect: (() => void) | null = null; | ||
private _onDisconnect: (() => void) | null = null; | ||
private _onFill: ((update: FillEventUpdate) => void) | null = null; | ||
private _onHead: ((update: HeadUpdate) => void) | null = null; | ||
private _onStatus: ((update: StatusMessage) => void) | null = null; | ||
|
||
constructor(url: string, options?: FillsFeedOptions) { | ||
this._url = url; | ||
this._subscriptions = options?.subscriptions; | ||
this._reconnectionIntervalMs = options?.reconnectIntervalMs ?? 5000; | ||
this._reconnectionAttempts = 0; | ||
this._reconnectionMaxAttempts = options?.reconnectionMaxAttempts ?? -1; | ||
|
||
this._connect(); | ||
} | ||
|
||
private _reconnectionAttemptsExhausted(): boolean { | ||
return this._reconnectionMaxAttempts != -1 && this._reconnectionAttempts >= this._reconnectionMaxAttempts | ||
} | ||
|
||
private _connect() { | ||
this._socket = new WebSocket(this._url); | ||
|
||
this._socket.addEventListener('error', (err) => { | ||
console.warn(`[FillsFeed] connection error: ${err.message}`); | ||
if (this._reconnectionAttemptsExhausted()) { | ||
console.error('[FillsFeed] fatal connection error') | ||
throw err.error; | ||
} | ||
}); | ||
|
||
this._socket.addEventListener('open', () => { | ||
if (this._subscriptions !== undefined) { | ||
this._connected = true; | ||
this._reconnectionAttempts = 0; | ||
this.subscribe(this._subscriptions); | ||
} | ||
if (this._onConnect) this._onConnect(); | ||
}); | ||
|
||
this._socket.addEventListener('close', () => { | ||
this._connected = false; | ||
setTimeout(() => { | ||
if (!this._reconnectionAttemptsExhausted()) { | ||
this._reconnectionAttempts++; | ||
this._connect(); | ||
} | ||
}, this._reconnectionIntervalMs); | ||
if (this._onDisconnect) this._onDisconnect(); | ||
}); | ||
|
||
this._socket.addEventListener('message', (msg: any) => { | ||
try { | ||
const data = JSON.parse(msg.data); | ||
if (isFillEventUpdate(data) && this._onFill) { | ||
this._onFill(data); | ||
} else if (isHeadUpdate(data) && this._onHead) { | ||
this._onHead(data); | ||
} else if (isStatusMessage(data) && this._onStatus) { | ||
this._onStatus(data); | ||
} | ||
} catch (err) { | ||
console.warn('[FillsFeed] error deserializing message', err); | ||
} | ||
}); | ||
} | ||
|
||
public subscribe(subscriptions: FillsFeedSubscriptionParams) { | ||
if (this._connected) { | ||
this._socket.send( | ||
JSON.stringify({ | ||
command: 'subscribe', | ||
...subscriptions, | ||
}), | ||
); | ||
} else { | ||
console.warn('[FillsFeed] attempt to subscribe when not connected'); | ||
} | ||
} | ||
|
||
public connected(): boolean { | ||
return this._connected; | ||
} | ||
|
||
public onConnect(callback: () => void) { | ||
this._onConnect = callback; | ||
} | ||
|
||
public onDisconnect(callback: () => void) { | ||
this._onDisconnect = callback; | ||
} | ||
|
||
public onFill(callback: (update: FillEventUpdate) => void) { | ||
this._onFill = callback; | ||
} | ||
|
||
public onHead(callback: (update: HeadUpdate) => void) { | ||
this._onHead = callback; | ||
} | ||
|
||
public onStatus(callback: (update: StatusMessage) => void) { | ||
this._onStatus = callback; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './fills'; |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"extends": "./tsconfig", | ||
"compilerOptions": { | ||
"declaration": true, | ||
"declarationMap": false, | ||
"module": "commonjs", | ||
"outDir": "dist/cjs", | ||
"sourceMap": false | ||
}, | ||
"include": [ | ||
"ts/client/src", | ||
"ts/client/scripts" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"extends": "./tsconfig", | ||
"compilerOptions": { | ||
"declaration": false, | ||
"declarationMap": false, | ||
"module": "esnext", | ||
"outDir": "dist/esm", | ||
"sourceMap": false, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
"compilerOptions": { | ||
"esModuleInterop": true, | ||
"module": "esnext", | ||
"moduleResolution": "node", | ||
"noEmit": true, | ||
"noImplicitAny": false, | ||
"resolveJsonModule": true, | ||
"skipLibCheck": true, | ||
"strictNullChecks": true, | ||
"target": "esnext", | ||
}, | ||
"ts-node": { | ||
// these options are overrides used only by ts-node | ||
// same as the --compilerOptions flag and the TS_NODE_COMPILER_OPTIONS environment variable | ||
"compilerOptions": { | ||
"module": "commonjs" | ||
} | ||
}, | ||
"include": [ | ||
"ts/client/src" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"extends": "./tsconfig", | ||
"compilerOptions": { | ||
"noEmit": false, | ||
"outDir": "./dist/types", | ||
"declaration": true, | ||
"declarationMap": true, | ||
"emitDeclarationOnly": true | ||
} | ||
} |
Oops, something went wrong.