UNPKG

send-crypto

Version:

A minimal JavaScript library / wallet for sending crypto assets

167 lines 18 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.BCHHandler = exports._apiFallbacks = void 0; const bchaddrjs_1 = require("bchaddrjs"); const bignumber_js_1 = __importDefault(require("bignumber.js")); const bitcoin = __importStar(require("bitgo-utxo-lib")); const immutable_1 = require("immutable"); const bitcoinDotCom_1 = require("../../common/apis/bitcoinDotCom"); const blockchain_1 = require("../../common/apis/blockchain"); const blockchair_1 = require("../../common/apis/blockchair"); const insight_1 = require("../../common/apis/insight"); const jsonrpc_1 = require("../../common/apis/jsonrpc"); const bitgoUtxoLib_1 = require("../../common/libraries/bitgoUtxoLib"); const confirmations_1 = require("../../lib/confirmations"); const promiEvent_1 = require("../../lib/promiEvent"); const retry_1 = require("../../lib/retry"); const testnetInsight = "https://api.bitcore.io/api/BCH/testnet/"; const mainnetInsight = "https://api.bitcore.io/api/BCH/mainnet/"; const toCashAddr = (legacyAddress) => { try { return (0, bchaddrjs_1.toCashAddress)(legacyAddress); } catch (error) { return legacyAddress; } }; exports._apiFallbacks = { fetchUTXO: (testnet, txHash, vOut) => [ () => blockchain_1.Blockchain.fetchUTXO(testnet ? blockchain_1.BlockchainNetwork.BitcoinCashTestnet : blockchain_1.BlockchainNetwork.BitcoinCash)(txHash, vOut), () => insight_1.Insight.fetchUTXO(testnet ? testnetInsight : mainnetInsight)(txHash, vOut), () => bitcoinDotCom_1.BitcoinDotCom.fetchUTXO(testnet)(txHash, vOut), testnet ? undefined : () => blockchair_1.Blockchair.fetchUTXO(blockchair_1.Blockchair.networks.BITCOIN_CASH)(txHash, vOut), ], fetchUTXOs: (testnet, address, confirmations) => [ () => blockchain_1.Blockchain.fetchUTXOs(testnet ? blockchain_1.BlockchainNetwork.BitcoinCashTestnet : blockchain_1.BlockchainNetwork.BitcoinCash)(address, confirmations), () => insight_1.Insight.fetchUTXOs(testnet ? testnetInsight : mainnetInsight)(address, confirmations), () => bitcoinDotCom_1.BitcoinDotCom.fetchUTXOs(testnet)(address, confirmations), testnet ? undefined : () => blockchair_1.Blockchair.fetchUTXOs(blockchair_1.Blockchair.networks.BITCOIN_CASH)(address, confirmations), ], fetchTXs: (testnet, address, confirmations = 0) => [ () => blockchain_1.Blockchain.fetchTXs(testnet ? blockchain_1.BlockchainNetwork.BitcoinCashTestnet : blockchain_1.BlockchainNetwork.BitcoinCash)(address, confirmations), () => insight_1.Insight.fetchTXs(testnet ? testnetInsight : mainnetInsight)(address, confirmations), // () => BitcoinDotCom.fetchTXs(testnet)(address, confirmations), testnet ? undefined : () => blockchair_1.Blockchair.fetchTXs(blockchair_1.Blockchair.networks.BITCOIN_CASH)(address, confirmations), ], broadcastTransaction: (testnet, hex) => [ () => jsonrpc_1.JSONRPC.broadcastTransaction(testnet ? jsonrpc_1.MULTICHAIN_URLS.BCHTEST : jsonrpc_1.MULTICHAIN_URLS.BCH)(hex), () => insight_1.Insight.broadcastTransaction(testnet ? testnetInsight : mainnetInsight)(hex), () => bitcoinDotCom_1.BitcoinDotCom.broadcastTransaction(testnet)(hex), testnet ? undefined : () => blockchair_1.Blockchair.broadcastTransaction(blockchair_1.Blockchair.networks.BITCOIN_CASH)(hex), ], }; class BCHHandler { constructor(privateKey, network) { this.decimals = 8; // Returns whether or not this can handle the asset this.handlesAsset = (asset) => typeof asset === "string" && ["BCH", "BITCOIN CASH", "BCASH", "BITCOINCASH", "BITCOIN-CASH"].indexOf(asset.toUpperCase()) !== -1; this.address = async (asset, options) => toCashAddr(this.privateKey.getAddress()); // Balance this.getBalance = async (asset, options) => (await this.getBalanceInSats(asset, options)).dividedBy(new bignumber_js_1.default(10).exponentiatedBy(this.decimals)); this.getBalanceInSats = async (asset, options) => { const utxos = await BCHHandler.getUTXOs(this.testnet, Object.assign(Object.assign({}, options), { address: (options && options.address) || (await this.address(asset)) })); return utxos.reduce((sum, utxo) => sum.plus(utxo.amount), new bignumber_js_1.default(0)); }; // Transfer this.send = (to, value, asset, options) => this.sendSats(to, value.times(new bignumber_js_1.default(10).exponentiatedBy(this.decimals)), asset, options); this.sendSats = (to, valueIn, asset, options) => { const promiEvent = (0, promiEvent_1.newPromiEvent)(); let txHash; let errored; (async () => { const fromAddress = (0, bchaddrjs_1.toLegacyAddress)(await this.address(asset)); const toAddress = (0, bchaddrjs_1.toLegacyAddress)(to); const changeAddress = fromAddress; const utxos = (0, immutable_1.List)(await BCHHandler.getUTXOs(this.testnet, Object.assign(Object.assign({}, options), { address: fromAddress }))) .sortBy((utxo) => utxo.amount) .reverse() .toArray(); const built = await bitgoUtxoLib_1.BitgoUTXOLib.buildUTXO(this._bitgoNetwork(), this.privateKey, changeAddress, toAddress, valueIn, utxos, Object.assign(Object.assign({}, options), { signFlag: // bitcoin.Transaction.SIGHASH_ALL | // tslint:disable-next-line: no-bitwise bitcoin.Transaction.SIGHASH_SINGLE | bitcoin.Transaction.SIGHASH_BITCOINCASHBIP143 })); txHash = await (0, retry_1.retryNTimes)(() => (0, retry_1.fallback)(exports._apiFallbacks.broadcastTransaction(this.testnet, built.toHex())), 3); promiEvent.emit("transactionHash", txHash); promiEvent.resolve(txHash); })().catch((error) => { errored = true; promiEvent.reject(error); }); (0, confirmations_1.subscribeToConfirmations)(promiEvent, () => errored, async () => (txHash ? this._getConfirmations(txHash) : 0)); return promiEvent; }; this._getConfirmations = async (txHash) => (await (0, retry_1.fallback)( // Fetch confirmations for first output of transaction. exports._apiFallbacks.fetchUTXO(this.testnet, txHash, 0))).confirmations; this._bitgoNetwork = () => this.testnet ? bitcoin.networks.bitcoincashTestnet : bitcoin.networks.bitcoincash; this.testnet = network !== "mainnet"; this.privateKey = bitgoUtxoLib_1.BitgoUTXOLib.loadPrivateKey(this._bitgoNetwork(), privateKey); } } exports.BCHHandler = BCHHandler; _a = BCHHandler; BCHHandler.getUTXOs = async (testnet, options) => { const address = toCashAddr(options.address); const confirmations = options.confirmations || 0; const endpoints = exports._apiFallbacks.fetchUTXOs(testnet, address, confirmations); const utxos = await (0, retry_1.fallback)(endpoints); return utxos; }; BCHHandler.getUTXO = async (testnet, txHash, vOut) => { const endpoints = exports._apiFallbacks.fetchUTXO(testnet, txHash, vOut); return (0, retry_1.fallback)(endpoints); }; BCHHandler.getTransactions = async (testnet, options) => { const address = toCashAddr(options.address); const confirmations = options && options.confirmations !== undefined ? options.confirmations : 0; const endpoints = exports._apiFallbacks.fetchTXs(testnet, address, confirmations); return (0, retry_1.fallback)(endpoints); }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQkNISGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9oYW5kbGVycy9CQ0gvQkNISGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx5Q0FBMkQ7QUFDM0QsZ0VBQXFDO0FBQ3JDLHdEQUEwQztBQUMxQyx5Q0FBaUM7QUFFakMsbUVBQWdFO0FBQ2hFLDZEQUE2RTtBQUM3RSw2REFBMEQ7QUFDMUQsdURBQW9EO0FBQ3BELHVEQUFxRTtBQUNyRSxzRUFBbUU7QUFDbkUsMkRBQW1FO0FBQ25FLHFEQUFpRTtBQUNqRSwyQ0FBd0Q7QUFJeEQsTUFBTSxjQUFjLEdBQUcseUNBQXlDLENBQUM7QUFDakUsTUFBTSxjQUFjLEdBQUcseUNBQXlDLENBQUM7QUFZakUsTUFBTSxVQUFVLEdBQUcsQ0FBQyxhQUFxQixFQUFFLEVBQUU7SUFDekMsSUFBSTtRQUNBLE9BQU8sSUFBQSx5QkFBYSxFQUFDLGFBQWEsQ0FBQyxDQUFDO0tBQ3ZDO0lBQUMsT0FBTyxLQUFVLEVBQUU7UUFDakIsT0FBTyxhQUFhLENBQUM7S0FDeEI7QUFDTCxDQUFDLENBQUM7QUFFVyxRQUFBLGFBQWEsR0FBRztJQUN6QixTQUFTLEVBQUUsQ0FBQyxPQUFnQixFQUFFLE1BQWMsRUFBRSxJQUFZLEVBQUUsRUFBRSxDQUFDO1FBQzNELEdBQUcsRUFBRSxDQUNELHVCQUFVLENBQUMsU0FBUyxDQUNoQixPQUFPO1lBQ0gsQ0FBQyxDQUFDLDhCQUFpQixDQUFDLGtCQUFrQjtZQUN0QyxDQUFDLENBQUMsOEJBQWlCLENBQUMsV0FBVyxDQUN0QyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUM7UUFDbkIsR0FBRyxFQUFFLENBQ0QsaUJBQU8sQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUN4RCxNQUFNLEVBQ04sSUFBSSxD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