Dev.to AI 🤖 Ai 👁 0 📖 3 min read

Designing a Telegram Swap Bot That's Hard to Impersonate

Telegram mini apps have passed 100 million monthly active users, according to the TON Foundation. For anyone building crypto services there, that distribution comes with a problem: your bot is trivially easy to imitate.

Telegram mini apps have passed 100 million monthly active users, according to the TON Foundation. For anyone building crypto services there, that distribution comes with a problem: your bot is trivially easy to imitate.

Scam Sniffer documented a campaign using a fake verification bot named OfficiaISafeguardBot, with a capital I in place of a lowercase l. Nothing in the Telegram UI stops that. You can't prevent lookalikes. What you can do is design your service so that impersonating it is harder, and so that users have a reliable way to tell the difference.

These notes assume a deposit-address swap flow: the user sends a specific amount to an address generated for their order and receives the output at an address they specify.

1. Minimize what the user hands over

The single biggest security decision is the custody model:

Model User hands over Worst case if impersonated or compromised
Bot-held wallet Private key Entire wallet
Connect + sign Approvals / signatures Whatever was approved
Deposit address One transaction's amount That transaction

A deposit-address flow means your bot never needs a seed phrase, a private key, or a token approval. Say that explicitly in the bot's description and first message. It turns "the bot asked for my seed phrase" into an instant, unambiguous red flag for your users.

2. Make the website the root of trust

Users can't verify a bot by how it looks. They can verify where the link came from.

  • Publish your exact bot username on your website
  • Put "Open in Telegram" deep links only on your own domain
  • Repeat the canonical website in the bot's description and about text, so users see it from both directions

Telegram deep links let you pass a start parameter of up to 64 characters from A-Z, a-z, 0-9, _ and -. You can use that to connect orders created on the website to the bot, and sign the payload so the bot only accepts links your backend issued:

import crypto from "node:crypto";

const SECRET = process.env.START_LINK_SECRET;

function sign(orderId) {
  return crypto
    .createHmac("sha256", SECRET)
    .update(orderId)
    .digest("base64url")
    .slice(0, 22);
}

// orderId: alphanumeric only, max ~40 chars, so the payload stays under 64
export function buildStartLink(botUsername, orderId) {
  return `https://t.me/${botUsername}?start=${orderId}_${sign(orderId)}`;
}

export function parseStartPayload(payload) {
  const i = payload.lastIndexOf("_");
  if (i <= 0) return null;

  const orderId = payload.slice(0, i);
  const received = Buffer.from(payload.slice(i + 1));
  const expected = Buffer.from(sign(orderId));

  if (received.length !== expected.length) return null;
  return crypto.timingSafeEqual(received, expected) ? orderId : null;
}

This doesn't stop a copycat bot from existing. It means the official bot shows the same order ID and the same deposit address the user just saw on the website, which gives them something concrete to cross-check.

3. Let users verify the deposit address outside Telegram

The core attack against a deposit-address flow is a fake bot showing an attacker's address. The defense is a second channel:

  • Every order gets an ID shown in both the bot and the Mini App
  • The website has an order lookup page that displays the deposit address for that ID
  • The bot's instructions tell users to confirm the address matches before sending

It adds one step for cautious users and costs you almost nothing.

4. Use the fact that bots can't message first

A Telegram bot can't start a conversation with a user who hasn't started it. That's a useful property to teach:

  • State in your onboarding that official support never messages first
  • Never have human support initiate DMs from personal accounts either, or you train users to accept exactly the pattern scammers rely on

5. Never build a "verification" step that runs anything

The fake Safeguard campaign worked because users were conditioned to expect verification gates in crypto groups. If your community uses a verification bot, make sure it never asks users to paste commands, install anything, or visit an external page to "prove they're human."

6. Reduce the value of a stale screenshot

Scammers reuse screenshots of real interfaces. Include dynamic details in order confirmations: order ID, creation time, and quote expiry. A static fake is easier to spot when the real thing is visibly specific.

Disclosure: written by the NefiSwap team. NefiSwap's Telegram Mini App and bot use a deposit-address flow that never requests keys or approvals, and the official way to open them is from nefiswap.com.

📰 Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.