tardis-dev 13.21.6 → 13.22.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.
@@ -1,7 +1,8 @@
1
1
  import { Filter } from '../types';
2
2
  import { RealTimeFeedBase } from './realtimefeed';
3
3
  export declare class CoinbaseRealTimeFeed extends RealTimeFeedBase {
4
- protected wssURL: string;
4
+ private _hasCredentials;
5
+ protected get wssURL(): "wss://ws-direct.exchange.coinbase.com" | "wss://ws-feed.exchange.coinbase.com";
5
6
  protected channelMappings: {
6
7
  full: string[];
7
8
  level2: string[];
@@ -9,6 +10,7 @@ export declare class CoinbaseRealTimeFeed extends RealTimeFeedBase {
9
10
  ticker: string[];
10
11
  };
11
12
  protected mapToSubscribeMessages(filters: Filter<string>[]): any[];
13
+ private getAuthParams;
12
14
  protected messageIsError(message: any): boolean;
13
15
  }
14
16
  //# sourceMappingURL=coinbase.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"coinbase.d.ts","sourceRoot":"","sources":["../../src/realtimefeeds/coinbase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAEjD,qBAAa,oBAAqB,SAAQ,gBAAgB;IACxD,SAAS,CAAC,MAAM,SAAwC;IAIxD,SAAS,CAAC,eAAe;;;;;MAKxB;IAED,SAAS,CAAC,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,GAAG,EAAE;IAmDlE,SAAS,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO;CAGhD"}
1
+ {"version":3,"file":"coinbase.d.ts","sourceRoot":"","sources":["../../src/realtimefeeds/coinbase.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAEjD,qBAAa,oBAAqB,SAAQ,gBAAgB;IACxD,OAAO,CAAC,eAAe,CAG4B;IAEnD,SAAS,KAAK,MAAM,oFAEnB;IAGD,SAAS,CAAC,eAAe;;;;;MAKxB;IAED,SAAS,CAAC,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,GAAG,EAAE;IAoElE,OAAO,CAAC,aAAa;IAerB,SAAS,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO;CAGhD"}
@@ -1,11 +1,17 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.CoinbaseRealTimeFeed = void 0;
7
+ const crypto_1 = __importDefault(require("crypto"));
4
8
  const realtimefeed_1 = require("./realtimefeed");
5
9
  class CoinbaseRealTimeFeed extends realtimefeed_1.RealTimeFeedBase {
6
10
  constructor() {
7
11
  super(...arguments);
8
- this.wssURL = 'wss://ws-feed.exchange.coinbase.com';
12
+ this._hasCredentials = process.env.COINBASE_API_KEY !== undefined &&
13
+ process.env.COINBASE_API_SECRET !== undefined &&
14
+ process.env.COINBASE_API_PASSPHRASE !== undefined;
9
15
  // map from coinbase subscribe 'channels' to more granular channels that tardis uses
10
16
  this.channelMappings = {
11
17
  full: ['received', 'open', 'done', 'match', 'change', 'full_snapshot'],
@@ -14,6 +20,9 @@ class CoinbaseRealTimeFeed extends realtimefeed_1.RealTimeFeedBase {
14
20
  ticker: ['ticker']
15
21
  };
16
22
  }
23
+ get wssURL() {
24
+ return this._hasCredentials ? 'wss://ws-direct.exchange.coinbase.com' : 'wss://ws-feed.exchange.coinbase.com';
25
+ }
17
26
  mapToSubscribeMessages(filters) {
18
27
  const channelsToSubscribe = filters
19
28
  .map((filter) => {
@@ -28,7 +37,13 @@ class CoinbaseRealTimeFeed extends realtimefeed_1.RealTimeFeedBase {
28
37
  channel = 'full';
29
38
  }
30
39
  else if (subscribeToLevel2Channel) {
31
- channel = 'level2';
40
+ if (this._hasCredentials) {
41
+ channel = 'level2';
42
+ }
43
+ else {
44
+ // for not authenticated connections use batch channel, non batched l2 updates require auth
45
+ channel = 'level2_batch';
46
+ }
32
47
  }
33
48
  else if (subscribeToMatchesChannel) {
34
49
  channel = 'matches';
@@ -55,6 +70,16 @@ class CoinbaseRealTimeFeed extends realtimefeed_1.RealTimeFeedBase {
55
70
  }
56
71
  return prev;
57
72
  }, []);
73
+ if (this._hasCredentials) {
74
+ const authParams = this.getAuthParams();
75
+ return [
76
+ {
77
+ type: 'subscribe',
78
+ channels: channelsToSubscribe,
79
+ ...authParams
80
+ }
81
+ ];
82
+ }
58
83
  return [
59
84
  {
60
85
  type: 'subscribe',
@@ -62,6 +87,19 @@ class CoinbaseRealTimeFeed extends realtimefeed_1.RealTimeFeedBase {
62
87
  }
63
88
  ];
64
89
  }
90
+ getAuthParams() {
91
+ const timestamp = Date.now().valueOf() / 1000;
92
+ const apiSecret = process.env.COINBASE_API_SECRET;
93
+ const message = `${timestamp}GET/users/self/verify`;
94
+ const hmac = crypto_1.default.createHmac('sha256', Buffer.from(apiSecret, 'base64'));
95
+ const signature = hmac.update(message).digest('base64');
96
+ return {
97
+ signature,
98
+ key: process.env.COINBASE_API_KEY,
99
+ passphrase: process.env.COINBASE_API_PASSPHRASE,
100
+ timestamp
101
+ };
102
+ }
65
103
  messageIsError(message) {
66
104
  return message.type === 'error';
67
105
  }
@@ -1 +1 @@
1
- {"version":3,"file":"coinbase.js","sourceRoot":"","sources":["../../src/realtimefeeds/coinbase.ts"],"names":[],"mappings":";;;AACA,iDAAiD;AAEjD,MAAa,oBAAqB,SAAQ,+BAAgB;IAA1D;;QACY,WAAM,GAAG,qCAAqC,CAAA;QAExD,oFAAoF;QAE1E,oBAAe,GAAG;YAC1B,IAAI,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,CAAC;YACtE,MAAM,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC;YAChC,OAAO,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC;YAChC,MAAM,EAAE,CAAC,QAAQ,CAAC;SACnB,CAAA;IAwDH,CAAC;IAtDW,sBAAsB,CAAC,OAAyB;QACxD,MAAM,mBAAmB,GAAG,OAAO;aAChC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YACd,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;gBAClD,MAAM,IAAI,KAAK,CAAC,0FAA0F,CAAC,CAAA;aAC5G;YAED,MAAM,sBAAsB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAA;YAC1G,MAAM,wBAAwB,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YACrF,MAAM,yBAAyB,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YACvF,IAAI,OAAO,CAAA;YAEX,IAAI,sBAAsB,EAAE;gBAC1B,OAAO,GAAG,MAAM,CAAA;aACjB;iBAAM,IAAI,wBAAwB,EAAE;gBACnC,OAAO,GAAG,QAAQ,CAAA;aACnB;iBAAM,IAAI,yBAAyB,EAAE;gBACpC,OAAO,GAAG,SAAS,CAAA;aACpB;iBAAM;gBACL,OAAO,GAAG,QAAQ,CAAA;aACnB;YAED,OAAO;gBACL,IAAI,EAAE,OAAO;gBACb,WAAW,EAAE,MAAM,CAAC,OAAO;aAC5B,CAAA;QACH,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;YACxB,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;YAClE,IAAI,gBAAgB,KAAK,SAAS,EAAE;gBAClC,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,WAAW,EAAE;oBACxC,IAAI,gBAAgB,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,KAAK,EAAE;wBAC3D,gBAAgB,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;qBAC1C;iBACF;aACF;iBAAM;gBACL,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;aACnB;YAED,OAAO,IAAI,CAAA;QACb,CAAC,EAAE,EAA+C,CAAC,CAAA;QAErD,OAAO;YACL;gBACE,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,mBAAmB;aAC9B;SACF,CAAA;IACH,CAAC;IAES,cAAc,CAAC,OAAY;QACnC,OAAO,OAAO,CAAC,IAAI,KAAK,OAAO,CAAA;IACjC,CAAC;CACF;AAlED,oDAkEC"}
1
+ {"version":3,"file":"coinbase.js","sourceRoot":"","sources":["../../src/realtimefeeds/coinbase.ts"],"names":[],"mappings":";;;;;;AAAA,oDAAqC;AAErC,iDAAiD;AAEjD,MAAa,oBAAqB,SAAQ,+BAAgB;IAA1D;;QACU,oBAAe,GACrB,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,SAAS;YAC1C,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,SAAS;YAC7C,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,SAAS,CAAA;QAMnD,oFAAoF;QAC1E,oBAAe,GAAG;YAC1B,IAAI,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,CAAC;YACtE,MAAM,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC;YAChC,OAAO,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC;YAChC,MAAM,EAAE,CAAC,QAAQ,CAAC;SACnB,CAAA;IAwFH,CAAC;IAlGC,IAAc,MAAM;QAClB,OAAO,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,uCAAuC,CAAC,CAAC,CAAC,qCAAqC,CAAA;IAC/G,CAAC;IAUS,sBAAsB,CAAC,OAAyB;QACxD,MAAM,mBAAmB,GAAG,OAAO;aAChC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YACd,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;gBAClD,MAAM,IAAI,KAAK,CAAC,0FAA0F,CAAC,CAAA;aAC5G;YAED,MAAM,sBAAsB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAA;YAC1G,MAAM,wBAAwB,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YACrF,MAAM,yBAAyB,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YACvF,IAAI,OAAO,CAAA;YAEX,IAAI,sBAAsB,EAAE;gBAC1B,OAAO,GAAG,MAAM,CAAA;aACjB;iBAAM,IAAI,wBAAwB,EAAE;gBACnC,IAAI,IAAI,CAAC,eAAe,EAAE;oBACxB,OAAO,GAAG,QAAQ,CAAA;iBACnB;qBAAM;oBACL,2FAA2F;oBAC3F,OAAO,GAAG,cAAc,CAAA;iBACzB;aACF;iBAAM,IAAI,yBAAyB,EAAE;gBACpC,OAAO,GAAG,SAAS,CAAA;aACpB;iBAAM;gBACL,OAAO,GAAG,QAAQ,CAAA;aACnB;YAED,OAAO;gBACL,IAAI,EAAE,OAAO;gBACb,WAAW,EAAE,MAAM,CAAC,OAAO;aAC5B,CAAA;QACH,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;YACxB,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;YAClE,IAAI,gBAAgB,KAAK,SAAS,EAAE;gBAClC,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,WAAW,EAAE;oBACxC,IAAI,gBAAgB,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,KAAK,EAAE;wBAC3D,gBAAgB,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;qBAC1C;iBACF;aACF;iBAAM;gBACL,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;aACnB;YAED,OAAO,IAAI,CAAA;QACb,CAAC,EAAE,EAA+C,CAAC,CAAA;QAErD,IAAI,IAAI,CAAC,eAAe,EAAE;YACxB,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAA;YAEvC,OAAO;gBACL;oBACE,IAAI,EAAE,WAAW;oBACjB,QAAQ,EAAE,mBAAmB;oBAC7B,GAAG,UAAU;iBACd;aACF,CAAA;SACF;QAED,OAAO;YACL;gBACE,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,mBAAmB;aAC9B;SACF,CAAA;IACH,CAAC;IAEO,aAAa;QACnB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,CAAA;QAC7C,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAoB,CAAA;QAClD,MAAM,OAAO,GAAG,GAAG,SAAS,uBAAuB,CAAA;QACnD,MAAM,IAAI,GAAG,gBAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAA;QAC1E,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAEvD,OAAO;YACL,SAAS;YACT,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAiB;YAClC,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAwB;YAChD,SAAS;SACV,CAAA;IACH,CAAC;IAES,cAAc,CAAC,OAAY;QACnC,OAAO,OAAO,CAAC,IAAI,KAAK,OAAO,CAAA;IACjC,CAAC;CACF;AAxGD,oDAwGC"}
@@ -90,7 +90,7 @@ class RealTimeFeedBase {
90
90
  const subscribeMessages = this.mapToSubscribeMessages(this._filters);
91
91
  const finalWssUrl = await this.getWebSocketUrl();
92
92
  this.debug('(connection id: %d) estabilishing connection to %s', this._connectionId, finalWssUrl);
93
- this.debug('(connection id: %d) provided filters: %o mapped to subscribe messages: %o', this._connectionId, this._filters, subscribeMessages);
93
+ this.debug('(connection id: %d) provided filters: %o mapped to subscribe messages: %j', this._connectionId, this._filters, subscribeMessages);
94
94
  if (this.originHeader !== undefined) {
95
95
  this._wsClientOptions.headers.origin = this.originHeader;
96
96
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tardis-dev",
3
- "version": "13.21.6",
3
+ "version": "13.22.0",
4
4
  "engines": {
5
5
  "node": ">=12"
6
6
  },
@@ -1,11 +1,18 @@
1
+ import crypto, { sign } from 'crypto'
1
2
  import { Filter } from '../types'
2
3
  import { RealTimeFeedBase } from './realtimefeed'
3
4
 
4
5
  export class CoinbaseRealTimeFeed extends RealTimeFeedBase {
5
- protected wssURL = 'wss://ws-feed.exchange.coinbase.com'
6
+ private _hasCredentials =
7
+ process.env.COINBASE_API_KEY !== undefined &&
8
+ process.env.COINBASE_API_SECRET !== undefined &&
9
+ process.env.COINBASE_API_PASSPHRASE !== undefined
6
10
 
7
- // map from coinbase subscribe 'channels' to more granular channels that tardis uses
11
+ protected get wssURL() {
12
+ return this._hasCredentials ? 'wss://ws-direct.exchange.coinbase.com' : 'wss://ws-feed.exchange.coinbase.com'
13
+ }
8
14
 
15
+ // map from coinbase subscribe 'channels' to more granular channels that tardis uses
9
16
  protected channelMappings = {
10
17
  full: ['received', 'open', 'done', 'match', 'change', 'full_snapshot'],
11
18
  level2: ['snapshot', 'l2update'],
@@ -29,7 +36,12 @@ export class CoinbaseRealTimeFeed extends RealTimeFeedBase {
29
36
  if (subscribeToFullChannel) {
30
37
  channel = 'full'
31
38
  } else if (subscribeToLevel2Channel) {
32
- channel = 'level2'
39
+ if (this._hasCredentials) {
40
+ channel = 'level2'
41
+ } else {
42
+ // for not authenticated connections use batch channel, non batched l2 updates require auth
43
+ channel = 'level2_batch'
44
+ }
33
45
  } else if (subscribeToMatchesChannel) {
34
46
  channel = 'matches'
35
47
  } else {
@@ -56,6 +68,18 @@ export class CoinbaseRealTimeFeed extends RealTimeFeedBase {
56
68
  return prev
57
69
  }, [] as { name: string; product_ids: string[] }[])
58
70
 
71
+ if (this._hasCredentials) {
72
+ const authParams = this.getAuthParams()
73
+
74
+ return [
75
+ {
76
+ type: 'subscribe',
77
+ channels: channelsToSubscribe,
78
+ ...authParams
79
+ }
80
+ ]
81
+ }
82
+
59
83
  return [
60
84
  {
61
85
  type: 'subscribe',
@@ -64,6 +88,21 @@ export class CoinbaseRealTimeFeed extends RealTimeFeedBase {
64
88
  ]
65
89
  }
66
90
 
91
+ private getAuthParams() {
92
+ const timestamp = Date.now().valueOf() / 1000
93
+ const apiSecret = process.env.COINBASE_API_SECRET!
94
+ const message = `${timestamp}GET/users/self/verify`
95
+ const hmac = crypto.createHmac('sha256', Buffer.from(apiSecret, 'base64'))
96
+ const signature = hmac.update(message).digest('base64')
97
+
98
+ return {
99
+ signature,
100
+ key: process.env.COINBASE_API_KEY!,
101
+ passphrase: process.env.COINBASE_API_PASSPHRASE!,
102
+ timestamp
103
+ }
104
+ }
105
+
67
106
  protected messageIsError(message: any): boolean {
68
107
  return message.type === 'error'
69
108
  }
@@ -79,7 +79,7 @@ export abstract class RealTimeFeedBase implements RealTimeFeedIterable {
79
79
  this.debug('(connection id: %d) estabilishing connection to %s', this._connectionId, finalWssUrl)
80
80
 
81
81
  this.debug(
82
- '(connection id: %d) provided filters: %o mapped to subscribe messages: %o',
82
+ '(connection id: %d) provided filters: %o mapped to subscribe messages: %j',
83
83
  this._connectionId,
84
84
  this._filters,
85
85
  subscribeMessages