Cuenta TRON no activada: qué bloquea y cómo resolverlo
Una dirección es un par de claves hasta que la red tiene una cuenta para ella. En eso consiste toda la «cuenta TRON no activada», y es la respuesta que sorprende: la dirección está bien formada, la cartera la muestra, el código QR se escanea, y la cadena nunca ha oído hablar de ella. Para una mesa de pagos el estado aparece en dos sitios distintos — la cartera que envía y la dirección a la que se paga — y solo uno de los dos es un rechazo.
Qué es en realidad la activación
Una dirección de TRON se deriva de un par de claves sin conexión. Al crearla no se registra nada en ninguna parte, y la red se entera de ella solo cuando una transacción le crea un registro de cuenta. Nuestra propia comprobación es literal en eso: pedimos a un nodo la cuenta que hay detrás de la dirección, y una respuesta vacía es lo que significa activated: false. No «no la hemos encontrado» ni «parece nueva»: ahí no hay ninguna cuenta.
La forma corriente de que nazca una es una transferencia de TRX entrante: envíe TRX a la dirección y la red crea la cuenta mientras ejecuta esa transferencia. Crear una cuenta no es gratis. Lo que cuesta es un parámetro de la cadena y no una cifra que merezca imprimirse en una página, así que léalo de la red y no de cualquier sitio que pueda llevar un año desactualizado. Lo que importa aquí es que es una transacción corriente, y que después la dirección es una cuenta como cualquier otra.
Qué bloquea: la cartera que va a enviar
La energía se delega a una cuenta, y no hay nada a lo que delegar cuando no existe ninguna cuenta. En eso consiste todo el rechazo. Un pedido en el mode A o en el mode C que nombre una cartera así como from vuelve como 422 invalid_address con details.reason en inactive_wallet, junto con details.index — qué transferencia del lote — y details.address. Es uno de los cuatro fallos que una mesa de pagos se encuentra una y otra vez, y uno de los dos que un pedido rechaza de plano en vez de ponerles precio.
Tres propiedades de ese rechazo importan antes de escribir el manejador.
No gasta la Idempotency-Key. Ninguno de los rechazos de esta familia lo hace: la petición está bien formada y simplemente no podemos aceptarla con esas direcciones. En cuanto la cartera exista, la misma clave con un cuerpo idéntico byte a byte es una repetición válida y no un conflicto, así que no hay que volver a derivar nada de su lado.
No se responde desde una caché. El estado de las direcciones se cachea aquí, pero la activación se vuelve a leer saltándose la caché antes de rechazar un pedido por ella: una cartera activada hace unos segundos se acepta enseguida y no cuando caduque alguna entrada. Repita de inmediato; no hay nada que esperar.
No existe en el mode B. Allí la transacción llega ya firmada por el propietario de la dirección de origen, así que la cuenta está ahí por construcción y la comprobación sería una pregunta que ya se ha respondido sola.
No activada no es mal formada
Dos respuestas llevan el mismo código de error y significan cosas opuestas. 400 invalid_address, sin ningún details.reason, va sobre la forma de la cadena de texto: no es una dirección de TRON, y nada de lo que ocurra en la cadena la convertirá en una. 422 invalid_address con un details.reason va sobre el estado de una dirección perfectamente buena, y una sola transacción lo arregla. Un pipeline que las trata igual reintenta la primera para siempre y abandona la segunda, así que conviene ramificar por la presencia de details.reason y no por el código de error, que las dos comparten.
Qué cuesta: la dirección a la que se paga
Del lado del que recibe no se rechaza nada; un destinatario sin activar es un precio. Una transferencia a una dirección sin saldo de USDT tiene que abrir la cuenta de token del destinatario además de mover los tokens, y eso consume unas 131,000 unidades de energía frente a unas 65,000 para una dirección que ya tiene USDT (por qué se diferencian las dos). A la tarifa del protocolo eso son 13.1 TRX de quema en vez de 6.5 TRX, y en una tanda de pagos a clientes nuevos buena parte del lote puede estar en ese estado a la vez — lo que cuesta alquilar esa energía se mueve con el mercado, la quema no.
Aquí las dos preguntas se separan, y los nombres invitan a confundirlas, así que sea exacto. activated pregunta si la red tiene una cuenta para la dirección. holds_usdt pregunta si su saldo de USDT está por encima de cero. El precio sigue a la segunda: kind es double siempre que la dirección no tenga USDT, esté activada o no. El aviso inactive_recipient sigue a la primera. Así que una dirección activada hace años a la que sencillamente nunca se le ha pagado en USDT no lleva aviso y aun así se cobra como double; y una dirección que nunca se ha activado puede tener USDT — un saldo TRC-20 vive en el almacenamiento del propio contrato del token, así que una transferencia entrante crea un saldo y no una cuenta —, lo que la cobra como single y la avisa con inactive_recipient al mismo tiempo. Las dos parecen una sola pregunta hasta que una dirección las responde de distinta manera.
Comprobar una dirección, y comprobar quinientas
Para una sola dirección, GET /v1/address-check responde a las dos preguntas y a dos más en una llamada: activated, holds_usdt, blacklisted, is_contract, y el expected_kind que se deduce de ellos.
Para un lote, POST /v1/estimate admite hasta 500 transferencias y no rechaza nada: todo lo que detecta vuelve como warnings en el ítem, incluidos los hallazgos que detendrían un pedido. A los destinatarios siempre se les examina. Al remitente se le examina solo si usted lo nombra: from es opcional en un ítem de estimación y no cambia ningún precio, y lo único que compra es la respuesta. Ahí inactive_sender es el mismo hallazgo que un pedido informa como un 422, llegando cuando no hay nada en juego.
POST /v1/estimate
{"transfers":[{"from":"TN3W…","to":"TMu1…"}]}
# avisos que puede llevar un ítem: blacklisted, inactive_recipient,
# contract_recipient, inactive_sender, blacklisted_sender
Ninguna de las dos llamadas reserva ni cobra nada, así que una lista se puede filtrar tantas veces como permitan los límites de peticiones. Lo que ninguna de las dos ensaya es el pedido en sí, que gasta dinero de verdad en todos los modos.
La solución
Envíe algo de TRX a la dirección, deje que esa transacción se confirme y repita el pedido con la misma clave y los mismos bytes. No hay paso de registro, ni solicitud, ni una segunda llamada a nosotros. La única regla de orden que merece anotarse es que la cartera tiene que existir antes del pedido, no antes de la transferencia: la energía se entrega a una cuenta, así que la cuenta tiene que estar ahí para recibirla.
El mismo requisito vale para una cartera que quiera mantener recargada. Una regla de Auto-refill se rechaza en una dirección sin activar con esa misma palabra de motivo, y en una dirección de contrato con contract_wallet: el consumo de energía de un contrato funciona de otra manera y la regla no tiene nada que dimensionar. Active primero, y ponga la regla después.