UNPKG

crypto-convert

Version:

Convert crypto to fiat and vice-versa instantly.

306 lines (304 loc) 14.8 kB
"use strict"; /*! * crypto-convert (c) 2022 * Author: Elis * License: https://github.com/coinconvert/crypto-convert */ var __awaiter = (this && this.__awaiter) || function (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()); }); }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var _CryptoConvert_instances, _CryptoConvert_getPrice, _CryptoConvert_wrapper, _CryptoConvert_isSafeKey, _CryptoConvert_setExtendedOptions, _CryptoConvert_populate; Object.defineProperty(exports, "__esModule", { value: true }); const helpers_1 = require("./helpers"); const worker_1 = __importDefault(require("./worker")); const custom_1 = __importDefault(require("./custom")); const customWorkers = new custom_1.default(); class CryptoConvert { constructor(options = {}) { _CryptoConvert_instances.add(this); this.precision = { fiat: 4, crypto: 8 }; if (helpers_1.isBrowser) { if (window['__ccInitialized']) { throw new Error("You have already initalized one instance of crypto-convert. You cannot initialize multiple instances."); } window['__ccInitialized'] = true; } __classPrivateFieldGet(this, _CryptoConvert_instances, "m", _CryptoConvert_setExtendedOptions).call(this, options); this.worker = new worker_1.default(options); this.workerReady = this.worker.run(); this.internalMethods = Object.getOwnPropertyNames(CryptoConvert.prototype); Promise.resolve(this.workerReady).then(() => { __classPrivateFieldGet(this, _CryptoConvert_instances, "m", _CryptoConvert_populate).call(this); this.worker.onCryptoListRefresh = () => { __classPrivateFieldGet(this, _CryptoConvert_instances, "m", _CryptoConvert_populate).call(this); }; }); } ; /** * Quick check if cache has loaded. */ get isReady() { return this.worker.isReady; } /** * Supported currencies list */ get list() { return { 'crypto': this.worker.list.crypto.concat(customWorkers.list), 'fiat': this.worker.list.fiat }; } /** * Metadata information about cryptocurrencies */ get cryptoInfo() { return this.worker.cryptoInfo; } /** * Get crypto prices last updated ms */ get lastUpdated() { return this.worker.data.crypto.last_updated; } /** * Price Tickers */ get ticker() { return this.worker.data; } /** * Update options */ setOptions(options) { __classPrivateFieldGet(this, _CryptoConvert_instances, "m", _CryptoConvert_setExtendedOptions).call(this, options); const workerIntervalChanged = (options.cryptoInterval || options.fiatInterval) && (options.cryptoInterval !== this.worker.options.cryptoInterval || options.fiatInterval !== this.worker.options.fiatInterval); if (workerIntervalChanged || (options.hasOwnProperty('refreshCryptoList') && options.refreshCryptoList !== this.worker.options.refreshCryptoList) || (options.hasOwnProperty('useHostedAPI') && options.useHostedAPI !== this.worker.options.useHostedAPI) || (options.listLimit && options.listLimit != this.worker.options.listLimit)) { if (!this.worker.isReady) { throw new Error("You cannot set these options here because CryptoConvert is not ready yet. Instead set the options on the constructor parameter."); } //Restart the worker in order to clear interval & update to new interval this.workerReady = Promise.resolve(this.worker.setOptions(options)) .then(() => __awaiter(this, void 0, void 0, function* () { yield this.worker.restart(); if (options.listLimit) { __classPrivateFieldGet(this, _CryptoConvert_instances, "m", _CryptoConvert_populate).call(this); } return this.worker; })); return this.worker; } return this.worker.setOptions(options); } /** * Stop the worker. * * It's recommended to do this on Component unmounts (i.e if you are using React). */ stop() { return this.worker.stop(); } /** * Re-start the worker when it has been stopped. */ restart() { this.workerReady = this.worker.restart(); return this.workerReady; } /** * Promise function that resolves when cache has loaded. */ ready() { return __awaiter(this, void 0, void 0, function* () { yield Promise.resolve(this.workerReady); yield Promise.resolve(customWorkers.ready()); return this; }); } /** * Add a custom currency fetcher. Can be anything. * * @example * ```javascript * convert.addCurrency('ANY','USD', async fetchPrice()=>{ * //...call your api here * return price; * }, 10000); * ``` */ addCurrency(base, ...rest) { return __awaiter(this, void 0, void 0, function* () { if (this.hasOwnProperty(base)) { throw new Error("This property already exists."); } return Promise.resolve(customWorkers.addCurrency.apply(customWorkers, [base, ...rest])).then(() => { if (this.worker.isReady) { __classPrivateFieldGet(this, _CryptoConvert_instances, "m", _CryptoConvert_populate).call(this); } }); }); } ; /** * Remove custom currency fetcher. */ removeCurrency(base, quote) { var _a, _b; if (customWorkers.list.includes(base) && __classPrivateFieldGet(this, _CryptoConvert_instances, "m", _CryptoConvert_isSafeKey).call(this, base)) { delete this[base]; const all_currencies = this.worker.list.crypto.concat(this.worker.list.fiat, customWorkers.list); for (const currency of all_currencies) { if ((_a = this[currency]) === null || _a === void 0 ? void 0 : _a[base]) { (_b = this[currency]) === null || _b === void 0 ? true : delete _b[base]; } } } return customWorkers.removeCurrency(base, quote); } } _CryptoConvert_instances = new WeakSet(), _CryptoConvert_getPrice = function _CryptoConvert_getPrice(coin, to = 'USD') { var customResult = customWorkers.ticker[coin + to] || (customWorkers.ticker[to + coin] ? 1 / customWorkers.ticker[to + coin] : null); var result = this.worker.data.crypto.current[coin + to] || (this.worker.data.crypto.current[to + coin] ? 1 / this.worker.data.crypto.current[to + coin] : null); return customResult || result; }, _CryptoConvert_wrapper = function _CryptoConvert_wrapper(coin, currency) { var coin = coin; var toCurrency = currency; const doExchange = (function (fromAmount) { if ((0, helpers_1.isEmpty)(this.worker.data.crypto.current) || (0, helpers_1.isEmpty)(this.worker.data.fiat.current)) { console.warn("[~] Prices are loading.\nYou should use `await convert.ready()` to make sure prices are loaded before calling convert."); return false; } if (!fromAmount) { return false; } fromAmount = (0, helpers_1.formatNumber)(fromAmount); if (isNaN(fromAmount)) { return false; } const fiatCurrencies = this.worker.data.fiat.current; const cryptoCurrenciesList = this.worker.list.crypto.concat(customWorkers.list); //Same if (toCurrency == coin) { return fromAmount; } //Crypto to Crypto if (cryptoCurrenciesList.includes(coin) && cryptoCurrenciesList.includes(toCurrency)) { let exchangePrice = __classPrivateFieldGet(this, _CryptoConvert_instances, "m", _CryptoConvert_getPrice).call(this, coin, toCurrency) || __classPrivateFieldGet(this, _CryptoConvert_instances, "m", _CryptoConvert_wrapper).call(this, "USD", toCurrency)(__classPrivateFieldGet(this, _CryptoConvert_instances, "m", _CryptoConvert_wrapper).call(this, coin, "USD")(1)); return (0, helpers_1.formatNumber)(exchangePrice * fromAmount, this.precision.crypto); } //Fiat to Fiat if (fiatCurrencies[coin] && fiatCurrencies[toCurrency]) { return (0, helpers_1.formatNumber)(((fromAmount / fiatCurrencies[coin]) * fiatCurrencies[toCurrency]), this.precision.fiat); } //Crypto->Fiat || Crypto->BTC->Fiat var getCryptoPrice = (function (coin) { var coinPrice = __classPrivateFieldGet(this, _CryptoConvert_instances, "m", _CryptoConvert_getPrice).call(this, coin) || __classPrivateFieldGet(this, _CryptoConvert_instances, "m", _CryptoConvert_wrapper).call(this, "BTC", "USD")(__classPrivateFieldGet(this, _CryptoConvert_instances, "m", _CryptoConvert_getPrice).call(this, coin, "BTC")) || __classPrivateFieldGet(this, _CryptoConvert_instances, "m", _CryptoConvert_wrapper).call(this, "ETH", "USD")(__classPrivateFieldGet(this, _CryptoConvert_instances, "m", _CryptoConvert_getPrice).call(this, coin, "ETH")); return coinPrice; }).bind(this); //Crypto to Fiat if (fiatCurrencies[toCurrency]) { let usdPrice = getCryptoPrice(coin); let exchangePrice = (usdPrice / fiatCurrencies['USD']) * fiatCurrencies[toCurrency]; //Convert USD to chosen FIAT return (0, helpers_1.formatNumber)(exchangePrice * fromAmount, this.precision.crypto); } //Fiat to Crypto if (fiatCurrencies[coin]) { let usdPrice = getCryptoPrice(toCurrency); let exchangePrice = (usdPrice / fiatCurrencies['USD']) * fiatCurrencies[coin]; //Convert USD to chosen FIAT return (0, helpers_1.formatNumber)(fromAmount / exchangePrice, this.precision.crypto); } return null; }).bind(this); return doExchange; }, _CryptoConvert_isSafeKey = function _CryptoConvert_isSafeKey(key) { const functionProto = function () { }; return (!this.internalMethods.includes(key) && !key.startsWith('__') && !functionProto[key]); }, _CryptoConvert_setExtendedOptions = function _CryptoConvert_setExtendedOptions(options) { if (options.precision) { for (const precisionKey in options.precision) { if (["crypto", "fiat"].includes(precisionKey) && typeof options.precision[precisionKey] == "number") { this.precision[precisionKey] = options.precision[precisionKey]; } } } }, _CryptoConvert_populate = function _CryptoConvert_populate() { let types = ''; //Generate typescript interface types += `type amount = (amount: number | string) => number | false | null;`; types += '\nexport interface Pairs {'; const all_currencies = this.worker.list.crypto.concat(this.worker.list.fiat, customWorkers.list); const all_currencies_unique = all_currencies.filter((v, i) => all_currencies.indexOf(v) == i); for (var i = 0; i < all_currencies_unique.length; i++) { var coin = all_currencies_unique[i]; if (!coin || typeof coin !== "string" || !__classPrivateFieldGet(this, _CryptoConvert_instances, "m", _CryptoConvert_isSafeKey).call(this, coin)) { continue; } if (!this[coin]) { this[coin] = {}; } types += `\n\t'${coin.replace(/\'/g, "\\'")}': {`; for (var a = 0; a < all_currencies_unique.length; a++) { var currency = all_currencies_unique[a]; if (!currency || typeof currency !== "string" || !__classPrivateFieldGet(this, _CryptoConvert_instances, "m", _CryptoConvert_isSafeKey).call(this, coin)) { continue; } this[coin][currency] = __classPrivateFieldGet(this, _CryptoConvert_instances, "m", _CryptoConvert_wrapper).call(this, coin, currency); types += `\n\t\t'${currency.replace(/\'/g, "\\'")}': amount,`; } types += '\n},'; } types += '\n}'; //Create types file for Node.js. With Runtime types generation ^^ if (typeof window === "undefined" && typeof module !== "undefined" && typeof process !== "undefined") { (function () { return __awaiter(this, void 0, void 0, function* () { try { // Here we save the types file. Using eval because static linting checks on frontend apps are annoying af. eval(` const fs = require('fs'); const path = require('path'); const isDist = path.basename(__dirname) == 'dist'; const typesFile = path.join(__dirname, isDist ? 'paris.d.ts' : 'paris.ts'); fs.writeFileSync(typesFile, types, 'utf-8'); `); } catch (err) { console.warn(err); } }); })(); } }; //@ts-ignore CryptoConvert.default = CryptoConvert; if (typeof module !== "undefined" && module.exports) { module.exports = CryptoConvert; } exports.default = CryptoConvert;