# ootle.rs
[](https://crates.io/crates/ootle-rs)
[](https://docs.rs/ootle-rs)
[](LICENSE-APACHE)
**High-performance, familiar interaction with the Tari Ootle (Layer 2) network.**
`ootle.rs` is a pure Rust library designed to be the standard interface for interacting with Tari Ootle. It is
architected to mirror the interface of [alloy-rs](https://github.com/alloy-rs/alloy), providing a seamless developer
experience for those transitioning from Ethereum or generic blockchain development to the Tari ecosystem.
## ✨ Features
* **Alloy-like API:** Uses the familiar `Provider`, `Signer`, and `Transport` architecture found in `alloy`.
* **Ootle Native:** First-class support for Tari Ootle
* **Type-Safe:** Strongly typed interactions with Tari's confidential assets.
* **Async/Await:** Built on `tokio` for high-performance, non-blocking I/O.
## 📦 Installation
Add this to your `Cargo.toml`:
```toml
[dependencies]
ootle-rs = "0.1.0"
```
## 🚀 Quick Start
Connect to a local Ootle indexer, create a wallet, and send a transaction.
```rust
use ootle_rs::{
address,
builtin_templates::account::IAccount,
key_provider::PrivateKeyProvider,
provider::ProviderBuilder,
wallet::OotleWallet,
TransactionRequest,
};
use tari_ootle_common_types::Network;
use tari_template_lib_types::constants::TARI_TOKEN;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let network = Network::LocalNet;
let indexer_api_url = "http://127.0.0.1:12500";
// 1. Setup a wallet with a random key
let signer = PrivateKeyProvider::random(network);
let wallet = OotleWallet::from(signer);
// 2. Create a provider
let provider = ProviderBuilder::new()
.with_network(network)
.wallet(wallet)
.connect(indexer_api_url)
.await?;
// 3. Craft and send a transaction (e.g., using IAccount for a transfer)
let recipient = address!("otl_loc_10mc0v2lyy43kldl0ft4c2x5pe7j0ckduv8zej6jgr2z2g9m07fz7gl96ar5wwgu0qu0atmr5tl53ye7n38xr5u7ytlmudq0ruxcau0gge7rxk");
let unsigned_tx = IAccount::new(&provider)
.pay_fee(1000u64)
.public_transfer(&recipient, TARI_TOKEN, 1_000_000u64)
.prepare()
.await?;
let tx = TransactionRequest::default()
.with_transaction(unsigned_tx)
.build(provider.wallet())
.await?;
let pending_tx = provider.send_transaction(tx).await?;
let outcome = pending_tx.watch().await?;
println!("✅ Transaction confirmed: {:?}", outcome);
Ok(())
}
```
## 🏗 Architecture
ootle.rs follows the modular design of alloy:
- Core: Defines the primitive types (Addresses, Signatures, Confidential Commitments) specific to Tari.
- Transport: Handles communication with Ootle Indexers and Validator Nodes (VNs).
- Provider: The high-level API for sending requests and managing state.
- Signer: Abstractions for signing transactions (support for Ristretto keys).
## 🤝 Contributing
We welcome contributions! Please see CONTRIBUTING.md for details on how to get started.
## 📄 License
This project is dual-licensed under either:
Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
---
"To the Ootle!" 🦉