UNPKG

send-crypto

Version:

A minimal JavaScript library / wallet for sending crypto assets

148 lines 18 kB
import BigNumber from "bignumber.js"; import * as bitcoin from "bitgo-utxo-lib"; import { List } from "immutable"; import { Insight } from "../../common/apis/insight"; import { JSONRPC, MULTICHAIN_URLS } from "../../common/apis/jsonrpc"; import { Sochain } from "../../common/apis/sochain"; import { BitgoUTXOLib } from "../../common/libraries/bitgoUtxoLib"; import { subscribeToConfirmations } from "../../lib/confirmations"; import { newPromiEvent } from "../../lib/promiEvent"; import { fallback, retryNTimes } from "../../lib/retry"; import { shuffleArray } from "../../lib/utils"; var InsightEndpoints; (function (InsightEndpoints) { // Testnet InsightEndpoints["TestnetZCash"] = "https://explorer.testnet.z.cash/api/"; // Mainnet InsightEndpoints["ZCash"] = "https://explorer.z.cash/api/"; InsightEndpoints["ZecBlockExplorer"] = "https://zecblockexplorer.com/api/"; InsightEndpoints["ZecChain"] = "https://zechain.net/api/v1/"; InsightEndpoints["BlockExplorer"] = "https://zcash.blockexplorer.com/api/"; })(InsightEndpoints || (InsightEndpoints = {})); export const _apiFallbacks = { fetchUTXO: (testnet, txHash, vOut) => testnet ? [ ...shuffleArray(() => Insight.fetchUTXO(InsightEndpoints.TestnetZCash)(txHash, vOut)), () => Sochain.fetchUTXO("ZECTEST")(txHash, vOut), ] : [ ...shuffleArray(() => Insight.fetchUTXO(InsightEndpoints.ZCash)(txHash, vOut), () => Insight.fetchUTXO(InsightEndpoints.ZecBlockExplorer)(txHash, vOut)), () => Insight.fetchUTXO(InsightEndpoints.ZecChain)(txHash, vOut), () => Insight.fetchUTXO(InsightEndpoints.BlockExplorer)(txHash, vOut), ], fetchUTXOs: (testnet, address, confirmations) => testnet ? [ ...shuffleArray(() => Insight.fetchUTXOs(InsightEndpoints.TestnetZCash)(address, confirmations)), () => Sochain.fetchUTXOs("ZECTEST")(address, confirmations), ] : [ ...shuffleArray(() => Insight.fetchUTXOs(InsightEndpoints.ZCash)(address, confirmations), () => Insight.fetchUTXOs(InsightEndpoints.ZecBlockExplorer)(address, confirmations)), () => Sochain.fetchUTXOs("ZEC")(address, confirmations), () => Insight.fetchUTXOs(InsightEndpoints.ZecChain)(address, confirmations), () => Insight.fetchUTXOs(InsightEndpoints.BlockExplorer)(address, confirmations), ], fetchTXs: (testnet, address, confirmations = 0) => testnet ? [ ...shuffleArray(() => Insight.fetchTXs(InsightEndpoints.TestnetZCash)(address, confirmations)), () => Sochain.fetchTXs("ZECTEST")(address, confirmations), ] : [ ...shuffleArray(() => Insight.fetchTXs(InsightEndpoints.ZCash)(address, confirmations), () => Insight.fetchTXs(InsightEndpoints.ZecBlockExplorer)(address, confirmations)), () => Sochain.fetchTXs("ZEC")(address, confirmations), () => Insight.fetchTXs(InsightEndpoints.ZecChain)(address, confirmations), () => Insight.fetchTXs(InsightEndpoints.BlockExplorer)(address, confirmations), ], broadcastTransaction: (testnet, hex) => testnet ? [ () => JSONRPC.broadcastTransaction(MULTICHAIN_URLS.ZECTEST)(hex), () => Insight.broadcastTransaction(InsightEndpoints.TestnetZCash)(hex), () => Sochain.broadcastTransaction("ZECTEST")(hex), ] : [ ...shuffleArray(() => Insight.broadcastTransaction(InsightEndpoints.ZCash)(hex), () => Insight.broadcastTransaction(InsightEndpoints.ZecBlockExplorer)(hex), () => Sochain.broadcastTransaction("ZEC")(hex)), () => Insight.broadcastTransaction(InsightEndpoints.ZecChain)(hex), () => Insight.broadcastTransaction(InsightEndpoints.BlockExplorer)(hex), () => JSONRPC.broadcastTransaction(MULTICHAIN_URLS.ZEC)(hex), ], }; export class ZECHandler { privateKey; testnet; decimals = 8; static getUTXOs = async (testnet, options) => { const confirmations = options && options.confirmations !== undefined ? options.confirmations : 0; return fallback(_apiFallbacks.fetchUTXOs(testnet, options.address, confirmations)); }; static getUTXO = async (testnet, txHash, vOut) => { const endpoints = _apiFallbacks.fetchUTXO(testnet, txHash, vOut); return fallback(endpoints); }; static getTransactions = async (testnet, options) => { const confirmations = options && options.confirmations !== undefined ? options.confirmations : 0; const endpoints = _apiFallbacks.fetchTXs(testnet, options.address, confirmations); return fallback(endpoints); }; constructor(privateKey, network) { this.testnet = network !== "mainnet"; this.privateKey = BitgoUTXOLib.loadPrivateKey(this.testnet ? bitcoin.networks.zcashTest : bitcoin.networks.zcash, privateKey); } // Returns whether or not this can handle the asset handlesAsset = (asset) => typeof asset === "string" && ["ZEC", "ZCASH"].indexOf(asset.toUpperCase()) !== -1; address = async (asset, options) => this.privateKey.getAddress(); // Balance getBalance = async (asset, options) => (await this.getBalanceInSats(asset, options)).dividedBy(new BigNumber(10).exponentiatedBy(this.decimals)); getBalanceInSats = async (asset, options) => { const utxos = await ZECHandler.getUTXOs(this.testnet, { ...options, address: (options && options.address) || (await this.address(asset)), }); return utxos.reduce((sum, utxo) => sum.plus(utxo.amount), new BigNumber(0)); }; // Transfer send = (to, value, asset, options) => this.sendSats(to, value.times(new BigNumber(10).exponentiatedBy(this.decimals)), asset, options); sendSats = (to, valueIn, asset, options) => { const promiEvent = newPromiEvent(); let txHash; let errored; (async () => { const fromAddress = await this.address(asset); const changeAddress = fromAddress; const utxos = List(await ZECHandler.getUTXOs(this.testnet, { ...options, address: fromAddress, })) .sortBy((utxo) => utxo.amount) .reverse() .toArray(); if (this.testnet) { // tslint:disable-next-line: no-object-mutation bitcoin.networks.zcashTest.consensusBranchId["4"] = 37519621; } const built = await BitgoUTXOLib.buildUTXO(this.testnet ? bitcoin.networks.zcashTest : bitcoin.networks.zcash, this.privateKey, changeAddress, to, valueIn, utxos, { ...options, version: 4, versionGroupID: 0x892f2085, consensusBranchId: 0x37519621, }); txHash = await retryNTimes(() => fallback(_apiFallbacks.broadcastTransaction(this.testnet, built.toHex())), 3); promiEvent.emit("transactionHash", txHash); promiEvent.resolve(txHash); })().catch((error) => { errored = true; promiEvent.reject(error); }); subscribeToConfirmations(promiEvent, () => errored, async () => (txHash ? this._getConfirmations(txHash) : 0)); return promiEvent; }; _getConfirmations = async (txHash) => (await fallback( // Fetch confirmations for first output of transaction. _apiFallbacks.fetchUTXO(this.testnet, txHash, 0))).confirmations; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiWkVDSGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9oYW5kbGVycy9aRUMvWkVDSGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLFNBQVMsTUFBTSxjQUFjLENBQUM7QUFDckMsT0FBTyxLQUFLLE9BQU8sTUFBTSxnQkFBZ0IsQ0FBQztBQUMxQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRWpDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDbkUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDbkUsT0FBTyxFQUFFLGFBQWEsRUFBYyxNQUFNLHNCQUFzQixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDeEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBYy9DLElBQUssZ0JBUUo7QUFSRCxXQUFLLGdCQUFnQjtJQUNqQixVQUFVO0lBQ1YseUVBQXFELENBQUE7SUFDckQsVUFBVTtJQUNWLDBEQUFzQyxDQUFBO0lBQ3RDLDBFQUFzRCxDQUFBO0lBQ3RELDREQUF3QyxDQUFBO0lBQ3hDLDBFQUFzRCxDQUFBO0FBQzFELENBQUMsRUFSSSxnQkFBZ0IsS0FBaEIsZ0JBQWdCLFFBUXBCO0FBRUQsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUFHO0lBQ3pCLFNBQVMsRUFBRSxDQUFDLE9BQWdCLEVBQUUsTUFBYyxFQUFFLElBQVksRUFBRSxFQUFFLENBQzFELE9BQU87UUFDSCxDQUFD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