Skip to content
This repository has been archived by the owner on Jan 20, 2020. It is now read-only.

Commit

Permalink
Normalize PublicClient with AuthenticatedClient (#178)
Browse files Browse the repository at this point in the history
* Deprecate productID argument in PublicClient constructor

PublicClient should no longer keep state about a particular product ID.

* Require productID as first argument to getProductOrderBook()

- Deprecate old usage of a default productID per PublicClient
- Remove redundant AuthenticatedClient#getProductOrderBook() override
  Closes #46
- Simplify OrderbookSync#loadOrderbook()

* Require productID as first argument to getProductTicker()

- Deprecate old usage of a default productID per PublicClient

* Require productID as first argument to getProductTrades()

- Deprecate old usage of a default productID per PublicClient

* Require productID as first argument to getProductTradeStream()

- Deprecate old usage of a default productID per PublicClient

* Require productID as first argument to getProductHistoricRates()

- Deprecate old usage of a default productID per PublicClient

* Require productID as first argument to getProduct24HrStats()

- Deprecate old usage of a default productID per PublicClient

* Consolidate deprecation & argument normalization logic in PublicClient
  • Loading branch information
rmm5t authored and fb55 committed Dec 27, 2017
1 parent 94c671c commit 7c536d9
Show file tree
Hide file tree
Showing 7 changed files with 396 additions and 152 deletions.
34 changes: 17 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ Some methods accept optional parameters, e.g.

```js
publicClient
.getProductOrderBook({ level: 3 })
.getProductOrderBook('BTC-USD', { level: 3 })
.then(book => { /* ... */ });
```

Expand All @@ -126,13 +126,13 @@ parameter(s) and the callback as the last parameter:

```js
publicClient
.getProductOrderBook({ level: 3 }, (error, response, book) => { /* ... */ });
.getProductOrderBook('ETH-USD', { level: 3 }, (error, response, book) => { /* ... */ });
```

### The Public API Client

```js
const publicClient = new Gdax.PublicClient(productID, endpoint);
const publicClient = new Gdax.PublicClient(endpoint);
```

- `productID` *optional* - defaults to 'BTC-USD' if not specified.
Expand All @@ -150,25 +150,25 @@ publicClient.getProducts(callback);

```js
// Get the order book at the default level of detail.
publicClient.getProductOrderBook(callback);
publicClient.getProductOrderBook('BTC-USD', callback);

// Get the order book at a specific level of detail.
publicClient.getProductOrderBook({'level': 3}, callback);
publicClient.getProductOrderBook('LTC-USD', { level: 3 }, callback);
```

* [`getProductTicker`](https://docs.gdax.com/#get-product-ticker)

```js
publicClient.getProductTicker(callback);
publicClient.getProductTicker('ETH-USD', callback);
```

* [`getProductTrades`](https://docs.gdax.com/#get-trades)

```js
publicClient.getProductTrades(callback);
publicClient.getProductTrades('BTC-USD', callback);

// To make paginated requests, include page parameters
publicClient.getProductTrades({'after': 1000}, callback);
publicClient.getProductTrades('BTC-USD', { after: 1000 }, callback);
```

* [`getProductTradeStream`](https://docs.gdax.com/#get-trades)
Expand All @@ -177,25 +177,25 @@ Wraps around `getProductTrades`, fetches all trades with IDs `>= tradesFrom` and
`<= tradesTo`. Handles pagination and rate limits.

```js
const trades = publicClient.getProductTradeStream(8408000, 8409000);
const trades = publicClient.getProductTradeStream('BTC-USD', 8408000, 8409000);

// tradesTo can also be a function
const trades = publicClient.getProductTradeStream(8408000, trade => Date.parse(trade.time) >= 1463068e6);
const trades = publicClient.getProductTradeStream('BTC-USD', 8408000, trade => Date.parse(trade.time) >= 1463068e6);
```

* [`getProductHistoricRates`](https://docs.gdax.com/#get-historic-rates)

```js
publicClient.getProductHistoricRates(callback);
publicClient.getProductHistoricRates('BTC-USD', callback);

// To include extra parameters:
publicClient.getProductHistoricRates({'granularity': 3000}, callback);
publicClient.getProductHistoricRates('BTC-USD', { granularity: 3000 }, callback);
```

* [`getProduct24HrStats`](https://docs.gdax.com/#get-24hr-stats)

```js
publicClient.getProduct24HrStats(callback);
publicClient.getProduct24HrStats('BTC-USD', callback);
```

* [`getCurrencies`](https://docs.gdax.com/#get-currencies)
Expand Down Expand Up @@ -269,7 +269,7 @@ const accountID = '7d0f7d8e-dd34-4d9c-a846-06f431c381ba';
authedClient.getAccountHistory(accountID, callback);

// For pagination, you can include extra page arguments
authedClient.getAccountHistory(accountID, {'before': 3000}, callback);
authedClient.getAccountHistory(accountID, { before: 3000 }, callback);
```

* [`getAccountHolds`](https://docs.gdax.com/#get-holds)
Expand All @@ -279,7 +279,7 @@ const accountID = '7d0f7d8e-dd34-4d9c-a846-06f431c381ba';
authedClient.getAccountHolds(accountID, callback);

// For pagination, you can include extra page arguments
authedClient.getAccountHolds(accountID, {'before': 3000}, callback);
authedClient.getAccountHolds(accountID, { before: 3000 }, callback);
```

* [`buy`, `sell`](https://docs.gdax.com/#place-a-new-order)
Expand Down Expand Up @@ -346,7 +346,7 @@ authedClient.cancelAllOrders({product_id: 'BTC-USD'}, callback);
```js
authedClient.getOrders(callback);
// For pagination, you can include extra page arguments
authedClient.getOrders({'after': 3000}, callback);
authedClient.getOrders({ after: 3000 }, callback);
```

* [`getOrder`](https://docs.gdax.com/#get-an-order)
Expand All @@ -361,7 +361,7 @@ authedClient.getOrder(orderID, callback);
```js
authedClient.getFills(callback);
// For pagination, you can include extra page arguments
authedClient.getFills({'before': 3000}, callback);
authedClient.getFills({ before: 3000 }, callback);
```

* [`getFundings`](https://docs.gdax.com/#list-fundings)
Expand Down
26 changes: 13 additions & 13 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,28 +133,28 @@ declare module 'gdax' {
}

export class PublicClient {
constructor(productId?: string, apiURI?: string);
constructor(apiURI?: string);

getProducts(callback: callback<ProductInfo[]>);
getProducts(): Promise<ProductInfo[]>;

getProductOrderBook(options: any, callback: callback<any>);
getProductOrderBook(options: any): Promise<any>;
getProductOrderBook(productID: string, options: any, callback: callback<any>);
getProductOrderBook(productID: string, options: any): Promise<any>;

getProductTicker(callback: callback<ProductTicker>);
getProductTicker(): Promise<ProductTicker>;
getProductTicker(productID: string, callback: callback<ProductTicker>);
getProductTicker(productID: string, ): Promise<ProductTicker>;

getProductTrades(callback: callback<any>);
getProductTrades(): Promise<any>;
getProductTrades(productID: string, callback: callback<any>);
getProductTrades(productID: string, ): Promise<any>;

getProductTradeStream(callback: callback<any>);
getProductTradeStream(): Promise<any>;
getProductTradeStream(productID: string, tradesFrom: number, tradesTo: any, callback: callback<any>);
getProductTradeStream(productID: string, tradesFrom: number, tradesTo: any): Promise<any>;

getProductHistoricRates(args: any, callback: callback<any[][]>);
getProductHistoricRates(args: any): Promise<any[][]>;
getProductHistoricRates(productID: string, args: any, callback: callback<any[][]>);
getProductHistoricRates(productID: string, args: any): Promise<any[][]>;

getProduct24HrStats(callback: callback<any>);
getProduct24HrStats(): Promise<any>;
getProduct24HrStats(productID: string, callback: callback<any>);
getProduct24HrStats(productID: string): Promise<any>;

getCurrencies(callback: callback<CurrencyInfo[]>);
getCurrencies(): Promise<CurrencyInfo[]>;
Expand Down
14 changes: 2 additions & 12 deletions lib/clients/authenticated.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const PublicClient = require('./public.js');

class AuthenticatedClient extends PublicClient {
constructor(key, secret, passphrase, apiURI) {
super('', apiURI);
super(apiURI);
this.key = key;
this.secret = secret;
this.passphrase = passphrase;
Expand Down Expand Up @@ -45,7 +45,7 @@ class AuthenticatedClient extends PublicClient {
getCoinbaseAccounts(callback) {
return this.get(['coinbase-accounts'], callback);
}

getPaymentMethods(callback) {
return this.get(['payment-methods'], callback);
}
Expand Down Expand Up @@ -127,16 +127,6 @@ class AuthenticatedClient extends PublicClient {
return this.delete(['orders'], callback);
}

// temp over ride public call to get Product Orderbook
getProductOrderBook(args = {}, productId, callback) {
if (!callback && typeof args === 'function') {
callback = args;
args = {};
}

return this.get(['products', productId, 'book'], { qs: args }, callback);
}

cancelAllOrders(args = {}, callback) {
if (!callback && typeof args === 'function') {
callback = args;
Expand Down
133 changes: 98 additions & 35 deletions lib/clients/public.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,17 @@ const request = require('request');
const { Readable } = require('stream');

class PublicClient {
constructor(productID = 'BTC-USD', apiURI = 'https://api.gdax.com') {
this.productID = productID;
constructor(apiURI = 'https://api.gdax.com') {
this.productID = 'BTC-USD';
if (apiURI && !apiURI.startsWith('http')) {
process.emitWarning(
'`new PublicClient()` no longer accepts a product ID as the first argument. ',
'DeprecationWarning'
);
this.productID = apiURI;
apiURI = arguments[1] || 'https://api.gdax.com';
}

this.apiURI = apiURI;
this.API_LIMIT = 100;
}
Expand Down Expand Up @@ -95,36 +104,54 @@ class PublicClient {
return this.get(['products'], callback);
}

getProductOrderBook(args = {}, callback) {
if (!callback && typeof args === 'function') {
callback = args;
args = {};
}
getProductOrderBook(productID, args, callback) {
[productID, args, callback] = this._normalizeProductArgs(
productID,
args,
callback,
'getProductOrderBook'
);

return this.get(
['products', this.productID, 'book'],
{ qs: args },
callback
const path = ['products', productID, 'book'];
return this.get(path, { qs: args }, callback);
}

getProductTicker(productID, callback) {
[productID, , callback] = this._normalizeProductArgs(
productID,
null,
callback,
'getProductTicker'
);

const path = ['products', productID, 'ticker'];
return this.get(path, callback);
}

getProductTicker(callback) {
return this.get(['products', this.productID, 'ticker'], callback);
getProductTrades(productID, args, callback) {
[productID, args, callback] = this._normalizeProductArgs(
productID,
args,
callback,
'getProductTrades'
);

const path = ['products', productID, 'trades'];
return this.get(path, { qs: args }, callback);
}

getProductTrades(args = {}, callback) {
if (!callback && typeof args === 'function') {
callback = args;
args = {};
getProductTradeStream(productID, tradesFrom, tradesTo) {
if (!productID || typeof productID !== 'string') {
[tradesFrom, tradesTo] = Array.prototype.slice.call(arguments);
}
return this.get(
['products', this.productID, 'trades'],
{ qs: args },
callback

[productID] = this._normalizeProductArgs(
productID,
null,
null,
'getProductTradeStream'
);
}

getProductTradeStream(tradesFrom, tradesTo) {
let shouldStop = null;

if (typeof tradesTo === 'function') {
Expand Down Expand Up @@ -155,7 +182,7 @@ class PublicClient {

let opts = { before: tradesFrom, after: after, limit: this.API_LIMIT };

this.getProductTrades(opts, (err, resp, data) => {
this.getProductTrades(productID, opts, (err, resp, data) => {
if (err) {
stream.emit('error', err);
return;
Expand Down Expand Up @@ -201,20 +228,28 @@ class PublicClient {
}
}

getProductHistoricRates(args = {}, callback) {
if (!callback && typeof args === 'function') {
callback = args;
args = {};
}
return this.get(
['products', this.productID, 'candles'],
{ qs: args },
callback
getProductHistoricRates(productID, args, callback) {
[productID, args, callback] = this._normalizeProductArgs(
productID,
args,
callback,
'getProductHistoricRates'
);

const path = ['products', productID, 'candles'];
return this.get(path, { qs: args }, callback);
}

getProduct24HrStats(callback) {
return this.get(['products', this.productID, 'stats'], callback);
getProduct24HrStats(productID, callback) {
[productID, , callback] = this._normalizeProductArgs(
productID,
null,
callback,
'getProduct24HrStats'
);

const path = ['products', productID, 'stats'];
return this.get(path, callback);
}

getCurrencies(callback) {
Expand All @@ -224,6 +259,34 @@ class PublicClient {
getTime(callback) {
return this.get(['time'], callback);
}

_normalizeProductArgs(productID, args, callback, caller) {
this._deprecationWarningIfProductIdMissing(productID, caller);

callback = [callback, args, productID].find(byType('function'));
args = [args, productID, {}].find(byType('object'));
productID = [productID, this.productID].find(byType('string'));

if (!productID) {
throw new Error('No productID specified.');
}

return [productID, args, callback];
}

_deprecationWarningIfProductIdMissing(productID, caller) {
if (!productID || typeof productID !== 'string') {
process.emitWarning(
`\`${caller}()\` now requires a product ID as the first argument. ` +
`Attempting to use PublicClient#productID (${
this.productID
}) instead.`,
'DeprecationWarning'
);
}
}
}

const byType = type => o => o !== null && typeof o === type;

module.exports = exports = PublicClient;
Loading

0 comments on commit 7c536d9

Please sign in to comment.