---
title: Token Program
description: Understand the standard Thru fungible-token program from the
  perspective of accounts, events, instructions, and client integration.
source_url:
  html: https://thru.org/docs/core-programs/token-program/
  md: https://thru.org/docs/core-programs/token-program.md
---

# Token Program

The Token Program is the standard fungible-asset program on Thru.

From a developer perspective, it owns mint accounts and token accounts, emits lifecycle and balance-change events, and expects clients to derive deterministic account addresses before building instruction payloads.

## Use This When

- you need a fungible-token mint and token account model on Thru
- you need to transfer, mint, burn, freeze, or thaw token balances
- you need to parse mint or token account state from chain data

## Quickstart

Fetch the ABI, generate TypeScript builders, then build instruction bytes and send the transaction.

```bash
thru abi account get --include-data --out ./token-program.abi.yaml <ABI_ACCOUNT_ADDRESS>

thru abi codegen \
  --files ./token-program.abi.yaml \
  --language typescript \
  --output ./generated
```

```ts
import { decodeAddress } from "@thru/sdk/helpers";
import {
  TokenInstruction,
  TransferInstruction,
} from "./generated/thru/program/token/types";

const instructionData = TokenInstruction.builder()
  .payload()
  .select("transfer")
  .writePayload(
    TransferInstruction.builder()
      .set_source_account_index(2)
      .set_dest_account_index(3)
      .set_amount(1_000_000)
  )
  .finish()
  .build();

const tx = await thru.transactions.build({
  feePayer: { publicKey: decodeAddress(feePayerAddress) },
  program: "taAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKqq",
  accounts: {
    readWrite: [sourceTokenAccount, destinationTokenAccount],
    readOnly: [],
  },
  instructionData,
});

const signedWire = await signTransaction(tx.toWireForSigning());
const signature = await thru.transactions.send(signedWire);
```

## How It Works

The program has two main account types:

- mint accounts define token-wide metadata and authorities
- token accounts hold balances for a specific owner and mint

In typical client flows:

1. derive the mint or token account address
2. create the account with a state proof for the new address
3. submit lifecycle or balance-changing instructions against those accounts
4. read account state or emitted events to verify the new balances and authorities

The Web SDK package mirrors this structure closely: it gives you address derivation helpers, instruction builders, and account parsers for the same program surface.

## Account Model

| Account | What it stores | Notes |
| - | - | - |
| `TokenMintAccount` | `decimals`, `supply`, `creator`, `mint_authority`, `freeze_authority`, `has_freeze_authority`, `ticker` | The mint defines token-wide configuration and supply. |
| `TokenAccount` | `mint`, `owner`, `amount`, `is_frozen` | Each token account is tied to one mint and one owner. |
| `TokenProgramAccount` | Size-discriminated envelope over mint and token accounts | The ABI distinguishes `mint_account` and `token_account` by expected size. |

### Address Derivation

Common client flows derive addresses deterministically:

- mint address: from `mintAuthority + seed`, then PDA-derived under the Token Program
- token account address: from `owner + mint + seed`, then PDA-derived under the Token Program

## Required Accounts

Token instructions refer to transaction accounts by index:

- lifecycle instructions include the mint, token account, authority, and sometimes owner account indices
- creation flows also include a state proof for the new address
- the same mint or authority may appear across multiple instructions in one transaction, so the final account list must stay stable

If you are using the Web package, the generated builders and helpers keep the instruction payload aligned with the ABI field names and account-index model.

## Events

| Event | What it means |
| - | - |
| `initialize_mint` | A new mint was created and configured. |
| `initialize_account` | A new token account was created for a mint and owner. |
| `transfer` | Tokens moved between two token accounts. |
| `mint_to` | New supply was minted into a destination token account. |
| `burn` | Supply was burned from a token account. |
| `close_account` | A token account was closed and cleaned up. |
| `freeze_account` | A token account was frozen by the freeze authority. |
| `thaw_account` | A previously frozen token account was thawed. |

## Instructions

| Instruction | Use it when | Notes |
| - | - | - |
| `initialize_mint` | Create a new fungible token mint | Includes ticker, decimals, authorities, seed, and state proof. |
| `initialize_account` | Create a token account for an owner and mint | Includes the new account seed and state proof. |
| `transfer` | Move tokens between token accounts | The common balance-changing path for user transfers. |
| `mint_to` | Increase supply and credit a token account | Requires the mint authority. |
| `burn` | Decrease supply and remove tokens from an account | Requires the account authority. |
| `close_account` | Close a token account and reclaim its balance | Often used for cleanup once a balance is empty. |
| `freeze_account` | Freeze a token account | Requires the freeze authority on the mint. |
| `thaw_account` | Unfreeze a token account | Also requires the freeze authority. |

## Related References

- [`@thru/programs`](https://thru.org/docs/sdks/web-packages/programs.md)
- [Build an Indexer](https://thru.org/docs/indexing/build-an-indexer.md)
- [Explorer MCP Overview](https://thru.org/docs/api-ref/explorer-mcp/overview.md)

## On-Chain Link

- Program explorer: [scan.thru.org/address/taAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKqq](https://scan.thru.org/address/taAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKqq)
