1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", { value: true });
|
4 | const buffer_1 = require("buffer");
|
5 | const querystring = require("querystring");
|
6 | const crypto_1 = require("crypto");
|
7 | const request = require("request");
|
8 | const cheerio = require("cheerio");
|
9 | const VError = require("verror");
|
10 | class 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 |
|
23 |
|
24 |
|
25 | if (path.split('/')[1] === 'account' ||
|
26 | path === '/fundtransfer/history') {
|
27 | method = 'GET';
|
28 | }
|
29 |
|
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;
|
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 |
|
98 | else if (data !== Object(data)) {
|
99 |
|
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 |
|
122 |
|
123 | getTick(instrument, currency) {
|
124 |
|
125 | return this.publicRequest(instrument, currency, 'tick');
|
126 | }
|
127 | ;
|
128 | getOrderBook(instrument, currency) {
|
129 |
|
130 | return this.publicRequest(instrument, currency, 'orderbook');
|
131 | }
|
132 | ;
|
133 | getTrades(instrument, currency, since) {
|
134 |
|
135 | return this.publicRequest(instrument, currency, 'trades', {
|
136 | since: since
|
137 | });
|
138 | }
|
139 | ;
|
140 |
|
141 |
|
142 |
|
143 | createOrder(instrument, currency, price = 0,
|
144 | volume, orderSide, ordertype, clientRequestId = "",
|
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 |
|
157 | return this.privateRequest('/order/create', params);
|
158 | }
|
159 | ;
|
160 | cancelOrders(orderIds) {
|
161 |
|
162 | return this.privateRequest('/order/cancel', {
|
163 | orderIds: orderIds
|
164 | });
|
165 | }
|
166 | ;
|
167 | getOrderDetail(orderIds) {
|
168 |
|
169 | return this.privateRequest('/order/detail', {
|
170 | orderIds: orderIds
|
171 | });
|
172 | }
|
173 | ;
|
174 | getOpenOrders(instrument, currency, limit = 10, since = null) {
|
175 |
|
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 |
|
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 |
|
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 |
|
206 | return this.privateRequest('/account/balance');
|
207 | }
|
208 | ;
|
209 | getTradingFee(instrument, currency) {
|
210 |
|
211 | return this.privateRequest('/account/' + instrument + "/" + currency + "/" + 'tradingfee');
|
212 | }
|
213 | ;
|
214 | withdrawCrypto(amount, address, crypto) {
|
215 |
|
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 |
|
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 |
|
237 | return this.privateRequest('/fundtransfer/history', {
|
238 | limit: limit,
|
239 | since: since,
|
240 | indexForward: indexForward
|
241 | });
|
242 | }
|
243 | ;
|
244 | }
|
245 |
|
246 | BTCMarkets.numberConverter = 100000000;
|
247 | exports.default = BTCMarkets;
|
248 |
|
\ | No newline at end of file |