From 9cc86d11123996b4edd6bc444fc4bd09bc070fa3 Mon Sep 17 00:00:00 2001 From: Ryan McGeary Date: Sun, 24 Dec 2017 21:28:05 -0700 Subject: [PATCH 1/3] Add checkAuth() utility function to check if auth object is valid --- lib/clients/websocket.js | 7 +------ lib/utilities.js | 10 ++++++++++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/clients/websocket.js b/lib/clients/websocket.js index 57f4bc46..fa73490a 100644 --- a/lib/clients/websocket.js +++ b/lib/clients/websocket.js @@ -19,13 +19,8 @@ class WebsocketClient extends EventEmitter { super(); this.productIDs = Utils.determineProductIDs(productIDs); this.websocketURI = websocketURI; - if (auth && !(auth.secret && auth.key && auth.passphrase)) { - throw new Error( - 'Invalid or incomplete authentication credentials. You should either provide all of the secret, key and passphrase fields, or leave auth null' - ); - } this.channels = channels; - this.auth = auth || {}; + this.auth = Utils.checkAuth(auth); this.heartbeat = heartbeat; this.connect(); } diff --git a/lib/utilities.js b/lib/utilities.js index 7e649d7e..b4cce05c 100644 --- a/lib/utilities.js +++ b/lib/utilities.js @@ -12,6 +12,16 @@ function determineProductIDs(productIDs) { return [productIDs]; } +function checkAuth(auth) { + if (auth && !(auth.secret && auth.key && auth.passphrase)) { + throw new Error( + 'Invalid or incomplete authentication credentials. You should either provide all of the secret, key and passphrase fields, or leave auth null' + ); + } + return auth || {}; +} + module.exports = { determineProductIDs, + checkAuth, }; From 11cf861ab74c37dd89e6b5eb64ab44a7f2befc1a Mon Sep 17 00:00:00 2001 From: Ryan McGeary Date: Sun, 24 Dec 2017 21:32:12 -0700 Subject: [PATCH 2/3] Simplify OrderbookSync constructor to take auth object ...instead of full instance of AuthenticatedClient --- lib/orderbook_sync.js | 21 ++++++++++++++++----- tests/orderbook_sync.spec.js | 19 ++++++------------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/lib/orderbook_sync.js b/lib/orderbook_sync.js index ff688a03..8a952f7f 100644 --- a/lib/orderbook_sync.js +++ b/lib/orderbook_sync.js @@ -1,6 +1,8 @@ const WebsocketClient = require('./clients/websocket.js'); +const AuthenticatedClient = require('./clients/authenticated.js'); const PublicClient = require('./clients/public.js'); const Orderbook = require('./orderbook.js'); +const Utils = require('./utilities.js'); // Orderbook syncing class OrderbookSync extends WebsocketClient { @@ -8,18 +10,27 @@ class OrderbookSync extends WebsocketClient { productIDs, apiURI = 'https://api.gdax.com', websocketURI = 'wss://ws-feed.gdax.com', - authenticatedClient = null, + auth = null, { heartbeat = false } = {} ) { - super(productIDs, websocketURI, authenticatedClient, { heartbeat }); + super(productIDs, websocketURI, auth, { heartbeat }); this.apiURI = apiURI; - this.authenticatedClient = authenticatedClient; + this.auth = Utils.checkAuth(auth); this._queues = {}; // [] this._sequences = {}; // -1 this._public_clients = {}; this.books = {}; + if (this.auth.secret) { + this._authenticatedClient = new AuthenticatedClient( + this.auth.key, + this.auth.secret, + this.auth.passphrase, + this.apiURI + ); + } + this.productIDs.forEach(productID => { this._queues[productID] = []; this._sequences[productID] = -2; @@ -55,8 +66,8 @@ class OrderbookSync extends WebsocketClient { const bookLevel = 3; const args = { level: bookLevel }; - if (this.authenticatedClient) { - this.authenticatedClient + if (this._authenticatedClient) { + this._authenticatedClient .getProductOrderBook(args, productID) .then(onData.bind(this)) .catch(onError.bind(this)); diff --git a/tests/orderbook_sync.spec.js b/tests/orderbook_sync.spec.js index 666bb940..abc99d0f 100644 --- a/tests/orderbook_sync.spec.js +++ b/tests/orderbook_sync.spec.js @@ -31,18 +31,13 @@ suite('OrderbookSync', () => { }); }); - test('passes authentication details to websocket (with AuthenticatedClient)', done => { + test('passes authentication details to websocket', done => { const server = testserver(++port, () => { - const authClient = new Gdax.AuthenticatedClient( - 'suchkey', - 'suchsecret', - 'muchpassphrase' - ); new Gdax.OrderbookSync( 'BTC-USD', EXCHANGE_API_URL, 'ws://localhost:' + port, - authClient + { key: 'suchkey', secret: 'suchsecret', passphrase: 'muchpassphrase' } ); }); @@ -89,7 +84,7 @@ suite('OrderbookSync', () => { }); }); - test('emits a message event (with AuthenticatedClient)', done => { + test('emits a message event (with auth)', done => { nock(EXCHANGE_API_URL) .get('/products/BTC-USD/book?level=3') .times(2) @@ -99,12 +94,11 @@ suite('OrderbookSync', () => { }); const server = testserver(++port, () => { - const authClient = new Gdax.AuthenticatedClient('key', 'secret', 'pass'); const orderbookSync = new Gdax.OrderbookSync( 'BTC-USD', EXCHANGE_API_URL, 'ws://localhost:' + port, - authClient + { key: 'key', secret: 'secret', passphrase: 'pass' } ); orderbookSync.on('message', data => { assert.deepEqual(data, { @@ -147,18 +141,17 @@ suite('OrderbookSync', () => { }); }); - test('emits an error event on error (with AuthenticatedClient)', done => { + test('emits an error event on error (with auth)', done => { nock(EXCHANGE_API_URL) .get('/products/BTC-USD/book?level=3') .replyWithError('whoops'); const server = testserver(++port, () => { - const authClient = new Gdax.AuthenticatedClient('key', 'secret', 'pass'); const orderbookSync = new Gdax.OrderbookSync( 'BTC-USD', EXCHANGE_API_URL, 'ws://localhost:' + port, - authClient + { key: 'key', secret: 'secret', passphrase: 'pass' } ); orderbookSync.on('message', () => From 09be1e8f2aa796132a21549d3e1b80414efb6935 Mon Sep 17 00:00:00 2001 From: Ryan McGeary Date: Mon, 25 Dec 2017 15:14:29 -0700 Subject: [PATCH 3/3] Add OrderbookSync test w/ AuthenticationClient for backwards compat --- tests/orderbook_sync.spec.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/orderbook_sync.spec.js b/tests/orderbook_sync.spec.js index abc99d0f..9065229b 100644 --- a/tests/orderbook_sync.spec.js +++ b/tests/orderbook_sync.spec.js @@ -54,6 +54,29 @@ suite('OrderbookSync', () => { }); }); + test('passes authentication details to websocket (via AuthenticationClient for backwards compatibility)', done => { + const server = testserver(++port, () => { + new Gdax.OrderbookSync( + 'BTC-USD', + EXCHANGE_API_URL, + 'ws://localhost:' + port, + new Gdax.AuthenticatedClient('mykey', 'mysecret', 'mypassphrase') + ); + }); + + server.on('connection', socket => { + socket.on('message', data => { + const msg = JSON.parse(data); + assert.equal(msg.type, 'subscribe'); + assert.equal(msg.key, 'mykey'); + assert.equal(msg.passphrase, 'mypassphrase'); + + server.close(); + done(); + }); + }); + }); + test('emits a message event', done => { nock(EXCHANGE_API_URL) .get('/products/BTC-USD/book?level=3')