diff --git a/README.md b/README.md index f01273c..a7d2df2 100644 --- a/README.md +++ b/README.md @@ -5,24 +5,28 @@ ## Features: * Tipbot for LBC. Responds to `!tip`. -* Price bot displays price of lbc for currency given. Responds to `!price - ` +* Price bot displays price of lbc for currency given. Responds to `!price ` * Stats bot display current market stats of lbc. Responds to `!stats` * Hash bot displays current hashrate of network. Responds to `!hash` + + Also Includes `!hash power ` to calculate given MH/s to LBC per hr, day, week, month. + * Github Release Notes bot displays release notes for current lbry-app release. - Responds to `!releasenotes` User with Defined Perms `!releasenotes post` to - send to specified channel + Responds to `!releasenotes` + + (moderator only) `!releasenotes post` to send to specified channel -* Purge Bot (moderator only) deletes X amount of messages. User with Defined - Perms Responds to `!purge ` +* Purge Bot (moderator only) deletes X amount of messages. Responds to `!purge ` * Speech bot displays top claim from provided image name(coming soon posting to speech). Responds to `!speech ` -* Welcome bot sends Direct Message when new users join, User with Defined Perms - can send using `!welcome <@username>` +* Welcome bot sends Direct Message when new users join, + + (moderator only) Responds to `!welcome <@username>` + * Spam Detection Bot to Prevent Discord Raids and Spammers * Dynamic plugin loading with permission support. diff --git a/bot/modules/hash.js b/bot/modules/hash.js index 1610b7c..42f9453 100644 --- a/bot/modules/hash.js +++ b/bot/modules/hash.js @@ -1,121 +1,172 @@ -let needle = require("needle"); -let config = require("config"); -let hasHashBotChannels = require("../helpers.js").hasHashBotChannels; -let inPrivate = require("../helpers.js").inPrivate; -let ChannelID = config.get("hashbot").mainchannel; +let needle = require('needle'); +let config = require('config'); +let hasHashBotChannels = require('../helpers.js').hasHashBotChannels; +let inPrivate = require('../helpers.js').inPrivate; +let ChannelID = config.get('hashbot').mainchannel; exports.commands = [ - "hash" // command that is in this file, every command needs it own export as shown below -]; + "hash" // command that is in this file, every command needs it own export as shown below +] -exports.custom = ["timedhash"]; +exports.custom = [ + "timedhash" +] exports.timedhash = function(bot) { - setInterval(function() { - sendMiningInfo(bot); - }, 6 * 60 * 60 * 1000); + setInterval(function() { + sendMiningInfo(bot); + }, 6 * 60 * 60 * 1000); + + function sendMiningInfo(bot) { +needle.get('https://explorer.lbry.io/api/v1/status', function(error, response) { + if (error || response.statusCode !== 200) { + msg.channel.send('Explorer API is not available'); + } + else { + var data = response.body; + var height = Number(data.status.height); + var hashrate = data.status.hashrate; + var difficulty = Number(data.status.difficulty); + needle.get('https://whattomine.com/coins/164.json', function(error, response) { + if (error || response.statusCode !== 200) { + msg.channel.send('whattomine API is not available'); + } else { + var data = response.body; + var reward = Number(data.block_reward); + var block_time = Number(data.block_time); + var difficulty24 = Number(data.difficulty24); + description = "Hashrate: "+numberWithCommas(hashrate)+"\n" + + "Difficulty: "+numberWithCommas(difficulty.toFixed(0))+"\n" + + "Difficulty 24 Hour Average: "+numberWithCommas(difficulty24.toFixed(0))+"\n" + + "Current block: "+numberWithCommas(height.toFixed(0))+"\n" + + "Block Time: "+numberWithCommas(block_time.toFixed(0))+" seconds \n" + + "Block Reward: "+numberWithCommas(reward.toFixed(0))+" LBC \n" + + "Sources: https://explorer.lbry.io & \n" + + "https://whattomine.com/coins/164-lbc-lbry"; + const embed = { + "description": description, + "color": 7976557, + "author": { + "name": "LBRY Network Stats", + "icon_url": "https://i.imgur.com/yWf5USu.png" + } + }; + bot.channels.get(ChannelID).send({ embed }) + return + } + }); + } + }); + function numberWithCommas(x) { + return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); +} +} +} - function sendMiningInfo(bot) { - needle.get("https://explorer.lbry.io/api/v1/status", function( - error, - response - ) { - if (error || response.statusCode !== 200) { - bot.channels.get(ChannelID).send("Explorer API is not available"); - } else { - var data, - hashrate = "", - difficulty = "", - height = ""; - data = response.body; - height += data.status.height; - hashrate += data.status.hashrate; - difficulty += data.status.difficulty; - description = - "Hashrate: " + - hashrate + - "\n" + - "Difficulty: " + - difficulty + - "\n" + - "Current block: " + - height + - "\n" + - "Source: https://explorer.lbry.io"; - const embed = { - description: description, - color: 7976557, - author: { - name: "LBRY Explorer Stats", - url: "https://explorer.lbry.io", - icon_url: "https://i.imgur.com/yWf5USu.png" - } - }; - bot.channels.get(ChannelID).send({ - embed - }); - } - }); - } -}; exports.hash = { - usage: "", - description: "Displays current Hashrate of Network", - process: function(bot, msg) { - var command = "!hash"; - sendMiningInfo(bot, msg); + usage: "", + description: 'Displays current Hashrate of Network\n**!hash power **\n Displays potential Earnings For Given Hashrate', + process: function(bot,msg,suffix){ + var command = '!hash'; + words = suffix.trim().split(' ').filter( function(n){return n !== "";} ); + profitcommand = words[0]; + myhashrate = words[1]; + console.log(suffix) + if (profitcommand == "power") { + sendProfitInfo(bot, msg, suffix); + return + } else { + sendMiningInfo(bot, msg, suffix); + return + } + - function sendMiningInfo(bot, msg) { - if (!inPrivate(msg) && !hasHashBotChannels(msg)) { - msg.channel.send( - "Please use <#" + ChannelID + "> or DMs to talk to hash bot." - ); - return; - } - needle.get("https://explorer.lbry.io/api/v1/status", function( - error, - response - ) { - if (error || response.statusCode !== 200) { - msg.channel.send("Explorer API is not available"); - } else { - var data, - hashrate = "", - difficulty = "", - height = ""; - data = response.body; - height += data.status.height; - hashrate += data.status.hashrate; - difficulty += data.status.difficulty; - description = - "Hashrate: " + - hashrate + - "\n" + - "Difficulty: " + - difficulty + - "\n" + - "Current block: " + - height + - "\n" + - "Source: https://explorer.lbry.io"; - const embed = { - description: description, - color: 7976557, - author: { - name: "LBRY Explorer Stats", - url: "https://explorer.lbry.io", - icon_url: "https://i.imgur.com/yWf5USu.png" - } - }; - msg.channel.send({ - embed - }); - } - }); - } - - function numberWithCommas(x) { - return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); - } +function sendMiningInfo(bot, msg, suffix) { + if(!inPrivate(msg) && !hasHashBotChannels(msg)){ + msg.channel.send('Please use <#' + ChannelID + '> or DMs to talk to hash bot.'); + return; } -}; + needle.get('https://explorer.lbry.io/api/v1/status', function(error, response) { + if (error || response.statusCode !== 200) { + msg.channel.send('Explorer API is not available'); + } + else { + var data = response.body; + var height = Number(data.status.height); + var hashrate = data.status.hashrate; + var difficulty = Number(data.status.difficulty); + needle.get('https://whattomine.com/coins/164.json', function(error, response) { + if (error || response.statusCode !== 200) { + msg.channel.send('whattomine API is not available'); + } else { + var data = response.body; + var reward = Number(data.block_reward); + var block_time = Number(data.block_time); + var difficulty24 = Number(data.difficulty24); + description = "Hashrate: "+numberWithCommas(hashrate)+"\n" + + "Difficulty: "+numberWithCommas(difficulty.toFixed(0))+"\n" + + "Difficulty 24 Hour Average: "+numberWithCommas(difficulty24.toFixed(0))+"\n" + + "Current block: "+numberWithCommas(height.toFixed(0))+"\n" + + "Block Time: "+numberWithCommas(block_time.toFixed(0))+" seconds \n" + + "Block Reward: "+numberWithCommas(reward.toFixed(0))+" LBC \n" + + "Sources: https://explorer.lbry.io & \n" + + "https://whattomine.com/coins/164-lbc-lbry"; + const embed = { + "description": description, + "color": 7976557, + "author": { + "name": "LBRY Network Stats", + "icon_url": "https://i.imgur.com/yWf5USu.png" + } + }; + msg.channel.send({ embed }); + return + } + }); + } + }); +} +function sendProfitInfo(bot, msg, suffix) { + needle.get('https://whattomine.com/coins/164.json', function(error, response) { + if (error || response.statusCode !== 200) { + msg.channel.send('whattomine API is not available'); + } else { + words = suffix.trim().split(' ').filter( function(n){return n !== "";} ); + var myhashrate = words[1]; + if (myhashrate == "" || myhashrate == null || myhashrate == undefined || myhashrate == " ") { + myhashrate = "100"; + } + var Diff = response.body.difficulty24; + var Reward = response.body.block_reward; + var myHash = Number(myhashrate) + var LBC = myHash / 2000 * (1 / (Diff * 2^32) * Reward) * 3600 + var LBC24 = myHash / 2000 * (1 / (Diff * 2^32) * Reward) * 86400 + var LBC1w = myHash / 2000 * (1 / (Diff * 2^32) * Reward) * 604800 + var LBC1m = myHash / 2000 * (1 / (Diff * 2^32) * Reward) * 2628000 + var message = "With **" + myHash + " Mh/s** and Average 24 hour Difficulty: **" + Diff.toFixed(0) + "**\n" + + "You can potentially earn the following amounts of **LBC**: \n" + + "1 Hour = **" + LBC.toFixed(4) + "** \n" + + "1 Day = **" + LBC24.toFixed(2) + "** \n" + + "1 Week = **" + LBC1w.toFixed(4) + "** \n" + + "1 Month = **" + LBC1m.toFixed(4) + "** \n" + const embed = { + "description": message, + "color": 7976557, + "author": { + "name": "Hashing Power Calculator!", + "icon_url": "https://i.imgur.com/nKHVQgq.png" + } + }; + msg.channel.send({ embed }) + return + } + }); +} +function numberWithCommas(x) { + return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); +} + + + +} +} \ No newline at end of file diff --git a/bot/modules/stats.js b/bot/modules/stats.js index 0ee828b..276bff8 100644 --- a/bot/modules/stats.js +++ b/bot/modules/stats.js @@ -1,304 +1,211 @@ -let jp = require("jsonpath"); -let moment = require("moment"); -let numeral = require("numeral"); -let request = require("request"); -let config = require("config"); -let hasStatsBotChannels = require("../helpers.js").hasStatsBotChannels; -let inPrivate = require("../helpers.js").inPrivate; -let ChannelID = config.get("statsbot").mainchannel; +let jp = require('jsonpath'); +let moment = require('moment'); +let numeral = require('numeral'); +let request = require('request'); +let config = require('config'); +let needle = require('needle'); +let hasStatsBotChannels = require('../helpers.js').hasStatsBotChannels; +let inPrivate = require('../helpers.js').inPrivate; +let ChannelID = config.get('statsbot').mainchannel; exports.commands = [ - "stats" // command that is in this file, every command needs it own export as shown below -]; + "stats" // command that is in this file, every command needs it own export as shown below +] exports.stats = { - usage: "", - description: "Displays current a list of current Market stats", - process: function(bot, msg, suffix) { - var options = { - defaultCurrency: "USD", + usage: "", + description: 'Displays current a list of current Market stats', + process: function(bot,msg,suffix){ + var options = { + defaultCurrency: 'USD', - // supported currencies and api steps to arrive at the final value - currencies: { - USD: { - steps: ["LBCUSD"], - format: "$0,0.00", - sign: "USD $" - }, - BTC: { - steps: ["LBCBTC"], - format: "BTC 0,0.00000000", - sign: "BTC" - }, - ETH: { - steps: ["LBCETH"], - format: "ETH 0,0.00000000", - sign: "ETH" - }, - GBP: { - steps: ["LBCGBP"], - format: "£0,0.00", - sign: "£" - }, - EUR: { - steps: ["LBCEUR"], - format: "€0,0.00", - sign: "€" - }, - CAD: { - steps: ["LBCCAD"], - format: "$0,0.00", - sign: "CAD $" - }, - AUD: { - steps: ["LBCAUD"], - format: "$0,0.00", - sign: "AUD $" - }, - IDR: { - steps: ["LBCIDR"], - format: "Rp0,0.00", - sign: "Rp" + // supported currencies and api steps to arrive at the final value + currencies: { + USD: { steps: ['LBCUSD'], format: '$0,0.00', sign:'USD $' }, + BTC: { steps: ['LBCBTC'], format: 'BTC 0,0.00000000', sign:'BTC' }, + ETH: { steps: ['LBCETH'], format: 'ETH 0,0.00000000', sign: 'ETH' }, + GBP: { steps: ['LBCGBP'], format: '£0,0.00', sign: '£' }, + EUR: { steps: ['LBCEUR'], format: '€0,0.00', sign: '€' }, + CAD: { steps: ['LBCCAD'], format: '$0,0.00', sign: 'CAD $' }, + AUD: { steps: ['LBCAUD'], format: '$0,0.00', sign: 'AUD $' }, + IDR: { steps: ['LBCIDR'], format: 'Rp0,0.00', sign: 'Rp' } + }, + + // api steps + api: { + LBCBTC: { url: 'https://bittrex.com/api/v1.1/public/getticker?market=BTC-LBC', path: '$.result.Bid' }, + LBCUSD: { url: 'https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=usd', path: '$[0].price_usd' }, + LBCGBP: { url: 'https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=gbp', path: '$[0].price_gbp' }, + LBCETH: { url: 'https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=eth', path: '$[0].price_eth' }, + LBCEUR: { url: 'https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=eur', path: '$[0].price_eur' }, + LBCAUD: { url: 'https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=aud', path: '$[0].price_aud' }, + LBCCAD: { url: 'https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=cad', path: '$[0].price_cad' }, + LBCIDR: { url: 'https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=idr', path: '$[0].price_idr'} + }, + + // display date/time format + dtFormat: 'Do MMM YYYY h:mma [UTC]', + + // refresh rate in milliseconds to retrieve a new price (default to 10 minutes) + refreshTime: 300000 +}; + +// store the last retrieved rate +var command = '!stats'; + + var currency = options.defaultCurrency; + var amount = 1; +if(!inPrivate(msg) && !hasStatsBotChannels(msg)){ + msg.channel.send('Please use <#' + ChannelID + '> or DMs to talk to stats bot.'); + return; + } else { + doSteps(bot, msg, 'USD', amount); + doSteps(bot, msg, 'EUR', amount); + doSteps(bot, msg, 'GBP', amount); + doSteps(bot, msg, 'ETH', amount); + doSteps(bot, msg, 'BTC', amount); + doSteps(bot, msg, 'CAD', amount); + doSteps(bot, msg, 'AUD', amount); + doSteps(bot, msg, 'IDR', amount); + marketstats(bot,msg,suffix); + //marketstats(bot,msg); + volume(bot,msg); + } + +function formatMessage(amount, rate, option) { + var cur = option.sign; + var value = rate.rate * amount; + if (option.sign == 'USD $' || option.sign == 'CAD $' || option.sign == 'AUD $' || option.sign == '£' || option.sign == '€'|| option.sign == 'Rp'){ + return '*' + numeral(amount).format('0,0[.][00000000]') + ' LBC = ' + cur +' '+ value.toFixed(2) + '*'; + } + else { + return '*' + numeral(amount).format('0,0[.][00000000]') + ' LBC = ' + cur +' ' + numeral(value).format('0,0[.][00000000]') + '*'; + } +} + +function formaty(n, decimals, currency) { + n = parseFloat(n); + return currency + " " + n.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,"); +} + +function doSteps(bot, msg, currency, amount) { + + var option = options.currencies[currency]; + // copy the steps array + var steps = []; + for (var i = 0; i < option.steps.length; i++) { + steps.push(option.steps[i]); } - }, - // api steps - api: { - LBCBTC: { - url: "https://bittrex.com/api/v1.1/public/getticker?market=BTC-LBC", - path: "$.result.Bid" - }, - LBCUSD: { - url: - "https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=usd", - path: "$[0].price_usd" - }, - LBCGBP: { - url: - "https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=gbp", - path: "$[0].price_gbp" - }, - LBCETH: { - url: - "https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=eth", - path: "$[0].price_eth" - }, - LBCEUR: { - url: - "https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=eur", - path: "$[0].price_eur" - }, - LBCAUD: { - url: - "https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=aud", - path: "$[0].price_aud" - }, - LBCCAD: { - url: - "https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=cad", - path: "$[0].price_cad" - }, - LBCIDR: { - url: - "https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=idr", - path: "$[0].price_idr" - } - }, + processSteps(bot, msg, currency, 0, amount, steps, option); +} - // display date/time format - dtFormat: "Do MMM YYYY h:mma [UTC]", +function marketstats(bot,msg,suffix) { + var statsurl='https://api.coinmarketcap.com/v1/ticker/library-credit/'; - // refresh rate in milliseconds to retrieve a new price (default to 10 minutes) - refreshTime: 300000 - }; + request.get(statsurl, function(error, response, body) { + if (error) { + msg.channel.send(err.message ? err.message : 'The request could not be completed at this time. Please try again later.'); + return; + } + var marketcap = 0; + try { + marketcap = jp.query(JSON.parse(body), '$[0].market_cap_usd'); + if (Array.isArray(marketcap) && marketcap.length > 0) { + marketcap = marketcap[0]; + marketcap = formaty(marketcap,2,'$') + } - // store the last retrieved rate - var command = "!stats"; + } catch (ignored) { + // invalid response or pair rate + } - var currency = options.defaultCurrency; - var amount = 1; - if (!inPrivate(msg) && !hasStatsBotChannels(msg)) { - msg.channel.send( - "Please use <#" + ChannelID + "> or DMs to talk to stats bot." - ); - return; + var statmsg = '*'+'Marketcap: '+marketcap+'*\n'; + + msg.channel.send(statmsg); + + }); +} + +function volume(bot,msg) { + needle.get('https://api.coinmarketcap.com/v1/ticker/library-credit/', function(error, response) { + if (error || response.statusCode !== 200) { + msg.channel.send('coinmarketcap API is not available'); } else { - doSteps(bot, msg, "USD", amount); - doSteps(bot, msg, "EUR", amount); - doSteps(bot, msg, "GBP", amount); - doSteps(bot, msg, "ETH", amount); - doSteps(bot, msg, "BTC", amount); - doSteps(bot, msg, "CAD", amount); - doSteps(bot, msg, "AUD", amount); - doSteps(bot, msg, "IDR", amount); - setTimeout(function() { - marketstats(bot, msg, suffix); - }, 250); - //marketstats(bot,msg); - //volume24(bot,msg); can't get this part to work, someone help me fix - i think it's because 24h_volume_usd starts with number - } + var json = response.body[0]; + var newjson = parse_obj(json) + var parse = JSON.stringify(newjson) + var volume = parse.replace(/[^0-9]/g, ''); + console.log(volume) + console.log(newjson) + var statmsg = '*Volume: $'+volume+'*\n'; + msg.channel.send(statmsg); + } + }); +} - function formatMessage(amount, rate, option) { - var cur = option.sign; - var value = rate.rate * amount; - if ( - option.sign == "USD $" || - option.sign == "CAD $" || - option.sign == "AUD $" || - option.sign == "£" || - option.sign == "€" || - option.sign == "Rp" - ) { - return ( - "*" + - numeral(amount).format("0,0[.][00000000]") + - " LBC = " + - cur + - " " + - value.toFixed(2) + - "*" - ); - } else { - return ( - "*" + - numeral(amount).format("0,0[.][00000000]") + - " LBC = " + - cur + - " " + - numeral(value).format("0,0[.][00000000]") + - "*" - ); - } - } - - function formaty(n, decimals, currency) { - n = parseFloat(n); - return ( - currency + " " + n.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,") - ); - } - - function doSteps(bot, msg, currency, amount) { - var option = options.currencies[currency]; - // copy the steps array - var steps = []; - for (var i = 0; i < option.steps.length; i++) { - steps.push(option.steps[i]); - } - - processSteps(bot, msg, currency, 0, amount, steps, option); - } - - function marketstats(bot, msg, suffix) { - var statsurl = "https://api.coinmarketcap.com/v1/ticker/library-credit/"; - - request.get(statsurl, function(error, response, body) { - if (error) { - msg.channel.send( - err.message - ? err.message - : "The request could not be completed at this time. Please try again later." - ); - return; +function parse_obj(obj) +{ + var array = []; + var prop; + for (prop in obj) + { + if (obj.hasOwnProperty(prop)) + { + var key = parseInt(prop, 10); + var value = obj[prop]; + if (typeof value == "object") + { + value = parse_obj(value); + } + array[key] = value; } - var marketcap = 0; - try { - marketcap = jp.query(JSON.parse(body), "$[0].market_cap_usd"); - if (Array.isArray(marketcap) && marketcap.length > 0) { - marketcap = marketcap[0]; - marketcap = formaty(marketcap, 2, "$"); - } - } catch (ignored) { - // invalid response or pair rate - } - - var statmsg = "*" + "Marketcap: " + marketcap + "*\n"; - - msg.channel.send(statmsg); - }); } + return array; +} - function volume24(bot, msg, suffix) { - var statsurl = "https://api.coinmarketcap.com/v1/ticker/library-credit/"; - request.get(statsurl, function(error, response, body) { - if (error) { - msg.channel.send( - err.message - ? err.message - : "The request could not be completed at this time. Please try again later." - ); - return; - } - var volume24 = 0; - try { - volume24 = jp.query(JSON.parse(body), "$[0].24h_volume_usd"); - if (Array.isArray(volume24) && volume24.length > 0) { - volume24 = volume24[0]; - } - } catch (ignored) { - // invalid response or pair rate - } - - var statmsg = "*" + "Volume: $" + volume24 + "*\n"; - - msg.channel.send(statmsg); - }); - } - - function processSteps(bot, msg, currency, rate, amount, steps, option) { - if (steps.length > 0) { +function processSteps(bot, msg, currency, rate, amount, steps, option) { + if (steps.length > 0) { var pairName = steps[0]; if (!options.api[pairName]) { - msg.channel.send( - "There was a configuration error. " + - pairName + - " pair was not found." - ); - return; + msg.channel.send('There was a configuration error. ' + pairName + ' pair was not found.'); + return; } var pair = options.api[pairName]; request.get(pair.url, function(error, response, body) { - if (error) { - msg.channel.send( - err.message - ? err.message - : "The request could not be completed at this time. Please try again later." - ); - return; - } - var pairRate = 0; - try { - pairRate = jp.query(JSON.parse(body), pair.path); - if (Array.isArray(pairRate) && pairRate.length > 0) { - pairRate = pairRate[0]; + if (error) { + msg.channel.send(err.message ? err.message : 'The request could not be completed at this time. Please try again later.'); + return; } - } catch (ignored) { - // invalid response or pair rate - } - - if (pairRate > 0) { - rate = rate === 0 ? pairRate : rate * pairRate; - steps.shift(); - if (steps.length > 0) { - processSteps(bot, currency, rate, amount, steps, option); - return; + var pairRate = 0; + try { + pairRate = jp.query(JSON.parse(body), pair.path); + if (Array.isArray(pairRate) && pairRate.length > 0) { + pairRate = pairRate[0]; + } + } catch (ignored) { + // invalid response or pair rate } - // final step, cache and then response - var result = { - rate: rate, - time: moment() - }; + if (pairRate > 0) { + rate = (rate === 0) ? pairRate : rate * pairRate; + steps.shift(); + if (steps.length > 0) { + processSteps(bot, currency, rate, amount, steps, option); + return; + } - msg.channel.send(formatMessage(amount, result, option)); - } else { - msg.channel.send( - "The rate returned for the " + pairName + " pair was invalid." - ); - } + // final step, cache and then response + var result = { rate: rate, time: moment() }; + + msg.channel.send(formatMessage(amount, result, option)); + } else { + msg.channel.send('The rate returned for the ' + pairName + ' pair was invalid.'); + } }); - } } - } -}; +} + + } +} \ No newline at end of file