From c4c09905bfc46e7ed57ab80194a46606fc6e34ad Mon Sep 17 00:00:00 2001 From: Joe Uhren Date: Sun, 26 Jun 2022 20:48:13 -0600 Subject: [PATCH] Add FreiExchange/FreiXLite exchange to markets -This exchange has 2 separate sites using the same api, so new functionality was added to the explorer to handle alt markets like this -market files now allow for new field names: "market_name_alt" was added for the alternate market name, "market_logo_alt" was added for displaying an alternate logo, a "market_url" function was added that will return a url string to replace the {url_prefix} code in the market_url_template and an "isAlt" function was added to determine if the alt name/logo should be used -A new freiexchange entry was added to the markets_page.exchanges setting -Updated the README with the updated market info --- README.md | 5 +- app.js | 40 ++++++++++-- lib/markets/freiexchange.js | 119 ++++++++++++++++++++++++++++++++++++ lib/settings.js | 12 +++- routes/index.js | 24 +++++--- settings.json.template | 13 +++- views/layout.pug | 20 ++++-- views/market.pug | 42 +++++++++---- 8 files changed, 239 insertions(+), 36 deletions(-) create mode 100644 lib/markets/freiexchange.js diff --git a/README.md b/README.md index 816bedc..5f4d383 100644 --- a/README.md +++ b/README.md @@ -87,15 +87,16 @@ Table of Contents - **Movement:** Displays latest blockchain transactions that are greater than a certain configurable amount - **Network:** Displays a list of peers that have connected to the coind wallet in the past 24 hours, along with useful addnode data that can be used to connect your own wallets to the network easier - **Top 100:** Displays the top 100 richest wallet addresses, the top 100 wallet addresses that have the highest total number of coins received based on adding up all received transactions, as well as a table and pie chart breakdown of wealth distribution. Additional support for omitting burned coins from top 100 lists - - **Markets:** Displays a number of exchange-related metrics including market summary, 24 hour chart, most recent buy/sell orders and latest trade history. The last known default exchange price is automatically converted to USD using the coingecko api from [https://www.coingecko.com/en/api](https://www.coingecko.com/en/api). The following 8 cryptocurrency exchanges are supported: + - **Markets:** Displays a number of exchange-related metrics including market summary, 24 hour chart, most recent buy/sell orders and latest trade history. The last known default exchange price is automatically converted to USD using the coingecko api from [https://www.coingecko.com/en/api](https://www.coingecko.com/en/api). The following 9 cryptocurrency exchanges are supported: - [AltMarkets](https://altmarkets.io) - [Bittrex](https://bittrex.com) - [Bleutrade](https://bleutrade.com) - [Crex24](https://crex24.com) + - [FreiExchange](https://freiexchange.com)/[FreiXLite](https://freixlite.com) *\*no chart support due to a lack of OHLCV api data* - [Poloniex](https://poloniex.com) - [SouthXchange](https://southxchange.com) - [Stex](https://stex.com) - - [Yobit](https://yobit.io) *\*no chart support due to yobit's lack of OHLCV api data* + - [Yobit](https://yobit.io) *\*no chart support due to a lack of OHLCV api data* - **API:** A listing of available public API's that can be used to retrieve information from the network without the need for a local wallet. The following public API's are supported: - **RPC API calls** (Return data from coind) - **getdifficulty:** Returns the current difficulty diff --git a/app.js b/app.js index 3f911ab..9593b13 100644 --- a/app.js +++ b/app.js @@ -616,16 +616,48 @@ if (settings.markets_page.enabled == true) { // load market file var exMarket = require('./lib/markets/' + key); // save market_name and market_logo from market file to settings - eval('market_data.push({id: "' + key + '", name: "' + (exMarket.market_name == null ? '' : exMarket.market_name) + '", logo: "' + (exMarket.market_logo == null ? '' : exMarket.market_logo) + '", trading_pairs: []});'); + eval('market_data.push({id: "' + key + '", name: "' + (exMarket.market_name == null ? '' : exMarket.market_name) + '", alt_name: "' + (exMarket.market_name_alt == null ? '' : exMarket.market_name_alt) + '", logo: "' + (exMarket.market_logo == null ? '' : exMarket.market_logo) + '", alt_logo: "' + (exMarket.market_logo_alt == null ? '' : exMarket.market_logo_alt) + '", trading_pairs: []});'); // loop through all trading pairs for this market for (var i = 0; i < settings.markets_page.exchanges[key].trading_pairs.length; i++) { - // ensure trading pair setting is always uppercase - settings.markets_page.exchanges[key].trading_pairs[i] = settings.markets_page.exchanges[key].trading_pairs[i].toUpperCase(); + var isAlt = false; + var pair = settings.markets_page.exchanges[key].trading_pairs[i].toUpperCase(); // ensure trading pair setting is always uppercase + var coin_symbol = pair.split('/')[0]; + var pair_symbol = pair.split('/')[1]; + + // determine if using the alt name + logo + if (exMarket.market_url_template != null && exMarket.market_url_template != '') { + switch ((exMarket.market_url_case == null || exMarket.market_url_case == '' ? 'l' : exMarket.market_url_case.toLowerCase())) { + case 'l': + case 'lower': + isAlt = (exMarket.isAlt != null ? exMarket.isAlt({coin: coin_symbol.toLowerCase(), exchange: pair_symbol.toLowerCase()}) : false); + break; + case 'u': + case 'upper': + isAlt = (exMarket.isAlt != null ? exMarket.isAlt({coin: coin_symbol.toUpperCase(), exchange: pair_symbol.toUpperCase()}) : false); + break; + default: + } + } + // add trading pair to market_data - market_data[market_data.length - 1].trading_pairs.push(settings.markets_page.exchanges[key].trading_pairs[i]); + market_data[market_data.length - 1].trading_pairs.push({ + pair: pair, + isAlt: isAlt + }); + // increment the market count market_count++; } + + // sort trading pairs by alt status + market_data[market_data.length - 1].trading_pairs.sort(function(a, b) { + if (a.isAlt < b.isAlt) + return -1; + else if (a.isAlt > b.isAlt) + return 1; + else + return 0; + }); } } }); diff --git a/lib/markets/freiexchange.js b/lib/markets/freiexchange.js new file mode 100644 index 0000000..0569052 --- /dev/null +++ b/lib/markets/freiexchange.js @@ -0,0 +1,119 @@ +var request = require('postman-request'); +var base_url = 'https://api.freiexchange.com/public/'; +const market_url_template = '{url_prefix}/market/{coin}/{base}'; + +function get_summary(coin, exchange, cb) { + var req_url = base_url + '/ticker/' + coin; + + request({uri: req_url, json: true}, function (error, response, body) { + if (error) + return cb(error, null); + else if (body.success != null && body.success == false) + return cb(body.result.messsage, null); + else { + var summary = {}; + + if (body[`${coin}_${exchange}`] != null && body[`${coin}_${exchange}`].length > 0) { + summary['bid'] = body[`${coin}_${exchange}`][0].highestBuy; + summary['ask'] = body[`${coin}_${exchange}`][0].lowestSell; + summary['volume'] = body[`${coin}_${exchange}`][0].volume24h; + summary['volume_btc'] = body[`${coin}_${exchange}`][0].volume24h_btc; + summary['low'] = body[`${coin}_${exchange}`][0].low; + summary['high'] = body[`${coin}_${exchange}`][0].high; + summary['last'] = body[`${coin}_${exchange}`][0].last; + summary['change'] = body[`${coin}_${exchange}`][0].percent_change_24h; + } + + return cb(null, summary); + } + }); +} + +function get_trades(coin, exchange, cb) { + var req_url = base_url + '/trades/' + coin + (exchange == 'LTC' ? '/LTC' : ''); + + request({ uri: req_url, json: true }, function (error, response, body) { + if (error) + return cb(error, null); + else if (body.success != null && body.success == false) + return cb(body.result.messsage, null); + else { + var trades = []; + + for (var i = 0; i < body.length; i++) { + // NOTE: timestamp is reduced by 7 hours (3600000ms * 7) to account for the fact the server time seems to display local time to the webserver instead of UTC time) + trades.push({ + ordertype: body[i].type, + price: body[i].price, + quantity: body[i].total_coin, + timestamp: parseInt((new Date(body[i].time).getTime()-(3600000 * 7))/1000) + }); + } + + return cb(null, trades); + } + }); +} + +function get_orders(coin, exchange, cb) { + var req_url = base_url + '/orderbook/' + coin + (exchange == 'LTC' ? '/LTC' : ''); + + request({uri: req_url, json: true}, function (error, response, body) { + if (error) + return cb(error, null); + else if (body.success != null && body.success == false) + return cb(body.result.messsage, null); + else { + var buys = []; + var sells = []; + + if (body['BUY'].length > 0) { + for (var i = 0; i < body['BUY'].length; i++) { + buys.push({ + price: body['BUY'][i].price, + quantity: body['BUY'][i].amount + }); + } + } + + if (body['SELL'].length > 0) { + for (var i = 0; i < body['SELL'].length; i++) { + sells.push({ + price: body['SELL'][i].price, + quantity: body['SELL'][i].amount + }); + } + } + + return cb(null, buys, sells); + } + }); +} + +module.exports = { + market_name: 'FreiExchange', + market_name_alt: 'FreiXLite', + market_logo: 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAF8WlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNi4wLWMwMDIgNzkuMTY0NDYwLCAyMDIwLzA1LzEyLTE2OjA0OjE3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMiAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDIyLTA2LTI2VDE2OjU2OjA2LTA2OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIyLTA2LTI2VDE2OjU2OjA2LTA2OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAyMi0wNi0yNlQxNjo1NjowNi0wNjowMCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpjM2IyNDVkYy1kZDI2LWYwNGEtYmIwYS03OWJjNDhmZTQxMzMiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDozZWIzNDAxZC00N2U4LTFmNGUtOGYwMi1kZmMzODg0MzFlZWYiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo3NzY1YTNlYi1mMjRlLWVlNGQtOGM0My0xYTY3NjgzYTNkMTAiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiBwaG90b3Nob3A6SUNDUHJvZmlsZT0ic1JHQiBJRUM2MTk2Ni0yLjEiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjc3NjVhM2ViLWYyNGUtZWU0ZC04YzQzLTFhNjc2ODNhM2QxMCIgc3RFdnQ6d2hlbj0iMjAyMi0wNi0yNlQxNjo1NjowNi0wNjowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIxLjIgKFdpbmRvd3MpIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDpjM2IyNDVkYy1kZDI2LWYwNGEtYmIwYS03OWJjNDhmZTQxMzMiIHN0RXZ0OndoZW49IjIwMjItMDYtMjZUMTY6NTY6MDYtMDY6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyMS4yIChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz48i0LMAAAC2UlEQVQ4jV1T70tTURh+7z0/7tbcKjT7XdC3QIi0yBD6F/rQl8A+SIUlaISETSVGn6QocFaYWhARTpG0MLAvFQZFEbg+ZVAYVnO7cwuderubc2/vOS2VLjzsfe/O87zPOee5ABwABMAOwcBrGFBjikA7k7UhJm/3c+vhVc7vdjDZcIKJvfsYB9Og9XwDcbYTylXzV8AigSCTzZ+FjOelhSg9iELo3xXqvwmRvcNFWBqGALZegCkY0MPlMHKJK4zjLMEmJLhAW0icJbhUI+E159EtvKQcxE4AuQ30c5NbvYqcAsAZQnwdbMPUIromoJQ4Jj3vwfSBxhGTHUOT4YLXh/PhTsw+G0X3+RhmX77Apf5+jHu8GCNiJhzG+UgEberRNLDJMK/o6UNcDKOaFghg3nXw/8eurCRU6ToZDGJGuSD0ADzSAtNC2r+UPX8AsVBAJxrFaerVVHd8HJ2JKLqZDC6MjGCS3iXBcBp8/ub2+vrGo9XVFZDilhMvCuRTKczGZ3D+chDnzp/DdLBVT87ZNsZMU08m312N9+6fKhrMQkpYTqIosDz5adX6MsGJx3S9MPpUO1ICIYBbTX19tcVlDkzJtS0UXBezX7/gD58P0y1BXFHkkWHM5XJoVxzQt5Rk/Hejr+RSy+kzDYeqqvbDIJeP9SH6N2pJ9+MEft+0GfNUZwYG9HkU1Kg3b/En1YuUD7W+GyCiD/GwyWqQ9qeucXEwgnO073RdHbp0jTYJKetzoRBt4wnGGMMU5UJl4QLjrRQEJWHCNS56VWzT/8JDuUgUg5OkGCeK75MUKEUe5d53AF4KMAUJDEkaArqFHEJlj+I6qyKs4kwEhST1WfUfkV8J9qEUfGUAW4lcphyQAJfgFRYEubg4KWRsWU+yivCg6qeEWOri1g2hvx6LeOpDKl0T2EMCfsbgIOMlbcxzso2Jzg4mHrQzfuc6k2ePc7FrNzll+uQ8qwJ/AJ4ryGtYbOHVAAAAAElFTkSuQmCC', + market_logo_alt: 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAF8WlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNi4wLWMwMDIgNzkuMTY0NDYwLCAyMDIwLzA1LzEyLTE2OjA0OjE3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMiAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDIyLTA2LTI2VDE5OjE0OjMzLTA2OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIyLTA2LTI2VDE5OjE0OjMzLTA2OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAyMi0wNi0yNlQxOToxNDozMy0wNjowMCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozYjE4MmI1ZC0zZjU3LWVhNGMtYWFiYS01NmQ0YjVkZWVmNTUiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDpiNWRkYTk5MS02MGNlLTc5NGQtOWFlNy04MDcwY2I3NWVjYzkiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDozMjM4NjRhMi0xNjk4LWU0NGUtODA5Yy1iYjc0ZjliM2UyMmEiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiBwaG90b3Nob3A6SUNDUHJvZmlsZT0ic1JHQiBJRUM2MTk2Ni0yLjEiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjMyMzg2NGEyLTE2OTgtZTQ0ZS04MDljLWJiNzRmOWIzZTIyYSIgc3RFdnQ6d2hlbj0iMjAyMi0wNi0yNlQxOToxNDozMy0wNjowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIxLjIgKFdpbmRvd3MpIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDozYjE4MmI1ZC0zZjU3LWVhNGMtYWFiYS01NmQ0YjVkZWVmNTUiIHN0RXZ0OndoZW49IjIwMjItMDYtMjZUMTk6MTQ6MzMtMDY6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyMS4yIChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4U//lqAAACLUlEQVQ4y42TQUiTYRzGf4GXITsowi4WjIRFXnYLPNRRXSB6M8kCD2J2cAgeJJFEIwRDqA42QmjDTiW2lGkGkRRBGkSktYrUNDZnmOg+9ZvfvqfDNjEx8oWH9/I+//eB/+8hDISBD0AcWIH8GFzagDtJGNyAm+tQOQ98BwzgFTACRMiaR4AZ4DecT8FHgQ5qE8Z/wul14PX+AY+BR8Ay9B1mPKgtqJ4EhoExgHFgHq79z7hZVKSk0ymBZuDsMPAMYA6O5x7Zbrfk9WbkdivtcEgDA9pubdWVzk6F6uslUApib+DYHEACAgJZeXmyUinlTjqRkBmJSJLiNTW63NWl5xUVe4liUHm/pARMWBLI9nhkS9rt79euzyfLspSWJL9fUVBDMKjPpaUSaA2in9rbb/dGImcQmALJ55MkWZK2q6tlR6Oyk0kJ9MLr1dVAIPf7zpfu7oe5pAh2BFJzcyZBU5PMlhZJkm0YEuhBebkuDg0p0NioREGBtVpWNpE0jIW4NIUJywIpGFRa0o7LJUkyp6eVlmT39mrU49GttjZd7+nRUnGxBOlFh6Mr3NEBcbgnkGZnZS0syKqtlR0KyXI6pbo62VVVh671K1yYIoPwCYHkckmFhToKTCbE3gHvASaBH9B+FGNOb+HcHkhPslwn4MZRzAZUjWfxf0qW5zDwDdiCSvMfZTJgYgVO/QJe7u/CGDAKLAIbmftkAvwW3N2FQRP6VqFhEfKXM439a8AfCVrpWXEdq70AAAAASUVORK5CYII=', + market_url_template: market_url_template, + market_url_case: 'u', + market_url: function(settings) { + return 'https://' + (settings.exchange.toUpperCase() == 'LTC' ? 'freixlite' : 'freiexchange') + '.com'; + }, + isAlt: function(settings) { + return settings.exchange.toUpperCase() == 'LTC'; + }, + get_data: function(settings, cb) { + var error = null; + get_orders(settings.coin.toUpperCase(), settings.exchange.toUpperCase(), function(err, buys, sells) { + if (err) { error = err; } + get_trades(settings.coin.toUpperCase(), settings.exchange.toUpperCase(), function(err, trades) { + if (err) { error = err; } + get_summary(settings.coin.toUpperCase(), settings.exchange.toUpperCase(), function(err, stats) { + if (err) { error = err; } + return cb(error, {buys: buys, sells: sells, chartdata: [], trades: trades, stats: stats}); + }); + }); + }); + } +}; \ No newline at end of file diff --git a/lib/settings.js b/lib/settings.js index 3c1e98f..ce0358b 100644 --- a/lib/settings.js +++ b/lib/settings.js @@ -729,7 +729,7 @@ exports.markets_page = { "show_market_select": true, // exchanges: Enable/disable api integration with any of the available built-in exchanges // Enabled exchanges display a number of exchange-related metrics including market summary, 24 hour chart, most recent buy/sell orders and latest trade history - // Supported exchanges: altmarkets, bittrex, bleutrade, crex, poloniex, southxchange, stex, yobit + // Supported exchanges: altmarkets, bittrex, bleutrade, crex, freiexchange/freixlite, poloniex, southxchange, stex, yobit "exchanges": { // altmarkets: a collection of settings that pertain to the altmarkets exchange "altmarkets": { @@ -775,6 +775,16 @@ exports.markets_page = { // Ex: "LTC/BTC", "LTC/USDT", "LTC/ETH" "trading_pairs": [ "LTC/BTC" ] }, + "freiexchange": { + // enabled: Enable/disable the freiexchange/freixlite exchange (true/false) + // If set to false, the freiexchange/freixlite page will be completely inaccessible and no market data will be downloaded for this exchange + "enabled": false, + // trading_pairs: An array of market trading pair symbols + // You can add as many trading pairs as necessary + // All entries must specify your coins symbol as it is displayed on the exchange, followed by a slash (/) and ending with the symbol of the market or asset that is being traded against + // Ex: "LTC/BTC", "LTC/USDT", "LTC/ETH" + "trading_pairs": [ "LTC/BTC" ] + }, // poloniex: a collection of settings that pertain to the poloniex exchange "poloniex": { // enabled: Enable/disable the poloniex exchange (true/false) diff --git a/routes/index.js b/routes/index.js index 07546d3..c7005ae 100644 --- a/routes/index.js +++ b/routes/index.js @@ -459,23 +459,29 @@ router.get('/markets/:market/:coin_symbol/:pair_symbol', function(req, res) { db.get_market(market_id, coin_symbol, pair_symbol, function(data) { // load market data var market_data = require('../lib/markets/' + market_id); + var isAlt = false; var url = ''; - // build the external exchange url link + // build the external exchange url link and determine if using the alt name + logo if (market_data.market_url_template != null && market_data.market_url_template != '') { switch ((market_data.market_url_case == null || market_data.market_url_case == '' ? 'l' : market_data.market_url_case.toLowerCase())) { case 'l': case 'lower': - url = market_data.market_url_template.replace('{base}', pair_symbol.toLowerCase()).replace('{coin}', coin_symbol.toLowerCase()); + url = market_data.market_url_template.replace('{base}', pair_symbol.toLowerCase()).replace('{coin}', coin_symbol.toLowerCase()).replace('{url_prefix}', (market_data.market_url != null ? market_data.market_url({coin: coin_symbol.toLowerCase(), exchange: pair_symbol.toLowerCase()}) : '')); + isAlt = (market_data.isAlt != null ? market_data.isAlt({coin: coin_symbol.toLowerCase(), exchange: pair_symbol.toLowerCase()}) : false); break; case 'u': case 'upper': - url = market_data.market_url_template.replace('{base}', pair_symbol.toUpperCase()).replace('{coin}', coin_symbol.toUpperCase()); + url = market_data.market_url_template.replace('{base}', pair_symbol.toUpperCase()).replace('{coin}', coin_symbol.toUpperCase()).replace('{url_prefix}', (market_data.market_url != null ? market_data.market_url({coin: coin_symbol.toUpperCase(), exchange: pair_symbol.toUpperCase()}) : '')); + isAlt = (market_data.isAlt != null ? market_data.isAlt({coin: coin_symbol.toUpperCase(), exchange: pair_symbol.toUpperCase()}) : false); break; default: } } + var market_name = (isAlt ? (market_data.market_name_alt == null ? '' : market_data.market_name_alt) : (market_data.market_name == null ? '' : market_data.market_name)); + var market_logo = (isAlt ? (market_data.market_logo_alt == null ? '' : market_data.market_logo_alt) : (market_data.market_logo == null ? '' : market_data.market_logo)); + // check if markets page should show last updated date if (settings.markets_page.page_header.show_last_updated == true) { // lookup last updated date @@ -485,8 +491,8 @@ router.get('/markets/:market/:coin_symbol/:pair_symbol', function(req, res) { { active: 'markets', marketdata: { - market_name: (market_data.market_name == null ? '' : market_data.market_name), - market_logo: (market_data.market_logo == null ? '' : market_data.market_logo), + market_name: market_name, + market_logo: market_logo, coin: coin_symbol, exchange: pair_symbol, data: data, @@ -498,7 +504,7 @@ router.get('/markets/:market/:coin_symbol/:pair_symbol', function(req, res) { customHash: get_file_timestamp('./public/css/custom.scss'), styleHash: get_file_timestamp('./public/css/style.scss'), themeHash: get_file_timestamp('./public/css/themes/' + settings.shared_pages.theme.toLowerCase() + '/bootstrap.min.css'), - page_title_prefix: locale.mkt_title.replace('{1}', (market_data.market_name == null ? '' : market_data.market_name) + ' (' + coin_symbol + '/' + pair_symbol + ')') + page_title_prefix: locale.mkt_title.replace('{1}', market_name + ' (' + coin_symbol + '/' + pair_symbol + ')') } ); }); @@ -509,8 +515,8 @@ router.get('/markets/:market/:coin_symbol/:pair_symbol', function(req, res) { { active: 'markets', marketdata: { - market_name: (market_data.market_name == null ? '' : market_data.market_name), - market_logo: (market_data.market_logo == null ? '' : market_data.market_logo), + market_name: market_name, + market_logo: market_logo, coin: coin_symbol, exchange: pair_symbol, data: data, @@ -522,7 +528,7 @@ router.get('/markets/:market/:coin_symbol/:pair_symbol', function(req, res) { customHash: get_file_timestamp('./public/css/custom.scss'), styleHash: get_file_timestamp('./public/css/style.scss'), themeHash: get_file_timestamp('./public/css/themes/' + settings.shared_pages.theme.toLowerCase() + '/bootstrap.min.css'), - page_title_prefix: locale.mkt_title.replace('{1}', (market_data.market_name == null ? '' : market_data.market_name) + ' (' + coin_symbol + '/' + pair_symbol + ')') + page_title_prefix: locale.mkt_title.replace('{1}', market_name + ' (' + coin_symbol + '/' + pair_symbol + ')') } ); } diff --git a/settings.json.template b/settings.json.template index cd0ff51..5948701 100644 --- a/settings.json.template +++ b/settings.json.template @@ -813,7 +813,7 @@ "show_market_select": true, // exchanges: Enable/disable api integration with any of the available built-in exchanges // Enabled exchanges display a number of exchange-related metrics including market summary, 24 hour chart, most recent buy/sell orders and latest trade history - // Supported exchanges: altmarkets, bittrex, bleutrade, crex, poloniex, southxchange, stex, yobit + // Supported exchanges: altmarkets, bittrex, bleutrade, crex, freiexchange/freixlite, poloniex, southxchange, stex, yobit "exchanges": { // altmarkets: a collection of settings that pertain to the altmarkets exchange "altmarkets": { @@ -859,6 +859,17 @@ // Ex: "LTC/BTC", "LTC/USDT", "LTC/ETH" "trading_pairs": [ "LTC/BTC" ] }, + // freiexchange: a collection of settings that pertain to the freiexchange/freixlite exchange + "freiexchange": { + // enabled: Enable/disable the freiexchange/freixlite exchange (true/false) + // If set to false, the freiexchange/freixlite page will be completely inaccessible and no market data will be downloaded for this exchange + "enabled": false, + // trading_pairs: An array of market trading pair symbols + // You can add as many trading pairs as necessary + // All entries must specify your coins symbol as it is displayed on the exchange, followed by a slash (/) and ending with the symbol of the market or asset that is being traded against + // Ex: "LTC/BTC", "LTC/USDT", "LTC/ETH" + "trading_pairs": [ "LTC/BTC" ] + }, // poloniex: a collection of settings that pertain to the poloniex exchange "poloniex": { // enabled: Enable/disable the poloniex exchange (true/false) diff --git a/views/layout.pug b/views/layout.pug index 72bae33..edc4af7 100644 --- a/views/layout.pug +++ b/views/layout.pug @@ -735,13 +735,21 @@ html(lang='en') each mkt in settings.market_data if mkt != null && mkt.id != null each pair in mkt.trading_pairs - a.dropdown-item(href='/markets/' + mkt.id + '/' + pair) - if mkt.logo != null && mkt.logo != '' - img.market-logo(src='data:image/png;base64,' + mkt.logo, title=mkt.name + ' (' + pair + ')', alt=mkt.name + ' (' + pair + ')') + a.dropdown-item(href='/markets/' + mkt.id + '/' + pair.pair) + if pair.isAlt == true + if mkt.alt_logo != null && mkt.alt_logo != '' + img.market-logo(src='data:image/png;base64,' + mkt.alt_logo, title=mkt.alt_name + ' (' + pair.pair + ')', alt=mkt.alt_name + ' (' + pair.pair + ')') + else + i.market-logo.fas.fa-question-circle + span #{mkt.alt_name} + span.small.fw-normal (#{pair.pair}) else - i.market-logo.fas.fa-question-circle - span #{mkt.name} - span.small.fw-normal (#{pair}) + if mkt.logo != null && mkt.logo != '' + img.market-logo(src='data:image/png;base64,' + mkt.logo, title=mkt.name + ' (' + pair.pair + ')', alt=mkt.name + ' (' + pair.pair + ')') + else + i.market-logo.fas.fa-question-circle + span #{mkt.name} + span.small.fw-normal (#{pair.pair}) else li#markets.nav-item a.nav-link(href='/markets/' + settings.markets_page.default_exchange.exchange_name + '/' + settings.markets_page.default_exchange.trading_pair) diff --git a/views/market.pug b/views/market.pug index 4574a1d..331a133 100644 --- a/views/market.pug +++ b/views/market.pug @@ -131,24 +131,40 @@ block content each mkt in settings.market_data if mkt != null && mkt.id != null each pair in mkt.trading_pairs - if market == mkt.id && marketdata.coin.toLowerCase() + '/' + marketdata.exchange.toLowerCase() == pair.toLowerCase() + if market == mkt.id && marketdata.coin.toLowerCase() + '/' + marketdata.exchange.toLowerCase() == pair.pair.toLowerCase() li.nav-item - a.nav-link.active(href='/markets/' + mkt.id + '/' + pair) - if mkt.logo != null && mkt.logo != '' - img.align-top.market-logo(src='data:image/png;base64,' + mkt.logo, title=mkt.name + ' (' + pair + ')', alt=mkt.name + ' (' + pair + ')') + a.nav-link.active(href='/markets/' + mkt.id + '/' + pair.pair) + if pair.isAlt == true + if mkt.alt_logo != null && mkt.alt_logo != '' + img.align-top.market-logo(src='data:image/png;base64,' + mkt.alt_logo, title=mkt.alt_name + ' (' + pair.pair + ')', alt=mkt.alt_name + ' (' + pair.pair + ')') + else + i.market-logo.fas.fa-question-circle + span #{mkt.alt_name} + span.small.fw-normal (#{pair.pair}) else - i.market-logo.fas.fa-question-circle - span #{mkt.name} - span.small.fw-normal (#{pair}) + if mkt.logo != null && mkt.logo != '' + img.align-top.market-logo(src='data:image/png;base64,' + mkt.logo, title=mkt.name + ' (' + pair.pair + ')', alt=mkt.name + ' (' + pair.pair + ')') + else + i.market-logo.fas.fa-question-circle + span #{mkt.name} + span.small.fw-normal (#{pair.pair}) else li.nav-item - a.nav-link(href='/markets/' + mkt.id + '/' + pair) - if mkt.logo != null && mkt.logo != '' - img.align-top.market-logo(src='data:image/png;base64,' + mkt.logo, title=mkt.name + ' (' + pair + ')', alt=mkt.name + ' (' + pair + ')') + a.nav-link(href='/markets/' + mkt.id + '/' + pair.pair) + if pair.isAlt == true + if mkt.alt_logo != null && mkt.alt_logo != '' + img.align-top.market-logo(src='data:image/png;base64,' + mkt.alt_logo, title=mkt.alt_name + ' (' + pair.pair + ')', alt=mkt.alt_name + ' (' + pair.pair + ')') + else + i.market-logo.fas.fa-question-circle + span #{mkt.alt_name} + span.small.fw-normal (#{pair.pair}) else - i.market-logo.fas.fa-question-circle - span #{mkt.name} - span.small.fw-normal (#{pair}) + if mkt.logo != null && mkt.logo != '' + img.align-top.market-logo(src='data:image/png;base64,' + mkt.logo, title=mkt.name + ' (' + pair.pair + ')', alt=mkt.name + ' (' + pair.pair + ')') + else + i.market-logo.fas.fa-question-circle + span #{mkt.name} + span.small.fw-normal (#{pair.pair}) if marketdata.data != null && ((marketdata.data.buys != null && marketdata.data.buys.length > 0) || (marketdata.data.sells != null && marketdata.data.sells.length > 0) || (marketdata.data.history != null && marketdata.data.history.length > 0)) block market_view script.