├── .gitattributes ├── .gitignore ├── .prettierignore ├── .prettierrc.json ├── LICENSE ├── README.md ├── default.avatar.ipfs.js ├── dist ├── Config.js ├── api │ ├── controllers │ │ ├── AffiliateController.js │ │ ├── AuthController.js │ │ ├── BalanceController.js │ │ ├── CoinController.js │ │ ├── DailyContestController.js │ │ ├── FutureBTCChallengeController.js │ │ ├── RewardsController.js │ │ └── UserController.js │ ├── middlewares │ │ ├── Auth.js │ │ ├── CORS.js │ │ ├── Kernel.js │ │ ├── Log.js │ │ ├── Middleware.js │ │ └── Validation.js │ ├── routes │ │ └── ApiRoutes.js │ └── services │ │ ├── AdminService.js │ │ ├── AffiliateService.js │ │ ├── AffiliateStatisticsService.js │ │ ├── BTCChallengePoolService.js │ │ ├── BalanceService.js │ │ ├── DepositService.js │ │ ├── FutureBTCChallengeService.js │ │ ├── NonceService.js │ │ ├── RewardService.js │ │ ├── TradingStatisticsService.js │ │ ├── TransactionService.js │ │ ├── UserService.js │ │ └── WithdrawService.js ├── config │ └── abi.js ├── exception │ └── Handler.js ├── index.js ├── interfaces │ ├── IBtcPrice.js │ ├── IFullStatistics.js │ ├── IHighRoller.js │ ├── IReturnData.js │ ├── IRoundResult.js │ ├── IRoundStatus.js │ ├── ITop100Winner.js │ ├── ITopWinRatio.js │ └── vendors │ │ ├── IError.js │ │ ├── INext.js │ │ ├── IRequest.js │ │ ├── IResponse.js │ │ └── index.js ├── models │ ├── Affiliate.js │ ├── AffiliateStatistics.js │ ├── BTCChallengePool.js │ ├── Balance.js │ ├── FutureBTCChallenge.js │ ├── Nonce.js │ ├── Record.js │ ├── Reward.js │ ├── SecondChallenge.js │ ├── TradingStatistics.js │ ├── Transaction.js │ └── User.js ├── providers │ ├── AblyWss.js │ ├── App.js │ ├── BinanceWss.js │ ├── Bot.js │ ├── Challenges.js │ ├── CoinManager │ │ ├── CoinIds.js │ │ ├── CoinManager.js │ │ ├── Config.js │ │ ├── Interfaces │ │ │ └── ICoinManager.js │ │ └── index.js │ ├── DailyEvent.js │ ├── Dashboard.js │ ├── DynamoDB.js │ ├── EventSchedule.js │ ├── Express.js │ ├── GameRound.js │ ├── GlobalState.js │ ├── Initalilize.js │ ├── Locals.js │ ├── MongoDBConnection.js │ ├── Publisher.js │ ├── Routes.js │ ├── Subscriber.js │ ├── Transaction.js │ └── rTradeSize.js └── utils │ └── utils.js ├── generateTradeSize.js ├── nodemon.json ├── package.json ├── public ├── assets │ ├── BTC-yLU7VgiD.png │ ├── affiliate_bg-MeA4VFI_.png │ ├── avatar_change_img-u3KcwCJV.png │ ├── background-wMyYhUG4.png │ ├── brazil-lKCJYs-D.svg │ ├── btc-MJnHZLpY.mp4 │ ├── btc_bg-_KYdQD9P.png │ ├── btc_name-QUnsET-k.png │ ├── card_gift_box-wATcTPFb.png │ ├── ccip-N7xyI9w3.js │ ├── ccpayment-Y1kGOioT.svg │ ├── coin-dCdECKC9.png │ ├── connect_mobile-arqBuLGa.png │ ├── connect_wallet-xbSjCbTb.svg │ ├── cover_bg-pI2KtuQz.png │ ├── cover_bg1-7kATJlWL.png │ ├── cwallet-9K58mR5C.svg │ ├── down_rocket-YMCp82iP.png │ ├── down_rocket-vVGUiwrl.svg │ ├── earning-2W3ZDEEv.png │ ├── earnings_D-FMs-fqUo.png │ ├── footer_radius-LSth15EO.png │ ├── footer_shadow_m-1HNGAYfZ.png │ ├── header_leftbtn-z1mLer45.svg │ ├── header_rightbtn-MxeEdifh.svg │ ├── index-A6_kHUeh.css │ ├── index-I64FNLPf.js │ ├── index-WqsLIS-d.js │ ├── index-cCjr7MQW.js │ ├── index-d5cPsESa.js │ ├── index.es-XC2Efg4Q.js │ ├── investment-kbVwWCb1.png │ ├── logo-ewbRlvst.png │ ├── money-AWSXWyLD.png │ ├── mx_ex-8mjZwiUH.png │ ├── nav_result-zgRwmMyt.png │ ├── networks-G8MaM_YQ.svg │ ├── pools_img-1f9QQBV4.png │ ├── radius_gradient_light-oL6OsEMZ.png │ ├── rocket_high-7L8ZaxBF.png │ ├── rocket_low-QilBhzmi.png │ ├── star_bg-iGUlcPOw.png │ ├── takelook-NFf4ZQGp.png │ ├── trading_view_img-m0xj7EXZ.png │ ├── up_rocket-i309ZTLu.svg │ ├── up_rocket-sJJ356rf.png │ ├── web3auth-3Qq0V6l-.svg │ └── weibo--hDRqVO2.svg ├── favicon.ico └── index.html ├── src ├── Config.ts ├── api │ ├── controllers │ │ ├── AffiliateController.ts │ │ ├── AuthController.ts │ │ ├── BalanceController.ts │ │ ├── CoinController.ts │ │ ├── DailyContestController.ts │ │ ├── FutureBTCChallengeController.ts │ │ ├── RewardsController.ts │ │ └── UserController.ts │ ├── middlewares │ │ ├── Auth.ts │ │ ├── CORS.ts │ │ ├── Kernel.ts │ │ ├── Log.ts │ │ ├── Middleware.ts │ │ └── Validation.ts │ ├── routes │ │ └── ApiRoutes.ts │ └── services │ │ ├── AdminService.ts │ │ ├── AffiliateService.ts │ │ ├── AffiliateStatisticsService.ts │ │ ├── BTCChallengePoolService.ts │ │ ├── BalanceService.ts │ │ ├── DepositService.ts │ │ ├── FutureBTCChallengeService.ts │ │ ├── NonceService.ts │ │ ├── RewardService.ts │ │ ├── TradingStatisticsService.ts │ │ ├── TransactionService.ts │ │ ├── UserService.ts │ │ └── WithdrawService.ts ├── config │ └── abi.ts ├── exception │ └── Handler.ts ├── index.ts ├── interfaces │ ├── IBtcPrice.ts │ ├── IFullStatistics.ts │ ├── IHighRoller.ts │ ├── IReturnData.ts │ ├── IRoundResult.ts │ ├── IRoundStatus.ts │ ├── ITop100Winner.ts │ ├── ITopWinRatio.ts │ └── vendors │ │ ├── IError.ts │ │ ├── INext.ts │ │ ├── IRequest.ts │ │ ├── IResponse.ts │ │ └── index.ts ├── models │ ├── Affiliate.ts │ ├── AffiliateStatistics.ts │ ├── BTCChallengePool.ts │ ├── Balance.ts │ ├── FutureBTCChallenge.ts │ ├── Nonce.ts │ ├── Record.ts │ ├── Reward.ts │ ├── SecondChallenge.ts │ ├── TradingStatistics.ts │ ├── Transaction.ts │ └── User.ts ├── providers │ ├── AblyWss.ts │ ├── App.ts │ ├── BinanceWss.ts │ ├── Bot.ts │ ├── Challenges.ts │ ├── CoinManager │ │ ├── CoinIds.ts │ │ ├── CoinManager.ts │ │ ├── Config.ts │ │ ├── Interfaces │ │ │ └── ICoinManager.ts │ │ └── index.ts │ ├── DailyEvent.ts │ ├── Dashboard.ts │ ├── DynamoDB.ts │ ├── EventSchedule.ts │ ├── Express.ts │ ├── GameRound.ts │ ├── GlobalState.ts │ ├── Initalilize.ts │ ├── Locals.ts │ ├── MongoDBConnection.ts │ ├── Publisher.ts │ ├── Routes.ts │ ├── Subscriber.ts │ ├── Transaction.ts │ ├── rTradeSize.ts │ └── ssl │ │ ├── ca_bundle.crt │ │ └── certificate.crt └── utils │ └── utils.ts └── tsconfig.json /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | private.key 2 | # Logs 3 | logs 4 | gameState 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | lerna-debug.log* 10 | .pnpm-debug.log* 11 | 12 | 13 | # Diagnostic reports (https://nodejs.org/api/report.html) 14 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 15 | 16 | # Runtime data 17 | pids 18 | *.pid 19 | *.seed 20 | *.pid.lock 21 | 22 | # Directory for instrumented libs generated by jscoverage/JSCover 23 | lib-cov 24 | 25 | # Coverage directory used by tools like istanbul 26 | coverage 27 | *.lcov 28 | 29 | # nyc test coverage 30 | .nyc_output 31 | 32 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 33 | .grunt 34 | 35 | # Bower dependency directory (https://bower.io/) 36 | bower_components 37 | 38 | # node-waf configuration 39 | .lock-wscript 40 | 41 | # Compiled binary addons (https://nodejs.org/api/addons.html) 42 | build/Release 43 | 44 | # Dependency directories 45 | node_modules/ 46 | jspm_packages/ 47 | 48 | # Snowpack dependency directory (https://snowpack.dev/) 49 | web_modules/ 50 | 51 | # TypeScript cache 52 | *.tsbuildinfo 53 | 54 | # Optional npm cache directory 55 | .npm 56 | 57 | # Optional eslint cache 58 | .eslintcache 59 | 60 | # Optional stylelint cache 61 | .stylelintcache 62 | 63 | # Microbundle cache 64 | .rpt2_cache/ 65 | .rts2_cache_cjs/ 66 | .rts2_cache_es/ 67 | .rts2_cache_umd/ 68 | 69 | # Optional REPL history 70 | .node_repl_history 71 | 72 | # Output of 'npm pack' 73 | *.tgz 74 | 75 | # Yarn Integrity file 76 | .yarn-integrity 77 | 78 | # dotenv environment variable files 79 | .env 80 | # frontend/src/config.ts 81 | .env.development.local 82 | .env.test.local 83 | .env.production.local 84 | .env.local 85 | 86 | # parcel-bundler cache (https://parceljs.org/) 87 | .cache 88 | .parcel-cache 89 | 90 | # Next.js build output 91 | .next 92 | out 93 | 94 | # Nuxt.js build / generate output 95 | .nuxt 96 | 97 | # Gatsby files 98 | .cache/ 99 | # Comment in the public line in if your project uses Gatsby and not Next.js 100 | # https://nextjs.org/blog/next-9-1#public-directory-support 101 | # public 102 | 103 | # vuepress build output 104 | .vuepress/dist 105 | 106 | # vuepress v2.x temp and cache directory 107 | .temp 108 | .cache 109 | 110 | # Serverless directories 111 | .serverless/ 112 | 113 | # FuseBox cache 114 | .fusebox/ 115 | 116 | # DynamoDB Local files 117 | .dynamodb/ 118 | 119 | # TernJS port file 120 | .tern-port 121 | 122 | # Stores VSCode versions used for testing VSCode extensions 123 | .vscode-test 124 | 125 | # yarn v2 126 | .yarn/cache 127 | .yarn/unplugged 128 | .yarn/build-state.yml 129 | .yarn/install-state.gz 130 | .pnp.* 131 | 132 | # Local Netlify folder 133 | .netlify 134 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | # Ignore artifacts: 3 | build 4 | coverage -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 4, 4 | "semi": false, 5 | "singleQuote": true 6 | } 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 isomd 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 | # Trade2Earn-Game 2 | Backend for HIxLo Trading Website 3 | 4 | This project is a simple crypto-based P2P Trading Game that gives players and tranders the opportunities to earn rewards based on their ability to analysis the market trends as a new form of Play to Earn by preciting the price of movement of Bitcoin in real-time. 5 | -------------------------------------------------------------------------------- /default.avatar.ipfs.js: -------------------------------------------------------------------------------- 1 | const Moralis = require('moralis').default 2 | const fs = require('fs') 3 | async function uploadToIpfs() { 4 | await Moralis.start({ 5 | apiKey: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJub25jZSI6IjE2NzA3NzQwLWI4OWMtNDNiYi1iMGZiLTkzYzc5NGZhZDM2OSIsIm9yZ0lkIjoiMzcxOTQ2IiwidXNlcklkIjoiMzgyMjUyIiwidHlwZUlkIjoiYTIyNmViOGUtMWJmYS00ODlmLWE0MDItOTYxM2FlZmVhNDdlIiwidHlwZSI6IlBST0pFQ1QiLCJpYXQiOjE3MDUwNzUxNDMsImV4cCI6NDg2MDgzNTE0M30.05MFAoMVUMNNga8sVNpqqHxI0btw76mStLFN05rNyNo', 6 | }) 7 | const uploadArray = [ 8 | { 9 | path: 'boy-0.jpg', 10 | content: fs.readFileSync('./avatar/avatar.zip', { 11 | encoding: 'base64', 12 | }), 13 | }, 14 | // { 15 | // path: 'boy-1.jpg', 16 | // content: fs.readFileSync('./avatar/boy-1.jpg', { 17 | // encoding: 'base64', 18 | // }), 19 | // }, 20 | // { 21 | // path: 'boy-2.jpg', 22 | // content: fs.readFileSync('./avatar/boy-2.jpg', { 23 | // encoding: 'base64', 24 | // }), 25 | // }, 26 | 27 | ] 28 | const response = await Moralis.EvmApi.ipfs.uploadFolder({ 29 | abi: uploadArray, 30 | }, ) 31 | console.log(response.result) 32 | } 33 | uploadToIpfs() 34 | -------------------------------------------------------------------------------- /dist/Config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.default = { 4 | minTradeSize: 5, 5 | maxTradeSize: 100, 6 | minWithdraw: 10, 7 | }; 8 | -------------------------------------------------------------------------------- /dist/api/controllers/AffiliateController.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __importDefault = (this && this.__importDefault) || function (mod) { 12 | return (mod && mod.__esModule) ? mod : { "default": mod }; 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | const Affiliate_1 = require("../../models/Affiliate"); 16 | const AffiliateService_1 = require("../services/AffiliateService"); 17 | const Log_1 = __importDefault(require("../middlewares/Log")); 18 | class AffiliateController { 19 | static createReferralLink(req, res) { 20 | return __awaiter(this, void 0, void 0, function* () { 21 | const { user, name } = req.body; 22 | try { 23 | const { data, success, error } = yield (0, AffiliateService_1.addReferralLink)(user._id, Affiliate_1.AffiliateType.FRIEND_METHOD, name); 24 | if (success) { 25 | return res.status(200).send({ result: true, affiliate: data }); 26 | } 27 | else { 28 | return res.status(500).send({ result: false, error }); 29 | } 30 | } 31 | catch (error) { 32 | Log_1.default.error(`AffiliateController :: Error creating referral link: ${error}`); 33 | return res 34 | .status(500) 35 | .send({ result: false, error: 'Internal Server Error' }); 36 | } 37 | }); 38 | } 39 | static getReferralLinks(req, res) { 40 | return __awaiter(this, void 0, void 0, function* () { 41 | const { user, name } = req.body; 42 | try { 43 | const { data, success, error } = yield (0, AffiliateService_1.getReferralIds)(user._id); 44 | if (success) { 45 | res.send({ result: true, affiliates: data }); 46 | } 47 | else { 48 | res.status(500).send({ result: false, error }); 49 | } 50 | } 51 | catch (error) { 52 | Log_1.default.error(`AffiliateController :: getReferralLinks: ${error}`); 53 | res.status(500).send({ 54 | result: false, 55 | error: 'Internal Server Error', 56 | }); 57 | } 58 | }); 59 | } 60 | } 61 | exports.default = AffiliateController; 62 | -------------------------------------------------------------------------------- /dist/api/controllers/BalanceController.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __importDefault = (this && this.__importDefault) || function (mod) { 12 | return (mod && mod.__esModule) ? mod : { "default": mod }; 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | const Balance_1 = __importDefault(require("../../models/Balance")); 16 | const Log_1 = __importDefault(require("../middlewares/Log")); 17 | class BalanceController { 18 | static getBalance(req, res, next) { 19 | return __awaiter(this, void 0, void 0, function* () { 20 | try { 21 | const { user } = req.body; 22 | // Find the balance document for the specified user ID 23 | const balance = yield Balance_1.default.findOne({ User: user._id }).exec(); 24 | if (!balance) { 25 | return res 26 | .status(404) 27 | .json({ message: 'Balance not found for the user' }); 28 | } 29 | res.status(200).send({ result: true, balance: balance.Balance, coin: balance.Coin }); 30 | } 31 | catch (error) { 32 | Log_1.default.error(`BalanceContgroller:: getBalance() : Error retrieving user balance: ${error}`); 33 | res.status(500).json({ message: 'Internal server error' }); 34 | } 35 | }); 36 | } 37 | } 38 | exports.default = BalanceController; 39 | -------------------------------------------------------------------------------- /dist/api/controllers/DailyContestController.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const GlobalState_1 = require("../../providers/GlobalState"); 4 | class DailyContestController { 5 | static getHighRollers(req, res) { 6 | var _a; 7 | const { user } = req.body; 8 | try { 9 | const now = new Date(); 10 | const end = new Date(now); 11 | end.setUTCHours(0, 0, 0, 0); 12 | end.setDate(end.getDate() + 1); // Move to the next day 13 | // Calculate the initial time left until the end of the contest 14 | const timeLeft = end.getTime() - now.getTime(); 15 | const position = user 16 | ? GlobalState_1.GlobalState.highRollers.filter(x => x.Turnover >= 500).findIndex((hr) => String(hr.UserId) === String(user._id)) 17 | : -1; 18 | const tradingVolume = user ? (((_a = GlobalState_1.GlobalState.highRollers.find(hr => String(hr.UserId) === String(user._id))) === null || _a === void 0 ? void 0 : _a.Turnover) || 0) : 0; 19 | res.status(200).json({ 20 | highRollers: GlobalState_1.GlobalState.highRollers.filter(x => x.Turnover >= 500), 21 | position, 22 | timeLeft, 23 | rewards: GlobalState_1.GlobalState.coinPerRank, 24 | tradingVolume, 25 | }); 26 | } 27 | catch (error) { 28 | console.error('Error fetching high rollers:', error); 29 | res.status(500).json({ error: 'Internal server error' }); 30 | } 31 | } 32 | static getWinRatioPlayers(req, res) { 33 | const { user } = req.body; 34 | try { 35 | const now = new Date(); 36 | const end = new Date(now); 37 | end.setUTCHours(0, 0, 0, 0); 38 | end.setDate(end.getDate() + 1); // Move to the next day 39 | // Calculate the initial time left until the end of the contest 40 | const timeLeft = end.getTime() - now.getTime(); 41 | const position = user 42 | ? GlobalState_1.GlobalState.topWinRatioPlayers.filter(x => x.NumberOfTrades >= 50).findIndex((tr) => String(tr.UserId) === String(user._id)) 43 | : -1; 44 | const detail = user ? GlobalState_1.GlobalState.topWinRatioPlayers.find(tr => String(tr.UserId) === String(user._id)) : null; 45 | res.status(200).json({ 46 | winRatioPlayers: GlobalState_1.GlobalState.topWinRatioPlayers.filter(x => x.NumberOfTrades >= 50), 47 | position, 48 | timeLeft, 49 | rewards: GlobalState_1.GlobalState.coinPerRank, 50 | detail, 51 | }); 52 | } 53 | catch (error) { 54 | console.error('Error fetching high rollers:', error); 55 | res.status(500).json({ error: 'Internal server error' }); 56 | } 57 | } 58 | } 59 | exports.default = DailyContestController; 60 | -------------------------------------------------------------------------------- /dist/api/controllers/RewardsController.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __importDefault = (this && this.__importDefault) || function (mod) { 12 | return (mod && mod.__esModule) ? mod : { "default": mod }; 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | const Reward_1 = __importDefault(require("../../models/Reward")); 16 | const BalanceService_1 = require("../services/BalanceService"); 17 | const mongoose_1 = __importDefault(require("mongoose")); 18 | class RewardsController { 19 | static claim(req, res) { 20 | return __awaiter(this, void 0, void 0, function* () { 21 | const session = yield mongoose_1.default.startSession(); 22 | try { 23 | session.startTransaction(); 24 | const { user, rewardId } = req.body; 25 | // Find the reward by ID and user ID 26 | const reward = yield Reward_1.default.findOne({ _id: rewardId, user: user._id }).session(session); 27 | if (!reward) { 28 | yield session.abortTransaction(); 29 | session.endSession(); 30 | return res.status(404).json({ result: false, message: 'Reward not found or user does not own the reward.' }); 31 | } 32 | // Check if the reward has already been claimed 33 | if (reward.claimed) { 34 | yield session.abortTransaction(); 35 | session.endSession(); 36 | return res.status(400).json({ result: false, message: 'Reward has already been claimed.' }); 37 | } 38 | // Update the reward to mark it as claimed 39 | reward.claimed = true; 40 | yield reward.save(); 41 | // Update user balance 42 | if (reward.currency === "USDT") 43 | yield (0, BalanceService_1.singleUpdateBalance)(user._id, reward.amount, session); 44 | if (reward.currency === "Coin") 45 | yield (0, BalanceService_1.singleUpdateCoin)(user._id, reward.amount, session); 46 | yield session.commitTransaction(); 47 | session.endSession(); 48 | return res.status(200).json({ result: true, message: 'Reward claimed successfully.' }); 49 | } 50 | catch (error) { 51 | console.error('Error claiming reward:', error); 52 | yield session.abortTransaction(); 53 | session.endSession(); 54 | return res.status(500).json({ result: false, message: 'An error occurred while claiming the reward.' }); 55 | } 56 | }); 57 | } 58 | static notifications(req, res) { 59 | return __awaiter(this, void 0, void 0, function* () { 60 | try { 61 | const { user } = req.body; 62 | // Query unclaimed rewards 63 | const unclaimedRewards = yield Reward_1.default.find({ claimed: false, user: user._id }); 64 | // Send the unclaimed rewards as the response 65 | res.json(unclaimedRewards); 66 | } 67 | catch (error) { 68 | // Handle errors 69 | console.error('Error fetching unclaimed rewards:', error); 70 | res.status(500).json({ error: 'Internal Server Error' }); 71 | } 72 | }); 73 | } 74 | } 75 | exports.default = RewardsController; 76 | -------------------------------------------------------------------------------- /dist/api/controllers/UserController.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | Object.defineProperty(exports, "__esModule", { value: true }); 12 | const TransactionService_1 = require("../services/TransactionService"); 13 | class UserController { 14 | static getUserGameHistory(req, res) { 15 | return __awaiter(this, void 0, void 0, function* () { 16 | try { 17 | const { user } = req.body; 18 | const { success, data, error } = yield (0, TransactionService_1.getTransactionsByUser)(user._id, 10); 19 | if (success && data) { 20 | // If transactions are successfully retrieved, send them in the response 21 | return res.status(200).send({ success: true, data: data }); 22 | } 23 | else if (!success && error) { 24 | // If there was an error while retrieving transactions, send an error response 25 | return res.status(500).send({ success: false, error: error }); 26 | } 27 | else { 28 | // If no transactions found, send an empty array 29 | return res.status(200).send({ success: true, data: [] }); 30 | } 31 | } 32 | catch (error) { 33 | // Handle any unexpected errors 34 | console.error('Error in getUserGameHistory:', error); 35 | return res 36 | .status(500) 37 | .send({ success: false, error: 'Internal server error' }); 38 | } 39 | }); 40 | } 41 | } 42 | exports.default = UserController; 43 | -------------------------------------------------------------------------------- /dist/api/middlewares/CORS.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * Enables the CORS 4 | * 5 | * @author Isom D. 6 | */ 7 | var __importDefault = (this && this.__importDefault) || function (mod) { 8 | return (mod && mod.__esModule) ? mod : { "default": mod }; 9 | }; 10 | Object.defineProperty(exports, "__esModule", { value: true }); 11 | const cors_1 = __importDefault(require("cors")); 12 | const Log_1 = __importDefault(require("./Log")); 13 | const Locals_1 = __importDefault(require("../../providers/Locals")); 14 | class CORS { 15 | mount(_express) { 16 | Log_1.default.info("Booting the 'CORS' middleware..."); 17 | const apiPrefix = Locals_1.default.config().apiPrefix; 18 | const corsOptions = { 19 | origin: '*', 20 | methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', 21 | credentials: true, 22 | optionsSuccessStatus: 204, 23 | }; 24 | _express.use(`/${apiPrefix}`, (0, cors_1.default)(corsOptions)); 25 | return _express; 26 | } 27 | } 28 | exports.default = new CORS(); 29 | -------------------------------------------------------------------------------- /dist/api/middlewares/Kernel.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | const CORS_1 = __importDefault(require("./CORS")); 7 | const Middleware_1 = __importDefault(require("./Middleware")); 8 | class Kernel { 9 | static init(_express) { 10 | _express = CORS_1.default.mount(_express); 11 | _express = Middleware_1.default.mount(_express); 12 | return _express; 13 | } 14 | } 15 | exports.default = Kernel; 16 | -------------------------------------------------------------------------------- /dist/api/middlewares/Log.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * Creates & maintains the log 4 | */ 5 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 6 | if (k2 === undefined) k2 = k; 7 | var desc = Object.getOwnPropertyDescriptor(m, k); 8 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 9 | desc = { enumerable: true, get: function() { return m[k]; } }; 10 | } 11 | Object.defineProperty(o, k2, desc); 12 | }) : (function(o, m, k, k2) { 13 | if (k2 === undefined) k2 = k; 14 | o[k2] = m[k]; 15 | })); 16 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 17 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 18 | }) : function(o, v) { 19 | o["default"] = v; 20 | }); 21 | var __importStar = (this && this.__importStar) || function (mod) { 22 | if (mod && mod.__esModule) return mod; 23 | var result = {}; 24 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 25 | __setModuleDefault(result, mod); 26 | return result; 27 | }; 28 | Object.defineProperty(exports, "__esModule", { value: true }); 29 | const fs = __importStar(require("fs")); 30 | const path = __importStar(require("path")); 31 | class Log { 32 | constructor() { 33 | this.today = new Date(); 34 | let _dateString = `${this.today.getFullYear()}-${this.today.getMonth() + 1}-${this.today.getDate()}`; 35 | let _timeString = `${this.today.getHours()}:${this.today.getMinutes()}:${this.today.getSeconds()}`; 36 | this.baseDir = path.join(__dirname, '../../../.logs/'); 37 | this.fileName = `${_dateString}.log`; 38 | this.linePrefix = `[${_dateString} ${_timeString}]`; 39 | } 40 | // Adds INFO prefix string to the log string 41 | info(_string) { 42 | this.addLog('INFO', _string); 43 | } 44 | // Adds WARN prefix string to the log string 45 | warn(_string) { 46 | this.addLog('WARN', _string); 47 | } 48 | // Adds ERROR prefix string to the log string 49 | error(_string) { 50 | // Line break and show the first line 51 | console.log('\x1b[31m%s\x1b[0m', '[ERROR] :: ' + _string.split(/r?\n/)[0]); 52 | this.addLog('ERROR', _string); 53 | } 54 | // Adds the custom prefix string to the log string 55 | custom(_filename, _string) { 56 | this.addLog(_filename, _string); 57 | } 58 | /** 59 | * Creates the file if does not exist, and 60 | * append the log kind & string into the file. 61 | */ 62 | addLog(_kind, _string) { 63 | const _that = this; 64 | _kind = _kind.toUpperCase(); 65 | fs.open(`${_that.baseDir}${_that.fileName}`, 'a', (_err, _fileDescriptor) => { 66 | if (!_err && _fileDescriptor) { 67 | // Append to file and close it 68 | fs.appendFile(_fileDescriptor, `${_that.linePrefix} [${_kind}] ${_string}\n`, (_err) => { 69 | if (!_err) { 70 | fs.close(_fileDescriptor, (_err) => { 71 | if (!_err) { 72 | return true; 73 | } 74 | else { 75 | return console.log('\x1b[31m%s\x1b[0m', 'Error closing log file that was being appended'); 76 | } 77 | }); 78 | } 79 | else { 80 | return console.log('\x1b[31m%s\x1b[0m', 'Error appending to the log file'); 81 | } 82 | }); 83 | } 84 | else { 85 | return console.log('\x1b[31m%s\x1b[0m', "Error cloudn't open the log file for appending"); 86 | } 87 | }); 88 | } 89 | /** 90 | * Deletes the log files older than 'X' days 91 | * 92 | * Note: 'X' is defined in .env file 93 | */ 94 | clean() { 95 | // 96 | } 97 | } 98 | exports.default = new Log(); 99 | -------------------------------------------------------------------------------- /dist/api/middlewares/Middleware.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * Defines all the requisites in HTTP 4 | * 5 | * @author Isom D. 6 | */ 7 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 8 | if (k2 === undefined) k2 = k; 9 | var desc = Object.getOwnPropertyDescriptor(m, k); 10 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 11 | desc = { enumerable: true, get: function() { return m[k]; } }; 12 | } 13 | Object.defineProperty(o, k2, desc); 14 | }) : (function(o, m, k, k2) { 15 | if (k2 === undefined) k2 = k; 16 | o[k2] = m[k]; 17 | })); 18 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 19 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 20 | }) : function(o, v) { 21 | o["default"] = v; 22 | }); 23 | var __importStar = (this && this.__importStar) || function (mod) { 24 | if (mod && mod.__esModule) return mod; 25 | var result = {}; 26 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 27 | __setModuleDefault(result, mod); 28 | return result; 29 | }; 30 | var __importDefault = (this && this.__importDefault) || function (mod) { 31 | return (mod && mod.__esModule) ? mod : { "default": mod }; 32 | }; 33 | Object.defineProperty(exports, "__esModule", { value: true }); 34 | // import flash from 'express-flash'; 35 | const compression_1 = __importDefault(require("compression")); 36 | const bodyParser = __importStar(require("body-parser")); 37 | const Log_1 = __importDefault(require("./Log")); 38 | const Locals_1 = __importDefault(require("../../providers/Locals")); 39 | class Http { 40 | static mount(_express) { 41 | Log_1.default.info("Booting the 'HTTP' middleware..."); 42 | // Enables the request body parser 43 | _express.use(bodyParser.json({ 44 | limit: Locals_1.default.config().maxUploadLimit, 45 | })); 46 | _express.use(bodyParser.urlencoded({ 47 | limit: Locals_1.default.config().maxUploadLimit, 48 | parameterLimit: Locals_1.default.config().maxParameterLimit, 49 | extended: false, 50 | })); 51 | // Disable the x-powered-by header in response 52 | _express.disable('x-powered-by'); 53 | // Enables the CORS 54 | // _express.use(cors()); 55 | // Enables the "gzip" / "deflate" compression for response 56 | _express.use((0, compression_1.default)()); 57 | return _express; 58 | } 59 | } 60 | exports.default = Http; 61 | -------------------------------------------------------------------------------- /dist/api/middlewares/Validation.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.depositValidation = void 0; 4 | const depositValidation = (req, res, next) => { 5 | const { chain } = req.body; 6 | if (!chain) { 7 | return res.status(400).json({ error: 'Chain is required' }); 8 | } 9 | next(); 10 | }; 11 | exports.depositValidation = depositValidation; 12 | -------------------------------------------------------------------------------- /dist/api/services/AdminService.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | const Log_1 = __importDefault(require("../middlewares/Log")); 7 | const BalanceService_1 = require("./BalanceService"); 8 | class AdminService { 9 | static feeTo(fee, userId, session) { 10 | try { 11 | (0, BalanceService_1.singleUpdateBalance)(userId, fee, session); 12 | } 13 | catch (error) { 14 | // Handle errors 15 | Log_1.default.error(`AdminService :: feeTo => Error increasing balance: ${error}`); 16 | throw error; 17 | } 18 | } 19 | } 20 | exports.default = AdminService; 21 | -------------------------------------------------------------------------------- /dist/api/services/AffiliateStatisticsService.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | -------------------------------------------------------------------------------- /dist/api/services/BTCChallengePoolService.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __importDefault = (this && this.__importDefault) || function (mod) { 12 | return (mod && mod.__esModule) ? mod : { "default": mod }; 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | exports.getNextRoundInProgress = exports.getCurrentRoundInProgress = void 0; 16 | const BTCChallengePool_1 = __importDefault(require("../../models/BTCChallengePool")); 17 | // Function to get the current round in progress 18 | const getCurrentRoundInProgress = () => __awaiter(void 0, void 0, void 0, function* () { 19 | try { 20 | // Get the current date and time 21 | const now = new Date(); 22 | // Find the round in progress where StartTime < Now and EndTime > Now 23 | const roundInProgress = yield BTCChallengePool_1.default.findOne({ 24 | StartTime: { $lt: now }, 25 | EndTime: { $gt: now }, 26 | StartPrice: { $gt: 0 }, 27 | EndPrice: { $eq: 0 } 28 | }).exec(); 29 | return roundInProgress; 30 | } 31 | catch (error) { 32 | console.error("Error occurred while getting current round in progress:", error); 33 | return null; 34 | } 35 | }); 36 | exports.getCurrentRoundInProgress = getCurrentRoundInProgress; 37 | const getNextRoundInProgress = () => __awaiter(void 0, void 0, void 0, function* () { 38 | try { 39 | // Get the current date and time 40 | const now = new Date(); 41 | const nextTimeInProgress = new Date(now); 42 | nextTimeInProgress.setUTCDate(now.getUTCDate() + 7); 43 | // nextTimeInProgress.setUTCMinutes(now.getUTCMinutes() + 1); 44 | // nextTimeInProgress.setUTCHours(now.getUTCHours() + 1); 45 | // Find the round in progress where StartTime < Now and EndTime > Now 46 | const nextRoundInProgress = yield BTCChallengePool_1.default.findOne({ 47 | StartTime: { $lt: nextTimeInProgress }, 48 | EndTime: { $gt: nextTimeInProgress }, 49 | StartPrice: { $eq: 0 }, 50 | EndPrice: { $eq: 0 } 51 | }).exec(); 52 | return nextRoundInProgress; 53 | } 54 | catch (error) { 55 | console.error("Error occurred while getting current round in progress:", error); 56 | return null; 57 | } 58 | }); 59 | exports.getNextRoundInProgress = getNextRoundInProgress; 60 | -------------------------------------------------------------------------------- /dist/api/services/BalanceService.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __importDefault = (this && this.__importDefault) || function (mod) { 12 | return (mod && mod.__esModule) ? mod : { "default": mod }; 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | exports.singleUpdateCoin = exports.singleUpdateBalance = exports.batchUpdateBalance = void 0; 16 | const Balance_1 = __importDefault(require("../../models/Balance")); 17 | const Log_1 = __importDefault(require("../middlewares/Log")); 18 | const batchUpdateBalance = (balanceUpdates, session) => __awaiter(void 0, void 0, void 0, function* () { 19 | try { 20 | const bulkOps = balanceUpdates.map((update) => ({ 21 | updateOne: { 22 | filter: { User: update.User }, 23 | update: { $inc: { Balance: update.Amount } }, 24 | }, 25 | })); 26 | yield Balance_1.default.bulkWrite(bulkOps, { session }); 27 | const userIds = balanceUpdates.map((b) => b.User); 28 | const updatedBalances = session 29 | ? yield Balance_1.default.find({ 30 | User: { $in: userIds }, 31 | }) 32 | .session(session) 33 | .exec() 34 | : yield Balance_1.default.find({ 35 | User: { $in: userIds }, 36 | }).exec(); 37 | return { success: true, data: updatedBalances }; 38 | } 39 | catch (error) { 40 | // if(session) { 41 | // await session.abortTransaction() 42 | // session.endSession() 43 | // } 44 | Log_1.default.error(`BalanceService :: BalanceUpdate => Error during bulk write operation: ${error}`); 45 | // return { success: false, error } 46 | throw error; 47 | // Handle the error as needed 48 | } 49 | }); 50 | exports.batchUpdateBalance = batchUpdateBalance; 51 | const singleUpdateBalance = (User, Amount, session) => __awaiter(void 0, void 0, void 0, function* () { 52 | try { 53 | // Find the balance document for the user and update it 54 | const updatedBalance = yield Balance_1.default.findOneAndUpdate({ User }, { $inc: { Balance: Amount } }, { new: true, session }); 55 | // Handle the updated balance if needed 56 | // For example, you can return it or perform additional actions 57 | return { success: true, data: updatedBalance }; 58 | } 59 | catch (error) { 60 | // if (session) { 61 | // await session.abortTransaction() 62 | // session.endSession() 63 | // } 64 | // Handle errors 65 | Log_1.default.error(`BalanceService :: singleUpdateBalance => Error increasing balance: ${error}`); 66 | // return { success: false, error } 67 | throw error; 68 | } 69 | }); 70 | exports.singleUpdateBalance = singleUpdateBalance; 71 | const singleUpdateCoin = (User, Amount, session) => __awaiter(void 0, void 0, void 0, function* () { 72 | try { 73 | // Find the balance document for the user and update it 74 | const updatedBalance = yield Balance_1.default.findOneAndUpdate({ User }, { $inc: { Coin: Amount } }, { new: true, session }); 75 | // Handle the updated balance if needed 76 | // For example, you can return it or perform additional actions 77 | return { success: true, data: updatedBalance }; 78 | } 79 | catch (error) { 80 | // if (session) { 81 | // await session.abortTransaction() 82 | // session.endSession() 83 | // } 84 | // Handle errors 85 | Log_1.default.error(`BalanceService :: singleUpdateBalance => Error increasing balance: ${error}`); 86 | // return { success: false, error } 87 | throw error; 88 | } 89 | }); 90 | exports.singleUpdateCoin = singleUpdateCoin; 91 | -------------------------------------------------------------------------------- /dist/api/services/FutureBTCChallengeService.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | -------------------------------------------------------------------------------- /dist/api/services/NonceService.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __importDefault = (this && this.__importDefault) || function (mod) { 12 | return (mod && mod.__esModule) ? mod : { "default": mod }; 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | exports.getNonce = exports.addNonce = void 0; 16 | const Log_1 = __importDefault(require("../middlewares/Log")); 17 | const Nonce_1 = __importDefault(require("../../models/Nonce")); 18 | const addNonce = (address, nonce) => __awaiter(void 0, void 0, void 0, function* () { 19 | try { 20 | const existingItem = yield Nonce_1.default.findOne({ address }); 21 | if (existingItem) { 22 | // Address exists, update the nonce field 23 | existingItem.nonce = nonce; 24 | yield existingItem.save(); 25 | } 26 | else { 27 | // Address does not exist, add a new item 28 | yield Nonce_1.default.create({ address, nonce }); 29 | } 30 | return { success: true }; 31 | } 32 | catch (error) { 33 | Log_1.default.error(`NonceService :: Error adding nonce: ${error}`); 34 | return { success: false }; 35 | } 36 | }); 37 | exports.addNonce = addNonce; 38 | const getNonce = (address) => __awaiter(void 0, void 0, void 0, function* () { 39 | try { 40 | const item = yield Nonce_1.default.findOne({ address }).select('nonce'); 41 | if (item) { 42 | return { success: true, data: item }; 43 | } 44 | else { 45 | return { success: false, error: 'Not exist' }; 46 | } 47 | } 48 | catch (error) { 49 | Log_1.default.error(`NonceService :: Error getting nonce: ${error}`); 50 | return { success: false }; 51 | } 52 | }); 53 | exports.getNonce = getNonce; 54 | -------------------------------------------------------------------------------- /dist/api/services/RewardService.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __importDefault = (this && this.__importDefault) || function (mod) { 12 | return (mod && mod.__esModule) ? mod : { "default": mod }; 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | exports.getUnclaimedRewards = exports.insertRewards = void 0; 16 | const Reward_1 = __importDefault(require("../../models/Reward")); 17 | const Log_1 = __importDefault(require("../middlewares/Log")); 18 | const insertRewards = (rewards, session) => __awaiter(void 0, void 0, void 0, function* () { 19 | try { 20 | const options = {}; 21 | if (session) { 22 | options.session = session; 23 | } 24 | const insertedRewards = yield Reward_1.default.insertMany(rewards, options); 25 | return insertedRewards; 26 | } 27 | catch (error) { 28 | Log_1.default.error(`RewardService :: Error adding batch rewards: ${error}`); 29 | throw error; 30 | } 31 | }); 32 | exports.insertRewards = insertRewards; 33 | function getUnclaimedRewards() { 34 | return __awaiter(this, void 0, void 0, function* () { 35 | try { 36 | // Query to find rewards where claimed is false 37 | const unclaimedRewards = yield Reward_1.default.find({ claimed: false }); 38 | return unclaimedRewards; 39 | } 40 | catch (error) { 41 | // Handle error 42 | console.error('Error fetching unclaimed rewards:', error); 43 | throw error; 44 | } 45 | }); 46 | } 47 | exports.getUnclaimedRewards = getUnclaimedRewards; 48 | -------------------------------------------------------------------------------- /dist/api/services/WithdrawService.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __importDefault = (this && this.__importDefault) || function (mod) { 12 | return (mod && mod.__esModule) ? mod : { "default": mod }; 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | exports.withdrawRecord = exports.RecordType = void 0; 16 | const mongoose_1 = __importDefault(require("mongoose")); 17 | const Record_1 = __importDefault(require("../../models/Record")); 18 | const Log_1 = __importDefault(require("../middlewares/Log")); 19 | var RecordType; 20 | (function (RecordType) { 21 | RecordType["DEPOSIT"] = "deposit"; 22 | RecordType["WITHDRAW"] = "withdraw"; 23 | })(RecordType || (exports.RecordType = RecordType = {})); 24 | function withdrawRecord(withdraw) { 25 | return __awaiter(this, void 0, void 0, function* () { 26 | try { 27 | // Check if a record with the same recordId exists 28 | const existingRecord = yield Record_1.default.findOne({ 29 | recordId: withdraw.recordId, 30 | }); 31 | if (existingRecord) { 32 | if (existingRecord.status === withdraw.status) { 33 | return { success: true }; 34 | } 35 | // If a record with the same recordId exists, update it 36 | existingRecord.status = withdraw.status; 37 | existingRecord.txId = withdraw.txId; 38 | // Save the updated record to the database 39 | const savedRecord = yield existingRecord.save(); 40 | return { success: true, data: savedRecord }; 41 | } 42 | else { 43 | // If no record with the same recordId exists, create a new one 44 | const newRecord = new Record_1.default({ 45 | recordId: withdraw.recordId, 46 | userId: new mongoose_1.default.Types.ObjectId(withdraw.userId), 47 | coinId: withdraw.coinId, 48 | status: withdraw.status, 49 | chain: withdraw.chain, 50 | amount: Number(withdraw.amount), 51 | txId: withdraw.txId, 52 | toAddress: withdraw.toAddress, 53 | fromAddress: withdraw.fromAddress, 54 | type: RecordType.WITHDRAW, 55 | accepted: true, 56 | }); 57 | // Save the new record to the database 58 | const savedRecord = yield newRecord.save(); 59 | // Return the newly created record 60 | return { success: true, data: savedRecord }; 61 | } 62 | } 63 | catch (error) { 64 | Log_1.default.error(`WithdrawService :: withdrawRecord: ${error}`); 65 | return { success: false, error }; 66 | } 67 | }); 68 | } 69 | exports.withdrawRecord = withdrawRecord; 70 | -------------------------------------------------------------------------------- /dist/exception/Handler.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * Define the error & exception handlers 4 | * Author: Isom D. 5 | */ 6 | var __importDefault = (this && this.__importDefault) || function (mod) { 7 | return (mod && mod.__esModule) ? mod : { "default": mod }; 8 | }; 9 | Object.defineProperty(exports, "__esModule", { value: true }); 10 | const Locals_1 = __importDefault(require("../providers/Locals")); 11 | const Log_1 = __importDefault(require("../api/middlewares/Log")); 12 | // Class responsible for handling errors and exceptions 13 | class ExceptionHandler { 14 | /** 15 | * Handles all the not found routes 16 | */ 17 | static notFoundHandler(_express) { 18 | const apiPrefix = Locals_1.default.config().apiPrefix; 19 | _express.use('*', (req, res) => { 20 | const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; 21 | Log_1.default.error(`Path '${req.originalUrl}' not found [IP: '${ip}']!`); 22 | if (req.xhr || req.originalUrl.includes(`/${apiPrefix}/`)) { 23 | return res.json({ error: 'Page Not Found' }); 24 | } 25 | else { 26 | res.status(404); 27 | return res.render('pages/error', { 28 | title: 'Page Not Found', 29 | error: [], 30 | }); 31 | } 32 | }); 33 | return _express; 34 | } 35 | /** 36 | * Handles your api/web routes errors/exception 37 | */ 38 | static clientErrorHandler(err, req, res, next) { 39 | Log_1.default.error(err.stack ? err.stack : ''); 40 | if (req.xhr) { 41 | return res.status(500).send({ error: 'Something went wrong!' }); 42 | } 43 | else { 44 | return next(err); 45 | } 46 | } 47 | /** 48 | * Show under maintenance page in case of errors 49 | */ 50 | static errorHandler(err, req, res, next) { 51 | Log_1.default.error(err.stack ? err.stack : ''); 52 | res.status(500); 53 | const apiPrefix = Locals_1.default.config().apiPrefix; 54 | if (req.originalUrl.includes(`/${apiPrefix}/`)) { 55 | if (err.name && err.name === 'UnauthorizedError') { 56 | const innerMessage = err.message ? err.message : undefined; 57 | return res.json({ error: ['Invalid Token!', innerMessage] }); 58 | } 59 | return res.json({ error: err }); 60 | } 61 | return res.render('pages/error', { 62 | error: err.stack, 63 | title: 'Under Maintenance', 64 | }); 65 | } 66 | /** 67 | * Register your error / exception monitoring tools right here ie. before "next(err)"! 68 | */ 69 | static logErrors(err, req, res, next) { 70 | Log_1.default.error(err.stack ? err.stack : ''); 71 | return next(err); 72 | } 73 | } 74 | // Export the ExceptionHandler class 75 | exports.default = ExceptionHandler; 76 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | // Import the App class from './providers/App' 7 | const App_1 = __importDefault(require("./providers/App")); 8 | // import "./providers/Challenges" 9 | // Call the loadServer method of the App class 10 | App_1.default.loadServer(); 11 | -------------------------------------------------------------------------------- /dist/interfaces/IBtcPrice.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /dist/interfaces/IFullStatistics.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /dist/interfaces/IHighRoller.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /dist/interfaces/IReturnData.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /dist/interfaces/IRoundResult.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /dist/interfaces/IRoundStatus.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.RoundPosition = void 0; 4 | var RoundPosition; 5 | (function (RoundPosition) { 6 | RoundPosition[RoundPosition["NONE"] = 0] = "NONE"; 7 | RoundPosition[RoundPosition["LOCKING"] = 1] = "LOCKING"; 8 | RoundPosition[RoundPosition["LOCKED"] = 2] = "LOCKED"; 9 | RoundPosition[RoundPosition["DISTRIBUTING"] = 3] = "DISTRIBUTING"; 10 | RoundPosition[RoundPosition["DISTRIBUTED"] = 4] = "DISTRIBUTED"; 11 | })(RoundPosition || (exports.RoundPosition = RoundPosition = {})); 12 | -------------------------------------------------------------------------------- /dist/interfaces/ITop100Winner.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /dist/interfaces/ITopWinRatio.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /dist/interfaces/vendors/IError.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /dist/interfaces/vendors/INext.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * Defines Custom method types over Express's NextFunction 4 | * 5 | * @author Faiz A. Farooqui 6 | */ 7 | Object.defineProperty(exports, "__esModule", { value: true }); 8 | -------------------------------------------------------------------------------- /dist/interfaces/vendors/IRequest.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * Defines Custom method types over Express's Request 4 | * 5 | * @author Faiz A. Farooqui 6 | */ 7 | Object.defineProperty(exports, "__esModule", { value: true }); 8 | -------------------------------------------------------------------------------- /dist/interfaces/vendors/IResponse.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * Defines Custom method types over Express's Response 4 | * 5 | * @author Faiz A. Farooqui 6 | */ 7 | Object.defineProperty(exports, "__esModule", { value: true }); 8 | -------------------------------------------------------------------------------- /dist/interfaces/vendors/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * Contains all your vendors' types definition 4 | * 5 | * @author Isom D. 6 | */ 7 | Object.defineProperty(exports, "__esModule", { value: true }); 8 | -------------------------------------------------------------------------------- /dist/models/Affiliate.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | Object.defineProperty(exports, "__esModule", { value: true }); 26 | exports.AffiliateType = void 0; 27 | var AffiliateType; 28 | (function (AffiliateType) { 29 | AffiliateType["FRIEND_METHOD"] = "FRIEND_METHOD"; 30 | AffiliateType["PARTNERSHIP"] = "PARTNERSHIP"; 31 | })(AffiliateType || (exports.AffiliateType = AffiliateType = {})); 32 | const mongoose_1 = __importStar(require("mongoose")); 33 | const affiliateSchema = new mongoose_1.Schema({ 34 | AffiliateType: { 35 | type: String, 36 | required: true, 37 | }, 38 | ReferralId: { 39 | type: String, 40 | required: true, 41 | unique: true, 42 | index: true, 43 | }, 44 | Name: { 45 | type: String, 46 | required: true, 47 | }, 48 | Tier1Paid: { 49 | type: Number, 50 | default: 0, 51 | }, 52 | Tier2Paid: { 53 | type: Number, 54 | default: 0, 55 | }, 56 | Tier3Paid: { 57 | type: Number, 58 | default: 0, 59 | }, 60 | Tier1Unclaimed: { 61 | type: Number, 62 | default: 0, 63 | index: true, 64 | }, 65 | Tier2Unclaimed: { 66 | type: Number, 67 | index: true, 68 | default: 0, 69 | }, 70 | Tier3Unclaimed: { 71 | type: Number, 72 | default: 0, 73 | index: true, 74 | }, 75 | CreatedAt: { 76 | type: Date, 77 | default: Date.now, 78 | }, 79 | User: { 80 | type: mongoose_1.Schema.Types.ObjectId, 81 | ref: 'User', 82 | index: true 83 | }, 84 | }); 85 | exports.default = mongoose_1.default.model('Affiliate', affiliateSchema); 86 | -------------------------------------------------------------------------------- /dist/models/AffiliateStatistics.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | Object.defineProperty(exports, "__esModule", { value: true }); 26 | const mongoose_1 = __importStar(require("mongoose")); 27 | const AffiliateStatisticsSchema = new mongoose_1.Schema({ 28 | Address: { type: String, required: true }, 29 | AllTime: { 30 | Tier1Paid: { type: Number, default: 0 }, 31 | Tier2Paid: { type: Number, default: 0 }, 32 | Tier3Paid: { type: Number, default: 0 }, 33 | TotalPaid: { type: Number, default: 0 }, 34 | }, 35 | ThisMonth: { 36 | Tier1Paid: { type: Number, default: 0 }, 37 | Tier2Paid: { type: Number, default: 0 }, 38 | Tier3Paid: { type: Number, default: 0 }, 39 | TotalPaid: { type: Number, default: 0 }, 40 | }, 41 | ThisWeek: { 42 | Tier1Paid: { type: Number, default: 0 }, 43 | Tier2Paid: { type: Number, default: 0 }, 44 | Tier3Paid: { type: Number, default: 0 }, 45 | TotalPaid: { type: Number, default: 0 }, 46 | }, 47 | Yesterday: { 48 | Tier1Paid: { type: Number, default: 0 }, 49 | Tier2Paid: { type: Number, default: 0 }, 50 | Tier3Paid: { type: Number, default: 0 }, 51 | TotalPaid: { type: Number, default: 0 }, 52 | }, 53 | Today: { 54 | Tier1Paid: { type: Number, default: 0 }, 55 | Tier2Paid: { type: Number, default: 0 }, 56 | Tier3Paid: { type: Number, default: 0 }, 57 | TotalPaid: { type: Number, default: 0 }, 58 | }, 59 | }); 60 | exports.default = mongoose_1.default.model('AffiliateStatistics', AffiliateStatisticsSchema); 61 | -------------------------------------------------------------------------------- /dist/models/BTCChallengePool.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const mongoose_1 = require("mongoose"); 4 | ; 5 | const btcChallengePoolSchema = new mongoose_1.Schema({ 6 | StartTime: { type: Date, required: true }, 7 | EndTime: { type: Date, required: true }, 8 | StartPrice: { type: Number, required: true, default: 0 }, 9 | EndPrice: { type: Number, required: true, default: 0 }, 10 | NextId: { type: mongoose_1.Schema.Types.ObjectId, ref: 'BTCChallengePool' }, 11 | PrevId: { type: mongoose_1.Schema.Types.ObjectId, ref: 'BTCChallengePool' }, 12 | Prize: { type: Number, required: true, default: 0 } 13 | }); 14 | const BTCChallengePool = (0, mongoose_1.model)('BTCChallengePool', btcChallengePoolSchema); 15 | exports.default = BTCChallengePool; 16 | -------------------------------------------------------------------------------- /dist/models/Balance.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const mongoose_1 = require("mongoose"); 4 | const balanceSchema = new mongoose_1.Schema({ 5 | Balance: { 6 | type: Number, 7 | default: 0, 8 | require: true, 9 | index: true, 10 | }, 11 | Coin: { 12 | type: Number, 13 | default: 0, 14 | require: true, 15 | index: true, 16 | }, 17 | User: { 18 | type: mongoose_1.Schema.Types.ObjectId, 19 | ref: 'User', // Reference to the User model 20 | index: true 21 | }, 22 | }); 23 | exports.default = (0, mongoose_1.model)('Balance', balanceSchema); 24 | -------------------------------------------------------------------------------- /dist/models/FutureBTCChallenge.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const mongoose_1 = require("mongoose"); 4 | const futureBTCChallengeSchema = new mongoose_1.Schema({ 5 | User: { type: mongoose_1.Schema.Types.ObjectId, ref: 'User', required: true }, 6 | Position: { type: Number, required: true }, 7 | BTCChallengePool: { type: mongoose_1.Schema.Types.ObjectId, ref: 'BTCChallengePool', required: true }, 8 | Place: { type: Number }, 9 | Reward: { type: Number } 10 | }); 11 | const FutureBTCChallenge = (0, mongoose_1.model)('FutureBTCChallenge', futureBTCChallengeSchema); 12 | exports.default = FutureBTCChallenge; 13 | -------------------------------------------------------------------------------- /dist/models/Nonce.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | Object.defineProperty(exports, "__esModule", { value: true }); 26 | const mongoose_1 = __importStar(require("mongoose")); 27 | const NonceSchema = new mongoose_1.Schema({ 28 | address: { 29 | type: String, 30 | required: true, 31 | unique: true, 32 | }, 33 | nonce: { 34 | type: String, 35 | required: true, 36 | }, 37 | createdAt: { 38 | type: Date, 39 | default: Date.now, 40 | }, 41 | }); 42 | exports.default = mongoose_1.default.model('Nonce', NonceSchema); 43 | -------------------------------------------------------------------------------- /dist/models/Record.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | Object.defineProperty(exports, "__esModule", { value: true }); 26 | const mongoose_1 = __importStar(require("mongoose")); 27 | // Define schema for the Record document 28 | const recordSchema = new mongoose_1.Schema({ 29 | recordId: { type: String, unique: true, index: true }, 30 | userId: { type: mongoose_1.default.Types.ObjectId, ref: 'User', index: true }, 31 | coinId: { type: Number }, 32 | createdAt: { type: Date, default: Date.now }, 33 | status: { type: String }, 34 | chain: { type: String }, 35 | amount: { type: Number }, 36 | txId: { type: String, unique: true }, 37 | toAddress: { type: String }, 38 | fromAddress: { type: String }, 39 | type: { type: String }, 40 | accepted: { type: Boolean, default: false }, 41 | }); 42 | // Create and export the Record model 43 | const Record = mongoose_1.default.model('Record', recordSchema); 44 | exports.default = Record; 45 | -------------------------------------------------------------------------------- /dist/models/Reward.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | Object.defineProperty(exports, "__esModule", { value: true }); 26 | const mongoose_1 = __importStar(require("mongoose")); 27 | const RewardSchema = new mongoose_1.Schema({ 28 | user: { type: mongoose_1.Schema.Types.ObjectId, ref: 'User', required: true, index: true }, 29 | amount: { type: Number, required: true }, 30 | currency: { type: String, require: true, enum: ['USDT', 'Coin'], }, 31 | description: { type: String, required: true }, 32 | claimed: { type: Boolean, default: false }, 33 | CreatedAt: { 34 | type: Date, 35 | default: Date.now, 36 | }, 37 | }); 38 | exports.default = mongoose_1.default.model('Reward', RewardSchema); 39 | -------------------------------------------------------------------------------- /dist/models/SecondChallenge.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const mongoose_1 = require("mongoose"); 4 | const secondChallengeSchema = new mongoose_1.Schema({ 5 | User: { type: mongoose_1.Schema.Types.ObjectId, ref: 'User', required: true }, 6 | Direction: { type: Boolean, required: true }, 7 | BTCChallengePool: { type: mongoose_1.Schema.Types.ObjectId, ref: 'BTCChallengePool', required: true }, 8 | Result: { type: Boolean }, 9 | Reward: { type: Number } 10 | }); 11 | const SecondChallenge = (0, mongoose_1.model)('SecondChallenge', secondChallengeSchema); 12 | exports.default = SecondChallenge; 13 | -------------------------------------------------------------------------------- /dist/models/Transaction.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | Object.defineProperty(exports, "__esModule", { value: true }); 26 | const mongoose_1 = __importStar(require("mongoose")); 27 | const TransactionSchema = new mongoose_1.Schema({ 28 | TradeSize: { type: Number, required: true }, 29 | Direction: { type: Boolean, required: true }, 30 | Result: { type: Boolean, required: true }, 31 | CreatedAt: { type: Date, required: true, default: Date.now }, 32 | PoolId: { type: String, required: true }, 33 | RoundId: { type: String, require: true }, 34 | User: { type: mongoose_1.Schema.Types.ObjectId, ref: 'User', index: true }, 35 | }); 36 | exports.default = mongoose_1.default.model('Transaction', TransactionSchema); 37 | -------------------------------------------------------------------------------- /dist/models/User.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | Object.defineProperty(exports, "__esModule", { value: true }); 26 | const mongoose_1 = __importStar(require("mongoose")); 27 | const userSchema = new mongoose_1.Schema({ 28 | Address: { 29 | type: String, 30 | required: true, 31 | unique: true, 32 | }, 33 | Username: String, 34 | Email: String, 35 | Avatar: String, 36 | InvitedPath: { 37 | type: String, 38 | required: true, 39 | }, 40 | CountryCode: { 41 | type: String, 42 | required: true, 43 | }, 44 | WhiteLabel: String, 45 | Enabled: { 46 | type: Boolean, 47 | default: true, 48 | }, 49 | WalletProvider: { 50 | type: String, 51 | required: true, 52 | }, 53 | CreatedAt: { 54 | type: Date, 55 | default: Date.now, 56 | }, 57 | Role: { 58 | type: String, 59 | enum: [ 60 | 'admin', 61 | 'user', 62 | 'jackpot_weekly', 63 | 'jackpot_monthly', 64 | 'daily_contest', 65 | ], 66 | default: 'user', 67 | }, 68 | }); 69 | exports.default = mongoose_1.default.model('User', userSchema); 70 | -------------------------------------------------------------------------------- /dist/providers/AblyWss.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __importDefault = (this && this.__importDefault) || function (mod) { 12 | return (mod && mod.__esModule) ? mod : { "default": mod }; 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | const ably_1 = __importDefault(require("ably")); 16 | const Locals_1 = __importDefault(require("./Locals")); 17 | const Log_1 = __importDefault(require("../api/middlewares/Log")); 18 | class AblyWss { 19 | constructor() { 20 | this.ablyPublishApiKey = Locals_1.default.config().ablyPublishApiKey; 21 | this.ablyChannelName = Locals_1.default.config().ablyChannelName; 22 | this.ably = new ably_1.default.Realtime.Promise(this.ablyPublishApiKey); 23 | } 24 | init() { 25 | return __awaiter(this, void 0, void 0, function* () { 26 | yield this.ably.connection.once('connected'); 27 | Log_1.default.info('Ably :: Connected!'); 28 | return this.ably.channels.get(this.ablyChannelName); 29 | }); 30 | } 31 | } 32 | exports.default = new AblyWss(); 33 | -------------------------------------------------------------------------------- /dist/providers/App.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __importDefault = (this && this.__importDefault) || function (mod) { 12 | return (mod && mod.__esModule) ? mod : { "default": mod }; 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | const Express_1 = __importDefault(require("./Express")); 16 | const GameRound_1 = __importDefault(require("./GameRound")); 17 | const Publisher_1 = __importDefault(require("./Publisher")); 18 | const Subscriber_1 = __importDefault(require("./Subscriber")); 19 | const Locals_1 = __importDefault(require("./Locals")); 20 | const MongoDBConnection_1 = __importDefault(require("./MongoDBConnection")); 21 | const EventSchedule_1 = require("./EventSchedule"); 22 | const Dashboard_1 = require("./Dashboard"); 23 | const Log_1 = __importDefault(require("../api/middlewares/Log")); 24 | const GlobalState_1 = require("./GlobalState"); 25 | const Initalilize_1 = require("./Initalilize"); 26 | class App { 27 | // Loads your Server 28 | loadServer() { 29 | return __awaiter(this, void 0, void 0, function* () { 30 | Log_1.default.info('Server:: Initialzing...'); 31 | Express_1.default.init(); 32 | // Create an instance of MongoDBConnection with the MongoDB URI 33 | const mongoConnection = MongoDBConnection_1.default.createInstance(Locals_1.default.config().mongodbURI); 34 | // Connect to MongoDB 35 | yield mongoConnection.connectToMongoDB(); 36 | console.log("Connected to mongodb successfully!"); 37 | // Initialize 38 | yield (0, Initalilize_1.initialize)(); 39 | // Start Schedule Events 40 | EventSchedule_1.EventSchedule.createInstance().start(); 41 | Dashboard_1.Dashboard.loadAllTimeWinsPaidFile(); 42 | require("./Challenges"); 43 | require("./DailyEvent"); 44 | const publisher = Publisher_1.default.createInstance(Express_1.default.server); 45 | const subscriber = Subscriber_1.default.createInstance(Locals_1.default.config().binanceWss); 46 | GlobalState_1.GlobalState.gameRound = GameRound_1.default.createInstance(publisher, subscriber); 47 | GlobalState_1.GlobalState.gameRound.start(); 48 | }); 49 | } 50 | } 51 | exports.default = new App(); 52 | -------------------------------------------------------------------------------- /dist/providers/BinanceWss.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | const ws_1 = require("ws"); 7 | const Locals_1 = __importDefault(require("./Locals")); 8 | class BinanceWss { 9 | constructor() { 10 | this.lastPrice = 0; 11 | this.binanceUrl = Locals_1.default.config().binanceWss; 12 | this.binanceWss = new ws_1.WebSocket(this.binanceUrl); 13 | } 14 | init() { 15 | this.binanceWss.on('message', (message) => { 16 | const data = JSON.parse(message); 17 | const lastPrice = parseFloat(data.p); 18 | this.lastPrice = lastPrice > 0 ? lastPrice : this.lastPrice; 19 | }); 20 | } 21 | } 22 | exports.default = BinanceWss; 23 | -------------------------------------------------------------------------------- /dist/providers/CoinManager/Interfaces/ICoinManager.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.OrderStatus = exports.WebHookMessageType = void 0; 4 | var WebHookMessageType; 5 | (function (WebHookMessageType) { 6 | WebHookMessageType["USER_DEPOSIT"] = "UserDeposit"; 7 | WebHookMessageType["USER_WITHDRAWAL"] = "UserWithdrawal"; 8 | })(WebHookMessageType || (exports.WebHookMessageType = WebHookMessageType = {})); 9 | var OrderStatus; 10 | (function (OrderStatus) { 11 | OrderStatus["SUCCESS"] = "Success"; 12 | OrderStatus["PROCESSING"] = "Processing"; 13 | OrderStatus["FAILED"] = "Failed"; 14 | OrderStatus["WAITING_APPROVAL"] = "WaitingApproval"; 15 | OrderStatus["SUBMITTED"] = "Submitted"; 16 | })(OrderStatus || (exports.OrderStatus = OrderStatus = {})); 17 | -------------------------------------------------------------------------------- /dist/providers/CoinManager/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | const CoinManager_1 = __importDefault(require("./CoinManager")); 7 | const coinManager = new CoinManager_1.default(); 8 | -------------------------------------------------------------------------------- /dist/providers/DynamoDB.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.DynamoDBConnection = void 0; 4 | const client_dynamodb_1 = require("@aws-sdk/client-dynamodb"); 5 | class DynamoDBConnection { 6 | } 7 | exports.DynamoDBConnection = DynamoDBConnection; 8 | DynamoDBConnection.client = new client_dynamodb_1.DynamoDBClient({ 9 | region: 'local', 10 | endpoint: 'http://localhost:8000', 11 | }); 12 | -------------------------------------------------------------------------------- /dist/providers/EventSchedule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __importDefault = (this && this.__importDefault) || function (mod) { 12 | return (mod && mod.__esModule) ? mod : { "default": mod }; 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | exports.EventSchedule = void 0; 16 | const GlobalState_1 = require("./GlobalState"); 17 | const TransactionService_1 = require("../api/services/TransactionService"); 18 | const TradingStatisticsService_1 = require("../api/services/TradingStatisticsService"); 19 | const Balance_1 = __importDefault(require("../models/Balance")); 20 | class EventSchedule { 21 | fullStatistics() { 22 | var _a; 23 | return __awaiter(this, void 0, void 0, function* () { 24 | const { success, data, error } = yield (0, TransactionService_1.getFullStatistics)(); 25 | if (success && data) { 26 | GlobalState_1.GlobalState.livePlayersFor24H = data.LivePlayersFor24H; 27 | GlobalState_1.GlobalState.winRatioFor24H = data.WinRatioFor24H; 28 | GlobalState_1.GlobalState.winsPaidFor24H = data.WinsPaidFor24H; 29 | } 30 | // console.log("Jackpot Address: ", this.jackpotAddress); 31 | GlobalState_1.GlobalState.contestPrize = 32 | ((_a = (yield Balance_1.default.findOne({ User: GlobalState_1.GlobalState.weeklyChallengeUser._id }))) === null || _a === void 0 ? void 0 : _a.Balance) || 0; 33 | GlobalState_1.GlobalState.highRollers = yield (0, TradingStatisticsService_1.getHighRollersForToday)(); 34 | GlobalState_1.GlobalState.top100WinnersForToday = yield (0, TradingStatisticsService_1.getTop100WinnersForToday)(); 35 | GlobalState_1.GlobalState.topWinRatioPlayers = yield (0, TradingStatisticsService_1.getTopWinRatioPlayers)(); 36 | }); 37 | } 38 | runFullStatisticsSchedule() { 39 | this.fullStatistics(); 40 | setInterval(this.fullStatistics, 1 * 60 * 1000); 41 | } 42 | // start schedule 43 | start() { 44 | this.runFullStatisticsSchedule(); 45 | } 46 | // create instance 47 | static createInstance() { 48 | return new EventSchedule(); 49 | } 50 | } 51 | exports.EventSchedule = EventSchedule; 52 | -------------------------------------------------------------------------------- /dist/providers/Express.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * Represents the Express server configuration and initialization. 4 | * Author: Isom D. 5 | */ 6 | var __importDefault = (this && this.__importDefault) || function (mod) { 7 | return (mod && mod.__esModule) ? mod : { "default": mod }; 8 | }; 9 | Object.defineProperty(exports, "__esModule", { value: true }); 10 | const express_1 = __importDefault(require("express")); 11 | const Locals_1 = __importDefault(require("./Locals")); 12 | const Handler_1 = __importDefault(require("../exception/Handler")); 13 | const Routes_1 = __importDefault(require("./Routes")); 14 | const http_1 = __importDefault(require("http")); 15 | const Kernel_1 = __importDefault(require("../api/middlewares/Kernel")); 16 | const Log_1 = __importDefault(require("../api/middlewares/Log")); 17 | const path_1 = __importDefault(require("path")); 18 | class Express { 19 | /** 20 | * Initializes the Express server with middleware and routes. 21 | */ 22 | constructor() { 23 | this.express = (0, express_1.default)(); 24 | // const privateKeyPath = path.join("src/providers/ssl", "private.key"); 25 | // const certPath = path.join("src/providers/ssl", "certificate.crt"); 26 | // this.server = Https.createServer({ // Create HTTPS server 27 | // key: fs.readFileSync(privateKeyPath), 28 | // cert: fs.readFileSync(certPath) 29 | // }, this.express); 30 | this.server = http_1.default.createServer(this.express); 31 | this.mountDotEnv(); 32 | this.mountMiddlewares(); 33 | this.mountRoutes(); 34 | } 35 | /** 36 | * Mounts environment variables. 37 | */ 38 | mountDotEnv() { 39 | this.express = Locals_1.default.init(this.express); 40 | } 41 | /** 42 | * Mounts middleware to the Express app. 43 | */ 44 | mountMiddlewares() { 45 | this.express = Kernel_1.default.init(this.express); 46 | } 47 | /** 48 | * Mounts API routes to the Express app. 49 | */ 50 | mountRoutes() { 51 | this.express = Routes_1.default.mountApi(this.express); 52 | } 53 | /** 54 | * Initializes the Express server and starts listening on the configured port. 55 | */ 56 | init() { 57 | const port = Locals_1.default.config().port; 58 | const publicPath = path_1.default.resolve(__dirname, '../../public'); 59 | this.express.use(express_1.default.static(publicPath)); 60 | // Registering Exception & Error Handlers 61 | this.express.use(Handler_1.default.logErrors); 62 | this.express.use(Handler_1.default.clientErrorHandler); 63 | this.express.use(Handler_1.default.errorHandler); 64 | this.express = Handler_1.default.notFoundHandler(this.express); 65 | // Start the server on the specified port 66 | this.server 67 | .listen(port, () => { 68 | return Log_1.default.info(`Express :: Running @ 'https://0.0.0.0:${port}'`); // Change protocol to HTTPS 69 | }) 70 | .on('error', (_error) => { 71 | return Log_1.default.error(`Express :: Error: ${_error.message}`); 72 | }); 73 | } 74 | } 75 | /** Export the Express module */ 76 | exports.default = new Express(); 77 | -------------------------------------------------------------------------------- /dist/providers/GlobalState.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.GlobalState = void 0; 7 | const Bot_1 = require("./Bot"); 8 | const CoinManager_1 = __importDefault(require("./CoinManager/CoinManager")); 9 | const Transaction_1 = __importDefault(require("./Transaction")); 10 | class GlobalState { 11 | } 12 | exports.GlobalState = GlobalState; 13 | GlobalState.coinPerRank = [1000, 900, 800, 700, 600, 500, 400, 300, 200, 100]; 14 | GlobalState.ratePerRankInChallenge = [0.5, 0.25, 0.125, 0.083, 0.042]; 15 | GlobalState.btcPrices = []; 16 | GlobalState.stop = false; 17 | GlobalState.stopBot = false; 18 | GlobalState.winRatioFor24H = 0; 19 | GlobalState.allTimeWinsPaid = 0; 20 | GlobalState.livePlayersFor24H = 0; 21 | GlobalState.winsPaidFor24H = 0; 22 | GlobalState.contestPrize = 0; 23 | GlobalState.txnManager = Transaction_1.default.createInstance(); 24 | GlobalState.coinManager = new CoinManager_1.default(); 25 | GlobalState.highRollers = []; 26 | GlobalState.topWinRatioPlayers = []; 27 | GlobalState.top100WinnersForToday = []; 28 | GlobalState.top100WinnersForThisWeek = []; 29 | GlobalState.top100WinnersForThisMonth = []; 30 | GlobalState.top100WinnersForAllTime = []; 31 | GlobalState.botPlayers = new Bot_1.Bot(); 32 | GlobalState.currentChallengeRound = null; 33 | GlobalState.nextChallengeRound = null; 34 | GlobalState.lastExpredChallengeRound = null; 35 | -------------------------------------------------------------------------------- /dist/providers/Initalilize.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __importDefault = (this && this.__importDefault) || function (mod) { 12 | return (mod && mod.__esModule) ? mod : { "default": mod }; 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | exports.initialize = void 0; 16 | const AffiliateService_1 = require("../api/services/AffiliateService"); 17 | const Affiliate_1 = require("../models/Affiliate"); 18 | const Balance_1 = __importDefault(require("../models/Balance")); 19 | const TradingStatistics_1 = __importDefault(require("../models/TradingStatistics")); 20 | const User_1 = __importDefault(require("../models/User")); 21 | const utils_1 = __importDefault(require("../utils/utils")); 22 | const GlobalState_1 = require("./GlobalState"); 23 | const Locals_1 = __importDefault(require("./Locals")); 24 | const initialize = () => __awaiter(void 0, void 0, void 0, function* () { 25 | const adminExists = yield User_1.default.findOne({ Role: 'admin' }).exec(); 26 | const dailyContest = yield User_1.default.findOne({ 27 | Role: 'daily_contest', 28 | }).exec(); 29 | const rootAffiliate = Locals_1.default.config().rootAffiliate; 30 | if (!dailyContest) { 31 | const weeklyChallengeUser = new User_1.default({ 32 | Address: '0x000003', 33 | Email: '', 34 | Avatar: `${Locals_1.default.config().ipfsBaseUrl}/${utils_1.default.getRandomInteger(1, 12)}.png`, 35 | InvitedPath: `${rootAffiliate}#${rootAffiliate}#${rootAffiliate}`, 36 | CountryCode: 'CH', 37 | WhiteLabel: 'trade2earn', 38 | Enabled: true, 39 | WalletProvider: 'web3', 40 | CreatedAt: new Date(), 41 | Role: 'daily_contest', 42 | }); 43 | yield weeklyChallengeUser.save(); 44 | const dailyContestBalance = new Balance_1.default({ 45 | User: weeklyChallengeUser._id, 46 | Balance: 0, 47 | Coin: 0, 48 | }); 49 | yield dailyContestBalance.save(); 50 | GlobalState_1.GlobalState.weeklyChallengeUser = weeklyChallengeUser; 51 | } 52 | else { 53 | GlobalState_1.GlobalState.weeklyChallengeUser = dailyContest; 54 | } 55 | // If admin doesn't exist, create a new admin user 56 | if (!adminExists) { 57 | const adminUser = new User_1.default({ 58 | Address: Locals_1.default.config().rootAffiliateWalletAddress.toLowerCase(), 59 | Email: '', 60 | Avatar: `${Locals_1.default.config().ipfsBaseUrl}/${utils_1.default.getRandomInteger(1, 12)}.png`, 61 | InvitedPath: `${rootAffiliate}#${rootAffiliate}#${rootAffiliate}`, 62 | CountryCode: 'CH', 63 | WhiteLabel: 'trade2earn', 64 | Enabled: true, 65 | WalletProvider: 'web3', 66 | CreatedAt: new Date(), 67 | Role: 'admin', 68 | }); 69 | yield adminUser.save(); 70 | const adminBalance = new Balance_1.default({ 71 | User: adminUser._id, 72 | Balance: 0, 73 | }); 74 | yield adminBalance.save(); 75 | // creates TradingStatistics 76 | const newTradingStatistics = new TradingStatistics_1.default({ 77 | User: adminUser._id, // Replace 'userId' with the actual user ID 78 | }); 79 | yield newTradingStatistics.save(); 80 | const { success, data: affiliate } = yield (0, AffiliateService_1.getAffiliate)(Locals_1.default.config().rootAffiliate); 81 | if (success && affiliate == null) { 82 | yield (0, AffiliateService_1.addReferralLink)(adminUser._id, Affiliate_1.AffiliateType.PARTNERSHIP, Locals_1.default.config().rootAffiliate, Locals_1.default.config().rootAffiliate); 83 | } 84 | } 85 | else { 86 | GlobalState_1.GlobalState.admin = adminExists; 87 | } 88 | }); 89 | exports.initialize = initialize; 90 | -------------------------------------------------------------------------------- /dist/providers/MongoDBConnection.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __importDefault = (this && this.__importDefault) || function (mod) { 12 | return (mod && mod.__esModule) ? mod : { "default": mod }; 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | const mongoose_1 = __importDefault(require("mongoose")); 16 | const GlobalState_1 = require("./GlobalState"); 17 | const Log_1 = __importDefault(require("../api/middlewares/Log")); 18 | class MongoDBConnection { 19 | constructor(uri) { 20 | this.uri = uri; 21 | } 22 | connectToMongoDB() { 23 | return __awaiter(this, void 0, void 0, function* () { 24 | try { 25 | yield mongoose_1.default.connect(this.uri); 26 | Log_1.default.info('MongoDBConnection :: Connected to MongoDB'); 27 | } 28 | catch (error) { 29 | Log_1.default.error(`MongoDBConnection :: Error connecting to MongoDB:${error}`); 30 | GlobalState_1.GlobalState.stop = false; 31 | } 32 | }); 33 | } 34 | static createInstance(uri) { 35 | return new MongoDBConnection(uri); 36 | } 37 | } 38 | exports.default = MongoDBConnection; 39 | -------------------------------------------------------------------------------- /dist/providers/Routes.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | const Locals_1 = __importDefault(require("./Locals")); 7 | const ApiRoutes_1 = __importDefault(require("../api/routes/ApiRoutes")); 8 | const Log_1 = __importDefault(require("../api/middlewares/Log")); 9 | class Routes { 10 | mountApi(_express) { 11 | const apiPrefix = Locals_1.default.config().apiPrefix; 12 | Log_1.default.info('Route :: Mounting API Routes...'); 13 | return _express.use(`/${apiPrefix}`, ApiRoutes_1.default.router); 14 | } 15 | } 16 | exports.default = new Routes(); 17 | -------------------------------------------------------------------------------- /dist/providers/Subscriber.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | const ws_1 = __importDefault(require("ws")); 7 | const Log_1 = __importDefault(require("../api/middlewares/Log")); 8 | class Subscriber { 9 | constructor(wssUrl) { 10 | this.wssUrl = wssUrl; 11 | this.ws = null; 12 | this.lastData = ''; 13 | this.reconnect(); 14 | } 15 | static createInstance(wssUrl) { 16 | return new Subscriber(wssUrl); 17 | } 18 | reconnect() { 19 | this.connect(); 20 | setTimeout(() => this.reconnect(), 1000 * 60 * 15); 21 | } 22 | connect() { 23 | this.ws = new ws_1.default(this.wssUrl); 24 | // Event: WebSocket connection is established 25 | this.ws.on('open', () => { 26 | Log_1.default.info('Subscriber :: WebSocket Client connection established'); 27 | }); 28 | this.ws.onclose = (event) => { 29 | // Abnormal closure, attempt to reconnect 30 | setTimeout(() => this.connect(), 2000); // Adjust delay as needed 31 | }; 32 | // Event: Received a message from the server 33 | this.ws.on('message', (data) => { 34 | this.lastData = data.toString(); 35 | }); 36 | this.ws.onerror = (error) => { 37 | // Handle errors 38 | Log_1.default.error(`Subscriber :: WebSocket Error: ${error.message}`); 39 | }; 40 | } 41 | } 42 | exports.default = Subscriber; 43 | -------------------------------------------------------------------------------- /generateTradeSize.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | 3 | function generateArrays( 4 | currentArray, 5 | currentSum, 6 | targetSum, 7 | allowedValues, 8 | results 9 | ) { 10 | if (currentSum === targetSum) { 11 | results.push([...currentArray]) 12 | return 13 | } 14 | 15 | if (currentSum > targetSum) { 16 | return 17 | } 18 | 19 | for (const value of allowedValues) { 20 | const newSum = currentSum + value 21 | if (newSum <= targetSum) { 22 | currentArray.push(value) 23 | generateArrays( 24 | currentArray, 25 | newSum, 26 | targetSum, 27 | allowedValues, 28 | results 29 | ) 30 | currentArray.pop() 31 | } 32 | } 33 | } 34 | 35 | function generateAllArrays() { 36 | const allowedValues = [5, 10, 15, 25, 50, 75, 100] 37 | const targetSums = [15, 20, 25, 30, 35, 40, 45, 50, 55, 60] 38 | const results = {} 39 | 40 | for (const targetSum of targetSums) { 41 | results[targetSum] = [] 42 | generateArrays([], 0, targetSum, allowedValues, results[targetSum]) 43 | } 44 | 45 | return results 46 | } 47 | 48 | const allArrays = generateAllArrays() 49 | const jsonOutput = JSON.stringify(allArrays, null, 2) 50 | 51 | fs.writeFile('arrays.json', jsonOutput, (err) => { 52 | if (err) { 53 | console.error('Error writing JSON file:', err) 54 | } else { 55 | console.log('JSON file saved successfully!') 56 | } 57 | }) 58 | -------------------------------------------------------------------------------- /nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignore": [".logs/*.log", "gameState/*"] 3 | } 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backend", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "npx tsc", 8 | "start": "start dist/index.js", 9 | "dev": "nodemon src/index.ts", 10 | "migration": "nodemon src/init.ts", 11 | "prettier": "npx prettier --write ." 12 | }, 13 | "keywords": [], 14 | "author": "", 15 | "license": "ISC", 16 | "dependencies": { 17 | "@aws-sdk/client-dynamodb": "^3.511.0", 18 | "@aws-sdk/util-dynamodb": "^3.514.0", 19 | "@types/jsonwebtoken": "^9.0.5", 20 | "ably": "^1.2.48", 21 | "alchemy-sdk": "^3.1.2", 22 | "aws-sdk": "^2.1555.0", 23 | "body-parser": "^1.20.2", 24 | "compression": "^1.7.4", 25 | "cors": "^2.8.5", 26 | "dotenv": "^16.4.1", 27 | "ethers": "^6.11.0", 28 | "express": "^4.18.2", 29 | "express-flash": "^0.0.2", 30 | "express-validator": "^7.0.1", 31 | "jose": "^5.2.2", 32 | "jsonwebtoken": "^9.0.2", 33 | "moment": "^2.30.1", 34 | "mongoose": "^8.1.3", 35 | "moralis": "^2.24.2", 36 | "node-schedule": "^2.1.1", 37 | "pm2": "^5.4.2", 38 | "pug": "^3.0.2", 39 | "uuid": "^9.0.1", 40 | "ws": "^8.16.0" 41 | }, 42 | "devDependencies": { 43 | "@types/compression": "^1.7.5", 44 | "@types/cors": "^2.8.17", 45 | "@types/express": "^4.17.21", 46 | "@types/express-flash": "^0.0.5", 47 | "@types/node": "^20.11.7", 48 | "@types/node-schedule": "^2.1.7", 49 | "@types/uuid": "^9.0.8", 50 | "@types/ws": "^8.5.10", 51 | "nodemon": "^3.0.3", 52 | "prettier": "3.2.5", 53 | "ts-node": "^10.9.2", 54 | "typescript": "^5.3.3" 55 | }, 56 | "nodemonConfig": { 57 | "ignore": [ 58 | "gameState/" 59 | ] 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /public/assets/BTC-yLU7VgiD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/BTC-yLU7VgiD.png -------------------------------------------------------------------------------- /public/assets/affiliate_bg-MeA4VFI_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/affiliate_bg-MeA4VFI_.png -------------------------------------------------------------------------------- /public/assets/avatar_change_img-u3KcwCJV.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/avatar_change_img-u3KcwCJV.png -------------------------------------------------------------------------------- /public/assets/background-wMyYhUG4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/background-wMyYhUG4.png -------------------------------------------------------------------------------- /public/assets/btc-MJnHZLpY.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/btc-MJnHZLpY.mp4 -------------------------------------------------------------------------------- /public/assets/btc_bg-_KYdQD9P.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/btc_bg-_KYdQD9P.png -------------------------------------------------------------------------------- /public/assets/btc_name-QUnsET-k.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/btc_name-QUnsET-k.png -------------------------------------------------------------------------------- /public/assets/card_gift_box-wATcTPFb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/card_gift_box-wATcTPFb.png -------------------------------------------------------------------------------- /public/assets/ccip-N7xyI9w3.js: -------------------------------------------------------------------------------- 1 | import{aH as l,aI as w,aJ as y,aK as p,aL as h,aM as g,aN as O,aO as k,aP as L,aQ as m,aR as E}from"./index-d5cPsESa.js";class x extends l{constructor({callbackSelector:e,cause:a,data:o,extraData:c,sender:d,urls:r}){var i;super(a.shortMessage||"An error occurred while fetching for an offchain result.",{cause:a,metaMessages:[...a.metaMessages||[],(i=a.metaMessages)!=null&&i.length?"":[],"Offchain Gateway Call:",r&&[" Gateway URL(s):",...r.map(u=>` ${w(u)}`)],` Sender: ${d}`,` Data: ${o}`,` Callback selector: ${e}`,` Extra data: ${c}`].flat()}),Object.defineProperty(this,"name",{enumerable:!0,configurable:!0,writable:!0,value:"OffchainLookupError"})}}class M extends l{constructor({result:e,url:a}){super("Offchain gateway response is malformed. Response data must be a hex value.",{metaMessages:[`Gateway URL: ${w(a)}`,`Response: ${y(e)}`]}),Object.defineProperty(this,"name",{enumerable:!0,configurable:!0,writable:!0,value:"OffchainLookupResponseMalformedError"})}}class R extends l{constructor({sender:e,to:a}){super("Reverted sender address does not match target contract address (`to`).",{metaMessages:[`Contract address: ${a}`,`OffchainLookup sender address: ${e}`]}),Object.defineProperty(this,"name",{enumerable:!0,configurable:!0,writable:!0,value:"OffchainLookupSenderMismatchError"})}}function $(n,e){if(!p(n))throw new h({address:n});if(!p(e))throw new h({address:e});return n.toLowerCase()===e.toLowerCase()}const v="0x556f1830",S={name:"OffchainLookup",type:"error",inputs:[{name:"sender",type:"address"},{name:"urls",type:"string[]"},{name:"callData",type:"bytes"},{name:"callbackFunction",type:"bytes4"},{name:"extraData",type:"bytes"}]};async function C(n,{blockNumber:e,blockTag:a,data:o,to:c}){const{args:d}=g({data:o,abi:[S]}),[r,i,u,t,s]=d;try{if(!$(c,r))throw new R({sender:r,to:c});const f=await A({data:u,sender:r,urls:i}),{data:b}=await O(n,{blockNumber:e,blockTag:a,data:k([t,L([{type:"bytes"},{type:"bytes"}],[f,s])]),to:c});return b}catch(f){throw new x({callbackSelector:t,cause:f,data:o,extraData:s,sender:r,urls:i})}}async function A({data:n,sender:e,urls:a}){var c;let o=new Error("An unknown error occurred.");for(let d=0;d 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /public/assets/earning-2W3ZDEEv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/earning-2W3ZDEEv.png -------------------------------------------------------------------------------- /public/assets/earnings_D-FMs-fqUo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/earnings_D-FMs-fqUo.png -------------------------------------------------------------------------------- /public/assets/footer_radius-LSth15EO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/footer_radius-LSth15EO.png -------------------------------------------------------------------------------- /public/assets/footer_shadow_m-1HNGAYfZ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/footer_shadow_m-1HNGAYfZ.png -------------------------------------------------------------------------------- /public/assets/investment-kbVwWCb1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/investment-kbVwWCb1.png -------------------------------------------------------------------------------- /public/assets/logo-ewbRlvst.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/logo-ewbRlvst.png -------------------------------------------------------------------------------- /public/assets/money-AWSXWyLD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/money-AWSXWyLD.png -------------------------------------------------------------------------------- /public/assets/mx_ex-8mjZwiUH.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/mx_ex-8mjZwiUH.png -------------------------------------------------------------------------------- /public/assets/nav_result-zgRwmMyt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/nav_result-zgRwmMyt.png -------------------------------------------------------------------------------- /public/assets/pools_img-1f9QQBV4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/pools_img-1f9QQBV4.png -------------------------------------------------------------------------------- /public/assets/radius_gradient_light-oL6OsEMZ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/radius_gradient_light-oL6OsEMZ.png -------------------------------------------------------------------------------- /public/assets/rocket_high-7L8ZaxBF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/rocket_high-7L8ZaxBF.png -------------------------------------------------------------------------------- /public/assets/rocket_low-QilBhzmi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/rocket_low-QilBhzmi.png -------------------------------------------------------------------------------- /public/assets/star_bg-iGUlcPOw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/star_bg-iGUlcPOw.png -------------------------------------------------------------------------------- /public/assets/takelook-NFf4ZQGp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/takelook-NFf4ZQGp.png -------------------------------------------------------------------------------- /public/assets/trading_view_img-m0xj7EXZ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/trading_view_img-m0xj7EXZ.png -------------------------------------------------------------------------------- /public/assets/up_rocket-i309ZTLu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /public/assets/up_rocket-sJJ356rf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/assets/up_rocket-sJJ356rf.png -------------------------------------------------------------------------------- /public/assets/weibo--hDRqVO2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | HixLo Trade 14 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 37 | 38 | -------------------------------------------------------------------------------- /src/Config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | minTradeSize: 5, 3 | maxTradeSize: 100, 4 | minWithdraw: 10, 5 | } 6 | -------------------------------------------------------------------------------- /src/api/controllers/AffiliateController.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response } from 'express' 2 | import { AffiliateType } from '../../models/Affiliate' 3 | import { IRequest } from '../../interfaces/vendors' 4 | import { addReferralLink, getReferralIds } from '../services/AffiliateService' 5 | import Log from '../middlewares/Log' 6 | 7 | class AffiliateController { 8 | public static async createReferralLink( 9 | req: Request, 10 | res: Response 11 | ): Promise { 12 | const { user, name } = req.body 13 | 14 | try { 15 | const { data, success, error } = await addReferralLink( 16 | user._id, 17 | AffiliateType.FRIEND_METHOD, 18 | name 19 | ) 20 | 21 | if (success) { 22 | return res.status(200).send({ result: true, affiliate: data }) 23 | } else { 24 | return res.status(500).send({ result: false, error }) 25 | } 26 | } catch (error) { 27 | Log.error( 28 | `AffiliateController :: Error creating referral link: ${error}` 29 | ) 30 | return res 31 | .status(500) 32 | .send({ result: false, error: 'Internal Server Error' }) 33 | } 34 | } 35 | 36 | public static async getReferralLinks( 37 | req: Request, 38 | res: Response 39 | ): Promise { 40 | const { user, name } = req.body 41 | 42 | try { 43 | const { data, success, error } = await getReferralIds(user._id) 44 | 45 | if (success) { 46 | res.send({ result: true, affiliates: data }) 47 | } else { 48 | res.status(500).send({ result: false, error }) 49 | } 50 | } catch (error) { 51 | Log.error(`AffiliateController :: getReferralLinks: ${error}`) 52 | res.status(500).send({ 53 | result: false, 54 | error: 'Internal Server Error', 55 | }) 56 | } 57 | } 58 | } 59 | 60 | export default AffiliateController 61 | -------------------------------------------------------------------------------- /src/api/controllers/AuthController.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response } from 'express' 2 | import utils from '../../utils/utils' 3 | import Locals from '../../providers/Locals' 4 | import { addNonce, getNonce } from '../services/NonceService' 5 | import { registerUser } from '../services/UserService' 6 | import Log from '../middlewares/Log' 7 | class AuthController { 8 | public static async signIn(req: Request, res: Response) { 9 | const userInfo = req.body.userInfo 10 | const address = String(userInfo.address).toLowerCase() 11 | 12 | try { 13 | const { data, success, error } = await getNonce(address) 14 | 15 | if (!success) return res.status(500).send({ result: false, error }) 16 | 17 | const verifiedSignature = utils.verifySignature( 18 | userInfo.signature, 19 | data?.nonce ?? '', 20 | address 21 | ) 22 | 23 | if (!verifiedSignature) 24 | return res.status(401).send({ 25 | result: false, 26 | error: 'Signature Verification Failed!', 27 | }) 28 | 29 | if (userInfo.typeOfLogin !== 'web3') { 30 | const { idToken, appPubKey } = userInfo 31 | const verified = await utils.verifyWeb3AuthJwt( 32 | idToken, 33 | appPubKey 34 | ) 35 | 36 | if (!verified) 37 | return res.status(401).send({ 38 | result: false, 39 | error: 'Web3Auth Verification Failed!', 40 | }) 41 | } 42 | 43 | const { 44 | success: registrationSuccess, 45 | error: registrationError, 46 | user, 47 | } = await registerUser({ 48 | Address: address, 49 | Email: userInfo?.email, 50 | Avatar: userInfo?.profileImage, 51 | CountryCode: userInfo.countryCode, 52 | WalletProvider: userInfo.typeOfLogin, 53 | ReferralLink: 54 | userInfo.referralLink || Locals.config().rootAffiliate, 55 | WhiteLabel: userInfo?.whiteLabel, 56 | }) 57 | 58 | if (registrationSuccess) { 59 | const accessToken = utils.generateJwtAuthToken({ 60 | userId: user?.UserId, 61 | }) 62 | return res.status(200).send({ result: true, accessToken, user }) 63 | } else { 64 | return res 65 | .status(500) 66 | .send({ result: false, error: registrationError }) 67 | } 68 | } catch (error) { 69 | Log.error(`UserController :: Error signing in ${error}`) 70 | return res 71 | .status(500) 72 | .send({ result: false, error: 'Internal Server Error' }) 73 | } 74 | } 75 | 76 | public static async verify(req: Request, res: Response): Promise { 77 | const address = String(req.body?.address).toLowerCase() 78 | const nonce = utils.generateNonce() 79 | 80 | try { 81 | await addNonce(address, nonce) 82 | return res.send({ nonce: nonce }) 83 | } catch (error) { 84 | Log.error(`UserController :: Error verifying address: ${error}`) 85 | return res 86 | .status(500) 87 | .send({ result: false, error: 'Internal Server Error' }) 88 | } 89 | } 90 | } 91 | 92 | export default AuthController 93 | -------------------------------------------------------------------------------- /src/api/controllers/BalanceController.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from 'express' 2 | import Balance from '../../models/Balance' 3 | import Log from '../middlewares/Log' 4 | 5 | export default class BalanceController { 6 | public static async getBalance( 7 | req: Request, 8 | res: Response, 9 | next: NextFunction 10 | ) { 11 | try { 12 | const { user } = req.body 13 | 14 | // Find the balance document for the specified user ID 15 | const balance = await Balance.findOne({ User: user._id }).exec() 16 | 17 | if (!balance) { 18 | return res 19 | .status(404) 20 | .json({ message: 'Balance not found for the user' }) 21 | } 22 | 23 | res.status(200).send({ result: true, balance: balance.Balance, coin: balance.Coin }) 24 | } catch (error) { 25 | Log.error(`BalanceContgroller:: getBalance() : Error retrieving user balance: ${error}`) 26 | res.status(500).json({ message: 'Internal server error' }) 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/api/controllers/DailyContestController.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response } from 'express' 2 | import { GlobalState } from '../../providers/GlobalState' 3 | import Utils from '../../utils/utils' 4 | import { ITopWinRatioPlayer } from '../../interfaces/ITopWinRatio'; 5 | 6 | class DailyContestController { 7 | public static getHighRollers(req: Request, res: Response): void { 8 | const { user } = req.body 9 | try { 10 | 11 | const now = new Date(); 12 | const end = new Date(now); 13 | end.setUTCHours(0, 0, 0, 0); 14 | end.setDate(end.getDate() + 1); // Move to the next day 15 | 16 | // Calculate the initial time left until the end of the contest 17 | const timeLeft = end.getTime() - now.getTime(); 18 | 19 | const position = user 20 | ? GlobalState.highRollers.filter(x => x.Turnover >= 500).findIndex( 21 | (hr) => String(hr.UserId) === String(user._id) 22 | ) 23 | : -1 24 | 25 | const tradingVolume = user ? (GlobalState.highRollers.find(hr => String(hr.UserId) === String(user._id))?.Turnover || 0) : 0 26 | 27 | res.status(200).json({ 28 | highRollers: GlobalState.highRollers.filter(x => x.Turnover >= 500), 29 | position, 30 | timeLeft, 31 | rewards: GlobalState.coinPerRank, 32 | tradingVolume, 33 | 34 | }) 35 | } catch (error) { 36 | console.error('Error fetching high rollers:', error) 37 | res.status(500).json({ error: 'Internal server error' }) 38 | } 39 | } 40 | 41 | public static getWinRatioPlayers(req: Request, res: Response): void { 42 | const { user } = req.body 43 | try { 44 | 45 | const now = new Date(); 46 | const end = new Date(now); 47 | end.setUTCHours(0, 0, 0, 0); 48 | end.setDate(end.getDate() + 1); // Move to the next day 49 | 50 | // Calculate the initial time left until the end of the contest 51 | const timeLeft = end.getTime() - now.getTime(); 52 | 53 | const position = user 54 | ? GlobalState.topWinRatioPlayers.filter(x => x.NumberOfTrades >= 50).findIndex( 55 | (tr) => String(tr.UserId) === String(user._id) 56 | ) 57 | : -1 58 | 59 | const detail: ITopWinRatioPlayer | null | undefined = user ? GlobalState.topWinRatioPlayers.find(tr => String(tr.UserId) === String(user._id)) : null ; 60 | 61 | res.status(200).json({ 62 | winRatioPlayers: GlobalState.topWinRatioPlayers.filter(x => x.NumberOfTrades >= 50), 63 | position, 64 | timeLeft, 65 | rewards: GlobalState.coinPerRank, 66 | detail, 67 | 68 | }) 69 | } catch (error) { 70 | console.error('Error fetching high rollers:', error) 71 | res.status(500).json({ error: 'Internal server error' }) 72 | } 73 | } 74 | } 75 | 76 | export default DailyContestController 77 | -------------------------------------------------------------------------------- /src/api/controllers/RewardsController.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response } from "express"; 2 | import Reward, { IReward, IRewardModel } from "../../models/Reward"; 3 | import { singleUpdateBalance, singleUpdateCoin } from "../services/BalanceService"; 4 | import mongoose from "mongoose"; 5 | 6 | class RewardsController { 7 | 8 | public static async claim(req: Request, res: Response) { 9 | const session = await mongoose.startSession(); 10 | 11 | try { 12 | session.startTransaction(); 13 | 14 | const { user, rewardId } = req.body; 15 | 16 | // Find the reward by ID and user ID 17 | const reward: IRewardModel | null = await Reward.findOne({ _id: rewardId, user: user._id }).session(session); 18 | 19 | if (!reward) { 20 | await session.abortTransaction(); 21 | session.endSession(); 22 | return res.status(404).json({ result: false, message: 'Reward not found or user does not own the reward.' }); 23 | } 24 | 25 | // Check if the reward has already been claimed 26 | if (reward.claimed) { 27 | await session.abortTransaction(); 28 | session.endSession(); 29 | return res.status(400).json({ result: false, message: 'Reward has already been claimed.' }); 30 | } 31 | 32 | // Update the reward to mark it as claimed 33 | reward.claimed = true; 34 | await reward.save(); 35 | 36 | // Update user balance 37 | if (reward.currency === "USDT") await singleUpdateBalance(user._id, reward.amount, session); 38 | if (reward.currency === "Coin") await singleUpdateCoin(user._id, reward.amount, session); 39 | 40 | await session.commitTransaction(); 41 | session.endSession(); 42 | 43 | return res.status(200).json({ result: true, message: 'Reward claimed successfully.' }); 44 | } catch (error) { 45 | console.error('Error claiming reward:', error); 46 | await session.abortTransaction(); 47 | session.endSession(); 48 | return res.status(500).json({ result: false, message: 'An error occurred while claiming the reward.' }); 49 | } 50 | } 51 | 52 | public static async notifications(req: Request, res: Response) { 53 | try { 54 | const { user } = req.body 55 | // Query unclaimed rewards 56 | const unclaimedRewards: IReward[] = await Reward.find({ claimed: false, user: user._id }); 57 | 58 | // Send the unclaimed rewards as the response 59 | res.json(unclaimedRewards); 60 | } catch (error) { 61 | // Handle errors 62 | console.error('Error fetching unclaimed rewards:', error); 63 | res.status(500).json({ error: 'Internal Server Error' }); 64 | } 65 | } 66 | } 67 | 68 | export default RewardsController; 69 | -------------------------------------------------------------------------------- /src/api/controllers/UserController.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response } from 'express' 2 | import { IRequest } from '../../interfaces/vendors' 3 | import { getTransactionsByUser } from '../services/TransactionService' 4 | 5 | class UserController { 6 | public static async getUserGameHistory(req: Request, res: Response) { 7 | try { 8 | const { user } = req.body 9 | const { success, data, error } = await getTransactionsByUser( 10 | user._id, 11 | 10 12 | ) 13 | 14 | if (success && data) { 15 | // If transactions are successfully retrieved, send them in the response 16 | return res.status(200).send({ success: true, data: data }) 17 | } else if (!success && error) { 18 | // If there was an error while retrieving transactions, send an error response 19 | return res.status(500).send({ success: false, error: error }) 20 | } else { 21 | // If no transactions found, send an empty array 22 | return res.status(200).send({ success: true, data: [] }) 23 | } 24 | } catch (error) { 25 | // Handle any unexpected errors 26 | console.error('Error in getUserGameHistory:', error) 27 | return res 28 | .status(500) 29 | .send({ success: false, error: 'Internal server error' }) 30 | } 31 | } 32 | } 33 | 34 | export default UserController 35 | -------------------------------------------------------------------------------- /src/api/middlewares/Auth.ts: -------------------------------------------------------------------------------- 1 | import jwt, { TokenExpiredError } from 'jsonwebtoken' 2 | import Locals from '../../providers/Locals' 3 | import Log from './Log' 4 | import { NextFunction, Request, Response } from 'express' 5 | import User, { IUser } from '../../models/User' 6 | 7 | export default class AuthJwtToken { 8 | public static async authorization( 9 | req: Request, 10 | res: Response, 11 | next: NextFunction 12 | ) { 13 | // Get the auth token from the request headers 14 | const token = req.headers.authorization 15 | 16 | // Check if token is present 17 | if (!token) { 18 | // Token is missing, send response asking for login 19 | return res 20 | .status(401) 21 | .json({ message: 'Unauthorized. Please log in.' }) 22 | } 23 | 24 | try { 25 | // Convert JWT token to user object 26 | const user = await AuthJwtToken.jwtToken2User(token) 27 | 28 | // Attach the decoded user information to the request object 29 | req.body.user = user 30 | next() 31 | } catch (error) { 32 | if (error instanceof Error) { 33 | Log.error(`Auth :: verify jwt token: ${error.message}`) 34 | return res.status(500).json({ message: error.message }) 35 | } else { 36 | return res 37 | .status(500) 38 | .json({ message: 'Internal server error' }) 39 | } 40 | } 41 | } 42 | 43 | public static async isAdmin( 44 | req: Request, 45 | res: Response, 46 | next: NextFunction 47 | ) { 48 | const { user } = req.body 49 | if (user.Role === 'admin') next() 50 | else return res.status(401).json({ message: 'Admin role is required!' }) 51 | } 52 | 53 | public static async jwtToken2User(token: string): Promise { 54 | return new Promise((resolve, reject) => { 55 | // Verify the token 56 | jwt.verify( 57 | token.split(' ')[1], 58 | Locals.config().secretKey, 59 | async (err: any, decoded: any) => { 60 | if (err) { 61 | if (err instanceof TokenExpiredError) { 62 | // Token has expired 63 | return reject(new Error('Token has expired')) 64 | } 65 | // Invalid token 66 | return reject(new Error('Invalid token')) 67 | } 68 | 69 | // Token is valid, but let's also check if it's expired 70 | const { exp, userId } = decoded as { 71 | exp: number 72 | userId: string 73 | } 74 | 75 | const currentTime = Math.floor(Date.now() / 1000) // Get current time in seconds 76 | 77 | if (currentTime > exp) { 78 | // Token has expired, send response asking for login 79 | return reject( 80 | new Error('Token has expired. Please log in again.') 81 | ) 82 | } 83 | 84 | try { 85 | // Fetch user data from the database using the userId stored in the token 86 | const user = await User.findById(userId) 87 | 88 | if (!user) { 89 | return reject(new Error('User not found')) 90 | } 91 | 92 | resolve(user) 93 | } catch (error) { 94 | reject(error) 95 | } 96 | } 97 | ) 98 | }) 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/api/middlewares/CORS.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enables the CORS 3 | * 4 | * @author Isom D. 5 | */ 6 | 7 | import cors from 'cors' 8 | import { Application } from 'express' 9 | 10 | import Log from './Log' 11 | import Locals from '../../providers/Locals' 12 | 13 | class CORS { 14 | public mount(_express: Application): Application { 15 | Log.info("Booting the 'CORS' middleware...") 16 | 17 | const apiPrefix = Locals.config().apiPrefix 18 | 19 | const corsOptions = { 20 | origin: '*', 21 | methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', 22 | credentials: true, 23 | optionsSuccessStatus: 204, 24 | } 25 | 26 | _express.use(`/${apiPrefix}`, cors(corsOptions)) 27 | 28 | return _express 29 | } 30 | } 31 | 32 | export default new CORS() 33 | -------------------------------------------------------------------------------- /src/api/middlewares/Kernel.ts: -------------------------------------------------------------------------------- 1 | import { Application } from 'express' 2 | import CORS from './CORS' 3 | import Http from './Middleware' 4 | 5 | class Kernel { 6 | public static init(_express: Application): Application { 7 | _express = CORS.mount(_express) 8 | _express = Http.mount(_express) 9 | 10 | return _express 11 | } 12 | } 13 | 14 | export default Kernel 15 | -------------------------------------------------------------------------------- /src/api/middlewares/Log.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Creates & maintains the log 3 | */ 4 | 5 | import * as fs from 'fs' 6 | import * as path from 'path' 7 | 8 | class Log { 9 | public baseDir: string 10 | public fileName: string 11 | public linePrefix: string 12 | 13 | public today: Date = new Date() 14 | 15 | constructor() { 16 | let _dateString = `${this.today.getFullYear()}-${this.today.getMonth() + 1}-${this.today.getDate()}` 17 | let _timeString = `${this.today.getHours()}:${this.today.getMinutes()}:${this.today.getSeconds()}` 18 | 19 | this.baseDir = path.join(__dirname, '../../../.logs/') 20 | 21 | this.fileName = `${_dateString}.log` 22 | this.linePrefix = `[${_dateString} ${_timeString}]` 23 | } 24 | 25 | // Adds INFO prefix string to the log string 26 | public info(_string: string): void { 27 | this.addLog('INFO', _string) 28 | } 29 | 30 | // Adds WARN prefix string to the log string 31 | public warn(_string: string): void { 32 | this.addLog('WARN', _string) 33 | } 34 | 35 | // Adds ERROR prefix string to the log string 36 | public error(_string: string): void { 37 | // Line break and show the first line 38 | console.log( 39 | '\x1b[31m%s\x1b[0m', 40 | '[ERROR] :: ' + _string.split(/r?\n/)[0] 41 | ) 42 | 43 | this.addLog('ERROR', _string) 44 | } 45 | 46 | // Adds the custom prefix string to the log string 47 | public custom(_filename: string, _string: string): void { 48 | this.addLog(_filename, _string) 49 | } 50 | 51 | /** 52 | * Creates the file if does not exist, and 53 | * append the log kind & string into the file. 54 | */ 55 | private addLog(_kind: string, _string: string): void { 56 | const _that = this 57 | _kind = _kind.toUpperCase() 58 | 59 | fs.open( 60 | `${_that.baseDir}${_that.fileName}`, 61 | 'a', 62 | (_err, _fileDescriptor) => { 63 | if (!_err && _fileDescriptor) { 64 | // Append to file and close it 65 | fs.appendFile( 66 | _fileDescriptor, 67 | `${_that.linePrefix} [${_kind}] ${_string}\n`, 68 | (_err) => { 69 | if (!_err) { 70 | fs.close(_fileDescriptor, (_err) => { 71 | if (!_err) { 72 | return true 73 | } else { 74 | return console.log( 75 | '\x1b[31m%s\x1b[0m', 76 | 'Error closing log file that was being appended' 77 | ) 78 | } 79 | }) 80 | } else { 81 | return console.log( 82 | '\x1b[31m%s\x1b[0m', 83 | 'Error appending to the log file' 84 | ) 85 | } 86 | } 87 | ) 88 | } else { 89 | return console.log( 90 | '\x1b[31m%s\x1b[0m', 91 | "Error cloudn't open the log file for appending" 92 | ) 93 | } 94 | } 95 | ) 96 | } 97 | 98 | /** 99 | * Deletes the log files older than 'X' days 100 | * 101 | * Note: 'X' is defined in .env file 102 | */ 103 | public clean(): void { 104 | // 105 | } 106 | } 107 | 108 | export default new Log() 109 | -------------------------------------------------------------------------------- /src/api/middlewares/Middleware.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Defines all the requisites in HTTP 3 | * 4 | * @author Isom D. 5 | */ 6 | 7 | import cors from 'cors' 8 | import { Application } from 'express' 9 | // import flash from 'express-flash'; 10 | import compress from 'compression' 11 | import * as bodyParser from 'body-parser' 12 | 13 | import Log from './Log' 14 | import Locals from '../../providers/Locals' 15 | 16 | class Http { 17 | public static mount(_express: Application): Application { 18 | Log.info("Booting the 'HTTP' middleware...") 19 | 20 | // Enables the request body parser 21 | _express.use( 22 | bodyParser.json({ 23 | limit: Locals.config().maxUploadLimit, 24 | }) 25 | ) 26 | 27 | _express.use( 28 | bodyParser.urlencoded({ 29 | limit: Locals.config().maxUploadLimit, 30 | parameterLimit: Locals.config().maxParameterLimit, 31 | extended: false, 32 | }) 33 | ) 34 | 35 | // Disable the x-powered-by header in response 36 | _express.disable('x-powered-by') 37 | 38 | // Enables the CORS 39 | // _express.use(cors()); 40 | 41 | // Enables the "gzip" / "deflate" compression for response 42 | _express.use(compress()) 43 | 44 | return _express 45 | } 46 | } 47 | 48 | export default Http 49 | -------------------------------------------------------------------------------- /src/api/middlewares/Validation.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from 'express' 2 | import Config from '../../providers/CoinManager/Config' 3 | 4 | export const depositValidation = ( 5 | req: Request, 6 | res: Response, 7 | next: NextFunction 8 | ) => { 9 | const { chain } = req.body 10 | if (!chain) { 11 | return res.status(400).json({ error: 'Chain is required' }) 12 | } 13 | 14 | next() 15 | } 16 | -------------------------------------------------------------------------------- /src/api/services/AdminService.ts: -------------------------------------------------------------------------------- 1 | import mongoose from 'mongoose' 2 | import Balance from '../../models/Balance' 3 | import { GlobalState } from '../../providers/GlobalState' 4 | import Log from '../middlewares/Log' 5 | import { singleUpdateBalance } from './BalanceService' 6 | 7 | export default class AdminService { 8 | public static feeTo( 9 | fee: number, 10 | userId: mongoose.Types.ObjectId, 11 | session: mongoose.mongo.ClientSession 12 | ) { 13 | try { 14 | singleUpdateBalance(userId, fee, session) 15 | } catch (error) { 16 | // Handle errors 17 | Log.error( 18 | `AdminService :: feeTo => Error increasing balance: ${error}` 19 | ) 20 | 21 | throw error 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/api/services/AffiliateStatisticsService.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/src/api/services/AffiliateStatisticsService.ts -------------------------------------------------------------------------------- /src/api/services/BTCChallengePoolService.ts: -------------------------------------------------------------------------------- 1 | import BTCChallengePool, { IBTCChallengePool, IBTCChallengePoolModel } from "../../models/BTCChallengePool"; 2 | 3 | // Function to get the current round in progress 4 | export const getCurrentRoundInProgress = async (): Promise => { 5 | try { 6 | // Get the current date and time 7 | const now = new Date(); 8 | 9 | // Find the round in progress where StartTime < Now and EndTime > Now 10 | const roundInProgress = await BTCChallengePool.findOne({ 11 | StartTime: { $lt: now }, 12 | EndTime: { $gt: now }, 13 | StartPrice: {$gt: 0}, 14 | EndPrice: {$eq: 0} 15 | }).exec(); 16 | 17 | return roundInProgress; 18 | } catch (error) { 19 | console.error("Error occurred while getting current round in progress:", error); 20 | return null; 21 | } 22 | }; 23 | 24 | 25 | export const getNextRoundInProgress = async (): Promise => { 26 | try { 27 | // Get the current date and time 28 | const now = new Date(); 29 | const nextTimeInProgress = new Date(now); 30 | nextTimeInProgress.setUTCDate(now.getUTCDate() + 7); 31 | // nextTimeInProgress.setUTCMinutes(now.getUTCMinutes() + 1); 32 | // nextTimeInProgress.setUTCHours(now.getUTCHours() + 1); 33 | 34 | // Find the round in progress where StartTime < Now and EndTime > Now 35 | const nextRoundInProgress = await BTCChallengePool.findOne({ 36 | StartTime: { $lt: nextTimeInProgress }, 37 | EndTime: { $gt: nextTimeInProgress }, 38 | StartPrice: {$eq: 0}, 39 | EndPrice: {$eq: 0} 40 | }).exec(); 41 | 42 | return nextRoundInProgress; 43 | } catch (error) { 44 | console.error("Error occurred while getting current round in progress:", error); 45 | return null; 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /src/api/services/BalanceService.ts: -------------------------------------------------------------------------------- 1 | import mongoose, { ObjectId } from 'mongoose' 2 | import Balance, { IBalance } from '../../models/Balance' 3 | import Log from '../middlewares/Log' 4 | import User, { IUser } from '../../models/User' 5 | import { IReturnData } from '../../interfaces/IReturnData' 6 | 7 | export interface BalanceUpdate { 8 | User: ObjectId 9 | Amount: number 10 | } 11 | 12 | export const batchUpdateBalance = async ( 13 | balanceUpdates: BalanceUpdate[], 14 | session?: mongoose.mongo.ClientSession 15 | ): Promise> => { 16 | try { 17 | const bulkOps = balanceUpdates.map((update) => ({ 18 | updateOne: { 19 | filter: { User: update.User }, 20 | update: { $inc: { Balance: update.Amount } }, 21 | }, 22 | })) 23 | 24 | await Balance.bulkWrite(bulkOps, { session }) 25 | 26 | const userIds = balanceUpdates.map((b) => b.User) 27 | 28 | const updatedBalances: IBalance[] = session 29 | ? await Balance.find({ 30 | User: { $in: userIds }, 31 | }) 32 | .session(session) 33 | .exec() 34 | : await Balance.find({ 35 | User: { $in: userIds }, 36 | }).exec() 37 | 38 | return { success: true, data: updatedBalances } 39 | } catch (error) { 40 | // if(session) { 41 | // await session.abortTransaction() 42 | // session.endSession() 43 | // } 44 | 45 | Log.error( 46 | `BalanceService :: BalanceUpdate => Error during bulk write operation: ${error}` 47 | ) 48 | 49 | // return { success: false, error } 50 | throw error 51 | // Handle the error as needed 52 | } 53 | } 54 | 55 | export const singleUpdateBalance = async ( 56 | User: mongoose.Types.ObjectId, 57 | Amount: number, 58 | session?: mongoose.mongo.ClientSession 59 | ): Promise> => { 60 | try { 61 | // Find the balance document for the user and update it 62 | const updatedBalance = await Balance.findOneAndUpdate( 63 | { User }, 64 | { $inc: { Balance: Amount } }, 65 | { new: true, session } 66 | ) 67 | 68 | // Handle the updated balance if needed 69 | // For example, you can return it or perform additional actions 70 | return { success: true, data: updatedBalance } 71 | } catch (error) { 72 | // if (session) { 73 | // await session.abortTransaction() 74 | // session.endSession() 75 | // } 76 | // Handle errors 77 | Log.error( 78 | `BalanceService :: singleUpdateBalance => Error increasing balance: ${error}` 79 | ) 80 | // return { success: false, error } 81 | throw error 82 | } 83 | } 84 | 85 | export const singleUpdateCoin = async ( 86 | User: mongoose.Types.ObjectId, 87 | Amount: number, 88 | session?: mongoose.mongo.ClientSession 89 | ): Promise> => { 90 | try { 91 | // Find the balance document for the user and update it 92 | const updatedBalance = await Balance.findOneAndUpdate( 93 | { User }, 94 | { $inc: { Coin: Amount } }, 95 | { new: true, session } 96 | ) 97 | 98 | // Handle the updated balance if needed 99 | // For example, you can return it or perform additional actions 100 | return { success: true, data: updatedBalance } 101 | } catch (error) { 102 | // if (session) { 103 | // await session.abortTransaction() 104 | // session.endSession() 105 | // } 106 | // Handle errors 107 | Log.error( 108 | `BalanceService :: singleUpdateBalance => Error increasing balance: ${error}` 109 | ) 110 | // return { success: false, error } 111 | throw error 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/api/services/FutureBTCChallengeService.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vector41/hixlo-backend/a6e13ac078727ef7b4a9c1e9d1fe719835999ce5/src/api/services/FutureBTCChallengeService.ts -------------------------------------------------------------------------------- /src/api/services/NonceService.ts: -------------------------------------------------------------------------------- 1 | import Log from '../middlewares/Log' 2 | import NonceModel, { INonce } from '../../models/Nonce' 3 | import { IReturnData } from '../../interfaces/IReturnData' 4 | 5 | export const addNonce = async ( 6 | address: string, 7 | nonce: string 8 | ): Promise> => { 9 | try { 10 | const existingItem = await NonceModel.findOne({ address }) 11 | 12 | if (existingItem) { 13 | // Address exists, update the nonce field 14 | existingItem.nonce = nonce 15 | await existingItem.save() 16 | } else { 17 | // Address does not exist, add a new item 18 | await NonceModel.create({ address, nonce }) 19 | } 20 | 21 | return { success: true } 22 | } catch (error) { 23 | Log.error(`NonceService :: Error adding nonce: ${error}`) 24 | return { success: false } 25 | } 26 | } 27 | 28 | export const getNonce = async ( 29 | address: string 30 | ): Promise> => { 31 | try { 32 | const item = await NonceModel.findOne({ address }).select('nonce') 33 | 34 | if (item) { 35 | return { success: true, data: item } 36 | } else { 37 | return { success: false, error: 'Not exist' } 38 | } 39 | } catch (error) { 40 | Log.error(`NonceService :: Error getting nonce: ${error}`) 41 | return { success: false } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/api/services/RewardService.ts: -------------------------------------------------------------------------------- 1 | import mongoose from 'mongoose' 2 | import { IReturnData } from '../../interfaces/IReturnData' 3 | import Reward, { IReward, IRewardModel } from '../../models/Reward' 4 | import Log from '../middlewares/Log' 5 | 6 | export const insertRewards = async ( 7 | rewards: IReward[], 8 | session?: mongoose.ClientSession 9 | ): Promise => { 10 | try { 11 | const options: any = {} 12 | if (session) { 13 | options.session = session 14 | } 15 | 16 | const insertedRewards = await Reward.insertMany( 17 | rewards, 18 | options 19 | ) 20 | 21 | return insertedRewards 22 | } catch (error) { 23 | Log.error(`RewardService :: Error adding batch rewards: ${error}`) 24 | 25 | throw error 26 | } 27 | } 28 | 29 | 30 | export async function getUnclaimedRewards() { 31 | try { 32 | // Query to find rewards where claimed is false 33 | const unclaimedRewards: IRewardModel[] = await Reward.find({ claimed: false }); 34 | 35 | return unclaimedRewards; 36 | } catch (error) { 37 | // Handle error 38 | console.error('Error fetching unclaimed rewards:', error); 39 | throw error; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/api/services/WithdrawService.ts: -------------------------------------------------------------------------------- 1 | import mongoose from 'mongoose' 2 | import { 3 | OrderStatus, 4 | Record, 5 | } from '../../providers/CoinManager/Interfaces/ICoinManager' 6 | import utils from '../../utils/utils' 7 | import RecordModel, { IRecord } from '../../models/Record' 8 | import Log from '../middlewares/Log' 9 | import { singleUpdateBalance } from './BalanceService' 10 | import { IBalance } from '../../models/Balance' 11 | import { GlobalState } from '../../providers/GlobalState' 12 | import Config from '../../providers/CoinManager/Config' 13 | import Utils from '../../utils/utils' 14 | import { MessageType } from '../../providers/Publisher' 15 | 16 | export enum RecordType { 17 | DEPOSIT = 'deposit', 18 | WITHDRAW = 'withdraw', 19 | } 20 | 21 | export async function withdrawRecord( 22 | withdraw: Record 23 | ): Promise<{ success: boolean; error?: any; data?: IRecord }> { 24 | try { 25 | // Check if a record with the same recordId exists 26 | const existingRecord = await RecordModel.findOne({ 27 | recordId: withdraw.recordId, 28 | }) 29 | 30 | if (existingRecord) { 31 | if (existingRecord.status === withdraw.status) { 32 | return { success: true } 33 | } 34 | 35 | // If a record with the same recordId exists, update it 36 | existingRecord.status = withdraw.status 37 | existingRecord.txId = withdraw.txId 38 | 39 | // Save the updated record to the database 40 | const savedRecord = await existingRecord.save() 41 | 42 | return { success: true, data: savedRecord } 43 | } else { 44 | // If no record with the same recordId exists, create a new one 45 | const newRecord = new RecordModel({ 46 | recordId: withdraw.recordId, 47 | userId: new mongoose.Types.ObjectId(withdraw.userId), 48 | coinId: withdraw.coinId, 49 | status: withdraw.status, 50 | chain: withdraw.chain, 51 | amount: Number(withdraw.amount), 52 | txId: withdraw.txId, 53 | toAddress: withdraw.toAddress, 54 | fromAddress: withdraw.fromAddress, 55 | type: RecordType.WITHDRAW, 56 | accepted: true, 57 | }) 58 | 59 | // Save the new record to the database 60 | const savedRecord = await newRecord.save() 61 | 62 | // Return the newly created record 63 | return { success: true, data: savedRecord } 64 | } 65 | } catch (error) { 66 | Log.error(`WithdrawService :: withdrawRecord: ${error}`) 67 | return { success: false, error } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/exception/Handler.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Define the error & exception handlers 3 | * Author: Isom D. 4 | */ 5 | 6 | import { Application, NextFunction, Request, Response } from 'express' 7 | import Locals from '../providers/Locals' 8 | import Log from '../api/middlewares/Log' 9 | 10 | // Class responsible for handling errors and exceptions 11 | class ExceptionHandler { 12 | /** 13 | * Handles all the not found routes 14 | */ 15 | public static notFoundHandler(_express: Application): any { 16 | const apiPrefix = Locals.config().apiPrefix 17 | 18 | _express.use('*', (req, res) => { 19 | const ip = 20 | req.headers['x-forwarded-for'] || req.connection.remoteAddress 21 | 22 | Log.error(`Path '${req.originalUrl}' not found [IP: '${ip}']!`) 23 | 24 | if (req.xhr || req.originalUrl.includes(`/${apiPrefix}/`)) { 25 | return res.json({ error: 'Page Not Found' }) 26 | } else { 27 | res.status(404) 28 | return res.render('pages/error', { 29 | title: 'Page Not Found', 30 | error: [], 31 | }) 32 | } 33 | }) 34 | 35 | return _express 36 | } 37 | 38 | /** 39 | * Handles your api/web routes errors/exception 40 | */ 41 | public static clientErrorHandler( 42 | err: Error, 43 | req: Request, 44 | res: Response, 45 | next: NextFunction 46 | ): any { 47 | Log.error(err.stack ? err.stack : '') 48 | 49 | if (req.xhr) { 50 | return res.status(500).send({ error: 'Something went wrong!' }) 51 | } else { 52 | return next(err) 53 | } 54 | } 55 | 56 | /** 57 | * Show under maintenance page in case of errors 58 | */ 59 | public static errorHandler( 60 | err: Error, 61 | req: Request, 62 | res: Response, 63 | next: NextFunction 64 | ): any { 65 | Log.error(err.stack ? err.stack : '') 66 | res.status(500) 67 | 68 | const apiPrefix = Locals.config().apiPrefix 69 | if (req.originalUrl.includes(`/${apiPrefix}/`)) { 70 | if (err.name && err.name === 'UnauthorizedError') { 71 | const innerMessage = err.message ? err.message : undefined 72 | return res.json({ error: ['Invalid Token!', innerMessage] }) 73 | } 74 | 75 | return res.json({ error: err }) 76 | } 77 | 78 | return res.render('pages/error', { 79 | error: err.stack, 80 | title: 'Under Maintenance', 81 | }) 82 | } 83 | 84 | /** 85 | * Register your error / exception monitoring tools right here ie. before "next(err)"! 86 | */ 87 | public static logErrors( 88 | err: Error, 89 | req: Request, 90 | res: Response, 91 | next: NextFunction 92 | ): any { 93 | Log.error(err.stack ? err.stack : '') 94 | 95 | return next(err) 96 | } 97 | } 98 | 99 | // Export the ExceptionHandler class 100 | export default ExceptionHandler 101 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | // Import the App class from './providers/App' 2 | import App from './providers/App' 3 | // import "./providers/Challenges" 4 | 5 | // Call the loadServer method of the App class 6 | App.loadServer() 7 | 8 | -------------------------------------------------------------------------------- /src/interfaces/IBtcPrice.ts: -------------------------------------------------------------------------------- 1 | export default interface IBtcPrice { 2 | value: number 3 | localTimeIndex: number 4 | } 5 | -------------------------------------------------------------------------------- /src/interfaces/IFullStatistics.ts: -------------------------------------------------------------------------------- 1 | import { ITransaction } from '../models/Transaction' 2 | import IBtcPrice from './IBtcPrice' 3 | import { ITop100Winner } from './ITop100Winner' 4 | 5 | export interface IRoundResult { 6 | roundId: string 7 | startPrice: number 8 | endPrice: number 9 | } 10 | export interface IFullStatistics { 11 | AllTimeWinsPaid: number 12 | WinRatioFor24H: number 13 | LivePlayersFor24H: number 14 | WinsPaidFor24H: number 15 | RoundResult: IRoundResult[] 16 | BtcPrices: IBtcPrice[] 17 | ContestPrize: number 18 | Traders: ITransaction[] 19 | Top100Winners: ITop100Winner[] 20 | } 21 | -------------------------------------------------------------------------------- /src/interfaces/IHighRoller.ts: -------------------------------------------------------------------------------- 1 | import mongoose from 'mongoose' 2 | 3 | export interface IHightRoller { 4 | UserId: mongoose.ObjectId 5 | Username: string 6 | CountryCode: string 7 | Avatar: string 8 | Turnover: number 9 | NumberOfTrades: number 10 | } 11 | -------------------------------------------------------------------------------- /src/interfaces/IReturnData.ts: -------------------------------------------------------------------------------- 1 | export interface IReturnData { 2 | success: boolean 3 | data?: T | any 4 | error?: any 5 | } 6 | -------------------------------------------------------------------------------- /src/interfaces/IRoundResult.ts: -------------------------------------------------------------------------------- 1 | export interface IRoundResults { 2 | roundResults: Map< 3 | string, 4 | { 5 | txnHash: string 6 | startPrice: number 7 | endPrice: number 8 | }[] 9 | > 10 | } 11 | -------------------------------------------------------------------------------- /src/interfaces/IRoundStatus.ts: -------------------------------------------------------------------------------- 1 | import IBtcPrice from './IBtcPrice' 2 | 3 | export enum RoundPosition { 4 | NONE = 0, 5 | LOCKING = 1, 6 | LOCKED = 2, 7 | DISTRIBUTING = 3, 8 | DISTRIBUTED = 4, 9 | } 10 | 11 | export default interface IRoundStatus { 12 | currentLocalFrameIndex: number 13 | currentBtcPrice: IBtcPrice 14 | startFrameIndex: number 15 | startPrice: number 16 | endPrice: number 17 | currentPosition: RoundPosition 18 | previousPosition: RoundPosition 19 | txnHash?: string 20 | } 21 | -------------------------------------------------------------------------------- /src/interfaces/ITop100Winner.ts: -------------------------------------------------------------------------------- 1 | export interface ITop100Winner { 2 | Avatar?: string 3 | Username: string 4 | CountryCode: string 5 | NumberOfTrades: number 6 | NumberOfWins: number 7 | NetProfit: number 8 | } -------------------------------------------------------------------------------- /src/interfaces/ITopWinRatio.ts: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose" 2 | 3 | export interface ITopWinRatioPlayer { 4 | UserId: mongoose.ObjectId 5 | Username: string 6 | CountryCode: string 7 | Avatar?: string 8 | WinRatio: number 9 | NumberOfTrades: number 10 | NumberOfWins: number 11 | } -------------------------------------------------------------------------------- /src/interfaces/vendors/IError.ts: -------------------------------------------------------------------------------- 1 | export interface IError extends Error { 2 | status?: number 3 | } 4 | -------------------------------------------------------------------------------- /src/interfaces/vendors/INext.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Defines Custom method types over Express's NextFunction 3 | * 4 | * @author Faiz A. Farooqui 5 | */ 6 | 7 | import { NextFunction } from 'express' 8 | 9 | export interface INext extends NextFunction {} 10 | -------------------------------------------------------------------------------- /src/interfaces/vendors/IRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Defines Custom method types over Express's Request 3 | * 4 | * @author Faiz A. Farooqui 5 | */ 6 | 7 | import { Request } from 'express' 8 | import { IUser } from '../../models/User' 9 | 10 | export interface IRequest extends Request { 11 | user: IUser 12 | address: string 13 | } 14 | -------------------------------------------------------------------------------- /src/interfaces/vendors/IResponse.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Defines Custom method types over Express's Response 3 | * 4 | * @author Faiz A. Farooqui 5 | */ 6 | 7 | import { Response } from 'express' 8 | 9 | export interface IResponse extends Response { 10 | redirect(arg0: any): unknown 11 | user?: any 12 | } 13 | -------------------------------------------------------------------------------- /src/interfaces/vendors/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Contains all your vendors' types definition 3 | * 4 | * @author Isom D. 5 | */ 6 | 7 | import { IRequest } from './IRequest' 8 | import { IResponse } from './IResponse' 9 | import { INext } from './INext' 10 | 11 | export { IRequest, IResponse, INext } 12 | -------------------------------------------------------------------------------- /src/models/Affiliate.ts: -------------------------------------------------------------------------------- 1 | export enum AffiliateType { 2 | FRIEND_METHOD = 'FRIEND_METHOD', 3 | PARTNERSHIP = 'PARTNERSHIP', 4 | } 5 | 6 | import mongoose, { Document, ObjectId, Schema } from 'mongoose' 7 | import { IUser } from './User' 8 | 9 | export interface IAffiliateDistribution { 10 | Tier1Paid: number 11 | Tier2Paid: number 12 | Tier3Paid: number 13 | Tier1Unclaimed: number 14 | Tier2Unclaimed: number 15 | Tier3Unclaimed: number 16 | ReferralId: string 17 | } 18 | 19 | export interface IAffiliate extends Document { 20 | AffiliateType: string 21 | ReferralId: string 22 | Name: string 23 | Tier1Paid: number 24 | Tier2Paid: number 25 | Tier3Paid: number 26 | Tier1Unclaimed: number 27 | Tier2Unclaimed: number 28 | Tier3Unclaimed: number 29 | CreatedAt: Date 30 | User: ObjectId | IUser 31 | } 32 | 33 | const affiliateSchema: Schema = new Schema({ 34 | AffiliateType: { 35 | type: String, 36 | required: true, 37 | }, 38 | ReferralId: { 39 | type: String, 40 | required: true, 41 | unique: true, 42 | index: true, 43 | }, 44 | Name: { 45 | type: String, 46 | required: true, 47 | }, 48 | Tier1Paid: { 49 | type: Number, 50 | default: 0, 51 | }, 52 | Tier2Paid: { 53 | type: Number, 54 | default: 0, 55 | }, 56 | Tier3Paid: { 57 | type: Number, 58 | default: 0, 59 | }, 60 | Tier1Unclaimed: { 61 | type: Number, 62 | default: 0, 63 | index: true, 64 | }, 65 | Tier2Unclaimed: { 66 | type: Number, 67 | index: true, 68 | default: 0, 69 | }, 70 | Tier3Unclaimed: { 71 | type: Number, 72 | default: 0, 73 | index: true, 74 | }, 75 | CreatedAt: { 76 | type: Date, 77 | default: Date.now, 78 | }, 79 | User: { 80 | type: Schema.Types.ObjectId, 81 | ref: 'User', 82 | index: true 83 | }, 84 | }) 85 | 86 | export default mongoose.model('Affiliate', affiliateSchema) 87 | -------------------------------------------------------------------------------- /src/models/AffiliateStatistics.ts: -------------------------------------------------------------------------------- 1 | import mongoose, { Schema, Document } from 'mongoose' 2 | 3 | export interface IAffiliateStatistics extends Document { 4 | Address: string 5 | AllTime: { 6 | Tier1Paid: number 7 | Tier2Paid: number 8 | Tier3Paid: number 9 | TotalPaid: number 10 | } 11 | ThisMonth: { 12 | Tier1Paid: number 13 | Tier2Paid: number 14 | Tier3Paid: number 15 | TotalPaid: number 16 | } 17 | ThisWeek: { 18 | Tier1Paid: number 19 | Tier2Paid: number 20 | Tier3Paid: number 21 | TotalPaid: number 22 | } 23 | Yesterday: { 24 | Tier1Paid: number 25 | Tier2Paid: number 26 | Tier3Paid: number 27 | TotalPaid: number 28 | } 29 | Today: { 30 | Tier1Paid: number 31 | Tier2Paid: number 32 | Tier3Paid: number 33 | TotalPaid: number 34 | } 35 | } 36 | 37 | const AffiliateStatisticsSchema: Schema = new Schema({ 38 | Address: { type: String, required: true }, 39 | AllTime: { 40 | Tier1Paid: { type: Number, default: 0 }, 41 | Tier2Paid: { type: Number, default: 0 }, 42 | Tier3Paid: { type: Number, default: 0 }, 43 | TotalPaid: { type: Number, default: 0 }, 44 | }, 45 | ThisMonth: { 46 | Tier1Paid: { type: Number, default: 0 }, 47 | Tier2Paid: { type: Number, default: 0 }, 48 | Tier3Paid: { type: Number, default: 0 }, 49 | TotalPaid: { type: Number, default: 0 }, 50 | }, 51 | ThisWeek: { 52 | Tier1Paid: { type: Number, default: 0 }, 53 | Tier2Paid: { type: Number, default: 0 }, 54 | Tier3Paid: { type: Number, default: 0 }, 55 | TotalPaid: { type: Number, default: 0 }, 56 | }, 57 | Yesterday: { 58 | Tier1Paid: { type: Number, default: 0 }, 59 | Tier2Paid: { type: Number, default: 0 }, 60 | Tier3Paid: { type: Number, default: 0 }, 61 | TotalPaid: { type: Number, default: 0 }, 62 | }, 63 | Today: { 64 | Tier1Paid: { type: Number, default: 0 }, 65 | Tier2Paid: { type: Number, default: 0 }, 66 | Tier3Paid: { type: Number, default: 0 }, 67 | TotalPaid: { type: Number, default: 0 }, 68 | }, 69 | }) 70 | 71 | export default mongoose.model( 72 | 'AffiliateStatistics', 73 | AffiliateStatisticsSchema 74 | ) 75 | -------------------------------------------------------------------------------- /src/models/BTCChallengePool.ts: -------------------------------------------------------------------------------- 1 | import { Document, Schema, model } from 'mongoose'; 2 | 3 | export interface IBTCChallengePool { 4 | StartTime: Date; 5 | EndTime: Date; 6 | StartPrice: number; 7 | EndPrice: number; 8 | NextId?: Schema.Types.ObjectId; 9 | PrevId?: Schema.Types.ObjectId; 10 | Prize: number; 11 | } 12 | 13 | export interface IBTCChallengePoolModel extends Document, IBTCChallengePool {}; 14 | 15 | const btcChallengePoolSchema = new Schema({ 16 | StartTime: { type: Date, required: true }, 17 | EndTime: { type: Date, required: true }, 18 | StartPrice: { type: Number, required: true, default: 0 }, 19 | EndPrice: { type: Number, required: true, default: 0 }, 20 | NextId: { type: Schema.Types.ObjectId, ref: 'BTCChallengePool' }, 21 | PrevId: { type: Schema.Types.ObjectId, ref: 'BTCChallengePool' }, 22 | Prize: { type: Number, required: true, default: 0 } 23 | }); 24 | 25 | const BTCChallengePool = model('BTCChallengePool', btcChallengePoolSchema); 26 | 27 | export default BTCChallengePool; 28 | -------------------------------------------------------------------------------- /src/models/Balance.ts: -------------------------------------------------------------------------------- 1 | import { Schema, Document, model, Types } from 'mongoose' 2 | import { IUser } from './User' 3 | 4 | export interface IBalance extends Document { 5 | Balance: number 6 | Coin: number 7 | User: Types.ObjectId | IUser // Define a type for the user reference 8 | } 9 | 10 | const balanceSchema = new Schema({ 11 | Balance: { 12 | type: Number, 13 | default: 0, 14 | require: true, 15 | index: true, 16 | }, 17 | Coin: { 18 | type: Number, 19 | default: 0, 20 | require: true, 21 | index: true, 22 | }, 23 | User: { 24 | type: Schema.Types.ObjectId, 25 | ref: 'User', // Reference to the User model 26 | index: true 27 | }, 28 | }) 29 | 30 | export default model('Balance', balanceSchema) 31 | -------------------------------------------------------------------------------- /src/models/FutureBTCChallenge.ts: -------------------------------------------------------------------------------- 1 | import { Document, Schema, model } from 'mongoose'; 2 | import { IUser } from './User'; 3 | 4 | export interface IFutureBTCChallenge extends Document { 5 | User: Schema.Types.ObjectId | IUser; 6 | Position: number; 7 | BTCChallengePool: Schema.Types.ObjectId; 8 | Place: number; 9 | Reward: number; 10 | } 11 | 12 | const futureBTCChallengeSchema = new Schema({ 13 | User: { type: Schema.Types.ObjectId, ref: 'User', required: true }, 14 | Position: { type: Number, required: true }, 15 | BTCChallengePool: { type: Schema.Types.ObjectId, ref: 'BTCChallengePool', required: true }, 16 | Place: { type: Number }, 17 | Reward: { type: Number } 18 | }); 19 | 20 | const FutureBTCChallenge = model('FutureBTCChallenge', futureBTCChallengeSchema); 21 | 22 | export default FutureBTCChallenge; 23 | -------------------------------------------------------------------------------- /src/models/Nonce.ts: -------------------------------------------------------------------------------- 1 | import mongoose, { Document, Schema } from 'mongoose' 2 | 3 | export interface INonce extends Document { 4 | address: string 5 | nonce: string 6 | createdAt: Date 7 | } 8 | 9 | const NonceSchema: Schema = new Schema({ 10 | address: { 11 | type: String, 12 | required: true, 13 | unique: true, 14 | }, 15 | nonce: { 16 | type: String, 17 | required: true, 18 | }, 19 | createdAt: { 20 | type: Date, 21 | default: Date.now, 22 | }, 23 | }) 24 | 25 | export default mongoose.model('Nonce', NonceSchema) 26 | -------------------------------------------------------------------------------- /src/models/Record.ts: -------------------------------------------------------------------------------- 1 | import mongoose, { Schema, Document } from 'mongoose' 2 | 3 | // Define interface for the Record document 4 | export interface IRecord extends Document { 5 | recordId: string 6 | userId: mongoose.Types.ObjectId 7 | coinId: number 8 | createdAt: number 9 | status: string 10 | chain: string 11 | amount: number 12 | txId: string 13 | toAddress: string 14 | fromAddress: string 15 | type: string 16 | accepted: boolean 17 | } 18 | 19 | // Define schema for the Record document 20 | const recordSchema: Schema = new Schema({ 21 | recordId: { type: String, unique: true, index: true }, 22 | userId: { type: mongoose.Types.ObjectId, ref: 'User', index: true }, 23 | coinId: { type: Number }, 24 | createdAt: { type: Date, default: Date.now }, 25 | status: { type: String }, 26 | chain: { type: String }, 27 | amount: { type: Number }, 28 | txId: { type: String, unique: true }, 29 | toAddress: { type: String }, 30 | fromAddress: { type: String }, 31 | type: { type: String }, 32 | accepted: { type: Boolean, default: false }, 33 | }) 34 | 35 | // Create and export the Record model 36 | const Record = mongoose.model('Record', recordSchema) 37 | 38 | export default Record 39 | -------------------------------------------------------------------------------- /src/models/Reward.ts: -------------------------------------------------------------------------------- 1 | import mongoose, { Schema, Document, ObjectId } from 'mongoose' 2 | import { IUser } from './User' 3 | 4 | export interface IReward { 5 | user: ObjectId | IUser 6 | amount: number 7 | currency: string, 8 | description: string 9 | claimed: boolean 10 | CreatedAt?: Date 11 | } 12 | 13 | export interface IRewardModel extends Document, IReward {} 14 | 15 | const RewardSchema: Schema = new Schema({ 16 | user: { type: Schema.Types.ObjectId, ref: 'User', required: true, index: true }, 17 | amount: { type: Number, required: true }, 18 | currency: { type: String, require: true, enum: ['USDT', 'Coin'], }, 19 | description: { type: String, required: true }, 20 | claimed: { type: Boolean, default: false }, 21 | CreatedAt: { 22 | type: Date, 23 | default: Date.now, 24 | }, 25 | }) 26 | 27 | export default mongoose.model('Reward', RewardSchema) 28 | -------------------------------------------------------------------------------- /src/models/SecondChallenge.ts: -------------------------------------------------------------------------------- 1 | import { Document, Schema, model } from 'mongoose'; 2 | import { IUser } from './User'; 3 | 4 | interface ISecondChallenge extends Document { 5 | User: Schema.Types.ObjectId | IUser; 6 | Direction: boolean; 7 | BTCChallengePool: Schema.Types.ObjectId; 8 | Result: boolean; 9 | Reward: number; 10 | } 11 | 12 | const secondChallengeSchema = new Schema({ 13 | User: { type: Schema.Types.ObjectId, ref: 'User', required: true }, 14 | Direction: { type: Boolean, required: true }, 15 | BTCChallengePool: { type: Schema.Types.ObjectId, ref: 'BTCChallengePool', required: true }, 16 | Result: { type: Boolean }, 17 | Reward: { type: Number } 18 | }); 19 | 20 | const SecondChallenge = model('SecondChallenge', secondChallengeSchema); 21 | 22 | export default SecondChallenge; 23 | -------------------------------------------------------------------------------- /src/models/Transaction.ts: -------------------------------------------------------------------------------- 1 | import mongoose, { Schema, Document, Types } from 'mongoose' 2 | import { IUser } from './User' 3 | 4 | export interface ITransaction { 5 | TradeSize: number 6 | Direction: boolean 7 | Result?: boolean 8 | CreatedAt?: Date 9 | PoolId: string 10 | NewTotal: number 11 | CountryCode?: string 12 | Avatar?: string 13 | RoundId: string 14 | User: Schema.Types.ObjectId 15 | IsBot?: boolean 16 | } 17 | export interface ITransactionModel extends Document { 18 | TradeSize: number 19 | Direction: boolean 20 | Result: boolean 21 | CreatedAt?: Date 22 | RoundId: string 23 | PoolId: string 24 | User: Types.ObjectId | IUser // Define a type for the user reference 25 | } 26 | 27 | const TransactionSchema: Schema = new Schema({ 28 | TradeSize: { type: Number, required: true }, 29 | Direction: { type: Boolean, required: true }, 30 | Result: { type: Boolean, required: true }, 31 | CreatedAt: { type: Date, required: true, default: Date.now }, 32 | PoolId: { type: String, required: true }, 33 | RoundId: { type: String, require: true }, 34 | User: { type: Schema.Types.ObjectId, ref: 'User', index: true }, 35 | }) 36 | 37 | export default mongoose.model( 38 | 'Transaction', 39 | TransactionSchema 40 | ) 41 | -------------------------------------------------------------------------------- /src/models/User.ts: -------------------------------------------------------------------------------- 1 | export interface UserViewModel { 2 | Address: string 3 | Email?: string 4 | Avatar?: string 5 | ReferralLink: string 6 | CountryCode: string 7 | WhiteLabel?: string 8 | Enabled?: boolean 9 | WalletProvider: string 10 | Signature?: string 11 | CreatedAt?: number 12 | } 13 | 14 | import mongoose, { Document, Schema } from 'mongoose' 15 | 16 | export interface IUser extends Document { 17 | Address: string 18 | Username: string 19 | Email?: string 20 | Avatar?: string 21 | InvitedPath: string 22 | CountryCode: string 23 | WhiteLabel: string 24 | Enabled: boolean 25 | WalletProvider: string 26 | CreatedAt: Date 27 | Role: string 28 | } 29 | 30 | export interface IUserViewModel { 31 | Username: string 32 | UserId: string 33 | Avatar?: string 34 | CountryCode: string 35 | WhiteLabel?: string 36 | Role?: string 37 | } 38 | 39 | const userSchema: Schema = new Schema({ 40 | Address: { 41 | type: String, 42 | required: true, 43 | unique: true, 44 | }, 45 | Username: String, 46 | Email: String, 47 | Avatar: String, 48 | InvitedPath: { 49 | type: String, 50 | required: true, 51 | }, 52 | CountryCode: { 53 | type: String, 54 | required: true, 55 | }, 56 | WhiteLabel: String, 57 | Enabled: { 58 | type: Boolean, 59 | default: true, 60 | }, 61 | WalletProvider: { 62 | type: String, 63 | required: true, 64 | }, 65 | CreatedAt: { 66 | type: Date, 67 | default: Date.now, 68 | }, 69 | Role: { 70 | type: String, 71 | enum: [ 72 | 'admin', 73 | 'user', 74 | 'jackpot_weekly', 75 | 'jackpot_monthly', 76 | 'daily_contest', 77 | ], 78 | default: 'user', 79 | }, 80 | }) 81 | 82 | export default mongoose.model('User', userSchema) 83 | -------------------------------------------------------------------------------- /src/providers/AblyWss.ts: -------------------------------------------------------------------------------- 1 | import Ably from 'ably' 2 | import Locals from './Locals' 3 | import Log from '../api/middlewares/Log' 4 | 5 | class AblyWss { 6 | public ably: Ably.Types.RealtimePromise 7 | public ablyPublishApiKey: string 8 | public ablyChannelName: string 9 | 10 | constructor() { 11 | this.ablyPublishApiKey = Locals.config().ablyPublishApiKey 12 | this.ablyChannelName = Locals.config().ablyChannelName 13 | this.ably = new Ably.Realtime.Promise(this.ablyPublishApiKey) 14 | } 15 | 16 | public async init(): Promise { 17 | await this.ably.connection.once('connected') 18 | Log.info('Ably :: Connected!') 19 | 20 | return this.ably.channels.get(this.ablyChannelName) 21 | } 22 | } 23 | 24 | export default new AblyWss() 25 | -------------------------------------------------------------------------------- /src/providers/App.ts: -------------------------------------------------------------------------------- 1 | import Express from './Express' 2 | import GameRound from './GameRound' 3 | import Publisher from './Publisher' 4 | import Subscriber from './Subscriber' 5 | import Locals from './Locals' 6 | import MongoDBConnection from './MongoDBConnection' 7 | import { AffiliateType } from '../models/Affiliate' 8 | import { EventSchedule } from './EventSchedule' 9 | import { Dashboard } from './Dashboard' 10 | import { addReferralLink, getAffiliate } from '../api/services/AffiliateService' 11 | import Log from '../api/middlewares/Log' 12 | import { GlobalState } from './GlobalState' 13 | import User from '../models/User' 14 | import utils from '../utils/utils' 15 | import Balance from '../models/Balance' 16 | import TradingStatistics, { ITradingStatistics, ITradingStatisticsModel } from '../models/TradingStatistics' 17 | import { initialize } from './Initalilize' 18 | import { getTop100WinnersForThisMonth } from '../api/services/TradingStatisticsService' 19 | 20 | class App { 21 | // Loads your Server 22 | public async loadServer(): Promise { 23 | Log.info('Server:: Initialzing...') 24 | Express.init() 25 | 26 | // Create an instance of MongoDBConnection with the MongoDB URI 27 | const mongoConnection = MongoDBConnection.createInstance( 28 | Locals.config().mongodbURI 29 | ) 30 | 31 | // Connect to MongoDB 32 | await mongoConnection.connectToMongoDB() 33 | 34 | console.log("Connected to mongodb successfully!") 35 | 36 | // Initialize 37 | await initialize(); 38 | 39 | // Start Schedule Events 40 | EventSchedule.createInstance().start() 41 | Dashboard.loadAllTimeWinsPaidFile() 42 | 43 | 44 | require("./Challenges"); 45 | 46 | require("./DailyEvent"); 47 | 48 | const publisher: Publisher = Publisher.createInstance(Express.server) 49 | const subscriber: Subscriber = Subscriber.createInstance( 50 | Locals.config().binanceWss 51 | ) 52 | GlobalState.gameRound = GameRound.createInstance(publisher, subscriber) 53 | GlobalState.gameRound.start() 54 | } 55 | } 56 | 57 | export default new App() 58 | -------------------------------------------------------------------------------- /src/providers/BinanceWss.ts: -------------------------------------------------------------------------------- 1 | import { WebSocket } from 'ws' 2 | import Locals from './Locals' 3 | 4 | class BinanceWss { 5 | private binanceUrl 6 | private binanceWss: WebSocket 7 | public lastPrice: number 8 | 9 | constructor() { 10 | this.lastPrice = 0 11 | 12 | this.binanceUrl = Locals.config().binanceWss 13 | this.binanceWss = new WebSocket(this.binanceUrl) 14 | } 15 | 16 | public init(): void { 17 | this.binanceWss.on('message', (message: string) => { 18 | const data: any = JSON.parse(message) 19 | const lastPrice: number = parseFloat(data.p) 20 | this.lastPrice = lastPrice > 0 ? lastPrice : this.lastPrice 21 | }) 22 | } 23 | } 24 | 25 | export default BinanceWss 26 | -------------------------------------------------------------------------------- /src/providers/CoinManager/Interfaces/ICoinManager.ts: -------------------------------------------------------------------------------- 1 | export interface Network { 2 | chain: string 3 | chainFullName: string 4 | contract: string 5 | precision: number 6 | canDeposit: boolean 7 | canWithdraw: boolean 8 | minimumDepositAmount: string 9 | minimumWithdrawAmount: string 10 | maximumWithdrawAmount: string 11 | isSupportMemo: boolean 12 | } 13 | 14 | export interface Coin { 15 | coinId: number 16 | symbol: string 17 | logoUrl: string 18 | status: string 19 | networks: { [key: string]: Network } 20 | } 21 | 22 | export interface ApiResponse { 23 | code: number 24 | msg: string 25 | data: any 26 | } 27 | 28 | export interface Record { 29 | userId: string 30 | recordId: string 31 | orderId: string 32 | coinId: number 33 | chain: string 34 | contract: string 35 | coinSymbol: string 36 | txId: string 37 | fromAddress: string 38 | toAddress: string 39 | ToAddress?: string 40 | toMemo: string 41 | amount: string 42 | serviceFee: string 43 | status: string 44 | arrivedAt: number 45 | } 46 | 47 | export interface UserBalance { 48 | userId: string 49 | asset: { 50 | coinId: number 51 | coinSymbol: string 52 | available: string 53 | } 54 | } 55 | 56 | export enum WebHookMessageType { 57 | USER_DEPOSIT = 'UserDeposit', 58 | USER_WITHDRAWAL = 'UserWithdrawal', 59 | } 60 | 61 | export enum OrderStatus { 62 | SUCCESS = 'Success', 63 | PROCESSING = 'Processing', 64 | FAILED = 'Failed', 65 | WAITING_APPROVAL = 'WaitingApproval', 66 | SUBMITTED = 'Submitted', 67 | } 68 | 69 | export interface UserDeposit { 70 | recordId: string 71 | userId: string 72 | coinId: number 73 | coinSymbol: string 74 | amount: string 75 | status: string 76 | } 77 | -------------------------------------------------------------------------------- /src/providers/CoinManager/index.ts: -------------------------------------------------------------------------------- 1 | import CoinManager from './CoinManager' 2 | 3 | const coinManager: CoinManager = new CoinManager() 4 | -------------------------------------------------------------------------------- /src/providers/Dashboard.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs' 2 | import * as path from 'path' 3 | import { GlobalState } from './GlobalState' 4 | import utils from '../utils/utils' 5 | import { IFullStatistics, IRoundResult } from '../interfaces/IFullStatistics' 6 | import Log from '../api/middlewares/Log' 7 | 8 | export class Dashboard { 9 | public static gameStateDirectory: string = 'gameState' 10 | 11 | public static roundResults: Map = new Map() 12 | 13 | public static getLatestFullStatistics(poolId: string): IFullStatistics { 14 | const roundResults = this.roundResults.get(poolId) ?? [] 15 | 16 | return { 17 | AllTimeWinsPaid: GlobalState.allTimeWinsPaid, 18 | LivePlayersFor24H: GlobalState.livePlayersFor24H, 19 | WinRatioFor24H: GlobalState.winRatioFor24H, 20 | WinsPaidFor24H: GlobalState.winsPaidFor24H, 21 | RoundResult: roundResults.slice(-10), 22 | BtcPrices: GlobalState.btcPrices, 23 | ContestPrize: GlobalState.contestPrize, 24 | Traders: 25 | GlobalState.txnManager.getFilteredTransactionsByPoolId(poolId), 26 | Top100Winners: GlobalState.top100WinnersForToday 27 | } 28 | } 29 | 30 | public static saveWinsPaid(): void { 31 | const timestamp = utils.getTimestamp() 32 | const filename = `${timestamp}.json` 33 | const filePath = path.join(this.gameStateDirectory, filename) 34 | 35 | if (!fs.existsSync(this.gameStateDirectory)) { 36 | fs.mkdirSync(this.gameStateDirectory) 37 | } 38 | 39 | const data = JSON.stringify({ 40 | allTimeWinsPaid: GlobalState.allTimeWinsPaid, 41 | }) 42 | 43 | fs.writeFileSync(filePath, data, 'utf-8') 44 | 45 | // Remove excess files 46 | this.removeExcessFiles() 47 | } 48 | 49 | public static removeExcessFiles(): void { 50 | const files = fs.readdirSync(this.gameStateDirectory) 51 | const sortedFiles = files.sort((a, b) => { 52 | return ( 53 | fs 54 | .statSync(path.join(this.gameStateDirectory, b)) 55 | .mtime.getTime() - 56 | fs 57 | .statSync(path.join(this.gameStateDirectory, a)) 58 | .mtime.getTime() 59 | ) 60 | }) 61 | 62 | for (let i = 10; i < sortedFiles.length; i++) { 63 | const filePath = path.join(this.gameStateDirectory, sortedFiles[i]) 64 | fs.unlinkSync(filePath) 65 | } 66 | } 67 | 68 | public static getLatestAllTimeWinsPaidFile(): string { 69 | const files = fs.readdirSync(this.gameStateDirectory) 70 | const sortedFiles = files.sort((a, b) => { 71 | return ( 72 | fs 73 | .statSync(path.join(this.gameStateDirectory, b)) 74 | .mtime.getTime() - 75 | fs 76 | .statSync(path.join(this.gameStateDirectory, a)) 77 | .mtime.getTime() 78 | ) 79 | }) 80 | 81 | return path.join(this.gameStateDirectory, sortedFiles[0]) 82 | } 83 | 84 | public static loadAllTimeWinsPaidFile(): void { 85 | try { 86 | const latestFile = this.getLatestAllTimeWinsPaidFile() 87 | const data = fs.readFileSync(latestFile, 'utf-8') 88 | 89 | GlobalState.allTimeWinsPaid = JSON.parse(data).allTimeWinsPaid 90 | } catch (error) { 91 | Log.error(`Dashboard :: loadAllTimeWinsPaidFile${error}`) 92 | } 93 | } 94 | 95 | public static addRoundResult( 96 | startPrice: number, 97 | endPrice: number, 98 | roundId: string, 99 | poolId: string 100 | ) { 101 | let poolRoundResults = this.roundResults.get(poolId) 102 | if (!poolRoundResults) { 103 | poolRoundResults = [] 104 | this.roundResults.set(poolId, poolRoundResults) 105 | } 106 | 107 | poolRoundResults.push({ startPrice, endPrice, roundId }) 108 | 109 | if (poolRoundResults.length > 20) { 110 | poolRoundResults = poolRoundResults.slice(-20) 111 | this.roundResults.set(poolId, poolRoundResults) 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/providers/DynamoDB.ts: -------------------------------------------------------------------------------- 1 | import { DynamoDBClient } from '@aws-sdk/client-dynamodb' 2 | 3 | export class DynamoDBConnection { 4 | public static client = new DynamoDBClient({ 5 | region: 'local', 6 | endpoint: 'http://localhost:8000', 7 | }) 8 | } 9 | -------------------------------------------------------------------------------- /src/providers/EventSchedule.ts: -------------------------------------------------------------------------------- 1 | import { GlobalState } from './GlobalState' 2 | import { IFullStatistics } from '../interfaces/IFullStatistics' 3 | import { Dashboard } from './Dashboard' 4 | import { getFullStatistics } from '../api/services/TransactionService' 5 | import Locals from './Locals' 6 | import { getHighRollersForToday, getTop100WinnersForAllTime, getTop100WinnersForThisMonth, getTop100WinnersForThisWeek, getTop100WinnersForToday, getTopWinRatioPlayers } from '../api/services/TradingStatisticsService' 7 | import Balance from '../models/Balance' 8 | 9 | export class EventSchedule { 10 | public async fullStatistics() { 11 | const { success, data, error } = await getFullStatistics() 12 | 13 | if (success && data) { 14 | GlobalState.livePlayersFor24H = ( 15 | data as IFullStatistics 16 | ).LivePlayersFor24H 17 | GlobalState.winRatioFor24H = ( 18 | data as IFullStatistics 19 | ).WinRatioFor24H 20 | GlobalState.winsPaidFor24H = ( 21 | data as IFullStatistics 22 | ).WinsPaidFor24H 23 | } 24 | 25 | // console.log("Jackpot Address: ", this.jackpotAddress); 26 | GlobalState.contestPrize = 27 | (await Balance.findOne({User: GlobalState.weeklyChallengeUser._id}))?.Balance || 0; 28 | 29 | GlobalState.highRollers = await getHighRollersForToday(); 30 | 31 | GlobalState.top100WinnersForToday = await getTop100WinnersForToday(); 32 | GlobalState.topWinRatioPlayers = await getTopWinRatioPlayers(); 33 | // GlobalState.top100WinnersForThisWeek = await getTop100WinnersForThisWeek(); 34 | // GlobalState.top100WinnersForThisMonth = await getTop100WinnersForThisMonth(); 35 | // GlobalState.top100WinnersForAllTime = await getTop100WinnersForAllTime(); 36 | 37 | } 38 | 39 | public runFullStatisticsSchedule() { 40 | this.fullStatistics() 41 | setInterval(this.fullStatistics, 1 * 60 * 1000) 42 | } 43 | 44 | // start schedule 45 | public start() { 46 | this.runFullStatisticsSchedule() 47 | } 48 | 49 | // create instance 50 | static createInstance(): EventSchedule { 51 | return new EventSchedule() 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/providers/Express.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents the Express server configuration and initialization. 3 | * Author: Isom D. 4 | */ 5 | 6 | import express from 'express'; 7 | import Locals from './Locals'; 8 | import ExceptionHandler from '../exception/Handler'; 9 | import Routes from './Routes'; 10 | import Https from 'https'; // Import HTTPS module 11 | import { Server as HttpsServer } from 'https'; // Import HTTPS Server type 12 | import Http, { Server as HttpServer } from 'http' 13 | import Kernel from '../api/middlewares/Kernel'; 14 | import Log from '../api/middlewares/Log'; 15 | import path from 'path'; 16 | import fs from 'fs'; 17 | 18 | class Express { 19 | public express: express.Application; 20 | public server: HttpsServer | HttpServer; 21 | 22 | /** 23 | * Initializes the Express server with middleware and routes. 24 | */ 25 | public constructor() { 26 | this.express = express(); 27 | 28 | // const privateKeyPath = path.join("src/providers/ssl", "private.key"); 29 | // const certPath = path.join("src/providers/ssl", "certificate.crt"); 30 | // this.server = Https.createServer({ // Create HTTPS server 31 | // key: fs.readFileSync(privateKeyPath), 32 | // cert: fs.readFileSync(certPath) 33 | // }, this.express); 34 | 35 | this.server = Http.createServer(this.express); 36 | 37 | this.mountDotEnv(); 38 | this.mountMiddlewares(); 39 | this.mountRoutes(); 40 | } 41 | 42 | /** 43 | * Mounts environment variables. 44 | */ 45 | private mountDotEnv(): void { 46 | this.express = Locals.init(this.express); 47 | } 48 | 49 | /** 50 | * Mounts middleware to the Express app. 51 | */ 52 | private mountMiddlewares(): void { 53 | this.express = Kernel.init(this.express); 54 | } 55 | 56 | /** 57 | * Mounts API routes to the Express app. 58 | */ 59 | private mountRoutes(): void { 60 | this.express = Routes.mountApi(this.express); 61 | } 62 | 63 | /** 64 | * Initializes the Express server and starts listening on the configured port. 65 | */ 66 | public init(): any { 67 | const port: number = Locals.config().port; 68 | 69 | const publicPath = path.resolve(__dirname, '../../public'); 70 | this.express.use(express.static(publicPath)); 71 | 72 | // Registering Exception & Error Handlers 73 | this.express.use(ExceptionHandler.logErrors); 74 | this.express.use(ExceptionHandler.clientErrorHandler); 75 | this.express.use(ExceptionHandler.errorHandler); 76 | this.express = ExceptionHandler.notFoundHandler(this.express); 77 | 78 | // Start the server on the specified port 79 | this.server 80 | .listen(port, () => { 81 | return Log.info(`Express :: Running @ 'https://0.0.0.0:${port}'`); // Change protocol to HTTPS 82 | }) 83 | .on('error', (_error) => { 84 | return Log.error(`Express :: Error: ${_error.message}`); 85 | }); 86 | } 87 | } 88 | 89 | /** Export the Express module */ 90 | export default new Express(); 91 | -------------------------------------------------------------------------------- /src/providers/GlobalState.ts: -------------------------------------------------------------------------------- 1 | import IBtcPrice from '../interfaces/IBtcPrice' 2 | import { IHightRoller } from '../interfaces/IHighRoller' 3 | import { ITop100Winner } from '../interfaces/ITop100Winner' 4 | import { ITopWinRatioPlayer } from '../interfaces/ITopWinRatio' 5 | import { IBTCChallengePool, IBTCChallengePoolModel } from '../models/BTCChallengePool' 6 | import { IUser } from '../models/User' 7 | import { Bot } from './Bot' 8 | import CoinManager from './CoinManager/CoinManager' 9 | import GameRound from './GameRound' 10 | import Transaction from './Transaction' 11 | 12 | export class GlobalState { 13 | 14 | public static coinPerRank = [1000, 900, 800, 700, 600, 500, 400, 300, 200, 100] 15 | public static ratePerRankInChallenge = [0.5, 0.25, 0.125, 0.083, 0.042] 16 | 17 | 18 | public static btcPrices: Array = [] 19 | public static stop: boolean = false 20 | public static stopBot: boolean = false 21 | public static winRatioFor24H: number = 0 22 | public static allTimeWinsPaid: number = 0 23 | public static livePlayersFor24H: number = 0 24 | public static winsPaidFor24H: number = 0 25 | public static contestPrize: number = 0 26 | 27 | public static txnManager: Transaction = Transaction.createInstance() 28 | 29 | public static coinManager = new CoinManager() 30 | public static gameRound: GameRound 31 | 32 | public static admin: IUser | null 33 | 34 | // public static jackpotMonthlyUser: IUser | null 35 | 36 | // public static jackpotWeeklyUser: IUser | null 37 | 38 | public static weeklyChallengeUser: IUser 39 | 40 | public static highRollers: IHightRoller[] = [] 41 | public static topWinRatioPlayers: ITopWinRatioPlayer[] = [] 42 | 43 | public static top100WinnersForToday: ITop100Winner[] = []; 44 | public static top100WinnersForThisWeek: ITop100Winner[] = []; 45 | public static top100WinnersForThisMonth: ITop100Winner[] = []; 46 | public static top100WinnersForAllTime: ITop100Winner[] = []; 47 | 48 | public static botPlayers: Bot = new Bot() 49 | 50 | public static currentChallengeRound: IBTCChallengePoolModel | null = null; 51 | public static nextChallengeRound: IBTCChallengePoolModel | null = null; 52 | public static lastExpredChallengeRound: IBTCChallengePoolModel | null = null; 53 | } 54 | -------------------------------------------------------------------------------- /src/providers/Initalilize.ts: -------------------------------------------------------------------------------- 1 | import { addReferralLink, getAffiliate } from "../api/services/AffiliateService" 2 | import { AffiliateType } from "../models/Affiliate" 3 | import Balance from "../models/Balance" 4 | import TradingStatistics from "../models/TradingStatistics" 5 | import User from "../models/User" 6 | import utils from "../utils/utils" 7 | import { GlobalState } from "./GlobalState" 8 | import Locals from "./Locals" 9 | 10 | export const initialize = async () => { 11 | const adminExists = await User.findOne({ Role: 'admin' }).exec() 12 | const dailyContest = await User.findOne({ 13 | Role: 'daily_contest', 14 | }).exec() 15 | 16 | const rootAffiliate = Locals.config().rootAffiliate 17 | 18 | if (!dailyContest) { 19 | const weeklyChallengeUser = new User({ 20 | Address: '0x000003', 21 | Email: '', 22 | Avatar: `${Locals.config().ipfsBaseUrl}/${utils.getRandomInteger(1, 12)}.png`, 23 | InvitedPath: `${rootAffiliate}#${rootAffiliate}#${rootAffiliate}`, 24 | CountryCode: 'CH', 25 | WhiteLabel: 'trade2earn', 26 | Enabled: true, 27 | WalletProvider: 'web3', 28 | CreatedAt: new Date(), 29 | Role: 'daily_contest', 30 | }) 31 | 32 | await weeklyChallengeUser.save() 33 | 34 | const dailyContestBalance = new Balance({ 35 | User: weeklyChallengeUser._id, 36 | Balance: 0, 37 | Coin: 0, 38 | }) 39 | 40 | await dailyContestBalance.save() 41 | 42 | GlobalState.weeklyChallengeUser = weeklyChallengeUser 43 | } else { 44 | GlobalState.weeklyChallengeUser = dailyContest 45 | } 46 | 47 | // If admin doesn't exist, create a new admin user 48 | if (!adminExists) { 49 | const adminUser = new User({ 50 | Address: 51 | Locals.config().rootAffiliateWalletAddress.toLowerCase(), 52 | Email: '', 53 | Avatar: `${Locals.config().ipfsBaseUrl}/${utils.getRandomInteger(1, 12)}.png`, 54 | InvitedPath: `${rootAffiliate}#${rootAffiliate}#${rootAffiliate}`, 55 | CountryCode: 'CH', 56 | WhiteLabel: 'trade2earn', 57 | Enabled: true, 58 | WalletProvider: 'web3', 59 | CreatedAt: new Date(), 60 | Role: 'admin', 61 | }) 62 | 63 | await adminUser.save() 64 | 65 | const adminBalance = new Balance({ 66 | User: adminUser._id, 67 | Balance: 0, 68 | }) 69 | 70 | await adminBalance.save() 71 | 72 | // creates TradingStatistics 73 | const newTradingStatistics = new TradingStatistics({ 74 | User: adminUser._id, // Replace 'userId' with the actual user ID 75 | }) 76 | 77 | await newTradingStatistics.save() 78 | 79 | const { success, data: affiliate } = await getAffiliate( 80 | Locals.config().rootAffiliate 81 | ) 82 | 83 | if (success && affiliate == null) { 84 | await addReferralLink( 85 | adminUser._id, 86 | AffiliateType.PARTNERSHIP, 87 | Locals.config().rootAffiliate, 88 | Locals.config().rootAffiliate 89 | ) 90 | } 91 | } else { 92 | GlobalState.admin = adminExists 93 | } 94 | } -------------------------------------------------------------------------------- /src/providers/MongoDBConnection.ts: -------------------------------------------------------------------------------- 1 | import mongoose from 'mongoose' 2 | import { GlobalState } from './GlobalState' 3 | import Log from '../api/middlewares/Log' 4 | 5 | class MongoDBConnection { 6 | private uri: string 7 | 8 | constructor(uri: string) { 9 | this.uri = uri 10 | } 11 | 12 | public async connectToMongoDB(): Promise { 13 | try { 14 | await mongoose.connect(this.uri) 15 | Log.info('MongoDBConnection :: Connected to MongoDB') 16 | } catch (error) { 17 | Log.error( 18 | `MongoDBConnection :: Error connecting to MongoDB:${error}` 19 | ) 20 | GlobalState.stop = false 21 | } 22 | } 23 | 24 | static createInstance(uri: string): MongoDBConnection { 25 | return new MongoDBConnection(uri) 26 | } 27 | } 28 | 29 | export default MongoDBConnection 30 | -------------------------------------------------------------------------------- /src/providers/Routes.ts: -------------------------------------------------------------------------------- 1 | import { Application } from 'express' 2 | import Locals from './Locals' 3 | import ApiRoutes from '../api/routes/ApiRoutes' 4 | import Log from '../api/middlewares/Log' 5 | 6 | class Routes { 7 | public mountApi(_express: Application): Application { 8 | const apiPrefix = Locals.config().apiPrefix 9 | Log.info('Route :: Mounting API Routes...') 10 | 11 | return _express.use(`/${apiPrefix}`, ApiRoutes.router) 12 | } 13 | } 14 | 15 | export default new Routes() 16 | -------------------------------------------------------------------------------- /src/providers/Subscriber.ts: -------------------------------------------------------------------------------- 1 | import WebSocket from 'ws' 2 | import Log from '../api/middlewares/Log' 3 | 4 | class Subscriber { 5 | public ws: WebSocket | null = null 6 | public lastData: string = '' 7 | 8 | constructor(private wssUrl: string) { 9 | this.reconnect() 10 | } 11 | 12 | static createInstance(wssUrl: string): Subscriber { 13 | return new Subscriber(wssUrl) 14 | } 15 | 16 | public reconnect(): void { 17 | this.connect() 18 | setTimeout(() => this.reconnect(), 1000 * 60 * 15) 19 | } 20 | 21 | public connect(): void { 22 | this.ws = new WebSocket(this.wssUrl) 23 | 24 | // Event: WebSocket connection is established 25 | this.ws.on('open', () => { 26 | Log.info('Subscriber :: WebSocket Client connection established') 27 | }) 28 | 29 | this.ws.onclose = (event) => { 30 | // Abnormal closure, attempt to reconnect 31 | setTimeout(() => this.connect(), 2000) // Adjust delay as needed 32 | } 33 | 34 | // Event: Received a message from the server 35 | this.ws.on('message', (data: WebSocket.Data) => { 36 | this.lastData = data.toString() 37 | }) 38 | 39 | this.ws.onerror = (error) => { 40 | // Handle errors 41 | Log.error(`Subscriber :: WebSocket Error: ${error.message}`) 42 | } 43 | } 44 | } 45 | 46 | export default Subscriber 47 | -------------------------------------------------------------------------------- /src/providers/ssl/ca_bundle.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIG1TCCBL2gAwIBAgIQbFWr29AHksedBwzYEZ7WvzANBgkqhkiG9w0BAQwFADCB 3 | iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl 4 | cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV 5 | BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMjAw 6 | MTMwMDAwMDAwWhcNMzAwMTI5MjM1OTU5WjBLMQswCQYDVQQGEwJBVDEQMA4GA1UE 7 | ChMHWmVyb1NTTDEqMCgGA1UEAxMhWmVyb1NTTCBSU0EgRG9tYWluIFNlY3VyZSBT 8 | aXRlIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAhmlzfqO1Mdgj 9 | 4W3dpBPTVBX1AuvcAyG1fl0dUnw/MeueCWzRWTheZ35LVo91kLI3DDVaZKW+TBAs 10 | JBjEbYmMwcWSTWYCg5334SF0+ctDAsFxsX+rTDh9kSrG/4mp6OShubLaEIUJiZo4 11 | t873TuSd0Wj5DWt3DtpAG8T35l/v+xrN8ub8PSSoX5Vkgw+jWf4KQtNvUFLDq8mF 12 | WhUnPL6jHAADXpvs4lTNYwOtx9yQtbpxwSt7QJY1+ICrmRJB6BuKRt/jfDJF9Jsc 13 | RQVlHIxQdKAJl7oaVnXgDkqtk2qddd3kCDXd74gv813G91z7CjsGyJ93oJIlNS3U 14 | gFbD6V54JMgZ3rSmotYbz98oZxX7MKbtCm1aJ/q+hTv2YK1yMxrnfcieKmOYBbFD 15 | hnW5O6RMA703dBK92j6XRN2EttLkQuujZgy+jXRKtaWMIlkNkWJmOiHmErQngHvt 16 | iNkIcjJumq1ddFX4iaTI40a6zgvIBtxFeDs2RfcaH73er7ctNUUqgQT5rFgJhMmF 17 | x76rQgB5OZUkodb5k2ex7P+Gu4J86bS15094UuYcV09hVeknmTh5Ex9CBKipLS2W 18 | 2wKBakf+aVYnNCU6S0nASqt2xrZpGC1v7v6DhuepyyJtn3qSV2PoBiU5Sql+aARp 19 | wUibQMGm44gjyNDqDlVp+ShLQlUH9x8CAwEAAaOCAXUwggFxMB8GA1UdIwQYMBaA 20 | FFN5v1qqK0rPVIDh2JvAnfKyA2bLMB0GA1UdDgQWBBTI2XhootkZaNU9ct5fCj7c 21 | tYaGpjAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHSUE 22 | FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwIgYDVR0gBBswGTANBgsrBgEEAbIxAQIC 23 | TjAIBgZngQwBAgEwUAYDVR0fBEkwRzBFoEOgQYY/aHR0cDovL2NybC51c2VydHJ1 24 | c3QuY29tL1VTRVJUcnVzdFJTQUNlcnRpZmljYXRpb25BdXRob3JpdHkuY3JsMHYG 25 | CCsGAQUFBwEBBGowaDA/BggrBgEFBQcwAoYzaHR0cDovL2NydC51c2VydHJ1c3Qu 26 | Y29tL1VTRVJUcnVzdFJTQUFkZFRydXN0Q0EuY3J0MCUGCCsGAQUFBzABhhlodHRw 27 | Oi8vb2NzcC51c2VydHJ1c3QuY29tMA0GCSqGSIb3DQEBDAUAA4ICAQAVDwoIzQDV 28 | ercT0eYqZjBNJ8VNWwVFlQOtZERqn5iWnEVaLZZdzxlbvz2Fx0ExUNuUEgYkIVM4 29 | YocKkCQ7hO5noicoq/DrEYH5IuNcuW1I8JJZ9DLuB1fYvIHlZ2JG46iNbVKA3ygA 30 | Ez86RvDQlt2C494qqPVItRjrz9YlJEGT0DrttyApq0YLFDzf+Z1pkMhh7c+7fXeJ 31 | qmIhfJpduKc8HEQkYQQShen426S3H0JrIAbKcBCiyYFuOhfyvuwVCFDfFvrjADjd 32 | 4jX1uQXd161IyFRbm89s2Oj5oU1wDYz5sx+hoCuh6lSs+/uPuWomIq3y1GDFNafW 33 | +LsHBU16lQo5Q2yh25laQsKRgyPmMpHJ98edm6y2sHUabASmRHxvGiuwwE25aDU0 34 | 2SAeepyImJ2CzB80YG7WxlynHqNhpE7xfC7PzQlLgmfEHdU+tHFeQazRQnrFkW2W 35 | kqRGIq7cKRnyypvjPMkjeiV9lRdAM9fSJvsB3svUuu1coIG1xxI1yegoGM4r5QP4 36 | RGIVvYaiI76C0djoSbQ/dkIUUXQuB8AL5jyH34g3BZaaXyvpmnV4ilppMXVAnAYG 37 | ON51WhJ6W0xNdNJwzYASZYH+tmCWI+N60Gv2NNMGHwMZ7e9bXgzUCZH5FaBFDGR5 38 | S9VWqHB73Q+OyIVvIbKYcSc2w/aSuFKGSA== 39 | -----END CERTIFICATE----- 40 | -------------------------------------------------------------------------------- /src/providers/ssl/certificate.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIGcDCCBFigAwIBAgIRAOQroRdCMPtHelIb+p4m7fgwDQYJKoZIhvcNAQEMBQAw 3 | SzELMAkGA1UEBhMCQVQxEDAOBgNVBAoTB1plcm9TU0wxKjAoBgNVBAMTIVplcm9T 4 | U0wgUlNBIERvbWFpbiBTZWN1cmUgU2l0ZSBDQTAeFw0yNDA1MTMwMDAwMDBaFw0y 5 | NDA4MTEyMzU5NTlaMBQxEjAQBgNVBAMTCWhpeGxvLmZ1bjCCASIwDQYJKoZIhvcN 6 | AQEBBQADggEPADCCAQoCggEBAKVrotIW8/pboscnFdvcdj0YCzm0f7ZkymVFNyCo 7 | giKObE/DTjY6s3wAo0szQlKk1Mo7YZLaKAv9IJ9d6NzEGJGiROvWF5nKNu/D6oXJ 8 | ERH/GTyB5HSQ2ZIXhAYMGpWvR/dGBgyuaMImUVRCyKePdi7kvhg0F3ZPzGJ94P5g 9 | 4zPcXbPX4U5dAL/Xpf4mq/EpW8lTJcgwcWJB4k/jlr+/ulEgSwbjWKvgAkm0Kt3N 10 | Qa2quP+CUD8ubBFp9Ei3pjkp1QrOGAv9rFjMkhsdIcAnWd+2cPmVpqxpeg8H/SVI 11 | P9DSuNy9XZs5B8cUoesdwXdkb9ETdfmqUc1O4Iwb7hlIaLkCAwEAAaOCAoQwggKA 12 | MB8GA1UdIwQYMBaAFMjZeGii2Rlo1T1y3l8KPty1hoamMB0GA1UdDgQWBBQA3U1v 13 | N6SxcBbg8H/ieqPipeiSzzAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADAd 14 | BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwSQYDVR0gBEIwQDA0BgsrBgEE 15 | AbIxAQICTjAlMCMGCCsGAQUFBwIBFhdodHRwczovL3NlY3RpZ28uY29tL0NQUzAI 16 | BgZngQwBAgEwgYgGCCsGAQUFBwEBBHwwejBLBggrBgEFBQcwAoY/aHR0cDovL3pl 17 | cm9zc2wuY3J0LnNlY3RpZ28uY29tL1plcm9TU0xSU0FEb21haW5TZWN1cmVTaXRl 18 | Q0EuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vemVyb3NzbC5vY3NwLnNlY3RpZ28u 19 | Y29tMIIBBAYKKwYBBAHWeQIEAgSB9QSB8gDwAHYAdv+IPwq2+5VRwmHM9Ye6NLSk 20 | zbsp3GhCCp/mZ0xaOnQAAAGPcFyPsAAABAMARzBFAiEApRrhYjcqmxZV8qvHKBba 21 | DBDaKM5hn0/GnbY9+TdHB3MCICTp7mF9wlUd9dXs7gFRLt+LLrgEmE+cHufu9TYB 22 | PY5rAHYAPxdLT9ciR1iUHWUchL4NEu2QN38fhWrrwb8ohez4ZG4AAAGPcFyPfAAA 23 | BAMARzBFAiEA1vCHgLrcYYKoMcbQFRBsp4zSQ5DhVlZOqsGI5dgAOkkCIDB/UPmn 24 | mkvjz7Dfk/gTN1aDVIxqGWbu/RCu0kOboYo4MCMGA1UdEQQcMBqCCWhpeGxvLmZ1 25 | boINd3d3LmhpeGxvLmZ1bjANBgkqhkiG9w0BAQwFAAOCAgEANC/QC3j14OtPVSBW 26 | tJZp9EM+T7Hg3ujDhulQeOW2V9Y0gaeO2pCTLL1ASDVLzy5KepRNHc1dMCN8bOnG 27 | xaRDkZ6A3k/5fXcLbJua2O4pJ08PKhxC2AZz80/ibWMVtgsBIQH86msaySbYZOD0 28 | 5zZIOMJ1041R6zkRsB/DBy6lGhFJxf/ykd5PwjwvjfGxy7ka03v7qexpADi+7V4o 29 | erzKjk4We19aWdiuunicbjj7dGD/WJzrX5YZJgxRJdo+GYTITn6yF9qiWyYXRTAr 30 | e+ycy72hgbp1roY7JdfPofE7MEgyAu+UfnSUqVYktNlDC7HUuTek0sLzMz9UVHG2 31 | IE4JPx5N3iA+6ofSNlsWxpqQmfB+AFw8LgYkHNk5sLStQpA96tIPxN6cjtaPPHQ6 32 | Wc/vuFCP2T8h5VTSKD0MsiP2kIh4H82udsedXO6pgx+lF9NY49hunn6IxoBbT9LO 33 | KLg2n2G/f6WRLET89vRcWhV0rTb8VijHalvkXgZexHi3sqY3UiXBapl871xed9fn 34 | NdOrUEPsWykM6sc0qZ+Tdy8E1VhZWIka+Tf1IZGyBLUkVzKfxVj9PvC3V6jxrtRr 35 | 11Fd7cRrrRD1CtpJM86HiUwQnCkRnVn03pOhRlI9wVRqwkP3XCMOjkYAH9yJrdpH 36 | d1bhBDospgiL37FuNncQt4xpPi8= 37 | -----END CERTIFICATE----- 38 | --------------------------------------------------------------------------------