@xchainjs/xchain-doge 0.5.11 → 0.5.13
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.esm.js +1546 -51
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +1545 -50
- package/lib/index.js.map +1 -1
- package/package.json +5 -5
package/lib/index.esm.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { ExplorerProvider, Network, standardFeeRates, calcFees, UTXOClient, checkFeeBounds } from '@xchainjs/xchain-client';
|
|
1
|
+
import { TxType, ExplorerProvider, Network, standardFeeRates, calcFees, UTXOClient, checkFeeBounds } from '@xchainjs/xchain-client';
|
|
2
2
|
import crypto$1$1 from 'crypto';
|
|
3
3
|
import buffer from 'buffer';
|
|
4
4
|
import axios from 'axios';
|
|
5
5
|
import readableStream from 'readable-stream';
|
|
6
6
|
import stream from 'stream';
|
|
7
7
|
import string_decoder from 'string_decoder';
|
|
8
|
-
import { SochainProvider, SochainNetwork, BlockcypherProvider, BlockcypherNetwork } from '@xchainjs/xchain-utxo-providers';
|
|
9
8
|
|
|
10
9
|
/*! *****************************************************************************
|
|
11
10
|
Copyright (c) Microsoft Corporation.
|
|
@@ -77961,55 +77960,6 @@ var accumulative = function accumulative (utxos, outputs, feeRate) {
|
|
|
77961
77960
|
return { fee: feeRate * bytesAccum }
|
|
77962
77961
|
};
|
|
77963
77962
|
|
|
77964
|
-
/**
|
|
77965
|
-
* Minimum transaction fee
|
|
77966
|
-
* 100000 satoshi/kB (similar to current `minrelaytxfee`)
|
|
77967
|
-
* @see https://github.com/dogecoin/dogecoin/blob/master/src/validation.h#L58
|
|
77968
|
-
*/
|
|
77969
|
-
const MIN_TX_FEE = 100000;
|
|
77970
|
-
const DOGE_DECIMAL = 8;
|
|
77971
|
-
const LOWER_FEE_BOUND = 40000;
|
|
77972
|
-
const UPPER_FEE_BOUND = 20000000;
|
|
77973
|
-
/**
|
|
77974
|
-
* Chain identifier for Dogecoin
|
|
77975
|
-
*
|
|
77976
|
-
*/
|
|
77977
|
-
const DOGEChain = 'DOGE';
|
|
77978
|
-
/**
|
|
77979
|
-
* Base "chain" asset on dogecoin
|
|
77980
|
-
*
|
|
77981
|
-
* Based on definition in Thorchain `common`
|
|
77982
|
-
* @see https://gitlab.com/thorchain/thornode/-/blob/master/common/asset.go#L12-24
|
|
77983
|
-
*/
|
|
77984
|
-
const AssetDOGE = { chain: DOGEChain, symbol: 'DOGE', ticker: 'DOGE', synth: false };
|
|
77985
|
-
// https://blockchair.com/
|
|
77986
|
-
const DOGE_MAINNET_EXPLORER = new ExplorerProvider('https://blockchair.com/dogecoin', 'https://blockchair.com/dogecoin/address/%%ADDRESS%%', 'https://blockchair.com/dogecoin/transaction/%%TX_ID%%');
|
|
77987
|
-
const DOGE_TESTNET_EXPLORER = new ExplorerProvider('https://blockexplorer.one/dogecoin/testnet', 'https://blockexplorer.one/dogecoin/testnet/address/%%ADDRESS%%', 'https://blockexplorer.one/dogecoin/testnet/tx/%%TX_ID%%');
|
|
77988
|
-
const blockstreamExplorerProviders = {
|
|
77989
|
-
[Network.Testnet]: DOGE_TESTNET_EXPLORER,
|
|
77990
|
-
[Network.Stagenet]: DOGE_MAINNET_EXPLORER,
|
|
77991
|
-
[Network.Mainnet]: DOGE_MAINNET_EXPLORER,
|
|
77992
|
-
};
|
|
77993
|
-
//======================
|
|
77994
|
-
// sochain
|
|
77995
|
-
//======================
|
|
77996
|
-
const testnetSochainProvider = new SochainProvider('https://sochain.com/api/v3', 'PLACEHOLDER_APIKEY', DOGEChain, AssetDOGE, 8, SochainNetwork.DOGETEST);
|
|
77997
|
-
const mainnetSochainProvider = new SochainProvider('https://sochain.com/api/v3', 'PLACEHOLDER_APIKEY', DOGEChain, AssetDOGE, 8, SochainNetwork.DOGE);
|
|
77998
|
-
const sochainDataProviders = {
|
|
77999
|
-
[Network.Testnet]: testnetSochainProvider,
|
|
78000
|
-
[Network.Stagenet]: mainnetSochainProvider,
|
|
78001
|
-
[Network.Mainnet]: mainnetSochainProvider,
|
|
78002
|
-
};
|
|
78003
|
-
//======================
|
|
78004
|
-
// Blockcypher
|
|
78005
|
-
//======================
|
|
78006
|
-
const mainnetBlockcypherProvider = new BlockcypherProvider('https://api.blockcypher.com/v1', DOGEChain, AssetDOGE, 8, BlockcypherNetwork.DOGE);
|
|
78007
|
-
const blockcypherDataProviders = {
|
|
78008
|
-
[Network.Testnet]: undefined,
|
|
78009
|
-
[Network.Stagenet]: mainnetBlockcypherProvider,
|
|
78010
|
-
[Network.Mainnet]: mainnetBlockcypherProvider,
|
|
78011
|
-
};
|
|
78012
|
-
|
|
78013
77963
|
var bignumber$1 = createCommonjsModule$1(function (module) {
|
|
78014
77964
|
(function (globalObject) {
|
|
78015
77965
|
|
|
@@ -80977,6 +80927,31 @@ const isBigNumberValue = (v) => typeof v === 'string' || typeof v === 'number' |
|
|
|
80977
80927
|
* ```
|
|
80978
80928
|
* */
|
|
80979
80929
|
const ASSET_DECIMAL = 8;
|
|
80930
|
+
/**
|
|
80931
|
+
* Factory to create values of assets (e.g. RUNE)
|
|
80932
|
+
*
|
|
80933
|
+
* @param {string|number|BigNumber|undefined} value - The asset amount, If the value is undefined, AssetAmount with value `0` will be returned.
|
|
80934
|
+
* @param {number} decimal The decimal places. (optional)
|
|
80935
|
+
* @returns {AssetAmount} The asset amount from the given value and decimal.
|
|
80936
|
+
*
|
|
80937
|
+
**/
|
|
80938
|
+
const assetAmount = (value, decimal = ASSET_DECIMAL) => {
|
|
80939
|
+
const amount = fixedBN(value, decimal);
|
|
80940
|
+
return {
|
|
80941
|
+
type: Denomination.Asset,
|
|
80942
|
+
amount: () => amount,
|
|
80943
|
+
plus: (v, d = decimal) => assetAmount(amount.plus(isBigNumberValue(v) ? v : v.amount()), d),
|
|
80944
|
+
minus: (v, d = decimal) => assetAmount(amount.minus(isBigNumberValue(v) ? v : v.amount()), d),
|
|
80945
|
+
times: (v, d = decimal) => assetAmount(amount.times(isBigNumberValue(v) ? v : v.amount()), d),
|
|
80946
|
+
div: (v, d = decimal) => assetAmount(amount.div(isBigNumberValue(v) ? v : v.amount()), d),
|
|
80947
|
+
lt: (v) => amount.lt(isBigNumberValue(v) ? v : v.amount()),
|
|
80948
|
+
lte: (v) => amount.lte(isBigNumberValue(v) ? v : v.amount()),
|
|
80949
|
+
gt: (v) => amount.gt(isBigNumberValue(v) ? v : v.amount()),
|
|
80950
|
+
gte: (v) => amount.gte(isBigNumberValue(v) ? v : v.amount()),
|
|
80951
|
+
eq: (v) => amount.eq(isBigNumberValue(v) ? v : v.amount()),
|
|
80952
|
+
decimal,
|
|
80953
|
+
};
|
|
80954
|
+
};
|
|
80980
80955
|
/**
|
|
80981
80956
|
* Factory to create base amounts (e.g. tor)
|
|
80982
80957
|
*
|
|
@@ -81001,6 +80976,19 @@ const baseAmount = (value, decimal = ASSET_DECIMAL) => {
|
|
|
81001
80976
|
decimal,
|
|
81002
80977
|
};
|
|
81003
80978
|
};
|
|
80979
|
+
/**
|
|
80980
|
+
* Helper to convert asset to base values (e.g. tor -> RUNE)
|
|
80981
|
+
*
|
|
80982
|
+
* @param {AssetAmount} asset
|
|
80983
|
+
* @returns {BaseAmount} The base amount from the given AssetAmount.
|
|
80984
|
+
* */
|
|
80985
|
+
const assetToBase = (asset) => {
|
|
80986
|
+
const value = asset
|
|
80987
|
+
.amount()
|
|
80988
|
+
.multipliedBy(Math.pow(10, asset.decimal))
|
|
80989
|
+
.integerValue();
|
|
80990
|
+
return baseAmount(value, asset.decimal);
|
|
80991
|
+
};
|
|
81004
80992
|
/**
|
|
81005
80993
|
* Currency symbols currently supported
|
|
81006
80994
|
*/
|
|
@@ -81013,6 +81001,1513 @@ var AssetCurrencySymbol;
|
|
|
81013
81001
|
AssetCurrencySymbol["USD"] = "$";
|
|
81014
81002
|
})(AssetCurrencySymbol || (AssetCurrencySymbol = {}));
|
|
81015
81003
|
|
|
81004
|
+
var SochainNetwork;
|
|
81005
|
+
(function (SochainNetwork) {
|
|
81006
|
+
SochainNetwork["BTC"] = "BTC";
|
|
81007
|
+
SochainNetwork["BTCTEST"] = "BTCTEST";
|
|
81008
|
+
SochainNetwork["LTC"] = "LTC";
|
|
81009
|
+
SochainNetwork["LTCTEST"] = "LTCTEST";
|
|
81010
|
+
SochainNetwork["DOGE"] = "DOGE";
|
|
81011
|
+
SochainNetwork["DOGETEST"] = "DOGETEST";
|
|
81012
|
+
})(SochainNetwork || (SochainNetwork = {}));
|
|
81013
|
+
|
|
81014
|
+
/*! *****************************************************************************
|
|
81015
|
+
Copyright (c) Microsoft Corporation.
|
|
81016
|
+
|
|
81017
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
81018
|
+
purpose with or without fee is hereby granted.
|
|
81019
|
+
|
|
81020
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
81021
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
81022
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
81023
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
81024
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
81025
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
81026
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
81027
|
+
***************************************************************************** */
|
|
81028
|
+
|
|
81029
|
+
function __awaiter$1(thisArg, _arguments, P, generator) {
|
|
81030
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
81031
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
81032
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
81033
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
81034
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
81035
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
81036
|
+
});
|
|
81037
|
+
}
|
|
81038
|
+
|
|
81039
|
+
/**
|
|
81040
|
+
* Get transaction by hash.
|
|
81041
|
+
*
|
|
81042
|
+
* @see https://sochain.com/api#get-tx
|
|
81043
|
+
*
|
|
81044
|
+
* @param {string} sochainUrl The sochain node url.
|
|
81045
|
+
* @param {string} network network id
|
|
81046
|
+
* @param {string} hash The transaction hash.
|
|
81047
|
+
* @returns {Transactions}
|
|
81048
|
+
*/
|
|
81049
|
+
const getTx = ({ apiKey, sochainUrl, network, hash }) => __awaiter$1(void 0, void 0, void 0, function* () {
|
|
81050
|
+
const url = `${sochainUrl}/transaction/${network}/${hash}`;
|
|
81051
|
+
const response = yield axios.get(url, { headers: { 'API-KEY': apiKey } });
|
|
81052
|
+
const tx = response.data;
|
|
81053
|
+
return tx.data;
|
|
81054
|
+
});
|
|
81055
|
+
/**
|
|
81056
|
+
* Get transactions
|
|
81057
|
+
*
|
|
81058
|
+
* @see https://sochain.com/api#get-tx
|
|
81059
|
+
*
|
|
81060
|
+
* @param {string} sochainUrl The sochain node url.
|
|
81061
|
+
* @param {string} network network id
|
|
81062
|
+
* @param {string} hash The transaction hash.
|
|
81063
|
+
* @returns {Transactions}
|
|
81064
|
+
*/
|
|
81065
|
+
const getTxs = ({ apiKey, address, sochainUrl, network, page, }) => __awaiter$1(void 0, void 0, void 0, function* () {
|
|
81066
|
+
const url = `${sochainUrl}/transactions/${network}/${address}/${page}`; //TODO support paging
|
|
81067
|
+
const response = yield axios.get(url, { headers: { 'API-KEY': apiKey } });
|
|
81068
|
+
const txs = response.data;
|
|
81069
|
+
return txs.data;
|
|
81070
|
+
});
|
|
81071
|
+
/**
|
|
81072
|
+
* Get address balance.
|
|
81073
|
+
*
|
|
81074
|
+
* @see https://sochain.com/api#get-balance
|
|
81075
|
+
*
|
|
81076
|
+
* @param {string} sochainUrl The sochain node url.
|
|
81077
|
+
* @param {string} network Network
|
|
81078
|
+
* @param {string} address Address
|
|
81079
|
+
* @param {boolean} confirmedOnly Flag whether to get balances of confirmed txs only or for all
|
|
81080
|
+
* @returns {number}
|
|
81081
|
+
*/
|
|
81082
|
+
const getBalance = ({ apiKey, sochainUrl, network, address, confirmedOnly, assetDecimals, }) => __awaiter$1(void 0, void 0, void 0, function* () {
|
|
81083
|
+
const url = `${sochainUrl}/balance/${network}/${address}`;
|
|
81084
|
+
const response = yield axios.get(url, { headers: { 'API-KEY': apiKey } });
|
|
81085
|
+
const balanceResponse = response.data;
|
|
81086
|
+
const confirmed = assetAmount(balanceResponse.data.confirmed, assetDecimals);
|
|
81087
|
+
const unconfirmed = assetAmount(balanceResponse.data.unconfirmed, assetDecimals);
|
|
81088
|
+
const netAmt = confirmedOnly ? confirmed : confirmed.plus(unconfirmed);
|
|
81089
|
+
const result = assetToBase(netAmt);
|
|
81090
|
+
return result;
|
|
81091
|
+
});
|
|
81092
|
+
/**
|
|
81093
|
+
* Get unspent txs
|
|
81094
|
+
*
|
|
81095
|
+
* @see https://sochain.com/api#get-unspent-tx
|
|
81096
|
+
*
|
|
81097
|
+
* @param {string} sochainUrl The sochain node url.
|
|
81098
|
+
* @param {string} network
|
|
81099
|
+
* @param {string} address
|
|
81100
|
+
* @returns {AddressUTXO[]}
|
|
81101
|
+
*/
|
|
81102
|
+
const getUnspentTxs = ({ apiKey, sochainUrl, network, address, page, }) => __awaiter$1(void 0, void 0, void 0, function* () {
|
|
81103
|
+
const url = [sochainUrl, 'unspent_outputs', network, address, page].filter((v) => !!v).join('/');
|
|
81104
|
+
const resp = yield axios.get(url, { headers: { 'API-KEY': apiKey } });
|
|
81105
|
+
const response = resp.data;
|
|
81106
|
+
const txs = response.data.outputs;
|
|
81107
|
+
if (txs.length === 10) {
|
|
81108
|
+
//fetch the next batch
|
|
81109
|
+
const nextBatch = yield getUnspentTxs({
|
|
81110
|
+
apiKey,
|
|
81111
|
+
sochainUrl,
|
|
81112
|
+
network,
|
|
81113
|
+
address,
|
|
81114
|
+
page: page + 1,
|
|
81115
|
+
});
|
|
81116
|
+
return txs.concat(nextBatch);
|
|
81117
|
+
}
|
|
81118
|
+
else {
|
|
81119
|
+
return txs;
|
|
81120
|
+
}
|
|
81121
|
+
});
|
|
81122
|
+
/**
|
|
81123
|
+
* Get address balance.
|
|
81124
|
+
*
|
|
81125
|
+
* @see https://sochain.com/api#get-balance
|
|
81126
|
+
*
|
|
81127
|
+
* @param {string} sochainUrl The sochain node url.
|
|
81128
|
+
* @param {string} network Network
|
|
81129
|
+
* @param {string} address Address
|
|
81130
|
+
* @param {boolean} confirmedOnly Flag whether to get balances of confirmed txs only or for all
|
|
81131
|
+
* @returns {number}
|
|
81132
|
+
*/
|
|
81133
|
+
const broadcastTx = ({ apiKey, sochainUrl, network, txHex, }) => __awaiter$1(void 0, void 0, void 0, function* () {
|
|
81134
|
+
const url = `${sochainUrl}/broadcast_transaction/${network}`;
|
|
81135
|
+
const response = yield axios.post(url, { tx_hex: txHex }, { headers: { 'API-KEY': apiKey } });
|
|
81136
|
+
const broadcastResponse = response.data;
|
|
81137
|
+
return broadcastResponse.tx_hex;
|
|
81138
|
+
});
|
|
81139
|
+
|
|
81140
|
+
class SochainProvider {
|
|
81141
|
+
constructor(baseUrl = 'https://sochain.com/api/v3', apiKey, chain, asset, assetDecimals, sochainNetwork) {
|
|
81142
|
+
this.baseUrl = baseUrl;
|
|
81143
|
+
this._apiKey = apiKey;
|
|
81144
|
+
this.chain = chain;
|
|
81145
|
+
this.asset = asset;
|
|
81146
|
+
this.assetDecimals = assetDecimals;
|
|
81147
|
+
this.sochainNetwork = sochainNetwork;
|
|
81148
|
+
this.asset;
|
|
81149
|
+
this.chain;
|
|
81150
|
+
}
|
|
81151
|
+
get apiKey() {
|
|
81152
|
+
return this._apiKey;
|
|
81153
|
+
}
|
|
81154
|
+
set apiKey(value) {
|
|
81155
|
+
this._apiKey = value;
|
|
81156
|
+
}
|
|
81157
|
+
broadcastTx(txHex) {
|
|
81158
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
81159
|
+
return yield broadcastTx({
|
|
81160
|
+
apiKey: this._apiKey,
|
|
81161
|
+
sochainUrl: this.baseUrl,
|
|
81162
|
+
network: this.sochainNetwork,
|
|
81163
|
+
txHex,
|
|
81164
|
+
});
|
|
81165
|
+
});
|
|
81166
|
+
}
|
|
81167
|
+
getConfirmedUnspentTxs(address) {
|
|
81168
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
81169
|
+
const allUnspent = yield getUnspentTxs({
|
|
81170
|
+
apiKey: this._apiKey,
|
|
81171
|
+
sochainUrl: this.baseUrl,
|
|
81172
|
+
network: this.sochainNetwork,
|
|
81173
|
+
address,
|
|
81174
|
+
page: 1,
|
|
81175
|
+
});
|
|
81176
|
+
const confirmedUnspent = allUnspent.filter((i) => i.block); //if it has a block noumber it's been confirmed
|
|
81177
|
+
return this.mapUTXOs(confirmedUnspent);
|
|
81178
|
+
});
|
|
81179
|
+
}
|
|
81180
|
+
getUnspentTxs(address) {
|
|
81181
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
81182
|
+
const allUnspent = yield getUnspentTxs({
|
|
81183
|
+
apiKey: this._apiKey,
|
|
81184
|
+
sochainUrl: this.baseUrl,
|
|
81185
|
+
network: this.sochainNetwork,
|
|
81186
|
+
address,
|
|
81187
|
+
page: 1,
|
|
81188
|
+
});
|
|
81189
|
+
return this.mapUTXOs(allUnspent);
|
|
81190
|
+
});
|
|
81191
|
+
}
|
|
81192
|
+
getBalance(address, assets /*ignored*/, confirmedOnly) {
|
|
81193
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
81194
|
+
try {
|
|
81195
|
+
const amount = yield getBalance({
|
|
81196
|
+
apiKey: this._apiKey,
|
|
81197
|
+
sochainUrl: this.baseUrl,
|
|
81198
|
+
network: this.sochainNetwork,
|
|
81199
|
+
address,
|
|
81200
|
+
confirmedOnly: !!confirmedOnly,
|
|
81201
|
+
assetDecimals: this.assetDecimals,
|
|
81202
|
+
});
|
|
81203
|
+
return [{ amount, asset: this.asset }];
|
|
81204
|
+
}
|
|
81205
|
+
catch (error) {
|
|
81206
|
+
throw new Error(`Could not get balances for address ${address}`);
|
|
81207
|
+
}
|
|
81208
|
+
});
|
|
81209
|
+
}
|
|
81210
|
+
/**
|
|
81211
|
+
* Get transaction history of a given address with pagination options.
|
|
81212
|
+
* By default it will return the transaction history of the current wallet.
|
|
81213
|
+
*
|
|
81214
|
+
* @param {TxHistoryParams} params The options to get transaction history. (optional)
|
|
81215
|
+
* @returns {TxsPage} The transaction history.
|
|
81216
|
+
*/
|
|
81217
|
+
getTransactions(params) {
|
|
81218
|
+
var _a;
|
|
81219
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
81220
|
+
const offset = (_a = params === null || params === void 0 ? void 0 : params.offset) !== null && _a !== void 0 ? _a : 0;
|
|
81221
|
+
const limit = (params === null || params === void 0 ? void 0 : params.limit) || 10;
|
|
81222
|
+
if (offset < 0 || limit < 0)
|
|
81223
|
+
throw Error('ofset and limit must be equal or greater than 0');
|
|
81224
|
+
const firstPage = Math.floor(offset / 10) + 1;
|
|
81225
|
+
const lastPage = limit > 10 ? firstPage + Math.floor(limit / 10) : firstPage;
|
|
81226
|
+
const offsetOnFirstPage = offset % 10;
|
|
81227
|
+
const txHashesToFetch = [];
|
|
81228
|
+
let page = firstPage;
|
|
81229
|
+
try {
|
|
81230
|
+
while (page <= lastPage) {
|
|
81231
|
+
const response = yield getTxs({
|
|
81232
|
+
apiKey: this._apiKey,
|
|
81233
|
+
sochainUrl: this.baseUrl,
|
|
81234
|
+
network: this.sochainNetwork,
|
|
81235
|
+
address: `${params === null || params === void 0 ? void 0 : params.address}`,
|
|
81236
|
+
page,
|
|
81237
|
+
});
|
|
81238
|
+
if (response.transactions.length === 0)
|
|
81239
|
+
break;
|
|
81240
|
+
if (page === firstPage && response.transactions.length > offsetOnFirstPage) {
|
|
81241
|
+
//start from offset
|
|
81242
|
+
const txsToGet = response.transactions.slice(offsetOnFirstPage);
|
|
81243
|
+
this.addArrayUpToLimit(txHashesToFetch, txsToGet.map((i) => i.hash), limit);
|
|
81244
|
+
}
|
|
81245
|
+
else {
|
|
81246
|
+
this.addArrayUpToLimit(txHashesToFetch, response.transactions.map((i) => i.hash), limit);
|
|
81247
|
+
}
|
|
81248
|
+
page++;
|
|
81249
|
+
}
|
|
81250
|
+
}
|
|
81251
|
+
catch (error) {
|
|
81252
|
+
console.error(error);
|
|
81253
|
+
//an errors means no more results
|
|
81254
|
+
}
|
|
81255
|
+
const total = txHashesToFetch.length;
|
|
81256
|
+
const transactions = yield Promise.all(txHashesToFetch.map((hash) => this.getTransactionData(hash)));
|
|
81257
|
+
const result = {
|
|
81258
|
+
total,
|
|
81259
|
+
txs: transactions,
|
|
81260
|
+
};
|
|
81261
|
+
return result;
|
|
81262
|
+
});
|
|
81263
|
+
}
|
|
81264
|
+
/**
|
|
81265
|
+
* Get the transaction details of a given transaction id.
|
|
81266
|
+
*
|
|
81267
|
+
* @param {string} txId The transaction id.
|
|
81268
|
+
* @returns {Tx} The transaction details of the given transaction id.
|
|
81269
|
+
*/
|
|
81270
|
+
getTransactionData(txId) {
|
|
81271
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
81272
|
+
try {
|
|
81273
|
+
const rawTx = yield getTx({
|
|
81274
|
+
apiKey: this._apiKey,
|
|
81275
|
+
sochainUrl: this.baseUrl,
|
|
81276
|
+
network: this.sochainNetwork,
|
|
81277
|
+
hash: txId,
|
|
81278
|
+
});
|
|
81279
|
+
return {
|
|
81280
|
+
asset: this.asset,
|
|
81281
|
+
from: rawTx.inputs.map((i) => ({
|
|
81282
|
+
from: i.address,
|
|
81283
|
+
amount: assetToBase(assetAmount(i.value, this.assetDecimals)),
|
|
81284
|
+
})),
|
|
81285
|
+
to: rawTx.outputs
|
|
81286
|
+
.filter((i) => i.type !== 'nulldata') //filter out op_return outputs
|
|
81287
|
+
.map((i) => ({ to: i.address, amount: assetToBase(assetAmount(i.value, this.assetDecimals)) })),
|
|
81288
|
+
date: new Date(rawTx.time * 1000),
|
|
81289
|
+
type: TxType.Transfer,
|
|
81290
|
+
hash: rawTx.hash,
|
|
81291
|
+
};
|
|
81292
|
+
}
|
|
81293
|
+
catch (error) {
|
|
81294
|
+
console.error(error);
|
|
81295
|
+
throw error;
|
|
81296
|
+
}
|
|
81297
|
+
});
|
|
81298
|
+
}
|
|
81299
|
+
mapUTXOs(utxos) {
|
|
81300
|
+
return utxos.map((utxo) => ({
|
|
81301
|
+
hash: utxo.hash,
|
|
81302
|
+
index: utxo.index,
|
|
81303
|
+
value: assetToBase(assetAmount(utxo.value, this.assetDecimals)).amount().toNumber(),
|
|
81304
|
+
witnessUtxo: {
|
|
81305
|
+
value: assetToBase(assetAmount(utxo.value, this.assetDecimals)).amount().toNumber(),
|
|
81306
|
+
script: Buffer.from(utxo.script, 'hex'),
|
|
81307
|
+
},
|
|
81308
|
+
txHex: utxo.tx_hex,
|
|
81309
|
+
}));
|
|
81310
|
+
}
|
|
81311
|
+
/**
|
|
81312
|
+
* helper function tto limit adding to an array
|
|
81313
|
+
*
|
|
81314
|
+
* @param arr array to be added to
|
|
81315
|
+
* @param toAdd elements to add
|
|
81316
|
+
* @param limit do not add more than this limit
|
|
81317
|
+
*/
|
|
81318
|
+
addArrayUpToLimit(arr, toAdd, limit) {
|
|
81319
|
+
for (let index = 0; index < toAdd.length; index++) {
|
|
81320
|
+
const element = toAdd[index];
|
|
81321
|
+
if (arr.length < limit) {
|
|
81322
|
+
arr.push(element);
|
|
81323
|
+
}
|
|
81324
|
+
}
|
|
81325
|
+
}
|
|
81326
|
+
}
|
|
81327
|
+
|
|
81328
|
+
/**
|
|
81329
|
+
* Haskoin API types
|
|
81330
|
+
*/
|
|
81331
|
+
var HaskoinNetwork;
|
|
81332
|
+
(function (HaskoinNetwork) {
|
|
81333
|
+
HaskoinNetwork["BTC"] = "btc";
|
|
81334
|
+
HaskoinNetwork["BTCTEST"] = "btctest";
|
|
81335
|
+
HaskoinNetwork["BCH"] = "bch";
|
|
81336
|
+
HaskoinNetwork["BCHTEST"] = "bchtest";
|
|
81337
|
+
})(HaskoinNetwork || (HaskoinNetwork = {}));
|
|
81338
|
+
|
|
81339
|
+
var commonjsGlobal$2 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
81340
|
+
|
|
81341
|
+
function unwrapExports$2 (x) {
|
|
81342
|
+
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
81343
|
+
}
|
|
81344
|
+
|
|
81345
|
+
function createCommonjsModule$2(fn, module) {
|
|
81346
|
+
return module = { exports: {} }, fn(module, module.exports), module.exports;
|
|
81347
|
+
}
|
|
81348
|
+
|
|
81349
|
+
var promisePoolError = createCommonjsModule$2(function (module, exports) {
|
|
81350
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
81351
|
+
exports.PromisePoolError = void 0;
|
|
81352
|
+
class PromisePoolError extends Error {
|
|
81353
|
+
/**
|
|
81354
|
+
* Create a new instance for the given `message` and `item`.
|
|
81355
|
+
*
|
|
81356
|
+
* @param error The original error
|
|
81357
|
+
* @param item The item causing the error
|
|
81358
|
+
*/
|
|
81359
|
+
constructor(error, item) {
|
|
81360
|
+
super();
|
|
81361
|
+
this.raw = error;
|
|
81362
|
+
this.item = item;
|
|
81363
|
+
this.name = this.constructor.name;
|
|
81364
|
+
this.message = this.messageFrom(error);
|
|
81365
|
+
Error.captureStackTrace(this, this.constructor);
|
|
81366
|
+
}
|
|
81367
|
+
/**
|
|
81368
|
+
* Returns a new promise pool error instance wrapping the `error` and `item`.
|
|
81369
|
+
*
|
|
81370
|
+
* @param {*} error
|
|
81371
|
+
* @param {*} item
|
|
81372
|
+
*
|
|
81373
|
+
* @returns {PromisePoolError}
|
|
81374
|
+
*/
|
|
81375
|
+
static createFrom(error, item) {
|
|
81376
|
+
return new this(error, item);
|
|
81377
|
+
}
|
|
81378
|
+
/**
|
|
81379
|
+
* Returns the error message from the given `error`.
|
|
81380
|
+
*
|
|
81381
|
+
* @param {*} error
|
|
81382
|
+
*
|
|
81383
|
+
* @returns {String}
|
|
81384
|
+
*/
|
|
81385
|
+
messageFrom(error) {
|
|
81386
|
+
if (error instanceof Error) {
|
|
81387
|
+
return error.message;
|
|
81388
|
+
}
|
|
81389
|
+
if (typeof error === 'object') {
|
|
81390
|
+
return error.message;
|
|
81391
|
+
}
|
|
81392
|
+
if (typeof error === 'string' || typeof error === 'number') {
|
|
81393
|
+
return error.toString();
|
|
81394
|
+
}
|
|
81395
|
+
return '';
|
|
81396
|
+
}
|
|
81397
|
+
}
|
|
81398
|
+
exports.PromisePoolError = PromisePoolError;
|
|
81399
|
+
});
|
|
81400
|
+
|
|
81401
|
+
unwrapExports$2(promisePoolError);
|
|
81402
|
+
var promisePoolError_1 = promisePoolError.PromisePoolError;
|
|
81403
|
+
|
|
81404
|
+
var stopThePromisePoolError = createCommonjsModule$2(function (module, exports) {
|
|
81405
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
81406
|
+
exports.StopThePromisePoolError = void 0;
|
|
81407
|
+
class StopThePromisePoolError extends Error {
|
|
81408
|
+
}
|
|
81409
|
+
exports.StopThePromisePoolError = StopThePromisePoolError;
|
|
81410
|
+
});
|
|
81411
|
+
|
|
81412
|
+
unwrapExports$2(stopThePromisePoolError);
|
|
81413
|
+
var stopThePromisePoolError_1 = stopThePromisePoolError.StopThePromisePoolError;
|
|
81414
|
+
|
|
81415
|
+
var validationError = createCommonjsModule$2(function (module, exports) {
|
|
81416
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
81417
|
+
exports.ValidationError = void 0;
|
|
81418
|
+
class ValidationError extends Error {
|
|
81419
|
+
/**
|
|
81420
|
+
* Create a new instance for the given `message`.
|
|
81421
|
+
*
|
|
81422
|
+
* @param message The error message
|
|
81423
|
+
*/
|
|
81424
|
+
constructor(message) {
|
|
81425
|
+
super(message);
|
|
81426
|
+
Error.captureStackTrace(this, this.constructor);
|
|
81427
|
+
}
|
|
81428
|
+
/**
|
|
81429
|
+
* Returns a validation error with the given `message`.
|
|
81430
|
+
*/
|
|
81431
|
+
static createFrom(message) {
|
|
81432
|
+
return new this(message);
|
|
81433
|
+
}
|
|
81434
|
+
}
|
|
81435
|
+
exports.ValidationError = ValidationError;
|
|
81436
|
+
});
|
|
81437
|
+
|
|
81438
|
+
unwrapExports$2(validationError);
|
|
81439
|
+
var validationError_1 = validationError.ValidationError;
|
|
81440
|
+
|
|
81441
|
+
var promisePoolExecutor = createCommonjsModule$2(function (module, exports) {
|
|
81442
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
81443
|
+
exports.PromisePoolExecutor = void 0;
|
|
81444
|
+
|
|
81445
|
+
|
|
81446
|
+
|
|
81447
|
+
|
|
81448
|
+
class PromisePoolExecutor {
|
|
81449
|
+
/**
|
|
81450
|
+
* Creates a new promise pool executer instance with a default concurrency of 10.
|
|
81451
|
+
*/
|
|
81452
|
+
constructor() {
|
|
81453
|
+
this.meta = {
|
|
81454
|
+
tasks: [],
|
|
81455
|
+
items: [],
|
|
81456
|
+
errors: [],
|
|
81457
|
+
results: [],
|
|
81458
|
+
stopped: false,
|
|
81459
|
+
concurrency: 10,
|
|
81460
|
+
shouldResultsCorrespond: false,
|
|
81461
|
+
processedItems: [],
|
|
81462
|
+
taskTimeout: 0
|
|
81463
|
+
};
|
|
81464
|
+
this.handler = () => { };
|
|
81465
|
+
this.errorHandler = undefined;
|
|
81466
|
+
this.onTaskStartedHandlers = [];
|
|
81467
|
+
this.onTaskFinishedHandlers = [];
|
|
81468
|
+
}
|
|
81469
|
+
/**
|
|
81470
|
+
* Set the number of tasks to process concurrently the promise pool.
|
|
81471
|
+
*
|
|
81472
|
+
* @param {Integer} concurrency
|
|
81473
|
+
*
|
|
81474
|
+
* @returns {PromisePoolExecutor}
|
|
81475
|
+
*/
|
|
81476
|
+
useConcurrency(concurrency) {
|
|
81477
|
+
if (!this.isValidConcurrency(concurrency)) {
|
|
81478
|
+
throw validationError.ValidationError.createFrom(`"concurrency" must be a number, 1 or up. Received "${concurrency}" (${typeof concurrency})`);
|
|
81479
|
+
}
|
|
81480
|
+
this.meta.concurrency = concurrency;
|
|
81481
|
+
return this;
|
|
81482
|
+
}
|
|
81483
|
+
/**
|
|
81484
|
+
* Determine whether the given `concurrency` value is valid.
|
|
81485
|
+
*
|
|
81486
|
+
* @param {Number} concurrency
|
|
81487
|
+
*
|
|
81488
|
+
* @returns {Boolean}
|
|
81489
|
+
*/
|
|
81490
|
+
isValidConcurrency(concurrency) {
|
|
81491
|
+
return typeof concurrency === 'number' && concurrency >= 1;
|
|
81492
|
+
}
|
|
81493
|
+
/**
|
|
81494
|
+
* Set the timeout in ms for the pool handler
|
|
81495
|
+
*
|
|
81496
|
+
* @param {Number} timeout
|
|
81497
|
+
*
|
|
81498
|
+
* @returns {PromisePool}
|
|
81499
|
+
*/
|
|
81500
|
+
withTaskTimeout(timeout) {
|
|
81501
|
+
this.meta.taskTimeout = timeout;
|
|
81502
|
+
return this;
|
|
81503
|
+
}
|
|
81504
|
+
/**
|
|
81505
|
+
* Returns the number of concurrently processed tasks.
|
|
81506
|
+
*
|
|
81507
|
+
* @returns {Number}
|
|
81508
|
+
*/
|
|
81509
|
+
concurrency() {
|
|
81510
|
+
return this.meta.concurrency;
|
|
81511
|
+
}
|
|
81512
|
+
/**
|
|
81513
|
+
* Assign whether to keep corresponding results between source items and resulting tasks.
|
|
81514
|
+
*/
|
|
81515
|
+
useCorrespondingResults(shouldResultsCorrespond) {
|
|
81516
|
+
this.meta.shouldResultsCorrespond = shouldResultsCorrespond;
|
|
81517
|
+
return this;
|
|
81518
|
+
}
|
|
81519
|
+
/**
|
|
81520
|
+
* Determine whether to keep corresponding results between source items and resulting tasks.
|
|
81521
|
+
*/
|
|
81522
|
+
shouldUseCorrespondingResults() {
|
|
81523
|
+
return this.meta.shouldResultsCorrespond;
|
|
81524
|
+
}
|
|
81525
|
+
/**
|
|
81526
|
+
* Returns the task timeout in milliseconds.
|
|
81527
|
+
*/
|
|
81528
|
+
taskTimeout() {
|
|
81529
|
+
return this.meta.taskTimeout;
|
|
81530
|
+
}
|
|
81531
|
+
/**
|
|
81532
|
+
* Set the items to be processed in the promise pool.
|
|
81533
|
+
*
|
|
81534
|
+
* @param {Array} items
|
|
81535
|
+
*
|
|
81536
|
+
* @returns {PromisePoolExecutor}
|
|
81537
|
+
*/
|
|
81538
|
+
for(items) {
|
|
81539
|
+
this.meta.items = items;
|
|
81540
|
+
return this;
|
|
81541
|
+
}
|
|
81542
|
+
/**
|
|
81543
|
+
* Returns the list of items to process.
|
|
81544
|
+
*
|
|
81545
|
+
* @returns {T[]}
|
|
81546
|
+
*/
|
|
81547
|
+
items() {
|
|
81548
|
+
return this.meta.items;
|
|
81549
|
+
}
|
|
81550
|
+
/**
|
|
81551
|
+
* Returns the number of items to process.
|
|
81552
|
+
*
|
|
81553
|
+
* @returns {Number}
|
|
81554
|
+
*/
|
|
81555
|
+
itemsCount() {
|
|
81556
|
+
return this.items().length;
|
|
81557
|
+
}
|
|
81558
|
+
/**
|
|
81559
|
+
* Returns the list of active tasks.
|
|
81560
|
+
*
|
|
81561
|
+
* @returns {Array}
|
|
81562
|
+
*/
|
|
81563
|
+
tasks() {
|
|
81564
|
+
return this.meta.tasks;
|
|
81565
|
+
}
|
|
81566
|
+
/**
|
|
81567
|
+
* Returns the number of currently active tasks.
|
|
81568
|
+
*
|
|
81569
|
+
* @returns {Number}
|
|
81570
|
+
*
|
|
81571
|
+
* @deprecated use the `activeTasksCount()` method (plural naming) instead
|
|
81572
|
+
*/
|
|
81573
|
+
activeTaskCount() {
|
|
81574
|
+
return this.activeTasksCount();
|
|
81575
|
+
}
|
|
81576
|
+
/**
|
|
81577
|
+
* Returns the number of currently active tasks.
|
|
81578
|
+
*
|
|
81579
|
+
* @returns {Number}
|
|
81580
|
+
*/
|
|
81581
|
+
activeTasksCount() {
|
|
81582
|
+
return this.tasks().length;
|
|
81583
|
+
}
|
|
81584
|
+
/**
|
|
81585
|
+
* Returns the list of processed items.
|
|
81586
|
+
*
|
|
81587
|
+
* @returns {T[]}
|
|
81588
|
+
*/
|
|
81589
|
+
processedItems() {
|
|
81590
|
+
return this.meta.processedItems;
|
|
81591
|
+
}
|
|
81592
|
+
/**
|
|
81593
|
+
* Returns the number of processed items.
|
|
81594
|
+
*
|
|
81595
|
+
* @returns {Number}
|
|
81596
|
+
*/
|
|
81597
|
+
processedCount() {
|
|
81598
|
+
return this.processedItems().length;
|
|
81599
|
+
}
|
|
81600
|
+
/**
|
|
81601
|
+
* Returns the percentage progress of items that have been processed.
|
|
81602
|
+
*/
|
|
81603
|
+
processedPercentage() {
|
|
81604
|
+
return (this.processedCount() / this.itemsCount()) * 100;
|
|
81605
|
+
}
|
|
81606
|
+
/**
|
|
81607
|
+
* Returns the list of results.
|
|
81608
|
+
*
|
|
81609
|
+
* @returns {R[]}
|
|
81610
|
+
*/
|
|
81611
|
+
results() {
|
|
81612
|
+
return this.meta.results;
|
|
81613
|
+
}
|
|
81614
|
+
/**
|
|
81615
|
+
* Returns the list of errors.
|
|
81616
|
+
*
|
|
81617
|
+
* @returns {Array<PromisePoolError<T>>}
|
|
81618
|
+
*/
|
|
81619
|
+
errors() {
|
|
81620
|
+
return this.meta.errors;
|
|
81621
|
+
}
|
|
81622
|
+
/**
|
|
81623
|
+
* Set the handler that is applied to each item.
|
|
81624
|
+
*
|
|
81625
|
+
* @param {Function} action
|
|
81626
|
+
*
|
|
81627
|
+
* @returns {PromisePoolExecutor}
|
|
81628
|
+
*/
|
|
81629
|
+
withHandler(action) {
|
|
81630
|
+
this.handler = action;
|
|
81631
|
+
return this;
|
|
81632
|
+
}
|
|
81633
|
+
/**
|
|
81634
|
+
* Determine whether a custom error handle is available.
|
|
81635
|
+
*
|
|
81636
|
+
* @returns {Boolean}
|
|
81637
|
+
*/
|
|
81638
|
+
hasErrorHandler() {
|
|
81639
|
+
return !!this.errorHandler;
|
|
81640
|
+
}
|
|
81641
|
+
/**
|
|
81642
|
+
* Set the error handler function to execute when an error occurs.
|
|
81643
|
+
*
|
|
81644
|
+
* @param {Function} errorHandler
|
|
81645
|
+
*
|
|
81646
|
+
* @returns {PromisePoolExecutor}
|
|
81647
|
+
*/
|
|
81648
|
+
handleError(handler) {
|
|
81649
|
+
this.errorHandler = handler;
|
|
81650
|
+
return this;
|
|
81651
|
+
}
|
|
81652
|
+
/**
|
|
81653
|
+
* Set the handler function to execute when started a task.
|
|
81654
|
+
*
|
|
81655
|
+
* @param {Function} handler
|
|
81656
|
+
*
|
|
81657
|
+
* @returns {this}
|
|
81658
|
+
*/
|
|
81659
|
+
onTaskStarted(handlers) {
|
|
81660
|
+
this.onTaskStartedHandlers = handlers;
|
|
81661
|
+
return this;
|
|
81662
|
+
}
|
|
81663
|
+
/**
|
|
81664
|
+
* Assign the given callback `handler` function to run when a task finished.
|
|
81665
|
+
*
|
|
81666
|
+
* @param {OnProgressCallback<T>} handlers
|
|
81667
|
+
*
|
|
81668
|
+
* @returns {this}
|
|
81669
|
+
*/
|
|
81670
|
+
onTaskFinished(handlers) {
|
|
81671
|
+
this.onTaskFinishedHandlers = handlers;
|
|
81672
|
+
return this;
|
|
81673
|
+
}
|
|
81674
|
+
/**
|
|
81675
|
+
* Determines whether the number of active tasks is greater or equal to the concurrency limit.
|
|
81676
|
+
*
|
|
81677
|
+
* @returns {Boolean}
|
|
81678
|
+
*/
|
|
81679
|
+
hasReachedConcurrencyLimit() {
|
|
81680
|
+
return this.activeTasksCount() >= this.concurrency();
|
|
81681
|
+
}
|
|
81682
|
+
/**
|
|
81683
|
+
* Stop a promise pool processing.
|
|
81684
|
+
*/
|
|
81685
|
+
stop() {
|
|
81686
|
+
this.markAsStopped();
|
|
81687
|
+
throw new stopThePromisePoolError.StopThePromisePoolError();
|
|
81688
|
+
}
|
|
81689
|
+
/**
|
|
81690
|
+
* Mark the promise pool as stopped.
|
|
81691
|
+
*
|
|
81692
|
+
* @returns {PromisePoolExecutor}
|
|
81693
|
+
*/
|
|
81694
|
+
markAsStopped() {
|
|
81695
|
+
this.meta.stopped = true;
|
|
81696
|
+
return this;
|
|
81697
|
+
}
|
|
81698
|
+
/**
|
|
81699
|
+
* Determine whether the pool is stopped.
|
|
81700
|
+
*
|
|
81701
|
+
* @returns {Boolean}
|
|
81702
|
+
*/
|
|
81703
|
+
isStopped() {
|
|
81704
|
+
return this.meta.stopped;
|
|
81705
|
+
}
|
|
81706
|
+
/**
|
|
81707
|
+
* Start processing the promise pool.
|
|
81708
|
+
*
|
|
81709
|
+
* @returns {ReturnValue}
|
|
81710
|
+
*/
|
|
81711
|
+
async start() {
|
|
81712
|
+
return await this
|
|
81713
|
+
.validateInputs()
|
|
81714
|
+
.prepareResultsArray()
|
|
81715
|
+
.process();
|
|
81716
|
+
}
|
|
81717
|
+
/**
|
|
81718
|
+
* Determine whether the pool should stop.
|
|
81719
|
+
*
|
|
81720
|
+
* @returns {PromisePoolExecutor}
|
|
81721
|
+
*
|
|
81722
|
+
* @throws
|
|
81723
|
+
*/
|
|
81724
|
+
validateInputs() {
|
|
81725
|
+
if (typeof this.handler !== 'function') {
|
|
81726
|
+
throw validationError.ValidationError.createFrom('The first parameter for the .process(fn) method must be a function');
|
|
81727
|
+
}
|
|
81728
|
+
const timeout = this.taskTimeout();
|
|
81729
|
+
if (!(timeout == null || (typeof timeout === 'number' && timeout >= 0))) {
|
|
81730
|
+
throw validationError.ValidationError.createFrom(`"timeout" must be undefined or a number. A number must be 0 or up. Received "${String(timeout)}" (${typeof timeout})`);
|
|
81731
|
+
}
|
|
81732
|
+
if (!Array.isArray(this.items())) {
|
|
81733
|
+
throw validationError.ValidationError.createFrom(`"items" must be an array. Received "${typeof this.items()}"`);
|
|
81734
|
+
}
|
|
81735
|
+
if (this.errorHandler && typeof this.errorHandler !== 'function') {
|
|
81736
|
+
throw validationError.ValidationError.createFrom(`The error handler must be a function. Received "${typeof this.errorHandler}"`);
|
|
81737
|
+
}
|
|
81738
|
+
this.onTaskStartedHandlers.forEach(handler => {
|
|
81739
|
+
if (handler && typeof handler !== 'function') {
|
|
81740
|
+
throw validationError.ValidationError.createFrom(`The onTaskStarted handler must be a function. Received "${typeof handler}"`);
|
|
81741
|
+
}
|
|
81742
|
+
});
|
|
81743
|
+
this.onTaskFinishedHandlers.forEach(handler => {
|
|
81744
|
+
if (handler && typeof handler !== 'function') {
|
|
81745
|
+
throw validationError.ValidationError.createFrom(`The error handler must be a function. Received "${typeof handler}"`);
|
|
81746
|
+
}
|
|
81747
|
+
});
|
|
81748
|
+
return this;
|
|
81749
|
+
}
|
|
81750
|
+
/**
|
|
81751
|
+
* Prefill the results array with `notRun` symbol values if results should correspond.
|
|
81752
|
+
*/
|
|
81753
|
+
prepareResultsArray() {
|
|
81754
|
+
if (this.shouldUseCorrespondingResults()) {
|
|
81755
|
+
this.meta.results = Array(this.items().length).fill(promisePool.PromisePool.notRun);
|
|
81756
|
+
}
|
|
81757
|
+
return this;
|
|
81758
|
+
}
|
|
81759
|
+
/**
|
|
81760
|
+
* Starts processing the promise pool by iterating over the items
|
|
81761
|
+
* and running each item through the async `callback` function.
|
|
81762
|
+
*
|
|
81763
|
+
* @param {Function} callback
|
|
81764
|
+
*
|
|
81765
|
+
* @returns {Promise}
|
|
81766
|
+
*/
|
|
81767
|
+
async process() {
|
|
81768
|
+
for (const [index, item] of this.items().entries()) {
|
|
81769
|
+
if (this.isStopped()) {
|
|
81770
|
+
break;
|
|
81771
|
+
}
|
|
81772
|
+
await this.waitForProcessingSlot();
|
|
81773
|
+
this.startProcessing(item, index);
|
|
81774
|
+
}
|
|
81775
|
+
return await this.drained();
|
|
81776
|
+
}
|
|
81777
|
+
/**
|
|
81778
|
+
* Wait for one of the active tasks to finish processing.
|
|
81779
|
+
*/
|
|
81780
|
+
async waitForProcessingSlot() {
|
|
81781
|
+
/**
|
|
81782
|
+
* We’re using a while loop here because it’s possible to decrease the pool’s
|
|
81783
|
+
* concurrency at runtime. We need to wait for as many tasks as needed to
|
|
81784
|
+
* finish processing before moving on to process the remaining tasks.
|
|
81785
|
+
*/
|
|
81786
|
+
while (this.hasReachedConcurrencyLimit()) {
|
|
81787
|
+
await this.waitForActiveTaskToFinish();
|
|
81788
|
+
}
|
|
81789
|
+
}
|
|
81790
|
+
/**
|
|
81791
|
+
* Wait for the next, currently active task to finish processing.
|
|
81792
|
+
*/
|
|
81793
|
+
async waitForActiveTaskToFinish() {
|
|
81794
|
+
await Promise.race(this.tasks());
|
|
81795
|
+
}
|
|
81796
|
+
/**
|
|
81797
|
+
* Create a processing function for the given `item`.
|
|
81798
|
+
*
|
|
81799
|
+
* @param {T} item
|
|
81800
|
+
* @param {number} index
|
|
81801
|
+
*/
|
|
81802
|
+
startProcessing(item, index) {
|
|
81803
|
+
const task = this.createTaskFor(item, index)
|
|
81804
|
+
.then(result => {
|
|
81805
|
+
this.save(result, index).removeActive(task);
|
|
81806
|
+
})
|
|
81807
|
+
.catch(async (error) => {
|
|
81808
|
+
await this.handleErrorFor(error, item, index);
|
|
81809
|
+
this.removeActive(task);
|
|
81810
|
+
})
|
|
81811
|
+
.finally(() => {
|
|
81812
|
+
this.processedItems().push(item);
|
|
81813
|
+
this.runOnTaskFinishedHandlers(item);
|
|
81814
|
+
});
|
|
81815
|
+
this.tasks().push(task);
|
|
81816
|
+
this.runOnTaskStartedHandlers(item);
|
|
81817
|
+
}
|
|
81818
|
+
/**
|
|
81819
|
+
* Ensures a returned promise for the processing of the given `item`.
|
|
81820
|
+
*
|
|
81821
|
+
* @param {T} item
|
|
81822
|
+
* @param {number} index
|
|
81823
|
+
*
|
|
81824
|
+
* @returns {*}
|
|
81825
|
+
*/
|
|
81826
|
+
async createTaskFor(item, index) {
|
|
81827
|
+
if (this.taskTimeout() === undefined) {
|
|
81828
|
+
return this.handler(item, index, this);
|
|
81829
|
+
}
|
|
81830
|
+
return Promise.race([
|
|
81831
|
+
this.handler(item, index, this),
|
|
81832
|
+
this.createTaskTimeout(item)
|
|
81833
|
+
]);
|
|
81834
|
+
}
|
|
81835
|
+
/**
|
|
81836
|
+
* Returns a promise that times-out after the configured task timeout.
|
|
81837
|
+
*/
|
|
81838
|
+
async createTaskTimeout(item) {
|
|
81839
|
+
return new Promise((_resolve, reject) => {
|
|
81840
|
+
setTimeout(() => {
|
|
81841
|
+
reject(new promisePoolError.PromisePoolError(`Promise in pool timed out after ${this.taskTimeout()}ms`, item));
|
|
81842
|
+
}, this.taskTimeout());
|
|
81843
|
+
});
|
|
81844
|
+
}
|
|
81845
|
+
/**
|
|
81846
|
+
* Save the given calculation `result`, possibly at the provided `position`.
|
|
81847
|
+
*
|
|
81848
|
+
* @param {*} result
|
|
81849
|
+
* @param {number} position
|
|
81850
|
+
*
|
|
81851
|
+
* @returns {PromisePoolExecutor}
|
|
81852
|
+
*/
|
|
81853
|
+
save(result, position) {
|
|
81854
|
+
this.shouldUseCorrespondingResults()
|
|
81855
|
+
? this.results()[position] = result
|
|
81856
|
+
: this.results().push(result);
|
|
81857
|
+
return this;
|
|
81858
|
+
}
|
|
81859
|
+
/**
|
|
81860
|
+
* Remove the given `task` from the list of active tasks.
|
|
81861
|
+
*
|
|
81862
|
+
* @param {Promise} task
|
|
81863
|
+
*/
|
|
81864
|
+
removeActive(task) {
|
|
81865
|
+
this.tasks().splice(this.tasks().indexOf(task), 1);
|
|
81866
|
+
return this;
|
|
81867
|
+
}
|
|
81868
|
+
/**
|
|
81869
|
+
* Create and save an error for the the given `item`.
|
|
81870
|
+
*
|
|
81871
|
+
* @param {Error} error
|
|
81872
|
+
* @param {T} item
|
|
81873
|
+
* @param {number} index
|
|
81874
|
+
*/
|
|
81875
|
+
async handleErrorFor(error, item, index) {
|
|
81876
|
+
if (this.shouldUseCorrespondingResults()) {
|
|
81877
|
+
this.results()[index] = promisePool.PromisePool.failed;
|
|
81878
|
+
}
|
|
81879
|
+
if (this.isStoppingThePoolError(error)) {
|
|
81880
|
+
return;
|
|
81881
|
+
}
|
|
81882
|
+
if (this.isValidationError(error)) {
|
|
81883
|
+
this.markAsStopped();
|
|
81884
|
+
throw error;
|
|
81885
|
+
}
|
|
81886
|
+
this.hasErrorHandler()
|
|
81887
|
+
? await this.runErrorHandlerFor(error, item)
|
|
81888
|
+
: this.saveErrorFor(error, item);
|
|
81889
|
+
}
|
|
81890
|
+
/**
|
|
81891
|
+
* Determine whether the given `error` is a `StopThePromisePoolError` instance.
|
|
81892
|
+
*
|
|
81893
|
+
* @param {Error} error
|
|
81894
|
+
*
|
|
81895
|
+
* @returns {Boolean}
|
|
81896
|
+
*/
|
|
81897
|
+
isStoppingThePoolError(error) {
|
|
81898
|
+
return error instanceof stopThePromisePoolError.StopThePromisePoolError;
|
|
81899
|
+
}
|
|
81900
|
+
/**
|
|
81901
|
+
* Determine whether the given `error` is a `ValidationError` instance.
|
|
81902
|
+
*
|
|
81903
|
+
* @param {Error} error
|
|
81904
|
+
*
|
|
81905
|
+
* @returns {Boolean}
|
|
81906
|
+
*/
|
|
81907
|
+
isValidationError(error) {
|
|
81908
|
+
return error instanceof validationError.ValidationError;
|
|
81909
|
+
}
|
|
81910
|
+
/**
|
|
81911
|
+
* Run the user’s error handler, if available.
|
|
81912
|
+
*
|
|
81913
|
+
* @param {Error} processingError
|
|
81914
|
+
* @param {T} item
|
|
81915
|
+
*/
|
|
81916
|
+
async runErrorHandlerFor(processingError, item) {
|
|
81917
|
+
var _a;
|
|
81918
|
+
try {
|
|
81919
|
+
await ((_a = this.errorHandler) === null || _a === void 0 ? void 0 : _a.call(this, processingError, item, this));
|
|
81920
|
+
}
|
|
81921
|
+
catch (error) {
|
|
81922
|
+
this.rethrowIfNotStoppingThePool(error);
|
|
81923
|
+
}
|
|
81924
|
+
}
|
|
81925
|
+
/**
|
|
81926
|
+
* Run the onTaskStarted handlers.
|
|
81927
|
+
*/
|
|
81928
|
+
runOnTaskStartedHandlers(item) {
|
|
81929
|
+
this.onTaskStartedHandlers.forEach(handler => {
|
|
81930
|
+
handler(item, this);
|
|
81931
|
+
});
|
|
81932
|
+
}
|
|
81933
|
+
/**
|
|
81934
|
+
* Run the onTaskFinished handlers.
|
|
81935
|
+
*/
|
|
81936
|
+
runOnTaskFinishedHandlers(item) {
|
|
81937
|
+
this.onTaskFinishedHandlers.forEach(handler => {
|
|
81938
|
+
handler(item, this);
|
|
81939
|
+
});
|
|
81940
|
+
}
|
|
81941
|
+
/**
|
|
81942
|
+
* Rethrow the given `error` if it’s not an instance of `StopThePromisePoolError`.
|
|
81943
|
+
*
|
|
81944
|
+
* @param {Error} error
|
|
81945
|
+
*/
|
|
81946
|
+
rethrowIfNotStoppingThePool(error) {
|
|
81947
|
+
if (this.isStoppingThePoolError(error)) {
|
|
81948
|
+
return;
|
|
81949
|
+
}
|
|
81950
|
+
throw error;
|
|
81951
|
+
}
|
|
81952
|
+
/**
|
|
81953
|
+
* Create and save an error for the the given `item`.
|
|
81954
|
+
*
|
|
81955
|
+
* @param {T} item
|
|
81956
|
+
*/
|
|
81957
|
+
saveErrorFor(error, item) {
|
|
81958
|
+
this.errors().push(promisePoolError.PromisePoolError.createFrom(error, item));
|
|
81959
|
+
}
|
|
81960
|
+
/**
|
|
81961
|
+
* Wait for all active tasks to finish. Once all the tasks finished
|
|
81962
|
+
* processing, returns an object containing the results and errors.
|
|
81963
|
+
*
|
|
81964
|
+
* @returns {Object}
|
|
81965
|
+
*/
|
|
81966
|
+
async drained() {
|
|
81967
|
+
await this.drainActiveTasks();
|
|
81968
|
+
return {
|
|
81969
|
+
errors: this.errors(),
|
|
81970
|
+
results: this.results()
|
|
81971
|
+
};
|
|
81972
|
+
}
|
|
81973
|
+
/**
|
|
81974
|
+
* Wait for all of the active tasks to finish processing.
|
|
81975
|
+
*/
|
|
81976
|
+
async drainActiveTasks() {
|
|
81977
|
+
await Promise.all(this.tasks());
|
|
81978
|
+
}
|
|
81979
|
+
}
|
|
81980
|
+
exports.PromisePoolExecutor = PromisePoolExecutor;
|
|
81981
|
+
});
|
|
81982
|
+
|
|
81983
|
+
unwrapExports$2(promisePoolExecutor);
|
|
81984
|
+
var promisePoolExecutor_1 = promisePoolExecutor.PromisePoolExecutor;
|
|
81985
|
+
|
|
81986
|
+
var promisePool = createCommonjsModule$2(function (module, exports) {
|
|
81987
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
81988
|
+
exports.PromisePool = void 0;
|
|
81989
|
+
|
|
81990
|
+
class PromisePool {
|
|
81991
|
+
/**
|
|
81992
|
+
* Instantiates a new promise pool with a default `concurrency: 10` and `items: []`.
|
|
81993
|
+
*
|
|
81994
|
+
* @param {Object} options
|
|
81995
|
+
*/
|
|
81996
|
+
constructor(items) {
|
|
81997
|
+
this.timeout = undefined;
|
|
81998
|
+
this.concurrency = 10;
|
|
81999
|
+
this.shouldResultsCorrespond = false;
|
|
82000
|
+
this.items = items !== null && items !== void 0 ? items : [];
|
|
82001
|
+
this.errorHandler = undefined;
|
|
82002
|
+
this.onTaskStartedHandlers = [];
|
|
82003
|
+
this.onTaskFinishedHandlers = [];
|
|
82004
|
+
}
|
|
82005
|
+
/**
|
|
82006
|
+
* Set the number of tasks to process concurrently in the promise pool.
|
|
82007
|
+
*
|
|
82008
|
+
* @param {Integer} concurrency
|
|
82009
|
+
*
|
|
82010
|
+
* @returns {PromisePool}
|
|
82011
|
+
*/
|
|
82012
|
+
withConcurrency(concurrency) {
|
|
82013
|
+
this.concurrency = concurrency;
|
|
82014
|
+
return this;
|
|
82015
|
+
}
|
|
82016
|
+
/**
|
|
82017
|
+
* Set the number of tasks to process concurrently in the promise pool.
|
|
82018
|
+
*
|
|
82019
|
+
* @param {Number} concurrency
|
|
82020
|
+
*
|
|
82021
|
+
* @returns {PromisePool}
|
|
82022
|
+
*/
|
|
82023
|
+
static withConcurrency(concurrency) {
|
|
82024
|
+
return new this().withConcurrency(concurrency);
|
|
82025
|
+
}
|
|
82026
|
+
/**
|
|
82027
|
+
* Set the timeout in milliseconds for the pool handler.
|
|
82028
|
+
*
|
|
82029
|
+
* @param {Number} timeout
|
|
82030
|
+
*
|
|
82031
|
+
* @returns {PromisePool}
|
|
82032
|
+
*/
|
|
82033
|
+
withTaskTimeout(timeout) {
|
|
82034
|
+
this.timeout = timeout;
|
|
82035
|
+
return this;
|
|
82036
|
+
}
|
|
82037
|
+
/**
|
|
82038
|
+
* Set the timeout in milliseconds for the pool handler.
|
|
82039
|
+
*
|
|
82040
|
+
* @param {Number} timeout
|
|
82041
|
+
*
|
|
82042
|
+
* @returns {PromisePool}
|
|
82043
|
+
*/
|
|
82044
|
+
static withTaskTimeout(timeout) {
|
|
82045
|
+
return new this().withTaskTimeout(timeout);
|
|
82046
|
+
}
|
|
82047
|
+
/**
|
|
82048
|
+
* Set the items to be processed in the promise pool.
|
|
82049
|
+
*
|
|
82050
|
+
* @param {T[]} items
|
|
82051
|
+
*
|
|
82052
|
+
* @returns {PromisePool}
|
|
82053
|
+
*/
|
|
82054
|
+
for(items) {
|
|
82055
|
+
return typeof this.timeout === 'number'
|
|
82056
|
+
? new PromisePool(items).withConcurrency(this.concurrency).withTaskTimeout(this.timeout)
|
|
82057
|
+
: new PromisePool(items).withConcurrency(this.concurrency);
|
|
82058
|
+
}
|
|
82059
|
+
/**
|
|
82060
|
+
* Set the items to be processed in the promise pool.
|
|
82061
|
+
*
|
|
82062
|
+
* @param {T[]} items
|
|
82063
|
+
*
|
|
82064
|
+
* @returns {PromisePool}
|
|
82065
|
+
*/
|
|
82066
|
+
static for(items) {
|
|
82067
|
+
return new this().for(items);
|
|
82068
|
+
}
|
|
82069
|
+
/**
|
|
82070
|
+
* Set the error handler function to execute when an error occurs.
|
|
82071
|
+
*
|
|
82072
|
+
* @param {ErrorHandler<T>} handler
|
|
82073
|
+
*
|
|
82074
|
+
* @returns {PromisePool}
|
|
82075
|
+
*/
|
|
82076
|
+
handleError(handler) {
|
|
82077
|
+
this.errorHandler = handler;
|
|
82078
|
+
return this;
|
|
82079
|
+
}
|
|
82080
|
+
/**
|
|
82081
|
+
* Assign the given callback `handler` function to run when a task starts.
|
|
82082
|
+
*
|
|
82083
|
+
* @param {OnProgressCallback<T>} handler
|
|
82084
|
+
*
|
|
82085
|
+
* @returns {PromisePool}
|
|
82086
|
+
*/
|
|
82087
|
+
onTaskStarted(handler) {
|
|
82088
|
+
this.onTaskStartedHandlers.push(handler);
|
|
82089
|
+
return this;
|
|
82090
|
+
}
|
|
82091
|
+
/**
|
|
82092
|
+
* Assign the given callback `handler` function to run when a task finished.
|
|
82093
|
+
*
|
|
82094
|
+
* @param {OnProgressCallback<T>} handler
|
|
82095
|
+
*
|
|
82096
|
+
* @returns {PromisePool}
|
|
82097
|
+
*/
|
|
82098
|
+
onTaskFinished(handler) {
|
|
82099
|
+
this.onTaskFinishedHandlers.push(handler);
|
|
82100
|
+
return this;
|
|
82101
|
+
}
|
|
82102
|
+
/**
|
|
82103
|
+
* Assign whether to keep corresponding results between source items and resulting tasks.
|
|
82104
|
+
*/
|
|
82105
|
+
useCorrespondingResults() {
|
|
82106
|
+
this.shouldResultsCorrespond = true;
|
|
82107
|
+
return this;
|
|
82108
|
+
}
|
|
82109
|
+
/**
|
|
82110
|
+
* Starts processing the promise pool by iterating over the items
|
|
82111
|
+
* and running each item through the async `callback` function.
|
|
82112
|
+
*
|
|
82113
|
+
* @param {ProcessHandler} The async processing function receiving each item from the `items` array.
|
|
82114
|
+
*
|
|
82115
|
+
* @returns Promise<{ results, errors }>
|
|
82116
|
+
*/
|
|
82117
|
+
async process(callback) {
|
|
82118
|
+
return new promisePoolExecutor.PromisePoolExecutor()
|
|
82119
|
+
.useConcurrency(this.concurrency)
|
|
82120
|
+
.useCorrespondingResults(this.shouldResultsCorrespond)
|
|
82121
|
+
.withTaskTimeout(this.timeout)
|
|
82122
|
+
.withHandler(callback)
|
|
82123
|
+
.handleError(this.errorHandler)
|
|
82124
|
+
.onTaskStarted(this.onTaskStartedHandlers)
|
|
82125
|
+
.onTaskFinished(this.onTaskFinishedHandlers)
|
|
82126
|
+
.for(this.items)
|
|
82127
|
+
.start();
|
|
82128
|
+
}
|
|
82129
|
+
}
|
|
82130
|
+
exports.PromisePool = PromisePool;
|
|
82131
|
+
PromisePool.notRun = Symbol('notRun');
|
|
82132
|
+
PromisePool.failed = Symbol('failed');
|
|
82133
|
+
});
|
|
82134
|
+
|
|
82135
|
+
unwrapExports$2(promisePool);
|
|
82136
|
+
var promisePool_1 = promisePool.PromisePool;
|
|
82137
|
+
|
|
82138
|
+
var contracts = createCommonjsModule$2(function (module, exports) {
|
|
82139
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
82140
|
+
});
|
|
82141
|
+
|
|
82142
|
+
unwrapExports$2(contracts);
|
|
82143
|
+
|
|
82144
|
+
var returnValue = createCommonjsModule$2(function (module, exports) {
|
|
82145
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
82146
|
+
});
|
|
82147
|
+
|
|
82148
|
+
unwrapExports$2(returnValue);
|
|
82149
|
+
|
|
82150
|
+
var dist$2 = createCommonjsModule$2(function (module, exports) {
|
|
82151
|
+
var __createBinding = (commonjsGlobal$2 && commonjsGlobal$2.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
82152
|
+
if (k2 === undefined) k2 = k;
|
|
82153
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
82154
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
82155
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
82156
|
+
}
|
|
82157
|
+
Object.defineProperty(o, k2, desc);
|
|
82158
|
+
}) : (function(o, m, k, k2) {
|
|
82159
|
+
if (k2 === undefined) k2 = k;
|
|
82160
|
+
o[k2] = m[k];
|
|
82161
|
+
}));
|
|
82162
|
+
var __exportStar = (commonjsGlobal$2 && commonjsGlobal$2.__exportStar) || function(m, exports) {
|
|
82163
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
82164
|
+
};
|
|
82165
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
82166
|
+
|
|
82167
|
+
exports.default = promisePool.PromisePool;
|
|
82168
|
+
__exportStar(contracts, exports);
|
|
82169
|
+
__exportStar(promisePool, exports);
|
|
82170
|
+
__exportStar(promisePoolError, exports);
|
|
82171
|
+
__exportStar(returnValue, exports);
|
|
82172
|
+
__exportStar(stopThePromisePoolError, exports);
|
|
82173
|
+
__exportStar(validationError, exports);
|
|
82174
|
+
});
|
|
82175
|
+
|
|
82176
|
+
var PromisePool = unwrapExports$2(dist$2);
|
|
82177
|
+
|
|
82178
|
+
/**
|
|
82179
|
+
* Get transaction by hash.
|
|
82180
|
+
*
|
|
82181
|
+
*
|
|
82182
|
+
* @param {string} baseUrl The sochain node url.
|
|
82183
|
+
* @param {string} network network id
|
|
82184
|
+
* @param {string} hash The transaction hash.
|
|
82185
|
+
* @returns {Transactions}
|
|
82186
|
+
*/
|
|
82187
|
+
const getTx$2 = ({ apiKey, baseUrl, network, hash }) => __awaiter$1(void 0, void 0, void 0, function* () {
|
|
82188
|
+
const params = { includeHex: 'true' };
|
|
82189
|
+
if (apiKey)
|
|
82190
|
+
params['token'] = apiKey;
|
|
82191
|
+
const url = `${baseUrl}/${network}/txs/${hash}`;
|
|
82192
|
+
const response = yield axios.get(url, { params });
|
|
82193
|
+
const tx = response.data;
|
|
82194
|
+
return tx;
|
|
82195
|
+
});
|
|
82196
|
+
/**
|
|
82197
|
+
* Get transactions
|
|
82198
|
+
*
|
|
82199
|
+
*
|
|
82200
|
+
* @param {string} baseUrl The sochain node url.
|
|
82201
|
+
* @param {string} network network id
|
|
82202
|
+
* @param {string} hash The transaction hash.
|
|
82203
|
+
* @returns {Transactions}
|
|
82204
|
+
*/
|
|
82205
|
+
const getTxs$2 = ({ apiKey, address, baseUrl, network, beforeBlock, limit, unspentOnly, }) => __awaiter$1(void 0, void 0, void 0, function* () {
|
|
82206
|
+
const params = { limit: `${limit}`, unspentOnly: `${unspentOnly}` };
|
|
82207
|
+
const url = `${baseUrl}/${network}/addrs/${address}`;
|
|
82208
|
+
if (apiKey)
|
|
82209
|
+
params['token'] = apiKey;
|
|
82210
|
+
if (beforeBlock)
|
|
82211
|
+
params['before'] = `${beforeBlock}`;
|
|
82212
|
+
const response = yield axios.get(url, { params });
|
|
82213
|
+
const txs = response.data;
|
|
82214
|
+
return txs;
|
|
82215
|
+
});
|
|
82216
|
+
/**
|
|
82217
|
+
* Get address balance.
|
|
82218
|
+
*
|
|
82219
|
+
*
|
|
82220
|
+
* @param {string} baseUrl The sochain node url.
|
|
82221
|
+
* @param {string} network Network
|
|
82222
|
+
* @param {string} address Address
|
|
82223
|
+
* @param {boolean} confirmedOnly Flag whether to get balances of confirmed txs only or for all
|
|
82224
|
+
* @returns {number}
|
|
82225
|
+
*/
|
|
82226
|
+
const getBalance$2 = ({ apiKey, baseUrl, network, address, confirmedOnly, assetDecimals, }) => __awaiter$1(void 0, void 0, void 0, function* () {
|
|
82227
|
+
const params = {};
|
|
82228
|
+
const url = `${baseUrl}/${network}/addrs/${address}/balance`;
|
|
82229
|
+
if (apiKey)
|
|
82230
|
+
params['token'] = apiKey;
|
|
82231
|
+
const response = yield axios.get(url, { params });
|
|
82232
|
+
const balanceResponse = response.data;
|
|
82233
|
+
const confirmedAmount = baseAmount(balanceResponse.balance, assetDecimals);
|
|
82234
|
+
const finalBalance = baseAmount(balanceResponse.final_balance, assetDecimals);
|
|
82235
|
+
return confirmedOnly ? confirmedAmount : finalBalance;
|
|
82236
|
+
});
|
|
82237
|
+
const broadcastTx$2 = ({ apiKey, baseUrl, network, txHex, }) => __awaiter$1(void 0, void 0, void 0, function* () {
|
|
82238
|
+
const params = {};
|
|
82239
|
+
const url = `${baseUrl}/${network}/txs/push`;
|
|
82240
|
+
if (apiKey)
|
|
82241
|
+
params['token'] = apiKey;
|
|
82242
|
+
const response = yield axios.post(url, { tx: txHex }, { params });
|
|
82243
|
+
const broadcastResponse = response.data;
|
|
82244
|
+
return broadcastResponse.tx.hash;
|
|
82245
|
+
});
|
|
82246
|
+
|
|
82247
|
+
class BlockcypherProvider {
|
|
82248
|
+
constructor(baseUrl = 'https://api.blockcypher.com/v1/', chain, asset, assetDecimals, blockcypherNetwork, apiKey) {
|
|
82249
|
+
this.baseUrl = baseUrl;
|
|
82250
|
+
this._apiKey = apiKey;
|
|
82251
|
+
this.chain = chain;
|
|
82252
|
+
this.asset = asset;
|
|
82253
|
+
this.assetDecimals = assetDecimals;
|
|
82254
|
+
this.blockcypherNetwork = blockcypherNetwork;
|
|
82255
|
+
this.asset;
|
|
82256
|
+
this.chain;
|
|
82257
|
+
}
|
|
82258
|
+
get apiKey() {
|
|
82259
|
+
return this._apiKey;
|
|
82260
|
+
}
|
|
82261
|
+
set apiKey(value) {
|
|
82262
|
+
this._apiKey = value;
|
|
82263
|
+
}
|
|
82264
|
+
broadcastTx(txHex) {
|
|
82265
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
82266
|
+
return yield broadcastTx$2({
|
|
82267
|
+
apiKey: this._apiKey,
|
|
82268
|
+
baseUrl: this.baseUrl,
|
|
82269
|
+
network: this.blockcypherNetwork,
|
|
82270
|
+
txHex,
|
|
82271
|
+
});
|
|
82272
|
+
});
|
|
82273
|
+
}
|
|
82274
|
+
getConfirmedUnspentTxs(address) {
|
|
82275
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
82276
|
+
const allUnspent = yield this.getRawTransactions({ address, offset: 0, limit: 2000 }, true);
|
|
82277
|
+
return this.mapUTXOs(address, allUnspent.filter((i) => i.confirmed));
|
|
82278
|
+
});
|
|
82279
|
+
}
|
|
82280
|
+
getUnspentTxs(address) {
|
|
82281
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
82282
|
+
const allUnspent = yield this.getRawTransactions({ address, offset: 0, limit: 2000 }, true);
|
|
82283
|
+
return this.mapUTXOs(address, allUnspent);
|
|
82284
|
+
});
|
|
82285
|
+
}
|
|
82286
|
+
getBalance(address, assets /*ignored*/, confirmedOnly) {
|
|
82287
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
82288
|
+
const amount = yield getBalance$2({
|
|
82289
|
+
apiKey: this._apiKey,
|
|
82290
|
+
baseUrl: this.baseUrl,
|
|
82291
|
+
network: this.blockcypherNetwork,
|
|
82292
|
+
address,
|
|
82293
|
+
confirmedOnly: !!confirmedOnly,
|
|
82294
|
+
assetDecimals: this.assetDecimals,
|
|
82295
|
+
});
|
|
82296
|
+
return [{ amount, asset: this.asset }];
|
|
82297
|
+
});
|
|
82298
|
+
}
|
|
82299
|
+
/**
|
|
82300
|
+
* Get transaction history of a given address with pagination options.
|
|
82301
|
+
* By default it will return the transaction history of the current wallet.
|
|
82302
|
+
*
|
|
82303
|
+
* @param {TxHistoryParams} params The options to get transaction history. (optional)
|
|
82304
|
+
* @returns {TxsPage} The transaction history.
|
|
82305
|
+
*/
|
|
82306
|
+
getTransactions(params, unspentOnly = false) {
|
|
82307
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
82308
|
+
const rawTxs = yield this.getRawTransactions(params, unspentOnly);
|
|
82309
|
+
const txs = rawTxs.map((i) => this.mapTransactionToTx(i));
|
|
82310
|
+
const result = {
|
|
82311
|
+
total: txs.length,
|
|
82312
|
+
txs,
|
|
82313
|
+
};
|
|
82314
|
+
return result;
|
|
82315
|
+
});
|
|
82316
|
+
}
|
|
82317
|
+
/**
|
|
82318
|
+
* Get the transaction details of a given transaction id.
|
|
82319
|
+
*
|
|
82320
|
+
* @param {string} txId The transaction id.
|
|
82321
|
+
* @returns {Tx} The transaction details of the given transaction id.
|
|
82322
|
+
*/
|
|
82323
|
+
getTransactionData(txId) {
|
|
82324
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
82325
|
+
try {
|
|
82326
|
+
const rawTx = yield getTx$2({
|
|
82327
|
+
apiKey: this._apiKey,
|
|
82328
|
+
baseUrl: this.baseUrl,
|
|
82329
|
+
network: this.blockcypherNetwork,
|
|
82330
|
+
hash: txId,
|
|
82331
|
+
});
|
|
82332
|
+
return this.mapTransactionToTx(rawTx);
|
|
82333
|
+
}
|
|
82334
|
+
catch (error) {
|
|
82335
|
+
console.error(error);
|
|
82336
|
+
throw error;
|
|
82337
|
+
}
|
|
82338
|
+
});
|
|
82339
|
+
}
|
|
82340
|
+
mapTransactionToTx(rawTx) {
|
|
82341
|
+
return {
|
|
82342
|
+
asset: this.asset,
|
|
82343
|
+
from: rawTx.inputs.map((i) => ({
|
|
82344
|
+
from: i.addresses[0],
|
|
82345
|
+
amount: baseAmount(i.output_value, this.assetDecimals),
|
|
82346
|
+
})),
|
|
82347
|
+
to: rawTx.outputs
|
|
82348
|
+
.filter((i) => i.script_type !== 'null-data') //filter out op_return outputs
|
|
82349
|
+
.map((i) => ({ to: i.addresses[0], amount: baseAmount(i.value, this.assetDecimals) })),
|
|
82350
|
+
date: new Date(rawTx.confirmed),
|
|
82351
|
+
type: TxType.Transfer,
|
|
82352
|
+
hash: rawTx.hash,
|
|
82353
|
+
};
|
|
82354
|
+
}
|
|
82355
|
+
mapUTXOs(address, utxos) {
|
|
82356
|
+
const utxosOut = [];
|
|
82357
|
+
for (let index = 0; index < utxos.length; index++) {
|
|
82358
|
+
const utxo = utxos[index];
|
|
82359
|
+
for (let index2 = 0; index2 < utxo.outputs.length; index2++) {
|
|
82360
|
+
const output = utxo.outputs[index2];
|
|
82361
|
+
if (output.addresses && output.addresses[0] === address) {
|
|
82362
|
+
const utxoOut = {
|
|
82363
|
+
hash: utxo.hash,
|
|
82364
|
+
index: index2,
|
|
82365
|
+
value: baseAmount(output.value, this.assetDecimals).amount().toNumber(),
|
|
82366
|
+
witnessUtxo: {
|
|
82367
|
+
value: baseAmount(output.value, this.assetDecimals).amount().toNumber(),
|
|
82368
|
+
script: Buffer.from(output.script, 'hex'),
|
|
82369
|
+
},
|
|
82370
|
+
txHex: utxo.hex,
|
|
82371
|
+
};
|
|
82372
|
+
utxosOut.push(utxoOut);
|
|
82373
|
+
}
|
|
82374
|
+
}
|
|
82375
|
+
}
|
|
82376
|
+
return utxosOut;
|
|
82377
|
+
}
|
|
82378
|
+
/**
|
|
82379
|
+
* helper function tto limit adding to an array
|
|
82380
|
+
*
|
|
82381
|
+
* @param arr array to be added to
|
|
82382
|
+
* @param toAdd elements to add
|
|
82383
|
+
* @param limit do not add more than this limit
|
|
82384
|
+
*/
|
|
82385
|
+
addArrayUpToLimit(arr, toAdd, limit) {
|
|
82386
|
+
for (let index = 0; index < toAdd.length; index++) {
|
|
82387
|
+
const element = toAdd[index];
|
|
82388
|
+
if (arr.length < limit) {
|
|
82389
|
+
arr.push(element);
|
|
82390
|
+
}
|
|
82391
|
+
}
|
|
82392
|
+
}
|
|
82393
|
+
delay(ms) {
|
|
82394
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
82395
|
+
}
|
|
82396
|
+
/**
|
|
82397
|
+
* Get transaction history of a given address with pagination options.
|
|
82398
|
+
* By default it will return the transaction history of the current wallet.
|
|
82399
|
+
*
|
|
82400
|
+
* @param {TxHistoryParams} params The options to get transaction history. (optional)
|
|
82401
|
+
* @returns {TxsPage} The transaction history.
|
|
82402
|
+
*/
|
|
82403
|
+
getRawTransactions(params, unspentOnly = false) {
|
|
82404
|
+
var _a;
|
|
82405
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
82406
|
+
const offset = (_a = params === null || params === void 0 ? void 0 : params.offset) !== null && _a !== void 0 ? _a : 0;
|
|
82407
|
+
const limit = (params === null || params === void 0 ? void 0 : params.limit) || 10;
|
|
82408
|
+
if (offset + limit > 2000)
|
|
82409
|
+
throw Error('cannot fetch more than last 2000 txs');
|
|
82410
|
+
if (offset < 0 || limit < 0)
|
|
82411
|
+
throw Error('ofset and limit must be equal or greater than 0');
|
|
82412
|
+
const txHashesToFetch = [];
|
|
82413
|
+
try {
|
|
82414
|
+
const response = yield getTxs$2({
|
|
82415
|
+
apiKey: this._apiKey,
|
|
82416
|
+
baseUrl: this.baseUrl,
|
|
82417
|
+
network: this.blockcypherNetwork,
|
|
82418
|
+
address: `${params === null || params === void 0 ? void 0 : params.address}`,
|
|
82419
|
+
limit: 2000,
|
|
82420
|
+
unspentOnly,
|
|
82421
|
+
});
|
|
82422
|
+
//remove duplicates
|
|
82423
|
+
const txs = response.txrefs.map((i) => i.tx_hash);
|
|
82424
|
+
const uniqTxs = [...new Set(txs)];
|
|
82425
|
+
const start = offset >= uniqTxs.length ? uniqTxs.length : offset;
|
|
82426
|
+
const end = offset + limit >= uniqTxs.length ? uniqTxs.length : offset + limit;
|
|
82427
|
+
const txsToFetch = uniqTxs.slice(start, end);
|
|
82428
|
+
// console.log(JSON.stringify(txsToFetch, null, 2))
|
|
82429
|
+
this.addArrayUpToLimit(txHashesToFetch, txsToFetch, limit);
|
|
82430
|
+
}
|
|
82431
|
+
catch (error) {
|
|
82432
|
+
console.error(error);
|
|
82433
|
+
//an errors means no more results
|
|
82434
|
+
}
|
|
82435
|
+
//note: blockcypher has rate of 3 req/sec --> https://www.blockcypher.com/dev/bitcoin/#rate-limits-and-tokens
|
|
82436
|
+
const batchResult = yield PromisePool.for(txHashesToFetch)
|
|
82437
|
+
.withConcurrency(3)
|
|
82438
|
+
.useCorrespondingResults()
|
|
82439
|
+
.process((hash) => __awaiter$1(this, void 0, void 0, function* () {
|
|
82440
|
+
yield this.delay(1000);
|
|
82441
|
+
const rawTx = yield getTx$2({
|
|
82442
|
+
apiKey: this._apiKey,
|
|
82443
|
+
baseUrl: this.baseUrl,
|
|
82444
|
+
network: this.blockcypherNetwork,
|
|
82445
|
+
hash,
|
|
82446
|
+
});
|
|
82447
|
+
return rawTx;
|
|
82448
|
+
}));
|
|
82449
|
+
return batchResult.results;
|
|
82450
|
+
});
|
|
82451
|
+
}
|
|
82452
|
+
}
|
|
82453
|
+
|
|
82454
|
+
var BlockcypherNetwork;
|
|
82455
|
+
(function (BlockcypherNetwork) {
|
|
82456
|
+
BlockcypherNetwork["BTC"] = "btc/main";
|
|
82457
|
+
BlockcypherNetwork["BTCTEST"] = "btc/test3";
|
|
82458
|
+
BlockcypherNetwork["LTC"] = "ltc/main";
|
|
82459
|
+
BlockcypherNetwork["DOGE"] = "doge/main";
|
|
82460
|
+
})(BlockcypherNetwork || (BlockcypherNetwork = {}));
|
|
82461
|
+
|
|
82462
|
+
/**
|
|
82463
|
+
* Minimum transaction fee
|
|
82464
|
+
* 100000 satoshi/kB (similar to current `minrelaytxfee`)
|
|
82465
|
+
* @see https://github.com/dogecoin/dogecoin/blob/master/src/validation.h#L58
|
|
82466
|
+
*/
|
|
82467
|
+
const MIN_TX_FEE = 100000;
|
|
82468
|
+
const DOGE_DECIMAL = 8;
|
|
82469
|
+
const LOWER_FEE_BOUND = 40000;
|
|
82470
|
+
const UPPER_FEE_BOUND = 20000000;
|
|
82471
|
+
/**
|
|
82472
|
+
* Chain identifier for Dogecoin
|
|
82473
|
+
*
|
|
82474
|
+
*/
|
|
82475
|
+
const DOGEChain = 'DOGE';
|
|
82476
|
+
/**
|
|
82477
|
+
* Base "chain" asset on dogecoin
|
|
82478
|
+
*
|
|
82479
|
+
* Based on definition in Thorchain `common`
|
|
82480
|
+
* @see https://gitlab.com/thorchain/thornode/-/blob/master/common/asset.go#L12-24
|
|
82481
|
+
*/
|
|
82482
|
+
const AssetDOGE = { chain: DOGEChain, symbol: 'DOGE', ticker: 'DOGE', synth: false };
|
|
82483
|
+
// https://blockchair.com/
|
|
82484
|
+
const DOGE_MAINNET_EXPLORER = new ExplorerProvider('https://blockchair.com/dogecoin', 'https://blockchair.com/dogecoin/address/%%ADDRESS%%', 'https://blockchair.com/dogecoin/transaction/%%TX_ID%%');
|
|
82485
|
+
const DOGE_TESTNET_EXPLORER = new ExplorerProvider('https://blockexplorer.one/dogecoin/testnet', 'https://blockexplorer.one/dogecoin/testnet/address/%%ADDRESS%%', 'https://blockexplorer.one/dogecoin/testnet/tx/%%TX_ID%%');
|
|
82486
|
+
const blockstreamExplorerProviders = {
|
|
82487
|
+
[Network.Testnet]: DOGE_TESTNET_EXPLORER,
|
|
82488
|
+
[Network.Stagenet]: DOGE_MAINNET_EXPLORER,
|
|
82489
|
+
[Network.Mainnet]: DOGE_MAINNET_EXPLORER,
|
|
82490
|
+
};
|
|
82491
|
+
//======================
|
|
82492
|
+
// sochain
|
|
82493
|
+
//======================
|
|
82494
|
+
const testnetSochainProvider = new SochainProvider('https://sochain.com/api/v3', 'PLACEHOLDER_APIKEY', DOGEChain, AssetDOGE, 8, SochainNetwork.DOGETEST);
|
|
82495
|
+
const mainnetSochainProvider = new SochainProvider('https://sochain.com/api/v3', 'PLACEHOLDER_APIKEY', DOGEChain, AssetDOGE, 8, SochainNetwork.DOGE);
|
|
82496
|
+
const sochainDataProviders = {
|
|
82497
|
+
[Network.Testnet]: testnetSochainProvider,
|
|
82498
|
+
[Network.Stagenet]: mainnetSochainProvider,
|
|
82499
|
+
[Network.Mainnet]: mainnetSochainProvider,
|
|
82500
|
+
};
|
|
82501
|
+
//======================
|
|
82502
|
+
// Blockcypher
|
|
82503
|
+
//======================
|
|
82504
|
+
const mainnetBlockcypherProvider = new BlockcypherProvider('https://api.blockcypher.com/v1', DOGEChain, AssetDOGE, 8, BlockcypherNetwork.DOGE);
|
|
82505
|
+
const blockcypherDataProviders = {
|
|
82506
|
+
[Network.Testnet]: undefined,
|
|
82507
|
+
[Network.Stagenet]: mainnetBlockcypherProvider,
|
|
82508
|
+
[Network.Mainnet]: mainnetBlockcypherProvider,
|
|
82509
|
+
};
|
|
82510
|
+
|
|
81016
82511
|
/*
|
|
81017
82512
|
info from:
|
|
81018
82513
|
https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/src/chainparams.cpp
|