Getting Started

Getting Started - Developer Quick Start Guide

This guide will help you get started building with Roru Labs. You'll learn how to install the SDK, create your first wallet, send a transaction, and integrate Roru into your application.

Prerequisites

Before you begin:

  1. Beta Access: Register at the Roru Labs portal and get approved

  2. API Key: Obtain your API key from the portal

  3. Development Environment: Set up your preferred language environment

Step 1: Installation

Choose Your Language

Install the SDK for your preferred language:

Rust:

cargo add roru-sdk

TypeScript/JavaScript:

npm install @roru/sdk

Python:

pip install roru-sdk

See Installation Guides for detailed instructions for all languages.

Step 2: Initialize Client

Basic Setup

Rust:

use roru_sdk::prelude::*;

#[tokio::main]
async fn main() -> Result<()> {
    let config = ClientConfig {
        infra_endpoint: "https://infra.roru.labs".to_string(),
        api_key: Some(env::var("RORU_API_KEY")?),
        ..Default::default()
    };
    
    let client = RoruClient::new(config).await?;
    // Use client...
    Ok(())
}

TypeScript:

import { RoruClient } from '@roru/sdk';

const client = new RoruClient({
    infraEndpoint: 'https://infra.roru.labs',
    apiKey: process.env.RORU_API_KEY,
});

Python:

from roru_sdk import RoruClient
import os

client = RoruClient(
    infra_endpoint="https://infra.roru.labs",
    api_key=os.getenv("RORU_API_KEY")
)

Step 3: Create or Load Wallet

Create New Wallet

Rust:

let wallet = client.create_wallet().await?;

// Save master key securely
let master_key = wallet.get_master_key()?;
save_master_key_securely(master_key)?;

TypeScript:

const wallet = await client.createWallet();
const masterKey = wallet.getMasterKey();
// Save master key securely

Load Existing Wallet

Rust:

let master_key = load_master_key_securely()?;
let wallet = client.load_wallet(&master_key).await?;

TypeScript:

const masterKey = loadMasterKeySecurely();
const wallet = await client.loadWallet(masterKey);

Step 4: Generate Address

Rust:

let address = wallet.generate_address()?;
println!("Your address: {}", address.to_string());

TypeScript:

const address = wallet.generateAddress();
console.log('Your address:', address.toString());

Step 5: Check Balance

Rust:

// Sync state first
wallet.sync_state().await?;

// Get balance
let balance = wallet.get_balance().await?;
println!("Shielded balance: {}", balance.shielded);

TypeScript:

await wallet.syncState();
const balance = await wallet.getBalance();
console.log('Shielded balance:', balance.shielded);

Step 6: Send Transaction

Basic Transaction

Rust:

use roru_sdk::prelude::*;

// Generate recipient address
let recipient = ShieldedAddress::from_string("roru1...")?;

// Build transaction
let tx = TransactionBuilder::new()
    .to(recipient)
    .amount(1_000_000) // 1.0 tokens
    .build()?;

// Send transaction
let result = wallet.send_transaction(tx).await?;
println!("Transaction sent: {:?}", result.tx_hash);

TypeScript:

import { TransactionBuilder } from '@roru/sdk';

const recipient = ShieldedAddress.fromString('roru1...');
const tx = new TransactionBuilder()
    .to(recipient)
    .amount(1_000_000)
    .build();

const result = await wallet.sendTransaction(tx);
console.log('Transaction sent:', result.txHash);

Transaction with Memo

Rust:

let tx = TransactionBuilder::new()
    .to(recipient)
    .amount(1_000_000)
    .memo(b"Payment for services")
    .build()?;

Multiple Outputs

Rust:

let recipient1 = wallet.generate_address()?;
let recipient2 = wallet.generate_address()?;

let tx = TransactionBuilder::new()
    .to(recipient1)
    .amount(500_000)
    .add_output(recipient2, 300_000)
    .build()?;

Step 7: Wait for Confirmation

Rust:

let confirmation = wallet.wait_for_confirmation(
    result.tx_hash,
    Duration::from_secs(60)
).await?;

println!("Confirmed in block: {}", confirmation.block_number);

TypeScript:

const confirmation = await wallet.waitForConfirmation(
    result.txHash,
    60000 // 60 seconds timeout
);
console.log('Confirmed in block:', confirmation.blockNumber);

Complete Example

Full Application

Rust:

use roru_sdk::prelude::*;
use std::env;
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<()> {
    // Initialize client
    let config = ClientConfig {
        infra_endpoint: env::var("RORU_INFRA_ENDPOINT")
            .unwrap_or_else(|_| "https://infra.roru.labs".to_string()),
        api_key: env::var("RORU_API_KEY").ok(),
        ..Default::default()
    };
    
    let client = RoruClient::new(config).await?;
    
    // Load or create wallet
    let wallet = if let Ok(master_key) = load_master_key() {
        client.load_wallet(&master_key).await?
    } else {
        let wallet = client.create_wallet().await?;
        save_master_key(wallet.get_master_key()?)?;
        wallet
    };
    
    // Sync state
    println!("Syncing state...");
    wallet.sync_state().await?;
    
    // Check balance
    let balance = wallet.get_balance().await?;
    println!("Current balance: {} tokens", balance.shielded as f64 / 1_000_000.0);
    
    // Generate address for receiving
    let address = wallet.generate_address()?;
    println!("Your address: {}", address.to_string());
    
    // Example: Send transaction (commented out for safety)
    /*
    let recipient = ShieldedAddress::from_string("roru1...")?;
    let tx = TransactionBuilder::new()
        .to(recipient)
        .amount(100_000) // 0.1 tokens
        .memo(b"Test transaction")
        .build()?;
    
    let result = wallet.send_transaction(tx).await?;
    println!("Transaction sent: {:?}", result.tx_hash);
    
    let confirmation = wallet.wait_for_confirmation(
        result.tx_hash,
        Duration::from_secs(60)
    ).await?;
    
    println!("Transaction confirmed!");
    */
    
    Ok(())
}

fn load_master_key() -> Result<MasterKey> {
    // Implement secure key loading
    todo!()
}

fn save_master_key(key: MasterKey) -> Result<()> {
    // Implement secure key saving
    todo!()
}

TypeScript:

import { RoruClient, TransactionBuilder, ShieldedAddress } from '@roru/sdk';

async function main() {
    // Initialize client
    const client = new RoruClient({
        infraEndpoint: process.env.RORU_INFRA_ENDPOINT || 'https://infra.roru.labs',
        apiKey: process.env.RORU_API_KEY,
    });
    
    // Load or create wallet
    let wallet;
    try {
        const masterKey = loadMasterKey();
        wallet = await client.loadWallet(masterKey);
    } catch {
        wallet = await client.createWallet();
        saveMasterKey(wallet.getMasterKey());
    }
    
    // Sync state
    console.log('Syncing state...');
    await wallet.syncState();
    
    // Check balance
    const balance = await wallet.getBalance();
    console.log(`Current balance: ${balance.shielded / 1_000_000} tokens`);
    
    // Generate address
    const address = wallet.generateAddress();
    console.log('Your address:', address.toString());
    
    // Example: Send transaction
    /*
    const recipient = ShieldedAddress.fromString('roru1...');
    const tx = new TransactionBuilder()
        .to(recipient)
        .amount(100_000)
        .memo(Buffer.from('Test transaction'))
        .build();
    
    const result = await wallet.sendTransaction(tx);
    console.log('Transaction sent:', result.txHash);
    
    const confirmation = await wallet.waitForConfirmation(result.txHash, 60000);
    console.log('Transaction confirmed!');
    */
}

function loadMasterKey(): MasterKey {
    // Implement secure key loading
    throw new Error('Not implemented');
}

function saveMasterKey(key: MasterKey): void {
    // Implement secure key saving
}

main().catch(console.error);

Next Steps

Now that you have the basics working:

  1. Read API Documentation: Explore the full API reference

  2. Learn About Proofs: Understand zero-knowledge proofs

  3. Explore Advanced Features: Offline transactions, hardware integration

  4. Build Your App: Start integrating Roru into your application

  5. Join Community: Get help and share your projects

Common Patterns

Error Handling

Rust:

match wallet.send_transaction(tx).await {
    Ok(result) => println!("Success: {:?}", result.tx_hash),
    Err(RoruError::InsufficientBalance) => {
        println!("Not enough funds");
    }
    Err(e) => println!("Error: {}", e),
}

Periodic State Sync

Rust:

use tokio::time::{interval, Duration};

let mut sync_interval = interval(Duration::from_secs(30));

loop {
    sync_interval.tick().await;
    if let Err(e) = wallet.sync_state().await {
        eprintln!("Sync error: {}", e);
    }
}

Transaction Monitoring

Rust:

let tx_hash = result.tx_hash;

tokio::spawn(async move {
    loop {
        if let Ok(status) = wallet.get_transaction_status(&tx_hash).await {
            match status {
                TransactionStatus::Confirmed(block) => {
                    println!("Confirmed in block: {}", block);
                    break;
                }
                TransactionStatus::Failed => {
                    println!("Transaction failed");
                    break;
                }
                _ => {
                    tokio::time::sleep(Duration::from_secs(5)).await;
                }
            }
        }
    }
});

Troubleshooting

Common Issues

"Network error":

  • Check API key is set correctly

  • Verify endpoint URL

  • Check network connectivity

"Insufficient balance":

  • Sync state: wallet.sync_state().await?

  • Check balance: wallet.get_balance().await?

  • Ensure you have received funds

"Invalid address":

  • Verify address format

  • Check address is for correct network

  • Ensure address is valid shielded address

Resources

Conclusion

You now have the basics to start building with Roru! The SDK provides a clean, type-safe API for creating private transactions. Continue exploring the documentation to learn about advanced features and best practices.

Last updated