Documentation Index
Fetch the complete documentation index at: https://companyname-a7d5b98e-vanity-edits.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
AppKit supports on-chain liquid Toncoin staking through pluggable staking providers. For most user-facing apps, the flow is:
- Register a staking provider.
- Show the terms and quote of the current provider.
- Build a transaction from that quote.
- Send the transaction from the connected wallet.
- Display the user’s staked balance.
Available providers
Tonstakers is the primary liquid staking AppKit provider. It is configured per network, similar to API clients:
// Or @ton/appkit-react for React
import { AppKit, Network } from '@ton/appkit';
import { createTonstakersProvider } from '@ton/appkit/staking/tonstakers';
const kit = new AppKit({
providers: [
// Optional configuration options — omit when not known.
createTonstakersProvider({
[Network.mainnet().chainId]: {
// Defaults to a known pool when available.
contractAddress: 'EQ...POOL_ADDRESS',
// Optional TonAPI key, get it at https://tonconsole.com/tonapi/api-keys
// TonAPI is an alternative API client to TON Center.
tonApiToken: '<TON_API_TOKEN>',
}
}),
],
});
Set up a staking provider
Before requesting quotes or building transactions, register at least one staking provider:
import {
AppKit,
AppKitProvider,
Network,
createTonConnectConnector,
} from '@ton/appkit-react';
import { createTonstakersProvider } from '@ton/appkit/staking/tonstakers';
import '@ton/appkit-react/styles.css';
const kit = new AppKit({
networks: {
[Network.mainnet().chainId]: {
apiClient: {
url: 'https://toncenter.com',
key: '<MAINNET_API_KEY>',
},
},
},
connectors: [
createTonConnectConnector({
tonConnectOptions: {
manifestUrl: 'https://tonconnect-sdk-demo-dapp.vercel.app/tonconnect-manifest.json',
},
}),
],
providers: [createTonstakersProvider()],
});
export function App() {
return <AppKitProvider appKit={kit}>{/* ...app... */}</AppKitProvider>;
}
Show provider terms and a quote
Retail staking UIs should display the provider and an up-to-date quote before asking the user to confirm the transaction.
import {
useAddress,
useStakingProviderInfo,
useStakingProviders,
useStakingQuote,
} from '@ton/appkit-react';
export const StakingQuoteCard = () => {
const address = useAddress();
const { data: providers } = useStakingProviders();
const providerId = providers?.[0];
const { data: providerInfo } = useStakingProviderInfo({ providerId });
const { data: quote, isLoading, error } = useStakingQuote({
providerId,
// Quote direction: 'stake' or 'unstake'
direction: 'stake',
// Staking user's TON wallet address
userAddress: address ?? '<TON_WALLET_ADDRESS>',
// Fractional Toncoin amount string.
// For example, '0.1' or '10' Toncoin.
amount: '1',
});
if (!providerId) {
return <p>No staking providers configured.</p>;
}
if (isLoading) {
return <p>Loading quote...</p>;
}
if (error) {
return <p>Error: {error.message}</p>;
}
return (
<div>
<p>Provider: {providerId}</p>
<p>APY: {providerInfo ? providerInfo.apy / 100 : 0}%</p>
<p>Stake amount: {quote?.amountIn} Toncoin</p>
<p>Estimated output: {quote?.amountOut} Toncoin</p>
</div>
);
};
Build and send the staking transaction
Build the transaction from the quote, then send it through the connected wallet:
import {
useAddress,
useBuildStakeTransaction,
useSendTransaction,
useStakingProviders,
useStakingQuote,
} from '@ton/appkit-react';
export const StakeButton = () => {
const address = useAddress();
const { data: providers } = useStakingProviders();
const providerId = providers?.[0];
const { data: quote } = useStakingQuote({
providerId,
// Quote direction: 'stake' or 'unstake'
direction: 'stake',
// Staking user's TON wallet address
userAddress: address ?? '<TON_WALLET_ADDRESS>',
// Fractional Toncoin amount string.
// For example, '0.1' or '10' Toncoin.
amount: '1',
});
const {
mutateAsync: buildTransaction,
isPending: isBuilding,
} = useBuildStakeTransaction();
const {
mutateAsync: sendTransaction,
isPending: isSending,
} = useSendTransaction();
const handleStake = async () => {
if (!quote || !address || !providerId) {
return;
}
const transaction = await buildTransaction({
providerId,
quote,
userAddress: address,
});
await sendTransaction(transaction);
};
return (
<button
onClick={() => void handleStake()}
disabled={!quote || !address || isBuilding || isSending}
>
{isBuilding || isSending ? 'Submitting...' : 'Stake 1 TON'}
</button>
);
};
Display the staked balance
After the transaction is sent, query the staking balance for the connected wallet:
import {
useAddress,
useStakingProviders,
useStakedBalance,
} from '@ton/appkit-react';
export const StakedBalanceCard = () => {
const address = useAddress();
const { data: providers } = useStakingProviders();
const providerId = providers?.[0];
const { data: balance, isLoading, error } = useStakedBalance({
providerId,
// Staking user's TON wallet address
userAddress: address ?? '<TON_WALLET_ADDRESS>',
});
if (!providerId) {
return <p>No staking providers configured.</p>;
}
if (isLoading) {
return <p>Loading staked balance...</p>;
}
if (error) {
return <p>Error: {error.message}</p>;
}
return <p>Staked balance: {balance?.stakedBalance ?? '0'}</p>;
};
See also