C# .NET client for TON API.
Supported platforms: .NET 10.0+
English version | Русская версия
dotnet add package TonapiClient✅ Full TON API v2 coverage ✅ Type-safe models for all endpoints ✅ Dependency Injection and HttpClientFactory support ✅ Retry logic and error handling ✅ CancellationToken support ✅ Asynchronous transaction waiting with exponential backoff ✅ Low-level access via LiteServer API ✅ Testnet and mainnet support
To run tests, create a configuration file:
- Copy
src/TonapiClient.Tests/appsettings.example.jsontosrc/TonapiClient.Tests/appsettings.json - Replace
YOUR_API_KEY_HEREwith your API key from TON API - For tests, it's recommended to use testnet API:
https://testnet.tonapi.io
{
"TonApiClient": {
"BaseUrl": "https://testnet.tonapi.io",
"ApiKey": "YOUR_API_KEY_HERE",
"TimeoutSeconds": 30
}
}Run tests:
dotnet testNote: The appsettings.json file is included in .gitignore and should not be committed to the repository.
using TonapiClient;
var client = new TonApiClient("https://tonapi.io", "your-api-key");
// Get blockchain information
var masterchainHead = await client.Blockchain.GetMasterchainHeadAsync();
Console.WriteLine($"Last block: {masterchainHead.Last.Seqno}");
// Get account information
var account = await client.Account.GetAsync("EQD...address");
Console.WriteLine($"Balance: {account.Balance}");
// Get account transactions
var transactions = await client.Account.GetTransactionsAsync("EQD...address", limit: 10);
foreach (var tx in transactions.Transactions)
{
Console.WriteLine($"TX: {tx.Hash}");
}
// Get Jetton information
var jetton = await client.Jetton.GetAsync("EQD...jetton-address");
Console.WriteLine($"Jetton: {jetton.Metadata.Name}");
// Get NFT collection
var nft = await client.Nft.GetCollectionAsync("EQD...collection-address");
Console.WriteLine($"NFT Collection: {nft.Metadata.Name}");The client uses HttpClientFactory to manage HTTP connections and supports full DI integration:
using Microsoft.Extensions.DependencyInjection;
using TonapiClient;
var services = new ServiceCollection();
// From configuration (appsettings.json)
services.AddTonApiClient(configuration);
// Or with explicit parameters
services.AddTonApiClient(options =>
{
options.BaseUrl = "https://tonapi.io";
options.ApiKey = "your-api-key";
options.TimeoutSeconds = 30;
});
var serviceProvider = services.BuildServiceProvider();
var client = serviceProvider.GetRequiredService<TonApiClient>();
// Use client...In ASP.NET Core, add to Program.cs:
builder.Services.AddTonApiClient(builder.Configuration);And in appsettings.json:
{
"TonApiClient": {
"BaseUrl": "https://tonapi.io",
"ApiKey": "your-api-key",
"TimeoutSeconds": 30
}
}The client is built on categories, each encapsulating logic for working with a specific area of TON API:
- 🔗 CategoryBase - base class for all categories with common HTTP methods
- 📦 TonApiClient - main facade providing access to all categories via properties
- 🔌 HttpClientFactory - used for efficient HTTP connection management
- ⚙️ IOptions - configuration via standard .NET mechanism
All categories are accessible as client properties: client.Blockchain, client.Account, client.Jetton, etc.
The client is organized by categories for ease of use:
GetBlockAsync()- Get block dataGetReducedBlocksAsync()- Get reduced block data within a time rangeGetMasterchainShardsAsync()- Get masterchain block shardsGetMasterchainHeadAsync()- Get latest masterchain blockGetMasterchainBlocksAsync()- Get blocks between masterchain blocksGetMasterchainTransactionsAsync()- Get transactions between masterchain blocksGetBlockTransactionsAsync()- Get transactions from a specific blockGetConfigAsync()- Get blockchain config by seqnoGetCurrentConfigAsync()- Get current blockchain configGetRawConfigAsync()- Get raw blockchain configGetTransactionAsync()- Get transaction by hashGetTransactionByMessageHashAsync()- Get transaction by message hashSendBocAsync()- Send BOC messageWaitForTransactionAsync()- Wait for transaction with exponential backoffGetValidatorsAsync()- Get validators listGetAccountAsync()- Get raw account dataGetAccountTransactionsAsync()- Get account transactionsExecuteGetMethodAsync()- Execute GET method on accountExecuteMethodAsync()- Execute POST method on accountInspectAccountAsync()- Inspect account
GetAsync()- Get account informationGetTonBalanceAsync()- Get account TON balanceGetBulkAsync()- Get information about multiple accountsGetTransactionsAsync()- Get account transactionsGetEventsAsync()- Get account eventsGetEventByIdAsync()- Get specific event by IDGetTracesAsync()- Get account traces (lightweight identifiers)GetJettonsAsync()- Get account Jetton balancesGetJettonBalanceAsync()- Get specific Jetton balance by master addressGetJettonBalance()- Get Jetton balance by name or addressGetJettonsHistoryAsync()- Get Jetton transfer historyGetNftsAsync()- Get account NFTsGetNftsHistoryAsync()- Get NFT transfer historyGetDnsBackresolveAsync()- Get account domain names via DNS backresolveGetSubscriptionsAsync()- Get account subscriptionsGetPublicKeyAsync()- Get account public keyGetDiffAsync()- Get balance change between two timestampsExecuteGetMethodAsync()- Execute smart contract GET methodInspectAsync()- Inspect account contractWaitForTransactionAsync()- Wait for transaction with exponential backoff
GetAsync()- Get Jetton informationGetAllAsync()- Get list of all JettonsGetBulkAsync()- Get metadata for multiple Jettons by addressesGetHoldersAsync()- Get Jetton holdersGetEventJettonsAsync()- Get event with Jetton transfer informationGetJettonWalletAddressAsync()- Get user's Jetton wallet address
GetItemAsync()- Get NFT by addressGetItemsBulkAsync()- Get multiple NFTs by addressesGetItemHistoryAsync()- Get NFT historyGetCollectionAsync()- Get NFT collectionGetCollectionsAsync()- Get list of collectionsGetCollectionsBulkAsync()- Get multiple collections by addressesGetCollectionItemsAsync()- Get NFTs from collection
GetRecordAsync()- Get DNS recordResolveAsync()- Resolve domain nameGetAuctionsAsync()- Get DNS auctionsGetBidsAsync()- Get bids for domain
GetPoolsAsync()- Get list of staking poolsGetPoolAsync()- Get pool informationGetAccountInfoAsync()- Get account staking information
GetAsync()- Get current token ratesGetChartAsync()- Get historical rate dataGetMarketsAsync()- Get TON rates from different exchanges
GetAsync()- Get trace by IDWaitForAsync()- Wait for trace completionEmulateAsync()- Emulate message and get trace
GetAsync()- Get wallet informationGetSeqnoAsync()- Get wallet seqnoGetWalletsByPublicKeyAsync()- Get wallets by public keyEmulateAsync()- Emulate sending message
GetConfigAsync()- Get gasless configurationEstimateAsync()- Estimate gasless transaction feeSendAsync()- Send gasless transaction
GetAsync()- Get event by IDWaitForAsync()- Wait for event completion
GetMasterchainInfoAsync()- Get masterchain informationGetMasterchainInfoExtAsync()- Get extended masterchain informationGetTimeAsync()- Get blockchain timeGetBlockAsync()- Get raw block by IDGetBlockHeaderAsync()- Get raw block headerGetAccountStateAsync()- Get raw account stateGetShardInfoAsync()- Get shard informationGetAllShardsInfoAsync()- Get information about all shardsGetTransactionsAsync()- Get raw account transactionsGetListBlockTransactionsAsync()- Get list of transactions from blockSendMessageAsync()- Send raw message to blockchainGetBlockProofAsync()- Get raw block proofGetShardBlockProofAsync()- Get raw shard block proofGetConfigAsync()- Get raw configuration parametersGetOutMsgQueueSizesAsync()- Get outgoing message queue sizes
GetProvidersAsync()- Get list of storage providers
GetAccountAsync()- Get multisig account informationGetOrdersAsync()- Get multisig orders (proposals)
DecodeMessageAsync()- Decode message
// Build and sign transaction (using TonSdk.NET)
var keys = Mnemonic.ToWalletKey(mnemonic.Split(" "));
var wallet = WalletV5R1.Create(0, keys.PublicKey, false);
var seqno = (await client.Wallet.GetSeqnoAsync(wallet.Address.ToString())).SeqnoValue;
var message = new MessageRelaxed(...); // Create your message
Cell unsignedTransfer = WalletV5R1Utils.CreateUnsignedTransfer(
wallet.WalletId, seqno, [message], SendMode.SendPayFwdFeesSeparately);
Cell transfer = WalletV5R1Utils.SignAndPack(unsignedTransfer, keys.SecretKey);
// Create external message
var externalMsg = new Message(
new CommonMessageInfo.ExternalIn(null, wallet.Address, BigInteger.Zero),
transfer,
seqno > 0 ? null : wallet.Init);
// Calculate message hash locally
var messageHash = WalletV5R1Utils.NormalizeHash(externalMsg).ToHex();
// Serialize to BOC
var boc = Convert.ToBase64String(Builder.BeginCell().StoreMessage(externalMsg).EndCell().ToBoc());
// Emulate before sending (optional)
var consequences = await Client.Traces.EmulateAsync(bocAsString);
Console.WriteLine($"Estimated fee: {consequences.GetTotalFees()}");
// Send transaction
await client.Blockchain.SendBocAsync(boc: boc);
// Wait for transaction
var tx = await client.Blockchain.WaitForTransactionAsync(
wallet.Address.ToString(),
messageHash,
maxWaitTime: 60);
if (tx != null && tx.Success)
{
Console.WriteLine($"Transaction confirmed: {tx.Hash}");
}// Get user's Jetton wallet address
var jettonWalletAddress = await client.GetJettonWalletAddressAsync(
jettonMasterAddress,
userAddress);
// Get Jetton information
var jetton = await client.Jetton.GetAsync(jettonMasterAddress);
Console.WriteLine($"{jetton.Metadata.Name} ({jetton.Metadata.Symbol})");
// Get holders
var holders = await client.Jetton.GetHoldersAsync(jettonMasterAddress, limit: 100);
Console.WriteLine($"Total holders: {holders.Total}");// Get NFT collection
var collection = await client.Nft.GetCollectionAsync(collectionAddress);
Console.WriteLine($"Collection: {collection.Metadata.Name}");
// Get NFTs from collection
var items = await client.Nft.GetCollectionItemsAsync(collectionAddress, limit: 10);
foreach (var item in items.NftItems)
{
Console.WriteLine($"NFT: {item.Metadata.Name}");
}
// Get NFT history
var history = await client.Nft.GetItemHistoryAsync(nftAddress);
foreach (var event in history.Events)
{
Console.WriteLine($"Event: {event.EventId}");
}// Inspect account to get list of available methods
var inspection = await client.Blockchain.InspectAccountAsync(contractAddress);
foreach (var method in inspection.Methods)
{
Console.WriteLine($"Method: {method.Name}");
}
// Execute GET method (parameters in query string)
var result = await client.Blockchain.ExecuteGetMethodAsync(
contractAddress,
"get_wallet_address",
new List<string> { "0:..." });
// Execute POST method (parameters in request body)
var postResult = await client.Blockchain.ExecuteMethodAsync(
contractAddress,
"get_wallet_address",
new List<MethodArg>
{
new() { Type = "slice", Value = "b5ee9c72..." }
});
Console.WriteLine($"Success: {postResult.Success}");// Get masterchain information
var info = await client.LiteServer.GetMasterchainInfoAsync();
Console.WriteLine($"Last block seqno: {info.Last.Seqno}");
// Get blockchain time
var time = await client.LiteServer.GetTimeAsync();
Console.WriteLine($"Blockchain time: {DateTimeOffset.FromUnixTimeSeconds(time.Time)}");
// Get raw block
var blockId = $"({info.Last.Workchain},{info.Last.Shard},{info.Last.Seqno},{info.Last.RootHash},{info.Last.FileHash})";
var block = await client.LiteServer.GetBlockAsync(blockId);
Console.WriteLine($"Block data length: {block.Data.Length}");
// Get raw account state
var accountState = await client.LiteServer.GetAccountStateAsync(
"0:...",
targetBlock: blockId);
Console.WriteLine($"Account balance: {accountState.Balance}");
// Get raw transactions
var rawTxs = await client.LiteServer.GetTransactionsAsync(
"0:...",
count: 10);
Console.WriteLine($"Transactions: {rawTxs.Transactions.Count}");TonapiClient/
├── src/
│ ├── TonapiClient/ # Main library
│ │ ├── Categories/ # API categories
│ │ │ ├── AccountCategory.cs
│ │ │ ├── BlockchainCategory.cs
│ │ │ ├── JettonCategory.cs
│ │ │ ├── NftCategory.cs
│ │ │ ├── LiteServerCategory.cs
│ │ │ └── ...
│ │ ├── Models/ # Data models
│ │ ├── TonApiClient.cs # Main client class
│ │ ├── TonApiClientOptions.cs # Configuration options
│ │ └── TonApiException.cs # Exceptions
│ └── TonapiClient.Tests/ # Integration tests
│ ├── AccountCategoryTests.cs
│ ├── BlockchainCategoryTests.cs
│ ├── LiteServerCategoryTests.cs
│ └── ...
├── .github/
│ └── workflows/
│ └── ci-cd.yml # CI/CD configuration
└── README.md
- .NET 10.0 SDK
- API key from TON API (for tests)
Contributions are welcome! Please feel free to submit a Pull Request.
UQAN9eHzTT6ntU0LSIcqwLJz9GdzeUAOjeXr0x8_XWO0W9S5
MIT