volt-client-grpc 0.0.3

TDX Volt gRPC client library for Rust
Documentation
# volt-client-grpc

A Rust client library for connecting to TDX Volt servers via gRPC.

## Overview

This library provides a Rust implementation for:
- Authenticating with Volt servers (direct and relayed connections)
- Managing persistent connections with automatic reconnection
- Making unary and streaming gRPC calls
- Resource management operations
- File operations
- Database operations
- Y.js/yrs document synchronization via SyncProvider

## Proto File Compilation

This package includes protobuf definitions in the `proto/volt_api/` directory. The build script uses `tonic-build` to compile these into Rust code.

```
packages/volt-client-grpc/
├── proto/
│   ├── sync.proto          # Sync protocol definitions
│   └── volt_api/
│       └── tdx/volt_api/
│           ├── volt/       # Main Volt API
│           ├── data/       # Database API
│           ├── relay/      # Relay API
│           └── proto_db_sync/  # DB sync protocol
├── src/
└── build.rs
```

The proto files are automatically compiled during the build process.

### Generated Types

The following modules are generated from proto files:

- `proto::volt` - Main Volt API (authentication, resources, connections)
- `proto::data` - Database API (SQLite operations)
- `proto::relay` - Relay API (for relayed connections through cloud relay)
- `proto::proto_db_sync` - Database sync protocol

## Installation

Add to your `Cargo.toml`:

```toml
[dependencies]
volt-client-grpc = { path = "path/to/volt-client-grpc" }
```

## Usage

### Basic Connection

```rust
use volt_client_grpc::{VoltClient, VoltClientConfig, InitialiseOptions};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Load configuration from file
    let mut client = VoltClient::new()?;
    
    client.initialise(
        "volt.config.json".into(),
        InitialiseOptions::default()
    ).await?;
    
    // Connect to the Volt
    let mut events = client.connect(None).await?;
    
    // Handle connection events
    tokio::spawn(async move {
        while let Some(event) = events.recv().await {
            match event {
                volt_client_grpc::volt_connection::ConnectionEvent::Connected(id) => {
                    println!("Connected with ID: {}", id);
                }
                volt_client_grpc::volt_connection::ConnectionEvent::Disconnected => {
                    println!("Disconnected");
                }
                volt_client_grpc::volt_connection::ConnectionEvent::Ping(ts) => {
                    println!("Ping: {}", ts);
                }
                _ => {}
            }
        }
    });
    
    // Make API calls
    let resources = client.get_resources(serde_json::json!({})).await?;
    println!("Resources: {:?}", resources);
    
    // Disconnect when done
    client.disconnect().await;
    
    Ok(())
}
```

### Configuration

Configuration can be provided in several ways:

```rust
use volt_client_grpc::{VoltClient, VoltClientConfig, VoltConfig, ConfigSource};

// From a file
let source: ConfigSource = "volt.config.json".into();

// From a config struct
let config = VoltClientConfig {
    client_name: "my-client".to_string(),
    volt: VoltConfig {
        id: "did:volt:example".to_string(),
        address: Some("localhost:8080".to_string()),
        ca_pem: Some("-----BEGIN CERTIFICATE-----...".to_string()),
        ..Default::default()
    },
    ..Default::default()
};
let source: ConfigSource = config.into();

// From JSON
let source: ConfigSource = serde_json::json!({
    "client_name": "my-client",
    "volt": {
        "id": "did:volt:example",
        "address": "localhost:8080"
    }
}).into();
```

### Configuration File Format

```json
{
  "client_name": "my-rust-client",
  "volt": {
    "id": "did:volt:your-volt-id",
    "address": "volt.example.com:443",
    "ca_pem": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
  },
  "auto_reconnect": true,
  "ping_interval": 10000,
  "reconnect_interval": 5000,
  "timeout_interval": 60000
}
```

### Authentication Options

```rust
use volt_client_grpc::InitialiseOptions;

// Default DID-based authentication
let options = InitialiseOptions::default();

// Session-only authentication (no DID)
let options = InitialiseOptions::new().with_no_did();

// Manage your own DID
let options = InitialiseOptions::new().with_own_did();

// Use an exchange token
let options = InitialiseOptions::new()
    .with_exchange_token("your-token".to_string());

// Custom DID registries
let options = InitialiseOptions::new()
    .with_did_registries(vec![
        "https://custom-registry.example.com".to_string()
    ]);
```

### Resource Operations

```rust
// Get a resource
let resource = client.get_resource(serde_json::json!({
    "resource_id": "resource-123"
})).await?;

// Save a resource
let result = client.save_resource(serde_json::json!({
    "id": "resource-123",
    "name": "My Resource",
    "type": "custom"
})).await?;

// Delete a resource
let result = client.delete_resource(serde_json::json!({
    "resource_id": "resource-123"
})).await?;

// Request access to a resource
use volt_client_grpc::VoltAccessType;
let granted = client.request_access_blocking(
    "resource-123",
    VoltAccessType::Read
).await?;
```

### Database Operations

```rust
// Create a database
let result = client.create_database(serde_json::json!({
    "name": "my-database"
})).await?;

// Bulk update
let result = client.bulk_update(serde_json::json!({
    "database_id": "db-123",
    "statement": ["INSERT INTO users (name) VALUES ('Alice')"]
})).await?;
```

## API Reference

### VoltClient

The main client struct for interacting with a Volt server.

#### Methods

- `new()` - Create a new client
- `initialise(config, options)` - Initialize with configuration
- `initialise_and_connect(config, options, hello)` - Initialize and connect
- `connect(hello)` - Connect to the server
- `disconnect()` - Disconnect from the server
- `is_connected()` - Check connection status
- `close()` - Close and release resources

#### Resource Management

- `can_access_resource(request)` - Check resource access
- `delete_resource(request)` - Delete a resource
- `get_resource(request)` - Get a resource
- `get_resources(request)` - Get multiple resources
- `save_resource(request)` - Save a resource
- `request_access(request)` - Request resource access

#### File Operations

- `get_file_content(request)` - Get file content
- `set_file_content(request)` - Set file content
- `get_file_descendants(request)` - Get file descendants

#### Database Operations

- `create_database(request)` - Create a database
- `bulk_update(request)` - Bulk update

### VoltCredential

Manages authentication credentials.

### VoltConnection

Manages the persistent connection with automatic reconnection.

## Examples

See the `examples/` directory for complete working examples:

| Example | Description |
|---------|-------------|
| `grpc-client` | Basic gRPC client connection |
| `grpc-create-resource` | Create resources via gRPC |
| `sync-provider` | Y.js document synchronization |
| `sync-provider-with-subdocs` | Subdocument sync with events |
| `sync-manager-example` | High-level SyncManager API |
| `subdoc-writer` | Interactive subdocument editing |

Run an example:

```bash
cd examples/sync-provider
cargo run
```


## Features

- **Async/Await**: Built on Tokio for async operations
- **TLS Support**: Secure connections using rustls
- **Auto-Reconnect**: Automatic reconnection on disconnect
- **DID Support**: Decentralized identifier authentication
- **Streaming**: Support for bidirectional streaming RPCs

## Comparison with JavaScript Version

| Feature | JavaScript | Rust |
|---------|------------|------|
| Runtime | Node.js | Tokio |
| gRPC | @grpc/grpc-js | tonic |
| TLS | Node crypto | rustls |
| Crypto | Node crypto | ring, ed25519-dalek |
| Events | EventEmitter | mpsc channels |


## Contributing

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