DeDust SDK integration bot (TON)
TON is not EVM-compatible blockchain. Its architecture fundamentally differs from Ethereum: asynchronous message model, actor model instead of synchronous calls, FunC/Tact instead of Solidity. Developer coming from EVM experience first looks for ethers.js equivalent — and finds @ton/ton SDK. But interaction patterns are completely different, which becomes clear on first DeDust swap attempt.
How DeDust works and how it differs from Uniswap
DeDust is AMM DEX on TON, using Volatile Pool architecture (like Uniswap V2) and Stable Pool (like Curve). Main difference from EVM DEX is interaction with pool happens through sending messages to token wallet contract, not directly to pool.
TON → Jetton (ERC-20 analog in TON) swap scheme:
- Send TON to
NativeVaultcontract with payload containing pool address and swap parameters -
NativeVaultforwards message toPool -
Poolexecutes calculation and sends Jetton to recipient
Jetton → TON swap scheme:
- Send
transfermessage to Jetton Wallet withforward_payloadfor DeDust - Jetton Wallet sends
transfer_notificationtoJettonVault -
JettonVaultforwards toPool, pool sends TON back
Key moment: each step — separate on-chain message. No atomicity in EVM sense. If some step fails (insufficient gas on intermediate contract), tokens can "hang" in vault. That's why queryId — not just parameter, but mechanism for identifying bounce messages and tracking transaction state.
Integration through DeDust SDK
DeDust provides official TypeScript SDK @dedust/sdk. Basic swap through SDK:
import { Factory, MAINNET_FACTORY_ADDR, VaultNative, PoolType, Asset, ReadinessStatus } from "@dedust/sdk";
import { TonClient4, WalletContractV4, internal } from "@ton/ton";
const client = new TonClient4({ endpoint: "https://mainnet-v4.tonhubapi.com" });
const factory = client.open(Factory.createFromAddress(MAINNET_FACTORY_ADDR));
// Get vault and pool addresses
const tonVault = client.open(await factory.getNativeVault());
const pool = client.open(await factory.getPool(PoolType.VOLATILE, [
Asset.native(),
Asset.jetton(JETTON_ADDRESS)
]));
// Check pool readiness
if ((await pool.getReadinessStatus()) !== ReadinessStatus.READY) {
throw new Error("Pool not ready");
}
// Send swap
await tonVault.sendSwap(wallet.sender(keyPair.secretKey), {
poolAddress: pool.address,
amount: toNano("1"), // 1 TON
gasAmount: toNano("0.25"),
// limit: minimum token output
});
Parameter gasAmount — critical. Insufficient gas → message doesn't reach pool, TON returns through bounce. Excess → unnecessary costs. For Jetton → TON swap gas higher: must cover transfer_notification + vault processing + sending TON back. Recommended values: 0.25-0.3 TON for TON→Jetton, 0.3-0.4 TON for Jetton→TON.
Tracking transaction execution
Unlike Ethereum where await tx.wait() confirms finality, in TON you track message chain. Transaction can complete successfully but one of messages in chain — with error.
Monitoring pattern through queryId:
const queryId = BigInt(Date.now()); // Unique ID
// Pass queryId to swap parameters
// Monitor through polling target wallet transactions
async function waitForSwapResult(wallet: Address, queryId: bigint, timeout: number) {
const deadline = Date.now() + timeout;
while (Date.now() < deadline) {
const txs = await client.getTransactions(wallet, { limit: 10 });
const completed = txs.find(tx =>
tx.inMessage?.body.beginParse().loadUint(32) === 0x7362d09c // transfer_notification
// parse queryId and compare
);
if (completed) return completed;
await sleep(2000);
}
throw new Error("Swap timeout");
}
For production bot correctly use TON HTTP API v2 with webhooks or IndexerAPI for more reliable event monitoring.
Slippage calculation and minimum output
DeDust uses CPMM formula (x*y=k) for Volatile Pool. Calculate expected output:
const [reserve0, reserve1] = await pool.getReserves();
const amountIn = toNano("1");
const fee = 3n; // 0.3% = 30 basis points from 10000
// Formula with fee
const amountInWithFee = amountIn * (10000n - fee);
const amountOut = (amountInWithFee * reserve1) / (reserve0 * 10000n + amountInWithFee);
// Minimum output with 1% slippage tolerance
const minAmountOut = amountOut * 99n / 100n;
Parameter limit in sendSwap takes this minAmountOut. If real output less than minimum — transaction rejected, TON returns through bounce.
Specifics for trading bot
Nonce and sequence number. TON has no nonce in EVM sense. Instead — seqno wallet. Two parallel messages with same seqno → second rejected. For high-frequency bot either use separate wallets for each direction, or queue with sequential sending.
Multi-wallet architecture. If bot works on multiple pairs simultaneously — recommend separate wallet for each trading pair. Avoids seqno conflicts and simplifies balance accounting.
TON Connect vs backend signing. For trading bot — only backend signing through mnemonic or keystore. TON Connect meant for user dApps, not automated operations.
Timeline estimates
Basic DeDust SDK integration (one swap direction, monitoring) — 3-4 days. Full trading bot with bidirectional swaps, slippage protection, position monitoring — 1 week. Cost calculated individually.







