How to build a Solana Telegram trading bot: the infrastructure guide

Written by:

Maksym Bogdan

13

min read

Date:

August 3, 2026

Updated on:

August 3, 2026

TL;DR

→  A Solana Telegram trading bot is three tiers: a Telegram interface, a backend that manages wallets and builds trades, and the Solana execution layer. The demo is a weekend of work; the production version is an infrastructure problem.

→  The whole appeal is speed. Paste an address, tap a button, filled in seconds instead of the 30-second wallet-and-DEX dance. On a launch, ten seconds of delay can be a very different entry price.

→  The bot has under 70 ms of server-side budget from command to submission before the Jupiter quote goes stale and the fill drifts from what the user saw. Most of that budget is spent on the RPC path.

→  Key handling is what users judge you on. Per-user keypair, private key encrypted at rest, decrypted only in memory to sign, exportable on demand. Plaintext keys or one shared hot wallet is how bots drain and die.

→  Use webhooks in production, not long polling. Webhooks push each update instantly and scale behind a load balancer; polling adds latency and is for local dev.

→  Scale with a queue, not inline execution. Redis-backed job queue, idempotency keys per trade, and timeout-plus-retry on stuck submissions. This is what prevents double-fills and silent misses under load.

→  Off-the-shelf Telegram bots plateau at 35–68% landing on competitive launches because they run on public RPC. A custom bot on dedicated infrastructure clears the 85% line. The bot logic is commoditized; the infrastructure is the edge.

A Solana Telegram trading bot does something deceptively simple: a user pastes a token address, taps buy, and a few seconds later they hold the token. No wallet popup, no DEX tab, no signing dance. The core flow really is a weekend of work: receive a command, get a Jupiter quote, sign a transaction, submit it, reply with the result.

But the gap between that weekend demo and a bot people trust with real money is entirely infrastructure. It is the wallet security model, the submission path that decides whether trades land during a launch, the queue that keeps a thousand concurrent users from double-filling each other, and the RPC layer underneath all of it. 

This guide walks through the whole build, with the infrastructure decisions that separate a bot that works in testing from one that works when the network is on fire.

The architecture: three tiers

Every Solana Telegram trading bot, from a hobby project to Trojan, is the same three tiers. Getting the boundaries between them right is most of the battle.

The three tiers of a Solana Telegram trading bot: the Telegram interface, the backend that manages wallets and builds trades, and the Solana execution layer. Each tier is only as fast as the one below it.

The Telegram interface is the thinnest tier. You register a bot with BotFather to get an API token, and from then on Telegram delivers user messages to your backend and relays your replies. Commands like /buy, /sell, and /snipe plus inline buttons are the entire surface the user sees.

The backend is where everything real happens: a command router that parses intent and validates input, a wallet manager that holds each user's keypair, an execution engine that turns an intent into a signed transaction, and a job queue with state in Redis. Frameworks like grammY or the raw Telegram Bot API handle the message plumbing so you can focus on the trading logic.

The Solana execution layer is where trades land or die: Jupiter for swap routing across DEXs, a dedicated RPC for blockhashes and submission, Jito bundles for MEV protection, and priority fees to stay included during congestion. This is the tier that determines your landing rate, and the one most tutorials skip.

The execution pipeline: from /buy to filled

When a user taps buy, a specific sequence runs, and every step is on the clock. The user sees one tap; the bot sees a latency budget.

The execution pipeline from command to confirmed fill. The server-side hot path (parse, quote, build, submit) has under 70 ms before the quote goes stale and the fill drifts from the price the user saw.

Here is the core of a buy handler. The message plumbing is abstracted; the trading logic is the point:

// /buy <mint> <amountSol> — the hot path
bot.command('buy', async (ctx) => {
  const [mint, amountSol] = parseArgs(ctx.message.text);
  const user = await users.get(ctx.from.id);
 
  // 1. Risk checks BEFORE spending latency on a quote
  if (!passesRiskFilters(mint, amountSol, user)) return ctx.reply('Blocked by risk rules');
 
  // 2. Jupiter quote — best route across DEXs
  const quote = await jupiter.quote({
    inputMint: SOL, outputMint: mint,
    amount: toLamports(amountSol), slippageBps: user.slippageBps,
  });
 
  // 3. Build a versioned tx with a priority fee
  const tx = await jupiter.swapTx({
    quote, userPublicKey: user.pubkey,
    prioritizationFeeLamports: user.priorityFee,   // do not skip this
  });
 
  // 4. Sign in memory, submit through the dedicated RPC / Jito
  tx.sign([await wallet.decryptKeypair(user.id)]);
  const sig = await submitWithRetry(tx, { timeoutMs: 3000 });
 
  await ctx.reply(sig ? `Filled: ${explorer(sig)}` : 'Trade did not land, funds untouched');
});

Three things in that handler are non-obvious and matter. Risk checks run before the quote, so a blocked trade costs no latency. The priority fee is set explicitly, because Solana's fee market drops transactions that underpay during congestion, which is exactly when launches happen. And submission goes through a retry wrapper with a timeout, which we will come back to, because it is where the expensive bugs live.

Wallet and key security: the part that earns trust

The clean architecture is not what makes or breaks a Telegram bot. Trust is. Nobody funds a bot they think will drain them, and the key-handling model is where that trust is won or lost. Most Telegram bots are custodial in practice: the bot generates and holds a keypair for each user.

The custodial key model most Telegram bots use, and the handling rules that separate a trustworthy bot from one that drains its users. Encrypt at rest, decrypt only in memory, let users export.

The rules are not negotiable, and they are the difference between a bot people fund and one that ends up on a scam list:

  • Generate a keypair per user, never one shared hot wallet. Shared custody means one compromise drains everyone.
  • Encrypt the private key at rest with a per-user secret backed by a KMS. The database should hold ciphertext, never a plaintext key.
  • Decrypt only in memory, only to sign, and never write the plaintext key to logs, error traces, or backups. Most key leaks are accidental, through observability, not attacks.
  • Let users export their key. A bot that holds your funds and will not give you the key is indistinguishable from a scam. Exportability is the single strongest trust signal you can offer.
  • Add withdrawal limits and confirmations for large trades, and validate the swap target before signing so a malformed or malicious mint cannot be traded into blindly.

Here is the shape of the encrypt-at-rest, decrypt-in-memory pattern. The plaintext key exists only inside the signing function and is never returned, logged, or persisted:

// Wallet store: ciphertext in the DB, plaintext only in memory to sign
import { Keypair } from '@solana/web3.js';
 
async function createUserWallet(userId) {
  const kp = Keypair.generate();
  const dek = await kms.generateDataKey(userId);        // per-user data key
  const ciphertext = aesGcmEncrypt(kp.secretKey, dek.plaintext);
  await db.wallets.put({
    userId,
    pubkey: kp.publicKey.toBase58(),
    secretCiphertext: ciphertext,        // never the raw key
    wrappedDek: dek.ciphertext,          // KMS-wrapped, unwrap only to sign
  });
  return kp.publicKey.toBase58();
}
 
async function decryptKeypair(userId) {
  const row = await db.wallets.get(userId);
  const dek = await kms.decrypt(row.wrappedDek);         // unwrap in memory
  const secret = aesGcmDecrypt(row.secretCiphertext, dek);
  return Keypair.fromSecretKey(secret);   // lives only for this call
}

This is also where non-custodial designs are worth considering. They are harder to build and give a worse UX, but they remove your server as a single point of catastrophic failure. For most bots the custodial model wins on UX, which makes disciplined key handling the price of that choice.

Your bot is only as fast as the RPC underneath it

RPC Fast runs dedicated bare-metal Solana nodes co-located with validators, with Jito bundle routing and SWQoS-staked submission built in. Free SaaS tier, no credit card. Point your bot's endpoint at it and watch the landing rate move.

→ Start free at rpcfast.com

Receiving updates: webhooks, not polling

There are two ways for Telegram to get a user's message to your bot, and the choice has real latency and scaling consequences for a trading bot.

Long polling versus webhooks. Polling repeatedly asks Telegram for updates and adds latency; webhooks push each update the instant it arrives and scale behind a load balancer.

With long polling, your bot repeatedly calls getUpdates and Telegram answers when there is something to deliver. It is trivial to run and needs no public URL, which makes it perfect for local development. But it adds poll latency and does not scale horizontally, because two instances polling the same bot fight over updates.

With webhooks, you register an HTTPS endpoint and Telegram pushes each update to it the instant a message arrives. That is lower latency and scales cleanly behind a load balancer, at the cost of needing a public HTTPS endpoint with valid TLS. For anything handling real trades, use webhooks in production and keep polling for your dev loop.

Submission and the stuck-transaction problem

The single biggest gap between a bot that works in testing and one that works in production lives in submission. In a demo, you submit a transaction and it confirms. In production, during congestion, a transaction can be accepted by the network and then sit unconfirmed, neither landing nor failing within your expected window.

Handled naively, this produces one of two expensive failures. If the bot assumes the trade failed and resubmits, it can double-fill, buying twice and costing the user money. If it assumes success and moves on, it can silently miss the trade and generate a furious support ticket. Both are common, and both are avoidable with explicit timeout and retry logic:

// Submit with a bounded retry and an idempotency guard
async function submitWithRetry(tx, { timeoutMs }) {
  const idem = idempotencyKey(tx);            // one logical trade = one key
  if (await alreadyInFlight(idem)) return null; // never double-submit
 
  await markInFlight(idem);
  const sig = await rpc.sendTransaction(tx, { maxRetries: 0 }); // we own retries
 
  const deadline = Date.now() + timeoutMs;
  while (Date.now() < deadline) {
    const status = await rpc.getSignatureStatus(sig);
    if (status?.confirmationStatus === 'confirmed') { await clear(idem); return sig; }
    if (status?.err) { await clear(idem); return null; }
    await sleep(200);                          // poll, do not resubmit blindly
  }
  await clear(idem);
  return null;   // timed out: report honestly, funds are safe
}

The idempotency key is what makes this safe: one logical trade maps to one key, so a re-queued or double-tapped job can never fill twice. Owning the retry loop yourself, rather than letting the RPC blindly resend, is what lets you poll for real confirmation using getSignatureStatus and report an honest outcome. Reading at processed commitment gives you the freshest possible status.

Scaling past your first user

A bot firing transactions inline, one at a time, in the message handler, falls over the moment it has real users. Two people buying the same launch in the same second will collide over blockhashes, nonces, and RPC connections. The fix is structural.

Scaling architecture: a Redis-backed job queue feeds a pool of execution workers that share a dedicated RPC connection pool. Idempotency keys and bounded retries prevent double-fills and silent misses.

The production pattern is a job queue between the command handler and execution. The handler validates and enqueues; a pool of workers pulls jobs and runs the build-sign-submit hot path. This gives you three things inline execution cannot: per-user ordering so a user's sells never race their buys, backpressure so a launch spike queues instead of crashing, and a natural place to attach idempotency and retry logic.

  • State in Redis, not in memory. In-memory user state dies with the process and cannot be shared across workers. Redis is the default for a reason.
  • A dedicated RPC connection pool with a fresh-blockhash cache, so a hundred concurrent trades are not each doing a cold round-trip for a blockhash.
  • Idempotency keys per trade and timeout-plus-retry on every submission, applied at the worker level so every path through the system is protected.

This is also where the RPC layer stops being a detail. Every worker is competing for the same blockspace as every other bot during a launch, and the submission path decides who lands. Shared or public RPC is the bottleneck the whole architecture above it is waiting on.

Production-readiness checklist

Before a Solana Telegram bot touches real user funds, these are the checks that separate a demo from a service people trust:

  • Keys encrypted at rest, decrypted only in memory, with export enabled and plaintext keys provably absent from logs, traces, and backups.
  • Webhooks in production, behind a load balancer with valid TLS, and long polling confined to local dev.
  • A job queue with per-user ordering, idempotency keys, and bounded timeout-plus-retry on every submission, so no trade can double-fill or silently vanish under load.
  • Risk filters before the quote: per-token caps, mint validation, honeypot and sell-restriction checks, and slippage bounds enforced server-side.
  • A dedicated RPC endpoint with a fresh-blockhash cache and a staked submission path, monitored on landing rate and slot lag, not just uptime.
  • Honest failure reporting: a timed-out trade tells the user their funds are untouched, never a false confirmation.

Why infrastructure decides the outcome

The Telegram bot landscape in 2026 is crowded, and the popular pre-built options all share one design choice: they run on public or shared RPC. That choice is invisible in casual use and decisive during a competitive launch.

Pre-built Telegram bots Custom bot on dedicated RPC
RPC path Public / shared Dedicated, validator-adjacent
Landing rate on competitive launches 35–68% over 85%
Data freshness Polling / public endpoints gRPC stream, processed commitment
MEV protection Limited or none Jito bundles, staked submission
Control over slot timing None Full

The landing-rate gap is the whole story. A pre-built bot that lands 50% of competitive trades and a custom bot that lands 90% are running similar logic against the same launches. The difference is not the strategy or the code. It is that one is submitting through crowded public infrastructure and the other is validator-adjacent with a staked path. On the same trade, that gap is the entire margin between profitable and not.

This is the reason to build custom rather than wrap a pre-built bot: not because the trading logic is hard, but because you cannot fix another bot's RPC path. When you own the stack, the infrastructure becomes a lever you can pull. When you rent it, you inherit whatever landing rate the crowd gets.

What actually matters

Building a Solana Telegram trading bot is mostly infrastructure work wearing a chat interface. The Telegram tier is thin, the trading logic is a solved problem with Jupiter, and the code that impresses in a demo is the easy 20 percent. The hard, valuable 80 percent is the wallet security model that earns trust, the submission logic that survives congestion without double-filling, the queue that scales past one user, and the RPC path that decides your landing rate.

If your bot works flawlessly in testing and then misses trades and frustrates users the moment a real launch hits, the problem is not your command parser. It is the infrastructure underneath, and specifically the submission path. That is the layer worth investing in, because it is the layer your users feel on every single trade.

Build the bot. We'll handle the RPC.

RPC Fast gives Solana trading bots dedicated bare-metal nodes co-located with validators, Yellowstone gRPC, ShredStream, and Jito bundle routing on a SaaS plan. Start on the free tier, no credit card, plug the endpoint into your bot, and benchmark your landing rate against public RPC on the first live launch.

→ Start for free at rpcfast.com
Table of Content

The fastest Solana RPC for MEV, HFT, and AI agents

Private nodes with gRPC, raw streams, and sub-ms latency.

Test for free
More articles

Infrastructure

All

Written by:

Maksym Bogdan

Date:

03 Aug 26

11

min read

Guide

All

Written by:

Olha Diachuk

Date:

31 Jul 26

11

min read

We use cookies to personalize your experience