ton-rs
Set of general-purpose rust libraries to interact with TON blockchain.
This crate is heavily based on the tonlib-rs repository and also uses tonlib-sys underneath for the tonlibjson_client implementation.
ton_macros
TLBDerive macros: Automatically derive TLB trait for your types based on it's members- Native
Enumsupport using TLBPrefix: Automatically match underlying variant by it's prefix (check enum.rs example). Provides powerful enums, but use them carefully; read the Enum with TLB macros chapter. ton_contract!: Generate aTonContractwrapper type and optionally implement method traits for it.#[ton_methods]: Generate async get-method implementations for contract traits or impl blocks, with optionalname_formatconversion for emulated method names.
ton_core
serdefeature: provides few mods to ser/de core types, check ton_core/src/serde.rs. Disabled by default.- EmulationProvider - Provider-neutral interface used to execute TVM get methods
- TonCell
- TonAddress
- TLB - Trait allows you read/write arbitrary objects in BOC format
- Types - Few basic types, common and stable enough to be in core
ton
lite-clientfeature: Disabled by default. Enable it for the ADNL-basedLiteClient; it also enables the networking dependencies required by that client.tonlibjsonfeature: Disabled by default. Enable it for the nativeTLClient, emulator implementations,TLStateProvider, andton::emulators::tl_emulation_provider::TLEmulationProvider.ContractClientandTonContractcan be used without it by supplying custom providers. This feature includeslite-clientbecauseTLClientuses it to refresh the network configuration's init block.WalletVersionandLiteNodeFilterserialize using their Rust variant names;TVMGetMethodIDserializes as an integer or string according to its variant.- Use
TON_NET_CONF_MAINNET_PATHorTON_NET_CONF_TESTNET_PATHenv variables to overridenetconfig.jsonand use your own TON nodes. - TLBAdapters - Allows you to work with rust types like HashMap, and still serialize it properly for TON
- BlockTLB - Bunch of types to interact with raw blockchain data (However it's not fully covered)
- TonWallet - Wrapper of wallet to sign and create external messages
- TLClient - Using
tonlibjsonto interact with TON network - TonContract - Use it with
ContractClient::builder(state_provider, emulation_provider)to get data or execute methods on TON contracts - Standard Jetton, NFT, SBT, and TON wallet contract wrappers live under
contracts::tep, grouped into public modules by standard and implementation. For example, usecontracts::tep::jetton::jetton_master_contract::JettonMasterContractorcontracts::tep::ton_wallet::TonWalletContract.
ContractClient::builder(...).with_default_caches() configures state caches. When using the native adapter, configure emulator library caches independently with ton::emulators::tl_emulation_provider::TLEmulationProvider::with_default_caches().
State caches require an active Tokio runtime when the client is built and start a background refresh task. Dropping the client does not cancel an in-flight provider call; initial sequence discovery also keeps retrying provider errors until it succeeds.
TonContract::new() synchronously stores the contract address and optional transaction ID. load_state() and load_parsed_data() load and retain state; emulation uses retained state when available. Otherwise, it lets the emulation provider resolve the address and transaction ID unless EmulationProvider::requires_resolved_state() returns true, in which case the configured state provider loads it first.
Mnemonic clears its owned words and password on drop, and KeyPair clears its
secret key bytes. Caller-owned mnemonic strings and copies read from the public
KeyPair::secret_key field remain the caller's responsibility.
Rust version
The minimum supported Rust version (MSRV) is 1.94. CI verifies every published crate, target, and feature against the declared MSRV and checks weekly whether the latest dependency releases still support it. MSRV increases are released as minor compatibility changes.
Getting started
Examples can be found in examples folder (feel free to add your own)
Interesting one:
- emulate_get_method - use your own TonContract
- ton_transfer - transfer TONs between wallets using TLClient
Basic usage
// Build and read custom cells
// describe TLB type:
#[derive(Debug, Clone, PartialEq, TLB)]
#[tlb(ensure_empty = true)]
pub struct StateInit {
#[tlb_derive(bits_len = 5)]
pub split_depth: Option<u8>,
pub tick_tock: Option<TickTock>,
pub code: Option<TLBRef<TonCell>>,
pub data: Option<TLBRef<TonCell>>,
#[tlb(adapter = "TLBHashMapE::<DictKeyAdapterTonHash, DictValAdapterTLB<_>>::new(256)")]
pub library: LibsDict,
}
fn main() {
let boc_hex = "b5ee9c720102160100030400020134020100510000082f29a9a31738dd3a33f904d35e2f4f6f9af2d2f9c563c05faa6bb0b12648d5632083ea3f89400114ff00f4a413f4bcf2c80b03020120090404f8f28308d71820d31fd31fd31f02f823bbf264ed44d0d31fd31fd3fff404d15143baf2a15151baf2a205f901541064f910f2a3f80024a4c8cb1f5240cb1f5230cbff5210f400c9ed54f80f01d30721c0009f6c519320d74a96d307d402fb00e830e021c001e30021c002e30001c0039130e30d03a4c8cb1f12cb1fcbff08070605000af400c9ed54006c810108d718fa00d33f305224810108f459f2a782106473747270748018c8cb05cb025005cf165003fa0213cb6acb1f12cb3fc973fb000070810108d718fa00d33fc8542047810108f451f2a782106e6f746570748018c8cb05cb025006cf165004fa0214cb6a12cb1fcb3fc973fb0002006ed207fa00d4d422f90005c8ca0715cbffc9d077748018c8cb05cb0222cf165005fa0214cb6b12ccccc973fb00c84014810108f451f2a702020148130a0201200c0b0059bd242b6f6a2684080a06b90fa0218470d4080847a4937d29910ce6903e9ff9837812801b7810148987159f31840201200e0d0011b8c97ed44d0d70b1f8020158120f02012011100019af1df6a26840106b90eb858fc00019adce76a26840206b90eb85ffc0003db29dfb513420405035c87d010c00b23281f2fff274006040423d029be84c6002e6d001d0d3032171b0925f04e022d749c120925f04e002d31f218210706c7567bd22821064737472bdb0925f05e003fa403020fa4401c8ca07cbffc9d0ed44d0810140d721f404305c810108f40a6fa131b3925f07e005d33fc8258210706c7567ba923830e30d03821064737472ba925f06e30d1514008a5004810108f45930ed44d0810140d720c801cf16f400c9ed540172b08e23821064737472831eb17080185005cb055003cf1623fa0213cb6acb1fcb3fc98040fb00925f03e2007801fa00f40430f8276f2230500aa121bef2e0508210706c7567831eb17080185004cb0526cf1658fa0219f400cb6917cb1f5260cb3f20c98040fb0006";
let state_init = StateInit::from_boc_hex(boc_hex).unwrap();
}
Enum with TLB macros
TLB macros can derive TLB for enums. You can define enums with a common prefix or with no common prefix. Enums without a common prefix are tricky: if you embed such an enum into another enum, its variants are effectively inlined into the outer enum.
;
;
// Common prefix
This is effectively parsed as:
Be careful with null (zero-length) prefixes. A null prefix acts like a wildcard; during parsing, variants are tried in declaration order, so a null-prefix variant placed earlier can consume the input before later variants are considered. See tests in ton_core/src/traits/tlb/test_tlb_enum.rs for the shadowing and the safe-prefix example.
Contribution
Repository and crate-specific guidance lives in AGENTS.md.
Public API changes must preserve wire formats, document compatibility impact,
and keep one supported construction path. Open enums and returned records use
#[non_exhaustive]; fixed TLB records remain exhaustive when their fields are
the serialization contract.
If you face with some unclear parts or bugs, your can add a new example or improve documentation.
If you implemented some general feature, please make sure it's covered by tests (unit tests if possible)