DEV Community

TateLyman
TateLyman

Posted on

5 Ways to Monetize a Telegram Bot (With Code Examples)

Telegram bots can make real money. Not "maybe someday" money — actual recurring revenue from day one.

I run @solscanitbot, a Solana trading and analytics bot with 44 commands, 12 background workers, and multiple revenue streams. In this article, I'll break down the five monetization strategies I use, with actual code for each one.


1. Transaction Fees (1% Per Swap)

If your bot executes trades, take a small cut. Users expect this — every trading platform charges fees. The key is keeping it low enough that nobody cares (1% or less) while processing enough volume that it adds up.

How It Works

When a user swaps tokens through your bot, you modify the transaction to split the output: 99% goes to the user, 1% goes to your fee wallet.

const FEE_WALLET = new PublicKey('NaTTUfDDQ8U1RBqb9q5rz6vJ22cWrrT5UAsXuxnb2Wr');
const FEE_PERCENTAGE = 0.01; // 1%

async function executeSwapWithFee(userWallet, tokenIn, tokenOut, amountIn) {
  // Get the swap quote from Jupiter
  const quoteUrl = `https://quote-api.jup.ag/v6/quote?inputMint=${tokenIn}&outputMint=${tokenOut}&amount=${amountIn}&slippageBps=100`;
  const quote = await fetch(quoteUrl).then(r => r.json());

  const outputAmount = parseInt(quote.outAmount);
  const feeAmount = Math.floor(outputAmount * FEE_PERCENTAGE);
  const userAmount = outputAmount - feeAmount;

  // Build the swap transaction
  const swapResponse = await fetch('https://quote-api.jup.ag/v6/swap', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      quoteResponse: quote,
      userPublicKey: userWallet.toString(),
      dynamicComputeUnitLimit: true,
    }),
  }).then(r => r.json());

  // Deserialize and add fee transfer instruction
  const transaction = VersionedTransaction.deserialize(
    Buffer.from(swapResponse.swapTransaction, 'base64')
  );

  // Add SOL fee transfer instruction
  const feeInstruction = SystemProgram.transfer({
    fromPubkey: userWallet,
    toPubkey: FEE_WALLET,
    lamports: feeAmount,
  });

  // Sign and send
  transaction.sign([userKeypair]);
  const signature = await connection.sendTransaction(transaction);

  await logFee(userWallet.toString(), feeAmount, signature);
  return { signature, userAmount, feeAmount };
}
Enter fullscreen mode Exit fullscreen mode

Revenue Potential

With 100 users each making 5 swaps/day averaging 0.5 SOL per swap:

  • Daily fee revenue: 100 x 5 x 0.5 x 0.01 = 2.5 SOL/day
  • Monthly: ~75 SOL/month

Fees scale linearly with user activity. Even modest usage generates meaningful income.


2. Premium Subscriptions (On-Chain SOL Verification)

Gate advanced features behind a subscription. Verify payment entirely on-chain — no payment processor needed, no recurring billing headaches.

How It Works

Users send SOL to your wallet. Your bot verifies the transaction on the Solana blockchain and unlocks premium for 30 days.

const { Connection, PublicKey, LAMPORTS_PER_SOL } = require('@solana/web3.js');

const PREMIUM_PRICE_SOL = 0.5;
const PREMIUM_DURATION_MS = 30 * 24 * 60 * 60 * 1000; // 30 days

async function verifyPremiumPayment(userId, txSignature) {
  const connection = new Connection(process.env.SOL_RPC_URL, 'confirmed');

  try {
    const tx = await connection.getParsedTransaction(txSignature, {
      maxSupportedTransactionVersion: 0,
    });

    if (!tx || tx.meta?.err) {
      return { success: false, error: 'Transaction failed or not found' };
    }

    // Verify the transfer went to our fee wallet
    for (const instruction of tx.transaction.message.instructions) {
      if (
        instruction.programId.toString() === '11111111111111111111111111111111' &&
        instruction.parsed?.type === 'transfer' &&
        instruction.parsed.info.destination === FEE_WALLET.toString()
      ) {
        const solAmount = instruction.parsed.info.lamports / LAMPORTS_PER_SOL;

        if (solAmount >= PREMIUM_PRICE_SOL * 0.98) {
          // Activate premium
          const expiresAt = Date.now() + PREMIUM_DURATION_MS;
          await savePremiumStatus(userId, {
            active: true,
            expiresAt,
            txSignature,
            paidSol: solAmount,
          });

          return {
            success: true,
            expiresAt,
            message: `Premium activated until ${new Date(expiresAt).toLocaleDateString()}`,
          };
        }
      }
    }

    return { success: false, error: 'No matching payment found in transaction' };
  } catch (err) {
    return { success: false, error: err.message };
  }
}

// Telegram command handler
bot.onText(/\/premium (.+)/, async (msg, match) => {
  const userId = msg.from.id;
  const txSignature = match[1].trim();

  const result = await verifyPremiumPayment(userId, txSignature);

  if (result.success) {
    bot.sendMessage(msg.chat.id, `Premium activated! ${result.message}`);
  } else {
    bot.sendMessage(msg.chat.id, `Verification failed: ${result.error}`);
  }
});
Enter fullscreen mode Exit fullscreen mode

Middleware for Premium-Gating

Create a simple check to gate any command:

function requirePremium(handler) {
  return async (msg, match) => {
    const status = await getPremiumStatus(msg.from.id);
    if (!status?.active || status.expiresAt < Date.now()) {
      return bot.sendMessage(
        msg.chat.id,
        `This feature requires Premium (${PREMIUM_PRICE_SOL} SOL/month).\nSend SOL to:\n\`${FEE_WALLET}\`\nThen run: /premium <tx_signature>`
      );
    }
    return handler(msg, match);
  };
}

// Usage
bot.onText(/\/alpha/, requirePremium(async (msg) => {
  const signals = await getAlphaSignals();
  bot.sendMessage(msg.chat.id, formatSignals(signals));
}));
Enter fullscreen mode Exit fullscreen mode

3. Paid Features (Token Promotions & Volume Bot)

Beyond subscriptions, sell individual features. Two that work particularly well in crypto bots: token promotions and volume boosting.

Token Promotions

Token creators pay to have their project featured in your bot's alerts or discovery feeds.

const PROMO_TIERS = {
  basic: { price: 0.5, duration: 24 * 60 * 60 * 1000, position: 'sidebar' },
  featured: { price: 1.0, duration: 48 * 60 * 60 * 1000, position: 'top' },
  premium: { price: 2.5, duration: 7 * 24 * 60 * 60 * 1000, position: 'pinned' },
};

bot.onText(/\/promote (\w+) (\w+)/, async (msg, match) => {
  const tokenMint = match[1];
  const tier = match[2].toLowerCase();

  if (!PROMO_TIERS[tier]) {
    return bot.sendMessage(msg.chat.id, 'Invalid tier. Options: basic, featured, premium');
  }

  const promo = PROMO_TIERS[tier];

  bot.sendMessage(
    msg.chat.id,
    `Promote ${tokenMint}\n` +
    `Tier: ${tier} (${promo.duration / 3600000}h)\n` +
    `Cost: ${promo.price} SOL\n\n` +
    `Send ${promo.price} SOL to:\n\`${FEE_WALLET}\`\n` +
    `Then reply with the TX signature.`
  );

  // Listen for the TX reply
  const listener = async (reply) => {
    if (reply.from.id !== msg.from.id) return;
    const sig = reply.text.trim();
    const verified = await verifyPayment(sig, promo.price);

    if (verified) {
      await savePromotion({
        tokenMint,
        tier,
        expiresAt: Date.now() + promo.duration,
        bookedBy: msg.from.id,
      });
      bot.sendMessage(msg.chat.id, `Promotion live! ${tokenMint} is now ${tier} promoted.`);
    }
    bot.removeListener('message', listener);
  };

  bot.on('message', listener);
  setTimeout(() => bot.removeListener('message', listener), 300000); // 5 min timeout
});
Enter fullscreen mode Exit fullscreen mode

Volume Bot (Bump Service)

Some token projects want to generate trading volume. Offer a bump service where the bot executes small trades at intervals.

const BUMP_PRICE_PER_HOUR = 0.3; // SOL

async function runBumpSession(tokenMint, durationHours, solPerTrade) {
  const intervalMs = 60000; // trade every minute
  const totalTrades = durationHours * 60;
  let tradesExecuted = 0;

  const interval = setInterval(async () => {
    if (tradesExecuted >= totalTrades) {
      clearInterval(interval);
      return;
    }

    try {
      // Alternate buy/sell to create volume without net position change
      const side = tradesExecuted % 2 === 0 ? 'buy' : 'sell';
      await executeSwap(side, tokenMint, solPerTrade);
      tradesExecuted++;
    } catch (err) {
      console.error('Bump trade failed:', err.message);
    }
  }, intervalMs);

  return { interval, totalTrades };
}
Enter fullscreen mode Exit fullscreen mode

4. Referral Programs (3-Tier System)

Referrals are free marketing. Give referrers a cut of the fees generated by people they bring in — and make it multi-tier to incentivize network growth.

const REFERRAL_TIERS = {
  tier1: 0.30, // 30% of fees from direct referrals
  tier2: 0.10, // 10% of fees from their referrals
  tier3: 0.05, // 5% of fees from third-level referrals
};

async function processReferralFees(userId, feeAmountLamports) {
  const referralChain = await getReferralChain(userId); // returns [tier1Id, tier2Id, tier3Id]
  const payouts = [];

  for (let i = 0; i < referralChain.length && i < 3; i++) {
    const referrerId = referralChain[i];
    if (!referrerId) continue;

    const tierKey = `tier${i + 1}`;
    const payoutLamports = Math.floor(feeAmountLamports * REFERRAL_TIERS[tierKey]);

    if (payoutLamports > 0) {
      await creditReferralBalance(referrerId, payoutLamports);
      payouts.push({ referrerId, tier: tierKey, amount: payoutLamports });
    }
  }

  return payouts;
}

// Track referrals when new users start the bot
bot.onText(/\/start(.*)/, async (msg, match) => {
  const userId = msg.from.id;
  const referralCode = match[1]?.trim();

  if (referralCode) {
    const referrerId = await getUserByReferralCode(referralCode);
    if (referrerId && referrerId !== userId) {
      await saveReferral(userId, referrerId);
      bot.sendMessage(msg.chat.id, `You were referred by a friend! You both benefit from reduced fees.`);
    }
  }

  // Generate this user's own referral link
  const userCode = generateReferralCode(userId);
  bot.sendMessage(
    msg.chat.id,
    `Welcome! Your referral link:\nhttps://t.me/solscanitbot?start=${userCode}\n\n` +
    `Earn 30% of trading fees from anyone you refer, 10% from their referrals, and 5% from the third tier.`
  );
});

// Withdrawal command
bot.onText(/\/withdraw/, async (msg) => {
  const userId = msg.from.id;
  const balance = await getReferralBalance(userId);

  if (balance < 10000000) { // minimum 0.01 SOL
    return bot.sendMessage(msg.chat.id, `Minimum withdrawal: 0.01 SOL. Your balance: ${balance / LAMPORTS_PER_SOL} SOL`);
  }

  const userWallet = await getUserWallet(userId);
  if (!userWallet) {
    return bot.sendMessage(msg.chat.id, 'Set your withdrawal wallet first: /setwallet <address>');
  }

  const sig = await sendSol(userWallet, balance);
  await resetReferralBalance(userId);
  bot.sendMessage(msg.chat.id, `Sent ${balance / LAMPORTS_PER_SOL} SOL!\nTX: ${sig}`);
});
Enter fullscreen mode Exit fullscreen mode

Why 3 Tiers?

Single-tier referrals plateau quickly. Multi-tier creates exponential growth incentives. Tier 1 users actively recruit because their earnings multiply when their referrals also bring people in.

The economics work because the total referral payout (30% + 10% + 5% = 45% max) comes out of your 1% trading fee — so you're giving up 0.45% to acquire and retain users, which is extremely efficient.


5. White-Labeling (Sell the Source Code)

Once your bot is proven and profitable, sell the entire source code as a product. Other developers will pay a premium for a working, battle-tested codebase instead of building from scratch.

How to Package It

Strip out your API keys, write setup instructions, and sell it as a zip file.

// Simple licensing system built into the bot
const LICENSE_KEY = process.env.LICENSE_KEY;

function validateLicense() {
  if (!LICENSE_KEY) {
    console.error('No license key found. Get one at https://devtools-site-delta.vercel.app/sol-bot-source');
    process.exit(1);
  }

  // Verify against your licensing API
  const response = await fetch(`https://your-api.com/verify-license?key=${LICENSE_KEY}`);
  const data = await response.json();

  if (!data.valid) {
    console.error('Invalid license key.');
    process.exit(1);
  }

  console.log(`License valid. Registered to: ${data.owner}`);
}

validateLicense();
Enter fullscreen mode Exit fullscreen mode

Pricing Strategy

Price based on proven revenue, not lines of code:

What You're Selling Price Point Justification
Full bot source code 2 SOL Months of development time saved
Grid trading bot 0.5 SOL Automated trading strategy
DeFi toolkit scripts 0.3 SOL 10 ready-to-use scripts
Prompt templates 0.1 SOL Low-effort digital good

I sell the complete source code for @solscanitbot at devtools-site-delta.vercel.app/sol-bot-source for 2 SOL. Buyers get 4,300+ lines of production Node.js code, all 44 commands, the referral system, the volume bot — everything discussed in this article.

Delivery Automation

Use the same HMAC token system from my Solana payments article to deliver the zip file automatically after on-chain payment verification. No manual fulfillment needed.


Revenue Stack Summary

Here's how these five streams combine:

Stream Type Effort to Implement
Trading fees Passive, per-transaction Medium
Premium subscriptions Recurring, monthly Low
Paid features (promos, bumps) One-time, per-use Medium
Referral program Growth + retention Medium
White-label source code One-time, high-margin Low (already built)

The beauty is that each stream reinforces the others. Referrals bring users who generate trading fees and buy premium. Premium users are more engaged and use paid features. And when the bot is successful enough, you can sell the whole thing as a product.


Getting Started

If you're building a Telegram bot and want to see all of this in action:

Start with trading fees (they require the least user buy-in), add premium subscriptions once you have 50+ daily active users, and layer in referrals and paid features as you grow.

The code in this article is production-tested. Adapt it, deploy it, and start earning.


Got questions about bot monetization? Drop a comment or reach out on Telegram.

Top comments (0)