UNPKG

@thorwallet/xchain-bitcoin

Version:

Custom Bitcoin client and utilities used by XChainJS clients

196 lines 6.81 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getSuggestedTxFee = exports.getConfirmedUnspentTxs = exports.getIsTxConfirmed = exports.getUnspentTxs = exports.getBalance = exports.getTx = exports.getAddress = void 0; const tslib_1 = require("tslib"); const axios_1 = tslib_1.__importDefault(require("axios")); const xchain_util_1 = require("@thorwallet/xchain-util"); const utils_1 = require("./utils"); const DEFAULT_SUGGESTED_TRANSACTION_FEE = 127; const toSochainNetwork = (net) => { return net === 'testnet' ? 'BTCTEST' : 'BTC'; }; /** * Get address information. * * @see https://sochain.com/api#get-display-data-address * * @param {string} sochainUrl The sochain node url. * @param {string} network * @param {string} address * @returns {BtcAddressDTO} */ const getAddress = ({ sochainUrl, network, address }) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { try { const url = `${sochainUrl}/address/${toSochainNetwork(network)}/${address}`; const response = yield axios_1.default.get(url); const addressResponse = response.data; return addressResponse.data; } catch (error) { return Promise.reject(error); } }); exports.getAddress = getAddress; /** * Get transaction by hash. * * @see https://sochain.com/api#get-tx * * @param {string} sochainUrl The sochain node url. * @param {string} network network id * @param {string} hash The transaction hash. * @returns {Transactions} */ const getTx = ({ sochainUrl, network, hash }) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { try { const url = `${sochainUrl}/get_tx/${toSochainNetwork(network)}/${hash.toLowerCase()}`; const response = yield axios_1.default.get(url); const tx = response.data; return tx.data; } catch (error) { return Promise.reject(error); } }); exports.getTx = getTx; /** * Get address balance. * * @see https://sochain.com/api#get-balance * * @param {string} sochainUrl The sochain node url. * @param {string} network * @param {string} address * @returns {number} */ const getBalance = ({ sochainUrl, network, address }) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { try { const url = `${sochainUrl}/get_address_balance/${toSochainNetwork(network)}/${address}`; const response = yield axios_1.default.get(url); const balanceResponse = response.data; const confirmed = xchain_util_1.assetAmount(balanceResponse.data.confirmed_balance, utils_1.BTC_DECIMAL); const unconfirmed = xchain_util_1.assetAmount(balanceResponse.data.unconfirmed_balance, utils_1.BTC_DECIMAL); const netAmt = confirmed.amount().plus(unconfirmed.amount()); const result = xchain_util_1.assetToBase(xchain_util_1.assetAmount(netAmt, utils_1.BTC_DECIMAL)); return result; } catch (error) { return Promise.reject(error); } }); exports.getBalance = getBalance; /** * Get unspent txs * * @see https://sochain.com/api#get-unspent-tx * * @param {string} sochainUrl The sochain node url. * @param {string} network * @param {string} address * @returns {BtcAddressUTXOs} */ const getUnspentTxs = ({ sochainUrl, network, address, startingFromTxId, }) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { try { let resp = null; if (startingFromTxId) { resp = yield axios_1.default.get(`${sochainUrl}/get_tx_unspent/${toSochainNetwork(network)}/${address}/${startingFromTxId}`); } else { resp = yield axios_1.default.get(`${sochainUrl}/get_tx_unspent/${toSochainNetwork(network)}/${address}`); } const response = resp.data; const txs = response.data.txs; if (txs.length === 100) { //fetch the next batch const lastTxId = txs[99].txid; const nextBatch = yield exports.getUnspentTxs({ sochainUrl, network, address, startingFromTxId: lastTxId, }); return txs.concat(nextBatch); } else { return txs; } } catch (error) { return Promise.reject(error); } }); exports.getUnspentTxs = getUnspentTxs; /** * Get Tx Confirmation status * * @see https://sochain.com/api#get-is-tx-confirmed * * @param {string} sochainUrl The sochain node url. * @param {string} network mainnet | testnet * @param {string} hash tx id * @returns {TxConfirmedStatus} */ const getIsTxConfirmed = ({ sochainUrl, network, hash }) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { try { const { data } = yield axios_1.default.get(`${sochainUrl}/is_tx_confirmed/${toSochainNetwork(network)}/${hash.toLowerCase()}`); return data.data; } catch (error) { return Promise.reject(error); } }); exports.getIsTxConfirmed = getIsTxConfirmed; /** * Get unspent txs and filter out pending UTXOs * * @see https://sochain.com/api#get-unspent-tx * * @param {string} sochainUrl The sochain node url. * @param {string} network * @param {string} address * @returns {BtcAddressUTXOs} */ const getConfirmedUnspentTxs = ({ sochainUrl, network, address, }) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { try { const txs = yield exports.getUnspentTxs({ sochainUrl, network, address, }); const confirmedUTXOs = []; yield Promise.all(txs.map((tx) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { const { is_confirmed: isTxConfirmed } = yield exports.getIsTxConfirmed({ sochainUrl, network, hash: tx.txid, }); if (isTxConfirmed) { confirmedUTXOs.push(tx); } }))); return confirmedUTXOs; } catch (error) { return Promise.reject(error); } }); exports.getConfirmedUnspentTxs = getConfirmedUnspentTxs; /** * Get Bitcoin suggested transaction fee. * * @returns {number} The Bitcoin suggested transaction fee per bytes in sat. */ const getSuggestedTxFee = () => tslib_1.__awaiter(void 0, void 0, void 0, function* () { //Note: sochain does not provide fee rate related data //So use Bitgo API for fee estimation //Refer: https://app.bitgo.com/docs/#operation/v2.tx.getfeeestimate try { const response = yield axios_1.default.get('https://app.bitgo.com/api/v2/btc/tx/fee'); return response.data.feePerKb / 1000; // feePerKb to feePerByte } catch (error) { return DEFAULT_SUGGESTED_TRANSACTION_FEE; } }); exports.getSuggestedTxFee = getSuggestedTxFee; //# sourceMappingURL=sochain-api.js.map