# Mintless jetton (https://docs-orhepa2tm-ton-core-docs.vercel.app/llms/standard/tokens/jettons/mintless/overview/content.md)



## Introduction [#introduction]

<Callout>
  To understand this document, you should be familiar with the other basic Jetton standards.
</Callout>

TON has introduced [Mintless Jettons](https://github.com/ton-community/mintless-jetton?tab=readme-ov-file), an innovative extension of the Jetton standard.

Mintless extension adopts [Merkle proofs](/llms/foundations/proofs/overview/content.md), using them to make airdrops without requiring traditional minting processes.

In this article, we will explore how mintless jettons work and how to use them.

## Overview [#overview]

Mintless jettons are an extension ([TEP-177](https://github.com/ton-blockchain/TEPs/pull/177) and [TEP-176](https://github.com/ton-blockchain/TEPs/pull/176)) of the standard Jetton implementation ([TEP-74](https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md)) on TON Blockchain.

This implementation enables large-scale, decentralized airdrops to millions of users while minimizing costs and blockchain load.

Note that to use a mintless jetton to its full extent, you will need to establish an off-chain architecture.

### Basic features [#basic-features]

* **Scalability**: Traditional minting processes can be resource-intensive and costly when distributing tokens to a vast number of users.
* **Efficiency**: By utilizing Merkle trees, mintless jettons store a single hash representing all airdropped amounts, reducing storage requirements.
* **User-friendly airdrops**: No separate pre-claim: wallets attach a Merkle proof on first transfer, so users don't perform a manual claim action.

Because mintless jettons extend the standard jettons, you can interact with them the same way as standard jettons — no additional steps required.

## How it works [#how-it-works]

Mintless jettons leverage [Merkle trees](/llms/foundations/proofs/overview/content.md) and cryptographic proofs to enable efficient, decentralized airdrops without traditional minting. Here's a detailed breakdown of the technical implementation:

### Merkle Tree foundation [#merkle-tree-foundation]

The core innovation lies in representing all airdrop data as a single Merkle tree, where:

* **Leaf nodes** contain airdrop information for individual addresses
* **Internal nodes** store cryptographic hashes of their children
* **Root hash** represents the entire airdrop dataset with a single 256-bit value

This approach reduces storage from O(n) per recipient to O(1) for the entire airdrop.

### Data structures [#data-structures]

Airdrop HashMap represents how we store individual users' airdrop information.

```tlb
_ amount:Coins start_from:uint48 expired_at:uint48 = AirdropItem;

_ _(HashMap 267 AirdropItem) = Airdrop;
```

Each airdrop entry contains:

* `amount`: Number of tokens allocated to the recipient
* `start_from`: Unix timestamp when claiming becomes available
* `expired_at`: Unix timestamp when claiming expires

The complete airdrop is stored as a HashMap where the key is a 267-bit internal TON account address and the value is an AirdropItem structure.

For the Jetton Master contract, standard storage is extended with `merkle_hash`: 256-bit root hash of the Merkle tree containing all airdrop data.

The standard wallet storage is extended with:

* `merkle_hash`: Copy of the master's Merkle hash for validation
* `already_claimed`: Boolean flag indicating whether the airdrop has been claimed

### Claiming mechanism [#claiming-mechanism]

```tlb
merkle_airdrop_claim#0df602d6 proof:^Cell = CustomPayload;
```

The claiming process uses the `custom_payload` field in standard jetton transfers with:

* `0x0df602d6`: Operation identifier for Merkle airdrop claims
* `proof`: MerkleProof exotic cell containing the cryptographic proof

```tlb
transfer#0f8a7ea5 query_id:uint64 amount:(VarUInteger 16) destination:MsgAddress
                 response_destination:MsgAddress custom_payload:(Maybe ^Cell)
                 forward_ton_amount:(VarUInteger 16) forward_payload:(Either Cell ^Cell)
                 = InternalMsgBody;
```

The standard transfer message is enhanced by including the claim proof in `custom_payload`.

### Cryptographic proof validation [#cryptographic-proof-validation]

When a jetton wallet receives a transfer with a claim payload, it performs these validation steps:

1. Merkle proof verification
   * Extracts the MerkleProof exotic cell from `custom_payload`
   * Verifies the proof's cryptographic integrity against the stored `merkle_hash`
   * Ensures the proof path leads to a valid `AirdropItem` for the sender's address
2. Timestamp validation
   * Checks that `now() >= start_from` (claiming period has begun)
   * Verifies that `now() <= expired_at` (claiming period hasn't expired)
3. Claim status check
   * Ensures `already_claimed == false` (prevents double-claiming)
4. Amount Validation
   * Extracts the airdrop amount from the validated AirdropItem
   * Credits this amount to the wallet's balance

### State transitions [#state-transitions]

Before claim:

```
JettonWallet {
  balance: 0,
  already_claimed: false,
  merkle_hash: <root_hash>
}
```

After successful claim:

```
JettonWallet {
  balance: <airdrop_amount>,
  already_claimed: true,
  merkle_hash: <root_hash>
}
```

### Off-chain infrastructure [#off-chain-infrastructure]

#### Merkle Tree generation [#merkle-tree-generation]

1. **Data collection**: Gather all recipient addresses and their allocated amounts
2. **Tree construction**: Build a binary Merkle tree with AirdropItem structures as leaves
3. **Hash computation**: Calculate SHA-256 hashes recursively up to the root
4. **Proof generation**: Create individual Merkle proofs for each recipient

#### Proof serving [#proof-serving]

* **Static storage**: Host the complete Merkle tree data at `mintless_merkle_dump_uri`
* **Dynamic API**: Implement `custom_payload_api_uri` to serve individual proofs on demand
* **Caching**: Optimize proof retrieval with appropriate caching strategies

## Supporting mintless jettons in wallet applications [#supporting-mintless-jettons-in-wallet-applications]

Wallet applications play a key role in improving the user experience with mintless jettons:

* **Display unclaimed jettons**: Wallets should show users the jettons they are eligible to claim based on the Merkle tree data.
* **Automated claim process**: When users initiate an outgoing transfer, wallets should automatically include the necessary Merkle proof in the transfer message's custom payload.

Wallets can achieve this by:

Integrating with the off-chain API specified in the [custom payload API](https://github.com/ton-blockchain/TEPs/blob/master/text/0064-token-data-standard.md#jetton-metadata-example-offchain):

* Check if the jetton is mintless.
* Verify whether the wallet owner has claimed it.
* If unclaimed, retrieve data from the custom payload API and add the off-chain balance to the on-chain one.
* If the user hasn’t claimed the airdrop, retrieve the custom payload and initialization data from the Custom Payload API and include it in the `transfer` message to the Jetton wallet.

Using a custom API:

* Download the airdrop tree from `mintless_merkle_dump_uri` in the jetton metadata.
* Parse the data as explained in [Merkle tree generation](#merkle-tree-generation).
* Make the parsed result available via API.

<Callout>
  Wallets are not required to support mintless claims, including indexing airdrop trees. Wallet applications may charge the jetton issuer for this service.
</Callout>

## Supporting mintless jettons in dApps [#supporting-mintless-jettons-in-dapps]

Because wallet applications handle claims automatically, dApps like DEXes or lending platforms don’t need special logic for mintless jettons. DApps can use APIs, such as TonAPI or [TON Center](/llms/ecosystem/api/toncenter/introduction/content.md), to display unclaimed balances.

To improve the user experience, DApps can check if the user's wallet application supports a specific mintless jetton. If unsupported, retrieve the airdrop proof and initialization data from the Jetton API and include it in the transfer message.

## See also [#see-also]

* [Understanding mintless jettons: a comprehensive guide](https://gist.github.com/EmelyanenkoK/bfe633bdf8e22ca92a5138e59134988f) - the original post.
* [Mintless jetton standard implementation](https://github.com/ton-community/mintless-jetton)
* [Jetton offchain payloads TEP](https://github.com/ton-blockchain/TEPs/blob/master/text/0064-token-data-standard.md#jetton-metadata-example-offchain)
* [Jetton metadata standard](https://github.com/ton-blockchain/TEPs/blob/master/text/0064-token-data-standard.md)
