Todos los artículos
9 min de lectura

Qué son los decimals de un jetton en TON (USDT = 6, no 9)

Decimals de un jetton en TON: por qué USDT usa 6 y casi todos los demás 9, cómo get_jetton_info devuelve decimals y por qué es crítico para balances y swaps

decimals de jettonUSDT en TONmetadatos de jettonTEP-64TON MCPunidades raw

Estás escribiendo un agente que muestra el balance de USDT. Consultas el balance del jetton-wallet, recibes 5000000, divides entre 10^9 — y en pantalla aparece 0.005 USDT en lugar de los 5 USDT reales. Las transacciones pasan, el RPC responde, el get-method devuelve un número — y aun así el monto falla exactamente por un factor de 1000. La culpable es una sola cifra que casi todo el mundo hardcodea por costumbre: decimals.

Si estás conectando un agente de IA a TON o calculas montos de jettons a mano, decimals es lo primero que hay que entender antes de tocar cualquier balance o swap. Veamos por qué USDT tiene decimals = 6 y no el 9 habitual de TON, de dónde sale ese número y cómo obtenerlo con una sola llamada, sin adivinar.

Decimals de un jetton en TON: unidades raw vs. número legible por humanos

La blockchain no puede almacenar fracciones. Sencillamente no puede. En TON, como en casi todas partes, cualquier monto vive en el contrato como un número entero — las llamadas unidades raw (las unidades mínimas indivisibles). No existe ningún 5.5 en el diccionario del contrato ni puede existir — solo hay un entero como 5500000.

Para convertir ese entero en el monto que ve una persona hace falta una escala. Esa escala es precisamente decimals: la potencia de diez que separa el entero almacenado del monto legible por humanos:

human = raw / 10^decimals
raw   = human * 10^decimals

La analogía es simple. El dinero de tu billetera está en dólares, pero la contabilidad del banco lo lleva todo en centavos, con números enteros: 100 centavos = 1 dólar, es decir, decimals = 2. ¿Quieres mostrarle dólares al usuario? Divides los centavos entre 10^2 = 100. Con los jettons pasa exactamente lo mismo, solo cambia la potencia de diez.

El punto clave: la propia blockchain no sabe dónde va la "coma" del número. Opera con unidades raw enteras. Dónde colocar la coma al mostrárselo al usuario lo decide el cliente, leyendo decimals de los metadatos del jetton. Si te equivocas con decimals, la coma se va de sitio y el importe que muestras deja de tener sentido.

USDT en TON tiene decimals = 6; la mayoría de los jettons, 9

Dos cifras que hay que memorizar:

  • USDT (Tether) en TON → decimals = 6. Es decir, 1 USDT = 1 000 000 de unidades raw.
  • La mayoría del resto de jettons de TON → decimals = 9. Ese mismo valor es además el que se asume por defecto: si el campo decimals no aparece en los metadatos, el estándar obliga al cliente a darlo por igual a 9.

De dónde sale el nueve. El propio GRAM (el antiguo Toncoin, renombrado en junio de 2026 — la red se sigue llamando TON) tiene 9 decimales: 1 GRAM = 10^9 nanogramos, y ese "nano" es justamente la unidad raw. El estándar de jettons de TON heredó ese valor por defecto, y la inmensa mayoría de tokens de la red vive con decimals = 9. Los desarrolladores se acostumbran a escribir / 1e9 sin mirar.

USDT, en cambio, es un recién llegado del mundo Ethereum, donde Tether ha usado siempre 6 decimales. El emisor conservó su precisión de siempre también en TON. Por eso USDT es la excepción con la que tropieza casi cualquiera que "simplemente hardcodeó el 9" — y resulta ser justo el jetton más usado para pagos.

Calculemos el precio del error. Supón que en el jetton-wallet hay 5 000 000 de unidades raw de USDT:

  • correcto (decimals = 6): 5 000 000 / 10^6 = 5 USDT;
  • incorrecto (decimals = 9): 5 000 000 / 10^9 = 0.005.

Un desfase de exactamente 10^(9−6) = 1000 veces. Y al revés: si el usuario escribe "envía 5 USDT" y tú multiplicas por 10^9, intentarás mover 1000 veces más. Para un bot de pagos, esa es la diferencia entre "pagado" y "rechazado".

De dónde sale decimals: los metadatos del jetton y el estándar TEP-64

Es importante entenderlo: decimals no es un campo del código del wallet ni una constante del protocolo. Es parte de los metadatos de cada jetton concreto, descritos por el estándar TEP-64 (Token Data Standard). Cada jetton declara por sí mismo su decimals, su nombre, su símbolo y su imagen.

TEP-64 permite almacenar los metadatos en tres formatos:

  • on-chain — todos los campos viven en un diccionario (dictionary) directamente en el contrato del jetton; no hay que descargar nada;
  • off-chain — en el contrato solo hay un enlace (uri), y todo el JSON con los campos (name, symbol, decimals, image) vive en esa URI, en un servidor web o en IPFS;
  • semi-chain (híbrido) — parte de los campos en el diccionario on-chain, parte vía uri; el cliente descarga el contenido off-chain y lo mergea con los valores del diccionario.

La regla de fusión según TEP-64 es esta: si el diccionario contiene la clave uri, el cliente está obligado a descargar el contenido off-chain del enlace y combinarlo con los valores del diccionario on-chain. Cada formato tiene un costo de lectura distinto: on-chain se lee con un único get-method, off-chain exige además una petición HTTP. Manejar los tres casos a mano no es precisamente divertido, y es justo aquí donde agradeces que una sola herramienta lo haga por ti.

Los metadatos de USDT: cómo get_jetton_info devuelve decimals = 6

USDT en TON guarda sus metadatos en formato off-chain: en el contrato maestro del jetton hay un enlace al JSON off-chain, y es en ese JSON donde están escritos name, symbol y, sobre todo, decimals = 6. Para montar correctamente la ficha del jetton, el cliente tiene que leer el contrato, extraer el enlace, descargar el JSON y parsear los campos.

No hace falta tener en la cabeza el formato TEP-64 ni parsear celdas del diccionario a mano: ese es exactamente el trabajo que asume una sola herramienta. get_jetton_info va al contrato por ti, parsea los metadatos y te devuelve directamente decimals = 6 — y sobre ese número se construye toda la aritmética.

Cómo obtener decimals con una sola llamada: get_jetton_info

En lugar de leer el diccionario a mano, detectar el formato (on/off/semi-chain), seguir la URI y mergear el JSON, existe get_jetton_info. Es una herramienta del servidor MCP de TONNode: recibe la dirección del contrato maestro del jetton y devuelve los metadatos ya ensamblados — nombre, símbolo, decimals y emisión.

TONNode es un servidor MCP hospedado para TON. MCP (Model Context Protocol) es el estándar mediante el cual los agentes de IA (Claude, Cursor, ChatGPT/Codex, cualquier cliente MCP) invocan herramientas. Se conecta gratis y de forma local, con el set completo de herramientas de lectura:

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

El paquete @tonnode/mcp es open source (MIT) y funciona sobre el protocolo nativo ADNL de TON, sin capas HTTP intermedias. A partir de ahí, al agente le basta una petición normal en lenguaje humano:

Con la herramienta get_jetton_info averigua los decimals del jetton USDT en TON (dirección del contrato maestro: tal y cual) y calcula cuánto es en USDT legibles para un balance de 5 000 000 raw.

get_jetton_info devolverá decimals = 6, y toda la aritmética posterior se apoya en ese número, no en una suposición. La misma llamada para cualquier otro jetton devolverá su propio valor (normalmente 9, pero siempre hay que comprobarlo). La regla de oro:

No hardcodees el 9. Lee decimals de get_jetton_info para cada jetton.

El nueve funcionará para la mayoría de los tokens y se romperá en silencio con USDT — que es justo el jetton donde más dinero real se mueve. Por qué un agente de IA necesita un acceso MCP propio a TON en lugar de un RPC público con límites lo explicamos en la nota sobre el servidor MCP para agentes en TON.

Por qué un decimals incorrecto rompe balances y swaps

decimals no es cosmética de presentación. Interviene en todos los puntos donde un monto cruza la frontera "raw ⇄ humano", y el error se propaga por toda la cadena.

Balances

get_jetton_balance devuelve el balance del jetton en unidades raw (el jetton-wallet correcto se calcula on-chain; no tienes que buscarlo tú). Ese entero por sí solo no significa nada sin decimals: no puedes mostrárselo bien al usuario hasta que lo dividas entre 10^decimals:

raw = 5 000 000
decimals = 6  → 5 USDT      ✅
decimals = 9  → 0.005       ❌ (1000 veces menos)

El orden correcto en el agente: primero get_jetton_info → tomar decimals, después get_jetton_balance → dividir el raw entre 10^decimals. Y cómo los liteservers públicos se estrellan contra sus límites justo con este tipo de lecturas lo desglosamos en el análisis de los límites de los liteservers públicos de TON.

Swaps

get_swap_quote entrega una cotización firme de DEX GRAM⇄jetton (vía el protocolo Omniston, liquidez de STON.fi + DeDust) — y tanto el monto de entrada como la estimación de salida van también en unidades raw del jetton. Aquí un decimals incorrecto golpea dos veces. Supón que el usuario quiere swapear 10 USDT: con decimals = 6 hay que pasar a la cotización 10 000 000 raw. Aplicaste 9 por error y pediste 10 000 000 000 raw, o sea un swap de 10 000 USDT que no existen en el wallet. El error inverso al parsear la respuesta rebajará el monto esperado 1000 veces, y el usuario concluirá que el tipo de cambio es un robo.

El mismo principio rige en las cotizaciones cross-chain y en cualquier transacción: en la blockchain todo va en unidades raw enteras, y el único puente hacia los montos legibles es el decimals correcto.

Comprobación en la práctica: get_jetton_balance y get_swap_quote

Armemos un escenario corto que el agente ejecuta solo, sin una sola cifra hardcodeada.

Escenario paso a paso

1. Averiguar decimals. get_jetton_info(USDT master) → decimals = 6.

2. Leer el balance. get_jetton_balance(propietario, USDT master) → 5 000 000 (raw). Calculamos: 5 000 000 / 10^6 = 5 USDT. Si hubiéramos usado 9, habríamos obtenido 0.005. Esa es tu señal de alarma: si ves un número inesperadamente diminuto en USDT, lo primero es comprobar si aplicaste 9 en lugar de 6.

3. Pedir la cotización. Queremos swapear 5 USDT a GRAM. En raw son 5 × 10^6 = 5 000 000 — es exactamente ese monto el que pasamos a get_swap_quote. El resultado también llega en raw, y GRAM usa 9 decimales, así que dividimos la respuesta entre 10^9 antes de mostrarla al usuario.

4. ¿No te fías de los metadatos? Puedes verificarlo on-chain directamente. run_get_method invoca cualquier get-method de solo lectura de un contrato — por esa vía puedes llamar a get_jetton_data del contrato maestro y comprobar que las cifras cuadran. Es más flexible, pero exige conocer el formato TEP-64 y parsear el diccionario a mano; cuando importan la velocidad y la fiabilidad, get_jetton_info cierra el asunto con una sola respuesta. En qué se diferencian los proveedores RPC de TON en cuanto a acceso a get-methods y al archivo lo repasamos en la comparativa honesta de proveedores RPC de TON.

El prompt para el agente

El prompt de todo el escenario suena de lo más cotidiano:

Toma USDT en TON. Con get_jetton_info lee los decimals. Con get_jetton_balance obtén mi balance en raw y conviértelo a USDT legibles. Después, con get_swap_quote, calcula la cotización para swapear 5 USDT a GRAM — no olvides convertir los 5 USDT a raw con el decimals que leíste.

Un detalle más para escenarios agénticos: las herramientas de swap de TONNode son estrictamente no custodiales. El servidor nunca firma ni guarda claves: build_swap_tx devuelve un mensaje TonConnect sin firmar, que firma el wallet del usuario. Ni siquiera un decimals correcto le da al servidor control sobre los fondos: solo calcula y construye la transacción. Dónde se pierden los milisegundos y de dónde sale la latencia en los swaps de TON lo cubrimos en el análisis del trading de alta velocidad en TON.

En resumen

  • decimals es la potencia de diez entre las unidades raw de la blockchain y el monto legible por humanos: human = raw / 10^decimals.
  • El valor por defecto en TON son 9 decimales; USDT usa 6 (1 USDT = 1 000 000 raw). Confundirlos = fallar por un factor de 1000.
  • decimals vive en los metadatos del jetton (TEP-64), no en el código. USDT guarda sus metadatos off-chain, pero get_jetton_info igualmente entrega decimals = 6 en una sola respuesta.
  • No hardcodees el 9. Lee decimals con get_jetton_info y construye sobre él todos los balances (get_jetton_balance) y cotizaciones (get_swap_quote).

Consigue tu clave gratuita Hobby (60 peticiones/min, sin tarjeta) y lee los decimals de cualquier jetton con get_jetton_info ahora mismo: https://tonnode.io/dashboard?plan=hobby

Dale a tu agente acceso a TON

16 herramientas MCP: lectura, swaps no custodiales, cross-chain y billeteras. Plan gratuito — 60 req/min, sin tarjeta.