{"id":13410175,"url":"https://github.com/ston-fi/tonlib-rs","last_synced_at":"2025-03-14T15:32:01.971Z","repository":{"id":154551795,"uuid":"625975621","full_name":"ston-fi/tonlib-rs","owner":"ston-fi","description":"Rust SDK for The Open Network","archived":false,"fork":false,"pushed_at":"2024-10-25T09:02:59.000Z","size":889,"stargazers_count":172,"open_issues_count":17,"forks_count":38,"subscribers_count":9,"default_branch":"main","last_synced_at":"2024-10-25T09:50:29.514Z","etag":null,"topics":["sdk-rust","ton"],"latest_commit_sha":null,"homepage":"https://github.com/ston-fi/tonlib-rs","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ston-fi.png","metadata":{"files":{"readme":null,"changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-10T14:27:28.000Z","updated_at":"2024-10-25T09:02:18.000Z","dependencies_parsed_at":null,"dependency_job_id":"7544f436-7670-47b5-ad28-55ba46a845be","html_url":"https://github.com/ston-fi/tonlib-rs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ston-fi%2Ftonlib-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ston-fi%2Ftonlib-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ston-fi%2Ftonlib-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ston-fi%2Ftonlib-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ston-fi","download_url":"https://codeload.github.com/ston-fi/tonlib-rs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221433393,"owners_count":16820219,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["sdk-rust","ton"],"created_at":"2024-07-30T20:01:05.369Z","updated_at":"2024-10-26T01:30:37.198Z","avatar_url":"https://github.com/ston-fi.png","language":"Rust","funding_links":[],"categories":["🧑‍💻 Development"],"sub_categories":["Libraries \u0026 SDKs"],"readme":"# Rust SDK for The Open Network\n\nRust SDK for [The Open Network](https://ton.org/)\n\n## Features\n\n* Rust SDK for The Open Network\n* Using `tonlibjson` as data provider\n* Support parsing and generation of Cells methods for more convenient interaction with data structures\n* Support of Wallet versions (3, 3 revision 2, 4 revision 2)\n* Derive wallet address\n* Support of TON Mnemonics\n* NaCL-compatible Ed25519 signing of transactions\n* Support jetton functions: getting of jetton data and wallet address for jetton\n* Support internal and external jetton metadata loading\n* Connection pooling \u0026 retries support for better server-level interaction\n* Support of IPFS jetton metadata\n\n## Dependencies\n\n`tonlib-sys` - https://github.com/ston-fi/tonlib-sys\n\n## Prerequisites\n\nFor Linux:\n```shell\nsudo apt install build-essential cmake libsodium-dev libsecp256k1-dev lz4 liblz4-dev\n```\n\nFor macOS:\n```shell\nbrew install --cask mactex\nbrew install readline secp256k1 ccache pkgconfig cmake libsodium\n```\n\n### Build library\n\nYou can build the library using the following command:\n\n```bash\ncargo build\n```\n\n## Usage\n\nTo use this library in your Rust application, add the following to your Cargo.toml file:\n\n```toml\n[dependencies]\ntonlib = \"0.15\"\n```\n\nThen, in your Rust code, you can import the library with:\n\n```rust\nuse tonlib;\n```\n\n### Cell\n\nCreating a `Cell` and writing data to it:\n\n``` rust\nuse anyhow::anyhow;\nuse tonlib::address::TonAddress;\nuse tonlib::cell::CellBuilder;\n\nfn write_cell() -\u003e anyhow::Result\u003c()\u003e {\nlet mut writer = CellBuilder::new();\nlet addr = TonAddress::from_base64_url(\"EQDk2VTvn04SUKJrW7rXahzdF8_Qi6utb0wj43InCu9vdjrR\")?;\nlet cell = writer\n    .store_u32(32, 0xFAD45AADu32)?\n    .store_bit(true)?\n    .store_u8(8, 234u8)?\n    .store_slice(\u0026[0xFA, 0xD4, 0x5A, 0xAD, 0xAA, 0x12, 0xFF, 0x45])?\n    .store_address(\u0026addr)?\n    .store_string(\"Hello, TON\")?\n    .build()?;\n    # Ok(())\n}\n```\n\n Reading data from a `Cell`:\n\n```rust\nuse tonlib::cell::Cell;\nfn read_cell(cell: Cell) -\u003e anyhow::Result\u003c()\u003e {\n    let mut reader = cell.parser();\n    let u32_value = reader.load_u32(32)?;\n    let bit_value = reader.load_bit()?;\n    let u8_value = reader.load_u8(8)?;\n    let bytes_value = reader.load_bytes(8)?;\n    let address_value = reader.load_address()?;\n    let str_value = reader.ensure_empty()?;\n    Ok(())\n}\n```\n\n### TON blockchain client\n\nTo call methods, create a client:\n\n```rust\n\nuse tonlib::client::TonClient;\nuse tonlib::client::TonClientBuilder;\nasync fn create_client()-\u003e anyhow::Result\u003c()\u003e{\n    TonClient::set_log_verbosity_level(2); //setup of logging level\n    let client = TonClientBuilder::new()\n    .with_pool_size(10)\n    .with_keystore_dir(String::from(\"/tmp\"))\n    .build()\n    .await?;\nOk(())\n}\n```\n\n\n\n`TonClient::set_log_verbosity_level(2);` sets the logging level.\n\nBy default, the connection is made to mainnet. But you can also specify a test network when creating the client:\n\n```rust\nuse tonlib::config::TESTNET_CONFIG;\nuse tonlib::client::TonConnectionParams;\nuse tonlib::client::TonClientBuilder;\nasync fn create_client_with_conn_params()-\u003e anyhow::Result\u003c()\u003e{\n    let client = TonClientBuilder::new()\n        .with_connection_params(\u0026TonConnectionParams {\n            config: TESTNET_CONFIG.to_string(),\n            blockchain_name: None,\n            use_callbacks_for_network: false,\n            ignore_cache: false,\n            keystore_dir: None,\n        })\n        .with_pool_size(10)\n        .build()\n        .await?;\n    Ok(())\n}\n```\n\n\nAfter creating the client, you can call methods on the TON blockchain:\n\n```rust\nuse tonlib::address::TonAddress;\nuse tonlib::tl::InternalTransactionId;\nuse tonlib::tl::NULL_BLOCKS_ACCOUNT_TRANSACTION_ID;\nuse tonlib::tl::BlocksTransactions;\nuse tonlib::tl::BlocksShards;\nuse tonlib::tl::BlockId;\nuse tonlib::tl::BlocksMasterchainInfo;\nuse tonlib::client::TonClient;\nuse tonlib::client::TonClientInterface;\n\nasync fn call_blockchain_methods()-\u003e anyhow::Result\u003c()\u003e{\n    let client = TonClient::builder().build().await?;\n    let (_, info) = client.get_masterchain_info().await?;\n    println!(\"MasterchainInfo: {:?}\", \u0026info);\n    let block_id = BlockId {\n        workchain: info.last.workchain,\n        shard: info.last.shard,\n        seqno: info.last.seqno,\n    };\n    let block_id_ext = client.lookup_block(1, \u0026block_id, 0, 0).await?;\n    println!(\"BlockIdExt: {:?}\", \u0026block_id_ext);\n    let block_shards: BlocksShards = client.get_block_shards(\u0026info.last).await?;\n    let mut shards = block_shards.shards.clone();\n    println!(\"Shards: {:?}\", \u0026block_shards);\n    shards.insert(0, info.last.clone());\n    for shard in \u0026shards {\n        println!(\"Processing shard: {:?}\", shard);\n        let workchain = shard.workchain;\n        let txs: BlocksTransactions = client\n            .get_block_transactions(\u0026shard, 7, 1024, \u0026NULL_BLOCKS_ACCOUNT_TRANSACTION_ID)\n            .await?;\n        println!(\n            \"Number of transactions: {}, incomplete: {}\",\n            txs.transactions.len(),\n            txs.incomplete\n        );\n        for tx_id in txs.transactions {\n            let mut t: [u8; 32] = [0; 32];\n            t.clone_from_slice(tx_id.account.as_slice());\n            let addr = TonAddress::new(workchain, \u0026t);\n            let id = InternalTransactionId {\n                hash: tx_id.hash.clone(),\n                lt: tx_id.lt,\n            };\n            let tx = client\n                .get_raw_transactions_v2(\u0026addr, \u0026id, 1, false)\n                .await?;\n            println!(\"Tx: {:?}\", tx.transactions[0])\n        }\n    }\n    Ok(())\n}\n```\n\nYou can get the account state for any contract:\n\n```rust\nuse tonlib::address::TonAddress;\nuse tonlib::client::TonClient;\nuse crate::tonlib::client::TonClientInterface;\n\nasync fn get_state()-\u003e anyhow::Result\u003c()\u003e{  \n    let client = TonClient::builder().build().await?;\n    let address = TonAddress::from_base64_url(\n        \"EQB3ncyBUTjZUA5EnFKR5_EnOMI9V1tTEAAPaiU71gc4TiUt-\",\n    )?;\n    let r = client\n            .get_account_state(\u0026address)\n            .await;\n    Ok(())\n}\n```\n\n\n\n### Working with contracts and jettons\n\nMethods for working with tokens and wallets:\n\n``` rust\nuse tonlib::client::TonClient;\nuse tonlib::contract::TonContractFactory;\nuse crate::tonlib::contract::JettonMasterContract;\nuse crate::tonlib::contract::JettonWalletContract;\n\nasync fn method_call() -\u003e anyhow::Result\u003c()\u003e { \n    let client = TonClient::builder().build().await?;\n    let contract_factory = TonContractFactory::builder(\u0026client).build().await?;\n    let master_contract = contract_factory.get_contract(\n        \u0026\"EQDk2VTvn04SUKJrW7rXahzdF8_Qi6utb0wj43InCu9vdjrR\".parse()?,\n    );\n    let jetton_data = master_contract.get_jetton_data().await?;\n\n    let wallet_contract = contract_factory.get_contract(\n        \u0026\"EQCGY3OVLtD9KRcOsP2ldQDtuY0FMzV7wPoxjrFbayBXc23c\".parse()?,\n    );\n    let wallet_data = wallet_contract.get_wallet_data().await?;\n    Ok(())\n}\n```\n\nTo load the metadata of the token, one may use generic `MetaLoader` and it type aliases: `JettonMetaLoader, NftItemMetaLoader NftColletionMetaLoader`:\n\n```rust\nuse tonlib::client::TonClient;\nuse tonlib::contract::TonContractFactory;\nuse tonlib::contract::JettonMasterContract;\nuse tonlib::meta::JettonMetaLoader;\nuse tonlib::meta::LoadMeta;\n\nasync fn load_meta() -\u003e anyhow::Result\u003c()\u003e { \n    let client = TonClient::builder().build().await?;\n    let contract_factory = TonContractFactory::builder(\u0026client).build().await?;\n    let contract =\n        contract_factory.get_contract(\u0026\"EQB-MPwrd1G6WKNkLz_VnV6WqBDd142KMQv-g1O-8QUA3728\".parse()?); \n    let jetton_data = contract.get_jetton_data().await?;\n    let loader = JettonMetaLoader::default()?;\n    let content_res = loader.load(\u0026jetton_data.content).await?;\n\nOk(())\n}\n```\n\n\nGet the wallet address for the token:\n\n```rust\nuse tonlib::address::TonAddress;\nuse tonlib::client::TonClient;\nuse tonlib::contract::TonContractFactory;\nuse tonlib::contract::JettonMasterContract; \n\nasync fn get_wallet_address() -\u003e anyhow::Result\u003c()\u003e {\n\n    let client = TonClient::default().await?;\n    let contract_factory = TonContractFactory::builder(\u0026client).build().await?;\n    let contract =\n        contract_factory.get_contract(\u0026\"EQDk2VTvn04SUKJrW7rXahzdF8_Qi6utb0wj43InCu9vdjrR\".parse()?,\n    );\n    let owner_address = TonAddress::from_base64_url(\n        \"EQB2BtXDXaQuIcMYW7JEWhHmwHfPPwa-eoCdefiAxOhU3pQg\",\n    )?;\n    let wallet_address = contract.get_wallet_address(\u0026owner_address).await?;\n    Ok(())\n}\n```\n\n### Send message to TON\n\nCreate key pair from secret phrase ( )\n\n```rust\nuse tonlib::mnemonic::Mnemonic;\nuse tonlib::mnemonic::KeyPair;\nasync fn create_key_pair() -\u003e anyhow::Result\u003c()\u003e {\n    let mnemonic = Mnemonic::new(\n        vec![\n            \"dose\", \"ice\", \"enrich\", \"trigger\", \"test\", \"dove\", \"century\", \"still\", \"betray\",\n            \"gas\", \"diet\", \"dune\",\n        ],\n        \u0026None,\n        )?;\n    let key_pair = mnemonic.to_key_pair();\n    Ok(())\n}\n\n```\nAnd now you are ready to send transfer messages to TON blockchain.\n\nCreate a jetton transfer:\n\n```rust\n\n\nuse num_bigint::BigUint;\nuse std::time::SystemTime;\n\nuse tonlib::address::TonAddress;\nuse tonlib::cell::BagOfCells;\nuse tonlib::client::TonClient;\nuse tonlib::client::TonClientInterface;\nuse tonlib::contract::TonContractFactory;\nuse tonlib::contract::JettonMasterContract;\nuse tonlib::message::JettonTransferMessage;\n\nuse tonlib::message::TransferMessage;\nuse tonlib::mnemonic::KeyPair;\nuse tonlib::mnemonic::Mnemonic;\nuse tonlib::wallet::TonWallet;\nuse tonlib::wallet::WalletVersion;\n\nasync fn create_jetton_transfer() -\u003e anyhow::Result\u003c()\u003e {\n\n    let seqno:i32 = 30000000;\n\n    let self_address: TonAddress = \"EQB2BtXDXaQuIcMYW7JEWhHmwHfPPwa-eoCdefiAxOhU3pQg \"\n        .parse()\n        .unwrap();\n    let mnemonic_str = \"mnemonic mnemonic mnemonic mnemonic mnemonic mnemonic mnemonic mnemonic mnemonic mnemonic mnemonic mnemonic mnemonic mnemonic mnemonic mnemonic mnemonic mnemonic mnemonic mnemonic mnemonic mnemonic mnemonic mnemonic\";\n    let mnemonic: Mnemonic = Mnemonic::from_str(mnemonic_str, \u0026None).unwrap();\n    let key_pair: KeyPair = mnemonic.to_key_pair().unwrap();\n    let jetton_master_address: TonAddress = \"EQDCJL0iQHofcBBvFBHdVG233Ri2V4kCNFgfRT-gqAd3Oc86\"\n        .parse()\n        .unwrap();\n\n    let client = TonClient::default().await?;\n        let contract_factory = TonContractFactory::builder(\u0026client).build().await?;\n    let jetton_master =\n        contract_factory.get_contract(\u0026jetton_master_address);\n    let self_jetton_wallet_addr = jetton_master.get_wallet_address(\u0026self_address).await?;\n    let wallet = TonWallet::derive_default(WalletVersion::V4R2, \u0026key_pair)?;\n    let dest: TonAddress = \"\u003cdestination wallet address\u003e\".parse()?;\n    let src: TonAddress = \"\u003csource wallet address\u003e\".parse()?;\n    let jetton_amount = BigUint::from(1000000u64);\n    let jetton_transfer = JettonTransferMessage::new(\u0026dest, \u0026jetton_amount)\n        .with_query_id(100500)\n        .with_response_destination(\u0026self_address)\n        .build()?;\n    let ton_amount = BigUint::from(200000000u64); // 0.2 TON\n    let transfer = TransferMessage::new(\u0026src, \u0026ton_amount)\n        .with_data(jetton_transfer)\n        .build()?;\n    let now = SystemTime::now()\n        .duration_since(SystemTime::UNIX_EPOCH)?\n        .as_secs() as u32;\n    let body = wallet.create_external_body(now + 60, seqno.try_into().unwrap(), vec![transfer])?;\n    let signed = wallet.sign_external_body(\u0026body)?;\n    let wrapped = wallet.wrap_signed_body(signed)?;\n    let boc = BagOfCells::from_root(wrapped);\n    let tx = boc.serialize(true)?;\n\n    let hash = client.send_raw_message_return_hash(tx.as_slice()).await?;\n\n    Ok(())\n}\n```\n\nCreate a simple transfer:\n\n```rust\n\nuse anyhow::anyhow;\nuse num_bigint::BigUint;\nuse std::time::SystemTime;\n\nuse tonlib::address::TonAddress;\nuse tonlib::cell::BagOfCells;\nuse tonlib::message::TransferMessage;\nuse tonlib::wallet::TonWallet;\nuse tonlib::client::TonClient;\nuse tonlib::client::TonClientInterface;\nuse tonlib::mnemonic::KeyPair;\nuse tonlib::mnemonic::Mnemonic;\nuse tonlib::wallet::WalletVersion;\n\n\nasync fn create_simple_transfer() -\u003e anyhow::Result\u003c()\u003e {\n    let mnemonic = Mnemonic::new(\n        vec![\n            \"dose\", \"ice\", \"enrich\", \"trigger\", \"test\", \"dove\", \"century\", \"still\", \"betray\",\n            \"gas\", \"diet\", \"dune\",\n        ],\n        \u0026None,\n        )?;\n    let key_pair = mnemonic.to_key_pair()?;\n    let seqno =  30000000;\n    \n\n    let client = TonClient::default().await?;\n    let wallet = TonWallet::derive_default(WalletVersion::V4R2, \u0026key_pair)?;\n    let dest: TonAddress = \"\u003cdestination wallet address\u003e\".parse()?;\n    let value = BigUint::from(10000000u64); // 0.01 TON\n    let transfer = TransferMessage::new(\u0026dest, \u0026value).build()?;\n    let now = SystemTime::now()\n        .duration_since(SystemTime::UNIX_EPOCH)?\n        .as_secs() as u32;\n    let body = wallet.create_external_body(now + 60, seqno, vec![transfer])?;\n    let signed = wallet.sign_external_body(\u0026body)?;\n    let wrapped = wallet.wrap_signed_body(signed)?;\n    let boc = BagOfCells::from_root(wrapped);\n    let tx = boc.serialize(true)?;\n    let hash = client.send_raw_message_return_hash(tx.as_slice()).await?;\n\n    Ok(())\n}\n```\n\n## Cross-compilation\nIn order to cross-compile for specific cpu microachitecture set environment variable `TARGET_CPU_MARCH` to the required. Supported values are listen in https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html\n\n## Contributing\n\nIf you want to contribute to this library, please feel free to open a pull request on GitHub.\n\n## License\nThis library is licensed under the MIT license. See the LICENSE file for details. --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fston-fi%2Ftonlib-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fston-fi%2Ftonlib-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fston-fi%2Ftonlib-rs/lists"}