UNPKG

8.91 kBJavaScriptView Raw
1"use strict";
2/// <reference path="./index.d.ts" />
3Object.defineProperty(exports, "__esModule", { value: true });
4const buffer_1 = require("buffer");
5const querystring = require("querystring");
6const crypto_1 = require("crypto");
7const request = require("request");
8const cheerio = require("cheerio");
9const VError = require("verror");
10class BTCMarkets {
11 constructor(key, secret, server = 'https://api.btcmarkets.net', timeout = 20000) {
12 this.key = key;
13 this.secret = secret;
14 this.server = server;
15 this.timeout = timeout;
16 }
17 privateRequest(path, params = {}) {
18 if (!this.key || !this.secret) {
19 throw new VError('must provide key and secret to make this API request.');
20 }
21 let method = 'POST';
22 // HTTP GET is used instead of POST for endpoints
23 // under /account/ eg /account/balance or /account/{instrument}/{currency}/tradingfee
24 // or /fundtransfer/history
25 if (path.split('/')[1] === 'account' ||
26 path === '/fundtransfer/history') {
27 method = 'GET';
28 }
29 // milliseconds elapsed between 1 January 1970 00:00:00 UTC and the given date
30 const timestamp = (new Date()).getTime();
31 let message;
32 if (method === 'POST') {
33 message = path + "\n" +
34 timestamp + "\n" +
35 JSON.stringify(params);
36 }
37 else if (Object.keys(params).length > 0) {
38 message = path + "\n" +
39 querystring.stringify(params) + "\n" +
40 timestamp + "\n";
41 }
42 else {
43 message = path + "\n" +
44 timestamp + "\n";
45 }
46 const signer = crypto_1.createHmac('sha512', new buffer_1.Buffer(this.secret, 'base64'));
47 const signature = signer.update(message).digest('base64');
48 const headers = {
49 "User-Agent": "BTC Markets Javascript API Client",
50 "apikey": this.key,
51 "timestamp": timestamp,
52 "signature": signature
53 };
54 const options = {
55 url: this.server + path,
56 method: method,
57 headers: headers,
58 timeout: this.timeout,
59 json: params
60 };
61 if (method === 'GET') {
62 options.qs = params;
63 }
64 const requestDesc = `${options.method} request to url ${options.url} with message ${message}`;
65 return this.executeRequest(options, requestDesc);
66 }
67 publicRequest(instrument, currency, action, params) {
68 const headers = { "User-Agent": "BTC Markets Javascript API Client" };
69 const path = '/market/' + instrument + '/' + currency + '/' + action;
70 const options = {
71 url: this.server + path,
72 method: 'GET',
73 headers: headers,
74 timeout: this.timeout,
75 json: {},
76 qs: params
77 };
78 const requestDesc = `${options.method} request to url ${options.url} with parameters ${JSON.stringify(params)}`;
79 return this.executeRequest(options, requestDesc);
80 }
81 ;
82 executeRequest(options, requestDesc) {
83 return new Promise((resolve, reject) => {
84 request(options, function (err, response, data) {
85 let error = null; // default to no errors
86 if (err) {
87 error = new VError(err, `failed ${requestDesc} with error message ${err.message}`);
88 error.name = err.code;
89 }
90 else if (response.statusCode < 200 || response.statusCode >= 300) {
91 error = new VError(`HTTP status code ${response.statusCode} returned from ${requestDesc}. Status message: ${response.statusMessage}`);
92 error.name = response.statusCode.toString();
93 }
94 else if (!data) {
95 error = new VError(`failed ${requestDesc}. No data returned.`);
96 }
97 // if request was not able to parse json response into an object
98 else if (data !== Object(data)) {
99 // try and parse HTML body form response
100 const $ = cheerio.load(data);
101 const responseBody = $('body').text();
102 if (responseBody) {
103 error = new VError(err, `Could not parse response body from ${requestDesc}\nResponse body: ${responseBody}`);
104 error.name = responseBody;
105 }
106 else {
107 error = new VError(err, `Could not parse json or HTML response from ${requestDesc}`);
108 }
109 }
110 else if (data.hasOwnProperty('success') && !data.success) {
111 error = new VError(`failed ${requestDesc}. Success: ${data.success}. Error message: ${data.errorMessage}`);
112 error.name = data.errorMessage;
113 }
114 if (error)
115 reject(error);
116 resolve(data);
117 });
118 });
119 }
120 //
121 // Public API functions
122 //
123 getTick(instrument, currency) {
124 // @ts-ignore
125 return this.publicRequest(instrument, currency, 'tick');
126 }
127 ;
128 getOrderBook(instrument, currency) {
129 // @ts-ignore
130 return this.publicRequest(instrument, currency, 'orderbook');
131 }
132 ;
133 getTrades(instrument, currency, since) {
134 // @ts-ignore
135 return this.publicRequest(instrument, currency, 'trades', {
136 since: since
137 });
138 }
139 ;
140 //
141 // Private API functions
142 //
143 createOrder(instrument, currency, price = 0, // price is not needed if a market order
144 volume, orderSide, ordertype, clientRequestId = "", // if no client id then set to an empty string
145 triggerPrice) {
146 const params = {
147 currency: currency,
148 instrument: instrument,
149 price: ordertype == 'Market' ? 0 : price,
150 volume: volume,
151 orderSide: orderSide,
152 ordertype: ordertype,
153 clientRequestId: clientRequestId,
154 triggerPrice: triggerPrice
155 };
156 // @ts-ignore
157 return this.privateRequest('/order/create', params);
158 }
159 ;
160 cancelOrders(orderIds) {
161 // @ts-ignore
162 return this.privateRequest('/order/cancel', {
163 orderIds: orderIds
164 });
165 }
166 ;
167 getOrderDetail(orderIds) {
168 // @ts-ignore
169 return this.privateRequest('/order/detail', {
170 orderIds: orderIds
171 });
172 }
173 ;
174 getOpenOrders(instrument, currency, limit = 10, since = null) {
175 // @ts-ignore
176 return this.privateRequest('/order/open', {
177 currency: currency,
178 instrument: instrument,
179 limit: limit,
180 since: since
181 });
182 }
183 ;
184 getOrderHistory(instrument, currency, limit = 100, since = null) {
185 // @ts-ignore
186 return this.privateRequest('/order/history', {
187 currency: currency,
188 instrument: instrument,
189 limit: limit,
190 since: since
191 });
192 }
193 ;
194 getTradeHistory(instrument, currency, limit = 100, since = null) {
195 // @ts-ignore
196 return this.privateRequest('/order/trade/history', {
197 currency: currency,
198 instrument: instrument,
199 limit: limit,
200 since: since
201 });
202 }
203 ;
204 getAccountBalances() {
205 // @ts-ignore
206 return this.privateRequest('/account/balance');
207 }
208 ;
209 getTradingFee(instrument, currency) {
210 // @ts-ignore
211 return this.privateRequest('/account/' + instrument + "/" + currency + "/" + 'tradingfee');
212 }
213 ;
214 withdrawCrypto(amount, address, crypto) {
215 // @ts-ignore
216 return this.privateRequest('/fundtransfer/withdrawCrypto', {
217 amount: amount,
218 address: address,
219 currency: crypto
220 });
221 }
222 ;
223 withdrawEFT(accountName, accountNumber, bankName, bsbNumber, amount) {
224 // @ts-ignore
225 return this.privateRequest('/fundtransfer/withdrawEFT', {
226 accountName: accountName,
227 accountNumber: accountNumber,
228 bankName: bankName,
229 bsbNumber: bsbNumber,
230 amount: amount,
231 currency: "AUD"
232 });
233 }
234 ;
235 withdrawHistory(limit, since, indexForward) {
236 // @ts-ignore
237 return this.privateRequest('/fundtransfer/history', {
238 limit: limit,
239 since: since,
240 indexForward: indexForward
241 });
242 }
243 ;
244}
245// used to convert decimal numbers to BTC Market integers. eg 0.001 BTC is 100000 when used in the BTC Markets API
246BTCMarkets.numberConverter = 100000000; // one hundred million
247exports.default = BTCMarkets;
248//# sourceMappingURL=index.js.map
\No newline at end of file