Tous les articles
9 min de lecture

EQ, UQ et raw : formats d'adresses TON et le dépôt qui rebondit

EQ, UQ et raw : les formats d'adresses TON, bounceable vs non-bounceable, et pourquoi le premier dépôt vers un wallet neuf revient à l'expéditeur.

TONadresses TONbounceableEQ UQ rawparse_addressdépôt

Un développeur génère un wallet tout neuf, copie l'adresse, y envoie ses 5 premiers GRAM pour le gas — et une minute plus tard, les fonds sont de retour sur le wallet émetteur. Solde de la nouvelle adresse : zéro. Aucune erreur, aucun « reverted », la transaction est passée avec succès. L'argent a simplement… rebondi. Dans les chats TON, c'est un grand classique : « j'ai envoyé vers ma propre adresse — rien n'est arrivé ». Et la cause est presque toujours la même : des formats d'adresse confondus et le flag bounceable.

Voyons, faits à l'appui, ce que sont les formats d'adresses TON — EQ, UQ et raw, ce qui distingue bounceable de non-bounceable, et pourquoi le premier dépôt vers un wallet neuf repart chez l'expéditeur. Au passage, je vous montre comment vérifier tout cela en un seul appel d'outil depuis un agent IA, sans monter ni SDK ni nœud.

Trois formats d'adresse TON : raw, EQ et UQ — quelle différence

Sous le capot, toute adresse TON repose sur la même chose : le numéro de workchain plus le hash 256 bits du state-init du contrat. C'est le format raw :

0:83dfd552e63729b472fcbcc8c45ebcc6691702558b68ec7527e1ba403a0f31a8

À gauche des deux-points, le workchain (en général 0 — la chaîne de base, -1 — la masterchain) ; à droite, le hash de 256 bits en hexadécimal. Le format est honnête et sans ambiguïté, mais il n'a pas de somme de contrôle : une faute de frappe sur un seul caractère et vous obtenez une autre adresse valide en apparence. C'est le raw qu'attendent en général les get-méthodes des contrats et les outils bas niveau, et on ne le montre presque jamais aux humains.

La deuxième représentation est le format user-friendly : ces fameux 48 caractères en base64url que vous voyez dans les wallets et les explorateurs :

EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N     (bounceable)
UQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqEBI     (non-bounceable)

Il encode la même paire « workchain + hash », plus un octet de flags et une somme de contrôle CRC16 à la fin. Le CRC attrape les fautes de frappe : une adresse corrompue échoue à la validation avant même l'envoi. Et c'est précisément de cet octet de flags que naissent les préfixes EQ et UQ.

L'essentiel à retenir d'emblée :

  • raw et user-friendly sont deux façons d'écrire la même adresse.
  • EQ et UQ sont deux variantes de la même adresse user-friendly, qui ne diffèrent que d'un seul flag.

Autrement dit, EQ… et UQ… pour un même wallet pointent vers le même hash raw, le même contrat, le même solde. Ce ne sont ni deux wallets différents ni deux comptes distincts. La seule différence tient à un bit : celui qui exprime l'intention de l'expéditeur.

Bounceable (EQ) contre non-bounceable (UQ) : ce que signifie le flag

C'est ce fameux octet de flags à l'intérieur de l'adresse user-friendly qui détermine le préfixe :

Flag Tag Préfixe (mainnet) Préfixe (testnet)
bounceable 0x11 EQ kQ
non-bounceable 0x51 UQ 0Q

Pour le testnet, on ajoute 0x80 au tag — d'où les exotiques kQ et 0Q. Mais ce qui nous intéresse ici, c'est le sens du flag, pas l'arithmétique des tags.

Bounceable (EQ) signifie littéralement : « si quelque chose tourne mal côté destinataire, renvoie-moi les fonds ». C'est une protection pour les smart contracts. Si vous envoyez de l'argent à un contrat censé le traiter et qu'il plante avec une erreur, n'est pas encore déployé ou manque de gas, vous ne voulez pas que les fonds restent suspendus dans le vide. Le mécanisme de bounce les renvoie à l'expéditeur, frais déduits.

Non-bounceable (UQ) signifie l'inverse : « livre et laisse, quoi qu'il arrive ». Aucun retour — les fonds sont simplement crédités sur l'adresse.

Pour les virements quotidiens entre particuliers, la différence est invisible — jusqu'à un cas bien précis.

Pourquoi le premier dépôt vers un wallet non déployé « rebondit »

Voici le piège. Dans TON, l'adresse d'un wallet existe avant que le contrat du wallet soit réellement déployé sur la blockchain. L'adresse est un hash déterministe du code du contrat et de ses données initiales (la clé publique) : vous la connaissez dès la génération de la mnémonique, entièrement hors ligne. Mais tant qu'aucune transaction n'est passée par cette adresse, le compte reste à l'état uninit (non initialisé) : l'adresse existe, le code du contrat, lui, n'y est pas.

Regardez maintenant ce qui se passe avec un transfert bounceable :

  1. Vous envoyez vers cette adresse uninit un transfert au format EQ (bounceable).
  2. Le réseau tente de livrer les fonds et d'« appeler » le contrat destinataire. Personne pour les recevoir — il n'y a pas de contrat à cette adresse.
  3. Le bounce se déclenche : la livraison a échoué, donc les fonds reviennent à l'expéditeur, frais déduits.

Résultat : le fameux « rebond ». La transaction a réussi, mais le solde du nouveau wallet reste à zéro, et l'argent est reparti d'où il venait. Personne n'a rien volé, le réseau a fonctionné exactement comme prévu — vous avez simplement utilisé le format bounceable là où il ne fallait pas.

Et si l'on envoie le même transfert au format UQ (non-bounceable) ?

  1. Le réseau tente de livrer les fonds sur l'adresse uninit.
  2. Le bounce est désactivé par le flag — rien à renvoyer.
  3. Les fonds restent sur l'adresse, même si le contrat n'est pas encore déployé.

Le wallet est approvisionné. Plus tard, quand vous en ferez la première transaction sortante, le code du contrat sera déployé avec elle — et le compte passera à l'état active. À partir de là, il accepte sans problème tous les transferts, y compris bounceable. La règle UQ n'est critique que pour le tout premier dépôt d'un wallet pas encore déployé.

Bonne nouvelle : l'écosystème colmate progressivement cette faille à la place de l'utilisateur. Les wallets v5r1 et plusieurs clients affichent par défaut l'adresse au format non-bounceable (UQ) — précisément pour qu'un débutant ne perde pas son premier dépôt. Mais dès que vous manipulez des adresses par code — depuis un backend, un script, un agent IA — la responsabilité du flag vous revient.

Comment envoyer correctement le premier transfert : UQ plutôt qu'EQ

La règle pratique tient en une ligne :

Premier dépôt vers un wallet neuf (uninit) — toujours en UQ. Ensuite, comme vous voulez.

La logique détaillée pour tout service qui envoie des fonds à un utilisateur :

  • Adresse du destinataire à l'état uninit → envoyez en UQ (non-bounceable).
  • Adresse active → vous pouvez envoyer en EQ (bounceable).
  • Vous envoyez vers un smart contract (DEX, minter de jetton, escrow) → EQ, pour que l'argent revienne en cas d'erreur.

Le problème, c'est qu'à l'œil nu, EQ et UQ ne diffèrent que d'un caractère de préfixe, et que l'état uninit/active est totalement invisible dans l'adresse. Les deux vérifications doivent donc se faire de façon programmatique. Et là, inutile d'embarquer @ton/ton dans le projet, de monter un provider et de parser des cellules : les deux questions se règlent avec deux outils du serveur MCP, que l'agent IA appelle lui-même.

Si la génération et le premier approvisionnement d'un wallet sont un sujet neuf pour vous, il y a une analyse dédiée dans le guide sur la création d'un wallet TON.

parse_address : convertir et vérifier des adresses hors ligne en un appel

parse_address est un outil hors ligne de TONNode, le serveur MCP hébergé pour TON. Il décode l'adresse, recalcule les formats et vérifie le CRC16 sans toucher au réseau : ni nœud ni clé nécessaires — c'est du pur calcul sur une chaîne de caractères, donc instantané et sans consommer votre quota.

Ce qu'il sait faire :

  • convertir EQ ⇄ UQ ⇄ raw dans tous les sens ;
  • vérifier la validité d'une adresse (la somme de contrôle tombe-t-elle juste ?) ;
  • afficher le flag bounceable et le numéro de workchain.

MCP (Model Context Protocol) est le standard par lequel les agents IA (Claude, Cursor, ChatGPT/Codex et tout client MCP) appellent des outils. Un serveur MCP se branche avec une seule entrée dans la config du client. La variante locale gratuite, avec l'ensemble complet des outils de lecture :

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

Ensuite, un prompt tout simple suffit à l'agent :

Prends l'adresse EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N et montre-la aux formats non-bounceable (UQ) et raw. Vérifie que la somme de contrôle est valide.

L'agent appellera parse_address et renverra la version UQ du même wallet, le hash raw et le statut de validité. Aucun jonglage manuel avec du base64url, aucun risque de se tromper sur l'un des 48 caractères.

get_account_state : savoir si le wallet est déployé avant d'envoyer

Le format ne fait pas tout — encore faut-il connaître l'état de l'adresse : active ou uninit. C'est cette fois une question on-chain, et c'est get_account_state qui y répond. L'outil renvoie le statut du compte, les flags et les données de la dernière transaction.

La logique avant d'envoyer un premier transfert :

  • get_account_state renvoie uninit → l'adresse n'est pas encore déployée → on envoie en UQ.
  • il renvoie active → le wallet est déployé → on peut envoyer sereinement en EQ.

Le prompt pour l'agent :

Vérifie via get_account_state si l'adresse UQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqEBI est déployée. Si l'état est uninit, rappelle que le premier dépôt doit partir au format UQ.

L'enchaînement complet ressemble à ceci : generate_wallet crée le wallet (versions v3r2/v4/v5r1/highload_v3) et renvoie une adresse qui, au moment de la création, est garantie uninit — le réseau ne la connaît pas encore. Le premier dépôt part donc strictement en UQ. Avant l'envoi, get_account_state confirme que l'adresse est bien uninit, et parse_address garantit que vous avez pris la représentation non-bounceable. Après l'approvisionnement, un appel à get_balance permet de vérifier que les fonds sont bien arrivés sur l'adresse au lieu de rebondir.

Point important sur la génération : generate_wallet renvoie la mnémonique, les clés et l'adresse à l'utilisateur — le serveur ne les stocke pas et ne signe rien à votre place. C'est une mécanique non custodiale, et elle s'applique à tous les outils de swap, de cross-chain et de wallet.

Petite précision terminologique : GRAM est le nouveau nom du Toncoin (renommé en juin 2026) ; le réseau, lui, s'appelle toujours TON.

Check-list : ne pas perdre son premier dépôt sur TON

L'algorithme court pour chaque premier transfert vers un nouveau wallet :

  1. Vous avez généré une adresse (generate_wallet ou votre SDK) — considérez-la uninit par défaut.
  2. Vérifiez l'état via get_account_state : uninit ou active.
  3. Si uninit — convertissez l'adresse du destinataire en UQ via parse_address et n'envoyez le premier dépôt que sur cette version de l'adresse.
  4. Si active — le format EQ convient ; pour les contrats, c'est même préférable.
  5. Vers les smart contracts, envoyez toujours en bounceable (EQ) pour récupérer les fonds en cas d'échec.
  6. Après l'approvisionnement, vérifiez get_balance : les fonds doivent être arrivés sur l'adresse, pas avoir rebondi.
  7. Rappelez-vous : EQ et UQ, c'est le même wallet (le même hash raw) ; vous ne choisissez pas une adresse, mais un comportement en cas de livraison ratée.

Les deux vérifications clés — parse_address (hors ligne) et get_account_state (on-chain) — sont disponibles immédiatement, sans avoir à monter votre propre infrastructure. Prenez une clé Hobby gratuite (60 requêtes/min, sans carte bancaire) et appelez les deux outils directement depuis votre agent IA : https://tonnode.io/dashboard?plan=hobby.

Ensuite, le même schéma s'applique aux tâches voisines : détecter les paiements USDT entrants sur TON, lire un solde USDT en un appel ou appeler une get-méthode de contrat sans SDK. Les formats d'adresses sont le socle sur lequel tout le reste repose : comprenez EQ/UQ une bonne fois pour toutes — et le dépôt « rebondi » ne vous prendra plus jamais au dépourvu.

Donnez à votre agent l'accès à TON

16 outils MCP : lecture, swaps non-custodial, cross-chain et wallets. Forfait gratuit — 60 req/min, sans carte.