Chains, links and limits
Chains, links and limits
The buy bot's 9 supported chains, how each of the 11 link tokens resolves to a URL, and every buy-bot limit confirmed in source.
The 9 supported chains
The buy bot recognizes a contract address on 9 chains across 4 address families: 6 EVM chains (Ethereum, BNB Chain, Base, PulseChain, HyperEVM, Robinhood Chain), plus Solana, TON and Sui.
The six EVM chains validate against the same address shape — 0x + 40 hex characters, case-insensitive, no EIP-55 checksum — so the address alone never names which of the six a token is on. Solana, TON and Sui each have a distinct shape and are inferred automatically.
| Chain | Address validation | Explorer | Chart providers |
|---|---|---|---|
| Ethereum | 0x + 40 hex chars — shared by all 6 EVM chains, not chain-specific | Etherscan | DexScreener (ethereum) · GeckoTerminal (eth) · Dextools (ether) |
| BNB Chain | 0x + 40 hex chars — shared by all 6 EVM chains, not chain-specific | BscScan | DexScreener (bsc) · GeckoTerminal (bsc) · Dextools (bnb) |
| Base | 0x + 40 hex chars — shared by all 6 EVM chains, not chain-specific | BaseScan | DexScreener (base) · GeckoTerminal (base) · Dextools (base) |
| PulseChain | 0x + 40 hex chars — shared by all 6 EVM chains, not chain-specific | PLSfolio / apphex | DexScreener (pulsechain) · GeckoTerminal (pulsechain) · Dextools (pulse) |
| HyperEVM | 0x + 40 hex chars — shared by all 6 EVM chains, not chain-specific | HyperEVMScan | DexScreener (hyperevm) · GeckoTerminal (hyperevm) · Dextools (hyperevm) |
| Robinhood Chain | 0x + 40 hex chars — shared by all 6 EVM chains, not chain-specific | Blockscout | DexScreener (robinhood) · GeckoTerminal (robinhood) · Dextools (robinhood) |
| Solana | Base58, 32–44 chars, decodes to exactly 32 bytes | Solscan | DexScreener (solana) · GeckoTerminal (solana) · Dextools (solana) |
| TON | EQ/UQ + 46 base64url chars (48 total) | Tonviewer | DexScreener (ton) · GeckoTerminal (ton) · Dextools (ton) |
| Sui | 0x + up to 64 hex chars + ::module::Type — checked before the EVM shape, since a Sui type also starts 0x | Suiscan | DexScreener (sui) · GeckoTerminal (sui-network) · Dextools (sui) |
Note
A pasted
0x…address that DexScreener can't place opens a chain picker instead of guessing —Which chain is this token on?— with one button per EVM chain, in this order: Ethereum, BNB Chain, Base, PulseChain, HyperEVM, Robinhood Chain.
Feature gaps by chain
- Uniswap V4 pools are watched only on the 4 chains with a known PoolManager contract: Ethereum, Base, BNB Chain, Robinhood Chain. A V4 pool on PulseChain or HyperEVM is never watched.
- TON pools are decoded only for STON.fi v1/v2 and DeDust v2 (plus DeDust's own launcher pools). A jetton with no pool on those protocols can't be watched.
{HOLDERS}has no source on HyperEVM — it always resolves empty there, and any line built only from it is dropped. PulseChain has exactly one source (Blockscout). Every other chain races 2–3 sources at once and keeps the fastest answer.- Token, chain and socials cards
- Chains and data sources (multi-chain scanner)
Link building
Eleven placeholder tokens resolve to a URL: {TX}, {CHART}, {WALLET}, {WEBSITE}, {TWITTER}, {TELEGRAM}, {DISCORD}, {DOCS}, {MEDIUM}, {REDDIT}, {GITHUB} (_LINK_PH_RE). Any of the eleven can be set as the url of a header, body or row text run. None of them can be used inside extraLinks or buttons — both require a literal https:// URL instead.
Three also work as text
{TX}, {CHART} and {WALLET} are text placeholders as well as link tokens: typed inside a run's visible text they substitute a value (Tx, the chart label, the shortened wallet) and the run becomes a link on its own, with no separate url field needed, as long as the run isn't mono and the value resolves. The other eight are link-only. Typed inside visible text, {WEBSITE} and the rest are not substituted at all — they print literally, brackets included — because only {TX}, {CHART}, {WALLET} and the buy's own market placeholders are in the text formatter's substitution list. Setting a run's url field to one of the eight is the only way to use them.
| Token | Resolves to |
|---|---|
{TX} | The chain's tx explorer base (below) + the buy's transaction id. Text shown: the literal word Tx. Empty when txLinkOn is off or the chain has no tx base. |
{CHART} | The chart URL for the configured chartProvider (below). Text shown: chartLabel (default Chart, 24-character cap). Empty when no chart resolves. |
{WALLET} | The chain's wallet explorer base (below) + the buyer's wallet address. Text shown: the wallet shortened to first 6 chars...last 4 chars. Empty when walletLinkOn is off or the chain has no wallet base. |
{WEBSITE} | siteLinks.website, verbatim. Identical on every chain — this and the 7 tokens below never vary by chain. |
{TWITTER} | siteLinks.twitter, verbatim. |
{TELEGRAM} | siteLinks.telegram, verbatim. |
{DISCORD} | siteLinks.discord, verbatim. |
{DOCS} | siteLinks.docs, verbatim. |
{MEDIUM} | siteLinks.medium, verbatim. |
{REDDIT} | siteLinks.reddit, verbatim. |
{GITHUB} | siteLinks.github, verbatim. |
Overrides and toggles
| Setting | Value |
|---|---|
| explorerWalletBase | URL, default empty — the chain's own wallet base applies. No dashboard control or Telegram command writes it. |
| explorerTxBase | URL, default empty — the chain's own tx base applies. Same. |
| walletLinkOn | boolean, default true. No control found that writes it. |
| txLinkOn | boolean, default true. Same. |
Note
Every base concatenates directly with the address or transaction id — no separator is inserted. PulseChain's tx base already ends in a query string (
?tx=); the other eight end in a path segment.
Chart provider
| chartProvider | URL built |
|---|---|
| dexscreener (default) | The pool's own DexScreener URL when one is known, else https://dexscreener.com/{chain}/{pair}. |
| geckoterminal | https://www.geckoterminal.com/{gecko-slug}/pools/{pair} |
| dextools | Posted message: https://www.dextools.io/app/{dextools-slug}/pair-explorer/{pair}. Dashboard preview: https://www.dextools.io/app/en/{dextools-slug}/pair-explorer/{pair} — one segment longer. |
| custom | The owner's own chartUrl, verbatim. |
Warning
The bot's own posted message and the dashboard's live preview build different Dextools URLs for the same pool — the posted link omits the
/ensegment the dashboard preview adds. Both point at the same pool on Dextools but are not the same URL string.
Note
The dashboard's Chart provider control has three buttons — Dex, Gecko, Dextools — writing
dexscreener,geckoterminalordextools.customis a valid fourth value in the config format, but no dashboard control or Telegram command setschartProvidertocustomor writeschartUrl.
{WALLET} on Ethereum
| Input | Output |
|---|---|
| Wallet explorer base (Ethereum) | https://etherscan.io/address/ |
| Buyer wallet | 0x952ced28fd48d24c1b2ee2d0a2b1a4d9f1c1e6a1 |
| Link text shown | 0x952c...e6a1 |
| Link target | https://etherscan.io/address/0x952ced28fd48d24c1b2ee2d0a2b1a4d9f1c1e6a1 |
The truncation (first 6 characters + "..." + last 4) is applied identically by the bot and by the dashboard's live preview.
Note
An unset link slot leaves its run's own visible text in place with no link — the text itself never disappears for this reason alone. In the default layout (no custom body), an unset site link is left out of the tail link row entirely instead of appearing as plain text.
Limits
Groups, prompts and dispatch
| Limit | Value | Enforced |
|---|---|---|
| Target groups per bot | 10 | /enablebuybot in Telegram and the dashboard's group patch both refuse an 11th group with the same message: Limit reached, we're already in 10 groups. Remove a group first… |
| Prompt TTL | 600 s (10 min) | A pending settings prompt or fork-wizard prompt is rejected once it's this old |
| Settings dispatch timeout | 20 s | The dashboard call behind every /buybotsettings action |
| Fork dispatch timeout | 45 s | The dashboard call behind /forkbuybot |
| Fork dispatch rate limit | 20 requests / 60 s | /api/internal/dispatch, action fork-buybot |
| Settings dispatch rate limit | 60 requests / 60 s | /api/internal/dispatch, action buybot-settings |
| Group-title rescan | 300 s | Manage Groups card: how often a target group's title is re-read in the background between an explicit open or Refresh |
| Token lookup memo | 600 s | Cached DexScreener token lookup, keyed chain:contract |
Message content
| Limit | Value | Enforced |
|---|---|---|
| Caption cap, post carries media | 1024 visible UTF-16 units | Every buy post; trailing lines that don't fit are dropped whole |
| Caption cap, text-only post | 4096 visible UTF-16 units | Same, when the post has no photo, GIF or video |
| Fork source text | 8192 chars | /api/internal/dispatch, action fork-buybot, before the pasted post is even parsed |
| Runs per header, and per row | 96 | headerParts, and independently for each of the 6 row keys |
| Runs per body | 256 | bodyParts |
| Text per run | 200 chars | Any header, body or row run |
| Emoji-atom glyph text | 8 chars | The fallback text of a premium-emoji run |
| Chart label | 24 chars | chartLabel, default Chart |
| Contract address accepted | 160 chars | Any CA pasted or sent to the bot |
Links, buttons and cards
| Limit | Value | Enforced |
|---|---|---|
| Extra links | 4 | extraLinks |
| Extra-link label | 32 chars | Same |
| Buttons on a post | 12 | buttons |
| Button text | 64 chars, default Open | Same |
| Link display on the settings/socials card | 40 chars (37 + …) | Any link shown on the settings or socials card in Telegram |
| Fork “Removed:” list | 8 items, 40 chars each | /forkbuybot's summary of stripped content |
| Error text in a callback alert | 180 chars | Any inline-button tap that answers with an error |
| Error text stored or echoed | 200 chars | Settings-dispatch and fork failures |
Buys, pools and holders
| Limit | Value | Enforced |
|---|---|---|
| Max emojis in the size row | default 50, clamp 1–80 | maxEmojis |
| USD per emoji | clamp 0.01–1e9 | usdPerEmoji |
| Min buy | default $0, clamp 0–1e9 | minBuyUsd |
| Min buy accepted from Telegram | 0 ≤ v < 1e9 | The /buybotsettings Min Buy prompt |
| Watched pools per family | EVM uncapped, Solana 16, Sui 12, TON 10 | The pool set the watcher subscribes to, best pools first |
| New-holder ratio | 1000× | {POSITION} reads a percentage only up to this multiple of the buyer's pre-buy balance; above it, and for a zero pre-buy balance, it reads New! |
| Holders cache | 300 s | The buy-post {HOLDERS} lookup, per chain:contract |
| Posts per catch-up burst | 5 | Missed buys posted after a reconnect or restart, at most this many at once |
| Buy staleness cutoff | 600 s | A buy older than this at catch-up time is marked seen but never posted |
Media — the two paths outside the dashboard uploader
| Limit | Value | Enforced |
|---|---|---|
| Settings-patch media (base64) | 20 MB, any 2–4 character extension | The media field of a /buybotsettings dispatch patch — separate from the dashboard's own multipart upload |
| Fork photo | 20 MB | /forkbuybot's attached media, at the dispatch layer |
Media
A buy post carries either one fixed picture or a fresh pick from a linked gallery site on every buy. The `imageMode` field (`'fixed'` / `'random'`)…
Raid bot
`/raid` posts a board that tracks a tweet's likes, retweets and replies against a goal, editing itself until the goal is met or the raid is stopped.