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

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.ton.org/feedback

```json
{
  "path": "/ecosystem/appkit/toncoin",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# How to work with Toncoin using AppKit

export const Aside = ({type = "note", title = "", icon = "", iconType = "regular", children}) => {
  const asideVariants = ["note", "tip", "caution", "danger"];
  const asideComponents = {
    note: {
      outerStyle: "border-sky-500/20 bg-sky-50/50 dark:border-sky-500/30 dark:bg-sky-500/10",
      innerStyle: "text-sky-900 dark:text-sky-200",
      calloutType: "note",
      icon: <svg width="14" height="14" viewBox="0 0 14 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="w-4 h-4 text-sky-500" aria-label="Note">
          <path fill-rule="evenodd" clip-rule="evenodd" d="M7 1.3C10.14 1.3 12.7 3.86 12.7 7C12.7 10.14 10.14 12.7 7 12.7C5.48908 12.6974 4.0408 12.096 2.97241 11.0276C1.90403 9.9592 1.30264 8.51092 1.3 7C1.3 3.86 3.86 1.3 7 1.3ZM7 0C3.14 0 0 3.14 0 7C0 10.86 3.14 14 7 14C10.86 14 14 10.86 14 7C14 3.14 10.86 0 7 0ZM8 3H6V8H8V3ZM8 9H6V11H8V9Z"></path>
        </svg>
    },
    tip: {
      outerStyle: "border-emerald-500/20 bg-emerald-50/50 dark:border-emerald-500/30 dark:bg-emerald-500/10",
      innerStyle: "text-emerald-900 dark:text-emerald-200",
      calloutType: "tip",
      icon: <svg width="11" height="14" viewBox="0 0 11 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="text-emerald-600 dark:text-emerald-400/80 w-3.5 h-auto" aria-label="Tip">
          <path d="M3.12794 12.4232C3.12794 12.5954 3.1776 12.7634 3.27244 12.907L3.74114 13.6095C3.88471 13.8248 4.21067 14 4.46964 14H6.15606C6.41415 14 6.74017 13.825 6.88373 13.6095L7.3508 12.9073C7.43114 12.7859 7.49705 12.569 7.49705 12.4232L7.50055 11.3513H3.12521L3.12794 12.4232ZM5.31288 0C2.52414 0.00875889 0.5 2.26889 0.5 4.78826C0.5 6.00188 0.949566 7.10829 1.69119 7.95492C2.14321 8.47011 2.84901 9.54727 3.11919 10.4557C3.12005 10.4625 3.12175 10.4698 3.12261 10.4771H7.50342C7.50427 10.4698 7.50598 10.463 7.50684 10.4557C7.77688 9.54727 8.48281 8.47011 8.93484 7.95492C9.67728 7.13181 10.1258 6.02703 10.1258 4.78826C10.1258 2.15486 7.9709 0.000106649 5.31288 0ZM7.94902 7.11267C7.52078 7.60079 6.99082 8.37878 6.6077 9.18794H4.02051C3.63739 8.37878 3.10743 7.60079 2.67947 7.11294C2.11997 6.47551 1.8126 5.63599 1.8126 4.78826C1.8126 3.09829 3.12794 1.31944 5.28827 1.3126C7.2435 1.3126 8.81315 2.88226 8.81315 4.78826C8.81315 5.63599 8.50688 6.47551 7.94902 7.11267ZM4.87534 2.18767C3.66939 2.18767 2.68767 3.16939 2.68767 4.37534C2.68767 4.61719 2.88336 4.81288 3.12521 4.81288C3.36705 4.81288 3.56274 4.61599 3.56274 4.37534C3.56274 3.6515 4.1515 3.06274 4.87534 3.06274C5.11719 3.06274 5.31288 2.86727 5.31288 2.62548C5.31288 2.38369 5.11599 2.18767 4.87534 2.18767Z"></path>
        </svg>
    },
    caution: {
      outerStyle: "border-amber-500/20 bg-amber-50/50 dark:border-amber-500/30 dark:bg-amber-500/10",
      innerStyle: "text-amber-900 dark:text-amber-200",
      calloutType: "warning",
      icon: <svg className="flex-none w-5 h-5 text-amber-400 dark:text-amber-300/80" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" aria-label="Warning">
          <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
        </svg>
    },
    danger: {
      outerStyle: "border-red-500/20 bg-red-50/50 dark:border-red-500/30 dark:bg-red-500/10",
      innerStyle: "text-red-900 dark:text-red-200",
      calloutType: "danger",
      icon: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor" className="text-red-600 dark:text-red-400/80 w-4 h-4" aria-label="Danger">
          <path d="M17.1 292c-12.9-22.3-12.9-49.7 0-72L105.4 67.1c12.9-22.3 36.6-36 62.4-36l176.6 0c25.7 0 49.5 13.7 62.4 36L494.9 220c12.9 22.3 12.9 49.7 0 72L406.6 444.9c-12.9 22.3-36.6 36-62.4 36l-176.6 0c-25.7 0-49.5-13.7-62.4-36L17.1 292zm41.6-48c-4.3 7.4-4.3 16.6 0 24l88.3 152.9c4.3 7.4 12.2 12 20.8 12l176.6 0c8.6 0 16.5-4.6 20.8-12L453.4 268c4.3-7.4 4.3-16.6 0-24L365.1 91.1c-4.3-7.4-12.2-12-20.8-12l-176.6 0c-8.6 0-16.5 4.6-20.8 12L58.6 244zM256 128c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"></path>
        </svg>
    }
  };
  let variant = type;
  let gotInvalidVariant = false;
  if (!asideVariants.includes(type)) {
    gotInvalidVariant = true;
    variant = "danger";
  }
  const iconVariants = ["regular", "solid", "light", "thin", "sharp-solid", "duotone", "brands"];
  if (!iconVariants.includes(iconType)) {
    iconType = "regular";
  }
  return <>
      <div className={`callout my-4 px-5 py-4 overflow-hidden rounded-2xl flex gap-3 border ${asideComponents[variant].outerStyle}`} data-callout-type={asideComponents[variant].calloutType}>
        <div className="mt-0.5 w-4" data-component-part="callout-icon">
          {}
          {icon === "" ? asideComponents[variant].icon : <Icon icon={icon} iconType={iconType} size={14} />}
        </div>
        <div className={`text-sm prose min-w-0 w-full ${asideComponents[variant].innerStyle}`} data-component-part="callout-content">
          {gotInvalidVariant ? <p>
              <span className="font-bold">
                Invalid <code>type</code> passed!
              </span>
              <br />
              <span className="font-bold">Received: </span>
              {type}
              <br />
              <span className="font-bold">Expected one of: </span>
              {asideVariants.join(", ")}
            </p> : <>
              {title && <p className="font-bold">{title}</p>}
              {children}
            </>}
        </div>
      </div>
    </>;
};

<Aside>
  [Initialize the AppKit](/ecosystem/appkit/init) before using examples on this page.
</Aside>

## Balance

Blockchain state changes constantly as new blocks are produced. This has implications for when and how to check TON wallet contract balances:

* [Discrete one-off checks](#on-demand-balance-check) have almost no value on their own — the state might change immediately after the query completes, invalidating its results. Thus, such checks are only practical when making outgoing transfers.
* [Continuous monitoring](#continuous-balance-monitoring) is useful for UI display, showing the most recent balance to users, but should not be used for transaction confirmations.

Notice that both cases require querying the blockchain data via the API client set during the [AppKit initialization](/ecosystem/appkit/init). Obtain and provide the key from the selected client to access higher requests-per-second limits.

### On-demand balance check

Balances are returned as strings representing fractional Toncoin units. For example, `'0.1'` is a balance of 0.1 Toncoin or 100000000 nanoToncoin. Decimal precision of Toncoin is 9 digits, so the smallest possible balance is `'0.000000001'` Toncoin or 1 nanoToncoin.

<Aside type="caution">
  Do not store the balance check results anywhere in the wallet service's state, as they become outdated quickly. For UI purposes, do [continuous balance monitoring](#continuous-balance-monitoring).
</Aside>

<CodeGroup>
  ```tsx title="React" icon="react" theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
  import { useBalance } from '@ton/appkit-react';

  export const BalanceCard = () => {
    const { data: balance } = useBalance();

    return (
      <p>TON wallet balance in fractional Toncoin: {balance ?? '0'}</p>
    );
  };
  ```

  ```ts title="TypeScript" icon="globe" theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
  import { getBalance } from '@ton/appkit';

  const balance = await getBalance(kit);
  if (balance) {
    console.log('TON wallet balance in fractional Toncoin:', balance);
  }
  ```
</CodeGroup>

### 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.

Modify the following examples according to the application logic:

<CodeGroup>
  ```tsx title="React" icon="react" expandable theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
  import { useBalance } from '@ton/appkit-react';

  export const BalanceCard = () => {
    const {
      data: balance,
      isLoading: isBalanceLoading,
      isError: isBalanceError,
      refetch: onRefresh,
    } = useBalance();

    if (isBalanceError) {
      return (
        <div>
          <p>Error retrieving balance</p>
          <button onClick={() => onRefresh()}>Try again</button>
        </div>
      );
    }

    return (
      <div>
        {isBalanceLoading ? (
          <p>Loading the balance...</p>
        ) : (
          <p>TON wallet balance in fractional Toncoin: {balance ?? '0'}</p>
        )}
      </div>
    );
  };
  ```

  ```ts title="TypeScript" icon="globe" expandable theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
  // Not runnable: implement the updateUI()
  import { type AppKit, getBalance } from '@ton/appkit';

  /**
   * Starts the monitoring of the currently connected wallet,
   * calling `onBalanceUpdate()` every `intervalMs` milliseconds
   *
   * @returns a function to stop monitoring
   */
  export function startBalanceMonitoring(
    kit: AppKit,
    onBalanceUpdate: (balance: string) => void,
    intervalMs: number = 10_000,
  ): () => void {
    let isRunning = true;

    const poll = async () => {
      while (isRunning) {
        const balance = await getBalance(kit);
        if (balance) {
          onBalanceUpdate(balance);
        }
        await new Promise((resolve) => setTimeout(resolve, intervalMs));
      }
    };

    // Start monitoring
    poll();

    // Return a cleanup function to stop monitoring
    return () => {
      isRunning = false;
    };
  }

  // Usage
  const stopMonitoring = startBalanceMonitoring(
    kit,
    // The updateUI() function is exemplary and should be replaced by
    // an app function that refreshes the state of the balance displayed
    // in the interface
    (balance) => updateUI(balance),
  );

  // Stop monitoring once it is no longer needed
  stopMonitoring();
  ```
</CodeGroup>

## Transfers

Modify the following examples according to the application logic:

<CodeGroup>
  ```tsx title="React (component)" icon="react" theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
  // Pre-built UI component for sending Toncoin transactions by clicking a button.
  // It handles success and error states while being customizable.
  import { SendTonButton } from '@ton/appkit-react';

  export const SendToncoin = () => {
    // For example: 'UQ...'
    const recipientAddress = '<TON_WALLET_ADDRESS>';
    // For example, '0.1' or '1' Toncoin.
    const toncoin = '<FRACTIONAL_AMOUNT>';

    return (
      <SendTonButton
        // Where to send Toncoin to
        recipientAddress={recipientAddress}

        // Toncoin amount
        amount={toncoin}

        // (optional) Comment string
        comment="Hello from AppKit!"

        // (optional) Add custom button title
        // Defaults to Send X TON, where X is Toncoin amount
        text="Send TON"

        // (optional) Handle successes
        onSuccess={(result) => console.log('Transaction sent:', result)}

        // (optional) Handle errors
        onError={(error) => console.error('Transaction failed:', error)}

        // (optional) Add custom CSS classes
        className=''

        // (optional) When set to `true`, the button is disabled
        disabled={false}
      />
    );
  };
  ```

  ```tsx title="React (hook)" icon="react" theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
  import { useTransferTon } from '@ton/appkit-react';

  export const SendToncoin = () => {
    const { mutate: transfer, isPending, error, data } = useTransferTon();

    const handleTransfer = () => {
      transfer({
        // Where to send Toncoin to.
        // For example: 'UQ...'
        recipientAddress: '<TON_WALLET_ADDRESS>',

        // Fractional Toncoin amount string.
        // For example, '0.1' or '10' Toncoin.
        amount: '<FRACTIONAL_AMOUNT>',

        // (optional) Comment string. Defaults to none if not provided.
        comment: 'Hello from AppKit!',

        // (optional) Payload data encoded as a Base64 string.
        //            Overrides the `comment`, if provided.
        payload: '<PAYLOAD>',

        // (optional) Initial state (code and data) for deploying a new contract,
        //            encoded as a Base64 string
        stateInit: '<STATE_INIT>',
      });
    };

    return (
      <div>
        <button onClick={handleTransfer} disabled={isPending}>
          {isPending ? 'Transferring...' : 'Transfer TON'}
        </button>
        {error && <div>Error: {error.message}</div>}
        {data && (
          <div>
            <p>Transfer successful: {data.boc}</p>
          </div>
        )}
      </div>
    );
  };
  ```

  ```ts title="TypeScript" icon="globe" theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
  import {
    type AppKit,
    type Base64String,
    // Single-call transfer
    transferTon,
    // Two-step transfer: create a transaction object separately from sending it
    createTransferTonTransaction,
    sendTransaction,
  } from '@ton/appkit';

  async function sendToncoin(
    /** Initialized AppKit instance */
    kit: AppKit,
    /** Recipient's TON wallet address as a string */
    recipientAddress: string,
    /** Amount in fractional Toncoin */
    amount: string,
    /** Optional comment string */
    comment?: string,
    /** Optional payload body as a BoC in Base64-encoded string */
    payload?: Base64String,
    /**
     * Optional initial state (code and data) for deploying a new contract,
     * stored as a BoC in Base64-encoded string
     */
    stateInit?: Base64String,
  ) {
    // Sign and send via TON Connect
    const result = await transferTon(kit, {
      recipientAddress,
      amount,
      // Optional comment OR payload, not both
      ...(comment && { comment }),
      ...(payload && { payload }),
      ...(stateInit && { stateInit }),
    });
    console.log('Transaction sent:', result.boc);

    // Alternatively, build the transaction first with createTransferTonTransaction,
    // then pass the resulting object to the sendTransaction function.
  }
  ```
</CodeGroup>

## Confirm transaction delivery

TON achieves transaction [finality](https://en.wikipedia.org/wiki/Blockchain#Finality) after a single masterchain block confirmation, where new blocks are produced approximately every 3 seconds. Once a transaction appears in a masterchain block, it becomes irreversible.

Therefore, to reliably confirm the transaction delivery and status, one needs to check whether a transaction has achieved masterchain finality using the selected API client. Applications should not block the UI while waiting for such confirmation. With [continuous balance monitoring](#continuous-balance-monitoring) and subsequent transaction requests, users will receive the latest information either way.

Confirmations are only needed to reliably display a list of past transactions, including the most recent ones. For detailed transaction tracking and message lookups, the [message lookup guide](/ecosystem/ton-connect/message-lookup) covers finding transactions by external message hash, waiting for confirmations, and applying message normalization.

## Next steps

<Columns cols={2}>
  <Card title="Work with jettons" icon="coins" horizontal="true" href="/ecosystem/appkit/jettons" />
</Columns>

## See also

* [Transaction fees](/foundations/fees)
* [AppKit overview](/ecosystem/appkit/overview)
* [TON Connect overview](/ecosystem/ton-connect)
