Skip to main content
Jettons are fungible tokens on TON, similar to ERC-20 tokens on Ethereum. Unlike Toncoin, which is the native TON currency used in all transfers, each Jetton has a separate master (minter) contract and an individual wallet contract for each holder. For example, USDT on TON is implemented as a Jetton, and its minter contract address is EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs. By providing this address and the recipient’s TON wallet contract address, WalletKit knows which tokens to send and to whom. To work with Jettons, the wallet service needs to handle Jetton balances and perform transfers initiated from dApps and from within the wallet service itself.

Balances

Jetton balances are stored in individual Jetton wallet contracts, one per holder per Jetton kind. It is possible to obtain the current Jetton balance by providing the address of the Jetton master (minter) contract for a given Jetton, or by querying a TON wallet. The latter can be done either by the getJettons() method of wallet adapters or by calling kit.jettons.getAddressJettons() and passing it the TON wallet address. Similar to Toncoin balance checks, discrete one-off checks have limited value on their own and continuous monitoring should be used for UI display.

On-demand balance check

Use the getJettonBalance() method to check a specific Jetton balance for a wallet managed by WalletKit. The balance is returned in the smallest Jetton unit, where 1 token equals 10decimals smallest units.
TypeScript
The most practical use of one-off balance checks is right before approving a transaction request. At this point, the actual balance usually is not less than the checked amount, though it might be higher if new funds arrived right after the check.
TypeScript

Continuous balance monitoring

Poll the balance at regular intervals to keep the displayed value up to date. Use an appropriate interval based on UX requirements — shorter intervals provide fresher data but increase API usage. This example should be modified according to the wallet service’s logic:
TypeScript

Transfers from dApps

When a connected dApp requests a Jetton transfer, the wallet service follows the same flow as Toncoin transfers: the dApp sends a transaction request through the bridge, WalletKit emulates it and presents a preview, the user approves or declines, and the result is returned to the dApp.
TypeScript
There is an additional consideration for Jetton transfers: they involve multiple internal messages between contracts. As such, Jetton transfers always take longer than regular Toncoin-only transfers. As with Toncoin transfers, the wallet service should not block the UI while waiting for confirmation. With continuous wallet balance monitoring and subsequent transaction requests, users will receive the latest information either way. Confirmations are only needed to display a list of past transactions reliably.

Transfers in the wallet service

Jetton transactions can be created directly from the wallet service (not from dApps) and fed into the regular approval flow via the handleNewTransaction() method of the WalletKit. It creates a new transaction request event, enabling the same UI confirmation-to-transaction flow for both dApp-initiated and wallet-initiated transactions. This example should be modified according to the wallet service’s logic:
TypeScript

See also

Jettons: General: