TON DEX Trading Bot Development (StonFi, DeDust)
TON blockchain is fundamentally different from EVM: asynchronous message model, no global state in conventional sense, FunC/Tact instead of Solidity. A trading bot for StonFi or DeDust is not "rewrite Ethereum bot in another language." It's a different architecture with different failure modes.
TON Asynchronicity: Why Normal Patterns Don't Work
Transactions in TON — Message Chains
On Ethereum, a swap is one call, one receipt, one status: success or reverted. In TON one user request spawns a chain of internal messages between contracts. StonFi v2 swap:
- User Wallet → Jetton Wallet:
transferwith forward payload - Jetton Wallet → Router:
transfer_notification - Router → Pool:
swap - Pool → Jetton Wallet (output token):
internal_transfer - Jetton Wallet → user wallet:
transfer_notification
Each step is separate transaction with separate hash. Success of step 1 doesn't guarantee success of whole chain. If step 3 or 4 fails — step 5 gets bounced message with token return.
Bot must: send step 1, remember outgoing message hash, track transaction tree by in_msg_hash, wait for either successful step 5 or bounced message with return.
TON API for Transaction Monitoring
TON Center API v2: GET /v2/transactions?address={}&limit=20<_={}&hash={} — get address transactions. To track specific chain, use lt (logical time) and hash for pagination.
More convenient for bots: TON API getBlockTransactions + WebSocket via TON Access. On each block received — check your address transactions. Latency 1-3 seconds after block finalization (TON finalizes in 5-6 seconds).
Libraries: @ton/ton (TypeScript, official) or tonutils-go (Go). For Python — pytoniq-core.
Working with StonFi and DeDust
StonFi v2: Router and Message Payload
StonFi v2 swap payload for jetton → jetton:
import { StonApiClient } from '@ston-fi/api';
import { DEX } from '@ston-fi/sdk';
const client = new StonApiClient();
const dex = client.openDex(DEX.v2);
const txParams = await dex.getSwapJettonToJettonTxParams({
userWalletAddress: walletAddress,
offerJettonAddress: USDT_ADDRESS,
askJettonAddress: STON_ADDRESS,
offerAmount: toNano('100'), // 100 USDT
minAskAmount: toNano('95'), // 5% slippage
});
await wallet.sendTransaction(txParams);
minAskAmount is on-chain slippage protection. If pool can't provide minimum amount — transaction bounced, tokens returned. Bot must calculate minAskAmount based on current pool price minus allowed slippage.
DeDust: Vault-Based Architecture
DeDust differs in architecture: instead of direct pool submission — via vault. Each token has its own vault contract. Swap starts with deposit to vault with attached swap params in payload:
import { Asset, Factory, MAINNET_FACTORY_ADDR, Pool, VaultJetton } from '@dedust/sdk';
const factory = client.open(Factory.createFromAddress(MAINNET_FACTORY_ADDR));
const tonVault = client.open(await factory.getNativeVault());
// TON → Jetton swap
await tonVault.sendSwap(wallet.getSender(), {
poolAddress: pool.address,
amount: toNano('1'),
gasAmount: toNano('0.25'),
});
DeDust supports both Uniswap v2-style (volatile pools) and Curve-style (stable pools). For stablecoin pairs — stable pool with lower slippage.
Getting Current Price Without Swap
For StonFi: GET https://api.ston.fi/v1/pools/{poolAddress} returns token0_address, token1_address, reserve0, reserve1. Price = reserve1 / reserve0 accounting for decimals.
For DeDust: call Pool.getEstimatedSwapOut — view function, returns amountOut for given amountIn. More accurate than reserves calculation, especially for stable pools.
Strategies: What's Implementable on TON DEX
Arbitrage StonFi ↔ DeDust. Same jetton/TON pair trades on both DEX. Price divergence >0.5% (above fees + gas) — arbitrage opportunity. No atomicity (no flash loans in same sense), so arbitrage is two-stage: swap on DEX1, then swap on DEX2. Risk: while executing first swap, second pool changes price.
Grid trading. Buy jetton when price drops below grid level, sell when rises. Simple strategy, works in sideways market. For TON pairs with sufficient liquidity ($500K+ TVL) — practical.
DCA (Dollar Cost Averaging). Automatic purchase of fixed volume TON→Jetton on schedule. Implemented via cron job + TON wallet SDK. Minimal complexity, good introduction to TON bot development.
Infrastructure
Wallet. Bot needs hot wallet — TON wallet v4 or v5. Seed phrase stored encrypted (AES-256), never plaintext. Hot wallet limits — operational reserves only, main funds separate.
Node or RPC. Public TON Center free but rate-limited (1 req/sec). For active trading — TON Center Pro ($49/month, 25 req/sec) or own lite-server node.
Monitoring. Telegram bot for trade notifications (ironically, bot monitors itself via Telegram). Prometheus metrics: trades_per_hour, profit_per_day, error_rate.
Development Process
TypeScript Prototype (3-5 days). Connect to TON, read prices from StonFi/DeDust API, simulate strategy on historical data.
Bot Development (1-2 weeks). Transaction builder, state machine for tracking pending swaps, error handling for bounced messages.
Testing on TON Testnet (3-5 days). TON has full testnet with testnet StonFi deployment.
Production Deployment. VPS + monitoring. Start with small capital, gradually scale.
Timeline Estimates
DCA or grid bot with one pair: 1-1.5 weeks. Arbitrage system with multiple pairs monitoring and automatic rebalancing: 2-3 weeks.







