diff --git a/index.js b/index.js index ea996bd6..93a31f97 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,6 @@ 'use strict' module.exports = { - RESTv1: require('./lib/rest'), + RESTv1: require('./lib/rest1'), RESTv2: require('./lib/rest2') } diff --git a/lib/rest.js b/lib/rest1.js similarity index 98% rename from lib/rest.js rename to lib/rest1.js index 32f85cfd..cfe944e8 100644 --- a/lib/rest.js +++ b/lib/rest1.js @@ -3,14 +3,14 @@ const request = require('request') const { genAuthSig, nonce } = require('bfx-api-node-util') -const { Config } = require('bfx-api-node-core') +const API_URL = 'https://api.bitfinex.com' /** * Communicates with v1 of the Bitfinex HTTP API */ class RESTv1 { constructor (opts = {}) { - this._url = opts.url || Config.REST_URL + this._url = opts.url || API_URL this._apiKey = opts.apiKey || '' this._apiSecret = opts.apiSecret || '' this._agent = opts.agent diff --git a/lib/rest2.js b/lib/rest2.js index cd40649c..d4dbe00d 100644 --- a/lib/rest2.js +++ b/lib/rest2.js @@ -1,9 +1,8 @@ 'use strict' const rp = require('request-promise') +const _isEmpty = require('lodash/isEmpty') const { URLSearchParams } = require('url') - -const RESTv1 = require('./rest') const { genAuthSig, nonce, isClass } = require('bfx-api-node-util') const { FundingCredit, @@ -21,9 +20,12 @@ const { Alert, Candle, Movement, - LedgerEntry + LedgerEntry, + UserInfo } = require('bfx-api-node-models') +const RESTv1 = require('./rest1') + const BASE_TIMEOUT = 15000 const API_URL = 'https://api.bitfinex.com' @@ -37,6 +39,7 @@ class RESTv2 { * @param {Object} opts * @param {string} opts.apiKey * @param {string} opts.apiSecret + * @param {string} opts.authToken - optional auth option * @param {string} opts.url - endpoint URL * @param {boolean} opts.transform - default false * @param {Object} opts.agent - optional node agent for connection (proxy) @@ -44,6 +47,7 @@ class RESTv2 { constructor (opts = { apiKey: '', apiSecret: '', + authToken: '', url: API_URL, transform: false, agent: null @@ -51,6 +55,7 @@ class RESTv2 { this._url = opts.url || API_URL this._apiKey = opts.apiKey || '' this._apiSecret = opts.apiSecret || '' + this._authToken = opts.authToken || '' this._transform = !!opts.transform this._agent = opts.agent @@ -66,22 +71,27 @@ class RESTv2 { * @private */ _makeAuthRequest (path, payload = {}, cb = () => {}, transformer) { - if (!this._apiKey || !this._apiSecret) { + if ((!this._apiKey || !this._apiSecret) && !this._authToken) { return cb(new Error('missing api key or secret')) } const url = `${this._url}/v2${path}` const n = nonce() - const sigPayload = `/api/v2${path}${n}${JSON.stringify(payload)}` - const { sig } = genAuthSig(this._apiSecret, sigPayload) + const keys = () => { + const sigPayload = `/api/v2${path}${n}${JSON.stringify(payload)}` + const { sig } = genAuthSig(this._apiSecret, sigPayload) + return { 'bfx-apikey': this._apiKey, 'bfx-signature': sig } + } + const auth = (this._authToken) + ? { 'bfx-token': this._authToken } + : keys() return rp({ url, method: 'POST', headers: { 'bfx-nonce': n, - 'bfx-apikey': this._apiKey, - 'bfx-signature': sig + ...auth }, agent: this._agent, body: payload, @@ -382,7 +392,7 @@ class RESTv2 { } /** - * @param {string} symbol + * @param {string?} symbol - optional, omit/leave empty for all * @param {number} start * @param {number} end * @param {number} limit @@ -391,8 +401,12 @@ class RESTv2 { * @return {Promise} p * @see https://docs.bitfinex.com/v2/reference#rest-auth-trades-hist */ - accountTrades (symbol = 'tBTCUSD', start = null, end = null, limit = null, sort = null, cb) { - return this._makeAuthRequest(`/auth/r/trades/${symbol}/hist`, { + accountTrades (symbol, start = null, end = null, limit = null, sort = null, cb) { + const url = !_isEmpty(symbol) + ? `/auth/r/trades/${symbol}/hist` + : '/auth/r/trades/hist' + + return this._makeAuthRequest(url, { start, end, limit, sort }, cb, Trade) } @@ -406,6 +420,15 @@ class RESTv2 { return this._makeAuthRequest('/auth/r/wallets', {}, cb, Wallet) } + /** + * @param {Method} cb + * @return {Promise} p + * @see https://docs.bitfinex.com/v2/reference#rest-auth-wallets + */ + userInfo (cb) { + return this._makeAuthRequest('/auth/r/info/user', {}, cb, UserInfo) + } + /** * @param {Method} cb * @return {Promise} p @@ -450,7 +473,7 @@ class RESTv2 { } /** - * @param {string} symbol + * @param {string?} symbol - optional, omit/leave empty for all * @param {number} start * @param {number} end * @param {number} limit @@ -458,8 +481,12 @@ class RESTv2 { * @return {Promise} p * @see https://docs.bitfinex.com/v2/reference#orders-history */ - orderHistory (symbol = 'tBTCUSD', start = null, end = null, limit = null, cb) { - return this._makeAuthRequest(`/auth/r/orders/${symbol}/hist`, { + orderHistory (symbol, start = null, end = null, limit = null, cb) { + const url = !_isEmpty(symbol) + ? `/auth/r/orders/${symbol}/hist` + : `/auth/r/orders/hist` + + return this._makeAuthRequest(url, { start, end, limit }, cb, Order) } @@ -500,7 +527,7 @@ class RESTv2 { } /** - * @param {string} symbol + * @param {string} symbol - optional, omit/leave empty for all * @param {number} start * @param {number} end * @param {number} limit @@ -508,8 +535,11 @@ class RESTv2 { * @return {Promise} p * @see https://docs.bitfinex.com/v2/reference#rest-auth-funding-offers-hist */ - fundingOfferHistory (symbol = 'tBTCUSD', start = null, end = null, limit = null, cb) { - return this._makeAuthRequest(`/auth/r/funding/offers/${symbol}/hist`, { + fundingOfferHistory (symbol, start = null, end = null, limit = null, cb) { + const url = !_isEmpty(symbol) + ? `/auth/r/funding/offers/${symbol}/hist` + : '/auth/r/funding/offers/hist' + return this._makeAuthRequest(url, { start, end, limit }, cb, FundingOffer) } @@ -525,7 +555,7 @@ class RESTv2 { } /** - * @param {string} symbol + * @param {string} symbol - optional, omit/leave empty for all * @param {number} start * @param {number} end * @param {number} limit @@ -533,8 +563,11 @@ class RESTv2 { * @return {Promise} p * @see https://docs.bitfinex.com/v2/reference#rest-auth-funding-loans-hist */ - fundingLoanHistory (symbol = 'tBTCUSD', start = null, end = null, limit = null, cb) { - return this._makeAuthRequest(`/auth/r/funding/loans/${symbol}/hist`, { + fundingLoanHistory (symbol, start = null, end = null, limit = null, cb) { + const url = !_isEmpty(symbol) + ? `/auth/r/funding/loans/${symbol}/hist` + : '/auth/r/funding/loans/hist' + return this._makeAuthRequest(url, { start, end, limit }, cb, FundingLoan) } @@ -550,7 +583,7 @@ class RESTv2 { } /** - * @param {string} symbol + * @param {string} symbol - optional, omit/leave empty for all * @param {number} start * @param {number} end * @param {number} limit @@ -558,8 +591,11 @@ class RESTv2 { * @return {Promise} p * @see https://docs.bitfinex.com/v2/reference#rest-auth-funding-credits-hist */ - fundingCreditHistory (symbol = 'tBTCUSD', start = null, end = null, limit = null, cb) { - return this._makeAuthRequest(`/auth/r/funding/credits/${symbol}/hist`, { + fundingCreditHistory (symbol, start = null, end = null, limit = null, cb) { + const url = !_isEmpty(symbol) + ? `/auth/r/funding/credits/${symbol}/hist` + : '/auth/r/funding/credits/hist' + return this._makeAuthRequest(url, { start, end, limit }, cb, FundingCredit) } diff --git a/test/helpers/data.js b/test/helpers/data.js deleted file mode 100644 index 1e4dcf4f..00000000 --- a/test/helpers/data.js +++ /dev/null @@ -1,68 +0,0 @@ -'use strict' - -const assert = require('assert') -const { FIELDS: TRADING_TICKER_FIELDS } = require('bfx-api-node-models/lib/trading_ticker') -const { FIELDS: FUNDING_TICKER_FIELDS } = require('bfx-api-node-models/lib/funding_ticker') - -const TRADING_TICKER = [ // NOTE: no symbol - 25, 0, 105, 0, -149, -0.9933, 1, 473, 150, 1 -] - -const FUNDING_TICKER = [ // NOTE: no symbol - 0.00063991, 0.000811, 2, 6576537.37384749, 0.00064119, 2, 225522.0501075, - -0.00056019, -0.4668, 0.00063981, 270141543.39509803, 0.0013, 0.00000224 -] - -const getTradingTicker = (symbol) => ([ - ...(symbol ? [symbol] : []), - ...TRADING_TICKER -]) - -const getFundingTicker = (symbol) => ([ - ...(symbol ? [symbol] : []), - ...FUNDING_TICKER -]) - -const auditTradingTicker = (ticker, symbol) => { - const fieldOffset = symbol ? 1 : 0 - - if (symbol) { - assert.equal(ticker.symbol, symbol) - } - - Object.keys(TRADING_TICKER_FIELDS).forEach(key => { - if (key === 'symbol') return - - const i = TRADING_TICKER_FIELDS[key] - assert.equal(ticker[key], TRADING_TICKER[i - fieldOffset]) - }) -} - -const auditFundingTicker = (ticker, symbol) => { - const fieldOffset = symbol ? 1 : 0 - - if (symbol) { - assert.equal(ticker.symbol, symbol) - } - - Object.keys(FUNDING_TICKER_FIELDS).forEach(key => { - if (key === 'symbol') return - - const i = FUNDING_TICKER_FIELDS[key] - assert.equal(ticker[key], FUNDING_TICKER[i - fieldOffset]) - }) -} - -const auditTicker = (ticker = {}, symbol) => { - return ((symbol && symbol[0] === 'f') || ticker.frr) - ? auditFundingTicker(ticker, symbol) - : auditTradingTicker(ticker, symbol) -} - -module.exports = { - getTradingTicker, - getFundingTicker, - auditTradingTicker, - auditFundingTicker, - auditTicker -} diff --git a/test/lib/rest-1-integration.js b/test/lib/rest-1-integration.js index 16820ea6..c3ae665e 100644 --- a/test/lib/rest-1-integration.js +++ b/test/lib/rest-1-integration.js @@ -5,7 +5,7 @@ const PORT = 1337 const assert = require('assert') const http = require('http') -const RESTv1 = require('../../lib/rest') +const RESTv1 = require('../../lib/rest1') describe('rest integration test', () => { it('should get the fundingbook asks, zero bids, 100 asks', (done) => { diff --git a/test/lib/rest-2-integration.js b/test/lib/rest-2-integration.js index 2b980501..9e236afc 100644 --- a/test/lib/rest-2-integration.js +++ b/test/lib/rest-2-integration.js @@ -4,7 +4,6 @@ const assert = require('assert') const RESTv2 = require('../../lib/rest2') const { MockRESTv2Server } = require('bfx-api-mock-srv') -const { getTradingTicker, getFundingTicker, auditTicker } = require('../helpers/data') const getTestREST2 = (args = {}) => { return new RESTv2({ @@ -143,61 +142,6 @@ describe('RESTv2 integration (mock server) tests', () => { }) }) - it('correctly parses a mixed tickers response', (done) => { - const srv = new MockRESTv2Server({ listen: true }) - const r = getTestREST2({ transform: true }) - - srv.setResponse('tickers', [ - getTradingTicker('tETHUSD'), - getFundingTicker('fUSD') - ]) - - r.tickers(['tETHUSD', 'fUSD'], (err, data = []) => { - if (err) { - return srv.close().then(() => done(err)).catch(done) - } - - assert.equal(data.length, 2) - - auditTicker(data[0], 'tETHUSD') - auditTicker(data[1], 'fUSD') - - srv.close().then(done).catch(done) - }) - }) - - it('correctly parses single trading ticker response', (done) => { - const srv = new MockRESTv2Server({ listen: true }) - const r = getTestREST2({ transform: true }) - - srv.setResponse('ticker.tETHUSD', getTradingTicker()) - - r.ticker('tETHUSD', (err, ticker = {}) => { - if (err) { - return srv.close().then(() => done(err)).catch(done) - } - - auditTicker(ticker, 'tETHUSD') - srv.close().then(done).catch(done) - }) - }) - - it('correctly parses single funding ticker response', (done) => { - const srv = new MockRESTv2Server({ listen: true }) - const r = getTestREST2({ transform: true }) - - srv.setResponse('ticker.fUSD', getFundingTicker()) - - r.ticker('fUSD', (err, ticker = {}) => { - if (err) { - return srv.close().then(() => done(err)).catch(done) - } - - auditTicker(ticker, 'fUSD') - srv.close().then(done).catch(done) - }) - }) - it('correctly parses funding offer response', (done) => { const srv = new MockRESTv2Server({ listen: true }) const r = getTestREST2({ transform: true }) diff --git a/test/lib/rest1.js b/test/lib/rest1.js index 42777176..9b1dacac 100644 --- a/test/lib/rest1.js +++ b/test/lib/rest1.js @@ -6,7 +6,7 @@ const assert = require('assert') const { expect } = require('chai') const DNS = require('dns') -const RESTv1 = require('../../lib/rest') +const RESTv1 = require('../../lib/rest1') const _ = require('lodash') describe('REST v1', () => {