Барлық мақалалар
6 мин оқу

TON әмиянындағы USDT балансын бір шақырумен білу

get_jetton_balance арқылы TON әмиянындағы USDT балансын бір шақырумен алу: жетон-әмиян он-чейн есептеледі, индексер керек емес.

USDT балансы TONget_jetton_balanceTON жетондарыTON үшін MCPTONNodeжетон decimals

Агенттің әмияны ашық, get_balance адал бірнеше GRAM қайтарды — ал USDT нөл. Ал стейблкоиндердің осы мекенжайға келгенін нақты білесіз ғой. Таныс па? Әмиян бос көрінеді, ал онда 500 USDT жатыр. Бұл баг та емес, жоғалып кеткен ақша да емес — сіз жай ғана басқа контрактіден сұрап отырсыз. ЖИ-агентті TON-мен байланыстыратын алғашқы интеграциялардың көбі дәл осы жерде құлайды: агент басқа мекенжайды оқиды.

USDT балансы неге TON-әмиянның балансы емес

Ethereum-да ERC-20 токені «мекенжайда жатады» дегенге үйреніп қалғансыз: токен контрактісі address → balance кестесін сақтайды, ал балансты білу үшін сіз сол жалғыз контрактіден сұрайсыз. TON-да модель басқаша, әрі шатасудың бірінші көзі — осы.

Нативті GRAM монетасы (бұрынғы Toncoin; желі бұрынғысынша TON деп аталады) сіздің әмияныңыздың смарт-контрактісінде тікелей жатады — оны get_balance аккаунт күйіне бір ғана жүгінумен оқиды. Ал USDT — бұл жетон (jetton, TON-ның өзара алмастырылатын токендерге арналған стандарты). Жетонның балансы сіздің негізгі әмияныңызда емес, бөлек кішкентай контрактіде — жетон-әмиянда (jetton wallet) сақталады.

Аналогия: сіздің негізгі TON-әмияныңыз — бұл адам ретіндегі сіз. Ал USDT жетон-әмияны — нақты бір банк (USDT мастер-контрактісі) сіздің атыңызға ашқан жеке шот. «Менде қанша доллар бар» деп адамның өзінен сұраудың мәні жоқ — ақша қалтада емес, шотта. Әр «иесі + жетон» жұбының өз жетон-әмияны бар: USDT үшін бір мекенжай, NOT үшін екіншісі, кез келген жетон үшін үшіншісі.

Жақсы жаңалық: бұл жетон-әмиянның мекенжайы кездейсоқ емес. Ол екі нәрседен детерминистік түрде шығарылады:

  • иесінің мекенжайы (сіздің әдеттегі TON-әмияныңыз, EQ…/UQ…);
  • жетонның мастер-контракт мекенжайы (jetton master — USDT үшін бұл бір бекітілген контракт).

Жаман жаңалық: бұл мекенжайды адал есептеу үшін мастер-контрактіге барып, оның get-әдісін шақыру, содан кейін жетон-әмиянның күйін оқу керек. Қолмен істегенде бұл бірнеше қадам, әрі интеграциялар дәл соларға сүрінеді.

get_jetton_balance: индексердің орнына бір шақыру

Әдетте бұл міндет екі жолдың бірімен шешіледі, әрі екеуі де ыңғайсыз:

  • Өз индексеріңіз. Нода көтеру, жетон-аударымдарды базаға индекстеу, оны өзекті күйде ұстау. Бір ғана сан үшін бұл қымбат әрі сынғыш, оның үстіне деректер әрқашан чейннен сәл артта қалады.
  • Жария HTTP-API. Лимиттерге тез тіреледі: кілтсіз бұл секундына шамамен бір сұраныс, ал асып кетсеңіз, адал HTTP 429 Too Many Requests аласыз. Оның үстіне сіз бөгде индекстеуге және оның тереңдігіне тәуелдісіз.

TONNode-тың get_jetton_balance құралы екі мәселені де жояды. Сіз оған мынаны бересіз:

  • иесінің мекенжайы — пайдаланушының әдеттегі TON-әмияны (EQ…/UQ…);
  • жетон идентификаторы — мысалы, USDT.

Әрі қарай сервер бүкіл жұмысты он-чейн өзі істейді:

  1. жетонның мастер-контрактісінің get-әдісін шақырады — ол иесінің мекенжайы бойынша оның жетон-әмиянының мекенжайын қайтарады (дәл сол детерминистік шығару);
  2. сол жетон-әмияннан балансты оқып, оны сізге қайтарады.

Ешқандай бөгде индексер жоқ, ешқандай база жоқ, чейннен артта қалу жоқ — тек контрактілердің get-әдістері арқылы желі күйін тікелей оқу.

TONNode — бұл TON үшін hosted MCP-сервер. MCP (Model Context Protocol) — ЖИ-агенттер (Claude, Cursor, ChatGPT/Codex және кез келген MCP-клиент) сыртқы құралдарды шақыратын стандарт. Яғни get_jetton_balance — сіздің кодыңыздағы жол емес, пайдаланушы баланс туралы сұрағанда агент өзі тартатын құрал. Капот астында @tonnode/mcp пакеті (open source, MIT) TON-ның нативті ADNL-протоколы бойынша, аралық HTTP-қабаттарсыз жұмыс істейді — агент желімен кезекті REST-шлюз арқылы емес, тікелей сөйлеседі.

Мысал: агентке промпт және не қайтарылады

Қосылу жергілікті, кілтсіз әрі картасыз. MCP-клиенттің конфигіне қосыңыз (Claude Desktop, Cursor, кез келген MCP-үйлесімді):

{
  "mcpServers": {
    "ton": {
      "command": "npx",
      "args": ["-y", "@tonnode/mcp"]
    }
  }
}

Одан кейін агентке адам тіліндегі қарапайым промпттың өзі жетеді:

UQAbc…xyz әмиянында қанша USDT бар? Адам оқитын мәнді қайтар.

Агент get_jetton_balance құралын өзі таңдайды, иесінің мекенжайын және USDT жетонын береді, ал сервер балансты қайтарады — бірақ әдеттегі «доллармен» емес, raw-бірліктермен (жетонның ең кіші бөлінбейтін үлестерімен). Баланстың өзінен бөлек, жауапта сервер он-чейн есептеген жетон-әмиянның мекенжайы да келеді — егер әрі қарай дәл осы контрактінің аударымдарын қадағалағыңыз келсе, бұл пайдалы. Біздің мысалдағы баланстың өзі — 12500000 тәрізді мән.

Бірақ 12500000 — бұл 12.5 миллион USDT емес. Мұнда оңай жаңылысатын екінші тұзақ басталады.

Raw-бірліктер және decimals: USDT-де неге 9 емес, 6

Блокчейндер бөлшек сандармен жұмыс істемейді. Барлық сома бүтін сандық raw-бірліктерде сақталады, ал «адами» мән 10^decimals-ке бөлуден шығады, мұндағы decimals — нақты жетонның қасиеті. Бұл тиын мен теңге сияқты: төменгі деңгейде бәрі тиынмен, ал decimals үтірді қайда қою керегін айтады.

TON-ның түйінді нюансы: әртүрлі жетондарда decimals саны әртүрлі.

  • Нативті GRAM-да және TON жетондарының көпшілігінде decimals = 9.
  • Ал TON-дағы USDT-де decimals = 6.

Сондықтан бір ғана raw-мән мүлдем әртүрлі соманы білдіреді. Мысалымызды дұрыстап қайта санаймыз:

raw      = 12500000
decimals = 6            // дәл USDT үшін
human = 12500000 / 10^6 = 12500000 / 1_000_000 = 12.5 USDT

12.5 USDT, 12.5 миллион емес. Егер әдеттің күшімен 10^9-ға бөлсеңіз (кәдімгі жетондағыдай), 0.0125 шығар еді — мың есе қате. Бір ғана сан — үш реттік айырма. Аңқау интеграцияларда ақша дәл осылай жоғалады: бәріне бірдей қатаң жазылған 10^9 бөлгіші. Сондықтан decimals-ті ешқашан хардкодтамаңыз — оны жетонның өз метадеректерінен алыңыз.

get_jetton_info: decimals пен жетон метадеректерін қайдан алу керек

Болжамай отыру үшін қосарлас құрал бар — get_jetton_info. Ол жетонның мастер-контрактісін оқып, оның метадеректерін береді:

  • атауы (name);
  • символы (symbol);
  • decimals — бөлгіш соның негізінде есептелетін дәл сол сан;
  • эмиссиясы (total supply).

Агент үшін сенімді сценарий — екі шақыру: жетон таныс емес болса, алдымен decimals мәнін білу үшін get_jetton_info, содан кейін raw-балансты алу үшін get_jetton_balance, тек ең соңында ғана көрсету үшін raw / 10^decimals амалын орындау.

1) get_jetton_info(USDT)            -> decimals = 6
2) get_jetton_balance(owner, USDT)  -> raw = 12500000
3) human = 12500000 / 10^6          -> 12.5 USDT

Промптты агент осы қадамдарды өзі жалғайтындай етіп құрастыруға болады:

USDT үшін decimals мәнін get_jetton_info арқылы ал, содан кейін UQAbc…xyz әмиянының балансын get_jetton_balance арқылы алып, raw-ды адам оқитын санға аудар.

Егер сіз тек USDT-мен емес, кез келген жетондармен жұмыс істесеңіз, мұндай реттілік міндетті: таныс емес токен үшін оның decimals мәні 6 па, 9 ба — алдын ала білмейсіз. USDT үшін decimals = 6 — константа, бірақ оны get_jetton_info-дан алып отыру әдеті сізді алғашқы стандартқа сай емес жетонда-ақ құтқарады. Дәл сол тәсіл TON-дағы кіріс USDT-төлемдерін анықтаудың негізінде жатыр — онда 1 USDT-ны микроскопиялық шаңмен шатастырмау үшін decimals критикалық маңызды.

parse_address: сұрау алдында мекенжайды офлайн тексеру

«Нөлдік» баланстың тағы бір жиі себебі — иесінің қисық мекенжайы. Пайдаланушылар мекенжайларды әртүрлі форматта жібереді: EQ… (bounceable), UQ… (non-bounceable), raw (0:…). Балансты сұрар алдында мекенжайды parse_address арқылы қалыпқа келтірген пайдалы — ол офлайн (желіге жүгінбей) кез келген форматтағы мекенжайды алып, оны үшеуіне де (EQ/UQ/raw) түрлендіреді және оның жалпы дұрыс-бұрыстығын айтады.

Бұл арзан, лезде орындалады және «мекенжай басқа болғандықтан баланс 0» деген қателердің тұтас класын жояды — әсіресе мекенжай сенімсіз көзден, пайдаланушы енгізуінен немесе чаттан келсе.

Қалай қосу керек: тегін жергілікті немесе hosted

Үш құрал — parse_address, get_jetton_info, get_jetton_balance — «әмиянда қанша USDT бар» деген сұраққа бірде-бір бөгде индексерсіз толық әрі адал жауап береді.

Тегін жергілікті

@tonnode/mcp пакеті — open source (MIT), npm мен GitHub-та жатыр. Жоғарыдағы мысалдан алынған сол жария конфигтің өзі (npx -y @tonnode/mcp) оқу құралдарының толық жинағын береді, оның ішінде get_jetton_balance, get_jetton_info және parse_address — бөлек кілттің қажеті жоқ.

Клиентті қайта іске қосасыз — сонда агент жетон балансын ADNL бойынша оқып та қояды. Агентке лимиттері бар жария шлюз емес, бөлек MCP-сервер жалпы не үшін керегін TON-дағы ЖИ-агенттерге арналған MCP туралы жазбада талдағанбыз. Ал тегін жария конфиг қай жерде және неге аяқталатыны — TON-ның жария лайтсерверлерінің лимиттерін талдауда.

Hosted — өткізу қабілеті керек болғанда

Жергілікті рейт жеткіліксіз болғанда (боттар, бэкендтер, продакшн-жүктеме) өз кілтіңізбен hosted-эндпоинтке ауысасыз. Құралдар жинағы бәрінде бірдей — барлығы 16, оның ішінде оқу блогы да; тарифтер тек кепілді өткізу қабілетімен ерекшеленеді:

  • Hobby — мәңгі тегін, минутына 60 сұраныс;
  • Pro — айына $29, минутына 300 сұраныс;
  • Scale — айына $199, минутына 1200 сұраныс.

Hosted-қосылу тек ортақ эндпоинтке өз кілтіңізбен жүгінетініңізбен ғана ерекшеленеді:

{
  "mcpServers": {
    "ton": {
      "type": "http",
      "url": "https://mcp.tonnode.io/mcp",
      "headers": { "Authorization": "Bearer tn_live_…" }
    }
  }
}

Егер дашборд, баланс тексеретін бот немесе мекенжайларды жиі сұрайтын агент жасап жатсаңыз — жария API лимиттеріне тірелмеу және ең қолайсыз сәтте 429 ұстамау үшін кілт алыңыз.

Қысқаша

  • TON-дағы USDT — жетон, әрі баланс негізгі мекенжайда емес, бөлек жетон-әмиянда жатыр.
  • get_jetton_balance жетон-әмиянның мекенжайын он-чейн өзі есептейді және балансты оқиды — индексер де, өз базаңыз да керек емес.
  • Баланс raw-бірліктермен келеді; көрсету үшін 10^decimals-ке бөліңіз.
  • USDT-де decimals = 6 (бөлгіші 1_000_000), жетондардың көпшілігінде — 9. Хардкодтамаңыз — get_jetton_info-дан алыңыз.
  • Бүкіл жолды тегін тексеруге болады: npx -y @tonnode/mcp, жария конфиг, оқудың толық жинағы.

Тегін Hobby кілті — минутына 60 сұраныс, картасыз — кірген бойда беріледі: кілт алу. Нақты әмиянда parse_address → get_jetton_info → get_jetton_balance тізбегін өткізіп, 12500000 raw дәл 12.5 USDT-ға айналатынына — 12.5 миллионға да, 0.0125-ке де емес — көз жеткізуге ол әбден жетеді.

Агентіңізге TON-ға қолжетімділік беріңіз

16 MCP-құрал: оқу, кастодиалды емес сваптар, кроссчейн және әмияндар. Тегін тариф — 60 сұрау/мин, карта керек емес.