tensora-rs 0.1.0

Rust SDK for the Tensora L2 AI Network built with OP Stack and BSC settlement.
Documentation

Tensora Rust SDK

Crates.io Documentation License Build

Official Rust SDK for the Tensora L2 AI Network

A production-ready SDK for building on Tensora โ€” an OP Stack Layer-2 blockchain with BSC settlement

๐Ÿ“– Documentation โ€ข ๐Ÿš€ Quick Start โ€ข ๐Ÿ—๏ธ Architecture โ€ข ๐Ÿ’ฌ Discord


๐Ÿš€ Features

  • โœ… Typed Contract Bindings โ€” Auto-generated bindings for TORA token, staking, subnets, bridge, and paymaster
  • ๐Ÿ” Wallet Abstraction โ€” Secure keystore and signer management
  • ๐ŸŒ‰ Bridge Helpers โ€” L1โ†”L2 token bridging (WTORA deposits/withdrawals)
  • ๐Ÿ“Š API Clients โ€” REST clients for indexer, explorer, and coordinator services
  • โ›ฝ Paymaster Support โ€” ERC-4337 gasless transactions
  • ๐Ÿ—๏ธ Subnet Management โ€” Create and manage subnets, validators, and miners
  • ๐Ÿ”„ Async-first โ€” Built on tokio and ethers-rs
  • ๐Ÿ›ก๏ธ BSC Reorg Handling โ€” Safe bridge operations with confirmation tracking

๐Ÿ“ฆ Installation

Add to your Cargo.toml:

[dependencies]
tensora = "0.1"
ethers = "2"
tokio = { version = "1", features = ["full"] }

Or use cargo add:

cargo add tensora ethers
cargo add tokio --features full

โšก Quick Start

1. Set Up Environment

Create a .env file:

TENSORA_RPC=https://rpc.tensora.sh
TENSORA_CHAIN_ID=44444444
BSC_RPC=https://bsc-dataseed.binance.org
PRIVATE_KEY=0x...  # Optional, for signing transactions

2. Connect to Tensora L2

use tensora::prelude::*;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Load configuration from environment
    let config = TensoraConfig::from_env()?;
    
    // Create client
    let client = TensoraClient::new(&config).await?;
    
    // Get current block number
    let block = client.get_block_number().await?;
    println!("Current block: {}", block);
    
    Ok(())
}

3. Check Balance

use tensora::prelude::*;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = TensoraClient::default().await?;
    
    let address: Address = "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb".parse()?;
    let balance = client.get_balance(address).await?;
    
    println!("Balance: {} BNB", ethers::utils::format_ether(balance));
    
    Ok(())
}

4. Work with TORA Token

use tensora::prelude::*;
use tensora::contracts::ToraToken;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = TensoraClient::default().await?;
    
    // WTORA token address on Tensora L2
    let wtora_addr: Address = "0x...".parse()?;
    let wtora = ToraToken::new(wtora_addr, &client);
    
    // Get token info
    let symbol = wtora.symbol().await?;
    let decimals = wtora.decimals().await?;
    let total_supply = wtora.total_supply().await?;
    
    println!("Token: {}", symbol);
    println!("Decimals: {}", decimals);
    println!("Total Supply: {}", ethers::utils::format_units(total_supply, decimals)?);
    
    // Check balance
    let my_addr: Address = "0x...".parse()?;
    let balance = wtora.balance_of(my_addr).await?;
    println!("My balance: {} {}", ethers::utils::format_units(balance, decimals)?, symbol);
    
    Ok(())
}

5. Query Subnet Information

use tensora::api::IndexerClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let indexer = IndexerClient::new("https://indexer.tensora.sh")?;
    
    // List all subnets
    let subnets = indexer.list_subnets().await?;
    for subnet in subnets {
        println!("Subnet #{}: {} ({} validators, {} miners)",
            subnet.id,
            subnet.name,
            subnet.validator_count,
            subnet.miner_count
        );
    }
    
    Ok(())
}

๐Ÿ“– Examples

Run the included examples:

# Check balance
cargo run --example get_balance

# Monitor bridge deposits
cargo run --example bridge_deposit

# Check staking info
cargo run --example stake

๐Ÿ”ง Configuration

Environment Variables

Variable Description Default
TENSORA_RPC Tensora L2 RPC endpoint https://rpc.tensora.sh
TENSORA_CHAIN_ID Tensora L2 chain ID 44444444
BSC_RPC BSC L1 RPC endpoint https://bsc-dataseed.binance.org
BSC_CHAIN_ID BSC chain ID 56
PRIVATE_KEY Private key for signing (optional) -
L1_WTORA WTORA address on BSC -
L2_WTORA WTORA address on Tensora -
L1_BRIDGE L1 Standard Bridge address -
L2_BRIDGE L2 Standard Bridge address -
STAKING_HUB Staking Hub contract address -
SUBNET_FACTORY Subnet Factory contract address -
ENTRY_POINT ERC-4337 EntryPoint address -
PAYMASTER Paymaster contract address -

Programmatic Configuration

use tensora::config::{TensoraConfig, AddressConfig};

let config = TensoraConfig::new(
    "https://rpc.tensora.sh".to_string(),
    "https://bsc-dataseed.binance.org".to_string(),
)
.with_private_key("0x...".to_string())
.with_addresses(AddressConfig {
    l2_wtora: Some("0x...".to_string()),
    staking_hub: Some("0x...".to_string()),
    ..Default::default()
});

๐Ÿ—๏ธ Architecture

Core Modules

  • client โ€” RPC client for L2 (Tensora) and L1 (BSC)
  • config โ€” Configuration management and validation
  • wallet โ€” Wallet and signer abstraction
  • types โ€” Shared types (SubnetInfo, ValidatorInfo, etc.)
  • errors โ€” Error handling with thiserror
  • contracts โ€” Smart contract bindings
    • tora_token โ€” TORA/WTORA ERC-20 token
    • staking_hub โ€” Staking and rewards
    • subnet_factory โ€” Subnet creation and management
    • bridge โ€” OP Stack L1/L2 Standard Bridge
    • paymaster โ€” ERC-4337 Paymaster
  • api โ€” Off-chain API clients
    • indexer โ€” Subnet, validator, and miner data
    • explorer โ€” Transaction and block data
    • coordinator โ€” Epoch and VRF data

๐ŸŒ‰ Bridge Operations

L1 โ†’ L2 Deposit (BSC โ†’ Tensora)

// Note: This requires a signer and actual bridge implementation
// Placeholder for reference:

// 1. Approve WTORA on L1
// 2. Call depositERC20() on L1 Bridge
// 3. Wait for L1 confirmation
// 4. Wait for L2 relay (2-5 minutes)
// 5. Verify balance on L2

โš ๏ธ Important: BSC can experience reorgs. Wait for at least 15 confirmations on L1 before considering a deposit finalized.

L2 โ†’ L1 Withdrawal (Tensora โ†’ BSC)

// Note: This requires a signer and actual bridge implementation
// Withdrawal process:

// 1. Call withdrawERC20() on L2 Bridge
// 2. Wait for state root submission (~1 hour)
// 3. Wait for challenge period (~7 days on mainnet, faster on testnet)
// 4. Call finalizeWithdrawal() on L1
// 5. Verify balance on L1

๐Ÿ”’ Staking

use tensora::contracts::StakingHub;

// Get staking info
let staking_hub = StakingHub::new(staking_addr, &client);
let total_staked = staking_hub.get_total_staked().await?;
let my_stake = staking_hub.get_stake(my_addr).await?;
let rewards = staking_hub.get_rewards(my_addr).await?;

// Note: stake(), unstake(), and claim() require SignerMiddleware

๐Ÿงช Testing

cargo test

๐Ÿ“š Documentation

Generate and view documentation:

cargo doc --open

Or visit docs.rs/tensora-rs

๐Ÿ”— Network Information

Tensora L2 Mainnet

Parameter Value
Chain ID 44444444
RPC https://rpc.tensora.sh
Explorer https://explorer.tensora.sh
Native Token BNB
Wrapped Token WTORA

BSC L1

Parameter Value
Chain ID 56
RPC https://bsc-dataseed.binance.org
Explorer https://bscscan.com

๐Ÿค Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

๐Ÿ“„ License

Licensed under the Apache License, Version 2.0. See LICENSE for details.

๐Ÿ”— Links

โš ๏ธ Disclaimer

This SDK is provided "as is" without warranty of any kind. Use at your own risk. Always test on testnet before using on mainnet.


Built with โค๏ธ by the Tensora Labs team