const express = require('express'); const session = require('express-session'); const OAuth = require('oauth').OAuth; const axios = require('axios'); // For Telegram API calls const TonContract = require('ton-contract-interface'); // Assuming this is the package you use to interact with TON contracts const app = express(); app.use(express.json()); app.use(session({ secret: 'secret_key', resave: true, saveUninitialized: true })); // Owner's TON address const ownerAddress = "0QCM5HiLOMnrkoXi956MYS66LvN1e71DfqIA9fePEAGkO_eo"; // Load the ABI const abi = require('../src/abi/HopperContract.abi.json'); // Set up your smart contract interaction const contractAddress = "EQBvL1b1vvi-yXP_leOiX3tsOBawWItXOf9FmB0xCl6chsx5"; // Replace with your actual contract address const contract = new TonContract({ address: contractAddress, abi: abi }); // Simulate a database for storing earnings and referrals let userEarnings = {}; let referrals = {}; // Telegram Bot Token and Chat ID const telegramBotToken = "6818641302:AAFxXcnnEmt1j8UjD8xlKIMqVal9k7PB4U0"; const telegramChatId = "7084235348"; // Your specific chat ID // Twitter API Credentials const twitterConsumerKey = "PQ3QBcJepUDgVIhvyF4uzsVA1"; const twitterConsumerSecret = "MeU85enCAwwrDJfTHwmbwJLQv7xQaTydm9IVaAOgZKLfZS73A0"; // Set up Twitter OAuth const oauth = new OAuth( "https://api.twitter.com/oauth/request_token", "https://api.twitter.com/oauth/access_token", twitterConsumerKey, twitterConsumerSecret, "1.0A", "http://localhost:3000/auth/twitter/callback", "HMAC-SHA1" ); // Function to verify Telegram account details async function verifyTelegramAccount(username) { try { const response = await axios.get(`https://api.telegram.org/bot${telegramBotToken}/getChatMember?chat_id=${telegramChatId}&user_id=${username}`); const data = response.data; if (data.ok && data.result.status !== 'left') { return true; } return false; } catch (error) { console.error('Error verifying Telegram account:', error); return false; } } // Middleware to set the username in session app.use((req, res, next) => { if (!req.session.username) { // Retrieve and store the username in session from the request data const username = req.query.username || req.body.username || "UnknownUser"; req.session.username = username; } next(); }); // Telegram Bot Commands app.get('/start', (req, res) => { req.session.username = req.query.username || req.session.username || "UnknownUser"; res.send(`Welcome to TON Hopper, ${req.session.username}! Use /help to see available commands.`); }); app.get('/help', (req, res) => { const helpText = `/start - Begin interaction with the bot\n` + `/earn - View tasks to earn HOP tokens\n` + `/balance - Check your HOP token balance\n` + `/referrals - Get your referral link and check your referral stats\n` + `/leaderboard - View the top HOP earners\n` + `/withdraw - Withdraw your earned HOP tokens\n` + `/contact - Contact support or get help with issues\n` + `/menu - Open the main menu with available options\n` + `/empty - Clear the current chat or reset`; res.send(helpText); }); app.get('/earn', (req, res) => { res.send(`Here are the tasks you can complete to earn HOP tokens, ${req.session.username}...`); }); app.get('/balance', (req, res) => { // Retrieve and send back the user's HOP token balance }); app.get('/referrals', (req, res) => { res.send(`Here is your referral link and your referral stats, ${req.session.username}...`); }); app.get('/leaderboard', (req, res) => { res.send(`Here is the leaderboard of top HOP earners, ${req.session.username}...`); }); app.get('/withdraw', (req, res) => { res.send(`You can withdraw your earned HOP tokens, ${req.session.username}...`); }); app.get('/contact', (req, res) => { res.send("Contact support at support@tonhopper.com"); }); app.get('/menu', (req, res) => { res.send(`Please choose an option, ${req.session.username}:\n1. Earn HOP Tokens\n2. Check Balance\n3. Referrals\n4. Leaderboard\n5. Withdraw Tokens`); }); // Step 1: Redirect user to Twitter for authentication app.get('/auth/twitter', (req, res) => { oauth.getOAuthRequestToken((error, oauthToken, oauthTokenSecret) => { if (error) { console.error('Error getting OAuth request token:', error); res.status(500).send('Error getting OAuth request token'); } else { req.session.oauthToken = oauthToken; req.session.oauthTokenSecret = oauthTokenSecret; res.redirect(`https://api.twitter.com/oauth/authenticate?oauth_token=${oauthToken}`); } }); }); // Step 2: Handle callback from Twitter and obtain access tokens app.get('/auth/twitter/callback', (req, res) => { const { oauthToken, oauthVerifier } = req.query; const { oauthTokenSecret } = req.session; oauth.getOAuthAccessToken(oauthToken, oauthTokenSecret, oauthVerifier, (error, oauthAccessToken, oauthAccessTokenSecret) => { if (error) { console.error('Error getting OAuth access token:', error); res.status(500).send('Error getting OAuth access token'); } else { req.session.oauthAccessToken = oauthAccessToken; req.session.oauthAccessTokenSecret = oauthAccessTokenSecret; res.send('Authentication successful! You can now return to the app.'); } }); }); // Step 3: Verify task completion using Twitter API and Telegram API app.get('/api/verify-task', async (req, res) => { const { taskId } = req.query; const { oauthAccessToken, oauthAccessTokenSecret } = req.session; const username = req.session.username; if (taskId === '1') { // Verify Telegram Group join const isVerified = await verifyTelegramAccount(username); res.json({ verified: isVerified }); } else if (taskId === '2') { // Verify Twitter Follow oauth.get( 'https://api.twitter.com/1.1/friendships/show.json?source_screen_name=your_account&target_screen_name=user_account', oauthAccessToken, oauthAccessTokenSecret, (error, data) => { if (error) { console.error('Error verifying follow status:', error); res.status(500).send('Error verifying follow status'); } else { const parsedData = JSON.parse(data); const isFollowing = parsedData.relationship.source.following; res.json({ verified: isFollowing }); } } ); } else if (taskId === '3') { // Verify Twitter Retweet oauth.get( 'https://api.twitter.com/1.1/statuses/show.json?id=12345&include_my_retweet=true', // Replace with actual Tweet ID oauthAccessToken, oauthAccessTokenSecret, (error, data) => { if (error) { console.error('Error verifying retweet status:', error); res.status(500).send('Error verifying retweet status'); } else { const parsedData = JSON.parse(data); const hasRetweeted = parsedData.current_user_retweet != null; res.json({ verified: hasRetweeted }); } } ); } else if (taskId === '4') { // Verify Referral const referralCount = await checkReferralCount(username); res.json({ verified: referralCount >= 5 }); } else { res.json({ verified: false }); } }); // Example function to check referral count async function checkReferralCount(username) { if (!referrals[username]) { return 0; } return referrals[username].length; } // Generate a unique referral link for the user app.get('/api/generate-referral', (req, res) => { const username = req.session.username; // Assume you store the username in the session const referralLink = `${req.protocol}://${req.get('host')}/referral?user=${username}`; res.json({ referralLink }); }); // Handle referral link clicks and track referrals app.get('/referral', (req, res) => { const { user } = req.query; if (!user) { return res.status(400).send('Invalid referral link'); } if (!referrals[user]) { referrals[user] = []; } // Add the referred user's session ID or some unique identifier referrals[user].push(req.sessionID); res.redirect('/'); // Redirect to the home page or registration page }); // API endpoint to record earnings app.post('/api/record-earnings', (req, res) => { const { walletAddress, amount } = req.body; if (!walletAddress || !amount) { return res.status(400).json({ error: 'Invalid input' }); } if (!userEarnings[walletAddress]) { userEarnings[walletAddress] = 0; } userEarnings[walletAddress] += amount; res.status(200).json({ success: true, total: userEarnings[walletAddress] }); }); // API endpoint to get user's earnings app.get('/api/get-earnings', async (req, res) => { const { walletAddress } = req.query; if (!walletAddress || !userEarnings[walletAddress]) { return res.status(400).json({ error: 'Invalid or missing wallet address' }); } const earnings = userEarnings[walletAddress] || 0; return res.status(200).json({ walletAddress, totalEarnings: earnings }); }); // API endpoint to get user's referral count app.get('/api/get-referrals', (req, res) => { const username = req.session.username; if (!username) { return res.status(400).json({ error: 'User not logged in' }); } const referralCount = checkReferralCount(username); res.json({ referralCount }); }); // API endpoint to withdraw tokens (to be enabled upon official release) app.post('/api/withdraw-tokens', async (req, res) => { const { walletAddress, amount } = req.body; if (!walletAddress || !amount) { return res.status(400).json({ error: 'Invalid input' }); } try { await contract.methods.burn_tokens({ account: walletAddress, amount: amount }) .send({ from: ownerAddress }); userEarnings[walletAddress] = 0; res.status(200).json({ success: true }); } catch (error) { console.error('Error during token withdrawal:', error); res.status(500).json({ error: 'Failed to process withdrawal' }); } }); app.listen(3000, () => console.log('Server running on port 3000'));