sdk.ton.dex — DEX Trading
Decentralized exchange operations via STON.fi and DeDust aggregators. Access via sdk.ton.dex in your plugin.
Quick Example
import type { PluginSDK } from "@teleton-agent/sdk";
const USDT = "EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs";
// Compare quotes from both DEXes
const quote = await sdk.ton.dex.quote({
fromAsset: "ton",
toAsset: USDT,
amount: 10,
slippage: 0.01, // 1%
});
console.log(`Recommended: ${quote.recommended}`);
console.log(`Savings: ${quote.savings}`);
if (quote.stonfi) {
console.log(`STON.fi: ${quote.stonfi.expectedOutput} USDT (fee: ${quote.stonfi.fee})`);
}
if (quote.dedust) {
console.log(`DeDust: ${quote.dedust.expectedOutput} USDT (fee: ${quote.dedust.fee})`);
}
// Execute swap on the recommended DEX
const result = await sdk.ton.dex.swap({
fromAsset: "ton",
toAsset: USDT,
amount: 10,
slippage: 0.01,
});
console.log(`Swapped on ${result.dex}: ${result.amountIn} TON -> ~${result.expectedOutput} USDT`);Overview
The DEX SDK provides a dual-aggregator interface to the two largest decentralized exchanges on TON: STON.fi and DeDust. The quote() method queries both and recommends the best rate. The swap() method executes the trade, either auto-selecting the best DEX or using a specific one via the dex parameter.
All DEX operations are accessed through sdk.ton.dex, a sub-namespace of the TON SDK.
- Use
"ton"as the asset identifier for native TON - Use the jetton master contract address for any other token
- Amounts are in human-readable units (e.g.,
10for 10 TON, not nanoTON) - Slippage is a decimal (e.g.,
0.01= 1%), range: 0.001 to 0.5
Methods
quote(params)
Compare quotes from both STON.fi and DeDust, and get a recommendation for the best rate.
| Method | Returns | Description |
|---|---|---|
quote(params: DexQuoteParams) | Promise<DexQuoteResult> | Aggregated quote comparing both DEXes with a recommendation. |
const SCALE = "EQBlqsm144Dq6SjbPI4jjZvlmHDqumGs1SfAW3IqjvnBqSZ8";
const quote = await sdk.ton.dex.quote({
fromAsset: "ton",
toAsset: SCALE,
amount: 5,
slippage: 0.02, // 2% slippage tolerance
});
// quote.recommended is "stonfi" or "dedust"
// quote.savings tells you the difference (e.g. "0.5%")
if (quote.recommended === "stonfi" && quote.stonfi) {
console.log(`Best rate on STON.fi: ${quote.stonfi.rate}`);
console.log(`Expected: ${quote.stonfi.expectedOutput} SCALE`);
console.log(`Min output: ${quote.stonfi.minOutput} (after slippage)`);
}quoteSTONfi(params) / quoteDeDust(params)
Get a quote from a specific DEX only. Returns null if the DEX has no liquidity for the pair.
| Method | Returns | Description |
|---|---|---|
quoteSTONfi(params: DexQuoteParams) | Promise<DexSingleQuote | null> | Quote from STON.fi only. Null if no liquidity. |
quoteDeDust(params: DexQuoteParams) | Promise<DexSingleQuote | null> | Quote from DeDust only. Null if no liquidity. |
const params = { fromAsset: "ton", toAsset: USDT, amount: 100 };
const stonfi = await sdk.ton.dex.quoteSTONfi(params);
const dedust = await sdk.ton.dex.quoteDeDust(params);
if (stonfi) {
console.log(`STON.fi rate: ${stonfi.rate}, fee: ${stonfi.fee}`);
if (stonfi.priceImpact) console.log(`Price impact: ${stonfi.priceImpact}`);
}
if (dedust) {
console.log(`DeDust rate: ${dedust.rate}, fee: ${dedust.fee}`);
console.log(`Pool type: ${dedust.poolType}`); // "volatile" or "stable"
}swap(params)
Execute a swap. By default, auto-selects the best DEX. Use params.dex to force a specific one.
| Method | Returns | Description |
|---|---|---|
swap(params: DexSwapParams) | Promise<DexSwapResult> | Execute swap via recommended DEX (or forced via params.dex). |
// Auto-select best DEX
const result = await sdk.ton.dex.swap({
fromAsset: "ton",
toAsset: USDT,
amount: 10,
slippage: 0.01,
});
console.log(`Swapped on ${result.dex}`);
console.log(`Sent: ${result.amountIn} TON`);
console.log(`Expected: ${result.expectedOutput} USDT`);
console.log(`Min output: ${result.minOutput} USDT`);
console.log(`Slippage: ${result.slippage}`);// Force STON.fi
const stonfiResult = await sdk.ton.dex.swap({
fromAsset: USDT,
toAsset: "ton",
amount: 50,
slippage: 0.01,
dex: "stonfi",
});
// Force DeDust
const dedustResult = await sdk.ton.dex.swap({
fromAsset: USDT,
toAsset: "ton",
amount: 50,
slippage: 0.01,
dex: "dedust",
});swapSTONfi(params) / swapDeDust(params)
Execute a swap on a specific DEX directly. Same as calling swap() with the dex parameter.
| Method | Returns | Description |
|---|---|---|
swapSTONfi(params: DexSwapParams) | Promise<DexSwapResult> | Execute swap on STON.fi specifically. |
swapDeDust(params: DexSwapParams) | Promise<DexSwapResult> | Execute swap on DeDust specifically. |
const result = await sdk.ton.dex.swapSTONfi({
fromAsset: "ton",
toAsset: USDT,
amount: 5,
slippage: 0.01,
});
console.log(`STON.fi swap: ${result.amountIn} -> ${result.expectedOutput}`);Type Definitions
interface DexQuoteParams {
fromAsset: string; // "ton" or jetton master address
toAsset: string; // "ton" or jetton master address
amount: number; // Human-readable units
slippage?: number; // 0.01 = 1% (default: 0.01, range: 0.001-0.5)
}interface DexQuoteResult {
stonfi: DexSingleQuote | null; // STON.fi quote (null if no liquidity)
dedust: DexSingleQuote | null; // DeDust quote (null if no liquidity)
recommended: "stonfi" | "dedust"; // Best DEX for this trade
savings: string; // Savings vs other DEX (e.g. "0.5%")
}interface DexSingleQuote {
dex: "stonfi" | "dedust"; // DEX name
expectedOutput: string; // Expected output amount
minOutput: string; // Minimum after slippage
rate: string; // Exchange rate
priceImpact?: string; // Price impact percentage
fee: string; // Fee amount
poolType?: string; // DeDust: "volatile" | "stable"
}interface DexSwapParams extends DexQuoteParams {
dex?: "stonfi" | "dedust"; // Force a specific DEX (omit for auto)
}interface DexSwapResult {
dex: "stonfi" | "dedust"; // DEX used
fromAsset: string; // Source asset address
toAsset: string; // Destination asset address
amountIn: string; // Amount sent
expectedOutput: string; // Expected output
minOutput: string; // Minimum after slippage
slippage: string; // Slippage used
}STON.fi vs DeDust
| Feature | STON.fi | DeDust |
|---|---|---|
| Pool types | Constant product (v1/v2) | Volatile + Stable pools |
| Stablecoin pairs | Standard AMM | Optimized stable curve |
| Liquidity | Generally higher for major pairs | Growing, strong on stables |
| Pool type info | Not exposed | Available via poolType |
| Price impact | Available via priceImpact | Available via priceImpact |
| Best for | Major TON/jetton pairs | Stablecoin swaps, newer tokens |
Use the aggregated quote() method to automatically find the best rate. The recommended field and savings percentage make it easy to present the comparison to users.
Risk Warnings
- Swaps are irreversible — once a swap transaction is sent to the blockchain, it cannot be undone. Always confirm with the user before executing.
- Slippage tolerance — setting slippage too low may cause the swap to fail. Setting it too high may result in unfavorable rates. The default 1% is suitable for most trades.
- Price impact — large trades relative to pool liquidity will move the price. Check
priceImpactin the quote before executing. Warn users if impact exceeds 3-5%. - MEV / frontrunning — on-chain swaps on TON are less susceptible to MEV than Ethereum, but large trades can still be sandwiched. Consider splitting large trades.
- Token verification — always verify the jetton address before swapping. Use
sdk.ton.getJettonInfo()to check theverifiedfield and confirm the token is legitimate. - Liquidity — a quote returning
nullmeans the DEX has no liquidity for the pair. Both DEXes returning null means the token is not tradable.
Complete Example: Quote, Compare, Swap
import type { PluginSDK, DexQuoteResult, DexSwapResult } from "@teleton-agent/sdk";
const USDT = "EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs";
export default {
name: "dex-trader",
version: "1.0.0",
tools: [
{
name: "swap_ton_to_usdt",
description: "Swap TON for USDT via the best DEX",
parameters: {
type: "object",
properties: {
amount: { type: "number", description: "TON amount to swap" },
maxSlippage: { type: "number", description: "Max slippage (default 0.01)" },
},
required: ["amount"],
},
execute: async (args: { amount: number; maxSlippage?: number }, sdk: PluginSDK) => {
const slippage = args.maxSlippage ?? 0.01;
// Step 1: Verify the token
const info = await sdk.ton.getJettonInfo(USDT);
if (!info?.verified) {
return { error: "USDT token not verified" };
}
// Step 2: Check balance
const balance = await sdk.ton.getBalance();
if (!balance || parseFloat(balance.balance) < args.amount + 0.5) {
return { error: "Insufficient balance (need amount + ~0.5 TON for gas)" };
}
// Step 3: Get quotes from both DEXes
const quote = await sdk.ton.dex.quote({
fromAsset: "ton",
toAsset: USDT,
amount: args.amount,
slippage,
});
// Step 4: Check for liquidity
if (!quote.stonfi && !quote.dedust) {
return { error: "No liquidity on either DEX" };
}
// Step 5: Check price impact
const best = quote.recommended === "stonfi" ? quote.stonfi! : quote.dedust!;
if (best.priceImpact && parseFloat(best.priceImpact) > 5) {
return {
warning: `High price impact: ${best.priceImpact}%. Consider a smaller trade.`,
quote: {
dex: quote.recommended,
output: best.expectedOutput,
minOutput: best.minOutput,
rate: best.rate,
},
};
}
// Step 6: Execute the swap
const result = await sdk.ton.dex.swap({
fromAsset: "ton",
toAsset: USDT,
amount: args.amount,
slippage,
});
return {
success: true,
dex: result.dex,
sent: `${result.amountIn} TON`,
expected: `${result.expectedOutput} USDT`,
minOutput: `${result.minOutput} USDT`,
slippage: result.slippage,
savings: quote.savings,
};
},
},
],
};