Todos los artículos
10 min de lectura

Cómo crear una wallet TON por código (v4, v5, highload)

Crea una wallet TON por código con una llamada a generate_wallet: v3r2, v4, v5r1, highload. Mnemónica, claves, dirección y primer depósito seguro.

TONgenerate_walletwallet TONwallet highloadMCPno custodial

Lanzaste una campaña con 500 códigos promocionales y cada pago necesita su propia wallet TON. O estás escribiendo un agente de IA que crea una wallet «caliente» al vuelo, recibe un depósito y hace algo con él. Lo primero que aparece al buscar en internet es un montón de ejemplos de SDK: instala @ton/ton, averigua en qué se diferencia WalletContractV4 de WalletContractV5R1, llama a mano a mnemonicNew(), deriva las claves, calcula la dirección y no te olvides del subwallet_id del highload. Media jornada se va en código de infraestructura que no tiene nada que ver con tu problema real. Y si las wallets las crea un agente de IA, tiene que saber hacerlo por sí solo, sin que tengas que programarle la criptografía a mano.

A continuación: cómo crear una wallet TON de forma programática (generate wallet / creación de wallets en TON) con una sola llamada a la herramienta generate_wallet, cómo entender las versiones v3r2, v4, v5r1 y highload_v3, y cómo no perder el primer depósito por el error típico con la dirección bounceable.

Por qué crear una wallet TON por código (y por qué no con el SDK)

Crearlas a mano con el SDK funciona bien exactamente hasta el primer despliegue en producción. A escala, aparecen los problemas:

  • Versiones. En TON no existe «una» wallet, sino varios contratos: v3r2, v4, v5r1, highload. Cada uno tiene su propia lógica y su propia dirección para la misma clave. Si te equivocas de versión, obtienes la dirección equivocada.
  • Formatos de dirección. La misma wallet tiene una forma EQ y una forma UQ. Si las confundes al entregar la dirección de depósito, el dinero «rebota» de vuelta (más sobre esto abajo).
  • Agente de IA. A un agente (Claude, Cursor, ChatGPT/Codex) no puedes «darle una librería»: necesita una herramienta que pueda invocar a partir de su descripción. Vía MCP (Model Context Protocol), el agente llama a generate_wallet como a una función normal y recibe una respuesta estructurada lista para usar. La lógica de versiones, claves y formatos vive en el lado del servidor MCP.
  • Stack políglota. No quieres mantener un SDK de TON en Go, Python y Node a la vez — MCP te da una única interfaz para todos.

generate_wallet es una de las 16 herramientas de TONNode, un servidor MCP hosted para TON. Hace exactamente una cosa: crea una wallet nueva y te entrega todo lo necesario para ser su dueño. Si es tu primer contacto con este enfoque, empieza por la guía de MCP para TON.

generate_wallet en una llamada: qué devuelve exactamente

generate_wallet crea una wallet TON nueva y devuelve el conjunto completo para poseerla y recuperarla:

  • la mnemónica (frase semilla) — un conjunto de palabras legible por humanos del que se deriva de forma determinista todo lo demás;
  • la clave privada — para firmar transacciones;
  • la clave pública;
  • la dirección de la wallet — en los formatos estándar de TON.

El prompt para el agente es literalmente así:

Crea una nueva wallet TON versión v5r1 con generate_wallet
y muéstrame la dirección y la mnemónica.

El agente invoca la herramienta con el parámetro de versión y devuelve una estructura más o menos así (los valores son ilustrativos; las claves Ed25519 en TON son hex plano, sin el prefijo 0x de Ethereum):

{
  "version": "v5r1",
  "mnemonic": ["word1", "word2", "...", "word24"],
  "public_key": "e3f1a2…",
  "private_key": "9b7c4d…",
  "address": {
    "bounceable": "EQ…",
    "non_bounceable": "UQ…",
    "raw": "0:abcd…"
  }
}

Sin SDK ni derivación manual. A partir de ahí, tú decides dónde guardarlo. El punto clave: el servidor no se queda con esa mnemónica ni con las claves — lo vemos abajo en la sección sobre no custodia.

Versiones de wallet v3r2, v4, v5r1 y highload_v3: cuál elegir

generate_wallet soporta cuatro versiones de contrato de wallet. Y no es que «más nueva = mejor»: cada una tiene su nicho.

v5r1 (W5) — la opción por defecto para proyectos nuevos

La versión más reciente. Soporta extensiones y escenarios gasless — cuando un relayer externo puede pagar la comisión en nombre del usuario. Es una propiedad del propio contrato v5, no un servicio de TONNode: el servidor solo crea la wallet, no proporciona ningún relayer gasless. Si estás construyendo un agente moderno desde cero y no necesitas específicamente highload, elige v5r1.

v4 — la versión con plugins

La generación anterior de adopción masiva. Soporta plugins: a la wallet se le pueden acoplar contratos-extensión (por ejemplo, para suscripciones y pagos diferidos). Fue durante mucho tiempo el estándar de facto y tiene soporte amplio en wallets y servicios. Elígela si dependes del modelo de plugins de v4.

v3r2 — la wallet básica y simple

Un contrato mínimo, sin extensiones ni plugins. Predecible y barato en gas. Adecuado para direcciones de servicio donde toda la lógica es «recibir y enviar».

highload_v3 — para pagos masivos

Una clase aparte. Una wallet pensada para alto throughput: un solo mensaje externo puede transportar muchas transferencias. Es lo que eliges para pagos por lotes, drops, reparto de recompensas, pasarelas de pago, retiros de exchange. El precio de esa eficiencia es un modelo especial de contabilidad de mensajes (query_id / expiración), así que exige un manejo cuidadoso — consulta la sección sobre cómo guardar los parámetros.

Versión Cuándo elegirla
v5r1 Proyectos nuevos, extensiones, gasless
v4 Necesitas plugins (suscripciones, etc.), máxima compatibilidad
v3r2 Wallet de servicio simple, sin florituras
highload_v3 Pagos masivos/por lotes, throughput alto

Ejemplo de prompt para pagos:

Genera una wallet highload_v3 para pagos por lotes y devuélveme
la mnemónica, las claves y la dirección.

El primer depósito: por qué enviarlo a la dirección UQ non-bounceable

El error más frecuente y más doloroso después de crear una wallet es perder el primer depósito. La mecánica es esta: una wallet recién creada todavía no está desplegada en la blockchain — el contrato físicamente no existe en esa dirección hasta que llega la primera transferencia que despliega el código.

En TON, las direcciones llevan un flag «bounceable»:

  • EQ (bounceable) — si en la dirección no hay un contrato activo, la red devuelve («bounce») la transferencia al remitente. Para una wallet nueva, ese es exactamente tu caso.
  • UQ (non-bounceable) — la transferencia «se queda pegada» a la dirección aunque el contrato aún no esté desplegado. Justo lo que necesitas para el primer depósito.

La regla es simple: el primer depósito a una wallet nueva se envía siempre a la dirección UQ. Si lo mandas a la EQ, rebotará de vuelta y te quedarás preguntándote por qué el saldo está vacío. Una vez que la wallet haga su primera transacción saliente y quede desplegada, puedes usar la forma bounceable con tranquilidad.

¿Cómo obtener la forma UQ de manera fiable? Con la herramienta offline parse_address — convierte y valida los formatos EQ/UQ/raw sin tocar la red:

Con parse_address convierte esta dirección a la forma
UQ non-bounceable para el primer depósito

Después del depósito, comprueba el estado con get_account_state — muestra el estado de la cuenta (uninitialized / active), los flags y la última transacción:

Comprueba get_account_state para UQ… — ¿está desplegada
la wallet y cuál es el saldo?

Mientras el contrato no esté activo, el estado te dirá que el depósito todavía no ha «levantado» la wallet. El desglose completo de formatos está en el artículo sobre los formatos de dirección EQ/UQ/raw.

Wallet highload: fija tú mismo el subwallet_id y el timeout

Una advertencia aparte para quien eligió highload_v3. Aquí la mnemónica sola no basta para reconstruir correctamente una wallet funcional y reproducir su comportamiento. El contrato highload, además de la clave, tiene otros dos parámetros que se definen al crearla y forman parte de su initial data (state init):

  • subwallet_id — identificador de sub-wallet (permite obtener varias direcciones distintas a partir de una misma frase semilla);
  • timeout — la ventana de vida de los mensajes externos, sobre la que se construye la lógica de query_id y expiración.

Importante: generate_wallet devuelve la mnemónica, las claves y la dirección — pero el subwallet_id y el timeout los eliges y los fijas tú como parámetros de construcción de la wallet highload. Eres tú el responsable de anotar los valores con los que se creó la wallet.

La wallet highload lleva la cuenta de qué mensajes siguen «vivos» a partir del timeout. Si restauras la wallet solo con la frase semilla, sin subwallet_id ni timeout:

  • obtendrás una dirección equivocada — tanto subwallet_id como timeout entran en el state init, así que cambiar cualquiera de los dos cambia la initial data del contrato y, por tanto, su dirección;
  • no reproducirás la lógica correcta de expiración y deduplicación de mensajes — y te arriesgas a romper la contabilidad de las transferencias salientes.

Regla práctica: para highload_v3, guarda el subwallet_id y el timeout en tu almacenamiento de secretos junto a la mnemónica, como parte del mismo registro de la wallet. No son metadatos opcionales: son parte de la identidad de la wallet.

# pseudo-registro del secreto
mnemonic:      "word1 word2 … word24"
version:       "highload_v3"
subwallet_id:  <el valor que definiste al crearla>
timeout:       <el valor que definiste al crearla>

Para v3r2/v4/v5r1 no existe este requisito — ahí basta con la mnemónica y saber la versión.

No custodial: el servidor no guarda ni firma claves

La gran pregunta cuando la wallet se crea «en algún servidor»: ¿quién acaba siendo el dueño de las claves? Aquí la respuesta es inequívoca.

generate_wallet es estrictamente no custodial:

  • el servidor nunca guarda las claves privadas, la mnemónica ni los fondos;
  • el servidor nunca firma transacciones por ti;
  • la wallet generada — mnemónica, claves, dirección — se te entrega íntegra en la respuesta y no se conserva en el lado del servidor.

No hay una base de datos con frases semilla ajenas, ni una clave de operador que firme algo en tu nombre. En esencia, generate_wallet es un envoltorio cómodo sobre la generación determinista: la criptografía ocurre, el resultado viaja hacia ti y al servidor no le queda nada. Es la diferencia de fondo frente a las wallets de agente custodiales, donde el servicio retiene la clave (o parte de ella) y firma las transacciones por su cuenta. La comparación completa, en su propio artículo: MCP custodial frente a no custodial.

Conclusión práctica: guarda la respuesta de generate_wallet en tu almacenamiento seguro de inmediato. El servidor no te «sacará» esa misma wallet una segunda vez — no la recuerda, y recuperarla «a través de soporte» será imposible. Es una feature, no un bug.

Cómo conectarlo y crear la primera wallet

Conectarlo es cuestión de un minuto. Levantas el paquete @tonnode/mcp en local con npx, gratis; todas las herramientas de lectura están disponibles sin clave.

Config del cliente MCP (Claude Desktop, Cursor, cualquier cliente MCP):

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

El paquete @tonnode/mcp es open source (MIT), está en npm y GitHub (tonnode/mcp) y funciona sobre el protocolo nativo ADNL de TON, sin capas HTTP intermedias entre tu agente y la red. Reinicia el cliente — y las 16 herramientas, incluidas generate_wallet, parse_address y get_account_state, quedan disponibles para el agente. Cómo engancharlo a un cliente concreto, en la guía de conexión de Claude y Cursor a TON.

generate_wallet está incluido en las 16 herramientas y disponible en todos los planes, incluido el gratuito Hobby — 60 solicitudes por minuto, sin tarjeta. La clave gratuita se emite nada más iniciar sesión. Pagas solo por el throughput, no por el acceso a las herramientas.

A partir de ahí, tres herramientas cubren el escenario completo de «crear la wallet y hacer el primer depósito con seguridad»:

  1. generate_wallet — crear la wallet de la versión que necesitas y llevarte la mnemónica, las claves y la dirección.
  2. parse_address — obtener la forma UQ de la dirección para el primer depósito (offline).
  3. get_account_state — confirmar que el depósito desplegó el contrato.

Ejemplo de prompt completo para el agente:

Crea una wallet v5r1 con generate_wallet. Luego, con
parse_address, dame su dirección UQ para el primer depósito.
Cuando haya enviado las monedas, comprueba con get_account_state
que la wallet está desplegada.

Cuándo necesitas una clave hosted

La ejecución local con npx usa la configuración pública y es perfecta para desarrollo. Si necesitas throughput garantizado bajo carga (esos mismos pagos masivos con highload), conecta el endpoint hosted con tu propia clave:

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

En resumen

  • generate_wallet crea una wallet TON en una sola llamada y devuelve la mnemónica, las claves privada/pública y la dirección — una llamada con la versión que elijas, no un montaje manual de SDK.
  • La versión por defecto para un proyecto nuevo es v5r1; para pagos masivos, highload_v3; v4, por los plugins; v3r2, cuando basta una wallet simple.
  • El primer depósito, siempre a la dirección UQ non-bounceable — de lo contrario rebota; la forma UQ te la da parse_address y el estado lo comprueba get_account_state.
  • Para highload, fija tú mismo el subwallet_id y el timeout y guárdalos junto a la mnemónica — ambos entran en el state init y afectan a la dirección.
  • El servidor es no custodial: no guarda claves ni fondos, y no firma nada por ti — las claves son tuyas.

Consigue la clave gratuita Hobby y crea tu primera wallet con generate_wallet en un par de minutos — 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.