├── .DS_Store ├── Cryptocurrency-crypto-bot.sql ├── LICENSE ├── README.md ├── avatar.png ├── config.js ├── discordbot.log ├── functions ├── chat.js ├── check.js ├── command.js ├── cron.js ├── log.js ├── storage.js ├── transaction.js ├── user.js └── wallet.js ├── index.js ├── lowdb └── lowdb.json ├── package-lock.json ├── package.json ├── preview ├── 10_rain_prev.jpg ├── 1_admin_commands_prev.jpg ├── 2_bot_commands_prev.jpg ├── 3_balance_prev.jpg ├── 4_deposit_prev.jpg ├── 5_messages_prev.jpg ├── 6_messages_prev.jpg ├── 6_profile_prev.jpg ├── 7_deposit_prev.jpg ├── 8_drop_prev.jpg └── 9_drop_prev.jpg └── transaction.sh /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crypto-node/Cryptocurrency-crypto-bot/d44d6c03422eb322faed2ae80f5a3431a48454be/.DS_Store -------------------------------------------------------------------------------- /Cryptocurrency-crypto-bot.sql: -------------------------------------------------------------------------------- 1 | # ************************************************************ 2 | # Sequel Pro SQL dump 3 | # Version 4541 4 | # 5 | # http://www.sequelpro.com/ 6 | # https://github.com/sequelpro/sequelpro 7 | # 8 | # Host: 35.205.165.129 (MySQL 5.7.14-google) 9 | # Datenbank: galilel 10 | # Erstellt am: 2019-11-18 20:35:27 +0000 11 | # ************************************************************ 12 | 13 | 14 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 15 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 16 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 17 | /*!40101 SET NAMES utf8 */; 18 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 19 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 20 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 21 | 22 | 23 | # Export von Tabelle coin_price_history 24 | # ------------------------------------------------------------ 25 | 26 | DROP TABLE IF EXISTS `coin_price_history`; 27 | 28 | CREATE TABLE `coin_price_history` ( 29 | `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 30 | `price` decimal(32,8) DEFAULT NULL, 31 | `currency` varchar(10) DEFAULT NULL, 32 | `datetime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, 33 | `api_service` tinytext CHARACTER SET utf8mb4 NOT NULL, 34 | PRIMARY KEY (`id`) 35 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 36 | 37 | 38 | 39 | # Export von Tabelle deposits 40 | # ------------------------------------------------------------ 41 | 42 | DROP TABLE IF EXISTS `deposits`; 43 | 44 | CREATE TABLE `deposits` ( 45 | `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 46 | `address` varchar(60) NOT NULL, 47 | `amount` decimal(32,8) NOT NULL, 48 | `txid` varchar(64) NOT NULL, 49 | `confirmations` int(11) NOT NULL, 50 | `credited` tinyint(1) unsigned NOT NULL, 51 | `datetime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, 52 | `coin_price` decimal(32,8) DEFAULT NULL, 53 | PRIMARY KEY (`id`), 54 | UNIQUE KEY `txid` (`txid`), 55 | KEY `address` (`address`), 56 | KEY `credited` (`credited`) 57 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 58 | 59 | 60 | 61 | # Export von Tabelle log 62 | # ------------------------------------------------------------ 63 | 64 | DROP TABLE IF EXISTS `log`; 65 | 66 | CREATE TABLE `log` ( 67 | `id` int(11) NOT NULL AUTO_INCREMENT, 68 | `discord_id` varchar(60) NOT NULL, 69 | `description` text NOT NULL, 70 | `value` decimal(32,8) DEFAULT NULL, 71 | `datetime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, 72 | `coin_price` decimal(32,8) DEFAULT NULL, 73 | PRIMARY KEY (`id`) 74 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 75 | 76 | 77 | 78 | # Export von Tabelle payments 79 | # ------------------------------------------------------------ 80 | 81 | DROP TABLE IF EXISTS `payments`; 82 | 83 | CREATE TABLE `payments` ( 84 | `id` int(11) NOT NULL AUTO_INCREMENT, 85 | `amount` double(32,8) NOT NULL, 86 | `from_discord_id` varchar(60) NOT NULL, 87 | `to_discord_id` varchar(60) NOT NULL, 88 | `type` tinytext NOT NULL, 89 | `datetime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, 90 | `coin_price` decimal(32,8) DEFAULT NULL, 91 | PRIMARY KEY (`id`), 92 | KEY `from_discord_id` (`from_discord_id`), 93 | KEY `to_discord_id` (`to_discord_id`) 94 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 95 | 96 | 97 | 98 | # Export von Tabelle transactions 99 | # ------------------------------------------------------------ 100 | 101 | DROP TABLE IF EXISTS `transactions`; 102 | 103 | CREATE TABLE `transactions` ( 104 | `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 105 | `txid` varchar(64) NOT NULL, 106 | `amount` decimal(32,8) NOT NULL DEFAULT '0.00000000', 107 | `credited` tinyint(1) unsigned NOT NULL DEFAULT '0', 108 | `stake` tinyint(1) unsigned NOT NULL DEFAULT '0', 109 | `checked` tinyint(1) unsigned NOT NULL DEFAULT '0', 110 | `datetime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, 111 | `coin_price` decimal(32,8) DEFAULT NULL, 112 | PRIMARY KEY (`id`), 113 | UNIQUE KEY `txid` (`txid`), 114 | KEY `credited` (`credited`) 115 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 116 | 117 | 118 | 119 | # Export von Tabelle user 120 | # ------------------------------------------------------------ 121 | 122 | DROP TABLE IF EXISTS `user`; 123 | 124 | CREATE TABLE `user` ( 125 | `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 126 | `username` varchar(60) NOT NULL, 127 | `balance` decimal(32,8) NOT NULL DEFAULT '0.00000000', 128 | `stake_balance` decimal(32,8) NOT NULL DEFAULT '0.00000000', 129 | `deposit_address` varchar(60) DEFAULT NULL, 130 | `discord_id` varchar(60) NOT NULL, 131 | `register_datetime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, 132 | `unstake_datetime` datetime NOT NULL DEFAULT '2000-01-01 00:00:00', 133 | PRIMARY KEY (`id`), 134 | UNIQUE KEY `discord_id` (`discord_id`), 135 | UNIQUE KEY `deposit_address` (`deposit_address`) 136 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 137 | 138 | 139 | 140 | # Export von Tabelle withdrawals 141 | # ------------------------------------------------------------ 142 | 143 | DROP TABLE IF EXISTS `withdrawals`; 144 | 145 | CREATE TABLE `withdrawals` ( 146 | `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 147 | `discord_id` varchar(60) NOT NULL, 148 | `address` varchar(60) NOT NULL, 149 | `amount` decimal(32,8) NOT NULL, 150 | `txid` varchar(64) NOT NULL, 151 | `datetime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, 152 | `coin_price` decimal(32,8) DEFAULT NULL, 153 | PRIMARY KEY (`id`), 154 | KEY `discord_id` (`discord_id`) 155 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 156 | 157 | 158 | 159 | 160 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 161 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 162 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 163 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 164 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 165 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 166 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Christian Grieger 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cryptocurrency-crypto-bot is an open-source Node.js wallet bot for Discord. 2 | 3 | ### Preview pictures 4 | 5 | 6 | ### BOT COMMANDS 7 | > ```+register | +r``` 8 | Register an account with the bot. 9 | ```+profile | +p``` 10 | Display account information. 11 | ```+balance | +b``` 12 | Display your current balance. 13 | ```+deposit | +d``` 14 | Get your deposit address. 15 | ```+withdraw
| +w
``` 16 | Withdraw balance to an address (0.01 VIP transaction fee will be added on top of the amount). 17 | ```+stake ``` 18 | Convert balance to stake balance for receiving stake pool payouts. (Its always possible to add balance but it will reset the unstake timer) 19 | ```+unstake ``` 20 | Convert balance to normal balance (Only once within 24 hours if no stake/unstake has been done).__ 21 | ```+tip <@username> ``` 22 | Tip a user from Discord. 23 | ```+rain ``` 24 | (all) Tip amount divided by total user count. / (online) Tip amount divided by active users. / (random) Tip amount divided by random user count. 25 | ```+drop <30 letter phrase>``` 26 | (phrase) Send coins to all users that reply with the asked phrase. / (react) Send coins to all users that react with the asked icon. 27 | ```+history | +history ``` 28 | (deposits) Show your latest deposits. / (withdrawals) Show your latest withdrawals. / (payments) Show your latest payments. 29 | ```+update | +u``` 30 | Update your username. 31 | ```+donate``` 32 | Show the bot creators tip address. 33 | ```+notify ``` 34 | Enable or disable to get mentioned by the bot. 35 | ```+version | +v``` 36 | Get current bot and wallet information. 37 | 38 | ### ADMIN COMMANDS 39 | > ```+start / +stop``` 40 | Enable/Disable all bot commands while the bot is running. 41 | ```+getdeposits | +gd``` 42 | Manually get latest transactions from wallet and update confirmations. 43 | ```+creditdeposits | +cd``` 44 | Manually check confirmations on database and credit deposits if they have min confirmations. 45 | ```+getstakes || +gs``` 46 | Manually check transactions on database if they are stakes. 47 | ```+creditstakes || +cs``` 48 | Manually credit stakes to users. 49 | ```+clear || +c``` 50 | Delete all visible messages from chat. 51 | 52 | ### Additional information 53 | 54 | - It supports all coins using the standard Bitcoin rpc commands 55 | - It's possible to configure a staking pool for POS coins 56 | - Written for Node.js 57 | - The bot offers the option to enable or disable all commands seperated, so its not needed to use them all 58 | - The backend is a mysql database 59 | - A massive configuration file to manage all content from one file 60 | - You can define administrators, moderators and a vip group 61 | ... and many many many more options, please check the config file 62 | 63 | ## Installation 64 | 1. Create a MySQL Database and import the cryptocurrency-crypto-bot.sql 65 | 2. Edit the config file carefully without missing any needed value! 66 | 3. Start your bot and enjoy! -> node index.js 67 | 68 | ## Staking 69 | 1. The database connection needs to work 70 | 2. Enable staking on your wallet and add walletnotify option to your coin config (change the path to the bots transactions.sh script) 71 | staking=1 72 | walletnotify=/path/to/your/bot/folder/transaction.sh %s 73 | 3. Enalbe staking options on the config file 74 | 4. Check if transactionns are coming in to database 75 | 76 | ## Projects using the bot - Feel free to contact me to get added 77 | - Limitless (VIP) - Discord: https://discord.gg/wtz6QYX - Website: http://vip.limitlessvip.co.za/ 78 | - BARE Coin (BARE) - Discord: https://discord.gg/xmQbzNH - Website: https://bare.network/ 79 | -------------------------------------------------------------------------------- /avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crypto-node/Cryptocurrency-crypto-bot/d44d6c03422eb322faed2ae80f5a3431a48454be/avatar.png -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "bot": { 3 | "version": "1.3.2", // Current bot version 4 | "setNewAvatar": false, // Bot does crash if avatar gets changed too often! If you set a new image, set the value to true and the bot sets the new avatar. After change the value back to false!!!! 5 | "avatar":"./avatar.png", // Set bot avatar img -> local file path 6 | "gameMessage":"bot game message | +help", // Message under the bot name in the discord user list 7 | "adminMode": false, // If enabled the bot only accepts commands from admins 8 | "errorLogging": true, // Enable error logging to file discordbot.log 9 | "commandPrefix": "+", // Bot prefix to trigger the bot <- if symbol changed it needs to get allowed on check.js 10 | "cooldownTime": 10, // Cooldown a user need to wait between commands in seconds 11 | "activeUserTime": 600, // Seconds a user counts as active for rain online users 12 | "botID": "XXX", // Bot Discord ID - important else it react to own messages 13 | "adminIDs": [ "XXX", "XXX", "XXX" ], // This discrod user IDs are able to use admin commands and bypass cooldowns 14 | "moderatorIDs": [ "XXX" ], // This discrod user IDs are able to use moderator commands and bypass cooldowns 15 | "vipGroupName": "Dev Team", // Users of this group are able to use vip commands and bypass cooldowns 16 | "respondChannelIDs": [ "XXX" ], // Discord server channel IDs the bot does listen to 17 | "commandIgnor": ["battle","cversion","destroy","gift","kill","lock","me","rez","top","use","me","cstart","cstop","cstart","jackpot","summary","shop","activate","mention","claim"], // commands to ignor because of other bots 18 | "stakePoolChannelID": "XXX", // If staking is configured use this channel to broadcast stake pool payouts 19 | "allowDM": true, // Allow or disable direct messages for commands to the bot with true or false 20 | "botToken": "XXX", // Discord bot token 21 | "listUsers": 30, // Define how many users get listed in one message on rain or drop <- Take care about 2200 letters limit from discord 22 | "dropBotReactIcon":"✅", // If change -> http://twitter.github.io/twemoji/2/test/preview.html -> click icon copy from popup and past it into the string!, // SOME ARE NOT WORKING!! TEST IT BEFORE MAKE IT LIVE 23 | "dropReactIcon":"🍀", // If change -> http://twitter.github.io/twemoji/2/test/preview.html -> click icon copy from popup and past it into the string!, // SOME ARE NOT WORKING!! TEST IT BEFORE MAKE IT LIVE 24 | "dropMinSeconds": 10, // Drop message min reply time in seconds 25 | "dropMaxSeconds": 300, // Drop message max reply time in seconds 26 | "dropMinUsers": 1, // Users minimum needed for drop 27 | "minDropValue": 0.00000001, // Minimum value for drop 28 | }, 29 | "mysql":{ // Dont forget to import the empty database before starting the bot 30 | "dbHost": "XXX", // Database server 31 | "dbName": "XXX", // Database name 32 | "dbUser": "XXX", // Database user 33 | "dbPassword": "XXX", // Database password 34 | "dbPort": 3306, // Database port 35 | "connectionLimit": 20, // Database maximal database pool connections 36 | "waitForConnections": true, // If true, the pool will queue the connection request and call it when one becomes available 37 | }, 38 | "wallet":{ 39 | "server": "127.0.0.1", // Wallet server 40 | "user": "XXX", // Wallet username 41 | "password": "XXX", // Wallet password 42 | "port": "1234", // Wallet port 43 | // TODO ENCRYPTION KEY FOR WALLET 44 | "coinSymbol": "Coin (CoinSymbol)", // Coin name 45 | "coinSymbolShort": "Symbol", // Coin name 46 | "thumbnailIcon": "https://domain.link/image.png", // Thumbnail icon for all messages (need to get enabled first in code to work = not ready) 47 | "check": true, // If enabled it checks (cron) for new transactions 48 | "credit": true, // If enabled it credits (cron) new transactions 49 | "depositsToCheck": 60, // How many latest deposits should be checked from the wallet 50 | "depositsCreditTime": 120, // How often deposits get checked for credit in seconds 51 | "depositsConfirmationTime": 40, // How often confirmations get checked 52 | "minConfirmationsDeposit": 2000, // Until this confirmations the deposit cron will update the confirmations on database 53 | "minConfirmationsCredit": 5, // Minimum confirmations to get the deposit balance credited 54 | "depositsHistory": 5, // How many deposits get shown on deposit history command !! Max value 7 !! 55 | "withdrawalsHistoryDisplayCount": 5, // How many withdrawals get shown on withdrawal history command !! Max value 5 !! 56 | "paymentHistoryCoun": 7, // How many payments get shown on withdrawals payments command !! Max value 7 !! 57 | "explorerLinkAddress": "https://explorer.link/#/address/", // Explorer link address for addresses 58 | "explorerLinkTransaction": "ttps://explorer.link/#/tx/", // Explorer link transaction 59 | "transactionFee": 0.01, // Fee taken for a transaction a user makes - Change value also on help command 60 | "minWithdrawalValue": 0.00000001, // Minimum value for withdrawal 61 | "minTipValue": 0.00000001, // Minimum value for tip 62 | "maxRainRandomUsers": 15, // Please take care as the bot can crash if the value is to big as for each user a database query is fired! 63 | "donateAddress":"XXX" // Address for donations 64 | }, 65 | "coinPrice":{ // If enabled the current coin price will be saved next to each transaction made from the bot and into the price history database table 66 | "enabled": false, 67 | "cronTime": 1800, // Cron time in seconds 68 | "apiService": "coinmarketcap", // define the api to use -> The coin must be listed on the api! Current possible values are "coinmarketcap" and "cryptocompare" -> you need to register to get a api key 69 | "apiKey": "XXX", 70 | "coinSymbol": "Symbol", // e.g. BTC 71 | "currency": "EUR" // Cent prices in this currency 72 | }, 73 | "staking":{ 74 | // Please hold this option disabled and configure it before! 75 | // 1. The database connection needs to work 76 | // 2. Enable staking on your wallet and add walletnotify option to your coin config (change the path to the bots transactions.sh script) 77 | // staking=1 78 | // walletnotify=/path/to/your/bot/folder/transaction.sh %s 79 | // 3. Check if transactionns are coming in to database 80 | "debug": false, // Debug stake credit on console 81 | "check": false, // If enabled it checks (cron) the saved transaction from walletnotify on database for stakes and calculated the amount 82 | "checkTime": 60, // Check for new transaction in seconds 83 | "checkCount": 50, // How many transactions max get checked at once from database 84 | "credit": false, // If enabled it credits (cron) all users with new stakes from database 85 | "creditTime": 80, // Credit new transactions in seconds 86 | "creditCount": 50, // How many transactions get credited to the users with one run 87 | "balanceDisplay": false, // Enable take balance display on balance command 88 | "minStake": 20, // Minimum value to stake 89 | "minUnstake": 20, // Minimum value to unstake 90 | "ownerPercentage": 95, // Bot owner percentage // Define how many percente users get from 100% 91 | "lockTime": 86400, // 24hours = 86400 - Lock time in seconds -> Check if the minimum time between payments and payouts as defined has been respected // Prevent stake pool hopping ;) 92 | "timezone": "Europe/Berlin" // Used for detect if unstake command can be used or is blocked <- only change if you know what you do! Best value would be same as mysql database time 93 | }, 94 | "commands": { 95 | // Enable or disable commands -> true/false 96 | // Admin commands 97 | "startstop": true, 98 | "getdeposits": true, 99 | "creditdeposits": true, 100 | // Please configure staking part first on top!!!! 101 | "getstakes": false, 102 | "creditstakes": false, 103 | /////// 104 | "clear": false, 105 | // Normal commands 106 | "help": true, 107 | "register": true, 108 | "profile": true, 109 | "balance": true, 110 | "deposit": true, 111 | "withdraw": true, 112 | "tip": true, 113 | "rain": true, 114 | "drop": true, 115 | "history": true, 116 | "update": true, 117 | "donate": true, 118 | "stake": false, 119 | "unstake": false, 120 | "notify": true, 121 | "version": true 122 | }, 123 | "colors": { 124 | "normal": "0xecf0f1", // grey 125 | "success": "0x2ecc71", // green 126 | "warning": "0xe67e22", // orange 127 | "error": "0xe74c3c", // red 128 | "special": "0xE91E63" // pink 129 | }, 130 | "messages": { // Some messages contain markdown -> http://markdown.de 131 | // Not command related messages 132 | "botStarted": "Bot started and online as", 133 | "adminMode": "Developer mode is enabled. Only admins are allowed to send commands.", 134 | "cooldown": "Please wait the cooldown of 10 sec on all commands.", 135 | "DMDisabled": "Direct messages are disabled. Please use the official command channel.", 136 | "notValidCommand": "This is not a valid command. Type **+help** for a list and try again.", 137 | "notAllowedCommand": "You are not allowed to use this command!", 138 | "walletOffline": "The wallet is not reachable. Please try again. \nIf the problem persists after another attempt, please contact the admin.", 139 | "wentWrong": "Somethig went wrong with your request. Please try again. \nIf the problem persists after another attempt, please contact the admin.", 140 | "comingSoon":"Coming soon!", 141 | "accountNotRegistered": "You are not registered. \nPlease type **+register** to create an account.", 142 | "currentlyBlocked":"Please wait until your other task is done before starting another one.", 143 | "payment": { 144 | "tip": { 145 | "send":"tip (sent)", 146 | "received":"tip (received)" 147 | }, 148 | "drop":{ 149 | "send":"drop (sent)", 150 | "received":"drop (received)" 151 | }, 152 | "stake": { 153 | "stake": "stake balance (added)", 154 | "unstake": "stake balance (removed)", 155 | "received":"stake(s) (received)" 156 | } 157 | 158 | }, 159 | "startstop": { 160 | "enabled":"Bot commands enabled.", 161 | "disabled":"Bot commands disabled.", 162 | }, 163 | "log": { 164 | "registered":"successfully registered.", 165 | "username":"Updated the username to", 166 | "depositaddress":"Deposit address created", 167 | "transctioncredited":"Credited blance to address", 168 | "transctioncreditedunknown":"Credited blance to unknown address", 169 | "withdrawrequest":"Withdraw request to address", 170 | "rain":"Sent rain to", 171 | "rain1":"users.", 172 | "tip":"Sent tip to user", 173 | "drop":"Sent drop to", 174 | "drop1":"users.", 175 | "stake":"Value removed from normal to stake balance", 176 | "stakeadd":"Value added from normal to stake balance", 177 | "unstake":"Value removed from stake to normal balance", 178 | "unstakeadd":"Value added from stake to normal balance", 179 | "stakecredit": "- Total wallet balance:", 180 | "stakecredit1": "- Total stake amount:", 181 | "stakecredit2": "- Total stake amount minus developer percentage:", 182 | "stakecredit3": "- Stake user count:", 183 | "stakecredit4": "- Stake users:", 184 | "stakecredit5": "- Total stake balance of all users:", 185 | "stakecredit6": "- Total value for stake users from the total stake amount (totalUserStakeBalance/walletBalance*totalStakeForStakers):", 186 | "stakecredit7":"- IDs of processing transactions:", 187 | "stakecredit8":"- Discord ID:", 188 | "stakecredit9":"- Stake balance:", 189 | "stakecredit10":"- Credit amount:" 190 | }, 191 | "balance": { 192 | "balance":"Balance", 193 | "username":"Username", 194 | "stakeTitle": "Stake balance", // Stake balance title 195 | }, 196 | "clear": { 197 | "no": "I am not allowed to delete private messages!", 198 | }, 199 | "creditdeposits": { 200 | "manually":"Manually credited", 201 | "deposits":"Deposits", 202 | "cron":"Cron credited", 203 | "cron2":"deposits" 204 | }, 205 | "deposit": { 206 | "title":"Deposit", 207 | "address":"Address", 208 | "description":"Please double check your deposit address before sending any coins." 209 | }, 210 | "donate": { 211 | "title":"Donate", 212 | "address":"Address", 213 | "description":"Feel free to send a tip to the following address if you want to support the bot creator. Thank you! :o)" 214 | }, 215 | "drop": { 216 | "private":"Please use the public chat to drop.", 217 | "big":"Drop amount", 218 | "big1":"is bigger as your balance", 219 | "big2":".", 220 | "min":"The min value for a drop is", 221 | "minTime":"Min seconds for a drop are", 222 | "maxTime":"Max seconds for a drop are", 223 | "minFailedUserTitle":"Drop terminated", 224 | "minFailedUser":"users entered into the drop.", 225 | "minFailedUser1":"users are needed for a successful drop.", 226 | "dropPhraseReply":"Answer in this channel with the following phrase to win a share.", 227 | "dropReactReply":"React with the following icon to win a share.", 228 | "title":"Drop started", 229 | "phrase":"Phrase (copy & paste)", 230 | "icon":"Icon", 231 | "amount":"Drop amount", 232 | "seconds":"Drop time (seconds)", 233 | "titleSent":"Drop sent", 234 | "rounded":"rounded to", 235 | "users":"Users", 236 | "each":"each", 237 | "description":"Drop successfully sent.", 238 | }, 239 | "getdeposits": { 240 | "manually":"Manually updated", 241 | "deposits":"Deposits", 242 | "cron":"Cron updated", 243 | "cron2":"deposits" 244 | }, 245 | "help": { 246 | "title":"Bot commands", 247 | "registerTitle":"+register || +r", 248 | "registerValue":"Register an account with the bot.", 249 | "profileTitle":"+profile || +p", 250 | "profileValue":"Display account information.", 251 | "balanceTitle":"+balance || +b", 252 | "balanceValue":"Display your current balance.", 253 | "depositTitle":"+deposit || +d", 254 | "depositValue":"Get your deposit address.", 255 | "withdrawTitle":"+withdraw
|| +w
", 256 | "withdrawValue":"Withdraw balance to an address (0.01 Symbol transaction fee will be added on top of the amount).", 257 | "stakeTitle":"+stake ", 258 | "stakeValue":"Convert balance to stake balance for receiving stake pool payouts. (Its always possible to add balance but it will reset the unstake timer)", 259 | "unstakeTitle":"+unstake ", 260 | "unstakeValue":"Convert balance to normal balance (Only once within 24 hours if no stake/unstake has been done).", 261 | "tipTitle":"+tip <@username> ", 262 | "tipValue":"Tip a user from Discord.", 263 | "rainTitle":"+rain all/online/random ", 264 | "rainValue":"(all) Tip amount divided by total user count. / (online) Tip amount divided by active users. / (random) Tip amount divided by random user count.", 265 | "dropTitle":"+drop phrase/react <30 letter phrase>", 266 | "dropValue":"(phrase) Send coins to all users that reply with the asked phrase. / (react) Send coins to all users that react with the asked icon.", 267 | "historyTitle":"+history deposits/withdrawals/payments || +history d/w/p", 268 | "historyValue":"(deposits) Show your latest deposits. / (withdrawals) Show your latest withdrawals. / (payments) Show your latest payments.", 269 | "updateTitle":"+update || +u", 270 | "updateValue":"Update your username.", 271 | "donateTitle":"+donate", 272 | "donateValue":"Show the bot creators tip address.", 273 | "notifyTitle": "+notify ", 274 | "notifyValue": "Enable or disable to get mentioned by the bot.", 275 | "versionTitle": "+version || +v", 276 | "versionValue": "Get current bot and wallet information.", 277 | "admin": { 278 | "title":"Admin commands", 279 | "startStopTitle":"+start / +stop", 280 | "startStopValue":"Enable/Disable all bot commands while the bot is running.", 281 | "getDepositsTitle":"+getdeposits || +gd", 282 | "getDepositsValue":"Manually get latest transactions from wallet and update confirmations.", 283 | "creditDepositsTitle":"+creditdeposits || +cd", 284 | "creditDepositsValue":"Manually check confiramtions on database and credit deposits if they have min confirmations.", 285 | "getStakesTitle":"+getstakes || +gs", 286 | "getStakesValue":"Manually check transactions on database if they are stakes.", 287 | "creditStakesTitle":"+creditstakes || +cs", 288 | "creditStakesValue":"Manually credit stakes to users.", 289 | "clearTitle":"+clear || +c", 290 | "clearValue":"Delete all visible messages from chat." 291 | } 292 | }, 293 | "title": { 294 | "warning":"Warning", 295 | "error":"Something went wrong" 296 | }, 297 | "history": { 298 | "deposits": { 299 | "no":"No deposits to display. Please use **+deposit** to display your deposit address.", 300 | "view":"View transactions online", 301 | "title":"Deposit history (latest first)", 302 | "credited":"credited", 303 | "pending":"pending", 304 | "amount":"Amount", 305 | "status":"Status", 306 | "confirmations":"Confirmations", 307 | "description":"Deposits need", 308 | "description1":"confirmations to get credited. Confirmations get updated every", 309 | "description2":"seconds." 310 | }, 311 | "withdrawals": { 312 | "no":"No withdrawals to display. Please use **+withdraw
** to withdraw your balance.", 313 | "title":"Withdrawal history (latest first)", 314 | "description":"Please be patient. It may take a few minutes until a new transaction appears in the blockexplorer." 315 | }, 316 | "payments": { 317 | "no":"No payments to display.", 318 | "title":"Payment history (latest first)", 319 | "description":"History about your latest payments/tips.", 320 | "type":"Type", 321 | "amount":"Amount" 322 | } 323 | }, 324 | "profile": { 325 | "title": "User profile", 326 | "userid": "User ID", 327 | "username": "Current username", 328 | "registered": "Register date", 329 | "description": "Your account related information." 330 | }, 331 | "rain": { 332 | "private":"Please use the public chat to rain.", 333 | "big":"Rain amount", 334 | "big1":"is bigger as your balance", 335 | "big2":".", 336 | "minimum":"Failed to send rain. The minimum value is", 337 | "minimum1":"for the count of", 338 | "minimum2":"users.", 339 | "title":"Rain sent", 340 | "description":"Rain successfully sent.", 341 | "amount":"Amount", 342 | "rounded":"rounded to", 343 | "users":"Users", 344 | "each":"each", 345 | "randommax": "A maximum of", 346 | "randommax1": "users can receive a rain at once. Please use a lower number." 347 | }, 348 | "register": { 349 | "already":"You are already registered. \nPlease type **+profile** to see your information.", 350 | "registered":"Please type **+profile** to see your information.", 351 | "title":"Successfully registered" 352 | }, 353 | "tip": { 354 | "private":"Please use the public chat to tip.", 355 | "big":"Tip amount", 356 | "big1":"is bigger as your balance", 357 | "big2":".", 358 | "no":"Sorry, there is no user to tip.", 359 | "notvalid":"The username is not valid. Please use @username from Discord as name.", 360 | "self":"You can't tip yourself :)", 361 | "min":"The min value for a tip is", 362 | "title":"Tip sent", 363 | "description":"Tip successfully sent.", 364 | "amount":"Amount", 365 | "user":"User" 366 | }, 367 | "update": { 368 | "title":"Username updated", 369 | "description":"Please type **+profile** to see your information.", 370 | }, 371 | "withdraw": { 372 | "notvalid":"The specified payout address is not valid.", 373 | "big": "Withdraw amount", 374 | "big1": "+ withdraw fee", 375 | "big2": "=", 376 | "big3": "and its bigger as your balance", 377 | "big4": ". Maximal available value for withdrawal is", 378 | "big5": ".", 379 | "min":"The min value for a withdrawal is", 380 | "failDBsave":"Withdrawal done but an error came up. Please contact the admin about this problem!", 381 | "title":"Withdrawal sent", 382 | "description":"Withdrawal successfully sent.", 383 | "amount":"Amount", 384 | "transaction":"Transaction", 385 | "address":"Address" 386 | }, 387 | "getstakes": { 388 | "manually":"Manually checked", 389 | "transactions":"Transactions", 390 | "cron":"Cron checked", 391 | "cron2":"stake transactions" 392 | }, 393 | "creditstakes": { 394 | "manually":"Manually credited", 395 | "transactions":"Stake(s)", 396 | "cron":"Cron credited", 397 | "cron2":"stake transactions", 398 | "title":"Staking pool payout", 399 | "stakes":"Stake(s)", 400 | "amount":"Amount", 401 | "users":"Users", 402 | "description":"To check your pool payouts please use the history command." 403 | }, 404 | "stake": { 405 | "big":"Stake amount", 406 | "big1":"is bigger as your balance", 407 | "big2":".", 408 | "title": "Stake balance updated (added)", 409 | "description": "Successfully updated stake balance.", 410 | "amount":"Amount added", 411 | "min":"The minimum value that has to be added to the stake balance is" 412 | }, 413 | "unstake":{ 414 | "big":"Unstake amount", 415 | "big1":"is bigger as your stake balance", 416 | "big2":".", 417 | "title": "Stake balance updated (reduced)", 418 | "description": "Successfully updated stake balance.", 419 | "amount":"Amount removed", 420 | "min":"The minimum value that must be subtracted from the stake balance is", 421 | "rest":"The remaining amount", 422 | "rest2":"would be below the min stake value of", 423 | "rest3":". The total stake value has been transferred.", 424 | "left":"Your balance is currently locked. We have implemented a freeze period and your next unstake is possible in", 425 | "left2":".", 426 | "leftdays":"DAYS", 427 | "lefthours":"HOURS", 428 | "leftminutes":"MINUTES", 429 | "leftseconds":"SECONDS", 430 | "locked":"Freeze period active" 431 | }, 432 | "notify": { 433 | "title": "Notification setting updated", 434 | "enabled": "Mentions have been enabled.", 435 | "disabled": "Mentions have been disabled." 436 | }, 437 | "version": { 438 | "title": "Bot and wallet information", 439 | "botversion": "Version (Bot)", 440 | "walletversion": "Version (Wallet)", 441 | "walletprotocolversion": "Protocolversion", 442 | "walletconnections": "Connections", 443 | "walletblocks": "Blocks", 444 | "walletdifficulty": "Difficulty" 445 | } 446 | } 447 | }; 448 | -------------------------------------------------------------------------------- /discordbot.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crypto-node/Cryptocurrency-crypto-bot/d44d6c03422eb322faed2ae80f5a3431a48454be/discordbot.log -------------------------------------------------------------------------------- /functions/chat.js: -------------------------------------------------------------------------------- 1 | //var config = require('../config.js'); 2 | try{ 3 | var config = process.cwd()+'/config.js'; 4 | config = require(config); 5 | }catch (error){ 6 | console.error('ERROR -> Unable to load config file.'); 7 | process.exit(1); 8 | } 9 | 10 | /* ------------------------------------------------------------------------------ */ 11 | // // // // // // // // // // // // // // // // // // // // // // // // // // // // 12 | /* ------------------------------------------------------------------------------ */ 13 | 14 | // A lightweight JavaScript date library for parsing, validating, manipulating, and formatting dates. 15 | const moment = require('moment-timezone'); 16 | 17 | const { RichEmbed } = require('discord.js'); 18 | 19 | const Big = require('big.js'); // https://github.com/MikeMcl/big.js -> http://mikemcl.github.io/big.js/ 20 | 21 | /* ------------------------------------------------------------------------------ */ 22 | // // // // // // // // // // // // // // // // // // // // // // // // // // // // 23 | /* ------------------------------------------------------------------------------ */ 24 | 25 | module.exports = { 26 | 27 | /* ------------------------------------------------------------------------------ */ 28 | // Create reply message 29 | /* ------------------------------------------------------------------------------ */ 30 | // msg.channel.send(chat.chat_build_reply('embed',userName,messageType,config.colors.special,['Test Author Name',config.wallet.thumbnailIcon,'https://google.de'],'Title',[['Testfield1','Testfield1 Value',true],['Testfield2','Testfield2 Value',true]],'This is a test description.',['Test Footer',config.wallet.thumbnailIcon],config.wallet.thumbnailIcon,'https://media.wired.com/photos/5ada3a2c1e66870735eada27/master/pass/DragonPasswordFINAL.jpg',1)); 31 | chat_build_reply: function(replyType,replyUsername,senderMessageType,replyEmbedColor,replyAuthor,replyTitle,replyFields,replyDescription,replyFooter,replyThumbnail,replyImage,replyTimestamp){ 32 | if(replyType == 'normal'){ 33 | if(senderMessageType == 'dm' || !replyUsername){ 34 | return replyDescription; 35 | }else{ 36 | return replyDescription + ' ' + replyUsername; 37 | } 38 | } 39 | if(replyType == 'embed' || 'private'){ 40 | var embed = new RichEmbed(); 41 | // Set embed color 42 | if(replyEmbedColor){ 43 | embed.setColor(replyEmbedColor); 44 | }else{ 45 | embed.setColor(config.colors.normal); 46 | } 47 | // Set reply autor 48 | if(replyAuthor){ 49 | var replyAuthorName = ''; 50 | var replyAuthorIcon = ''; 51 | var replyAuthorLink = ''; 52 | if(replyAuthor[0]) 53 | replyAuthorName = replyAuthor[0]; 54 | if(replyAuthor[1]) 55 | replyAuthorIcon = replyAuthor[1]; 56 | if(replyAuthor[2]) 57 | replyAuthorLink = replyAuthor[2]; 58 | embed.setAuthor(replyAuthorName,replyAuthorIcon,replyAuthorLink); 59 | } 60 | // Set Title 61 | if(replyTitle){ 62 | embed.setTitle(replyTitle.toUpperCase()); 63 | } 64 | // This could be added to be able to set a link for the title 65 | // embed.setURL('http://google.de'); 66 | // Set description 67 | if(replyDescription){ 68 | //console.log(senderMessageType+' '+replyUsername+' '+typeof(replyUsername)); 69 | // Check if request was not private or add username disabled 70 | if(senderMessageType === 'dm' || !replyUsername){ 71 | embed.setDescription(replyDescription); 72 | }else{ 73 | embed.setDescription(replyDescription + ' ' + replyUsername); 74 | } 75 | } 76 | // Set reply fields 77 | for (var i = 0 ; i < replyFields.length ; ++i){ 78 | if(replyFields[i][0] === 0 && replyFields[i][1] === 0){ 79 | embed.addBlankField(replyFields[i][2]); 80 | }else{ 81 | embed.addField(replyFields[i][0],replyFields[i][1],replyFields[i][2]); 82 | } 83 | 84 | } 85 | // Set reply footer 86 | if(replyFooter){ 87 | var replyFooterText = ''; 88 | var replyFooterIcon = ''; 89 | if(replyFooter[0]) 90 | replyFooterText = replyFooter[0]; 91 | if(replyFooter[1]) 92 | replyFooterIcon = replyFooter[1]; 93 | embed.setFooter(replyFooterText,replyFooterIcon); 94 | } 95 | // Set thumbnail 96 | if(replyThumbnail){ 97 | embed.setThumbnail(replyThumbnail); 98 | } 99 | // Set image 100 | if(replyImage){ 101 | embed.setImage(replyImage); 102 | } 103 | // Set timestamp 104 | if(replyTimestamp){ 105 | embed.setTimestamp(); 106 | } 107 | // all done and return embed 108 | return embed; 109 | } 110 | }, 111 | 112 | /* ------------------------------------------------------------------------------ */ 113 | // Build chat reply 114 | /* ------------------------------------------------------------------------------ */ 115 | 116 | chat_reply: function(msg,replyType,replyUsername,senderMessageType,replyEmbedColor,replyAuthor,replyTitle,replyFields,replyDescription,replyFooter,replyThumbnail,replyImage,replyTimestamp){ 117 | if(replyType == 'private'){ 118 | return msg.author.send(this.chat_build_reply(replyType,replyUsername,senderMessageType,replyEmbedColor,replyAuthor,replyTitle,replyFields,replyDescription,replyFooter,replyThumbnail,replyImage,replyTimestamp)); 119 | }else if(replyType == 'pool'){ 120 | var poolChannel = globalClient.channels.get(config.bot.stakePoolChannelID); 121 | return poolChannel.send(this.chat_build_reply(replyType,replyUsername,senderMessageType,replyEmbedColor,replyAuthor,replyTitle,replyFields,replyDescription,replyFooter,replyThumbnail,replyImage,replyTimestamp)); 122 | }else{ 123 | return msg.channel.send(this.chat_build_reply(replyType,replyUsername,senderMessageType,replyEmbedColor,replyAuthor,replyTitle,replyFields,replyDescription,replyFooter,replyThumbnail,replyImage,replyTimestamp)); 124 | } 125 | } 126 | 127 | }; -------------------------------------------------------------------------------- /functions/check.js: -------------------------------------------------------------------------------- 1 | //var config = require('../config.js'); 2 | try{ 3 | var config = process.cwd()+'/config.js'; 4 | config = require(config); 5 | }catch (error){ 6 | console.error('ERROR -> Unable to load config file.'); 7 | process.exit(1); 8 | } 9 | 10 | /* ------------------------------------------------------------------------------ */ 11 | // // // // // // // // // // // // // // // // // // // // // // // // // // // // 12 | /* ------------------------------------------------------------------------------ */ 13 | 14 | const Big = require('big.js'); // https://github.com/MikeMcl/big.js -> http://mikemcl.github.io/big.js/ 15 | const rp = require('request-promise'); 16 | 17 | /* ------------------------------------------------------------------------------ */ 18 | // // // // // // // // // // // // // // // // // // // // // // // // // // // // 19 | /* ------------------------------------------------------------------------------ */ 20 | 21 | module.exports = { 22 | 23 | /* ------------------------------------------------------------------------------ */ 24 | // Get x random elements from array 25 | /* ------------------------------------------------------------------------------ */ 26 | 27 | check_getRandomFromArray: function (arr, n) { 28 | var result = new Array(n), 29 | len = arr.length, 30 | taken = new Array(len); 31 | if (n > len) 32 | throw new RangeError("getRandom: more elements taken than available"); 33 | while (n--) { 34 | var x = Math.floor(Math.random() * len); 35 | result[n] = arr[x in taken ? taken[x] : x]; 36 | taken[x] = --len in taken ? taken[len] : len; 37 | } 38 | return result; 39 | }, 40 | 41 | /* ------------------------------------------------------------------------------ */ 42 | // Check if valid json 43 | /* ------------------------------------------------------------------------------ */ 44 | 45 | check_valid_json: function (n) { 46 | if (/^[\],:{}\s]*$/.test(n.replace(/\\["\\\/bfnrtu]/g, '@'). 47 | replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'). 48 | replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { 49 | return true; 50 | }else{ 51 | return false; 52 | } 53 | }, 54 | 55 | /* ------------------------------------------------------------------------------ */ 56 | // Check if value is out of javascript max integer range 57 | /* ------------------------------------------------------------------------------ */ 58 | 59 | check_out_of_int_range: function (n) { 60 | if(Big(n).gte(Big(Number.MAX_SAFE_INTEGER))){ 61 | return true; 62 | } 63 | if(Big(n).lte(Big(Number.MIN_SAFE_INTEGER))){ 64 | return true; 65 | } 66 | return false; 67 | }, 68 | 69 | /* ------------------------------------------------------------------------------ */ 70 | // Check if value is a number 71 | /* ------------------------------------------------------------------------------ */ 72 | 73 | check_isNumeric: function (n) { 74 | return !isNaN(parseFloat(n)) && isFinite(n); 75 | }, 76 | 77 | /* ------------------------------------------------------------------------------ */ 78 | // Slice string 79 | /* ------------------------------------------------------------------------------ */ 80 | 81 | check_slice_string: function(string,lenght){ 82 | try{ 83 | return string.substring(0, lenght); 84 | }catch (error){ 85 | return 'noName'; 86 | } 87 | }, 88 | 89 | /* ------------------------------------------------------------------------------ */ 90 | // Check if the message is a valid message and only contains valid characters 91 | /* ------------------------------------------------------------------------------ */ 92 | 93 | check_valid_content: function(msg){ 94 | //console.log(msg); 95 | return /^[a-zA-Z0-9\.\ \_\:\!\+\[\]\#\@\<\>]{2,500}$/.test(msg); 96 | }, 97 | 98 | /* ------------------------------------------------------------------------------ */ 99 | // Check valid discord id (start with <@ , mid only numbers, end >) 100 | /* ------------------------------------------------------------------------------ */ 101 | 102 | /*check_valid_discord_id: function(msg){ 103 | return /^\/<@?|<@!?\d+\>$/.test(msg); 104 | },*/ 105 | 106 | check_valid_discord_id: function(msg){ 107 | //console.log(msg); 108 | //return /^\<@\d+\>$/.test(msg); 109 | if(/^\<@\d+\>$/.test(msg)){ 110 | return true; 111 | }else if(/^\<@!\d+\>$/.test(msg)){ 112 | return true; 113 | }else{ 114 | return false; 115 | } 116 | }, 117 | 118 | /* ------------------------------------------------------------------------------ */ 119 | // Check if the channel is a valid channel to repond to 120 | /* ------------------------------------------------------------------------------ */ 121 | 122 | check_respond_channel: function(channelID){ 123 | var respondChannelIDs = {}; 124 | for (var i = 0 ; i < config.bot.respondChannelIDs.length ; ++i) 125 | respondChannelIDs[config.bot.respondChannelIDs[i]] = true; 126 | return respondChannelIDs[channelID]; 127 | }, 128 | 129 | /* ------------------------------------------------------------------------------ */ 130 | // Return the user role 131 | /* ------------------------------------------------------------------------------ */ 132 | 133 | check_user_role: function(userID,userRoles){ // Role value 0 = normal user, 1 = vip user, 2 = moderator, 3 = admin 134 | var adminIDs = {}; 135 | for (var i = 0 ; i < config.bot.adminIDs.length ; ++i) 136 | adminIDs[config.bot.adminIDs[i]] = true; 137 | if(adminIDs[userID]) 138 | return 3; // if admin 139 | var moderatorIDs = {}; 140 | for (var i = 0 ; i < config.bot.moderatorIDs.length ; ++i) 141 | moderatorIDs[config.bot.moderatorIDs[i]] = true; 142 | if(moderatorIDs[userID]) 143 | return 2; // if moderator 144 | if(userRoles !== 'none'){ 145 | if(userRoles.find(x => x.name === config.bot.vipGroupName)) 146 | return 1; // if vip user 147 | } 148 | return 0; // If no role 149 | }, 150 | 151 | /* ------------------------------------------------------------------------------ */ 152 | // Get current currency price for coin id 153 | /* ------------------------------------------------------------------------------ */ 154 | check_get_coin_price: function(){ 155 | return new Promise((resolve, reject)=>{ 156 | 157 | var apiService = config.coinPrice.apiService; 158 | var requestOptions = {}; 159 | 160 | switch (apiService) { 161 | case 'coinmarketcap': 162 | requestOptions = { 163 | method: 'GET', 164 | uri: 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest', 165 | qs: { 166 | 'symbol': config.coinPrice.coinSymbol, 167 | 'convert': config.coinPrice.currency 168 | }, 169 | headers: { 170 | 'X-CMC_PRO_API_KEY': config.coinPrice.apiKey 171 | }, 172 | json: true, 173 | gzip: true 174 | }; 175 | rp(requestOptions).then(response => { 176 | if(response.status.error_code > 0){ 177 | resolve(false); 178 | }else{ 179 | resolve(response.data[config.coinPrice.coinSymbol].quote[config.coinPrice.currency].price); 180 | } 181 | }).catch((err) => { 182 | resolve(false); 183 | }); 184 | break; 185 | case 'cryptocompare': 186 | requestOptions = { 187 | method: 'GET', 188 | uri: 'https://min-api.cryptocompare.com/data/price', 189 | qs: { 190 | 'fsym': config.coinPrice.coinSymbol, 191 | 'tsyms': config.coinPrice.currency, 192 | 'api_key': config.coinPrice.apiKey 193 | }, 194 | json: true, 195 | gzip: true 196 | }; 197 | rp(requestOptions).then(response => { 198 | if(response.Response == "Error"){ 199 | resolve(false); 200 | }else{ 201 | resolve(response[config.coinPrice.currency]); 202 | } 203 | }).catch((err) => { 204 | resolve(false); 205 | }); 206 | break; 207 | default: 208 | resolve(false); 209 | } 210 | 211 | }); 212 | } 213 | 214 | }; -------------------------------------------------------------------------------- /functions/cron.js: -------------------------------------------------------------------------------- 1 | //var config = require('../config.js'); 2 | try{ 3 | var config = process.cwd()+'/config.js'; 4 | config = require(config); 5 | }catch (error){ 6 | console.error('ERROR -> Unable to load config file.'); 7 | process.exit(1); 8 | } 9 | 10 | const Big = require('big.js'); // https://github.com/MikeMcl/big.js -> http://mikemcl.github.io/big.js/ 11 | 12 | var command = require("./command.js"); 13 | var check = require("./check.js"); 14 | var transaction = require("./transaction.js"); 15 | 16 | /* ------------------------------------------------------------------------------ */ 17 | // // // // // // // // // // // // // // // // // // // // // // // // // // // // 18 | /* ------------------------------------------------------------------------------ */ 19 | 20 | module.exports = { 21 | 22 | /* ------------------------------------------------------------------------------ */ 23 | // Process deposits cron 24 | /* ------------------------------------------------------------------------------ */ 25 | 26 | cron_get_deposits: function() { 27 | setInterval(function (){ 28 | command.command_get_deposits(0); 29 | }, config.wallet.depositsConfirmationTime*1000); 30 | }, 31 | 32 | /* ------------------------------------------------------------------------------ */ 33 | // Credit deposits cron 34 | /* ------------------------------------------------------------------------------ */ 35 | 36 | cron_credit_deposits: function() { 37 | setInterval(function (){ 38 | command.command_credit_deposits(0); 39 | }, config.wallet.depositsCreditTime*1000); 40 | }, 41 | 42 | /* ------------------------------------------------------------------------------ */ 43 | // Check saved wallet transactions for stakes 44 | /* ------------------------------------------------------------------------------ */ 45 | 46 | cron_get_stakes: function() { 47 | setInterval(function (){ 48 | command.command_get_stakes(0); 49 | }, config.staking.checkTime*1000); 50 | }, 51 | 52 | /* ------------------------------------------------------------------------------ */ 53 | // Credit stake transactions 54 | /* ------------------------------------------------------------------------------ */ 55 | 56 | cron_credit_stakes: function() { 57 | setInterval(function (){ 58 | command.command_credit_stakes(0); 59 | }, config.staking.creditTime*1000); 60 | }, 61 | 62 | /* ------------------------------------------------------------------------------ */ 63 | // Get coin price 64 | /* ------------------------------------------------------------------------------ */ 65 | 66 | cron_price: async function() { 67 | var newCoinPrice = 0; 68 | newCoinPrice = await check.check_get_coin_price(); 69 | if(newCoinPrice){ 70 | coinPrice = newCoinPrice; 71 | coinCentPrice = Big(0.01).div(newCoinPrice).toFixed(8); 72 | saveCoinPriceHistory = await transaction.transaction_coin_price_history(coinPrice); 73 | } 74 | setInterval(async function (){ 75 | // Check if bot is curently disabled 76 | if(botEnabled){ 77 | newCoinPrice = await check.check_get_coin_price(); 78 | if(newCoinPrice){ 79 | coinPrice = newCoinPrice; 80 | coinCentPrice = Big(0.01).div(newCoinPrice).toFixed(8); 81 | saveCoinPriceHistory = await transaction.transaction_coin_price_history(coinPrice); 82 | } 83 | } 84 | }, config.coinPrice.cronTime*1000); 85 | } 86 | 87 | }; -------------------------------------------------------------------------------- /functions/log.js: -------------------------------------------------------------------------------- 1 | //var config = require('../config.js'); 2 | try{ 3 | var config = process.cwd()+'/config.js'; 4 | config = require(config); 5 | }catch (error){ 6 | console.error('ERROR -> Unable to load config file.'); 7 | process.exit(1); 8 | } 9 | 10 | /* ------------------------------------------------------------------------------ */ 11 | // // // // // // // // // // // // // // // // // // // // // // // // // // // // 12 | /* ------------------------------------------------------------------------------ */ 13 | 14 | const log4js = require('log4js'); 15 | log4js.configure({ 16 | appenders: { discordbot: { type: 'file', filename: 'discordbot.log' } }, 17 | categories: { default: { appenders: ['discordbot'], level: 'error' } } 18 | }); 19 | const logger = log4js.getLogger('discordbot'); 20 | 21 | /* ------------------------------------------------------------------------------ */ 22 | // // // // // // // // // // // // // // // // // // // // // // // // // // // // 23 | /* ------------------------------------------------------------------------------ */ 24 | 25 | module.exports = { 26 | 27 | /* ------------------------------------------------------------------------------ */ 28 | // Log: Message to database 29 | /* ------------------------------------------------------------------------------ */ 30 | 31 | log_write_database: function(UserID,logDescription = '',logValue = 0) { 32 | var self = this; 33 | mysqlPool.getConnection(function(error, connection){ 34 | if(error){ 35 | try 36 | { 37 | mysqlPool.releaseConnection(connection); 38 | } 39 | catch (e){} 40 | var errorMessage = "log_write_database: MySQL connection problem."; 41 | if(config.bot.errorLogging){ 42 | self.log_write_file(errorMessage); 43 | self.log_write_file(error); 44 | } 45 | self.log_write_console(errorMessage); 46 | self.log_write_console(error); 47 | } 48 | connection.execute("INSERT INTO log (discord_id,description,value,coin_price) VALUES (?,?,?,?)",[UserID,logDescription,logValue,coinPrice],function (error, results, fields){ 49 | mysqlPool.releaseConnection(connection); 50 | if(error) 51 | { 52 | var errorMessage = "log_write_database: MySQL query problem. (INSERT INTO log (discord_id,description,value,coin_price) VALUES (?,?,?,?))"; 53 | if(config.bot.errorLogging){ 54 | self.log_write_file(errorMessage); 55 | self.log_write_file(error); 56 | } 57 | self.log_write_console(errorMessage); 58 | self.log_write_console(error); 59 | } 60 | }); 61 | }); 62 | }, 63 | 64 | /* ------------------------------------------------------------------------------ */ 65 | // Log: Message to file 66 | /* ------------------------------------------------------------------------------ */ 67 | 68 | log_write_file: function(message) { 69 | logger.error(message); 70 | }, 71 | 72 | /* ------------------------------------------------------------------------------ */ 73 | // Log: Message to console 74 | /* ------------------------------------------------------------------------------ */ 75 | 76 | log_write_console: function(message) { 77 | console.error(message); 78 | }, 79 | 80 | }; -------------------------------------------------------------------------------- /functions/storage.js: -------------------------------------------------------------------------------- 1 | //var config = require('../config.js'); 2 | try{ 3 | var config = process.cwd()+'/config.js'; 4 | config = require(config); 5 | }catch (error){ 6 | console.error('ERROR -> Unable to load config file.'); 7 | process.exit(1); 8 | } 9 | 10 | var log = require("./log.js"); 11 | 12 | /* ------------------------------------------------------------------------------ */ 13 | // // // // // // // // // // // // // // // // // // // // // // // // // // // // 14 | /* ------------------------------------------------------------------------------ */ 15 | 16 | // https://github.com/typicode/lowdb 17 | // lowdb for content that is not as important but needs to be queried fast 18 | const low = require('lowdb'); 19 | const FileSync = require('lowdb/adapters/FileSync'); 20 | const adapter = new FileSync(process.cwd()+'/lowdb/lowdb.json') 21 | const db = low(adapter); 22 | 23 | /* ------------------------------------------------------------------------------ */ 24 | // // // // // // // // // // // // // // // // // // // // // // // // // // // // 25 | /* ------------------------------------------------------------------------------ */ 26 | 27 | module.exports = { 28 | 29 | /* ------------------------------------------------------------------------------ */ 30 | // Write to local storage 31 | /* ------------------------------------------------------------------------------ */ 32 | 33 | storage_write_local_storage: function(userID,valueName,value) { 34 | return new Promise((resolve, reject)=>{ 35 | try{ 36 | var storage_write = db.set(userID+'.'+valueName, value).write(); 37 | resolve(true); 38 | }catch (error){ 39 | var errorMessage = "storage_write_local_storage: Can't write to local storage."; 40 | if(config.bot.errorLogging){ 41 | log.log_write_file(errorMessage); 42 | log.log_write_file(error); 43 | } 44 | log.log_write_console(errorMessage); 45 | log.log_write_console(error); 46 | resolve(false); 47 | }; 48 | }); 49 | }, 50 | 51 | /* ------------------------------------------------------------------------------ */ 52 | // Delete from local storage 53 | /* ------------------------------------------------------------------------------ */ 54 | 55 | storage_delete_local_storage: function(userID,valueName) { 56 | return new Promise((resolve, reject)=>{ 57 | try{ 58 | var storage_delete = db.unset(userID+'.'+valueName).write(); 59 | resolve(true); 60 | }catch (error){ 61 | var errorMessage = "storage_delte_local_storage: Can't delete from local storage."; 62 | if(config.bot.errorLogging){ 63 | log.log_write_file(errorMessage); 64 | log.log_write_file(error); 65 | } 66 | log.log_write_console(errorMessage); 67 | log.log_write_console(error); 68 | resolve(false); 69 | }; 70 | }); 71 | }, 72 | 73 | /* ------------------------------------------------------------------------------ */ 74 | // Read from local storage 75 | /* ------------------------------------------------------------------------------ */ 76 | 77 | storage_read_local_storage: function(userID,valueName) { 78 | return new Promise((resolve, reject)=>{ 79 | try{ 80 | var storage_read = db.get(userID+'.'+valueName).value(); 81 | resolve(storage_read); 82 | }catch (error){ 83 | var errorMessage = "storage_read_local_storage: Can't read from local storage."; 84 | if(config.bot.errorLogging){ 85 | log.log_write_file(errorMessage); 86 | log.log_write_file(error); 87 | } 88 | log.log_write_console(errorMessage); 89 | log.log_write_console(error); 90 | resolve(false); 91 | }; 92 | }); 93 | } 94 | 95 | }; -------------------------------------------------------------------------------- /functions/transaction.js: -------------------------------------------------------------------------------- 1 | //var config = require('../config.js'); 2 | try{ 3 | var config = process.cwd()+'/config.js'; 4 | config = require(config); 5 | }catch (error){ 6 | console.error('ERROR -> Unable to load config file.'); 7 | process.exit(1); 8 | } 9 | 10 | var log = require("./log.js"); 11 | 12 | /* ------------------------------------------------------------------------------ */ 13 | // // // // // // // // // // // // // // // // // // // // // // // // // // // // 14 | /* ------------------------------------------------------------------------------ */ 15 | 16 | // Mysql2 17 | const mysql = require('mysql2'); 18 | // connect mysql database 19 | mysqlPool = mysql.createPool({ 20 | connectionLimit : config.mysql.connectionLimit, 21 | waitForConnections: config.mysql.waitForConnections, 22 | host : config.mysql.dbHost, 23 | user : config.mysql.dbUser, 24 | port : config.mysql.dbPort, 25 | password : config.mysql.dbPassword, 26 | database : config.mysql.dbName 27 | }); 28 | 29 | const Big = require('big.js'); // https://github.com/MikeMcl/big.js -> http://mikemcl.github.io/big.js/ 30 | 31 | /* ------------------------------------------------------------------------------ */ 32 | // // // // // // // // // // // // // // // // // // // // // // // // // // // // 33 | /* ------------------------------------------------------------------------------ */ 34 | 35 | module.exports = { 36 | 37 | /* ------------------------------------------------------------------------------ */ 38 | // Get confirmed deposits from database 39 | /* ------------------------------------------------------------------------------ */ 40 | transaction_get_confirmed_deposits: function(){ 41 | return new Promise((resolve, reject)=>{ 42 | mysqlPool.getConnection(function(error, connection){ 43 | if(error){ 44 | try 45 | { 46 | mysqlPool.releaseConnection(connection); 47 | } 48 | catch (e){} 49 | var errorMessage = "transaction_get_confirmed_deposits: MySQL connection problem."; 50 | if(config.bot.errorLogging){ 51 | log.log_write_file(errorMessage); 52 | log.log_write_file(error); 53 | } 54 | log.log_write_console(errorMessage); 55 | log.log_write_console(error); 56 | resolve(false); 57 | }else{ 58 | connection.execute("SELECT * FROM deposits WHERE credited = ? AND confirmations > ?",[0,config.wallet.minConfirmationsCredit],function (error, results, fields){ 59 | mysqlPool.releaseConnection(connection); 60 | if(error) 61 | { 62 | var errorMessage = "transaction_get_confirmed_deposits: MySQL query problem. (SELECT * FROM deposits WHERE credited = ? AND confirmations > ?)"; 63 | if(config.bot.errorLogging){ 64 | log.log_write_file(errorMessage); 65 | log.log_write_file(error); 66 | } 67 | log.log_write_console(errorMessage); 68 | log.log_write_console(error); 69 | resolve(false); 70 | }else{ 71 | resolve(results); 72 | } 73 | }); 74 | } 75 | }); 76 | }); 77 | }, 78 | 79 | /* ------------------------------------------------------------------------------ */ 80 | // Get deposits from database by address and limit for history 81 | /* ------------------------------------------------------------------------------ */ 82 | transaction_get_deposits_by_address: function(depositHistoryDisplayCount,userDepositAddress){ 83 | return new Promise((resolve, reject)=>{ 84 | mysqlPool.getConnection(function(error, connection){ 85 | if(error){ 86 | try 87 | { 88 | mysqlPool.releaseConnection(connection); 89 | } 90 | catch (e){} 91 | var errorMessage = "transaction_get_confirmed_deposits: MySQL connection problem."; 92 | if(config.bot.errorLogging){ 93 | log.log_write_file(errorMessage); 94 | log.log_write_file(error); 95 | } 96 | log.log_write_console(errorMessage); 97 | log.log_write_console(error); 98 | resolve(false); 99 | }else{ 100 | connection.execute("SELECT * FROM deposits WHERE address = ? ORDER BY id DESC LIMIT "+depositHistoryDisplayCount,[userDepositAddress],function (error, results, fields){ 101 | mysqlPool.releaseConnection(connection); 102 | if(error) 103 | { 104 | var errorMessage = "transaction_get_confirmed_deposits: MySQL query problem. (SELECT * FROM deposits WHERE address = ? ORDER BY id DESC LIMIT "+depositHistoryDisplayCount+")"; 105 | if(config.bot.errorLogging){ 106 | log.log_write_file(errorMessage); 107 | log.log_write_file(error); 108 | } 109 | log.log_write_console(errorMessage); 110 | log.log_write_console(error); 111 | resolve(false); 112 | }else{ 113 | resolve(results); 114 | } 115 | }); 116 | } 117 | }); 118 | }); 119 | }, 120 | 121 | /* ------------------------------------------------------------------------------ */ 122 | // Set deposit as confirmed on database 123 | /* ------------------------------------------------------------------------------ */ 124 | transaction_set_deposit_confirmed: function(creditID){ 125 | return new Promise((resolve, reject)=>{ 126 | mysqlPool.getConnection(function(error, connection){ 127 | if(error){ 128 | try 129 | { 130 | mysqlPool.releaseConnection(connection); 131 | } 132 | catch (e){} 133 | var errorMessage = "transaction_set_deposit_confirmed: MySQL connection problem."; 134 | if(config.bot.errorLogging){ 135 | log.log_write_file(errorMessage); 136 | log.log_write_file(error); 137 | } 138 | log.log_write_console(errorMessage); 139 | log.log_write_console(error); 140 | resolve(false); 141 | }else{ 142 | connection.execute("UPDATE deposits SET credited = ? WHERE id = ?",[1,creditID],function (error, results, fields){ // Set deposit as credited 143 | mysqlPool.releaseConnection(connection); 144 | if(error) 145 | { 146 | var errorMessage = "transaction_set_deposit_confirmed: MySQL query problem. (UPDATE deposits SET credited = ? WHERE id = ?)"; 147 | if(config.bot.errorLogging){ 148 | log.log_write_file(errorMessage); 149 | log.log_write_file(error); 150 | } 151 | log.log_write_console(errorMessage); 152 | log.log_write_console(error); 153 | resolve(false); 154 | }else{ 155 | resolve(true); 156 | } 157 | }); 158 | } 159 | }); 160 | }); 161 | }, 162 | 163 | /* ------------------------------------------------------------------------------ */ 164 | // Add new transactions or update confirmations of existing transactions 165 | /* ------------------------------------------------------------------------------ */ 166 | transaction_add_update_deposits_on_db: function(deposit_address,deposit_amount,deposit_confirmations,deposit_txid){ 167 | return new Promise((resolve, reject)=>{ 168 | mysqlPool.getConnection(function(error, connection){ 169 | if(error){ 170 | try 171 | { 172 | mysqlPool.releaseConnection(connection); 173 | } 174 | catch (e){} 175 | var errorMessage = "transaction_add_update_deposits_on_db: MySQL connection problem."; 176 | if(config.bot.errorLogging){ 177 | log.log_write_file(errorMessage); 178 | log.log_write_file(error); 179 | } 180 | log.log_write_console(errorMessage); 181 | log.log_write_console(error); 182 | resolve(false); 183 | }else{ 184 | connection.execute("INSERT INTO deposits (address,amount,txid,confirmations,credited,coin_price) VALUES (?,?,?,?,?,?) ON DUPLICATE KEY UPDATE confirmations = ?",[deposit_address,Big(deposit_amount).toString(),deposit_txid,deposit_confirmations,0,coinPrice,deposit_confirmations],function (error, results, fields){ 185 | mysqlPool.releaseConnection(connection); 186 | if(error) 187 | { 188 | var errorMessage = "transaction_add_update_deposits_on_db: MySQL query problem. (INSERT INTO deposits (address,amount,txid,confirmations,credited,coin_price) VALUES (?,?,?,?,?,?) ON DUPLICATE KEY UPDATE confirmations = ?)"; 189 | if(config.bot.errorLogging){ 190 | log.log_write_file(errorMessage); 191 | log.log_write_file(error); 192 | } 193 | log.log_write_console(errorMessage); 194 | log.log_write_console(error); 195 | resolve(false); 196 | }else{ 197 | resolve(true); 198 | } 199 | }); 200 | } 201 | }); 202 | }) 203 | }, 204 | 205 | /* ------------------------------------------------------------------------------ */ 206 | // Save withdrawal to database 207 | /* ------------------------------------------------------------------------------ */ 208 | transaction_save_withdrawal_to_db: function(userID,withdrawAddress,withdrawAmount,txID){ 209 | return new Promise((resolve, reject)=>{ 210 | mysqlPool.getConnection(function(error, connection){ 211 | if(error){ 212 | try 213 | { 214 | mysqlPool.releaseConnection(connection); 215 | } 216 | catch (e){} 217 | var errorMessage = "transaction_save_withdrawal_to_db: MySQL connection problem."; 218 | if(config.bot.errorLogging){ 219 | log.log_write_file(errorMessage); 220 | log.log_write_file(error); 221 | } 222 | log.log_write_console(errorMessage); 223 | log.log_write_console(error); 224 | resolve(false); 225 | }else{ 226 | connection.execute("INSERT INTO withdrawals (discord_id,address,amount,txid,coin_price) VALUES (?,?,?,?,?)",[userID,withdrawAddress,Big(withdrawAmount).toString(),txID,coinPrice],function (error, results, fields){ 227 | mysqlPool.releaseConnection(connection); 228 | if(error) 229 | { 230 | var errorMessage = "transaction_save_withdrawal_to_db: MySQL query problem. (INSERT INTO withdrawals (discord_id,address,amount,txid,coin_price) VALUES (?,?,?,?,?))"; 231 | if(config.bot.errorLogging){ 232 | log.log_write_file(errorMessage); 233 | log.log_write_file(error); 234 | } 235 | log.log_write_console(errorMessage); 236 | log.log_write_console(error); 237 | resolve(false); 238 | }else{ 239 | resolve(true); 240 | } 241 | }); 242 | } 243 | }); 244 | }) 245 | }, 246 | 247 | /* ------------------------------------------------------------------------------ */ 248 | // Get withdrawals from database by user id and limit for withdrawals 249 | /* ------------------------------------------------------------------------------ */ 250 | transaction_get_withdrawals_by_user_id: function(withdrawalsHistoryDisplayCount,userID){ 251 | return new Promise((resolve, reject)=>{ 252 | mysqlPool.getConnection(function(error, connection){ 253 | if(error){ 254 | try 255 | { 256 | mysqlPool.releaseConnection(connection); 257 | } 258 | catch (e){} 259 | var errorMessage = "transaction_get_withdrawals_by_user_id: MySQL connection problem."; 260 | if(config.bot.errorLogging){ 261 | log.log_write_file(errorMessage); 262 | log.log_write_file(error); 263 | } 264 | log.log_write_console(errorMessage); 265 | log.log_write_console(error); 266 | resolve(false); 267 | }else{ 268 | connection.execute("SELECT * FROM withdrawals WHERE discord_id = ? ORDER BY id DESC LIMIT "+withdrawalsHistoryDisplayCount,[userID],function (error, results, fields){ 269 | mysqlPool.releaseConnection(connection); 270 | if(error) 271 | { 272 | var errorMessage = "transaction_get_withdrawals_by_user_id: MySQL query problem. (SELECT * FROM withdrawals WHERE discord_id = ? ORDER BY id DESC LIMIT "+withdrawalsHistoryDisplayCount+")"; 273 | if(config.bot.errorLogging){ 274 | log.log_write_file(errorMessage); 275 | log.log_write_file(error); 276 | } 277 | log.log_write_console(errorMessage); 278 | log.log_write_console(error); 279 | resolve(false); 280 | }else{ 281 | resolve(results); 282 | } 283 | }); 284 | } 285 | }); 286 | }); 287 | }, 288 | 289 | /* ------------------------------------------------------------------------------ */ 290 | // Save payment to db 291 | /* ------------------------------------------------------------------------------ */ 292 | transaction_save_payment_to_db: function(paymentAmount,fromID,toID,type){ 293 | return new Promise((resolve, reject)=>{ 294 | mysqlPool.getConnection(function(error, connection){ 295 | if(error){ 296 | try 297 | { 298 | mysqlPool.releaseConnection(connection); 299 | } 300 | catch (e){} 301 | var errorMessage = "transaction_save_payment_to_db: MySQL connection problem."; 302 | if(config.bot.errorLogging){ 303 | log.log_write_file(errorMessage); 304 | log.log_write_file(error); 305 | } 306 | log.log_write_console(errorMessage); 307 | log.log_write_console(error); 308 | resolve(false); 309 | }else{ 310 | connection.execute("INSERT INTO payments (amount,from_discord_id,to_discord_id,type,coin_price) VALUES (?,?,?,?,?)",[Big(paymentAmount).toString(),fromID,toID,type,coinPrice],function (error, results, fields){ 311 | mysqlPool.releaseConnection(connection); 312 | if(error) 313 | { 314 | var errorMessage = "transaction_save_payment_to_db: MySQL query problem. (INSERT INTO payments (amount,from_discord_id,to_discord_id,type,coin_price) VALUES (?,?,?,?,?))"; 315 | if(config.bot.errorLogging){ 316 | log.log_write_file(errorMessage); 317 | log.log_write_file(error); 318 | } 319 | log.log_write_console(errorMessage); 320 | log.log_write_console(error); 321 | resolve(false); 322 | }else{ 323 | resolve(true); 324 | } 325 | }); 326 | } 327 | }); 328 | }) 329 | }, 330 | 331 | /* ------------------------------------------------------------------------------ */ 332 | // Get payments by id 333 | /* ------------------------------------------------------------------------------ */ 334 | transaction_get_payments_by_user_id: function(paymentHistoryCoun,userID){ 335 | return new Promise((resolve, reject)=>{ 336 | mysqlPool.getConnection(function(error, connection){ 337 | if(error){ 338 | try 339 | { 340 | mysqlPool.releaseConnection(connection); 341 | } 342 | catch (e){} 343 | var errorMessage = "transaction_get_payments_by_user_id: MySQL connection problem."; 344 | if(config.bot.errorLogging){ 345 | log.log_write_file(errorMessage); 346 | log.log_write_file(error); 347 | } 348 | log.log_write_console(errorMessage); 349 | log.log_write_console(error); 350 | resolve(false); 351 | }else{ 352 | connection.execute("SELECT * FROM payments WHERE from_discord_id = ? OR from_discord_id = 'rainall' OR from_discord_id = ? AND to_discord_id = ? ORDER BY id DESC LIMIT "+paymentHistoryCoun,[userID,config.bot.botID,userID],function (error, results, fields){ 353 | mysqlPool.releaseConnection(connection); 354 | if(error) 355 | { 356 | var errorMessage = "transaction_get_payments_by_user_id: MySQL query problem. (SELECT * FROM payments WHERE from_discord_id = ? ORDER BY id DESC LIMIT)"; 357 | if(config.bot.errorLogging){ 358 | log.log_write_file(errorMessage); 359 | log.log_write_file(error); 360 | } 361 | log.log_write_console(errorMessage); 362 | log.log_write_console(error); 363 | resolve(false); 364 | }else{ 365 | resolve(results); 366 | } 367 | }); 368 | } 369 | }); 370 | }); 371 | }, 372 | 373 | /* ------------------------------------------------------------------------------ */ 374 | // Get transactions from walletnotify stake table that are not checked 375 | /* ------------------------------------------------------------------------------ */ 376 | transaction_get_stake_transactions: function(){ 377 | return new Promise((resolve, reject)=>{ 378 | mysqlPool.getConnection(function(error, connection){ 379 | if(error){ 380 | try 381 | { 382 | mysqlPool.releaseConnection(connection); 383 | } 384 | catch (e){} 385 | var errorMessage = "transaction_get_stake_transactions: MySQL connection problem."; 386 | if(config.bot.errorLogging){ 387 | log.log_write_file(errorMessage); 388 | log.log_write_file(error); 389 | } 390 | log.log_write_console(errorMessage); 391 | log.log_write_console(error); 392 | resolve(false); 393 | }else{ 394 | connection.execute("SELECT txid FROM transactions WHERE checked = ? LIMIT ?",[0,config.staking.checkCount],function (error, results, fields){ 395 | mysqlPool.releaseConnection(connection); 396 | if(error) 397 | { 398 | var errorMessage = "transaction_get_stake_transactions: MySQL query problem. (SELECT * FROM transactions WHERE checked = ?)"; 399 | if(config.bot.errorLogging){ 400 | log.log_write_file(errorMessage); 401 | log.log_write_file(error); 402 | } 403 | log.log_write_console(errorMessage); 404 | log.log_write_console(error); 405 | resolve(false); 406 | }else{ 407 | resolve(results); 408 | } 409 | }); 410 | } 411 | }); 412 | }); 413 | }, 414 | 415 | /* ------------------------------------------------------------------------------ */ 416 | // Get transactions from walletnotify stake table that are checked and stake transactions but not credited 417 | /* ------------------------------------------------------------------------------ */ 418 | transaction_get_stake_transactions_to_credit: function(){ 419 | return new Promise((resolve, reject)=>{ 420 | mysqlPool.getConnection(function(error, connection){ 421 | if(error){ 422 | try 423 | { 424 | mysqlPool.releaseConnection(connection); 425 | } 426 | catch (e){} 427 | var errorMessage = "transaction_get_stake_transactions_to_credit: MySQL connection problem."; 428 | if(config.bot.errorLogging){ 429 | log.log_write_file(errorMessage); 430 | log.log_write_file(error); 431 | } 432 | log.log_write_console(errorMessage); 433 | log.log_write_console(error); 434 | resolve(false); 435 | }else{ 436 | connection.execute("SELECT id, txid, amount FROM transactions WHERE checked = ? AND credited = ? AND stake = ? ORDER BY id ASC LIMIT ?",[1,0,1,config.staking.creditCount],function (error, results, fields){ 437 | mysqlPool.releaseConnection(connection); 438 | if(error) 439 | { 440 | var errorMessage = "transaction_get_stake_transactions_to_credit: MySQL query problem. (SELECT txid FROM transactions WHERE checked = ? AND credited = ? LIMIT ?)"; 441 | if(config.bot.errorLogging){ 442 | log.log_write_file(errorMessage); 443 | log.log_write_file(error); 444 | } 445 | log.log_write_console(errorMessage); 446 | log.log_write_console(error); 447 | resolve(false); 448 | }else{ 449 | resolve(results); 450 | } 451 | }); 452 | } 453 | }); 454 | }); 455 | }, 456 | 457 | /* ------------------------------------------------------------------------------ */ 458 | // Update transaction on stake transaction table as checked 459 | /* ------------------------------------------------------------------------------ */ 460 | transaction_update_stake_transaction: function(txid,stake_amount,transaction_stake){ 461 | return new Promise((resolve, reject)=>{ 462 | mysqlPool.getConnection(function(error, connection){ 463 | if(error){ 464 | try 465 | { 466 | mysqlPool.releaseConnection(connection); 467 | } 468 | catch (e){} 469 | var errorMessage = "transaction_update_stake_transaction: MySQL connection problem."; 470 | if(config.bot.errorLogging){ 471 | log.log_write_file(errorMessage); 472 | log.log_write_file(error); 473 | } 474 | log.log_write_console(errorMessage); 475 | log.log_write_console(error); 476 | resolve(false); 477 | }else{ 478 | connection.execute("UPDATE transactions SET amount = ?, stake = ?, checked = ? WHERE txid = ?",[stake_amount,transaction_stake,1,txid],function (error, results, fields){ 479 | mysqlPool.releaseConnection(connection); 480 | if(error) 481 | { 482 | var errorMessage = "transaction_update_stake_transaction: MySQL query problem. (SELECT * FROM transactions WHERE checked = ?)"; 483 | if(config.bot.errorLogging){ 484 | log.log_write_file(errorMessage); 485 | log.log_write_file(error); 486 | } 487 | log.log_write_console(errorMessage); 488 | log.log_write_console(error); 489 | resolve(false); 490 | }else{ 491 | resolve(results); 492 | } 493 | }); 494 | } 495 | }); 496 | }); 497 | }, 498 | 499 | /* ------------------------------------------------------------------------------ */ 500 | // Update transaction on stake transaction table as credited 501 | /* ------------------------------------------------------------------------------ */ 502 | transaction_update_stake_transaction_credited: function(highestTransactionID){ 503 | return new Promise((resolve, reject)=>{ 504 | mysqlPool.getConnection(function(error, connection){ 505 | if(error){ 506 | try 507 | { 508 | mysqlPool.releaseConnection(connection); 509 | } 510 | catch (e){} 511 | var errorMessage = "transaction_update_stake_transaction_credited: MySQL connection problem."; 512 | if(config.bot.errorLogging){ 513 | log.log_write_file(errorMessage); 514 | log.log_write_file(error); 515 | } 516 | log.log_write_console(errorMessage); 517 | log.log_write_console(error); 518 | resolve(false); 519 | }else{ 520 | connection.execute("UPDATE transactions SET credited = ? WHERE id <= ? AND stake = ?",[1,highestTransactionID,1],function (error, results, fields){ 521 | mysqlPool.releaseConnection(connection); 522 | if(error) 523 | { 524 | var errorMessage = "transaction_update_stake_transaction_credited: MySQL query problem. (SELECT * FROM transactions WHERE checked = ?)"; 525 | if(config.bot.errorLogging){ 526 | log.log_write_file(errorMessage); 527 | log.log_write_file(error); 528 | } 529 | log.log_write_console(errorMessage); 530 | log.log_write_console(error); 531 | resolve(false); 532 | }else{ 533 | resolve(results); 534 | } 535 | }); 536 | } 537 | }); 538 | }); 539 | }, 540 | 541 | 542 | /* ------------------------------------------------------------------------------ */ 543 | // Save current coin price to price history table 544 | /* ------------------------------------------------------------------------------ */ 545 | transaction_coin_price_history: function(historyPrice){ 546 | return new Promise((resolve, reject)=>{ 547 | mysqlPool.getConnection(function(error, connection){ 548 | if(error){ 549 | try 550 | { 551 | mysqlPool.releaseConnection(connection); 552 | } 553 | catch (e){} 554 | var errorMessage = "transaction_coin_price_history: MySQL connection problem."; 555 | if(config.bot.errorLogging){ 556 | log.log_write_file(errorMessage); 557 | log.log_write_file(error); 558 | } 559 | log.log_write_console(errorMessage); 560 | log.log_write_console(error); 561 | resolve(false); 562 | }else{ 563 | connection.execute("INSERT INTO coin_price_history (price,currency,api_service) VALUES (?,?,?)",[historyPrice,config.coinPrice.currency,config.coinPrice.apiService],function (error, results, fields){ 564 | mysqlPool.releaseConnection(connection); 565 | if(error) 566 | { 567 | var errorMessage = "INSERT INTO coin_price_history (price,currency) VALUES (?,?)"; 568 | if(config.bot.errorLogging){ 569 | log.log_write_file(errorMessage); 570 | log.log_write_file(error); 571 | } 572 | log.log_write_console(errorMessage); 573 | log.log_write_console(error); 574 | resolve(false); 575 | }else{ 576 | resolve(results); 577 | } 578 | }); 579 | } 580 | }); 581 | }); 582 | } 583 | 584 | }; -------------------------------------------------------------------------------- /functions/user.js: -------------------------------------------------------------------------------- 1 | //var config = require('../config.js'); 2 | try{ 3 | var config = process.cwd()+'/config.js'; 4 | config = require(config); 5 | }catch (error){ 6 | console.error('ERROR -> Unable to load config file.'); 7 | process.exit(1); 8 | } 9 | 10 | var check = require("./check.js"); 11 | var log = require("./log.js"); 12 | 13 | /* ------------------------------------------------------------------------------ */ 14 | // // // // // // // // // // // // // // // // // // // // // // // // // // // // 15 | /* ------------------------------------------------------------------------------ */ 16 | 17 | // Mysql2 18 | const mysql = require('mysql2'); 19 | // connect mysql database 20 | mysqlPool = mysql.createPool({ 21 | connectionLimit : config.mysql.connectionLimit, 22 | waitForConnections: config.mysql.waitForConnections, 23 | host : config.mysql.dbHost, 24 | user : config.mysql.dbUser, 25 | port : config.mysql.dbPort, 26 | password : config.mysql.dbPassword, 27 | database : config.mysql.dbName 28 | }); 29 | 30 | const Big = require('big.js'); // https://github.com/MikeMcl/big.js -> http://mikemcl.github.io/big.js/ 31 | 32 | /* ------------------------------------------------------------------------------ */ 33 | // // // // // // // // // // // // // // // // // // // // // // // // // // // // 34 | /* ------------------------------------------------------------------------------ */ 35 | 36 | module.exports = { 37 | 38 | /* ------------------------------------------------------------------------------ */ 39 | // Check if user is registered by id 40 | /* ------------------------------------------------------------------------------ */ 41 | 42 | user_registered_check: function(userID){ 43 | return new Promise((resolve, reject)=>{ 44 | mysqlPool.getConnection(function(error, connection){ 45 | if(error){ 46 | try 47 | { 48 | mysqlPool.releaseConnection(connection); 49 | } 50 | catch (e){} 51 | var errorMessage = "user_registered_check: MySQL connection problem."; 52 | if(config.bot.errorLogging){ 53 | log.log_write_file(errorMessage); 54 | log.log_write_file(error); 55 | } 56 | log.log_write_console(errorMessage); 57 | log.log_write_console(error); 58 | resolve('error'); 59 | }else{ 60 | connection.execute("SELECT * FROM user WHERE discord_id = ?",[userID],function (error, results, fields){ 61 | mysqlPool.releaseConnection(connection); 62 | if(error) 63 | { 64 | var errorMessage = "user_registered_check: MySQL query problem. (SELECT * FROM user WHERE discord_id = ?)"; 65 | if(config.bot.errorLogging){ 66 | log.log_write_file(errorMessage); 67 | log.log_write_file(error); 68 | } 69 | log.log_write_console(errorMessage); 70 | log.log_write_console(error); 71 | resolve('error'); 72 | }else{ 73 | if(results.length > 0){ 74 | resolve(true); 75 | }else{ 76 | resolve(false); 77 | } 78 | } 79 | }); 80 | } 81 | }); 82 | }); 83 | }, 84 | 85 | /* ------------------------------------------------------------------------------ */ 86 | // Get user id by address 87 | /* ------------------------------------------------------------------------------ */ 88 | 89 | user_get_id_by_address: function(address){ 90 | return new Promise((resolve, reject)=>{ 91 | mysqlPool.getConnection(function(error, connection){ 92 | if(error){ 93 | try 94 | { 95 | mysqlPool.releaseConnection(connection); 96 | } 97 | catch (e){} 98 | var errorMessage = "user_get_id_by_address: MySQL connection problem."; 99 | if(config.bot.errorLogging){ 100 | log.log_write_file(errorMessage); 101 | log.log_write_file(error); 102 | } 103 | log.log_write_console(errorMessage); 104 | log.log_write_console(error); 105 | resolve(false); 106 | }else{ 107 | connection.execute("SELECT discord_id FROM user WHERE deposit_address = ? LIMIT 1",[address],function (error, results, fields){ 108 | mysqlPool.releaseConnection(connection); 109 | if(error) 110 | { 111 | var errorMessage = "user_get_id_by_address: MySQL query problem. (SELECT discord_id FROM user WHERE deposit_address = ? LIMIT 1)"; 112 | if(config.bot.errorLogging){ 113 | log.log_write_file(errorMessage); 114 | log.log_write_file(error); 115 | } 116 | log.log_write_console(errorMessage); 117 | log.log_write_console(error); 118 | resolve(false); 119 | }else{ 120 | if(results.length > 0){ 121 | resolve(results[0].discord_id); 122 | }else{ 123 | resolve('notregisteredaddress'); 124 | } 125 | } 126 | }); 127 | } 128 | }); 129 | }); 130 | }, 131 | 132 | /* ------------------------------------------------------------------------------ */ 133 | // Get user balance by id 134 | /* ------------------------------------------------------------------------------ */ 135 | 136 | user_get_balance: function(userID){ 137 | return new Promise((resolve, reject)=>{ 138 | mysqlPool.getConnection(function(error, connection){ 139 | if(error){ 140 | try 141 | { 142 | mysqlPool.releaseConnection(connection); 143 | } 144 | catch (e){} 145 | var errorMessage = "user_get_balance: MySQL connection problem."; 146 | if(config.bot.errorLogging){ 147 | log.log_write_file(errorMessage); 148 | log.log_write_file(error); 149 | } 150 | log.log_write_console(errorMessage); 151 | log.log_write_console(error); 152 | resolve(false); 153 | }else{ 154 | connection.execute("SELECT balance FROM user WHERE discord_id = ? LIMIT 1",[userID],function (error, results, fields){ 155 | mysqlPool.releaseConnection(connection); 156 | if(error) 157 | { 158 | var errorMessage = "user_get_balance: MySQL query problem. (SELECT balance FROM user WHERE discord_id = ? LIMIT 1)"; 159 | if(config.bot.errorLogging){ 160 | log.log_write_file(errorMessage); 161 | log.log_write_file(error); 162 | } 163 | log.log_write_console(errorMessage); 164 | log.log_write_console(error); 165 | resolve(false); 166 | }else{ 167 | resolve(Big(results[0].balance).toString()); 168 | } 169 | }); 170 | } 171 | }); 172 | }); 173 | }, 174 | 175 | /* ------------------------------------------------------------------------------ */ 176 | // Get user stake balance by id 177 | /* ------------------------------------------------------------------------------ */ 178 | 179 | user_get_stake_balance: function(userID){ 180 | return new Promise((resolve, reject)=>{ 181 | mysqlPool.getConnection(function(error, connection){ 182 | if(error){ 183 | try 184 | { 185 | mysqlPool.releaseConnection(connection); 186 | } 187 | catch (e){} 188 | var errorMessage = "user_get_stake_balance: MySQL connection problem."; 189 | if(config.bot.errorLogging){ 190 | log.log_write_file(errorMessage); 191 | log.log_write_file(error); 192 | } 193 | log.log_write_console(errorMessage); 194 | log.log_write_console(error); 195 | resolve(false); 196 | }else{ 197 | connection.execute("SELECT stake_balance FROM user WHERE discord_id = ? LIMIT 1",[userID],function (error, results, fields){ 198 | mysqlPool.releaseConnection(connection); 199 | if(error) 200 | { 201 | var errorMessage = "user_get_stake_balance: MySQL query problem. (SELECT stake_balance FROM user WHERE discord_id = ? LIMIT 1)"; 202 | if(config.bot.errorLogging){ 203 | log.log_write_file(errorMessage); 204 | log.log_write_file(error); 205 | } 206 | log.log_write_console(errorMessage); 207 | log.log_write_console(error); 208 | resolve(false); 209 | }else{ 210 | resolve(Big(results[0].stake_balance).toString()); 211 | } 212 | }); 213 | } 214 | }); 215 | }); 216 | }, 217 | 218 | /* ------------------------------------------------------------------------------ */ 219 | // Add stake balance to user 220 | /* ------------------------------------------------------------------------------ */ 221 | 222 | user_add_stake_balance: function(stakeAmount,userID,currentDatetime){ 223 | return new Promise((resolve, reject)=>{ 224 | mysqlPool.getConnection(function(error, connection){ 225 | if(error){ 226 | try 227 | { 228 | mysqlPool.releaseConnection(connection); 229 | } 230 | catch (e){} 231 | var errorMessage = "user_add_stake_balance: MySQL connection problem."; 232 | if(config.bot.errorLogging){ 233 | log.log_write_file(errorMessage); 234 | log.log_write_file(error); 235 | } 236 | log.log_write_console(errorMessage); 237 | log.log_write_console(error); 238 | resolve(false); 239 | }else{ 240 | connection.execute("INSERT INTO user (username,discord_id,stake_balance,unstake_datetime) VALUES (?,?,?,?) ON DUPLICATE KEY UPDATE stake_balance = stake_balance + ?, unstake_datetime = ?",['tipUser',userID,Big(stakeAmount).toString(),currentDatetime,Big(stakeAmount).toString(),currentDatetime],function (error, results, fields){ 241 | mysqlPool.releaseConnection(connection); 242 | if(error) 243 | { 244 | var errorMessage = "user_add_stake_balance: MySQL query problem. (INSERT INTO user (username,discord_id,stake_balance) VALUES (?,?,?) ON DUPLICATE KEY UPDATE stake_balance = stake_balance + ?)"; 245 | if(config.bot.errorLogging){ 246 | log.log_write_file(errorMessage); 247 | log.log_write_file(error); 248 | } 249 | log.log_write_console(errorMessage); 250 | log.log_write_console(error); 251 | resolve(false); 252 | }else{ 253 | resolve(true); 254 | } 255 | }); 256 | } 257 | }); 258 | }); 259 | }, 260 | 261 | /* ------------------------------------------------------------------------------ */ 262 | // Get user address by id 263 | /* ------------------------------------------------------------------------------ */ 264 | 265 | user_get_address: function(userID){ 266 | return new Promise((resolve, reject)=>{ 267 | mysqlPool.getConnection(function(error, connection){ 268 | if(error){ 269 | try 270 | { 271 | mysqlPool.releaseConnection(connection); 272 | } 273 | catch (e){} 274 | var errorMessage = "user_get_address: MySQL connection problem."; 275 | if(config.bot.errorLogging){ 276 | log.log_write_file(errorMessage); 277 | log.log_write_file(error); 278 | } 279 | log.log_write_console(errorMessage); 280 | log.log_write_console(error); 281 | resolve(false); 282 | }else{ 283 | connection.execute("SELECT deposit_address FROM user WHERE discord_id = ? LIMIT 1",[userID],function (error, results, fields){ 284 | mysqlPool.releaseConnection(connection); 285 | if(error) 286 | { 287 | var errorMessage = "user_get_address: MySQL query problem. (SELECT deposit_address FROM user WHERE discord_id = ? LIMIT 1)"; 288 | if(config.bot.errorLogging){ 289 | log.log_write_file(errorMessage); 290 | log.log_write_file(error); 291 | } 292 | log.log_write_console(errorMessage); 293 | log.log_write_console(error); 294 | resolve(false); 295 | }else{ 296 | resolve(results[0].deposit_address); 297 | } 298 | }); 299 | } 300 | }); 301 | }); 302 | }, 303 | 304 | /* ------------------------------------------------------------------------------ */ 305 | // Credit balance to user by address 306 | /* ------------------------------------------------------------------------------ */ 307 | 308 | user_credit_balance: function(creditAddress,creditAmount){ 309 | return new Promise((resolve, reject)=>{ 310 | mysqlPool.getConnection(function(error, connection){ 311 | if(error){ 312 | try 313 | { 314 | mysqlPool.releaseConnection(connection); 315 | } 316 | catch (e){} 317 | var errorMessage = "user_credit_balance: MySQL connection problem."; 318 | if(config.bot.errorLogging){ 319 | log.log_write_file(errorMessage); 320 | log.log_write_file(error); 321 | } 322 | log.log_write_console(errorMessage); 323 | log.log_write_console(error); 324 | resolve(false); 325 | }else{ 326 | connection.execute("UPDATE user SET balance = balance + ? WHERE deposit_address = ?",[creditAmount,creditAddress],function (error, results, fields){ 327 | mysqlPool.releaseConnection(connection); 328 | if(error) 329 | { 330 | var errorMessage = "user_credit_balance: MySQL query problem. (UPDATE user SET balance = balance + ? WHERE deposit_address = ?)"; 331 | if(config.bot.errorLogging){ 332 | log.log_write_file(errorMessage); 333 | log.log_write_file(error); 334 | } 335 | log.log_write_console(errorMessage); 336 | log.log_write_console(error); 337 | resolve(false); 338 | }else{ 339 | resolve(results); 340 | } 341 | }); 342 | } 343 | }); 344 | }); 345 | }, 346 | 347 | /* ------------------------------------------------------------------------------ */ 348 | // Substract balance from user by id 349 | /* ------------------------------------------------------------------------------ */ 350 | 351 | user_substract_balance: function(substractAmount,userID){ 352 | return new Promise((resolve, reject)=>{ 353 | mysqlPool.getConnection(function(error, connection){ 354 | if(error){ 355 | try 356 | { 357 | mysqlPool.releaseConnection(connection); 358 | } 359 | catch (e){} 360 | var errorMessage = "user_substract_balance: MySQL connection problem."; 361 | if(config.bot.errorLogging){ 362 | log.log_write_file(errorMessage); 363 | log.log_write_file(error); 364 | } 365 | log.log_write_console(errorMessage); 366 | log.log_write_console(error); 367 | resolve(false); 368 | }else{ 369 | connection.execute("UPDATE user SET balance = balance - ? WHERE discord_id = ?",[Big(substractAmount).toString(),userID],function (error, results, fields){ 370 | mysqlPool.releaseConnection(connection); 371 | if(error) 372 | { 373 | var errorMessage = "user_substract_balance: MySQL query problem. (UPDATE user SET balance = balance - ? WHERE discord_id = ?)"; 374 | if(config.bot.errorLogging){ 375 | log.log_write_file(errorMessage); 376 | log.log_write_file(error); 377 | } 378 | log.log_write_console(errorMessage); 379 | log.log_write_console(error); 380 | resolve(false); 381 | }else{ 382 | resolve(true); 383 | } 384 | }); 385 | } 386 | }); 387 | }); 388 | }, 389 | 390 | /* ------------------------------------------------------------------------------ */ 391 | // Substract stake balance from user by id 392 | /* ------------------------------------------------------------------------------ */ 393 | 394 | user_substract_stake_balance: function(substractAmount,userID,currentDatetime){ 395 | return new Promise((resolve, reject)=>{ 396 | mysqlPool.getConnection(function(error, connection){ 397 | if(error){ 398 | try 399 | { 400 | mysqlPool.releaseConnection(connection); 401 | } 402 | catch (e){} 403 | var errorMessage = "user_substract_stake_balance: MySQL connection problem."; 404 | if(config.bot.errorLogging){ 405 | log.log_write_file(errorMessage); 406 | log.log_write_file(error); 407 | } 408 | log.log_write_console(errorMessage); 409 | log.log_write_console(error); 410 | resolve(false); 411 | }else{ 412 | connection.execute("UPDATE user SET stake_balance = stake_balance - ?, unstake_datetime = ? WHERE discord_id = ?",[Big(substractAmount).toString(),currentDatetime,userID],function (error, results, fields){ 413 | mysqlPool.releaseConnection(connection); 414 | if(error) 415 | { 416 | var errorMessage = "user_substract_stake_balance: MySQL query problem. (UPDATE user SET stake_balance = stake_balance - ? WHERE discord_id = ?)"; 417 | if(config.bot.errorLogging){ 418 | log.log_write_file(errorMessage); 419 | log.log_write_file(error); 420 | } 421 | log.log_write_console(errorMessage); 422 | log.log_write_console(error); 423 | resolve(false); 424 | }else{ 425 | resolve(true); 426 | } 427 | }); 428 | } 429 | }); 430 | }); 431 | }, 432 | 433 | /* ------------------------------------------------------------------------------ */ 434 | // Add balance to user profile 435 | /* ------------------------------------------------------------------------------ */ 436 | 437 | user_add_balance: function(addAmount,userID){ 438 | return new Promise((resolve, reject)=>{ 439 | mysqlPool.getConnection(function(error, connection){ 440 | if(error){ 441 | try 442 | { 443 | mysqlPool.releaseConnection(connection); 444 | } 445 | catch (e){} 446 | var errorMessage = "user_add_balance: MySQL connection problem."; 447 | if(config.bot.errorLogging){ 448 | log.log_write_file(errorMessage); 449 | log.log_write_file(error); 450 | } 451 | log.log_write_console(errorMessage); 452 | log.log_write_console(error); 453 | resolve(false); 454 | }else{ 455 | connection.execute("INSERT INTO user (username,discord_id,balance) VALUES (?,?,?) ON DUPLICATE KEY UPDATE balance = balance + ?",['tipUser',userID,Big(addAmount).toString(),Big(addAmount).toString()],function (error, results, fields){ 456 | mysqlPool.releaseConnection(connection); 457 | if(error) 458 | { 459 | var errorMessage = "user_add_balance: MySQL query problem. (INSERT INTO user (username,discord_id,balance) VALUES (?,?,?) ON DUPLICATE KEY UPDATE balance = balance + ?)"; 460 | if(config.bot.errorLogging){ 461 | log.log_write_file(errorMessage); 462 | log.log_write_file(error); 463 | } 464 | log.log_write_console(errorMessage); 465 | log.log_write_console(error); 466 | resolve(false); 467 | }else{ 468 | resolve(true); 469 | } 470 | }); 471 | } 472 | }); 473 | }); 474 | }, 475 | 476 | /* ------------------------------------------------------------------------------ */ 477 | // Add balance to all users from rain all 478 | /* ------------------------------------------------------------------------------ */ 479 | 480 | user_add_balance_all: function(addAmount){ 481 | return new Promise((resolve, reject)=>{ 482 | mysqlPool.getConnection(function(error, connection){ 483 | if(error){ 484 | try 485 | { 486 | mysqlPool.releaseConnection(connection); 487 | } 488 | catch (e){} 489 | var errorMessage = "user_add_balance_all: MySQL connection problem."; 490 | if(config.bot.errorLogging){ 491 | log.log_write_file(errorMessage); 492 | log.log_write_file(error); 493 | } 494 | log.log_write_console(errorMessage); 495 | log.log_write_console(error); 496 | resolve(false); 497 | }else{ 498 | connection.execute("UPDATE user SET balance = balance + ? WHERE discord_id != 'undefined'",[Big(addAmount).toString()],function (error, results, fields){ 499 | mysqlPool.releaseConnection(connection); 500 | if(error) 501 | { 502 | var errorMessage = "user_add_balance_all: MySQL query problem. (UPDATE user SET balance = balance + ? WHERE discord_id != 'undefined')"; 503 | if(config.bot.errorLogging){ 504 | log.log_write_file(errorMessage); 505 | log.log_write_file(error); 506 | } 507 | log.log_write_console(errorMessage); 508 | log.log_write_console(error); 509 | resolve(false); 510 | }else{ 511 | resolve(true); 512 | } 513 | }); 514 | } 515 | }); 516 | }); 517 | }, 518 | 519 | /* ------------------------------------------------------------------------------ */ 520 | // Add deposit address 521 | /* ------------------------------------------------------------------------------ */ 522 | 523 | user_add_deposit_address: function(depositAddress,userID){ 524 | return new Promise((resolve, reject)=>{ 525 | mysqlPool.getConnection(function(error, connection){ 526 | if(error){ 527 | try 528 | { 529 | mysqlPool.releaseConnection(connection); 530 | } 531 | catch (e){} 532 | var errorMessage = "user_add_deposit_address: MySQL connection problem."; 533 | if(config.bot.errorLogging){ 534 | log.log_write_file(errorMessage); 535 | log.log_write_file(error); 536 | } 537 | log.log_write_console(errorMessage); 538 | log.log_write_console(error); 539 | resolve(false); 540 | }else{ 541 | connection.execute("UPDATE user SET deposit_address = ? WHERE discord_id = ?",[depositAddress,userID],function (error, results, fields){ 542 | mysqlPool.releaseConnection(connection); 543 | if(error) 544 | { 545 | var errorMessage = "user_add_deposit_address: MySQL query problem. (UPDATE user SET balance = balance + ? WHERE deposit_address = ?)"; 546 | if(config.bot.errorLogging){ 547 | log.log_write_file(errorMessage); 548 | log.log_write_file(error); 549 | } 550 | log.log_write_console(errorMessage); 551 | log.log_write_console(error); 552 | resolve(false); 553 | }else{ 554 | resolve(true); 555 | } 556 | }); 557 | } 558 | }); 559 | }); 560 | }, 561 | 562 | /* ------------------------------------------------------------------------------ */ 563 | // Get user info by id 564 | /* ------------------------------------------------------------------------------ */ 565 | 566 | user_get_info: function(userID){ 567 | return new Promise((resolve, reject)=>{ 568 | mysqlPool.getConnection(function(error, connection){ 569 | if(error){ 570 | try 571 | { 572 | mysqlPool.releaseConnection(connection); 573 | } 574 | catch (e){} 575 | var errorMessage = "user_get_info: MySQL connection problem."; 576 | if(config.bot.errorLogging){ 577 | log.log_write_file(errorMessage); 578 | log.log_write_file(error); 579 | } 580 | log.log_write_console(errorMessage); 581 | log.log_write_console(error); 582 | resolve(false); 583 | }else{ 584 | connection.execute("SELECT * FROM user WHERE discord_id = ?",[userID],function (error, results, fields){ 585 | mysqlPool.releaseConnection(connection); 586 | if(error) 587 | { 588 | var errorMessage = "user_get_info: MySQL query problem. (SELECT * FROM user WHERE discord_id = ?)"; 589 | if(config.bot.errorLogging){ 590 | log.log_write_file(errorMessage); 591 | log.log_write_file(error); 592 | } 593 | log.log_write_console(errorMessage); 594 | log.log_write_console(error); 595 | resolve(false); 596 | }else{ 597 | resolve(results); 598 | } 599 | }); 600 | } 601 | }); 602 | }); 603 | }, 604 | 605 | /* ------------------------------------------------------------------------------ */ 606 | // Register new user 607 | /* ------------------------------------------------------------------------------ */ 608 | 609 | user_register: function(userName,userID){ 610 | return new Promise((resolve, reject)=>{ 611 | mysqlPool.getConnection(function(error, connection){ 612 | if(error){ 613 | try 614 | { 615 | mysqlPool.releaseConnection(connection); 616 | } 617 | catch (e){} 618 | var errorMessage = "user_get_info: MySQL connection problem."; 619 | if(config.bot.errorLogging){ 620 | log.log_write_file(errorMessage); 621 | log.log_write_file(error); 622 | } 623 | log.log_write_console(errorMessage); 624 | log.log_write_console(error); 625 | resolve(false); 626 | }else{ 627 | connection.execute("INSERT INTO user (username,discord_id) VALUES (?,?) ON DUPLICATE KEY UPDATE username = ?",[userName,userID,userName],function (error, results, fields){ 628 | mysqlPool.releaseConnection(connection); 629 | if(error){ 630 | var errorMessage = "user_register: MySQL query problem. (INSERT INTO user (username,discord_id) VALUES (?,?) ON DUPLICATE KEY UPDATE username = ?)"; 631 | if(config.bot.errorLogging){ 632 | log.log_write_file(errorMessage); 633 | log.log_write_file(error); 634 | } 635 | log.log_write_console(errorMessage); 636 | log.log_write_console(error); 637 | resolve(false); 638 | }else{ 639 | resolve(true) 640 | } 641 | }); 642 | } 643 | }); 644 | }); 645 | }, 646 | 647 | /* ------------------------------------------------------------------------------ */ 648 | // Update username 649 | /* ------------------------------------------------------------------------------ */ 650 | 651 | user_update_username: function(userName,userID){ 652 | return new Promise((resolve, reject)=>{ 653 | mysqlPool.getConnection(function(error, connection){ 654 | if(error){ 655 | try 656 | { 657 | mysqlPool.releaseConnection(connection); 658 | } 659 | catch (e){} 660 | var errorMessage = "user_update_username: MySQL connection problem."; 661 | if(config.bot.errorLogging){ 662 | log.log_write_file(errorMessage); 663 | log.log_write_file(error); 664 | } 665 | log.log_write_console(errorMessage); 666 | log.log_write_console(error); 667 | resolve(false); 668 | }else{ 669 | connection.execute("UPDATE user SET username = ? WHERE discord_id = ?",[userName,userID],function (error, results, fields){ 670 | mysqlPool.releaseConnection(connection); 671 | if(error){ 672 | var errorMessage = "user_update_username: MySQL query problem. (UPDATE user SET username = ? WHERE discord_id = ?)"; 673 | if(config.bot.errorLogging){ 674 | log.log_write_file(errorMessage); 675 | log.log_write_file(error); 676 | } 677 | log.log_write_console(errorMessage); 678 | log.log_write_console(error); 679 | resolve(false); 680 | }else{ 681 | resolve(true) 682 | } 683 | }); 684 | } 685 | }); 686 | }); 687 | }, 688 | 689 | /* ------------------------------------------------------------------------------ */ 690 | // Get all users that have stake value 691 | /* ------------------------------------------------------------------------------ */ 692 | 693 | user_get_stake_users: function(){ 694 | return new Promise((resolve, reject)=>{ 695 | mysqlPool.getConnection(function(error, connection){ 696 | if(error){ 697 | try 698 | { 699 | mysqlPool.releaseConnection(connection); 700 | } 701 | catch (e){} 702 | var errorMessage = "user_get_stake_users: MySQL connection problem."; 703 | if(config.bot.errorLogging){ 704 | log.log_write_file(errorMessage); 705 | log.log_write_file(error); 706 | } 707 | log.log_write_console(errorMessage); 708 | log.log_write_console(error); 709 | resolve(false); 710 | }else{ 711 | connection.execute("SELECT id,discord_id,stake_balance FROM user WHERE stake_balance > ?",[0],function (error, results, fields){ 712 | mysqlPool.releaseConnection(connection); 713 | if(error){ 714 | var errorMessage = "user_get_stake_users: MySQL query problem. (UPDATE user SET username = ? WHERE discord_id = ?)"; 715 | if(config.bot.errorLogging){ 716 | log.log_write_file(errorMessage); 717 | log.log_write_file(error); 718 | } 719 | log.log_write_console(errorMessage); 720 | log.log_write_console(error); 721 | resolve(false); 722 | }else{ 723 | resolve(results) 724 | } 725 | }); 726 | } 727 | }); 728 | }); 729 | }, 730 | 731 | /* ------------------------------------------------------------------------------ */ 732 | // Get random users discord ids from database 733 | /* ------------------------------------------------------------------------------ */ 734 | 735 | user_get_discord_ids: function(randomCount){ 736 | return new Promise((resolve, reject)=>{ 737 | mysqlPool.getConnection(function(error, connection){ 738 | if(error){ 739 | try 740 | { 741 | mysqlPool.releaseConnection(connection); 742 | } 743 | catch (e){} 744 | var errorMessage = "user_get_discord_ids: MySQL connection problem."; 745 | if(config.bot.errorLogging){ 746 | log.log_write_file(errorMessage); 747 | log.log_write_file(error); 748 | } 749 | log.log_write_console(errorMessage); 750 | log.log_write_console(error); 751 | resolve(false); 752 | }else{ 753 | connection.execute("SELECT discord_id FROM user WHERE discord_id != 'undefined' ORDER BY RAND() LIMIT ?",[randomCount],function (error, results, fields){ 754 | mysqlPool.releaseConnection(connection); 755 | if(error) 756 | { 757 | var errorMessage = "user_get_discord_ids: MySQL query problem. (SELECT discord_id FROM user WHERE discord_id != 'undefined' ORDER BY RAND() LIMIT ?)"; 758 | if(config.bot.errorLogging){ 759 | log.log_write_file(errorMessage); 760 | log.log_write_file(error); 761 | } 762 | log.log_write_console(errorMessage); 763 | log.log_write_console(error); 764 | resolve(false); 765 | }else{ 766 | resolve(results); 767 | } 768 | }); 769 | } 770 | }); 771 | }); 772 | }, 773 | 774 | /* ------------------------------------------------------------------------------ */ 775 | // Get user database count 776 | /* ------------------------------------------------------------------------------ */ 777 | 778 | user_get_total_count: function(){ 779 | return new Promise((resolve, reject)=>{ 780 | mysqlPool.getConnection(function(error, connection){ 781 | if(error){ 782 | try 783 | { 784 | mysqlPool.releaseConnection(connection); 785 | } 786 | catch (e){} 787 | var errorMessage = "user_get_total_count: MySQL connection problem."; 788 | if(config.bot.errorLogging){ 789 | log.log_write_file(errorMessage); 790 | log.log_write_file(error); 791 | } 792 | log.log_write_console(errorMessage); 793 | log.log_write_console(error); 794 | resolve(false); 795 | }else{ 796 | connection.execute("SELECT count(id) as totalusers FROM user WHERE discord_id != 'undefined'",[],function (error, results, fields){ 797 | mysqlPool.releaseConnection(connection); 798 | if(error) 799 | { 800 | var errorMessage = "user_get_total_count: MySQL query problem. (SELECT count(id) FROM user WHERE discord_id != 'undefined')"; 801 | if(config.bot.errorLogging){ 802 | log.log_write_file(errorMessage); 803 | log.log_write_file(error); 804 | } 805 | log.log_write_console(errorMessage); 806 | log.log_write_console(error); 807 | resolve(false); 808 | }else{ 809 | resolve(results); 810 | } 811 | }); 812 | } 813 | }); 814 | }); 815 | } 816 | 817 | }; -------------------------------------------------------------------------------- /functions/wallet.js: -------------------------------------------------------------------------------- 1 | //var config = require('../config.js'); 2 | try{ 3 | var config = process.cwd()+'/config.js'; 4 | config = require(config); 5 | }catch (error){ 6 | console.error('ERROR -> Unable to load config file.'); 7 | process.exit(1); 8 | } 9 | 10 | var log = require('./log.js'); 11 | 12 | /* ------------------------------------------------------------------------------ */ 13 | // // // // // // // // // // // // // // // // // // // // // // // // // // // // 14 | /* ------------------------------------------------------------------------------ */ 15 | 16 | // A node.js library for communicating with Bitcoin daemon. -> https://www.npmjs.com/package/altcoin-rpc 17 | const Client = require('altcoin-rpc'); 18 | const coinClient = new Client({ host: config.wallet.server, username: config.wallet.user, password: config.wallet.password, port: config.wallet.port }); 19 | 20 | const Big = require('big.js'); // https://github.com/MikeMcl/big.js -> http://mikemcl.github.io/big.js/ 21 | 22 | /* ------------------------------------------------------------------------------ */ 23 | // // // // // // // // // // // // // // // // // // // // // // // // // // // // 24 | /* ------------------------------------------------------------------------------ */ 25 | 26 | module.exports = { 27 | 28 | /* ------------------------------------------------------------------------------ */ 29 | // Create deposit address for user id 30 | /* ------------------------------------------------------------------------------ */ 31 | 32 | wallet_create_deposit_address: function(){ 33 | return new Promise((resolve, reject)=>{ 34 | coinClient.getNewAddress(function(error, result) { 35 | if(error){ 36 | var errorMessage = "wallet_create_deposit_address: Wallet query problem. (getnewaddress)"; 37 | if(config.bot.errorLogging){ 38 | log.log_write_file(errorMessage); 39 | log.log_write_file(error); 40 | } 41 | log.log_write_console(errorMessage); 42 | log.log_write_console(error); 43 | resolve(false); 44 | }else{ 45 | resolve(result); 46 | } 47 | }); 48 | }); 49 | }, 50 | 51 | /* ------------------------------------------------------------------------------ */ 52 | // Get latest deposits from wallet 53 | /* ------------------------------------------------------------------------------ */ 54 | 55 | wallet_get_latest_deposits: function(){ 56 | return new Promise((resolve, reject)=>{ 57 | coinClient.listTransactions('*', config.wallet.depositsToCheck, function(error, result) { 58 | if(error){ 59 | var errorMessage = "wallet_get_latest_deposits: Wallet query problem. (listTransactions)"; 60 | if(config.bot.errorLogging){ 61 | log.log_write_file(errorMessage); 62 | log.log_write_file(error); 63 | } 64 | log.log_write_console(errorMessage); 65 | log.log_write_console(error); 66 | resolve(false); 67 | }else{ 68 | resolve(result); 69 | } 70 | }); 71 | }); 72 | }, 73 | 74 | /* ------------------------------------------------------------------------------ */ 75 | // Check if payout address is valid 76 | /* ------------------------------------------------------------------------------ */ 77 | 78 | wallet_validate_address: function(address){ 79 | return new Promise((resolve, reject)=>{ 80 | coinClient.validateAddress(address, function(error, result) { 81 | if(error){ 82 | var errorMessage = "wallet_validate_address: Wallet query problem. (validateAddress)"; 83 | if(config.bot.errorLogging){ 84 | log.log_write_file(errorMessage); 85 | log.log_write_file(error); 86 | } 87 | log.log_write_console(errorMessage); 88 | log.log_write_console(error); 89 | resolve('error'); 90 | }else{ 91 | resolve(result.isvalid); 92 | } 93 | }); 94 | }); 95 | }, 96 | 97 | /* ------------------------------------------------------------------------------ */ 98 | // Do withdrawal to address 99 | /* ------------------------------------------------------------------------------ */ 100 | 101 | wallet_send_to_address: function(address,amount){ 102 | return new Promise((resolve, reject)=>{ 103 | coinClient.sendToAddress(address,amount, function(error, result) { 104 | if(error){ 105 | var errorMessage = "wallet_send_to_address: Wallet query problem. (sendToAddress)"; 106 | if(config.bot.errorLogging){ 107 | log.log_write_file(errorMessage); 108 | log.log_write_file(error); 109 | } 110 | log.log_write_console(errorMessage); 111 | log.log_write_console(error); 112 | resolve(false); 113 | }else{ 114 | resolve(result); 115 | } 116 | }); 117 | }); 118 | }, 119 | 120 | /* ------------------------------------------------------------------------------ */ 121 | // Get transaction 122 | /* ------------------------------------------------------------------------------ */ 123 | 124 | wallet_get_transaction: function(txid){ 125 | return new Promise((resolve, reject)=>{ 126 | coinClient.getTransaction(txid, function(error, result) { 127 | if(error){ 128 | var errorMessage = "wallet_get_transaction: Wallet query problem. (getTransaction)"; 129 | if(config.bot.errorLogging){ 130 | log.log_write_file(errorMessage); 131 | log.log_write_file(error); 132 | } 133 | log.log_write_console(errorMessage); 134 | log.log_write_console(error); 135 | resolve(false); 136 | }else{ 137 | resolve(result); 138 | } 139 | }); 140 | }); 141 | }, 142 | 143 | /* ------------------------------------------------------------------------------ */ 144 | // Get balance 145 | /* ------------------------------------------------------------------------------ */ 146 | 147 | wallet_get_balance: function(){ 148 | return new Promise((resolve, reject)=>{ 149 | coinClient.getBalance('*',function(error, result) { 150 | if(error){ 151 | var errorMessage = "wallet_get_balance: Wallet query problem. (getTransaction)"; 152 | if(config.bot.errorLogging){ 153 | log.log_write_file(errorMessage); 154 | log.log_write_file(error); 155 | } 156 | log.log_write_console(errorMessage); 157 | log.log_write_console(error); 158 | resolve(false); 159 | }else{ 160 | resolve(result); 161 | } 162 | }); 163 | }); 164 | }, 165 | 166 | /* ------------------------------------------------------------------------------ */ 167 | // Get wallet info 168 | /* ------------------------------------------------------------------------------ */ 169 | 170 | wallet_get_info: function(){ 171 | return new Promise((resolve, reject)=>{ 172 | coinClient.getInfo(function(error, result) { 173 | if(error){ 174 | var errorMessage = "wallet_get_info: Wallet query problem. (getInfo)"; 175 | if(config.bot.errorLogging){ 176 | log.log_write_file(errorMessage); 177 | log.log_write_file(error); 178 | } 179 | log.log_write_console(errorMessage); 180 | log.log_write_console(error); 181 | resolve('error'); 182 | }else{ 183 | resolve(result); 184 | } 185 | }); 186 | }); 187 | } 188 | 189 | }; -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | //var config = require('./config.js'); 2 | try{ 3 | var config = process.cwd()+'/config.js'; 4 | config = require(config); 5 | }catch (error){ 6 | console.error('ERROR -> Unable to load config file.'); 7 | process.exit(1); 8 | } 9 | 10 | var chat = require("./functions/chat.js"); 11 | var check = require("./functions/check.js"); 12 | var command = require("./functions/command.js"); 13 | var cron = require("./functions/cron.js"); 14 | // var storage = require("./functions/storage.js"); 15 | var log = require("./functions/log.js"); 16 | 17 | /* ------------------------------------------------------------------------------ */ 18 | // // // // // // // // // // // // // // // // // // // // // // // // // // // // 19 | /* ------------------------------------------------------------------------------ */ 20 | 21 | const { Client } = require('discord.js'); 22 | const client = new Client(); 23 | global.globalClient = client; 24 | 25 | var cooldownTimes = {}; // Cooldown timers by user, id and timestamp 26 | 27 | /* Latest active users */ 28 | var activeUsers = []; 29 | 30 | /* BOT ENABLE/DISABLE */ 31 | var botEnabled = 1; 32 | 33 | // Coin price if real price enabled on config 34 | global.coinPrice = 0; 35 | global.coinCentPrice = 0; 36 | 37 | /* ------------------------------------------------------------------------------ */ 38 | // // // // // // // // // // // // // // // // // // // // // // // // // // // // 39 | /* ------------------------------------------------------------------------------ */ 40 | 41 | client.on('error', console.error); 42 | process.on('unhandledRejection', error => console.error('Uncaught Promise Rejection', error)); 43 | 44 | client.on('ready', () => { 45 | log.log_write_console(config.messages.botStarted + ` ${client.user.tag}!`); 46 | client.user.setPresence({ status: 'online', game: { name: config.bot.gameMessage } }); 47 | if(config.bot.setNewAvatar){ 48 | client.user.setAvatar(config.bot.avatar); 49 | } 50 | }); 51 | 52 | client.on('message', msg => { 53 | 54 | var userID = msg.author.id; 55 | var userName = msg.author; 56 | var messageFull = msg; 57 | var messageType = msg.channel.type; 58 | var messageContent = msg.content; 59 | var channelID = msg.channel.id; 60 | var userRoles = 'none'; 61 | var serverUsers = []; 62 | var userBot = msg.author.bot; 63 | var currentTimestamp = Math.floor(Date.now() / 1000); 64 | 65 | // Only check messages if its not the bot itself or another bot 66 | if(userID == config.bot.botID) 67 | return; 68 | 69 | // Only check if its not other bot 70 | if(userBot) 71 | return; 72 | 73 | // Save and delete active users by time 74 | activeUsers[userID] = currentTimestamp; 75 | //console.log('Added/Updated -> '+userID+' t: '+currentTimestamp); 76 | // -> and remove inactive if no more in timeframe 77 | for (var key in activeUsers) { 78 | if(activeUsers[key] < (currentTimestamp-config.bot.activeUserTime)){ 79 | //console.log('deleted: '+activeUsers[key]+' - id: '+ key); 80 | delete activeUsers[key]; 81 | } 82 | } 83 | 84 | // If message has command prefix 85 | if(messageContent.startsWith(config.bot.commandPrefix)){ 86 | 87 | // Get user role if not direct message 88 | if(messageType !== 'dm'){ 89 | try{ 90 | var userRoles = msg.member.roles; 91 | }catch (error){ 92 | log.log_write_console('Failed to get role 1'); 93 | var userRoles = 'none'; 94 | } 95 | } 96 | 97 | try{ 98 | var userRole = check.check_user_role(userID,userRoles); 99 | }catch (error){ 100 | log.log_write_console('Failed to get role 2'); 101 | var userRole = 0; 102 | } 103 | 104 | // Enable / Disable bot commands 105 | // Check if command is start or stop 106 | var startStopCheck = messageContent.split(/ +/); 107 | if(startStopCheck[0].substr(1) === 'stop' && userRole == 3){ 108 | botEnabled = 0; 109 | chat.chat_reply(msg,'embed',false,messageType,config.colors.special,false,false,false,config.messages.startstop.disabled,false,false,false,false); 110 | return; 111 | } 112 | if(startStopCheck[0].substr(1) === 'start' && userRole == 3){ 113 | botEnabled = 1; 114 | chat.chat_reply(msg,'embed',false,messageType,config.colors.special,false,false,false,config.messages.startstop.enabled,false,false,false,false); 115 | return; 116 | } 117 | if(!botEnabled){ 118 | return; 119 | } 120 | 121 | // If its not a dm message check if its a valid channel for commands 122 | if(!check.check_respond_channel(channelID) && messageType !== 'dm') 123 | return; 124 | 125 | // Check if admin mode is enabled and only allow commands from admins 126 | if(config.bot.adminMode && userRole != 3){ 127 | if(messageType !== 'dm') 128 | msg.delete(); 129 | //msg,replyType,replyUsername,senderMessageType,replyEmbedColor,replyAuthor,replyTitle,replyFields,replyDescription,replyFooter,replyThumbnail,replyImage,replyTimestamp 130 | chat.chat_reply(msg,'embed',userName,messageType,config.colors.warning,false,config.messages.title.warning,false,config.messages.adminMode,false,false,false,false); 131 | return; 132 | } 133 | 134 | // Save and check cooldown timer but ignor admins/mods/vips ˇˇ 135 | if(userRole < 1){ 136 | if(cooldownTimes[userID] > (currentTimestamp-config.bot.cooldownTime) && cooldownTimes[userID] !== undefined){ 137 | //msg,replyType,replyUsername,senderMessageType,replyEmbedColor,replyAuthor,replyTitle,replyFields,replyDescription,replyFooter,replyThumbnail,replyImage,replyTimestamp 138 | chat.chat_reply(msg,'embed',userName,messageType,config.colors.warning,false,config.messages.title.warning,false,config.messages.cooldown,false,false,false,false); 139 | return; 140 | } 141 | cooldownTimes[userID] = currentTimestamp; 142 | } 143 | 144 | // Check if direct messages to bot are disabled 145 | if(!config.bot.allowDM && messageType === 'dm'){ 146 | //msg,replyType,replyUsername,senderMessageType,replyEmbedColor,replyAuthor,replyTitle,replyFields,replyDescription,replyFooter,replyThumbnail,replyImage,replyTimestamp 147 | chat.chat_reply(msg,'embed',userName,messageType,config.colors.error,false,config.messages.title.error,false,config.messages.DMDisabled,false,false,false,false); 148 | return; 149 | } 150 | 151 | // Check if its a valid message and if it use the right prefix 152 | if(!check.check_valid_content(messageContent)){ // if not valid 153 | // Delete message if not direct message and delete 154 | if(messageType !== 'dm') 155 | msg.delete(); 156 | //msg,replyType,replyUsername,senderMessageType,replyEmbedColor,replyAuthor,replyTitle,replyFields,replyDescription,replyFooter,replyThumbnail,replyImage,replyTimestamp 157 | chat.chat_reply(msg,'embed',userName,messageType,config.colors.error,false,config.messages.title.error,false,config.messages.notValidCommand,false,false,false,false); 158 | return; 159 | } 160 | 161 | // Check if command is withdrawal request and not lowercase it because of address 162 | var withdrawalCheck = messageContent.split(/ +/); 163 | if(withdrawalCheck[0].substr(1) === 'w' || withdrawalCheck[0].substr(1) === 'withdraw'){ 164 | var recievedCommand = messageContent.split(/ +/); 165 | }else{ 166 | var recievedCommand = messageContent.toLowerCase().split(/ +/); 167 | } 168 | 169 | // Build recievedCommand partFive for drop phrase 170 | var dropPhrase = ""; 171 | for (var i = 4 ; i < recievedCommand.length ; ++i){ 172 | if(i != 4) 173 | dropPhrase = dropPhrase + ' '; 174 | dropPhrase = dropPhrase + recievedCommand[i]; 175 | // If phrase is longer as defined on config 176 | if(dropPhrase.length > config.bot.dropMessageMaxLength){ 177 | i = recievedCommand.length; 178 | } 179 | } 180 | // Cut it to max lengh and remove space on start and end 181 | dropPhrase = dropPhrase.substring(0,config.bot.dropMessageMaxLength); 182 | dropPhrase = dropPhrase.trim(); 183 | 184 | /// DISABLED AND NOT USED AND OVERWRITTEN ON RAIN FUNCTION // Check if command is rain and get user list from discord server 185 | var rainCheck = messageContent.split(/ +/); 186 | if(rainCheck[0].substr(1) === 'rain' && rainCheck[1] === 'all' || rainCheck[1] === 'random'){ 187 | // This crashes the bot if there are to many discord users and multiple channel the bot is in so changed to grab random users from database with maxRainRandomUsers from config as more is not needed because rain all just grabs total count and credits all users 188 | /*if(client.users){ 189 | Array.from(client.users.filter(user => user.bot == false).values()).forEach(element => { 190 | serverUsers.push(element.id); 191 | }); 192 | }*/ 193 | } 194 | 195 | // Check if command is on ignor list 196 | var ignorCheck = recievedCommand[0].substr(1); 197 | if(config.bot.commandIgnor.includes(ignorCheck)){ 198 | return; 199 | } 200 | 201 | // Process command 202 | command.fire_command(messageFull,userID,userName,messageType,userRole,recievedCommand[0].substr(1),recievedCommand[1],recievedCommand[2],recievedCommand[3],dropPhrase,serverUsers,activeUsers); 203 | } 204 | 205 | }); 206 | 207 | // Start the bot 208 | client.login(config.bot.botToken); 209 | 210 | // Start cronjobs 211 | if(config.wallet.check) // Check for new deposits 212 | cron.cron_get_deposits(); 213 | if(config.wallet.credit) // Credit new deposits 214 | cron.cron_credit_deposits(); 215 | if(config.staking.check) // Check for new stakes 216 | cron.cron_get_stakes(); 217 | if(config.staking.credit) // Credit new stakes 218 | cron.cron_credit_stakes(); 219 | if(config.coinPrice.enabled) // Get coin price 220 | cron.cron_price(); 221 | -------------------------------------------------------------------------------- /lowdb/lowdb.json: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cryptocurrency-crypto-bot", 3 | "version": "1.3.2", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@uphold/request-logger": { 8 | "version": "2.0.0", 9 | "resolved": "https://registry.npmjs.org/@uphold/request-logger/-/request-logger-2.0.0.tgz", 10 | "integrity": "sha1-xYXAvblCEBmJRcZZfk/iPW5j4IQ=", 11 | "requires": { 12 | "uuid": "^3.0.1" 13 | } 14 | }, 15 | "ajv": { 16 | "version": "6.5.5", 17 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.5.tgz", 18 | "integrity": "sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg==", 19 | "requires": { 20 | "fast-deep-equal": "^2.0.1", 21 | "fast-json-stable-stringify": "^2.0.0", 22 | "json-schema-traverse": "^0.4.1", 23 | "uri-js": "^4.2.2" 24 | } 25 | }, 26 | "altcoin-rpc": { 27 | "version": "1.0.2", 28 | "resolved": "https://registry.npmjs.org/altcoin-rpc/-/altcoin-rpc-1.0.2.tgz", 29 | "integrity": "sha512-Pr1IuAIhxX3fpXeJjxnuVwdpPH0lnHebbriGDPzb0ZyLn9Yh1PE3SJVZNBQExGq/c4cbLNgOxlIlav4tJUvAAQ==", 30 | "requires": { 31 | "@uphold/request-logger": "^2.0.0", 32 | "bluebird": "^3.4.1", 33 | "json-bigint": "^0.2.0", 34 | "lodash": "^4.0.0", 35 | "request": "^2.53.0", 36 | "semver": "^5.1.0", 37 | "standard-error": "^1.1.0" 38 | } 39 | }, 40 | "array-unique": { 41 | "version": "0.3.2", 42 | "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", 43 | "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" 44 | }, 45 | "asn1": { 46 | "version": "0.2.4", 47 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", 48 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", 49 | "requires": { 50 | "safer-buffer": "~2.1.0" 51 | } 52 | }, 53 | "assert-plus": { 54 | "version": "1.0.0", 55 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 56 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 57 | }, 58 | "async-limiter": { 59 | "version": "1.0.0", 60 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", 61 | "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" 62 | }, 63 | "asynckit": { 64 | "version": "0.4.0", 65 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 66 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 67 | }, 68 | "aws-sign2": { 69 | "version": "0.7.0", 70 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 71 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" 72 | }, 73 | "aws4": { 74 | "version": "1.8.0", 75 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", 76 | "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" 77 | }, 78 | "bcrypt-pbkdf": { 79 | "version": "1.0.2", 80 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 81 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 82 | "requires": { 83 | "tweetnacl": "^0.14.3" 84 | }, 85 | "dependencies": { 86 | "tweetnacl": { 87 | "version": "0.14.5", 88 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 89 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" 90 | } 91 | } 92 | }, 93 | "big.js": { 94 | "version": "5.2.2", 95 | "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", 96 | "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" 97 | }, 98 | "bignumber.js": { 99 | "version": "4.1.0", 100 | "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.1.0.tgz", 101 | "integrity": "sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA==" 102 | }, 103 | "bindings": { 104 | "version": "1.3.1", 105 | "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.1.tgz", 106 | "integrity": "sha512-i47mqjF9UbjxJhxGf+pZ6kSxrnI3wBLlnGI2ArWJ4r0VrvDS7ZYXkprq/pLaBWYq4GM0r4zdHY+NNRqEMU7uew==" 107 | }, 108 | "bluebird": { 109 | "version": "3.5.3", 110 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", 111 | "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==" 112 | }, 113 | "bufferutil": { 114 | "version": "4.0.0", 115 | "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.0.tgz", 116 | "integrity": "sha512-jpnqMVLo7sqfUY2W92RC4jjj9TuiOSkjB0k43TxPcrBSntZwXUOl8Krfd3eVEdApuScpSTwYKntm/dXU2T8gnw==", 117 | "requires": { 118 | "node-gyp-build": "~3.4.0" 119 | } 120 | }, 121 | "caseless": { 122 | "version": "0.12.0", 123 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 124 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" 125 | }, 126 | "circular-json": { 127 | "version": "0.5.9", 128 | "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", 129 | "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==" 130 | }, 131 | "combined-stream": { 132 | "version": "1.0.7", 133 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", 134 | "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", 135 | "requires": { 136 | "delayed-stream": "~1.0.0" 137 | } 138 | }, 139 | "commander": { 140 | "version": "2.19.0", 141 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", 142 | "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==" 143 | }, 144 | "core-util-is": { 145 | "version": "1.0.2", 146 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 147 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 148 | }, 149 | "dashdash": { 150 | "version": "1.14.1", 151 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 152 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 153 | "requires": { 154 | "assert-plus": "^1.0.0" 155 | } 156 | }, 157 | "date-format": { 158 | "version": "1.2.0", 159 | "resolved": "https://registry.npmjs.org/date-format/-/date-format-1.2.0.tgz", 160 | "integrity": "sha1-YV6CjiM90aubua4JUODOzPpuytg=" 161 | }, 162 | "debug": { 163 | "version": "3.2.6", 164 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", 165 | "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", 166 | "requires": { 167 | "ms": "^2.1.1" 168 | } 169 | }, 170 | "delayed-stream": { 171 | "version": "1.0.0", 172 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 173 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 174 | }, 175 | "denque": { 176 | "version": "1.3.0", 177 | "resolved": "https://registry.npmjs.org/denque/-/denque-1.3.0.tgz", 178 | "integrity": "sha512-4SRaSj+PqmrS1soW5/Avd7eJIM2JJIqLLmwhRqIGleZM/8KwZq80njbSS2Iqas+6oARkSkLDHEk4mm78q3JlIg==" 179 | }, 180 | "discord.js": { 181 | "version": "11.4.2", 182 | "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-11.4.2.tgz", 183 | "integrity": "sha512-MDwpu0lMFTjqomijDl1Ed9miMQe6kB4ifKdP28QZllmLv/HVOJXhatRgjS8urp/wBlOfx+qAYSXcdI5cKGYsfg==", 184 | "requires": { 185 | "long": "^4.0.0", 186 | "prism-media": "^0.0.3", 187 | "snekfetch": "^3.6.4", 188 | "tweetnacl": "^1.0.0", 189 | "ws": "^4.0.0" 190 | } 191 | }, 192 | "ecc-jsbn": { 193 | "version": "0.1.2", 194 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", 195 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", 196 | "requires": { 197 | "jsbn": "~0.1.0", 198 | "safer-buffer": "^2.1.0" 199 | } 200 | }, 201 | "erlpack": { 202 | "version": "0.1.2", 203 | "resolved": "https://registry.npmjs.org/erlpack/-/erlpack-0.1.2.tgz", 204 | "integrity": "sha1-zx9PdV0HKOvC0RsuPJK9Lag0UU4=", 205 | "requires": { 206 | "bindings": "^1.2.1", 207 | "nan": "^2.1.0" 208 | } 209 | }, 210 | "extend": { 211 | "version": "3.0.2", 212 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 213 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 214 | }, 215 | "extsprintf": { 216 | "version": "1.3.0", 217 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 218 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" 219 | }, 220 | "fast-deep-equal": { 221 | "version": "2.0.1", 222 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", 223 | "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" 224 | }, 225 | "fast-json-stable-stringify": { 226 | "version": "2.0.0", 227 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 228 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" 229 | }, 230 | "forever-agent": { 231 | "version": "0.6.1", 232 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 233 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" 234 | }, 235 | "form-data": { 236 | "version": "2.3.3", 237 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", 238 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", 239 | "requires": { 240 | "asynckit": "^0.4.0", 241 | "combined-stream": "^1.0.6", 242 | "mime-types": "^2.1.12" 243 | } 244 | }, 245 | "fs": { 246 | "version": "0.0.1-security", 247 | "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", 248 | "integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ=" 249 | }, 250 | "generate-function": { 251 | "version": "2.3.1", 252 | "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", 253 | "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", 254 | "requires": { 255 | "is-property": "^1.0.2" 256 | } 257 | }, 258 | "getpass": { 259 | "version": "0.1.7", 260 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 261 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 262 | "requires": { 263 | "assert-plus": "^1.0.0" 264 | } 265 | }, 266 | "graceful-fs": { 267 | "version": "4.1.15", 268 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", 269 | "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" 270 | }, 271 | "har-schema": { 272 | "version": "2.0.0", 273 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 274 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" 275 | }, 276 | "har-validator": { 277 | "version": "5.1.3", 278 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", 279 | "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", 280 | "requires": { 281 | "ajv": "^6.5.5", 282 | "har-schema": "^2.0.0" 283 | } 284 | }, 285 | "http-signature": { 286 | "version": "1.2.0", 287 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 288 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 289 | "requires": { 290 | "assert-plus": "^1.0.0", 291 | "jsprim": "^1.2.2", 292 | "sshpk": "^1.7.0" 293 | } 294 | }, 295 | "iconv-lite": { 296 | "version": "0.4.24", 297 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 298 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 299 | "requires": { 300 | "safer-buffer": ">= 2.1.2 < 3" 301 | } 302 | }, 303 | "inherits": { 304 | "version": "2.0.3", 305 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 306 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 307 | }, 308 | "is-promise": { 309 | "version": "2.1.0", 310 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", 311 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" 312 | }, 313 | "is-property": { 314 | "version": "1.0.2", 315 | "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", 316 | "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" 317 | }, 318 | "is-typedarray": { 319 | "version": "1.0.0", 320 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 321 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 322 | }, 323 | "isarray": { 324 | "version": "1.0.0", 325 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 326 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 327 | }, 328 | "isstream": { 329 | "version": "0.1.2", 330 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 331 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" 332 | }, 333 | "jsbn": { 334 | "version": "0.1.1", 335 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 336 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" 337 | }, 338 | "json-bigint": { 339 | "version": "0.2.3", 340 | "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.2.3.tgz", 341 | "integrity": "sha1-EY1/b/HThlnxn5TPc+ZKdaP5iKg=", 342 | "requires": { 343 | "bignumber.js": "^4.0.0" 344 | } 345 | }, 346 | "json-schema": { 347 | "version": "0.2.3", 348 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 349 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" 350 | }, 351 | "json-schema-traverse": { 352 | "version": "0.4.1", 353 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 354 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" 355 | }, 356 | "json-stringify-safe": { 357 | "version": "5.0.1", 358 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 359 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 360 | }, 361 | "jsonfile": { 362 | "version": "5.0.0", 363 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-5.0.0.tgz", 364 | "integrity": "sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w==", 365 | "requires": { 366 | "graceful-fs": "^4.1.6", 367 | "universalify": "^0.1.2" 368 | } 369 | }, 370 | "jsprim": { 371 | "version": "1.4.1", 372 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 373 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 374 | "requires": { 375 | "assert-plus": "1.0.0", 376 | "extsprintf": "1.3.0", 377 | "json-schema": "0.2.3", 378 | "verror": "1.10.0" 379 | } 380 | }, 381 | "libsodium": { 382 | "version": "0.7.3", 383 | "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.3.tgz", 384 | "integrity": "sha512-ld+deUNqSsZYbAobUs63UyduPq8ICp/Ul/5lbvBIYpuSNWpPRU0PIxbW+xXipVZtuopR6fIz9e0tTnNuPMNeqw==" 385 | }, 386 | "libsodium-wrappers": { 387 | "version": "0.7.3", 388 | "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.3.tgz", 389 | "integrity": "sha512-dw5Jh6TZ5qc5rQVZe3JrSO/J05CE+DmAPnqD7Q2glBUE969xZ6o3fchnUxyPlp6ss3x0MFxmdJntveFN+XTg1g==", 390 | "requires": { 391 | "libsodium": "0.7.3" 392 | } 393 | }, 394 | "lodash": { 395 | "version": "4.17.21", 396 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 397 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" 398 | }, 399 | "log4js": { 400 | "version": "3.0.6", 401 | "resolved": "https://registry.npmjs.org/log4js/-/log4js-3.0.6.tgz", 402 | "integrity": "sha512-ezXZk6oPJCWL483zj64pNkMuY/NcRX5MPiB0zE6tjZM137aeusrOnW1ecxgF9cmwMWkBMhjteQxBPoZBh9FDxQ==", 403 | "requires": { 404 | "circular-json": "^0.5.5", 405 | "date-format": "^1.2.0", 406 | "debug": "^3.1.0", 407 | "rfdc": "^1.1.2", 408 | "streamroller": "0.7.0" 409 | } 410 | }, 411 | "long": { 412 | "version": "4.0.0", 413 | "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", 414 | "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" 415 | }, 416 | "lowdb": { 417 | "version": "1.0.0", 418 | "resolved": "https://registry.npmjs.org/lowdb/-/lowdb-1.0.0.tgz", 419 | "integrity": "sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ==", 420 | "requires": { 421 | "graceful-fs": "^4.1.3", 422 | "is-promise": "^2.1.0", 423 | "lodash": "4", 424 | "pify": "^3.0.0", 425 | "steno": "^0.4.1" 426 | } 427 | }, 428 | "lru-cache": { 429 | "version": "4.1.3", 430 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", 431 | "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", 432 | "requires": { 433 | "pseudomap": "^1.0.2", 434 | "yallist": "^2.1.2" 435 | } 436 | }, 437 | "mime-db": { 438 | "version": "1.37.0", 439 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", 440 | "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" 441 | }, 442 | "mime-types": { 443 | "version": "2.1.21", 444 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", 445 | "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", 446 | "requires": { 447 | "mime-db": "~1.37.0" 448 | } 449 | }, 450 | "minimist": { 451 | "version": "0.0.8", 452 | "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 453 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" 454 | }, 455 | "mkdirp": { 456 | "version": "0.5.1", 457 | "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 458 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 459 | "requires": { 460 | "minimist": "0.0.8" 461 | } 462 | }, 463 | "moment": { 464 | "version": "2.22.2", 465 | "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", 466 | "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=" 467 | }, 468 | "moment-timezone": { 469 | "version": "0.5.23", 470 | "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.23.tgz", 471 | "integrity": "sha512-WHFH85DkCfiNMDX5D3X7hpNH3/PUhjTGcD0U1SgfBGZxJ3qUmJh5FdvaFjcClxOvB3rzdfj4oRffbI38jEnC1w==", 472 | "requires": { 473 | "moment": ">= 2.9.0" 474 | } 475 | }, 476 | "ms": { 477 | "version": "2.1.1", 478 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 479 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 480 | }, 481 | "mysql2": { 482 | "version": "1.6.4", 483 | "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-1.6.4.tgz", 484 | "integrity": "sha512-ZYbYgK06HKfxU45tYYLfwW5gKt8BslfE7FGyULNrf2K2fh+DuEX+e0QKsd2ObpZkMILefaVn8hsakVsTFqravQ==", 485 | "requires": { 486 | "denque": "1.3.0", 487 | "generate-function": "^2.3.1", 488 | "iconv-lite": "^0.4.24", 489 | "long": "^4.0.0", 490 | "lru-cache": "4.1.3", 491 | "named-placeholders": "1.1.1", 492 | "seq-queue": "0.0.5", 493 | "sqlstring": "2.3.1" 494 | } 495 | }, 496 | "named-placeholders": { 497 | "version": "1.1.1", 498 | "resolved": "http://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.1.tgz", 499 | "integrity": "sha1-O3oNJiA910s6nfTJz7gnsvuQfmQ=", 500 | "requires": { 501 | "lru-cache": "2.5.0" 502 | }, 503 | "dependencies": { 504 | "lru-cache": { 505 | "version": "2.5.0", 506 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz", 507 | "integrity": "sha1-2COIrpyWC+y+oMc7uet5tsbOmus=" 508 | } 509 | } 510 | }, 511 | "nan": { 512 | "version": "2.12.1", 513 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz", 514 | "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==" 515 | }, 516 | "node-addon-api": { 517 | "version": "1.6.2", 518 | "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.6.2.tgz", 519 | "integrity": "sha512-479Bjw9nTE5DdBSZZWprFryHGjUaQC31y1wHo19We/k0BZlrmhqQitWoUL0cD8+scljCbIUL+E58oRDEakdGGA==" 520 | }, 521 | "node-gyp-build": { 522 | "version": "3.4.0", 523 | "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.4.0.tgz", 524 | "integrity": "sha512-YoviGBJYGrPdLOKDIQB0sKxuKy/EEsxzooNkOZak4vSTKT/qH0Pa6dj3t1MJjEQGsefih61IyHDmO1WW7xOFfw==" 525 | }, 526 | "node-opus": { 527 | "version": "0.3.1", 528 | "resolved": "https://registry.npmjs.org/node-opus/-/node-opus-0.3.1.tgz", 529 | "integrity": "sha512-1Cb8OvHhdDspVfeKMjEgbedJabyE1Ib6OcN2BMEsRCU7FIsciuBpOErcie3y0qTf83nclPAY+kBU3Oj+U+oRlQ==", 530 | "requires": { 531 | "bindings": "~1.2.1", 532 | "commander": "^2.9.0", 533 | "nan": "^2.10.0", 534 | "ogg-packet": "^1.0.0" 535 | }, 536 | "dependencies": { 537 | "bindings": { 538 | "version": "1.2.1", 539 | "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz", 540 | "integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE=" 541 | } 542 | } 543 | }, 544 | "oauth-sign": { 545 | "version": "0.9.0", 546 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", 547 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" 548 | }, 549 | "ogg-packet": { 550 | "version": "1.0.0", 551 | "resolved": "https://registry.npmjs.org/ogg-packet/-/ogg-packet-1.0.0.tgz", 552 | "integrity": "sha1-RbiFchrI991c8iOR1CEGrlM6xng=", 553 | "optional": true, 554 | "requires": { 555 | "ref-struct": "*" 556 | } 557 | }, 558 | "opusscript": { 559 | "version": "0.0.6", 560 | "resolved": "https://registry.npmjs.org/opusscript/-/opusscript-0.0.6.tgz", 561 | "integrity": "sha512-F7nx1SWZCD5Rq2W+5Fx39HlkRkz/5Zqt0LglEB9uHexk8HjedDEiM+u/Y2rBfDFcS/0uQIWu2lJhw+Gjsta+cA==" 562 | }, 563 | "performance-now": { 564 | "version": "2.1.0", 565 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 566 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" 567 | }, 568 | "pify": { 569 | "version": "3.0.0", 570 | "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", 571 | "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" 572 | }, 573 | "prism-media": { 574 | "version": "0.0.3", 575 | "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-0.0.3.tgz", 576 | "integrity": "sha512-c9KkNifSMU/iXT8FFTaBwBMr+rdVcN+H/uNv1o+CuFeTThNZNTOrQ+RgXA1yL/DeLk098duAeRPP3QNPNbhxYQ==" 577 | }, 578 | "process-nextick-args": { 579 | "version": "2.0.0", 580 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", 581 | "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" 582 | }, 583 | "pseudomap": { 584 | "version": "1.0.2", 585 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 586 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" 587 | }, 588 | "psl": { 589 | "version": "1.1.29", 590 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", 591 | "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==" 592 | }, 593 | "punycode": { 594 | "version": "2.1.1", 595 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 596 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" 597 | }, 598 | "qs": { 599 | "version": "6.5.2", 600 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 601 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" 602 | }, 603 | "readable-stream": { 604 | "version": "2.3.6", 605 | "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", 606 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 607 | "requires": { 608 | "core-util-is": "~1.0.0", 609 | "inherits": "~2.0.3", 610 | "isarray": "~1.0.0", 611 | "process-nextick-args": "~2.0.0", 612 | "safe-buffer": "~5.1.1", 613 | "string_decoder": "~1.1.1", 614 | "util-deprecate": "~1.0.1" 615 | } 616 | }, 617 | "ref": { 618 | "version": "1.3.5", 619 | "resolved": "https://registry.npmjs.org/ref/-/ref-1.3.5.tgz", 620 | "integrity": "sha512-2cBCniTtxcGUjDpvFfVpw323a83/0RLSGJJY5l5lcomZWhYpU2cuLdsvYqMixvsdLJ9+sTdzEkju8J8ZHDM2nA==", 621 | "optional": true, 622 | "requires": { 623 | "bindings": "1", 624 | "debug": "2", 625 | "nan": "2" 626 | }, 627 | "dependencies": { 628 | "debug": { 629 | "version": "2.6.9", 630 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 631 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 632 | "optional": true, 633 | "requires": { 634 | "ms": "2.0.0" 635 | } 636 | }, 637 | "ms": { 638 | "version": "2.0.0", 639 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 640 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 641 | "optional": true 642 | } 643 | } 644 | }, 645 | "ref-struct": { 646 | "version": "1.1.0", 647 | "resolved": "https://registry.npmjs.org/ref-struct/-/ref-struct-1.1.0.tgz", 648 | "integrity": "sha1-XV7mWtQc78Olxf60BYcmHkee3BM=", 649 | "optional": true, 650 | "requires": { 651 | "debug": "2", 652 | "ref": "1" 653 | }, 654 | "dependencies": { 655 | "debug": { 656 | "version": "2.6.9", 657 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 658 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 659 | "optional": true, 660 | "requires": { 661 | "ms": "2.0.0" 662 | } 663 | }, 664 | "ms": { 665 | "version": "2.0.0", 666 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 667 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 668 | "optional": true 669 | } 670 | } 671 | }, 672 | "request": { 673 | "version": "2.88.0", 674 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", 675 | "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", 676 | "requires": { 677 | "aws-sign2": "~0.7.0", 678 | "aws4": "^1.8.0", 679 | "caseless": "~0.12.0", 680 | "combined-stream": "~1.0.6", 681 | "extend": "~3.0.2", 682 | "forever-agent": "~0.6.1", 683 | "form-data": "~2.3.2", 684 | "har-validator": "~5.1.0", 685 | "http-signature": "~1.2.0", 686 | "is-typedarray": "~1.0.0", 687 | "isstream": "~0.1.2", 688 | "json-stringify-safe": "~5.0.1", 689 | "mime-types": "~2.1.19", 690 | "oauth-sign": "~0.9.0", 691 | "performance-now": "^2.1.0", 692 | "qs": "~6.5.2", 693 | "safe-buffer": "^5.1.2", 694 | "tough-cookie": "~2.4.3", 695 | "tunnel-agent": "^0.6.0", 696 | "uuid": "^3.3.2" 697 | } 698 | }, 699 | "request-promise": { 700 | "version": "4.2.4", 701 | "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.4.tgz", 702 | "integrity": "sha512-8wgMrvE546PzbR5WbYxUQogUnUDfM0S7QIFZMID+J73vdFARkFy+HElj4T+MWYhpXwlLp0EQ8Zoj8xUA0he4Vg==", 703 | "requires": { 704 | "bluebird": "^3.5.0", 705 | "request-promise-core": "1.1.2", 706 | "stealthy-require": "^1.1.1", 707 | "tough-cookie": "^2.3.3" 708 | } 709 | }, 710 | "request-promise-core": { 711 | "version": "1.1.2", 712 | "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", 713 | "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", 714 | "requires": { 715 | "lodash": "^4.17.11" 716 | } 717 | }, 718 | "rfdc": { 719 | "version": "1.1.2", 720 | "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.2.tgz", 721 | "integrity": "sha512-92ktAgvZhBzYTIK0Mja9uen5q5J3NRVMoDkJL2VMwq6SXjVCgqvQeVP2XAaUY6HT+XpQYeLSjb3UoitBryKmdA==" 722 | }, 723 | "safe-buffer": { 724 | "version": "5.1.2", 725 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 726 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 727 | }, 728 | "safer-buffer": { 729 | "version": "2.1.2", 730 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 731 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 732 | }, 733 | "semver": { 734 | "version": "5.6.0", 735 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", 736 | "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" 737 | }, 738 | "seq-queue": { 739 | "version": "0.0.5", 740 | "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", 741 | "integrity": "sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4=" 742 | }, 743 | "snekfetch": { 744 | "version": "3.6.4", 745 | "resolved": "https://registry.npmjs.org/snekfetch/-/snekfetch-3.6.4.tgz", 746 | "integrity": "sha512-NjxjITIj04Ffqid5lqr7XdgwM7X61c/Dns073Ly170bPQHLm6jkmelye/eglS++1nfTWktpP6Y2bFXjdPlQqdw==" 747 | }, 748 | "sodium": { 749 | "version": "3.0.2", 750 | "resolved": "https://registry.npmjs.org/sodium/-/sodium-3.0.2.tgz", 751 | "integrity": "sha512-IsTwTJeoNBU97km3XkrbCGC/n/9aUQejgD3QPr2YY2gtbSPru3TI6nhCqgoez9Mv88frF9oVZS/jrXFbd6WXyA==", 752 | "requires": { 753 | "node-addon-api": "*" 754 | } 755 | }, 756 | "sqlstring": { 757 | "version": "2.3.1", 758 | "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", 759 | "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=" 760 | }, 761 | "sshpk": { 762 | "version": "1.15.2", 763 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz", 764 | "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==", 765 | "requires": { 766 | "asn1": "~0.2.3", 767 | "assert-plus": "^1.0.0", 768 | "bcrypt-pbkdf": "^1.0.0", 769 | "dashdash": "^1.12.0", 770 | "ecc-jsbn": "~0.1.1", 771 | "getpass": "^0.1.1", 772 | "jsbn": "~0.1.0", 773 | "safer-buffer": "^2.0.2", 774 | "tweetnacl": "~0.14.0" 775 | }, 776 | "dependencies": { 777 | "tweetnacl": { 778 | "version": "0.14.5", 779 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 780 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" 781 | } 782 | } 783 | }, 784 | "standard-error": { 785 | "version": "1.1.0", 786 | "resolved": "https://registry.npmjs.org/standard-error/-/standard-error-1.1.0.tgz", 787 | "integrity": "sha1-I+UWj6HAggGJ5YEnAaeQWFENDTQ=" 788 | }, 789 | "stealthy-require": { 790 | "version": "1.1.1", 791 | "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", 792 | "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" 793 | }, 794 | "steno": { 795 | "version": "0.4.4", 796 | "resolved": "https://registry.npmjs.org/steno/-/steno-0.4.4.tgz", 797 | "integrity": "sha1-BxEFvfwobmYVwEA8J+nXtdy4Vcs=", 798 | "requires": { 799 | "graceful-fs": "^4.1.3" 800 | } 801 | }, 802 | "streamroller": { 803 | "version": "0.7.0", 804 | "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz", 805 | "integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==", 806 | "requires": { 807 | "date-format": "^1.2.0", 808 | "debug": "^3.1.0", 809 | "mkdirp": "^0.5.1", 810 | "readable-stream": "^2.3.0" 811 | } 812 | }, 813 | "string_decoder": { 814 | "version": "1.1.1", 815 | "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 816 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 817 | "requires": { 818 | "safe-buffer": "~5.1.0" 819 | } 820 | }, 821 | "tough-cookie": { 822 | "version": "2.4.3", 823 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", 824 | "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", 825 | "requires": { 826 | "psl": "^1.1.24", 827 | "punycode": "^1.4.1" 828 | }, 829 | "dependencies": { 830 | "punycode": { 831 | "version": "1.4.1", 832 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 833 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" 834 | } 835 | } 836 | }, 837 | "tunnel-agent": { 838 | "version": "0.6.0", 839 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 840 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 841 | "requires": { 842 | "safe-buffer": "^5.0.1" 843 | } 844 | }, 845 | "tweetnacl": { 846 | "version": "1.0.0", 847 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.0.tgz", 848 | "integrity": "sha1-cT2LgY2kIGh0C/aDhtBHnmb8ins=" 849 | }, 850 | "universalify": { 851 | "version": "0.1.2", 852 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 853 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" 854 | }, 855 | "uri-js": { 856 | "version": "4.2.2", 857 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 858 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 859 | "requires": { 860 | "punycode": "^2.1.0" 861 | } 862 | }, 863 | "util-deprecate": { 864 | "version": "1.0.2", 865 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 866 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 867 | }, 868 | "uuid": { 869 | "version": "3.3.2", 870 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", 871 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" 872 | }, 873 | "uws": { 874 | "version": "99.0.0", 875 | "resolved": "https://registry.npmjs.org/uws/-/uws-99.0.0.tgz", 876 | "integrity": "sha512-gbzhpHHE37BsiCB1raq5Wzf4ENKTaxyg1gZ7LJ/Z0za9Ic6EEwq5VpfivNh9Or2Tpf3f3jPEWCGLVDle2MukTg==" 877 | }, 878 | "verror": { 879 | "version": "1.10.0", 880 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 881 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 882 | "requires": { 883 | "assert-plus": "^1.0.0", 884 | "core-util-is": "1.0.2", 885 | "extsprintf": "^1.2.0" 886 | } 887 | }, 888 | "ws": { 889 | "version": "4.1.0", 890 | "resolved": "http://registry.npmjs.org/ws/-/ws-4.1.0.tgz", 891 | "integrity": "sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA==", 892 | "requires": { 893 | "async-limiter": "~1.0.0", 894 | "safe-buffer": "~5.1.0" 895 | } 896 | }, 897 | "yallist": { 898 | "version": "2.1.2", 899 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 900 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" 901 | } 902 | } 903 | } 904 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cryptocurrency-crypto-bot", 3 | "version": "1.3.2", 4 | "description": "Cryptocurrency-crypto-bot is an open-source Node.js wallet bot for Discord.", 5 | "main": "./index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "bin": { 10 | "cryptobot": "./index.js" 11 | }, 12 | "pkg": { 13 | "scripts": "./functions/**/*.js", 14 | "assets": "./storage/**/*" 15 | }, 16 | "author": "Christian Grieger", 17 | "license": "MIT", 18 | "dependencies": { 19 | "altcoin-rpc": "^1.0.2", 20 | "array-unique": "^0.3.2", 21 | "big.js": "^5.2.2", 22 | "bufferutil": "^4.0.0", 23 | "discord.js": "^11.4.2", 24 | "erlpack": "^0.1.2", 25 | "fs": "0.0.1-security", 26 | "jsonfile": "^5.0.0", 27 | "libsodium-wrappers": "^0.7.3", 28 | "log4js": "^3.0.6", 29 | "lowdb": "^1.0.0", 30 | "moment": "^2.22.2", 31 | "moment-timezone": "^0.5.23", 32 | "mysql2": "^1.6.4", 33 | "node-opus": "^0.3.1", 34 | "opusscript": "0.0.6", 35 | "request-promise": "^4.2.4", 36 | "sodium": "^3.0.2", 37 | "uws": "^99.0.0" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /preview/10_rain_prev.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crypto-node/Cryptocurrency-crypto-bot/d44d6c03422eb322faed2ae80f5a3431a48454be/preview/10_rain_prev.jpg -------------------------------------------------------------------------------- /preview/1_admin_commands_prev.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crypto-node/Cryptocurrency-crypto-bot/d44d6c03422eb322faed2ae80f5a3431a48454be/preview/1_admin_commands_prev.jpg -------------------------------------------------------------------------------- /preview/2_bot_commands_prev.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crypto-node/Cryptocurrency-crypto-bot/d44d6c03422eb322faed2ae80f5a3431a48454be/preview/2_bot_commands_prev.jpg -------------------------------------------------------------------------------- /preview/3_balance_prev.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crypto-node/Cryptocurrency-crypto-bot/d44d6c03422eb322faed2ae80f5a3431a48454be/preview/3_balance_prev.jpg -------------------------------------------------------------------------------- /preview/4_deposit_prev.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crypto-node/Cryptocurrency-crypto-bot/d44d6c03422eb322faed2ae80f5a3431a48454be/preview/4_deposit_prev.jpg -------------------------------------------------------------------------------- /preview/5_messages_prev.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crypto-node/Cryptocurrency-crypto-bot/d44d6c03422eb322faed2ae80f5a3431a48454be/preview/5_messages_prev.jpg -------------------------------------------------------------------------------- /preview/6_messages_prev.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crypto-node/Cryptocurrency-crypto-bot/d44d6c03422eb322faed2ae80f5a3431a48454be/preview/6_messages_prev.jpg -------------------------------------------------------------------------------- /preview/6_profile_prev.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crypto-node/Cryptocurrency-crypto-bot/d44d6c03422eb322faed2ae80f5a3431a48454be/preview/6_profile_prev.jpg -------------------------------------------------------------------------------- /preview/7_deposit_prev.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crypto-node/Cryptocurrency-crypto-bot/d44d6c03422eb322faed2ae80f5a3431a48454be/preview/7_deposit_prev.jpg -------------------------------------------------------------------------------- /preview/8_drop_prev.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crypto-node/Cryptocurrency-crypto-bot/d44d6c03422eb322faed2ae80f5a3431a48454be/preview/8_drop_prev.jpg -------------------------------------------------------------------------------- /preview/9_drop_prev.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crypto-node/Cryptocurrency-crypto-bot/d44d6c03422eb322faed2ae80f5a3431a48454be/preview/9_drop_prev.jpg -------------------------------------------------------------------------------- /transaction.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ####################################################################### 4 | # Config file path and name 5 | ####################################################################### 6 | 7 | filepath=$(echo "$0" | grep -o -P '(?<=).*(?=/transaction.sh)') 8 | file="$filepath/config.js" 9 | 10 | ####################################################################### 11 | # Check if transaction string empty 12 | ####################################################################### 13 | 14 | if [[ -z "$1" ]]; then 15 | echo "Error: txid not defined." 16 | exit 0 17 | fi 18 | 19 | ####################################################################### 20 | # Read line by line to grab database connection info 21 | ####################################################################### 22 | 23 | while IFS= read -r line 24 | do 25 | if [[ $line == *"dbHost"* ]]; then 26 | dbhost="$line" 27 | fi 28 | if [[ $line == *"dbName"* ]]; then 29 | dbName="$line" 30 | fi 31 | if [[ $line == *"dbUser"* ]]; then 32 | dbUser="$line" 33 | fi 34 | if [[ $line == *"dbPassword"* ]]; then 35 | dbPassword="$line" 36 | fi 37 | if [[ $line == *"dbPort"* ]]; then 38 | dbPort="$line" 39 | fi 40 | done <"$file" 41 | 42 | ####################################################################### 43 | # Check if any result is empty and exit 44 | ####################################################################### 45 | 46 | if [[ -z "$dbhost" ]]; then 47 | echo "Error: dbhost not defined." 48 | exit 0 49 | fi 50 | if [[ -z "$dbName" ]]; then 51 | echo "Error: dbName not defined." 52 | exit 0 53 | fi 54 | if [[ -z "$dbUser" ]]; then 55 | echo "Error: dbUser not defined." 56 | exit 0 57 | fi 58 | if [[ -z "$dbPassword" ]]; then 59 | echo "Error: dbPassword not defined." 60 | exit 0 61 | fi 62 | if [[ -z "$dbPort" ]]; then 63 | echo "Error: dbPort not defined." 64 | exit 0 65 | fi 66 | 67 | ####################################################################### 68 | # Parse strings 69 | ####################################################################### 70 | 71 | dbhost=$(echo $dbhost | sed 's/^.*dbHost"//' | grep -o -P '(?<=").*(?=")') 72 | dbName=$(echo $dbName | sed 's/^.*dbName"//' | grep -o -P '(?<=").*(?=")') 73 | dbUser=$(echo $dbUser | sed 's/^.*dbUser"//' | grep -o -P '(?<=").*(?=")') 74 | dbPassword=$(echo $dbPassword | sed 's/^.*dbPassword"//' | grep -o -P '(?<=").*(?=")') 75 | dbPort=$(echo "${dbPort//[!0-9]/}") 76 | 77 | ####################################################################### 78 | # Check if any result is empty and exit 79 | ####################################################################### 80 | 81 | if [[ -z "$dbhost" ]]; then 82 | echo "Error: dbhost not defined." 83 | exit 0 84 | fi 85 | if [[ -z "$dbName" ]]; then 86 | echo "Error: dbName not defined." 87 | exit 0 88 | fi 89 | if [[ -z "$dbUser" ]]; then 90 | echo "Error: dbUser not defined." 91 | exit 0 92 | fi 93 | if [[ -z "$dbPassword" ]]; then 94 | echo "Error: dbPassword not defined." 95 | exit 0 96 | fi 97 | if [[ -z "$dbPort" ]]; then 98 | echo "Error: dbPort not defined." 99 | exit 0 100 | fi 101 | 102 | ####################################################################### 103 | # Write transaction to db 104 | ####################################################################### 105 | 106 | mysql --user=$dbUser --password=$dbPassword --host=$dbhost --port=$dbPort $dbName 2>/dev/null << EOF 107 | INSERT INTO transactions (txid) VALUES ("$1"); 108 | EOF 109 | 110 | ####################################################################### 111 | # Success 112 | ####################################################################### 113 | 114 | echo "Transaction received and saved: $1" --------------------------------------------------------------------------------