# @ton/appkit-react

React components and hooks for AppKit.

## Overview

- [Initialization](#initialization)
- [Basic Usage](#basic-usage)
- [Swap](#swap)
- [Staking](#staking)
- [Creating a Swap Provider](./docs/creating-swap-provider.md): Implement your own swap provider for any DEX or protocol.
- [Hooks](./docs/hooks.md): React hooks for wallet connection, state, and data fetching.
- [Components](./docs/components.md): UI components for AppKit.

## Installation

```bash
npm install @ton/appkit-react @tanstack/react-query @tonconnect/ui-react @ton/core @ton/crypto
```

## Dependencies

`@ton/appkit-react` requires the following peer dependencies:

-   `react` (>= 18.0.0)
-   `react-dom` (>= 18.0.0)
-   `@tanstack/react-query` (>= 5.0.0)
-   `@tonconnect/ui-react` (>= 2.4.1)

## Initialization

Initialize `QueryClient` and `AppKit`, then wrap your application in `QueryClientProvider` and `AppKitProvider`.

> [!NOTE]
> Don't forget to import styles from `@ton/appkit-react/styles.css`.

```tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { AppKit, Network, createTonConnectConnector } from '@ton/appkit';
import { AppKitProvider } from '@ton/appkit-react';
import type { FC } from 'react';

// Import styles
import '@ton/appkit-react/styles.css';

// Initialize QueryClient
const queryClient = new QueryClient({
    defaultOptions: {
        queries: {
            refetchOnWindowFocus: false,
        },
    },
});

// Initialize AppKit
const appKit = new AppKit({
    networks: {
        [Network.mainnet().chainId]: {
            apiClient: {
                url: 'https://toncenter.com',
                key: 'your-key',
            },
        },
        // Optional: add testnet
        // [Network.testnet().chainId]: {
        //     apiClient: {
        //         url: 'https://testnet.toncenter.com',
        //         key: 'your-key',
        //     },
        // },
    },
    connectors: [
        createTonConnectConnector({
            tonConnectOptions: {
                manifestUrl: 'https://tonconnect-sdk-demo-dapp.vercel.app/tonconnect-manifest.json',
            },
        }),
    ],
});

export const App: FC = () => {
    return (
        <QueryClientProvider client={queryClient}>
            <AppKitProvider appKit={appKit}>{/* <AppContent /> */}</AppKitProvider>
        </QueryClientProvider>
    );
};
```
[Read more about TanStack Query](https://tanstack.com/query/latest/docs/framework/react/overview)

### TonConnect Configuration

When using `TonConnectConnector`, you can pass `tonConnectOptions` which accepts standard [TonConnectUI options](https://github.com/ton-connect/sdk/tree/main/packages/ui-react#parameters), including `manifestUrl`, `uiOptions`, etc.

## Basic Usage

### Connect Wallet

Use `TonConnectButton` to allow users to connect their wallets. It handles the connection flow and UI.

```tsx
import { TonConnectButton } from '@ton/appkit-react';

export const Header = () => {
    return (
        <header>
            <TonConnectButton />
        </header>
    );
};
```

### Get Wallet Address

Use `useAddress` to get the currently connected wallet address.

```tsx
import { useAddress } from '@ton/appkit-react';

export const AddressBlock = () => {
    const address = useAddress();

    if (!address) {
        return <div>Wallet not connected</div>;
    }

    return <div>Address: {address}</div>;
};
```

### Get Balance

Use `useBalance` to fetch the TON balance of the connected wallet.

```tsx
import { useBalance } from '@ton/appkit-react';

export const Balance = () => {
    const { data: balance, isLoading } = useBalance();

    if (isLoading) {
        return <div>Loading...</div>;
    }

    return <div>Balance: {balance?.toString()} TON</div>;
};
```

> See [Hooks Documentation](./docs/hooks.md) for all available hooks and [Components Documentation](./docs/components.md) for UI components.

## Send Transaction

Use the `Send` component to trigger a transaction from a button. It handles the entire send flow.

```tsx
return (
    <Send
        request={{
            messages: [
                {
                    address: 'EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c', // Recipient address
                    amount: '100000000', // 0.1 TON in nanotons (raw format)
                    payload: beginCell()
                        .storeUint(0, 32)
                        .storeStringTail('Hello')
                        .endCell()
                        .toBoc()
                        .toString('base64') as Base64String,
                },
            ],
        }}
        text="Send Transaction"
        onSuccess={(result: SendTransactionReturnType) => {
            console.log('Transaction sent:', result);
        }}
        onError={(error: Error) => {
            console.error('Transaction failed:', error);
        }}
    />
);
```

For a custom UI, use `SendProvider` with `useSendContext` — see [Components Documentation](./docs/components.md#sendprovider).

## Swap

AppKit uses a provider-based architecture for swaps. Any DEX or protocol can implement a swap provider by extending the `SwapProvider` class — AppKit handles routing, hooks, and transaction building through a unified interface.

`OmnistonSwapProvider` is an available provider. You can use it, replace it, or run multiple providers side by side. To implement your own, see [Creating a Swap Provider](./docs/creating-swap-provider.md).

### Installation

```bash
npm install @ston-fi/omniston-sdk
```

### Setup

Initialize `AppKit` with `OmnistonSwapProvider`:

```ts
// Initialize AppKit with swap providers
const appKit = new AppKit({
    networks: {
        [Network.mainnet().chainId]: {
            apiClient: {
                url: 'https://toncenter.com',
                key: 'your-key',
            },
        },
    },
    providers: [
        createOmnistonProvider({
            apiUrl: 'https://api.ston.fi',
            defaultSlippageBps: 100, // 1%
        }),
        createDeDustProvider({
            defaultSlippageBps: 100,
            referralAddress: 'EQ...', // Optional
        }),
    ],
});
```

### Hooks

Use `useSwapQuote` to get a quote and `useBuildSwapTransaction` to build the transaction.

See [Swap Hooks](./docs/hooks.md#swap) for usage examples.

## Staking

AppKit supports staking through various providers (e.g., Tonstakers). The staking functionality is integrated into the core action and hook system.

### Hooks

Use `useStakingQuote` to get a staking/unstaking quote and `useBuildStakeTransaction` to build the transaction.

[Read more about Staking](https://github.com/ton-connect/kit/tree/main/packages/appkit/docs/staking.md)

```tsx
const {
    data: quote,
    isLoading,
    error,
} = useStakingQuote({
    amount: '10',
    direction: 'stake',
});

if (isLoading) return <div>Loading quote...</div>;
if (error) return <div>Error: {error.message}</div>;

return <div>Expected Output: {quote?.amountOut}</div>;
```

```tsx
const { data: quote } = useStakingQuote({
    amount: '10',
    direction: 'stake',
});

const { mutateAsync: buildTx, isPending: isBuilding } = useBuildStakeTransaction();
const { mutateAsync: sendTx, isPending: isSending } = useSendTransaction();

const handleStake = async () => {
    if (!quote) return;
    try {
        const transaction = await buildTx({
            quote,
            userAddress: 'EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c',
        });
        await sendTx(transaction);
    } catch (e) {
        console.error(e);
    }
};

const isPending = isBuilding || isSending;

return (
    <div>
        <button onClick={handleStake} disabled={!quote || isPending}>
            {isPending ? 'Processing...' : 'Stake'}
        </button>
    </div>
);
```

## Migration from TonConnect UI

`AppKitProvider` automatically bridges TonConnect if a `TonConnectConnector` is configured, so `@tonconnect/ui-react` hooks (like `useTonAddress`, `useTonWallet`, etc.) work out of the box inside `AppKitProvider`.

You can use standard TonConnect hooks in your components:

```tsx
import { useTonAddress } from '@tonconnect/ui-react';

export const AppContent: FC = () => {
    const address = useTonAddress();

    return <p>Address: {address}</p>;
};
```

## License

MIT

<!--
This file is auto-generated. Do not edit manually.
Changes will be overwritten when running the docs update script.
Source template: template/packages/appkit-react/README.md
-->

