UNPKG

@xchainjs/xchain-utxo

Version:
359 lines (349 loc) 14.6 kB
'use strict'; var xchainClient = require('@xchainjs/xchain-client'); var xchainUtil = require('@xchainjs/xchain-util'); /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */ function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; /** * Abstract base class for creating blockchain clients in the UTXO model. */ class Client extends xchainClient.BaseXChainClient { /** * Constructor for creating a UTXO client instance. * * @param {Chain} chain The blockchain chain type. * @param {UtxoClientParams} params The parameters required for client initialization. */ constructor(chain, params) { super(chain, { network: params.network, rootDerivationPaths: params.rootDerivationPaths, phrase: params.phrase, feeBounds: params.feeBounds, }); this.explorerProviders = params.explorerProviders; this.dataProviders = params.dataProviders; } /** * Get the explorer URL based on the network. * * @returns {string} The explorer URL. */ getExplorerUrl() { return this.explorerProviders[this.network].getExplorerUrl(); } /** * Get the explorer URL for a given address based on the network. * * @param {string} address The address to query. * @returns {string} The explorer URL for the address. */ getExplorerAddressUrl(address) { return this.explorerProviders[this.network].getExplorerAddressUrl(address); } /** * Get the explorer URL for a given transaction ID based on the network. * * @param {string} txID The transaction ID. * @returns {string} The explorer URL for the transaction. */ getExplorerTxUrl(txID) { return this.explorerProviders[this.network].getExplorerTxUrl(txID); } /** * Get the transaction history of a given address with pagination options. * * @param {TxHistoryParams} params The options to get transaction history. * @returns {TxsPage} The transaction history. */ getTransactions(params) { return __awaiter(this, void 0, void 0, function* () { // Filter the parameters for transaction history const filteredParams = { address: (params === null || params === void 0 ? void 0 : params.address) || (yield this.getAddress()), offset: params === null || params === void 0 ? void 0 : params.offset, limit: params === null || params === void 0 ? void 0 : params.limit, startTime: params === null || params === void 0 ? void 0 : params.startTime, asset: params === null || params === void 0 ? void 0 : params.asset, }; return yield this.roundRobinGetTransactions(filteredParams); }); } /** * Get the transaction details of a given transaction ID. * * @param {string} txId The transaction ID. * @returns {Tx} The transaction details. */ getTransactionData(txId) { return __awaiter(this, void 0, void 0, function* () { return yield this.roundRobinGetTransactionData(txId); }); } /** * Gets balance of a given address. * * @param {Address} address The address to get balances from * @param {undefined} Needed for legacy only to be in common with `XChainClient` interface - will be removed by a next version * @param {confirmedOnly} Flag to get balances of confirmed txs only * * @returns {Balance[]} BTC balances */ // TODO (@xchain-team|@veado) Change params to be an object to be extendable more easily // see changes for `xchain-bitcoin` https://github.com/xchainjs/xchainjs-lib/pull/490 getBalance(address, _assets /* not used */, confirmedOnly) { return __awaiter(this, void 0, void 0, function* () { return yield this.roundRobinGetBalance(address); }); } /** * Scan UTXOs for a given address. * * @param {string} address The address to scan. * @param {boolean} confirmedOnly Flag to scan only confirmed UTXOs. * @returns {UTXO[]} The UTXOs found. */ scanUTXOs(address, confirmedOnly = true) { return __awaiter(this, void 0, void 0, function* () { return this.roundRobinGetUnspentTxs(address, confirmedOnly); }); } /** * Get estimated fees with fee rates. * * @param {FeeEstimateOptions} options Options for fee estimation. * @returns {Promise<FeesWithRates>} Estimated fees along with fee rates. */ getFeesWithRates(options) { return __awaiter(this, void 0, void 0, function* () { // Scan UTXOs if sender address is provided const utxos = (options === null || options === void 0 ? void 0 : options.sender) ? yield this.scanUTXOs(options.sender, false) : []; // Compile memo if memo is provided const compiledMemo = (options === null || options === void 0 ? void 0 : options.memo) ? this.compileMemo(options.memo) : null; // Get fee rates const rates = yield this.getFeeRates(); return { fees: { average: xchainUtil.baseAmount(this.getFeeFromUtxos(utxos, rates.average, compiledMemo)), fast: xchainUtil.baseAmount(this.getFeeFromUtxos(utxos, rates.fast, compiledMemo)), fastest: xchainUtil.baseAmount(this.getFeeFromUtxos(utxos, rates.fastest, compiledMemo)), type: xchainClient.FeeType.PerByte, }, rates, }; }); } /** * Get estimated fees. * * @param {FeeEstimateOptions} options Options for fee estimation. * @returns {Promise<Fees>} Estimated fees. */ getFees(options) { return __awaiter(this, void 0, void 0, function* () { const { fees } = yield this.getFeesWithRates(options); return fees; }); } /** * Get fee rates * @param {Protocol} protocol Protocol to interact with. If there's no protocol provided, fee rates are retrieved from chain data providers * * @returns {FeeRates} The fee rates (average, fast, fastest) in `Satoshis/byte` */ getFeeRates(protocol) { return __awaiter(this, void 0, void 0, function* () { if (!protocol) { try { const feeRates = yield this.roundRobinGetFeeRates(); return feeRates; } catch (error) { console.warn('Can not retrieve fee rates from provider'); } } if (!protocol || xchainClient.Protocol.THORCHAIN) { try { const feeRate = yield this.getFeeRateFromThorchain(); return xchainClient.standardFeeRates(feeRate); } catch (error) { console.warn(`Can not retrieve fee rates from Thorchain`); } } // TODO: Return default value throw Error('Can not retrieve fee rates'); }); } /** * Broadcast a transaction. * * @param {string} txHex The transaction hex string. * @returns {Promise<TxHash>} The transaction hash. */ broadcastTx(txHex) { return __awaiter(this, void 0, void 0, function* () { return yield this.roundRobinBroadcastTx(txHex); }); } /** * Round-robin method to get balance from data providers. * Throws error if no provider can get balance. * * @param {Address} address The address to get balance for. * @returns {Promise<Balance[]>} The balances. * @throws Error If no provider is able to get balance. */ roundRobinGetBalance(address) { return __awaiter(this, void 0, void 0, function* () { for (const provider of this.dataProviders) { try { const prov = provider[this.network]; if (prov) return yield prov.getBalance(address); } catch (error) { console.warn(error); } } throw Error('no provider able to get balance'); }); } /** * Round-robin method to get unspent transactions from data providers. * Throws error if no provider can get unspent transactions. * * @param {Address} address The address to get unspent transactions for. * @param {boolean} confirmed Flag to indicate whether to get confirmed transactions only. * @returns {Promise<UTXO[]>} The unspent transactions. * @throws Error If no provider is able to get unspent transactions. */ roundRobinGetUnspentTxs(address, confirmed) { return __awaiter(this, void 0, void 0, function* () { for (const provider of this.dataProviders) { try { const prov = provider[this.network]; if (prov) { return confirmed ? yield prov.getConfirmedUnspentTxs(address) : yield prov.getUnspentTxs(address); } } catch (error) { console.warn(error); } } throw Error('no provider able to GetUnspentTxs'); }); } /** * Round-robin method to get transaction data from data providers. * Throws error if no provider can get transaction data. * * @param {string} txid The transaction ID to get data for. * @returns {Promise<Tx>} The transaction data. * @throws Error If no provider is able to get transaction data. */ roundRobinGetTransactionData(txid) { return __awaiter(this, void 0, void 0, function* () { for (const provider of this.dataProviders) { try { const prov = provider[this.network]; if (prov) return yield prov.getTransactionData(txid); } catch (error) { console.warn(error); } } throw Error('no provider able to GetTransactionData'); }); } /** * Round-robin method to get transactions from data providers. * Throws error if no provider can get transactions. * * @param {TxHistoryParams} params The parameters for fetching transactions. * @returns {Promise<TxsPage>} The transaction history. * @throws Error If no provider is able to get transactions. */ roundRobinGetTransactions(params) { return __awaiter(this, void 0, void 0, function* () { for (const provider of this.dataProviders) { try { const prov = provider[this.network]; if (prov) return yield prov.getTransactions(params); } catch (error) { console.warn(error); } } throw Error('no provider able to GetTransactions'); }); } /** * Broadcasts a transaction hex using a round-robin approach across multiple data providers. * @param {string} txHex The transaction hex to broadcast. * @returns {Promise<TxHash>} The hash of the broadcasted transaction. * @throws {Error} Throws an error if no provider is able to broadcast the transaction. */ roundRobinBroadcastTx(txHex) { return __awaiter(this, void 0, void 0, function* () { for (const provider of this.dataProviders) { try { const prov = provider[this.network]; if (prov) return yield prov.broadcastTx(txHex); } catch (error) { console.warn(error); } } throw Error('no provider able to BroadcastTx'); }); } /** * Retrieves fee rates using a round-robin approach across multiple data providers. * @returns {Promise<FeeRates>} The fee rates (average, fast, fastest) in `Satoshis/byte`. * @throws {Error} Throws an error if no provider is able to retrieve fee rates. */ roundRobinGetFeeRates() { return __awaiter(this, void 0, void 0, function* () { for (const provider of this.dataProviders) { try { const prov = provider[this.network]; if (prov) return yield prov.getFeeRates(); } catch (error) { console.warn(error); } } throw Error('no provider able to get fee rates'); }); } } exports.Client = Client; //# sourceMappingURL=index.js.map