@xchainjs/xchain-utxo-providers 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/lib/index.d.ts +1 -1
  2. package/lib/index.esm.js +1874 -0
  3. package/lib/index.js +1883 -6
  4. package/lib/providers/blockcypher/blockcypher-api-types.d.ts +96 -96
  5. package/lib/providers/blockcypher/blockcypher-api.d.ts +69 -69
  6. package/lib/providers/blockcypher/blockcypher-data-provider.d.ts +52 -52
  7. package/lib/providers/haskoin/haskoin-api-types.d.ts +113 -113
  8. package/lib/providers/haskoin/haskoin-api.d.ts +150 -150
  9. package/lib/providers/haskoin/haskoin-data-provider.d.ts +37 -37
  10. package/lib/providers/index.d.ts +8 -8
  11. package/lib/providers/sochainv3/sochain-api-types.d.ts +101 -101
  12. package/lib/providers/sochainv3/sochain-api.d.ts +113 -113
  13. package/lib/providers/sochainv3/sochain-data-provider.d.ts +42 -42
  14. package/package.json +5 -6
  15. package/lib/index.js.map +0 -1
  16. package/lib/providers/blockcypher/blockcypher-api-types.js +0 -11
  17. package/lib/providers/blockcypher/blockcypher-api-types.js.map +0 -1
  18. package/lib/providers/blockcypher/blockcypher-api.js +0 -231
  19. package/lib/providers/blockcypher/blockcypher-api.js.map +0 -1
  20. package/lib/providers/blockcypher/blockcypher-data-provider.js +0 -366
  21. package/lib/providers/blockcypher/blockcypher-data-provider.js.map +0 -1
  22. package/lib/providers/haskoin/haskoin-api-types.js +0 -14
  23. package/lib/providers/haskoin/haskoin-api-types.js.map +0 -1
  24. package/lib/providers/haskoin/haskoin-api.js +0 -485
  25. package/lib/providers/haskoin/haskoin-api.js.map +0 -1
  26. package/lib/providers/haskoin/haskoin-data-provider.js +0 -269
  27. package/lib/providers/haskoin/haskoin-data-provider.js.map +0 -1
  28. package/lib/providers/index.js +0 -34
  29. package/lib/providers/index.js.map +0 -1
  30. package/lib/providers/sochainv3/sochain-api-types.js +0 -13
  31. package/lib/providers/sochainv3/sochain-api-types.js.map +0 -1
  32. package/lib/providers/sochainv3/sochain-api.js +0 -354
  33. package/lib/providers/sochainv3/sochain-api.js.map +0 -1
  34. package/lib/providers/sochainv3/sochain-data-provider.js +0 -312
  35. package/lib/providers/sochainv3/sochain-data-provider.js.map +0 -1
@@ -0,0 +1,1874 @@
1
+ import { assetAmount, assetToBase, baseAmount, delay } from '@xchainjs/xchain-util';
2
+ import axios from 'axios';
3
+ import { TxType } from '@xchainjs/xchain-client';
4
+
5
+ var SochainNetwork;
6
+ (function (SochainNetwork) {
7
+ SochainNetwork["BTC"] = "BTC";
8
+ SochainNetwork["BTCTEST"] = "BTCTEST";
9
+ SochainNetwork["LTC"] = "LTC";
10
+ SochainNetwork["LTCTEST"] = "LTCTEST";
11
+ SochainNetwork["DOGE"] = "DOGE";
12
+ SochainNetwork["DOGETEST"] = "DOGETEST";
13
+ })(SochainNetwork || (SochainNetwork = {}));
14
+
15
+ /*! *****************************************************************************
16
+ Copyright (c) Microsoft Corporation.
17
+
18
+ Permission to use, copy, modify, and/or distribute this software for any
19
+ purpose with or without fee is hereby granted.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
22
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
23
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
24
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
25
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27
+ PERFORMANCE OF THIS SOFTWARE.
28
+ ***************************************************************************** */
29
+
30
+ function __awaiter(thisArg, _arguments, P, generator) {
31
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
32
+ return new (P || (P = Promise))(function (resolve, reject) {
33
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
34
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
35
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
36
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
37
+ });
38
+ }
39
+
40
+ /**
41
+ * Get transaction by hash.
42
+ *
43
+ * @see https://sochain.com/api#get-tx
44
+ *
45
+ * @param {string} sochainUrl The sochain node url.
46
+ * @param {string} network network id
47
+ * @param {string} hash The transaction hash.
48
+ * @returns {Transactions}
49
+ */
50
+ const getTx = ({ apiKey, sochainUrl, network, hash }) => __awaiter(void 0, void 0, void 0, function* () {
51
+ const url = `${sochainUrl}/transaction/${network}/${hash}`;
52
+ const response = yield axios.get(url, { headers: { 'API-KEY': apiKey } });
53
+ const tx = response.data;
54
+ return tx.data;
55
+ });
56
+ /**
57
+ * Get transactions
58
+ *
59
+ * @see https://sochain.com/api#get-tx
60
+ *
61
+ * @param {string} sochainUrl The sochain node url.
62
+ * @param {string} network network id
63
+ * @param {string} hash The transaction hash.
64
+ * @returns {Transactions}
65
+ */
66
+ const getTxs = ({ apiKey, address, sochainUrl, network, page, }) => __awaiter(void 0, void 0, void 0, function* () {
67
+ const url = `${sochainUrl}/transactions/${network}/${address}/${page}`; //TODO support paging
68
+ const response = yield axios.get(url, { headers: { 'API-KEY': apiKey } });
69
+ const txs = response.data;
70
+ return txs.data;
71
+ });
72
+ /**
73
+ * Get address balance.
74
+ *
75
+ * @see https://sochain.com/api#get-balance
76
+ *
77
+ * @param {string} sochainUrl The sochain node url.
78
+ * @param {string} network Network
79
+ * @param {string} address Address
80
+ * @param {boolean} confirmedOnly Flag whether to get balances of confirmed txs only or for all
81
+ * @returns {number}
82
+ */
83
+ const getBalance = ({ apiKey, sochainUrl, network, address, confirmedOnly, assetDecimals, }) => __awaiter(void 0, void 0, void 0, function* () {
84
+ const url = `${sochainUrl}/balance/${network}/${address}`;
85
+ const response = yield axios.get(url, { headers: { 'API-KEY': apiKey } });
86
+ const balanceResponse = response.data;
87
+ const confirmed = assetAmount(balanceResponse.data.confirmed, assetDecimals);
88
+ const unconfirmed = assetAmount(balanceResponse.data.unconfirmed, assetDecimals);
89
+ const netAmt = confirmedOnly ? confirmed : confirmed.plus(unconfirmed);
90
+ const result = assetToBase(netAmt);
91
+ return result;
92
+ });
93
+ /**
94
+ * Get unspent txs
95
+ *
96
+ * @see https://sochain.com/api#get-unspent-tx
97
+ *
98
+ * @param {string} sochainUrl The sochain node url.
99
+ * @param {string} network
100
+ * @param {string} address
101
+ * @returns {AddressUTXO[]}
102
+ */
103
+ const getUnspentTxs = ({ apiKey, sochainUrl, network, address, page, }) => __awaiter(void 0, void 0, void 0, function* () {
104
+ const url = [sochainUrl, 'unspent_outputs', network, address, page].filter((v) => !!v).join('/');
105
+ const resp = yield axios.get(url, { headers: { 'API-KEY': apiKey } });
106
+ const response = resp.data;
107
+ const txs = response.data.outputs;
108
+ if (txs.length === 10) {
109
+ //fetch the next batch
110
+ const nextBatch = yield getUnspentTxs({
111
+ apiKey,
112
+ sochainUrl,
113
+ network,
114
+ address,
115
+ page: page + 1,
116
+ });
117
+ return txs.concat(nextBatch);
118
+ }
119
+ else {
120
+ return txs;
121
+ }
122
+ });
123
+ /**
124
+ * Get address balance.
125
+ *
126
+ * @see https://sochain.com/api#get-balance
127
+ *
128
+ * @param {string} sochainUrl The sochain node url.
129
+ * @param {string} network Network
130
+ * @param {string} address Address
131
+ * @param {boolean} confirmedOnly Flag whether to get balances of confirmed txs only or for all
132
+ * @returns {number}
133
+ */
134
+ const broadcastTx = ({ apiKey, sochainUrl, network, txHex, }) => __awaiter(void 0, void 0, void 0, function* () {
135
+ const url = `${sochainUrl}/broadcast_transaction/${network}`;
136
+ const response = yield axios.post(url, { tx_hex: txHex }, { headers: { 'API-KEY': apiKey } });
137
+ const broadcastResponse = response.data;
138
+ return broadcastResponse.tx_hex;
139
+ });
140
+
141
+ class SochainProvider {
142
+ constructor(baseUrl = 'https://sochain.com/api/v3', apiKey, chain, asset, assetDecimals, sochainNetwork) {
143
+ this.baseUrl = baseUrl;
144
+ this._apiKey = apiKey;
145
+ this.chain = chain;
146
+ this.asset = asset;
147
+ this.assetDecimals = assetDecimals;
148
+ this.sochainNetwork = sochainNetwork;
149
+ this.asset;
150
+ this.chain;
151
+ }
152
+ get apiKey() {
153
+ return this._apiKey;
154
+ }
155
+ set apiKey(value) {
156
+ this._apiKey = value;
157
+ }
158
+ broadcastTx(txHex) {
159
+ return __awaiter(this, void 0, void 0, function* () {
160
+ return yield broadcastTx({
161
+ apiKey: this._apiKey,
162
+ sochainUrl: this.baseUrl,
163
+ network: this.sochainNetwork,
164
+ txHex,
165
+ });
166
+ });
167
+ }
168
+ getConfirmedUnspentTxs(address) {
169
+ return __awaiter(this, void 0, void 0, function* () {
170
+ const allUnspent = yield getUnspentTxs({
171
+ apiKey: this._apiKey,
172
+ sochainUrl: this.baseUrl,
173
+ network: this.sochainNetwork,
174
+ address,
175
+ page: 1,
176
+ });
177
+ const confirmedUnspent = allUnspent.filter((i) => i.block); //if it has a block noumber it's been confirmed
178
+ return this.mapUTXOs(confirmedUnspent);
179
+ });
180
+ }
181
+ getUnspentTxs(address) {
182
+ return __awaiter(this, void 0, void 0, function* () {
183
+ const allUnspent = yield getUnspentTxs({
184
+ apiKey: this._apiKey,
185
+ sochainUrl: this.baseUrl,
186
+ network: this.sochainNetwork,
187
+ address,
188
+ page: 1,
189
+ });
190
+ return this.mapUTXOs(allUnspent);
191
+ });
192
+ }
193
+ getBalance(address, assets /*ignored*/, confirmedOnly) {
194
+ return __awaiter(this, void 0, void 0, function* () {
195
+ try {
196
+ const amount = yield getBalance({
197
+ apiKey: this._apiKey,
198
+ sochainUrl: this.baseUrl,
199
+ network: this.sochainNetwork,
200
+ address,
201
+ confirmedOnly: !!confirmedOnly,
202
+ assetDecimals: this.assetDecimals,
203
+ });
204
+ return [{ amount, asset: this.asset }];
205
+ }
206
+ catch (error) {
207
+ throw new Error(`Could not get balances for address ${address}`);
208
+ }
209
+ });
210
+ }
211
+ /**
212
+ * Get transaction history of a given address with pagination options.
213
+ * By default it will return the transaction history of the current wallet.
214
+ *
215
+ * @param {TxHistoryParams} params The options to get transaction history. (optional)
216
+ * @returns {TxsPage} The transaction history.
217
+ */
218
+ getTransactions(params) {
219
+ var _a;
220
+ return __awaiter(this, void 0, void 0, function* () {
221
+ const offset = (_a = params === null || params === void 0 ? void 0 : params.offset) !== null && _a !== void 0 ? _a : 0;
222
+ const limit = (params === null || params === void 0 ? void 0 : params.limit) || 10;
223
+ if (offset < 0 || limit < 0)
224
+ throw Error('ofset and limit must be equal or greater than 0');
225
+ const firstPage = Math.floor(offset / 10) + 1;
226
+ const lastPage = limit > 10 ? firstPage + Math.floor(limit / 10) : firstPage;
227
+ const offsetOnFirstPage = offset % 10;
228
+ const txHashesToFetch = [];
229
+ let page = firstPage;
230
+ try {
231
+ while (page <= lastPage) {
232
+ const response = yield getTxs({
233
+ apiKey: this._apiKey,
234
+ sochainUrl: this.baseUrl,
235
+ network: this.sochainNetwork,
236
+ address: `${params === null || params === void 0 ? void 0 : params.address}`,
237
+ page,
238
+ });
239
+ if (response.transactions.length === 0)
240
+ break;
241
+ if (page === firstPage && response.transactions.length > offsetOnFirstPage) {
242
+ //start from offset
243
+ const txsToGet = response.transactions.slice(offsetOnFirstPage);
244
+ this.addArrayUpToLimit(txHashesToFetch, txsToGet.map((i) => i.hash), limit);
245
+ }
246
+ else {
247
+ this.addArrayUpToLimit(txHashesToFetch, response.transactions.map((i) => i.hash), limit);
248
+ }
249
+ page++;
250
+ }
251
+ }
252
+ catch (error) {
253
+ console.error(error);
254
+ //an errors means no more results
255
+ }
256
+ const total = txHashesToFetch.length;
257
+ const transactions = yield Promise.all(txHashesToFetch.map((hash) => this.getTransactionData(hash)));
258
+ const result = {
259
+ total,
260
+ txs: transactions,
261
+ };
262
+ return result;
263
+ });
264
+ }
265
+ /**
266
+ * Get the transaction details of a given transaction id.
267
+ *
268
+ * @param {string} txId The transaction id.
269
+ * @returns {Tx} The transaction details of the given transaction id.
270
+ */
271
+ getTransactionData(txId) {
272
+ return __awaiter(this, void 0, void 0, function* () {
273
+ try {
274
+ const rawTx = yield getTx({
275
+ apiKey: this._apiKey,
276
+ sochainUrl: this.baseUrl,
277
+ network: this.sochainNetwork,
278
+ hash: txId,
279
+ });
280
+ return {
281
+ asset: this.asset,
282
+ from: rawTx.inputs.map((i) => ({
283
+ from: i.address,
284
+ amount: assetToBase(assetAmount(i.value, this.assetDecimals)),
285
+ })),
286
+ to: rawTx.outputs
287
+ .filter((i) => i.type !== 'nulldata') //filter out op_return outputs
288
+ .map((i) => ({ to: i.address, amount: assetToBase(assetAmount(i.value, this.assetDecimals)) })),
289
+ date: new Date(rawTx.time * 1000),
290
+ type: TxType.Transfer,
291
+ hash: rawTx.hash,
292
+ };
293
+ }
294
+ catch (error) {
295
+ console.error(error);
296
+ throw error;
297
+ }
298
+ });
299
+ }
300
+ mapUTXOs(utxos) {
301
+ return utxos.map((utxo) => ({
302
+ hash: utxo.hash,
303
+ index: utxo.index,
304
+ value: assetToBase(assetAmount(utxo.value, this.assetDecimals)).amount().toNumber(),
305
+ witnessUtxo: {
306
+ value: assetToBase(assetAmount(utxo.value, this.assetDecimals)).amount().toNumber(),
307
+ script: Buffer.from(utxo.script, 'hex'),
308
+ },
309
+ txHex: utxo.tx_hex,
310
+ }));
311
+ }
312
+ /**
313
+ * helper function tto limit adding to an array
314
+ *
315
+ * @param arr array to be added to
316
+ * @param toAdd elements to add
317
+ * @param limit do not add more than this limit
318
+ */
319
+ addArrayUpToLimit(arr, toAdd, limit) {
320
+ for (let index = 0; index < toAdd.length; index++) {
321
+ const element = toAdd[index];
322
+ if (arr.length < limit) {
323
+ arr.push(element);
324
+ }
325
+ }
326
+ }
327
+ }
328
+
329
+ /**
330
+ * Haskoin API types
331
+ */
332
+ var HaskoinNetwork;
333
+ (function (HaskoinNetwork) {
334
+ HaskoinNetwork["BTC"] = "btc";
335
+ HaskoinNetwork["BTCTEST"] = "btctest";
336
+ HaskoinNetwork["BCH"] = "bch";
337
+ HaskoinNetwork["BCHTEST"] = "bchtest";
338
+ })(HaskoinNetwork || (HaskoinNetwork = {}));
339
+
340
+ /**
341
+ * Module to interact with Haskoin API
342
+ *
343
+ * Doc (SwaggerHub) https://app.swaggerhub.com/apis/eligecode/blockchain-api/0.0.1-oas3
344
+ *
345
+ */
346
+ /**
347
+ * Check error response.
348
+ *
349
+ * @param {any} response The api response.
350
+ * @returns {boolean}
351
+ */
352
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
353
+ const isErrorResponse = (response) => {
354
+ return !!response.error;
355
+ };
356
+ /**
357
+ * Get account from address.
358
+ *
359
+ * @param {string} haskoinUrl The haskoin API url.
360
+ * @param {string} address The BCH address.
361
+ * @returns {AddressBalance}
362
+ *
363
+ * @throws {"failed to query account by a given address"} thrown if failed to query account by a given address
364
+ */
365
+ const getAccount = ({ haskoinUrl, network, address }) => __awaiter(void 0, void 0, void 0, function* () {
366
+ const url = `${haskoinUrl}/${network}/address/${address}/balance`;
367
+ const result = (yield axios.get(url)).data;
368
+ if (!result || isErrorResponse(result))
369
+ throw new Error(`failed to query account by given address ${address}`);
370
+ return result;
371
+ });
372
+ /**
373
+ * Get address information.
374
+ *
375
+ * @param {string} haskoinUrl The haskoin node url.
376
+ * @param {string} network
377
+ * @param {string} address
378
+ * @returns {AddressDTO}
379
+ */
380
+ const getAddress = ({ haskoinUrl, network, address }) => __awaiter(void 0, void 0, void 0, function* () {
381
+ const url = `${haskoinUrl}/${network}/address/${address}/balance`;
382
+ const response = yield axios.get(url);
383
+ const addressResponse = response.data;
384
+ return addressResponse.data;
385
+ });
386
+ /**
387
+ * Get transaction by hash.
388
+ *
389
+ * @param {string} haskoinUrl The haskoin API url.
390
+ * @param {string} txId The transaction id.
391
+ * @returns {Transaction}
392
+ *
393
+ * @throws {"failed to query transaction by a given hash"} thrown if failed to query transaction by a given hash
394
+ */
395
+ const getTx$1 = ({ haskoinUrl, txId, network }) => __awaiter(void 0, void 0, void 0, function* () {
396
+ const result = (yield axios.get(`${haskoinUrl}/${network}/transaction/${txId}`)).data;
397
+ if (!result || isErrorResponse(result))
398
+ throw new Error(`failed to query transaction by a given hash ${txId}`);
399
+ return result;
400
+ });
401
+ /**
402
+ * Get raw transaction by hash.
403
+ *
404
+ * @param {string} haskoinUrl The haskoin API url.
405
+ * @param {string} txId The transaction id.
406
+ * @returns {Transaction}
407
+ *
408
+ * @throws {"failed to query transaction by a given hash"} thrown if failed to query raw transaction by a given hash
409
+ */
410
+ const getRawTransaction = ({ haskoinUrl, network, txId }) => __awaiter(void 0, void 0, void 0, function* () {
411
+ const result = (yield axios.get(`${haskoinUrl}/${network}/transaction/${txId}/raw`))
412
+ .data;
413
+ if (!result || isErrorResponse(result))
414
+ throw new Error(`failed to query transaction by a given hash ${txId}`);
415
+ return result.result;
416
+ });
417
+ /**
418
+ * Get transactions
419
+ *
420
+ * @see https://haskoin.com/api#get-tx
421
+ *
422
+ * @param {string} haskoinUrl The haskoin node url.
423
+ * @param {string} network network id
424
+ * @param {string} hash The transaction hash.
425
+ * @returns {Transactions}
426
+ */
427
+ const getTxs$1 = ({ address, haskoinUrl, network, limit, offset, }) => __awaiter(void 0, void 0, void 0, function* () {
428
+ const params = { limit: `${limit}`, offset: `${offset}` };
429
+ const url = `${haskoinUrl}/${network}/address/${address}/transactions/full`;
430
+ const result = (yield axios.get(url, { params })).data;
431
+ if (!result || isErrorResponse(result))
432
+ throw new Error('failed to query transactions');
433
+ return result;
434
+ });
435
+ /**
436
+ *
437
+ * @param param
438
+ * @returns Returns BaseAmount
439
+ */
440
+ const getBalance$1 = ({ haskoinUrl, haskoinNetwork, address, confirmedOnly, assetDecimals, }) => __awaiter(void 0, void 0, void 0, function* () {
441
+ const { data: { confirmed, unconfirmed }, } = yield axios.get(`${haskoinUrl}/${haskoinNetwork}/address/${address}/balance`);
442
+ const confirmedAmount = baseAmount(confirmed, assetDecimals);
443
+ const unconfirmedAmount = baseAmount(unconfirmed, assetDecimals);
444
+ return confirmedOnly ? confirmedAmount : confirmedAmount.plus(unconfirmedAmount);
445
+ });
446
+ /**
447
+ * Get unspent transactions.
448
+ *
449
+ * @param {string} haskoinUrl The haskoin API url.
450
+ * @param {string} address The BCH address.
451
+ * @returns {TxUnspent[]}
452
+ *
453
+ * @throws {"failed to query unspent transactions"} thrown if failed to query unspent transactions
454
+ */
455
+ const getUnspentTxs$1 = ({ haskoinUrl, network, address }) => __awaiter(void 0, void 0, void 0, function* () {
456
+ // Get transaction count for a given address.
457
+ const account = yield getAccount({ haskoinUrl, network, address });
458
+ // Set limit to the transaction count to be all the utxos.
459
+ const result = (yield axios.get(`${haskoinUrl}/${network}/address/${address}/unspent?limit${account === null || account === void 0 ? void 0 : account.utxo}`)).data;
460
+ if (!result || isErrorResponse(result))
461
+ throw new Error('failed to query unspent transactions');
462
+ return result;
463
+ });
464
+ /**
465
+ * Get Tx Confirmation status
466
+ *
467
+ * @param {string} haskoinUrl The haskoin node url.
468
+ * @param {Network} network
469
+ * @param {string} hash tx id
470
+ * @returns {TxConfirmedStatus}
471
+ */
472
+ const getIsTxConfirmed = ({ haskoinUrl, network, txId }) => __awaiter(void 0, void 0, void 0, function* () {
473
+ const tx = yield getTx$1({ haskoinUrl, network, txId });
474
+ return {
475
+ network: network,
476
+ txid: txId,
477
+ confirmations: tx.confirmations,
478
+ is_confirmed: tx.confirmations >= 1,
479
+ };
480
+ });
481
+ /**
482
+ * List of confirmed txs
483
+ *
484
+ * Stores a list of confirmed txs (hashes) in memory to avoid requesting same data
485
+ */
486
+ const confirmedTxs = [];
487
+ /**
488
+ * Helper to get `confirmed` status of a tx.
489
+ *
490
+ * It will get it from cache or try to get it from haskoin (if not cached before)
491
+ */
492
+ const getConfirmedTxStatus = ({ txHash, haskoinUrl, network, }) => __awaiter(void 0, void 0, void 0, function* () {
493
+ // try to get it from cache
494
+ if (confirmedTxs.includes(txHash))
495
+ return true;
496
+ // or get status from haskoin
497
+ const { is_confirmed } = yield getIsTxConfirmed({
498
+ haskoinUrl,
499
+ network,
500
+ txId: txHash,
501
+ });
502
+ // cache status
503
+ confirmedTxs.push(txHash);
504
+ return is_confirmed;
505
+ });
506
+ /**
507
+ * Get unspent txs and filter out pending UTXOs
508
+ *
509
+ * @see https://haskoin.com/api#get-unspent-tx
510
+ *
511
+ * @param {string} haskoinUrl The haskoin node url.
512
+ * @param {Network} network
513
+ * @param {string} address
514
+ * @returns {AddressUTXO[]}
515
+ */
516
+ const getConfirmedUnspentTxs = ({ haskoinUrl, network, address }) => __awaiter(void 0, void 0, void 0, function* () {
517
+ const txs = yield getUnspentTxs$1({
518
+ haskoinUrl,
519
+ network,
520
+ address,
521
+ });
522
+ const confirmedUTXOs = [];
523
+ yield Promise.all(txs.map((tx) => __awaiter(void 0, void 0, void 0, function* () {
524
+ const confirmed = yield getConfirmedTxStatus({
525
+ haskoinUrl,
526
+ network,
527
+ txHash: tx.txid,
528
+ });
529
+ if (confirmed) {
530
+ confirmedUTXOs.push(tx);
531
+ }
532
+ })));
533
+ return confirmedUTXOs;
534
+ });
535
+ // Stores list of txHex in memory to avoid requesting same data
536
+ const txHexMap = {};
537
+ /**
538
+ * Helper to get `hex` of `Tx`
539
+ *
540
+ * It will try to get it from cache before requesting it from Sochain
541
+ */
542
+ const getTxHex = ({ haskoinUrl, network, txId }) => __awaiter(void 0, void 0, void 0, function* () {
543
+ // try to get hex from cache
544
+ let txHex = txHexMap[txId];
545
+ if (!!txHex)
546
+ return txHex;
547
+ // or get it from Haskoin
548
+ txHex = yield getRawTransaction({ haskoinUrl, txId: txId, network: network });
549
+ // cache it
550
+ txHexMap[txId] = txHex;
551
+ return txHex;
552
+ });
553
+ /**
554
+ * Get unspent transactions.
555
+ *
556
+ * @param {string} haskoinUrl The haskoin API url.
557
+ * @param {string} address The BCH address.
558
+ * @returns {TxUnspent[]}
559
+ *
560
+ * @throws {"failed to query unspent transactions"} thrown if failed to query unspent transactions
561
+ */
562
+ const getUnspentTransactions = ({ haskoinUrl, network, address }) => __awaiter(void 0, void 0, void 0, function* () {
563
+ // Get transaction count for a given address.
564
+ const account = yield getAccount({ haskoinUrl, network, address });
565
+ // Set limit to the transaction count to be all the utxos.
566
+ const result = (yield axios.get(`${haskoinUrl}/${network}/address/${address}/unspent?limit${account === null || account === void 0 ? void 0 : account.utxo}`)).data;
567
+ if (!result || isErrorResponse(result))
568
+ throw new Error('failed to query unspent transactions');
569
+ return result;
570
+ });
571
+ /**
572
+ * Broadcast transaction.
573
+ *
574
+ * @see https://app.swaggerhub.com/apis/eligecode/blockchain-api/0.0.1-oas3#/blockchain/sendTransaction
575
+ *
576
+ * Note: Because of an Haskoin issue (@see https://github.com/haskoin/haskoin-store/issues/25),
577
+ * we need to broadcast same tx several times in case of `500` errors
578
+ * @see https://github.com/xchainjs/xchainjs-lib/issues/492
579
+ *
580
+ * @param {BroadcastTxParams} params
581
+ * @returns {TxHash} Transaction hash.
582
+ */
583
+ const broadcastTx$1 = ({ txHex, haskoinUrl, haskoinNetwork, }) => __awaiter(void 0, void 0, void 0, function* () {
584
+ var _a;
585
+ const MAX_RETRIES = 5;
586
+ let retries = 0;
587
+ const axiosInstance = axios.create();
588
+ const url = `${haskoinUrl}/${haskoinNetwork}/transactions`;
589
+ while (retries < MAX_RETRIES) {
590
+ try {
591
+ const response = yield axiosInstance.post(url, txHex);
592
+ const { txid } = response.data;
593
+ return txid;
594
+ }
595
+ catch (error) {
596
+ if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 500) {
597
+ retries++;
598
+ yield delay(200 * retries);
599
+ }
600
+ else {
601
+ return Promise.reject(error);
602
+ }
603
+ }
604
+ }
605
+ return Promise.reject(new Error('Max retries exceeded'));
606
+ });
607
+
608
+ class HaskoinProvider {
609
+ constructor(baseUrl = 'https://api.haskoin.com/', chain, asset, assetDecimals, haskoinNetwork) {
610
+ this.baseUrl = baseUrl;
611
+ this.chain = chain;
612
+ this.asset = asset;
613
+ this.assetDecimals = assetDecimals;
614
+ this.haskoinNetwork = haskoinNetwork;
615
+ this.asset;
616
+ this.chain;
617
+ }
618
+ broadcastTx(txHex) {
619
+ return __awaiter(this, void 0, void 0, function* () {
620
+ return yield broadcastTx$1({
621
+ haskoinUrl: this.baseUrl,
622
+ haskoinNetwork: this.haskoinNetwork,
623
+ txHex,
624
+ });
625
+ });
626
+ }
627
+ getConfirmedUnspentTxs(address) {
628
+ return __awaiter(this, void 0, void 0, function* () {
629
+ const allUnspent = yield getUnspentTransactions({
630
+ haskoinUrl: this.baseUrl,
631
+ network: this.haskoinNetwork,
632
+ address,
633
+ });
634
+ const confirmedUnspent = allUnspent.filter((i) => i.block); //if it has a block noumber it's been confirmed
635
+ return this.mapUTXOs(confirmedUnspent);
636
+ });
637
+ }
638
+ getUnspentTxs(address) {
639
+ return __awaiter(this, void 0, void 0, function* () {
640
+ const allUnspent = yield getUnspentTxs$1({
641
+ haskoinUrl: this.baseUrl,
642
+ network: this.haskoinNetwork,
643
+ address,
644
+ });
645
+ return yield this.mapUTXOs(allUnspent);
646
+ });
647
+ }
648
+ getBalance(address, assets /*ignored*/, confirmedOnly) {
649
+ return __awaiter(this, void 0, void 0, function* () {
650
+ const amount = yield getBalance$1({
651
+ haskoinUrl: this.baseUrl,
652
+ haskoinNetwork: this.haskoinNetwork,
653
+ address,
654
+ confirmedOnly: !!confirmedOnly,
655
+ assetDecimals: this.assetDecimals,
656
+ });
657
+ return [{ amount, asset: this.asset }];
658
+ });
659
+ }
660
+ /**
661
+ * Get transaction history of a given address with pagination options.
662
+ * By default it will return the transaction history of the current wallet.
663
+ *
664
+ * @param {TxHistoryParams} params The options to get transaction history. (optional)
665
+ * @returns {TxsPage} The transaction history.
666
+ */
667
+ getTransactions(params) {
668
+ var _a;
669
+ return __awaiter(this, void 0, void 0, function* () {
670
+ const offset = (_a = params === null || params === void 0 ? void 0 : params.offset) !== null && _a !== void 0 ? _a : 0;
671
+ const limit = (params === null || params === void 0 ? void 0 : params.limit) || 10;
672
+ if (offset + limit > 2000)
673
+ throw Error('cannot fetch more than last 2000 txs');
674
+ if (offset < 0 || limit < 0)
675
+ throw Error('ofset and limit must be equal or greater than 0');
676
+ const response = yield getTxs$1({
677
+ address: `${params === null || params === void 0 ? void 0 : params.address}`,
678
+ haskoinUrl: this.baseUrl,
679
+ network: this.haskoinNetwork,
680
+ limit: limit,
681
+ offset,
682
+ });
683
+ const txs = response.map((i) => this.mapTransactionToTx(i));
684
+ const result = {
685
+ total: txs.length,
686
+ txs: txs,
687
+ };
688
+ return result;
689
+ });
690
+ }
691
+ mapTransactionToTx(rawTx) {
692
+ return {
693
+ asset: this.asset,
694
+ from: rawTx.inputs.map((i) => ({
695
+ from: i.address,
696
+ amount: baseAmount(i.value, this.assetDecimals),
697
+ })),
698
+ to: rawTx.outputs
699
+ .filter((i) => i.script !== 'null-data') //filter out op_return outputs
700
+ .map((i) => ({ to: i.address, amount: baseAmount(i.value, this.assetDecimals) })),
701
+ date: new Date(rawTx.time),
702
+ type: TxType.Transfer,
703
+ hash: rawTx.txid,
704
+ };
705
+ }
706
+ /**
707
+ * Get the transaction details of a given transaction id.
708
+ *
709
+ * @param {string} txId The transaction id.
710
+ * @returns {Tx} The transaction details of the given transaction id.
711
+ */
712
+ getTransactionData(txId) {
713
+ return __awaiter(this, void 0, void 0, function* () {
714
+ try {
715
+ const rawTx = yield getTx$1({
716
+ haskoinUrl: this.baseUrl,
717
+ network: this.haskoinNetwork,
718
+ txId: txId,
719
+ });
720
+ return this.mapTransactionToTx(rawTx);
721
+ }
722
+ catch (error) {
723
+ console.error(error);
724
+ throw error;
725
+ }
726
+ });
727
+ }
728
+ /**
729
+ *
730
+ * @param utxos
731
+ * @returns utxo array
732
+ */
733
+ mapUTXOs(utxos) {
734
+ return __awaiter(this, void 0, void 0, function* () {
735
+ return yield Promise.all(utxos.map((utxo) => __awaiter(this, void 0, void 0, function* () {
736
+ return ({
737
+ hash: utxo.txid,
738
+ index: utxo.index,
739
+ value: baseAmount(utxo.value, this.assetDecimals).amount().toNumber(),
740
+ witnessUtxo: {
741
+ value: baseAmount(utxo.value, this.assetDecimals).amount().toNumber(),
742
+ script: Buffer.from(utxo.pkscript, 'hex'),
743
+ },
744
+ txHex: yield getTxHex({ haskoinUrl: this.baseUrl, txId: utxo.txid, network: this.haskoinNetwork }),
745
+ });
746
+ })));
747
+ });
748
+ }
749
+ }
750
+
751
+ var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
752
+
753
+ function unwrapExports (x) {
754
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
755
+ }
756
+
757
+ function createCommonjsModule(fn, module) {
758
+ return module = { exports: {} }, fn(module, module.exports), module.exports;
759
+ }
760
+
761
+ var promisePoolError = createCommonjsModule(function (module, exports) {
762
+ Object.defineProperty(exports, "__esModule", { value: true });
763
+ exports.PromisePoolError = void 0;
764
+ class PromisePoolError extends Error {
765
+ /**
766
+ * Create a new instance for the given `message` and `item`.
767
+ *
768
+ * @param error The original error
769
+ * @param item The item causing the error
770
+ */
771
+ constructor(error, item) {
772
+ super();
773
+ this.raw = error;
774
+ this.item = item;
775
+ this.name = this.constructor.name;
776
+ this.message = this.messageFrom(error);
777
+ Error.captureStackTrace(this, this.constructor);
778
+ }
779
+ /**
780
+ * Returns a new promise pool error instance wrapping the `error` and `item`.
781
+ *
782
+ * @param {*} error
783
+ * @param {*} item
784
+ *
785
+ * @returns {PromisePoolError}
786
+ */
787
+ static createFrom(error, item) {
788
+ return new this(error, item);
789
+ }
790
+ /**
791
+ * Returns the error message from the given `error`.
792
+ *
793
+ * @param {*} error
794
+ *
795
+ * @returns {String}
796
+ */
797
+ messageFrom(error) {
798
+ if (error instanceof Error) {
799
+ return error.message;
800
+ }
801
+ if (typeof error === 'object') {
802
+ return error.message;
803
+ }
804
+ if (typeof error === 'string' || typeof error === 'number') {
805
+ return error.toString();
806
+ }
807
+ return '';
808
+ }
809
+ }
810
+ exports.PromisePoolError = PromisePoolError;
811
+ });
812
+
813
+ unwrapExports(promisePoolError);
814
+ var promisePoolError_1 = promisePoolError.PromisePoolError;
815
+
816
+ var stopThePromisePoolError = createCommonjsModule(function (module, exports) {
817
+ Object.defineProperty(exports, "__esModule", { value: true });
818
+ exports.StopThePromisePoolError = void 0;
819
+ class StopThePromisePoolError extends Error {
820
+ }
821
+ exports.StopThePromisePoolError = StopThePromisePoolError;
822
+ });
823
+
824
+ unwrapExports(stopThePromisePoolError);
825
+ var stopThePromisePoolError_1 = stopThePromisePoolError.StopThePromisePoolError;
826
+
827
+ var validationError = createCommonjsModule(function (module, exports) {
828
+ Object.defineProperty(exports, "__esModule", { value: true });
829
+ exports.ValidationError = void 0;
830
+ class ValidationError extends Error {
831
+ /**
832
+ * Create a new instance for the given `message`.
833
+ *
834
+ * @param message The error message
835
+ */
836
+ constructor(message) {
837
+ super(message);
838
+ Error.captureStackTrace(this, this.constructor);
839
+ }
840
+ /**
841
+ * Returns a validation error with the given `message`.
842
+ */
843
+ static createFrom(message) {
844
+ return new this(message);
845
+ }
846
+ }
847
+ exports.ValidationError = ValidationError;
848
+ });
849
+
850
+ unwrapExports(validationError);
851
+ var validationError_1 = validationError.ValidationError;
852
+
853
+ var promisePoolExecutor = createCommonjsModule(function (module, exports) {
854
+ Object.defineProperty(exports, "__esModule", { value: true });
855
+ exports.PromisePoolExecutor = void 0;
856
+
857
+
858
+
859
+
860
+ class PromisePoolExecutor {
861
+ /**
862
+ * Creates a new promise pool executer instance with a default concurrency of 10.
863
+ */
864
+ constructor() {
865
+ this.meta = {
866
+ tasks: [],
867
+ items: [],
868
+ errors: [],
869
+ results: [],
870
+ stopped: false,
871
+ concurrency: 10,
872
+ shouldResultsCorrespond: false,
873
+ processedItems: [],
874
+ taskTimeout: 0
875
+ };
876
+ this.handler = () => { };
877
+ this.errorHandler = undefined;
878
+ this.onTaskStartedHandlers = [];
879
+ this.onTaskFinishedHandlers = [];
880
+ }
881
+ /**
882
+ * Set the number of tasks to process concurrently the promise pool.
883
+ *
884
+ * @param {Integer} concurrency
885
+ *
886
+ * @returns {PromisePoolExecutor}
887
+ */
888
+ useConcurrency(concurrency) {
889
+ if (!this.isValidConcurrency(concurrency)) {
890
+ throw validationError.ValidationError.createFrom(`"concurrency" must be a number, 1 or up. Received "${concurrency}" (${typeof concurrency})`);
891
+ }
892
+ this.meta.concurrency = concurrency;
893
+ return this;
894
+ }
895
+ /**
896
+ * Determine whether the given `concurrency` value is valid.
897
+ *
898
+ * @param {Number} concurrency
899
+ *
900
+ * @returns {Boolean}
901
+ */
902
+ isValidConcurrency(concurrency) {
903
+ return typeof concurrency === 'number' && concurrency >= 1;
904
+ }
905
+ /**
906
+ * Set the timeout in ms for the pool handler
907
+ *
908
+ * @param {Number} timeout
909
+ *
910
+ * @returns {PromisePool}
911
+ */
912
+ withTaskTimeout(timeout) {
913
+ this.meta.taskTimeout = timeout;
914
+ return this;
915
+ }
916
+ /**
917
+ * Returns the number of concurrently processed tasks.
918
+ *
919
+ * @returns {Number}
920
+ */
921
+ concurrency() {
922
+ return this.meta.concurrency;
923
+ }
924
+ /**
925
+ * Assign whether to keep corresponding results between source items and resulting tasks.
926
+ */
927
+ useCorrespondingResults(shouldResultsCorrespond) {
928
+ this.meta.shouldResultsCorrespond = shouldResultsCorrespond;
929
+ return this;
930
+ }
931
+ /**
932
+ * Determine whether to keep corresponding results between source items and resulting tasks.
933
+ */
934
+ shouldUseCorrespondingResults() {
935
+ return this.meta.shouldResultsCorrespond;
936
+ }
937
+ /**
938
+ * Returns the task timeout in milliseconds.
939
+ */
940
+ taskTimeout() {
941
+ return this.meta.taskTimeout;
942
+ }
943
+ /**
944
+ * Set the items to be processed in the promise pool.
945
+ *
946
+ * @param {Array} items
947
+ *
948
+ * @returns {PromisePoolExecutor}
949
+ */
950
+ for(items) {
951
+ this.meta.items = items;
952
+ return this;
953
+ }
954
+ /**
955
+ * Returns the list of items to process.
956
+ *
957
+ * @returns {T[]}
958
+ */
959
+ items() {
960
+ return this.meta.items;
961
+ }
962
+ /**
963
+ * Returns the number of items to process.
964
+ *
965
+ * @returns {Number}
966
+ */
967
+ itemsCount() {
968
+ return this.items().length;
969
+ }
970
+ /**
971
+ * Returns the list of active tasks.
972
+ *
973
+ * @returns {Array}
974
+ */
975
+ tasks() {
976
+ return this.meta.tasks;
977
+ }
978
+ /**
979
+ * Returns the number of currently active tasks.
980
+ *
981
+ * @returns {Number}
982
+ *
983
+ * @deprecated use the `activeTasksCount()` method (plural naming) instead
984
+ */
985
+ activeTaskCount() {
986
+ return this.activeTasksCount();
987
+ }
988
+ /**
989
+ * Returns the number of currently active tasks.
990
+ *
991
+ * @returns {Number}
992
+ */
993
+ activeTasksCount() {
994
+ return this.tasks().length;
995
+ }
996
+ /**
997
+ * Returns the list of processed items.
998
+ *
999
+ * @returns {T[]}
1000
+ */
1001
+ processedItems() {
1002
+ return this.meta.processedItems;
1003
+ }
1004
+ /**
1005
+ * Returns the number of processed items.
1006
+ *
1007
+ * @returns {Number}
1008
+ */
1009
+ processedCount() {
1010
+ return this.processedItems().length;
1011
+ }
1012
+ /**
1013
+ * Returns the percentage progress of items that have been processed.
1014
+ */
1015
+ processedPercentage() {
1016
+ return (this.processedCount() / this.itemsCount()) * 100;
1017
+ }
1018
+ /**
1019
+ * Returns the list of results.
1020
+ *
1021
+ * @returns {R[]}
1022
+ */
1023
+ results() {
1024
+ return this.meta.results;
1025
+ }
1026
+ /**
1027
+ * Returns the list of errors.
1028
+ *
1029
+ * @returns {Array<PromisePoolError<T>>}
1030
+ */
1031
+ errors() {
1032
+ return this.meta.errors;
1033
+ }
1034
+ /**
1035
+ * Set the handler that is applied to each item.
1036
+ *
1037
+ * @param {Function} action
1038
+ *
1039
+ * @returns {PromisePoolExecutor}
1040
+ */
1041
+ withHandler(action) {
1042
+ this.handler = action;
1043
+ return this;
1044
+ }
1045
+ /**
1046
+ * Determine whether a custom error handle is available.
1047
+ *
1048
+ * @returns {Boolean}
1049
+ */
1050
+ hasErrorHandler() {
1051
+ return !!this.errorHandler;
1052
+ }
1053
+ /**
1054
+ * Set the error handler function to execute when an error occurs.
1055
+ *
1056
+ * @param {Function} errorHandler
1057
+ *
1058
+ * @returns {PromisePoolExecutor}
1059
+ */
1060
+ handleError(handler) {
1061
+ this.errorHandler = handler;
1062
+ return this;
1063
+ }
1064
+ /**
1065
+ * Set the handler function to execute when started a task.
1066
+ *
1067
+ * @param {Function} handler
1068
+ *
1069
+ * @returns {this}
1070
+ */
1071
+ onTaskStarted(handlers) {
1072
+ this.onTaskStartedHandlers = handlers;
1073
+ return this;
1074
+ }
1075
+ /**
1076
+ * Assign the given callback `handler` function to run when a task finished.
1077
+ *
1078
+ * @param {OnProgressCallback<T>} handlers
1079
+ *
1080
+ * @returns {this}
1081
+ */
1082
+ onTaskFinished(handlers) {
1083
+ this.onTaskFinishedHandlers = handlers;
1084
+ return this;
1085
+ }
1086
+ /**
1087
+ * Determines whether the number of active tasks is greater or equal to the concurrency limit.
1088
+ *
1089
+ * @returns {Boolean}
1090
+ */
1091
+ hasReachedConcurrencyLimit() {
1092
+ return this.activeTasksCount() >= this.concurrency();
1093
+ }
1094
+ /**
1095
+ * Stop a promise pool processing.
1096
+ */
1097
+ stop() {
1098
+ this.markAsStopped();
1099
+ throw new stopThePromisePoolError.StopThePromisePoolError();
1100
+ }
1101
+ /**
1102
+ * Mark the promise pool as stopped.
1103
+ *
1104
+ * @returns {PromisePoolExecutor}
1105
+ */
1106
+ markAsStopped() {
1107
+ this.meta.stopped = true;
1108
+ return this;
1109
+ }
1110
+ /**
1111
+ * Determine whether the pool is stopped.
1112
+ *
1113
+ * @returns {Boolean}
1114
+ */
1115
+ isStopped() {
1116
+ return this.meta.stopped;
1117
+ }
1118
+ /**
1119
+ * Start processing the promise pool.
1120
+ *
1121
+ * @returns {ReturnValue}
1122
+ */
1123
+ async start() {
1124
+ return await this
1125
+ .validateInputs()
1126
+ .prepareResultsArray()
1127
+ .process();
1128
+ }
1129
+ /**
1130
+ * Determine whether the pool should stop.
1131
+ *
1132
+ * @returns {PromisePoolExecutor}
1133
+ *
1134
+ * @throws
1135
+ */
1136
+ validateInputs() {
1137
+ if (typeof this.handler !== 'function') {
1138
+ throw validationError.ValidationError.createFrom('The first parameter for the .process(fn) method must be a function');
1139
+ }
1140
+ const timeout = this.taskTimeout();
1141
+ if (!(timeout == null || (typeof timeout === 'number' && timeout >= 0))) {
1142
+ throw validationError.ValidationError.createFrom(`"timeout" must be undefined or a number. A number must be 0 or up. Received "${String(timeout)}" (${typeof timeout})`);
1143
+ }
1144
+ if (!Array.isArray(this.items())) {
1145
+ throw validationError.ValidationError.createFrom(`"items" must be an array. Received "${typeof this.items()}"`);
1146
+ }
1147
+ if (this.errorHandler && typeof this.errorHandler !== 'function') {
1148
+ throw validationError.ValidationError.createFrom(`The error handler must be a function. Received "${typeof this.errorHandler}"`);
1149
+ }
1150
+ this.onTaskStartedHandlers.forEach(handler => {
1151
+ if (handler && typeof handler !== 'function') {
1152
+ throw validationError.ValidationError.createFrom(`The onTaskStarted handler must be a function. Received "${typeof handler}"`);
1153
+ }
1154
+ });
1155
+ this.onTaskFinishedHandlers.forEach(handler => {
1156
+ if (handler && typeof handler !== 'function') {
1157
+ throw validationError.ValidationError.createFrom(`The error handler must be a function. Received "${typeof handler}"`);
1158
+ }
1159
+ });
1160
+ return this;
1161
+ }
1162
+ /**
1163
+ * Prefill the results array with `notRun` symbol values if results should correspond.
1164
+ */
1165
+ prepareResultsArray() {
1166
+ if (this.shouldUseCorrespondingResults()) {
1167
+ this.meta.results = Array(this.items().length).fill(promisePool.PromisePool.notRun);
1168
+ }
1169
+ return this;
1170
+ }
1171
+ /**
1172
+ * Starts processing the promise pool by iterating over the items
1173
+ * and running each item through the async `callback` function.
1174
+ *
1175
+ * @param {Function} callback
1176
+ *
1177
+ * @returns {Promise}
1178
+ */
1179
+ async process() {
1180
+ for (const [index, item] of this.items().entries()) {
1181
+ if (this.isStopped()) {
1182
+ break;
1183
+ }
1184
+ await this.waitForProcessingSlot();
1185
+ this.startProcessing(item, index);
1186
+ }
1187
+ return await this.drained();
1188
+ }
1189
+ /**
1190
+ * Wait for one of the active tasks to finish processing.
1191
+ */
1192
+ async waitForProcessingSlot() {
1193
+ /**
1194
+ * We’re using a while loop here because it’s possible to decrease the pool’s
1195
+ * concurrency at runtime. We need to wait for as many tasks as needed to
1196
+ * finish processing before moving on to process the remaining tasks.
1197
+ */
1198
+ while (this.hasReachedConcurrencyLimit()) {
1199
+ await this.waitForActiveTaskToFinish();
1200
+ }
1201
+ }
1202
+ /**
1203
+ * Wait for the next, currently active task to finish processing.
1204
+ */
1205
+ async waitForActiveTaskToFinish() {
1206
+ await Promise.race(this.tasks());
1207
+ }
1208
+ /**
1209
+ * Create a processing function for the given `item`.
1210
+ *
1211
+ * @param {T} item
1212
+ * @param {number} index
1213
+ */
1214
+ startProcessing(item, index) {
1215
+ const task = this.createTaskFor(item, index)
1216
+ .then(result => {
1217
+ this.save(result, index).removeActive(task);
1218
+ })
1219
+ .catch(async (error) => {
1220
+ await this.handleErrorFor(error, item, index);
1221
+ this.removeActive(task);
1222
+ })
1223
+ .finally(() => {
1224
+ this.processedItems().push(item);
1225
+ this.runOnTaskFinishedHandlers(item);
1226
+ });
1227
+ this.tasks().push(task);
1228
+ this.runOnTaskStartedHandlers(item);
1229
+ }
1230
+ /**
1231
+ * Ensures a returned promise for the processing of the given `item`.
1232
+ *
1233
+ * @param {T} item
1234
+ * @param {number} index
1235
+ *
1236
+ * @returns {*}
1237
+ */
1238
+ async createTaskFor(item, index) {
1239
+ if (this.taskTimeout() === undefined) {
1240
+ return this.handler(item, index, this);
1241
+ }
1242
+ return Promise.race([
1243
+ this.handler(item, index, this),
1244
+ this.createTaskTimeout(item)
1245
+ ]);
1246
+ }
1247
+ /**
1248
+ * Returns a promise that times-out after the configured task timeout.
1249
+ */
1250
+ async createTaskTimeout(item) {
1251
+ return new Promise((_resolve, reject) => {
1252
+ setTimeout(() => {
1253
+ reject(new promisePoolError.PromisePoolError(`Promise in pool timed out after ${this.taskTimeout()}ms`, item));
1254
+ }, this.taskTimeout());
1255
+ });
1256
+ }
1257
+ /**
1258
+ * Save the given calculation `result`, possibly at the provided `position`.
1259
+ *
1260
+ * @param {*} result
1261
+ * @param {number} position
1262
+ *
1263
+ * @returns {PromisePoolExecutor}
1264
+ */
1265
+ save(result, position) {
1266
+ this.shouldUseCorrespondingResults()
1267
+ ? this.results()[position] = result
1268
+ : this.results().push(result);
1269
+ return this;
1270
+ }
1271
+ /**
1272
+ * Remove the given `task` from the list of active tasks.
1273
+ *
1274
+ * @param {Promise} task
1275
+ */
1276
+ removeActive(task) {
1277
+ this.tasks().splice(this.tasks().indexOf(task), 1);
1278
+ return this;
1279
+ }
1280
+ /**
1281
+ * Create and save an error for the the given `item`.
1282
+ *
1283
+ * @param {Error} error
1284
+ * @param {T} item
1285
+ * @param {number} index
1286
+ */
1287
+ async handleErrorFor(error, item, index) {
1288
+ if (this.shouldUseCorrespondingResults()) {
1289
+ this.results()[index] = promisePool.PromisePool.failed;
1290
+ }
1291
+ if (this.isStoppingThePoolError(error)) {
1292
+ return;
1293
+ }
1294
+ if (this.isValidationError(error)) {
1295
+ this.markAsStopped();
1296
+ throw error;
1297
+ }
1298
+ this.hasErrorHandler()
1299
+ ? await this.runErrorHandlerFor(error, item)
1300
+ : this.saveErrorFor(error, item);
1301
+ }
1302
+ /**
1303
+ * Determine whether the given `error` is a `StopThePromisePoolError` instance.
1304
+ *
1305
+ * @param {Error} error
1306
+ *
1307
+ * @returns {Boolean}
1308
+ */
1309
+ isStoppingThePoolError(error) {
1310
+ return error instanceof stopThePromisePoolError.StopThePromisePoolError;
1311
+ }
1312
+ /**
1313
+ * Determine whether the given `error` is a `ValidationError` instance.
1314
+ *
1315
+ * @param {Error} error
1316
+ *
1317
+ * @returns {Boolean}
1318
+ */
1319
+ isValidationError(error) {
1320
+ return error instanceof validationError.ValidationError;
1321
+ }
1322
+ /**
1323
+ * Run the user’s error handler, if available.
1324
+ *
1325
+ * @param {Error} processingError
1326
+ * @param {T} item
1327
+ */
1328
+ async runErrorHandlerFor(processingError, item) {
1329
+ var _a;
1330
+ try {
1331
+ await ((_a = this.errorHandler) === null || _a === void 0 ? void 0 : _a.call(this, processingError, item, this));
1332
+ }
1333
+ catch (error) {
1334
+ this.rethrowIfNotStoppingThePool(error);
1335
+ }
1336
+ }
1337
+ /**
1338
+ * Run the onTaskStarted handlers.
1339
+ */
1340
+ runOnTaskStartedHandlers(item) {
1341
+ this.onTaskStartedHandlers.forEach(handler => {
1342
+ handler(item, this);
1343
+ });
1344
+ }
1345
+ /**
1346
+ * Run the onTaskFinished handlers.
1347
+ */
1348
+ runOnTaskFinishedHandlers(item) {
1349
+ this.onTaskFinishedHandlers.forEach(handler => {
1350
+ handler(item, this);
1351
+ });
1352
+ }
1353
+ /**
1354
+ * Rethrow the given `error` if it’s not an instance of `StopThePromisePoolError`.
1355
+ *
1356
+ * @param {Error} error
1357
+ */
1358
+ rethrowIfNotStoppingThePool(error) {
1359
+ if (this.isStoppingThePoolError(error)) {
1360
+ return;
1361
+ }
1362
+ throw error;
1363
+ }
1364
+ /**
1365
+ * Create and save an error for the the given `item`.
1366
+ *
1367
+ * @param {T} item
1368
+ */
1369
+ saveErrorFor(error, item) {
1370
+ this.errors().push(promisePoolError.PromisePoolError.createFrom(error, item));
1371
+ }
1372
+ /**
1373
+ * Wait for all active tasks to finish. Once all the tasks finished
1374
+ * processing, returns an object containing the results and errors.
1375
+ *
1376
+ * @returns {Object}
1377
+ */
1378
+ async drained() {
1379
+ await this.drainActiveTasks();
1380
+ return {
1381
+ errors: this.errors(),
1382
+ results: this.results()
1383
+ };
1384
+ }
1385
+ /**
1386
+ * Wait for all of the active tasks to finish processing.
1387
+ */
1388
+ async drainActiveTasks() {
1389
+ await Promise.all(this.tasks());
1390
+ }
1391
+ }
1392
+ exports.PromisePoolExecutor = PromisePoolExecutor;
1393
+ });
1394
+
1395
+ unwrapExports(promisePoolExecutor);
1396
+ var promisePoolExecutor_1 = promisePoolExecutor.PromisePoolExecutor;
1397
+
1398
+ var promisePool = createCommonjsModule(function (module, exports) {
1399
+ Object.defineProperty(exports, "__esModule", { value: true });
1400
+ exports.PromisePool = void 0;
1401
+
1402
+ class PromisePool {
1403
+ /**
1404
+ * Instantiates a new promise pool with a default `concurrency: 10` and `items: []`.
1405
+ *
1406
+ * @param {Object} options
1407
+ */
1408
+ constructor(items) {
1409
+ this.timeout = undefined;
1410
+ this.concurrency = 10;
1411
+ this.shouldResultsCorrespond = false;
1412
+ this.items = items !== null && items !== void 0 ? items : [];
1413
+ this.errorHandler = undefined;
1414
+ this.onTaskStartedHandlers = [];
1415
+ this.onTaskFinishedHandlers = [];
1416
+ }
1417
+ /**
1418
+ * Set the number of tasks to process concurrently in the promise pool.
1419
+ *
1420
+ * @param {Integer} concurrency
1421
+ *
1422
+ * @returns {PromisePool}
1423
+ */
1424
+ withConcurrency(concurrency) {
1425
+ this.concurrency = concurrency;
1426
+ return this;
1427
+ }
1428
+ /**
1429
+ * Set the number of tasks to process concurrently in the promise pool.
1430
+ *
1431
+ * @param {Number} concurrency
1432
+ *
1433
+ * @returns {PromisePool}
1434
+ */
1435
+ static withConcurrency(concurrency) {
1436
+ return new this().withConcurrency(concurrency);
1437
+ }
1438
+ /**
1439
+ * Set the timeout in milliseconds for the pool handler.
1440
+ *
1441
+ * @param {Number} timeout
1442
+ *
1443
+ * @returns {PromisePool}
1444
+ */
1445
+ withTaskTimeout(timeout) {
1446
+ this.timeout = timeout;
1447
+ return this;
1448
+ }
1449
+ /**
1450
+ * Set the timeout in milliseconds for the pool handler.
1451
+ *
1452
+ * @param {Number} timeout
1453
+ *
1454
+ * @returns {PromisePool}
1455
+ */
1456
+ static withTaskTimeout(timeout) {
1457
+ return new this().withTaskTimeout(timeout);
1458
+ }
1459
+ /**
1460
+ * Set the items to be processed in the promise pool.
1461
+ *
1462
+ * @param {T[]} items
1463
+ *
1464
+ * @returns {PromisePool}
1465
+ */
1466
+ for(items) {
1467
+ return typeof this.timeout === 'number'
1468
+ ? new PromisePool(items).withConcurrency(this.concurrency).withTaskTimeout(this.timeout)
1469
+ : new PromisePool(items).withConcurrency(this.concurrency);
1470
+ }
1471
+ /**
1472
+ * Set the items to be processed in the promise pool.
1473
+ *
1474
+ * @param {T[]} items
1475
+ *
1476
+ * @returns {PromisePool}
1477
+ */
1478
+ static for(items) {
1479
+ return new this().for(items);
1480
+ }
1481
+ /**
1482
+ * Set the error handler function to execute when an error occurs.
1483
+ *
1484
+ * @param {ErrorHandler<T>} handler
1485
+ *
1486
+ * @returns {PromisePool}
1487
+ */
1488
+ handleError(handler) {
1489
+ this.errorHandler = handler;
1490
+ return this;
1491
+ }
1492
+ /**
1493
+ * Assign the given callback `handler` function to run when a task starts.
1494
+ *
1495
+ * @param {OnProgressCallback<T>} handler
1496
+ *
1497
+ * @returns {PromisePool}
1498
+ */
1499
+ onTaskStarted(handler) {
1500
+ this.onTaskStartedHandlers.push(handler);
1501
+ return this;
1502
+ }
1503
+ /**
1504
+ * Assign the given callback `handler` function to run when a task finished.
1505
+ *
1506
+ * @param {OnProgressCallback<T>} handler
1507
+ *
1508
+ * @returns {PromisePool}
1509
+ */
1510
+ onTaskFinished(handler) {
1511
+ this.onTaskFinishedHandlers.push(handler);
1512
+ return this;
1513
+ }
1514
+ /**
1515
+ * Assign whether to keep corresponding results between source items and resulting tasks.
1516
+ */
1517
+ useCorrespondingResults() {
1518
+ this.shouldResultsCorrespond = true;
1519
+ return this;
1520
+ }
1521
+ /**
1522
+ * Starts processing the promise pool by iterating over the items
1523
+ * and running each item through the async `callback` function.
1524
+ *
1525
+ * @param {ProcessHandler} The async processing function receiving each item from the `items` array.
1526
+ *
1527
+ * @returns Promise<{ results, errors }>
1528
+ */
1529
+ async process(callback) {
1530
+ return new promisePoolExecutor.PromisePoolExecutor()
1531
+ .useConcurrency(this.concurrency)
1532
+ .useCorrespondingResults(this.shouldResultsCorrespond)
1533
+ .withTaskTimeout(this.timeout)
1534
+ .withHandler(callback)
1535
+ .handleError(this.errorHandler)
1536
+ .onTaskStarted(this.onTaskStartedHandlers)
1537
+ .onTaskFinished(this.onTaskFinishedHandlers)
1538
+ .for(this.items)
1539
+ .start();
1540
+ }
1541
+ }
1542
+ exports.PromisePool = PromisePool;
1543
+ PromisePool.notRun = Symbol('notRun');
1544
+ PromisePool.failed = Symbol('failed');
1545
+ });
1546
+
1547
+ unwrapExports(promisePool);
1548
+ var promisePool_1 = promisePool.PromisePool;
1549
+
1550
+ var contracts = createCommonjsModule(function (module, exports) {
1551
+ Object.defineProperty(exports, "__esModule", { value: true });
1552
+ });
1553
+
1554
+ unwrapExports(contracts);
1555
+
1556
+ var returnValue = createCommonjsModule(function (module, exports) {
1557
+ Object.defineProperty(exports, "__esModule", { value: true });
1558
+ });
1559
+
1560
+ unwrapExports(returnValue);
1561
+
1562
+ var dist = createCommonjsModule(function (module, exports) {
1563
+ var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) {
1564
+ if (k2 === undefined) k2 = k;
1565
+ var desc = Object.getOwnPropertyDescriptor(m, k);
1566
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
1567
+ desc = { enumerable: true, get: function() { return m[k]; } };
1568
+ }
1569
+ Object.defineProperty(o, k2, desc);
1570
+ }) : (function(o, m, k, k2) {
1571
+ if (k2 === undefined) k2 = k;
1572
+ o[k2] = m[k];
1573
+ }));
1574
+ var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) {
1575
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
1576
+ };
1577
+ Object.defineProperty(exports, "__esModule", { value: true });
1578
+
1579
+ exports.default = promisePool.PromisePool;
1580
+ __exportStar(contracts, exports);
1581
+ __exportStar(promisePool, exports);
1582
+ __exportStar(promisePoolError, exports);
1583
+ __exportStar(returnValue, exports);
1584
+ __exportStar(stopThePromisePoolError, exports);
1585
+ __exportStar(validationError, exports);
1586
+ });
1587
+
1588
+ var PromisePool = unwrapExports(dist);
1589
+
1590
+ /**
1591
+ * Get transaction by hash.
1592
+ *
1593
+ *
1594
+ * @param {string} baseUrl The sochain node url.
1595
+ * @param {string} network network id
1596
+ * @param {string} hash The transaction hash.
1597
+ * @returns {Transactions}
1598
+ */
1599
+ const getTx$2 = ({ apiKey, baseUrl, network, hash }) => __awaiter(void 0, void 0, void 0, function* () {
1600
+ const params = { includeHex: 'true' };
1601
+ if (apiKey)
1602
+ params['token'] = apiKey;
1603
+ const url = `${baseUrl}/${network}/txs/${hash}`;
1604
+ const response = yield axios.get(url, { params });
1605
+ const tx = response.data;
1606
+ return tx;
1607
+ });
1608
+ /**
1609
+ * Get transactions
1610
+ *
1611
+ *
1612
+ * @param {string} baseUrl The sochain node url.
1613
+ * @param {string} network network id
1614
+ * @param {string} hash The transaction hash.
1615
+ * @returns {Transactions}
1616
+ */
1617
+ const getTxs$2 = ({ apiKey, address, baseUrl, network, beforeBlock, limit, unspentOnly, }) => __awaiter(void 0, void 0, void 0, function* () {
1618
+ const params = { limit: `${limit}`, unspentOnly: `${unspentOnly}` };
1619
+ const url = `${baseUrl}/${network}/addrs/${address}`;
1620
+ if (apiKey)
1621
+ params['token'] = apiKey;
1622
+ if (beforeBlock)
1623
+ params['before'] = `${beforeBlock}`;
1624
+ const response = yield axios.get(url, { params });
1625
+ const txs = response.data;
1626
+ return txs;
1627
+ });
1628
+ /**
1629
+ * Get address balance.
1630
+ *
1631
+ *
1632
+ * @param {string} baseUrl The sochain node url.
1633
+ * @param {string} network Network
1634
+ * @param {string} address Address
1635
+ * @param {boolean} confirmedOnly Flag whether to get balances of confirmed txs only or for all
1636
+ * @returns {number}
1637
+ */
1638
+ const getBalance$2 = ({ apiKey, baseUrl, network, address, confirmedOnly, assetDecimals, }) => __awaiter(void 0, void 0, void 0, function* () {
1639
+ const params = {};
1640
+ const url = `${baseUrl}/${network}/addrs/${address}/balance`;
1641
+ if (apiKey)
1642
+ params['token'] = apiKey;
1643
+ const response = yield axios.get(url, { params });
1644
+ const balanceResponse = response.data;
1645
+ const confirmedAmount = baseAmount(balanceResponse.balance, assetDecimals);
1646
+ const finalBalance = baseAmount(balanceResponse.final_balance, assetDecimals);
1647
+ return confirmedOnly ? confirmedAmount : finalBalance;
1648
+ });
1649
+ const broadcastTx$2 = ({ apiKey, baseUrl, network, txHex, }) => __awaiter(void 0, void 0, void 0, function* () {
1650
+ const params = {};
1651
+ const url = `${baseUrl}/${network}/txs/push`;
1652
+ if (apiKey)
1653
+ params['token'] = apiKey;
1654
+ const response = yield axios.post(url, { tx: txHex }, { params });
1655
+ const broadcastResponse = response.data;
1656
+ return broadcastResponse.tx.hash;
1657
+ });
1658
+
1659
+ class BlockcypherProvider {
1660
+ constructor(baseUrl = 'https://api.blockcypher.com/v1/', chain, asset, assetDecimals, blockcypherNetwork, apiKey) {
1661
+ this.baseUrl = baseUrl;
1662
+ this._apiKey = apiKey;
1663
+ this.chain = chain;
1664
+ this.asset = asset;
1665
+ this.assetDecimals = assetDecimals;
1666
+ this.blockcypherNetwork = blockcypherNetwork;
1667
+ this.asset;
1668
+ this.chain;
1669
+ }
1670
+ get apiKey() {
1671
+ return this._apiKey;
1672
+ }
1673
+ set apiKey(value) {
1674
+ this._apiKey = value;
1675
+ }
1676
+ broadcastTx(txHex) {
1677
+ return __awaiter(this, void 0, void 0, function* () {
1678
+ return yield broadcastTx$2({
1679
+ apiKey: this._apiKey,
1680
+ baseUrl: this.baseUrl,
1681
+ network: this.blockcypherNetwork,
1682
+ txHex,
1683
+ });
1684
+ });
1685
+ }
1686
+ getConfirmedUnspentTxs(address) {
1687
+ return __awaiter(this, void 0, void 0, function* () {
1688
+ const allUnspent = yield this.getRawTransactions({ address, offset: 0, limit: 2000 }, true);
1689
+ return this.mapUTXOs(address, allUnspent.filter((i) => i.confirmed));
1690
+ });
1691
+ }
1692
+ getUnspentTxs(address) {
1693
+ return __awaiter(this, void 0, void 0, function* () {
1694
+ const allUnspent = yield this.getRawTransactions({ address, offset: 0, limit: 2000 }, true);
1695
+ return this.mapUTXOs(address, allUnspent);
1696
+ });
1697
+ }
1698
+ getBalance(address, assets /*ignored*/, confirmedOnly) {
1699
+ return __awaiter(this, void 0, void 0, function* () {
1700
+ const amount = yield getBalance$2({
1701
+ apiKey: this._apiKey,
1702
+ baseUrl: this.baseUrl,
1703
+ network: this.blockcypherNetwork,
1704
+ address,
1705
+ confirmedOnly: !!confirmedOnly,
1706
+ assetDecimals: this.assetDecimals,
1707
+ });
1708
+ return [{ amount, asset: this.asset }];
1709
+ });
1710
+ }
1711
+ /**
1712
+ * Get transaction history of a given address with pagination options.
1713
+ * By default it will return the transaction history of the current wallet.
1714
+ *
1715
+ * @param {TxHistoryParams} params The options to get transaction history. (optional)
1716
+ * @returns {TxsPage} The transaction history.
1717
+ */
1718
+ getTransactions(params, unspentOnly = false) {
1719
+ return __awaiter(this, void 0, void 0, function* () {
1720
+ const rawTxs = yield this.getRawTransactions(params, unspentOnly);
1721
+ const txs = rawTxs.map((i) => this.mapTransactionToTx(i));
1722
+ const result = {
1723
+ total: txs.length,
1724
+ txs,
1725
+ };
1726
+ return result;
1727
+ });
1728
+ }
1729
+ /**
1730
+ * Get the transaction details of a given transaction id.
1731
+ *
1732
+ * @param {string} txId The transaction id.
1733
+ * @returns {Tx} The transaction details of the given transaction id.
1734
+ */
1735
+ getTransactionData(txId) {
1736
+ return __awaiter(this, void 0, void 0, function* () {
1737
+ try {
1738
+ const rawTx = yield getTx$2({
1739
+ apiKey: this._apiKey,
1740
+ baseUrl: this.baseUrl,
1741
+ network: this.blockcypherNetwork,
1742
+ hash: txId,
1743
+ });
1744
+ return this.mapTransactionToTx(rawTx);
1745
+ }
1746
+ catch (error) {
1747
+ console.error(error);
1748
+ throw error;
1749
+ }
1750
+ });
1751
+ }
1752
+ mapTransactionToTx(rawTx) {
1753
+ return {
1754
+ asset: this.asset,
1755
+ from: rawTx.inputs.map((i) => ({
1756
+ from: i.addresses[0],
1757
+ amount: baseAmount(i.output_value, this.assetDecimals),
1758
+ })),
1759
+ to: rawTx.outputs
1760
+ .filter((i) => i.script_type !== 'null-data') //filter out op_return outputs
1761
+ .map((i) => ({ to: i.addresses[0], amount: baseAmount(i.value, this.assetDecimals) })),
1762
+ date: new Date(rawTx.confirmed),
1763
+ type: TxType.Transfer,
1764
+ hash: rawTx.hash,
1765
+ };
1766
+ }
1767
+ mapUTXOs(address, utxos) {
1768
+ const utxosOut = [];
1769
+ for (let index = 0; index < utxos.length; index++) {
1770
+ const utxo = utxos[index];
1771
+ for (let index2 = 0; index2 < utxo.outputs.length; index2++) {
1772
+ const output = utxo.outputs[index2];
1773
+ if (output.addresses && output.addresses[0] === address) {
1774
+ const utxoOut = {
1775
+ hash: utxo.hash,
1776
+ index: index2,
1777
+ value: baseAmount(output.value, this.assetDecimals).amount().toNumber(),
1778
+ witnessUtxo: {
1779
+ value: baseAmount(output.value, this.assetDecimals).amount().toNumber(),
1780
+ script: Buffer.from(output.script, 'hex'),
1781
+ },
1782
+ txHex: utxo.hex,
1783
+ };
1784
+ utxosOut.push(utxoOut);
1785
+ }
1786
+ }
1787
+ }
1788
+ return utxosOut;
1789
+ }
1790
+ /**
1791
+ * helper function tto limit adding to an array
1792
+ *
1793
+ * @param arr array to be added to
1794
+ * @param toAdd elements to add
1795
+ * @param limit do not add more than this limit
1796
+ */
1797
+ addArrayUpToLimit(arr, toAdd, limit) {
1798
+ for (let index = 0; index < toAdd.length; index++) {
1799
+ const element = toAdd[index];
1800
+ if (arr.length < limit) {
1801
+ arr.push(element);
1802
+ }
1803
+ }
1804
+ }
1805
+ delay(ms) {
1806
+ return new Promise((resolve) => setTimeout(resolve, ms));
1807
+ }
1808
+ /**
1809
+ * Get transaction history of a given address with pagination options.
1810
+ * By default it will return the transaction history of the current wallet.
1811
+ *
1812
+ * @param {TxHistoryParams} params The options to get transaction history. (optional)
1813
+ * @returns {TxsPage} The transaction history.
1814
+ */
1815
+ getRawTransactions(params, unspentOnly = false) {
1816
+ var _a;
1817
+ return __awaiter(this, void 0, void 0, function* () {
1818
+ const offset = (_a = params === null || params === void 0 ? void 0 : params.offset) !== null && _a !== void 0 ? _a : 0;
1819
+ const limit = (params === null || params === void 0 ? void 0 : params.limit) || 10;
1820
+ if (offset + limit > 2000)
1821
+ throw Error('cannot fetch more than last 2000 txs');
1822
+ if (offset < 0 || limit < 0)
1823
+ throw Error('ofset and limit must be equal or greater than 0');
1824
+ const txHashesToFetch = [];
1825
+ try {
1826
+ const response = yield getTxs$2({
1827
+ apiKey: this._apiKey,
1828
+ baseUrl: this.baseUrl,
1829
+ network: this.blockcypherNetwork,
1830
+ address: `${params === null || params === void 0 ? void 0 : params.address}`,
1831
+ limit: 2000,
1832
+ unspentOnly,
1833
+ });
1834
+ //remove duplicates
1835
+ const txs = response.txrefs.map((i) => i.tx_hash);
1836
+ const uniqTxs = [...new Set(txs)];
1837
+ const start = offset >= uniqTxs.length ? uniqTxs.length : offset;
1838
+ const end = offset + limit >= uniqTxs.length ? uniqTxs.length : offset + limit;
1839
+ const txsToFetch = uniqTxs.slice(start, end);
1840
+ // console.log(JSON.stringify(txsToFetch, null, 2))
1841
+ this.addArrayUpToLimit(txHashesToFetch, txsToFetch, limit);
1842
+ }
1843
+ catch (error) {
1844
+ console.error(error);
1845
+ //an errors means no more results
1846
+ }
1847
+ //note: blockcypher has rate of 3 req/sec --> https://www.blockcypher.com/dev/bitcoin/#rate-limits-and-tokens
1848
+ const batchResult = yield PromisePool.for(txHashesToFetch)
1849
+ .withConcurrency(3)
1850
+ .useCorrespondingResults()
1851
+ .process((hash) => __awaiter(this, void 0, void 0, function* () {
1852
+ yield this.delay(1000);
1853
+ const rawTx = yield getTx$2({
1854
+ apiKey: this._apiKey,
1855
+ baseUrl: this.baseUrl,
1856
+ network: this.blockcypherNetwork,
1857
+ hash,
1858
+ });
1859
+ return rawTx;
1860
+ }));
1861
+ return batchResult.results;
1862
+ });
1863
+ }
1864
+ }
1865
+
1866
+ var BlockcypherNetwork;
1867
+ (function (BlockcypherNetwork) {
1868
+ BlockcypherNetwork["BTC"] = "btc/main";
1869
+ BlockcypherNetwork["BTCTEST"] = "btc/test3";
1870
+ BlockcypherNetwork["LTC"] = "ltc/main";
1871
+ BlockcypherNetwork["DOGE"] = "doge/main";
1872
+ })(BlockcypherNetwork || (BlockcypherNetwork = {}));
1873
+
1874
+ export { BlockcypherNetwork, BlockcypherProvider, HaskoinNetwork, HaskoinProvider, SochainNetwork, SochainProvider, broadcastTx$1 as broadcastTx, getAccount, getAddress, getBalance$1 as getBalance, getConfirmedTxStatus, getConfirmedUnspentTxs, getIsTxConfirmed, getTx$1 as getTx, getTxs$1 as getTxs, getUnspentTxs$1 as getUnspentTxs };