> ## Documentation Index
> Fetch the complete documentation index at: https://developers.fireblocks.com/llms.txt
> Use this file to discover all available pages before exploring further.

# TON Transfer Fees

> Understand who pays which fees in a TON or Jetton transfer, and read the per-wallet fee breakdown in feeInfo and blockchainInfo (Early Access).

> [!NOTE]
>
> **Early Access.** The per-wallet fee breakdown described on this page (`feeInfo.sender`, `feeInfo.recipient` and `blockchainInfo.feeBreakdowns`) is in Early Access and is enabled per workspace. To join, contact your Customer Success Manager. Fields may be added during Early Access. The existing `networkFee` field does not change.

## Overview

On The Open Network (TON), a single transfer is carried out by several on-chain transactions, and each of them charges a fee to the account that runs it. A transfer of a Jetton (a fungible token on TON, such as USDT) involves more accounts than a native TON transfer, and the sender also attaches TON to pay for the steps that happen in other accounts.

Fireblocks reports a single `networkFee` per transaction. For TON, that number does not always match what your own wallet paid. The Early Access fee breakdown adds, for each of your wallets that took part in the transfer, the TON that was deducted from it and what that amount is made of.

This page explains how fees work on TON, what each new field means, and how to reconcile your TON balances with them.

## Why several accounts pay fees on TON

Every account on TON is a smart contract, and accounts communicate only by sending messages to each other. Each message is processed in a separate transaction of the receiving account, and each transaction charges fees to that account.

### Native TON transfer

A native TON transfer involves two transactions:

1. **The sender's wallet** receives your signed request from outside the blockchain (an external message), runs its code and sends an internal message carrying the TON to the recipient. The sender pays for this transaction and for forwarding the message.
2. **The recipient's wallet** receives the message. Its own fees for processing it are taken from its balance, so it is credited slightly less than the amount sent.

### Jetton transfer

Jettons are not held in your wallet itself. Each owner of a Jetton has a separate **Jetton wallet** (a token wallet) contract that holds the balance. A Jetton transfer follows the flow defined in the Jetton standard:

1. **The sender's wallet** sends a `transfer` message to its own Jetton wallet. Fireblocks attaches TON to this message to pay for the next steps. By default this is the transaction's fee value (0.1 TON unless you set another fee).
2. **The sender's Jetton wallet** sends an `internal_transfer` message with the tokens to the recipient's Jetton wallet. Its fees are paid from the attached TON.
3. **The recipient's Jetton wallet** credits the tokens and pays its fees from the attached TON. If this transfer creates the recipient's Jetton wallet, part of the attached TON stays in that new wallet as its minimum balance for storage.
4. **The recipient's wallet** receives a `transfer_notification` message carrying a small amount of TON (the forward amount) when the sender sets one. Processing this notification charges the recipient's wallet a fee. When the forward amount is too small to pay for running the wallet's code, which is common, the wallet pays only its storage fee, often a few nanoTON (1 TON is 1,000,000,000 nanoTON).
5. **The unused TON** (the excess) goes back in an `excesses` message to the response destination, which is normally the sender's wallet. Receiving it costs that wallet a small fee. You can send the excess to another wallet with `extraParameters.feeExcessDestination`.

### Fee types

Each transaction's fee is made of the following TON fee types:

| Fee type | Charged for |
| - | - |
| Storage fee | Keeping the account on the blockchain. It accumulates over time and is collected the next time the account runs a transaction, so a wallet that has been idle for a long time pays a larger storage fee on its next transfer. |
| Import fee | Accepting a message from outside the blockchain. Only the transaction that receives your signed request pays it. |
| Gas fee | Running the account's code. |
| Action fee | Processing the messages the transaction sends. |
| Forward fee | Delivering each message the transaction sends to its destination. It is paid by the account that sends the message. |

For the official definitions, see [Transaction fees](https://docs.ton.org/foundations/fees) and [Execution phases](https://docs.ton.org/foundations/phases) in the TON documentation.

## What networkFee contains on TON

`networkFee` keeps its current meaning. On TON it is calculated from the transaction that started the transfer and the last message of the transfer, so it describes the transfer, not necessarily your wallet:

| Transfer | What `networkFee` contains |
| - | - |
| Native TON, outgoing | The fees of your sending wallet. It equals the sender's `feesDeducted`. |
| Jetton, outgoing | The fees of your sending wallet plus the TON attached to the transfer and the forward amount delivered to the recipient, minus the excess when it returns to the sending wallet. It does not include the fee your wallet paid to receive the excess. When the excess goes to another wallet, the full attached TON is included. |
| Incoming, native or Jetton | The fees of the account that started the transfer, which is usually not your wallet. For example, when a deposit comes from a distribution contract, `networkFee` reflects that contract's costs, not yours. |
| Between two of your vault accounts | The fees of the sending vault account only. |

To know what your own wallets paid, use `feeInfo.sender` and `feeInfo.recipient`, and the entries in `blockchainInfo.feeBreakdowns`.

## Where the breakdown is reported

The breakdown is reported in two places:

* **`feeInfo.sender` and `feeInfo.recipient`**: a short summary in TON, with nine decimals like `networkFee`, for each wallet of your workspace in the transfer: `feesDeducted` and, for a Jetton recipient, `valueCredited`. When both the sender and the recipient are wallets of your workspace, Fireblocks records a single transaction that has both. These objects are only in the top-level `feeInfo`, not inside `blockchainInfo`. See [feeInfo](https://developers.fireblocks.com/reference/webhooks-structures-eventtypes-transaction.md#feeinfo) for the fields.
* **`blockchainInfo.feeBreakdowns`**: the full detail, one entry for each of your wallets that took part in the transfer, with amounts as integer strings in nanoTON. See [TonFeeBreakdown](https://developers.fireblocks.com/reference/transaction-objects.md#tonfeebreakdown) for the fields.

Only wallets that belong to your workspace are reported. The fees of external wallets, other Fireblocks workspaces and Jetton wallets are not listed. The fees of Jetton wallets are paid from the TON your sending wallet attached, so they are part of the sender's `fundingSpent`.

### How the amounts add up

The amounts relate to each other as follows:

* `totalFees` = `storageFees` + `importFee` + `gasFees` + `actionFees` + `bounceFees`.
* For each entry, the TON deducted from that wallet is `totalFees` + `totalOutMsgsForwardFees` + `fundingSpent` (`fundingSpent` is 0 when absent). Converted from nanoTON to TON, this equals the `feesDeducted` of the matching role in `feeInfo` (`feeInfo.sender` for the `SENDER` entry, `feeInfo.recipient` for the `RECIPIENT` entry).
* `forwardFees` is the total forwarding charge as the blockchain reports it, and it already includes `actionFees`. Do not add `forwardFees` to `totalFees`; use `totalOutMsgsForwardFees` instead.
* `importFee` is not recorded by the blockchain. Fireblocks derives it as the part of `totalFees` that the other components do not explain, so it appears only on the transaction that received your signed request.

### What feesDeducted means for each wallet

| Wallet | `feesDeducted` |
| - | - |
| Sender, native transfer | The wallet's fees plus the forward fees of the messages it sent. |
| Sender, Jetton transfer, excess returned to the sender | The TON the wallet lost for the transfer: its fees, plus the attached TON, minus the excess returned, plus the fee to receive the excess. When one external message carries several Jetton transfers (a multi-send), the loss is that of the whole message: every excess that came back to the wallet is subtracted. |
| Sender, Jetton transfer, excess sent to another wallet | The wallet's fees plus the full attached TON. The excess arrives in the other wallet as a separate transaction (see [Excess sent to another wallet](#excess-sent-to-another-wallet)). |
| Recipient | The fees of the wallet's transaction that received the transfer. For a native transfer this is mostly the gas fee to process the incoming message. For a Jetton transfer with a forward amount too small to pay for running the wallet's code, it is only the wallet's storage fee. |

For a Jetton sender, `fundingSpent` is everything in `feesDeducted` that was not the sending wallet's own transaction fee. It covers the fees of both Jetton wallets, the TON kept by the recipient's Jetton wallet when the transfer creates it, the forward amount delivered to the recipient and, when the excess returns to the sender, the fee to receive it. These parts are not reported separately.

> [!WARNING]
>
> A `feesDeducted` of a Jetton sender is not only a fee. It can include TON that stays in another account, such as the minimum balance of a newly created Jetton wallet and the forward amount delivered to the recipient.

### When an entry is missing

Fireblocks reports an amount only when it can be proven from the completed on-chain transactions. If it cannot, that wallet's entry and its object in `feeInfo` are left out rather than reported with an estimated value. The other wallet's figures are still reported.

A wallet that paid nothing is reported as zero, never left out. For example, an incoming Jetton transfer with no forward amount sends no notification to your wallet. Your wallet then gets a `RECIPIENT` entry with no `txHash` and every figure `"0"`, and `feeInfo.recipient.feesDeducted` is `"0.000000000"`.

The breakdown is not reported for:

* Transfers processed before the feature was enabled for your workspace.
* Jetton transfers that bounced.

When a transfer carries a very long message, `feeBreakdowns`, `messageContent` or both may be left out. `tonTransferType`, the `hashes`, `isFeeExcess` and the top-level `feeInfo` are always included.

## Worked examples

All amounts below come from completed mainnet transfers. Addresses and hashes are placeholders.

### Native TON transfer between two of your vault accounts

You send 0.468899688 TON from one vault account to another. Both wallets belong to your workspace, so Fireblocks records one transaction that carries both entries, and `feeInfo` has both `sender` and `recipient`.

```json theme={"system"}
"feeInfo": {
  "networkFee": "0.0004755",
  "sender": { "feesDeducted": "0.000475500" },
  "recipient": { "feesDeducted": "0.000066069" }
},
"blockchainInfo": {
  "tonTransferType": "NATIVE",
  "feeBreakdowns": [
    {
      "role": "SENDER",
      "address": { "raw": "0:<sender-raw-address>", "userFriendly": "<sender-address>" },
      "txHash": "<sender-transaction-hash>",
      "feeBreakdown": {
        "totalOutMsgsForwardFees": "57424",
        "chainReported": {
          "totalFees": "418076",
          "storageFees": "31",
          "gasFees": "220534",
          "actionFees": "28710",
          "forwardFees": "86134",
          "importFee": "168801"
        }
      }
    },
    {
      "role": "RECIPIENT",
      "address": { "raw": "0:<recipient-raw-address>", "userFriendly": "<recipient-address>" },
      "txHash": "<recipient-transaction-hash>",
      "feeBreakdown": {
        "totalOutMsgsForwardFees": "0",
        "chainReported": {
          "totalFees": "66069",
          "storageFees": "1",
          "gasFees": "66068",
          "actionFees": "0",
          "forwardFees": "0"
        }
      }
    }
  ]
}
```

* Sender: `feesDeducted` = `totalFees` + `totalOutMsgsForwardFees` = 418,076 + 57,424 = 475,500 nanoTON. For an outgoing native transfer this equals `networkFee`.
* `forwardFees` (86,134) is `actionFees` (28,710) plus `totalOutMsgsForwardFees` (57,424). Adding it to `totalFees` would count `actionFees` twice.
* Recipient: the receiving wallet paid 66,069 nanoTON, so it was credited 0.468899688 - 0.000066069 = 0.468833619 TON.
* The workspace's total cost is 475,500 + 66,069 = 541,569 nanoTON (0.000541569 TON). `networkFee` covers the sending wallet only.

If the destination is an external address, the transaction carries only the `SENDER` entry and `feeInfo.sender`.

### Outgoing Jetton transfer with the excess returned

You send 2.24 USDT to an external address. Fireblocks attaches 0.14 TON, and 0.138533961 TON comes back to your wallet as the excess. The transfer creates the recipient's Jetton wallet.

```json theme={"system"}
"feeInfo": {
  "networkFee": "0.002638983",
  "sender": { "feesDeducted": "0.002677450" }
},
"blockchainInfo": {
  "tonTransferType": "JETTON",
  "feeBreakdowns": [
    {
      "role": "SENDER",
      "address": { "raw": "0:<sender-raw-address>", "userFriendly": "<sender-address>" },
      "txHash": "<sender-transaction-hash>",
      "feeBreakdown": {
        "totalOutMsgsForwardFees": "78757",
        "chainReported": {
          "totalFees": "1094186",
          "storageFees": "7",
          "gasFees": "433001",
          "actionFees": "39377",
          "forwardFees": "118134",
          "importFee": "621801"
        },
        "fundingSpent": "1504507"
      }
    }
  ]
}
```

Where the 0.002677450 TON went:

| Part | TON |
| - | -: |
| Sending wallet's own fees (`totalFees` + `totalOutMsgsForwardFees`) | 0.001172943 |
| Fees of the two Jetton wallets, paid from the attached TON | 0.000491605 |
| Kept by the recipient's new Jetton wallet as its minimum balance | 0.000974433 |
| Forward amount delivered to the recipient | 0.000000001 |
| Fee to receive the excess | 0.000038468 |
| **`feesDeducted`, the decrease of the wallet's TON balance caused by the transfer** | **0.002677450** |

* The last four rows add up to `fundingSpent` (0.001504507 TON): the attached 0.14 TON, minus the 0.138533961 TON excess, plus the 0.000038468 TON fee to receive it.
* `networkFee` is 0.002638983 TON because it does not include the fee to receive the excess and it adds the forward amount once more.
* The sender's Jetton wallet also paid 0.000000005 TON of storage from its own balance. Fees that a Jetton wallet pays from its own balance are not part of the breakdown.

### Incoming native TON transfer

An external wallet sends 1 TON to your vault account.

```json theme={"system"}
"amount": "1",
"feeInfo": {
  "networkFee": "0.000388277",
  "recipient": { "feesDeducted": "0.000051706" }
},
"blockchainInfo": {
  "tonTransferType": "NATIVE",
  "feeBreakdowns": [
    {
      "role": "RECIPIENT",
      "address": { "raw": "0:<your-raw-address>", "userFriendly": "<your-address>" },
      "txHash": "<your-transaction-hash>",
      "feeBreakdown": {
        "totalOutMsgsForwardFees": "0",
        "chainReported": {
          "totalFees": "51706",
          "storageFees": "38",
          "gasFees": "51668",
          "actionFees": "0",
          "forwardFees": "0"
        }
      }
    }
  ]
}
```

* Your wallet paid 0.000051706 TON, almost all of it gas, and its balance increased by 1 - 0.000051706 = 0.999948294 TON.
* `networkFee` (0.000388277 TON) is the sending wallet's cost, not yours.

The difference matters most for deposits sent by a contract. In a mainnet deposit of 0.00001 TON sent by a distribution contract, `networkFee` was 0.002074288 TON, the cost of the account that started the distribution. The receiving wallet's `feesDeducted` was 0.000009936 TON (`storageFees` 2 and `gasFees` 9,934 nanoTON), so it was credited 0.000000064 TON.

### Incoming Jetton transfer

Another Fireblocks workspace sends you 53,661 USDT with a forward amount of 1 nanoTON. Your wallet's only cost is processing the token notification. The forward amount is too small to pay for running the wallet's code, so the wallet pays only its storage fee.

```json theme={"system"}
"feeInfo": {
  "networkFee": "0.001035344",
  "recipient": { "feesDeducted": "0.000000056", "valueCredited": "0.000000001" }
},
"blockchainInfo": {
  "tonTransferType": "JETTON",
  "feeBreakdowns": [
    {
      "role": "RECIPIENT",
      "address": { "raw": "0:<your-raw-address>", "userFriendly": "<your-address>" },
      "txHash": "<your-transaction-hash>",
      "feeBreakdown": {
        "totalOutMsgsForwardFees": "0",
        "chainReported": {
          "totalFees": "56",
          "storageFees": "56",
          "gasFees": "0",
          "actionFees": "0",
          "forwardFees": "0"
        }
      }
    }
  ]
}
```

* The net change of your wallet's TON balance is `valueCredited` minus `feesDeducted`: 1 - 56 = -55 nanoTON.
* `networkFee` (0.001035344 TON) is the sending workspace's cost. That workspace sees its own figure in its own transaction: `feeInfo.sender.feesDeducted` is `0.001101411`.
* The fees of your Jetton wallet were paid from the TON the sender attached.

### Excess sent to another wallet

You send 1,000 USDT between two of your vault accounts with 0.158895 TON attached, and `extraParameters.feeExcessDestination` sends the excess to a third vault account. When reporting the excess as its own transaction is enabled for your workspace, Fireblocks records two transactions with the same transaction hash.

The Jetton transfer:

```json theme={"system"}
"feeInfo": {
  "networkFee": "0.159474513",
  "sender": { "feesDeducted": "0.159474512" },
  "recipient": { "feesDeducted": "0.000000001", "valueCredited": "0.000000001" }
}
```

The sender's `feesDeducted` counts the full attached TON (`fundingSpent` is `158895000` nanoTON) on top of the wallet's own fees (579,512 nanoTON). The transaction also carries the `RECIPIENT` entry, and `feeInfo.recipient` shows the recipient's 1 nanoTON fee and the 1 nanoTON forward amount it received.

The excess, recorded as an incoming native TON transfer of 0.158363394 TON to the third vault account:

```json theme={"system"}
"feeInfo": {
  "networkFee": "0",
  "recipient": { "feesDeducted": "0.000038470" }
},
"blockchainInfo": {
  "tonTransferType": "NATIVE",
  "isFeeExcess": true,
  "feeBreakdowns": [
    {
      "role": "RECIPIENT",
      "address": { "raw": "0:<excess-raw-address>", "userFriendly": "<excess-address>" },
      "txHash": "<excess-transaction-hash>",
      "feeBreakdown": {
        "totalOutMsgsForwardFees": "0",
        "chainReported": {
          "totalFees": "38470",
          "storageFees": "2",
          "gasFees": "38468",
          "actionFees": "0",
          "forwardFees": "0"
        }
      }
    }
  ]
}
```

To get the workspace's cost, combine the two transactions: the sender's `feesDeducted`, minus the amount of the excess transaction, plus the excess transaction's `feesDeducted`. Here that is 0.159474512 - 0.158363394 + 0.000038470 = 0.001149588 TON. The recipient's 1 nanoTON fee and 1 nanoTON forward amount cancel out.

## Learn more

* [Transaction fees](https://docs.ton.org/foundations/fees) in the TON documentation: storage, gas, action, forward and import fees.
* [Execution phases](https://docs.ton.org/foundations/phases) in the TON documentation: the order in which fees are charged, and when the compute phase is skipped.
* [Jetton: how it works](https://docs.ton.org/contracts/standard/tokens/jettons/how-it-works#token-transfer) in the TON documentation: the transfer, notification and excess messages.
* [TEP-74 Jetton standard](https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md), the TON Enhancement Proposal that defines Jettons.
* [feeInfo](https://developers.fireblocks.com/reference/webhooks-structures-eventtypes-transaction.md#feeinfo) and [BlockchainInfo](https://developers.fireblocks.com/reference/transaction-objects.md#blockchaininfo) in the API reference.
