-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
374 lines (323 loc) · 12.1 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
const axios = require("axios");
const FormData = require("form-data");
let API_PROTO = "https://";
let API_MAIN = "api.bitails.io";
let API_TESTNET = "test-api.bitails.io";
class Explorer {
/**
* Bitails API Wrapper
* @param {string} network Selected network: main or test
* @param {object} opts timeout, userAgent, apiKey and enableCache
*/
constructor(network = 'main', opts = {}) {
this._network = (network === 'main' || network === 'mainnet' || network === 'livenet') ? 'main' : (network === 'test' || network === 'testnet') ? 'test' : 'stn';
this._timeout = opts.timeout || 30000;
this._userAgent = opts.userAgent || opts._userAgent;
this._apiKey = opts.apiKey;
this._enableCache = (opts.enableCache === undefined) ? true : !!opts.enableCache;
this.url = opts.url ? opts.url : this._network === "main" ? `${API_PROTO}${API_MAIN}` : `${API_PROTO}${API_TESTNET}`;
this._init();
}
_init() {
// Enhance the original axios adapter with throttle and cache enhancer
const headers = {
'Cache-Control': 'no-cache'
};
if (this._userAgent) {
headers['User-Agent'] = this._userAgent;
}
this._httpClient = axios.create({
baseURL: `${this.url}/`,
timeout: this._timeout,
headers
});
return this;
}
_parseResponse(response) {
return response.data;
}
_parseError(error) {
if (error.response) {
throw new Error(JSON.stringify(error.response.data));
} else if (error.request) {
throw new Error(error.message);
} else {
throw error;
}
}
_get(command, params = {}) {
const options = {
params
}
return this._httpClient.get(command, options).then(this._parseResponse).catch(this._parseError);
}
_post(command, data) {
const options = {
headers: {
'Content-Type': 'application/json'
}
}
return this._httpClient.post(command, data, options).then((resp) => { return this._parseResponse(resp); }).catch(this._parseError);
}
_postBinary(command, data, url = "") {
const form_data = new FormData();
form_data.append("raw", new Blob([data]), { type: 'raw' });
if (url === "") {
url = `${this.url}/tx/broadcast/multipart`;
}
return axios({
method: 'post',
url: url,
headers: { 'Content-Type': 'multipart/form-data' },
data: form_data,
timeout: 100000,
maxBodyLength: Infinity
}).then(this._parseResponse).catch(this._parseError);
}
/**
* Get api status
* Simple endpoint to show API server is up and running
* https://docs.bitails.io/#get-api-status
*/
status() {
return this._get('network/stats').then(result => result);
}
/**
* Get blockhain info
* This endpoint retrieves various state info of the chain for the selected network.
* https://docs.bitails.io/#chain-info
*/
chainInfo() {
return this._get('network/info');
}
/**
* Get by hash
* This endpoint retrieves block details with given hash.
* https://docs.bitails.io/#get-block-by-hash
* @param {string} hash The hash of the block to retrieve
*/
blockHash(hash) {
return this._get(`block/${hash}`);
}
/**
* Get by height
* This endpoint retrieves block details with given block height.
* https://docs.bitails.io/#get-by-height
* @param {number} height The height of the block to retrieve
*/
blockHeight(height) {
return this._get(`block/height/${height}`);
}
/**
* Get latest block
* This endpoint retrieves latest block header details.
* https://docs.bitails.io/#get-latest-block
*/
blockLatest() {
return this._get(`block/latest`);
}
/**
* Get block pages
* If the block has more that 1000 transactions the page URIs will be provided in the pages element when getting a block by hash or height.
* https://docs.bitails.io/#get-block-pages
* @param {string} hash The hash of the block to retrieve
* @param {number} page Page number
*/
blockList(height, opt = { skip: 0, limit: 100, sort: 'height', order: 'asc' }) {
const { skip, limit, sort, order } = { ...{ skip: 0, limit: 100, sort: 'height', order: 'asc' }, ...opt };
return this._get(`block/list?fromHeight=${height}&skip=${skip}&limit=${limit}&sort=${sort}&order=${order}`);
}
/**
* Returns the transactions of a block based on the index
*/
blockTransactions(hash, opt = { from: 0, limit: 10 }) {
return this._get(`block/${hash}/transactions?from=${opt.from}&limit=${opt.limit}`);
}
/**
* Returns the tags stats of blocks
* Perdiod: 1h || 24h || 7d
*/
blockTagHistogram(period = '24h', opt = {}) {
return this._get(`block/stats/tag/${period}/histogramblock?fromTime=${opt.from}&toTime=${opt.to}`);
}
/**
* Returns the mining stats of blocks
* Perdiod: 1h || 24h || 7d
*/
blockMiningHistogram(period = '24h', opt = {}) {
return this._get(`block/stats/mining/${period}/histogramblock?fromTime=${opt.from}&toTime=${opt.to}`);
}
/**
* Returns the props of blocks in given period
* * Perdiod: 1h || 24h || 7d
*/
blockPropsHistogram(period = '24h', opt = {}) {
return this._get(`block/stats/props/${period}/histogramblock?fromTime=${opt.from}&toTime=${opt.to}`);
}
/**
* Get by tx hash
* This endpoint retrieves transaction details with given transaction hash.
* In the response body, if any output hex size, exceeds 100KB then data is truncated
* NOTICE:A separate endpoint get raw transaction output data can be used to fetch full hex data
* https://docs.bitails.io/#get-by-tx-hash
* @param {string} hash The hash/txId of the transaction to retrieve
*/
txHash(hash) {
return this._get(`tx/${hash}`);
}
/**
* Download raw transactions
* https://docs.bitails.io/#download-transaction
* @param {string} hash The hash/txId of the transaction to retrieve
*/
downloadTx(hash) {
return this._get(`download/tx/${hash}`, { responseType: 'arraybuffer' });
}
/**
* Download specific transaction output
* https://docs.bitails.io/#download-transaction
* @param {string} hash The hash/txId of the transaction to retrieve
* @param {integer} index The index of the output to retrieve
*/
downloadTxOut(hash, index) {
return this._get(`download/tx/${hash}/output/${index}`);
}
/**
* Broadcast transaction
* Broadcast transaction using this endpoint. Get txid in response or error msg from node with header content-type: text/plain.
* https://docs.bitails.io/#broadcast-transaction
* @param {string} txhex Raw transaction data in hex
*/
broadcast(txhex) {
return this._post('tx/broadcast', {
raw: txhex
});
}
broadcastBinary(txBuf) {
return this._postBinary('tx/broadcast/multipart', txBuf);
}
/**
* Get raw transaction output data
* Get raw transaction vout data in hex
* https://docs.bitails.io/#get-raw-transaction-output-data
* @param {string} hash The hash/txId of the transaction
* @param {number} outputIndex Output index
*/
getOutputData(hash, outputIndex) {
return this._get(`tx/${hash}/output/${outputIndex}`);
}
getOutputsData(hash, fromIndex, toIndex) {
return this._get(`tx/${hash}/outputs/${fromIndex}/${toIndex}`);
}
/**
* Get merkle proof
* This endpoint returns merkle branch to a confirmed transaction
* https://docs.bitails.io/#get-merkle-proof
* @param {string} hash The hash/txId of the transaction
*/
merkleProof(hash) {
return this._get(`tx/${hash}/proof`);
}
/**
* Get mempool info
* This endpoint retrieves various info about the node's mempool for the selected network.
* https://docs.bitails.io/#get-mempool-info
*/
mempoolInfo() {
return this._get(`mempool`);
}
/**
* Get mempool transactions
* This endpoint retrieve list of transaction ids from the node's mempool for the selected network.
* https://docs.bitails.io/#get-mempool-transactions
*
*/
mempoolTxs() {
return this._get(`mempool/transactions`);
}
/**
* Get address info
* This endpoint retrieves various address info.
* @param {string} address
*/
addressInfo(address) {
return this._get(`address/${address}/details`);
}
/**
* Get balance
* This endpoint retrieves confirmed and unconfirmed address balance.
* @param {string} address
*/
balance(address) {
return this._get(`address/${address}/balance`);
}
/**
* Get history
* This endpoint retrieves confirmed and unconfirmed address transactions.
* https://docs.bitails.io/#get-history
* @param {string} address
*/
history(address, pgkey = "", limit = 100, pagination = true, pagesize = 10, page = 1) {
let pgkeyParam = "";
if (pgkey != "") { pgkeyParam = `pgkey=${pgkey}&`; } else { pgkeyParam = ""; }
return this._get(`address/${address}/history?${pgkeyParam}limit=${limit}`);
}
/**
* Get unspent transactions
* This endpoint retrieves ordered list of UTXOs.
* https://docs.bitails.io/#get-unspent-transactions
* @param {string} address
*/
utxos(address, from = 0, limit = 100) {
return this._get(`address/${address}/unspent?from=${from}&limit=${limit}`);
}
/**
* Get balance of scriptHash
* This endpoint retrieves balace if ScriptHash
* https://docs.bitails.io/#get-balance-of-scripthash
* @param {string} scriptHash Script hash: Sha256 hash of the binary bytes of the locking script (ScriptPubKey), expressed as a hexadecimal string.
*/
balanceScriptHash(scriptHash) {
return this._get(`scripthash/${scriptHash}/balance`);
}
/**
* Get scriptHash history
* This endpoint retrieves confirmed and unconfirmed script transactions.
* https://docs.bitails.io/#get-history-of-scripthash
* @param {string} scriptHash Script hash: Sha256 hash of the binary bytes of the locking script (ScriptPubKey), expressed as a hexadecimal string.
*/
historyByScriptHash(scriptHash, pgkey = "", limit = 100, pagination = true, pagesize = 100, page = 1) {
let pgkeyParam = "";
if (pgkey != "") { pgkeyParam = `pgkey=${pgkey}&`; } else { pgkeyParam = ""; }
return this._get(`scripthash/${scriptHash}/history?${pgkeyParam}limit=${limit}`);
}
/**
* Get scriptHash information
* This endpoint retrieves information abut ScriptHash
* https://docs.bitails.io/#get-details-of-scripthash
* @param {string} scriptHash Script hash: Sha256 hash of the binary bytes of the locking script (ScriptPubKey), expressed as a hexadecimal string.
*/
detailsScriptHash(scriptHash) {
return this._get(`scripthash/${scriptHash}/details`);
}
/**
* Get scriptHash unspent transactions
* This endpoint retrieves ordered list of UTXOs.
* https://docs.bitails.io/#get-script-unspent-transactions
* @param {string} scriptHash Script hash: Sha256 hash of the binary bytes of the locking script (ScriptPubKey), expressed as a hexadecimal string.
*/
utxosByScriptHash(scriptHash, from = 0, limit = 100) {
return this._get(`scripthash/${scriptHash}/unspent?from=${from}&limit=${limit}`);
}
/**
* Get txid details links
* This endpoint retrieves transactions including the search parameter.
* https://docs.bitails.io/#Search
* type: all || ops || tx || block || scripthash || address
* @param {string}
*/
search(q, opts = { type: 'ops', from: 0, limit: 10 }) {
return this._get(`search?type=${opts.type}&q={${q}}&from=${opts.from}&limit=${opts.limit}`);
}
}
module.exports = Explorer;