EQ, UQ y raw: formatos de dirección TON y el depósito que rebota
EQ, UQ y raw: formatos de dirección en TON, bounceable vs non-bounceable y por qué el primer depósito a una wallet nueva rebota al remitente.
Un desarrollador genera una wallet nueva, copia la dirección, le manda los primeros 5 GRAM para gas — y un minuto después las monedas vuelven a la wallet de origen. Saldo de la dirección nueva: cero. Sin errores, sin «reverted», la transacción salió bien. Simplemente el dinero… rebotó. En los chats de TON es un clásico: «envié a mi propia dirección y no llegó». Y casi siempre la causa es la misma — formatos de dirección confundidos y el flag bounceable.
Vamos a ver, con hechos, qué son los formatos de dirección de TON — EQ, UQ y raw, en qué se diferencia bounceable de non-bounceable, y por qué el primer depósito a una wallet nueva vuelve al remitente. Y de paso te muestro cómo comprobar todo esto con una sola llamada a una herramienta desde un agente de IA, sin levantar ni SDK ni nodo.
Los tres formatos de dirección en TON: raw, EQ y UQ — en qué se diferencian
Por dentro, todas las direcciones de TON son lo mismo: el número de workchain más el hash de 256 bits del state init del contrato. Eso es exactamente el formato raw:
0:83dfd552e63729b472fcbcc8c45ebcc6691702558b68ec7527e1ba403a0f31a8
A la izquierda de los dos puntos va el workchain (normalmente 0, el básico; -1 es el masterchain), a la derecha el hash de 256 bits en hex. Es un formato honesto y sin ambigüedad, pero no tiene checksum: un error de tipeo en un solo carácter y obtienes otra dirección que parece válida. El formato raw es el que suelen esperar los get-methods de los contratos y las herramientas de bajo nivel; a los humanos casi nunca se les muestra.
La segunda representación es la user-friendly: esos 48 caracteres en base64url que ves en wallets y exploradores:
EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N (bounceable)
UQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqEBI (non-bounceable)
Dentro lleva el mismo par «workchain + hash», más un byte de flags y un checksum CRC16 al final. El CRC detecta los errores de tipeo: una dirección corrupta simplemente no pasa la validación, antes siquiera de enviarla. Y es de ese byte de flags de donde nacen los prefijos EQ y UQ.
Lo esencial, para tenerlo claro desde el principio:
- raw y user-friendly son dos maneras de escribir la misma dirección.
- EQ y UQ son dos variantes de la misma dirección user-friendly, que difieren exactamente en un flag.
Es decir, EQ… y UQ… de una misma wallet apuntan al mismo hash raw, al mismo contrato, al mismo saldo. No son dos wallets distintas ni dos cuentas distintas. La única diferencia es un bit que expresa la intención del remitente.
Bounceable (EQ) vs non-bounceable (UQ): qué significa el flag
Ese byte de flags dentro de la dirección user-friendly es lo que determina el prefijo:
| Flag | Tag | Prefijo (mainnet) | Prefijo (testnet) |
|---|---|---|---|
| bounceable | 0x11 |
EQ |
kQ |
| non-bounceable | 0x51 |
UQ |
0Q |
Para testnet, al tag se le suma 0x80 — de ahí los exóticos kQ y 0Q. Pero lo que nos interesa es el significado del flag, no la aritmética de los tags.
Bounceable (EQ) significa literalmente: «si algo sale mal en el lado receptor, devuélveme las monedas». Es una protección pensada para smart contracts. Si mandas dinero a un contrato que debería procesarlo y resulta que falla con un error, que todavía no está desplegado o que se queda sin gas, no quieres que las monedas se pierdan en el vacío. El mecanismo de bounce las devuelve al remitente, menos la comisión.
Non-bounceable (UQ) significa lo contrario: «entrega y déjalo ahí, pase lo que pase». Sin devoluciones: las monedas simplemente se quedan en la dirección.
Para transferencias cotidianas entre personas la diferencia es invisible… hasta que llega un caso muy concreto.
Por qué el primer depósito a una wallet sin desplegar «rebota»
Aquí está la trampa. En TON, la dirección de una wallet existe antes de que el contrato de esa wallet esté realmente desplegado en la blockchain. La dirección es un hash determinista del código del contrato y sus datos iniciales (la clave pública), así que la conoces nada más generar la mnemónica, completamente offline. Pero mientras por esa dirección no haya pasado la primera transacción, la cuenta está en estado uninit (no inicializada): la dirección existe, pero el código del contrato todavía no.
Ahora mira lo que pasa con una transferencia bounceable:
- Envías a esa dirección uninit una transferencia en formato EQ (bounceable).
- La red intenta entregar las monedas y «llamar» al contrato receptor. No hay quien las reciba — en la dirección no hay contrato.
- Se dispara el bounce: como la entrega falló, las monedas vuelven al remitente, menos la comisión.
Resultado: el famoso «rebote». La transacción se ejecutó con éxito, pero el saldo de la wallet nueva sigue en cero y el dinero regresó a donde vino. Nadie robó nada, la red funcionó exactamente como está diseñada — simplemente usaste el formato bounceable donde no debías.
¿Y si la misma transferencia se envía en formato UQ (non-bounceable)?
- La red intenta entregar las monedas a la dirección uninit.
- El bounce está desactivado por el flag — no hay nada que devolver.
- Las monedas se quedan en la dirección, aunque el contrato todavía no esté desplegado.
Wallet fondeada. Más tarde, cuando envíes desde ella la primera transacción saliente, junto con ella se desplegará el código del contrato — y la cuenta pasará a active. A partir de ese momento acepta sin problema cualquier transferencia, incluidas las bounceable. La regla del UQ es crítica solo para el primer depósito a una wallet aún sin desplegar.
La buena noticia: el ecosistema va cerrando este agujero por el usuario. Las wallets v5r1 y varios clientes muestran la dirección por defecto justamente en formato non-bounceable (UQ) — precisamente para que el novato no pierda su primer depósito. Pero en cuanto trabajas con direcciones de forma programática — desde un backend, un script o un agente de IA — la responsabilidad del flag vuelve a ser tuya.
Cómo enviar bien la primera transferencia: UQ en lugar de EQ
La regla práctica cabe en una línea:
El primer depósito a una wallet nueva (uninit) — siempre a UQ. Después, como quieras.
La lógica completa para cualquier servicio que envía fondos al usuario:
- Dirección del destinatario en estado uninit → envía a UQ (non-bounceable).
- Dirección active → puedes enviar a EQ (bounceable).
- Envías a un smart contract (DEX, minter de jettons, escrow) → EQ, para que ante un error el dinero vuelva.
El problema es que «a ojo» EQ y UQ se distinguen por un solo carácter de prefijo, y el estado uninit/active no se ve en la dirección en absoluto. Ambas comprobaciones hay que hacerlas por código. Y aquí no hace falta meter @ton/ton en el proyecto, levantar un provider y parsear celdas — las dos preguntas se resuelven con dos herramientas de un servidor MCP que el agente de IA invoca por su cuenta.
Si el tema de generar una wallet y hacerle el primer depósito te resulta nuevo, tienes un análisis aparte en la guía sobre cómo crear una wallet TON.
parse_address: convertir y validar direcciones offline con una sola llamada
parse_address es una herramienta offline de TONNode, el servidor MCP hosted para TON. Decodifica la dirección, recalcula los formatos y verifica el CRC16 sin tocar la red: no necesita ni nodo ni clave — es pura matemática sobre una cadena de texto, así que es instantánea y no gasta cuota de tus límites.
Esto es lo que hace:
- convertir
EQ ⇄ UQ ⇄ rawen cualquier sentido; - verificar la validez de la dirección (si cuadra el checksum);
- mostrar el flag bounceable y el número de workchain.
MCP (Model Context Protocol) es el estándar por el que los agentes de IA (Claude, Cursor, ChatGPT/Codex y cualquier cliente MCP) invocan herramientas. El servidor MCP se conecta con una sola entrada en la config del cliente. La variante local y gratuita con el set completo de herramientas de lectura:
{
"mcpServers": {
"ton": {
"command": "npx",
"args": ["-y", "@tonnode/mcp"]
}
}
}
A partir de ahí, al agente le basta un prompt normal:
Toma la dirección
EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2Ny muéstrala en formato non-bounceable (UQ) y raw. Verifica que el checksum sea válido.
El agente llamará a parse_address y devolverá la versión UQ de la misma wallet, el hash raw y el estado de validez. Nada de malabares manuales con base64url ni riesgo de equivocarte en 48 caracteres.
get_account_state: cómo saber si la wallet está desplegada antes de enviar
El asunto no termina en el formato — falta saber en qué estado está la dirección: active o uninit. Esa ya es una pregunta on-chain, y la responde get_account_state. La herramienta devuelve el estado de la cuenta, los flags y los datos de la última transacción.
La lógica antes de enviar la primera transferencia:
get_account_statedevolvió uninit → la dirección aún no está desplegada → enviamos a UQ.- devolvió active → la wallet está desplegada → se puede enviar tranquilamente a EQ.
Prompt para el agente:
Comprueba con get_account_state si la dirección
UQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqEBIestá desplegada. Si el estado es uninit, recuérdame que el primer depósito hay que enviarlo en formato UQ.
La combinación queda así: generate_wallet crea la wallet (versiones v3r2/v4/v5r1/highload_v3) y devuelve una dirección que, recién creada, está siempre en uninit — la red todavía no sabe que existe. Por tanto, el primer depósito va estrictamente a UQ. Antes de enviar, get_account_state confirma que la dirección de verdad está uninit, y parse_address garantiza que tomaste justamente la representación non-bounceable. Tras el depósito, conviene llamar a get_balance y comprobar que las monedas se quedaron en la dirección y no rebotaron.
Un punto importante sobre la generación: generate_wallet devuelve la mnemónica, las claves y la dirección al usuario — el servidor no las guarda ni firma nada por ti. Es una mecánica no custodial, y se aplica a todas las herramientas de swap, cross-chain y wallet.
Una pequeña aclaración terminológica: GRAM es el Toncoin renombrado (el cambio fue en junio de 2026); la red en sí sigue llamándose TON.
Checklist: cómo no perder el primer depósito en TON
Un algoritmo corto para cada primera transferencia a una wallet nueva:
- Generaste la dirección (
generate_walleto tu propio SDK) — asúmela uninit por defecto. - Comprueba el estado con
get_account_state:uninitoactive. - Si es uninit — convierte la dirección del destinatario a UQ con
parse_addressy envía el primer depósito únicamente a esa versión. - Si es active — puedes usar
EQ; para contratos incluso es preferible. - A smart contracts envía siempre bounceable (
EQ), para que ante un fallo el dinero vuelva. - Tras el depósito verifica con
get_balance— las monedas deben quedar en la dirección, no rebotar. - Recuerda:
EQyUQson la misma wallet (el mismo hash raw); no eliges una dirección, eliges el comportamiento ante una entrega fallida.
Las dos comprobaciones clave — parse_address (offline) y get_account_state (on-chain) — están disponibles de inmediato, sin infraestructura propia. Consigue una clave Hobby gratuita (60 solicitudes/min, sin tarjeta) y llama a ambas herramientas directamente desde tu agente de IA: https://tonnode.io/dashboard?plan=hobby.
Y a partir de ahí, con el mismo esquema, se resuelven cómodamente tareas vecinas: detectar pagos entrantes de USDT en TON, leer el saldo de USDT con una sola llamada o invocar un get-method de un contrato sin SDK. Los formatos de dirección son el cimiento sobre el que se apoya todo lo demás: entiende EQ/UQ una sola vez y ningún depósito «rebotado» volverá a tomarte por sorpresa.
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.