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