Как собрать торгового агента на TON: читать, котировать, свапать
Торговый агент TON на MCP: как агент читает балансы, берёт котировку и собирает своп некастодиально — get_balance, get_swap_quote, build_swap_tx.
Проблема, с которой начинается любой торговый агент на TON
Вы просите ИИ-агента «свапнуть 50 USDT в GRAM, когда цена просядет» — а он отправляет транзакцию на 50 000 USDT вместо 50. Потому что у USDT в TON decimals = 6 (50 USDT = 50 000 000 raw-единиц), а агент по умолчанию посчитал как для обычного жетона с девятью нулями — и заложил в сумму в 1000 раз больше. Ошибка в 1000 раз, реальные деньги, необратимая транзакция. Тот же корень у зеркальной ошибки: агент видит на балансе сырое 1000000000 и уверенно рапортует «у вас миллиард USDT», хотя там 1000.
Это не выдуманные страшилки, а ровно те грабли, на которые наступает каждый, кто подключает LLM к DeFi на TON напрямую через сырые RPC: перепутанные decimals, невозможность прочитать баланс жетона без адреса джеттон-кошелька, утёкший через контекст приватный ключ. Ниже — как собрать торговый агент на TON (trading agent TON), который читает балансы, берёт твёрдую котировку и собирает своп, ни разу не прикоснувшись к вашим ключам. Инструмент — TONNode, hosted MCP-сервер для TON.
Что такое торговый агент на TON и зачем ему MCP
Торговый агент — это LLM (Claude, Cursor, Codex или любой другой MCP-клиент), которая по запросу пользователя умеет читать состояние сети и готовить сделки: «покажи мой баланс USDT», «сколько GRAM я получу за 500 USDT», «собери своп». Сама по себе модель блокчейн не видит — ей нужны инструменты.
Именно это и делает MCP (Model Context Protocol) — стандарт, по которому агенты вызывают внешние инструменты. Вместо того чтобы учить модель сочинять сырые ADNL-запросы и парсить BOC-ячейки, вы отдаёте ей набор типизированных функций: «дай баланс», «дай котировку», «собери транзакцию». TONNode подключается как источник таких инструментов и даёт агенту ровно 16 функций для работы с сетью: чтение, свап, кроссчейн, генерация кошелька.
Торговому агенту из них нужны пять, и все пять доступны даже на бесплатном тарифе:
читать (get_balance, get_jetton_balance)
-> уточнить decimals (get_jetton_info)
-> котировать (get_swap_quote)
-> собрать своп (build_swap_tx)
-> кошелёк подписывает через TonConnect
Ключевая деталь последнего шага: подписывает кошелёк пользователя, а не сервер. TONNode возвращает неподписанные сообщения — почему это принципиально, разберём в конце.
Шаг 1: агент читает балансы (get_balance, get_jetton_balance)
Прежде чем что-то свапать, агент должен понять, чем он располагает. Два инструмента:
get_balance— баланс GRAM на адресе. GRAM — это переименованный в июне 2026 Toncoin; сама сеть по-прежнему называется TON.get_jetton_balance— баланс жетона: USDT, NOT, любого другого. Магия здесь в том, что джеттон-кошелёк вычисляется он-чейн. Вы передаёте адрес владельца и мастер-адрес жетона, а TONNode сам выводит адрес джеттон-кошелька и читает его баланс. Не нужно заранее знать этот адрес и где-то его хранить.
Промпт агенту выглядит буквально так:
Проверь баланс кошелька UQAbc...xyz:
сколько на нём GRAM и сколько USDT?
Под капотом модель вызывает get_balance для нативного баланса и get_jetton_balance для USDT. Одна беда: то, что вернётся, — это ещё не «человеческие» суммы, а сырые единицы. И вот тут начинается самое важное. Про то, как получить баланс USDT одним вызовом без плясок с адресами джеттон-кошелька, есть отдельный разбор: /blog/usdt-balance-ton-one-call.
decimals решают всё: get_jetton_info и почему USDT = 6
Балансы и суммы в TON хранятся в raw-единицах — целых числах без дробной части. Чтобы получить человекочитаемую сумму, сырое число нужно поделить на 10^decimals. И вот засада: у разных жетонов разное число decimals.
- У USDT
decimals = 6. То есть1 USDT = 1 000 000raw-единиц. - У большинства жетонов в TON
decimals = 9(как у GRAM). То есть1 жетон = 1 000 000 000raw-единиц.
Перепутать 6 и 9 — это ошибиться в сумме ровно в 1000 раз. Тот самый «миллиард USDT» из начала статьи. Для торгового агента это не косметика, а корень доверия: если он путает порядки, ему нельзя давать собирать сделки.
Поэтому в конвейер встраивается get_jetton_info — он отдаёт метаданные жетона: имя, символ, эмиссию и — самое важное — decimals. Правильная логика внутри агента:
raw = get_jetton_balance(...) // например, 1000000000
decimals = get_jetton_info(...) // для USDT → 6
human = raw / 10 ** decimals // 1000000000 / 1e6 = 1000 USDT
Тот же самый raw при decimals = 9 дал бы 1 токен — разница колоссальная. Не хардкодьте decimals в промпте и не давайте модели «додумывать» их по памяти: на новом жетоне она ошибётся. Пусть тянет из get_jetton_info каждый раз и пересчитывает по факту. Подробно про эту ловушку и почему она стоит людям денег: /blog/jetton-decimals-ton.
Шаг 2: твёрдая котировка через Omniston (get_swap_quote)
Балансы прочитаны и пересчитаны в правильных единицах — теперь агенту нужна цена. В DeFi «примерная цена из головы» не работает: ликвидность размазана по нескольким DEX, курс двигается, и агент должен опираться на актуальную котировку, а не на догадку.
get_swap_quote даёт твёрдую котировку на своп GRAM ⇄ жетон через протокол Omniston, который агрегирует ликвидность сразу двух крупнейших DEX TON — STON.fi и DeDust. Агенту не нужно самому опрашивать пулы, сравнивать цены и считать проскальзывание: Omniston возвращает лучший маршрут из объединённой ликвидности.
Дай котировку: сколько GRAM я получу за 50 USDT прямо сейчас?
Модель вызывает get_swap_quote с суммой 50000000 (те самые raw-единицы из прошлого шага) и получает конкретные числа: сколько на входе, сколько на выходе, по какому маршруту, с каким проскальзыванием. Это точка принятия решения: если у агента есть условие («свапай только если курс лучше X»), он сравнивает котировку с порогом и либо идёт дальше, либо ждёт следующей итерации. Важно: котировка — это ещё не сделка. Никакие средства не двигаются, ничего не подписывается. Это чистое чтение рынка.
Шаг 3: сборка неподписанного свопа (build_swap_tx) и подпись в кошельке
Пользователь увидел котировку и говорит «да, свапаем». Агент вызывает build_swap_tx и получает неподписанную транзакцию свопа, готовую для TonConnect.
Подчеркну слово «неподписанную». Сервер собирает корректное сообщение — адрес получателя, payload, сумму, параметры маршрута — и возвращает его как есть. Дальше сообщение уходит в кошелёк пользователя (Tonkeeper, MyTonWallet, любой TonConnect-совместимый), пользователь видит, что именно подписывает, и подтверждает сам. Подпись ставит приватный ключ пользователя, который живёт в его кошельке, а не на сервере.
get_balance / get_jetton_balance → прочитать, что есть
↓
get_jetton_info → уточнить decimals, пересчитать
↓
get_swap_quote (Omniston) → твёрдая котировка
↓
build_swap_tx → неподписанная транзакция
↓
кошелёк пользователя (TonConnect) → подпись и отправка
Каждый шаг — отдельный явный вызов инструмента. Агент ничего не «доделывает по своему усмотрению» с деньгами: он готовит, а решение и подпись остаются за человеком. Полный сценарий некастодиального свапа, от котировки до подписи, разобран по шагам здесь: /blog/agent-swap-ton-noncustodial.
Некастодиальность: почему сервер никогда не держит ключи агента
Это не маркетинговая формулировка, а архитектурная граница. У TONNode инструменты свапа, кроссчейна и генерации кошелька строго некастодиальны:
- Сервер никогда не подписывает транзакции.
- Сервер никогда не хранит приватные ключи и средства.
- Всё, что он отдаёт наружу, — это неподписанные TonConnect-сообщения.
Почему это важно именно для торгового агента? Потому что агент по определению работает с деньгами и по определению может ошибиться — не так понять запрос, перепутать сумму, зациклиться. Если бы ключи лежали на сервере и он подписывал сам, ошибка агента означала бы утрату средств без вашего ведома. В некастодиальной схеме последний рубеж — вы: ни одна транзакция не уходит, пока её не подтвердил ваш кошелёк.
Сравните с официальным @ton/mcp от TON Foundation — это кастодиальный агент-кошелёк: он держит operator-ключ и подписывает сам (схема split-key, где operator-ключ у агента, owner-ключ у пользователя). У него свои сильные стороны — автономная трата без участия человека, работа с NFT и DNS, официальный статус Foundation. Но модель доверия другая: там агент реально может двигать средства. TONNode сознательно выбирает противоположную границу: сервер не подписывает вообще ничего. Развёрнутое сравнение двух подходов: /blog/custodial-vs-noncustodial-mcp.
Как подключить и с чего начать за 5 минут
Хорошая новость: чтобы собрать торговый конвейер, платить не нужно. Но важно не путать два бесплатных пути — у них разный набор инструментов.
Локальный публичный конфиг даёт полный набор чтения (8 инструментов: get_masterchain_info, get_balance, get_account_state, get_transactions, run_get_method, get_jetton_balance, parse_address, get_jetton_info). Ставится через npx, без ключа:
{
"mcpServers": {
"ton": {
"command": "npx",
"args": ["-y", "@tonnode/mcp"]
}
}
}
Пакет @tonnode/mcp — open source (MIT), лежит на npm и GitHub (tonnode/mcp), работает по нативному ADNL-протоколу TON без HTTP-прослоек между агентом и сетью. Вставили конфиг в Claude Desktop, Cursor или любой MCP-клиент — и агент уже умеет читать балансы и дёргать get_jetton_info.
А вот сами котировки — get_swap_quote и build_swap_tx — относятся к группе СВАП и идут через hosted-эндпоинт. Ключевой момент: на бесплатном ключе Hobby доступны все 16 инструментов, включая котировку и сборку свопа. То есть весь торговый конвейер (чтение → котировка → своп) собирается бесплатно — но именно через hosted-ключ Hobby, а не через локальный публичный конфиг. Конфиг для hosted-эндпоинта:
{
"mcpServers": {
"ton": {
"type": "http",
"url": "https://mcp.tonnode.io/mcp",
"headers": { "Authorization": "Bearer tn_live_…" }
}
}
}
У TONNode ровно 16 инструментов, и на всех тарифах доступны все 16 — вы платите только за пропускную способность, а не за функциональность:
- Hobby — бесплатно навсегда, 60 запросов/мин, без карты.
- Pro — $29/мес, 300 запросов/мин.
- Scale — $199/мес, 1200 запросов/мин.
Для старта и обкатки торгового конвейера бесплатного ключа Hobby хватает с запасом: 60 запросов в минуту — это много последовательных вызовов агента. Карта не нужна, ключ выдаётся сразу после входа.
Получить бесплатный ключ Hobby (60 req/min, без карты): tonnode.io/dashboard?plan=hobby
Полный список из 16 инструментов: tonnode.io/mcp · Тарифы: tonnode.io/pricing
Соберите конвейер из пяти инструментов — get_balance, get_jetton_balance, get_jetton_info, get_swap_quote, build_swap_tx — держите decimals под контролем и отдавайте подпись кошельку. Так у вас получится торговый агент, который честно читает балансы, берёт твёрдую котировку и готовит своп на реальные суммы, ни на секунду не получив доступа к чужим ключам. Именно так и должен работать торговый агент на TON.
Дайте вашему агенту доступ к TON
16 MCP-инструментов: чтение, некастодиальные свапы, кроссчейн и кошельки. Бесплатный тариф — 60 запр/мин, карта не нужна.